Flutter Engine
The Flutter Engine
mixedtextblobs.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2013 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"
11#include "include/core/SkFont.h"
14#include "include/core/SkRect.h"
17#include "include/core/SkSize.h"
21#include "tools/Resources.h"
22#include "tools/ToolUtils.h"
24
25#include <string.h>
26
27namespace skiagm {
28
29static void draw_blob(SkCanvas* canvas, const SkTextBlob* blob, const SkPaint& skPaint,
30 const SkRect& clipRect) {
31 SkPaint clipHairline;
32 clipHairline.setColor(SK_ColorWHITE);
33 clipHairline.setStyle(SkPaint::kStroke_Style);
34
35 SkPaint paint(skPaint);
36 canvas->save();
37 canvas->drawRect(clipRect, clipHairline);
38 paint.setAlphaf(0.125f);
39 canvas->drawTextBlob(blob, 0, 0, paint);
40 canvas->clipRect(clipRect);
41 paint.setAlphaf(1.0f);
42 canvas->drawTextBlob(blob, 0, 0, paint);
43 canvas->restore();
44}
45
46class MixedTextBlobsGM : public GM {
47public:
49
50protected:
51 void onOnceBeforeDraw() override {
52 fEmojiTypeface = ToolUtils::PlanetTypeface();
53 fEmojiText = "♁♃";
54 fReallyBigATypeface = ToolUtils::CreateTypefaceFromResource("fonts/ReallyBigA.ttf");
55 if (!fReallyBigATypeface) {
56 fReallyBigATypeface = ToolUtils::DefaultPortableTypeface();
57 }
58
60
61 // make textblob
62 // Text so large we draw as paths
65 const char* text = "O";
66
68 font.measureText(text, strlen(text), SkTextEncoding::kUTF8, &bounds);
69
70 SkScalar yOffset = bounds.height();
72 SkScalar corruptedAx = bounds.width();
73 SkScalar corruptedAy = yOffset;
74
75 const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf;
76 const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf;
77
78 SkScalar xOffset = boundsHalfWidth;
79 yOffset = boundsHalfHeight;
80
81 // LCD
82 font.setSize(32);
84 font.setSubpixel(true);
85 text = "LCD!!!!!";
86 font.measureText(text, strlen(text), SkTextEncoding::kUTF8, &bounds);
88 text,
89 font,
90 xOffset - bounds.width() * 0.25f,
91 yOffset - bounds.height() * 0.5f);
92
93 // color emoji font with large glyph
94 if (fEmojiTypeface) {
96 font.setSubpixel(false);
97 font.setTypeface(fEmojiTypeface);
98 font.measureText(fEmojiText, strlen(fEmojiText), SkTextEncoding::kUTF8, &bounds);
99 ToolUtils::add_to_text_blob(&builder, fEmojiText, font, xOffset, yOffset);
100 }
101
102 // outline font with large glyph
103 font.setSize(12);
104 text = "aA";
105 font.setTypeface(fReallyBigATypeface);
106 ToolUtils::add_to_text_blob(&builder, text, font, corruptedAx, corruptedAy);
107 fBlob = builder.make();
108 }
109
110 SkString getName() const override { return SkString("mixedtextblobs"); }
111
112 SkISize getISize() override { return SkISize::Make(kWidth, kHeight); }
113
114 void onDraw(SkCanvas* canvas) override {
115
116 canvas->drawColor(SK_ColorGRAY);
117
119
120 // setup work needed to draw text with different clips
121 paint.setColor(SK_ColorBLACK);
122 canvas->translate(10, 40);
123
124 // compute the bounds of the text and setup some clips
125 SkRect bounds = fBlob->bounds();
126
127 const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf;
128 const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf;
129 const SkScalar boundsQuarterWidth = boundsHalfWidth * SK_ScalarHalf;
130 const SkScalar boundsQuarterHeight = boundsHalfHeight * SK_ScalarHalf;
131
132 SkRect upperLeftClip = SkRect::MakeXYWH(bounds.left(), bounds.top(),
133 boundsHalfWidth, boundsHalfHeight);
134 SkRect lowerRightClip = SkRect::MakeXYWH(bounds.centerX(), bounds.centerY(),
135 boundsHalfWidth, boundsHalfHeight);
136 SkRect interiorClip = bounds;
137 interiorClip.inset(boundsQuarterWidth, boundsQuarterHeight);
138
139 const SkRect clipRects[] = { bounds, upperLeftClip, lowerRightClip, interiorClip};
140
141 size_t count = sizeof(clipRects) / sizeof(SkRect);
142 for (size_t x = 0; x < count; ++x) {
143 draw_blob(canvas, fBlob.get(), paint, clipRects[x]);
144 if (x == (count >> 1) - 1) {
146 -(x * SkScalarFloorToScalar(bounds.height() +
147 SkIntToScalar(25))));
148 } else {
149 canvas->translate(0, SkScalarFloorToScalar(bounds.height() + SkIntToScalar(25)));
150 }
151 }
152 }
153
154private:
155 sk_sp<SkTypeface> fEmojiTypeface;
156 sk_sp<SkTypeface> fReallyBigATypeface;
157 const char* fEmojiText;
158 sk_sp<SkTextBlob> fBlob;
159
160 inline static constexpr int kWidth = 1250;
161 inline static constexpr int kHeight = 700;
162
163 using INHERITED = GM;
164};
165
166//////////////////////////////////////////////////////////////////////////////
167
168DEF_GM(return new MixedTextBlobsGM;)
169} // namespace skiagm
int count
Definition: FontMgrTest.cpp:50
constexpr SkColor SK_ColorGRAY
Definition: SkColor.h:113
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
@ kUTF8
uses bytes to represent UTF-8 or ASCII
#define SkScalarFloorToScalar(x)
Definition: SkScalar.h:30
#define SK_ScalarHalf
Definition: SkScalar.h:19
#define SkIntToScalar(x)
Definition: SkScalar.h:57
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
Definition: SkCanvas.cpp:1361
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
Definition: SkCanvas.h:1182
int save()
Definition: SkCanvas.cpp:447
void drawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y, const SkPaint &paint)
Definition: SkCanvas.cpp:2484
Definition: SkFont.h:35
@ kAlias
no transparent pixels on glyph edges
@ kSubpixelAntiAlias
glyph positioned in pixel using transparency
void setStyle(Style style)
Definition: SkPaint.cpp:105
void setColor(SkColor color)
Definition: SkPaint.cpp:119
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
const SkRect & bounds() const
Definition: SkTextBlob.h:53
T * get() const
Definition: SkRefCnt.h:303
Definition: gm.h:110
GM(SkColor backgroundColor=SK_ColorWHITE)
Definition: gm.cpp:81
void onDraw(SkCanvas *canvas) override
void onOnceBeforeDraw() override
SkString getName() const override
SkISize getISize() override
const Paint & paint
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
std::u16string text
double x
Optional< SkRect > bounds
Definition: SkRecords.h:189
clipRect(r.rect, r.opAA.op(), r.opAA.aa())) template<> void Draw
sk_sp< SkTypeface > DefaultPortableTypeface()
void add_to_text_blob(SkTextBlobBuilder *builder, const char *text, const SkFont &font, SkScalar x, SkScalar y)
Definition: ToolUtils.cpp:228
sk_sp< SkTypeface > PlanetTypeface()
sk_sp< SkTypeface > CreateTypefaceFromResource(const char *resource, int ttcIndex)
font
Font Metadata and Metrics.
DEF_GM(return F(C(clipbox), 0.0f, 0.0f, {})) DEF_GM(return F(C(clipbox)
static void draw_blob(SkCanvas *canvas, const SkTextBlob *blob, const SkPaint &skPaint, const SkRect &clipRect)
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
void inset(float dx, float dy)
Definition: SkRect.h:1060
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659