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