PathOpsCubicReduceOrderTest.cpp revision 0a657bbc2c6fc9daf699942e023050536d5ec95f
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 157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic bool controls_inside(const SkDCubic& cubic) { 167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return between(cubic[0].fX, cubic[1].fX, cubic[3].fX) 177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && between(cubic[0].fX, cubic[2].fX, cubic[3].fX) 187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && between(cubic[0].fY, cubic[1].fY, cubic[3].fY) 197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && between(cubic[0].fY, cubic[2].fY, cubic[3].fY); 207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic bool tiny(const SkDCubic& cubic) { 237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int index, minX, maxX, minY, maxY; 247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger minX = maxX = minY = maxY = 0; 257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = 1; index < 4; ++index) { 267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (cubic[minX].fX > cubic[index].fX) { 277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger minX = index; 287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (cubic[minY].fY > cubic[index].fY) { 307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger minY = index; 317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (cubic[maxX].fX < cubic[index].fX) { 337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger maxX = index; 347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (cubic[maxY].fY < cubic[index].fY) { 367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger maxY = index; 377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return approximately_equal(cubic[maxX].fX, cubic[minX].fX) 407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && approximately_equal(cubic[maxY].fY, cubic[minY].fY); 417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic void find_tight_bounds(const SkDCubic& cubic, SkDRect& bounds) { 447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDCubicPair cubicPair = cubic.chopAt(0.5); 457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (!tiny(cubicPair.first()) && !controls_inside(cubicPair.first())) { 467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger find_tight_bounds(cubicPair.first(), bounds); 477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } else { 487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bounds.add(cubicPair.first()[0]); 497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bounds.add(cubicPair.first()[3]); 507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (!tiny(cubicPair.second()) && !controls_inside(cubicPair.second())) { 527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger find_tight_bounds(cubicPair.second(), bounds); 537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } else { 547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bounds.add(cubicPair.second()[0]); 557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bounds.add(cubicPair.second()[3]); 567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic void PathOpsReduceOrderCubicTest(skiatest::Reporter* reporter) { 607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger size_t index; 617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkReduceOrder reducer; 627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int order; 637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger enum { 647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunAll, 657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunPointDegenerates, 667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunNotPointDegenerates, 677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunLines, 687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunNotLines, 697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunModEpsilonLines, 707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunLessEpsilonLines, 717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunNegEpsilonLines, 727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunQuadraticLines, 737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunQuadraticPoints, 747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunQuadraticModLines, 757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunComputedLines, 767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger RunNone 777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } run = RunAll; 787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstTestIndex = 0; 797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if 0 807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger run = RunComputedLines; 817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger firstTestIndex = 18; 827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstPointDegeneratesTest = run == RunAll ? 0 : run == RunPointDegenerates 847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstNotPointDegeneratesTest = run == RunAll ? 0 : run == RunNotPointDegenerates 867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstLinesTest = run == RunAll ? 0 : run == RunLines ? firstTestIndex : SK_MaxS32; 887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstNotLinesTest = run == RunAll ? 0 : run == RunNotLines ? firstTestIndex : SK_MaxS32; 897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstModEpsilonTest = run == RunAll ? 0 : run == RunModEpsilonLines 907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstLessEpsilonTest = run == RunAll ? 0 : run == RunLessEpsilonLines 927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstNegEpsilonTest = run == RunAll ? 0 : run == RunNegEpsilonLines 947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstQuadraticPointTest = run == RunAll ? 0 : run == RunQuadraticPoints 967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstQuadraticLineTest = run == RunAll ? 0 : run == RunQuadraticLines 987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstQuadraticModLineTest = run == RunAll ? 0 : run == RunQuadraticModLines 1007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 1017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int firstComputedLinesTest = run == RunAll ? 0 : run == RunComputedLines 1027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger ? firstTestIndex : SK_MaxS32; 1037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstPointDegeneratesTest; index < pointDegenerates_count; ++index) { 1057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDCubic& cubic = pointDegenerates[index]; 10658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidCubic(cubic)); 1077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics, SkReduceOrder::kFill_Style); 1087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order != 1) { 1097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] pointDegenerates order=%d\n", static_cast<int>(index), order); 1107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstNotPointDegeneratesTest; index < notPointDegenerates_count; ++index) { 1147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDCubic& cubic = notPointDegenerates[index]; 11558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidCubic(cubic)); 1167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics, SkReduceOrder::kFill_Style); 1177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order == 1) { 1187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] notPointDegenerates order=%d\n", static_cast<int>(index), order); 1190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics, 1200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkReduceOrder::kFill_Style); 1217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstLinesTest; index < lines_count; ++index) { 1257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDCubic& cubic = lines[index]; 12658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidCubic(cubic)); 1277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics, SkReduceOrder::kFill_Style); 1287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order != 2) { 1297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] lines order=%d\n", static_cast<int>(index), order); 1307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstNotLinesTest; index < notLines_count; ++index) { 1347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDCubic& cubic = notLines[index]; 13558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidCubic(cubic)); 1367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics, SkReduceOrder::kFill_Style); 1377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order == 2) { 1387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] notLines order=%d\n", static_cast<int>(index), order); 1397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstModEpsilonTest; index < modEpsilonLines_count; ++index) { 1437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDCubic& cubic = modEpsilonLines[index]; 14458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidCubic(cubic)); 1457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics, SkReduceOrder::kFill_Style); 1467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order == 2) { 1477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] line mod by epsilon order=%d\n", static_cast<int>(index), order); 1487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstLessEpsilonTest; index < lessEpsilonLines_count; ++index) { 1527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDCubic& cubic = lessEpsilonLines[index]; 15358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidCubic(cubic)); 1547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics, SkReduceOrder::kFill_Style); 1557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order != 2) { 1567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] line less by epsilon/2 order=%d\n", static_cast<int>(index), order); 1570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics, 1580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkReduceOrder::kFill_Style); 1597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstNegEpsilonTest; index < negEpsilonLines_count; ++index) { 1637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDCubic& cubic = negEpsilonLines[index]; 16458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidCubic(cubic)); 1657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics, SkReduceOrder::kFill_Style); 1667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order != 2) { 1677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] line neg by epsilon/2 order=%d\n", static_cast<int>(index), order); 1687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstQuadraticPointTest; index < quadraticPoints_count; ++index) { 1727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDQuad& quad = quadraticPoints[index]; 17358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidQuad(quad)); 1747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDCubic cubic = quad.toCubic(); 1757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics, SkReduceOrder::kFill_Style); 1767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order != 1) { 1777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] point quad order=%d\n", static_cast<int>(index), order); 1787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstQuadraticLineTest; index < quadraticLines_count; ++index) { 1827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDQuad& quad = quadraticLines[index]; 18358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidQuad(quad)); 1847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDCubic cubic = quad.toCubic(); 1857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics, SkReduceOrder::kFill_Style); 1867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order != 2) { 1877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] line quad order=%d\n", static_cast<int>(index), order); 1887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstQuadraticModLineTest; index < quadraticModEpsilonLines_count; ++index) { 1927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDQuad& quad = quadraticModEpsilonLines[index]; 19358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidQuad(quad)); 1947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDCubic cubic = quad.toCubic(); 1957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics, SkReduceOrder::kFill_Style); 1967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order != 3) { 1977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] line mod quad order=%d\n", static_cast<int>(index), order); 1987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 1997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 2007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 2017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 2027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // test if computed line end points are valid 2037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger for (index = firstComputedLinesTest; index < lines_count; ++index) { 2047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkDCubic& cubic = lines[index]; 20558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(ValidCubic(cubic)); 2067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bool controlsInside = controls_inside(cubic); 2077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics, 2087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkReduceOrder::kStroke_Style); 2097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (order == 2 && reducer.fLine[0] == reducer.fLine[1]) { 2107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] line computed ends match order=%d\n", static_cast<int>(index), order); 2117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 2127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 2137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (controlsInside) { 2147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if ( (reducer.fLine[0].fX != cubic[0].fX && reducer.fLine[0].fX != cubic[3].fX) 2157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger || (reducer.fLine[0].fY != cubic[0].fY && reducer.fLine[0].fY != cubic[3].fY) 2167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger || (reducer.fLine[1].fX != cubic[0].fX && reducer.fLine[1].fX != cubic[3].fX) 2177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger || (reducer.fLine[1].fY != cubic[0].fY && reducer.fLine[1].fY != cubic[3].fY)) { 2187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] line computed ends order=%d\n", static_cast<int>(index), order); 2197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 2207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 2217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } else { 2227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // binary search for extrema, compare against actual results 2237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // while a control point is outside of bounding box formed by end points, split 2247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDRect bounds = {DBL_MAX, DBL_MAX, -DBL_MAX, -DBL_MAX}; 2257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger find_tight_bounds(cubic, bounds); 2267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if ( (!AlmostEqualUlps(reducer.fLine[0].fX, bounds.fLeft) 2277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && !AlmostEqualUlps(reducer.fLine[0].fX, bounds.fRight)) 2287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger || (!AlmostEqualUlps(reducer.fLine[0].fY, bounds.fTop) 2297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && !AlmostEqualUlps(reducer.fLine[0].fY, bounds.fBottom)) 2307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger || (!AlmostEqualUlps(reducer.fLine[1].fX, bounds.fLeft) 2317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && !AlmostEqualUlps(reducer.fLine[1].fX, bounds.fRight)) 2327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger || (!AlmostEqualUlps(reducer.fLine[1].fY, bounds.fTop) 2337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger && !AlmostEqualUlps(reducer.fLine[1].fY, bounds.fBottom))) { 2347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDebugf("[%d] line computed tight bounds order=%d\n", static_cast<int>(index), order); 2357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger REPORTER_ASSERT(reporter, 0); 2367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 2377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 2387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 2397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 2407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 2417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "TestClassDef.h" 2420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 2437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerDEFINE_TESTCLASS_SHORT(PathOpsReduceOrderCubicTest) 244