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

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

Issue 434623002: Remove ALL font fallback logic from Skia. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix win font host Created 6 years, 4 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/core/SkScalerContext.cpp ('k') | src/ports/SkFontConfigInterface_android.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 17 matching lines...) Expand all
28 #include "SkPDFUtils.h" 28 #include "SkPDFUtils.h"
29 #include "SkRect.h" 29 #include "SkRect.h"
30 #include "SkRRect.h" 30 #include "SkRRect.h"
31 #include "SkString.h" 31 #include "SkString.h"
32 #include "SkSurface.h" 32 #include "SkSurface.h"
33 #include "SkTextFormatParams.h" 33 #include "SkTextFormatParams.h"
34 #include "SkTemplates.h" 34 #include "SkTemplates.h"
35 #include "SkTypefacePriv.h" 35 #include "SkTypefacePriv.h"
36 #include "SkTSet.h" 36 #include "SkTSet.h"
37 37
38 #ifdef SK_BUILD_FOR_ANDROID
39 #include "SkTypeface_android.h"
40
41 struct TypefaceFallbackData {
42 SkTypeface* typeface;
43 int lowerBounds;
44 int upperBounds;
45
46 bool operator==(const TypefaceFallbackData& b) const {
47 return typeface == b.typeface &&
48 lowerBounds == b.lowerBounds &&
49 upperBounds == b.upperBounds;
50 }
51 };
52 #endif
53
54 #define DPI_FOR_RASTER_SCALE_ONE 72 38 #define DPI_FOR_RASTER_SCALE_ONE 72
55 39
56 // Utility functions 40 // Utility functions
57 41
58 static void emit_pdf_color(SkColor color, SkWStream* result) { 42 static void emit_pdf_color(SkColor color, SkWStream* result) {
59 SkASSERT(SkColorGetA(color) == 0xFF); // We handle alpha elsewhere. 43 SkASSERT(SkColorGetA(color) == 0xFF); // We handle alpha elsewhere.
60 SkScalar colorMax = SkIntToScalar(0xFF); 44 SkScalar colorMax = SkIntToScalar(0xFF);
61 SkPDFScalar::Append( 45 SkPDFScalar::Append(
62 SkScalarDiv(SkIntToScalar(SkColorGetR(color)), colorMax), result); 46 SkScalarDiv(SkIntToScalar(SkColorGetR(color)), colorMax), result);
63 result->writeText(" "); 47 result->writeText(" ");
(...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 // making text unreadable (e.g. same text twice when using CSS shadows). 1152 // making text unreadable (e.g. same text twice when using CSS shadows).
1169 return; 1153 return;
1170 } 1154 }
1171 SkASSERT(1 == scalarsPerPos || 2 == scalarsPerPos); 1155 SkASSERT(1 == scalarsPerPos || 2 == scalarsPerPos);
1172 SkPaint textPaint = calculate_text_paint(paint); 1156 SkPaint textPaint = calculate_text_paint(paint);
1173 ScopedContentEntry content(this, d, textPaint, true); 1157 ScopedContentEntry content(this, d, textPaint, true);
1174 if (!content.entry()) { 1158 if (!content.entry()) {
1175 return; 1159 return;
1176 } 1160 }
1177 1161
1178 #ifdef SK_BUILD_FOR_ANDROID
1179 /*
1180 * In the case that we have enabled fallback fonts on Android we need to
1181 * take the following steps to ensure that the PDF draws all characters,
1182 * regardless of their underlying font file, correctly.
1183 *
1184 * 1. Convert input into GlyphID encoding if it currently is not
1185 * 2. Iterate over the glyphIDs and identify the actual typeface that each
1186 * glyph resolves to
1187 * 3. Iterate over those typefaces and recursively call this function with
1188 * only the glyphs (and their positions) that the typeface is capable of
1189 * resolving.
1190 */
1191 if (paint.getPaintOptionsAndroid().isUsingFontFallbacks()) {
1192 uint16_t* glyphIDs = NULL;
1193 SkGlyphStorage tmpStorage(0);
1194 size_t numGlyphs = 0;
1195
1196 // convert to glyphIDs
1197 if (paint.getTextEncoding() == SkPaint::kGlyphID_TextEncoding) {
1198 numGlyphs = len / 2;
1199 glyphIDs = reinterpret_cast<uint16_t*>(const_cast<void*>(text));
1200 } else {
1201 numGlyphs = paint.textToGlyphs(text, len, NULL);
1202 tmpStorage.reset(numGlyphs);
1203 paint.textToGlyphs(text, len, tmpStorage.get());
1204 glyphIDs = tmpStorage.get();
1205 }
1206
1207 // if no typeface is provided in the paint get the default
1208 SkAutoTUnref<SkTypeface> origFace(SkSafeRef(paint.getTypeface()));
1209 if (NULL == origFace.get()) {
1210 origFace.reset(SkTypeface::RefDefault());
1211 }
1212 const uint16_t origGlyphCount = origFace->countGlyphs();
1213
1214 // keep a list of the already visited typefaces and some data about them
1215 SkTDArray<TypefaceFallbackData> visitedTypefaces;
1216
1217 // find all the typefaces needed to resolve this run of text
1218 bool usesOriginalTypeface = false;
1219 for (uint16_t x = 0; x < numGlyphs; ++x) {
1220 // optimization that checks to see if original typeface can resolve
1221 // the glyph
1222 if (glyphIDs[x] < origGlyphCount) {
1223 usesOriginalTypeface = true;
1224 continue;
1225 }
1226
1227 // find the fallback typeface that supports this glyph
1228 TypefaceFallbackData data;
1229 data.typeface =
1230 SkGetTypefaceForGlyphID(glyphIDs[x], origFace.get(),
1231 paint.getPaintOptionsAndroid(),
1232 &data.lowerBounds,
1233 &data.upperBounds);
1234 // add the typeface and its data if we don't have it
1235 if (data.typeface && !visitedTypefaces.contains(data)) {
1236 visitedTypefaces.push(data);
1237 }
1238 }
1239
1240 // if the original font was used then add it to the list as well
1241 if (usesOriginalTypeface) {
1242 TypefaceFallbackData* data = visitedTypefaces.push();
1243 data->typeface = origFace.get();
1244 data->lowerBounds = 0;
1245 data->upperBounds = origGlyphCount;
1246 }
1247
1248 // keep a scratch glyph and pos storage
1249 SkAutoTMalloc<SkScalar> posStorage(len * scalarsPerPos);
1250 SkScalar* tmpPos = posStorage.get();
1251 SkGlyphStorage glyphStorage(numGlyphs);
1252 uint16_t* tmpGlyphIDs = glyphStorage.get();
1253
1254 // loop through all the valid typefaces, trim the glyphs to only those
1255 // resolved by the typeface, and then draw that run of glyphs
1256 for (int x = 0; x < visitedTypefaces.count(); ++x) {
1257 const TypefaceFallbackData& data = visitedTypefaces[x];
1258
1259 int tmpGlyphCount = 0;
1260 for (uint16_t y = 0; y < numGlyphs; ++y) {
1261 if (glyphIDs[y] >= data.lowerBounds &&
1262 glyphIDs[y] < data.upperBounds) {
1263 tmpGlyphIDs[tmpGlyphCount] = glyphIDs[y] - data.lowerBounds;
1264 memcpy(&(tmpPos[tmpGlyphCount * scalarsPerPos]),
1265 &(pos[y * scalarsPerPos]),
1266 scalarsPerPos * sizeof(SkScalar));
1267 tmpGlyphCount++;
1268 }
1269 }
1270
1271 // recursively call this function with the right typeface
1272 SkPaint tmpPaint = paint;
1273 tmpPaint.setTypeface(data.typeface);
1274 tmpPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
1275
1276 // turn off fallback chaining
1277 SkPaintOptionsAndroid paintOpts = tmpPaint.getPaintOptionsAndroid();
1278 paintOpts.setUseFontFallbacks(false);
1279 tmpPaint.setPaintOptionsAndroid(paintOpts);
1280
1281 this->drawPosText(d, tmpGlyphIDs, tmpGlyphCount * 2, tmpPos, constY,
1282 scalarsPerPos, tmpPaint);
1283 }
1284 return;
1285 }
1286 #endif
1287
1288 SkGlyphStorage storage(0); 1162 SkGlyphStorage storage(0);
1289 uint16_t* glyphIDs = NULL; 1163 uint16_t* glyphIDs = NULL;
1290 size_t numGlyphs = force_glyph_encoding(paint, text, len, &storage, 1164 size_t numGlyphs = force_glyph_encoding(paint, text, len, &storage,
1291 &glyphIDs); 1165 &glyphIDs);
1292 textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 1166 textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
1293 1167
1294 SkDrawCacheProc glyphCacheProc = textPaint.getDrawCacheProc(); 1168 SkDrawCacheProc glyphCacheProc = textPaint.getDrawCacheProc();
1295 content.entry()->fContent.writeText("BT\n"); 1169 content.entry()->fContent.writeText("BT\n");
1296 updateFont(textPaint, glyphIDs[0], content.entry()); 1170 updateFont(textPaint, glyphIDs[0], content.entry());
1297 for (size_t i = 0; i < numGlyphs; i++) { 1171 for (size_t i = 0; i < numGlyphs; i++) {
(...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after
2311 SkAutoTUnref<SkPDFImage> image( 2185 SkAutoTUnref<SkPDFImage> image(
2312 SkPDFImage::CreateImage(*bitmap, subset, fEncoder)); 2186 SkPDFImage::CreateImage(*bitmap, subset, fEncoder));
2313 if (!image) { 2187 if (!image) {
2314 return; 2188 return;
2315 } 2189 }
2316 2190
2317 SkPDFUtils::DrawFormXObject(this->addXObjectResource(image.get()), 2191 SkPDFUtils::DrawFormXObject(this->addXObjectResource(image.get()),
2318 &content.entry()->fContent); 2192 &content.entry()->fContent);
2319 } 2193 }
2320 2194
OLDNEW
« no previous file with comments | « src/core/SkScalerContext.cpp ('k') | src/ports/SkFontConfigInterface_android.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698