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

Side by Side Diff: src/pdf/SkPDFUtils.cpp

Issue 1374383004: SkPDF: when drawing stroked path, draw using SVG rules for zero-length segments (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 2015-10-06 (Tuesday) 12:31:14 EDT Created 5 years, 2 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 | « src/pdf/SkPDFUtils.h ('k') | 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 2011 Google Inc. 2 * Copyright 2011 Google Inc.
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 8
9 #include "SkData.h" 9 #include "SkData.h"
10 #include "SkGeometry.h" 10 #include "SkGeometry.h"
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 SkPDFUtils::AppendScalar(bottom, content); 111 SkPDFUtils::AppendScalar(bottom, content);
112 content->writeText(" "); 112 content->writeText(" ");
113 SkPDFUtils::AppendScalar(rect.width(), content); 113 SkPDFUtils::AppendScalar(rect.width(), content);
114 content->writeText(" "); 114 content->writeText(" ");
115 SkPDFUtils::AppendScalar(rect.height(), content); 115 SkPDFUtils::AppendScalar(rect.height(), content);
116 content->writeText(" re\n"); 116 content->writeText(" re\n");
117 } 117 }
118 118
119 // static 119 // static
120 void SkPDFUtils::EmitPath(const SkPath& path, SkPaint::Style paintStyle, 120 void SkPDFUtils::EmitPath(const SkPath& path, SkPaint::Style paintStyle,
121 SkWStream* content) { 121 bool doConsumeDegerates, SkWStream* content) {
122 // Filling a path with no area results in a drawing in PDF renderers but 122 // Filling a path with no area results in a drawing in PDF renderers but
123 // Chrome expects to be able to draw some such entities with no visible 123 // Chrome expects to be able to draw some such entities with no visible
124 // result, so we detect those cases and discard the drawing for them. 124 // result, so we detect those cases and discard the drawing for them.
125 // Specifically: moveTo(X), lineTo(Y) and moveTo(X), lineTo(X), lineTo(Y). 125 // Specifically: moveTo(X), lineTo(Y) and moveTo(X), lineTo(X), lineTo(Y).
126 enum SkipFillState { 126 enum SkipFillState {
127 kEmpty_SkipFillState = 0, 127 kEmpty_SkipFillState,
128 kSingleLine_SkipFillState = 1, 128 kSingleLine_SkipFillState,
129 kNonSingleLine_SkipFillState = 2, 129 kNonSingleLine_SkipFillState,
130 }; 130 };
131 SkipFillState fillState = kEmpty_SkipFillState; 131 SkipFillState fillState = kEmpty_SkipFillState;
132 if (paintStyle != SkPaint::kFill_Style) { 132 //if (paintStyle != SkPaint::kFill_Style) {
133 fillState = kNonSingleLine_SkipFillState; 133 // fillState = kNonSingleLine_SkipFillState;
134 } 134 //}
135 SkPoint lastMovePt = SkPoint::Make(0,0); 135 SkPoint lastMovePt = SkPoint::Make(0,0);
136 SkDynamicMemoryWStream currentSegment; 136 SkDynamicMemoryWStream currentSegment;
137 SkPoint args[4]; 137 SkPoint args[4];
138 SkPath::Iter iter(path, false); 138 SkPath::Iter iter(path, false);
139 for (SkPath::Verb verb = iter.next(args); verb != SkPath::kDone_Verb; verb = iter.next(args)) { 139 for (SkPath::Verb verb = iter.next(args, doConsumeDegerates);
140 verb != SkPath::kDone_Verb;
141 verb = iter.next(args, doConsumeDegerates)) {
140 // args gets all the points, even the implicit first point. 142 // args gets all the points, even the implicit first point.
141 switch (verb) { 143 switch (verb) {
142 case SkPath::kMove_Verb: 144 case SkPath::kMove_Verb:
143 MoveTo(args[0].fX, args[0].fY, &currentSegment); 145 MoveTo(args[0].fX, args[0].fY, &currentSegment);
144 lastMovePt = args[0]; 146 lastMovePt = args[0];
145 fillState = kEmpty_SkipFillState; 147 fillState = kEmpty_SkipFillState;
146 break; 148 break;
147 case SkPath::kLine_Verb: 149 case SkPath::kLine_Verb:
148 AppendLine(args[1].fX, args[1].fY, &currentSegment); 150 AppendLine(args[1].fX, args[1].fY, &currentSegment);
149 if (fillState == kEmpty_SkipFillState) { 151 if ((fillState == kEmpty_SkipFillState) && (args[0] != lastMoveP t)) {
150 if (args[0] != lastMovePt) { 152 fillState = kSingleLine_SkipFillState;
151 fillState = kSingleLine_SkipFillState; 153 break;
152 }
153 } else if (fillState == kSingleLine_SkipFillState) {
154 fillState = kNonSingleLine_SkipFillState;
155 } 154 }
155 fillState = kNonSingleLine_SkipFillState;
156 break; 156 break;
157 case SkPath::kQuad_Verb: 157 case SkPath::kQuad_Verb:
158 append_quad(args, &currentSegment); 158 append_quad(args, &currentSegment);
159 fillState = kNonSingleLine_SkipFillState; 159 fillState = kNonSingleLine_SkipFillState;
160 break; 160 break;
161 case SkPath::kConic_Verb: { 161 case SkPath::kConic_Verb: {
162 const SkScalar tol = SK_Scalar1 / 4; 162 const SkScalar tol = SK_Scalar1 / 4;
163 SkAutoConicToQuads converter; 163 SkAutoConicToQuads converter;
164 const SkPoint* quads = converter.computeQuads(args, iter.conicWe ight(), tol); 164 const SkPoint* quads = converter.computeQuads(args, iter.conicWe ight(), tol);
165 for (int i = 0; i < converter.countQuads(); ++i) { 165 for (int i = 0; i < converter.countQuads(); ++i) {
166 append_quad(&quads[i * 2], &currentSegment); 166 append_quad(&quads[i * 2], &currentSegment);
167 } 167 }
168 fillState = kNonSingleLine_SkipFillState;
168 } break; 169 } break;
169 case SkPath::kCubic_Verb: 170 case SkPath::kCubic_Verb:
170 AppendCubic(args[1].fX, args[1].fY, args[2].fX, args[2].fY, 171 AppendCubic(args[1].fX, args[1].fY, args[2].fX, args[2].fY,
171 args[3].fX, args[3].fY, &currentSegment); 172 args[3].fX, args[3].fY, &currentSegment);
172 fillState = kNonSingleLine_SkipFillState; 173 fillState = kNonSingleLine_SkipFillState;
173 break; 174 break;
174 case SkPath::kClose_Verb: 175 case SkPath::kClose_Verb:
175 if (fillState != kSingleLine_SkipFillState) { 176
176 ClosePath(&currentSegment); 177 ClosePath(&currentSegment);
177 currentSegment.writeToStream(content); 178
178 } 179 currentSegment.writeToStream(content);
179 currentSegment.reset(); 180 currentSegment.reset();
180 break; 181 break;
181 default: 182 default:
182 SkASSERT(false); 183 SkASSERT(false);
183 break; 184 break;
184 } 185 }
185 } 186 }
186 if (currentSegment.bytesWritten() > 0) { 187 if (currentSegment.bytesWritten() > 0) {
187 currentSegment.writeToStream(content); 188 currentSegment.writeToStream(content);
188 } 189 }
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 for (size_t i = 0; i < len; i++) { 337 for (size_t i = 0; i < len; i++) {
337 uint8_t c = static_cast<uint8_t>(cin[i]); 338 uint8_t c = static_cast<uint8_t>(cin[i]);
338 static const char gHex[] = "0123456789ABCDEF"; 339 static const char gHex[] = "0123456789ABCDEF";
339 *str++ = gHex[(c >> 4) & 0xF]; 340 *str++ = gHex[(c >> 4) & 0xF];
340 *str++ = gHex[(c ) & 0xF]; 341 *str++ = gHex[(c ) & 0xF];
341 } 342 }
342 *str++ = '>'; 343 *str++ = '>';
343 } 344 }
344 return result; 345 return result;
345 } 346 }
OLDNEW
« no previous file with comments | « src/pdf/SkPDFUtils.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698