drawatlas.cpp revision 45561a0b15fe045ba272c328684c3f7ae290785a
171c3c760a83123ee0b3127b8c65c6394ce541c50reed/* 271c3c760a83123ee0b3127b8c65c6394ce541c50reed * Copyright 2015 Google Inc. 371c3c760a83123ee0b3127b8c65c6394ce541c50reed * 471c3c760a83123ee0b3127b8c65c6394ce541c50reed * Use of this source code is governed by a BSD-style license that can be 571c3c760a83123ee0b3127b8c65c6394ce541c50reed * found in the LICENSE file. 671c3c760a83123ee0b3127b8c65c6394ce541c50reed */ 771c3c760a83123ee0b3127b8c65c6394ce541c50reed 871c3c760a83123ee0b3127b8c65c6394ce541c50reed#include "gm.h" 971c3c760a83123ee0b3127b8c65c6394ce541c50reed#include "SkCanvas.h" 1071c3c760a83123ee0b3127b8c65c6394ce541c50reed#include "SkRSXform.h" 1171c3c760a83123ee0b3127b8c65c6394ce541c50reed#include "SkSurface.h" 1271c3c760a83123ee0b3127b8c65c6394ce541c50reed 1371c3c760a83123ee0b3127b8c65c6394ce541c50reedclass DrawAtlasGM : public skiagm::GM { 149ce9d6772df650ceb0511f275e1a83dffa78ff72reed static sk_sp<SkImage> MakeAtlas(SkCanvas* caller, const SkRect& target) { 1571c3c760a83123ee0b3127b8c65c6394ce541c50reed SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100); 16e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surface(caller->makeSurface(info)); 1796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == surface) { 18e8f3062a36d3682f4019309a32b5b84dc9eddf8creed surface = SkSurface::MakeRaster(info); 1971c3c760a83123ee0b3127b8c65c6394ce541c50reed } 2071c3c760a83123ee0b3127b8c65c6394ce541c50reed SkCanvas* canvas = surface->getCanvas(); 2171c3c760a83123ee0b3127b8c65c6394ce541c50reed // draw red everywhere, but we don't expect to see it in the draw, testing the notion 2271c3c760a83123ee0b3127b8c65c6394ce541c50reed // that drawAtlas draws a subset-region of the atlas. 2371c3c760a83123ee0b3127b8c65c6394ce541c50reed canvas->clear(SK_ColorRED); 2471c3c760a83123ee0b3127b8c65c6394ce541c50reed 2571c3c760a83123ee0b3127b8c65c6394ce541c50reed SkPaint paint; 2671c3c760a83123ee0b3127b8c65c6394ce541c50reed paint.setXfermodeMode(SkXfermode::kClear_Mode); 2771c3c760a83123ee0b3127b8c65c6394ce541c50reed SkRect r(target); 2871c3c760a83123ee0b3127b8c65c6394ce541c50reed r.inset(-1, -1); 2971c3c760a83123ee0b3127b8c65c6394ce541c50reed // zero out a place (with a 1-pixel border) to land our drawing. 3071c3c760a83123ee0b3127b8c65c6394ce541c50reed canvas->drawRect(r, paint); 3196fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint.setXfermode(nullptr); 3271c3c760a83123ee0b3127b8c65c6394ce541c50reed paint.setColor(SK_ColorBLUE); 3371c3c760a83123ee0b3127b8c65c6394ce541c50reed paint.setAntiAlias(true); 3471c3c760a83123ee0b3127b8c65c6394ce541c50reed canvas->drawOval(target, paint); 359ce9d6772df650ceb0511f275e1a83dffa78ff72reed return surface->makeImageSnapshot(); 3671c3c760a83123ee0b3127b8c65c6394ce541c50reed } 3771c3c760a83123ee0b3127b8c65c6394ce541c50reed 389ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> fAtlas; 3971c3c760a83123ee0b3127b8c65c6394ce541c50reed 4071c3c760a83123ee0b3127b8c65c6394ce541c50reedpublic: 4171c3c760a83123ee0b3127b8c65c6394ce541c50reed DrawAtlasGM() {} 429d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 4371c3c760a83123ee0b3127b8c65c6394ce541c50reedprotected: 449d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 4571c3c760a83123ee0b3127b8c65c6394ce541c50reed SkString onShortName() override { 4671c3c760a83123ee0b3127b8c65c6394ce541c50reed return SkString("draw-atlas"); 4771c3c760a83123ee0b3127b8c65c6394ce541c50reed } 489d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 4971c3c760a83123ee0b3127b8c65c6394ce541c50reed SkISize onISize() override { 5071c3c760a83123ee0b3127b8c65c6394ce541c50reed return SkISize::Make(640, 480); 5171c3c760a83123ee0b3127b8c65c6394ce541c50reed } 529d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 5371c3c760a83123ee0b3127b8c65c6394ce541c50reed void onDraw(SkCanvas* canvas) override { 5471c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect target = { 50, 50, 80, 90 }; 5596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fAtlas) { 569ce9d6772df650ceb0511f275e1a83dffa78ff72reed fAtlas = MakeAtlas(canvas, target); 5771c3c760a83123ee0b3127b8c65c6394ce541c50reed } 5871c3c760a83123ee0b3127b8c65c6394ce541c50reed 5971c3c760a83123ee0b3127b8c65c6394ce541c50reed const struct { 6071c3c760a83123ee0b3127b8c65c6394ce541c50reed SkScalar fScale; 6171c3c760a83123ee0b3127b8c65c6394ce541c50reed SkScalar fDegrees; 6271c3c760a83123ee0b3127b8c65c6394ce541c50reed SkScalar fTx; 6371c3c760a83123ee0b3127b8c65c6394ce541c50reed SkScalar fTy; 649d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 6571c3c760a83123ee0b3127b8c65c6394ce541c50reed void apply(SkRSXform* xform) const { 6671c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkScalar rad = SkDegreesToRadians(fDegrees); 6771c3c760a83123ee0b3127b8c65c6394ce541c50reed xform->fSCos = fScale * SkScalarCos(rad); 6871c3c760a83123ee0b3127b8c65c6394ce541c50reed xform->fSSin = fScale * SkScalarSin(rad); 6971c3c760a83123ee0b3127b8c65c6394ce541c50reed xform->fTx = fTx; 7071c3c760a83123ee0b3127b8c65c6394ce541c50reed xform->fTy = fTy; 7171c3c760a83123ee0b3127b8c65c6394ce541c50reed } 7271c3c760a83123ee0b3127b8c65c6394ce541c50reed } rec[] = { 7371c3c760a83123ee0b3127b8c65c6394ce541c50reed { 1, 0, 10, 10 }, // just translate 7471c3c760a83123ee0b3127b8c65c6394ce541c50reed { 2, 0, 110, 10 }, // scale + translate 7571c3c760a83123ee0b3127b8c65c6394ce541c50reed { 1, 30, 210, 10 }, // rotate + translate 7671c3c760a83123ee0b3127b8c65c6394ce541c50reed { 2, -30, 310, 30 }, // scale + rotate + translate 7771c3c760a83123ee0b3127b8c65c6394ce541c50reed }; 7871c3c760a83123ee0b3127b8c65c6394ce541c50reed 7971c3c760a83123ee0b3127b8c65c6394ce541c50reed const int N = SK_ARRAY_COUNT(rec); 8071c3c760a83123ee0b3127b8c65c6394ce541c50reed SkRSXform xform[N]; 8171c3c760a83123ee0b3127b8c65c6394ce541c50reed SkRect tex[N]; 8271c3c760a83123ee0b3127b8c65c6394ce541c50reed SkColor colors[N]; 8371c3c760a83123ee0b3127b8c65c6394ce541c50reed 8471c3c760a83123ee0b3127b8c65c6394ce541c50reed for (int i = 0; i < N; ++i) { 8571c3c760a83123ee0b3127b8c65c6394ce541c50reed rec[i].apply(&xform[i]); 8671c3c760a83123ee0b3127b8c65c6394ce541c50reed tex[i] = target; 8771c3c760a83123ee0b3127b8c65c6394ce541c50reed colors[i] = 0x80FF0000 + (i * 40 * 256); 8871c3c760a83123ee0b3127b8c65c6394ce541c50reed } 8971c3c760a83123ee0b3127b8c65c6394ce541c50reed 9071c3c760a83123ee0b3127b8c65c6394ce541c50reed SkPaint paint; 9171c3c760a83123ee0b3127b8c65c6394ce541c50reed paint.setFilterQuality(kLow_SkFilterQuality); 9271c3c760a83123ee0b3127b8c65c6394ce541c50reed paint.setAntiAlias(true); 9371c3c760a83123ee0b3127b8c65c6394ce541c50reed 949ce9d6772df650ceb0511f275e1a83dffa78ff72reed canvas->drawAtlas(fAtlas.get(), xform, tex, N, nullptr, &paint); 9571c3c760a83123ee0b3127b8c65c6394ce541c50reed canvas->translate(0, 100); 969ce9d6772df650ceb0511f275e1a83dffa78ff72reed canvas->drawAtlas(fAtlas.get(), xform, tex, colors, N, SkXfermode::kSrcIn_Mode, nullptr, &paint); 9771c3c760a83123ee0b3127b8c65c6394ce541c50reed } 989d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 9971c3c760a83123ee0b3127b8c65c6394ce541c50reedprivate: 10071c3c760a83123ee0b3127b8c65c6394ce541c50reed typedef GM INHERITED; 10171c3c760a83123ee0b3127b8c65c6394ce541c50reed}; 10271c3c760a83123ee0b3127b8c65c6394ce541c50reedDEF_GM( return new DrawAtlasGM; ) 10345561a0b15fe045ba272c328684c3f7ae290785areed 10445561a0b15fe045ba272c328684c3f7ae290785areed/////////////////////////////////////////////////////////////////////////////////////////////////// 10545561a0b15fe045ba272c328684c3f7ae290785areed#include "SkPath.h" 10645561a0b15fe045ba272c328684c3f7ae290785areed#include "SkPathMeasure.h" 10745561a0b15fe045ba272c328684c3f7ae290785areed 10845561a0b15fe045ba272c328684c3f7ae290785areedstatic void draw_text_on_path_rigid(SkCanvas* canvas, const void* text, size_t length, 10945561a0b15fe045ba272c328684c3f7ae290785areed const SkPoint xy[], const SkPath& path, const SkPaint& paint) { 11045561a0b15fe045ba272c328684c3f7ae290785areed SkPathMeasure meas(path, false); 11145561a0b15fe045ba272c328684c3f7ae290785areed 11245561a0b15fe045ba272c328684c3f7ae290785areed int count = paint.countText(text, length); 11345561a0b15fe045ba272c328684c3f7ae290785areed SkAutoSTArray<100, SkRSXform> xform(count); 11445561a0b15fe045ba272c328684c3f7ae290785areed 11545561a0b15fe045ba272c328684c3f7ae290785areed for (int i = 0; i < count; ++i) { 11645561a0b15fe045ba272c328684c3f7ae290785areed SkPoint pos; 11745561a0b15fe045ba272c328684c3f7ae290785areed SkVector tan; 11845561a0b15fe045ba272c328684c3f7ae290785areed if (!meas.getPosTan(xy[i].x(), &pos, &tan)) { 11945561a0b15fe045ba272c328684c3f7ae290785areed pos = xy[i]; 12045561a0b15fe045ba272c328684c3f7ae290785areed tan.set(1, 0); 12145561a0b15fe045ba272c328684c3f7ae290785areed } 12245561a0b15fe045ba272c328684c3f7ae290785areed xform[i].fSCos = tan.x(); 12345561a0b15fe045ba272c328684c3f7ae290785areed xform[i].fSSin = tan.y(); 12445561a0b15fe045ba272c328684c3f7ae290785areed xform[i].fTx = pos.x(); 12545561a0b15fe045ba272c328684c3f7ae290785areed xform[i].fTy = pos.y(); 12645561a0b15fe045ba272c328684c3f7ae290785areed } 12745561a0b15fe045ba272c328684c3f7ae290785areed 12845561a0b15fe045ba272c328684c3f7ae290785areed canvas->drawTextRSXform(text, length, &xform[0], nullptr, paint); 12945561a0b15fe045ba272c328684c3f7ae290785areed} 13045561a0b15fe045ba272c328684c3f7ae290785areed 13145561a0b15fe045ba272c328684c3f7ae290785areedDEF_SIMPLE_GM(drawTextRSXform, canvas, 510, 310) { 13245561a0b15fe045ba272c328684c3f7ae290785areed const char text[] = "ABCDFGHJKLMNOPQRSTUVWXYZ"; 13345561a0b15fe045ba272c328684c3f7ae290785areed const int N = sizeof(text) - 1; 13445561a0b15fe045ba272c328684c3f7ae290785areed SkPoint pos[N]; 13545561a0b15fe045ba272c328684c3f7ae290785areed SkRSXform xform[N]; 13645561a0b15fe045ba272c328684c3f7ae290785areed 13745561a0b15fe045ba272c328684c3f7ae290785areed canvas->translate(0, 30); 13845561a0b15fe045ba272c328684c3f7ae290785areed 13945561a0b15fe045ba272c328684c3f7ae290785areed SkScalar x = 20; 14045561a0b15fe045ba272c328684c3f7ae290785areed SkScalar dx = 20; 14145561a0b15fe045ba272c328684c3f7ae290785areed SkScalar rad = 0; 14245561a0b15fe045ba272c328684c3f7ae290785areed SkScalar drad = 2 * SK_ScalarPI / (N - 1); 14345561a0b15fe045ba272c328684c3f7ae290785areed for (int i = 0; i < N; ++i) { 14445561a0b15fe045ba272c328684c3f7ae290785areed xform[i].fSCos = SkScalarCos(rad); 14545561a0b15fe045ba272c328684c3f7ae290785areed xform[i].fSSin = SkScalarSin(rad); 14645561a0b15fe045ba272c328684c3f7ae290785areed xform[i].fTx = x; 14745561a0b15fe045ba272c328684c3f7ae290785areed xform[i].fTy = 0; 14845561a0b15fe045ba272c328684c3f7ae290785areed pos[i].set(x, 0); 14945561a0b15fe045ba272c328684c3f7ae290785areed x += dx; 15045561a0b15fe045ba272c328684c3f7ae290785areed rad += drad; 15145561a0b15fe045ba272c328684c3f7ae290785areed } 15245561a0b15fe045ba272c328684c3f7ae290785areed 15345561a0b15fe045ba272c328684c3f7ae290785areed SkPaint paint; 15445561a0b15fe045ba272c328684c3f7ae290785areed paint.setAntiAlias(true); 15545561a0b15fe045ba272c328684c3f7ae290785areed paint.setTextSize(20); 15645561a0b15fe045ba272c328684c3f7ae290785areed canvas->drawTextRSXform(text, N, xform, nullptr, paint); 15745561a0b15fe045ba272c328684c3f7ae290785areed 15845561a0b15fe045ba272c328684c3f7ae290785areed SkPath path; 15945561a0b15fe045ba272c328684c3f7ae290785areed path.addOval(SkRect::MakeXYWH(150, 50, 200, 200)); 16045561a0b15fe045ba272c328684c3f7ae290785areed 16145561a0b15fe045ba272c328684c3f7ae290785areed draw_text_on_path_rigid(canvas, text, N, pos, path, paint); 16245561a0b15fe045ba272c328684c3f7ae290785areed 16345561a0b15fe045ba272c328684c3f7ae290785areed paint.setStyle(SkPaint::kStroke_Style); 16445561a0b15fe045ba272c328684c3f7ae290785areed canvas->drawPath(path, paint); 16545561a0b15fe045ba272c328684c3f7ae290785areed} 16645561a0b15fe045ba272c328684c3f7ae290785areed 16745561a0b15fe045ba272c328684c3f7ae290785areed 168