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
895e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "SkAutoMalloc.h"
9b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com#include "SkBlurMask.h"
10b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com#include "SkBlurMaskFilter.h"
11b7061176c7f414616fe2e79e832b3e0abe326af6robertphillips@google.com#include "SkLayerDrawLooper.h"
12a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com#include "SkPaint.h"
138f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "SkPath.h"
14bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com#include "SkRandom.h"
15aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#include "SkReadBuffer.h"
16bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com#include "SkTypeface.h"
17bcb42aecf1bdb9ae80d766d203b4f636b954cf03reed@google.com#include "SkUtils.h"
18aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#include "SkWriteBuffer.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) {
24fbaace082745a0e301186b2d3b84af62e2fb87ecbsalomon        int n = SkToInt(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) {
33fbaace082745a0e301186b2d3b84af62e2fb87ecbsalomon        int n = SkToInt(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;
8313b9c95295f4c5732e34574789e721a6bc08f7b4bungeman    paint.setTypeface(SkTypeface::MakeDefault());
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
11993a1215fe0ab007ce941c721f1fd3e9dcb5d4754reedDEF_TEST(Paint_filterQuality, reporter) {
1209cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com    SkPaint p0, p1;
1215c561cb8d8151d38c69128345106cbf225033a1askia.committer@gmail.com
12293a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed    REPORTER_ASSERT(reporter, kNone_SkFilterQuality == p0.getFilterQuality());
1235c561cb8d8151d38c69128345106cbf225033a1askia.committer@gmail.com
12493a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed    static const SkFilterQuality gQualitys[] = {
12593a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        kNone_SkFilterQuality,
12693a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        kLow_SkFilterQuality,
12793a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        kMedium_SkFilterQuality,
12893a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        kHigh_SkFilterQuality
1299cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com    };
13093a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed    for (size_t i = 0; i < SK_ARRAY_COUNT(gQualitys); ++i) {
13193a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        p0.setFilterQuality(gQualitys[i]);
13293a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        REPORTER_ASSERT(reporter, gQualitys[i] == p0.getFilterQuality());
1339cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com        p1 = p0;
13493a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        REPORTER_ASSERT(reporter, gQualitys[i] == p1.getFilterQuality());
1359cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com
1369cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com        p0.reset();
13793a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        REPORTER_ASSERT(reporter, kNone_SkFilterQuality == p0.getFilterQuality());
1389cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com    }
13925b3bd58dfaf0d1704c48ed3a50e1482fd336e62reed@google.com}
14025b3bd58dfaf0d1704c48ed3a50e1482fd336e62reed@google.com
141e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.orgDEF_TEST(Paint_copy, reporter) {
142b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    SkPaint paint;
143b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    // set a few member variables
144b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    paint.setStyle(SkPaint::kStrokeAndFill_Style);
145b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    paint.setTextAlign(SkPaint::kLeft_Align);
146b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    paint.setStrokeWidth(SkIntToScalar(2));
147b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    // set a few pointers
14873cb15351f33459e0c861a96135c634dec77ef9dcommit-bot@chromium.org    SkLayerDrawLooper::Builder looperBuilder;
1497b380d0d0e91ae6967c52bfa14853a77b9551de4reed    paint.setLooper(looperBuilder.detach());
150efdfd51b68a300d5c6e28743fe0344ca05d1cec9reed    paint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
151efdfd51b68a300d5c6e28743fe0344ca05d1cec9reed                                               SkBlurMask::ConvertRadiusToSigma(1)));
152b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com
153b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    // copy the paint using the copy constructor and check they are the same
154b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    SkPaint copiedPaint = paint;
155b265741cc17f897b349caacdb890119e4111a415robertphillips@google.com    REPORTER_ASSERT(reporter, paint == copiedPaint);
156b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com
157b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    // copy the paint using the equal operator and check they are the same
158b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    copiedPaint = paint;
159b265741cc17f897b349caacdb890119e4111a415robertphillips@google.com    REPORTER_ASSERT(reporter, paint == copiedPaint);
160b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com
161b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    // clean the paint and check they are back to their initial states
162b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    SkPaint cleanPaint;
163b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    paint.reset();
164b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com    copiedPaint.reset();
165b265741cc17f897b349caacdb890119e4111a415robertphillips@google.com    REPORTER_ASSERT(reporter, cleanPaint == paint);
166b265741cc17f897b349caacdb890119e4111a415robertphillips@google.com    REPORTER_ASSERT(reporter, cleanPaint == copiedPaint);
167b44cd65a53fa016a238e2bd3d01b5434dbc05da3djsollen@google.com}
168a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
169a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com// found and fixed for webkit: mishandling when we hit recursion limit on
170a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com// mostly degenerate cubic flatness test
171e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.orgDEF_TEST(Paint_regression_cubic, reporter) {
172a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    SkPath path, stroke;
173a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    SkPaint paint;
174a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
1754b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    path.moveTo(460.2881309415525f,
1764b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                303.250847066498f);
1774b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    path.cubicTo(463.36378422175284f,
1784b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                 302.1169735073363f,
1794b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                 456.32239330810046f,
1804b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                 304.720354932878f,
1814b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                 453.15255460013304f,
1824b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org                 305.788586869862f);
183d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
184a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    SkRect fillR, strokeR;
185a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    fillR = path.getBounds();
186a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
187a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    paint.setStyle(SkPaint::kStroke_Style);
188a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    paint.setStrokeWidth(SkIntToScalar(2));
189a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    paint.getFillPath(path, &stroke);
190a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    strokeR = stroke.getBounds();
191a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
192a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    SkRect maxR = fillR;
193a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    SkScalar miter = SkMaxScalar(SK_Scalar1, paint.getStrokeMiter());
194a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    SkScalar inset = paint.getStrokeJoin() == SkPaint::kMiter_Join ?
195df85c38163245c7fc3c23cad3a4ad104949f3a62Mike Reed                            paint.getStrokeWidth() * miter :
196a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com                            paint.getStrokeWidth();
197a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    maxR.inset(-inset, -inset);
198a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
199a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    // test that our stroke didn't explode
200a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com    REPORTER_ASSERT(reporter, maxR.contains(strokeR));
201a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com}
202a0f5d1546d499ef0cd7dbfba9a866ae5a27e1541reed@android.com
20385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.orgDEF_TEST(Paint_flattening, reporter) {
20493a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed    const SkFilterQuality levels[] = {
20593a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        kNone_SkFilterQuality,
20693a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        kLow_SkFilterQuality,
20793a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        kMedium_SkFilterQuality,
20893a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        kHigh_SkFilterQuality,
20985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    };
21085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    const SkPaint::Hinting hinting[] = {
21185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kNo_Hinting,
21285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kSlight_Hinting,
21385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kNormal_Hinting,
21485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kFull_Hinting,
21585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    };
21685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    const SkPaint::Align align[] = {
21785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kLeft_Align,
21885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kCenter_Align,
21985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kRight_Align
22085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    };
22185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    const SkPaint::Cap caps[] = {
22285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kButt_Cap,
22385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kRound_Cap,
22485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kSquare_Cap,
22585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    };
22685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    const SkPaint::Join joins[] = {
22785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kMiter_Join,
22885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kRound_Join,
22985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kBevel_Join,
23085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    };
23185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    const SkPaint::TextEncoding encodings[] = {
23285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kUTF8_TextEncoding,
23385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kUTF16_TextEncoding,
23485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kUTF32_TextEncoding,
23585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kGlyphID_TextEncoding,
23685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    };
23785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    const SkPaint::Style styles[] = {
23885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kFill_Style,
23985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kStroke_Style,
24085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        SkPaint::kStrokeAndFill_Style,
24185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    };
24285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org
24385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org#define FOR_SETUP(index, array, setter)                                 \
24485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    for (size_t index = 0; index < SK_ARRAY_COUNT(array); ++index) {    \
24585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org        paint.setter(array[index]);                                     \
24685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org
24785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    SkPaint paint;
24885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    paint.setFlags(0x1234);
24985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org
25093a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed    FOR_SETUP(i, levels, setFilterQuality)
25185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    FOR_SETUP(j, hinting, setHinting)
25285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    FOR_SETUP(k, align, setTextAlign)
25385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    FOR_SETUP(l, caps, setStrokeCap)
25485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    FOR_SETUP(m, joins, setStrokeJoin)
25585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    FOR_SETUP(n, encodings, setTextEncoding)
25685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    FOR_SETUP(p, styles, setStyle)
25785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org
258fad98562d8f9db63839a8d902a301b174320f27fbrianosman    SkBinaryWriteBuffer writer;
25985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    paint.flatten(writer);
26085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org
261b4c899d48d4c5d8e867beb611551f7b55ec60abbmtklein    SkAutoMalloc buf(writer.bytesWritten());
262b4c899d48d4c5d8e867beb611551f7b55ec60abbmtklein    writer.writeToMemory(buf.get());
263b4c899d48d4c5d8e867beb611551f7b55ec60abbmtklein    SkReadBuffer reader(buf.get(), writer.bytesWritten());
264667b98d947892cec939669bccf204ab9ed565c4eskia.committer@gmail.com
26585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    SkPaint paint2;
26685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    paint2.unflatten(reader);
26785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    REPORTER_ASSERT(reporter, paint2 == paint);
26885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org
26985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org    }}}}}}}
27085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org#undef FOR_SETUP
27185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org
27285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org}
27385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org
27446348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com// found and fixed for android: not initializing rect for string's of length 0
275e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.orgDEF_TEST(Paint_regression_measureText, reporter) {
27646348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com
27746348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com    SkPaint paint;
2784b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    paint.setTextSize(12.0f);
27946348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com
28046348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com    SkRect r;
28146348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com    r.setLTRB(SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN);
28246348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com
28346348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com    // test that the rect was reset
28499ae881a7f55a03c2b16fb5704e6e90ea86d965dreed    paint.measureText("", 0, &r);
28546348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com    REPORTER_ASSERT(reporter, r.isEmpty());
28646348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com}
28746348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com
288aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#define ASSERT(expr) REPORTER_ASSERT(r, expr)
289aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org
290610a015fda84cd5d1e3f3f826bab393f1193bc0emtkleinDEF_TEST(Paint_MoreFlattening, r) {
291aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    SkPaint paint;
292aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    paint.setColor(0x00AABBCC);
293ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein    paint.setTextScaleX(1.0f);  // Default value, ignored.
294aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    paint.setTextSize(19);
295374772bd61951f01bf84fe17bf53d8867681c9aereed    paint.setBlendMode(SkBlendMode::kModulate);
29696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    paint.setLooper(nullptr);  // Default value, ignored.
297aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org
298fad98562d8f9db63839a8d902a301b174320f27fbrianosman    SkBinaryWriteBuffer writer;
299610a015fda84cd5d1e3f3f826bab393f1193bc0emtklein    paint.flatten(writer);
300aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org
301b4c899d48d4c5d8e867beb611551f7b55ec60abbmtklein    SkAutoMalloc buf(writer.bytesWritten());
302b4c899d48d4c5d8e867beb611551f7b55ec60abbmtklein    writer.writeToMemory(buf.get());
303b4c899d48d4c5d8e867beb611551f7b55ec60abbmtklein    SkReadBuffer reader(buf.get(), writer.bytesWritten());
304b4c899d48d4c5d8e867beb611551f7b55ec60abbmtklein
305aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    SkPaint other;
306610a015fda84cd5d1e3f3f826bab393f1193bc0emtklein    other.unflatten(reader);
307aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    ASSERT(reader.offset() == writer.bytesWritten());
308aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org
309aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    // No matter the encoding, these must always hold.
310aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    ASSERT(other.getColor()      == paint.getColor());
311aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    ASSERT(other.getTextScaleX() == paint.getTextScaleX());
312aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    ASSERT(other.getTextSize()   == paint.getTextSize());
313aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org    ASSERT(other.getLooper()     == paint.getLooper());
314374772bd61951f01bf84fe17bf53d8867681c9aereed    ASSERT(other.getBlendMode()  == paint.getBlendMode());
315aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org}
316fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein
317fb1fe4f51820731f557e765f8c71cba9a0d28048mtkleinDEF_TEST(Paint_getHash, r) {
318fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    // Try not to inspect the actual hash values in here.
319fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    // We might want to change the hash function.
320fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein
321fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    SkPaint paint;
322fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    const uint32_t defaultHash = paint.getHash();
323fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein
324fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    // Check that some arbitrary field affects the hash.
325fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    paint.setColor(0xFF00FF00);
326fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    REPORTER_ASSERT(r, paint.getHash() != defaultHash);
327fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    paint.setColor(SK_ColorBLACK);  // Reset to default value.
328fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    REPORTER_ASSERT(r, paint.getHash() == defaultHash);
329fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein
330fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    // SkTypeface is the first field we hash, so test it specially.
33113b9c95295f4c5732e34574789e721a6bc08f7b4bungeman    paint.setTypeface(SkTypeface::MakeDefault());
332fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    REPORTER_ASSERT(r, paint.getHash() != defaultHash);
33396fcdcc219d2a0d3579719b84b28bede76efba64halcanary    paint.setTypeface(nullptr);
334fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    REPORTER_ASSERT(r, paint.getHash() == defaultHash);
335fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein
336fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    // This is part of fBitfields, the last field we hash.
337fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    paint.setHinting(SkPaint::kSlight_Hinting);
338fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    REPORTER_ASSERT(r, paint.getHash() != defaultHash);
339fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    paint.setHinting(SkPaint::kNormal_Hinting);
340fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein    REPORTER_ASSERT(r, paint.getHash() == defaultHash);
341fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein}
342f539b8cdee0204985edca028eec826ee94a0c472reed
343f539b8cdee0204985edca028eec826ee94a0c472reed#include "SkColorMatrixFilter.h"
344f539b8cdee0204985edca028eec826ee94a0c472reed
345f539b8cdee0204985edca028eec826ee94a0c472reedDEF_TEST(Paint_nothingToDraw, r) {
346f539b8cdee0204985edca028eec826ee94a0c472reed    SkPaint paint;
347f539b8cdee0204985edca028eec826ee94a0c472reed
348f539b8cdee0204985edca028eec826ee94a0c472reed    REPORTER_ASSERT(r, !paint.nothingToDraw());
349f539b8cdee0204985edca028eec826ee94a0c472reed    paint.setAlpha(0);
350f539b8cdee0204985edca028eec826ee94a0c472reed    REPORTER_ASSERT(r, paint.nothingToDraw());
351f539b8cdee0204985edca028eec826ee94a0c472reed
352f539b8cdee0204985edca028eec826ee94a0c472reed    paint.setAlpha(0xFF);
353374772bd61951f01bf84fe17bf53d8867681c9aereed    paint.setBlendMode(SkBlendMode::kDst);
354f539b8cdee0204985edca028eec826ee94a0c472reed    REPORTER_ASSERT(r, paint.nothingToDraw());
355f539b8cdee0204985edca028eec826ee94a0c472reed
356f539b8cdee0204985edca028eec826ee94a0c472reed    paint.setAlpha(0);
357374772bd61951f01bf84fe17bf53d8867681c9aereed    paint.setBlendMode(SkBlendMode::kSrcOver);
358f539b8cdee0204985edca028eec826ee94a0c472reed
359f539b8cdee0204985edca028eec826ee94a0c472reed    SkColorMatrix cm;
360f539b8cdee0204985edca028eec826ee94a0c472reed    cm.setIdentity();   // does not change alpha
361d053ce9c54d4e5937a142278359e5a4cde18095ereed    paint.setColorFilter(SkColorFilter::MakeMatrixFilterRowMajor255(cm.fMat));
362f539b8cdee0204985edca028eec826ee94a0c472reed    REPORTER_ASSERT(r, paint.nothingToDraw());
363f539b8cdee0204985edca028eec826ee94a0c472reed
364f539b8cdee0204985edca028eec826ee94a0c472reed    cm.postTranslate(0, 0, 0, 1);    // wacks alpha
365d053ce9c54d4e5937a142278359e5a4cde18095ereed    paint.setColorFilter(SkColorFilter::MakeMatrixFilterRowMajor255(cm.fMat));
366f539b8cdee0204985edca028eec826ee94a0c472reed    REPORTER_ASSERT(r, !paint.nothingToDraw());
367f539b8cdee0204985edca028eec826ee94a0c472reed}
368