| Index: src/core/SkEdgeBuilder.cpp
|
| diff --git a/src/core/SkEdgeBuilder.cpp b/src/core/SkEdgeBuilder.cpp
|
| index 92c8330c16d6267e170314da6619617931622f62..dc390389c088cf437f59f1ab934805530a8c1e6a 100644
|
| --- a/src/core/SkEdgeBuilder.cpp
|
| +++ b/src/core/SkEdgeBuilder.cpp
|
| @@ -22,11 +22,70 @@ SkEdgeBuilder::SkEdgeBuilder() : fAlloc(16*1024) {
|
| fEdgeList = nullptr;
|
| }
|
|
|
| +SkEdgeBuilder::Combine SkEdgeBuilder::CombineVertical(const SkEdge* edge, SkEdge* last) {
|
| + if (last->fCurveCount || last->fDX || edge->fX != last->fX) {
|
| + return kNo_Combine;
|
| + }
|
| + if (edge->fWinding == last->fWinding) {
|
| + if (edge->fLastY + 1 == last->fFirstY) {
|
| + last->fFirstY = edge->fFirstY;
|
| + return kPartial_Combine;
|
| + }
|
| + if (edge->fFirstY == last->fLastY + 1) {
|
| + last->fLastY = edge->fLastY;
|
| + return kPartial_Combine;
|
| + }
|
| + return kNo_Combine;
|
| + }
|
| + if (edge->fFirstY == last->fFirstY) {
|
| + if (edge->fLastY == last->fLastY) {
|
| + return kTotal_Combine;
|
| + }
|
| + if (edge->fLastY < last->fLastY) {
|
| + last->fFirstY = edge->fLastY + 1;
|
| + return kPartial_Combine;
|
| + }
|
| + last->fFirstY = last->fLastY + 1;
|
| + last->fLastY = edge->fLastY;
|
| + last->fWinding = edge->fWinding;
|
| + return kPartial_Combine;
|
| + }
|
| + if (edge->fLastY == last->fLastY) {
|
| + if (edge->fFirstY > last->fFirstY) {
|
| + last->fLastY = edge->fFirstY - 1;
|
| + return kPartial_Combine;
|
| + }
|
| + last->fLastY = last->fFirstY - 1;
|
| + last->fFirstY = edge->fFirstY;
|
| + last->fWinding = edge->fWinding;
|
| + return kPartial_Combine;
|
| + }
|
| + return kNo_Combine;
|
| +}
|
| +
|
| +static bool vertical_line(const SkEdge* edge) {
|
| +#ifdef SK_SUPPORT_LEGACY_VERTICAL_EDGE // this disables combining vertical overlapping edges
|
| + return false;
|
| +#endif
|
| + return !edge->fDX && !edge->fCurveCount;
|
| +}
|
| +
|
| void SkEdgeBuilder::addLine(const SkPoint pts[]) {
|
| SkEdge* edge = typedAllocThrow<SkEdge>(fAlloc);
|
| if (edge->setLine(pts[0], pts[1], fShiftUp)) {
|
| + if (vertical_line(edge) && fList.count()) {
|
| + Combine combine = CombineVertical(edge, *(fList.end() - 1));
|
| + if (kNo_Combine != combine) {
|
| + if (kTotal_Combine == combine) {
|
| + fList.pop();
|
| + }
|
| + goto unallocate_edge;
|
| + }
|
| + }
|
| fList.push(edge);
|
| } else {
|
| +unallocate_edge:
|
| + ;
|
| // TODO: unallocate edge from storage...
|
| }
|
| }
|
| @@ -79,6 +138,11 @@ static void setShiftedClip(SkRect* dst, const SkIRect& src, int shift) {
|
| SkIntToScalar(src.fBottom >> shift));
|
| }
|
|
|
| +SkEdgeBuilder::Combine SkEdgeBuilder::checkVertical(const SkEdge* edge, SkEdge** edgePtr) {
|
| + return !vertical_line(edge) || edgePtr <= fEdgeList ? kNo_Combine :
|
| + CombineVertical(edge, edgePtr[-1]);
|
| +}
|
| +
|
| int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shiftUp,
|
| bool canCullToTheRight) {
|
| SkPath::Iter iter(path, true);
|
| @@ -119,7 +183,12 @@ int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shift
|
| SkASSERT(lineCount <= SkLineClipper::kMaxClippedLineSegments);
|
| for (int i = 0; i < lineCount; i++) {
|
| if (edge->setLine(lines[i], lines[i + 1], shiftUp)) {
|
| - *edgePtr++ = edge++;
|
| + Combine combine = checkVertical(edge, edgePtr);
|
| + if (kNo_Combine == combine) {
|
| + *edgePtr++ = edge++;
|
| + } else if (kTotal_Combine == combine) {
|
| + --edgePtr;
|
| + }
|
| }
|
| }
|
| break;
|
| @@ -139,7 +208,12 @@ int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shift
|
| break;
|
| case SkPath::kLine_Verb:
|
| if (edge->setLine(pts[0], pts[1], shiftUp)) {
|
| - *edgePtr++ = edge++;
|
| + Combine combine = checkVertical(edge, edgePtr);
|
| + if (kNo_Combine == combine) {
|
| + *edgePtr++ = edge++;
|
| + } else if (kTotal_Combine == combine) {
|
| + --edgePtr;
|
| + }
|
| }
|
| break;
|
| default:
|
|
|