| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 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 | 8 |
| 9 | 9 |
| 10 #include "SkBuffer.h" | 10 #include "SkBuffer.h" |
| (...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1082 if (rrect.isEmpty()) { | 1082 if (rrect.isEmpty()) { |
| 1083 return; | 1083 return; |
| 1084 } | 1084 } |
| 1085 | 1085 |
| 1086 const SkRect& bounds = rrect.getBounds(); | 1086 const SkRect& bounds = rrect.getBounds(); |
| 1087 | 1087 |
| 1088 if (rrect.isRect()) { | 1088 if (rrect.isRect()) { |
| 1089 this->addRect(bounds, dir); | 1089 this->addRect(bounds, dir); |
| 1090 } else if (rrect.isOval()) { | 1090 } else if (rrect.isOval()) { |
| 1091 this->addOval(bounds, dir); | 1091 this->addOval(bounds, dir); |
| 1092 #ifdef SK_IGNORE_QUAD_RR_CORNERS_OPT | |
| 1093 } else if (rrect.isSimple()) { | |
| 1094 const SkVector& rad = rrect.getSimpleRadii(); | |
| 1095 this->addRoundRect(bounds, rad.x(), rad.y(), dir); | |
| 1096 #endif | |
| 1097 } else { | 1092 } else { |
| 1098 fDirection = this->hasOnlyMoveTos() ? dir : kUnknown_Direction; | 1093 fDirection = this->hasOnlyMoveTos() ? dir : kUnknown_Direction; |
| 1099 | 1094 |
| 1100 SkAutoPathBoundsUpdate apbu(this, bounds); | 1095 SkAutoPathBoundsUpdate apbu(this, bounds); |
| 1101 SkAutoDisableDirectionCheck addc(this); | 1096 SkAutoDisableDirectionCheck addc(this); |
| 1102 | 1097 |
| 1103 this->incReserve(21); | 1098 this->incReserve(21); |
| 1104 if (kCW_Direction == dir) { | 1099 if (kCW_Direction == dir) { |
| 1105 this->moveTo(bounds.fLeft, | 1100 this->moveTo(bounds.fLeft, |
| 1106 bounds.fBottom - rrect.fRadii[SkRRect::kLowerLeft_Corne
r].fY); | 1101 bounds.fBottom - rrect.fRadii[SkRRect::kLowerLeft_Corne
r].fY); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1128 *verbs == kQuad_Verb || | 1123 *verbs == kQuad_Verb || |
| 1129 *verbs == kConic_Verb || | 1124 *verbs == kConic_Verb || |
| 1130 *verbs == kCubic_Verb) { | 1125 *verbs == kCubic_Verb) { |
| 1131 return false; | 1126 return false; |
| 1132 } | 1127 } |
| 1133 ++verbs; | 1128 ++verbs; |
| 1134 } | 1129 } |
| 1135 return true; | 1130 return true; |
| 1136 } | 1131 } |
| 1137 | 1132 |
| 1138 #ifdef SK_IGNORE_QUAD_RR_CORNERS_OPT | |
| 1139 #define CUBIC_ARC_FACTOR ((SK_ScalarSqrt2 - SK_Scalar1) * 4 / 3) | |
| 1140 #endif | |
| 1141 | |
| 1142 void SkPath::addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, | 1133 void SkPath::addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, |
| 1143 Direction dir) { | 1134 Direction dir) { |
| 1144 assert_known_direction(dir); | 1135 assert_known_direction(dir); |
| 1145 | 1136 |
| 1146 if (rx < 0 || ry < 0) { | 1137 if (rx < 0 || ry < 0) { |
| 1147 SkErrorInternals::SetError( kInvalidArgument_SkError, | 1138 SkErrorInternals::SetError( kInvalidArgument_SkError, |
| 1148 "I got %f and %f as radii to SkPath::AddRoun
dRect, " | 1139 "I got %f and %f as radii to SkPath::AddRoun
dRect, " |
| 1149 "but negative radii are not allowed.", | 1140 "but negative radii are not allowed.", |
| 1150 SkScalarToDouble(rx), SkScalarToDouble(ry) )
; | 1141 SkScalarToDouble(rx), SkScalarToDouble(ry) )
; |
| 1151 return; | 1142 return; |
| 1152 } | 1143 } |
| 1153 | 1144 |
| 1154 #ifdef SK_IGNORE_QUAD_RR_CORNERS_OPT | |
| 1155 SkScalar w = rect.width(); | |
| 1156 SkScalar halfW = SkScalarHalf(w); | |
| 1157 SkScalar h = rect.height(); | |
| 1158 SkScalar halfH = SkScalarHalf(h); | |
| 1159 | |
| 1160 if (halfW <= 0 || halfH <= 0) { | |
| 1161 return; | |
| 1162 } | |
| 1163 | |
| 1164 bool skip_hori = rx >= halfW; | |
| 1165 bool skip_vert = ry >= halfH; | |
| 1166 | |
| 1167 if (skip_hori && skip_vert) { | |
| 1168 this->addOval(rect, dir); | |
| 1169 return; | |
| 1170 } | |
| 1171 | |
| 1172 fDirection = this->hasOnlyMoveTos() ? dir : kUnknown_Direction; | |
| 1173 | |
| 1174 SkAutoPathBoundsUpdate apbu(this, rect); | |
| 1175 SkAutoDisableDirectionCheck addc(this); | |
| 1176 | |
| 1177 if (skip_hori) { | |
| 1178 rx = halfW; | |
| 1179 } else if (skip_vert) { | |
| 1180 ry = halfH; | |
| 1181 } | |
| 1182 SkScalar sx = SkScalarMul(rx, CUBIC_ARC_FACTOR); | |
| 1183 SkScalar sy = SkScalarMul(ry, CUBIC_ARC_FACTOR); | |
| 1184 | |
| 1185 this->incReserve(17); | |
| 1186 this->moveTo(rect.fRight - rx, rect.fTop); // top-right | |
| 1187 if (dir == kCCW_Direction) { | |
| 1188 if (!skip_hori) { | |
| 1189 this->lineTo(rect.fLeft + rx, rect.fTop); // top | |
| 1190 } | |
| 1191 this->cubicTo(rect.fLeft + rx - sx, rect.fTop, | |
| 1192 rect.fLeft, rect.fTop + ry - sy, | |
| 1193 rect.fLeft, rect.fTop + ry); // top-left | |
| 1194 if (!skip_vert) { | |
| 1195 this->lineTo(rect.fLeft, rect.fBottom - ry); // left | |
| 1196 } | |
| 1197 this->cubicTo(rect.fLeft, rect.fBottom - ry + sy, | |
| 1198 rect.fLeft + rx - sx, rect.fBottom, | |
| 1199 rect.fLeft + rx, rect.fBottom); // bot-left | |
| 1200 if (!skip_hori) { | |
| 1201 this->lineTo(rect.fRight - rx, rect.fBottom); // bottom | |
| 1202 } | |
| 1203 this->cubicTo(rect.fRight - rx + sx, rect.fBottom, | |
| 1204 rect.fRight, rect.fBottom - ry + sy, | |
| 1205 rect.fRight, rect.fBottom - ry); // bot-right | |
| 1206 if (!skip_vert) { | |
| 1207 this->lineTo(rect.fRight, rect.fTop + ry); // right | |
| 1208 } | |
| 1209 this->cubicTo(rect.fRight, rect.fTop + ry - sy, | |
| 1210 rect.fRight - rx + sx, rect.fTop, | |
| 1211 rect.fRight - rx, rect.fTop); // top-right | |
| 1212 } else { | |
| 1213 this->cubicTo(rect.fRight - rx + sx, rect.fTop, | |
| 1214 rect.fRight, rect.fTop + ry - sy, | |
| 1215 rect.fRight, rect.fTop + ry); // top-right | |
| 1216 if (!skip_vert) { | |
| 1217 this->lineTo(rect.fRight, rect.fBottom - ry); // right | |
| 1218 } | |
| 1219 this->cubicTo(rect.fRight, rect.fBottom - ry + sy, | |
| 1220 rect.fRight - rx + sx, rect.fBottom, | |
| 1221 rect.fRight - rx, rect.fBottom); // bot-right | |
| 1222 if (!skip_hori) { | |
| 1223 this->lineTo(rect.fLeft + rx, rect.fBottom); // bottom | |
| 1224 } | |
| 1225 this->cubicTo(rect.fLeft + rx - sx, rect.fBottom, | |
| 1226 rect.fLeft, rect.fBottom - ry + sy, | |
| 1227 rect.fLeft, rect.fBottom - ry); // bot-left | |
| 1228 if (!skip_vert) { | |
| 1229 this->lineTo(rect.fLeft, rect.fTop + ry); // left | |
| 1230 } | |
| 1231 this->cubicTo(rect.fLeft, rect.fTop + ry - sy, | |
| 1232 rect.fLeft + rx - sx, rect.fTop, | |
| 1233 rect.fLeft + rx, rect.fTop); // top-left | |
| 1234 if (!skip_hori) { | |
| 1235 this->lineTo(rect.fRight - rx, rect.fTop); // top | |
| 1236 } | |
| 1237 } | |
| 1238 this->close(); | |
| 1239 #else | |
| 1240 SkRRect rrect; | 1145 SkRRect rrect; |
| 1241 rrect.setRectXY(rect, rx, ry); | 1146 rrect.setRectXY(rect, rx, ry); |
| 1242 this->addRRect(rrect, dir); | 1147 this->addRRect(rrect, dir); |
| 1243 #endif | |
| 1244 } | 1148 } |
| 1245 | 1149 |
| 1246 void SkPath::addOval(const SkRect& oval, Direction dir) { | 1150 void SkPath::addOval(const SkRect& oval, Direction dir) { |
| 1247 assert_known_direction(dir); | 1151 assert_known_direction(dir); |
| 1248 | 1152 |
| 1249 /* If addOval() is called after previous moveTo(), | 1153 /* If addOval() is called after previous moveTo(), |
| 1250 this path is still marked as an oval. This is used to | 1154 this path is still marked as an oval. This is used to |
| 1251 fit into WebKit's calling sequences. | 1155 fit into WebKit's calling sequences. |
| 1252 We can't simply check isEmpty() in this case, as additional | 1156 We can't simply check isEmpty() in this case, as additional |
| 1253 moveTo() would mark the path non empty. | 1157 moveTo() would mark the path non empty. |
| (...skipping 1634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2888 switch (this->getFillType()) { | 2792 switch (this->getFillType()) { |
| 2889 case SkPath::kEvenOdd_FillType: | 2793 case SkPath::kEvenOdd_FillType: |
| 2890 case SkPath::kInverseEvenOdd_FillType: | 2794 case SkPath::kInverseEvenOdd_FillType: |
| 2891 w &= 1; | 2795 w &= 1; |
| 2892 break; | 2796 break; |
| 2893 default: | 2797 default: |
| 2894 break; | 2798 break; |
| 2895 } | 2799 } |
| 2896 return SkToBool(w); | 2800 return SkToBool(w); |
| 2897 } | 2801 } |
| OLD | NEW |