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())); }
void PolygonShape::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList& result) const { const FloatPolygon& polygon = shapeMarginBounds(); if (polygon.isEmpty()) return; float y1 = logicalTop; float y2 = logicalTop + logicalHeight; FloatShapeIntervals y1XIntervals, y2XIntervals; computeXIntersections(polygon, y1, true, y1XIntervals); computeXIntersections(polygon, y2, false, y2XIntervals); FloatShapeIntervals mergedIntervals; FloatShapeInterval::uniteShapeIntervals(y1XIntervals, y2XIntervals, mergedIntervals); FloatShapeIntervals edgeIntervals; computeOverlappingEdgeXProjections(polygon, y1, y2, edgeIntervals); FloatShapeIntervals excludedIntervals; FloatShapeInterval::uniteShapeIntervals(mergedIntervals, edgeIntervals, excludedIntervals); for (unsigned i = 0; i < excludedIntervals.size(); ++i) { FloatShapeInterval interval = excludedIntervals[i]; result.append(LineSegment(interval.x1(), interval.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 bool compareX1(const FloatShapeInterval a, const FloatShapeInterval& b) { return a.x1() < b.x1(); }