Flutter Engine
The Flutter Engine
DrawTextTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2011 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
11#include "include/core/SkFont.h"
15#include "include/core/SkPathEffect.h" // IWYU pragma: keep
17#include "include/core/SkRect.h"
25#include "tests/Test.h"
27
28#include <array>
29#include <cmath>
30#include <cstring>
31
33
34static void create(SkBitmap* bm, SkIRect bound) {
35 bm->allocN32Pixels(bound.width(), bound.height());
36}
37
38/** Assumes that the ref draw was completely inside ref canvas --
39 implies that everything outside is "bgColor".
40 Checks that all overlap is the same and that all non-overlap on the
41 ref is "bgColor".
42 */
43static bool compare(const SkBitmap& ref, const SkIRect& iref,
44 const SkBitmap& test, const SkIRect& itest)
45{
46 const int xOff = itest.fLeft - iref.fLeft;
47 const int yOff = itest.fTop - iref.fTop;
48
49 for (int y = 0; y < test.height(); ++y) {
50 for (int x = 0; x < test.width(); ++x) {
51 SkColor testColor = test.getColor(x, y);
52 int refX = x + xOff;
53 int refY = y + yOff;
54 SkColor refColor;
55 if (refX >= 0 && refX < ref.width() &&
56 refY >= 0 && refY < ref.height())
57 {
58 refColor = ref.getColor(refX, refY);
59 } else {
60 refColor = bgColor;
61 }
62 if (refColor != testColor) {
63 return false;
64 }
65 }
66 }
67 return true;
68}
69
70/** Test that drawing glyphs with empty paths is different from drawing glyphs without paths. */
71DEF_TEST(DrawText_dashout, reporter) {
73
74 SkBitmap drawTextBitmap;
75 create(&drawTextBitmap, size);
76 SkCanvas drawTextCanvas(drawTextBitmap);
77
78 SkBitmap drawDashedTextBitmap;
79 create(&drawDashedTextBitmap, size);
80 SkCanvas drawDashedTextCanvas(drawDashedTextBitmap);
81
82 SkBitmap emptyBitmap;
83 create(&emptyBitmap, size);
84 SkCanvas emptyCanvas(emptyBitmap);
85
86 SkPoint point = SkPoint::Make(25.0f, 25.0f);
89 font.setSubpixel(true);
90
92 paint.setColor(SK_ColorGRAY);
94
95 // Draw a stroked "A" without a dash which will draw something.
96 drawTextCanvas.drawColor(SK_ColorWHITE);
97 drawTextCanvas.drawString("A", point.fX, point.fY, font, paint);
98
99 // Draw an "A" but with a dash which will never draw anything.
100 paint.setStrokeWidth(2);
101 constexpr SkScalar bigInterval = 10000;
102 static constexpr SkScalar intervals[] = { 1, bigInterval };
103 paint.setPathEffect(SkDashPathEffect::Make(intervals, std::size(intervals), 2));
104
105 drawDashedTextCanvas.drawColor(SK_ColorWHITE);
106 drawDashedTextCanvas.drawString("A", point.fX, point.fY, font, paint);
107
108 // Draw nothing.
109 emptyCanvas.drawColor(SK_ColorWHITE);
110
111 REPORTER_ASSERT(reporter, !compare(drawTextBitmap, size, emptyBitmap, size));
112 REPORTER_ASSERT(reporter, compare(drawDashedTextBitmap, size, emptyBitmap, size));
113}
114
115// Test drawing text at some unusual coordinates.
116// We measure success by not crashing or asserting.
117DEF_TEST(DrawText_weirdCoordinates, r) {
119 auto canvas = surface->getCanvas();
121
122 SkScalar oddballs[] = { 0.0f, (float)INFINITY, (float)NAN, 34359738368.0f };
123
124 for (auto x : oddballs) {
125 canvas->drawString("a", +x, 0.0f, font, SkPaint());
126 canvas->drawString("a", -x, 0.0f, font, SkPaint());
127 }
128 for (auto y : oddballs) {
129 canvas->drawString("a", 0.0f, +y, font, SkPaint());
130 canvas->drawString("a", 0.0f, -y, font, SkPaint());
131 }
132}
133
134// Test drawing text with some unusual matrices.
135// We measure success by not crashing or asserting.
136DEF_TEST(DrawText_weirdMatricies, r) {
138 auto canvas = surface->getCanvas();
139
142
143 struct {
144 SkScalar textSize;
145 SkScalar matrix[9];
146 } testCases[] = {
147 // 2x2 singular
148 {10, { 0, 0, 0, 0, 0, 0, 0, 0, 1}},
149 {10, { 0, 0, 0, 0, 1, 0, 0, 0, 1}},
150 {10, { 0, 0, 0, 1, 0, 0, 0, 0, 1}},
151 {10, { 0, 0, 0, 1, 1, 0, 0, 0, 1}},
152 {10, { 0, 1, 0, 0, 1, 0, 0, 0, 1}},
153 {10, { 1, 0, 0, 0, 0, 0, 0, 0, 1}},
154 {10, { 1, 0, 0, 1, 0, 0, 0, 0, 1}},
155 {10, { 1, 1, 0, 0, 0, 0, 0, 0, 1}},
156 {10, { 1, 1, 0, 1, 1, 0, 0, 0, 1}},
157 // See https://bugzilla.mozilla.org/show_bug.cgi?id=1305085 .
158 { 1, {10, 20, 0, 20, 40, 0, 0, 0, 1}},
159 };
160
161 for (const auto& testCase : testCases) {
162 font.setSize(testCase.textSize);
163 const SkScalar(&m)[9] = testCase.matrix;
164 SkMatrix mat;
165 mat.setAll(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]);
166 canvas->setMatrix(mat);
167 canvas->drawString("Hamburgefons", 10, 10, font, SkPaint());
168 }
169}
170
171// This produces no glyphs, and is to check that buffers from previous draws don't get
172// reused.
173DEF_TEST(DrawText_noglyphs, r) {
175 auto canvas = surface->getCanvas();
177 auto text = "Hamburgfons";
178 {
179 // scoped to ensure blob is deleted.
180 auto blob = SkTextBlob::MakeFromText(text, strlen(text), font);
181 canvas->drawTextBlob(blob, 10, 10, SkPaint());
182 }
183 canvas->drawString(
184 "\x0d\xf3\xf2\xf2\xe9\x0d\x0d\x0d\x05\x0d\x0d\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3",
185 10, 20, font, SkPaint());
186}
static void create(SkBitmap *bm, SkIRect bound)
static bool compare(const SkBitmap &ref, const SkIRect &iref, const SkBitmap &test, const SkIRect &itest)
DEF_TEST(DrawText_dashout, reporter)
static const SkColor bgColor
reporter
Definition: FontMgrTest.cpp:39
uint32_t SkColor
Definition: SkColor.h:37
constexpr SkColor SK_ColorGRAY
Definition: SkColor.h:113
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
SkColor getColor(int x, int y) const
Definition: SkBitmap.h:874
int width() const
Definition: SkBitmap.h:149
void allocN32Pixels(int width, int height, bool isOpaque=false)
Definition: SkBitmap.cpp:232
int height() const
Definition: SkBitmap.h:158
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
Definition: SkCanvas.h:1182
void drawString(const char str[], SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
Definition: SkCanvas.h:1803
static sk_sp< SkPathEffect > Make(const SkScalar intervals[], int count, SkScalar phase)
Definition: SkFont.h:35
@ kSubpixelAntiAlias
glyph positioned in pixel using transparency
SkMatrix & setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar persp0, SkScalar persp1, SkScalar persp2)
Definition: SkMatrix.h:562
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
static sk_sp< SkTextBlob > MakeFromText(const void *text, size_t byteLength, const SkFont &font, SkTextEncoding encoding=SkTextEncoding::kUTF8)
Definition: SkTextBlob.cpp:788
const Paint & paint
Definition: color_source.cc:38
VkSurfaceKHR surface
Definition: main.cc:49
float SkScalar
Definition: extension.cpp:12
std::u16string text
double y
double x
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
SkFont DefaultFont()
sk_sp< SkTypeface > DefaultTypeface()
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
font
Font Metadata and Metrics.
Definition: SkRect.h:32
constexpr int32_t height() const
Definition: SkRect.h:165
int32_t fTop
smaller y-axis bounds
Definition: SkRect.h:34
constexpr int32_t width() const
Definition: SkRect.h:158
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition: SkRect.h:56
int32_t fLeft
smaller x-axis bounds
Definition: SkRect.h:33
static SkImageInfo MakeN32Premul(int width, int height)
float fX
x-axis value
Definition: SkPoint_impl.h:164
static constexpr SkPoint Make(float x, float y)
Definition: SkPoint_impl.h:173
float fY
y-axis value
Definition: SkPoint_impl.h:165