blob: 4bb499dbdf76541a33cc5987febaa5c5396cb541 [file] [log] [blame]
Herb Derby5d9d8372020-09-23 12:00:53 -04001/*
2 * Copyright 2020 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 "include/core/SkCanvas.h"
9#include "include/core/SkSurface.h"
10#include "include/core/SkTextBlob.h"
11#include "src/core/SkSurfacePriv.h"
12#include "tests/Test.h"
13#include "tools/ToolUtils.h"
14
15SkBitmap rasterize_blob(SkTextBlob* blob,
16 const SkPaint& paint,
17 GrRecordingContext* rContext,
18 const SkMatrix& matrix) {
19 const SkImageInfo info =
20 SkImageInfo::Make(500, 500, kN32_SkColorType, kPremul_SkAlphaType);
21 auto surface = SkSurface::MakeRenderTarget(rContext, SkBudgeted::kNo, info);
22 auto canvas = surface->getCanvas();
23 canvas->drawColor(SK_ColorWHITE);
24 canvas->concat(matrix);
25 canvas->drawTextBlob(blob, 10, 250, paint);
26 SkBitmap bitmap;
27 bitmap.allocN32Pixels(500, 500);
28 surface->readPixels(bitmap, 0, 0);
29 return bitmap;
30}
31
32bool check_for_black(const SkBitmap& bm) {
33 for (int y = 0; y < bm.height(); y++) {
34 for (int x = 0; x < bm.width(); x++) {
35 if (bm.getColor(x, y) == SK_ColorBLACK) {
36 return true;
37 }
38 }
39 }
40 return false;
41}
42
43DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextBlobScaleAnimation, reporter, ctxInfo) {
44 auto tf = ToolUtils::create_portable_typeface("Mono", SkFontStyle());
45 SkFont font{tf};
46 font.setHinting(SkFontHinting::kNormal);
47 font.setSize(12);
48 font.setEdging(SkFont::Edging::kAntiAlias);
49 font.setSubpixel(true);
50
51 SkTextBlobBuilder builder;
52 const auto& runBuffer = builder.allocRunPosH(font, 30, 0, nullptr);
53
54 for (int i = 0; i < 30; i++) {
55 runBuffer.glyphs[i] = static_cast<SkGlyphID>(i);
56 runBuffer.pos[i] = SkIntToScalar(i);
57 }
58 auto blob = builder.make();
59
60 auto dContext = ctxInfo.directContext();
61 bool anyBlack = false;
62 for (int n = -13; n < 5; n++) {
63 SkMatrix m = SkMatrix::Scale(std::exp2(n), std::exp2(n));
64 auto bm = rasterize_blob(blob.get(), SkPaint(), dContext, m);
65 anyBlack |= check_for_black(bm);
66 }
67 REPORTER_ASSERT(reporter, anyBlack);
68}
Herb Derby25f9db42020-11-06 10:21:59 -050069
70// Test extreme positions for all combinations of positions, origins, and translation matrices.
71DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextBlobMoveAround, reporter, ctxInfo) {
72 auto tf = ToolUtils::create_portable_typeface("Mono", SkFontStyle());
73 SkFont font{tf};
74 font.setHinting(SkFontHinting::kNormal);
75 font.setSize(12);
76 font.setEdging(SkFont::Edging::kAntiAlias);
77 font.setSubpixel(true);
78
79 auto makeBlob = [&](SkPoint delta) {
80 SkTextBlobBuilder builder;
81 const auto& runBuffer = builder.allocRunPos(font, 30, nullptr);
82
83 for (int i = 0; i < 30; i++) {
84 runBuffer.glyphs[i] = static_cast<SkGlyphID>(i);
85 runBuffer.points()[i] = SkPoint::Make(SkIntToScalar(i*10) + delta.x(), 50 + delta.y());
86 }
87 return builder.make();
88 };
89
90 auto dContext = ctxInfo.directContext();
91 auto rasterizeBlob = [&](SkTextBlob* blob, SkPoint origin, const SkMatrix& matrix) {
92 SkPaint paint;
93 const SkImageInfo info =
94 SkImageInfo::Make(350, 80, kN32_SkColorType, kPremul_SkAlphaType);
95 auto surface = SkSurface::MakeRenderTarget(dContext, SkBudgeted::kNo, info);
96 auto canvas = surface->getCanvas();
97 canvas->drawColor(SK_ColorWHITE);
98 canvas->concat(matrix);
99 canvas->drawTextBlob(blob, 10 + origin.x(), 40 + origin.y(), paint);
100 SkBitmap bitmap;
101 bitmap.allocN32Pixels(350, 80);
102 surface->readPixels(bitmap, 0, 0);
103 return bitmap;
104 };
105
106 SkBitmap benchMark;
107 {
108 auto blob = makeBlob({0, 0});
109 benchMark = rasterizeBlob(blob.get(), {0,0}, SkMatrix::I());
110 }
111
112 auto checkBitmap = [&](const SkBitmap& bitmap) {
113 REPORTER_ASSERT(reporter, benchMark.width() == bitmap.width());
114 REPORTER_ASSERT(reporter, benchMark.width() == bitmap.width());
115
116 for (int y = 0; y < benchMark.height(); y++) {
117 for (int x = 0; x < benchMark.width(); x++) {
118 if (benchMark.getColor(x, y) != bitmap.getColor(x, y)) {
119 return false;
120 }
121 }
122 }
123 return true;
124 };
125
126 SkScalar interestingNumbers[] = {-10'000'000, -1'000'000, -1, 0, +1, +1'000'000, +10'000'000};
127 for (auto originX : interestingNumbers) {
128 for (auto originY : interestingNumbers) {
129 for (auto translateX : interestingNumbers) {
130 for (auto translateY : interestingNumbers) {
131 // Make sure everything adds to zero.
132 SkScalar deltaPosX = -(originX + translateX);
133 SkScalar deltaPosY = -(originY + translateY);
134 auto blob = makeBlob({deltaPosX, deltaPosY});
135 SkMatrix t = SkMatrix::Translate(translateX, translateY);
136 auto bitmap = rasterizeBlob(blob.get(), {originX, originY}, t);
137 REPORTER_ASSERT(reporter, checkBitmap(bitmap));
138 }
139 }
140 }
141 }
142}