Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 #include "SkPDFDevice.h" | 8 #include "SkPDFDevice.h" |
| 9 | 9 |
| 10 #include "SkAnnotationKeys.h" | 10 #include "SkAnnotationKeys.h" |
| (...skipping 1049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1060 } | 1060 } |
| 1061 | 1061 |
| 1062 // Create a PDF string. Maximum length (in bytes) is 65,535. | 1062 // Create a PDF string. Maximum length (in bytes) is 65,535. |
| 1063 // @param input A string value. | 1063 // @param input A string value. |
| 1064 // @param len The length of the input array. | 1064 // @param len The length of the input array. |
| 1065 // @param wideChars True iff the upper byte in each uint16_t is | 1065 // @param wideChars True iff the upper byte in each uint16_t is |
| 1066 // significant and should be encoded and not | 1066 // significant and should be encoded and not |
| 1067 // discarded. If true, the upper byte is encoded | 1067 // discarded. If true, the upper byte is encoded |
| 1068 // first. Otherwise, we assert the upper byte is | 1068 // first. Otherwise, we assert the upper byte is |
| 1069 // zero. | 1069 // zero. |
| 1070 static SkString format_wide_string(const uint16_t* input, | 1070 static void write_wide_string(SkDynamicMemoryWStream* wStream, |
| 1071 size_t len, | 1071 const uint16_t* input, |
| 1072 bool wideChars) { | 1072 size_t len, |
| 1073 bool wideChars) { | |
| 1073 if (wideChars) { | 1074 if (wideChars) { |
| 1074 SkASSERT(2 * len < 65535); | 1075 SkASSERT(2 * len < 65535); |
| 1075 static const char gHex[] = "0123456789ABCDEF"; | 1076 static const char gHex[] = "0123456789ABCDEF"; |
| 1076 SkString result(4 * len + 2); | 1077 wStream->writeText("<"); |
| 1077 result[0] = '<'; | |
| 1078 for (size_t i = 0; i < len; i++) { | 1078 for (size_t i = 0; i < len; i++) { |
| 1079 result[4 * i + 1] = gHex[(input[i] >> 12) & 0xF]; | 1079 char result[4]; // Big-endian |
| 1080 result[4 * i + 2] = gHex[(input[i] >> 8) & 0xF]; | 1080 result[0] = gHex[(input[i] >> 12) & 0xF]; |
| 1081 result[4 * i + 3] = gHex[(input[i] >> 4) & 0xF]; | 1081 result[1] = gHex[(input[i] >> 8) & 0xF]; |
| 1082 result[4 * i + 4] = gHex[(input[i] ) & 0xF]; | 1082 result[2] = gHex[(input[i] >> 4) & 0xF]; |
| 1083 result[3] = gHex[(input[i]) & 0xF]; | |
| 1084 wStream->write(result, 4); | |
| 1083 } | 1085 } |
| 1084 result[4 * len + 1] = '>'; | 1086 wStream->writeText(">"); |
| 1085 return result; | |
| 1086 } else { | 1087 } else { |
| 1087 SkASSERT(len <= 65535); | 1088 SkASSERT(len <= 65535); |
| 1088 SkString tmp(len); | 1089 SkAutoMalloc buffer(len); // Remove every other byte. |
|
tomhudson
2016/06/23 20:39:11
Seems like you haven't gotten rid of the allocatio
hal.canary
2016/06/23 20:57:12
Before, I had TWO allocations. Can you see an eas
tomhudson
2016/06/23 21:03:51
The wideChars section avoids it, but I'd suggest w
| |
| 1090 uint8_t* ptr = (uint8_t*)buffer.get(); | |
| 1089 for (size_t i = 0; i < len; i++) { | 1091 for (size_t i = 0; i < len; i++) { |
| 1090 SkASSERT(0 == input[i] >> 8); | 1092 SkASSERT(0 == input[i] >> 8); |
| 1091 tmp[i] = static_cast<uint8_t>(input[i]); | 1093 ptr[i] = static_cast<uint8_t>(input[i]); |
| 1092 } | 1094 } |
| 1093 return SkPDFUtils::FormatString(tmp.c_str(), tmp.size()); | 1095 SkPDFUtils::WriteString(wStream, (char*)buffer.get(), len); |
| 1094 } | 1096 } |
| 1095 } | 1097 } |
| 1096 | 1098 |
| 1097 static void draw_transparent_text(SkPDFDevice* device, | 1099 static void draw_transparent_text(SkPDFDevice* device, |
| 1098 const SkDraw& d, | 1100 const SkDraw& d, |
| 1099 const void* text, size_t len, | 1101 const void* text, size_t len, |
| 1100 SkScalar x, SkScalar y, | 1102 SkScalar x, SkScalar y, |
| 1101 const SkPaint& srcPaint) { | 1103 const SkPaint& srcPaint) { |
| 1102 | 1104 |
| 1103 SkPaint transparent; | 1105 SkPaint transparent; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1177 while (numGlyphs > consumedGlyphCount) { | 1179 while (numGlyphs > consumedGlyphCount) { |
| 1178 this->updateFont(textPaint, glyphIDs[consumedGlyphCount], content.entry( )); | 1180 this->updateFont(textPaint, glyphIDs[consumedGlyphCount], content.entry( )); |
| 1179 SkPDFFont* font = content.entry()->fState.fFont; | 1181 SkPDFFont* font = content.entry()->fState.fFont; |
| 1180 | 1182 |
| 1181 int availableGlyphs = font->glyphsToPDFFontEncoding( | 1183 int availableGlyphs = font->glyphsToPDFFontEncoding( |
| 1182 glyphIDsCopy.begin() + consumedGlyphCount, | 1184 glyphIDsCopy.begin() + consumedGlyphCount, |
| 1183 numGlyphs - consumedGlyphCount); | 1185 numGlyphs - consumedGlyphCount); |
| 1184 fFontGlyphUsage->noteGlyphUsage( | 1186 fFontGlyphUsage->noteGlyphUsage( |
| 1185 font, glyphIDsCopy.begin() + consumedGlyphCount, | 1187 font, glyphIDsCopy.begin() + consumedGlyphCount, |
| 1186 availableGlyphs); | 1188 availableGlyphs); |
| 1187 SkString encodedString = | 1189 write_wide_string(&content.entry()->fContent, |
| 1188 format_wide_string(glyphIDsCopy.begin() + consumedGlyphCount, | 1190 glyphIDsCopy.begin() + consumedGlyphCount, |
| 1189 availableGlyphs, font->multiByteGlyphs()); | 1191 availableGlyphs, font->multiByteGlyphs()); |
| 1190 content.entry()->fContent.writeText(encodedString.c_str()); | |
| 1191 consumedGlyphCount += availableGlyphs; | 1192 consumedGlyphCount += availableGlyphs; |
| 1192 content.entry()->fContent.writeText(" Tj\n"); | 1193 content.entry()->fContent.writeText(" Tj\n"); |
| 1193 } | 1194 } |
| 1194 content.entry()->fContent.writeText("ET\n"); | 1195 content.entry()->fContent.writeText("ET\n"); |
| 1195 } | 1196 } |
| 1196 | 1197 |
| 1197 void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len, | 1198 void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len, |
| 1198 const SkScalar pos[], int scalarsPerPos, | 1199 const SkScalar pos[], int scalarsPerPos, |
| 1199 const SkPoint& offset, const SkPaint& srcPaint) { | 1200 const SkPoint& offset, const SkPaint& srcPaint) { |
| 1200 if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fDocument->canon()) ) { | 1201 if (!SkPDFFont::CanEmbedTypeface(srcPaint.getTypeface(), fDocument->canon()) ) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1257 continue; | 1258 continue; |
| 1258 } | 1259 } |
| 1259 } | 1260 } |
| 1260 | 1261 |
| 1261 fFontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1); | 1262 fFontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1); |
| 1262 SkScalar x = offset.x() + pos[i * scalarsPerPos]; | 1263 SkScalar x = offset.x() + pos[i * scalarsPerPos]; |
| 1263 SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[i * scalarsPerPos + 1] : 0); | 1264 SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[i * scalarsPerPos + 1] : 0); |
| 1264 | 1265 |
| 1265 align_text(glyphCacheProc, textPaint, glyphIDs + i, 1, &x, &y); | 1266 align_text(glyphCacheProc, textPaint, glyphIDs + i, 1, &x, &y); |
| 1266 set_text_transform(x, y, textPaint.getTextSkewX(), &content.entry()->fCo ntent); | 1267 set_text_transform(x, y, textPaint.getTextSkewX(), &content.entry()->fCo ntent); |
| 1267 SkString encodedString = | 1268 write_wide_string(&content.entry()->fContent, &encodedValue, 1, |
| 1268 format_wide_string(&encodedValue, 1, font->multiByteGlyphs()); | 1269 font->multiByteGlyphs()); |
| 1269 content.entry()->fContent.writeText(encodedString.c_str()); | |
| 1270 content.entry()->fContent.writeText(" Tj\n"); | 1270 content.entry()->fContent.writeText(" Tj\n"); |
| 1271 } | 1271 } |
| 1272 content.entry()->fContent.writeText("ET\n"); | 1272 content.entry()->fContent.writeText("ET\n"); |
| 1273 } | 1273 } |
| 1274 | 1274 |
| 1275 void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode, | 1275 void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode, |
| 1276 int vertexCount, const SkPoint verts[], | 1276 int vertexCount, const SkPoint verts[], |
| 1277 const SkPoint texs[], const SkColor colors[], | 1277 const SkPoint texs[], const SkColor colors[], |
| 1278 SkXfermode* xmode, const uint16_t indices[], | 1278 SkXfermode* xmode, const uint16_t indices[], |
| 1279 int indexCount, const SkPaint& paint) { | 1279 int indexCount, const SkPaint& paint) { |
| (...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2138 if (!pdfimage) { | 2138 if (!pdfimage) { |
| 2139 return; | 2139 return; |
| 2140 } | 2140 } |
| 2141 fDocument->serialize(pdfimage); // serialize images early. | 2141 fDocument->serialize(pdfimage); // serialize images early. |
| 2142 fDocument->canon()->addPDFBitmap(key, pdfimage); | 2142 fDocument->canon()->addPDFBitmap(key, pdfimage); |
| 2143 } | 2143 } |
| 2144 // TODO(halcanary): addXObjectResource() should take a sk_sp<SkPDFObject> | 2144 // TODO(halcanary): addXObjectResource() should take a sk_sp<SkPDFObject> |
| 2145 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), | 2145 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), |
| 2146 &content.entry()->fContent); | 2146 &content.entry()->fContent); |
| 2147 } | 2147 } |
| OLD | NEW |