1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2012 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "PathOpsCubicIntersectionTestData.h" 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "PathOpsQuadIntersectionTestData.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "PathOpsTestCommon.h" 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkIntersections.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPathOpsRect.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkReduceOrder.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "Test.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if 0 // disable test until stroke reduction is supported 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic bool controls_inside(const SkDCubic& cubic) { 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return between(cubic[0].fX, cubic[1].fX, cubic[3].fX) 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot && between(cubic[0].fX, cubic[2].fX, cubic[3].fX) 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot && between(cubic[0].fY, cubic[1].fY, cubic[3].fY) 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot && between(cubic[0].fY, cubic[2].fY, cubic[3].fY); 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic bool tiny(const SkDCubic& cubic) { 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int index, minX, maxX, minY, maxY; 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot minX = maxX = minY = maxY = 0; 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (index = 1; index < 4; ++index) { 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (cubic[minX].fX > cubic[index].fX) { 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot minX = index; 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (cubic[minY].fY > cubic[index].fY) { 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot minY = index; 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (cubic[maxX].fX < cubic[index].fX) { 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot maxX = index; 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (cubic[maxY].fY < cubic[index].fY) { 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot maxY = index; 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return approximately_equal(cubic[maxX].fX, cubic[minX].fX) 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot && approximately_equal(cubic[maxY].fY, cubic[minY].fY); 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void find_tight_bounds(const SkDCubic& cubic, SkDRect& bounds) { 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDCubicPair cubicPair = cubic.chopAt(0.5); 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!tiny(cubicPair.first()) && !controls_inside(cubicPair.first())) { 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot find_tight_bounds(cubicPair.first(), bounds); 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bounds.add(cubicPair.first()[0]); 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bounds.add(cubicPair.first()[3]); 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!tiny(cubicPair.second()) && !controls_inside(cubicPair.second())) { 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot find_tight_bounds(cubicPair.second(), bounds); 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bounds.add(cubicPair.second()[0]); 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bounds.add(cubicPair.second()[3]); 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_TEST(PathOpsReduceOrderCubic, reporter) { 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t index; 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkReduceOrder reducer; 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int order; 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot enum { 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RunAll, 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RunPointDegenerates, 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RunNotPointDegenerates, 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RunLines, 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RunNotLines, 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RunModEpsilonLines, 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RunLessEpsilonLines, 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RunNegEpsilonLines, 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RunQuadraticLines, 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RunQuadraticPoints, 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RunQuadraticModLines, 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RunComputedLines, 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot RunNone 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } run = RunAll; 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int firstTestIndex = 0; 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if 0 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot run = RunComputedLines; 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot firstTestIndex = 18; 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int firstPointDegeneratesTest = run == RunAll ? 0 : run == RunPointDegenerates 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ? firstTestIndex : SK_MaxS32; 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int firstNotPointDegeneratesTest = run == RunAll ? 0 : run == RunNotPointDegenerates 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ? firstTestIndex : SK_MaxS32; 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int firstLinesTest = run == RunAll ? 0 : run == RunLines ? firstTestIndex : SK_MaxS32; 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int firstNotLinesTest = run == RunAll ? 0 : run == RunNotLines ? firstTestIndex : SK_MaxS32; 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int firstModEpsilonTest = run == RunAll ? 0 : run == RunModEpsilonLines 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ? firstTestIndex : SK_MaxS32; 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int firstLessEpsilonTest = run == RunAll ? 0 : run == RunLessEpsilonLines 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ? firstTestIndex : SK_MaxS32; 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int firstNegEpsilonTest = run == RunAll ? 0 : run == RunNegEpsilonLines 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ? firstTestIndex : SK_MaxS32; 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int firstQuadraticPointTest = run == RunAll ? 0 : run == RunQuadraticPoints 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ? firstTestIndex : SK_MaxS32; 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int firstQuadraticLineTest = run == RunAll ? 0 : run == RunQuadraticLines 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ? firstTestIndex : SK_MaxS32; 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int firstQuadraticModLineTest = run == RunAll ? 0 : run == RunQuadraticModLines 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ? firstTestIndex : SK_MaxS32; 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if 0 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int firstComputedLinesTest = run == RunAll ? 0 : run == RunComputedLines 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ? firstTestIndex : SK_MaxS32; 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (index = firstPointDegeneratesTest; index < pointDegenerates_count; ++index) { 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const CubicPts& c = pointDegenerates[index]; 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDCubic cubic; 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cubic.debugSet(c.fPts); 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(ValidCubic(cubic)); 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (order != 1) { 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("[%d] pointDegenerates order=%d\n", static_cast<int>(index), order); 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0); 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (index = firstNotPointDegeneratesTest; index < notPointDegenerates_count; ++index) { 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const CubicPts& c = notPointDegenerates[index]; 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDCubic cubic; 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cubic.debugSet(c.fPts); 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(ValidCubic(cubic)); 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (order == 1) { 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("[%d] notPointDegenerates order=%d\n", static_cast<int>(index), order); 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0); 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (index = firstLinesTest; index < lines_count; ++index) { 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const CubicPts& c = lines[index]; 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDCubic cubic; 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cubic.debugSet(c.fPts); 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(ValidCubic(cubic)); 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (order != 2) { 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("[%d] lines order=%d\n", static_cast<int>(index), order); 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0); 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (index = firstNotLinesTest; index < notLines_count; ++index) { 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const CubicPts& c = notLines[index]; 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDCubic cubic; 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cubic.debugSet(c.fPts); 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(ValidCubic(cubic)); 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (order == 2) { 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("[%d] notLines order=%d\n", static_cast<int>(index), order); 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0); 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (index = firstModEpsilonTest; index < modEpsilonLines_count; ++index) { 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const CubicPts& c = modEpsilonLines[index]; 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDCubic cubic; 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cubic.debugSet(c.fPts); 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(ValidCubic(cubic)); 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (order == 2) { 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("[%d] line mod by epsilon order=%d\n", static_cast<int>(index), order); 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0); 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (index = firstLessEpsilonTest; index < lessEpsilonLines_count; ++index) { 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const CubicPts& c = lessEpsilonLines[index]; 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDCubic cubic; 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cubic.debugSet(c.fPts); 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(ValidCubic(cubic)); 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (order != 2) { 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("[%d] line less by epsilon/2 order=%d\n", static_cast<int>(index), order); 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0); 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (index = firstNegEpsilonTest; index < negEpsilonLines_count; ++index) { 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const CubicPts& c = negEpsilonLines[index]; 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDCubic cubic; 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot cubic.debugSet(c.fPts); 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(ValidCubic(cubic)); 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (order != 2) { 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("[%d] line neg by epsilon/2 order=%d\n", static_cast<int>(index), order); 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0); 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (index = firstQuadraticPointTest; index < quadraticPoints_count; ++index) { 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const QuadPts& q = quadraticPoints[index]; 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDQuad quad; 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot quad.debugSet(q.fPts); 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(ValidQuad(quad)); 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDCubic cubic = quad.debugToCubic(); 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (order != 1) { 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("[%d] point quad order=%d\n", static_cast<int>(index), order); 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0); 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (index = firstQuadraticLineTest; index < quadraticLines_count; ++index) { 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const QuadPts& q = quadraticLines[index]; 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDQuad quad; 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot quad.debugSet(q.fPts); 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(ValidQuad(quad)); 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDCubic cubic = quad.debugToCubic(); 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (order != 2) { 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("[%d] line quad order=%d\n", static_cast<int>(index), order); 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0); 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (index = firstQuadraticModLineTest; index < quadraticModEpsilonLines_count; ++index) { 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const QuadPts& q = quadraticModEpsilonLines[index]; 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDQuad quad; 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot quad.debugSet(q.fPts); 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(ValidQuad(quad)); 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDCubic cubic = quad.debugToCubic(); 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics); 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (order != 3) { 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("[%d] line mod quad order=%d\n", static_cast<int>(index), order); 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0); 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if 0 // disable test until stroke reduction is supported 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// test if computed line end points are valid 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (index = firstComputedLinesTest; index < lines_count; ++index) { 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkDCubic& cubic = lines[index]; 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(ValidCubic(cubic)); 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool controlsInside = controls_inside(cubic); 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot order = reducer.reduce(cubic, SkReduceOrder::kAllow_Quadratics, 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkReduceOrder::kStroke_Style); 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (order == 2 && reducer.fLine[0] == reducer.fLine[1]) { 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("[%d] line computed ends match order=%d\n", static_cast<int>(index), order); 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0); 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (controlsInside) { 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if ( (reducer.fLine[0].fX != cubic[0].fX && reducer.fLine[0].fX != cubic[3].fX) 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot || (reducer.fLine[0].fY != cubic[0].fY && reducer.fLine[0].fY != cubic[3].fY) 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot || (reducer.fLine[1].fX != cubic[0].fX && reducer.fLine[1].fX != cubic[3].fX) 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot || (reducer.fLine[1].fY != cubic[0].fY && reducer.fLine[1].fY != cubic[3].fY)) { 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("[%d] line computed ends order=%d\n", static_cast<int>(index), order); 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0); 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // binary search for extrema, compare against actual results 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // while a control point is outside of bounding box formed by end points, split 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDRect bounds = {DBL_MAX, DBL_MAX, -DBL_MAX, -DBL_MAX}; 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot find_tight_bounds(cubic, bounds); 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if ( (!AlmostEqualUlps(reducer.fLine[0].fX, bounds.fLeft) 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot && !AlmostEqualUlps(reducer.fLine[0].fX, bounds.fRight)) 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot || (!AlmostEqualUlps(reducer.fLine[0].fY, bounds.fTop) 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot && !AlmostEqualUlps(reducer.fLine[0].fY, bounds.fBottom)) 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot || (!AlmostEqualUlps(reducer.fLine[1].fX, bounds.fLeft) 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot && !AlmostEqualUlps(reducer.fLine[1].fX, bounds.fRight)) 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot || (!AlmostEqualUlps(reducer.fLine[1].fY, bounds.fTop) 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot && !AlmostEqualUlps(reducer.fLine[1].fY, bounds.fBottom))) { 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDebugf("[%d] line computed tight bounds order=%d\n", static_cast<int>(index), order); 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, 0); 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 263