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 |