gfx/skia/trunk/src/pathops/SkPathOpsLine.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /*
michael@0 2 * Copyright 2012 Google Inc.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7 #include "SkPathOpsLine.h"
michael@0 8
michael@0 9 SkDLine SkDLine::subDivide(double t1, double t2) const {
michael@0 10 SkDVector delta = tangent();
michael@0 11 SkDLine dst = {{{
michael@0 12 fPts[0].fX - t1 * delta.fX, fPts[0].fY - t1 * delta.fY}, {
michael@0 13 fPts[0].fX - t2 * delta.fX, fPts[0].fY - t2 * delta.fY}}};
michael@0 14 return dst;
michael@0 15 }
michael@0 16
michael@0 17 // may have this below somewhere else already:
michael@0 18 // copying here because I thought it was clever
michael@0 19
michael@0 20 // Copyright 2001, softSurfer (www.softsurfer.com)
michael@0 21 // This code may be freely used and modified for any purpose
michael@0 22 // providing that this copyright notice is included with it.
michael@0 23 // SoftSurfer makes no warranty for this code, and cannot be held
michael@0 24 // liable for any real or imagined damage resulting from its use.
michael@0 25 // Users of this code must verify correctness for their application.
michael@0 26
michael@0 27 // Assume that a class is already given for the object:
michael@0 28 // Point with coordinates {float x, y;}
michael@0 29 //===================================================================
michael@0 30
michael@0 31 // isLeft(): tests if a point is Left|On|Right of an infinite line.
michael@0 32 // Input: three points P0, P1, and P2
michael@0 33 // Return: >0 for P2 left of the line through P0 and P1
michael@0 34 // =0 for P2 on the line
michael@0 35 // <0 for P2 right of the line
michael@0 36 // See: the January 2001 Algorithm on Area of Triangles
michael@0 37 // return (float) ((P1.x - P0.x)*(P2.y - P0.y) - (P2.x - P0.x)*(P1.y - P0.y));
michael@0 38 double SkDLine::isLeft(const SkDPoint& pt) const {
michael@0 39 SkDVector p0 = fPts[1] - fPts[0];
michael@0 40 SkDVector p2 = pt - fPts[0];
michael@0 41 return p0.cross(p2);
michael@0 42 }
michael@0 43
michael@0 44 SkDPoint SkDLine::ptAtT(double t) const {
michael@0 45 if (0 == t) {
michael@0 46 return fPts[0];
michael@0 47 }
michael@0 48 if (1 == t) {
michael@0 49 return fPts[1];
michael@0 50 }
michael@0 51 double one_t = 1 - t;
michael@0 52 SkDPoint result = { one_t * fPts[0].fX + t * fPts[1].fX, one_t * fPts[0].fY + t * fPts[1].fY };
michael@0 53 return result;
michael@0 54 }
michael@0 55
michael@0 56 double SkDLine::exactPoint(const SkDPoint& xy) const {
michael@0 57 if (xy == fPts[0]) { // do cheapest test first
michael@0 58 return 0;
michael@0 59 }
michael@0 60 if (xy == fPts[1]) {
michael@0 61 return 1;
michael@0 62 }
michael@0 63 return -1;
michael@0 64 }
michael@0 65
michael@0 66 double SkDLine::nearPoint(const SkDPoint& xy) const {
michael@0 67 if (!AlmostBetweenUlps(fPts[0].fX, xy.fX, fPts[1].fX)
michael@0 68 || !AlmostBetweenUlps(fPts[0].fY, xy.fY, fPts[1].fY)) {
michael@0 69 return -1;
michael@0 70 }
michael@0 71 // project a perpendicular ray from the point to the line; find the T on the line
michael@0 72 SkDVector len = fPts[1] - fPts[0]; // the x/y magnitudes of the line
michael@0 73 double denom = len.fX * len.fX + len.fY * len.fY; // see DLine intersectRay
michael@0 74 SkDVector ab0 = xy - fPts[0];
michael@0 75 double numer = len.fX * ab0.fX + ab0.fY * len.fY;
michael@0 76 if (!between(0, numer, denom)) {
michael@0 77 return -1;
michael@0 78 }
michael@0 79 double t = numer / denom;
michael@0 80 SkDPoint realPt = ptAtT(t);
michael@0 81 double dist = realPt.distance(xy); // OPTIMIZATION: can we compare against distSq instead ?
michael@0 82 // find the ordinal in the original line with the largest unsigned exponent
michael@0 83 double tiniest = SkTMin(SkTMin(SkTMin(fPts[0].fX, fPts[0].fY), fPts[1].fX), fPts[1].fY);
michael@0 84 double largest = SkTMax(SkTMax(SkTMax(fPts[0].fX, fPts[0].fY), fPts[1].fX), fPts[1].fY);
michael@0 85 largest = SkTMax(largest, -tiniest);
michael@0 86 if (!AlmostEqualUlps(largest, largest + dist)) { // is the dist within ULPS tolerance?
michael@0 87 return -1;
michael@0 88 }
michael@0 89 t = SkPinT(t);
michael@0 90 SkASSERT(between(0, t, 1));
michael@0 91 return t;
michael@0 92 }
michael@0 93
michael@0 94 bool SkDLine::nearRay(const SkDPoint& xy) const {
michael@0 95 // project a perpendicular ray from the point to the line; find the T on the line
michael@0 96 SkDVector len = fPts[1] - fPts[0]; // the x/y magnitudes of the line
michael@0 97 double denom = len.fX * len.fX + len.fY * len.fY; // see DLine intersectRay
michael@0 98 SkDVector ab0 = xy - fPts[0];
michael@0 99 double numer = len.fX * ab0.fX + ab0.fY * len.fY;
michael@0 100 double t = numer / denom;
michael@0 101 SkDPoint realPt = ptAtT(t);
michael@0 102 double dist = realPt.distance(xy); // OPTIMIZATION: can we compare against distSq instead ?
michael@0 103 // find the ordinal in the original line with the largest unsigned exponent
michael@0 104 double tiniest = SkTMin(SkTMin(SkTMin(fPts[0].fX, fPts[0].fY), fPts[1].fX), fPts[1].fY);
michael@0 105 double largest = SkTMax(SkTMax(SkTMax(fPts[0].fX, fPts[0].fY), fPts[1].fX), fPts[1].fY);
michael@0 106 largest = SkTMax(largest, -tiniest);
michael@0 107 return RoughlyEqualUlps(largest, largest + dist); // is the dist within ULPS tolerance?
michael@0 108 }
michael@0 109
michael@0 110 // Returns true if a ray from (0,0) to (x1,y1) is coincident with a ray (0,0) to (x2,y2)
michael@0 111 // OPTIMIZE: a specialty routine could speed this up -- may not be called very often though
michael@0 112 bool SkDLine::NearRay(double x1, double y1, double x2, double y2) {
michael@0 113 double denom1 = x1 * x1 + y1 * y1;
michael@0 114 double denom2 = x2 * x2 + y2 * y2;
michael@0 115 SkDLine line = {{{0, 0}, {x1, y1}}};
michael@0 116 SkDPoint pt = {x2, y2};
michael@0 117 if (denom2 > denom1) {
michael@0 118 SkTSwap(line[1], pt);
michael@0 119 }
michael@0 120 return line.nearRay(pt);
michael@0 121 }
michael@0 122
michael@0 123 double SkDLine::ExactPointH(const SkDPoint& xy, double left, double right, double y) {
michael@0 124 if (xy.fY == y) {
michael@0 125 if (xy.fX == left) {
michael@0 126 return 0;
michael@0 127 }
michael@0 128 if (xy.fX == right) {
michael@0 129 return 1;
michael@0 130 }
michael@0 131 }
michael@0 132 return -1;
michael@0 133 }
michael@0 134
michael@0 135 double SkDLine::NearPointH(const SkDPoint& xy, double left, double right, double y) {
michael@0 136 if (!AlmostBequalUlps(xy.fY, y)) {
michael@0 137 return -1;
michael@0 138 }
michael@0 139 if (!AlmostBetweenUlps(left, xy.fX, right)) {
michael@0 140 return -1;
michael@0 141 }
michael@0 142 double t = (xy.fX - left) / (right - left);
michael@0 143 t = SkPinT(t);
michael@0 144 SkASSERT(between(0, t, 1));
michael@0 145 double realPtX = (1 - t) * left + t * right;
michael@0 146 SkDVector distU = {xy.fY - y, xy.fX - realPtX};
michael@0 147 double distSq = distU.fX * distU.fX + distU.fY * distU.fY;
michael@0 148 double dist = sqrt(distSq); // OPTIMIZATION: can we compare against distSq instead ?
michael@0 149 double tiniest = SkTMin(SkTMin(y, left), right);
michael@0 150 double largest = SkTMax(SkTMax(y, left), right);
michael@0 151 largest = SkTMax(largest, -tiniest);
michael@0 152 if (!AlmostEqualUlps(largest, largest + dist)) { // is the dist within ULPS tolerance?
michael@0 153 return -1;
michael@0 154 }
michael@0 155 return t;
michael@0 156 }
michael@0 157
michael@0 158 double SkDLine::ExactPointV(const SkDPoint& xy, double top, double bottom, double x) {
michael@0 159 if (xy.fX == x) {
michael@0 160 if (xy.fY == top) {
michael@0 161 return 0;
michael@0 162 }
michael@0 163 if (xy.fY == bottom) {
michael@0 164 return 1;
michael@0 165 }
michael@0 166 }
michael@0 167 return -1;
michael@0 168 }
michael@0 169
michael@0 170 double SkDLine::NearPointV(const SkDPoint& xy, double top, double bottom, double x) {
michael@0 171 if (!AlmostBequalUlps(xy.fX, x)) {
michael@0 172 return -1;
michael@0 173 }
michael@0 174 if (!AlmostBetweenUlps(top, xy.fY, bottom)) {
michael@0 175 return -1;
michael@0 176 }
michael@0 177 double t = (xy.fY - top) / (bottom - top);
michael@0 178 t = SkPinT(t);
michael@0 179 SkASSERT(between(0, t, 1));
michael@0 180 double realPtY = (1 - t) * top + t * bottom;
michael@0 181 SkDVector distU = {xy.fX - x, xy.fY - realPtY};
michael@0 182 double distSq = distU.fX * distU.fX + distU.fY * distU.fY;
michael@0 183 double dist = sqrt(distSq); // OPTIMIZATION: can we compare against distSq instead ?
michael@0 184 double tiniest = SkTMin(SkTMin(x, top), bottom);
michael@0 185 double largest = SkTMax(SkTMax(x, top), bottom);
michael@0 186 largest = SkTMax(largest, -tiniest);
michael@0 187 if (!AlmostEqualUlps(largest, largest + dist)) { // is the dist within ULPS tolerance?
michael@0 188 return -1;
michael@0 189 }
michael@0 190 return t;
michael@0 191 }
michael@0 192
michael@0 193 #ifdef SK_DEBUG
michael@0 194 void SkDLine::dump() {
michael@0 195 SkDebugf("{{");
michael@0 196 fPts[0].dump();
michael@0 197 SkDebugf(", ");
michael@0 198 fPts[1].dump();
michael@0 199 SkDebugf("}}\n");
michael@0 200 }
michael@0 201 #endif

mercurial