Пример #1
0
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());
}
Пример #2
0
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());
}
Пример #5
0
bool FloatPolygon::contains(const FloatPoint& point) const
{
    if (!m_boundingBox.contains(point))
        return false;
    return fillRule() == RULE_NONZERO ? containsNonZero(point) : containsEvenOdd(point);
}
Пример #6
0
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++;
    }
}