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> computeShapeMarginBounds(const FloatPolygon& polygon, float margin, WindRule fillRule)
{
    OwnPtr<Vector<FloatPoint> > marginVertices = 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, outwardEdgeNormal(thisEdge) * margin);
        OffsetPolygonEdge prevOffsetEdge(prevEdge, outwardEdgeNormal(prevEdge) * margin);

        if (prevOffsetEdge.intersection(thisOffsetEdge, intersection))
            marginVertices->append(intersection);
        else
            appendArc(*marginVertices, thisEdge.vertex1(), margin, prevOffsetEdge.vertex2(), thisOffsetEdge.vertex1(), false);
    }

    snapVerticesToLayoutUnitGrid(*marginVertices);
    return adoptPtr(new FloatPolygon(marginVertices.release(), fillRule));
}