1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8#include "Test.h"
9#include "SkPath.h"
10#include "SkPaint.h"
11#include "SkLayerDrawLooper.h"
12#include "SkBlurMaskFilter.h"
13
14static void test_copy(skiatest::Reporter* reporter) {
15    SkPaint paint;
16    // set a few member variables
17    paint.setStyle(SkPaint::kStrokeAndFill_Style);
18    paint.setTextAlign(SkPaint::kLeft_Align);
19    paint.setStrokeWidth(SkIntToScalar(2));
20    // set a few pointers
21    SkLayerDrawLooper* looper = new SkLayerDrawLooper();
22    paint.setLooper(looper)->unref();
23    SkMaskFilter* mask = SkBlurMaskFilter::Create(1, SkBlurMaskFilter::kNormal_BlurStyle);
24    paint.setMaskFilter(mask)->unref();
25
26    // copy the paint using the copy constructor and check they are the same
27    SkPaint copiedPaint = paint;
28    REPORTER_ASSERT(reporter, paint == copiedPaint);
29
30#ifdef SK_BUILD_FOR_ANDROID
31    // the copy constructor should preserve the Generation ID
32    int32_t paintGenID = paint.getGenerationID();
33    int32_t copiedPaintGenID = copiedPaint.getGenerationID();
34    REPORTER_ASSERT(reporter, paintGenID == copiedPaintGenID);
35    REPORTER_ASSERT(reporter, !memcmp(&paint, &copiedPaint, sizeof(paint)));
36#endif
37
38    // copy the paint using the equal operator and check they are the same
39    copiedPaint = paint;
40    REPORTER_ASSERT(reporter, paint == copiedPaint);
41
42#ifdef SK_BUILD_FOR_ANDROID
43    // the equals operator should increment the Generation ID
44    REPORTER_ASSERT(reporter, paint.getGenerationID() == paintGenID);
45    REPORTER_ASSERT(reporter, copiedPaint.getGenerationID() != copiedPaintGenID);
46    copiedPaintGenID = copiedPaint.getGenerationID(); // reset to the new value
47    REPORTER_ASSERT(reporter, memcmp(&paint, &copiedPaint, sizeof(paint)));
48#endif
49
50    // clean the paint and check they are back to their initial states
51    SkPaint cleanPaint;
52    paint.reset();
53    copiedPaint.reset();
54    REPORTER_ASSERT(reporter, cleanPaint == paint);
55    REPORTER_ASSERT(reporter, cleanPaint == copiedPaint);
56
57#ifdef SK_BUILD_FOR_ANDROID
58    // the reset function should increment the Generation ID
59    REPORTER_ASSERT(reporter, paint.getGenerationID() != paintGenID);
60    REPORTER_ASSERT(reporter, copiedPaint.getGenerationID() != copiedPaintGenID);
61    REPORTER_ASSERT(reporter, memcmp(&cleanPaint, &paint, sizeof(cleanPaint)));
62    REPORTER_ASSERT(reporter, memcmp(&cleanPaint, &copiedPaint, sizeof(cleanPaint)));
63#endif
64}
65
66// found and fixed for webkit: mishandling when we hit recursion limit on
67// mostly degenerate cubic flatness test
68static void regression_cubic(skiatest::Reporter* reporter) {
69    SkPath path, stroke;
70    SkPaint paint;
71
72    path.moveTo(SkFloatToFixed(460.2881309415525f),
73                SkFloatToFixed(303.250847066498));
74    path.cubicTo(SkFloatToFixed(463.36378422175284),
75                 SkFloatToFixed(302.1169735073363),
76                 SkFloatToFixed(456.32239330810046),
77                 SkFloatToFixed(304.720354932878),
78                 SkFloatToFixed(453.15255460013304),
79                 SkFloatToFixed(305.788586869862));
80
81    SkRect fillR, strokeR;
82    fillR = path.getBounds();
83
84    paint.setStyle(SkPaint::kStroke_Style);
85    paint.setStrokeWidth(SkIntToScalar(2));
86    paint.getFillPath(path, &stroke);
87    strokeR = stroke.getBounds();
88
89    SkRect maxR = fillR;
90    SkScalar miter = SkMaxScalar(SK_Scalar1, paint.getStrokeMiter());
91    SkScalar inset = paint.getStrokeJoin() == SkPaint::kMiter_Join ?
92                            SkScalarMul(paint.getStrokeWidth(), miter) :
93                            paint.getStrokeWidth();
94    maxR.inset(-inset, -inset);
95
96    // test that our stroke didn't explode
97    REPORTER_ASSERT(reporter, maxR.contains(strokeR));
98}
99
100static void TestPaint(skiatest::Reporter* reporter) {
101    // TODO add general paint tests
102    test_copy(reporter);
103
104    // regression tests
105    regression_cubic(reporter);
106}
107
108#include "TestClassDef.h"
109DEFINE_TESTCLASS("Paint", TestPaintClass, TestPaint)
110