Exemplo n.º 1
0
// Verify that associated bitmap cache entries are purged on SkImage destruction.
DEF_TEST(BitmapCache_discarded_image, reporter) {
    // Cache entries associated with SkImages fall into two categories:
    //
    // 1) generated image bitmaps (managed by the image cacherator)
    // 2) scaled/resampled bitmaps (cached when HQ filters are used)
    //
    // To exercise the first cache type, we use generated/picture-backed SkImages.
    // To exercise the latter, we draw scaled bitmap images using HQ filters.

    const SkMatrix xforms[] = {
        SkMatrix::MakeScale(1, 1),
        SkMatrix::MakeScale(1.7f, 0.5f),
    };

    for (size_t i = 0; i < SK_ARRAY_COUNT(xforms); ++i) {
        test_discarded_image(reporter, xforms[i], []() {
            auto surface(SkSurface::MakeRasterN32Premul(10, 10));
            surface->getCanvas()->clear(SK_ColorCYAN);
            return surface->makeImageSnapshot();
        });

        test_discarded_image(reporter, xforms[i], []() {
            SkPictureRecorder recorder;
            SkCanvas* canvas = recorder.beginRecording(10, 10);
            canvas->clear(SK_ColorCYAN);
            return SkImage::MakeFromPicture(recorder.finishRecordingAsPicture(),
                                            SkISize::Make(10, 10), nullptr, nullptr,
                                            SkImage::BitDepth::kU8,
                                            SkColorSpace::MakeSRGB());
        });
    }
}
Exemplo n.º 2
0
 void onDraw(SkCanvas* canvas) override {
     SkPaint blurPaint;
     SkAutoTUnref<SkImageFilter> blur(SkBlurImageFilter::Create(5.0f, 5.0f));
     blurPaint.setImageFilter(blur);
     const SkScalar tile_size = SkIntToScalar(128);
     SkRect bounds;
     if (!canvas->getClipBounds(&bounds)) {
         bounds.setEmpty();
     }
     int ts = SkScalarCeilToInt(tile_size);
     SkImageInfo info = SkImageInfo::MakeN32Premul(ts, ts);
     auto tileSurface(canvas->makeSurface(info));
     if (!tileSurface) {
         tileSurface = SkSurface::MakeRaster(info);
     }
     SkCanvas* tileCanvas = tileSurface->getCanvas();
     for (SkScalar y = bounds.top(); y < bounds.bottom(); y += tile_size) {
         for (SkScalar x = bounds.left(); x < bounds.right(); x += tile_size) {
             tileCanvas->save();
             tileCanvas->clear(0);
             tileCanvas->translate(-x, -y);
             SkRect rect = SkRect::MakeWH(WIDTH, HEIGHT);
             tileCanvas->saveLayer(&rect, &blurPaint);
             SkRRect rrect = SkRRect::MakeRectXY(rect.makeInset(20, 20), 25, 25);
             tileCanvas->clipRRect(rrect, SkRegion::kDifference_Op, true);
             SkPaint paint;
             tileCanvas->drawRect(rect, paint);
             tileCanvas->restore();
             tileCanvas->restore();
             canvas->drawImage(tileSurface->makeImageSnapshot().get(), x, y);
         }
     }
 }
Exemplo n.º 3
0
static sk_sp<SkImage> render(const SkTextBlob* blob) {
    auto surf = SkSurface::MakeRasterN32Premul(SkScalarRoundToInt(blob->bounds().width()),
                                               SkScalarRoundToInt(blob->bounds().height()));
    if (!surf) {
        return nullptr; // bounds are empty?
    }
    surf->getCanvas()->clear(SK_ColorWHITE);
    surf->getCanvas()->drawTextBlob(blob, -blob->bounds().left(), -blob->bounds().top(), SkPaint());
    return surf->makeImageSnapshot();
}
Exemplo n.º 4
0
void draw(SkCanvas* canvas) {
    SkDebugf("SkSurface::MakeNull(0, 0) %c= nullptr\n", SkSurface::MakeNull(0, 0) == nullptr ?
             '=' : '!');
    const int w = 37;
    const int h = 1000;
    auto surf = SkSurface::MakeNull(w, h);
    auto nullCanvas = surf->getCanvas();
    nullCanvas->drawPaint(SkPaint());   // does not crash, nothing draws
    SkDebugf("surf->makeImageSnapshot() %c= nullptr\n", surf->makeImageSnapshot() == nullptr ?
            '=' : '!');
}
Exemplo n.º 5
0
static sk_sp<SkImage> make_image(SkCanvas* rootCanvas) {
    SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
    auto surface(rootCanvas->makeSurface(info));
    if (!surface) {
        surface = SkSurface::MakeRaster(info);
    }

    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setColor(SK_ColorRED);
    surface->getCanvas()->drawCircle(50, 50, 50, paint);
    return surface->makeImageSnapshot();
}
static void draw_zero_length_capped_paths(SkCanvas* canvas, bool aa) {
    canvas->translate(kCellPad, kCellPad);

    SkImageInfo info = canvas->imageInfo().makeWH(kCellWidth, kCellHeight);
    auto surface = canvas->makeSurface(info);
    if (!surface) {
        surface = SkSurface::MakeRasterN32Premul(kCellWidth, kCellHeight);
    }

    SkPaint paint;
    paint.setColor(SK_ColorWHITE);
    paint.setAntiAlias(aa);
    paint.setStyle(SkPaint::kStroke_Style);

    int numFailedTests = 0;
    for (auto cap : kCaps) {
        for (auto width : kWidths) {
            paint.setStrokeCap(cap);
            paint.setStrokeWidth(width);
            canvas->save();

            for (auto verb : kAllVerbs) {
                SkString pathStr;
                pathStr.appendf("M %f %f ", (kCellWidth - 1) * 0.5f, (kCellHeight - 1) * 0.5f);
                if (verb) {
                    pathStr.append(verb);
                }

                SkPath path;
                SkParsePath::FromSVGString(pathStr.c_str(), &path);

                surface->getCanvas()->clear(SK_ColorTRANSPARENT);
                surface->getCanvas()->drawPath(path, paint);
                auto img = surface->makeImageSnapshot();

                // All cases should draw one cap, except for butt capped, and dangling moves
                // (without a verb or close), which shouldn't draw anything.
                int expectedCaps = ((SkPaint::kButt_Cap == cap) || !verb) ? 0 : 1;

                if (!draw_path_cell(canvas, img.get(), expectedCaps)) {
                    ++numFailedTests;
                }
                canvas->translate(kCellWidth + kCellPad, 0);
            }
            canvas->restore();
            canvas->translate(0, kCellHeight + kCellPad);
        }
    }

    canvas->drawColor(numFailedTests > 0 ? kFailureRed : kSuccessGreen);
}
Exemplo n.º 7
0
DEF_TEST(RecordDraw_drawImage, r){
    class SkCanvasMock : public SkCanvas {
    public:
        SkCanvasMock(int width, int height) : SkCanvas(width, height) {
            this->resetTestValues();
        }

        void onDrawImage(const SkImage* image, SkScalar left, SkScalar top,
                         const SkPaint* paint) override {
            fDrawImageCalled = true;
        }

        void onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
                             const SkPaint* paint, SrcRectConstraint) override {
            fDrawImageRectCalled = true;
        }

        void resetTestValues() {
            fDrawImageCalled = fDrawImageRectCalled = false;
        }

        bool fDrawImageCalled;
        bool fDrawImageRectCalled;
    };

    auto surface(SkSurface::MakeRasterN32Premul(10, 10));
    surface->getCanvas()->clear(SK_ColorGREEN);
    sk_sp<SkImage> image(surface->makeImageSnapshot());

    SkCanvasMock canvas(10, 10);

    {
        SkRecord record;
        SkRecorder recorder(&record, 10, 10);
        recorder.drawImage(image, 0, 0);
        SkRecordDraw(record, &canvas, nullptr, nullptr, 0, nullptr, 0);
    }
    REPORTER_ASSERT(r, canvas.fDrawImageCalled);
    canvas.resetTestValues();

    {
        SkRecord record;
        SkRecorder recorder(&record, 10, 10);
        recorder.drawImageRect(image, SkRect::MakeWH(10, 10), nullptr);
        SkRecordDraw(record, &canvas, nullptr, nullptr, 0, nullptr, 0);
    }
    REPORTER_ASSERT(r, canvas.fDrawImageRectCalled);

}
 void onPerCanvasPreDraw(SkCanvas* canvas) override {
     auto ii = SkImageInfo::Make(fImageSize, fImageSize, kRGBA_8888_SkColorType,
                                 kPremul_SkAlphaType, nullptr);
     SkRandom random;
     for (int i = 0; i < kNumImages; ++i) {
         auto surf = canvas->makeSurface(ii);
         SkColor color = random.nextU();
         surf->getCanvas()->clear(color);
         SkPaint paint;
         paint.setColor(~color);
         paint.setBlendMode(SkBlendMode::kSrc);
         surf->getCanvas()->drawRect(SkRect::MakeLTRB(3, 3, fImageSize - 3, fImageSize - 3),
                                     paint);
         fImages[i] = surf->makeImageSnapshot();
     }
 }
Exemplo n.º 9
0
// Tests that MIP maps are created and invalidated as expected when drawing to and from GrTextures.
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureMipMapInvalidationTest, reporter, ctxInfo) {
    GrContext* context = ctxInfo.grContext();
    if (!context->priv().caps()->mipMapSupport()) {
        return;
    }

    auto isMipped = [] (SkSurface* surf) {
        const GrTexture* texture = surf->makeImageSnapshot()->getTexture();
        return GrMipMapped::kYes == texture->texturePriv().mipMapped();
    };

    auto mipsAreDirty = [] (SkSurface* surf) {
        return surf->makeImageSnapshot()->getTexture()->texturePriv().mipMapsAreDirty();
    };

    auto info = SkImageInfo::MakeN32Premul(256, 256);
    for (auto allocateMips : {false, true}) {
        auto surf1 = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 0,
                                                 kBottomLeft_GrSurfaceOrigin, nullptr,
                                                 allocateMips);
        auto surf2 = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info);
        // Draw something just in case we ever had a solid color optimization
        surf1->getCanvas()->drawCircle(128, 128, 50, SkPaint());
        surf1->flush();

        // No mipmaps initially
        REPORTER_ASSERT(reporter, isMipped(surf1.get()) == allocateMips);

        // Painting with downscale and medium filter quality should result in mipmap creation
        // Flush the context rather than the canvas as flushing the canvas triggers MIP level
        // generation.
        SkPaint paint;
        paint.setFilterQuality(kMedium_SkFilterQuality);
        surf2->getCanvas()->scale(0.2f, 0.2f);
        surf2->getCanvas()->drawImage(surf1->makeImageSnapshot(), 0, 0, &paint);
        context->flush();
        REPORTER_ASSERT(reporter, isMipped(surf1.get()) == allocateMips);
        REPORTER_ASSERT(reporter, !allocateMips || !mipsAreDirty(surf1.get()));

        // Changing the contents of the surface should invalidate the mipmap, but not de-allocate
        surf1->getCanvas()->drawCircle(128, 128, 100, SkPaint());
        context->flush();
        REPORTER_ASSERT(reporter, isMipped(surf1.get()) == allocateMips);
        REPORTER_ASSERT(reporter, mipsAreDirty(surf1.get()));
    }
}
Exemplo n.º 10
0
static sk_sp<SkImage> make_image(SkCanvas* rootCanvas) {
    static constexpr SkScalar kSize = 50;
    SkImageInfo info = SkImageInfo::MakeN32Premul(kSize, kSize);
    auto                      surface = ToolUtils::makeSurface(rootCanvas, info);

    SkPaint p;
    p.setAntiAlias(true);
    p.setColor(SK_ColorGREEN);

    surface->getCanvas()->drawCircle(kSize / 2, kSize / 2, kSize / 2, p);

    p.setStyle(SkPaint::kStroke_Style);
    p.setColor(SK_ColorRED);
    surface->getCanvas()->drawLine(kSize * .25f, kSize * .50f, kSize * .75f, kSize * .50f, p);
    surface->getCanvas()->drawLine(kSize * .50f, kSize * .25f, kSize * .50f, kSize * .75f, p);

    return surface->makeImageSnapshot();
}
Exemplo n.º 11
0
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReimportImageTextureWithMipLevels, reporter, ctxInfo) {
    auto* ctx = ctxInfo.grContext();
    if (!ctx->priv().caps()->mipMapSupport()) {
        return;
    }
    static constexpr auto kCreateWithMipMaps = true;
    auto surf = SkSurface::MakeRenderTarget(
            ctx, SkBudgeted::kYes,
            SkImageInfo::Make(100, 100, kRGBA_8888_SkColorType, kPremul_SkAlphaType), 1,
            kTopLeft_GrSurfaceOrigin, nullptr, kCreateWithMipMaps);
    if (!surf) {
        return;
    }
    surf->getCanvas()->drawColor(SK_ColorDKGRAY);
    auto img = surf->makeImageSnapshot();
    if (!img) {
        return;
    }
    surf.reset();
    GrBackendTexture btex;
    SkImage::BackendTextureReleaseProc texRelease;
    if (!SkImage::MakeBackendTextureFromSkImage(ctx, std::move(img), &btex, &texRelease)) {
        // Not all backends support stealing textures yet.
        // ERRORF(reporter, "Could not turn image into texture");
        return;
    }
    REPORTER_ASSERT(reporter, btex.hasMipMaps());
    // Reimport the texture as an image and perform a downsampling draw with medium quality which
    // should use the upper MIP levels.
    img = SkImage::MakeFromTexture(ctx, btex, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
                                   kPremul_SkAlphaType, nullptr);
    const auto singlePixelInfo =
            SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
    surf = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kYes, singlePixelInfo, 1,
                                       kTopLeft_GrSurfaceOrigin, nullptr);
    SkPaint paint;
    paint.setFilterQuality(kMedium_SkFilterQuality);
    surf->getCanvas()->drawImageRect(img, SkRect::MakeWH(1, 1), &paint);
    uint32_t pixel;
    surf->readPixels(singlePixelInfo, &pixel, sizeof(uint32_t), 0, 0);
    REPORTER_ASSERT(reporter, pixel == SkPreMultiplyColor(SK_ColorDKGRAY));
    img.reset();
    texRelease(btex);
}
Exemplo n.º 12
0
DEF_TEST(Recorder_drawImage_takeReference, reporter) {

    sk_sp<SkImage> image;
    {
        auto surface(SkSurface::MakeRasterN32Premul(100, 100));
        surface->getCanvas()->clear(SK_ColorGREEN);
        image = surface->makeImageSnapshot();
    }
    {
        SkRecord record;
        SkRecorder recorder(&record, 100, 100);

        // DrawImage is supposed to take a reference
        recorder.drawImage(image, 0, 0);
        REPORTER_ASSERT(reporter, !image->unique());

        Tally tally;
        tally.apply(record);

        REPORTER_ASSERT(reporter, 1 == tally.count<SkRecords::DrawImage>());
    }
    REPORTER_ASSERT(reporter, image->unique());

    {
        SkRecord record;
        SkRecorder recorder(&record, 100, 100);

        // DrawImageRect is supposed to take a reference
        recorder.drawImageRect(image, SkRect::MakeWH(100, 100), nullptr);
        REPORTER_ASSERT(reporter, !image->unique());

        Tally tally;
        tally.apply(record);

        REPORTER_ASSERT(reporter, 1 == tally.count<SkRecords::DrawImageRect>());
    }
    REPORTER_ASSERT(reporter, image->unique());
}
Exemplo n.º 13
0
    static sk_sp<SkImage> MakeAtlas(SkCanvas* caller, const SkRect& target) {
        SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
        auto surface(caller->makeSurface(info));
        if (nullptr == surface) {
            surface = SkSurface::MakeRaster(info);
        }
        SkCanvas* canvas = surface->getCanvas();
        // draw red everywhere, but we don't expect to see it in the draw, testing the notion
        // that drawAtlas draws a subset-region of the atlas.
        canvas->clear(SK_ColorRED);

        SkPaint paint;
        paint.setBlendMode(SkBlendMode::kClear);
        SkRect r(target);
        r.inset(-1, -1);
        // zero out a place (with a 1-pixel border) to land our drawing.
        canvas->drawRect(r, paint);
        paint.setBlendMode(SkBlendMode::kSrcOver);
        paint.setColor(SK_ColorBLUE);
        paint.setAntiAlias(true);
        canvas->drawOval(target, paint);
        return surface->makeImageSnapshot();
    }
// Tests that MIP maps are created and invalidated as expected when drawing to and from GrTextures.
DEF_GPUTEST_FOR_NULLGL_CONTEXT(GrTextureMipMapInvalidationTest, reporter, ctxInfo) {
    auto isMipped = [] (SkSurface* surf) {
        const GrTexture* texture = surf->makeImageSnapshot()->getTexture();
        return GrMipMapped::kYes == texture->texturePriv().mipMapped();
    };

    auto mipsAreDirty = [] (SkSurface* surf) {
        return surf->makeImageSnapshot()->getTexture()->texturePriv().mipMapsAreDirty();
    };

    GrContext* context = ctxInfo.grContext();
    auto info = SkImageInfo::MakeN32Premul(256, 256);
    auto surf1 = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info);
    auto surf2 = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info);
    // Draw something just in case we ever had a solid color optimization
    surf1->getCanvas()->drawCircle(128, 128, 50, SkPaint());
    surf1->getCanvas()->flush();

    // No mipmaps initially
    REPORTER_ASSERT(reporter, !isMipped(surf1.get()));

    // Painting with downscale and medium filter quality should result in mipmap creation
    SkPaint paint;
    paint.setFilterQuality(kMedium_SkFilterQuality);
    surf2->getCanvas()->scale(0.2f, 0.2f);
    surf2->getCanvas()->drawImage(surf1->makeImageSnapshot(), 0, 0, &paint);
    surf2->getCanvas()->flush();
    REPORTER_ASSERT(reporter, isMipped(surf1.get()));
    REPORTER_ASSERT(reporter, !mipsAreDirty(surf1.get()));

    // Changing the contents of the surface should invalidate the mipmap, but not de-allocate
    surf1->getCanvas()->drawCircle(128, 128, 100, SkPaint());
    surf1->getCanvas()->flush();
    REPORTER_ASSERT(reporter, isMipped(surf1.get()));
    REPORTER_ASSERT(reporter, mipsAreDirty(surf1.get()));
}
static void draw_zero_length_capped_paths_dbl_contour(SkCanvas* canvas, bool aa) {
    canvas->translate(kCellPad, kCellPad);

    SkImageInfo info = canvas->imageInfo().makeWH(kCellWidth, kCellHeight);
    auto surface = canvas->makeSurface(info);
    if (!surface) {
        surface = SkSurface::MakeRasterN32Premul(kCellWidth, kCellHeight);
    }

    SkPaint paint;
    paint.setColor(SK_ColorWHITE);
    paint.setAntiAlias(aa);
    paint.setStyle(SkPaint::kStroke_Style);

    int numFailedTests = 0;
    for (auto cap : kCaps) {
        for (auto width : kWidths) {
            paint.setStrokeCap(cap);
            paint.setStrokeWidth(width);
            canvas->save();

            for (auto firstVerb : kSomeVerbs) {
                for (auto secondVerb : kSomeVerbs) {
                    int expectedCaps = 0;

                    SkString pathStr;
                    pathStr.append("M 9.5 9.5 ");
                    if (firstVerb) {
                        pathStr.append(firstVerb);
                        ++expectedCaps;
                    }
                    pathStr.append("M 40.5 9.5 ");
                    if (secondVerb) {
                        pathStr.append(secondVerb);
                        ++expectedCaps;
                    }

                    SkPath path;
                    SkParsePath::FromSVGString(pathStr.c_str(), &path);

                    surface->getCanvas()->clear(SK_ColorTRANSPARENT);
                    surface->getCanvas()->drawPath(path, paint);
                    auto img = surface->makeImageSnapshot();

                    if (SkPaint::kButt_Cap == cap) {
                        expectedCaps = 0;
                    }

                    if (!draw_path_cell(canvas, img.get(), expectedCaps)) {
                        ++numFailedTests;
                    }
                    canvas->translate(kCellWidth + kCellPad, 0);
                }
            }
            canvas->restore();
            canvas->translate(0, kCellHeight + kCellPad);
        }
    }

    canvas->drawColor(numFailedTests > 0 ? kFailureRed : kSuccessGreen);
}
Exemplo n.º 16
0
static sk_sp<SkImage> picture_to_image(sk_sp<SkPicture> pic) {
    SkIRect r = pic->cullRect().round();
    auto surf = SkSurface::MakeRasterN32Premul(r.width(), r.height());
    surf->getCanvas()->drawPicture(pic);
    return surf->makeImageSnapshot();
}
Exemplo n.º 17
0
static sk_sp<SkImage> makebm(SkCanvas* origCanvas, SkBitmap* resultBM, int w, int h) {
    SkImageInfo info = SkImageInfo::MakeN32Premul(w, h);

    auto surface(origCanvas->makeSurface(info));
    if (nullptr == surface) {
        // picture canvas will return null, so fall-back to raster
        surface = SkSurface::MakeRaster(info);
    }

    SkCanvas* canvas = surface->getCanvas();

    canvas->clear(SK_ColorTRANSPARENT);

    SkScalar wScalar = SkIntToScalar(w);
    SkScalar hScalar = SkIntToScalar(h);

    SkPoint     pt = { wScalar / 2, hScalar / 2 };

    SkScalar    radius = 4 * SkMaxScalar(wScalar, hScalar);

    SkColor     colors[] = { SK_ColorRED, SK_ColorYELLOW,
                             SK_ColorGREEN, SK_ColorMAGENTA,
                             SK_ColorBLUE, SK_ColorCYAN,
                             SK_ColorRED};

    SkScalar    pos[] = {0,
                         SK_Scalar1 / 6,
                         2 * SK_Scalar1 / 6,
                         3 * SK_Scalar1 / 6,
                         4 * SK_Scalar1 / 6,
                         5 * SK_Scalar1 / 6,
                         SK_Scalar1};

    SkPaint     paint;
    SkRect rect = SkRect::MakeWH(wScalar, hScalar);
    SkMatrix mat = SkMatrix::I();
    for (int i = 0; i < 4; ++i) {
        paint.setShader(SkGradientShader::MakeRadial(
                        pt, radius,
                        colors, pos,
                        SK_ARRAY_COUNT(colors),
                        SkShader::kRepeat_TileMode,
                        0, &mat));
        canvas->drawRect(rect, paint);
        rect.inset(wScalar / 8, hScalar / 8);
        mat.postScale(SK_Scalar1 / 4, SK_Scalar1 / 4);
    }

    auto image = surface->makeImageSnapshot();

    SkBitmap tempBM;

#if SK_SUPPORT_GPU
    if (GrTexture* texture = as_IB(image)->peekTexture()) {
        GrWrapTextureInBitmap(texture, image->width(), image->height(), image->isOpaque(), &tempBM);
    } else
#endif
    {
        image->asLegacyBitmap(&tempBM, SkImage::kRO_LegacyBitmapMode);
    }

    // Let backends know we won't change this, so they don't have to deep copy it defensively.
    tempBM.setImmutable();
    *resultBM = tempBM;

    return image;
}
Exemplo n.º 18
0
    void onDraw(SkCanvas* canvas) override{

        SkPaint blackFill;

        //-----------
        // Normal paints (no source)
        SkTArray<SkPaint> paints;
        create_paints(nullptr, &paints);

        //-----------
        // Paints with a PictureImageFilter as a source
        sk_sp<SkPicture> pic;

        {
            SkPictureRecorder rec;

            SkCanvas* c = rec.beginRecording(10, 10);
            c->drawRect(SkRect::MakeWH(10, 10), blackFill);
            pic = rec.finishRecordingAsPicture();
        }

        SkAutoTUnref<SkImageFilter> pif(SkPictureImageFilter::Create(pic.get()));

        SkTArray<SkPaint> pifPaints;
        create_paints(pif, &pifPaints);

        //-----------
        // Paints with a SkImageSource as a source

        auto surface(SkSurface::MakeRasterN32Premul(10, 10));
        {
            SkPaint p;
            SkCanvas* temp = surface->getCanvas();
            temp->clear(SK_ColorYELLOW);
            p.setColor(SK_ColorBLUE);
            temp->drawRect(SkRect::MakeLTRB(5, 5, 10, 10), p);
            p.setColor(SK_ColorGREEN);
            temp->drawRect(SkRect::MakeLTRB(5, 0, 10, 5), p);
        }

        sk_sp<SkImage> image(surface->makeImageSnapshot());
        SkAutoTUnref<SkImageFilter> imageSource(SkImageSource::Create(image.get()));

        SkTArray<SkPaint> bmsPaints;
        create_paints(imageSource, &bmsPaints);

        //-----------
        SkASSERT(paints.count() == kNumVertTiles);
        SkASSERT(paints.count() == pifPaints.count());
        SkASSERT(paints.count() == bmsPaints.count());

        // horizontal separators
        for (int i = 1; i < paints.count(); ++i) {
            canvas->drawLine(0,
                             i*SkIntToScalar(kTileHeight),
                             SkIntToScalar((SK_ARRAY_COUNT(gDrawMthds) + kNumXtraCols)*kTileWidth),
                             i*SkIntToScalar(kTileHeight),
                             blackFill);
        }
        // vertical separators
        for (int i = 0; i < (int)SK_ARRAY_COUNT(gDrawMthds) + kNumXtraCols; ++i) {
            canvas->drawLine(SkIntToScalar(i * kTileWidth),
                             0,
                             SkIntToScalar(i * kTileWidth), 
                             SkIntToScalar(paints.count() * kTileWidth),
                             blackFill);
        }

        // A column of saveLayers with PictureImageFilters
        for (int i = 0; i < pifPaints.count(); ++i) {
            draw_savelayer_with_paint(SkIPoint::Make(0, i*kTileHeight), 
                                      canvas, pifPaints[i]);
        }

        // A column of saveLayers with BitmapSources
        for (int i = 0; i < pifPaints.count(); ++i) {
            draw_savelayer_with_paint(SkIPoint::Make(kTileWidth, i*kTileHeight),
                                      canvas, bmsPaints[i]);
        }

        // Multiple columns with different geometry
        for (int i = 0; i < (int)SK_ARRAY_COUNT(gDrawMthds); ++i) {
            for (int j = 0; j < paints.count(); ++j) {
                draw_geom_with_paint(*gDrawMthds[i],
                                     SkIPoint::Make((i+kNumXtraCols) * kTileWidth, j*kTileHeight),
                                     canvas, paints[j]);
            }
        }

    }
Exemplo n.º 19
0
    virtual void onDraw(SkCanvas* inputCanvas) override {
        SkScalar textSizes[] = { 9.0f, 9.0f*2.0f, 9.0f*5.0f, 9.0f*2.0f*5.0f };
        SkScalar scales[] = { 2.0f*5.0f, 5.0f, 2.0f, 1.0f };

        // set up offscreen rendering with distance field text
        GrContext* ctx = inputCanvas->getGrContext();
        SkISize size = onISize();
        SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), kPremul_SkAlphaType,
                                                inputCanvas->imageInfo().refColorSpace());
        SkSurfaceProps props(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
                             SkSurfaceProps::kLegacyFontHost_InitType);
        auto surface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info, 0, &props));
        SkCanvas* canvas = surface ? surface->getCanvas() : inputCanvas;
        // init our new canvas with the old canvas's matrix
        canvas->setMatrix(inputCanvas->getTotalMatrix());
        // apply global scale to test glyph positioning
        canvas->scale(1.05f, 1.05f);
        canvas->clear(0xffffffff);

        SkPaint paint;
        paint.setAntiAlias(true);

        SkFont font(ToolUtils::create_portable_typeface("serif", SkFontStyle()));
        font.setSubpixel(true);

        const char* text = "Hamburgefons";
        const size_t textLen = strlen(text);

        // check scaling up
        SkScalar x = SkIntToScalar(0);
        SkScalar y = SkIntToScalar(78);
        for (size_t i = 0; i < SK_ARRAY_COUNT(textSizes); ++i) {
            SkAutoCanvasRestore acr(canvas, true);
            canvas->translate(x, y);
            canvas->scale(scales[i], scales[i]);
            font.setSize(textSizes[i]);
            canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, 0, 0, font, paint);
            y += font.getMetrics(nullptr)*scales[i];
        }

        // check rotation
        for (size_t i = 0; i < 5; ++i) {
            SkScalar rotX = SkIntToScalar(10);
            SkScalar rotY = y;

            SkAutoCanvasRestore acr(canvas, true);
            canvas->translate(SkIntToScalar(10 + i * 200), -80);
            canvas->rotate(SkIntToScalar(i * 5), rotX, rotY);
            for (int ps = 6; ps <= 32; ps += 3) {
                font.setSize(SkIntToScalar(ps));
                canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, rotX, rotY, font, paint);
                rotY += font.getMetrics(nullptr);
            }
        }

        // check scaling down
        font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
        x = SkIntToScalar(680);
        y = SkIntToScalar(20);
        size_t arraySize = SK_ARRAY_COUNT(textSizes);
        for (size_t i = 0; i < arraySize; ++i) {
            SkAutoCanvasRestore acr(canvas, true);
            canvas->translate(x, y);
            SkScalar scaleFactor = SkScalarInvert(scales[arraySize - i - 1]);
            canvas->scale(scaleFactor, scaleFactor);
            font.setSize(textSizes[i]);
            canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, 0, 0, font, paint);
            y += font.getMetrics(nullptr)*scaleFactor;
        }

        // check pos text
        {
            SkAutoCanvasRestore acr(canvas, true);

            canvas->scale(2.0f, 2.0f);

            SkAutoTArray<SkGlyphID> glyphs(SkToInt(textLen));
            int count = font.textToGlyphs(text, textLen, SkTextEncoding::kUTF8, glyphs.get(), textLen);
            SkAutoTArray<SkPoint>  pos(count);
            font.setSize(textSizes[0]);
            font.getPos(glyphs.get(), count, pos.get(), {340, 75});

            auto blob = SkTextBlob::MakeFromPosText(glyphs.get(), count * sizeof(SkGlyphID),
                                                    pos.get(), font, SkTextEncoding::kGlyphID);
            canvas->drawTextBlob(blob, 0, 0, paint);
        }


        // check gamma-corrected blending
        const SkColor fg[] = {
            0xFFFFFFFF,
            0xFFFFFF00, 0xFFFF00FF, 0xFF00FFFF,
            0xFFFF0000, 0xFF00FF00, 0xFF0000FF,
            0xFF000000,
        };

        paint.setColor(0xFFF7F3F7);
        SkRect r = SkRect::MakeLTRB(670, 215, 820, 397);
        canvas->drawRect(r, paint);

        x = SkIntToScalar(680);
        y = SkIntToScalar(235);
        font.setSize(SkIntToScalar(19));
        for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) {
            paint.setColor(fg[i]);

            canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, x, y, font, paint);
            y += font.getMetrics(nullptr);
        }

        paint.setColor(0xFF181C18);
        r = SkRect::MakeLTRB(820, 215, 970, 397);
        canvas->drawRect(r, paint);

        x = SkIntToScalar(830);
        y = SkIntToScalar(235);
        font.setSize(SkIntToScalar(19));
        for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) {
            paint.setColor(fg[i]);

            canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, x, y, font, paint);
            y += font.getMetrics(nullptr);
        }

        // check skew
        {
            font.setEdging(SkFont::Edging::kAntiAlias);
            SkAutoCanvasRestore acr(canvas, true);
            canvas->skew(0.0f, 0.151515f);
            font.setSize(SkIntToScalar(32));
            canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, 745, 70, font, paint);
        }
        {
            font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
            SkAutoCanvasRestore acr(canvas, true);
            canvas->skew(0.5f, 0.0f);
            font.setSize(SkIntToScalar(32));
            canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, 580, 125, font, paint);
        }

        // check perspective
        {
            font.setEdging(SkFont::Edging::kAntiAlias);
            SkAutoCanvasRestore acr(canvas, true);
            SkMatrix persp;
            persp.setAll(0.9839f, 0, 0,
                         0.2246f, 0.6829f, 0,
                         0.0002352f, -0.0003844f, 1);
            canvas->concat(persp);
            canvas->translate(1100, -295);
            font.setSize(37.5f);
            canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, 0, 0, font, paint);
        }
        {
            font.setSubpixel(false);
            font.setEdging(SkFont::Edging::kAlias);
            SkAutoCanvasRestore acr(canvas, true);
            SkMatrix persp;
            persp.setAll(0.9839f, 0, 0,
                         0.2246f, 0.6829f, 0,
                         0.0002352f, -0.0003844f, 1);
            canvas->concat(persp);
            canvas->translate(1075, -245);
            canvas->scale(375, 375);
            font.setSize(0.1f);
            canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, 0, 0, font, paint);
        }

        // check color emoji
        if (fEmojiTypeface) {
            SkFont emoiFont;
            emoiFont.setSubpixel(true);
            emoiFont.setTypeface(fEmojiTypeface);
            emoiFont.setSize(SkIntToScalar(19));
            canvas->drawSimpleText(fEmojiText, strlen(fEmojiText), SkTextEncoding::kUTF8, 670, 90, emoiFont, paint);
        }

        // render offscreen buffer
        if (surface) {
            SkAutoCanvasRestore acr(inputCanvas, true);
            // since we prepended this matrix already, we blit using identity
            inputCanvas->resetMatrix();
            inputCanvas->drawImage(surface->makeImageSnapshot().get(), 0, 0, nullptr);
        }
    }
Exemplo n.º 20
0
void SetImageShader(SkPaint* paint, int imageWidth, int imageHeight, SkShader::TileMode xTile,
                    SkShader::TileMode yTile) {
    auto surface = SkSurface::MakeRasterN32Premul(imageWidth, imageHeight);
    paint->setShader(SkImageShader::Make(surface->makeImageSnapshot(), xTile, yTile, nullptr));
}