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" |
11 #include "SkMath.h" | 11 #include "SkMath.h" |
12 #include "SkPath.h" | 12 #include "SkPath.h" |
13 #include "SkPathRef.h" | 13 #include "SkPathRef.h" |
14 #include "SkRRect.h" | 14 #include "SkRRect.h" |
15 #include "SkThread.h" | 15 #include "SkThread.h" |
16 | 16 |
| 17 // These two should be removed once we fix any gpu bugs, and then |
| 18 // just move them into skia_for_chromium_defines.gypi |
17 #define SK_SUPPORT_LEGACY_ADDOVAL | 19 #define SK_SUPPORT_LEGACY_ADDOVAL |
| 20 #define SK_SUPPORT_LEGACY_ADDRRECT |
18 | 21 |
19 //////////////////////////////////////////////////////////////////////////// | 22 //////////////////////////////////////////////////////////////////////////// |
20 | 23 |
21 /** | 24 /** |
22 * Path.bounds is defined to be the bounds of all the control points. | 25 * Path.bounds is defined to be the bounds of all the control points. |
23 * If we called bounds.join(r) we would skip r if r was empty, which breaks | 26 * If we called bounds.join(r) we would skip r if r was empty, which breaks |
24 * our promise. Hence we have a custom joiner that doesn't look at emptiness | 27 * our promise. Hence we have a custom joiner that doesn't look at emptiness |
25 */ | 28 */ |
26 static void joinNoEmptyChecks(SkRect* dst, const SkRect& src) { | 29 static void joinNoEmptyChecks(SkRect* dst, const SkRect& src) { |
27 dst->fLeft = SkMinScalar(dst->fLeft, src.fLeft); | 30 dst->fLeft = SkMinScalar(dst->fLeft, src.fLeft); |
(...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 &matrix, pts); | 966 &matrix, pts); |
964 } | 967 } |
965 | 968 |
966 void SkPath::addRoundRect(const SkRect& rect, const SkScalar radii[], | 969 void SkPath::addRoundRect(const SkRect& rect, const SkScalar radii[], |
967 Direction dir) { | 970 Direction dir) { |
968 SkRRect rrect; | 971 SkRRect rrect; |
969 rrect.setRectRadii(rect, (const SkVector*) radii); | 972 rrect.setRectRadii(rect, (const SkVector*) radii); |
970 this->addRRect(rrect, dir); | 973 this->addRRect(rrect, dir); |
971 } | 974 } |
972 | 975 |
| 976 #ifdef SK_SUPPORT_LEGACY_ADDRRECT |
973 /* The inline clockwise and counterclockwise round rect quad approximations | 977 /* The inline clockwise and counterclockwise round rect quad approximations |
974 make it easier to see the symmetry patterns used by add corner quads. | 978 make it easier to see the symmetry patterns used by add corner quads. |
975 Clockwise corner value | 979 Clockwise corner value |
976 path->lineTo(rect.fLeft, rect.fTop + ry); 0 upper left | 980 path->lineTo(rect.fLeft, rect.fTop + ry); 0 upper left |
977 path->quadTo(rect.fLeft, rect.fTop + offPtY, | 981 path->quadTo(rect.fLeft, rect.fTop + offPtY, |
978 rect.fLeft + midPtX, rect.fTop + midPtY); | 982 rect.fLeft + midPtX, rect.fTop + midPtY); |
979 path->quadTo(rect.fLeft + offPtX, rect.fTop, | 983 path->quadTo(rect.fLeft + offPtX, rect.fTop, |
980 rect.fLeft + rx, rect.fTop); | 984 rect.fLeft + rx, rect.fTop); |
981 | 985 |
982 path->lineTo(rect.fRight - rx, rect.fTop); 1 upper right | 986 path->lineTo(rect.fRight - rx, rect.fTop); 1 upper right |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1089 path->lineTo(xOff[0], yOff[0]); | 1093 path->lineTo(xOff[0], yOff[0]); |
1090 } | 1094 } |
1091 if (rx || ry) { | 1095 if (rx || ry) { |
1092 path->quadTo(xOff[1], yOff[1], xOff[2], yOff[2]); | 1096 path->quadTo(xOff[1], yOff[1], xOff[2], yOff[2]); |
1093 path->quadTo(xOff[3], yOff[3], xOff[4], yOff[4]); | 1097 path->quadTo(xOff[3], yOff[3], xOff[4], yOff[4]); |
1094 } else { | 1098 } else { |
1095 path->lineTo(xOff[2], yOff[2]); | 1099 path->lineTo(xOff[2], yOff[2]); |
1096 path->lineTo(xOff[4], yOff[4]); | 1100 path->lineTo(xOff[4], yOff[4]); |
1097 } | 1101 } |
1098 } | 1102 } |
| 1103 #endif |
1099 | 1104 |
1100 void SkPath::addRRect(const SkRRect& rrect, Direction dir) { | 1105 void SkPath::addRRect(const SkRRect& rrect, Direction dir) { |
1101 assert_known_direction(dir); | 1106 assert_known_direction(dir); |
1102 | 1107 |
1103 if (rrect.isEmpty()) { | 1108 if (rrect.isEmpty()) { |
1104 return; | 1109 return; |
1105 } | 1110 } |
1106 | 1111 |
1107 const SkRect& bounds = rrect.getBounds(); | 1112 const SkRect& bounds = rrect.getBounds(); |
1108 | 1113 |
1109 if (rrect.isRect()) { | 1114 if (rrect.isRect()) { |
1110 this->addRect(bounds, dir); | 1115 this->addRect(bounds, dir); |
1111 } else if (rrect.isOval()) { | 1116 } else if (rrect.isOval()) { |
1112 this->addOval(bounds, dir); | 1117 this->addOval(bounds, dir); |
1113 } else { | 1118 } else { |
1114 fDirection = this->hasOnlyMoveTos() ? dir : kUnknown_Direction; | 1119 fDirection = this->hasOnlyMoveTos() ? dir : kUnknown_Direction; |
1115 | 1120 |
1116 SkAutoPathBoundsUpdate apbu(this, bounds); | 1121 SkAutoPathBoundsUpdate apbu(this, bounds); |
1117 SkAutoDisableDirectionCheck addc(this); | 1122 SkAutoDisableDirectionCheck addc(this); |
1118 | 1123 |
| 1124 #ifdef SK_SUPPORT_LEGACY_ADDRRECT |
1119 this->incReserve(21); | 1125 this->incReserve(21); |
1120 if (kCW_Direction == dir) { | 1126 if (kCW_Direction == dir) { |
1121 this->moveTo(bounds.fLeft, | 1127 this->moveTo(bounds.fLeft, |
1122 bounds.fBottom - rrect.fRadii[SkRRect::kLowerLeft_Corne
r].fY); | 1128 bounds.fBottom - rrect.fRadii[SkRRect::kLowerLeft_Corne
r].fY); |
1123 add_corner_quads(this, rrect, SkRRect::kUpperLeft_Corner, dir); | 1129 add_corner_quads(this, rrect, SkRRect::kUpperLeft_Corner, dir); |
1124 add_corner_quads(this, rrect, SkRRect::kUpperRight_Corner, dir); | 1130 add_corner_quads(this, rrect, SkRRect::kUpperRight_Corner, dir); |
1125 add_corner_quads(this, rrect, SkRRect::kLowerRight_Corner, dir); | 1131 add_corner_quads(this, rrect, SkRRect::kLowerRight_Corner, dir); |
1126 add_corner_quads(this, rrect, SkRRect::kLowerLeft_Corner, dir); | 1132 add_corner_quads(this, rrect, SkRRect::kLowerLeft_Corner, dir); |
1127 } else { | 1133 } else { |
1128 this->moveTo(bounds.fLeft, | 1134 this->moveTo(bounds.fLeft, |
1129 bounds.fTop + rrect.fRadii[SkRRect::kUpperLeft_Corner].
fY); | 1135 bounds.fTop + rrect.fRadii[SkRRect::kUpperLeft_Corner].
fY); |
1130 add_corner_quads(this, rrect, SkRRect::kLowerLeft_Corner, dir); | 1136 add_corner_quads(this, rrect, SkRRect::kLowerLeft_Corner, dir); |
1131 add_corner_quads(this, rrect, SkRRect::kLowerRight_Corner, dir); | 1137 add_corner_quads(this, rrect, SkRRect::kLowerRight_Corner, dir); |
1132 add_corner_quads(this, rrect, SkRRect::kUpperRight_Corner, dir); | 1138 add_corner_quads(this, rrect, SkRRect::kUpperRight_Corner, dir); |
1133 add_corner_quads(this, rrect, SkRRect::kUpperLeft_Corner, dir); | 1139 add_corner_quads(this, rrect, SkRRect::kUpperLeft_Corner, dir); |
1134 } | 1140 } |
| 1141 #else |
| 1142 const SkScalar L = bounds.fLeft; |
| 1143 const SkScalar T = bounds.fTop; |
| 1144 const SkScalar R = bounds.fRight; |
| 1145 const SkScalar B = bounds.fBottom; |
| 1146 const SkScalar W = SK_ScalarRoot2Over2; |
| 1147 |
| 1148 this->incReserve(13); |
| 1149 if (kCW_Direction == dir) { |
| 1150 this->moveTo(L, B - rrect.fRadii[SkRRect::kLowerLeft_Corner].fY); |
| 1151 |
| 1152 this->lineTo(L, T + rrect.fRadii[SkRRect::kUpperLeft_Corner].fY); |
| 1153 this->conicTo(L, T, L + rrect.fRadii[SkRRect::kUpperLeft_Corner].fX,
T, W); |
| 1154 |
| 1155 this->lineTo(R - rrect.fRadii[SkRRect::kUpperRight_Corner].fX, T); |
| 1156 this->conicTo(R, T, R, T + rrect.fRadii[SkRRect::kUpperRight_Corner]
.fY, W); |
| 1157 |
| 1158 this->lineTo(R, B - rrect.fRadii[SkRRect::kLowerRight_Corner].fY); |
| 1159 this->conicTo(R, B, R - rrect.fRadii[SkRRect::kLowerRight_Corner].fX
, B, W); |
| 1160 |
| 1161 this->lineTo(L + rrect.fRadii[SkRRect::kLowerLeft_Corner].fX, B); |
| 1162 this->conicTo(L, B, L, B - rrect.fRadii[SkRRect::kLowerLeft_Corner].
fY, W); |
| 1163 } else { |
| 1164 this->moveTo(L, T + rrect.fRadii[SkRRect::kUpperLeft_Corner].fY); |
| 1165 |
| 1166 this->lineTo(L, B - rrect.fRadii[SkRRect::kLowerLeft_Corner].fY); |
| 1167 this->conicTo(L, B, L + rrect.fRadii[SkRRect::kLowerLeft_Corner].fX,
B, W); |
| 1168 |
| 1169 this->lineTo(R - rrect.fRadii[SkRRect::kLowerRight_Corner].fX, B); |
| 1170 this->conicTo(R, B, R, B - rrect.fRadii[SkRRect::kLowerRight_Corner]
.fY, W); |
| 1171 |
| 1172 this->lineTo(R, T + rrect.fRadii[SkRRect::kUpperRight_Corner].fY); |
| 1173 this->conicTo(R, T, R - rrect.fRadii[SkRRect::kUpperRight_Corner].fX
, T, W); |
| 1174 |
| 1175 this->lineTo(L + rrect.fRadii[SkRRect::kUpperLeft_Corner].fX, T); |
| 1176 this->conicTo(L, T, L, T + rrect.fRadii[SkRRect::kUpperLeft_Corner].
fY, W); |
| 1177 } |
| 1178 #endif |
1135 this->close(); | 1179 this->close(); |
1136 } | 1180 } |
1137 SkDEBUGCODE(fPathRef->validate();) | 1181 SkDEBUGCODE(fPathRef->validate();) |
1138 } | 1182 } |
1139 | 1183 |
1140 bool SkPath::hasOnlyMoveTos() const { | 1184 bool SkPath::hasOnlyMoveTos() const { |
1141 int count = fPathRef->countVerbs(); | 1185 int count = fPathRef->countVerbs(); |
1142 const uint8_t* verbs = const_cast<const SkPathRef*>(fPathRef.get())->verbsMe
mBegin(); | 1186 const uint8_t* verbs = const_cast<const SkPathRef*>(fPathRef.get())->verbsMe
mBegin(); |
1143 for (int i = 0; i < count; ++i) { | 1187 for (int i = 0; i < count; ++i) { |
1144 if (*verbs == kLine_Verb || | 1188 if (*verbs == kLine_Verb || |
(...skipping 1749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2894 switch (this->getFillType()) { | 2938 switch (this->getFillType()) { |
2895 case SkPath::kEvenOdd_FillType: | 2939 case SkPath::kEvenOdd_FillType: |
2896 case SkPath::kInverseEvenOdd_FillType: | 2940 case SkPath::kInverseEvenOdd_FillType: |
2897 w &= 1; | 2941 w &= 1; |
2898 break; | 2942 break; |
2899 default: | 2943 default: |
2900 break; | 2944 break; |
2901 } | 2945 } |
2902 return SkToBool(w); | 2946 return SkToBool(w); |
2903 } | 2947 } |
OLD | NEW |