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