void GraphicsContext::fillPath(const Path& path) { if (paintingDisabled()) return; CGContextRef context = platformContext(); CGContextBeginPath(context); CGContextAddPath(context, path.platformPath()); if (m_state.fillGradient) { CGContextSaveGState(context); if (fillRule() == RULE_EVENODD) CGContextEOClip(context); else CGContextClip(context); CGContextConcatCTM(context, m_state.fillGradient->gradientSpaceTransform()); m_state.fillGradient->paint(this); CGContextRestoreGState(context); return; } if (m_state.fillPattern) applyFillPattern(); fillPathWithFillRule(context, fillRule()); }
void GraphicsContext::fillRectWithRoundedHole(const IntRect& rect, const RoundedRect& roundedHoleRect, const Color& color, ColorSpace colorSpace) { if (paintingDisabled()) return; Path path; path.addRect(rect); if (!roundedHoleRect.radii().isZero()) path.addRoundedRect(roundedHoleRect); else path.addRect(roundedHoleRect.rect()); WindRule oldFillRule = fillRule(); Color oldFillColor = fillColor(); ColorSpace oldFillColorSpace = fillColorSpace(); setFillRule(RULE_EVENODD); setFillColor(color, colorSpace); fillPath(path); setFillRule(oldFillRule); setFillColor(oldFillColor, oldFillColorSpace); }
void GraphicsContext::fillPath() { if (paintingDisabled()) return; cairo_t* cr = m_data->cr; cairo_save(cr); cairo_set_fill_rule(cr, fillRule() == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING); switch (m_common->state.fillColorSpace) { case SolidColorSpace: setColor(cr, fillColor()); cairo_clip(cr); cairo_paint_with_alpha(cr, m_common->state.globalAlpha); break; case PatternColorSpace: { TransformationMatrix affine; cairo_set_source(cr, m_common->state.fillPattern->createPlatformPattern(affine)); cairo_clip(cr); cairo_paint_with_alpha(cr, m_common->state.globalAlpha); break; } case GradientColorSpace: cairo_pattern_t* pattern = m_common->state.fillGradient->platformGradient(); pattern = applySpreadMethod(pattern, spreadMethod()); cairo_set_source(cr, pattern); cairo_clip(cr); cairo_paint_with_alpha(cr, m_common->state.globalAlpha); break; } cairo_restore(cr); }
void GraphicsContext::fillPath(const Path& pathToFill) { if (paintingDisabled()) return; syncPlatformContext(this); platformContext()->fillPath(pathToFill, fillRule()); }
bool FloatPolygon::contains(const FloatPoint& point) const { if (!m_boundingBox.contains(point)) return false; return fillRule() == RULE_NONZERO ? containsNonZero(point) : containsEvenOdd(point); }
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++; } }