| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2006 The Android Open Source Project | 2  * Copyright 2006 The Android Open Source Project | 
| 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 "SkBuffer.h" | 8 #include "SkBuffer.h" | 
| 9 #include "SkErrorInternals.h" | 9 #include "SkErrorInternals.h" | 
| 10 #include "SkGeometry.h" | 10 #include "SkGeometry.h" | 
| (...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 833     if (fLastMoveToIndex >= 0) { | 833     if (fLastMoveToIndex >= 0) { | 
| 834         fLastMoveToIndex = ~fLastMoveToIndex; | 834         fLastMoveToIndex = ~fLastMoveToIndex; | 
| 835     } | 835     } | 
| 836 #else | 836 #else | 
| 837     fLastMoveToIndex ^= ~fLastMoveToIndex >> (8 * sizeof(fLastMoveToIndex) - 1); | 837     fLastMoveToIndex ^= ~fLastMoveToIndex >> (8 * sizeof(fLastMoveToIndex) - 1); | 
| 838 #endif | 838 #endif | 
| 839 } | 839 } | 
| 840 | 840 | 
| 841 /////////////////////////////////////////////////////////////////////////////// | 841 /////////////////////////////////////////////////////////////////////////////// | 
| 842 | 842 | 
|  | 843 namespace { | 
|  | 844 | 
|  | 845 template <unsigned N> | 
|  | 846 class PointIterator { | 
|  | 847 public: | 
|  | 848     PointIterator(SkPath::Direction dir, unsigned startIndex) | 
|  | 849         : fCurrent(startIndex % N) | 
|  | 850         , fAdvance(dir == SkPath::kCW_Direction ? 1 : N - 1) { } | 
|  | 851 | 
|  | 852     const SkPoint& current() const { | 
|  | 853         SkASSERT(fCurrent < N); | 
|  | 854         return fPts[fCurrent]; | 
|  | 855     } | 
|  | 856 | 
|  | 857     const SkPoint& next() { | 
|  | 858         fCurrent = (fCurrent + fAdvance) % N; | 
|  | 859         return this->current(); | 
|  | 860     } | 
|  | 861 | 
|  | 862 protected: | 
|  | 863     SkPoint fPts[N]; | 
|  | 864 | 
|  | 865 private: | 
|  | 866     unsigned fCurrent; | 
|  | 867     unsigned fAdvance; | 
|  | 868 }; | 
|  | 869 | 
|  | 870 class RectPointIterator : public PointIterator<4> { | 
|  | 871 public: | 
|  | 872     RectPointIterator(const SkRect& rect, SkPath::Direction dir, unsigned startI
      ndex) | 
|  | 873         : PointIterator(dir, startIndex) { | 
|  | 874 | 
|  | 875         fPts[0] = SkPoint::Make(rect.fLeft, rect.fTop); | 
|  | 876         fPts[1] = SkPoint::Make(rect.fRight, rect.fTop); | 
|  | 877         fPts[2] = SkPoint::Make(rect.fRight, rect.fBottom); | 
|  | 878         fPts[3] = SkPoint::Make(rect.fLeft, rect.fBottom); | 
|  | 879     } | 
|  | 880 }; | 
|  | 881 | 
|  | 882 class OvalPointIterator : public PointIterator<4> { | 
|  | 883 public: | 
|  | 884     OvalPointIterator(const SkRect& oval, SkPath::Direction dir, unsigned startI
      ndex) | 
|  | 885         : PointIterator(dir, startIndex) { | 
|  | 886 | 
|  | 887         const SkScalar cx = oval.centerX(); | 
|  | 888         const SkScalar cy = oval.centerY(); | 
|  | 889 | 
|  | 890         fPts[0] = SkPoint::Make(cx, oval.fTop); | 
|  | 891         fPts[1] = SkPoint::Make(oval.fRight, cy); | 
|  | 892         fPts[2] = SkPoint::Make(cx, oval.fBottom); | 
|  | 893         fPts[3] = SkPoint::Make(oval.fLeft, cy); | 
|  | 894     } | 
|  | 895 }; | 
|  | 896 | 
|  | 897 class RRectPointIterator : public PointIterator<8> { | 
|  | 898 public: | 
|  | 899     RRectPointIterator(const SkRRect& rrect, SkPath::Direction dir, unsigned sta
      rtIndex) | 
|  | 900         : PointIterator(dir, startIndex) { | 
|  | 901 | 
|  | 902         const SkRect& bounds = rrect.getBounds(); | 
|  | 903         const SkScalar L = bounds.fLeft; | 
|  | 904         const SkScalar T = bounds.fTop; | 
|  | 905         const SkScalar R = bounds.fRight; | 
|  | 906         const SkScalar B = bounds.fBottom; | 
|  | 907 | 
|  | 908         fPts[0] = SkPoint::Make(L + rrect.radii(SkRRect::kUpperLeft_Corner).fX, 
      T); | 
|  | 909         fPts[1] = SkPoint::Make(R - rrect.radii(SkRRect::kUpperRight_Corner).fX,
       T); | 
|  | 910         fPts[2] = SkPoint::Make(R, T + rrect.radii(SkRRect::kUpperRight_Corner).
      fY); | 
|  | 911         fPts[3] = SkPoint::Make(R, B - rrect.radii(SkRRect::kLowerRight_Corner).
      fY); | 
|  | 912         fPts[4] = SkPoint::Make(R - rrect.radii(SkRRect::kLowerRight_Corner).fX,
       B); | 
|  | 913         fPts[5] = SkPoint::Make(L + rrect.radii(SkRRect::kLowerLeft_Corner).fX, 
      B); | 
|  | 914         fPts[6] = SkPoint::Make(L, B - rrect.radii(SkRRect::kLowerLeft_Corner).f
      Y); | 
|  | 915         fPts[7] = SkPoint::Make(L, T + rrect.radii(SkRRect::kUpperLeft_Corner).f
      Y); | 
|  | 916     } | 
|  | 917 }; | 
|  | 918 | 
|  | 919 } // anonymous namespace | 
|  | 920 | 
| 843 static void assert_known_direction(int dir) { | 921 static void assert_known_direction(int dir) { | 
| 844     SkASSERT(SkPath::kCW_Direction == dir || SkPath::kCCW_Direction == dir); | 922     SkASSERT(SkPath::kCW_Direction == dir || SkPath::kCCW_Direction == dir); | 
| 845 } | 923 } | 
| 846 | 924 | 
| 847 void SkPath::addRect(const SkRect& rect, Direction dir) { | 925 void SkPath::addRect(const SkRect& rect, Direction dir) { | 
| 848     this->addRect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, dir); | 926     this->addRect(rect, dir, 0); | 
| 849 } | 927 } | 
| 850 | 928 | 
| 851 void SkPath::addRect(SkScalar left, SkScalar top, SkScalar right, | 929 void SkPath::addRect(SkScalar left, SkScalar top, SkScalar right, | 
| 852                      SkScalar bottom, Direction dir) { | 930                      SkScalar bottom, Direction dir) { | 
|  | 931     this->addRect(SkRect::MakeLTRB(left, top, right, bottom), dir, 0); | 
|  | 932 } | 
|  | 933 | 
|  | 934 void SkPath::addRect(const SkRect &rect, Direction dir, unsigned startIndex) { | 
| 853     assert_known_direction(dir); | 935     assert_known_direction(dir); | 
| 854     fFirstDirection = this->hasOnlyMoveTos() ? | 936     fFirstDirection = this->hasOnlyMoveTos() ? | 
| 855                         (SkPathPriv::FirstDirection)dir : SkPathPriv::kUnknown_F
      irstDirection; | 937         (SkPathPriv::FirstDirection)dir : SkPathPriv::kUnknown_FirstDirection; | 
| 856     SkAutoDisableDirectionCheck addc(this); | 938     SkAutoDisableDirectionCheck addc(this); | 
|  | 939     SkAutoPathBoundsUpdate apbu(this, rect); | 
| 857 | 940 | 
| 858     SkAutoPathBoundsUpdate apbu(this, left, top, right, bottom); | 941     SkDEBUGCODE(int initialVerbCount = this->countVerbs()); | 
| 859 | 942 | 
| 860     this->incReserve(5); | 943     const int kVerbs = 5; // moveTo + 3x lineTo + close | 
|  | 944     this->incReserve(kVerbs); | 
| 861 | 945 | 
| 862     this->moveTo(left, top); | 946     RectPointIterator iter(rect, dir, startIndex); | 
| 863     if (dir == kCCW_Direction) { | 947 | 
| 864         this->lineTo(left, bottom); | 948     this->moveTo(iter.current()); | 
| 865         this->lineTo(right, bottom); | 949     this->lineTo(iter.next()); | 
| 866         this->lineTo(right, top); | 950     this->lineTo(iter.next()); | 
| 867     } else { | 951     this->lineTo(iter.next()); | 
| 868         this->lineTo(right, top); |  | 
| 869         this->lineTo(right, bottom); |  | 
| 870         this->lineTo(left, bottom); |  | 
| 871     } |  | 
| 872     this->close(); | 952     this->close(); | 
|  | 953 | 
|  | 954     SkASSERT(this->countVerbs() == initialVerbCount + kVerbs); | 
| 873 } | 955 } | 
| 874 | 956 | 
| 875 void SkPath::addPoly(const SkPoint pts[], int count, bool close) { | 957 void SkPath::addPoly(const SkPoint pts[], int count, bool close) { | 
| 876     SkDEBUGCODE(this->validate();) | 958     SkDEBUGCODE(this->validate();) | 
| 877     if (count <= 0) { | 959     if (count <= 0) { | 
| 878         return; | 960         return; | 
| 879     } | 961     } | 
| 880 | 962 | 
| 881     fLastMoveToIndex = fPathRef->countPoints(); | 963     fLastMoveToIndex = fPathRef->countPoints(); | 
| 882 | 964 | 
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 972 } | 1054 } | 
| 973 | 1055 | 
| 974 void SkPath::addRoundRect(const SkRect& rect, const SkScalar radii[], | 1056 void SkPath::addRoundRect(const SkRect& rect, const SkScalar radii[], | 
| 975                           Direction dir) { | 1057                           Direction dir) { | 
| 976     SkRRect rrect; | 1058     SkRRect rrect; | 
| 977     rrect.setRectRadii(rect, (const SkVector*) radii); | 1059     rrect.setRectRadii(rect, (const SkVector*) radii); | 
| 978     this->addRRect(rrect, dir); | 1060     this->addRRect(rrect, dir); | 
| 979 } | 1061 } | 
| 980 | 1062 | 
| 981 void SkPath::addRRect(const SkRRect& rrect, Direction dir) { | 1063 void SkPath::addRRect(const SkRRect& rrect, Direction dir) { | 
| 982     assert_known_direction(dir); | 1064     // legacy start indices: 6 (CW) and 7(CCW) | 
|  | 1065     this->addRRect(rrect, dir, dir == kCW_Direction ? 6 : 7); | 
|  | 1066 } | 
| 983 | 1067 | 
| 984     if (rrect.isEmpty()) { | 1068 void SkPath::addRRect(const SkRRect &rrect, Direction dir, unsigned startIndex) 
      { | 
| 985         return; | 1069         assert_known_direction(dir); | 
| 986     } |  | 
| 987 | 1070 | 
| 988     const SkRect& bounds = rrect.getBounds(); | 1071         if (rrect.isEmpty()) { | 
|  | 1072             return; | 
|  | 1073         } | 
| 989 | 1074 | 
| 990     if (rrect.isRect()) { | 1075         const SkRect& bounds = rrect.getBounds(); | 
| 991         this->addRect(bounds, dir); |  | 
| 992     } else if (rrect.isOval()) { |  | 
| 993         this->addOval(bounds, dir); |  | 
| 994     } else { |  | 
| 995         fFirstDirection = this->hasOnlyMoveTos() ? |  | 
| 996                             (SkPathPriv::FirstDirection)dir : SkPathPriv::kUnkno
      wn_FirstDirection; |  | 
| 997 | 1076 | 
| 998         SkAutoPathBoundsUpdate apbu(this, bounds); | 1077         if (rrect.isRect()) { | 
| 999         SkAutoDisableDirectionCheck addc(this); | 1078             // degenerate(rect) => radii points are collapsing | 
|  | 1079             this->addRect(bounds, dir, (startIndex + 1) / 2); | 
|  | 1080         } else if (rrect.isOval()) { | 
|  | 1081             // degenerate(oval) => line points are collapsing | 
|  | 1082             this->addOval(bounds, dir, startIndex / 2); | 
|  | 1083         } else { | 
|  | 1084             fFirstDirection = this->hasOnlyMoveTos() ? | 
|  | 1085                                 (SkPathPriv::FirstDirection)dir : SkPathPriv::kU
      nknown_FirstDirection; | 
| 1000 | 1086 | 
| 1001         const SkScalar L = bounds.fLeft; | 1087             SkAutoPathBoundsUpdate apbu(this, bounds); | 
| 1002         const SkScalar T = bounds.fTop; | 1088             SkAutoDisableDirectionCheck addc(this); | 
| 1003         const SkScalar R = bounds.fRight; |  | 
| 1004         const SkScalar B = bounds.fBottom; |  | 
| 1005         const SkScalar W = SK_ScalarRoot2Over2; |  | 
| 1006 | 1089 | 
| 1007         this->incReserve(13); | 1090             // we start with a conic on odd indices when moving CW vs. even indi
      ces when moving CCW | 
| 1008         if (kCW_Direction == dir) { | 1091             const bool startsWithConic = ((startIndex & 1) == (dir == kCW_Direct
      ion)); | 
| 1009             this->moveTo(L, B - rrect.fRadii[SkRRect::kLowerLeft_Corner].fY); | 1092             const SkScalar weight = SK_ScalarRoot2Over2; | 
| 1010 | 1093 | 
| 1011             this->lineTo(L, T + rrect.fRadii[SkRRect::kUpperLeft_Corner].fY); | 1094             SkDEBUGCODE(int initialVerbCount = this->countVerbs()); | 
| 1012             this->conicTo(L, T, L + rrect.fRadii[SkRRect::kUpperLeft_Corner].fX,
       T, W); | 1095             const int kVerbs = startsWithConic | 
|  | 1096                 ? 9   // moveTo + 4x conicTo + 3x lineTo + close | 
|  | 1097                 : 10; // moveTo + 4x lineTo + 4x conicTo + close | 
|  | 1098             this->incReserve(kVerbs); | 
| 1013 | 1099 | 
| 1014             this->lineTo(R - rrect.fRadii[SkRRect::kUpperRight_Corner].fX, T); | 1100             RRectPointIterator rrectIter(rrect, dir, startIndex); | 
| 1015             this->conicTo(R, T, R, T + rrect.fRadii[SkRRect::kUpperRight_Corner]
      .fY, W); | 1101             // Corner iterator indices follow the collapsed radii model, | 
|  | 1102             // adjusted such that the start pt is "behind" the radii start pt. | 
|  | 1103             const unsigned rectStartIndex = startIndex / 2 + (dir == kCW_Directi
      on ? 0 : 1); | 
|  | 1104             RectPointIterator rectIter(bounds, dir, rectStartIndex); | 
| 1016 | 1105 | 
| 1017             this->lineTo(R, B - rrect.fRadii[SkRRect::kLowerRight_Corner].fY); | 1106             this->moveTo(rrectIter.current()); | 
| 1018             this->conicTo(R, B, R - rrect.fRadii[SkRRect::kLowerRight_Corner].fX
      , B, W); | 1107             if (startsWithConic) { | 
|  | 1108                 for (unsigned i = 0; i < 3; ++i) { | 
|  | 1109                     this->conicTo(rectIter.next(), rrectIter.next(), weight); | 
|  | 1110                     this->lineTo(rrectIter.next()); | 
|  | 1111                 } | 
|  | 1112                 this->conicTo(rectIter.next(), rrectIter.next(), weight); | 
|  | 1113                 // final lineTo handled by close(). | 
|  | 1114             } else { | 
|  | 1115                 for (unsigned i = 0; i < 4; ++i) { | 
|  | 1116                     this->lineTo(rrectIter.next()); | 
|  | 1117                     this->conicTo(rectIter.next(), rrectIter.next(), weight); | 
|  | 1118                 } | 
|  | 1119             } | 
|  | 1120             this->close(); | 
| 1019 | 1121 | 
| 1020             this->lineTo(L + rrect.fRadii[SkRRect::kLowerLeft_Corner].fX, B); | 1122             SkASSERT(this->countVerbs() == initialVerbCount + kVerbs); | 
| 1021             this->conicTo(L, B, L, B - rrect.fRadii[SkRRect::kLowerLeft_Corner].
      fY, W); | 1123         } | 
| 1022         } else { |  | 
| 1023             this->moveTo(L, T + rrect.fRadii[SkRRect::kUpperLeft_Corner].fY); |  | 
| 1024 | 1124 | 
| 1025             this->lineTo(L, B - rrect.fRadii[SkRRect::kLowerLeft_Corner].fY); | 1125         SkDEBUGCODE(fPathRef->validate();) | 
| 1026             this->conicTo(L, B, L + rrect.fRadii[SkRRect::kLowerLeft_Corner].fX,
       B, W); |  | 
| 1027 |  | 
| 1028             this->lineTo(R - rrect.fRadii[SkRRect::kLowerRight_Corner].fX, B); |  | 
| 1029             this->conicTo(R, B, R, B - rrect.fRadii[SkRRect::kLowerRight_Corner]
      .fY, W); |  | 
| 1030 |  | 
| 1031             this->lineTo(R, T + rrect.fRadii[SkRRect::kUpperRight_Corner].fY); |  | 
| 1032             this->conicTo(R, T, R - rrect.fRadii[SkRRect::kUpperRight_Corner].fX
      , T, W); |  | 
| 1033 |  | 
| 1034             this->lineTo(L + rrect.fRadii[SkRRect::kUpperLeft_Corner].fX, T); |  | 
| 1035             this->conicTo(L, T, L, T + rrect.fRadii[SkRRect::kUpperLeft_Corner].
      fY, W); |  | 
| 1036         } |  | 
| 1037         this->close(); |  | 
| 1038     } |  | 
| 1039     SkDEBUGCODE(fPathRef->validate();) |  | 
| 1040 } | 1126 } | 
| 1041 | 1127 | 
| 1042 bool SkPath::hasOnlyMoveTos() const { | 1128 bool SkPath::hasOnlyMoveTos() const { | 
| 1043     int count = fPathRef->countVerbs(); | 1129     int count = fPathRef->countVerbs(); | 
| 1044     const uint8_t* verbs = const_cast<const SkPathRef*>(fPathRef.get())->verbsMe
      mBegin(); | 1130     const uint8_t* verbs = const_cast<const SkPathRef*>(fPathRef.get())->verbsMe
      mBegin(); | 
| 1045     for (int i = 0; i < count; ++i) { | 1131     for (int i = 0; i < count; ++i) { | 
| 1046         if (*verbs == kLine_Verb || | 1132         if (*verbs == kLine_Verb || | 
| 1047             *verbs == kQuad_Verb || | 1133             *verbs == kQuad_Verb || | 
| 1048             *verbs == kConic_Verb || | 1134             *verbs == kConic_Verb || | 
| 1049             *verbs == kCubic_Verb) { | 1135             *verbs == kCubic_Verb) { | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 1065                                     SkScalarToDouble(rx), SkScalarToDouble(ry) )
      ; | 1151                                     SkScalarToDouble(rx), SkScalarToDouble(ry) )
      ; | 
| 1066         return; | 1152         return; | 
| 1067     } | 1153     } | 
| 1068 | 1154 | 
| 1069     SkRRect rrect; | 1155     SkRRect rrect; | 
| 1070     rrect.setRectXY(rect, rx, ry); | 1156     rrect.setRectXY(rect, rx, ry); | 
| 1071     this->addRRect(rrect, dir); | 1157     this->addRRect(rrect, dir); | 
| 1072 } | 1158 } | 
| 1073 | 1159 | 
| 1074 void SkPath::addOval(const SkRect& oval, Direction dir) { | 1160 void SkPath::addOval(const SkRect& oval, Direction dir) { | 
|  | 1161     // legacy start index: 1 | 
|  | 1162     this->addOval(oval, dir, 1); | 
|  | 1163 } | 
|  | 1164 | 
|  | 1165 void SkPath::addOval(const SkRect &oval, Direction dir, unsigned startPointIndex
      ) { | 
| 1075     assert_known_direction(dir); | 1166     assert_known_direction(dir); | 
| 1076 | 1167 | 
| 1077     /* If addOval() is called after previous moveTo(), | 1168     /* If addOval() is called after previous moveTo(), | 
| 1078        this path is still marked as an oval. This is used to | 1169        this path is still marked as an oval. This is used to | 
| 1079        fit into WebKit's calling sequences. | 1170        fit into WebKit's calling sequences. | 
| 1080        We can't simply check isEmpty() in this case, as additional | 1171        We can't simply check isEmpty() in this case, as additional | 
| 1081        moveTo() would mark the path non empty. | 1172        moveTo() would mark the path non empty. | 
| 1082      */ | 1173      */ | 
| 1083     bool isOval = hasOnlyMoveTos(); | 1174     bool isOval = hasOnlyMoveTos(); | 
| 1084     if (isOval) { | 1175     if (isOval) { | 
| 1085         fFirstDirection = (SkPathPriv::FirstDirection)dir; | 1176         fFirstDirection = (SkPathPriv::FirstDirection)dir; | 
| 1086     } else { | 1177     } else { | 
| 1087         fFirstDirection = SkPathPriv::kUnknown_FirstDirection; | 1178         fFirstDirection = SkPathPriv::kUnknown_FirstDirection; | 
| 1088     } | 1179     } | 
| 1089 | 1180 | 
| 1090     SkAutoDisableDirectionCheck addc(this); | 1181     SkAutoDisableDirectionCheck addc(this); | 
| 1091 |  | 
| 1092     SkAutoPathBoundsUpdate apbu(this, oval); | 1182     SkAutoPathBoundsUpdate apbu(this, oval); | 
| 1093 | 1183 | 
| 1094     const SkScalar L = oval.fLeft; | 1184     SkDEBUGCODE(int initialVerbCount = this->countVerbs()); | 
| 1095     const SkScalar T = oval.fTop; | 1185     const int kVerbs = 6; // moveTo + 4x conicTo + close | 
| 1096     const SkScalar R = oval.fRight; | 1186     this->incReserve(kVerbs); | 
| 1097     const SkScalar B = oval.fBottom; | 1187 | 
| 1098     const SkScalar cx = oval.centerX(); | 1188     OvalPointIterator ovalIter(oval, dir, startPointIndex); | 
| 1099     const SkScalar cy = oval.centerY(); | 1189     // The corner iterator pts are tracking "behind" the oval/radii pts. | 
|  | 1190     RectPointIterator rectIter(oval, dir, startPointIndex + (dir == kCW_Directio
      n ? 0 : 1)); | 
| 1100     const SkScalar weight = SK_ScalarRoot2Over2; | 1191     const SkScalar weight = SK_ScalarRoot2Over2; | 
| 1101 | 1192 | 
| 1102     this->incReserve(9);   // move + 4 conics | 1193     this->moveTo(ovalIter.current()); | 
| 1103     this->moveTo(R, cy); | 1194     for (unsigned i = 0; i < 4; ++i) { | 
| 1104     if (dir == kCCW_Direction) { | 1195         this->conicTo(rectIter.next(), ovalIter.next(), weight); | 
| 1105         this->conicTo(R, T, cx, T, weight); |  | 
| 1106         this->conicTo(L, T, L, cy, weight); |  | 
| 1107         this->conicTo(L, B, cx, B, weight); |  | 
| 1108         this->conicTo(R, B, R, cy, weight); |  | 
| 1109     } else { |  | 
| 1110         this->conicTo(R, B, cx, B, weight); |  | 
| 1111         this->conicTo(L, B, L, cy, weight); |  | 
| 1112         this->conicTo(L, T, cx, T, weight); |  | 
| 1113         this->conicTo(R, T, R, cy, weight); |  | 
| 1114     } | 1196     } | 
| 1115     this->close(); | 1197     this->close(); | 
| 1116 | 1198 | 
|  | 1199     SkASSERT(this->countVerbs() == initialVerbCount + kVerbs); | 
|  | 1200 | 
| 1117     SkPathRef::Editor ed(&fPathRef); | 1201     SkPathRef::Editor ed(&fPathRef); | 
| 1118 | 1202 | 
| 1119     ed.setIsOval(isOval); | 1203     ed.setIsOval(isOval); | 
| 1120 } | 1204 } | 
| 1121 | 1205 | 
| 1122 void SkPath::addCircle(SkScalar x, SkScalar y, SkScalar r, Direction dir) { | 1206 void SkPath::addCircle(SkScalar x, SkScalar y, SkScalar r, Direction dir) { | 
| 1123     if (r > 0) { | 1207     if (r > 0) { | 
| 1124         SkRect  rect; | 1208         this->addOval(SkRect::MakeLTRB(x - r, y - r, x + r, y + r), dir); | 
| 1125         rect.set(x - r, y - r, x + r, y + r); |  | 
| 1126         this->addOval(rect, dir); |  | 
| 1127     } | 1209     } | 
| 1128 } | 1210 } | 
| 1129 | 1211 | 
| 1130 void SkPath::arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, | 1212 void SkPath::arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, | 
| 1131                    bool forceMoveTo) { | 1213                    bool forceMoveTo) { | 
| 1132     if (oval.width() < 0 || oval.height() < 0) { | 1214     if (oval.width() < 0 || oval.height() < 0) { | 
| 1133         return; | 1215         return; | 
| 1134     } | 1216     } | 
| 1135 | 1217 | 
| 1136     if (fPathRef->countVerbs() == 0) { | 1218     if (fPathRef->countVerbs() == 0) { | 
| (...skipping 1676 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2813     switch (this->getFillType()) { | 2895     switch (this->getFillType()) { | 
| 2814         case SkPath::kEvenOdd_FillType: | 2896         case SkPath::kEvenOdd_FillType: | 
| 2815         case SkPath::kInverseEvenOdd_FillType: | 2897         case SkPath::kInverseEvenOdd_FillType: | 
| 2816             w &= 1; | 2898             w &= 1; | 
| 2817             break; | 2899             break; | 
| 2818         default: | 2900         default: | 
| 2819             break; | 2901             break; | 
| 2820     } | 2902     } | 
| 2821     return SkToBool(w); | 2903     return SkToBool(w); | 
| 2822 } | 2904 } | 
| OLD | NEW | 
|---|