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> 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)); }
static inline FloatSize outwardEdgeNormal(const FloatPolygonEdge& edge) { return -inwardEdgeNormal(edge); }