OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrTessellator.h" | 8 #include "GrTessellator.h" |
9 | 9 |
10 #include "GrDefaultGeoProcFactory.h" | 10 #include "GrDefaultGeoProcFactory.h" |
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 | 669 |
670 SkPoint pts[4]; | 670 SkPoint pts[4]; |
671 bool done = false; | 671 bool done = false; |
672 *isLinear = true; | 672 *isLinear = true; |
673 SkPath::Iter iter(path, false); | 673 SkPath::Iter iter(path, false); |
674 Vertex* prev = nullptr; | 674 Vertex* prev = nullptr; |
675 Vertex* head = nullptr; | 675 Vertex* head = nullptr; |
676 if (path.isInverseFillType()) { | 676 if (path.isInverseFillType()) { |
677 SkPoint quad[4]; | 677 SkPoint quad[4]; |
678 clipBounds.toQuad(quad); | 678 clipBounds.toQuad(quad); |
679 for (int i = 0; i < 4; i++) { | 679 for (int i = 3; i >= 0; i--) { |
680 prev = append_point_to_contour(quad[i], prev, &head, alloc); | 680 prev = append_point_to_contour(quad[i], prev, &head, alloc); |
681 } | 681 } |
682 head->fPrev = prev; | 682 head->fPrev = prev; |
683 prev->fNext = head; | 683 prev->fNext = head; |
684 *contours++ = head; | 684 *contours++ = head; |
685 head = prev = nullptr; | 685 head = prev = nullptr; |
686 } | 686 } |
687 SkAutoConicToQuads converter; | 687 SkAutoConicToQuads converter; |
688 while (!done) { | 688 while (!done) { |
689 SkPath::Verb verb = iter.next(pts); | 689 SkPath::Verb verb = iter.next(pts); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
751 if (!poly) { | 751 if (!poly) { |
752 return false; | 752 return false; |
753 } | 753 } |
754 int winding = poly->fWinding; | 754 int winding = poly->fWinding; |
755 switch (fillType) { | 755 switch (fillType) { |
756 case SkPath::kWinding_FillType: | 756 case SkPath::kWinding_FillType: |
757 return winding != 0; | 757 return winding != 0; |
758 case SkPath::kEvenOdd_FillType: | 758 case SkPath::kEvenOdd_FillType: |
759 return (winding & 1) != 0; | 759 return (winding & 1) != 0; |
760 case SkPath::kInverseWinding_FillType: | 760 case SkPath::kInverseWinding_FillType: |
761 return winding == -1; | 761 return winding == 1; |
762 case SkPath::kInverseEvenOdd_FillType: | 762 case SkPath::kInverseEvenOdd_FillType: |
763 return (winding & 1) == 1; | 763 return (winding & 1) == 1; |
764 default: | 764 default: |
765 SkASSERT(false); | 765 SkASSERT(false); |
766 return false; | 766 return false; |
767 } | 767 } |
768 } | 768 } |
769 | 769 |
770 Edge* new_edge(Vertex* prev, Vertex* next, SkChunkAlloc& alloc, Comparator& c, | 770 Edge* new_edge(Vertex* prev, Vertex* next, SkChunkAlloc& alloc, Comparator& c, |
771 int winding_scale = 1) { | 771 int winding_scale = 1) { |
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1630 LOG("path.moveTo(%20.20g, %20.20g);\n", v->fPoint.fX, v->fPoint.fY); | 1630 LOG("path.moveTo(%20.20g, %20.20g);\n", v->fPoint.fX, v->fPoint.fY); |
1631 for (v = v->fNext; v != contours[i]; v = v->fNext) { | 1631 for (v = v->fNext; v != contours[i]; v = v->fNext) { |
1632 LOG("path.lineTo(%20.20g, %20.20g);\n", v->fPoint.fX, v->fPoint.fY); | 1632 LOG("path.lineTo(%20.20g, %20.20g);\n", v->fPoint.fX, v->fPoint.fY); |
1633 } | 1633 } |
1634 } | 1634 } |
1635 #endif | 1635 #endif |
1636 sanitize_contours(contours, contourCnt, antialias); | 1636 sanitize_contours(contours, contourCnt, antialias); |
1637 return build_edges(contours, contourCnt, c, alloc); | 1637 return build_edges(contours, contourCnt, c, alloc); |
1638 } | 1638 } |
1639 | 1639 |
1640 Poly* mesh_to_polys(Vertex** vertices, SkPath::FillType fillType, Comparator& c, | 1640 Poly* mesh_to_polys(Vertex** vertices, Comparator& c, SkChunkAlloc& alloc) { |
1641 SkChunkAlloc& alloc) { | |
1642 if (!vertices || !*vertices) { | 1641 if (!vertices || !*vertices) { |
1643 return nullptr; | 1642 return nullptr; |
1644 } | 1643 } |
1645 | 1644 |
1646 // Sort vertices in Y (secondarily in X). | 1645 // Sort vertices in Y (secondarily in X). |
1647 merge_sort(vertices, c); | 1646 merge_sort(vertices, c); |
1648 merge_coincident_vertices(vertices, c, alloc); | 1647 merge_coincident_vertices(vertices, c, alloc); |
1649 #if LOGGING_ENABLED | 1648 #if LOGGING_ENABLED |
1650 for (Vertex* v = *vertices; v != nullptr; v = v->fNext) { | 1649 for (Vertex* v = *vertices; v != nullptr; v = v->fNext) { |
1651 static float gID = 0.0f; | 1650 static float gID = 0.0f; |
1652 v->fID = gID++; | 1651 v->fID = gID++; |
1653 } | 1652 } |
1654 #endif | 1653 #endif |
1655 simplify(*vertices, c, alloc); | 1654 simplify(*vertices, c, alloc); |
1656 return tessellate(*vertices, alloc); | 1655 return tessellate(*vertices, alloc); |
1657 } | 1656 } |
1658 | 1657 |
1659 Poly* contours_to_polys(Vertex** contours, int contourCnt, SkPath::FillType fill
Type, | 1658 Poly* contours_to_polys(Vertex** contours, int contourCnt, SkPath::FillType fill
Type, |
1660 const SkRect& pathBounds, bool antialias, | 1659 const SkRect& pathBounds, bool antialias, |
1661 SkChunkAlloc& alloc) { | 1660 SkChunkAlloc& alloc) { |
1662 Comparator c; | 1661 Comparator c; |
1663 if (pathBounds.width() > pathBounds.height()) { | 1662 if (pathBounds.width() > pathBounds.height()) { |
1664 c.sweep_lt = sweep_lt_horiz; | 1663 c.sweep_lt = sweep_lt_horiz; |
1665 c.sweep_gt = sweep_gt_horiz; | 1664 c.sweep_gt = sweep_gt_horiz; |
1666 } else { | 1665 } else { |
1667 c.sweep_lt = sweep_lt_vert; | 1666 c.sweep_lt = sweep_lt_vert; |
1668 c.sweep_gt = sweep_gt_vert; | 1667 c.sweep_gt = sweep_gt_vert; |
1669 } | 1668 } |
1670 Vertex* mesh = contours_to_mesh(contours, contourCnt, antialias, c, alloc); | 1669 Vertex* mesh = contours_to_mesh(contours, contourCnt, antialias, c, alloc); |
1671 Poly* polys = mesh_to_polys(&mesh, fillType, c, alloc); | 1670 Poly* polys = mesh_to_polys(&mesh, c, alloc); |
1672 if (antialias) { | 1671 if (antialias) { |
1673 EdgeList* boundaries = extract_boundaries(mesh, fillType, alloc); | 1672 EdgeList* boundaries = extract_boundaries(mesh, fillType, alloc); |
1674 VertexList aaMesh; | 1673 VertexList aaMesh; |
1675 for (EdgeList* boundary = boundaries; boundary != nullptr; boundary = bo
undary->fNext) { | 1674 for (EdgeList* boundary = boundaries; boundary != nullptr; boundary = bo
undary->fNext) { |
1676 simplify_boundary(boundary, c, alloc); | 1675 simplify_boundary(boundary, c, alloc); |
1677 if (boundary->fCount > 2) { | 1676 if (boundary->fCount > 2) { |
1678 boundary_to_aa_mesh(boundary, &aaMesh, c, alloc); | 1677 boundary_to_aa_mesh(boundary, &aaMesh, c, alloc); |
1679 } | 1678 } |
1680 } | 1679 } |
1681 return mesh_to_polys(&aaMesh.fHead, SkPath::kWinding_FillType, c, alloc)
; | 1680 return mesh_to_polys(&aaMesh.fHead, c, alloc); |
1682 } | 1681 } |
1683 return polys; | 1682 return polys; |
1684 } | 1683 } |
1685 | 1684 |
1686 // Stage 6: Triangulate the monotone polygons into a vertex buffer. | 1685 // Stage 6: Triangulate the monotone polygons into a vertex buffer. |
1687 void* polys_to_triangles(Poly* polys, SkPath::FillType fillType, const AAParams*
aaParams, | 1686 void* polys_to_triangles(Poly* polys, SkPath::FillType fillType, const AAParams*
aaParams, |
1688 void* data) { | 1687 void* data) { |
1689 for (Poly* poly = polys; poly; poly = poly->fNext) { | 1688 for (Poly* poly = polys; poly; poly = poly->fNext) { |
1690 if (apply_fill_type(fillType, poly)) { | 1689 if (apply_fill_type(fillType, poly)) { |
1691 data = poly->emit(aaParams, data); | 1690 data = poly->emit(aaParams, data); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1748 int contourCnt; | 1747 int contourCnt; |
1749 int sizeEstimate; | 1748 int sizeEstimate; |
1750 get_contour_count_and_size_estimate(path, tolerance, &contourCnt, &sizeEstim
ate); | 1749 get_contour_count_and_size_estimate(path, tolerance, &contourCnt, &sizeEstim
ate); |
1751 if (contourCnt <= 0) { | 1750 if (contourCnt <= 0) { |
1752 *isLinear = true; | 1751 *isLinear = true; |
1753 return 0; | 1752 return 0; |
1754 } | 1753 } |
1755 SkChunkAlloc alloc(sizeEstimate); | 1754 SkChunkAlloc alloc(sizeEstimate); |
1756 Poly* polys = path_to_polys(path, tolerance, clipBounds, contourCnt, alloc,
antialias, | 1755 Poly* polys = path_to_polys(path, tolerance, clipBounds, contourCnt, alloc,
antialias, |
1757 isLinear); | 1756 isLinear); |
1758 SkPath::FillType fillType = path.getFillType(); | 1757 SkPath::FillType fillType = antialias ? SkPath::kWinding_FillType : path.get
FillType(); |
1759 int count = count_points(polys, fillType); | 1758 int count = count_points(polys, fillType); |
1760 if (0 == count) { | 1759 if (0 == count) { |
1761 return 0; | 1760 return 0; |
1762 } | 1761 } |
1763 | 1762 |
1764 void* verts = vertexAllocator->lock(count); | 1763 void* verts = vertexAllocator->lock(count); |
1765 if (!verts) { | 1764 if (!verts) { |
1766 SkDebugf("Could not allocate vertices\n"); | 1765 SkDebugf("Could not allocate vertices\n"); |
1767 return 0; | 1766 return 0; |
1768 } | 1767 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1815 } | 1814 } |
1816 } | 1815 } |
1817 int actualCount = static_cast<int>(vertsEnd - *verts); | 1816 int actualCount = static_cast<int>(vertsEnd - *verts); |
1818 SkASSERT(actualCount <= count); | 1817 SkASSERT(actualCount <= count); |
1819 SkASSERT(pointsEnd - points == actualCount); | 1818 SkASSERT(pointsEnd - points == actualCount); |
1820 delete[] points; | 1819 delete[] points; |
1821 return actualCount; | 1820 return actualCount; |
1822 } | 1821 } |
1823 | 1822 |
1824 } // namespace | 1823 } // namespace |
OLD | NEW |