Пример #1
0
SkRect FindCanvas::addMatchPos(int index,
        const SkPaint& paint, int count, const uint16_t* glyphs,
        const SkScalar xPos[], SkScalar /* y */) {
    SkRect r;
    r.setEmpty();
    const SkPoint* temp = reinterpret_cast<const SkPoint*> (xPos);
    const SkPoint* points = &temp[index];
    int countInBytes = count * sizeof(uint16_t);
    SkPaint::FontMetrics fontMetrics;
    paint.getFontMetrics(&fontMetrics);
    // Need to check each character individually, since the heights may be
    // different.
    for (int j = 0; j < count; j++) {
        SkRect bounds;
        bounds.fLeft = points[j].fX;
        bounds.fRight = bounds.fLeft +
                paint.measureText(&glyphs[j], sizeof(uint16_t), 0);
        SkScalar baseline = points[j].fY;
        bounds.fTop = baseline + fontMetrics.fAscent;
        bounds.fBottom = baseline + fontMetrics.fDescent;
        /* Accumulate and then add the resulting rect to mMatches */
        r.join(bounds);
    }
    SkMatrix matrix = getTotalMatrix();
    matrix.mapRect(&r);
    SkCanvas* canvas = getWorkingCanvas();
    int saveCount = canvas->save();
    canvas->concat(matrix);
    canvas->drawPosText(glyphs, countInBytes, points, paint);
    canvas->restoreToCount(saveCount);
    return r;
}
Пример #2
0
void GpuGMTask::draw(GrContextFactory* grFactory) {
    SkImageInfo info = SkImageInfo::Make(SkScalarCeilToInt(fGM->width()),
                                         SkScalarCeilToInt(fGM->height()),
                                         kN32_SkColorType,
                                         kPremul_SkAlphaType);
    SkAutoTUnref<SkSurface> surface(NewGpuSurface(grFactory, fContextType, fGpuAPI, info,
                                                  fSampleCount));
    if (!surface) {
        if (!gAlreadyWarned[fContextType][fGpuAPI]) {
            SkDebugf("FYI: couldn't create GPU context, type %d API %d.  Will skip.\n",
                     fContextType, fGpuAPI);
            gAlreadyWarned[fContextType][fGpuAPI] = true;
        }
        return;
    }
    SkCanvas* canvas = surface->getCanvas();
    CanvasPreflight(canvas);

    canvas->concat(fGM->getInitialTransform());
    fGM->draw(canvas);
    canvas->flush();
#if GR_CACHE_STATS && SK_SUPPORT_GPU
    if (FLAGS_veryVerbose) {
        grFactory->get(fContextType)->printCacheStats();
    }
#endif

    SkBitmap bitmap;
    bitmap.setInfo(info);
    canvas->readPixels(&bitmap, 0, 0);

    this->spawnChild(SkNEW_ARGS(WriteTask, (*this, "GM", bitmap)));
}
Пример #3
0
SkRect FindCanvas::addMatchPosH(int index,
        const SkPaint& paint, int count, const uint16_t* glyphs,
        const SkScalar position[], SkScalar constY) {
    SkRect r;
    // We only care about the positions starting at the index of our match
    const SkScalar* xPos = &position[index];
    // This assumes that the position array is monotonic increasing
    // The left bounds will be the position of the left most character
    r.fLeft = xPos[0];
    // The right bounds will be the position of the last character plus its
    // width
    int lastIndex = count - 1;
    r.fRight = paint.measureText(&glyphs[lastIndex], sizeof(uint16_t), 0)
            + xPos[lastIndex];
    // Grab font metrics to determine the top and bottom of the bounds
    SkPaint::FontMetrics fontMetrics;
    paint.getFontMetrics(&fontMetrics);
    r.fTop = constY + fontMetrics.fAscent;
    r.fBottom = constY + fontMetrics.fDescent;
    const SkMatrix& matrix = getTotalMatrix();
    matrix.mapRect(&r);
    SkCanvas* canvas = getWorkingCanvas();
    int saveCount = canvas->save();
    canvas->concat(matrix);
    canvas->drawPosTextH(glyphs, count * sizeof(uint16_t), xPos, constY, paint);
    canvas->restoreToCount(saveCount);
    return r;
}
static void render_picture(GrContext* grContext,
                           int width,
                           int height,
                           const SkPicture* picture,
                           const SkMatrix& matrix) {
    SkASSERT(grContext);
    if (!picture) {
        SkDebugf(TAG "!picture\n");
        return;
    }
    // Render to the default framebuffer render target.
    GrBackendRenderTargetDesc desc;
    desc.fWidth = width;
    desc.fHeight = height;
    desc.fConfig = kSkia8888_GrPixelConfig;
    desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
    SkSurfaceProps surfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
                                kUnknown_SkPixelGeometry);
    // TODO:  Check to see if we can keep the surface between draw calls.
    SkAutoTUnref<SkSurface> surface(
            SkSurface::NewFromBackendRenderTarget(
                    grContext, desc, &surfaceProps));
    if (surface) {
        SkCanvas* canvas = surface->getCanvas();
        SkASSERT(canvas);
        canvas->clear(SK_ColorGRAY);
        canvas->concat(matrix);
        SkRect cullRect = picture->cullRect();
        canvas->clipRect(cullRect);
        picture->playback(canvas);
        canvas->flush();
    }
}
Пример #5
0
static void test_discarded_image(skiatest::Reporter* reporter, const SkMatrix& transform,
                                 sk_sp<SkImage> (*buildImage)()) {
    auto surface(SkSurface::MakeRasterN32Premul(10, 10));
    SkCanvas* canvas = surface->getCanvas();

    // SkBitmapCache is global, so other threads could be evicting our bitmaps.  Loop a few times
    // to mitigate this risk.
    const unsigned kRepeatCount = 42;
    for (unsigned i = 0; i < kRepeatCount; ++i) {
        SkAutoCanvasRestore acr(canvas, true);

        sk_sp<SkImage> image(buildImage());

        // always use high quality to ensure caching when scaled
        SkPaint paint;
        paint.setFilterQuality(kHigh_SkFilterQuality);

        // draw the image (with a transform, to tickle different code paths) to ensure
        // any associated resources get cached
        canvas->concat(transform);
        canvas->drawImage(image, 0, 0, &paint);

        const auto desc = SkBitmapCacheDesc::Make(image.get());

        // delete the image
        image.reset(nullptr);

        // all resources should have been purged
        SkBitmap result;
        REPORTER_ASSERT(reporter, !SkBitmapCache::Find(desc, &result));
    }
}
Пример #6
0
// Each version of addMatch returns a rectangle for a match.
// Not all of the parameters are used by each version.
SkRect FindCanvas::addMatchNormal(int index,
        const SkPaint& paint, int count, const uint16_t* glyphs,
        const SkScalar pos[], SkScalar y) {
    const uint16_t* lineStart = glyphs - index;
    /* Use the original paint, since "text" is in glyphs */
    SkScalar before = paint.measureText(lineStart, index * sizeof(uint16_t), 0);
    SkRect rect;
    rect.fLeft = pos[0] + before;
    int countInBytes = count * sizeof(uint16_t);
    rect.fRight = paint.measureText(glyphs, countInBytes, 0) + rect.fLeft;
    SkPaint::FontMetrics fontMetrics;
    paint.getFontMetrics(&fontMetrics);
    SkScalar baseline = y;
    rect.fTop = baseline + fontMetrics.fAscent;
    rect.fBottom = baseline + fontMetrics.fDescent;
    const SkMatrix& matrix = getTotalMatrix();
    matrix.mapRect(&rect);
    // Add the text to our picture.
    SkCanvas* canvas = getWorkingCanvas();
    int saveCount = canvas->save();
    canvas->concat(matrix);
    canvas->drawText(glyphs, countInBytes, pos[0] + before, y, paint);
    canvas->restoreToCount(saveCount);
    return rect;
}
Пример #7
0
SkPicture* RecordPicture(skiagm::GM* gm, uint32_t recordFlags, SkBBHFactory* factory) {
    const SkISize size = gm->getISize();
    SkPictureRecorder recorder;
    SkCanvas* canvas = recorder.beginRecording(size.width(), size.height(), factory, recordFlags);
    canvas->concat(gm->getInitialTransform());
    gm->draw(canvas);
    canvas->flush();
    return recorder.endRecording();
}
Пример #8
0
void View::draw(SkCanvas & canvas)
{
    SkAutoCanvasRestore restore(&canvas, true);
    canvas.concat(m_props.matrix());
    canvas.clipRect(m_props.localRect(), SkRegion::kIntersect_Op, true);

    onDraw(canvas);

    for (View* v : m_children) {
        v->draw(canvas);
    }
}
Пример #9
0
void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
                                       const SkTDArray<GrHoistedLayer>& atlased) {
    if (atlased.count() > 0) {
        // All the atlased layers are rendered into the same GrTexture
        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
                                        atlased[0].fLayer->texture()->asRenderTarget(), NULL));

        SkCanvas* atlasCanvas = surface->getCanvas();

        SkPaint clearPaint;
        clearPaint.setColor(SK_ColorTRANSPARENT);
        clearPaint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode))->unref();

        for (int i = 0; i < atlased.count(); ++i) {
            const GrCachedLayer* layer = atlased[i].fLayer;
            const SkPicture* pict = atlased[i].fPicture;
            const SkIPoint offset = atlased[i].fOffset;
            SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();)

            SkASSERT(!layerPaint || !layerPaint->getImageFilter());

            atlasCanvas->save();

            // Add a rect clip to make sure the rendering doesn't
            // extend beyond the boundaries of the atlased sub-rect
            SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft),
                                            SkIntToScalar(layer->rect().fTop),
                                            SkIntToScalar(layer->rect().width()),
                                            SkIntToScalar(layer->rect().height()));
            atlasCanvas->clipRect(bound);

            // Since 'clear' doesn't respect the clip we need to draw a rect
            atlasCanvas->drawRect(bound, clearPaint);

            // '-offset' maps the layer's top/left to the origin.
            // Since this layer is atlased, the top/left corner needs
            // to be offset to the correct location in the backing texture.
            SkMatrix initialCTM;
            initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset.fY));
            initialCTM.preTranslate(bound.fLeft, bound.fTop);
            initialCTM.preConcat(atlased[i].fPreMat);

            atlasCanvas->setMatrix(initialCTM);
            atlasCanvas->concat(atlased[i].fLocalMat);

            SkRecordPartialDraw(*pict->fRecord.get(), atlasCanvas, bound,
                                layer->start() + 1, layer->stop(), initialCTM);

            atlasCanvas->restore();
        }

        atlasCanvas->flush();
    }
Пример #10
0
bool SkWindow::update(SkIRect* updateArea) {
    if (!fDirtyRgn.isEmpty()) {
        SkBitmap bm = this->getBitmap();

#if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
        char* buffer = (char*)GXBeginDraw();
        SkASSERT(buffer);

        RECT    rect;
        GetWindowRect((HWND)((SkOSWindow*)this)->getHWND(), &rect);
        buffer += rect.top * gDisplayProps.cbyPitch + rect.left * gDisplayProps.cbxPitch;

        bm.setPixels(buffer);
#endif

        SkAutoTUnref<SkSurface> surface(this->createSurface());
        SkCanvas* canvas = surface->getCanvas();

        canvas->clipRegion(fDirtyRgn);
        if (updateArea)
            *updateArea = fDirtyRgn.getBounds();

        SkAutoCanvasRestore acr(canvas, true);
        canvas->concat(fMatrix);

        // empty this now, so we can correctly record any inval calls that
        // might be made during the draw call.
        fDirtyRgn.setEmpty();

#ifdef SK_SIMULATE_FAILED_MALLOC
        gEnableControlledThrow = true;
#endif
#ifdef SK_BUILD_FOR_WIN32
        //try {
            this->draw(canvas);
        //}
        //catch (...) {
        //}
#else
        this->draw(canvas);
#endif
#ifdef SK_SIMULATE_FAILED_MALLOC
        gEnableControlledThrow = false;
#endif

#if defined(SK_BUILD_FOR_WINCE) && defined(USE_GX_SCREEN)
        GXEndDraw();
#endif

        return true;
    }
    return false;
}
Пример #11
0
void OsmAnd::MapRasterizer_P::rasterizePolylineIcons(
    const Context& context,
    SkCanvas& canvas,
    const SkPath& path,
    const MapStyleEvaluationResult& evalResult)
{
    bool ok;

    QString pathIconName;
    ok = evalResult.getStringValue(context.env->styleBuiltinValueDefs->id_OUTPUT_PATH_ICON, pathIconName);
    if (!ok || pathIconName.isEmpty())
        return;

    float pathIconStep = 0.0f;
    ok = evalResult.getFloatValue(context.env->styleBuiltinValueDefs->id_OUTPUT_PATH_ICON_STEP, pathIconStep);
    if (!ok || pathIconStep <= 0.0f)
        return;

    std::shared_ptr<const SkBitmap> pathIcon;
    ok = context.env->obtainMapIcon(pathIconName, pathIcon);
    if (!ok || !pathIcon)
        return;

    SkMatrix mIconTransform;
    mIconTransform.setIdentity();
    mIconTransform.setTranslate(-0.5f * pathIcon->width(), -0.5f * pathIcon->height());
    mIconTransform.postRotate(90.0f);

    SkPathMeasure pathMeasure(path, false);

    const auto length = pathMeasure.getLength();
    auto iconOffset = 0.5f * pathIconStep;
    const auto iconInstancesCount = static_cast<int>((length - iconOffset) / pathIconStep) + 1;
    if (iconInstancesCount < 1)
        return;

    SkMatrix mIconInstanceTransform;
    for (auto iconInstanceIdx = 0; iconInstanceIdx < iconInstancesCount; iconInstanceIdx++, iconOffset += pathIconStep)
    {
        SkMatrix mPinPoint;
        ok = pathMeasure.getMatrix(iconOffset, &mPinPoint);
        if (!ok)
            break;

        mIconInstanceTransform.setConcat(mPinPoint, mIconTransform);
        canvas.save();
        canvas.concat(mIconInstanceTransform);
        canvas.drawBitmap(*pathIcon, 0, 0, &_defaultPaint);
        canvas.restore();
    }
}
Пример #12
0
void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
                                       const SkTDArray<GrHoistedLayer>& atlased) {
    if (atlased.count() > 0) {
        // All the atlased layers are rendered into the same GrTexture
        SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
                                        atlased[0].fLayer->texture()->asRenderTarget(), &props));

        SkCanvas* atlasCanvas = surface->getCanvas();

        for (int i = 0; i < atlased.count(); ++i) {
            const GrCachedLayer* layer = atlased[i].fLayer;
            const SkBigPicture* pict = atlased[i].fPicture->asSkBigPicture();
            if (!pict) {
                // TODO: can we assume / assert this?
                continue;
            }
            const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
            SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();)

            SkASSERT(!layerPaint || !layerPaint->getImageFilter());
            SkASSERT(!layer->filter());

            atlasCanvas->save();

            // Add a rect clip to make sure the rendering doesn't
            // extend beyond the boundaries of the atlased sub-rect
            const SkRect bound = SkRect::Make(layer->rect());
            atlasCanvas->clipRect(bound);
            atlasCanvas->clear(0);

            // '-offset' maps the layer's top/left to the origin.
            // Since this layer is atlased, the top/left corner needs
            // to be offset to the correct location in the backing texture.
            SkMatrix initialCTM;
            initialCTM.setTranslate(SkIntToScalar(-offset.fX), SkIntToScalar(-offset.fY));
            initialCTM.preTranslate(bound.fLeft, bound.fTop);
            initialCTM.preConcat(atlased[i].fPreMat);

            atlasCanvas->setMatrix(initialCTM);
            atlasCanvas->concat(atlased[i].fLocalMat);

            pict->partialPlayback(atlasCanvas, layer->start() + 1, layer->stop(), initialCTM);
            atlasCanvas->restore();
        }

        atlasCanvas->flush();
    }
Пример #13
0
static void test_sweep_fuzzer(skiatest::Reporter*) {
    static const SkColor gColors0[] = { 0x30303030, 0x30303030, 0x30303030 };
    static const SkScalar   gPos0[] = { -47919293023455565225163489280.0f, 0, 1 };
    static const SkScalar gMatrix0[9] = {
        1.12116716e-13f,  0              ,  8.50489682e+16f,
        4.1917041e-41f ,  3.51369881e-23f, -2.54344271e-26f,
        9.61111907e+17f, -3.35263808e-29f, -1.35659403e+14f
    };
    static const struct {
        SkPoint            fCenter;
        const SkColor*     fColors;
        const SkScalar*    fPos;
        int                fCount;
        const SkScalar*    fGlobalMatrix;
    } gConfigs[] = {
        {
            { 0, 0 },
            gColors0,
            gPos0,
            SK_ARRAY_COUNT(gColors0),
            gMatrix0
        },
    };

    sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(100, 100);
    SkCanvas* canvas = surface->getCanvas();
    SkPaint paint;

    for (const auto& config : gConfigs) {
        paint.setShader(SkGradientShader::MakeSweep(config.fCenter.x(),
                                                    config.fCenter.y(),
                                                    config.fColors,
                                                    config.fPos,
                                                    config.fCount));

        SkAutoCanvasRestore acr(canvas, false);
        if (config.fGlobalMatrix) {
            SkMatrix m;
            m.set9(config.fGlobalMatrix);
            canvas->save();
            canvas->concat(m);
        }
        canvas->drawPaint(paint);
    }
}
Пример #14
0
static void DrawRoundRect(SkCanvas& canvas) {
   bool ret = false;
   SkPaint  paint;
   SkBitmap bitmap;
   SkMatrix matrix;
   matrix.reset();

   bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1370, 812);
   bitmap.allocPixels();
#if 0
    SkCanvas canvas;
    canvas.setBitmapDevice(bitmap);
#endif

   // set up clipper
   SkRect skclip;
   skclip.set(SkIntToScalar(284), SkIntToScalar(40), SkIntToScalar(1370), SkIntToScalar(708));

//   ret = canvas.clipRect(skclip);
//   SkASSERT(ret);

   matrix.set(SkMatrix::kMTransX, SkFloatToScalar(-1153.28f));
   matrix.set(SkMatrix::kMTransY, SkFloatToScalar(1180.50f));

   matrix.set(SkMatrix::kMScaleX, SkFloatToScalar(0.177171f));
   matrix.set(SkMatrix::kMScaleY, SkFloatToScalar(0.177043f));

   matrix.set(SkMatrix::kMSkewX, SkFloatToScalar(0.126968f));
   matrix.set(SkMatrix::kMSkewY, SkFloatToScalar(-0.126876f));

   matrix.set(SkMatrix::kMPersp0, SkFloatToScalar(0.0f));
   matrix.set(SkMatrix::kMPersp1, SkFloatToScalar(0.0f));

   ret = canvas.concat(matrix);

   paint.setAntiAlias(true);
   paint.setColor(0xb2202020);
   paint.setStyle(SkPaint::kStroke_Style);
   paint.setStrokeWidth(SkFloatToScalar(68.13f));

   SkRect r;
   r.set(SkFloatToScalar(-313.714417f), SkFloatToScalar(-4.826389f), SkFloatToScalar(18014.447266f), SkFloatToScalar(1858.154541f));
   canvas.drawRoundRect(r, SkFloatToScalar(91.756363f), SkFloatToScalar(91.756363f), paint);
}
Пример #15
0
static void DrawRoundRect() {
#ifdef SK_SCALAR_IS_FIXED
    bool ret = false;
    SkPaint  paint;
    SkBitmap bitmap;
    SkCanvas canvas;
    SkMatrix matrix;
    matrix.reset();

    bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1370, 812);
    bitmap.allocPixels();
    canvas.setBitmapDevice(bitmap);

    // set up clipper
    SkRect skclip;
    skclip.set(SkIntToFixed(284), SkIntToFixed(40), SkIntToFixed(1370), SkIntToFixed(708));

    ret = canvas.clipRect(skclip);
    SkASSERT(ret);

    matrix.set(SkMatrix::kMTransX, SkFloatToFixed(-1153.28));
    matrix.set(SkMatrix::kMTransY, SkFloatToFixed(1180.50));

    matrix.set(SkMatrix::kMScaleX, SkFloatToFixed(0.177171));
    matrix.set(SkMatrix::kMScaleY, SkFloatToFixed(0.177043));

    matrix.set(SkMatrix::kMSkewX, SkFloatToFixed(0.126968));
    matrix.set(SkMatrix::kMSkewY, SkFloatToFixed(-0.126876));

    matrix.set(SkMatrix::kMPersp0, SkFloatToFixed(0.0));
    matrix.set(SkMatrix::kMPersp1, SkFloatToFixed(0.0));

    ret = canvas.concat(matrix);

    paint.setAntiAlias(true);
    paint.setColor(0xb2202020);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(SkFloatToFixed(68.13));

    SkRect r;
    r.set(SkFloatToFixed(-313.714417), SkFloatToFixed(-4.826389), SkFloatToFixed(18014.447266), SkFloatToFixed(1858.154541));
    canvas.drawRoundRect(r, SkFloatToFixed(91.756363), SkFloatToFixed(91.756363), paint);
#endif
}
Пример #16
0
void GpuGMTask::draw(GrContextFactory* grFactory) {
    SkImageInfo info = SkImageInfo::Make(SkScalarCeilToInt(fGM->width()),
                                         SkScalarCeilToInt(fGM->height()),
                                         kPMColor_SkColorType,
                                         kPremul_SkAlphaType);
    SkAutoTUnref<SkSurface> surface(NewGpuSurface(grFactory, fContextType, info, fSampleCount));
    SkCanvas* canvas = surface->getCanvas();

    canvas->concat(fGM->getInitialTransform());
    fGM->draw(canvas);
    canvas->flush();

    SkBitmap bitmap;
    bitmap.setConfig(info);
    canvas->readPixels(&bitmap, 0, 0);

    this->spawnChild(SkNEW_ARGS(ExpectationsTask, (*this, fExpectations, bitmap)));
    this->spawnChild(SkNEW_ARGS(WriteTask, (*this, bitmap)));
}
Пример #17
0
    void copyMinToMax() {
        erase(fMaxSurface);
        SkCanvas* canvas = fMaxSurface->getCanvas();
        canvas->save();
        canvas->concat(fMatrix);
        fMinSurface->draw(canvas, 0, 0, NULL);
        canvas->restore();

        SkPaint paint;
        paint.setXfermodeMode(SkXfermode::kClear_Mode);
        for (int iy = 1; iy < fH; ++iy) {
            SkScalar y = SkIntToScalar(iy * fZoom);
            canvas->drawLine(0, y - SK_ScalarHalf, 999, y - SK_ScalarHalf, paint);
        }
        for (int ix = 1; ix < fW; ++ix) {
            SkScalar x = SkIntToScalar(ix * fZoom);
            canvas->drawLine(x - SK_ScalarHalf, 0, x - SK_ScalarHalf, 999, paint);
        }
    }
Пример #18
0
void PipeTask::draw() {
    SkBitmap bitmap;
    SetupBitmap(fReference.config(), fGM.get(), &bitmap);

    SkCanvas canvas(bitmap);
    PipeController pipeController(&canvas, &SkImageDecoder::DecodeMemory);
    SkGPipeWriter writer;

    SkCanvas* pipeCanvas = writer.startRecording(&pipeController,
                                                 fFlags,
                                                 bitmap.width(),
                                                 bitmap.height());
    pipeCanvas->concat(fGM->getInitialTransform());
    fGM->draw(pipeCanvas);
    writer.endRecording();

    if (!BitmapsEqual(bitmap, fReference)) {
        this->fail();
        this->spawnChild(SkNEW_ARGS(WriteTask, (*this, bitmap)));
    }
}
Пример #19
0
PassRefPtr<SkImage> DragImage::resizeAndOrientImage(PassRefPtr<SkImage> image, ImageOrientation orientation,
    FloatSize imageScale, float opacity, InterpolationQuality interpolationQuality)
{
    IntSize size(image->width(), image->height());
    size.scale(imageScale.width(), imageScale.height());
    AffineTransform transform;
    if (orientation != DefaultImageOrientation) {
        if (orientation.usesWidthAsHeight())
            size = size.transposedSize();
        transform *= orientation.transformFromDefault(size);
    }
    transform.scaleNonUniform(imageScale.width(), imageScale.height());

    if (size.isEmpty())
        return nullptr;

    if (transform.isIdentity() && opacity == 1) {
        // Nothing to adjust, just use the original.
        ASSERT(image->width() == size.width());
        ASSERT(image->height() == size.height());
        return image;
    }

    RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterN32Premul(size.width(), size.height()));
    if (!surface)
        return nullptr;

    SkPaint paint;
    ASSERT(opacity >= 0 && opacity <= 1);
    paint.setAlpha(opacity * 255);
    paint.setFilterQuality(interpolationQuality == InterpolationNone
        ? kNone_SkFilterQuality : kHigh_SkFilterQuality);

    SkCanvas* canvas = surface->getCanvas();
    canvas->clear(SK_ColorTRANSPARENT);
    canvas->concat(affineTransformToSkMatrix(transform));
    canvas->drawImage(image.get(), 0, 0, &paint);

    return adoptRef(surface->newImageSnapshot());
}
Пример #20
0
bool SkWindow::update(SkIRect* updateArea) {
    if (!fDirtyRgn.isEmpty()) {
        SkAutoTUnref<SkSurface> surface(this->createSurface());
        SkCanvas* canvas = surface->getCanvas();

        canvas->clipRegion(fDirtyRgn);
        if (updateArea) {
            *updateArea = fDirtyRgn.getBounds();
        }

        SkAutoCanvasRestore acr(canvas, true);
        canvas->concat(fMatrix);

        // empty this now, so we can correctly record any inval calls that
        // might be made during the draw call.
        fDirtyRgn.setEmpty();

#ifdef SK_SIMULATE_FAILED_MALLOC
        gEnableControlledThrow = true;
#endif
#ifdef SK_BUILD_FOR_WIN32
        //try {
            this->draw(canvas);
        //}
        //catch (...) {
        //}
#else
        this->draw(canvas);
#endif
#ifdef SK_SIMULATE_FAILED_MALLOC
        gEnableControlledThrow = false;
#endif

        return true;
    }
    return false;
}
Пример #21
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);
        }
    }
Пример #22
0
// "Interesting" fuzzer values.
static void test_linear_fuzzer(skiatest::Reporter*) {
    static const SkColor gColors0[] = { 0x30303030, 0x30303030 };
    static const SkColor gColors1[] = { 0x30303030, 0x30303030, 0x30303030 };

    static const SkScalar gPos1[]   = { 0, 0, 1 };

    static const SkScalar gMatrix0[9] = {
        6.40969056e-10f, 0              , 6.40969056e-10f,
        0              , 4.42539023e-39f, 6.40969056e-10f,
        0              , 0              , 1
    };
    static const SkScalar gMatrix1[9] = {
        -2.75294113f    , 6.40969056e-10f,  6.40969056e-10f,
         6.40969056e-10f, 6.40969056e-10f, -3.32810161e+24f,
         6.40969056e-10f, 6.40969056e-10f,  0
    };
    static const SkScalar gMatrix2[9] = {
        7.93481258e+17f, 6.40969056e-10f, 6.40969056e-10f,
        6.40969056e-10f, 6.40969056e-10f, 6.40969056e-10f,
        6.40969056e-10f, 6.40969056e-10f, 0.688235283f
    };
    static const SkScalar gMatrix3[9] = {
        1.89180674e+11f,     6.40969056e-10f, 6.40969056e-10f,
        6.40969056e-10f,     6.40969056e-10f, 6.40969056e-10f,
        6.40969056e-10f, 11276.0469f        , 8.12524808e+20f
    };

    static const struct {
        SkPoint            fPts[2];
        const SkColor*     fColors;
        const SkScalar*    fPos;
        int                fCount;
        SkTileMode         fTileMode;
        uint32_t           fFlags;
        const SkScalar*    fLocalMatrix;
        const SkScalar*    fGlobalMatrix;
    } gConfigs[] = {
        {
            {{0, -2.752941f}, {0, 0}},
            gColors0,
            nullptr,
            SK_ARRAY_COUNT(gColors0),
            SkTileMode::kClamp,
            0,
            gMatrix0,
            nullptr
        },
        {
            {{4.42539023e-39f, -4.42539023e-39f}, {9.78041162e-15f, 4.42539023e-39f}},
            gColors1,
            gPos1,
            SK_ARRAY_COUNT(gColors1),
            SkTileMode::kClamp,
            0,
            nullptr,
            gMatrix1
        },
        {
            {{4.42539023e-39f, 6.40969056e-10f}, {6.40969056e-10f, 1.49237238e-19f}},
            gColors1,
            gPos1,
            SK_ARRAY_COUNT(gColors1),
            SkTileMode::kClamp,
            0,
            nullptr,
            gMatrix2
        },
        {
            {{6.40969056e-10f, 6.40969056e-10f}, {6.40969056e-10f, -0.688235283f}},
            gColors0,
            nullptr,
            SK_ARRAY_COUNT(gColors0),
            SkTileMode::kClamp,
            0,
            gMatrix3,
            nullptr
        },
    };

    sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
    SkColorSpace* colorSpaces[] = {
        nullptr,     // hits the legacy gradient impl
        srgb.get(),  // triggers 4f/raster-pipeline
    };

    SkPaint paint;

    for (auto colorSpace : colorSpaces) {

        sk_sp<SkSurface> surface = SkSurface::MakeRaster(SkImageInfo::Make(100, 100,
                                                                           kN32_SkColorType,
                                                                           kPremul_SkAlphaType,
                                                                           sk_ref_sp(colorSpace)));
        SkCanvas* canvas = surface->getCanvas();

        for (const auto& config : gConfigs) {
            SkAutoCanvasRestore acr(canvas, false);
            SkTLazy<SkMatrix> localMatrix;
            if (config.fLocalMatrix) {
                localMatrix.init();
                localMatrix.get()->set9(config.fLocalMatrix);
            }

            paint.setShader(SkGradientShader::MakeLinear(config.fPts,
                                                         config.fColors,
                                                         config.fPos,
                                                         config.fCount,
                                                         config.fTileMode,
                                                         config.fFlags,
                                                         localMatrix.getMaybeNull()));
            if (config.fGlobalMatrix) {
                SkMatrix m;
                m.set9(config.fGlobalMatrix);
                canvas->save();
                canvas->concat(m);
            }

            canvas->drawPaint(paint);
        }
    }
}
Пример #23
0
void GrLayerHoister::DrawLayers(const SkTDArray<GrHoistedLayer>& atlased,
                                const SkTDArray<GrHoistedLayer>& nonAtlased,
                                const SkTDArray<GrHoistedLayer>& recycled,
                                GrReplacements* replacements) {
    // Render the atlased layers that require it
    if (atlased.count() > 0) {
        // All the atlased layers are rendered into the same GrTexture
        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
                                        atlased[0].fLayer->texture()->asRenderTarget(), NULL));

        SkCanvas* atlasCanvas = surface->getCanvas();

        SkPaint paint;
        paint.setColor(SK_ColorTRANSPARENT);
        paint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode))->unref();

        for (int i = 0; i < atlased.count(); ++i) {
            GrCachedLayer* layer = atlased[i].fLayer;
            const SkPicture* pict = atlased[i].fPicture;
            const SkIPoint offset = atlased[i].fOffset;

            atlasCanvas->save();

            // Add a rect clip to make sure the rendering doesn't
            // extend beyond the boundaries of the atlased sub-rect
            SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft),
                                            SkIntToScalar(layer->rect().fTop),
                                            SkIntToScalar(layer->rect().width()),
                                            SkIntToScalar(layer->rect().height()));
            atlasCanvas->clipRect(bound);

            // Since 'clear' doesn't respect the clip we need to draw a rect
            // TODO: ensure none of the atlased layers contain a clear call!
            atlasCanvas->drawRect(bound, paint);

            // info.fCTM maps the layer's top/left to the origin.
            // Since this layer is atlased, the top/left corner needs
            // to be offset to the correct location in the backing texture.
            SkMatrix initialCTM;
            initialCTM.setTranslate(SkIntToScalar(-offset.fX), 
                                    SkIntToScalar(-offset.fY));
            initialCTM.postTranslate(bound.fLeft, bound.fTop);
            
            atlasCanvas->translate(SkIntToScalar(-offset.fX), 
                                   SkIntToScalar(-offset.fY));
            atlasCanvas->translate(bound.fLeft, bound.fTop);
            atlasCanvas->concat(atlased[i].fCTM);

            SkRecordPartialDraw(*pict->fRecord.get(), atlasCanvas, bound,
                                layer->start()+1, layer->stop(), initialCTM);

            atlasCanvas->restore();
        }

        atlasCanvas->flush();
    }

    // Render the non-atlased layers that require it
    for (int i = 0; i < nonAtlased.count(); ++i) {
        GrCachedLayer* layer = nonAtlased[i].fLayer;
        const SkPicture* pict = nonAtlased[i].fPicture;
        const SkIPoint offset = nonAtlased[i].fOffset;

        // Each non-atlased layer has its own GrTexture
        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
                                        layer->texture()->asRenderTarget(), NULL));

        SkCanvas* layerCanvas = surface->getCanvas();

        // Add a rect clip to make sure the rendering doesn't
        // extend beyond the boundaries of the atlased sub-rect
        SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft),
                                        SkIntToScalar(layer->rect().fTop),
                                        SkIntToScalar(layer->rect().width()),
                                        SkIntToScalar(layer->rect().height()));

        layerCanvas->clipRect(bound); // TODO: still useful?

        layerCanvas->clear(SK_ColorTRANSPARENT);

        SkMatrix initialCTM;
        initialCTM.setTranslate(SkIntToScalar(-offset.fX), 
                                SkIntToScalar(-offset.fY));

        layerCanvas->translate(SkIntToScalar(-offset.fX), 
                               SkIntToScalar(-offset.fY));
        layerCanvas->concat(nonAtlased[i].fCTM);

        SkRecordPartialDraw(*pict->fRecord.get(), layerCanvas, bound,
                            layer->start()+1, layer->stop(), initialCTM);

        layerCanvas->flush();
    }

    convert_layers_to_replacements(atlased, replacements);
    convert_layers_to_replacements(nonAtlased, replacements);
    convert_layers_to_replacements(recycled, replacements);
}