• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
8 #include "include/core/SkFont.h"
9 #include "include/core/SkMaskFilter.h"
10 #include "include/core/SkPath.h"
11 #include "include/core/SkTypeface.h"
12 #include "include/private/SkTo.h"
13 #include "include/utils/SkRandom.h"
14 #include "src/core/SkAutoMalloc.h"
15 #include "src/core/SkBlurMask.h"
16 #include "src/core/SkPaintPriv.h"
17 #include "src/core/SkReadBuffer.h"
18 #include "src/core/SkWriteBuffer.h"
19 #include "src/utils/SkUTF.h"
20 #include "tests/Test.h"
21 #undef ASSERT
22 
DEF_TEST(Paint_copy,reporter)23 DEF_TEST(Paint_copy, reporter) {
24     SkPaint paint;
25     // set a few member variables
26     paint.setStyle(SkPaint::kStrokeAndFill_Style);
27     paint.setStrokeWidth(SkIntToScalar(2));
28     // set a few pointers
29     paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle,
30                                                SkBlurMask::ConvertRadiusToSigma(1)));
31 
32     // copy the paint using the copy constructor and check they are the same
33     SkPaint copiedPaint = paint;
34     REPORTER_ASSERT(reporter, paint == copiedPaint);
35 
36     // copy the paint using the equal operator and check they are the same
37     copiedPaint = paint;
38     REPORTER_ASSERT(reporter, paint == copiedPaint);
39 
40     // clean the paint and check they are back to their initial states
41     SkPaint cleanPaint;
42     paint.reset();
43     copiedPaint.reset();
44     REPORTER_ASSERT(reporter, cleanPaint == paint);
45     REPORTER_ASSERT(reporter, cleanPaint == copiedPaint);
46 }
47 
48 // found and fixed for webkit: mishandling when we hit recursion limit on
49 // mostly degenerate cubic flatness test
DEF_TEST(Paint_regression_cubic,reporter)50 DEF_TEST(Paint_regression_cubic, reporter) {
51     SkPath path, stroke;
52     SkPaint paint;
53 
54     path.moveTo(460.2881309415525f,
55                 303.250847066498f);
56     path.cubicTo(463.36378422175284f,
57                  302.1169735073363f,
58                  456.32239330810046f,
59                  304.720354932878f,
60                  453.15255460013304f,
61                  305.788586869862f);
62 
63     SkRect fillR, strokeR;
64     fillR = path.getBounds();
65 
66     paint.setStyle(SkPaint::kStroke_Style);
67     paint.setStrokeWidth(SkIntToScalar(2));
68     paint.getFillPath(path, &stroke);
69     strokeR = stroke.getBounds();
70 
71     SkRect maxR = fillR;
72     SkScalar miter = std::max(SK_Scalar1, paint.getStrokeMiter());
73     SkScalar inset = paint.getStrokeJoin() == SkPaint::kMiter_Join ?
74                             paint.getStrokeWidth() * miter :
75                             paint.getStrokeWidth();
76     maxR.inset(-inset, -inset);
77 
78     // test that our stroke didn't explode
79     REPORTER_ASSERT(reporter, maxR.contains(strokeR));
80 }
81 
DEF_TEST(Paint_flattening,reporter)82 DEF_TEST(Paint_flattening, reporter) {
83     const SkPaint::Cap caps[] = {
84         SkPaint::kButt_Cap,
85         SkPaint::kRound_Cap,
86         SkPaint::kSquare_Cap,
87     };
88     const SkPaint::Join joins[] = {
89         SkPaint::kMiter_Join,
90         SkPaint::kRound_Join,
91         SkPaint::kBevel_Join,
92     };
93     const SkPaint::Style styles[] = {
94         SkPaint::kFill_Style,
95         SkPaint::kStroke_Style,
96         SkPaint::kStrokeAndFill_Style,
97     };
98 
99 #define FOR_SETUP(index, array, setter)                                 \
100     for (size_t index = 0; index < SK_ARRAY_COUNT(array); ++index) {    \
101         paint.setter(array[index]);
102 
103     SkPaint paint;
104     paint.setAntiAlias(true);
105 
106     // we don't serialize hinting or encoding -- soon to be removed from paint
107 
108     FOR_SETUP(l, caps, setStrokeCap)
109     FOR_SETUP(m, joins, setStrokeJoin)
110     FOR_SETUP(p, styles, setStyle)
111 
112     SkBinaryWriteBuffer writer;
113     SkPaintPriv::Flatten(paint, writer);
114 
115     SkAutoMalloc buf(writer.bytesWritten());
116     writer.writeToMemory(buf.get());
117     SkReadBuffer reader(buf.get(), writer.bytesWritten());
118 
119     SkPaint paint2 = reader.readPaint();
120     REPORTER_ASSERT(reporter, paint2 == paint);
121 
122     }}}
123 #undef FOR_SETUP
124 
125 }
126 
127 // found and fixed for android: not initializing rect for string's of length 0
128 DEF_TEST(Paint_regression_measureText, reporter) {
129 
130     SkFont font;
131     font.setSize(12.0f);
132 
133     SkRect r;
134     r.setLTRB(SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN);
135 
136     // test that the rect was reset
137     font.measureText("", 0, SkTextEncoding::kUTF8, &r);
138     REPORTER_ASSERT(reporter, r.isEmpty());
139 }
140 
141 #define ASSERT(expr) REPORTER_ASSERT(r, expr)
142 
143 DEF_TEST(Paint_MoreFlattening, r) {
144     SkPaint paint;
145     paint.setColor(0x00AABBCC);
146     paint.setBlendMode(SkBlendMode::kModulate);
147 
148     SkBinaryWriteBuffer writer;
149     SkPaintPriv::Flatten(paint, writer);
150 
151     SkAutoMalloc buf(writer.bytesWritten());
152     writer.writeToMemory(buf.get());
153     SkReadBuffer reader(buf.get(), writer.bytesWritten());
154 
155     SkPaint other = reader.readPaint();
156     ASSERT(reader.offset() == writer.bytesWritten());
157 
158     // No matter the encoding, these must always hold.
159     ASSERT(other.getColor()    == paint.getColor());
160     ASSERT(other.asBlendMode() == paint.asBlendMode());
161 }
162 
163 #include "include/effects/SkColorMatrixFilter.h"
164 
165 DEF_TEST(Paint_nothingToDraw, r) {
166     SkPaint paint;
167 
168     REPORTER_ASSERT(r, !paint.nothingToDraw());
169     paint.setAlpha(0);
170     REPORTER_ASSERT(r, paint.nothingToDraw());
171 
172     paint.setAlpha(0xFF);
173     paint.setBlendMode(SkBlendMode::kDst);
174     REPORTER_ASSERT(r, paint.nothingToDraw());
175 
176     paint.setAlpha(0);
177     paint.setBlendMode(SkBlendMode::kSrcOver);
178 
179     SkColorMatrix cm;
180     cm.setIdentity();   // does not change alpha
181     paint.setColorFilter(SkColorFilters::Matrix(cm));
182     REPORTER_ASSERT(r, paint.nothingToDraw());
183 
184     cm.postTranslate(0, 0, 0, 1.0f/255);    // wacks alpha
185     paint.setColorFilter(SkColorFilters::Matrix(cm));
186     REPORTER_ASSERT(r, !paint.nothingToDraw());
187 }
188 
189 DEF_TEST(Font_getpos, r) {
190     SkFont font;
191     const char text[] = "Hamburgefons!@#!#23425,./;'[]";
192     int count = font.countText(text, strlen(text), SkTextEncoding::kUTF8);
193     SkAutoTArray<uint16_t> glyphStorage(count);
194     uint16_t* glyphs = glyphStorage.get();
195     (void)font.textToGlyphs(text, strlen(text), SkTextEncoding::kUTF8, glyphs, count);
196 
197     SkAutoTArray<SkScalar> widthStorage(count);
198     SkAutoTArray<SkScalar> xposStorage(count);
199     SkAutoTArray<SkPoint> posStorage(count);
200 
201     SkScalar* widths = widthStorage.get();
202     SkScalar* xpos = xposStorage.get();
203     SkPoint* pos = posStorage.get();
204 
205     for (bool subpix : { false, true }) {
206         font.setSubpixel(subpix);
207         for (auto hint : { SkFontHinting::kNone, SkFontHinting::kSlight, SkFontHinting::kNormal, SkFontHinting::kFull}) {
208             font.setHinting(hint);
209             for (auto size : { 1.0f, 12.0f, 100.0f }) {
210                 font.setSize(size);
211 
212                 font.getWidths(glyphs, count, widths);
213                 font.getXPos(glyphs, count, xpos, 10);
214                 font.getPos(glyphs, count, pos, {10, 20});
215 
216                 auto nearly_eq = [](SkScalar a, SkScalar b) {
217                     return SkScalarAbs(a - b) < 0.000001f;
218                 };
219 
220                 SkScalar x = 10;
221                 for (int i = 0; i < count; ++i) {
222                     REPORTER_ASSERT(r, nearly_eq(x,  xpos[i]));
223                     REPORTER_ASSERT(r, nearly_eq(x,   pos[i].fX));
224                     REPORTER_ASSERT(r, nearly_eq(20,  pos[i].fY));
225                     x += widths[i];
226                 }
227             }
228         }
229     }
230 }
231 
232 DEF_TEST(Paint_dither, reporter) {
233     SkPaint p;
234     p.setDither(true);
235 
236     bool shouldDither = SkPaintPriv::ShouldDither(p, kBGRA_8888_SkColorType);
237 
238     REPORTER_ASSERT(reporter, !shouldDither);
239 }
240