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 1061 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1072 SkAutoMalloc buffer(len); // Remove every other byte. | 1072 SkAutoMalloc buffer(len); // Remove every other byte. |
1073 uint8_t* ptr = (uint8_t*)buffer.get(); | 1073 uint8_t* ptr = (uint8_t*)buffer.get(); |
1074 for (size_t i = 0; i < len; i++) { | 1074 for (size_t i = 0; i < len; i++) { |
1075 SkASSERT(0 == input[i] >> 8); | 1075 SkASSERT(0 == input[i] >> 8); |
1076 ptr[i] = static_cast<uint8_t>(input[i]); | 1076 ptr[i] = static_cast<uint8_t>(input[i]); |
1077 } | 1077 } |
1078 SkPDFUtils::WriteString(wStream, (char*)buffer.get(), len); | 1078 SkPDFUtils::WriteString(wStream, (char*)buffer.get(), len); |
1079 } | 1079 } |
1080 } | 1080 } |
1081 | 1081 |
| 1082 namespace { |
| 1083 class GlyphPositioner { |
| 1084 public: |
| 1085 GlyphPositioner(SkDynamicMemoryWStream* content, |
| 1086 SkScalar textSkewX, |
| 1087 bool wideChars) |
| 1088 : fContent(content) |
| 1089 , fCurrentMatrixX(0.0f) |
| 1090 , fCurrentMatrixY(0.0f) |
| 1091 , fXAdvance(0.0f) |
| 1092 , fWideChars(wideChars) |
| 1093 , fInText(false) { |
| 1094 set_text_transform(0.0f, 0.0f, textSkewX, fContent); |
| 1095 } |
| 1096 ~GlyphPositioner() { SkASSERT(!fInText); /* flush first */ } |
| 1097 void flush() { |
| 1098 if (fInText) { |
| 1099 fContent->writeText("> Tj\n"); |
| 1100 fInText = false; |
| 1101 } |
| 1102 } |
| 1103 void setWideChars(bool wideChars) { |
| 1104 if (fWideChars != wideChars) { |
| 1105 SkASSERT(!fInText); |
| 1106 fWideChars = wideChars; |
| 1107 } |
| 1108 } |
| 1109 void writeGlyph(SkScalar x, |
| 1110 SkScalar y, |
| 1111 SkScalar advanceWidth, |
| 1112 uint16_t glyph) { |
| 1113 SkScalar xPosition = x - fCurrentMatrixX; |
| 1114 SkScalar yPosition = y - fCurrentMatrixY; |
| 1115 if (xPosition != fXAdvance || yPosition != 0) { |
| 1116 this->flush(); |
| 1117 SkPDFUtils::AppendScalar(xPosition, fContent); |
| 1118 fContent->writeText(" "); |
| 1119 SkPDFUtils::AppendScalar(-yPosition, fContent); |
| 1120 fContent->writeText(" Td "); |
| 1121 fCurrentMatrixX = x; |
| 1122 fCurrentMatrixY = y; |
| 1123 fXAdvance = 0; |
| 1124 } |
| 1125 if (!fInText) { |
| 1126 fContent->writeText("<"); |
| 1127 fInText = true; |
| 1128 } |
| 1129 if (fWideChars) { |
| 1130 SkPDFUtils::WriteUInt16BE(fContent, glyph); |
| 1131 } else { |
| 1132 SkASSERT(0 == glyph >> 8); |
| 1133 SkPDFUtils::WriteUInt8(fContent, static_cast<uint8_t>(glyph)); |
| 1134 } |
| 1135 fXAdvance += advanceWidth; |
| 1136 } |
| 1137 |
| 1138 private: |
| 1139 SkDynamicMemoryWStream* fContent; |
| 1140 SkScalar fCurrentMatrixX; |
| 1141 SkScalar fCurrentMatrixY; |
| 1142 SkScalar fXAdvance; |
| 1143 bool fWideChars; |
| 1144 bool fInText; |
| 1145 }; |
| 1146 } // namespace |
| 1147 |
1082 static void draw_transparent_text(SkPDFDevice* device, | 1148 static void draw_transparent_text(SkPDFDevice* device, |
1083 const SkDraw& d, | 1149 const SkDraw& d, |
1084 const void* text, size_t len, | 1150 const void* text, size_t len, |
1085 SkScalar x, SkScalar y, | 1151 SkScalar x, SkScalar y, |
1086 const SkPaint& srcPaint) { | 1152 const SkPaint& srcPaint) { |
1087 | 1153 |
1088 SkPaint transparent; | 1154 SkPaint transparent; |
1089 if (!SkPDFFont::CanEmbedTypeface(transparent.getTypeface(), | 1155 if (!SkPDFFont::CanEmbedTypeface(transparent.getTypeface(), |
1090 device->getCanon())) { | 1156 device->getCanon())) { |
1091 SkDEBUGFAIL("default typeface should be embeddable"); | 1157 SkDEBUGFAIL("default typeface should be embeddable"); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1223 } | 1289 } |
1224 | 1290 |
1225 SkGlyphStorage storage(0); | 1291 SkGlyphStorage storage(0); |
1226 const uint16_t* glyphIDs = nullptr; | 1292 const uint16_t* glyphIDs = nullptr; |
1227 size_t numGlyphs = force_glyph_encoding(paint, text, len, &storage, &glyphID
s); | 1293 size_t numGlyphs = force_glyph_encoding(paint, text, len, &storage, &glyphID
s); |
1228 textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | 1294 textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
1229 | 1295 |
1230 SkPaint::GlyphCacheProc glyphCacheProc = textPaint.getGlyphCacheProc(true); | 1296 SkPaint::GlyphCacheProc glyphCacheProc = textPaint.getGlyphCacheProc(true); |
1231 content.entry()->fContent.writeText("BT\n"); | 1297 content.entry()->fContent.writeText("BT\n"); |
1232 this->updateFont(textPaint, glyphIDs[0], content.entry()); | 1298 this->updateFont(textPaint, glyphIDs[0], content.entry()); |
| 1299 GlyphPositioner glyphPositioner(&content.entry()->fContent, |
| 1300 textPaint.getTextSkewX(), |
| 1301 content.entry()->fState.fFont->multiByteGlyp
hs()); |
1233 SkPDFGlyphSetMap* fontGlyphUsage = fDocument->getGlyphUsage(); | 1302 SkPDFGlyphSetMap* fontGlyphUsage = fDocument->getGlyphUsage(); |
1234 for (size_t i = 0; i < numGlyphs; i++) { | 1303 for (size_t i = 0; i < numGlyphs; i++) { |
1235 SkPDFFont* font = content.entry()->fState.fFont; | 1304 SkPDFFont* font = content.entry()->fState.fFont; |
1236 uint16_t encodedValue = glyphIDs[i]; | 1305 uint16_t encodedValue = glyphIDs[i]; |
1237 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) { | 1306 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) { |
1238 // The current pdf font cannot encode the current glyph. | 1307 // The current pdf font cannot encode the current glyph. |
1239 // Try to get a pdf font which can encode the current glyph. | 1308 // Try to get a pdf font which can encode the current glyph. |
| 1309 glyphPositioner.flush(); |
1240 this->updateFont(textPaint, glyphIDs[i], content.entry()); | 1310 this->updateFont(textPaint, glyphIDs[i], content.entry()); |
1241 font = content.entry()->fState.fFont; | 1311 font = content.entry()->fState.fFont; |
| 1312 glyphPositioner.setWideChars(font->multiByteGlyphs()); |
1242 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) { | 1313 if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) { |
1243 SkDEBUGFAIL("PDF could not encode glyph."); | 1314 SkDEBUGFAIL("PDF could not encode glyph."); |
1244 continue; | 1315 continue; |
1245 } | 1316 } |
1246 } | 1317 } |
1247 | 1318 |
1248 fontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1); | 1319 fontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1); |
1249 SkScalar x = offset.x() + pos[i * scalarsPerPos]; | 1320 SkScalar x = offset.x() + pos[i * scalarsPerPos]; |
1250 SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[i * scalarsPerPos +
1] : 0); | 1321 SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[i * scalarsPerPos +
1] : 0); |
| 1322 align_text(glyphCacheProc, textPaint, glyphIDs + i, 1, &x, &y); |
1251 | 1323 |
1252 align_text(glyphCacheProc, textPaint, glyphIDs + i, 1, &x, &y); | 1324 SkScalar advanceWidth = textPaint.measureText(&encodedValue, sizeof(uint
16_t)); |
1253 set_text_transform(x, y, textPaint.getTextSkewX(), &content.entry()->fCo
ntent); | 1325 glyphPositioner.writeGlyph(x, y, advanceWidth, encodedValue); |
1254 write_wide_string(&content.entry()->fContent, &encodedValue, 1, | |
1255 font->multiByteGlyphs()); | |
1256 content.entry()->fContent.writeText(" Tj\n"); | |
1257 } | 1326 } |
| 1327 glyphPositioner.flush(); // Must flush before ending text object. |
1258 content.entry()->fContent.writeText("ET\n"); | 1328 content.entry()->fContent.writeText("ET\n"); |
1259 } | 1329 } |
1260 | 1330 |
1261 void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode, | 1331 void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode, |
1262 int vertexCount, const SkPoint verts[], | 1332 int vertexCount, const SkPoint verts[], |
1263 const SkPoint texs[], const SkColor colors[], | 1333 const SkPoint texs[], const SkColor colors[], |
1264 SkXfermode* xmode, const uint16_t indices[], | 1334 SkXfermode* xmode, const uint16_t indices[], |
1265 int indexCount, const SkPaint& paint) { | 1335 int indexCount, const SkPaint& paint) { |
1266 if (d.fRC->isEmpty()) { | 1336 if (d.fRC->isEmpty()) { |
1267 return; | 1337 return; |
(...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2121 if (!pdfimage) { | 2191 if (!pdfimage) { |
2122 return; | 2192 return; |
2123 } | 2193 } |
2124 fDocument->serialize(pdfimage); // serialize images early. | 2194 fDocument->serialize(pdfimage); // serialize images early. |
2125 fDocument->canon()->addPDFBitmap(key, pdfimage); | 2195 fDocument->canon()->addPDFBitmap(key, pdfimage); |
2126 } | 2196 } |
2127 // TODO(halcanary): addXObjectResource() should take a sk_sp<SkPDFObject> | 2197 // TODO(halcanary): addXObjectResource() should take a sk_sp<SkPDFObject> |
2128 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), | 2198 SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), |
2129 &content.entry()->fContent); | 2199 &content.entry()->fContent); |
2130 } | 2200 } |
OLD | NEW |