void anchor_handle_renderer::draw_anchor (SkCanvas &canvas, const SkRect &rect, SkPaint &paint) const { switch (m_node_type) { case handle_type::DIAMOND: { canvas.save (); canvas.translate (rect.centerX (), rect.centerY ()); canvas.rotate (45); SkRect moved_rect = rect; moved_rect.offset (-rect.centerX (), -rect.centerY ()); paint.setAntiAlias (true); canvas.drawRect (moved_rect, paint); canvas.restore (); break; } case handle_type::SQUARE: canvas.drawRect (rect, paint); break; case handle_type::CIRCLE: canvas.drawOval (rect, paint); break; case handle_type::DOUBLE_HEADED_ARROW: case handle_type::ROTATE_ARROW: SkPath path = qt2skia::path (*m_paths.at (m_node_type)); SkMatrix trans; trans.setIdentity (); trans.postRotate (m_rotation_angle, 32, 32); // TODO: change all these to use info from path_storage (bounding box and center (possibly should be made 0)) trans.postConcat (qt2skia::matrix (geom::rect2rect (QRectF (0, 0, 64, 64), qt2skia::rect (rect)))); path.transform (trans); paint.setAntiAlias (true); canvas.drawPath (path, paint); break; } }
static void drawRectWithLines(SkCanvas* canvas, const SkRect& r, const SkPaint& p) { canvas->drawRect(r, p); canvas->drawLine(r.fLeft, r.fTop, r.fRight, r.fBottom, p); canvas->drawLine(r.fLeft, r.fBottom, r.fRight, r.fTop, p); canvas->drawLine(r.fLeft, r.centerY(), r.fRight, r.centerY(), p); canvas->drawLine(r.centerX(), r.fTop, r.centerX(), r.fBottom, p); }
bool intersects(SkRect tRect, float tRot, TextDrawInfo* s) { float sRot = s->pathRotate; if (absFloat(tRot) < M_PI / 15 && absFloat(sRot) < M_PI / 15) { return SkRect::Intersects(tRect, s->bounds); } float dist = sqrt(sqr(tRect.centerX() - s->bounds.centerX()) + sqr(tRect.centerY() - s->bounds.centerY())); if(dist < 3) { return true; } SkRect sRect = s->bounds; // difference close to 90/270 degrees if(absFloat(cos(tRot-sRot)) < 0.3 ){ // rotate one rectangle to 90 degrees tRot += M_PI_2; tRect = SkRect::MakeXYWH(tRect.centerX() - tRect.height() / 2, tRect.centerY() - tRect.width() / 2, tRect.height(), tRect.width()); } // determine difference close to 180/0 degrees if(absFloat(sin(tRot-sRot)) < 0.3){ // rotate t box // (calculate offset for t center suppose we rotate around s center) float diff = atan2(tRect.centerY() - sRect.centerY(), tRect.centerX() - sRect.centerX()); diff -= sRot; float left = sRect.centerX() + dist* cos(diff) - tRect.width()/2; float top = sRect.centerY() - dist* sin(diff) - tRect.height()/2; SkRect nRect = SkRect::MakeXYWH(left, top, tRect.width(), tRect.height()); return SkRect::Intersects(nRect, sRect); } // TODO other cases not covered return SkRect::Intersects(tRect, sRect); }
void onDraw(SkCanvas* canvas) override { SkAutoCanvasRestore acr(canvas, false); SkPaint paint; paint.setAntiAlias(true); if (fInterp) { SkScalar values[5]; SkInterpolator::Result res = fInterp->timeToValues(fTime, values); fColor = floats_to_color(values); canvas->save(); canvas->translate(fR.centerX(), fR.centerY()); canvas->rotate(values[4]); canvas->translate(-fR.centerX(), -fR.centerY()); switch (res) { case SkInterpolator::kFreezeEnd_Result: delete fInterp; fInterp = nullptr; break; default: break; } } paint.setColor(fColor); canvas->drawRect(fR, paint); }
void drawBorders(SkCanvas* canvas) { SkPaint p; p.setStyle(SkPaint::kStroke_Style); p.setColor(SK_ColorBLUE); SkRect r = SkRect::MakeWH(fCell.width() * 2, fCell.height() * 2); r.inset(SK_ScalarHalf, SK_ScalarHalf); canvas->drawRect(r, p); canvas->drawLine(r.left(), r.centerY(), r.right(), r.centerY(), p); canvas->drawLine(r.centerX(), r.top(), r.centerX(), r.bottom(), p); }
void draw(SkCanvas* canvas) { SkPaint paint; paint.setColor(SK_ColorGRAY); paint.setAntiAlias(true); SkRect rect = {20, 20, 100, 100}; canvas->drawRect(rect, paint); paint.setColor(SK_ColorRED); SkMatrix matrix; matrix.setRSXform(SkRSXform::Make(.85f, .25f, rect.centerX(), rect.centerY())); canvas->concat(matrix); canvas->translate(-rect.centerX(), -rect.centerY()); canvas->drawRect(rect, paint); }
static void draw_path(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) { SkPaint paint; paint.setColor(SK_ColorMAGENTA); paint.setImageFilter(std::move(imf)); paint.setAntiAlias(true); canvas->drawCircle(r.centerX(), r.centerY(), r.width()*2/5, paint); }
void showPath(SkCanvas* canvas, int x, int y, SkPath::FillType ft, SkScalar scale, const SkPaint& paint) { const SkRect r = { 0, 0, SkIntToScalar(150), SkIntToScalar(150) }; canvas->save(); canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); canvas->clipRect(r); canvas->drawColor(SK_ColorWHITE); fPath.setFillType(ft); canvas->translate(r.centerX(), r.centerY()); canvas->scale(scale, scale); canvas->translate(-r.centerX(), -r.centerY()); canvas->drawPath(fPath, paint); canvas->restore(); }
void SkSVGDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) { AutoElement ellipse("ellipse", fWriter, fResourceBucket, draw, paint); ellipse.addAttribute("cx", oval.centerX()); ellipse.addAttribute("cy", oval.centerY()); ellipse.addAttribute("rx", oval.width() / 2); ellipse.addAttribute("ry", oval.height() / 2); }
PathTexture* PathCache::getArc(float width, float height, float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) { PathDescription entry(kShapeArc, paint); entry.shape.arc.mWidth = width; entry.shape.arc.mHeight = height; entry.shape.arc.mStartAngle = startAngle; entry.shape.arc.mSweepAngle = sweepAngle; entry.shape.arc.mUseCenter = useCenter; PathTexture* texture = get(entry); if (!texture) { SkPath path; SkRect r; r.set(0.0f, 0.0f, width, height); if (useCenter) { path.moveTo(r.centerX(), r.centerY()); } path.arcTo(r, startAngle, sweepAngle, !useCenter); if (useCenter) { path.close(); } texture = addTexture(entry, &path, paint); } return texture; }
static void draw_sweep(SkCanvas* c, int width, int height, SkScalar angle) { SkRect r; SkPaint p; p.setAntiAlias(true); // p.setDither(true); p.setStrokeWidth(SkIntToScalar(width/10)); p.setStyle(SkPaint::kStroke_Style); r.set(0, 0, SkIntToScalar(width), SkIntToScalar(height)); // SkColor colors[] = { SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN, SK_ColorCYAN }; SkColor colors[] = { 0x4c737373, 0x4c737373, 0xffffd300 }; SkShader* s = SkGradientShader::CreateSweep(r.centerX(), r.centerY(), colors, NULL, SK_ARRAY_COUNT(colors)); p.setShader(s)->unref(); SkAutoCanvasRestore acr(c, true); c->translate(r.centerX(), r.centerY()); c->rotate(angle); c->translate(-r.centerX(), -r.centerY()); SkRect bounds = r; r.inset(p.getStrokeWidth(), p.getStrokeWidth()); SkRect innerBounds = r; if (true) { c->drawOval(r, p); } else { SkScalar x = r.centerX(); SkScalar y = r.centerY(); SkScalar radius = r.width() / 2; SkScalar thickness = p.getStrokeWidth(); SkScalar sweep = SkFloatToScalar(360.0f); SkPath path; path.moveTo(x + radius, y); // outer top path.lineTo(x + radius + thickness, y); // outer arc path.arcTo(bounds, 0, sweep, false); // inner arc path.arcTo(innerBounds, sweep, -sweep, false); path.close(); } }
static void draw_text(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) { SkPaint paint; paint.setImageFilter(std::move(imf)); paint.setColor(SK_ColorGREEN); SkFont font(ToolUtils::create_portable_typeface(), r.height() / 2); SkTextUtils::DrawString(canvas, "Text", r.centerX(), r.centerY(), font, paint, SkTextUtils::kCenter_Align); }
virtual void onDraw(SkCanvas* canvas) { canvas->drawColor(SK_ColorGRAY); SkPaint paint; paint.setTypeface(fTypeface); const char* text = "hamburgerfons"; // draw text at different point sizes const int textSize[] = { 10, 30, 50 }; const int textYOffset[] = { 10, 40, 100}; SkASSERT(sizeof(textSize) == sizeof(textYOffset)); for (size_t y = 0; y < sizeof(textSize) / sizeof(int); ++y) { paint.setTextSize(SkIntToScalar(textSize[y])); canvas->drawText(text, strlen(text), 10, SkIntToScalar(textYOffset[y]), paint); } // setup work needed to draw text with different clips canvas->translate(10, 160); paint.setTextSize(40); // compute the bounds of the text SkRect bounds; paint.measureText(text, strlen(text), &bounds); const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf; const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf; const SkScalar boundsQuarterWidth = boundsHalfWidth * SK_ScalarHalf; const SkScalar boundsQuarterHeight = boundsHalfHeight * SK_ScalarHalf; SkRect upperLeftClip = SkRect::MakeXYWH(bounds.left(), bounds.top(), boundsHalfWidth, boundsHalfHeight); SkRect lowerRightClip = SkRect::MakeXYWH(bounds.centerX(), bounds.centerY(), boundsHalfWidth, boundsHalfHeight); SkRect interiorClip = bounds; interiorClip.inset(boundsQuarterWidth, boundsQuarterHeight); const SkRect clipRects[] = { bounds, upperLeftClip, lowerRightClip, interiorClip }; SkPaint clipHairline; clipHairline.setColor(SK_ColorWHITE); clipHairline.setStyle(SkPaint::kStroke_Style); for (size_t x = 0; x < sizeof(clipRects) / sizeof(SkRect); ++x) { canvas->save(); canvas->drawRect(clipRects[x], clipHairline); paint.setAlpha(0x20); canvas->drawText(text, strlen(text), 0, 0, paint); canvas->clipRect(clipRects[x]); paint.setAlpha(0xFF); canvas->drawText(text, strlen(text), 0, 0, paint); canvas->restore(); canvas->translate(0, bounds.height() + SkIntToScalar(25)); } }
static void draw_path(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) { SkPaint paint; paint.setColor(SK_ColorMAGENTA); paint.setImageFilter(imf); paint.setAntiAlias(true); canvas->save(); canvas->clipRect(r); canvas->drawCircle(r.centerX(), r.centerY(), r.width()*2/5, paint); canvas->restore(); }
static void draw_text(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) { SkPaint paint; paint.setImageFilter(std::move(imf)); paint.setColor(SK_ColorGREEN); paint.setAntiAlias(true); sk_tool_utils::set_portable_typeface(&paint); paint.setTextSize(r.height()/2); paint.setTextAlign(SkPaint::kCenter_Align); canvas->drawText("Text", 4, r.centerX(), r.centerY(), paint); }
static void draw_path(SkCanvas* canvas, const SkRect& r, sk_sp<SkImageFilter> imf) { SkPaint paint; paint.setColor(SK_ColorGREEN); paint.setImageFilter(std::move(imf)); paint.setAntiAlias(true); canvas->save(); canvas->clipRect(r); canvas->drawCircle(r.centerX(), r.centerY(), r.width()/3, paint); canvas->restore(); }
static void doDraw(SkCanvas* canvas, const SkPaint& paint, const char text[]) { canvas->drawColor(SK_ColorWHITE); SkPaint red; red.setColor(SK_ColorRED); canvas->drawCircle(150.0, 150.0, 100.0, red); SkRect bounds; canvas->getClipBounds(&bounds); canvas->drawText(text, strlen(text), bounds.centerX(), bounds.centerY(), paint); }
static void draw_center_letter(char c, SkPaint* p, SkColor color, SkScalar x, SkScalar y, SkCanvas* canvas) { SkRect bounds; p->setColor(color); p->measureText(&c, 1, &bounds); canvas->drawText(&c, 1, x - bounds.centerX(), y - bounds.centerY(), *p); }
static void draw_text(SkCanvas* canvas, const SkRect& r, SkImageFilter* imf) { SkPaint paint; paint.setImageFilter(imf); paint.setColor(SK_ColorGREEN); paint.setAntiAlias(true); paint.setTextSize(r.height()/2); paint.setTextAlign(SkPaint::kCenter_Align); canvas->save(); canvas->clipRect(r); canvas->drawText("Text", 4, r.centerX(), r.centerY(), paint); canvas->restore(); }
static void compute_rects(SkRect* devOutside, SkRect* devOutsideAssist, SkRect* devInside, bool* isDegenerate, const SkMatrix& viewMatrix, const SkRect& rect, SkScalar strokeWidth, bool miterStroke) { SkRect devRect; viewMatrix.mapRect(&devRect, rect); SkVector devStrokeSize; if (strokeWidth > 0) { devStrokeSize.set(strokeWidth, strokeWidth); viewMatrix.mapVectors(&devStrokeSize, 1); devStrokeSize.setAbs(devStrokeSize); } else { devStrokeSize.set(SK_Scalar1, SK_Scalar1); } const SkScalar dx = devStrokeSize.fX; const SkScalar dy = devStrokeSize.fY; const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf); const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf); *devOutside = devRect; *devOutsideAssist = devRect; *devInside = devRect; devOutside->outset(rx, ry); devInside->inset(rx, ry); // If we have a degenerate stroking rect(ie the stroke is larger than inner rect) then we // make a degenerate inside rect to avoid double hitting. We will also jam all of the points // together when we render these rects. SkScalar spare; { SkScalar w = devRect.width() - dx; SkScalar h = devRect.height() - dy; spare = SkTMin(w, h); } *isDegenerate = spare <= 0; if (*isDegenerate) { devInside->fLeft = devInside->fRight = devRect.centerX(); devInside->fTop = devInside->fBottom = devRect.centerY(); } // For bevel-stroke, use 2 SkRect instances(devOutside and devOutsideAssist) // to draw the outside of the octagon. Because there are 8 vertices on the outer // edge, while vertex number of inner edge is 4, the same as miter-stroke. if (!miterStroke) { devOutside->inset(0, ry); devOutsideAssist->outset(0, ry); } }
void drawTestBox(SkCanvas* cv, SkRect* r, float rot, SkPaint* paintIcon, std::string text, SkPaint* paintText) { cv->save(); cv->translate(r->centerX(),r->centerY()); cv->rotate(rot * 180 / M_PI); SkRect rs = SkRect::MakeLTRB(-r->width()/2, -r->height()/2, r->width()/2, r->height()/2); cv->drawRect(rs, *paintIcon); if (paintText != NULL) { cv->drawText(text.data(), text.length(), rs.centerX(), rs.centerY(), *paintText); } cv->restore(); }
static void draw_label(SkCanvas* canvas, const SkRect& rect, int start, int sweep) { SkPaint paint; paint.setAntiAlias(true); paint.setTextAlign(SkPaint::kCenter_Align); SkString str; str.appendS32(start); str.append(", "); str.appendS32(sweep); canvas->drawText(str.c_str(), str.size(), rect.centerX(), rect.fBottom + paint.getTextSize() * 5/4, paint); }
static void draw_clipped_filter(SkCanvas* canvas, sk_sp<SkImageFilter> filter, size_t i, const SkRect& primBounds, const SkRect& clipBounds) { SkPaint paint; paint.setColor(SK_ColorWHITE); paint.setImageFilter(std::move(filter)); paint.setAntiAlias(true); canvas->save(); canvas->clipRect(clipBounds); 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(primBounds.centerX(), primBounds.centerY(), primBounds.width() * 2 / 5, paint); canvas->restore(); }
void onDraw(SkCanvas* canvas) override { SkPaint paint; paint.setAntiAlias(true); sk_tool_utils::set_portable_typeface(&paint); paint.setTextSize(1500); SkRect r; (void)paint.measureText("/", 1, &r); SkPoint pos = { this->width()/2 - r.centerX(), this->height()/2 - r.centerY() }; paint.setColor(SK_ColorRED); canvas->drawString("/", pos.fX, pos.fY, paint); paint.setColor(SK_ColorBLUE); canvas->drawPosText("\\", 1, &pos, paint); }
void onDrawContent(SkCanvas* canvas) override { const SkRect oval = fOval.makeOffset(fCenter.fX - fOval.centerX(), fCenter.fY - fOval.centerY()); SkPaint p; p.setAntiAlias(true); p.setStyle(SkPaint::kStroke_Style); canvas->drawOval(oval, p); const SkRect r = SkRect::MakeLTRB(200, 200, 300, 300); canvas->clipRect(r); p.setStyle(SkPaint::kFill_Style); p.setColor(SK_ColorRED); canvas->drawRect(r, p); p.setColor(0x800000FF); canvas->drawOval(oval, p); }
PathTexture* ArcShapeCache::getArc(float width, float height, float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) { ArcShapeCacheEntry entry(width, height, startAngle, sweepAngle, useCenter, paint); PathTexture* texture = get(entry); if (!texture) { SkPath path; SkRect r; r.set(0.0f, 0.0f, width, height); if (useCenter) { path.moveTo(r.centerX(), r.centerY()); } path.arcTo(r, startAngle, sweepAngle, !useCenter); if (useCenter) { path.close(); } texture = addTexture(entry, &path, paint); } return texture; }
void onDrawContent(SkCanvas* canvas) override { SkRect oval = fOval; oval.offset(fCenter.fX - oval.centerX(), fCenter.fY - oval.centerY()); SkPaint p; p.setAntiAlias(true); p.setStyle(SkPaint::kStroke_Style); canvas->drawOval(oval, p); SkRect r; r.set(SkIntToScalar(200), SkIntToScalar(200), SkIntToScalar(300), SkIntToScalar(300)); canvas->clipRect(r); p.setStyle(SkPaint::kFill_Style); p.setColor(SK_ColorRED); canvas->drawRect(r, p); p.setColor(0x800000FF); r.set(SkIntToScalar(150), SkIntToScalar(10), SkIntToScalar(250), SkIntToScalar(400)); canvas->drawOval(oval, p); }
static void draw_oval(SkCanvas* canvas, bool showGL, int flags) { SkPaint paint; paint.setAntiAlias(true); SkRect r = SkRect::MakeLTRB(50, 70, 250, 370); setFade(&paint, showGL); canvas->drawOval(r, paint); if (showGL) { switch (flags) { case 0: { SkPath path; path.addOval(r); show_glframe(canvas, path); } break; case 1: case 3: { SkPath src, dst; src.addOval(r); tesselate(src, &dst); show_fan(canvas, dst, r.centerX(), r.centerY()); } break; case 2: { SkPaint p(paint); show_mesh(canvas, r); setGLFrame(&p); paint.setStyle(SkPaint::kFill_Style); canvas->drawCircle(r.centerX(), r.centerY(), 3, p); } break; } } canvas->translate(320, 0); paint.setStyle(SkPaint::kStroke_Style); paint.setStrokeWidth(25); canvas->drawOval(r, paint); if (showGL) { switch (flags) { case 0: { SkPath path; SkScalar rad = paint.getStrokeWidth() / 2; r.outset(rad, rad); path.addOval(r); r.inset(rad*2, rad*2); path.addOval(r); show_glframe(canvas, path); } break; case 1: { SkPath path0, path1; SkScalar rad = paint.getStrokeWidth() / 2; r.outset(rad, rad); path0.addOval(r); r.inset(rad*2, rad*2); path1.addOval(r); show_mesh_between(canvas, path0, path1); } break; case 2: { SkPath path; path.addOval(r); show_glframe(canvas, path); SkScalar rad = paint.getStrokeWidth() / 2; r.outset(rad, rad); show_mesh(canvas, r); } break; case 3: { SkScalar rad = paint.getStrokeWidth() / 2; r.outset(rad, rad); SkPaint paint; paint.setAlpha(0x33); canvas->drawRect(r, paint); show_mesh(canvas, r); } break; } } }
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]); } }
void onDraw(SkCanvas* canvas) override { canvas->drawColor(sk_tool_utils::color_to_565(SK_ColorGRAY)); SkPaint paint; paint.setTypeface(emojiFont.typeface); const char* text = emojiFont.text; // draw text at different point sizes const int textSize[] = { 10, 30, 50, }; const int textYOffset[] = { 10, 40, 100, }; SkASSERT(sizeof(textSize) == sizeof(textYOffset)); size_t y_offset = 0; for (size_t y = 0; y < sizeof(textSize) / sizeof(int); y++) { paint.setTextSize(SkIntToScalar(textSize[y])); canvas->drawText(text, strlen(text), 10, SkIntToScalar(textYOffset[y]), paint); y_offset += textYOffset[y]; } // draw with shaders and image filters for (int makeLinear = 0; makeLinear < 2; makeLinear++) { for (int makeBlur = 0; makeBlur < 2; makeBlur++) { for (int makeGray = 0; makeGray < 2; makeGray++) { SkPaint shaderPaint; shaderPaint.setTypeface(paint.getTypeface()); if (SkToBool(makeLinear)) { shaderPaint.setShader(MakeLinear())->unref(); } if (SkToBool(makeBlur) && SkToBool(makeGray)) { SkAutoTUnref<SkImageFilter> grayScale(make_grayscale(nullptr)); SkAutoTUnref<SkImageFilter> blur(make_blur(3.0f, grayScale)); shaderPaint.setImageFilter(blur); } else if (SkToBool(makeBlur)) { SkAutoTUnref<SkImageFilter> blur(make_blur(3.0f, nullptr)); shaderPaint.setImageFilter(blur); } else if (SkToBool(makeGray)) { SkAutoTUnref<SkImageFilter> grayScale(make_grayscale(nullptr)); shaderPaint.setImageFilter(grayScale); } shaderPaint.setTextSize(30); canvas->drawText(text, strlen(text), 380, SkIntToScalar(y_offset), shaderPaint); y_offset += 32; } } } // setup work needed to draw text with different clips canvas->translate(10, 160); paint.setTextSize(40); // compute the bounds of the text SkRect bounds; paint.measureText(text, strlen(text), &bounds); const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf; const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf; const SkScalar boundsQuarterWidth = boundsHalfWidth * SK_ScalarHalf; const SkScalar boundsQuarterHeight = boundsHalfHeight * SK_ScalarHalf; SkRect upperLeftClip = SkRect::MakeXYWH(bounds.left(), bounds.top(), boundsHalfWidth, boundsHalfHeight); SkRect lowerRightClip = SkRect::MakeXYWH(bounds.centerX(), bounds.centerY(), boundsHalfWidth, boundsHalfHeight); SkRect interiorClip = bounds; interiorClip.inset(boundsQuarterWidth, boundsQuarterHeight); const SkRect clipRects[] = { bounds, upperLeftClip, lowerRightClip, interiorClip }; SkPaint clipHairline; clipHairline.setColor(SK_ColorWHITE); clipHairline.setStyle(SkPaint::kStroke_Style); for (size_t x = 0; x < sizeof(clipRects) / sizeof(SkRect); ++x) { canvas->save(); canvas->drawRect(clipRects[x], clipHairline); paint.setAlpha(0x20); canvas->drawText(text, strlen(text), 0, 0, paint); canvas->clipRect(clipRects[x]); paint.setAlpha(0xFF); canvas->drawText(text, strlen(text), 0, 0, paint); canvas->restore(); canvas->translate(0, bounds.height() + SkIntToScalar(25)); } }