/* * Copyright 2015 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/SkFont.h" #include "include/core/SkFontArguments.h" #include "include/core/SkFontMgr.h" #include "include/core/SkFontTypes.h" #include "include/core/SkPaint.h" #include "include/core/SkRect.h" #include "include/core/SkRefCnt.h" #include "include/core/SkScalar.h" #include "include/core/SkSize.h" #include "include/core/SkStream.h" #include "include/core/SkString.h" #include "include/core/SkTypeface.h" #include "include/core/SkTypes.h" #include "tools/Resources.h" #include #include #include namespace skiagm { class FontScalerDistortableGM : public GM { public: FontScalerDistortableGM() { this->setBGColor(0xFFFFFFFF); } private: SkString onShortName() override { return SkString("fontscalerdistortable"); } SkISize onISize() override { return SkISize::Make(550, 700); } inline static constexpr int rows = 2; inline static constexpr int cols = 5; sk_sp typeface[rows][cols]; void onOnceBeforeDraw() override { sk_sp fontMgr(SkFontMgr::RefDefault()); constexpr SkFourByteTag wght = SkSetFourByteTag('w','g','h','t'); //constexpr SkFourByteTag wdth = SkSetFourByteTag('w','d','t','h'); struct { sk_sp distortable; SkFourByteTag axisTag; SkScalar axisMin; SkScalar axisMax; } info = { MakeResourceAsTypeface("fonts/Distortable.ttf"), wght, 0.5f, 2.0f //SkTypeface::MakeFromFile("/Library/Fonts/Skia.ttf"), wght, 0.48f, 3.2f //SkTypeface::MakeFromName("Skia", SkFontStyle()), wdth, 0.62f, 1.3f //SkTypeface::MakeFromFile("/System/Library/Fonts/SFNS.ttf"), wght, 100.0f, 900.0f //SkTypeface::MakeFromName(".SF NS", SkFontStyle()), wght, 100.0f, 900.0f }; std::unique_ptr distortableStream( info.distortable ? info.distortable->openStream(nullptr) : nullptr); for (int row = 0; row < rows; ++row) { for (int col = 0; col < cols; ++col) { SkScalar styleValue = SkScalarInterp(info.axisMin, info.axisMax, SkScalar(row * cols + col) / (rows * cols)); SkFontArguments::VariationPosition::Coordinate coordinates[] = { {info.axisTag, styleValue}, {info.axisTag, styleValue} }; SkFontArguments::VariationPosition position = { coordinates, SK_ARRAY_COUNT(coordinates) }; typeface[row][col] = [&]() -> sk_sp { if (row == 0 && info.distortable) { return info.distortable->makeClone( SkFontArguments().setVariationDesignPosition(position)); } if (distortableStream) { return fontMgr->makeFromStream(distortableStream->duplicate(), SkFontArguments().setVariationDesignPosition(position)); } return nullptr; }(); } } } DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override { SkPaint paint; paint.setAntiAlias(true); SkFont font; font.setEdging(SkFont::Edging::kSubpixelAntiAlias); const char* text = "abc"; const size_t textLen = strlen(text); for (int row = 0; row < rows; ++row) { for (int col = 0; col < cols; ++col) { SkScalar x = SkIntToScalar(10); SkScalar y = SkIntToScalar(20); font.setTypeface(typeface[row][col] ? typeface[row][col] : nullptr); SkAutoCanvasRestore acr(canvas, true); canvas->translate(SkIntToScalar(30 + col * 100), SkIntToScalar(20)); canvas->rotate(SkIntToScalar(col * 5), x, y * 10); { SkPaint p; p.setAntiAlias(true); SkRect r; r.setLTRB(x - 3, 15, x - 1, 280); canvas->drawRect(r, p); } for (int ps = 6; ps <= 22; ps++) { font.setSize(SkIntToScalar(ps)); canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, x, y, font, paint); y += font.getMetrics(nullptr); } } canvas->translate(0, SkIntToScalar(360)); font.setSubpixel(true); font.setLinearMetrics(true); font.setBaselineSnap(false); } return DrawResult::kOk; } }; ////////////////////////////////////////////////////////////////////////////// DEF_GM( return new FontScalerDistortableGM; ) } // namespace skiagm