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

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

Issue 929173002: Remove SK_SUPPORT_LEGACY_ADDRRECT (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Created 5 years, 10 months 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"
(...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 } 968 }
969 #endif 969 #endif
970 970
971 void SkPath::addRoundRect(const SkRect& rect, const SkScalar radii[], 971 void SkPath::addRoundRect(const SkRect& rect, const SkScalar radii[],
972 Direction dir) { 972 Direction dir) {
973 SkRRect rrect; 973 SkRRect rrect;
974 rrect.setRectRadii(rect, (const SkVector*) radii); 974 rrect.setRectRadii(rect, (const SkVector*) radii);
975 this->addRRect(rrect, dir); 975 this->addRRect(rrect, dir);
976 } 976 }
977 977
978 #ifdef SK_SUPPORT_LEGACY_ADDRRECT
979 /* The inline clockwise and counterclockwise round rect quad approximations
980 make it easier to see the symmetry patterns used by add corner quads.
981 Clockwise corner value
982 path->lineTo(rect.fLeft, rect.fTop + ry); 0 upper left
983 path->quadTo(rect.fLeft, rect.fTop + offPtY,
984 rect.fLeft + midPtX, rect.fTop + midPtY);
985 path->quadTo(rect.fLeft + offPtX, rect.fTop,
986 rect.fLeft + rx, rect.fTop);
987
988 path->lineTo(rect.fRight - rx, rect.fTop); 1 upper right
989 path->quadTo(rect.fRight - offPtX, rect.fTop,
990 rect.fRight - midPtX, rect.fTop + midPtY);
991 path->quadTo(rect.fRight, rect.fTop + offPtY,
992 rect.fRight, rect.fTop + ry);
993
994 path->lineTo(rect.fRight, rect.fBottom - ry); 2 lower right
995 path->quadTo(rect.fRight, rect.fBottom - offPtY,
996 rect.fRight - midPtX, rect.fBottom - midPtY);
997 path->quadTo(rect.fRight - offPtX, rect.fBottom,
998 rect.fRight - rx, rect.fBottom);
999
1000 path->lineTo(rect.fLeft + rx, rect.fBottom); 3 lower left
1001 path->quadTo(rect.fLeft + offPtX, rect.fBottom,
1002 rect.fLeft + midPtX, rect.fBottom - midPtY);
1003 path->quadTo(rect.fLeft, rect.fBottom - offPtY,
1004 rect.fLeft, rect.fBottom - ry);
1005
1006 Counterclockwise
1007 path->lineTo(rect.fLeft, rect.fBottom - ry); 3 lower left
1008 path->quadTo(rect.fLeft, rect.fBottom - offPtY,
1009 rect.fLeft + midPtX, rect.fBottom - midPtY);
1010 path->quadTo(rect.fLeft + offPtX, rect.fBottom,
1011 rect.fLeft + rx, rect.fBottom);
1012
1013 path->lineTo(rect.fRight - rx, rect.fBottom); 2 lower right
1014 path->quadTo(rect.fRight - offPtX, rect.fBottom,
1015 rect.fRight - midPtX, rect.fBottom - midPtY);
1016 path->quadTo(rect.fRight, rect.fBottom - offPtY,
1017 rect.fRight, rect.fBottom - ry);
1018
1019 path->lineTo(rect.fRight, rect.fTop + ry); 1 upper right
1020 path->quadTo(rect.fRight, rect.fTop + offPtY,
1021 rect.fRight - midPtX, rect.fTop + midPtY);
1022 path->quadTo(rect.fRight - offPtX, rect.fTop,
1023 rect.fRight - rx, rect.fTop);
1024
1025 path->lineTo(rect.fLeft + rx, rect.fTop); 0 upper left
1026 path->quadTo(rect.fLeft + offPtX, rect.fTop,
1027 rect.fLeft + midPtX, rect.fTop + midPtY);
1028 path->quadTo(rect.fLeft, rect.fTop + offPtY,
1029 rect.fLeft, rect.fTop + ry);
1030 */
1031 static void add_corner_quads(SkPath* path, const SkRRect& rrect,
1032 SkRRect::Corner corner, SkPath::Direction dir) {
1033 const SkRect& rect = rrect.rect();
1034 const SkVector& radii = rrect.radii(corner);
1035 SkScalar rx = radii.fX;
1036 SkScalar ry = radii.fY;
1037 // The mid point of the quadratic arc approximation is half way between the two
1038 // control points.
1039 const SkScalar mid = 1 - (SK_Scalar1 + SK_ScalarTanPIOver8) / 2;
1040 SkScalar midPtX = rx * mid;
1041 SkScalar midPtY = ry * mid;
1042 const SkScalar control = 1 - SK_ScalarTanPIOver8;
1043 SkScalar offPtX = rx * control;
1044 SkScalar offPtY = ry * control;
1045 static const int kCornerPts = 5;
1046 SkScalar xOff[kCornerPts];
1047 SkScalar yOff[kCornerPts];
1048
1049 if ((corner & 1) == (dir == SkPath::kCCW_Direction)) { // corners always al ternate direction
1050 SkASSERT(dir == SkPath::kCCW_Direction
1051 ? corner == SkRRect::kLowerLeft_Corner || corner == SkRRect::kUpper Right_Corner
1052 : corner == SkRRect::kUpperLeft_Corner || corner == SkRRect::kLower Right_Corner);
1053 xOff[0] = xOff[1] = 0;
1054 xOff[2] = midPtX;
1055 xOff[3] = offPtX;
1056 xOff[4] = rx;
1057 yOff[0] = ry;
1058 yOff[1] = offPtY;
1059 yOff[2] = midPtY;
1060 yOff[3] = yOff[4] = 0;
1061 } else {
1062 xOff[0] = rx;
1063 xOff[1] = offPtX;
1064 xOff[2] = midPtX;
1065 xOff[3] = xOff[4] = 0;
1066 yOff[0] = yOff[1] = 0;
1067 yOff[2] = midPtY;
1068 yOff[3] = offPtY;
1069 yOff[4] = ry;
1070 }
1071 if ((corner - 1) & 2) {
1072 SkASSERT(corner == SkRRect::kLowerLeft_Corner || corner == SkRRect::kUpp erLeft_Corner);
1073 for (int i = 0; i < kCornerPts; ++i) {
1074 xOff[i] = rect.fLeft + xOff[i];
1075 }
1076 } else {
1077 SkASSERT(corner == SkRRect::kLowerRight_Corner || corner == SkRRect::kUp perRight_Corner);
1078 for (int i = 0; i < kCornerPts; ++i) {
1079 xOff[i] = rect.fRight - xOff[i];
1080 }
1081 }
1082 if (corner < SkRRect::kLowerRight_Corner) {
1083 for (int i = 0; i < kCornerPts; ++i) {
1084 yOff[i] = rect.fTop + yOff[i];
1085 }
1086 } else {
1087 for (int i = 0; i < kCornerPts; ++i) {
1088 yOff[i] = rect.fBottom - yOff[i];
1089 }
1090 }
1091
1092 SkPoint lastPt;
1093 SkAssertResult(path->getLastPt(&lastPt));
1094 if (lastPt.fX != xOff[0] || lastPt.fY != yOff[0]) {
1095 path->lineTo(xOff[0], yOff[0]);
1096 }
1097 if (rx || ry) {
1098 path->quadTo(xOff[1], yOff[1], xOff[2], yOff[2]);
1099 path->quadTo(xOff[3], yOff[3], xOff[4], yOff[4]);
1100 } else {
1101 path->lineTo(xOff[2], yOff[2]);
1102 path->lineTo(xOff[4], yOff[4]);
1103 }
1104 }
1105 #endif
1106
1107 void SkPath::addRRect(const SkRRect& rrect, Direction dir) { 978 void SkPath::addRRect(const SkRRect& rrect, Direction dir) {
1108 assert_known_direction(dir); 979 assert_known_direction(dir);
1109 980
1110 if (rrect.isEmpty()) { 981 if (rrect.isEmpty()) {
1111 return; 982 return;
1112 } 983 }
1113 984
1114 const SkRect& bounds = rrect.getBounds(); 985 const SkRect& bounds = rrect.getBounds();
1115 986
1116 if (rrect.isRect()) { 987 if (rrect.isRect()) {
1117 this->addRect(bounds, dir); 988 this->addRect(bounds, dir);
1118 } else if (rrect.isOval()) { 989 } else if (rrect.isOval()) {
1119 this->addOval(bounds, dir); 990 this->addOval(bounds, dir);
1120 } else { 991 } else {
1121 fDirection = this->hasOnlyMoveTos() ? dir : kUnknown_Direction; 992 fDirection = this->hasOnlyMoveTos() ? dir : kUnknown_Direction;
1122 993
1123 SkAutoPathBoundsUpdate apbu(this, bounds); 994 SkAutoPathBoundsUpdate apbu(this, bounds);
1124 SkAutoDisableDirectionCheck addc(this); 995 SkAutoDisableDirectionCheck addc(this);
1125 996
1126 #ifdef SK_SUPPORT_LEGACY_ADDRRECT
1127 this->incReserve(21);
1128 if (kCW_Direction == dir) {
1129 this->moveTo(bounds.fLeft,
1130 bounds.fBottom - rrect.fRadii[SkRRect::kLowerLeft_Corne r].fY);
1131 add_corner_quads(this, rrect, SkRRect::kUpperLeft_Corner, dir);
1132 add_corner_quads(this, rrect, SkRRect::kUpperRight_Corner, dir);
1133 add_corner_quads(this, rrect, SkRRect::kLowerRight_Corner, dir);
1134 add_corner_quads(this, rrect, SkRRect::kLowerLeft_Corner, dir);
1135 } else {
1136 this->moveTo(bounds.fLeft,
1137 bounds.fTop + rrect.fRadii[SkRRect::kUpperLeft_Corner]. fY);
1138 add_corner_quads(this, rrect, SkRRect::kLowerLeft_Corner, dir);
1139 add_corner_quads(this, rrect, SkRRect::kLowerRight_Corner, dir);
1140 add_corner_quads(this, rrect, SkRRect::kUpperRight_Corner, dir);
1141 add_corner_quads(this, rrect, SkRRect::kUpperLeft_Corner, dir);
1142 }
1143 #else
1144 const SkScalar L = bounds.fLeft; 997 const SkScalar L = bounds.fLeft;
1145 const SkScalar T = bounds.fTop; 998 const SkScalar T = bounds.fTop;
1146 const SkScalar R = bounds.fRight; 999 const SkScalar R = bounds.fRight;
1147 const SkScalar B = bounds.fBottom; 1000 const SkScalar B = bounds.fBottom;
1148 const SkScalar W = SK_ScalarRoot2Over2; 1001 const SkScalar W = SK_ScalarRoot2Over2;
1149 1002
1150 this->incReserve(13); 1003 this->incReserve(13);
1151 if (kCW_Direction == dir) { 1004 if (kCW_Direction == dir) {
1152 this->moveTo(L, B - rrect.fRadii[SkRRect::kLowerLeft_Corner].fY); 1005 this->moveTo(L, B - rrect.fRadii[SkRRect::kLowerLeft_Corner].fY);
1153 1006
(...skipping 16 matching lines...) Expand all
1170 1023
1171 this->lineTo(R - rrect.fRadii[SkRRect::kLowerRight_Corner].fX, B); 1024 this->lineTo(R - rrect.fRadii[SkRRect::kLowerRight_Corner].fX, B);
1172 this->conicTo(R, B, R, B - rrect.fRadii[SkRRect::kLowerRight_Corner] .fY, W); 1025 this->conicTo(R, B, R, B - rrect.fRadii[SkRRect::kLowerRight_Corner] .fY, W);
1173 1026
1174 this->lineTo(R, T + rrect.fRadii[SkRRect::kUpperRight_Corner].fY); 1027 this->lineTo(R, T + rrect.fRadii[SkRRect::kUpperRight_Corner].fY);
1175 this->conicTo(R, T, R - rrect.fRadii[SkRRect::kUpperRight_Corner].fX , T, W); 1028 this->conicTo(R, T, R - rrect.fRadii[SkRRect::kUpperRight_Corner].fX , T, W);
1176 1029
1177 this->lineTo(L + rrect.fRadii[SkRRect::kUpperLeft_Corner].fX, T); 1030 this->lineTo(L + rrect.fRadii[SkRRect::kUpperLeft_Corner].fX, T);
1178 this->conicTo(L, T, L, T + rrect.fRadii[SkRRect::kUpperLeft_Corner]. fY, W); 1031 this->conicTo(L, T, L, T + rrect.fRadii[SkRRect::kUpperLeft_Corner]. fY, W);
1179 } 1032 }
1180 #endif
1181 this->close(); 1033 this->close();
1182 } 1034 }
1183 SkDEBUGCODE(fPathRef->validate();) 1035 SkDEBUGCODE(fPathRef->validate();)
1184 } 1036 }
1185 1037
1186 bool SkPath::hasOnlyMoveTos() const { 1038 bool SkPath::hasOnlyMoveTos() const {
1187 int count = fPathRef->countVerbs(); 1039 int count = fPathRef->countVerbs();
1188 const uint8_t* verbs = const_cast<const SkPathRef*>(fPathRef.get())->verbsMe mBegin(); 1040 const uint8_t* verbs = const_cast<const SkPathRef*>(fPathRef.get())->verbsMe mBegin();
1189 for (int i = 0; i < count; ++i) { 1041 for (int i = 0; i < count; ++i) {
1190 if (*verbs == kLine_Verb || 1042 if (*verbs == kLine_Verb ||
(...skipping 1754 matching lines...) Expand 10 before | Expand all | Expand 10 after
2945 switch (this->getFillType()) { 2797 switch (this->getFillType()) {
2946 case SkPath::kEvenOdd_FillType: 2798 case SkPath::kEvenOdd_FillType:
2947 case SkPath::kInverseEvenOdd_FillType: 2799 case SkPath::kInverseEvenOdd_FillType:
2948 w &= 1; 2800 w &= 1;
2949 break; 2801 break;
2950 default: 2802 default:
2951 break; 2803 break;
2952 } 2804 }
2953 return SkToBool(w); 2805 return SkToBool(w);
2954 } 2806 }
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