| /* |
| * Copyright 2018 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "gm/gm.h" |
| #include "include/core/SkCanvas.h" |
| #include "include/core/SkColor.h" |
| #include "include/core/SkFont.h" |
| #include "include/core/SkFontMetrics.h" |
| #include "include/core/SkFontStyle.h" |
| #include "include/core/SkFontTypes.h" |
| #include "include/core/SkPaint.h" |
| #include "include/core/SkRefCnt.h" |
| #include "include/core/SkScalar.h" |
| #include "include/core/SkSize.h" |
| #include "include/core/SkString.h" |
| #include "include/core/SkTypeface.h" |
| #include "src/core/SkEnumerate.h" |
| #include "tools/Resources.h" |
| #include "tools/ToolUtils.h" |
| |
| #include <string.h> |
| #include <initializer_list> |
| |
| namespace skiagm { |
| class ScaledEmojiRenderingGM : public GM { |
| public: |
| ScaledEmojiRenderingGM() {} |
| |
| protected: |
| struct Test { |
| enum class Source { Resource, Portable }; |
| Source const fontSource; |
| char const * const fontName; |
| char const * const text; |
| }; |
| static constexpr char const * const sampleText = ToolUtils::emoji_sample_text(); |
| static constexpr const Test tests[] = { |
| { Test::Source::Resource, "fonts/colr.ttf" , sampleText }, |
| { Test::Source::Resource, "fonts/sbix.ttf" , sampleText }, |
| { Test::Source::Resource, "fonts/cbdt.ttf" , sampleText }, |
| { Test::Source::Portable, "Emoji" , sampleText }, |
| { Test::Source::Resource, "fonts/SampleSVG.ttf", "abcdefghi" }, |
| }; |
| sk_sp<SkTypeface> typefaces[SK_ARRAY_COUNT(tests)]; |
| void onOnceBeforeDraw() override { |
| for (auto&& [i, test] : SkMakeEnumerate(tests)) { |
| if (test.fontSource == Test::Source::Resource) { |
| typefaces[i] = MakeResourceAsTypeface(test.fontName); |
| } else if (test.fontSource == Test::Source::Portable) { |
| typefaces[i] = ToolUtils::create_portable_typeface(test.fontName, SkFontStyle()); |
| } else { |
| SK_ABORT("Unknown test type"); |
| } |
| } |
| } |
| |
| SkString onShortName() override { |
| return SkString("scaledemoji_rendering"); |
| } |
| |
| SkISize onISize() override { return SkISize::Make(1200, 1200); } |
| |
| void onDraw(SkCanvas* canvas) override { |
| |
| canvas->drawColor(SK_ColorGRAY); |
| SkPaint textPaint; |
| textPaint.setColor(SK_ColorCYAN); |
| |
| SkPaint boundsPaint; |
| boundsPaint.setStrokeWidth(2); |
| boundsPaint.setStyle(SkPaint::kStroke_Style); |
| boundsPaint.setColor(SK_ColorGREEN); |
| |
| SkPaint advancePaint; |
| advancePaint.setColor(SK_ColorRED); |
| |
| SkScalar y = 0; |
| for (auto&& [i, test] : SkMakeEnumerate(tests)) { |
| SkFont font(typefaces[i]); |
| font.setEdging(SkFont::Edging::kAlias); |
| |
| const char* text = test.text; |
| SkFontMetrics metrics; |
| |
| for (SkScalar textSize : { 70, 150 }) { |
| font.setSize(textSize); |
| font.getMetrics(&metrics); |
| // All typefaces should support subpixel mode |
| font.setSubpixel(true); |
| |
| y += -metrics.fAscent; |
| |
| SkScalar x = 0; |
| for (bool fakeBold : { false, true }) { |
| font.setEmbolden(fakeBold); |
| SkRect bounds; |
| SkScalar advance = font.measureText(text, strlen(text), SkTextEncoding::kUTF8, |
| &bounds, &textPaint); |
| canvas->drawSimpleText(text, strlen(text), SkTextEncoding::kUTF8, |
| x, y, font, textPaint); |
| if ((false)) { |
| bounds.offset(x, y); |
| canvas->drawRect(bounds, boundsPaint); |
| SkRect advanceRect = SkRect::MakeLTRB(x, y + 2, x + advance, y + 4); |
| canvas->drawRect(advanceRect, advancePaint); |
| } |
| x += bounds.width() * 1.2; |
| } |
| y += metrics.fDescent + metrics.fLeading; |
| x = 0; |
| } |
| } |
| } |
| |
| private: |
| using INHERITED = GM; |
| }; |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| DEF_GM(return new ScaledEmojiRenderingGM;) |
| } // namespace skiagm |