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

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

Issue 1124193003: SkPDF: Move utility fns to SkPDFUtils (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 2015-05-06 (Wednesday) 13:16:21 EDT Created 5 years, 7 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
2 /* 1 /*
3 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
4 * 3 *
5 * 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
6 * found in the LICENSE file. 5 * found in the LICENSE file.
7 */ 6 */
8 7
9 8
10 #include "SkData.h" 9 #include "SkData.h"
11 #include "SkGeometry.h" 10 #include "SkGeometry.h"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 return result; 42 return result;
44 } 43 }
45 44
46 // static 45 // static
47 void SkPDFUtils::AppendTransform(const SkMatrix& matrix, SkWStream* content) { 46 void SkPDFUtils::AppendTransform(const SkMatrix& matrix, SkWStream* content) {
48 SkScalar values[6]; 47 SkScalar values[6];
49 if (!matrix.asAffine(values)) { 48 if (!matrix.asAffine(values)) {
50 SkMatrix::SetAffineIdentity(values); 49 SkMatrix::SetAffineIdentity(values);
51 } 50 }
52 for (size_t i = 0; i < SK_ARRAY_COUNT(values); i++) { 51 for (size_t i = 0; i < SK_ARRAY_COUNT(values); i++) {
53 SkPDFScalar::Append(values[i], content); 52 SkPDFUtils::AppendScalar(values[i], content);
54 content->writeText(" "); 53 content->writeText(" ");
55 } 54 }
56 content->writeText("cm\n"); 55 content->writeText("cm\n");
57 } 56 }
58 57
59 // static 58 // static
60 void SkPDFUtils::MoveTo(SkScalar x, SkScalar y, SkWStream* content) { 59 void SkPDFUtils::MoveTo(SkScalar x, SkScalar y, SkWStream* content) {
61 SkPDFScalar::Append(x, content); 60 SkPDFUtils::AppendScalar(x, content);
62 content->writeText(" "); 61 content->writeText(" ");
63 SkPDFScalar::Append(y, content); 62 SkPDFUtils::AppendScalar(y, content);
64 content->writeText(" m\n"); 63 content->writeText(" m\n");
65 } 64 }
66 65
67 // static 66 // static
68 void SkPDFUtils::AppendLine(SkScalar x, SkScalar y, SkWStream* content) { 67 void SkPDFUtils::AppendLine(SkScalar x, SkScalar y, SkWStream* content) {
69 SkPDFScalar::Append(x, content); 68 SkPDFUtils::AppendScalar(x, content);
70 content->writeText(" "); 69 content->writeText(" ");
71 SkPDFScalar::Append(y, content); 70 SkPDFUtils::AppendScalar(y, content);
72 content->writeText(" l\n"); 71 content->writeText(" l\n");
73 } 72 }
74 73
75 // static 74 // static
76 void SkPDFUtils::AppendCubic(SkScalar ctl1X, SkScalar ctl1Y, 75 void SkPDFUtils::AppendCubic(SkScalar ctl1X, SkScalar ctl1Y,
77 SkScalar ctl2X, SkScalar ctl2Y, 76 SkScalar ctl2X, SkScalar ctl2Y,
78 SkScalar dstX, SkScalar dstY, SkWStream* content) { 77 SkScalar dstX, SkScalar dstY, SkWStream* content) {
79 SkString cmd("y\n"); 78 SkString cmd("y\n");
80 SkPDFScalar::Append(ctl1X, content); 79 SkPDFUtils::AppendScalar(ctl1X, content);
81 content->writeText(" "); 80 content->writeText(" ");
82 SkPDFScalar::Append(ctl1Y, content); 81 SkPDFUtils::AppendScalar(ctl1Y, content);
83 content->writeText(" "); 82 content->writeText(" ");
84 if (ctl2X != dstX || ctl2Y != dstY) { 83 if (ctl2X != dstX || ctl2Y != dstY) {
85 cmd.set("c\n"); 84 cmd.set("c\n");
86 SkPDFScalar::Append(ctl2X, content); 85 SkPDFUtils::AppendScalar(ctl2X, content);
87 content->writeText(" "); 86 content->writeText(" ");
88 SkPDFScalar::Append(ctl2Y, content); 87 SkPDFUtils::AppendScalar(ctl2Y, content);
89 content->writeText(" "); 88 content->writeText(" ");
90 } 89 }
91 SkPDFScalar::Append(dstX, content); 90 SkPDFUtils::AppendScalar(dstX, content);
92 content->writeText(" "); 91 content->writeText(" ");
93 SkPDFScalar::Append(dstY, content); 92 SkPDFUtils::AppendScalar(dstY, content);
94 content->writeText(" "); 93 content->writeText(" ");
95 content->writeText(cmd.c_str()); 94 content->writeText(cmd.c_str());
96 } 95 }
97 96
98 static void append_quad(const SkPoint quad[], SkWStream* content) { 97 static void append_quad(const SkPoint quad[], SkWStream* content) {
99 SkPoint cubic[4]; 98 SkPoint cubic[4];
100 SkConvertQuadToCubic(quad, cubic); 99 SkConvertQuadToCubic(quad, cubic);
101 SkPDFUtils::AppendCubic(cubic[1].fX, cubic[1].fY, cubic[2].fX, cubic[2].fY, 100 SkPDFUtils::AppendCubic(cubic[1].fX, cubic[1].fY, cubic[2].fX, cubic[2].fY,
102 cubic[3].fX, cubic[3].fY, content); 101 cubic[3].fX, cubic[3].fY, content);
103 } 102 }
104 103
105 // static 104 // static
106 void SkPDFUtils::AppendRectangle(const SkRect& rect, SkWStream* content) { 105 void SkPDFUtils::AppendRectangle(const SkRect& rect, SkWStream* content) {
107 // Skia has 0,0 at top left, pdf at bottom left. Do the right thing. 106 // Skia has 0,0 at top left, pdf at bottom left. Do the right thing.
108 SkScalar bottom = SkMinScalar(rect.fBottom, rect.fTop); 107 SkScalar bottom = SkMinScalar(rect.fBottom, rect.fTop);
109 108
110 SkPDFScalar::Append(rect.fLeft, content); 109 SkPDFUtils::AppendScalar(rect.fLeft, content);
111 content->writeText(" "); 110 content->writeText(" ");
112 SkPDFScalar::Append(bottom, content); 111 SkPDFUtils::AppendScalar(bottom, content);
113 content->writeText(" "); 112 content->writeText(" ");
114 SkPDFScalar::Append(rect.width(), content); 113 SkPDFUtils::AppendScalar(rect.width(), content);
115 content->writeText(" "); 114 content->writeText(" ");
116 SkPDFScalar::Append(rect.height(), content); 115 SkPDFUtils::AppendScalar(rect.height(), content);
117 content->writeText(" re\n"); 116 content->writeText(" re\n");
118 } 117 }
119 118
120 // static 119 // static
121 void SkPDFUtils::EmitPath(const SkPath& path, SkPaint::Style paintStyle, 120 void SkPDFUtils::EmitPath(const SkPath& path, SkPaint::Style paintStyle,
122 SkWStream* content) { 121 SkWStream* content) {
123 // 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
124 // 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
125 // 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.
126 // 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).
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 // color (SCN, scn) 244 // color (SCN, scn)
246 SkString resourceName = SkPDFResourceDict::getResourceName( 245 SkString resourceName = SkPDFResourceDict::getResourceName(
247 SkPDFResourceDict::kPattern_ResourceType, 246 SkPDFResourceDict::kPattern_ResourceType,
248 objectIndex); 247 objectIndex);
249 content->writeText("/Pattern CS/Pattern cs/"); 248 content->writeText("/Pattern CS/Pattern cs/");
250 content->writeText(resourceName.c_str()); 249 content->writeText(resourceName.c_str());
251 content->writeText(" SCN/"); 250 content->writeText(" SCN/");
252 content->writeText(resourceName.c_str()); 251 content->writeText(resourceName.c_str());
253 content->writeText(" scn\n"); 252 content->writeText(" scn\n");
254 } 253 }
254
255 void SkPDFUtils::AppendScalar(SkScalar value, SkWStream* stream) {
256 // The range of reals in PDF/A is the same as SkFixed: +/- 32,767 and
257 // +/- 1/65,536 (though integers can range from 2^31 - 1 to -2^31).
258 // When using floats that are outside the whole value range, we can use
259 // integers instead.
260
261 #if !defined(SK_ALLOW_LARGE_PDF_SCALARS)
262 if (value > 32767 || value < -32767) {
263 stream->writeDecAsText(SkScalarRoundToInt(value));
264 return;
265 }
266
267 char buffer[SkStrAppendScalar_MaxSize];
268 char* end = SkStrAppendFixed(buffer, SkScalarToFixed(value));
269 stream->write(buffer, end - buffer);
270 return;
271 #endif // !SK_ALLOW_LARGE_PDF_SCALARS
272
273 #if defined(SK_ALLOW_LARGE_PDF_SCALARS)
274 // Floats have 24bits of significance, so anything outside that range is
275 // no more precise than an int. (Plus PDF doesn't support scientific
276 // notation, so this clamps to SK_Max/MinS32).
277 if (value > (1 << 24) || value < -(1 << 24)) {
278 stream->writeDecAsText(value);
279 return;
280 }
281 // Continue to enforce the PDF limits for small floats.
282 if (value < 1.0f/65536 && value > -1.0f/65536) {
283 stream->writeDecAsText(0);
284 return;
285 }
286 // SkStrAppendFloat might still use scientific notation, so use snprintf
287 // directly..
288 static const int kFloat_MaxSize = 19;
289 char buffer[kFloat_MaxSize];
290 int len = SNPRINTF(buffer, kFloat_MaxSize, "%#.8f", value);
291 // %f always prints trailing 0s, so strip them.
292 for (; buffer[len - 1] == '0' && len > 0; len--) {
293 buffer[len - 1] = '\0';
294 }
295 if (buffer[len - 1] == '.') {
296 buffer[len - 1] = '\0';
297 }
298 stream->writeText(buffer);
299 return;
300 #endif // SK_ALLOW_LARGE_PDF_SCALARS
301 }
302
303 SkString SkPDFUtils::FormatString(const char* cin, size_t len) {
304 SkDEBUGCODE(static const size_t kMaxLen = 65535;)
305 SkASSERT(len <= kMaxLen);
306
307 // 7-bit clean is a heuristic to decide what string format to use;
308 // a 7-bit clean string should require little escaping.
309 bool sevenBitClean = true;
310 size_t characterCount = 2 + len;
311 for (size_t i = 0; i < len; i++) {
312 if (cin[i] > '~' || cin[i] < ' ') {
313 sevenBitClean = false;
314 break;
315 }
316 if (cin[i] == '\\' || cin[i] == '(' || cin[i] == ')') {
317 ++characterCount;
318 }
319 }
320 SkString result;
321 if (sevenBitClean) {
322 result.resize(characterCount);
323 char* str = result.writable_str();
324 *str++ = '(';
325 for (size_t i = 0; i < len; i++) {
326 if (cin[i] == '\\' || cin[i] == '(' || cin[i] == ')') {
327 *str++ = '\\';
328 }
329 *str++ = cin[i];
330 }
331 *str++ = ')';
332 } else {
333 result.resize(2 * len + 2);
334 char* str = result.writable_str();
335 *str++ = '<';
336 for (size_t i = 0; i < len; i++) {
337 uint8_t c = static_cast<uint8_t>(cin[i]);
338 static const char gHex[] = "0123456789ABCDEF";
339 *str++ = gHex[(c >> 4) & 0xF];
340 *str++ = gHex[(c ) & 0xF];
341 }
342 *str++ = '>';
343 }
344 return result;
345 }
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