Beispiel #1
0
void PolygonShape::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList& result) const
{
    float y1 = logicalTop;
    float y2 = logicalTop + logicalHeight;

    if (m_polygon.isEmpty() || !m_polygon.boundingBox().overlapsYRange(y1 - shapeMargin(), y2 + shapeMargin()))
        return;

    Vector<const FloatPolygonEdge*> overlappingEdges;
    if (!m_polygon.overlappingEdges(y1 - shapeMargin(), y2 + shapeMargin(), overlappingEdges))
        return;

    FloatShapeInterval excludedInterval;
    for (unsigned i = 0; i < overlappingEdges.size(); i++) {
        const FloatPolygonEdge& edge = *(overlappingEdges[i]);
        if (!shapeMargin())
            excludedInterval.unite(OffsetPolygonEdge(edge, FloatSize()).clippedEdgeXRange(y1, y2));
        else {
            excludedInterval.unite(OffsetPolygonEdge(edge, outwardEdgeNormal(edge) * shapeMargin()).clippedEdgeXRange(y1, y2));
            excludedInterval.unite(OffsetPolygonEdge(edge, inwardEdgeNormal(edge) * shapeMargin()).clippedEdgeXRange(y1, y2));
            excludedInterval.unite(clippedCircleXRange(edge.vertex1(), shapeMargin(), y1, y2));
        }
    }

    if (!excludedInterval.isEmpty())
        result.append(LineSegment(excludedInterval.x1(), excludedInterval.x2()));
}
LineSegment PolygonShape::getExcludedInterval(LayoutUnit logicalTop, LayoutUnit logicalHeight) const
{
    float y1 = logicalTop.toFloat();
    float y2 = logicalTop.toFloat() + logicalHeight.toFloat();

    if (m_polygon.isEmpty() || !overlapsYRange(m_polygon.boundingBox(), y1 - shapeMargin(), y2 + shapeMargin()))
        return LineSegment();

    Vector<const FloatPolygonEdge*> overlappingEdges;
    if (!m_polygon.overlappingEdges(y1 - shapeMargin(), y2 + shapeMargin(), overlappingEdges))
        return LineSegment();

    FloatShapeInterval excludedInterval;
    for (unsigned i = 0; i < overlappingEdges.size(); i++) {
        const FloatPolygonEdge& edge = *(overlappingEdges[i]);
        if (edge.maxY() == edge.minY())
            continue;
        if (!shapeMargin()) {
            excludedInterval.unite(OffsetPolygonEdge(edge, FloatSize()).clippedEdgeXRange(y1, y2));
        } else {
            excludedInterval.unite(OffsetPolygonEdge(edge, outwardEdgeNormal(edge) * shapeMargin()).clippedEdgeXRange(y1, y2));
            excludedInterval.unite(OffsetPolygonEdge(edge, inwardEdgeNormal(edge) * shapeMargin()).clippedEdgeXRange(y1, y2));
            excludedInterval.unite(clippedCircleXRange(edge.vertex1(), shapeMargin(), y1, y2));
        }
    }

    if (excludedInterval.isEmpty())
        return LineSegment();

    return LineSegment(excludedInterval.x1(), excludedInterval.x2());
}
Beispiel #3
0
static inline PassOwnPtr<FloatPolygon> computeShapePaddingBounds(const FloatPolygon& polygon, float padding, WindRule fillRule)
{
    OwnPtr<Vector<FloatPoint> > paddedVertices = adoptPtr(new Vector<FloatPoint>());
    FloatPoint intersection;

    for (unsigned i = 0; i < polygon.numberOfEdges(); ++i) {
        const FloatPolygonEdge& thisEdge = polygon.edgeAt(i);
        const FloatPolygonEdge& prevEdge = thisEdge.previousEdge();
        OffsetPolygonEdge thisOffsetEdge(thisEdge, inwardEdgeNormal(thisEdge) * padding);
        OffsetPolygonEdge prevOffsetEdge(prevEdge, inwardEdgeNormal(prevEdge) * padding);

        if (prevOffsetEdge.intersection(thisOffsetEdge, intersection))
            paddedVertices->append(intersection);
        else if (isReflexVertex(prevEdge.vertex1(), thisEdge.vertex1(), thisEdge.vertex2()))
            appendArc(*paddedVertices, thisEdge.vertex1(), padding, prevOffsetEdge.vertex2(), thisOffsetEdge.vertex1(), true);
    }

    snapVerticesToLayoutUnitGrid(*paddedVertices);
    return adoptPtr(new FloatPolygon(paddedVertices.release(), fillRule));
}
Beispiel #4
0
static inline FloatSize outwardEdgeNormal(const FloatPolygonEdge& edge)
{
    return -inwardEdgeNormal(edge);
}