Example #1
0
    virtual void onDraw(SkCanvas* canvas) {
        // explicitly add spaces, to test a prev. bug
        const char* text = "Ham bur ge fons";
        int len = SkToInt(strlen(text));
        SkPath path;

        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setTextSize(SkIntToScalar(48));

        canvas->translate(SkIntToScalar(10), SkIntToScalar(64));

        canvas->drawText(text, len, 0, 0, paint);
        paint.getTextPath(text, len, 0, 0, &path);
        strokePath(canvas, path);
        path.reset();

        SkAutoTArray<SkPoint>  pos(len);
        SkAutoTArray<SkScalar> widths(len);
        paint.getTextWidths(text, len, &widths[0]);

        SkLCGRandom rand;
        SkScalar x = SkIntToScalar(20);
        SkScalar y = SkIntToScalar(100);
        for (int i = 0; i < len; ++i) {
            pos[i].set(x, y + rand.nextSScalar1() * 24);
            x += widths[i];
        }

        canvas->translate(0, SkIntToScalar(64));

        canvas->drawPosText(text, len, &pos[0], paint);
        paint.getPosTextPath(text, len, &pos[0], &path);
        strokePath(canvas, path);
    }
Example #2
0
void GraphicsContext::drawPath(const Path& path)
{
    if (paintingDisabled())
        return;

    CGContextRef context = platformContext();
    const GraphicsContextState& state = m_state;

    if (state.fillGradient || state.strokeGradient) {
        // We don't have any optimized way to fill & stroke a path using gradients
        // FIXME: Be smarter about this.
        fillPath(path);
        strokePath(path);
        return;
    }

    CGContextBeginPath(context);
    CGContextAddPath(context, path.platformPath());

    if (state.fillPattern)
        applyFillPattern();
    if (state.strokePattern)
        applyStrokePattern();

    CGPathDrawingMode drawingMode;
    if (calculateDrawingMode(state, drawingMode))
        CGContextDrawPath(context, drawingMode);
}
void Graphics::drawRoundedRectangle (const float x, const float y, const float width, const float height,
                                     const float cornerSize, const float lineThickness) const
{
    // passing in a silly number can cause maths problems in rendering!
    jassert (areCoordsSensibleNumbers (x, y, width, height));

    Path p;
    p.addRoundedRectangle (x, y, width, height, cornerSize);
    strokePath (p, PathStrokeType (lineThickness));
}
void SVGPaintServer::renderPath(GraphicsContext*& context, const RenderPath* path, SVGPaintTargetType type) const
{
    RenderStyle* style = path->style();
    CGContextRef contextRef = context->platformContext();

    if ((type & ApplyToFillTargetType) && style->svgStyle()->hasFill())
        fillPath(contextRef, path);

    if ((type & ApplyToStrokeTargetType) && style->svgStyle()->hasStroke())
        strokePath(contextRef, path);
}
void GraphicsContext::strokeRect(const FloatRect& rect, float width)
{
    if (paintingDisabled())
        return;

    cairo_t* cr = m_data->cr;
    cairo_save(cr);
    cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
    cairo_set_line_width(cr, width);
    strokePath();
    cairo_restore(cr);
}
void GraphicsContext::strokeRect(const FloatRect& rect, float width)
{
    if (paintingDisabled())
        return;

    QPainterPath path;
    path.addRect(rect);
    setStrokeThickness(width);
    m_data->currentPath = path;

    strokePath();
}
Example #7
0
void GraphicsContext::strokeRect(const FloatRect& rect, float width)
{
    if (paintingDisabled())
        return;

    QPainterPath path;
    path.addRect(rect);
    QPen nPen = m_data->p()->pen();
    nPen.setWidthF(width);

    strokePath();
}
void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
{
    if (paintingDisabled())
        return;

    if (strokeGradient() || strokePattern()) {
        Path path;
        path.addRect(rect);
        float oldLineWidth = m_state.strokeThickness;
        setPlatformStrokeThickness(lineWidth);
        strokePath(path);
        setPlatformStrokeThickness(oldLineWidth);
    } else
        platformContext()->addStrokeRect(rect, lineWidth);
}
void Graphics::drawEllipse (Rectangle<float> area, float lineThickness) const
{
    Path p;

    if (area.getWidth() == area.getHeight())
    {
        // For a circle, we can avoid having to generate a stroke
        p.addEllipse (area.expanded (lineThickness * 0.5f));
        p.addEllipse (area.reduced  (lineThickness * 0.5f));
        p.setUsingNonZeroWinding (false);
        fillPath (p);
    }
    else
    {
        p.addEllipse (area);
        strokePath (p, PathStrokeType (lineThickness));
    }
}
Example #10
0
FloatRect Path::strokeBoundingRect(const StrokeData& strokeData,
                                   BoundsType boundsType) const {
  return pathBounds(strokePath(strokeData), boundsType);
}
Example #11
0
bool Path::strokeContains(const FloatPoint& point,
                          const StrokeData& strokeData) const {
  return strokePath(strokeData)
      .contains(WebCoreFloatToSkScalar(point.x()),
                WebCoreFloatToSkScalar(point.y()));
}
Example #12
0
void GraphicsContext::strokeEllipseAsPath(const FloatRect& ellipse)
{
    Path path;
    path.addEllipse(ellipse);
    strokePath(path);
}
void Graphics::drawRoundedRectangle (const Rectangle<float>& r, float cornerSize, float lineThickness) const
{
    Path p;
    p.addRoundedRectangle (r, cornerSize);
    strokePath (p, PathStrokeType (lineThickness));
}
void Graphics::drawEllipse (float x, float y, float width, float height, float lineThickness) const
{
    Path p;
    p.addEllipse (x, y, width, height);
    strokePath (p, PathStrokeType (lineThickness));
}
void GraphicsContext::drawPath()
{
    fillPath();
    strokePath();
}
Example #16
0
void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
{
#ifdef QT_DEBUG_DRAW
    qDebug() << "QPaintEngineEx::stroke()" << pen;
#endif

    Q_D(QPaintEngineEx);

    if (path.isEmpty())
        return;

    if (!d->strokeHandler) {
        d->strokeHandler = new StrokeHandler(path.elementCount()+4);
        d->stroker.setMoveToHook(qpaintengineex_moveTo);
        d->stroker.setLineToHook(qpaintengineex_lineTo);
        d->stroker.setCubicToHook(qpaintengineex_cubicTo);
    }

    if (!qpen_fast_equals(pen, d->strokerPen)) {
        d->strokerPen = pen;
        d->stroker.setJoinStyle(pen.joinStyle());
        d->stroker.setCapStyle(pen.capStyle());
        d->stroker.setMiterLimit(pen.miterLimit());
        qreal penWidth = pen.widthF();
        if (penWidth == 0)
            d->stroker.setStrokeWidth(1);
        else
            d->stroker.setStrokeWidth(penWidth);

        Qt::PenStyle style = pen.style();
        if (style == Qt::SolidLine) {
            d->activeStroker = &d->stroker;
        } else if (style == Qt::NoPen) {
            d->activeStroker = 0;
        } else {
            d->dasher.setDashPattern(pen.dashPattern());
            d->dasher.setDashOffset(pen.dashOffset());
            d->activeStroker = &d->dasher;
        }
    }

    if (!d->activeStroker) {
        return;
    }

    if (pen.style() > Qt::SolidLine) {
        if (pen.isCosmetic()) {
            d->activeStroker->setClipRect(d->exDeviceRect);
        } else {
            QRectF clipRect = state()->matrix.inverted().mapRect(QRectF(d->exDeviceRect));
            d->activeStroker->setClipRect(clipRect);
        }
    }

    const QPainterPath::ElementType *types = path.elements();
    const qreal *points = path.points();
    int pointCount = path.elementCount();

    const qreal *lastPoint = points + (pointCount<<1);

    d->strokeHandler->types.reset();
    d->strokeHandler->pts.reset();

    // Some engines might decide to optimize for the non-shape hint later on...
    uint flags = QVectorPath::WindingFill;

    if (path.elementCount() > 2)
        flags |= QVectorPath::NonConvexShapeMask;

    if (d->stroker.capStyle() == Qt::RoundCap || d->stroker.joinStyle() == Qt::RoundJoin)
        flags |= QVectorPath::CurvedShapeMask;

    // ### Perspective Xforms are currently not supported...
    if (!pen.isCosmetic()) {
        // We include cosmetic pens in this case to avoid having to
        // change the current transform. Normal transformed,
        // non-cosmetic pens will be transformed as part of fill
        // later, so they are also covered here..
        d->activeStroker->setCurveThresholdFromTransform(state()->matrix);
        d->activeStroker->begin(d->strokeHandler);
        if (types) {
            while (points < lastPoint) {
                switch (*types) {
                case QPainterPath::MoveToElement:
                    d->activeStroker->moveTo(points[0], points[1]);
                    points += 2;
                    ++types;
                    break;
                case QPainterPath::LineToElement:
                    d->activeStroker->lineTo(points[0], points[1]);
                    points += 2;
                    ++types;
                    break;
                case QPainterPath::CurveToElement:
                    d->activeStroker->cubicTo(points[0], points[1],
                                              points[2], points[3],
                                              points[4], points[5]);
                    points += 6;
                    types += 3;
                    flags |= QVectorPath::CurvedShapeMask;
                    break;
                default:
                    break;
                }
            }
            if (path.hasImplicitClose())
                d->activeStroker->lineTo(path.points()[0], path.points()[1]);

        } else {
            d->activeStroker->moveTo(points[0], points[1]);
            points += 2;
            while (points < lastPoint) {
                d->activeStroker->lineTo(points[0], points[1]);
                points += 2;
            }
            if (path.hasImplicitClose())
                d->activeStroker->lineTo(path.points()[0], path.points()[1]);
        }
        d->activeStroker->end();

        if (!d->strokeHandler->types.size()) // an empty path...
            return;

        QVectorPath strokePath(d->strokeHandler->pts.data(),
                               d->strokeHandler->types.size(),
                               d->strokeHandler->types.data(),
                               flags);
        fill(strokePath, pen.brush());
    } else {
        // For cosmetic pens we need a bit of trickery... We to process xform the input points
        if (state()->matrix.type() >= QTransform::TxProject) {
            QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath());
            d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform());
        } else {
            d->activeStroker->setCurveThresholdFromTransform(QTransform());
            d->activeStroker->begin(d->strokeHandler);
            if (types) {
                while (points < lastPoint) {
                    switch (*types) {
                    case QPainterPath::MoveToElement: {
                        QPointF pt = (*(QPointF *) points) * state()->matrix;
                        d->activeStroker->moveTo(pt.x(), pt.y());
                        points += 2;
                        ++types;
                        break;
                    }
                    case QPainterPath::LineToElement: {
                        QPointF pt = (*(QPointF *) points) * state()->matrix;
                        d->activeStroker->lineTo(pt.x(), pt.y());
                        points += 2;
                        ++types;
                        break;
                    }
                    case QPainterPath::CurveToElement: {
                        QPointF c1 = ((QPointF *) points)[0] * state()->matrix;
                        QPointF c2 = ((QPointF *) points)[1] * state()->matrix;
                        QPointF e =  ((QPointF *) points)[2] * state()->matrix;
                        d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y());
                        points += 6;
                        types += 3;
                        flags |= QVectorPath::CurvedShapeMask;
                        break;
                    }
                    default:
                        break;
                    }
                }
                if (path.hasImplicitClose()) {
                    QPointF pt = * ((QPointF *) path.points()) * state()->matrix;
                    d->activeStroker->lineTo(pt.x(), pt.y());
                }

            } else {
                QPointF p = ((QPointF *)points)[0] * state()->matrix;
                d->activeStroker->moveTo(p.x(), p.y());
                points += 2;
                while (points < lastPoint) {
                    QPointF p = ((QPointF *)points)[0] * state()->matrix;
                    d->activeStroker->lineTo(p.x(), p.y());
                    points += 2;
                }
                if (path.hasImplicitClose())
                    d->activeStroker->lineTo(p.x(), p.y());
            }
            d->activeStroker->end();
        }

        QVectorPath strokePath(d->strokeHandler->pts.data(),
                               d->strokeHandler->types.size(),
                               d->strokeHandler->types.data(),
                               flags);

        QTransform xform = state()->matrix;
        state()->matrix = QTransform();
        transformChanged();

        QBrush brush = pen.brush();
        if (qbrush_style(brush) != Qt::SolidPattern)
            brush.setTransform(brush.transform() * xform);

        fill(strokePath, brush);

        state()->matrix = xform;
        transformChanged();
    }
}