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 "SkAnnotation.h" | 10 #include "SkAnnotation.h" |
(...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 if (d.fClip->isEmpty()) { | 1044 if (d.fClip->isEmpty()) { |
1045 return; | 1045 return; |
1046 } | 1046 } |
1047 | 1047 |
1048 SkMatrix matrix; | 1048 SkMatrix matrix; |
1049 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); | 1049 matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); |
1050 this->internalDrawBitmap(matrix, d.fClipStack, *d.fClip, bitmap, NULL, | 1050 this->internalDrawBitmap(matrix, d.fClipStack, *d.fClip, bitmap, NULL, |
1051 paint); | 1051 paint); |
1052 } | 1052 } |
1053 | 1053 |
| 1054 // Create a PDF string. Maximum length (in bytes) is 65,535. |
| 1055 // @param input A string value. |
| 1056 // @param len The length of the input array. |
| 1057 // @param wideChars True iff the upper byte in each uint16_t is |
| 1058 // significant and should be encoded and not |
| 1059 // discarded. If true, the upper byte is encoded |
| 1060 // first. Otherwise, we assert the upper byte is |
| 1061 // zero. |
| 1062 static SkString format_wide_string(const uint16_t* input, |
| 1063 size_t len, |
| 1064 bool wideChars) { |
| 1065 if (wideChars) { |
| 1066 SkASSERT(2 * len < 65535); |
| 1067 static const char gHex[] = "0123456789ABCDEF"; |
| 1068 SkString result(4 * len + 2); |
| 1069 result[0] = '<'; |
| 1070 for (size_t i = 0; i < len; i++) { |
| 1071 result[4 * i + 1] = gHex[(input[i] >> 12) & 0xF]; |
| 1072 result[4 * i + 2] = gHex[(input[i] >> 8) & 0xF]; |
| 1073 result[4 * i + 3] = gHex[(input[i] >> 4) & 0xF]; |
| 1074 result[4 * i + 4] = gHex[(input[i] ) & 0xF]; |
| 1075 } |
| 1076 result[4 * len + 1] = '>'; |
| 1077 return result; |
| 1078 } else { |
| 1079 SkASSERT(len <= 65535); |
| 1080 SkString tmp(len); |
| 1081 for (size_t i = 0; i < len; i++) { |
| 1082 SkASSERT(0 == input[i] >> 8); |
| 1083 tmp[i] = static_cast<uint8_t>(input[i]); |
| 1084 } |
| 1085 return SkPDFString::FormatString(tmp.c_str(), tmp.size()); |
| 1086 } |
| 1087 } |
| 1088 |
1054 void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, | 1089 void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, |
1055 SkScalar x, SkScalar y, const SkPaint& paint) { | 1090 SkScalar x, SkScalar y, const SkPaint& paint) { |
1056 NOT_IMPLEMENTED(paint.getMaskFilter() != NULL, false); | 1091 NOT_IMPLEMENTED(paint.getMaskFilter() != NULL, false); |
1057 if (paint.getMaskFilter() != NULL) { | 1092 if (paint.getMaskFilter() != NULL) { |
1058 // Don't pretend we support drawing MaskFilters, it makes for artifacts | 1093 // Don't pretend we support drawing MaskFilters, it makes for artifacts |
1059 // making text unreadable (e.g. same text twice when using CSS shadows). | 1094 // making text unreadable (e.g. same text twice when using CSS shadows). |
1060 return; | 1095 return; |
1061 } | 1096 } |
1062 SkPaint textPaint = calculate_text_paint(paint); | 1097 SkPaint textPaint = calculate_text_paint(paint); |
1063 ScopedContentEntry content(this, d, textPaint, true); | 1098 ScopedContentEntry content(this, d, textPaint, true); |
(...skipping 19 matching lines...) Expand all Loading... |
1083 updateFont(textPaint, glyphIDs[consumedGlyphCount], content.entry()); | 1118 updateFont(textPaint, glyphIDs[consumedGlyphCount], content.entry()); |
1084 SkPDFFont* font = content.entry()->fState.fFont; | 1119 SkPDFFont* font = content.entry()->fState.fFont; |
1085 | 1120 |
1086 int availableGlyphs = font->glyphsToPDFFontEncoding( | 1121 int availableGlyphs = font->glyphsToPDFFontEncoding( |
1087 glyphIDsCopy.begin() + consumedGlyphCount, | 1122 glyphIDsCopy.begin() + consumedGlyphCount, |
1088 numGlyphs - consumedGlyphCount); | 1123 numGlyphs - consumedGlyphCount); |
1089 fFontGlyphUsage->noteGlyphUsage( | 1124 fFontGlyphUsage->noteGlyphUsage( |
1090 font, glyphIDsCopy.begin() + consumedGlyphCount, | 1125 font, glyphIDsCopy.begin() + consumedGlyphCount, |
1091 availableGlyphs); | 1126 availableGlyphs); |
1092 SkString encodedString = | 1127 SkString encodedString = |
1093 SkPDFString::FormatString(glyphIDsCopy.begin() + consumedGlyphCount, | 1128 format_wide_string(glyphIDsCopy.begin() + consumedGlyphCount, |
1094 availableGlyphs, font->multiByteGlyphs()); | 1129 availableGlyphs, font->multiByteGlyphs()); |
1095 content.entry()->fContent.writeText(encodedString.c_str()); | 1130 content.entry()->fContent.writeText(encodedString.c_str()); |
1096 consumedGlyphCount += availableGlyphs; | 1131 consumedGlyphCount += availableGlyphs; |
1097 content.entry()->fContent.writeText(" Tj\n"); | 1132 content.entry()->fContent.writeText(" Tj\n"); |
1098 } | 1133 } |
1099 content.entry()->fContent.writeText("ET\n"); | 1134 content.entry()->fContent.writeText("ET\n"); |
1100 } | 1135 } |
1101 | 1136 |
1102 void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len, | 1137 void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len, |
1103 const SkScalar pos[], int scalarsPerPos, | 1138 const SkScalar pos[], int scalarsPerPos, |
1104 const SkPoint& offset, const SkPaint& paint) { | 1139 const SkPoint& offset, const SkPaint& paint) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1137 } | 1172 } |
1138 } | 1173 } |
1139 | 1174 |
1140 fFontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1); | 1175 fFontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1); |
1141 SkScalar x = offset.x() + pos[i * scalarsPerPos]; | 1176 SkScalar x = offset.x() + pos[i * scalarsPerPos]; |
1142 SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[i * scalarsPerPos +
1] : 0); | 1177 SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[i * scalarsPerPos +
1] : 0); |
1143 | 1178 |
1144 align_text(glyphCacheProc, textPaint, glyphIDs + i, 1, &x, &y); | 1179 align_text(glyphCacheProc, textPaint, glyphIDs + i, 1, &x, &y); |
1145 set_text_transform(x, y, textPaint.getTextSkewX(), &content.entry()->fCo
ntent); | 1180 set_text_transform(x, y, textPaint.getTextSkewX(), &content.entry()->fCo
ntent); |
1146 SkString encodedString = | 1181 SkString encodedString = |
1147 SkPDFString::FormatString(&encodedValue, 1, font->multiByteGlyphs())
; | 1182 format_wide_string(&encodedValue, 1, font->multiByteGlyphs()); |
1148 content.entry()->fContent.writeText(encodedString.c_str()); | 1183 content.entry()->fContent.writeText(encodedString.c_str()); |
1149 content.entry()->fContent.writeText(" Tj\n"); | 1184 content.entry()->fContent.writeText(" Tj\n"); |
1150 } | 1185 } |
1151 content.entry()->fContent.writeText("ET\n"); | 1186 content.entry()->fContent.writeText("ET\n"); |
1152 } | 1187 } |
1153 | 1188 |
1154 void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode, | 1189 void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode, |
1155 int vertexCount, const SkPoint verts[], | 1190 int vertexCount, const SkPoint verts[], |
1156 const SkPoint texs[], const SkColor colors[], | 1191 const SkPoint texs[], const SkColor colors[], |
1157 SkXfermode* xmode, const uint16_t indices[], | 1192 SkXfermode* xmode, const uint16_t indices[], |
(...skipping 974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2132 return; | 2167 return; |
2133 } | 2168 } |
2134 SkAutoTUnref<SkPDFObject> image(SkPDFBitmap::Create(fCanon, subsetBitmap)); | 2169 SkAutoTUnref<SkPDFObject> image(SkPDFBitmap::Create(fCanon, subsetBitmap)); |
2135 if (!image) { | 2170 if (!image) { |
2136 return; | 2171 return; |
2137 } | 2172 } |
2138 | 2173 |
2139 SkPDFUtils::DrawFormXObject(this->addXObjectResource(image.get()), | 2174 SkPDFUtils::DrawFormXObject(this->addXObjectResource(image.get()), |
2140 &content.entry()->fContent); | 2175 &content.entry()->fContent); |
2141 } | 2176 } |
OLD | NEW |