• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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/gm.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkColor.h"
11 #include "include/core/SkFont.h"
12 #include "include/core/SkFontMetrics.h"
13 #include "include/core/SkPaint.h"
14 #include "include/core/SkRefCnt.h"
15 #include "include/core/SkScalar.h"
16 #include "include/core/SkSize.h"
17 #include "include/core/SkString.h"
18 #include "include/core/SkTypeface.h"
19 #include "tools/Resources.h"
20 #include "tools/ToolUtils.h"
21 
22 #include <string.h>
23 #include <initializer_list>
24 
25 namespace skiagm {
26 
27 class ColrV1GM : public GM {
28 public:
29 
30   // TODO(drott): Consolidate test fonts.
31   enum ColrV1TestType {
32     kSkiaSampleFont,
33     kColorFontsRepoGradients,
34     kColorFontsRepoScaling,
35     kColorFontsRepoExtendMode,
36     kColorFontsRepoRotate,
37     kColorFontsRepoSkew,
38     kColorFontsRepoTransform,
39     kColorFontsRepoClipBox,
40     kColorFontsRepoComposite,
41     kColorFontsRepoForeground
42   };
43 
ColrV1GM(ColrV1TestType testType,SkScalar skewX,SkScalar rotateDeg)44   ColrV1GM(ColrV1TestType testType, SkScalar skewX, SkScalar rotateDeg)
45           : fSkewX(skewX), fRotateDeg(rotateDeg), fTestType(testType) {}
46 
47 protected:
testTypeToString(ColrV1TestType testType)48     static SkString testTypeToString(ColrV1TestType testType) {
49         switch (testType) {
50             case kSkiaSampleFont:
51                 return SkString("skia");
52             case kColorFontsRepoGradients:
53                 return SkString("gradients");
54             case kColorFontsRepoScaling:
55                 return SkString("scaling");
56             case kColorFontsRepoExtendMode:
57                 return SkString("extend_mode");
58             case kColorFontsRepoRotate:
59                 return SkString("rotate");
60             case kColorFontsRepoSkew:
61                 return SkString("skew");
62             case kColorFontsRepoTransform:
63                 return SkString("transform");
64             case kColorFontsRepoClipBox:
65                 return SkString("clipbox");
66             case kColorFontsRepoComposite:
67                 return SkString("composite");
68             case kColorFontsRepoForeground:
69                 return SkString("foreground");
70         }
71         SkASSERT(false); /* not reached */
72         return SkString();
73     }
74 
75     struct EmojiFont {
76         sk_sp<SkTypeface> fTypeface;
77         std::vector<uint16_t> fGlyphs;
bytesizeskiagm::ColrV1GM::EmojiFont78         size_t bytesize() { return fGlyphs.size() * sizeof(uint16_t); }
79     } fEmojiFont;
80 
onOnceBeforeDraw()81     void onOnceBeforeDraw() override {
82         if (fTestType == kSkiaSampleFont) {
83             fEmojiFont.fTypeface = MakeResourceAsTypeface("fonts/colrv1_samples.ttf");
84             fEmojiFont.fGlyphs = {19, 33, 34, 35, 20, 21, 22, 23, 24, 25};
85             return;
86         }
87 
88         fEmojiFont.fTypeface = MakeResourceAsTypeface("fonts/more_samples-glyf_colr_1.ttf");
89 
90         switch (fTestType) {
91             case kSkiaSampleFont:
92                 SkASSERT(false);
93                 break;
94             case kColorFontsRepoGradients:
95                 fEmojiFont.fGlyphs = {2, 5, 6, 7, 8};
96                 break;
97             case kColorFontsRepoScaling:
98                 fEmojiFont.fGlyphs = {9, 10, 11, 12, 13, 14};
99                 break;
100             case kColorFontsRepoExtendMode:
101                 fEmojiFont.fGlyphs = {15, 16, 17, 18, 19, 20};
102                 break;
103             case kColorFontsRepoRotate:
104                 fEmojiFont.fGlyphs = {21, 22, 23, 24};
105                 break;
106             case kColorFontsRepoSkew:
107                 fEmojiFont.fGlyphs = {25, 26, 27, 28, 29, 30};
108                 break;
109             case kColorFontsRepoTransform:
110                 fEmojiFont.fGlyphs = {31, 32, 33, 34};
111                 break;
112             case kColorFontsRepoClipBox:
113                 fEmojiFont.fGlyphs = {35, 36, 37, 38, 39};
114                 break;
115             case kColorFontsRepoComposite:
116                 fEmojiFont.fGlyphs = {40, 41, 42, 43, 44, 45, 46};
117                 break;
118             case kColorFontsRepoForeground:
119                 fEmojiFont.fGlyphs = {47, 48, 49, 50, 51, 52, 53, 54};
120                 break;
121         }
122     }
123 
onShortName()124     SkString onShortName() override {
125         SkString gm_name = SkStringPrintf("colrv1_%s_samples",
126                                           testTypeToString(fTestType).c_str());
127         if (fSkewX) {
128             gm_name.append("_skew");
129         }
130 
131         if (fRotateDeg) {
132             gm_name.append("_rotate");
133         }
134         return gm_name;
135     }
136 
onISize()137     SkISize onISize() override { return SkISize::Make(1400, 600); }
138 
onDraw(SkCanvas * canvas,SkString * errorMsg)139     DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
140         canvas->drawColor(SK_ColorWHITE);
141         SkPaint paint;
142 
143         canvas->translate(200, 20);
144 
145         if (!fEmojiFont.fTypeface) {
146           *errorMsg = "Did not recognize COLR v1 font format.";
147           return DrawResult::kSkip;
148         }
149 
150         canvas->rotate(fRotateDeg);
151         canvas->skew(fSkewX, 0);
152 
153         SkFont font(fEmojiFont.fTypeface);
154 
155         SkFontMetrics metrics;
156         SkScalar y = 0;
157         std::vector<SkColor> paint_colors = {
158                 SK_ColorBLACK, SK_ColorGREEN, SK_ColorRED, SK_ColorBLUE};
159         auto paint_color_iterator = paint_colors.begin();
160         for (SkScalar textSize : { 12, 18, 30, 120 }) {
161             font.setSize(textSize);
162             font.getMetrics(&metrics);
163             y += -metrics.fAscent;
164             paint.setColor(*paint_color_iterator);
165             canvas->drawSimpleText(fEmojiFont.fGlyphs.data(),
166                                    fEmojiFont.bytesize(),
167                                    SkTextEncoding::kGlyphID,
168                                    10, y, font, paint);
169             y += metrics.fDescent + metrics.fLeading;
170             paint_color_iterator++;
171         }
172         return DrawResult::kOk;
173     }
174 
175 private:
176     using INHERITED = GM;
177     SkScalar fSkewX;
178     SkScalar fRotateDeg;
179     ColrV1TestType fTestType;
180 };
181 
182 DEF_GM(return new ColrV1GM(ColrV1GM::kSkiaSampleFont, 0.f, 0.f);)
183 DEF_GM(return new ColrV1GM(ColrV1GM::kSkiaSampleFont, -0.5f, 0.f);)
184 DEF_GM(return new ColrV1GM(ColrV1GM::kSkiaSampleFont, 0.f, 20.f);)
185 DEF_GM(return new ColrV1GM(ColrV1GM::kSkiaSampleFont, -0.5f, 20.f);)
186 DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoGradients, 0.f, 0.f);)
187 DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoScaling, 0.f, 0.f);)
188 DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoExtendMode, 0.f, 0.f);)
189 DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoRotate, 0.f, 0.f);)
190 DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoSkew, 0.f, 0.f);)
191 DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoTransform, 0.f, 0.f);)
192 DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoClipBox, 0.f, 0.f);)
193 DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoClipBox, -0.5f, 20.f);)
194 DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoComposite, 0.f, 0.f);)
195 DEF_GM(return new ColrV1GM(ColrV1GM::kColorFontsRepoForeground, 0.f, 0.f);)
196 
197 }  // namespace skiagm
198