コード例 #1
0
ファイル: PaintTest.cpp プロジェクト: BertiKarsunke/skia
// found and fixed for webkit: mishandling when we hit recursion limit on
// mostly degenerate cubic flatness test
DEF_TEST(Paint_regression_cubic, reporter) {
    SkPath path, stroke;
    SkPaint paint;

    path.moveTo(460.2881309415525f,
                303.250847066498f);
    path.cubicTo(463.36378422175284f,
                 302.1169735073363f,
                 456.32239330810046f,
                 304.720354932878f,
                 453.15255460013304f,
                 305.788586869862f);

    SkRect fillR, strokeR;
    fillR = path.getBounds();

    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(SkIntToScalar(2));
    paint.getFillPath(path, &stroke);
    strokeR = stroke.getBounds();

    SkRect maxR = fillR;
    SkScalar miter = SkMaxScalar(SK_Scalar1, paint.getStrokeMiter());
    SkScalar inset = paint.getStrokeJoin() == SkPaint::kMiter_Join ?
                            SkScalarMul(paint.getStrokeWidth(), miter) :
                            paint.getStrokeWidth();
    maxR.inset(-inset, -inset);

    // test that our stroke didn't explode
    REPORTER_ASSERT(reporter, maxR.contains(strokeR));
}
コード例 #2
0
ファイル: SkStrokeRec.cpp プロジェクト: 3rdexp/soui
void SkStrokeRec::init(const SkPaint& paint, SkPaint::Style style) {
    switch (style) {
        case SkPaint::kFill_Style:
            fWidth = kStrokeRec_FillStyleWidth;
            fStrokeAndFill = false;
            break;
        case SkPaint::kStroke_Style:
            fWidth = paint.getStrokeWidth();
            fStrokeAndFill = false;
            break;
        case SkPaint::kStrokeAndFill_Style:
            if (0 == paint.getStrokeWidth()) {
                // hairline+fill == fill
                fWidth = kStrokeRec_FillStyleWidth;
                fStrokeAndFill = false;
            } else {
                fWidth = paint.getStrokeWidth();
                fStrokeAndFill = true;
            }
            break;
        default:
            SkDEBUGFAIL("unknown paint style");
            // fall back on just fill
            fWidth = kStrokeRec_FillStyleWidth;
            fStrokeAndFill = false;
            break;
    }

    // copy these from the paint, regardless of our "style"
    fMiterLimit = paint.getStrokeMiter();
    fCap        = paint.getStrokeCap();
    fJoin       = paint.getStrokeJoin();
}
コード例 #3
0
    virtual void handlePath(SkCanvas* canvas, const SkPath& path,
                            const SkPaint& paint, int N) override {
        SkPoint pts[2];
        if (!path.isLine(pts) || pts[0].fY != pts[1].fY) {
            this->INHERITED::handlePath(canvas, path, paint, N);
        } else {
            SkRect rect;
            rect.fLeft = pts[0].fX;
            rect.fTop = pts[0].fY - paint.getStrokeWidth() / 2;
            rect.fRight = rect.fLeft + SkIntToScalar(fWidth);
            rect.fBottom = rect.fTop + paint.getStrokeWidth();

            SkPaint p(paint);
            p.setStyle(SkPaint::kFill_Style);
            p.setPathEffect(nullptr);

            int count = SkScalarRoundToInt((pts[1].fX - pts[0].fX) / (2*fWidth));
            SkScalar dx = SkIntToScalar(2 * fWidth);

            for (int i = 0; i < N*10; ++i) {
                SkRect r = rect;
                for (int j = 0; j < count; ++j) {
                    canvas->drawRect(r, p);
                    r.offset(dx, 0);
                }
            }
        }
    }
コード例 #4
0
ファイル: addarc.cpp プロジェクト: 03050903/skia
    void onDraw(SkCanvas* canvas) override {
        canvas->translate(20, 20);

        SkRect r = SkRect::MakeWH(1000, 1000);

        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setStrokeWidth(15);

        const SkScalar inset = paint.getStrokeWidth() + 4;
        const SkScalar sweepAngle = 345;
        SkRandom rand;

        SkScalar sign = 1;
        while (r.width() > paint.getStrokeWidth() * 3) {
            paint.setColor(sk_tool_utils::color_to_565(rand.nextU() | (0xFF << 24)));
            SkScalar startAngle = rand.nextUScalar1() * 360;

            SkScalar speed = SkScalarSqrt(16 / r.width()) * 0.5f;
            startAngle += fRotate * 360 * speed * sign;

            SkPath path;
            path.addArc(r, startAngle, sweepAngle);
            canvas->drawPath(path, paint);

            r.inset(inset, inset);
            sign = -sign;
        }
    }
コード例 #5
0
ファイル: SampleStrokeText.cpp プロジェクト: bunhere/skia
static void lettersToBitmap2(SkBitmap* dst, const char chars[],
                            const SkPaint& original, SkBitmap::Config config) {
    SkPath path;
    SkScalar x = 0;
    SkScalar width;
    SkPath p;
    for (size_t i = 0; i < strlen(chars); i++) {
        original.getTextPath(&chars[i], 1, x, 0, &p);
        path.addPath(p);
        original.getTextWidths(&chars[i], 1, &width);
        x += width;
    }
    SkRect bounds = path.getBounds();
    SkScalar sw = -original.getStrokeWidth();
    bounds.inset(sw, sw);
    path.offset(-bounds.fLeft, -bounds.fTop);
    bounds.offset(-bounds.fLeft, -bounds.fTop);

    int w = SkScalarRound(bounds.width());
    int h = SkScalarRound(bounds.height());
    SkPaint paint(original);

    paint.setAntiAlias(true);
    paint.setXfermodeMode(SkXfermode::kDstATop_Mode);
    paint.setColor(original.getColor());
    paint.setStyle(SkPaint::kStroke_Style);

    dst->setConfig(config, w, h);
    dst->allocPixels();
    dst->eraseColor(SK_ColorWHITE);

    SkCanvas canvas(*dst);
    canvas.drawPath(path, paint);
}
コード例 #6
0
SkStroke::SkStroke(const SkPaint& p) {
    fWidth      = p.getStrokeWidth();
    fMiterLimit = p.getStrokeMiter();
    fCap        = (uint8_t)p.getStrokeCap();
    fJoin       = (uint8_t)p.getStrokeJoin();
    fDoFill     = SkToU8(p.getStyle() == SkPaint::kStrokeAndFill_Style);
}
コード例 #7
0
bool GrStencilAndCoverTextContext::canDraw(const GrRenderTarget* rt,
                                           const GrClip& clip,
                                           const GrPaint& paint,
                                           const SkPaint& skPaint,
                                           const SkMatrix& viewMatrix) {
    if (skPaint.getRasterizer()) {
        return false;
    }
    if (skPaint.getMaskFilter()) {
        return false;
    }
    if (SkPathEffect* pe = skPaint.getPathEffect()) {
        if (pe->asADash(NULL) != SkPathEffect::kDash_DashType) {
            return false;
        }
    }

    // No hairlines unless we can map the 1 px width to the object space.
    if (skPaint.getStyle() == SkPaint::kStroke_Style
        && skPaint.getStrokeWidth() == 0
        && viewMatrix.hasPerspective()) {
        return false;
    }

    // No color bitmap fonts.
    SkScalerContext::Rec    rec;
    SkScalerContext::MakeRec(skPaint, &fDeviceProperties, NULL, &rec);
    return rec.getFormat() != SkMask::kARGB32_Format;
}
コード例 #8
0
void OsmAnd::MapRasterizer_P::rasterizePolylineShadow(
    const Context& context,
    SkCanvas& canvas,
    const SkPath& path,
    SkPaint& paint,
    const ColorARGB shadowColor,
    const float shadowRadius)
{
    if (context.shadowMode == MapPresentationEnvironment::ShadowMode::BlurShadow && shadowRadius > 0.0f)
    {
        // simply draw shadow? difference from option 3 ?
        paint.setLooper(SkBlurDrawLooper::Create(
            shadowColor.toSkColor(),
            SkBlurMaskFilter::ConvertRadiusToSigma(shadowRadius),
            0,
            0))->unref();
        canvas.drawPath(path, paint);
    }
    else if (context.shadowMode == MapPresentationEnvironment::ShadowMode::SolidShadow && shadowRadius > 0.0f)
    {
        paint.setLooper(nullptr);
        paint.setStrokeWidth(paint.getStrokeWidth() + shadowRadius * 2);
        paint.setColorFilter(SkColorFilter::CreateModeFilter(
            shadowColor.toSkColor(),
            SkXfermode::kSrcIn_Mode))->unref();
        canvas.drawPath(path, paint);
    }
}
コード例 #9
0
ファイル: SampleDash.cpp プロジェクト: UIKit0/skia
    virtual void onDrawContent(SkCanvas* canvas) {
        static const char* gStr[] = {
            "11",
            "44",
            "112233",
            "411327463524",
        };

        SkPaint paint;
        paint.setStrokeWidth(SkIntToScalar(1));

        SkScalar x0 = SkIntToScalar(10);
        SkScalar y0 = SkIntToScalar(10);
        SkScalar x1 = x0 + SkIntToScalar(1000);
        for (size_t i = 0; i < SK_ARRAY_COUNT(gStr); i++) {
            SkScalar interval[12];
            size_t len = SkMin32(strlen(gStr[i]), SK_ARRAY_COUNT(interval));
            for (size_t j = 0; j < len; j++) {
                interval[j] = SkIntToScalar(gStr[i][j] - '0');
            }

            SkDashPathEffect dash(interval, len, 0);
            paint.setPathEffect(&dash);
            canvas->drawLine(x0, y0, x1, y0, paint);
            paint.setPathEffect(NULL);

            y0 += paint.getStrokeWidth() * 3;
        }

        setBitmapDash(&paint, 3);
        canvas->drawLine(x0, y0, x1, y0, paint);
    }
コード例 #10
0
ファイル: techtalk1.cpp プロジェクト: bunhere/skia
static void draw_rect(SkCanvas* canvas, bool showGL, int flags) {
    SkPaint paint;
    paint.setAntiAlias(true);

    SkRect r = SkRect::MakeLTRB(50, 70, 250, 370);

    setFade(&paint, showGL);
    canvas->drawRect(r, paint);
    if (showGL) {
        show_mesh(canvas, r);
    }

    canvas->translate(320, 0);

    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(25);
    canvas->drawRect(r, paint);
    if (showGL) {
        SkScalar rad = paint.getStrokeWidth() / 2;
        SkPoint pts[8];
        r.outset(rad, rad);
        r.toQuad(&pts[0]);
        r.inset(rad*2, rad*2);
        r.toQuad(&pts[4]);

        const uint16_t indices[] = {
            0, 4, 1, 5, 2, 6, 3, 7, 0, 4
        };
        show_mesh(canvas, pts, indices, SK_ARRAY_COUNT(indices));
    }
}
コード例 #11
0
ファイル: SkPDFGraphicState.cpp プロジェクト: rotorliu/skia
SkPDFGraphicState::SkPDFGraphicState(const SkPaint& p)
    : fStrokeWidth(p.getStrokeWidth())
    , fStrokeMiter(p.getStrokeMiter())
    , fAlpha(p.getAlpha())
    , fStrokeCap(SkToU8(p.getStrokeCap()))
    , fStrokeJoin(SkToU8(p.getStrokeJoin()))
    , fMode(SkToU8(mode_for_pdf(p.getXfermode()))) {}
コード例 #12
0
static void draw_sweep(SkCanvas* c, int width, int height, SkScalar angle) {
    SkRect  r;
    SkPaint p;
    
    p.setAntiAlias(true);
//    p.setDither(true);
    p.setStrokeWidth(SkIntToScalar(width/10));
    p.setStyle(SkPaint::kStroke_Style);

    r.set(0, 0, SkIntToScalar(width), SkIntToScalar(height));
    
    //    SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN, SK_ColorCYAN };
    SkColor colors[] = { 0x4c737373, 0x4c737373, 0xffffd300 };
    SkShader* s = SkGradientShader::CreateSweep(r.centerX(), r.centerY(),
                                                colors, NULL, SK_ARRAY_COUNT(colors));
    p.setShader(s)->unref();
    
    SkAutoCanvasRestore acr(c, true);

    c->translate(r.centerX(), r.centerY());
    c->rotate(angle);
    c->translate(-r.centerX(), -r.centerY());

    SkRect bounds = r;
    r.inset(p.getStrokeWidth(), p.getStrokeWidth());
    SkRect innerBounds = r;

    if (true) {
        c->drawOval(r, p);
    } else {
        SkScalar x = r.centerX();
        SkScalar y = r.centerY();
        SkScalar radius = r.width() / 2;
        SkScalar thickness = p.getStrokeWidth();
        SkScalar sweep = SkFloatToScalar(360.0f);
        SkPath path;
        
        path.moveTo(x + radius, y);
        // outer top
        path.lineTo(x + radius + thickness, y);
        // outer arc
        path.arcTo(bounds, 0, sweep, false);
        // inner arc
        path.arcTo(innerBounds, sweep, -sweep, false);
        path.close();
    }
}
コード例 #13
0
TessellationCache::Description::Description(Type type, const Matrix4& transform, const SkPaint& paint)
        : type(type)
        , aa(paint.isAntiAlias())
        , cap(paint.getStrokeCap())
        , style(paint.getStyle())
        , strokeWidth(paint.getStrokeWidth()) {
    PathTessellator::extractTessellationScales(transform, &scaleX, &scaleY);
    memset(&shape, 0, sizeof(Shape));
}
コード例 #14
0
ファイル: SampleStrokeRect.cpp プロジェクト: Adenilson/skia
    virtual void onDrawContent(SkCanvas* canvas) {
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setStyle(SkPaint::kStroke_Style);
        paint.setStrokeWidth(SkIntToScalar(20));

        SkPaint hair;
        hair.setStyle(SkPaint::kStroke_Style);
        hair.setColor(SK_ColorRED);

        static const SkISize gSize[] = {
            {   100,   50 },
            {   100,    0 },
            {     0,   50 },
            {     0,    0 }
        };

        static const SkPaint::Join gJoin[] = {
            SkPaint::kMiter_Join,
            SkPaint::kRound_Join,
            SkPaint::kBevel_Join
        };

        canvas->translate(paint.getStrokeWidth(), paint.getStrokeWidth());
        for (size_t i = 0; i < SK_ARRAY_COUNT(gJoin); ++i) {
            paint.setStrokeJoin(gJoin[i]);

            canvas->save();
            for (size_t j = 0; j < SK_ARRAY_COUNT(gSize); ++j) {
                SkRect r = SkRect::MakeWH(SkIntToScalar(gSize[j].fWidth),
                                          SkIntToScalar(gSize[j].fHeight));
                canvas->drawRect(r, paint);
                canvas->drawRect(r, hair);
                canvas->translate(0, SkIntToScalar(100));
            }
            canvas->restore();
            canvas->translate(SkIntToScalar(150), 0);
        }
    }
コード例 #15
0
void SkPDFDevice::drawPoints(const SkDraw& d, SkCanvas::PointMode mode,
                             size_t count, const SkPoint* points,
                             const SkPaint& paint) {
    if (count == 0)
        return;

    switch (mode) {
    case SkCanvas::kPolygon_PointMode:
        updateGSFromPaint(paint, false);
        SkPDFUtils::MoveTo(points[0].fX, points[0].fY, &fContent);
        for (size_t i = 1; i < count; i++) {
            SkPDFUtils::AppendLine(points[i].fX, points[i].fY, &fContent);
        }
        SkPDFUtils::StrokePath(&fContent);
        break;
    case SkCanvas::kLines_PointMode:
        updateGSFromPaint(paint, false);
        for (size_t i = 0; i < count/2; i++) {
            SkPDFUtils::MoveTo(points[i * 2].fX, points[i * 2].fY,
                               &fContent);
            SkPDFUtils::AppendLine(points[i * 2 + 1].fX,
                                   points[i * 2 + 1].fY, &fContent);
            SkPDFUtils::StrokePath(&fContent);
        }
        break;
    case SkCanvas::kPoints_PointMode:
        if (paint.getStrokeCap() == SkPaint::kRound_Cap) {
            updateGSFromPaint(paint, false);
            for (size_t i = 0; i < count; i++) {
                SkPDFUtils::MoveTo(points[i].fX, points[i].fY, &fContent);
                SkPDFUtils::StrokePath(&fContent);
            }
        } else {
            // PDF won't draw a single point with square/butt caps because
            // the orientation is ambiguous.  Draw a rectangle instead.
            SkPaint newPaint = paint;
            newPaint.setStyle(SkPaint::kFill_Style);
            SkScalar strokeWidth = paint.getStrokeWidth();
            SkScalar halfStroke = strokeWidth * SK_ScalarHalf;
            for (size_t i = 0; i < count; i++) {
                SkRect r = SkRect::MakeXYWH(points[i].fX, points[i].fY,
                                            0, 0);
                r.inset(-halfStroke, -halfStroke);
                drawRect(d, r, newPaint);
            }
        }
        break;
    default:
        SkASSERT(false);
    }
}
コード例 #16
0
ファイル: SkPipeCanvas.cpp プロジェクト: aseprite/skia
static uint16_t compute_nondef(const SkPaint& paint, PaintUsage usage) {
    // kRespectsStroke_PaintUsage is only valid if other bits are also set
    SkASSERT(0 != (usage & ~kRespectsStroke_PaintUsage));

    const SkScalar kTextSize_Default    = 12;
    const SkScalar kTextScaleX_Default  = 1;
    const SkScalar kTextSkewX_Default   = 0;
    const SkScalar kStrokeWidth_Default = 0;
    const SkScalar kStrokeMiter_Default = 4;
    const SkColor  kColor_Default       = SK_ColorBLACK;

    unsigned bits = (paint.getColor() != kColor_Default) ? kColor_NonDef : 0;

    if (usage & kText_PaintUsage) {
        bits |= (paint.getTextSize() != kTextSize_Default       ? kTextSize_NonDef : 0);
        bits |= (paint.getTextScaleX() != kTextScaleX_Default   ? kTextScaleX_NonDef : 0);
        bits |= (paint.getTextSkewX() != kTextSkewX_Default     ? kTextSkewX_NonDef : 0);
        bits |= (paint.getTypeface()                            ? kTypeface_NonDef : 0);
    }

    // TODO: kImage_PaintUsage only needs the shader/maskfilter IF its colortype is kAlpha_8

    if (usage & (kVertices_PaintUsage | kDrawPaint_PaintUsage | kImage_PaintUsage |
                 kText_PaintUsage | kGeometry_PaintUsage | kTextBlob_PaintUsage)) {
        bits |= (paint.getShader()      ? kShader_NonDef : 0);
    }

    if (usage & (kText_PaintUsage | kGeometry_PaintUsage | kTextBlob_PaintUsage)) {
        bits |= (paint.getPathEffect()  ? kPathEffect_NonDef : 0);
        bits |= (paint.getRasterizer()  ? kRasterizer_NonDef : 0);

        if (paint.getStyle() != SkPaint::kFill_Style || (usage & kRespectsStroke_PaintUsage)) {
            bits |= (paint.getStrokeWidth() != kStrokeWidth_Default ? kStrokeWidth_NonDef : 0);
            bits |= (paint.getStrokeMiter() != kStrokeMiter_Default ? kStrokeMiter_NonDef : 0);
        }
    }

    if (usage &
        (kText_PaintUsage | kGeometry_PaintUsage | kImage_PaintUsage | kTextBlob_PaintUsage))
    {
        bits |= (paint.getMaskFilter()  ? kMaskFilter_NonDef : 0);
    }

    bits |= (paint.getColorFilter() ? kColorFilter_NonDef : 0);
    bits |= (paint.getImageFilter() ? kImageFilter_NonDef : 0);
    bits |= (paint.getDrawLooper()  ? kDrawLooper_NonDef : 0);

    return SkToU16(bits);
}
コード例 #17
0
bool GrStencilAndCoverTextContext::internalCanDraw(const SkPaint& skPaint) {
    if (skPaint.getRasterizer()) {
        return false;
    }
    if (skPaint.getMaskFilter()) {
        return false;
    }
    if (SkPathEffect* pe = skPaint.getPathEffect()) {
        if (pe->asADash(nullptr) != SkPathEffect::kDash_DashType) {
            return false;
        }
    }
    // No hairlines. They would require new paths with customized strokes for every new draw matrix.
    return SkPaint::kStroke_Style != skPaint.getStyle() || 0 != skPaint.getStrokeWidth();
}
コード例 #18
0
ファイル: SkSVGDevice.cpp プロジェクト: Jichao/skia
void SkSVGDevice::AutoElement::addPaint(const SkPaint& paint, const Resources& resources) {
    SkPaint::Style style = paint.getStyle();
    if (style == SkPaint::kFill_Style || style == SkPaint::kStrokeAndFill_Style) {
        this->addAttribute("fill", resources.fPaintServer);

        if (SK_AlphaOPAQUE != SkColorGetA(paint.getColor())) {
            this->addAttribute("fill-opacity", svg_opacity(paint.getColor()));
        }
    } else {
        SkASSERT(style == SkPaint::kStroke_Style);
        this->addAttribute("fill", "none");
    }

    if (style == SkPaint::kStroke_Style || style == SkPaint::kStrokeAndFill_Style) {
        this->addAttribute("stroke", resources.fPaintServer);

        SkScalar strokeWidth = paint.getStrokeWidth();
        if (strokeWidth == 0) {
            // Hairline stroke
            strokeWidth = 1;
            this->addAttribute("vector-effect", "non-scaling-stroke");
        }
        this->addAttribute("stroke-width", strokeWidth);

        if (const char* cap = svg_cap(paint.getStrokeCap())) {
            this->addAttribute("stroke-linecap", cap);
        }

        if (const char* join = svg_join(paint.getStrokeJoin())) {
            this->addAttribute("stroke-linejoin", join);
        }

        if (paint.getStrokeJoin() == SkPaint::kMiter_Join) {
            this->addAttribute("stroke-miterlimit", paint.getStrokeMiter());
        }

        if (SK_AlphaOPAQUE != SkColorGetA(paint.getColor())) {
            this->addAttribute("stroke-opacity", svg_opacity(paint.getColor()));
        }
    } else {
        SkASSERT(style == SkPaint::kFill_Style);
        this->addAttribute("stroke", "none");
    }
}
コード例 #19
0
static void paint_write(const SkPaint& paint, SkFlattenableWriteBuffer& buffer)
{
    buffer.writeBool(paint.isAntiAlias());
    buffer.write8(paint.getStyle());
    buffer.write8(paint.getAlpha());
    
    if (paint.getStyle() != SkPaint::kFill_Style)
    {
        buffer.writeScalar(paint.getStrokeWidth());
        buffer.writeScalar(paint.getStrokeMiter());
        buffer.write8(paint.getStrokeCap());
        buffer.write8(paint.getStrokeJoin());
    }
    
    buffer.writeFlattenable(paint.getMaskFilter());
    buffer.writeFlattenable(paint.getPathEffect());
    buffer.writeFlattenable(paint.getRasterizer());
    buffer.writeFlattenable(paint.getXfermode());
}
コード例 #20
0
ファイル: SkGLDevice.cpp プロジェクト: Dieken/SurfaceFlinger
void SkGLDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
                            size_t count, const SkPoint pts[], const SkPaint& paint) {
    TRACE_DRAW("coreDrawPoints", this, draw);
    
    SkScalar width = paint.getStrokeWidth();
    if (width < 0) {
        return;
    }
    
    /*  We should really only use drawverts for hairlines, since gl and skia
     treat the thickness differently...
     */
    
    AutoPaintShader shader(this, paint);
    
    if (width <= 0) {
        width = SK_Scalar1;
    }
    
    if (SkCanvas::kPoints_PointMode == mode) {
        glPointSize(SkScalarToFloat(width));
    } else {
        glLineWidth(SkScalarToFloat(width));
    }
    
    const SkGLVertex* verts;
    
#if GLSCALAR_IS_SCALAR
    verts = (const SkGLVertex*)pts;
#else
    SkAutoSTMalloc<32, SkGLVertex> storage(count);
    SkGLVertex* v = storage.get();
    
    v->setPoints(pts, count);
    verts = v;
#endif
    
    const SkGLVertex* texs = shader.useTex() ? verts : NULL;
    
    SkGL::DrawVertices(count, gPointMode2GL[mode], verts, texs, NULL, NULL,
                       this->updateMatrixClip());
}
コード例 #21
0
static bool setupForText(SkPaint* paint, GraphicsContext* gc,
                         const SimpleFontData* font) {
    int mode = gc->textDrawingMode();
    
    if ((mode & (cTextFill | cTextStroke)) == (cTextFill | cTextStroke)) {
        SkLayerDrawLooper* looper = new SkLayerDrawLooper;
        paint->setLooper(looper)->unref();
        
        // we clear the looper, in case we have a shadow

        SkPaint* fillP = NULL;
        SkPaint* strokeP = NULL;
        if (gc->willStroke()) {
            strokeP = setupStroke(looper->addLayer(), gc, font);
            strokeP->setLooper(NULL);
        }
        if (gc->willFill()) {
            fillP = setupFill(looper->addLayer(), gc, font);
            fillP->setLooper(NULL);
        }

        SkPaint shadowPaint;
        SkPoint offset;
        if (gc->setupShadowPaint(&shadowPaint, &offset)) {
            SkPaint* p = looper->addLayer(offset.fX, offset.fY);
            *p = shadowPaint;
            if (strokeP && !fillP) {
                // stroke the shadow if we have stroke but no fill
                p->setStyle(SkPaint::kStroke_Style);
                p->setStrokeWidth(strokeP->getStrokeWidth());
            }
            updateForFont(p, font);
        }
    } else if (mode & cTextFill) {
        (void)setupFill(paint, gc, font);
    } else if (mode & cTextStroke) {
        (void)setupStroke(paint, gc, font);
    } else {
        return false;
    }
    return true;
}
コード例 #22
0
ファイル: SkBBoxRecord.cpp プロジェクト: Adenilson/skia
void SkBBoxRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts[],
                              const SkPaint& paint) {
    SkRect bbox;
    bbox.set(pts, SkToInt(count));
    // Small min width value, just to ensure hairline point bounding boxes aren't empty.
    // Even though we know hairline primitives are drawn one pixel wide, we do not use a
    // minimum of 1 because the playback scale factor is unknown at record time. Later
    // outsets will take care of adding additional padding for antialiasing and rounding out
    // to integer device coordinates, guaranteeing that the rasterized pixels will be included
    // in the computed bounds.
    // Note: The device coordinate outset in SkBBoxHierarchyRecord::handleBBox is currently
    // done in the recording coordinate space, which is wrong.
    // http://code.google.com/p/skia/issues/detail?id=1021
    static const SkScalar kMinWidth = 0.01f;
    SkScalar halfStrokeWidth = SkMaxScalar(paint.getStrokeWidth(), kMinWidth) / 2;
    bbox.outset(halfStrokeWidth, halfStrokeWidth);
    if (this->transformBounds(bbox, &paint)) {
        INHERITED::drawPoints(mode, count, pts, paint);
    }
}
コード例 #23
0
PassRefPtr<JSONObject> LoggingCanvas::objectForSkPaint(const SkPaint& paint)
{
    RefPtr<JSONObject> paintItem = JSONObject::create();
    paintItem->setNumber("textSize", paint.getTextSize());
    paintItem->setNumber("textScaleX", paint.getTextScaleX());
    paintItem->setNumber("textSkewX", paint.getTextSkewX());
    if (SkShader* shader = paint.getShader())
        paintItem->setObject("shader", objectForSkShader(*shader));
    paintItem->setString("color", stringForSkColor(paint.getColor()));
    paintItem->setNumber("strokeWidth", paint.getStrokeWidth());
    paintItem->setNumber("strokeMiter", paint.getStrokeMiter());
    paintItem->setString("flags", stringForSkPaintFlags(paint));
    paintItem->setString("filterLevel", filterQualityName(paint.getFilterQuality()));
    paintItem->setString("textAlign", textAlignName(paint.getTextAlign()));
    paintItem->setString("strokeCap", strokeCapName(paint.getStrokeCap()));
    paintItem->setString("strokeJoin", strokeJoinName(paint.getStrokeJoin()));
    paintItem->setString("styleName", styleName(paint.getStyle()));
    paintItem->setString("textEncoding", textEncodingName(paint.getTextEncoding()));
    paintItem->setString("hinting", hintingName(paint.getHinting()));
    return paintItem.release();
}
コード例 #24
0
sk_sp<SkPDFDict> SkPDFGraphicState::GetGraphicStateForPaint(SkPDFCanon* canon,
                                                            const SkPaint& p) {
    SkASSERT(canon);
    if (SkPaint::kFill_Style == p.getStyle()) {
        SkPDFFillGraphicState fillKey = {p.getAlpha(), pdf_blend_mode(p.getBlendMode())};
        auto& fillMap = canon->fFillGSMap;
        if (sk_sp<SkPDFDict>* statePtr = fillMap.find(fillKey)) {
            return *statePtr;
        }
        auto state = sk_make_sp<SkPDFDict>();
        state->reserve(2);
        state->insertScalar("ca", fillKey.fAlpha / 255.0f);
        state->insertName("BM", as_pdf_blend_mode_name((SkBlendMode)fillKey.fBlendMode));
        fillMap.set(fillKey, state);
        return state;
    } else {
        SkPDFStrokeGraphicState strokeKey = {
            p.getStrokeWidth(), p.getStrokeMiter(),
            SkToU8(p.getStrokeCap()), SkToU8(p.getStrokeJoin()),
            p.getAlpha(), pdf_blend_mode(p.getBlendMode())};
        auto& sMap = canon->fStrokeGSMap;
        if (sk_sp<SkPDFDict>* statePtr = sMap.find(strokeKey)) {
            return *statePtr;
        }
        auto state = sk_make_sp<SkPDFDict>();
        state->reserve(8);
        state->insertScalar("CA", strokeKey.fAlpha / 255.0f);
        state->insertScalar("ca", strokeKey.fAlpha / 255.0f);
        state->insertInt("LC", to_stroke_cap(strokeKey.fStrokeCap));
        state->insertInt("LJ", to_stroke_join(strokeKey.fStrokeJoin));
        state->insertScalar("LW", strokeKey.fStrokeWidth);
        state->insertScalar("ML", strokeKey.fStrokeMiter);
        state->insertBool("SA", true);  // SA = Auto stroke adjustment.
        state->insertName("BM", as_pdf_blend_mode_name((SkBlendMode)strokeKey.fBlendMode));
        sMap.set(strokeKey, state);
        return state;
    }
}
コード例 #25
0
bool GrStencilAndCoverTextContext::canDraw(const SkPaint& paint) {
    if (paint.getRasterizer()) {
        return false;
    }
    if (paint.getMaskFilter()) {
        return false;
    }
    if (paint.getPathEffect()) {
        return false;
    }

    // No hairlines unless we can map the 1 px width to the object space.
    if (paint.getStyle() == SkPaint::kStroke_Style
        && paint.getStrokeWidth() == 0
        && fContext->getMatrix().hasPerspective()) {
        return false;
    }

    // No color bitmap fonts.
    SkScalerContext::Rec    rec;
    SkScalerContext::MakeRec(paint, &fDeviceProperties, NULL, &rec);
    return rec.getFormat() != SkMask::kARGB32_Format;
}
コード例 #26
0
ファイル: SkJSONCanvas.cpp プロジェクト: atyenoria/skia
Json::Value SkJSONCanvas::makePaint(const SkPaint& paint) {
    Json::Value result(Json::objectValue);
    store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
    store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(), 
                 SkPaintDefaults_MiterLimit);
    store_bool(&result, SKJSONCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
    store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(), 
                 SkPaintDefaults_TextSize);
    store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1);
    store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f);
    apply_paint_color(paint, &result);
    apply_paint_style(paint, &result);
    apply_paint_cap(paint, &result);
    apply_paint_textalign(paint, &result);
    apply_paint_patheffect(paint, &result, fSendBinaries);
    apply_paint_maskfilter(paint, &result, fSendBinaries);
    apply_paint_shader(paint, &result, fSendBinaries);
    apply_paint_xfermode(paint, &result, fSendBinaries);
    apply_paint_imagefilter(paint, &result, fSendBinaries);
    apply_paint_colorfilter(paint, &result, fSendBinaries);
    apply_paint_typeface(paint, &result, fSendBinaries);
    return result;
}
コード例 #27
0
ファイル: SkiaUtils.cpp プロジェクト: dstockwell/blink
void drawPlatformFocusRing(const PrimitiveType& primitive, SkCanvas* canvas, SkColor color, int width)
{
    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setColor(color);
    paint.setStrokeWidth(GraphicsContext::focusRingWidth(width));

#if OS(MACOSX)
    paint.setAlpha(64);
    const float cornerRadius = (width - 1) * 0.5f;
#else
    const float cornerRadius = 1;
#endif

    drawFocusRingPrimitive(primitive, canvas, paint, cornerRadius);

#if OS(MACOSX)
    // Inner part
    paint.setAlpha(128);
    paint.setStrokeWidth(paint.getStrokeWidth() * 0.5f);
    drawFocusRingPrimitive(primitive, canvas, paint, cornerRadius);
#endif
}
コード例 #28
0
SkStrokePathEffect::SkStrokePathEffect(const SkPaint& paint)
    : fWidth(paint.getStrokeWidth()), fMiter(paint.getStrokeMiter()),
      fStyle(SkToU8(paint.getStyle())), fJoin(SkToU8(paint.getStrokeJoin())), fCap(SkToU8(paint.getStrokeCap()))
{
}
コード例 #29
0
ファイル: GrAtlasTextBlob.cpp プロジェクト: jszwedko/skia
bool GrAtlasTextBlob::mustRegenerate(const SkPaint& paint,
                                     GrColor color, const SkMaskFilter::BlurRec& blurRec,
                                     const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
    // If we have LCD text then our canonical color will be set to transparent, in this case we have
    // to regenerate the blob on any color change
    // We use the grPaint to get any color filter effects
    if (fKey.fCanonicalColor == SK_ColorTRANSPARENT &&
        fPaintColor != color) {
        return true;
    }

    if (fInitialViewMatrix.hasPerspective() != viewMatrix.hasPerspective()) {
        return true;
    }

    if (fInitialViewMatrix.hasPerspective() && !fInitialViewMatrix.cheapEqualTo(viewMatrix)) {
        return true;
    }

    // We only cache one masked version
    if (fKey.fHasBlur &&
        (fBlurRec.fSigma != blurRec.fSigma ||
         fBlurRec.fStyle != blurRec.fStyle ||
         fBlurRec.fQuality != blurRec.fQuality)) {
        return true;
    }

    // Similarly, we only cache one version for each style
    if (fKey.fStyle != SkPaint::kFill_Style &&
        (fStrokeInfo.fFrameWidth != paint.getStrokeWidth() ||
         fStrokeInfo.fMiterLimit != paint.getStrokeMiter() ||
         fStrokeInfo.fJoin != paint.getStrokeJoin())) {
        return true;
    }

    // Mixed blobs must be regenerated.  We could probably figure out a way to do integer scrolls
    // for mixed blobs if this becomes an issue.
    if (this->hasBitmap() && this->hasDistanceField()) {
        // Identical viewmatrices and we can reuse in all cases
        if (fInitialViewMatrix.cheapEqualTo(viewMatrix) && x == fInitialX && y == fInitialY) {
            return false;
        }
        return true;
    }

    if (this->hasBitmap()) {
        if (fInitialViewMatrix.getScaleX() != viewMatrix.getScaleX() ||
            fInitialViewMatrix.getScaleY() != viewMatrix.getScaleY() ||
            fInitialViewMatrix.getSkewX() != viewMatrix.getSkewX() ||
            fInitialViewMatrix.getSkewY() != viewMatrix.getSkewY()) {
            return true;
        }

        // We can update the positions in the cachedtextblobs without regenerating the whole blob,
        // but only for integer translations.
        // This cool bit of math will determine the necessary translation to apply to the already
        // generated vertex coordinates to move them to the correct position
        SkScalar transX = viewMatrix.getTranslateX() +
                          viewMatrix.getScaleX() * (x - fInitialX) +
                          viewMatrix.getSkewX() * (y - fInitialY) -
                          fInitialViewMatrix.getTranslateX();
        SkScalar transY = viewMatrix.getTranslateY() +
                          viewMatrix.getSkewY() * (x - fInitialX) +
                          viewMatrix.getScaleY() * (y - fInitialY) -
                          fInitialViewMatrix.getTranslateY();
        if (!SkScalarIsInt(transX) || !SkScalarIsInt(transY)) {
            return true;
        }
    } else if (this->hasDistanceField()) {
        // A scale outside of [blob.fMaxMinScale, blob.fMinMaxScale] would result in a different
        // distance field being generated, so we have to regenerate in those cases
        SkScalar newMaxScale = viewMatrix.getMaxScale();
        SkScalar oldMaxScale = fInitialViewMatrix.getMaxScale();
        SkScalar scaleAdjust = newMaxScale / oldMaxScale;
        if (scaleAdjust < fMaxMinScale || scaleAdjust > fMinMaxScale) {
            return true;
        }
    }

    // It is possible that a blob has neither distanceField nor bitmaptext.  This is in the case
    // when all of the runs inside the blob are drawn as paths.  In this case, we always regenerate
    // the blob anyways at flush time, so no need to regenerate explicitly
    return false;
}
コード例 #30
0
ファイル: techtalk1.cpp プロジェクト: bunhere/skia
static void draw_oval(SkCanvas* canvas, bool showGL, int flags) {
    SkPaint paint;
    paint.setAntiAlias(true);

    SkRect r = SkRect::MakeLTRB(50, 70, 250, 370);

    setFade(&paint, showGL);
    canvas->drawOval(r, paint);
    if (showGL) {
        switch (flags) {
            case 0: {
                SkPath path;
                path.addOval(r);
                show_glframe(canvas, path);
            } break;
            case 1:
            case 3: {
                SkPath src, dst;
                src.addOval(r);
                tesselate(src, &dst);
                show_fan(canvas, dst, r.centerX(), r.centerY());
            } break;
            case 2: {
                SkPaint p(paint);
                show_mesh(canvas, r);
                setGLFrame(&p);
                paint.setStyle(SkPaint::kFill_Style);
                canvas->drawCircle(r.centerX(), r.centerY(), 3, p);
            } break;
        }
    }

    canvas->translate(320, 0);

    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(25);
    canvas->drawOval(r, paint);
    if (showGL) {
        switch (flags) {
            case 0: {
                SkPath path;
                SkScalar rad = paint.getStrokeWidth() / 2;
                r.outset(rad, rad);
                path.addOval(r);
                r.inset(rad*2, rad*2);
                path.addOval(r);
                show_glframe(canvas, path);
            } break;
            case 1: {
                SkPath path0, path1;
                SkScalar rad = paint.getStrokeWidth() / 2;
                r.outset(rad, rad);
                path0.addOval(r);
                r.inset(rad*2, rad*2);
                path1.addOval(r);
                show_mesh_between(canvas, path0, path1);
            } break;
            case 2: {
                SkPath path;
                path.addOval(r);
                show_glframe(canvas, path);
                SkScalar rad = paint.getStrokeWidth() / 2;
                r.outset(rad, rad);
                show_mesh(canvas, r);
            } break;
            case 3: {
                SkScalar rad = paint.getStrokeWidth() / 2;
                r.outset(rad, rad);
                SkPaint paint;
                paint.setAlpha(0x33);
                canvas->drawRect(r, paint);
                show_mesh(canvas, r);
            } break;
        }
    }
}