1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2013 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "gm/gm.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFont.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontTypes.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTextBlob.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypeface.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "tools/Resources.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h"
24*c8dee2aaSAndroid Build Coastguard Worker
25*c8dee2aaSAndroid Build Coastguard Worker #include <string.h>
26*c8dee2aaSAndroid Build Coastguard Worker
27*c8dee2aaSAndroid Build Coastguard Worker namespace skiagm {
28*c8dee2aaSAndroid Build Coastguard Worker
draw_blob(SkCanvas * canvas,const SkTextBlob * blob,const SkPaint & skPaint,const SkRect & clipRect)29*c8dee2aaSAndroid Build Coastguard Worker static void draw_blob(SkCanvas* canvas, const SkTextBlob* blob, const SkPaint& skPaint,
30*c8dee2aaSAndroid Build Coastguard Worker const SkRect& clipRect) {
31*c8dee2aaSAndroid Build Coastguard Worker SkPaint clipHairline;
32*c8dee2aaSAndroid Build Coastguard Worker clipHairline.setColor(SK_ColorWHITE);
33*c8dee2aaSAndroid Build Coastguard Worker clipHairline.setStyle(SkPaint::kStroke_Style);
34*c8dee2aaSAndroid Build Coastguard Worker
35*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint(skPaint);
36*c8dee2aaSAndroid Build Coastguard Worker canvas->save();
37*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(clipRect, clipHairline);
38*c8dee2aaSAndroid Build Coastguard Worker paint.setAlphaf(0.125f);
39*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(blob, 0, 0, paint);
40*c8dee2aaSAndroid Build Coastguard Worker canvas->clipRect(clipRect);
41*c8dee2aaSAndroid Build Coastguard Worker paint.setAlphaf(1.0f);
42*c8dee2aaSAndroid Build Coastguard Worker canvas->drawTextBlob(blob, 0, 0, paint);
43*c8dee2aaSAndroid Build Coastguard Worker canvas->restore();
44*c8dee2aaSAndroid Build Coastguard Worker }
45*c8dee2aaSAndroid Build Coastguard Worker
46*c8dee2aaSAndroid Build Coastguard Worker class MixedTextBlobsGM : public GM {
47*c8dee2aaSAndroid Build Coastguard Worker public:
MixedTextBlobsGM()48*c8dee2aaSAndroid Build Coastguard Worker MixedTextBlobsGM() { }
49*c8dee2aaSAndroid Build Coastguard Worker
50*c8dee2aaSAndroid Build Coastguard Worker protected:
onOnceBeforeDraw()51*c8dee2aaSAndroid Build Coastguard Worker void onOnceBeforeDraw() override {
52*c8dee2aaSAndroid Build Coastguard Worker fEmojiTypeface = ToolUtils::PlanetTypeface();
53*c8dee2aaSAndroid Build Coastguard Worker fEmojiText = "♁♃";
54*c8dee2aaSAndroid Build Coastguard Worker fReallyBigATypeface = ToolUtils::CreateTypefaceFromResource("fonts/ReallyBigA.ttf");
55*c8dee2aaSAndroid Build Coastguard Worker if (!fReallyBigATypeface) {
56*c8dee2aaSAndroid Build Coastguard Worker fReallyBigATypeface = ToolUtils::DefaultPortableTypeface();
57*c8dee2aaSAndroid Build Coastguard Worker }
58*c8dee2aaSAndroid Build Coastguard Worker
59*c8dee2aaSAndroid Build Coastguard Worker SkTextBlobBuilder builder;
60*c8dee2aaSAndroid Build Coastguard Worker
61*c8dee2aaSAndroid Build Coastguard Worker // make textblob
62*c8dee2aaSAndroid Build Coastguard Worker // Text so large we draw as paths
63*c8dee2aaSAndroid Build Coastguard Worker SkFont font(ToolUtils::DefaultPortableTypeface(), 385);
64*c8dee2aaSAndroid Build Coastguard Worker font.setEdging(SkFont::Edging::kAlias);
65*c8dee2aaSAndroid Build Coastguard Worker const char* text = "O";
66*c8dee2aaSAndroid Build Coastguard Worker
67*c8dee2aaSAndroid Build Coastguard Worker SkRect bounds;
68*c8dee2aaSAndroid Build Coastguard Worker font.measureText(text, strlen(text), SkTextEncoding::kUTF8, &bounds);
69*c8dee2aaSAndroid Build Coastguard Worker
70*c8dee2aaSAndroid Build Coastguard Worker SkScalar yOffset = bounds.height();
71*c8dee2aaSAndroid Build Coastguard Worker ToolUtils::add_to_text_blob(&builder, text, font, 10, yOffset);
72*c8dee2aaSAndroid Build Coastguard Worker SkScalar corruptedAx = bounds.width();
73*c8dee2aaSAndroid Build Coastguard Worker SkScalar corruptedAy = yOffset;
74*c8dee2aaSAndroid Build Coastguard Worker
75*c8dee2aaSAndroid Build Coastguard Worker const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf;
76*c8dee2aaSAndroid Build Coastguard Worker const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf;
77*c8dee2aaSAndroid Build Coastguard Worker
78*c8dee2aaSAndroid Build Coastguard Worker SkScalar xOffset = boundsHalfWidth;
79*c8dee2aaSAndroid Build Coastguard Worker yOffset = boundsHalfHeight;
80*c8dee2aaSAndroid Build Coastguard Worker
81*c8dee2aaSAndroid Build Coastguard Worker // LCD
82*c8dee2aaSAndroid Build Coastguard Worker font.setSize(32);
83*c8dee2aaSAndroid Build Coastguard Worker font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
84*c8dee2aaSAndroid Build Coastguard Worker font.setSubpixel(true);
85*c8dee2aaSAndroid Build Coastguard Worker text = "LCD!!!!!";
86*c8dee2aaSAndroid Build Coastguard Worker font.measureText(text, strlen(text), SkTextEncoding::kUTF8, &bounds);
87*c8dee2aaSAndroid Build Coastguard Worker ToolUtils::add_to_text_blob(&builder,
88*c8dee2aaSAndroid Build Coastguard Worker text,
89*c8dee2aaSAndroid Build Coastguard Worker font,
90*c8dee2aaSAndroid Build Coastguard Worker xOffset - bounds.width() * 0.25f,
91*c8dee2aaSAndroid Build Coastguard Worker yOffset - bounds.height() * 0.5f);
92*c8dee2aaSAndroid Build Coastguard Worker
93*c8dee2aaSAndroid Build Coastguard Worker // color emoji font with large glyph
94*c8dee2aaSAndroid Build Coastguard Worker if (fEmojiTypeface) {
95*c8dee2aaSAndroid Build Coastguard Worker font.setEdging(SkFont::Edging::kAlias);
96*c8dee2aaSAndroid Build Coastguard Worker font.setSubpixel(false);
97*c8dee2aaSAndroid Build Coastguard Worker font.setTypeface(fEmojiTypeface);
98*c8dee2aaSAndroid Build Coastguard Worker font.measureText(fEmojiText, strlen(fEmojiText), SkTextEncoding::kUTF8, &bounds);
99*c8dee2aaSAndroid Build Coastguard Worker ToolUtils::add_to_text_blob(&builder, fEmojiText, font, xOffset, yOffset);
100*c8dee2aaSAndroid Build Coastguard Worker }
101*c8dee2aaSAndroid Build Coastguard Worker
102*c8dee2aaSAndroid Build Coastguard Worker // outline font with large glyph
103*c8dee2aaSAndroid Build Coastguard Worker font.setSize(12);
104*c8dee2aaSAndroid Build Coastguard Worker text = "aA";
105*c8dee2aaSAndroid Build Coastguard Worker font.setTypeface(fReallyBigATypeface);
106*c8dee2aaSAndroid Build Coastguard Worker ToolUtils::add_to_text_blob(&builder, text, font, corruptedAx, corruptedAy);
107*c8dee2aaSAndroid Build Coastguard Worker fBlob = builder.make();
108*c8dee2aaSAndroid Build Coastguard Worker }
109*c8dee2aaSAndroid Build Coastguard Worker
getName() const110*c8dee2aaSAndroid Build Coastguard Worker SkString getName() const override { return SkString("mixedtextblobs"); }
111*c8dee2aaSAndroid Build Coastguard Worker
getISize()112*c8dee2aaSAndroid Build Coastguard Worker SkISize getISize() override { return SkISize::Make(kWidth, kHeight); }
113*c8dee2aaSAndroid Build Coastguard Worker
onDraw(SkCanvas * canvas)114*c8dee2aaSAndroid Build Coastguard Worker void onDraw(SkCanvas* canvas) override {
115*c8dee2aaSAndroid Build Coastguard Worker
116*c8dee2aaSAndroid Build Coastguard Worker canvas->drawColor(SK_ColorGRAY);
117*c8dee2aaSAndroid Build Coastguard Worker
118*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
119*c8dee2aaSAndroid Build Coastguard Worker
120*c8dee2aaSAndroid Build Coastguard Worker // setup work needed to draw text with different clips
121*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorBLACK);
122*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(10, 40);
123*c8dee2aaSAndroid Build Coastguard Worker
124*c8dee2aaSAndroid Build Coastguard Worker // compute the bounds of the text and setup some clips
125*c8dee2aaSAndroid Build Coastguard Worker SkRect bounds = fBlob->bounds();
126*c8dee2aaSAndroid Build Coastguard Worker
127*c8dee2aaSAndroid Build Coastguard Worker const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf;
128*c8dee2aaSAndroid Build Coastguard Worker const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf;
129*c8dee2aaSAndroid Build Coastguard Worker const SkScalar boundsQuarterWidth = boundsHalfWidth * SK_ScalarHalf;
130*c8dee2aaSAndroid Build Coastguard Worker const SkScalar boundsQuarterHeight = boundsHalfHeight * SK_ScalarHalf;
131*c8dee2aaSAndroid Build Coastguard Worker
132*c8dee2aaSAndroid Build Coastguard Worker SkRect upperLeftClip = SkRect::MakeXYWH(bounds.left(), bounds.top(),
133*c8dee2aaSAndroid Build Coastguard Worker boundsHalfWidth, boundsHalfHeight);
134*c8dee2aaSAndroid Build Coastguard Worker SkRect lowerRightClip = SkRect::MakeXYWH(bounds.centerX(), bounds.centerY(),
135*c8dee2aaSAndroid Build Coastguard Worker boundsHalfWidth, boundsHalfHeight);
136*c8dee2aaSAndroid Build Coastguard Worker SkRect interiorClip = bounds;
137*c8dee2aaSAndroid Build Coastguard Worker interiorClip.inset(boundsQuarterWidth, boundsQuarterHeight);
138*c8dee2aaSAndroid Build Coastguard Worker
139*c8dee2aaSAndroid Build Coastguard Worker const SkRect clipRects[] = { bounds, upperLeftClip, lowerRightClip, interiorClip};
140*c8dee2aaSAndroid Build Coastguard Worker
141*c8dee2aaSAndroid Build Coastguard Worker size_t count = sizeof(clipRects) / sizeof(SkRect);
142*c8dee2aaSAndroid Build Coastguard Worker for (size_t x = 0; x < count; ++x) {
143*c8dee2aaSAndroid Build Coastguard Worker draw_blob(canvas, fBlob.get(), paint, clipRects[x]);
144*c8dee2aaSAndroid Build Coastguard Worker if (x == (count >> 1) - 1) {
145*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(SkScalarFloorToScalar(bounds.width() + SkIntToScalar(25)),
146*c8dee2aaSAndroid Build Coastguard Worker -(x * SkScalarFloorToScalar(bounds.height() +
147*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(25))));
148*c8dee2aaSAndroid Build Coastguard Worker } else {
149*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(0, SkScalarFloorToScalar(bounds.height() + SkIntToScalar(25)));
150*c8dee2aaSAndroid Build Coastguard Worker }
151*c8dee2aaSAndroid Build Coastguard Worker }
152*c8dee2aaSAndroid Build Coastguard Worker }
153*c8dee2aaSAndroid Build Coastguard Worker
154*c8dee2aaSAndroid Build Coastguard Worker private:
155*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> fEmojiTypeface;
156*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> fReallyBigATypeface;
157*c8dee2aaSAndroid Build Coastguard Worker const char* fEmojiText;
158*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTextBlob> fBlob;
159*c8dee2aaSAndroid Build Coastguard Worker
160*c8dee2aaSAndroid Build Coastguard Worker inline static constexpr int kWidth = 1250;
161*c8dee2aaSAndroid Build Coastguard Worker inline static constexpr int kHeight = 700;
162*c8dee2aaSAndroid Build Coastguard Worker
163*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = GM;
164*c8dee2aaSAndroid Build Coastguard Worker };
165*c8dee2aaSAndroid Build Coastguard Worker
166*c8dee2aaSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
167*c8dee2aaSAndroid Build Coastguard Worker
168*c8dee2aaSAndroid Build Coastguard Worker DEF_GM(return new MixedTextBlobsGM;)
169*c8dee2aaSAndroid Build Coastguard Worker } // namespace skiagm
170