Flutter Engine
The Flutter Engine
drawglyphs.cpp
Go to the documentation of this file.
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"
10#include "include/core/SkFont.h"
13#include "include/core/SkSpan.h"
15#include "src/base/SkZip.h"
16#include "tools/ToolUtils.h"
18
19static const char gText[] = "Call me Ishmael. Some years ago—never mind how long precisely";
20
21class DrawGlyphsGM : public skiagm::GM {
22public:
23 void onOnceBeforeDraw() override {
24 fTypeface = ToolUtils::CreatePortableTypeface("serif", SkFontStyle());
25 fFont = SkFont(fTypeface);
26 fFont.setSubpixel(true);
27 fFont.setSize(18);
28 const size_t txtLen = strlen(gText);
29 fGlyphCount = fFont.countText(gText, txtLen, SkTextEncoding::kUTF8);
30
31 fGlyphs.append(fGlyphCount);
32 fFont.textToGlyphs(gText, txtLen, SkTextEncoding::kUTF8, fGlyphs.begin(), fGlyphCount);
33
34 fPositions.append(fGlyphCount);
35 fFont.getPos(fGlyphs.begin(), fGlyphCount, fPositions.begin());
36 auto positions = SkSpan(fPositions.begin(), fGlyphCount);
37
38 fLength = positions.back().x() - positions.front().x();
39 fRadius = fLength / SK_FloatPI;
40 fXforms.append(fGlyphCount);
41
42 for (auto [xform, pos] : SkMakeZip(fXforms.begin(), positions)) {
43 const SkScalar lengthToGlyph = pos.x() - positions.front().x();
44 const SkScalar angle = SK_FloatPI * (fLength - lengthToGlyph) / fLength;
45 const SkScalar cos = std::cos(angle);
46 const SkScalar sin = std::sin(angle);
47 xform = SkRSXform::Make(sin, cos, fRadius*cos, -fRadius*sin);
48 }
49 }
50
51 SkString getName() const override { return SkString("drawglyphs"); }
52
53 SkISize getISize() override { return SkISize::Make(640, 480); }
54
55 void onDraw(SkCanvas* canvas) override {
56 canvas->drawGlyphs(fGlyphCount, fGlyphs.begin(), fPositions.begin(), {50, 100}, fFont,
57 SkPaint{});
58
59 canvas->drawGlyphs(fGlyphCount, fGlyphs.begin(), fPositions.begin(), {50, 120}, fFont,
60 SkPaint{});
61
62 // Check bounding box calculation.
63 for (auto& pos : fPositions) {
64 pos += {0, -500};
65 }
66 canvas->drawGlyphs(fGlyphCount, fGlyphs.begin(), fPositions.begin(), {50, 640}, fFont,
67 SkPaint{});
68
69 canvas->drawGlyphs(fGlyphCount, fGlyphs.begin(), fXforms.begin(),
70 {50 + fLength / 2, 160 + fRadius}, fFont, SkPaint{});
71
72 // TODO: add tests for cluster versions of drawGlyphs.
73 }
74
75private:
76 sk_sp<SkTypeface> fTypeface;
77 SkFont fFont;
79 SkTDArray<SkPoint> fPositions;
81 int fGlyphCount;
82 SkScalar fRadius;
83 SkScalar fLength;
84};
85
86DEF_GM(return new DrawGlyphsGM{};)
SkPoint pos
constexpr float SK_FloatPI
@ kUTF8
uses bytes to represent UTF-8 or ASCII
SkSpan(Container &&) -> SkSpan< std::remove_pointer_t< decltype(std::data(std::declval< Container >()))> >
constexpr auto SkMakeZip(Ts &&... ts)
Definition: SkZip.h:212
SkISize getISize() override
Definition: drawglyphs.cpp:53
SkString getName() const override
Definition: drawglyphs.cpp:51
void onOnceBeforeDraw() override
Definition: drawglyphs.cpp:23
void onDraw(SkCanvas *canvas) override
Definition: drawglyphs.cpp:55
void drawGlyphs(int count, const SkGlyphID glyphs[], const SkPoint positions[], const uint32_t clusters[], int textByteCount, const char utf8text[], SkPoint origin, const SkFont &font, const SkPaint &paint)
Definition: SkFont.h:35
void setSubpixel(bool subpixel)
Definition: SkFont.cpp:109
void getPos(const SkGlyphID glyphs[], int count, SkPoint pos[], SkPoint origin={0, 0}) const
Definition: SkFont.cpp:258
void setSize(SkScalar textSize)
Definition: SkFont.cpp:129
int countText(const void *text, size_t byteLength, SkTextEncoding encoding) const
Definition: SkFont.h:323
int textToGlyphs(const void *text, size_t byteLength, SkTextEncoding encoding, SkGlyphID glyphs[], int maxGlyphCount) const
Definition: SkFont.cpp:181
T * begin()
Definition: SkTDArray.h:150
T * append()
Definition: SkTDArray.h:191
Definition: gm.h:110
static const char gText[]
Definition: drawglyphs.cpp:19
float SkScalar
Definition: extension.cpp:12
#define DEF_GM(CODE)
Definition: gm.h:40
sk_sp< SkTypeface > CreatePortableTypeface(const char *name, SkFontStyle style)
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
constexpr float x() const
Definition: SkPoint_impl.h:181
static SkRSXform Make(SkScalar scos, SkScalar ssin, SkScalar tx, SkScalar ty)
Definition: SkRSXform.h:24