| OLD | NEW | 
|---|
| 1 | 1 | 
| 2 /* | 2 /* | 
| 3  * Copyright 2011 Google Inc. | 3  * Copyright 2011 Google Inc. | 
| 4  * | 4  * | 
| 5  * Use of this source code is governed by a BSD-style license that can be | 5  * Use of this source code is governed by a BSD-style license that can be | 
| 6  * found in the LICENSE file. | 6  * found in the LICENSE file. | 
| 7  */ | 7  */ | 
| 8 #include "SkEdgeBuilder.h" | 8 #include "SkEdgeBuilder.h" | 
| 9 #include "SkPath.h" | 9 #include "SkPath.h" | 
| 10 #include "SkEdge.h" | 10 #include "SkEdge.h" | 
| 11 #include "SkEdgeClipper.h" | 11 #include "SkEdgeClipper.h" | 
| 12 #include "SkLineClipper.h" | 12 #include "SkLineClipper.h" | 
| 13 #include "SkGeometry.h" | 13 #include "SkGeometry.h" | 
| 14 | 14 | 
| 15 template <typename T> static T* typedAllocThrow(SkChunkAlloc& alloc) { | 15 template <typename T> static T* typedAllocThrow(SkChunkAlloc& alloc) { | 
| 16     return static_cast<T*>(alloc.allocThrow(sizeof(T))); | 16     return static_cast<T*>(alloc.allocThrow(sizeof(T))); | 
| 17 } | 17 } | 
| 18 | 18 | 
| 19 /////////////////////////////////////////////////////////////////////////////// | 19 /////////////////////////////////////////////////////////////////////////////// | 
| 20 | 20 | 
| 21 SkEdgeBuilder::SkEdgeBuilder() : fAlloc(16*1024) { | 21 SkEdgeBuilder::SkEdgeBuilder() : fAlloc(16*1024) { | 
| 22     fEdgeList = nullptr; | 22     fEdgeList = nullptr; | 
| 23 } | 23 } | 
| 24 | 24 | 
|  | 25 SkEdgeBuilder::Combine SkEdgeBuilder::CombineVertical(const SkEdge* edge, SkEdge
     * last) { | 
|  | 26     if (last->fCurveCount || last->fDX || edge->fX != last->fX) { | 
|  | 27         return kNo_Combine; | 
|  | 28     } | 
|  | 29     if (edge->fWinding == last->fWinding) { | 
|  | 30         if (edge->fLastY + 1 == last->fFirstY) { | 
|  | 31             last->fFirstY = edge->fFirstY; | 
|  | 32             return kPartial_Combine; | 
|  | 33         } | 
|  | 34         if (edge->fFirstY == last->fLastY + 1) { | 
|  | 35             last->fLastY = edge->fLastY; | 
|  | 36             return kPartial_Combine; | 
|  | 37         } | 
|  | 38         return kNo_Combine; | 
|  | 39     } | 
|  | 40     if (edge->fFirstY == last->fFirstY) { | 
|  | 41         if (edge->fLastY == last->fLastY) { | 
|  | 42             return kTotal_Combine; | 
|  | 43         } | 
|  | 44         if (edge->fLastY < last->fLastY) { | 
|  | 45             last->fFirstY = edge->fLastY + 1; | 
|  | 46             return kPartial_Combine; | 
|  | 47         } | 
|  | 48         last->fFirstY = last->fLastY + 1; | 
|  | 49         last->fLastY = edge->fLastY; | 
|  | 50         last->fWinding = edge->fWinding; | 
|  | 51         return kPartial_Combine; | 
|  | 52     } | 
|  | 53     if (edge->fLastY == last->fLastY) { | 
|  | 54         if (edge->fFirstY > last->fFirstY) { | 
|  | 55             last->fLastY = edge->fFirstY - 1; | 
|  | 56             return kPartial_Combine; | 
|  | 57         } | 
|  | 58         last->fLastY = last->fFirstY - 1; | 
|  | 59         last->fFirstY = edge->fFirstY; | 
|  | 60         last->fWinding = edge->fWinding; | 
|  | 61         return kPartial_Combine; | 
|  | 62     } | 
|  | 63     return kNo_Combine; | 
|  | 64 } | 
|  | 65 | 
|  | 66 static bool vertical_line(const SkEdge* edge) { | 
|  | 67 #ifdef SK_SUPPORT_LEGACY_VERTICAL_EDGE  // this disables combining vertical over
     lapping edges | 
|  | 68     return false; | 
|  | 69 #endif | 
|  | 70     return !edge->fDX && !edge->fCurveCount; | 
|  | 71 } | 
|  | 72 | 
| 25 void SkEdgeBuilder::addLine(const SkPoint pts[]) { | 73 void SkEdgeBuilder::addLine(const SkPoint pts[]) { | 
| 26     SkEdge* edge = typedAllocThrow<SkEdge>(fAlloc); | 74     SkEdge* edge = typedAllocThrow<SkEdge>(fAlloc); | 
| 27     if (edge->setLine(pts[0], pts[1], fShiftUp)) { | 75     if (edge->setLine(pts[0], pts[1], fShiftUp)) { | 
|  | 76         if (vertical_line(edge) && fList.count()) { | 
|  | 77             Combine combine = CombineVertical(edge, *(fList.end() - 1)); | 
|  | 78             if (kNo_Combine != combine) { | 
|  | 79                 if (kTotal_Combine == combine) { | 
|  | 80                     fList.pop(); | 
|  | 81                 } | 
|  | 82                 goto unallocate_edge; | 
|  | 83             } | 
|  | 84         } | 
| 28         fList.push(edge); | 85         fList.push(edge); | 
| 29     } else { | 86     } else { | 
|  | 87 unallocate_edge: | 
|  | 88         ; | 
| 30         // TODO: unallocate edge from storage... | 89         // TODO: unallocate edge from storage... | 
| 31     } | 90     } | 
| 32 } | 91 } | 
| 33 | 92 | 
| 34 void SkEdgeBuilder::addQuad(const SkPoint pts[]) { | 93 void SkEdgeBuilder::addQuad(const SkPoint pts[]) { | 
| 35     SkQuadraticEdge* edge = typedAllocThrow<SkQuadraticEdge>(fAlloc); | 94     SkQuadraticEdge* edge = typedAllocThrow<SkQuadraticEdge>(fAlloc); | 
| 36     if (edge->setQuadratic(pts, fShiftUp)) { | 95     if (edge->setQuadratic(pts, fShiftUp)) { | 
| 37         fList.push(edge); | 96         fList.push(edge); | 
| 38     } else { | 97     } else { | 
| 39         // TODO: unallocate edge from storage... | 98         // TODO: unallocate edge from storage... | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 72 | 131 | 
| 73 /////////////////////////////////////////////////////////////////////////////// | 132 /////////////////////////////////////////////////////////////////////////////// | 
| 74 | 133 | 
| 75 static void setShiftedClip(SkRect* dst, const SkIRect& src, int shift) { | 134 static void setShiftedClip(SkRect* dst, const SkIRect& src, int shift) { | 
| 76     dst->set(SkIntToScalar(src.fLeft >> shift), | 135     dst->set(SkIntToScalar(src.fLeft >> shift), | 
| 77              SkIntToScalar(src.fTop >> shift), | 136              SkIntToScalar(src.fTop >> shift), | 
| 78              SkIntToScalar(src.fRight >> shift), | 137              SkIntToScalar(src.fRight >> shift), | 
| 79              SkIntToScalar(src.fBottom >> shift)); | 138              SkIntToScalar(src.fBottom >> shift)); | 
| 80 } | 139 } | 
| 81 | 140 | 
|  | 141 SkEdgeBuilder::Combine SkEdgeBuilder::checkVertical(const SkEdge* edge, SkEdge**
      edgePtr) { | 
|  | 142     return !vertical_line(edge) || edgePtr <= fEdgeList ? kNo_Combine : | 
|  | 143             CombineVertical(edge, edgePtr[-1]); | 
|  | 144 } | 
|  | 145 | 
| 82 int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shift
     Up, | 146 int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shift
     Up, | 
| 83                              bool canCullToTheRight) { | 147                              bool canCullToTheRight) { | 
| 84     SkPath::Iter    iter(path, true); | 148     SkPath::Iter    iter(path, true); | 
| 85     SkPoint         pts[4]; | 149     SkPoint         pts[4]; | 
| 86     SkPath::Verb    verb; | 150     SkPath::Verb    verb; | 
| 87 | 151 | 
| 88     int maxEdgeCount = path.countPoints(); | 152     int maxEdgeCount = path.countPoints(); | 
| 89     if (iclip) { | 153     if (iclip) { | 
| 90         // clipping can turn 1 line into (up to) kMaxClippedLineSegments, since | 154         // clipping can turn 1 line into (up to) kMaxClippedLineSegments, since | 
| 91         // we turn portions that are clipped out on the left/right into vertical | 155         // we turn portions that are clipped out on the left/right into vertical | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 112                 case SkPath::kClose_Verb: | 176                 case SkPath::kClose_Verb: | 
| 113                     // we ignore these, and just get the whole segment from | 177                     // we ignore these, and just get the whole segment from | 
| 114                     // the corresponding line/quad/cubic verbs | 178                     // the corresponding line/quad/cubic verbs | 
| 115                     break; | 179                     break; | 
| 116                 case SkPath::kLine_Verb: { | 180                 case SkPath::kLine_Verb: { | 
| 117                     SkPoint lines[SkLineClipper::kMaxPoints]; | 181                     SkPoint lines[SkLineClipper::kMaxPoints]; | 
| 118                     int lineCount = SkLineClipper::ClipLine(pts, clip, lines, ca
     nCullToTheRight); | 182                     int lineCount = SkLineClipper::ClipLine(pts, clip, lines, ca
     nCullToTheRight); | 
| 119                     SkASSERT(lineCount <= SkLineClipper::kMaxClippedLineSegments
     ); | 183                     SkASSERT(lineCount <= SkLineClipper::kMaxClippedLineSegments
     ); | 
| 120                     for (int i = 0; i < lineCount; i++) { | 184                     for (int i = 0; i < lineCount; i++) { | 
| 121                         if (edge->setLine(lines[i], lines[i + 1], shiftUp)) { | 185                         if (edge->setLine(lines[i], lines[i + 1], shiftUp)) { | 
| 122                             *edgePtr++ = edge++; | 186                             Combine combine = checkVertical(edge, edgePtr); | 
|  | 187                             if (kNo_Combine == combine) { | 
|  | 188                                 *edgePtr++ = edge++; | 
|  | 189                             } else if (kTotal_Combine == combine) { | 
|  | 190                                 --edgePtr; | 
|  | 191                             } | 
| 123                         } | 192                         } | 
| 124                     } | 193                     } | 
| 125                     break; | 194                     break; | 
| 126                 } | 195                 } | 
| 127                 default: | 196                 default: | 
| 128                     SkDEBUGFAIL("unexpected verb"); | 197                     SkDEBUGFAIL("unexpected verb"); | 
| 129                     break; | 198                     break; | 
| 130             } | 199             } | 
| 131         } | 200         } | 
| 132     } else { | 201     } else { | 
| 133         while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { | 202         while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { | 
| 134             switch (verb) { | 203             switch (verb) { | 
| 135                 case SkPath::kMove_Verb: | 204                 case SkPath::kMove_Verb: | 
| 136                 case SkPath::kClose_Verb: | 205                 case SkPath::kClose_Verb: | 
| 137                     // we ignore these, and just get the whole segment from | 206                     // we ignore these, and just get the whole segment from | 
| 138                     // the corresponding line/quad/cubic verbs | 207                     // the corresponding line/quad/cubic verbs | 
| 139                     break; | 208                     break; | 
| 140                 case SkPath::kLine_Verb: | 209                 case SkPath::kLine_Verb: | 
| 141                     if (edge->setLine(pts[0], pts[1], shiftUp)) { | 210                     if (edge->setLine(pts[0], pts[1], shiftUp)) { | 
| 142                         *edgePtr++ = edge++; | 211                         Combine combine = checkVertical(edge, edgePtr); | 
|  | 212                         if (kNo_Combine == combine) { | 
|  | 213                             *edgePtr++ = edge++; | 
|  | 214                         } else if (kTotal_Combine == combine) { | 
|  | 215                             --edgePtr; | 
|  | 216                         } | 
| 143                     } | 217                     } | 
| 144                     break; | 218                     break; | 
| 145                 default: | 219                 default: | 
| 146                     SkDEBUGFAIL("unexpected verb"); | 220                     SkDEBUGFAIL("unexpected verb"); | 
| 147                     break; | 221                     break; | 
| 148             } | 222             } | 
| 149         } | 223         } | 
| 150     } | 224     } | 
| 151     SkASSERT((char*)edge <= (char*)fEdgeList); | 225     SkASSERT((char*)edge <= (char*)fEdgeList); | 
| 152     SkASSERT(edgePtr - fEdgeList <= maxEdgeCount); | 226     SkASSERT(edgePtr - fEdgeList <= maxEdgeCount); | 
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 256                 } | 330                 } | 
| 257                 default: | 331                 default: | 
| 258                     SkDEBUGFAIL("unexpected verb"); | 332                     SkDEBUGFAIL("unexpected verb"); | 
| 259                     break; | 333                     break; | 
| 260             } | 334             } | 
| 261         } | 335         } | 
| 262     } | 336     } | 
| 263     fEdgeList = fList.begin(); | 337     fEdgeList = fList.begin(); | 
| 264     return fList.count(); | 338     return fList.count(); | 
| 265 } | 339 } | 
| OLD | NEW | 
|---|