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()); }
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)); }