1 /*
2  * Copyright 2015 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "gm.h"
9 #include "sk_tool_utils.h"
10 
11 #include "Resources.h"
12 #include "SkCanvas.h"
13 #include "SkGradientShader.h"
14 #include "SkStream.h"
15 #include "SkTextBlob.h"
16 #include "SkTypeface.h"
17 
18 namespace skiagm {
19 class TextBlobColorTrans : public GM {
20 public:
21     // This gm tests that textblobs can be translated and have their colors regenerated
22     // correctly.  With smaller atlas sizes, it can also trigger regeneration of texture coords on
23     // the GPU backend
TextBlobColorTrans()24     TextBlobColorTrans() { }
25 
26 protected:
onOnceBeforeDraw()27     void onOnceBeforeDraw() override {
28         SkTextBlobBuilder builder;
29 
30         // make textblob
31         // Large text is used to trigger atlas eviction
32         SkFont font(sk_tool_utils::create_portable_typeface(), 256);
33         font.setEdging(SkFont::Edging::kAlias);
34         const char* text = "AB";
35 
36         SkRect bounds;
37         font.measureText(text, strlen(text), kUTF8_SkTextEncoding, &bounds);
38 
39         SkScalar yOffset = bounds.height();
40         sk_tool_utils::add_to_text_blob(&builder, text, font, 0, yOffset - 30);
41 
42         // A8
43         font.setSize(28);
44         text = "The quick brown fox jumps over the lazy dog.";
45         font.measureText(text, strlen(text), kUTF8_SkTextEncoding, &bounds);
46         sk_tool_utils::add_to_text_blob(&builder, text, font, 0, yOffset - 8);
47 
48         // build
49         fBlob = builder.make();
50     }
51 
onShortName()52     SkString onShortName() override {
53         return SkString("textblobcolortrans");
54     }
55 
onISize()56     SkISize onISize() override {
57         return SkISize::Make(kWidth, kHeight);
58     }
59 
onDraw(SkCanvas * canvas)60     void onDraw(SkCanvas* canvas) override {
61 
62         canvas->drawColor(SK_ColorGRAY);
63 
64         SkPaint paint;
65         canvas->translate(10, 40);
66 
67         SkRect bounds = fBlob->bounds();
68 
69         // Colors were chosen to map to pairs of canonical colors.  The GPU Backend will cache A8
70         // Texture Blobs based on the canonical color they map to.  Canonical colors are used to
71         // create masks.  For A8 there are 8 of them.
72         SkColor colors[] = {SK_ColorCYAN, SK_ColorLTGRAY, SK_ColorYELLOW, SK_ColorWHITE};
73 
74         size_t count = SK_ARRAY_COUNT(colors);
75         size_t colorIndex = 0;
76         for (int y = 0; y + SkScalarFloorToInt(bounds.height()) < kHeight;
77              y += SkScalarFloorToInt(bounds.height())) {
78             paint.setColor(colors[colorIndex++ % count]);
79             canvas->save();
80             canvas->translate(0, SkIntToScalar(y));
81             canvas->drawTextBlob(fBlob, 0, 0, paint);
82             canvas->restore();
83         }
84     }
85 
86 private:
87     sk_sp<SkTextBlob> fBlob;
88 
89     static constexpr int kWidth = 675;
90     static constexpr int kHeight = 1600;
91 
92     typedef GM INHERITED;
93 };
94 
95 //////////////////////////////////////////////////////////////////////////////
96 
97 DEF_GM(return new TextBlobColorTrans;)
98 }
99