// Return the X projections of the edges that overlap y1,y2. void ExclusionPolygon::computeEdgeIntersections(float y1, float y2, Vector<ExclusionInterval>& result) const { Vector<ExclusionPolygon::EdgeInterval> overlappingEdges; m_edgeTree.allOverlaps(ExclusionPolygon::EdgeInterval(y1, y2, 0), overlappingEdges); EdgeIntersection intersection; for (unsigned i = 0; i < overlappingEdges.size(); i++) { const ExclusionPolygonEdge *edge = static_cast<ExclusionPolygonEdge*>(overlappingEdges[i].data()); float x1; float x2; if (edge->minY() < y1) { computeXIntersection(edge, y1, intersection); x1 = intersection.point.x(); } else x1 = (edge->vertex1().y() < edge->vertex2().y()) ? edge->vertex1().x() : edge->vertex2().x(); if (edge->maxY() > y2) { computeXIntersection(edge, y2, intersection); x2 = intersection.point.x(); } else x2 = (edge->vertex1().y() > edge->vertex2().y()) ? edge->vertex1().x() : edge->vertex2().x(); if (x1 > x2) std::swap(x1, x2); if (x2 > x1) result.append(ExclusionInterval(x1, x2)); } sortExclusionIntervals(result); }
static void computeOverlappingEdgeXProjections(const FloatPolygon& polygon, float y1, float y2, Vector<ExclusionInterval>& result) { Vector<const FloatPolygonEdge*> edges; if (!polygon.overlappingEdges(y1, y2, edges)) return; EdgeIntersection intersection; for (unsigned i = 0; i < edges.size(); ++i) { const FloatPolygonEdge *edge = edges[i]; float x1; float x2; if (edge->minY() < y1) { computeXIntersection(edge, y1, intersection); x1 = intersection.point.x(); } else x1 = (edge->vertex1().y() < edge->vertex2().y()) ? edge->vertex1().x() : edge->vertex2().x(); if (edge->maxY() > y2) { computeXIntersection(edge, y2, intersection); x2 = intersection.point.x(); } else x2 = (edge->vertex1().y() > edge->vertex2().y()) ? edge->vertex1().x() : edge->vertex2().x(); if (x1 > x2) std::swap(x1, x2); if (x2 > x1) result.append(ExclusionInterval(x1, x2)); } sortExclusionIntervals(result); }
void ExclusionPolygon::computeXIntersections(float y, bool isMinY, Vector<ExclusionInterval>& result) const { Vector<ExclusionPolygon::EdgeInterval> overlappingEdges; m_edgeTree.allOverlaps(ExclusionPolygon::EdgeInterval(y, y, 0), overlappingEdges); Vector<EdgeIntersection> intersections; EdgeIntersection intersection; for (unsigned i = 0; i < overlappingEdges.size(); i++) { ExclusionPolygonEdge* edge = static_cast<ExclusionPolygonEdge*>(overlappingEdges[i].data()); if (computeXIntersection(edge, y, intersection) && intersection.type != VertexYBoth) intersections.append(intersection); } if (intersections.size() < 2) return; std::sort(intersections.begin(), intersections.end(), WebCore::compareEdgeIntersectionX); unsigned index = 0; int windCount = 0; bool inside = false; while (index < intersections.size()) { const EdgeIntersection& thisIntersection = intersections[index]; if (index + 1 < intersections.size()) { const EdgeIntersection& nextIntersection = intersections[index + 1]; if ((thisIntersection.point.x() == nextIntersection.point.x()) && (thisIntersection.type == VertexMinY || thisIntersection.type == VertexMaxY)) { if (thisIntersection.type == nextIntersection.type) { // Skip pairs of intersections whose types are VertexMaxY,VertexMaxY and VertexMinY,VertexMinY. index += 2; } else { // Replace pairs of intersections whose types are VertexMinY,VertexMaxY or VertexMaxY,VertexMinY with one intersection. index++; } continue; } } const ExclusionPolygonEdge& thisEdge = *thisIntersection.edge; bool evenOddCrossing = !windCount; if (fillRule() == RULE_EVENODD) { windCount += (thisEdge.vertex2().y() > thisEdge.vertex1().y()) ? 1 : -1; evenOddCrossing = evenOddCrossing || !windCount; } if (evenOddCrossing) { bool edgeCrossing = thisIntersection.type == Normal; if (!edgeCrossing) { FloatPoint prevVertex; FloatPoint thisVertex; FloatPoint nextVertex; if (getVertexIntersectionVertices(thisIntersection, prevVertex, thisVertex, nextVertex)) { if (nextVertex.y() == y) edgeCrossing = (isMinY) ? prevVertex.y() > y : prevVertex.y() < y; else if (prevVertex.y() == y) edgeCrossing = (isMinY) ? nextVertex.y() > y : nextVertex.y() < y; else edgeCrossing = true; } } if (edgeCrossing) inside = appendIntervalX(thisIntersection.point.x(), inside, result); } index++; } }