11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc.
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
8215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed#include "Test.h"
9215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed#include "SkPath.h"
10215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed#include "SkPaint.h"
111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkLayerDrawLooper.h"
121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkBlurMaskFilter.h"
131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_copy(skiatest::Reporter* reporter) {
151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPaint paint;
161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // set a few member variables
171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.setStyle(SkPaint::kStrokeAndFill_Style);
181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.setTextAlign(SkPaint::kLeft_Align);
191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.setStrokeWidth(SkIntToScalar(2));
201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // set a few pointers
211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkLayerDrawLooper* looper = new SkLayerDrawLooper();
221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.setLooper(looper)->unref();
231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkMaskFilter* mask = SkBlurMaskFilter::Create(1, SkBlurMaskFilter::kNormal_BlurStyle);
241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.setMaskFilter(mask)->unref();
251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // copy the paint using the copy constructor and check they are the same
271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPaint copiedPaint = paint;
281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, paint == copiedPaint);
291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // the copy constructor should preserve the Generation ID
321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int32_t paintGenID = paint.getGenerationID();
331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int32_t copiedPaintGenID = copiedPaint.getGenerationID();
341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, paintGenID == copiedPaintGenID);
351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, !memcmp(&paint, &copiedPaint, sizeof(paint)));
361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // copy the paint using the equal operator and check they are the same
391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    copiedPaint = paint;
401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, paint == copiedPaint);
411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // the equals operator should increment the Generation ID
441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, paint.getGenerationID() == paintGenID);
451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, copiedPaint.getGenerationID() != copiedPaintGenID);
461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    copiedPaintGenID = copiedPaint.getGenerationID(); // reset to the new value
471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, memcmp(&paint, &copiedPaint, sizeof(paint)));
481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // clean the paint and check they are back to their initial states
511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPaint cleanPaint;
521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.reset();
531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    copiedPaint.reset();
541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, cleanPaint == paint);
551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, cleanPaint == copiedPaint);
561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // the reset function should increment the Generation ID
591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, paint.getGenerationID() != paintGenID);
601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, copiedPaint.getGenerationID() != copiedPaintGenID);
611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, memcmp(&cleanPaint, &paint, sizeof(cleanPaint)));
621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    REPORTER_ASSERT(reporter, memcmp(&cleanPaint, &copiedPaint, sizeof(cleanPaint)));
631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
65215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed
66215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed// found and fixed for webkit: mishandling when we hit recursion limit on
67215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed// mostly degenerate cubic flatness test
68215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reedstatic void regression_cubic(skiatest::Reporter* reporter) {
69215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    SkPath path, stroke;
70215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    SkPaint paint;
71215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed
7205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    path.moveTo(SkFloatToFixed(460.2881309415525f),
7305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                SkFloatToFixed(303.250847066498));
7405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    path.cubicTo(SkFloatToFixed(463.36378422175284),
7505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                 SkFloatToFixed(302.1169735073363),
7605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                 SkFloatToFixed(456.32239330810046),
7705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                 SkFloatToFixed(304.720354932878),
7805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                 SkFloatToFixed(453.15255460013304),
7905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                 SkFloatToFixed(305.788586869862));
80215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed
81215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    SkRect fillR, strokeR;
82215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    fillR = path.getBounds();
83215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed
84215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    paint.setStyle(SkPaint::kStroke_Style);
85215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    paint.setStrokeWidth(SkIntToScalar(2));
86215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    paint.getFillPath(path, &stroke);
87215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    strokeR = stroke.getBounds();
88215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed
89215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    SkRect maxR = fillR;
90215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    SkScalar miter = SkMaxScalar(SK_Scalar1, paint.getStrokeMiter());
91215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    SkScalar inset = paint.getStrokeJoin() == SkPaint::kMiter_Join ?
92215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed                            SkScalarMul(paint.getStrokeWidth(), miter) :
93215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed                            paint.getStrokeWidth();
94215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    maxR.inset(-inset, -inset);
95215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed
96215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    // test that our stroke didn't explode
97215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    REPORTER_ASSERT(reporter, maxR.contains(strokeR));
98215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed}
99215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed
100215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reedstatic void TestPaint(skiatest::Reporter* reporter) {
101215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    // TODO add general paint tests
1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    test_copy(reporter);
103215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed
104215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    // regression tests
105215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed    regression_cubic(reporter);
106215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed}
107215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed
108215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed#include "TestClassDef.h"
109215473cea1702d8acc0316da3e5a9bf4ce0130efMike ReedDEFINE_TESTCLASS("Paint", TestPaintClass, TestPaint)
110