#ifndef GridCoordinate_h
#define GridCoordinate_h
#include "core/rendering/style/GridPosition.h"
#include "wtf/HashMap.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
struct GridSpan {
static PassOwnPtr<GridSpan> create(size_t initialPosition, size_t finalPosition)
{
return adoptPtr(new GridSpan(initialPosition, finalPosition));
}
static PassOwnPtr<GridSpan> createWithSpanAgainstOpposite(size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
{
size_t positionOffset = position.spanPosition() - 1;
if (side == ColumnStartSide || side == RowStartSide) {
size_t initialResolvedPosition = std::max<int>(0, resolvedOppositePosition - positionOffset);
return GridSpan::create(initialResolvedPosition, resolvedOppositePosition);
}
return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition + positionOffset);
}
static PassOwnPtr<GridSpan> createWithNamedSpanAgainstOpposite(size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side, const Vector<size_t>& gridLines)
{
if (side == RowStartSide || side == ColumnStartSide)
return createWithInitialNamedSpanAgainstOpposite(resolvedOppositePosition, position, gridLines);
return createWithFinalNamedSpanAgainstOpposite(resolvedOppositePosition, position, gridLines);
}
static PassOwnPtr<GridSpan> createWithInitialNamedSpanAgainstOpposite(size_t resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines)
{
size_t firstLineBeforeOppositePositionIndex = 0;
const size_t* firstLineBeforeOppositePosition = std::lower_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition);
if (firstLineBeforeOppositePosition != gridLines.end()) {
if (*firstLineBeforeOppositePosition > resolvedOppositePosition && firstLineBeforeOppositePosition != gridLines.begin())
--firstLineBeforeOppositePosition;
firstLineBeforeOppositePositionIndex = firstLineBeforeOppositePosition - gridLines.begin();
}
size_t gridLineIndex = std::max<int>(0, firstLineBeforeOppositePositionIndex - position.spanPosition() + 1);
size_t resolvedGridLinePosition = gridLines[gridLineIndex];
if (resolvedGridLinePosition > resolvedOppositePosition)
resolvedGridLinePosition = resolvedOppositePosition;
return GridSpan::create(resolvedGridLinePosition, resolvedOppositePosition);
}
static PassOwnPtr<GridSpan> createWithFinalNamedSpanAgainstOpposite(size_t resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines)
{
size_t firstLineAfterOppositePositionIndex = gridLines.size() - 1;
const size_t* firstLineAfterOppositePosition = std::upper_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition);
if (firstLineAfterOppositePosition != gridLines.end())
firstLineAfterOppositePositionIndex = firstLineAfterOppositePosition - gridLines.begin();
size_t gridLineIndex = std::min(gridLines.size() - 1, firstLineAfterOppositePositionIndex + position.spanPosition() - 1);
size_t resolvedGridLinePosition = GridPosition::adjustGridPositionForAfterEndSide(gridLines[gridLineIndex]);
if (resolvedGridLinePosition < resolvedOppositePosition)
resolvedGridLinePosition = resolvedOppositePosition;
return GridSpan::create(resolvedOppositePosition, resolvedGridLinePosition);
}
GridSpan(size_t initialPosition, size_t finalPosition)
: initialPositionIndex(initialPosition)
, finalPositionIndex(finalPosition)
{
ASSERT(initialPositionIndex <= finalPositionIndex);
}
bool operator==(const GridSpan& o) const
{
return initialPositionIndex == o.initialPositionIndex && finalPositionIndex == o.finalPositionIndex;
}
size_t initialPositionIndex;
size_t finalPositionIndex;
};
struct GridCoordinate {
GridCoordinate()
: columns(0, 0)
, rows(0, 0)
{
}
GridCoordinate(const GridSpan& r, const GridSpan& c)
: columns(c)
, rows(r)
{
}
bool operator==(const GridCoordinate& o) const
{
return columns == o.columns && rows == o.rows;
}
bool operator!=(const GridCoordinate& o) const
{
return !(*this == o);
}
GridSpan columns;
GridSpan rows;
};
typedef HashMap<String, GridCoordinate> NamedGridAreaMap;
}
#endif