17839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/* 27839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Copyright 2012 Google Inc. 37839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * 47839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be 57839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * found in the LICENSE file. 67839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */ 77839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "PathOpsCubicIntersectionTestData.h" 87839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "PathOpsQuadIntersectionTestData.h" 958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "PathOpsTestCommon.h" 107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkIntersections.h" 117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkPathOpsRect.h" 127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkReduceOrder.h" 137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "Test.h" 147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 15910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger#if 0 // disable test until stroke reduction is supported 167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic bool controls_inside(const SkDCubic& cubic) { 177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return between(cubic[0].fX, cubic[1].fX, cubic[3].fX) 187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && between(cubic[0].fX, cubic[2].fX, cubic[3].fX) 197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && between(cubic[0].fY, cubic[1].fY, cubic[3].fY) 207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && between(cubic[0].fY, cubic[2].fY, cubic[3].fY); 217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic bool tiny(const SkDCubic& cubic) { 247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int index, minX, maxX, minY, maxY; 257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger minX = maxX = minY = maxY = 0; 267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = 1; index < 4; ++index) { 277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (cubic[minX].fX > cubic[index].fX) { 287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger minX = index; 297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (cubic[minY].fY > cubic[index].fY) { 317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger minY = index; 327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (cubic[maxX].fX < cubic[index].fX) { 347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger maxX = index; 357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (cubic[maxY].fY < cubic[index].fY) { 377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger maxY = index; 387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return approximately_equal(cubic[maxX].fX, cubic[minX].fX) 417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && approximately_equal(cubic[maxY].fY, cubic[minY].fY); 427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic void find_tight_bounds(const SkDCubic& cubic, SkDRect& bounds) { 457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDCubicPair cubicPair = cubic.chopAt(0.5); 467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (!tiny(cubicPair.first()) && !controls_inside(cubicPair.first())) { 477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger find_tight_bounds(cubicPair.first(), bounds); 487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } else { 497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bounds.add(cubicPair.first()[0]); 507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bounds.add(cubicPair.first()[3]); 517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (!tiny(cubicPair.second()) && !controls_inside(cubicPair.second())) { 537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger find_tight_bounds(cubicPair.second(), bounds); 547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } else { 557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bounds.add(cubicPair.second()[0]); 567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bounds.add(cubicPair.second()[3]); 577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 59910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger#endif 607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic void PathOpsReduceOrderCubicTest(skiatest::Reporter* reporter) { 627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger size_t index; 637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkReduceOrder reducer; 647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int order; 657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger enum { 667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunAll, 677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunPointDegenerates, 687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunNotPointDegenerates, 697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunLines, 707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunNotLines, 717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunModEpsilonLines, 727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunLessEpsilonLines, 737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunNegEpsilonLines, 747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunQuadraticLines, 757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunQuadraticPoints, 767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunQuadraticModLines, 777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunComputedLines, 787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunNone 797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } run = RunAll; 807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstTestIndex = 0; 817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if 0 827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger run = RunComputedLines; 837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger firstTestIndex = 18; 847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstPointDegeneratesTest = run == RunAll ? 0 : run == RunPointDegenerates 867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstNotPointDegeneratesTest = run == RunAll ? 0 : run == RunNotPointDegenerates 887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstLinesTest = run == RunAll ? 0 : run == RunLines ? firstTestIndex : SK_MaxS32; 907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstNotLinesTest = run == RunAll ? 0 : run == RunNotLines ? firstTestIndex : SK_MaxS32; 917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstModEpsilonTest = run == RunAll ? 0 : run == RunModEpsilonLines 927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstLessEpsilonTest = run == RunAll ? 0 : run == RunLessEpsilonLines 947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstNegEpsilonTest = run == RunAll ? 0 : run == RunNegEpsilonLines 967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstQuadraticPointTest = run == RunAll ? 0 : run == RunQuadraticPoints 987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstQuadraticLineTest = run == RunAll ? 0 : run == RunQuadraticLines 1007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 1017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstQuadraticModLineTest = run == RunAll ? 0 : run == RunQuadraticModLines 1027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 103910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger#if 0 1047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstComputedLinesTest = run == RunAll ? 0 : run == RunComputedLines 1057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 106910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger#endif 1077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstPointDegeneratesTest; index < pointDegenerates_count; ++index) { 1087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDCubic& cubic = pointDegenerates[index]; 10958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidCubic(cubic)); 110910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 1117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order != 1) { 1127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] pointDegenerates order=%d\n", static_cast<int>(index), order); 1137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstNotPointDegeneratesTest; index < notPointDegenerates_count; ++index) { 1177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDCubic& cubic = notPointDegenerates[index]; 11858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidCubic(cubic)); 119910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 1207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order == 1) { 1217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] notPointDegenerates order=%d\n", static_cast<int>(index), order); 122910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 1237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstLinesTest; index < lines_count; ++index) { 1277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDCubic& cubic = lines[index]; 12858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidCubic(cubic)); 129910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 1307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order != 2) { 1317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] lines order=%d\n", static_cast<int>(index), order); 1327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstNotLinesTest; index < notLines_count; ++index) { 1367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDCubic& cubic = notLines[index]; 13758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidCubic(cubic)); 138910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 1397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order == 2) { 1407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] notLines order=%d\n", static_cast<int>(index), order); 1417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstModEpsilonTest; index < modEpsilonLines_count; ++index) { 1457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDCubic& cubic = modEpsilonLines[index]; 14658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidCubic(cubic)); 147910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 1487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order == 2) { 1497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] line mod by epsilon order=%d\n", static_cast<int>(index), order); 1507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstLessEpsilonTest; index < lessEpsilonLines_count; ++index) { 1547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDCubic& cubic = lessEpsilonLines[index]; 15558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidCubic(cubic)); 156910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 1577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order != 2) { 1587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] line less by epsilon/2 order=%d\n", static_cast<int>(index), order); 159910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 1607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstNegEpsilonTest; index < negEpsilonLines_count; ++index) { 1647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDCubic& cubic = negEpsilonLines[index]; 16558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidCubic(cubic)); 166910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 1677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order != 2) { 1687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] line neg by epsilon/2 order=%d\n", static_cast<int>(index), order); 1697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstQuadraticPointTest; index < quadraticPoints_count; ++index) { 1737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDQuad& quad = quadraticPoints[index]; 17458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidQuad(quad)); 1757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDCubic cubic = quad.toCubic(); 176910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 1777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order != 1) { 1787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] point quad order=%d\n", static_cast<int>(index), order); 1797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstQuadraticLineTest; index < quadraticLines_count; ++index) { 1837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDQuad& quad = quadraticLines[index]; 18458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidQuad(quad)); 1857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDCubic cubic = quad.toCubic(); 186910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 1877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order != 2) { 1887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] line quad order=%d\n", static_cast<int>(index), order); 1897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstQuadraticModLineTest; index < quadraticModEpsilonLines_count; ++index) { 1937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDQuad& quad = quadraticModEpsilonLines[index]; 19458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidQuad(quad)); 1957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDCubic cubic = quad.toCubic(); 196910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 1977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order != 3) { 1987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] line mod quad order=%d\n", static_cast<int>(index), order); 1997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 2007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 2017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 2027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 203910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger#if 0 // disable test until stroke reduction is supported 204910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger// test if computed line end points are valid 2057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstComputedLinesTest; index < lines_count; ++index) { 2067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDCubic& cubic = lines[index]; 20758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidCubic(cubic)); 2087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bool controlsInside = controls_inside(cubic); 2097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics, 2107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkReduceOrder::kStroke_Style); 2117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order == 2 && reducer.fLine[0] == reducer.fLine[1]) { 2127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] line computed ends match order=%d\n", static_cast<int>(index), order); 2137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 2147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 2157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (controlsInside) { 2167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if ( (reducer.fLine[0].fX != cubic[0].fX && reducer.fLine[0].fX != cubic[3].fX) 2177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger || (reducer.fLine[0].fY != cubic[0].fY && reducer.fLine[0].fY != cubic[3].fY) 2187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger || (reducer.fLine[1].fX != cubic[0].fX && reducer.fLine[1].fX != cubic[3].fX) 2197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger || (reducer.fLine[1].fY != cubic[0].fY && reducer.fLine[1].fY != cubic[3].fY)) { 2207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] line computed ends order=%d\n", static_cast<int>(index), order); 2217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 2227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 2237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } else { 2247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // binary search for extrema, compare against actual results 2257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // while a control point is outside of bounding box formed by end points, split 2267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDRect bounds = {DBL_MAX, DBL_MAX, -DBL_MAX, -DBL_MAX}; 2277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger find_tight_bounds(cubic, bounds); 2287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if ( (!AlmostEqualUlps(reducer.fLine[0].fX, bounds.fLeft) 2297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && !AlmostEqualUlps(reducer.fLine[0].fX, bounds.fRight)) 2307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger || (!AlmostEqualUlps(reducer.fLine[0].fY, bounds.fTop) 2317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && !AlmostEqualUlps(reducer.fLine[0].fY, bounds.fBottom)) 2327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger || (!AlmostEqualUlps(reducer.fLine[1].fX, bounds.fLeft) 2337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && !AlmostEqualUlps(reducer.fLine[1].fX, bounds.fRight)) 2347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger || (!AlmostEqualUlps(reducer.fLine[1].fY, bounds.fTop) 2357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && !AlmostEqualUlps(reducer.fLine[1].fY, bounds.fBottom))) { 2367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] line computed tight bounds order=%d\n", static_cast<int>(index), order); 2377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 2387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 2397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 2407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 241910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger#endif 2427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 2437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 2447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "TestClassDef.h" 2450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 2467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerDEFINE_TESTCLASS_SHORT(PathOpsReduceOrderCubicTest) 247