// Reduce to a single drawBitmapRectToRect call by folding the clipRect's into
// the src and dst Rects and the saveLayer paints into the drawBitmapRectToRect's
// paint.
static void apply_7(SkDebugCanvas* canvas, int curCommand) {
    SkSaveLayerCommand* saveLayer0 =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+2);
    SkSaveLayerCommand* saveLayer1 =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+5);
    SkClipRectCommand* clip2 =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+7);
    SkDrawBitmapRectCommand* dbmr =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+8);

    SkScalar newSrcLeft = dbmr->srcRect()->fLeft + clip2->rect().fLeft - dbmr->dstRect().fLeft;
    SkScalar newSrcTop = dbmr->srcRect()->fTop + clip2->rect().fTop - dbmr->dstRect().fTop;

    SkRect newSrc = SkRect::MakeXYWH(newSrcLeft, newSrcTop,
                                     clip2->rect().width(), clip2->rect().height());

    dbmr->setSrcRect(newSrc);
    dbmr->setDstRect(clip2->rect());

    SkColor color = 0xFF000000;
    int a0, a1;

    const SkPaint* saveLayerPaint0 = saveLayer0->paint();
    if (NULL != saveLayerPaint0) {
        color = saveLayerPaint0->getColor();
        a0 = SkColorGetA(color);
    } else {
        a0 = 0xFF;
    }

    const SkPaint* saveLayerPaint1 = saveLayer1->paint();
    if (NULL != saveLayerPaint1) {
        color = saveLayerPaint1->getColor();
        a1 = SkColorGetA(color);
    } else {
        a1 = 0xFF;
    }

    int newA = SkMulDiv255Round(a0, a1);
    SkASSERT(newA <= 0xFF);

    SkPaint* dbmrPaint = dbmr->paint();

    if (NULL != dbmrPaint) {
        SkColor newColor = SkColorSetA(dbmrPaint->getColor(), newA);
        dbmrPaint->setColor(newColor);
    } else {
        SkColor newColor = SkColorSetA(color, newA);

        SkPaint newPaint;
        newPaint.setColor(newColor);
        dbmr->setPaint(newPaint);
    }

    // remove everything except the drawbitmaprect
    canvas->deleteDrawCommandAt(curCommand+13);   // restore
    canvas->deleteDrawCommandAt(curCommand+12);   // restore
    canvas->deleteDrawCommandAt(curCommand+11);   // restore
    canvas->deleteDrawCommandAt(curCommand+10);   // restore
    canvas->deleteDrawCommandAt(curCommand+9);    // restore
    canvas->deleteDrawCommandAt(curCommand+7);    // clipRect
    canvas->deleteDrawCommandAt(curCommand+6);    // save
    canvas->deleteDrawCommandAt(curCommand+5);    // saveLayer
    canvas->deleteDrawCommandAt(curCommand+4);    // clipRect
    canvas->deleteDrawCommandAt(curCommand+3);    // save
    canvas->deleteDrawCommandAt(curCommand+2);    // saveLayer
    canvas->deleteDrawCommandAt(curCommand+1);    // clipRect
    canvas->deleteDrawCommandAt(curCommand);      // save
}
Example #2
0
    virtual void onDrawContent(SkCanvas* canvas) {
        SkPath path;
        path.moveTo(SkIntToScalar(0),   SkIntToScalar(50));
        path.quadTo(SkIntToScalar(0),   SkIntToScalar(0),   SkIntToScalar(50),  SkIntToScalar(0));
        path.lineTo(SkIntToScalar(175), SkIntToScalar(0));
        path.quadTo(SkIntToScalar(200), SkIntToScalar(0),   SkIntToScalar(200), SkIntToScalar(25));
        path.lineTo(SkIntToScalar(200), SkIntToScalar(150));
        path.quadTo(SkIntToScalar(200), SkIntToScalar(200), SkIntToScalar(150), SkIntToScalar(200));
        path.lineTo(SkIntToScalar(0),   SkIntToScalar(200));
        path.close();
        path.moveTo(SkIntToScalar(50),  SkIntToScalar(50));
        path.lineTo(SkIntToScalar(150), SkIntToScalar(50));
        path.lineTo(SkIntToScalar(150), SkIntToScalar(125));
        path.quadTo(SkIntToScalar(150), SkIntToScalar(150), SkIntToScalar(125), SkIntToScalar(150));
        path.lineTo(SkIntToScalar(50),  SkIntToScalar(150));
        path.close();
        path.setFillType(SkPath::kEvenOdd_FillType);
        SkColor pathColor = SK_ColorBLACK;
        SkPaint pathPaint;
        pathPaint.setAntiAlias(true);
        pathPaint.setColor(pathColor);

        SkPath clipA;
        clipA.moveTo(SkIntToScalar(10),  SkIntToScalar(20));
        clipA.lineTo(SkIntToScalar(165), SkIntToScalar(22));
        clipA.lineTo(SkIntToScalar(70),  SkIntToScalar(105));
        clipA.lineTo(SkIntToScalar(165), SkIntToScalar(177));
        clipA.lineTo(SkIntToScalar(-5),  SkIntToScalar(180));
        clipA.close();
        SkColor colorA = SK_ColorCYAN;

        SkPath clipB;
        clipB.moveTo(SkIntToScalar(40),  SkIntToScalar(10));
        clipB.lineTo(SkIntToScalar(190), SkIntToScalar(15));
        clipB.lineTo(SkIntToScalar(195), SkIntToScalar(190));
        clipB.lineTo(SkIntToScalar(40),  SkIntToScalar(185));
        clipB.lineTo(SkIntToScalar(155), SkIntToScalar(100));
        clipB.close();
        SkColor colorB = SK_ColorRED;

        SkPaint paint;
        paint.setAntiAlias(true);

        paint.setStyle(SkPaint::kStroke_Style);
        paint.setStrokeWidth(0);

        canvas->translate(SkIntToScalar(10),SkIntToScalar(10));
        canvas->drawPath(path, pathPaint);
        paint.setColor(colorA);
        canvas->drawPath(clipA, paint);
        paint.setColor(colorB);
        canvas->drawPath(clipB, paint);

        static const struct {
            SkRegion::Op fOp;
            const char*  fName;
        } gOps[] = { //extra spaces in names for measureText
            {SkRegion::kIntersect_Op,         "Isect "},
            {SkRegion::kDifference_Op,        "Diff " },
            {SkRegion::kUnion_Op,             "Union "},
            {SkRegion::kXOR_Op,               "Xor "  },
            {SkRegion::kReverseDifference_Op, "RDiff "}
        };

        canvas->translate(0, SkIntToScalar(40));
        canvas->scale(3 * SK_Scalar1 / 4, 3 * SK_Scalar1 / 4);
        canvas->save();

        for (int invA = 0; invA < 2; ++invA) {
            for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) {
                int idx = invA * SK_ARRAY_COUNT(gOps) + op;
                if (!(idx % 3)) {
                    canvas->restore();
                    canvas->translate(0, SkIntToScalar(250));
                    canvas->save();
                }
                canvas->save();
                    // set clip
                    clipA.setFillType(invA ? SkPath::kInverseEvenOdd_FillType :
                                             SkPath::kEvenOdd_FillType);
                    canvas->clipPath(clipA);
                    canvas->clipPath(clipB, gOps[op].fOp);

                    // draw path clipped
                    canvas->drawPath(path, pathPaint);
                canvas->restore();

                // draw path in hairline
                paint.setColor(pathColor);
                canvas->drawPath(path, paint);

                // draw clips in hair line
                paint.setColor(colorA);
                canvas->drawPath(clipA, paint);
                paint.setColor(colorB);
                canvas->drawPath(clipB, paint);

                paint.setTextSize(SkIntToScalar(20));

                SkScalar txtX = SkIntToScalar(55);
                paint.setColor(colorA);
                const char* aTxt = invA ? "InverseA " : "A ";
                canvas->drawText(aTxt, strlen(aTxt), txtX, SkIntToScalar(220), paint);
                txtX += paint.measureText(aTxt, strlen(aTxt));
                paint.setColor(SK_ColorBLACK);
                canvas->drawText(gOps[op].fName, strlen(gOps[op].fName),
                                    txtX, SkIntToScalar(220), paint);
                txtX += paint.measureText(gOps[op].fName, strlen(gOps[op].fName));
                paint.setColor(colorB);
                canvas->drawText("B", 1, txtX, SkIntToScalar(220), paint);

                canvas->translate(SkIntToScalar(250),0);
            }
        }
        canvas->restore();
    }
Example #3
0
void TestShell::dump()
{
    WebScriptController::flushConsoleMessages();

    // Dump the requested representation.
    WebFrame* frame = m_webView->mainFrame();
    if (!frame)
        return;
    bool shouldDumpAsText = m_layoutTestController->shouldDumpAsText();
    bool shouldGeneratePixelResults = m_layoutTestController->shouldGeneratePixelResults();
    bool dumpedAnything = false;
    if (m_params.dumpTree) {
        dumpedAnything = true;
        m_printer->handleTextHeader();
        // Text output: the test page can request different types of output
        // which we handle here.
        if (!shouldDumpAsText) {
            // Plain text pages should be dumped as text
            string mimeType = frame->dataSource()->response().mimeType().utf8();
            if (mimeType == "text/plain") {
                shouldDumpAsText = true;
                shouldGeneratePixelResults = false;
            }
        }
        if (shouldDumpAsText) {
            bool recursive = m_layoutTestController->shouldDumpChildFramesAsText();
            string dataUtf8 = dumpFramesAsText(frame, recursive);
            if (fwrite(dataUtf8.c_str(), 1, dataUtf8.size(), stdout) != dataUtf8.size())
                FATAL("Short write to stdout, disk full?\n");
        } else {
            printf("%s", frame->renderTreeAsText().utf8().data());
            bool recursive = m_layoutTestController->shouldDumpChildFrameScrollPositions();
            dumpFrameScrollPosition(frame, recursive);
        }
        if (m_layoutTestController->shouldDumpBackForwardList())
            printf("%s", dumpAllBackForwardLists().c_str());
    }
    if (dumpedAnything && m_params.printSeparators)
        m_printer->handleTextFooter();

    if (m_params.dumpPixels && shouldGeneratePixelResults) {
        // Image output: we write the image data to the file given on the
        // command line (for the dump pixels argument), and the MD5 sum to
        // stdout.
        dumpedAnything = true;
        m_webView->layout();
        if (m_layoutTestController->testRepaint()) {
            WebSize viewSize = m_webView->size();
            int width = viewSize.width;
            int height = viewSize.height;
            if (m_layoutTestController->sweepHorizontally()) {
                for (WebRect column(0, 0, 1, height); column.x < width; column.x++)
                    m_webViewHost->paintRect(column);
            } else {
                for (WebRect line(0, 0, width, 1); line.y < height; line.y++)
                    m_webViewHost->paintRect(line);
            }
        } else
            m_webViewHost->paintInvalidatedRegion();

        // See if we need to draw the selection bounds rect. Selection bounds
        // rect is the rect enclosing the (possibly transformed) selection.
        // The rect should be drawn after everything is laid out and painted.
        if (m_layoutTestController->shouldDumpSelectionRect()) {
            // If there is a selection rect - draw a red 1px border enclosing rect
            WebRect wr = frame->selectionBoundsRect();
            if (!wr.isEmpty()) {
                // Render a red rectangle bounding selection rect
                SkPaint paint;
                paint.setColor(0xFFFF0000); // Fully opaque red
                paint.setStyle(SkPaint::kStroke_Style);
                paint.setFlags(SkPaint::kAntiAlias_Flag);
                paint.setStrokeWidth(1.0f);
                SkIRect rect; // Bounding rect
                rect.set(wr.x, wr.y, wr.x + wr.width, wr.y + wr.height);
                m_webViewHost->canvas()->drawIRect(rect, paint);
            }
        }

        dumpImage(m_webViewHost->canvas());
    }
    m_printer->handleImageFooter();
    m_printer->handleTestFooter(dumpedAnything);
    fflush(stdout);
    fflush(stderr);
}
    void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
                          const SkPoint3& zPlaneParams,
                          const SkPaint& paint, SkScalar ambientAlpha,
                          const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) {
        if (!fShowAmbient) {
            ambientAlpha = 0;
        }
        if (!fShowSpot) {
            spotAlpha = 0;
        }
        uint32_t flags = 0;
        if (fUseAlt) {
            flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
        }

        if (fTwoPassColor) {
            SkColor ambientColor = SkColorSetARGB(ambientAlpha*255, 0, 0, 0);
            SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
                                      lightPos, lightWidth,
                                      ambientColor, SK_ColorTRANSPARENT, flags);

            if (paint.getColor() != SK_ColorBLACK) {
                SkColor color = paint.getColor();

                uint8_t max = SkTMax(SkTMax(SkColorGetR(color), SkColorGetG(color)),
                                     SkColorGetB(color));
                uint8_t min = SkTMin(SkTMin(SkColorGetR(color), SkColorGetG(color)),
                                     SkColorGetB(color));
                SkScalar luminance = 0.5f*(max + min) / 255.f;
                SkScalar alpha = (.6 - .4*luminance)*luminance*luminance + 0.3f;
                spotAlpha -= (alpha - 0.3f)*.5f;
                SkColor spotColor = SkColorSetARGB(alpha*SkColorGetA(color), SkColorGetR(color),
                                                   SkColorGetG(color), SkColorGetB(color));

                SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
                                          lightPos, lightWidth,
                                          SK_ColorTRANSPARENT, spotColor, flags);
            }

            SkColor spotGreyscale = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
            SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
                                      lightPos, lightWidth,
                                      SK_ColorTRANSPARENT, spotGreyscale, flags);
        } else {
            SkColor color = paint.getColor();
            SkColor baseAmbient = SkColorSetARGB(ambientAlpha*SkColorGetA(color),
                                                 SkColorGetR(color), SkColorGetG(color),
                                                 SkColorGetB(color));
            SkColor baseSpot = SkColorSetARGB(spotAlpha*SkColorGetA(color),
                                              SkColorGetR(color), SkColorGetG(color),
                                              SkColorGetB(color));
            SkColor tonalAmbient, tonalSpot;
            SkShadowUtils::ComputeTonalColors(baseAmbient, baseSpot, &tonalAmbient, &tonalSpot);
            SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
                                      lightPos, lightWidth,
                                      tonalAmbient, tonalSpot, flags);
        }
        if (fShowObject) {
            canvas->drawPath(path, paint);
        } else {
            SkPaint strokePaint;

            strokePaint.setColor(paint.getColor());
            strokePaint.setStyle(SkPaint::kStroke_Style);

            canvas->drawPath(path, strokePaint);
        }
    }
Example #5
0
    virtual void onDraw(SkCanvas* canvas) {
        SkPath path;
        path.moveTo(SkIntToScalar(0),   SkIntToScalar(50));
        path.quadTo(SkIntToScalar(0),   SkIntToScalar(0),   SkIntToScalar(50),  SkIntToScalar(0));
        path.lineTo(SkIntToScalar(175), SkIntToScalar(0));
        path.quadTo(SkIntToScalar(200), SkIntToScalar(0),   SkIntToScalar(200), SkIntToScalar(25));
        path.lineTo(SkIntToScalar(200), SkIntToScalar(150));
        path.quadTo(SkIntToScalar(200), SkIntToScalar(200), SkIntToScalar(150), SkIntToScalar(200));
        path.lineTo(SkIntToScalar(0),   SkIntToScalar(200));
        path.close();
        path.moveTo(SkIntToScalar(50),  SkIntToScalar(50));
        path.lineTo(SkIntToScalar(150), SkIntToScalar(50));
        path.lineTo(SkIntToScalar(150), SkIntToScalar(125));
        path.quadTo(SkIntToScalar(150), SkIntToScalar(150), SkIntToScalar(125), SkIntToScalar(150));
        path.lineTo(SkIntToScalar(50),  SkIntToScalar(150));
        path.close();
        path.setFillType(SkPath::kEvenOdd_FillType);
        SkPaint pathPaint;
        pathPaint.setAntiAlias(true);
        pathPaint.setColor(gPathColor);

        SkPath clipA;
        clipA.moveTo(SkIntToScalar(10),  SkIntToScalar(20));
        clipA.lineTo(SkIntToScalar(165), SkIntToScalar(22));
        clipA.lineTo(SkIntToScalar(70),  SkIntToScalar(105));
        clipA.lineTo(SkIntToScalar(165), SkIntToScalar(177));
        clipA.lineTo(SkIntToScalar(-5),  SkIntToScalar(180));
        clipA.close();

        SkPath clipB;
        clipB.moveTo(SkIntToScalar(40),  SkIntToScalar(10));
        clipB.lineTo(SkIntToScalar(190), SkIntToScalar(15));
        clipB.lineTo(SkIntToScalar(195), SkIntToScalar(190));
        clipB.lineTo(SkIntToScalar(40),  SkIntToScalar(185));
        clipB.lineTo(SkIntToScalar(155), SkIntToScalar(100));
        clipB.close();

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

        static const struct {
            SkRegion::Op fOp;
            const char*  fName;
        } gOps[] = { //extra spaces in names for measureText
            {SkRegion::kIntersect_Op,         "Isect "},
            {SkRegion::kDifference_Op,        "Diff " },
            {SkRegion::kUnion_Op,             "Union "},
            {SkRegion::kXOR_Op,               "Xor "  },
            {SkRegion::kReverseDifference_Op, "RDiff "}
        };

        canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
        canvas->scale(3 * SK_Scalar1 / 4, 3 * SK_Scalar1 / 4);

        for (int invBits = 0; invBits < 4; ++invBits) {
            canvas->save();
            for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) {
                this->drawHairlines(canvas, path, clipA, clipB);

                bool doInvA = SkToBool(invBits & 1);
                bool doInvB = SkToBool(invBits & 2);
                canvas->save();
                // set clip
                clipA.setFillType(doInvA ? SkPath::kInverseEvenOdd_FillType :
                                  SkPath::kEvenOdd_FillType);
                clipB.setFillType(doInvB ? SkPath::kInverseEvenOdd_FillType :
                                  SkPath::kEvenOdd_FillType);
                canvas->clipPath(clipA, SkRegion::kIntersect_Op, fDoAAClip);
                canvas->clipPath(clipB, gOps[op].fOp, fDoAAClip);

                // draw path clipped
                canvas->drawPath(path, pathPaint);
                canvas->restore();


                SkScalar txtX = SkIntToScalar(45);
                paint.setColor(gClipAColor);
                const char* aTxt = doInvA ? "InvA " : "A ";
                canvas->drawText(aTxt, strlen(aTxt), txtX, SkIntToScalar(220), paint);
                txtX += paint.measureText(aTxt, strlen(aTxt));
                paint.setColor(SK_ColorBLACK);
                canvas->drawText(gOps[op].fName, strlen(gOps[op].fName),
                                 txtX, SkIntToScalar(220), paint);
                txtX += paint.measureText(gOps[op].fName, strlen(gOps[op].fName));
                paint.setColor(gClipBColor);
                const char* bTxt = doInvB ? "InvB " : "B ";
                canvas->drawText(bTxt, strlen(bTxt), txtX, SkIntToScalar(220), paint);

                canvas->translate(SkIntToScalar(250),0);
            }
            canvas->restore();
            canvas->translate(0, SkIntToScalar(250));
        }
    }
Example #6
0
bool OsmAnd::BinaryMapDataMetricsBitmapTileProvider_P::obtainData(const TileId tileId, const ZoomLevel zoom, std::shared_ptr<MapTiledData>& outTiledData, const IQueryController* const queryController)
{
    BinaryMapDataProvider_Metrics::Metric_obtainData obtainDataMetric;

    // Obtain offline map data tile
    std::shared_ptr<MapTiledData> dataTile_;
    owner->dataProvider->obtainData(tileId, zoom, dataTile_, &obtainDataMetric);
    if (!dataTile_)
    {
        outTiledData.reset();
        return true;
    }
    const auto dataTile = std::static_pointer_cast<BinaryMapDataTile>(dataTile_);

    // Prepare drawing canvas
    const std::shared_ptr<SkBitmap> bitmap(new SkBitmap());
    bitmap->setConfig(SkBitmap::kARGB_8888_Config, owner->tileSize, owner->tileSize);
    if (!bitmap->allocPixels())
    {
        LogPrintf(LogSeverityLevel::Error, "Failed to allocate buffer for ARGB8888 rasterization surface %dx%d", owner->tileSize, owner->tileSize);
        return false;
    }
    SkBitmapDevice target(*bitmap);
    SkCanvas canvas(&target);
    canvas.clear(SK_ColorDKGRAY);

    QString text;
    text += QString(QLatin1String("TILE   %1x%2@%3\n"))
        .arg(tileId.x)
        .arg(tileId.y)
        .arg(zoom);
    text += QString(QLatin1String("BLOCKS r:%1+s:%2=%3\n"))
        .arg(obtainDataMetric.loadMapObjectsMetric.mapObjectsBlocksRead)
        .arg(obtainDataMetric.loadMapObjectsMetric.mapObjectsBlocksReferenced)
        .arg(obtainDataMetric.loadMapObjectsMetric.mapObjectsBlocksProcessed);
    text += QString(QLatin1String("OBJS   u:%1+s:%2=%3\n"))
        .arg(obtainDataMetric.uniqueObjectsCount)
        .arg(obtainDataMetric.sharedObjectsCount)
        .arg(obtainDataMetric.objectsCount);
    text += QString(QLatin1String("TIME   r:%1+?=%2s\n"))
        .arg(QString::number(obtainDataMetric.elapsedTimeForRead, 'f', 2))
        .arg(QString::number(obtainDataMetric.elapsedTime, 'f', 2));
    text = text.trimmed();

    const auto fontSize = 16.0f;

    SkPaint textPaint;
    textPaint.setAntiAlias(true);
    textPaint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
    textPaint.setTextSize(fontSize);
    textPaint.setColor(SK_ColorGREEN);

    auto topOffset = fontSize;
    const auto lines = text.split(QLatin1Char('\n'), QString::SkipEmptyParts);
    for (const auto& line : lines)
    {
        canvas.drawText(
            line.constData(), line.length()*sizeof(QChar),
            5, topOffset,
            textPaint);
        topOffset += 1.25f * fontSize;
    }

    outTiledData.reset(new BinaryMapDataMetricsTile(
        dataTile,
        bitmap,
        owner->densityFactor,
        tileId,
        zoom));

    return true;
}
    void onDraw(SkCanvas* canvas) override {
        SkRect dstRect = { 0, 0, SkIntToScalar(64), SkIntToScalar(64)};
        static const int kMaxSrcRectSize = 1 << (SkNextLog2(gBmpSize) + 2);

        static const int kPadX = 30;
        static const int kPadY = 40;
        SkPaint paint;
        paint.setAlpha(0x20);
        canvas->drawBitmapRect(fLargeBitmap, SkRect::MakeIWH(gSize, gSize), &paint);
        canvas->translate(SK_Scalar1 * kPadX / 2,
                          SK_Scalar1 * kPadY / 2);
        SkPaint blackPaint;
        SkScalar titleHeight = SK_Scalar1 * 24;
        blackPaint.setColor(SK_ColorBLACK);
        blackPaint.setTextSize(titleHeight);
        blackPaint.setAntiAlias(true);
        sk_tool_utils::set_portable_typeface(&blackPaint);
        SkString title;
        title.printf("Bitmap size: %d x %d", gBmpSize, gBmpSize);
        canvas->drawText(title.c_str(), title.size(), 0,
                         titleHeight, blackPaint);

        canvas->translate(0, SK_Scalar1 * kPadY / 2  + titleHeight);
        int rowCount = 0;
        canvas->save();
        for (int w = 1; w <= kMaxSrcRectSize; w *= 4) {
            for (int h = 1; h <= kMaxSrcRectSize; h *= 4) {

                SkIRect srcRect = SkIRect::MakeXYWH((gBmpSize - w) / 2, (gBmpSize - h) / 2, w, h);
                fProc(canvas, fImage, fLargeBitmap, srcRect, dstRect);

                SkString label;
                label.appendf("%d x %d", w, h);
                blackPaint.setAntiAlias(true);
                blackPaint.setStyle(SkPaint::kFill_Style);
                blackPaint.setTextSize(SK_Scalar1 * 10);
                SkScalar baseline = dstRect.height() +
                                    blackPaint.getTextSize() + SK_Scalar1 * 3;
                canvas->drawText(label.c_str(), label.size(),
                                    0, baseline,
                                    blackPaint);
                blackPaint.setStyle(SkPaint::kStroke_Style);
                blackPaint.setStrokeWidth(SK_Scalar1);
                blackPaint.setAntiAlias(false);
                canvas->drawRect(dstRect, blackPaint);

                canvas->translate(dstRect.width() + SK_Scalar1 * kPadX, 0);
                ++rowCount;
                if ((dstRect.width() + kPadX) * rowCount > gSize) {
                    canvas->restore();
                    canvas->translate(0, dstRect.height() + SK_Scalar1 * kPadY);
                    canvas->save();
                    rowCount = 0;
                }
            }
        }

        {
            // test the following code path:
            // SkGpuDevice::drawPath() -> SkGpuDevice::drawWithMaskFilter()
            SkIRect srcRect;
            SkPaint paint;
            SkBitmap bm;

            bm = make_chessbm(5, 5);
            paint.setFilterQuality(kLow_SkFilterQuality);

            srcRect.setXYWH(1, 1, 3, 3);
            SkMaskFilter* mf = SkBlurMaskFilter::Create(
                kNormal_SkBlurStyle,
                SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(5)),
                SkBlurMaskFilter::kHighQuality_BlurFlag |
                SkBlurMaskFilter::kIgnoreTransform_BlurFlag);
            paint.setMaskFilter(mf)->unref();
            canvas->drawBitmapRect(bm, srcRect, dstRect, &paint);
        }
    }
Example #8
0
    virtual void onDraw(SkCanvas* canvas) {
        if (!fInitialized) {
            make_bitmap();
            fInitialized = true;
        }
        canvas->clear(0xFF101010);
        SkPaint checkPaint;
        checkPaint.setColor(0xFF202020);
        for (int y = 0; y < HEIGHT; y += 16) {
          for (int x = 0; x < WIDTH; x += 16) {
            canvas->save();
            canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
            canvas->drawRect(SkRect::MakeXYWH(8, 0, 8, 8), checkPaint);
            canvas->drawRect(SkRect::MakeXYWH(0, 8, 8, 8), checkPaint);
            canvas->restore();
          }
        }
        SkPoint3 pointLocation(0, 0, SkIntToScalar(10));
        SkScalar azimuthRad = SkDegreesToRadians(SkIntToScalar(225));
        SkScalar elevationRad = SkDegreesToRadians(SkIntToScalar(5));
        SkPoint3 distantDirection(SkScalarMul(SkScalarCos(azimuthRad), SkScalarCos(elevationRad)),
                                  SkScalarMul(SkScalarSin(azimuthRad), SkScalarCos(elevationRad)),
                                  SkScalarSin(elevationRad));
        SkPoint3 spotLocation(SkIntToScalar(-10), SkIntToScalar(-10), SkIntToScalar(20));
        SkPoint3 spotTarget(SkIntToScalar(40), SkIntToScalar(40), 0);
        SkScalar spotExponent = SK_Scalar1;
        SkScalar cutoffAngle = SkIntToScalar(15);
        SkScalar kd = SkIntToScalar(2);
        SkScalar ks = SkIntToScalar(1);
        SkScalar shininess = SkIntToScalar(8);
        SkScalar surfaceScale = SkIntToScalar(1);
        SkColor white(0xFFFFFFFF);
        SkPaint paint;

        SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(20, 10, 60, 65));

        int y = 0;
        for (int i = 0; i < 2; i++) {
            const SkImageFilter::CropRect* cr = (i == 0) ? NULL : &cropRect;
            paint.setImageFilter(SkLightingImageFilter::CreatePointLitDiffuse(pointLocation, white, surfaceScale, kd, NULL, cr))->unref();
            drawClippedBitmap(canvas, paint, 0, y);

            paint.setImageFilter(SkLightingImageFilter::CreateDistantLitDiffuse(distantDirection, white, surfaceScale, kd, NULL, cr))->unref();
            drawClippedBitmap(canvas, paint, 110, y);

            paint.setImageFilter(SkLightingImageFilter::CreateSpotLitDiffuse(spotLocation, spotTarget, spotExponent, cutoffAngle, white, surfaceScale, kd, NULL, cr))->unref();
            drawClippedBitmap(canvas, paint, 220, y);

            y += 110;

            paint.setImageFilter(SkLightingImageFilter::CreatePointLitSpecular(pointLocation, white, surfaceScale, ks, shininess, NULL, cr))->unref();
            drawClippedBitmap(canvas, paint, 0, y);

            paint.setImageFilter(SkLightingImageFilter::CreateDistantLitSpecular(distantDirection, white, surfaceScale, ks, shininess, NULL, cr))->unref();
            drawClippedBitmap(canvas, paint, 110, y);

            paint.setImageFilter(SkLightingImageFilter::CreateSpotLitSpecular(spotLocation, spotTarget, spotExponent, cutoffAngle, white, surfaceScale, ks, shininess, NULL, cr))->unref();
            drawClippedBitmap(canvas, paint, 220, y);

            y += 110;
        }
    }
Example #9
0
    /* The srcType argument indicates what to draw for the source part. Skia
     * uses the implied shape of the drawing command and these modes
     * demonstrate that.
     */
    void draw_mode(SkCanvas* canvas, SkXfermode* mode, SrcType srcType,
                   SkScalar x, SkScalar y) {
        SkPaint p;
        SkMatrix m;
        bool restoreNeeded = false;
        m.setTranslate(x, y);

        canvas->drawBitmap(fSrcB, x, y, &p);
        p.setXfermode(mode);
        switch (srcType) {
            case kSmallTransparentImage_SrcType: {
                m.postScale(SK_ScalarHalf, SK_ScalarHalf, x, y);

                SkAutoCanvasRestore acr(canvas, true);
                canvas->concat(m);
                canvas->drawBitmap(fTransparent, 0, 0, &p);
                break;
            }
            case kQuarterClearInLayer_SrcType: {
                SkRect bounds = SkRect::MakeXYWH(x, y, SkIntToScalar(W),
                                                 SkIntToScalar(H));
                canvas->saveLayer(&bounds, &p);
                restoreNeeded = true;
                p.setXfermodeMode(SkXfermode::kSrcOver_Mode);
                // Fall through.
            }
            case kQuarterClear_SrcType: {
                SkScalar halfW = SkIntToScalar(W) / 2;
                SkScalar halfH = SkIntToScalar(H) / 2;
                p.setColor(sk_tool_utils::color_to_565(0xFF66AAFF));
                SkRect r = SkRect::MakeXYWH(x + halfW, y, halfW,
                                            SkIntToScalar(H));
                canvas->drawRect(r, p);
                p.setColor(sk_tool_utils::color_to_565(0xFFAA66FF));
                r = SkRect::MakeXYWH(x, y + halfH, SkIntToScalar(W), halfH);
                canvas->drawRect(r, p);
                break;
            }
            case kRectangleWithMask_SrcType: {
                canvas->save();
                restoreNeeded = true;
                SkScalar w = SkIntToScalar(W);
                SkScalar h = SkIntToScalar(H);
                SkRect r = SkRect::MakeXYWH(x, y + h / 4, w, h * 23 / 60);
                canvas->clipRect(r);
                // Fall through.
            }
            case kRectangle_SrcType: {
                SkScalar w = SkIntToScalar(W);
                SkScalar h = SkIntToScalar(H);
                SkRect r = SkRect::MakeXYWH(x + w / 3, y + h / 3,
                                            w * 37 / 60, h * 37 / 60);
                p.setColor(sk_tool_utils::color_to_565(0xFF66AAFF));
                canvas->drawRect(r, p);
                break;
            }
            case kSmallRectangleImageWithAlpha_SrcType:
                m.postScale(SK_ScalarHalf, SK_ScalarHalf, x, y);
                // Fall through.
            case kRectangleImageWithAlpha_SrcType:
                p.setAlpha(0x88);
                // Fall through.
            case kRectangleImage_SrcType: {
                SkAutoCanvasRestore acr(canvas, true);
                canvas->concat(m);
                canvas->drawBitmap(fDstB, 0, 0, &p);
                break;
            }
            default:
                break;
        }

        if (restoreNeeded) {
            canvas->restore();
        }
    }
Example #10
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(make_number(), SkBlurMaskFilter::kNormal_BlurStyle)));
                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;



            }
        }

    }
    virtual void onDraw(SkCanvas* canvas) {
        struct FillAndName {
            SkPath::FillType fFill;
            const char*      fName;
        };
        static const FillAndName gFills[] = {
            {SkPath::kWinding_FillType, "Winding"},
            {SkPath::kEvenOdd_FillType, "Even / Odd"},
            {SkPath::kInverseWinding_FillType, "Inverse Winding"},
            {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
        };
        struct StyleAndName {
            SkPaint::Style fStyle;
            const char*    fName;
        };
        static const StyleAndName gStyles[] = {
            {SkPaint::kFill_Style, "Fill"},
            {SkPaint::kStroke_Style, "Stroke"},
            {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
        };

        SkPaint titlePaint;
        titlePaint.setColor(SK_ColorBLACK);
        titlePaint.setAntiAlias(true);
        titlePaint.setLCDRenderText(true);
        titlePaint.setTextSize(15 * SK_Scalar1);
        const char title[] = "Empty Paths Drawn Into Rectangle Clips With "
                             "Indicated Style and Fill";
        canvas->drawText(title, strlen(title),
                            20 * SK_Scalar1,
                            20 * SK_Scalar1,
                            titlePaint);

        SkRandom rand;
        SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
        int i = 0;
        canvas->save();
        canvas->translate(10 * SK_Scalar1, 0);
        canvas->save();
        for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
            for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
                if (0 == i % 4) {
                    canvas->restore();
                    canvas->translate(0, rect.height() + 40 * SK_Scalar1);
                    canvas->save();
                } else {
                    canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
                }
                ++i;


                SkColor color = rand.nextU();
                color = 0xff000000| color; // force solid
                this->drawEmpty(canvas, color, rect,
                                gStyles[style].fStyle, gFills[fill].fFill);

                SkPaint rectPaint;
                rectPaint.setColor(SK_ColorBLACK);
                rectPaint.setStyle(SkPaint::kStroke_Style);
                rectPaint.setStrokeWidth(-1);
                rectPaint.setAntiAlias(true);
                canvas->drawRect(rect, rectPaint);

                SkPaint labelPaint;
                labelPaint.setColor(color);
                labelPaint.setAntiAlias(true);
                labelPaint.setLCDRenderText(true);
                labelPaint.setTextSize(12 * SK_Scalar1);
                canvas->drawText(gStyles[style].fName,
                                 strlen(gStyles[style].fName),
                                 0, rect.height() + 15 * SK_Scalar1,
                                 labelPaint);
                canvas->drawText(gFills[fill].fName,
                                 strlen(gFills[fill].fName),
                                 0, rect.height() + 28 * SK_Scalar1,
                                 labelPaint);
            }
        }
        canvas->restore();
        canvas->restore();
    }
void OsmAnd::RasterizerEnvironment_P::initializeOneWayPaint( SkPaint& paint )
{
    paint.setAntiAlias(true);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setColor(0xff6c70d5);
}
bool OsmAnd::BinaryMapPrimitivesMetricsBitmapTileProvider_P::obtainData(const TileId tileId, const ZoomLevel zoom, std::shared_ptr<MapTiledData>& outTiledData, const IQueryController* const queryController)
{
    BinaryMapPrimitivesProvider_Metrics::Metric_obtainData obtainDataMetric;

    // Obtain offline map primitives tile
    std::shared_ptr<MapTiledData> primitivesTile_;
    owner->primitivesProvider->obtainData(tileId, zoom, primitivesTile_, &obtainDataMetric, nullptr);
    if (!primitivesTile_)
    {
        outTiledData.reset();
        return true;
    }
    const auto primitivesTile = std::static_pointer_cast<BinaryMapPrimitivesTile>(primitivesTile_);

    // Prepare drawing canvas
    const std::shared_ptr<SkBitmap> bitmap(new SkBitmap());
    bitmap->setConfig(SkBitmap::kARGB_8888_Config, owner->tileSize, owner->tileSize);
    if (!bitmap->allocPixels())
    {
        LogPrintf(LogSeverityLevel::Error, "Failed to allocate buffer for ARGB8888 rasterization surface %dx%d", owner->tileSize, owner->tileSize);
        return false;
    }
    SkBitmapDevice target(*bitmap);
    SkCanvas canvas(&target);
    canvas.clear(SK_ColorDKGRAY);

    QString text;
    text += QString(QLatin1String("TILE   %1x%2@%3\n"))
        .arg(tileId.x)
        .arg(tileId.y)
        .arg(zoom);
    text += QString(QLatin1String("order  %1/-%2 %3s\n"))
        .arg(obtainDataMetric.primitiviseMetric.orderEvaluations)
        .arg(obtainDataMetric.primitiviseMetric.orderRejects)
        .arg(QString::number(obtainDataMetric.primitiviseMetric.elapsedTimeForOrderEvaluation, 'f', 2));
    text += QString(QLatin1String("polyg  %1/-%2(-%3) %4s\n"))
        .arg(obtainDataMetric.primitiviseMetric.polygonEvaluations)
        .arg(obtainDataMetric.primitiviseMetric.polygonRejects)
        .arg(obtainDataMetric.primitiviseMetric.polygonsRejectedByArea)
        .arg(QString::number(obtainDataMetric.primitiviseMetric.elapsedTimeForPolygonEvaluation, 'f', 2));
    text += QString(QLatin1String("polyl  %1/-%2 %3s\n"))
        .arg(obtainDataMetric.primitiviseMetric.polylineEvaluations)
        .arg(obtainDataMetric.primitiviseMetric.polylineRejects)
        .arg(QString::number(obtainDataMetric.primitiviseMetric.elapsedTimeForPolylineEvaluation, 'f', 2));
    text += QString(QLatin1String("point  %1/-%2 %3s\n"))
        .arg(obtainDataMetric.primitiviseMetric.pointEvaluations)
        .arg(obtainDataMetric.primitiviseMetric.pointRejects)
        .arg(QString::number(obtainDataMetric.primitiviseMetric.elapsedTimeForPointEvaluation, 'f', 2));
    text += QString(QLatin1String("groups %1s\n"))
        .arg(QString::number(obtainDataMetric.primitiviseMetric.elapsedTimeForObtainingPrimitivesGroups, 'f', 2));
    text += QString(QLatin1String("d/b/c  %1s/%2s/%3s\n"))
        .arg(QString::number(obtainDataMetric.primitiviseMetric.elapsedTimeForObtainingPrimitivesFromDetailedmap, 'f', 2))
        .arg(QString::number(obtainDataMetric.primitiviseMetric.elapsedTimeForObtainingPrimitivesFromBasemap, 'f', 2))
        .arg(QString::number(obtainDataMetric.primitiviseMetric.elapsedTimeForObtainingPrimitivesFromCoastlines, 'f', 2));
    text += QString(QLatin1String("sym    %1s\n"))
        .arg(QString::number(obtainDataMetric.primitiviseMetric.elapsedTimeForObtainingPrimitivesSymbols, 'f', 2));
    text += QString(QLatin1String("TIME   r%1+p%2+?=%3s\n"))
        .arg(QString::number(obtainDataMetric.obtainBinaryMapDataMetric.elapsedTime, 'f', 2))
        .arg(QString::number(obtainDataMetric.primitiviseMetric.elapsedTime, 'f', 2))
        .arg(QString::number(obtainDataMetric.elapsedTime, 'f', 2));
    text = text.trimmed();

    const auto fontSize = 16.0f;

    SkPaint textPaint;
    textPaint.setAntiAlias(true);
    textPaint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
    textPaint.setTextSize(fontSize);
    textPaint.setColor(SK_ColorGREEN);

    auto topOffset = fontSize;
    const auto lines = text.split(QLatin1Char('\n'), QString::SkipEmptyParts);
    for (const auto& line : lines)
    {
        canvas.drawText(
            line.constData(), line.length()*sizeof(QChar),
            5, topOffset,
            textPaint);
        topOffset += 1.25f * fontSize;
    }

    outTiledData.reset(new BinaryMapPrimitivesMetricsTile(
        primitivesTile,
        bitmap,
        owner->densityFactor,
        tileId,
        zoom));

    return true;
}
Example #14
0
void WebTestThemeEngineMock::paint(
    blink::WebCanvas* canvas,
    WebThemeEngine::Part part,
    WebThemeEngine::State state,
    const blink::WebRect& rect,
    const WebThemeEngine::ExtraParams* extraParams)
{
    SkIRect irect = webRectToSkIRect(rect);
    SkPaint paint;

    // Indent amounts for the check in a checkbox or radio button.
    const int checkIndent = 3;

    // Indent amounts for short and long sides of the scrollbar notches.
    const int notchLongOffset = 1;
    const int notchShortOffset = 4;
    const int noOffset = 0;

    // Indent amounts for the short and long sides of a scroll thumb box.
    const int thumbLongIndent = 0;
    const int thumbShortIndent = 2;

    // Indents for the crosshatch on a scroll grip.
    const int gripLongIndent = 3;
    const int gripShortIndent = 5;

    // Indents for the the slider track.
    const int sliderIndent = 2;

    int halfHeight = irect.height() / 2;
    int halfWidth = irect.width() / 2;
    int quarterHeight = irect.height() / 4;
    int quarterWidth = irect.width() / 4;
    int left = irect.fLeft;
    int right = irect.fRight;
    int top = irect.fTop;
    int bottom = irect.fBottom;

    switch (part) {
    case WebThemeEngine::PartScrollbarDownArrow:
        box(canvas, irect, bgColors[state]);
        triangle(canvas,
            left  + quarterWidth, top    + quarterHeight,
            right - quarterWidth, top    + quarterHeight,
            left  + halfWidth,    bottom - quarterHeight,
            edgeColor);
        markState(canvas, irect, state);
        break;

    case WebThemeEngine::PartScrollbarLeftArrow:
        box(canvas, irect, bgColors[state]);
        triangle(canvas,
            right - quarterWidth, top    + quarterHeight,
            right - quarterWidth, bottom - quarterHeight,
            left  + quarterWidth, top    + halfHeight,
            edgeColor);
        break;

    case WebThemeEngine::PartScrollbarRightArrow:
        box(canvas, irect, bgColors[state]);
        triangle(canvas,
            left  + quarterWidth, top    + quarterHeight,
            right - quarterWidth, top    + halfHeight,
            left  + quarterWidth, bottom - quarterHeight,
            edgeColor);
        break;

    case WebThemeEngine::PartScrollbarUpArrow:
        box(canvas, irect, bgColors[state]);
        triangle(canvas,
            left  + quarterWidth, bottom - quarterHeight,
            left  + halfWidth,    top    + quarterHeight,
            right - quarterWidth, bottom - quarterHeight,
            edgeColor);
        markState(canvas, irect, state);
        break;

    case WebThemeEngine::PartScrollbarHorizontalThumb: {
        // Draw a narrower box on top of the outside box.
        nestedBoxes(canvas, irect, thumbLongIndent, thumbShortIndent,
            thumbLongIndent, thumbShortIndent,
            bgColors[state], bgColors[state]);
        // Draw a horizontal crosshatch for the grip.
        int longOffset = halfWidth - gripLongIndent;
        line(canvas,
            left  + gripLongIndent, top    + halfHeight,
            right - gripLongIndent, top    + halfHeight,
            edgeColor);
        line(canvas,
            left  + longOffset,     top    + gripShortIndent,
            left  + longOffset,     bottom - gripShortIndent,
            edgeColor);
        line(canvas,
            right - longOffset,     top    + gripShortIndent,
            right - longOffset,     bottom - gripShortIndent,
            edgeColor);
        markState(canvas, irect, state);
        break;
    }

    case WebThemeEngine::PartScrollbarVerticalThumb: {
        // Draw a shorter box on top of the outside box.
        nestedBoxes(canvas, irect, thumbShortIndent, thumbLongIndent,
            thumbShortIndent, thumbLongIndent,
            bgColors[state], bgColors[state]);
        // Draw a vertical crosshatch for the grip.
        int longOffset = halfHeight - gripLongIndent;
        line(canvas,
            left  + halfWidth,       top    + gripLongIndent,
            left  + halfWidth,       bottom - gripLongIndent,
            edgeColor);
        line(canvas,
            left  + gripShortIndent, top    + longOffset,
            right - gripShortIndent, top    + longOffset,
            edgeColor);
        line(canvas,
            left  + gripShortIndent, bottom - longOffset,
            right - gripShortIndent, bottom - longOffset,
            edgeColor);
        markState(canvas, irect, state);
        break;
    }

    case WebThemeEngine::PartScrollbarHorizontalTrack: {
        int longOffset = halfHeight - notchLongOffset;
        int shortOffset = irect.width() - notchShortOffset;
        if (extraParams->scrollbarTrack.isBack) {
            // back, notch on left
            nestedBoxes(canvas, irect, noOffset, longOffset, shortOffset,
                longOffset, bgColors[state], edgeColor);
        } else {
            // forward, notch on right
            nestedBoxes(canvas, irect, shortOffset, longOffset, noOffset,
                longOffset, bgColors[state], edgeColor);
        }

        markState(canvas, irect, state);
        break;
    }

    case WebThemeEngine::PartScrollbarVerticalTrack: {
        int longOffset = halfWidth - notchLongOffset;
        int shortOffset = irect.height() - notchShortOffset;
        if (extraParams->scrollbarTrack.isBack) {
            // back, notch at top
            nestedBoxes(canvas, irect, longOffset, noOffset, longOffset,
                shortOffset, bgColors[state], edgeColor);
        } else {
            // forward, notch at bottom
            nestedBoxes(canvas, irect, longOffset, shortOffset, longOffset,
                noOffset, bgColors[state], edgeColor);
        }

        markState(canvas, irect, state);
        break;
    }

    case WebThemeEngine::PartCheckbox:
        if (extraParams->button.indeterminate) {
            nestedBoxes(canvas, irect,
                checkIndent, halfHeight,
                checkIndent, halfHeight,
                bgColors[state], edgeColor);
        } else if (extraParams->button.checked) {
            irect = validate(irect, part);
            nestedBoxes(canvas, irect,
                checkIndent, checkIndent,
                checkIndent, checkIndent,
                bgColors[state], edgeColor);
        } else {
            irect = validate(irect, part);
            box(canvas, irect, bgColors[state]);
        }
        break;

    case WebThemeEngine::PartRadio:
        irect = validate(irect, part);
        halfHeight = irect.height() / 2;
        if (extraParams->button.checked) {
            circle(canvas, irect, SkIntToScalar(halfHeight), bgColors[state]);
            circle(canvas, irect, SkIntToScalar(halfHeight - checkIndent), edgeColor);
        } else {
            circle(canvas, irect, SkIntToScalar(halfHeight), bgColors[state]);
        }
        break;

    case WebThemeEngine::PartButton:
        roundRect(canvas, irect, bgColors[state]);
        markState(canvas, irect, state);
        break;

    case WebThemeEngine::PartTextField:
        paint.setColor(extraParams->textField.backgroundColor);
        paint.setStyle(SkPaint::kFill_Style);
        canvas->drawIRect(irect, paint);

        paint.setColor(edgeColor);
        paint.setStyle(SkPaint::kStroke_Style);
        canvas->drawIRect(irect, paint);

        markState(canvas, irect, state);
        break;

    case WebThemeEngine::PartMenuList:
        if (extraParams->menuList.fillContentArea) {
            box(canvas, irect, extraParams->menuList.backgroundColor);
        } else {
            SkPaint paint;
            paint.setColor(edgeColor);
            paint.setStyle(SkPaint::kStroke_Style);
            canvas->drawIRect(irect, paint);
        }

        // clip the drop-down arrow to be inside the select box
        if (extraParams->menuList.arrowX - 4 > irect.fLeft)
            irect.fLeft = extraParams->menuList.arrowX - 4;
        if (extraParams->menuList.arrowX + 12 < irect.fRight)
            irect.fRight = extraParams->menuList.arrowX + 12;

        irect.fTop = extraParams->menuList.arrowY - (extraParams->menuList.arrowHeight) / 2;
        irect.fBottom = extraParams->menuList.arrowY + (extraParams->menuList.arrowHeight - 1) / 2;
        halfWidth = irect.width() / 2;
        quarterWidth = irect.width() / 4;

        if (state == WebThemeEngine::StateFocused) // FIXME: draw differenty?
            state = WebThemeEngine::StateNormal;
        box(canvas, irect, bgColors[state]);
        triangle(canvas,
            irect.fLeft  + quarterWidth, irect.fTop,
            irect.fRight - quarterWidth, irect.fTop,
            irect.fLeft  + halfWidth,    irect.fBottom,
            edgeColor);

        break;

    case WebThemeEngine::PartSliderTrack: {
        SkIRect lirect =  irect;

        // Draw a narrow rect for the track plus box hatches on the ends.
        if (state == WebThemeEngine::StateFocused) // FIXME: draw differently?
            state = WebThemeEngine::StateNormal;
        if (extraParams->slider.vertical) {
            lirect.inset(halfWidth - sliderIndent, noOffset);
            box(canvas, lirect, bgColors[state]);
            line(canvas, left, top, right, top, edgeColor);
            line(canvas, left, bottom, right, bottom, edgeColor);
        } else {
            lirect.inset(noOffset, halfHeight - sliderIndent);
            box(canvas, lirect, bgColors[state]);
            line(canvas, left, top, left, bottom, edgeColor);
            line(canvas, right, top, right, bottom, edgeColor);
        }
        break;
    }

    case WebThemeEngine::PartSliderThumb:
        if (state == WebThemeEngine::StateFocused) // FIXME: draw differently?
            state = WebThemeEngine::StateNormal;
        oval(canvas, irect, bgColors[state]);
        break;

    case WebThemeEngine::PartInnerSpinButton: {
        // stack half-height up and down arrows on top of each other
        SkIRect lirect;
        int halfHeight = rect.height / 2;
        if (extraParams->innerSpin.readOnly)
            state = blink::WebThemeEngine::StateDisabled;

        lirect.set(rect.x, rect.y, rect.x + rect.width - 1, rect.y + halfHeight - 1);
        box(canvas, lirect, bgColors[state]);
        bottom = lirect.fBottom;
        quarterHeight = lirect.height() / 4;
        triangle(canvas,
            left  + quarterWidth, bottom - quarterHeight,
            right - quarterWidth, bottom - quarterHeight,
            left  + halfWidth,    top    + quarterHeight,
            edgeColor);

        lirect.set(rect.x, rect.y + halfHeight, rect.x + rect.width - 1,
            rect.y + 2 * halfHeight - 1);
        top = lirect.fTop;
        bottom = lirect.fBottom;
        quarterHeight = lirect.height() / 4;
        box(canvas, lirect, bgColors[state]);
        triangle(canvas,
            left  + quarterWidth, top    + quarterHeight,
            right - quarterWidth, top    + quarterHeight,
            left  + halfWidth,    bottom - quarterHeight,
            edgeColor);
        markState(canvas, irect, state);
        break;
    }
    case WebThemeEngine::PartProgressBar: {
        paint.setColor(bgColors[state]);
        paint.setStyle(SkPaint::kFill_Style);
        canvas->drawIRect(irect, paint);

        // Emulate clipping
        SkIRect tofill = irect;
        if (extraParams->progressBar.determinate) {
            tofill.set(extraParams->progressBar.valueRectX,
                extraParams->progressBar.valueRectY,
                extraParams->progressBar.valueRectX +
                extraParams->progressBar.valueRectWidth - 1,
                extraParams->progressBar.valueRectY +
                extraParams->progressBar.valueRectHeight);
        }

        tofill.intersect(irect, tofill);
        paint.setColor(edgeColor);
        paint.setStyle(SkPaint::kFill_Style);
        canvas->drawIRect(tofill, paint);

        markState(canvas, irect, state);
        break;
    }
    default:
        // FIXME: Should we do something here to indicate that we got an invalid part?
        // Unfortunately, we can't assert because we don't have access to WTF or base.
        break;
    }
}
Example #15
0
    virtual void onDraw(SkCanvas* canvas) {
        this->drawBG(canvas);
        
        if (true) {
            SkRect r;
			r.set(SkIntToScalar(0), SkIntToScalar(0),
				  SkIntToScalar(220), SkIntToScalar(120));
            SkPaint p;
            canvas->saveLayer(&r, &p);
            canvas->drawColor(0xFFFF0000);
            p.setAlpha(1);  // or 0
            p.setXfermodeMode(SkXfermode::kSrc_Mode);
            canvas->drawOval(r, p);
            canvas->restore();
            return;
        }
        
        if (false) {
            SkRect r;
			r.set(SkIntToScalar(0), SkIntToScalar(0),
				  SkIntToScalar(220), SkIntToScalar(120));
            SkPaint p;
            p.setAlpha(0x88);
            p.setAntiAlias(true);
            
            if (true) {
                canvas->saveLayer(&r, &p);
                p.setColor(0xFFFF0000);
                canvas->drawOval(r, p);
                canvas->restore();
            }

            p.setColor(0xFF0000FF);
            r.offset(SkIntToScalar(20), SkIntToScalar(50));
            canvas->drawOval(r, p);
        }

        if (false) {
            SkPaint p;
            p.setAlpha(0x88);
            p.setAntiAlias(true);

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

            SkRect r;
			r.set(SkIntToScalar(0), SkIntToScalar(0),
				  SkIntToScalar(220), SkIntToScalar(60));

            canvas->saveLayer(&r, &p, (SkCanvas::SaveFlags)(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag));
//            canvas->clipRect(r, SkRegion::kDifference_Op);
//            canvas->clipRect(r, SkRegion::kIntersect_Op);

			r.set(SkIntToScalar(0), SkIntToScalar(0),
				  SkIntToScalar(220), SkIntToScalar(120));
            p.setColor(SK_ColorBLUE);
            canvas->drawOval(r, p);
            canvas->restore();
            return;
        }
        
        //canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
        test_fade(canvas);
        return;

    //    canvas->setDrawFilter(new RedFilter)->unref();
        
        SkRect  r;
        SkPaint p;
        
        canvas->translate(SkIntToScalar(220), SkIntToScalar(20));
        
        p.setAntiAlias(true);
        r.set(SkIntToScalar(20), SkIntToScalar(20),
              SkIntToScalar(220), SkIntToScalar(120));
        
        p.setColor(SK_ColorBLUE);
     //   p.setMaskFilter(SkBlurMaskFilter::Create(SkIntToScalar(8), SkBlurMaskFilter::kNormal_BlurStyle))->unref();
        canvas->drawRect(r, p);
        p.setMaskFilter(NULL);

        SkRect bounds = r;
        bounds.fBottom = bounds.centerY();
        canvas->saveLayer(&bounds, NULL, SkCanvas::kARGB_NoClipLayer_SaveFlag);

        p.setColor(SK_ColorRED);
        canvas->drawOval(r, p);
        
        p.setAlpha(0x80);
        p.setXfermodeMode(SkXfermode::kDstIn_Mode);
        canvas->drawRect(bounds, p);

        canvas->restore();
    }
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);
}
Example #17
0
// test drawing with strips of fading gradient above and below
static void test_fade(SkCanvas* canvas) {
    SkAutoCanvasRestore ar(canvas, true);

    SkRect r;
    
    SkPaint p;
    p.setAlpha(0x88);

    SkAutoCanvasRestore(canvas, false);

    // create the layers

    r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100));
    canvas->clipRect(r);
    
    r.fBottom = SkIntToScalar(20);
    canvas->saveLayer(&r, NULL, (SkCanvas::SaveFlags)(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag));

    r.fTop = SkIntToScalar(80);
    r.fBottom = SkIntToScalar(100);
    canvas->saveLayer(&r, NULL, (SkCanvas::SaveFlags)(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag));
    
    // now draw the "content" 

    if (true) {
        r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100));

        canvas->saveLayerAlpha(&r, 0x80);

        SkPaint p;
        p.setColor(SK_ColorRED);
        p.setAntiAlias(true);
        canvas->drawOval(r, p);
        
        dump_layers("inside layer alpha", canvas);
        
        canvas->restore();
    } else {
        r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100));
        
        SkPaint p;
        p.setColor(SK_ColorRED);
        p.setAntiAlias(true);
        canvas->drawOval(r, p);
    }
    
//    return;

    dump_layers("outside layer alpha", canvas);

    // now apply an effect

    SkPaint paint;
    make_paint(&paint);
    r.set(0, 0, SkIntToScalar(100), SkIntToScalar(20));
//    SkDebugf("--------- draw top grad\n");
    canvas->drawRect(r, paint);

    SkMatrix m;
    SkShader* s = paint.getShader();
    m.setScale(SK_Scalar1, -SK_Scalar1);
    m.postTranslate(0, SkIntToScalar(100));
    s->setLocalMatrix(m);
    
    r.fTop = SkIntToScalar(80);
    r.fBottom = SkIntToScalar(100);
//    SkDebugf("--------- draw bot grad\n");
    canvas->drawRect(r, paint);
}
Example #18
0
static void test_savelayer_extraction(skiatest::Reporter* reporter) {
    static const int kWidth = 100;
    static const int kHeight = 100;

    // Create complex paint that the bounding box computation code can't
    // optimize away
    SkScalar blueToRedMatrix[20] = { 0 };
    blueToRedMatrix[2] = blueToRedMatrix[18] = SK_Scalar1;
    auto blueToRed(SkColorFilter::MakeMatrixFilterRowMajor255(blueToRedMatrix));
    SkAutoTUnref<SkImageFilter> filter(SkColorFilterImageFilter::Create(blueToRed.get()));

    SkPaint complexPaint;
    complexPaint.setImageFilter(filter);

    sk_sp<SkPicture> pict, child;
    SkRTreeFactory bbhFactory;

    {
        SkPictureRecorder recorder;

        SkCanvas* c = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight),
                                              &bbhFactory,
                                              SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag);

        c->saveLayer(nullptr, &complexPaint);
        c->restore();

        child = recorder.finishRecordingAsPicture();
    }

    // create a picture with the structure:
    // 1)
    //      SaveLayer
    //      Restore
    // 2)
    //      SaveLayer
    //          Translate
    //          SaveLayer w/ bound
    //          Restore
    //      Restore
    // 3)
    //      SaveLayer w/ copyable paint
    //      Restore
    // 4)
    //      SaveLayer
    //          DrawPicture (which has a SaveLayer/Restore pair)
    //      Restore
    // 5)
    //      SaveLayer
    //          DrawPicture with Matrix & Paint (with SaveLayer/Restore pair)
    //      Restore
    {
        SkPictureRecorder recorder;

        SkCanvas* c = recorder.beginRecording(SkIntToScalar(kWidth),
                                              SkIntToScalar(kHeight),
                                              &bbhFactory,
                                              SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag);
        // 1)
        c->saveLayer(nullptr, &complexPaint); // layer #0
        c->restore();

        // 2)
        c->saveLayer(nullptr, nullptr); // layer #1
            c->translate(kWidth / 2.0f, kHeight / 2.0f);
            SkRect r = SkRect::MakeXYWH(0, 0, kWidth/2, kHeight/2);
            c->saveLayer(&r, &complexPaint); // layer #2
            c->restore();
        c->restore();

        // 3)
        {
            c->saveLayer(nullptr, &complexPaint); // layer #3
            c->restore();
        }

        SkPaint layerPaint;
        layerPaint.setColor(SK_ColorRED);  // Non-alpha only to avoid SaveLayerDrawRestoreNooper
        // 4)
        {
            c->saveLayer(nullptr, &layerPaint);  // layer #4
                c->drawPicture(child);  // layer #5 inside picture
            c->restore();
        }
        // 5
        {
            SkPaint picturePaint;
            SkMatrix trans;
            trans.setTranslate(10, 10);

            c->saveLayer(nullptr, &layerPaint);  // layer #6
                c->drawPicture(child, &trans, &picturePaint); // layer #7 inside picture
            c->restore();
        }

        pict = recorder.finishRecordingAsPicture();
    }

    // Now test out the SaveLayer extraction
    if (!SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds()) {
        const SkBigPicture* bp = pict->asSkBigPicture();
        REPORTER_ASSERT(reporter, bp);

        const SkBigPicture::AccelData* data = bp->accelData();
        REPORTER_ASSERT(reporter, data);

        const SkLayerInfo *gpuData = static_cast<const SkLayerInfo*>(data);
        REPORTER_ASSERT(reporter, 8 == gpuData->numBlocks());

        const SkLayerInfo::BlockInfo& info0 = gpuData->block(0);
        // The parent/child layers appear in reverse order
        const SkLayerInfo::BlockInfo& info1 = gpuData->block(2);
        const SkLayerInfo::BlockInfo& info2 = gpuData->block(1);

        const SkLayerInfo::BlockInfo& info3 = gpuData->block(3);

        // The parent/child layers appear in reverse order
        const SkLayerInfo::BlockInfo& info4 = gpuData->block(5);
        const SkLayerInfo::BlockInfo& info5 = gpuData->block(4);

        // The parent/child layers appear in reverse order
        const SkLayerInfo::BlockInfo& info6 = gpuData->block(7);
        const SkLayerInfo::BlockInfo& info7 = gpuData->block(6);

        REPORTER_ASSERT(reporter, nullptr == info0.fPicture);
        REPORTER_ASSERT(reporter, kWidth == info0.fBounds.width() &&
                                  kHeight == info0.fBounds.height());
        REPORTER_ASSERT(reporter, info0.fLocalMat.isIdentity());
        REPORTER_ASSERT(reporter, info0.fPreMat.isIdentity());
        REPORTER_ASSERT(reporter, 0 == info0.fBounds.fLeft && 0 == info0.fBounds.fTop);
        REPORTER_ASSERT(reporter, nullptr != info0.fPaint);
        REPORTER_ASSERT(reporter, !info0.fIsNested && !info0.fHasNestedLayers);

        REPORTER_ASSERT(reporter, nullptr == info1.fPicture);
        REPORTER_ASSERT(reporter, kWidth/2.0 == info1.fBounds.width() &&
                                  kHeight/2.0 == info1.fBounds.height());
        REPORTER_ASSERT(reporter, info1.fLocalMat.isIdentity());
        REPORTER_ASSERT(reporter, info1.fPreMat.isIdentity());
        REPORTER_ASSERT(reporter, kWidth/2.0 == info1.fBounds.fLeft &&
                                  kHeight/2.0 == info1.fBounds.fTop);
        REPORTER_ASSERT(reporter, nullptr == info1.fPaint);
        REPORTER_ASSERT(reporter, !info1.fIsNested &&
                                  info1.fHasNestedLayers); // has a nested SL

        REPORTER_ASSERT(reporter, nullptr == info2.fPicture);
        REPORTER_ASSERT(reporter, kWidth / 2 == info2.fBounds.width() &&
                                  kHeight / 2 == info2.fBounds.height()); // bound reduces size
        REPORTER_ASSERT(reporter, !info2.fLocalMat.isIdentity());
        REPORTER_ASSERT(reporter, info2.fPreMat.isIdentity());
        REPORTER_ASSERT(reporter, kWidth / 2 == info2.fBounds.fLeft &&   // translated
                                  kHeight / 2 == info2.fBounds.fTop);
        REPORTER_ASSERT(reporter, nullptr != info2.fPaint);
        REPORTER_ASSERT(reporter, info2.fIsNested && !info2.fHasNestedLayers); // is nested

        REPORTER_ASSERT(reporter, nullptr == info3.fPicture);
        REPORTER_ASSERT(reporter, kWidth == info3.fBounds.width() &&
                                  kHeight == info3.fBounds.height());
        REPORTER_ASSERT(reporter, info3.fLocalMat.isIdentity());
        REPORTER_ASSERT(reporter, info3.fPreMat.isIdentity());
        REPORTER_ASSERT(reporter, 0 == info3.fBounds.fLeft && 0 == info3.fBounds.fTop);
        REPORTER_ASSERT(reporter, info3.fPaint);
        REPORTER_ASSERT(reporter, !info3.fIsNested && !info3.fHasNestedLayers);

        REPORTER_ASSERT(reporter, nullptr == info4.fPicture);
        REPORTER_ASSERT(reporter, kWidth == info4.fBounds.width() &&
                                  kHeight == info4.fBounds.height());
        REPORTER_ASSERT(reporter, 0 == info4.fBounds.fLeft && 0 == info4.fBounds.fTop);
        REPORTER_ASSERT(reporter, info4.fLocalMat.isIdentity());
        REPORTER_ASSERT(reporter, info4.fPreMat.isIdentity());
        REPORTER_ASSERT(reporter, info4.fPaint);
        REPORTER_ASSERT(reporter, !info4.fIsNested &&
                                  info4.fHasNestedLayers); // has a nested SL

        REPORTER_ASSERT(reporter, child.get() == info5.fPicture); // in a child picture
        REPORTER_ASSERT(reporter, kWidth == info5.fBounds.width() &&
                                  kHeight == info5.fBounds.height());
        REPORTER_ASSERT(reporter, 0 == info5.fBounds.fLeft && 0 == info5.fBounds.fTop);
        REPORTER_ASSERT(reporter, info5.fLocalMat.isIdentity());
        REPORTER_ASSERT(reporter, info5.fPreMat.isIdentity());
        REPORTER_ASSERT(reporter, nullptr != info5.fPaint);
        REPORTER_ASSERT(reporter, info5.fIsNested && !info5.fHasNestedLayers); // is nested

        REPORTER_ASSERT(reporter, nullptr == info6.fPicture);
        REPORTER_ASSERT(reporter, kWidth-10 == info6.fBounds.width() &&
                                  kHeight-10 == info6.fBounds.height());
        REPORTER_ASSERT(reporter, 10 == info6.fBounds.fLeft && 10 == info6.fBounds.fTop);
        REPORTER_ASSERT(reporter, info6.fLocalMat.isIdentity());
        REPORTER_ASSERT(reporter, info6.fPreMat.isIdentity());
        REPORTER_ASSERT(reporter, info6.fPaint);
        REPORTER_ASSERT(reporter, !info6.fIsNested &&
                                  info6.fHasNestedLayers); // has a nested SL

        REPORTER_ASSERT(reporter, child.get() == info7.fPicture); // in a child picture
        REPORTER_ASSERT(reporter, kWidth == info7.fBounds.width() &&
                                  kHeight == info7.fBounds.height());
        REPORTER_ASSERT(reporter, 0 == info7.fBounds.fLeft && 0 == info7.fBounds.fTop);
        REPORTER_ASSERT(reporter, info7.fLocalMat.isIdentity());
        REPORTER_ASSERT(reporter, info7.fPreMat.isIdentity());
        REPORTER_ASSERT(reporter, nullptr != info7.fPaint);
        REPORTER_ASSERT(reporter, info7.fIsNested && !info7.fHasNestedLayers); // is nested
    }
}
Example #19
0
void drawTextOverCanvas(RenderingContext* rc, SkCanvas* cv) {
	SkRect r = SkRect::MakeLTRB(0, 0, rc->getWidth(), rc->getHeight());
	r.inset(-100, -100);
	quad_tree<TextDrawInfo*> boundsIntersect(r, 4, 0.6);

	SkPaint paintIcon;
	paintIcon.setStyle(SkPaint::kStroke_Style);
	paintIcon.setStrokeWidth(1);
	paintIcon.setColor(0xff000000);
	paintIcon.setFilterBitmap(true);
	SkPaint paintText;
	paintText.setStyle(SkPaint::kFill_Style);
	paintText.setStrokeWidth(1);
	paintText.setColor(0xff000000);
	paintText.setTextAlign(SkPaint::kCenter_Align);
    if(!sTypeface)
        sTypeface = SkTypeface::CreateFromName("Droid Serif", SkTypeface::kNormal);
	paintText.setTypeface(sTypeface);
	paintText.setAntiAlias(true);
	SkPaint::FontMetrics fm;

	// 1. Sort text using text order
	std::sort(rc->textToDraw.begin(), rc->textToDraw.end(), textOrder);
	for (uint32_t i = 0; i < rc->textToDraw.size(); i++) {
		TextDrawInfo* text = rc->textToDraw.at(i);
		if (text->text.length() > 0) {
			// sest text size before finding intersection (it is used there)
			float textSize = rc->getDensityValue(text->textSize);
			paintText.setTextSize(textSize);
			paintText.setFakeBoldText(text->bold);
			paintText.setColor(text->textColor);
			// align center y
			paintText.getFontMetrics(&fm);
			text->centerY += (-fm.fAscent);

			// calculate if there is intersection
			bool intersects = findTextIntersection(cv, rc, boundsIntersect, text, &paintText, &paintIcon);
			if (!intersects) {
				if(rc->interrupted()){
						return;
				}
				if (text->drawOnPath && text->path != NULL) {
					if (text->textShadow > 0) {
						paintText.setColor(0xFFFFFFFF);
						paintText.setStyle(SkPaint::kStroke_Style);
						paintText.setStrokeWidth(2 + text->textShadow);
						rc->nativeOperations.Pause();
						cv->drawTextOnPathHV(text->text.c_str(), text->text.length(), *text->path, text->hOffset,
								text->vOffset, paintText);
						rc->nativeOperations.Start();
						// reset
						paintText.setStyle(SkPaint::kFill_Style);
						paintText.setStrokeWidth(2);
						paintText.setColor(text->textColor);
					}
					rc->nativeOperations.Pause();
					cv->drawTextOnPathHV(text->text.c_str(), text->text.length(), *text->path, text->hOffset,
							text->vOffset, paintText);
					rc->nativeOperations.Start();
				} else {
					if (text->shieldRes.length() > 0) {
						SkBitmap* ico = getCachedBitmap(rc, text->shieldRes);
						if (ico != NULL) {
							float left = text->centerX - rc->getDensityValue(ico->width() / 2) - 0.5f;
							float top = text->centerY - rc->getDensityValue(ico->height() / 2)
									- rc->getDensityValue(4.5f);
							SkRect r = SkRect::MakeXYWH(left, top, rc->getDensityValue(ico->width()),
									rc->getDensityValue(ico->height()));
							PROFILE_NATIVE_OPERATION(rc, cv->drawBitmapRect(*ico, (SkIRect*) NULL, r, &paintIcon));
						}
					}
					drawWrappedText(rc, cv, text, textSize, paintText);
				}
			}
		}
	}
}
Example #20
0
 void drawBG(SkCanvas* canvas) {
     SkPaint p;
     p.setDither(true);
     p.setColor(0xFF909090);
     canvas->drawPaint(p);
 }
Example #21
0
    virtual void onDraw(SkCanvas* canvas) {
        struct FillAndName {
            SkPath::FillType fFill;
            const char*      fName;
        };
        static const FillAndName gFills[] = {
            {SkPath::kWinding_FillType, "Winding"},
            {SkPath::kEvenOdd_FillType, "Even / Odd"},
            {SkPath::kInverseWinding_FillType, "Inverse Winding"},
            {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
        };
        struct StyleAndName {
            SkPaint::Style fStyle;
            const char*    fName;
        };
        static const StyleAndName gStyles[] = {
            {SkPaint::kFill_Style, "Fill"},
            {SkPaint::kStroke_Style, "Stroke"},
            {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
        };
        struct CapAndName {
            SkPaint::Cap  fCap;
            SkPaint::Join fJoin;
            const char*   fName;
        };
        static const CapAndName gCaps[] = {
            {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
            {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
            {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
        };
        struct PathAndName {
            SkPath      fPath;
            const char* fName;
        };
        PathAndName path;
        path.fPath.moveTo(25*SK_Scalar1, 10*SK_Scalar1);
        path.fPath.cubicTo(40*SK_Scalar1, 20*SK_Scalar1,
                           60*SK_Scalar1, 20*SK_Scalar1,
                           75*SK_Scalar1, 10*SK_Scalar1);
        path.fPath.close();
        path.fName = "moveTo-cubic-close";

        SkPaint titlePaint;
        titlePaint.setColor(SK_ColorBLACK);
        titlePaint.setAntiAlias(true);
        sk_tool_utils::set_portable_typeface(&titlePaint);
        titlePaint.setTextSize(15 * SK_Scalar1);
        const char title[] = "Cubic Closed Drawn Into Rectangle Clips With "
                             "Indicated Style, Fill and Linecaps, with stroke width 10";
        canvas->drawText(title, strlen(title),
                            20 * SK_Scalar1,
                            20 * SK_Scalar1,
                            titlePaint);

        SkRandom rand;
        SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
        canvas->save();
        canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
        canvas->save();
        for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
            if (0 < cap) {
                canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
            }
            canvas->save();
            for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
                if (0 < fill) {
                    canvas->translate(0, rect.height() + 40 * SK_Scalar1);
                }
                canvas->save();
                for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
                    if (0 < style) {
                        canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
                    }

                    SkColor color = 0xff007000;
                    this->drawPath(path.fPath, canvas, color, rect,
                                    gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
                                    gFills[fill].fFill, SK_Scalar1*10);

                    SkPaint rectPaint;
                    rectPaint.setColor(SK_ColorBLACK);
                    rectPaint.setStyle(SkPaint::kStroke_Style);
                    rectPaint.setStrokeWidth(-1);
                    rectPaint.setAntiAlias(true);
                    canvas->drawRect(rect, rectPaint);

                    SkPaint labelPaint;
                    labelPaint.setColor(color);
                    labelPaint.setAntiAlias(true);
                    sk_tool_utils::set_portable_typeface(&labelPaint);
                    labelPaint.setTextSize(10 * SK_Scalar1);
                    canvas->drawText(gStyles[style].fName,
                                        strlen(gStyles[style].fName),
                                        0, rect.height() + 12 * SK_Scalar1,
                                        labelPaint);
                    canvas->drawText(gFills[fill].fName,
                                        strlen(gFills[fill].fName),
                                        0, rect.height() + 24 * SK_Scalar1,
                                        labelPaint);
                    canvas->drawText(gCaps[cap].fName,
                                        strlen(gCaps[cap].fName),
                                        0, rect.height() + 36 * SK_Scalar1,
                                        labelPaint);
                }
                canvas->restore();
            }
            canvas->restore();
        }
        canvas->restore();
        canvas->restore();
    }
Example #22
0
static bool drawStars(SkCanvas* canvas, int step)
{
    SkPath path, out;
    const int stars = 25;
    int pts[stars];
    static bool initialize = true;
    int s;
    for (s = 0; s < stars; ++s) {
        pts[s] = 4 + (s % 7);
    }
    SkPoint locs[stars];
    SkScalar angles[stars];
    SkScalar innerRadius[stars];
    SkScalar outerRadius[stars];
    const int width = 640;
    const int height = 480;
    const int margin = 30;
    const int minRadius = 120;
    const int maxInner = 800;
    const int maxOuter = 1153;
    for (s = 0; s < stars; ++s) {
        int starW = width - margin * 2 + (SkScalar) s * (stars - s) / stars;
        locs[s].fX = (int) (step * (1.3f * (s + 1) / stars) + s * 121) % (starW * 2);
        if (locs[s].fX > starW) {
            locs[s].fX = starW * 2 - locs[s].fX;
        }
        locs[s].fX += margin;
        int starH = height - margin * 2 + (SkScalar) s * s / stars;
        locs[s].fY = (int) (step * (1.7f * (s + 1) / stars) + s * 183) % (starH * 2);
        if (locs[s].fY > starH) {
            locs[s].fY = starH * 2 - locs[s].fY;
        }
        locs[s].fY += margin;
        angles[s] = ((step + s * 47) % (360 * 4)) * 3.1415f / 180 / 4;
        innerRadius[s] = (step + s * 30) % (maxInner * 2);
        if (innerRadius[s] > maxInner) {
            innerRadius[s] = (maxInner * 2) - innerRadius[s];
        }
        innerRadius[s] = innerRadius[s] / 4 + minRadius;
        outerRadius[s] = (step + s * 70) % (maxOuter * 2);
        if (outerRadius[s] > maxOuter) {
            outerRadius[s] = (maxOuter * 2) - outerRadius[s];
        }
        outerRadius[s] = outerRadius[s] / 4 + minRadius;
        createStar(path, innerRadius[s] / 4.0f, outerRadius[s] / 4.0f,
                angles[s], pts[s], locs[s]);
    }
#define SHOW_PATH 0
#if SHOW_PATH
    showPath(path, "original:");
#endif
#define TEST_SIMPLIFY 01
#if TEST_SIMPLIFY
    simplify(path, true, out);
#if SHOW_PATH
    showPath(out, "simplified:");
#endif
#endif
    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(6);
    paint.setColor(0x1F003f7f);
    canvas->drawPath(path, paint);
    paint.setColor(0xFF305F00);
    paint.setStrokeWidth(1);
#if TEST_SIMPLIFY
    canvas->drawPath(out, paint);
#endif
    return true;
}
SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) : fState(state) {
    fState.get()->fImage.lockPixels();

    SkMatrix finalMatrix = fState.get()->fCanvasTransform;
    finalMatrix.preConcat(fState.get()->fShaderTransform);
    SkRect surfaceBBox;
    surfaceBBox.set(fState.get()->fBBox);
    transformBBox(finalMatrix, &surfaceBBox);

    SkMatrix unflip;
    unflip.setTranslate(0, SkScalarRound(surfaceBBox.height()));
    unflip.preScale(SK_Scalar1, -SK_Scalar1);
    SkISize size = SkISize::Make(SkScalarRound(surfaceBBox.width()),
                                 SkScalarRound(surfaceBBox.height()));
    SkPDFDevice pattern(size, size, unflip);
    SkCanvas canvas(&pattern);
    canvas.translate(-surfaceBBox.fLeft, -surfaceBBox.fTop);
    finalMatrix.preTranslate(surfaceBBox.fLeft, surfaceBBox.fTop);

    const SkBitmap* image = &fState.get()->fImage;
    int width = image->width();
    int height = image->height();
    SkShader::TileMode tileModes[2];
    tileModes[0] = fState.get()->fImageTileModes[0];
    tileModes[1] = fState.get()->fImageTileModes[1];

    canvas.drawBitmap(*image, 0, 0);
    SkRect patternBBox = SkRect::MakeXYWH(-surfaceBBox.fLeft, -surfaceBBox.fTop,
                                          width, height);

    // Tiling is implied.  First we handle mirroring.
    if (tileModes[0] == SkShader::kMirror_TileMode) {
        SkMatrix xMirror;
        xMirror.setScale(-1, 1);
        xMirror.postTranslate(2 * width, 0);
        canvas.drawBitmapMatrix(*image, xMirror);
        patternBBox.fRight += width;
    }
    if (tileModes[1] == SkShader::kMirror_TileMode) {
        SkMatrix yMirror;
        yMirror.setScale(SK_Scalar1, -SK_Scalar1);
        yMirror.postTranslate(0, 2 * height);
        canvas.drawBitmapMatrix(*image, yMirror);
        patternBBox.fBottom += height;
    }
    if (tileModes[0] == SkShader::kMirror_TileMode &&
            tileModes[1] == SkShader::kMirror_TileMode) {
        SkMatrix mirror;
        mirror.setScale(-1, -1);
        mirror.postTranslate(2 * width, 2 * height);
        canvas.drawBitmapMatrix(*image, mirror);
    }

    // Then handle Clamping, which requires expanding the pattern canvas to
    // cover the entire surfaceBBox.

    // If both x and y are in clamp mode, we start by filling in the corners.
    // (Which are just a rectangles of the corner colors.)
    if (tileModes[0] == SkShader::kClamp_TileMode &&
            tileModes[1] == SkShader::kClamp_TileMode) {
        SkPaint paint;
        SkRect rect;
        rect = SkRect::MakeLTRB(surfaceBBox.fLeft, surfaceBBox.fTop, 0, 0);
        if (!rect.isEmpty()) {
            paint.setColor(image->getColor(0, 0));
            canvas.drawRect(rect, paint);
        }

        rect = SkRect::MakeLTRB(width, surfaceBBox.fTop, surfaceBBox.fRight, 0);
        if (!rect.isEmpty()) {
            paint.setColor(image->getColor(width - 1, 0));
            canvas.drawRect(rect, paint);
        }

        rect = SkRect::MakeLTRB(width, height, surfaceBBox.fRight,
                                surfaceBBox.fBottom);
        if (!rect.isEmpty()) {
            paint.setColor(image->getColor(width - 1, height - 1));
            canvas.drawRect(rect, paint);
        }

        rect = SkRect::MakeLTRB(surfaceBBox.fLeft, height, 0,
                                surfaceBBox.fBottom);
        if (!rect.isEmpty()) {
            paint.setColor(image->getColor(0, height - 1));
            canvas.drawRect(rect, paint);
        }
    }

    // Then expand the left, right, top, then bottom.
    if (tileModes[0] == SkShader::kClamp_TileMode) {
        SkIRect subset = SkIRect::MakeXYWH(0, 0, 1, height);
        if (surfaceBBox.fLeft < 0) {
            SkBitmap left;
            SkAssertResult(image->extractSubset(&left, subset));

            SkMatrix leftMatrix;
            leftMatrix.setScale(-surfaceBBox.fLeft, 1);
            leftMatrix.postTranslate(surfaceBBox.fLeft, 0);
            canvas.drawBitmapMatrix(left, leftMatrix);

            if (tileModes[1] == SkShader::kMirror_TileMode) {
                leftMatrix.postScale(SK_Scalar1, -SK_Scalar1);
                leftMatrix.postTranslate(0, 2 * height);
                canvas.drawBitmapMatrix(left, leftMatrix);
            }
            patternBBox.fLeft = 0;
        }

        if (surfaceBBox.fRight > width) {
            SkBitmap right;
            subset.offset(width - 1, 0);
            SkAssertResult(image->extractSubset(&right, subset));

            SkMatrix rightMatrix;
            rightMatrix.setScale(surfaceBBox.fRight - width, 1);
            rightMatrix.postTranslate(width, 0);
            canvas.drawBitmapMatrix(right, rightMatrix);

            if (tileModes[1] == SkShader::kMirror_TileMode) {
                rightMatrix.postScale(SK_Scalar1, -SK_Scalar1);
                rightMatrix.postTranslate(0, 2 * height);
                canvas.drawBitmapMatrix(right, rightMatrix);
            }
            patternBBox.fRight = surfaceBBox.width();
        }
    }

    if (tileModes[1] == SkShader::kClamp_TileMode) {
        SkIRect subset = SkIRect::MakeXYWH(0, 0, width, 1);
        if (surfaceBBox.fTop < 0) {
            SkBitmap top;
            SkAssertResult(image->extractSubset(&top, subset));

            SkMatrix topMatrix;
            topMatrix.setScale(SK_Scalar1, -surfaceBBox.fTop);
            topMatrix.postTranslate(0, surfaceBBox.fTop);
            canvas.drawBitmapMatrix(top, topMatrix);

            if (tileModes[0] == SkShader::kMirror_TileMode) {
                topMatrix.postScale(-1, 1);
                topMatrix.postTranslate(2 * width, 0);
                canvas.drawBitmapMatrix(top, topMatrix);
            }
            patternBBox.fTop = 0;
        }

        if (surfaceBBox.fBottom > height) {
            SkBitmap bottom;
            subset.offset(0, height - 1);
            SkAssertResult(image->extractSubset(&bottom, subset));

            SkMatrix bottomMatrix;
            bottomMatrix.setScale(SK_Scalar1, surfaceBBox.fBottom - height);
            bottomMatrix.postTranslate(0, height);
            canvas.drawBitmapMatrix(bottom, bottomMatrix);

            if (tileModes[0] == SkShader::kMirror_TileMode) {
                bottomMatrix.postScale(-1, 1);
                bottomMatrix.postTranslate(2 * width, 0);
                canvas.drawBitmapMatrix(bottom, bottomMatrix);
            }
            patternBBox.fBottom = surfaceBBox.height();
        }
    }

    SkRefPtr<SkPDFArray> patternBBoxArray = new SkPDFArray;
    patternBBoxArray->unref();  // SkRefPtr and new both took a reference.
    patternBBoxArray->reserve(4);
    patternBBoxArray->appendScalar(patternBBox.fLeft);
    patternBBoxArray->appendScalar(patternBBox.fTop);
    patternBBoxArray->appendScalar(patternBBox.fRight);
    patternBBoxArray->appendScalar(patternBBox.fBottom);

    // Put the canvas into the pattern stream (fContent).
    SkRefPtr<SkStream> content = pattern.content();
    content->unref();  // SkRefPtr and content() both took a reference.
    pattern.getResources(&fResources);

    setData(content.get());
    insertName("Type", "Pattern");
    insertInt("PatternType", 1);
    insertInt("PaintType", 1);
    insertInt("TilingType", 1);
    insert("BBox", patternBBoxArray.get());
    insertScalar("XStep", patternBBox.width());
    insertScalar("YStep", patternBBox.height());
    insert("Resources", pattern.getResourceDict());
    insert("Matrix", SkPDFUtils::MatrixToArray(finalMatrix))->unref();

    fState.get()->fImage.unlockPixels();
}
Example #24
0
    virtual void onDraw(SkCanvas* canvas) {
        if (!fInitialized) {
            this->make_checkerboard();
            this->make_gradient_circle(64, 64);
            fInitialized = true;
        }
        canvas->clear(0x00000000);

        SkAutoTUnref<SkImageFilter> gradient(SkBitmapSource::Create(fGradientCircle));
        SkAutoTUnref<SkImageFilter> checkerboard(SkBitmapSource::Create(fCheckerboard));
        SkAutoTUnref<SkShader> noise(SkPerlinNoiseShader::CreateFractalNoise(
            SkDoubleToScalar(0.1), SkDoubleToScalar(0.05), 1, 0));
        SkMatrix resizeMatrix;
        resizeMatrix.setScale(RESIZE_FACTOR_X, RESIZE_FACTOR_Y);

        SkImageFilter* filters[] = {
            SkBlurImageFilter::Create(SkIntToScalar(12), SkIntToScalar(12)),
            SkDropShadowImageFilter::Create(SkIntToScalar(10), SkIntToScalar(10), SkIntToScalar(3),
                                            SK_ColorGREEN),
            SkDisplacementMapEffect::Create(SkDisplacementMapEffect::kR_ChannelSelectorType,
                                            SkDisplacementMapEffect::kR_ChannelSelectorType,
                                            SkIntToScalar(12),
                                            gradient.get(),
                                            checkerboard.get()),
            SkDilateImageFilter::Create(2, 2, checkerboard.get()),
            SkErodeImageFilter::Create(2, 2, checkerboard.get()),
            SkOffsetImageFilter::Create(SkIntToScalar(-16), SkIntToScalar(32)),
            SkMatrixImageFilter::Create(resizeMatrix, SkPaint::kNone_FilterLevel),
            SkRectShaderImageFilter::Create(noise),
        };

        SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64));
        SkScalar margin = SkIntToScalar(16);
        SkRect bounds = r;
        bounds.outset(margin, margin);

        for (int xOffset = 0; xOffset < 80; xOffset += 16) {
            canvas->save();
            bounds.fLeft = SkIntToScalar(xOffset);
            for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
                SkPaint paint;
                paint.setColor(SK_ColorWHITE);
                paint.setImageFilter(filters[i]);
                paint.setAntiAlias(true);
                canvas->save();
                canvas->clipRect(bounds);
                if (5 == i) {
                    canvas->translate(SkIntToScalar(16), SkIntToScalar(-32));
                } else if (6 == i) {
                    canvas->scale(SkScalarInvert(RESIZE_FACTOR_X),
                                  SkScalarInvert(RESIZE_FACTOR_Y));
                }
                canvas->drawCircle(r.centerX(), r.centerY(),
                                   SkScalarDiv(r.width()*2, SkIntToScalar(5)), paint);
                canvas->restore();
                canvas->translate(r.width() + margin, 0);
            }
            canvas->restore();
            canvas->translate(0, r.height() + margin);
        }

        for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
            SkSafeUnref(filters[i]);
        }
    }
Example #25
0
    void makePaints() {
        {
            // no AA
            SkPaint p;
            p.setColor(SK_ColorWHITE);
            fPaints.push_back(p);
        }

        {
            // AA
            SkPaint p;
            p.setColor(SK_ColorWHITE);
            p.setAntiAlias(true);
            fPaints.push_back(p);
        }

        {
            // AA with translucent
            SkPaint p;
            p.setColor(SK_ColorWHITE);
            p.setAntiAlias(true);
            p.setAlpha(0x66);
            fPaints.push_back(p);
        }

        {
            // AA with mask filter
            SkPaint p;
            p.setColor(SK_ColorWHITE);
            p.setAntiAlias(true);
            SkMaskFilter* mf = SkBlurMaskFilter::Create(
                                   kNormal_SkBlurStyle,
                                   SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(5)),
                                   SkBlurMaskFilter::kHighQuality_BlurFlag);
            p.setMaskFilter(mf)->unref();
            fPaints.push_back(p);
        }

        {
            // AA with radial shader
            SkPaint p;
            p.setColor(SK_ColorWHITE);
            p.setAntiAlias(true);
            SkPoint center = SkPoint::Make(SkIntToScalar(-5), SkIntToScalar(30));
            SkColor colors[] = { SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN };
            SkScalar pos[] = { 0, SK_ScalarHalf, SK_Scalar1 };
            SkShader* s = SkGradientShader::CreateRadial(center,
                                                         SkIntToScalar(20),
                                                         colors,
                                                         pos,
                                                         SK_ARRAY_COUNT(colors),
                                                         SkShader::kClamp_TileMode);
            p.setShader(s)->unref();
            fPaints.push_back(p);
        }

        {
            // AA with blur
            SkPaint p;
            p.setColor(SK_ColorWHITE);
            p.setAntiAlias(true);
            SkDrawLooper* shadowLooper =
                SkBlurDrawLooper::Create(SK_ColorWHITE,
                                         SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(10)),
                                         SkIntToScalar(5), SkIntToScalar(10),
                                         SkBlurDrawLooper::kIgnoreTransform_BlurFlag |
                                         SkBlurDrawLooper::kOverrideColor_BlurFlag |
                                         SkBlurDrawLooper::kHighQuality_BlurFlag);
            SkAutoUnref aurL0(shadowLooper);
            p.setLooper(shadowLooper);
            fPaints.push_back(p);
        }

        {
            // AA with stroke style
            SkPaint p;
            p.setColor(SK_ColorWHITE);
            p.setAntiAlias(true);
            p.setStyle(SkPaint::kStroke_Style);
            p.setStrokeWidth(SkIntToScalar(3));
            fPaints.push_back(p);
        }

        {
            // AA with bevel-stroke style
            SkPaint p;
            p.setColor(SK_ColorWHITE);
            p.setAntiAlias(true);
            p.setStyle(SkPaint::kStroke_Style);
            p.setStrokeJoin(SkPaint::kBevel_Join);
            p.setStrokeWidth(SkIntToScalar(3));
            fPaints.push_back(p);
        }

        {
            // AA with round-stroke style
            SkPaint p;
            p.setColor(SK_ColorWHITE);
            p.setAntiAlias(true);
            p.setStyle(SkPaint::kStroke_Style);
            p.setStrokeJoin(SkPaint::kRound_Join);
            p.setStrokeWidth(SkIntToScalar(3));
            fPaints.push_back(p);
        }

        {
            // AA with stroke style, width = 0
            SkPaint p;
            p.setColor(SK_ColorWHITE);
            p.setAntiAlias(true);
            p.setStyle(SkPaint::kStroke_Style);
            fPaints.push_back(p);
        }

        {
            // AA with stroke style, width wider than rect width and/or height
            SkPaint p;
            p.setColor(SK_ColorWHITE);
            p.setAntiAlias(true);
            p.setStyle(SkPaint::kStroke_Style);
            p.setStrokeWidth(SkIntToScalar(40));
            fPaints.push_back(p);
        }

        {
            // AA with stroke and fill style
            SkPaint p;
            p.setColor(SK_ColorWHITE);
            p.setAntiAlias(true);
            p.setStyle(SkPaint::kStrokeAndFill_Style);
            p.setStrokeWidth(SkIntToScalar(2));
            fPaints.push_back(p);
        }
    }
Example #26
0
SkPDFImageShader* SkPDFImageShader::Create(
        SkPDFCanon* canon,
        SkScalar dpi,
        SkAutoTDelete<SkPDFShader::State>* autoState) {
    const SkPDFShader::State& state = **autoState;

    state.fImage.lockPixels();

    // The image shader pattern cell will be drawn into a separate device
    // in pattern cell space (no scaling on the bitmap, though there may be
    // translations so that all content is in the device, coordinates > 0).

    // Map clip bounds to shader space to ensure the device is large enough
    // to handle fake clamping.
    SkMatrix finalMatrix = state.fCanvasTransform;
    finalMatrix.preConcat(state.fShaderTransform);
    SkRect deviceBounds;
    deviceBounds.set(state.fBBox);
    if (!inverse_transform_bbox(finalMatrix, &deviceBounds)) {
        return NULL;
    }

    const SkBitmap* image = &state.fImage;
    SkRect bitmapBounds;
    image->getBounds(&bitmapBounds);

    // For tiling modes, the bounds should be extended to include the bitmap,
    // otherwise the bitmap gets clipped out and the shader is empty and awful.
    // For clamp modes, we're only interested in the clip region, whether
    // or not the main bitmap is in it.
    SkShader::TileMode tileModes[2];
    tileModes[0] = state.fImageTileModes[0];
    tileModes[1] = state.fImageTileModes[1];
    if (tileModes[0] != SkShader::kClamp_TileMode ||
            tileModes[1] != SkShader::kClamp_TileMode) {
        deviceBounds.join(bitmapBounds);
    }

    SkISize size = SkISize::Make(SkScalarRoundToInt(deviceBounds.width()),
                                 SkScalarRoundToInt(deviceBounds.height()));
    SkAutoTUnref<SkPDFDevice> patternDevice(
            SkPDFDevice::CreateUnflipped(size, dpi, canon));
    SkCanvas canvas(patternDevice.get());

    SkRect patternBBox;
    image->getBounds(&patternBBox);

    // Translate the canvas so that the bitmap origin is at (0, 0).
    canvas.translate(-deviceBounds.left(), -deviceBounds.top());
    patternBBox.offset(-deviceBounds.left(), -deviceBounds.top());
    // Undo the translation in the final matrix
    finalMatrix.preTranslate(deviceBounds.left(), deviceBounds.top());

    // If the bitmap is out of bounds (i.e. clamp mode where we only see the
    // stretched sides), canvas will clip this out and the extraneous data
    // won't be saved to the PDF.
    canvas.drawBitmap(*image, 0, 0);

    SkScalar width = SkIntToScalar(image->width());
    SkScalar height = SkIntToScalar(image->height());

    // Tiling is implied.  First we handle mirroring.
    if (tileModes[0] == SkShader::kMirror_TileMode) {
        SkMatrix xMirror;
        xMirror.setScale(-1, 1);
        xMirror.postTranslate(2 * width, 0);
        drawBitmapMatrix(&canvas, *image, xMirror);
        patternBBox.fRight += width;
    }
    if (tileModes[1] == SkShader::kMirror_TileMode) {
        SkMatrix yMirror;
        yMirror.setScale(SK_Scalar1, -SK_Scalar1);
        yMirror.postTranslate(0, 2 * height);
        drawBitmapMatrix(&canvas, *image, yMirror);
        patternBBox.fBottom += height;
    }
    if (tileModes[0] == SkShader::kMirror_TileMode &&
            tileModes[1] == SkShader::kMirror_TileMode) {
        SkMatrix mirror;
        mirror.setScale(-1, -1);
        mirror.postTranslate(2 * width, 2 * height);
        drawBitmapMatrix(&canvas, *image, mirror);
    }

    // Then handle Clamping, which requires expanding the pattern canvas to
    // cover the entire surfaceBBox.

    // If both x and y are in clamp mode, we start by filling in the corners.
    // (Which are just a rectangles of the corner colors.)
    if (tileModes[0] == SkShader::kClamp_TileMode &&
            tileModes[1] == SkShader::kClamp_TileMode) {
        SkPaint paint;
        SkRect rect;
        rect = SkRect::MakeLTRB(deviceBounds.left(), deviceBounds.top(), 0, 0);
        if (!rect.isEmpty()) {
            paint.setColor(image->getColor(0, 0));
            canvas.drawRect(rect, paint);
        }

        rect = SkRect::MakeLTRB(width, deviceBounds.top(),
                                deviceBounds.right(), 0);
        if (!rect.isEmpty()) {
            paint.setColor(image->getColor(image->width() - 1, 0));
            canvas.drawRect(rect, paint);
        }

        rect = SkRect::MakeLTRB(width, height,
                                deviceBounds.right(), deviceBounds.bottom());
        if (!rect.isEmpty()) {
            paint.setColor(image->getColor(image->width() - 1,
                                           image->height() - 1));
            canvas.drawRect(rect, paint);
        }

        rect = SkRect::MakeLTRB(deviceBounds.left(), height,
                                0, deviceBounds.bottom());
        if (!rect.isEmpty()) {
            paint.setColor(image->getColor(0, image->height() - 1));
            canvas.drawRect(rect, paint);
        }
    }

    // Then expand the left, right, top, then bottom.
    if (tileModes[0] == SkShader::kClamp_TileMode) {
        SkIRect subset = SkIRect::MakeXYWH(0, 0, 1, image->height());
        if (deviceBounds.left() < 0) {
            SkBitmap left;
            SkAssertResult(image->extractSubset(&left, subset));

            SkMatrix leftMatrix;
            leftMatrix.setScale(-deviceBounds.left(), 1);
            leftMatrix.postTranslate(deviceBounds.left(), 0);
            drawBitmapMatrix(&canvas, left, leftMatrix);

            if (tileModes[1] == SkShader::kMirror_TileMode) {
                leftMatrix.postScale(SK_Scalar1, -SK_Scalar1);
                leftMatrix.postTranslate(0, 2 * height);
                drawBitmapMatrix(&canvas, left, leftMatrix);
            }
            patternBBox.fLeft = 0;
        }

        if (deviceBounds.right() > width) {
            SkBitmap right;
            subset.offset(image->width() - 1, 0);
            SkAssertResult(image->extractSubset(&right, subset));

            SkMatrix rightMatrix;
            rightMatrix.setScale(deviceBounds.right() - width, 1);
            rightMatrix.postTranslate(width, 0);
            drawBitmapMatrix(&canvas, right, rightMatrix);

            if (tileModes[1] == SkShader::kMirror_TileMode) {
                rightMatrix.postScale(SK_Scalar1, -SK_Scalar1);
                rightMatrix.postTranslate(0, 2 * height);
                drawBitmapMatrix(&canvas, right, rightMatrix);
            }
            patternBBox.fRight = deviceBounds.width();
        }
    }

    if (tileModes[1] == SkShader::kClamp_TileMode) {
        SkIRect subset = SkIRect::MakeXYWH(0, 0, image->width(), 1);
        if (deviceBounds.top() < 0) {
            SkBitmap top;
            SkAssertResult(image->extractSubset(&top, subset));

            SkMatrix topMatrix;
            topMatrix.setScale(SK_Scalar1, -deviceBounds.top());
            topMatrix.postTranslate(0, deviceBounds.top());
            drawBitmapMatrix(&canvas, top, topMatrix);

            if (tileModes[0] == SkShader::kMirror_TileMode) {
                topMatrix.postScale(-1, 1);
                topMatrix.postTranslate(2 * width, 0);
                drawBitmapMatrix(&canvas, top, topMatrix);
            }
            patternBBox.fTop = 0;
        }

        if (deviceBounds.bottom() > height) {
            SkBitmap bottom;
            subset.offset(0, image->height() - 1);
            SkAssertResult(image->extractSubset(&bottom, subset));

            SkMatrix bottomMatrix;
            bottomMatrix.setScale(SK_Scalar1, deviceBounds.bottom() - height);
            bottomMatrix.postTranslate(0, height);
            drawBitmapMatrix(&canvas, bottom, bottomMatrix);

            if (tileModes[0] == SkShader::kMirror_TileMode) {
                bottomMatrix.postScale(-1, 1);
                bottomMatrix.postTranslate(2 * width, 0);
                drawBitmapMatrix(&canvas, bottom, bottomMatrix);
            }
            patternBBox.fBottom = deviceBounds.height();
        }
    }

    // Put the canvas into the pattern stream (fContent).
    SkAutoTDelete<SkStreamAsset> content(patternDevice->content());

    SkPDFImageShader* imageShader =
            SkNEW_ARGS(SkPDFImageShader, (autoState->detach()));
    imageShader->setData(content.get());

    SkAutoTUnref<SkPDFDict> resourceDict(
            patternDevice->createResourceDict());
    populate_tiling_pattern_dict(imageShader, patternBBox,
                                 resourceDict.get(), finalMatrix);

    imageShader->fShaderState->fImage.unlockPixels();

    canon->addImageShader(imageShader);
    return imageShader;
}
Example #27
0
static void do_draw(SkCanvas* canvas, const SkRect& r) {
    SkPaint paint;
    paint.setBlendMode(SkBlendMode::kSrc);
    paint.setColor(0x800000FF);
    canvas->drawRect(r, paint);
}
Example #28
0
    void onDraw(SkCanvas* canvas) override {
        SkRandom rand(1);
        canvas->translate(20 * SK_Scalar1, 20 * SK_Scalar1);
        SkRect oval = SkRect::MakeLTRB(-20, -30, 20, 30);

        const SkScalar kXStart = 60.0f;
        const SkScalar kYStart = 80.0f;
        const int kXStep = 150;
        const int kYStep = 160;
        int maxX = fMatrices.count();

        SkPaint rectPaint;
        rectPaint.setAntiAlias(true);
        rectPaint.setStyle(SkPaint::kStroke_Style);
        rectPaint.setStrokeWidth(SkIntToScalar(0));
        rectPaint.setColor(sk_tool_utils::color_to_565(SK_ColorLTGRAY));

        int testCount = 0;
        for (int i = 0; i < fPaints.count(); ++i) {
            for (int j = 0; j < fMatrices.count(); ++j) {
                canvas->save();
                SkMatrix mat = fMatrices[j];
                // position the oval, and make it at off-integer coords.
                mat.postTranslate(kXStart + SK_Scalar1 * kXStep * (testCount % maxX) +
                                  SK_Scalar1 / 4,
                                  kYStart + SK_Scalar1 * kYStep * (testCount / maxX) +
                                  3 * SK_Scalar1 / 4);
                canvas->concat(mat);

                SkColor color = genColor(&rand);
                fPaints[i].setColor(color);

                canvas->drawRect(oval, rectPaint);
                canvas->drawOval(oval, fPaints[i]);

                canvas->restore();

                ++testCount;
            }
        }

        // special cases

        // non-scaled tall and skinny oval
        for (int i = 0; i < fPaints.count(); ++i) {
            SkRect oval = SkRect::MakeLTRB(-20, -60, 20, 60);
            canvas->save();
            // position the oval, and make it at off-integer coords.
            canvas->translate(kXStart + SK_Scalar1 * kXStep * 2.55f + SK_Scalar1 / 4,
                              kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4);

            SkColor color = genColor(&rand);
            fPaints[i].setColor(color);

            canvas->drawRect(oval, rectPaint);
            canvas->drawOval(oval, fPaints[i]);
            canvas->restore();
        }

        // non-scaled wide and short oval
        for (int i = 0; i < fPaints.count(); ++i) {
            SkRect oval = SkRect::MakeLTRB(-80, -30, 80, 30);
            canvas->save();
            // position the oval, and make it at off-integer coords.
            canvas->translate(kXStart + SK_Scalar1 * kXStep * 4 + SK_Scalar1 / 4,
                              kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
                              SK_ScalarHalf * kYStep);

            SkColor color = genColor(&rand);
            fPaints[i].setColor(color);

            canvas->drawRect(oval, rectPaint);
            canvas->drawOval(oval, fPaints[i]);
            canvas->restore();
        }

        // super skinny oval
        for (int i = 0; i < fPaints.count(); ++i) {
            SkRect oval = SkRect::MakeLTRB(0, -60, 1, 60);
            canvas->save();
            // position the oval, and make it at off-integer coords.
            canvas->translate(kXStart + SK_Scalar1 * kXStep * 3.25f + SK_Scalar1 / 4,
                              kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4);

            SkColor color = genColor(&rand);
            fPaints[i].setColor(color);

            canvas->drawOval(oval, fPaints[i]);
            canvas->restore();
        }

        // super short oval
        for (int i = 0; i < fPaints.count(); ++i) {
            SkRect oval = SkRect::MakeLTRB(-80, -1, 80, 0);
            canvas->save();
            // position the oval, and make it at off-integer coords.
            canvas->translate(kXStart + SK_Scalar1 * kXStep * 2.5f + SK_Scalar1 / 4,
                              kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
                              SK_ScalarHalf * kYStep);

            SkColor color = genColor(&rand);
            fPaints[i].setColor(color);

            canvas->drawOval(oval, fPaints[i]);
            canvas->restore();
        }

        // radial gradient
        SkPoint center = SkPoint::Make(SkIntToScalar(0), SkIntToScalar(0));
        SkColor colors[] = { SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN };
        SkScalar pos[] = { 0, SK_ScalarHalf, SK_Scalar1 };
        auto shader = SkGradientShader::MakeRadial(center, 20, colors, pos, SK_ARRAY_COUNT(colors),
                                                   SkShader::kClamp_TileMode);

        for (int i = 0; i < fPaints.count(); ++i) {
            canvas->save();
            // position the path, and make it at off-integer coords.
            canvas->translate(kXStart + SK_Scalar1 * kXStep * 0 + SK_Scalar1 / 4,
                              kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
                              SK_ScalarHalf * kYStep);

            SkColor color = genColor(&rand);
            fPaints[i].setColor(color);
            fPaints[i].setShader(shader);

            canvas->drawRect(oval, rectPaint);
            canvas->drawOval(oval, fPaints[i]);

            fPaints[i].setShader(nullptr);

            canvas->restore();
        }
    }
Example #29
0
static void
SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, TempBitmap& aTmpBitmap,
                Float aAlpha = 1.0)
{
  switch (aPattern.GetType()) {
    case PatternType::COLOR: {
      Color color = static_cast<const ColorPattern&>(aPattern).mColor;
      aPaint.setColor(ColorToSkColor(color, aAlpha));
      break;
    }
    case PatternType::LINEAR_GRADIENT: {
      const LinearGradientPattern& pat = static_cast<const LinearGradientPattern&>(aPattern);
      GradientStopsSkia *stops = static_cast<GradientStopsSkia*>(pat.mStops.get());
      SkShader::TileMode mode = ExtendModeToTileMode(stops->mExtendMode);

      if (stops->mCount >= 2) {
        SkPoint points[2];
        points[0] = SkPoint::Make(SkFloatToScalar(pat.mBegin.x), SkFloatToScalar(pat.mBegin.y));
        points[1] = SkPoint::Make(SkFloatToScalar(pat.mEnd.x), SkFloatToScalar(pat.mEnd.y));

        SkShader* shader = SkGradientShader::CreateLinear(points, 
                                                          &stops->mColors.front(), 
                                                          &stops->mPositions.front(), 
                                                          stops->mCount, 
                                                          mode);

        if (shader) {
            SkMatrix mat;
            GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
            shader->setLocalMatrix(mat);
            SkSafeUnref(aPaint.setShader(shader));
        }

      } else {
        aPaint.setColor(SkColorSetARGB(0, 0, 0, 0));
      }
      break;
    }
    case PatternType::RADIAL_GRADIENT: {
      const RadialGradientPattern& pat = static_cast<const RadialGradientPattern&>(aPattern);
      GradientStopsSkia *stops = static_cast<GradientStopsSkia*>(pat.mStops.get());
      SkShader::TileMode mode = ExtendModeToTileMode(stops->mExtendMode);

      if (stops->mCount >= 2) {
        SkPoint points[2];
        points[0] = SkPoint::Make(SkFloatToScalar(pat.mCenter1.x), SkFloatToScalar(pat.mCenter1.y));
        points[1] = SkPoint::Make(SkFloatToScalar(pat.mCenter2.x), SkFloatToScalar(pat.mCenter2.y));

        SkShader* shader = SkGradientShader::CreateTwoPointConical(points[0], 
                                                                   SkFloatToScalar(pat.mRadius1),
                                                                   points[1], 
                                                                   SkFloatToScalar(pat.mRadius2),
                                                                   &stops->mColors.front(), 
                                                                   &stops->mPositions.front(), 
                                                                   stops->mCount, 
                                                                   mode);
        if (shader) {
            SkMatrix mat;
            GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
            shader->setLocalMatrix(mat);
            SkSafeUnref(aPaint.setShader(shader));
        }

      } else {
        aPaint.setColor(SkColorSetARGB(0, 0, 0, 0));
      }
      break;
    }
    case PatternType::SURFACE: {
      const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern);
      aTmpBitmap = GetBitmapForSurface(pat.mSurface);
      const SkBitmap& bitmap = aTmpBitmap.mBitmap;

      SkShader::TileMode mode = ExtendModeToTileMode(pat.mExtendMode);
      SkShader* shader = SkShader::CreateBitmapShader(bitmap, mode, mode);
      SkMatrix mat;
      GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
      shader->setLocalMatrix(mat);
      SkSafeUnref(aPaint.setShader(shader));
      if (pat.mFilter == Filter::POINT) {
        aPaint.setFilterBitmap(false);
      }
      break;
    }
  }
}
Example #30
0
void OsmAnd::MapRasterizer_P::rasterize(
    const AreaI area31,
    const std::shared_ptr<const MapPrimitiviser::PrimitivisedObjects>& primitivisedObjects,
    SkCanvas& canvas,
    const bool fillBackground,
    const AreaI* const pDestinationArea,
    MapRasterizer_Metrics::Metric_rasterize* const metric,
    const std::shared_ptr<const IQueryController>& queryController)
{
    const Stopwatch totalStopwatch(metric != nullptr);

    const Context context(
        area31,
        primitivisedObjects,
        pDestinationArea ? *pDestinationArea : AreaI(0, 0, canvas.imageInfo().height(), canvas.imageInfo().width()));

    // Deal with background
    if (fillBackground)
    {
        // Get default background color
        const auto defaultBackgroundColor = context.env->getDefaultBackgroundColor(context.zoom);

        if (pDestinationArea)
        {
            // If destination area is specified, fill only it with background
            SkPaint bgPaint;
            bgPaint.setColor(defaultBackgroundColor.toSkColor());
            bgPaint.setStyle(SkPaint::kFill_Style);
            canvas.drawRectCoords(
                pDestinationArea->top(),
                pDestinationArea->left(),
                pDestinationArea->right(),
                pDestinationArea->bottom(),
                bgPaint);
        }
        else
        {
            // Since destination area is not specified, erase whole canvas with specified color
            canvas.clear(defaultBackgroundColor.toSkColor());
        }
    }

    AreaI destinationArea;
    if (pDestinationArea)
    {
        destinationArea = *pDestinationArea;
    }
    else
    {
        const auto targetSize = canvas.getDeviceSize();
        destinationArea = AreaI(0, 0, targetSize.height(), targetSize.width());
    }

    // Rasterize layers of map:
    rasterizeMapPrimitives(context, canvas, primitivisedObjects->polygons, PrimitivesType::Polygons, queryController);
    if (context.shadowMode != MapPresentationEnvironment::ShadowMode::NoShadow)
        rasterizeMapPrimitives(context, canvas, primitivisedObjects->polylines, PrimitivesType::Polylines_ShadowOnly, queryController);
    rasterizeMapPrimitives(context, canvas, primitivisedObjects->polylines, PrimitivesType::Polylines, queryController);

    if (metric)
        metric->elapsedTime += totalStopwatch.elapsed();
}