Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: src/core/SkPath.cpp

Issue 792493005: use conics for addRRect (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698