示例#1
0
文件: DrawPathTest.cpp 项目: Cue/skia
// http://crbug.com/165432
// Limit extreme dash path effects to avoid exhausting the system memory.
static void test_crbug_165432(skiatest::Reporter* reporter) {
    SkPath path;
    path.moveTo(0, 0);
    path.lineTo(10000000, 0);

    SkScalar intervals[] = { 0.5f, 0.5f };
    SkDashPathEffect dash(intervals, 2, 0);

    SkPaint paint;
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setPathEffect(&dash);

    SkPath filteredPath;
    SkStrokeRec rec(paint);
    REPORTER_ASSERT(reporter, !dash.filterPath(&filteredPath, path, &rec, NULL));
    REPORTER_ASSERT(reporter, filteredPath.isEmpty());
}
SkPath create_concave_path(const SkPoint& offset) {
    SkPath concavePath;
    concavePath.moveTo(kMin, kMin);
    concavePath.lineTo(kMid, 105.0f);
    concavePath.lineTo(kMax, kMin);
    concavePath.lineTo(295.0f, kMid);
    concavePath.lineTo(kMax, kMax);
    concavePath.lineTo(kMid, 295.0f);
    concavePath.lineTo(kMin, kMax);
    concavePath.lineTo(105.0f, kMid);
    concavePath.close();

    concavePath.offset(offset.fX, offset.fY);
    return concavePath;
}
示例#3
0
static SkPathEffect* make_warp_pe()
{
    SkPath  path;
    path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
    for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
        path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
    path.close();
    path.offset(SkIntToScalar(-6), 0);

    SkPathEffect* outer = new SkPath1DPathEffect(path, SkIntToScalar(12), gPhase, SkPath1DPathEffect::kMorph_Style);
    SkPathEffect* inner = new SkCornerPathEffect(SkIntToScalar(CORNER_RADIUS));

    SkPathEffect* pe = new SkComposePathEffect(outer, inner);
    outer->unref();
    inner->unref();
    return pe;
}
示例#4
0
static void test4(SkCanvas* canvas) {
    SkPaint paint;
    paint.setAntiAlias(true);
    SkPoint pts[] = {
        {10, 160}, {610, 160},
        {610, 160}, {10, 160},

        {610, 160}, {610, 160},
        {610, 199}, {610, 199},

        {10, 198}, {610, 198},
        {610, 199}, {10, 199},

        {10, 160}, {10, 160},
        {10, 199}, {10, 199}
    };
    char verbs[] = {
        0, 1, 1, 1, 4,
        0, 1, 1, 1, 4,
        0, 1, 1, 1, 4,
        0, 1, 1, 1, 4
    };
    SkPath path;
    SkPoint* ptPtr = pts;
    for (size_t i = 0; i < sizeof(verbs); ++i) {
        switch ((SkPath::Verb) verbs[i]) {
            case SkPath::kMove_Verb:
                path.moveTo(ptPtr->fX, ptPtr->fY);
                ++ptPtr;
                break;
            case SkPath::kLine_Verb:
                path.lineTo(ptPtr->fX, ptPtr->fY);
                ++ptPtr;
                break;
            case SkPath::kClose_Verb:
                path.close();
                break;
            default:
                SkASSERT(false);
                break;
        }
    }
    SkRect clip = {0, 130, 772, 531};
    canvas->clipRect(clip);
    canvas->drawPath(path, paint);
}
示例#5
0
文件: DrawPathTest.cpp 项目: Cue/skia
// Extremely large path_length/dash_length ratios may cause infinite looping
// in SkDashPathEffect::filterPath() due to single precision rounding.
// The test is quite expensive, but it should get much faster after the fix
// for http://crbug.com/165432 goes in.
static void test_infinite_dash(skiatest::Reporter* reporter) {
    SkPath path;
    path.moveTo(0, 0);
    path.lineTo(5000000, 0);

    SkScalar intervals[] = { 0.2f, 0.2f };
    SkDashPathEffect dash(intervals, 2, 0);

    SkPath filteredPath;
    SkPaint paint;
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setPathEffect(&dash);

    paint.getFillPath(path, &filteredPath);
    // If we reach this, we passed.
    REPORTER_ASSERT(reporter, true);
}
示例#6
0
    void onDraw(SkCanvas* canvas) override {
        SkPaint p;
        p.setColor(SK_ColorRED);
        p.setAntiAlias(true);

        canvas->clear(0xFFFFFFFF);

        canvas->save();
        canvas->rotate(1);
        const SkScalar R = 115.2f, C = 128.0f;
        SkPath path;
        path.moveTo(C + R, C);
        for (int i = 1; i < 8; ++i) {
            SkScalar a = 2.6927937f * i;
            SkScalar cosine;
            SkScalar sine = SkScalarSinCos(a, &cosine);
            path.lineTo(C + R * cosine, C + R * sine);
        }
        canvas->drawPath(path, p);
        canvas->restore();

        canvas->save();
        canvas->translate(200, 0);
        canvas->rotate(1);
        p.setStyle(SkPaint::kStroke_Style);
        p.setStrokeWidth(5);
        canvas->drawPath(path, p);
        canvas->restore();


        // The following two paths test if we correctly cumulates the alpha on the middle pixel
        // column where the left rect and the right rect abut.
        p.setStyle(SkPaint::kFill_Style);
        canvas->translate(0, 300);
        path.reset();
        path.addRect({20, 20, 100.4999f, 100});
        path.addRect({100.5001f, 20, 200, 100});
        canvas->drawPath(path, p);

        canvas->translate(300, 0);
        path.reset();
        path.addRect({20, 20, 100.1f, 100});
        path.addRect({100.9f, 20, 200, 100});
        canvas->drawPath(path, p);
    }
void WebTestThemeControlWin::triangle(int x0, int y0, int x1, int y1, int x2, int y2, SkColor color)
{
    SkPath path;
    SkPaint paint;

    paint.setColor(color);
    paint.setStyle(SkPaint::kFill_Style);
    path.incReserve(4);
    path.moveTo(SkIntToScalar(x0), SkIntToScalar(y0));
    path.lineTo(SkIntToScalar(x1), SkIntToScalar(y1));
    path.lineTo(SkIntToScalar(x2), SkIntToScalar(y2));
    path.close();
    m_canvas->drawPath(path, paint);

    paint.setColor(m_edgeColor);
    paint.setStyle(SkPaint::kStroke_Style);
    m_canvas->drawPath(path, paint);
}
示例#8
0
// Creates a star type shape using a SkPath
static SkPath create_star() {
    static const int kNumPoints = 5;
    SkPath concavePath;
    SkPoint points[kNumPoints] = {{0, SkIntToScalar(-50)} };
    SkMatrix rot;
    rot.setRotate(SkIntToScalar(360) / kNumPoints);
    for (int i = 1; i < kNumPoints; ++i) {
        rot.mapPoints(points + i, points + i - 1, 1);
    }
    concavePath.moveTo(points[0]);
    for (int i = 0; i < kNumPoints; ++i) {
        concavePath.lineTo(points[(2 * i) % kNumPoints]);
    }
    concavePath.setFillType(SkPath::kEvenOdd_FillType);
    SkASSERT(!concavePath.isConvex());
    concavePath.close();
    return concavePath;
}
示例#9
0
文件: EdgeDemo.cpp 项目: ghub/NVprSDK
static void createStar(SkPath& path, SkScalar innerRadius, SkScalar outerRadius, 
        SkScalar startAngle, int points, SkPoint center) {
    SkScalar angle = startAngle;
    for (int index = 0; index < points * 2; ++index) {
        SkScalar radius = index & 1 ? outerRadius : innerRadius;
        SkScalar x = radius * cos(angle);
        SkScalar y = radius * sin(angle);
        x += center.fX;
        y += center.fY;
        if (index == 0) {
            path.moveTo(x, y);
        } else {
            path.lineTo(x, y);
        }
        angle += 3.1415f / points;
    }
    path.close();
}
// An edge collapse event causes an edge to become collinear, requiring
// its event to be removed.
static SkPath create_path_26() {
    SkPath path;
    path.moveTo( 43.44110107421875,  148.15106201171875);
    path.lineTo( 44.64471435546875,  148.16748046875);
    path.lineTo( 46.35009765625,     147.403076171875);
    path.lineTo( 46.45404052734375,  148.34906005859375);
    path.lineTo( 45.0400390625,      148.54205322265625);
    path.lineTo( 44.624053955078125, 148.9810791015625);
    path.lineTo( 44.59405517578125,  149.16107177734375);
    path.lineTo( 44.877044677734375, 149.62005615234375);
    path.lineTo(144.373016357421875,  68.8070068359375);
    return path;
}
// A path which contains out-of-range colinear intersections.
static SkPath create_path_23() {
    SkPath path;
    path.moveTo(                   0, 63.39080047607421875);
    path.lineTo(-0.70804601907730102539, 63.14350128173828125);
    path.lineTo(-7.8608899287380243391e-17, 64.14080047607421875);
    path.moveTo(                   0, 64.14080047607421875);
    path.lineTo(44.285900115966796875, 64.14080047607421875);
    path.lineTo(                   0, 62.64080047607421875);
    path.moveTo(21.434900283813476562, -0.24732701480388641357);
    path.lineTo(-0.70804601907730102539, 63.14350128173828125);
    path.lineTo(0.70804601907730102539,  63.6381988525390625);
    return path;
}
示例#12
0
static void test_nan_antihair() {
    SkBitmap bm;
    bm.allocN32Pixels(20, 20);

    SkCanvas canvas(bm);

    SkPath path;
    path.moveTo(0, 0);
    path.lineTo(10, SK_ScalarNaN);

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

    // before our fix to SkScan_Antihair.cpp to check for integral NaN (0x800...)
    // this would trigger an assert/crash.
    //
    // see rev. 3558
    canvas.drawPath(path, paint);
}
// Handle the case where edge.dist(edge.fTop) != 0.0.
static SkPath create_path_12() {
    SkPath path;
    path.moveTo(                  0.0f,  400.0f);
    path.lineTo(                138.0f,  202.0f);
    path.lineTo(                  0.0f,  202.0f);
    path.moveTo( 12.62693023681640625f,  250.57464599609375f);
    path.lineTo(  8.13896942138671875f,  254.556884765625f);
    path.lineTo(-18.15641021728515625f,  220.40203857421875f);
    path.lineTo(-15.986493110656738281f, 219.6513519287109375f);
    path.moveTo( 36.931194305419921875f, 282.485504150390625f);
    path.lineTo( 15.617521286010742188f, 261.2901611328125f);
    path.lineTo( 10.3829498291015625f,   252.565765380859375f);
    path.lineTo(-16.165292739868164062f, 222.646026611328125f);
    return path;
}
示例#14
0
static void testTightBoundsLines(PathOpsThreadState* data) {
    SkRandom ran;
    for (int index = 0; index < 1000; ++index) {
        SkPath path;
        int contourCount = ran.nextRangeU(1, 10);
        for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
            int lineCount = ran.nextRangeU(1, 10);
            path.moveTo(ran.nextRangeF(-1000, 1000), ran.nextRangeF(-1000, 1000));
            for (int lIndex = 0; lIndex < lineCount; ++lIndex) {
                path.lineTo(ran.nextRangeF(-1000, 1000), ran.nextRangeF(-1000, 1000));
            }
            if (ran.nextBool()) {
                path.close();
            }
        }
        SkRect classicBounds = path.getBounds();
        SkRect tightBounds;
        REPORTER_ASSERT(data->fReporter, TightBounds(path, &tightBounds));
        REPORTER_ASSERT(data->fReporter, classicBounds == tightBounds);
    }
}
示例#15
0
static sk_sp<SkPathEffect> make_pe(int flags, SkScalar phase) {
    if (flags == 1) {
        return SkCornerPathEffect::Make(SkIntToScalar(CORNER_RADIUS));
    }

    SkPath  path;
    path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
    for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
        path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
    path.close();
    path.offset(SkIntToScalar(-6), 0);

    auto outer = SkPath1DPathEffect::Make(path, 12, phase, SkPath1DPathEffect::kRotate_Style);

    if (flags == 2)
        return outer;

    auto inner = SkCornerPathEffect::Make(SkIntToScalar(CORNER_RADIUS));

    return SkComposePathEffect::Make(outer, inner);
}
示例#16
0
SkPath ValueTraits<ShapeValue>::As<SkPath>(const ShapeValue& shape) {
    SkPath path;

    if (!shape.fVertices.empty()) {
        // conservatively assume all cubics
        path.incReserve(1 + SkToU32(shape.fVertices.size() * 3));

        path.moveTo(shape.fVertices.front().fVertex);
    }

    const auto& addCubic = [&](size_t from, size_t to) {
        const auto c0 = shape.fVertices[from].fVertex + shape.fVertices[from].fOutPoint,
                   c1 = shape.fVertices[to].fVertex   + shape.fVertices[to].fInPoint;

        if (c0 == shape.fVertices[from].fVertex &&
            c1 == shape.fVertices[to].fVertex) {
            // If the control points are coincident, we can power-reduce to a straight line.
            // TODO: we could also do that when the controls are on the same line as the
            //       vertices, but it's unclear how common that case is.
            path.lineTo(shape.fVertices[to].fVertex);
        } else {
            path.cubicTo(c0, c1, shape.fVertices[to].fVertex);
        }
    };

    for (size_t i = 1; i < shape.fVertices.size(); ++i) {
        addCubic(i - 1, i);
    }

    if (!shape.fVertices.empty() && shape.fClosed) {
        addCubic(shape.fVertices.size() - 1, 0);
        path.close();
    }

    path.setIsVolatile(shape.fVolatile);
    path.shrinkToFit();

    return path;
}
示例#17
0
// TODO: expand the testing to include the different ops & AA types!
static void emit_clip(SkCanvas* canvas, ClipType clip) {
    switch (clip) {
        case kNone_ClipType:
            break;
        case kRect_ClipType: {
            SkRect r = SkRect::MakeLTRB(10, 10, 90, 90);
            canvas->clipRect(r, SkRegion::kIntersect_Op, true);
            break;
        }
        case kRRect_ClipType: {
            SkRect r = SkRect::MakeLTRB(10, 10, 90, 90);
            SkRRect rr;
            rr.setRectXY(r, 10, 10);
            canvas->clipRRect(rr, SkRegion::kIntersect_Op, true);
            break;
        }
        case kPath_ClipType: {
            SkPath p;
            p.moveTo(5.0f, 5.0f);
            p.lineTo(50.0f, 50.0f);
            p.lineTo(100.0f, 5.0f);
            p.close();
            canvas->clipPath(p, SkRegion::kIntersect_Op, true);
            break;
        }
        case kRegion_ClipType: {
            SkIRect rects[2] = {
                { 1, 1, 55, 55 },
                { 45, 45, 99, 99 },
            };
            SkRegion r;
            r.setRects(rects, 2);
            canvas->clipRegion(r, SkRegion::kIntersect_Op);
            break;
        }
        default:
            SkASSERT(0);
    }
}
示例#18
0
int
sk_test_multi_line(caskbench_context_t *ctx)
{
    int w = ctx->canvas_width;
    int h = ctx->canvas_height;
    double x = (double)rnd()/RAND_MAX * w;
    double y = (double)rnd()/RAND_MAX * h;
    SkPath path;

    path.moveTo(x, y);
    for (int i=0; i<ctx->size; i++) {
        x = (double)rnd()/RAND_MAX * w;
        y = (double)rnd()/RAND_MAX * h;

        path.lineTo(x, y);
    }

    skiaRandomizePaintColor(ctx);
    ctx->skia_canvas->drawPath(path, *(ctx->skia_paint));

    return 1;
}
示例#19
0
static SkPath make_path() {
    SkPath path;
    uint8_t numOps;
    fuzz->nextRange(&numOps, 0, 30);
    for (uint8_t i = 0; i < numOps; ++i) {
        uint8_t op;
        fuzz->nextRange(&op, 0, 5);
        SkScalar a, b, c, d, e, f;
        switch (op) {
            case 0:
                fuzz->next(&a, &b);
                path.moveTo(a, b);
                break;
            case 1:
                fuzz->next(&a, &b);
                path.lineTo(a, b);
                break;
            case 2:
                fuzz->next(&a, &b, &c, &d);
                path.quadTo(a, b, c, d);
                break;
            case 3:
                fuzz->next(&a, &b, &c, &d, &e);
                path.conicTo(a, b, c, d, e);
                break;
            case 4:
                fuzz->next(&a, &b, &c, &d, &e, &f);
                path.cubicTo(a, b, c, d, e, f);
                break;
            case 5:
            default:
                fuzz->next(&a, &b, &c, &d, &e);
                path.arcTo(a, b, c, d, e);
                break;
        }
    }
    path.close();
    return path;
}
// This test case including path coords and matrix taken from crbug.com/627443.
// Because of inaccuracies in large floating point values this causes the
// the path renderer to attempt to add a path DF to its atlas that is larger
// than the plot size which used to crash rather than fail gracefully.
static void test_far_from_origin(GrDrawContext* drawContext, GrPathRenderer* pr,
                                 GrResourceProvider* rp) {
    SkPath path;
    path.lineTo(49.0255089839f, 0.473541f);
    static constexpr SkScalar mvals[] = {14.0348252854f, 2.13026182736f,
                                         13.6122547187f, 118.309922702f,
                                         1912337682.09f, 2105391889.87f};
    SkMatrix matrix;
    matrix.setAffine(mvals);
    SkMatrix inverse;
    SkAssertResult(matrix.invert(&inverse));
    path.transform(inverse);

    SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
    rec.setStrokeStyle(1.f);
    rec.setStrokeParams(SkPaint::kRound_Cap, SkPaint::kRound_Join, 1.f);
    GrStyle style(rec, nullptr);

    GrShape shape(path, style);
    shape = shape.applyStyle(GrStyle::Apply::kPathEffectAndStrokeRec, 1.f);

    GrPaint paint;
    paint.setXPFactory(GrPorterDuffXPFactory::Make(SkXfermode::kSrc_Mode));

    GrNoClip noClip;
    GrPathRenderer::DrawPathArgs args;
    args.fPaint = &paint;
    args.fUserStencilSettings = &GrUserStencilSettings::kUnused;
    args.fDrawContext = drawContext;
    args.fClip = &noClip;
    args.fResourceProvider = rp;
    args.fViewMatrix = &matrix;
    args.fShape = &shape;
    args.fAntiAlias = true;
    args.fGammaCorrect = false;
    args.fColor = 0x0;
    pr->drawPath(args);
}
示例#21
0
    void onDraw(SkCanvas* canvas) override {
        SkRect r = { 10, 10, 100, 60 };

        SkPath path;

        path.addRect(r); test_rev(canvas, path);

        canvas->translate(0, 100);
        path.offset(20, 20);
        path.addRect(r); test_rev(canvas, path);

        canvas->translate(0, 100);
        path.reset();
        path.moveTo(10, 10); path.lineTo(30, 30);
        path.addOval(r);
        r.offset(50, 20);
        path.addOval(r);
        test_rev(canvas, path);

        path = hiragino_maru_goth_pro_e();
        canvas->translate(0, 100);
        test_rev(canvas, path);
    }
示例#22
0
    virtual void onDraw(SkCanvas* canvas) {
        SkPath path;
        SkRandom rand;

        int scale = 300;
        for (int i = 0; i < 4; ++i) {
            path.lineTo(rand.nextUScalar1() * scale, rand.nextUScalar1() * scale);
            path.quadTo(rand.nextUScalar1() * scale, rand.nextUScalar1() * scale,
                        rand.nextUScalar1() * scale, rand.nextUScalar1() * scale);
            path.cubicTo(rand.nextUScalar1() * scale, rand.nextUScalar1() * scale,
                         rand.nextUScalar1() * scale, rand.nextUScalar1() * scale,
                         rand.nextUScalar1() * scale, rand.nextUScalar1() * scale);
        }

        path.setFillType(SkPath::kEvenOdd_FillType);
        path.offset(SkIntToScalar(20), SkIntToScalar(20));

        test_hittest(canvas, path);

        canvas->translate(SkIntToScalar(scale), 0);
        path.setFillType(SkPath::kWinding_FillType);

        test_hittest(canvas, path);
    }
示例#23
0
static void dontFailOne(skiatest::Reporter* reporter, int index) {
    SkPath path;
    int f = (int) (index % finitePtsCount);
    int g = (int) ((f + 1) % finitePtsCount);
    switch (index % 11) {
        case 0: path.lineTo(finitePts[f]); break;
        case 1: path.quadTo(finitePts[f], finitePts[f]); break;
        case 2: path.quadTo(finitePts[f], finitePts[g]); break;
        case 3: path.quadTo(finitePts[g], finitePts[f]); break;
        case 4: path.cubicTo(finitePts[f], finitePts[f], finitePts[f]); break;
        case 5: path.cubicTo(finitePts[f], finitePts[f], finitePts[g]); break;
        case 6: path.cubicTo(finitePts[f], finitePts[g], finitePts[f]); break;
        case 7: path.cubicTo(finitePts[f], finitePts[g], finitePts[g]); break;
        case 8: path.cubicTo(finitePts[g], finitePts[f], finitePts[f]); break;
        case 9: path.cubicTo(finitePts[g], finitePts[f], finitePts[g]); break;
        case 10: path.moveTo(finitePts[f]); break;
    }
    SkPath result;
    result.setFillType(SkPath::kWinding_FillType);
    bool success = Simplify(path, &result);
    REPORTER_ASSERT(reporter, success);
    REPORTER_ASSERT(reporter, result.getFillType() != SkPath::kWinding_FillType);
    reporter->bumpTestCount();
}
示例#24
0
void SkTestFont::init(const SkScalar* pts, const unsigned char* verbs) {
    fPaths = new SkPath* [fCharCodesCount];
    for (unsigned index = 0; index < fCharCodesCount; ++index) {
        SkPath* path = new SkPath;
        SkPath::Verb verb;
        while ((verb = (SkPath::Verb) *verbs++) != SkPath::kDone_Verb) {
            switch (verb) {
                case SkPath::kMove_Verb:
                    path->moveTo(pts[0], pts[1]);
                    pts += 2;
                    break;
                case SkPath::kLine_Verb:
                    path->lineTo(pts[0], pts[1]);
                    pts += 2;
                    break;
                case SkPath::kQuad_Verb:
                    path->quadTo(pts[0], pts[1], pts[2], pts[3]);
                    pts += 4;
                    break;
                case SkPath::kCubic_Verb:
                    path->cubicTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
                    pts += 6;
                    break;
                case SkPath::kClose_Verb:
                    path->close();
                    break;
                default:
                    SkDEBUGFAIL("bad verb");
                    return;
            }
        }
        // This should make SkPath::getBounds() queries threadsafe.
        path->updateBoundsCache();
        fPaths[index] = path;
    }
}
示例#25
0
    PathIterBench(bool raw)  {
        fName.printf("pathiter_%s", raw ? "raw" : "consume");
        fRaw = raw;

        SkRandom rand;
        for (int i = 0; i < 1000; ++i) {
            SkPoint pts[4];
            int n = rand_pts(rand, pts);
            switch (n) {
                case 1:
                    fPath.moveTo(pts[0]);
                    break;
                case 2:
                    fPath.lineTo(pts[1]);
                    break;
                case 3:
                    fPath.quadTo(pts[1], pts[2]);
                    break;
                case 4:
                    fPath.cubicTo(pts[1], pts[2], pts[3]);
                    break;
            }
        }
    }
示例#26
0
static void test_stroke(SkCanvas* canvas) {
    if (true) {
        SkPath path;
        dump(path);
        path.reset(); path.moveTo(0, 0);
        dump(path);
        path.reset(); path.moveTo(100, 100);
        dump(path);
        path.reset(); path.moveTo(0, 0); path.moveTo(100, 100);
        dump(path);
        path.reset(); path.moveTo(0, 0); path.lineTo(100, 100);
        dump(path);
        path.reset(); path.moveTo(0, 0); path.lineTo(100, 100); path.moveTo(200, 200);
        dump(path);
    }

#if 0
    // TEST 1 - The rectangle as it's expected to look
    var canvas = document.createElement('canvas');
    document.body.appendChild(canvas);
    var ctx = canvas.getContext("2d");
#else
    SkJSCanvas ctx(canvas);
#endif

    ctx.save();
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.moveTo(10, 100);
    ctx.lineTo(150, 100);
    ctx.lineTo(150, 15);
    ctx.lineTo(10, 15);
    ctx.closePath();

    // no extra moveTo here
    // ctx.moveTo(175, 125);

    ctx.stroke();
    ctx.restore();

    ctx.fillText("As Expected", 10, 10);

#if 0
    // TEST 2 - Includes an extra moveTo call before stroke; the rectangle appears larger
    canvas = document.createElement('canvas');
    document.body.appendChild(canvas);
    ctx = canvas.getContext("2d");
#else
    canvas->translate(200, 0);
#endif

    ctx.save();
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.moveTo(10, 100);
    ctx.lineTo(150, 100);
    ctx.lineTo(150, 15);
    ctx.lineTo(10, 15);
    ctx.closePath();

    ctx.moveTo(175, 125);

    ctx.stroke();
    ctx.restore();

    ctx.fillText("Larger Rectangle", 10, 10);

#if 0
    // TEST 3 - Identical to test 2 except the line width is 1
    canvas = document.createElement('canvas');
    document.body.appendChild(canvas);
    ctx = canvas.getContext("2d");
#else
    canvas->translate(200, 0);
#endif

    ctx.save();
    ctx.lineWidth = 1;
    ctx.beginPath();
    ctx.moveTo(10, 100);
    ctx.lineTo(150, 100);
    ctx.lineTo(150, 15);
    ctx.lineTo(10, 15);
    ctx.closePath();

    ctx.moveTo(175, 125);

    ctx.stroke();
    ctx.restore();

    ctx.fillText("As Expected - line width 1", 10, 10);
}
示例#27
0
void SkJSCanvas::lineTo(double x, double y) {
    fPath.lineTo(SkDoubleToScalar(x), SkDoubleToScalar(y));
}
示例#28
0
    void onDrawContent(SkCanvas* canvas) override {
        SkPaint paintFill;
        SkPaint paintStroke;
        SkPath  path;

        canvas->save();
        canvas->translate(150, 150);
        canvas->scale(0.4f, 0.4f);
        canvas->rotate(-180.f/2.f);

        paintFill.setAntiAlias(true);
        paintFill.setColor(SK_ColorBLACK);
        paintStroke.setAntiAlias(true);
        paintStroke.setStyle(SkPaint::kStroke_Style);
        paintStroke.setColor(SK_ColorBLACK);
        paintStroke.setStrokeWidth(8);
        paintStroke.setStrokeCap(SkPaint::kRound_Cap);

        // Hour marks
        SkRect rect;
#ifndef USE_PATH
        rect = SkRect::MakeLTRB(200-4, -4, 240+4, 4);
        SkRRect rrect;
        SkVector radii[4] = {{4,4}, {4,4}, {4,4}, {4,4}};
        rrect.setRectRadii(rect, radii);
#endif
        canvas->save();
        for (int i=0;i<12;i++){
            canvas->rotate(180.f/6.f);
#ifdef USE_PATH
            path.reset();
            path.moveTo(200,0);
            path.lineTo(240,0);
            canvas->drawPath(path, paintStroke);
#else
            canvas->drawRRect(rrect, paintFill);
#endif
        }
        canvas->restore();

        // Minute marks
        canvas->save();
#ifdef USE_PATH
        paintStroke.setStrokeWidth(5);
#else
        rect = SkRect::MakeLTRB(231.5f, -2.5f, 242.5, 2.5f);
        radii[0] = SkPoint::Make(2.5f,2.5f);
        radii[1] = SkPoint::Make(2.5f,2.5f);
        radii[2] = SkPoint::Make(2.5f,2.5f);
        radii[3] = SkPoint::Make(2.5f,2.5f);
        rrect.setRectRadii(rect, radii);
#endif
        for (int i=0;i<60;i++){
            if (i%5 == 0) {
                canvas->rotate(180.f/30.f);
                continue;
            }
#ifdef USE_PATH
            path.reset();
            path.moveTo(234,0);
            path.lineTo(240,0);
            canvas->drawPath(path, paintStroke);
#else
            canvas->drawRRect(rrect, paintFill);
#endif
            canvas->rotate(180.f/30.f);
        }
        canvas->restore();

        SkTime::DateTime time;
        SkTime::GetDateTime(&time);
        time.fHour = time.fHour >= 12 ? time.fHour-12 : time.fHour;
        paintFill.setColor(SK_ColorBLACK);

        // Write hours
        canvas->save();
        canvas->rotate(time.fHour*(180.f/6.f) + time.fMinute*(180.f/360.f)
                       + time.fSecond*(180.f/21600.f) );
#ifdef USE_PATH
        paintStroke.setStrokeWidth(14);
        path.reset();
        path.moveTo(-20,0);
        path.lineTo(80,0);
        canvas->drawPath(path, paintStroke);
#else
        rect = SkRect::MakeLTRB(-20-7, -7, 80+7, 7);
        radii[0] = SkPoint::Make(7,7);
        radii[1] = SkPoint::Make(7,7);
        radii[2] = SkPoint::Make(7,7);
        radii[3] = SkPoint::Make(7,7);
        rrect.setRectRadii(rect, radii);
        canvas->drawRRect(rrect, paintFill);
#endif
        canvas->restore();

        // Write minutes
        canvas->save();
        canvas->rotate(time.fMinute*(180.f/30.f)
                       + time.fSecond*(180.f/1800.f) );
#ifdef USE_PATH
        paintStroke.setStrokeWidth(10);
        path.reset();
        path.moveTo(-56,0);
        path.lineTo(224,0);
        canvas->drawPath(path, paintStroke);
#else
        rect = SkRect::MakeLTRB(-56-5, -5, 224+5, 5);
        radii[0] = SkPoint::Make(5,5);
        radii[1] = SkPoint::Make(5,5);
        radii[2] = SkPoint::Make(5,5);
        radii[3] = SkPoint::Make(5,5);
        rrect.setRectRadii(rect, radii);
        canvas->drawRRect(rrect, paintFill);
#endif
        canvas->restore();

        // Write seconds
        canvas->save();
        canvas->rotate(time.fSecond*(180.f/30.f));
        paintFill.setColor(0xffd40000);
        paintStroke.setColor(0xffd40000);
        paintStroke.setStrokeWidth(6);
#ifdef USE_PATH
        path.reset();
        path.moveTo(-60,0);
        path.lineTo(166,0);
        canvas->drawPath(path, paintStroke);
#else
        rect = SkRect::MakeLTRB(-60-3, -3, 166+3, 3);
        radii[0] = SkPoint::Make(3,3);
        radii[1] = SkPoint::Make(3,3);
        radii[2] = SkPoint::Make(3,3);
        radii[3] = SkPoint::Make(3,3);
        rrect.setRectRadii(rect, radii);
        canvas->drawRRect(rrect, paintFill);
#endif
        rect = SkRect::MakeLTRB(-20, -20, 20, 20);
#ifdef USE_PATH
        path.reset();
        path.arcTo(rect, 0, 0, false);
        path.addOval(rect, SkPath::kCCW_Direction);
        path.arcTo(rect, 360, 0, true);
        canvas->drawPath(path, paintFill);
#else
        canvas->drawOval(rect, paintFill);
#endif
        rect = SkRect::MakeLTRB(-20+190, -20, 20+190, 20);
#ifdef USE_PATH
        path.reset();
        path.arcTo(rect, 0, 0, false);
        path.addOval(rect, SkPath::kCCW_Direction);
        path.arcTo(rect, 360, 0, true);
        canvas->drawPath(path, paintStroke);
#else
        canvas->drawOval(rect, paintStroke);
#endif
        paintFill.setColor(0xff505050);
#ifdef USE_PATH
        rect = SkRect::MakeLTRB(-6, -6, 6, 6);
        path.arcTo(rect, 0, 0, false);
        path.addOval(rect, SkPath::kCCW_Direction);
        path.arcTo(rect, 360, 0, true);
        canvas->drawPath(path, paintFill);
#else
        canvas->drawOval(rect, paintFill);
        rect = SkRect::MakeLTRB(-6, -6, 6, 6);
        canvas->drawOval(rect, paintFill);
#endif
        canvas->restore();

        paintStroke.setStrokeWidth(18);
        paintStroke.setColor(0xff325FA2);
        rect = SkRect::MakeLTRB(-284, -284, 284, 284);
#ifdef USE_PATH
        path.reset();
        path.arcTo(rect, 0, 0, false);
        path.addOval(rect, SkPath::kCCW_Direction);
        path.arcTo(rect, 360, 0, true);
        canvas->drawPath(path, paintStroke);
#else
        canvas->drawOval(rect, paintStroke);
#endif

        canvas->restore();

        this->inval(nullptr);
    }
示例#29
0
static void do_fuzz(SkCanvas* canvas) {
    SkPath path;
    SkPaint paint;
    paint.setAntiAlias(true);

  for (int i=0;i<100;i++) {
  switch (R(33)) {

    case 0:
          paint.setColor(make_fill());
      break;

    case 1:
      paint.setAlpha(gRand.nextU() & 0xFF);
      break;

      case 2: {
          SkXfermode::Mode mode;
          switch (R(3)) {
            case 0: mode = SkXfermode::kSrc_Mode; break;
            case 1: mode = SkXfermode::kXor_Mode; break;
            case 2:
            default:  // silence warning
              mode = SkXfermode::kSrcOver_Mode; break;
          }
          paint.setXfermodeMode(mode);
      }
      break;

    case 3:
      switch (R(2)) {
          case 0: paint.setStrokeCap(SkPaint::kRound_Cap); break;
        case 1: paint.setStrokeCap(SkPaint::kButt_Cap); break;
      }
      break;

    case 4:
      switch (R(2)) {
          case 0: paint.setStrokeJoin(SkPaint::kRound_Join); break;
        case 1: paint.setStrokeJoin(SkPaint::kMiter_Join); break;
      }
      break;

    case 5:
      paint.setStrokeWidth(make_number());
      break;

    case 6:
      paint.setStrokeMiter(make_number());
      break;

    case 7:
      if (quick == true) break;
          SkSafeUnref(paint.setMaskFilter(SkBlurMaskFilter::Create(kNormal_SkBlurStyle,
                                                                   make_number())));
      break;

    case 8:
      if (quick == true) break;
      //ctx.shadowColor = make_fill();
      break;

    case 9:
      if (quick == true) break;
      //ctx.shadowOffsetX = make_number();
      //ctx.shadowOffsetY = make_number();
      break;

    case 10:
      canvas->restore();
      break;

    case 11:
      canvas->rotate(make_number());
      break;

    case 12:
      canvas->save();
      break;

    case 13:
      canvas->scale(-1,-1);
      break;

    case 14:

      if (quick == true) break;

      if (transval == 0) {
        transval = make_number();
        canvas->translate(transval,0);
      } else {
        canvas->translate(-transval,0);
        transval = 0;
      }

      break;

          case 15: {
              SkRect r;
              r.set(make_number(),make_number(),make_number(),make_number());
              SkPaint::Style s = paint.getStyle();
              paint.setStyle(SkPaint::kFill_Style);
              canvas->drawRect(r, paint);
              paint.setStyle(s);
              // clearrect
          } break;

    case 16:
      if (quick == true) break;
//      ctx.drawImage(imgObj,make_number(),make_number(),make_number(),make_number(),make_number(),make_number(),make_number(),make_number());
      break;

          case 17: {
          SkRect r;
          r.set(make_number(),make_number(),make_number(),make_number());
              SkPaint::Style s = paint.getStyle();
              paint.setStyle(SkPaint::kFill_Style);
          canvas->drawRect(r, paint);
              paint.setStyle(s);
          } break;

    case 18:
          path.reset();
      break;

    case 19:
      // ctx.clip() is evil.
      break;

    case 20:
          path.close();
      break;

          case 21: {
          SkPaint::Style s = paint.getStyle();
          paint.setStyle(SkPaint::kFill_Style);
          canvas->drawPath(path, paint);
          paint.setStyle(s);
          } break;

          case 22: {
              SkPaint::Style s = paint.getStyle();
              paint.setStyle(SkPaint::kFill_Style);
              canvas->drawPath(path, paint);
              paint.setStyle(s);
          } break;

          case 23: {
              SkRect r;
              r.set(make_number(),make_number(),make_number(),make_number());
              SkPaint::Style s = paint.getStyle();
              paint.setStyle(SkPaint::kStroke_Style);
              canvas->drawRect(r, paint);
              paint.setStyle(s);
          } break;

    case 24:
      if (quick == true) break;
      //ctx.arc(make_number(),make_number(),make_number(),make_number(),make_number(),true);
      break;

    case 25:
      if (quick == true) break;
      //ctx.arcTo(make_number(),make_number(),make_number(),make_number(),make_number());
      break;

    case 26:
      if (quick == true) break;
      //ctx.bezierCurveTo(make_number(),make_number(),make_number(),make_number(),make_number(),make_number());
      break;

    case 27:
      path.lineTo(make_number(),make_number());
      break;

    case 28:
      path.moveTo(make_number(),make_number());
      break;

    case 29:
      if (quick == true) break;
      path.quadTo(make_number(),make_number(),make_number(),make_number());
      break;

          case 30: {
      if (quick == true) break;
              SkMatrix matrix;
      set2x3(&matrix, make_number(),make_number(),make_number(),make_number(),make_number(),make_number());
              canvas->concat(matrix);
          } break;

          case 31: {
      if (quick == true) break;
          SkMatrix matrix;
          set2x3(&matrix, make_number(),make_number(),make_number(),make_number(),make_number(),make_number());
          canvas->setMatrix(matrix);
          } break;

    case 32:

      if (scale_large == true) {

        switch (scval) {
          case 0: canvas->scale(-1000000000,1);
                  canvas->scale(-1000000000,1);
                  scval = 1; break;
          case 1: canvas->scale(-.000000001f,1); scval = 2; break;
          case 2: canvas->scale(-.000000001f,1); scval = 0; break;
        }

      }

      break;



  }
  }

}
示例#30
0
static void draw_vector_logo(SkCanvas* canvas, const SkRect& viewBox) {
    constexpr char kSkiaStr[] = "SKIA";
    constexpr SkScalar kGradientPad = .1f;
    constexpr SkScalar kVerticalSpacing = 0.25f;
    constexpr SkScalar kAccentScale = 1.20f;

    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setSubpixelText(true);
    paint.setFakeBoldText(true);
    sk_tool_utils::set_portable_typeface(&paint);

    SkPath path;
    SkRect iBox, skiBox, skiaBox;
    paint.getTextPath("SKI", 3, 0, 0, &path);
    TightBounds(path, &skiBox);
    paint.getTextPath("I", 1, 0, 0, &path);
    TightBounds(path, &iBox);
    iBox.offsetTo(skiBox.fRight - iBox.width(), iBox.fTop);

    const size_t textLen = strlen(kSkiaStr);
    paint.getTextPath(kSkiaStr, textLen, 0, 0, &path);
    TightBounds(path, &skiaBox);
    skiaBox.outset(0, 2 * iBox.width() * (kVerticalSpacing + 1));

    const SkScalar accentSize = iBox.width() * kAccentScale;
    const SkScalar underlineY = iBox.bottom() +
        (kVerticalSpacing + SkScalarSqrt(3) / 2) * accentSize;
    SkMatrix m;
    m.setRectToRect(skiaBox, viewBox, SkMatrix::kFill_ScaleToFit);
    SkAutoCanvasRestore acr(canvas, true);
    canvas->concat(m);

    canvas->drawCircle(iBox.centerX(),
                       iBox.y() - (0.5f + kVerticalSpacing) * accentSize,
                       accentSize / 2,
                       paint);

    path.reset();
    path.moveTo(iBox.centerX() - accentSize / 2, iBox.bottom() + kVerticalSpacing * accentSize);
    path.rLineTo(accentSize, 0);
    path.lineTo(iBox.centerX(), underlineY);
    canvas->drawPath(path, paint);

    SkRect underlineRect = SkRect::MakeLTRB(iBox.centerX() - iBox.width() * accentSize * 3,
                                            underlineY,
                                            iBox.centerX(),
                                            underlineY + accentSize / 10);
    const SkPoint pts1[] = { SkPoint::Make(underlineRect.x(), 0),
                             SkPoint::Make(iBox.centerX(), 0) };
    const SkScalar pos1[] = { 0, 0.75f };
    const SkColor colors1[] = { SK_ColorTRANSPARENT, SK_ColorBLACK };
    SkASSERT(SK_ARRAY_COUNT(pos1) == SK_ARRAY_COUNT(colors1));
    paint.setShader(SkGradientShader::MakeLinear(pts1, colors1, pos1, SK_ARRAY_COUNT(pos1),
                                                 SkShader::kClamp_TileMode));
    canvas->drawRect(underlineRect, paint);

    const SkPoint pts2[] = { SkPoint::Make(iBox.x() - iBox.width() * kGradientPad, 0),
                             SkPoint::Make(iBox.right() + iBox.width() * kGradientPad, 0) };
    const SkScalar pos2[] = { 0, .01f, 1.0f/3, 1.0f/3, 2.0f/3, 2.0f/3, .99f, 1 };
    const SkColor colors2[] = {
        SK_ColorBLACK,
        0xffca5139,
        0xffca5139,
        0xff8dbd53,
        0xff8dbd53,
        0xff5460a5,
        0xff5460a5,
        SK_ColorBLACK
    };
    SkASSERT(SK_ARRAY_COUNT(pos2) == SK_ARRAY_COUNT(colors2));
    paint.setShader(SkGradientShader::MakeLinear(pts2, colors2, pos2, SK_ARRAY_COUNT(pos2),
                                                 SkShader::kClamp_TileMode));
    canvas->drawText(kSkiaStr, textLen, 0, 0, paint);
}