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 "SkLineClipper.h" 11215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed#include "SkEdgeClipper.h" 12215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test_edgeclipper(skiatest::Reporter* reporter) { 141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkEdgeClipper clipper; 151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPoint pts[] = { 171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { SkFloatToScalar(3.0995476e+010), SkFloatToScalar(42.929779) }, 181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { SkFloatToScalar(-3.0995163e+010), SkFloatToScalar(51.050385) }, 191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { SkFloatToScalar(-3.0995157e+010), SkFloatToScalar(51.050392) }, 201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { SkFloatToScalar(-3.0995134e+010), SkFloatToScalar(51.050400) }, 211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger }; 221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkRect clip = { 0, 0, SkIntToScalar(300), SkIntToScalar(200) }; 241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // this should not assert, even though our choppers do a poor numerical 261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // job when computing their t values. 271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // http://code.google.com/p/skia/issues/detail?id=444 281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger clipper.clipCubic(pts, clip); 291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 31215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reedstatic void test_intersectline(skiatest::Reporter* reporter) { 32215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed static const SkScalar L = 0; 33215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed static const SkScalar T = 0; 34215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed static const SkScalar R = SkIntToScalar(100); 35215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed static const SkScalar B = SkIntToScalar(100); 36215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed static const SkScalar CX = SkScalarHalf(L + R); 37215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed static const SkScalar CY = SkScalarHalf(T + B); 38215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed static const SkRect gR = { L, T, R, B }; 39215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 40215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed size_t i; 41215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkPoint dst[2]; 42215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 43215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed static const SkPoint gEmpty[] = { 44215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed // sides 45215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { L, CY }, { L - 10, CY }, 46215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { R, CY }, { R + 10, CY }, 47215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { CX, T }, { CX, T - 10 }, 48215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { CX, B }, { CX, B + 10 }, 49215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed // corners 50215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { L, T }, { L - 10, T - 10 }, 51215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { L, B }, { L - 10, B + 10 }, 52215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { R, T }, { R + 10, T - 10 }, 53215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { R, B }, { R + 10, B + 10 }, 54215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed }; 55215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed for (i = 0; i < SK_ARRAY_COUNT(gEmpty); i += 2) { 56215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed bool valid = SkLineClipper::IntersectLine(&gEmpty[i], gR, dst); 57215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed if (valid) { 58215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkDebugf("----- [%d] %g %g -> %g %g\n", i/2, dst[0].fX, dst[0].fY, dst[1].fX, dst[1].fY); 59215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 60215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, !valid); 61215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 62215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 63215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed static const SkPoint gFull[] = { 64215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed // diagonals, chords 65215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { L, T }, { R, B }, 66215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { L, B }, { R, T }, 67215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { CX, T }, { CX, B }, 68215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { L, CY }, { R, CY }, 69215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { CX, T }, { R, CY }, 70215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { CX, T }, { L, CY }, 71215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { L, CY }, { CX, B }, 72215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { R, CY }, { CX, B }, 73215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed // edges 74215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { L, T }, { L, B }, 75215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { R, T }, { R, B }, 76215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { L, T }, { R, T }, 77215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { L, B }, { R, B }, 78215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed }; 79215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed for (i = 0; i < SK_ARRAY_COUNT(gFull); i += 2) { 80215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed bool valid = SkLineClipper::IntersectLine(&gFull[i], gR, dst); 81215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed if (!valid || memcmp(&gFull[i], dst, sizeof(dst))) { 82215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkDebugf("++++ [%d] %g %g -> %g %g\n", i/2, dst[0].fX, dst[0].fY, dst[1].fX, dst[1].fY); 83215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 84215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, valid && !memcmp(&gFull[i], dst, sizeof(dst))); 85215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 86215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 87215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed static const SkPoint gPartial[] = { 88215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { L - 10, CY }, { CX, CY }, { L, CY }, { CX, CY }, 89215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { CX, T - 10 }, { CX, CY }, { CX, T }, { CX, CY }, 90215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { R + 10, CY }, { CX, CY }, { R, CY }, { CX, CY }, 91215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { CX, B + 10 }, { CX, CY }, { CX, B }, { CX, CY }, 92215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed // extended edges 93215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { L, T - 10 }, { L, B + 10 }, { L, T }, { L, B }, 94215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { R, T - 10 }, { R, B + 10 }, { R, T }, { R, B }, 95215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { L - 10, T }, { R + 10, T }, { L, T }, { R, T }, 96215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed { L - 10, B }, { R + 10, B }, { L, B }, { R, B }, 97215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed }; 98215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed for (i = 0; i < SK_ARRAY_COUNT(gPartial); i += 4) { 99215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed bool valid = SkLineClipper::IntersectLine(&gPartial[i], gR, dst); 100215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed if (!valid || memcmp(&gPartial[i+2], dst, sizeof(dst))) { 101215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed SkDebugf("++++ [%d] %g %g -> %g %g\n", i/2, dst[0].fX, dst[0].fY, dst[1].fX, dst[1].fY); 102215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 103215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed REPORTER_ASSERT(reporter, valid && 104215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed !memcmp(&gPartial[i+2], dst, sizeof(dst))); 105215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed } 106215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 107215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed} 108215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 109215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reedvoid TestClipper(skiatest::Reporter* reporter) { 110215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed test_intersectline(reporter); 1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger test_edgeclipper(reporter); 112215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed} 113215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed 114215473cea1702d8acc0316da3e5a9bf4ce0130efMike Reed#include "TestClassDef.h" 115215473cea1702d8acc0316da3e5a9bf4ce0130efMike ReedDEFINE_TESTCLASS("Clipper", TestClipperClass, TestClipper) 116