1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com
8b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com#include "SkBlurMask.h"
9b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com#include "SkBlurMaskFilter.h"
10b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com#include "SkLayerDrawLooper.h"
11a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com#include "SkPaint.h"
128f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "SkPath.h"
13bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com#include "SkRandom.h"
14aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#include "SkReadBuffer.h"
15bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com#include "SkTypeface.h"
16bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com#include "SkUtils.h"
17aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#include "SkWriteBuffer.h"
18aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#include "SkXfermode.h"
198f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "Test.h"
20bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com
21bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.comstatic size_t uni_to_utf8(const SkUnichar src[], void* dst, int count) {
22bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    char* u8 = (char*)dst;
23bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    for (int i = 0; i < count; ++i) {
24bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        int n = SkUTF8_FromUnichar(src[i], u8);
25bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        u8 += n;
26bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    }
27bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    return u8 - (char*)dst;
28bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com}
29bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com
30bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.comstatic size_t uni_to_utf16(const SkUnichar src[], void* dst, int count) {
31bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    uint16_t* u16 = (uint16_t*)dst;
32bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    for (int i = 0; i < count; ++i) {
33bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        int n = SkUTF16_FromUnichar(src[i], u16);
34bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        u16 += n;
35bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    }
36bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    return (char*)u16 - (char*)dst;
37bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com}
38bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com
39bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.comstatic size_t uni_to_utf32(const SkUnichar src[], void* dst, int count) {
40bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    SkUnichar* u32 = (SkUnichar*)dst;
41bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    if (src != u32) {
42bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        memcpy(u32, src, count * sizeof(SkUnichar));
43bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    }
44bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    return count * sizeof(SkUnichar);
45bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com}
46bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com
47bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.comstatic SkTypeface::Encoding paint2encoding(const SkPaint& paint) {
48bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    SkPaint::TextEncoding enc = paint.getTextEncoding();
49bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    SkASSERT(SkPaint::kGlyphID_TextEncoding != enc);
50bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    return (SkTypeface::Encoding)enc;
51bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com}
52bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com
53bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.comstatic int find_first_zero(const uint16_t glyphs[], int count) {
54bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    for (int i = 0; i < count; ++i) {
55bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        if (0 == glyphs[i]) {
56bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com            return i;
57bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        }
58bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    }
59bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    return count;
60bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com}
61bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com
62e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.orgDEF_TEST(Paint_cmap, reporter) {
63e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org    // need to implement charsToGlyphs on other backends (e.g. linux, win)
64e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org    // before we can run this tests everywhere
65e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org    return;
66e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org
67bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    static const int NGLYPHS = 64;
68bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com
69bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    SkUnichar src[NGLYPHS];
70bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    SkUnichar dst[NGLYPHS]; // used for utf8, utf16, utf32 storage
71bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com
72bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    static const struct {
73bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        size_t (*fSeedTextProc)(const SkUnichar[], void* dst, int count);
74bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        SkPaint::TextEncoding   fEncoding;
75bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    } gRec[] = {
76bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        { uni_to_utf8,  SkPaint::kUTF8_TextEncoding },
77bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        { uni_to_utf16, SkPaint::kUTF16_TextEncoding },
78bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        { uni_to_utf32, SkPaint::kUTF32_TextEncoding },
79bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    };
80bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com
81e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    SkRandom rand;
82bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    SkPaint paint;
83bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    paint.setTypeface(SkTypeface::RefDefault())->unref();
84bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    SkTypeface* face = paint.getTypeface();
85bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com
86bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    for (int i = 0; i < 1000; ++i) {
87bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        // generate some random text
88bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        for (int j = 0; j < NGLYPHS; ++j) {
89bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com            src[j] = ' ' + j;
90bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        }
91bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        // inject some random chars, to sometimes abort early
92bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        src[rand.nextU() & 63] = rand.nextU() & 0xFFF;
9398a196770cc7b9914ad68367c5b06829a5e0b440skia.committer@gmail.com
94bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        for (size_t k = 0; k < SK_ARRAY_COUNT(gRec); ++k) {
95bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com            paint.setTextEncoding(gRec[k].fEncoding);
96bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com
97bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com            size_t len = gRec[k].fSeedTextProc(src, dst, NGLYPHS);
9898a196770cc7b9914ad68367c5b06829a5e0b440skia.committer@gmail.com
99bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com            uint16_t    glyphs0[NGLYPHS], glyphs1[NGLYPHS];
10098a196770cc7b9914ad68367c5b06829a5e0b440skia.committer@gmail.com
101bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com            bool contains = paint.containsText(dst, len);
102bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com            int nglyphs = paint.textToGlyphs(dst, len, glyphs0);
103bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com            int first = face->charsToGlyphs(dst, paint2encoding(paint), glyphs1, NGLYPHS);
104bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com            int index = find_first_zero(glyphs1, NGLYPHS);
105bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com
106bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com            REPORTER_ASSERT(reporter, NGLYPHS == nglyphs);
107bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com            REPORTER_ASSERT(reporter, index == first);
108e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org            REPORTER_ASSERT(reporter, 0 == memcmp(glyphs0, glyphs1, NGLYPHS * sizeof(uint16_t)));
109bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com            if (contains) {
110bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com                REPORTER_ASSERT(reporter, NGLYPHS == first);
111bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com            } else {
112bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com                REPORTER_ASSERT(reporter, NGLYPHS > first);
113bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com            }
114bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com        }
115bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com    }
116bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com}
117b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com
11825b3bd58dfaf0d1704c48ed3a50e1482fd336e62reed@google.com// temparary api for bicubic, just be sure we can set/clear it
119e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.orgDEF_TEST(Paint_filterlevel, reporter) {
1209cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com    SkPaint p0, p1;
1215c561cb8d8151d38c69128345106cbf225033a1askia.committer@gmail.com
1229cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com    REPORTER_ASSERT(reporter,
1239cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com                    SkPaint::kNone_FilterLevel == p0.getFilterLevel());
1245c561cb8d8151d38c69128345106cbf225033a1askia.committer@gmail.com
1259cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com    static const SkPaint::FilterLevel gLevels[] = {
1269cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com        SkPaint::kNone_FilterLevel,
1279cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com        SkPaint::kLow_FilterLevel,
1289cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com        SkPaint::kMedium_FilterLevel,
1299cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com        SkPaint::kHigh_FilterLevel
1309cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com    };
1319cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gLevels); ++i) {
1329cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com        p0.setFilterLevel(gLevels[i]);
1339cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com        REPORTER_ASSERT(reporter, gLevels[i] == p0.getFilterLevel());
1349cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com        p1 = p0;
1359cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com        REPORTER_ASSERT(reporter, gLevels[i] == p1.getFilterLevel());
1369cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com
1379cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com        p0.reset();
1389cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com        REPORTER_ASSERT(reporter,
1399cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com                        SkPaint::kNone_FilterLevel == p0.getFilterLevel());
1409cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com    }
14125b3bd58dfaf0d1704c48ed3a50e1482fd336e62reed@google.com}
14225b3bd58dfaf0d1704c48ed3a50e1482fd336e62reed@google.com
143e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.orgDEF_TEST(Paint_copy, reporter) {
144b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    SkPaint paint;
145b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    // set a few member variables
146b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    paint.setStyle(SkPaint::kStrokeAndFill_Style);
147b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    paint.setTextAlign(SkPaint::kLeft_Align);
148b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    paint.setStrokeWidth(SkIntToScalar(2));
149b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    // set a few pointers
15073cb15351f33459e0c861a96135c634dec77ef9dcommit-bot@chromium.org    SkLayerDrawLooper::Builder looperBuilder;
15173cb15351f33459e0c861a96135c634dec77ef9dcommit-bot@chromium.org    SkLayerDrawLooper* looper = looperBuilder.detachLooper();
152b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    paint.setLooper(looper)->unref();
153e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org    SkMaskFilter* mask = SkBlurMaskFilter::Create(kNormal_SkBlurStyle,
154b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com                                      SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(1)));
155b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    paint.setMaskFilter(mask)->unref();
156b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com
157b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    // copy the paint using the copy constructor and check they are the same
158b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    SkPaint copiedPaint = paint;
159b265741cc17f897b349caacdb890119e4111a415robertphillips@google.com    REPORTER_ASSERT(reporter, paint == copiedPaint);
160b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com
161b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
162b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    // the copy constructor should preserve the Generation ID
163efbe8e9bedda21a3e061ebf3d96431a0f250a654djsollen@google.com    uint32_t paintGenID = paint.getGenerationID();
164efbe8e9bedda21a3e061ebf3d96431a0f250a654djsollen@google.com    uint32_t copiedPaintGenID = copiedPaint.getGenerationID();
165b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    REPORTER_ASSERT(reporter, paintGenID == copiedPaintGenID);
166e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org    REPORTER_ASSERT(reporter, paint == copiedPaint);
167b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com#endif
168b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com
169b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    // copy the paint using the equal operator and check they are the same
170b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    copiedPaint = paint;
171b265741cc17f897b349caacdb890119e4111a415robertphillips@google.com    REPORTER_ASSERT(reporter, paint == copiedPaint);
172b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com
173b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
174b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    // the equals operator should increment the Generation ID
175b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    REPORTER_ASSERT(reporter, paint.getGenerationID() == paintGenID);
176b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    REPORTER_ASSERT(reporter, copiedPaint.getGenerationID() != copiedPaintGenID);
177b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    copiedPaintGenID = copiedPaint.getGenerationID(); // reset to the new value
178e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org    REPORTER_ASSERT(reporter, paint == copiedPaint);  // operator== ignores fGenerationID
179b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com#endif
180b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com
181b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    // clean the paint and check they are back to their initial states
182b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    SkPaint cleanPaint;
183b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    paint.reset();
184b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    copiedPaint.reset();
185b265741cc17f897b349caacdb890119e4111a415robertphillips@google.com    REPORTER_ASSERT(reporter, cleanPaint == paint);
186b265741cc17f897b349caacdb890119e4111a415robertphillips@google.com    REPORTER_ASSERT(reporter, cleanPaint == copiedPaint);
187b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com
188b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
189b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    // the reset function should increment the Generation ID
190b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    REPORTER_ASSERT(reporter, paint.getGenerationID() != paintGenID);
191b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    REPORTER_ASSERT(reporter, copiedPaint.getGenerationID() != copiedPaintGenID);
192e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org    // operator== ignores fGenerationID
193e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org    REPORTER_ASSERT(reporter, cleanPaint == paint);
194e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org    REPORTER_ASSERT(reporter, cleanPaint == copiedPaint);
195b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com#endif
196b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com}
197a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
198a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com// found and fixed for webkit: mishandling when we hit recursion limit on
199a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com// mostly degenerate cubic flatness test
200e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.orgDEF_TEST(Paint_regression_cubic, reporter) {
201a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    SkPath path, stroke;
202a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    SkPaint paint;
203a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
2044b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    path.moveTo(460.2881309415525f,
2054b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                303.250847066498f);
2064b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    path.cubicTo(463.36378422175284f,
2074b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                 302.1169735073363f,
2084b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                 456.32239330810046f,
2094b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                 304.720354932878f,
2104b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                 453.15255460013304f,
2114b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                 305.788586869862f);
212d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
213a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    SkRect fillR, strokeR;
214a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    fillR = path.getBounds();
215a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
216a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    paint.setStyle(SkPaint::kStroke_Style);
217a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    paint.setStrokeWidth(SkIntToScalar(2));
218a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    paint.getFillPath(path, &stroke);
219a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    strokeR = stroke.getBounds();
220a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
221a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    SkRect maxR = fillR;
222a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    SkScalar miter = SkMaxScalar(SK_Scalar1, paint.getStrokeMiter());
223a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    SkScalar inset = paint.getStrokeJoin() == SkPaint::kMiter_Join ?
224a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com                            SkScalarMul(paint.getStrokeWidth(), miter) :
225a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com                            paint.getStrokeWidth();
226a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    maxR.inset(-inset, -inset);
227a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
228a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    // test that our stroke didn't explode
229a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    REPORTER_ASSERT(reporter, maxR.contains(strokeR));
230a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com}
231a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
23285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.orgDEF_TEST(Paint_flattening, reporter) {
23385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    const SkPaint::FilterLevel levels[] = {
23485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kNone_FilterLevel,
23585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kLow_FilterLevel,
23685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kMedium_FilterLevel,
23785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kHigh_FilterLevel,
23885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    };
23985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    const SkPaint::Hinting hinting[] = {
24085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kNo_Hinting,
24185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kSlight_Hinting,
24285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kNormal_Hinting,
24385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kFull_Hinting,
24485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    };
24585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    const SkPaint::Align align[] = {
24685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kLeft_Align,
24785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kCenter_Align,
24885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kRight_Align
24985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    };
25085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    const SkPaint::Cap caps[] = {
25185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kButt_Cap,
25285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kRound_Cap,
25385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kSquare_Cap,
25485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    };
25585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    const SkPaint::Join joins[] = {
25685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kMiter_Join,
25785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kRound_Join,
25885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kBevel_Join,
25985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    };
26085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    const SkPaint::TextEncoding encodings[] = {
26185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kUTF8_TextEncoding,
26285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kUTF16_TextEncoding,
26385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kUTF32_TextEncoding,
26485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kGlyphID_TextEncoding,
26585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    };
26685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    const SkPaint::Style styles[] = {
26785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kFill_Style,
26885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kStroke_Style,
26985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kStrokeAndFill_Style,
27085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    };
27185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org
27285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org#define FOR_SETUP(index, array, setter)                                 \
27385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    for (size_t index = 0; index < SK_ARRAY_COUNT(array); ++index) {    \
27485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        paint.setter(array[index]);                                     \
27585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org
27685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    SkPaint paint;
27785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    paint.setFlags(0x1234);
27885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org
27985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    FOR_SETUP(i, levels, setFilterLevel)
28085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    FOR_SETUP(j, hinting, setHinting)
28185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    FOR_SETUP(k, align, setTextAlign)
28285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    FOR_SETUP(l, caps, setStrokeCap)
28385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    FOR_SETUP(m, joins, setStrokeJoin)
28485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    FOR_SETUP(n, encodings, setTextEncoding)
28585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    FOR_SETUP(p, styles, setStyle)
28685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org
28785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    SkWriteBuffer writer;
28885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    paint.flatten(writer);
28985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org
29085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    const uint32_t* written = writer.getWriter32()->contiguousArray();
29185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    SkReadBuffer reader(written, writer.bytesWritten());
292667b98d947892cec939669bccf204ab9ed565c4eskia.committer@gmail.com
29385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    SkPaint paint2;
29485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    paint2.unflatten(reader);
29585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    REPORTER_ASSERT(reporter, paint2 == paint);
29685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org
29785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    }}}}}}}
29885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org#undef FOR_SETUP
29985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org
30085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org}
30185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org
30246348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com// found and fixed for android: not initializing rect for string's of length 0
303e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.orgDEF_TEST(Paint_regression_measureText, reporter) {
30446348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com
30546348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com    SkPaint paint;
3064b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    paint.setTextSize(12.0f);
30746348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com
30846348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com    SkRect r;
30946348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com    r.setLTRB(SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN);
31046348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com
31146348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com    // test that the rect was reset
3124b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    paint.measureText("", 0, &r, 1.0f);
31346348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com    REPORTER_ASSERT(reporter, r.isEmpty());
31446348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com}
31546348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com
316aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#define ASSERT(expr) REPORTER_ASSERT(r, expr)
317aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org
318aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.orgDEF_TEST(Paint_FlatteningTraits, r) {
319aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    SkPaint paint;
320aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    paint.setColor(0x00AABBCC);
321aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    paint.setTextScaleX(1.0f);  // Encoded despite being the default value.
322aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    paint.setTextSize(19);
323aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    paint.setXfermode(SkXfermode::Create(SkXfermode::kModulate_Mode))->unref();
324aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    paint.setLooper(NULL);  // Ignored.
325aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org
326aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    SkWriteBuffer writer;
327aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    SkPaint::FlatteningTraits::Flatten(writer, paint);
328273a00d14f78c34c4654bf6aef3e5bdb7cf105d2reed@google.com    const size_t expectedBytesWritten = sizeof(void*) == 8 ? 36 : 32;
329aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    ASSERT(expectedBytesWritten == writer.bytesWritten());
330aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org
331aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    const uint32_t* written = writer.getWriter32()->contiguousArray();
332aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    SkASSERT(written != NULL);
33345d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org    ASSERT(*written == ((1<<0) | (1<<1) | (1<<2) | (1<<8)));  // Dirty bits for our 4.
334aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org
335aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    SkReadBuffer reader(written, writer.bytesWritten());
336aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    SkPaint other;
337aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    SkPaint::FlatteningTraits::Unflatten(reader, &other);
338aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    ASSERT(reader.offset() == writer.bytesWritten());
339aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org
340aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    // No matter the encoding, these must always hold.
341aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    ASSERT(other.getColor()      == paint.getColor());
342aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    ASSERT(other.getTextScaleX() == paint.getTextScaleX());
343aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    ASSERT(other.getTextSize()   == paint.getTextSize());
344aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    ASSERT(other.getLooper()     == paint.getLooper());
345aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org
346aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    // We have to be a little looser and compare just the modes.  Pointers might not be the same.
347aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    SkXfermode::Mode otherMode, paintMode;
348aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    ASSERT(other.getXfermode()->asMode(&otherMode));
349aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    ASSERT(paint.getXfermode()->asMode(&paintMode));
350aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    ASSERT(otherMode == paintMode);
351aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org}
352