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

Side by Side Diff: experimental/PdfViewer/SkPdfFont.h

Issue 1266093003: Remove experimental/PdfViewer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 2015-08-03 (Monday) 10:43:56 EDT Created 5 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 | « experimental/PdfViewer/SkPdfConfig.h ('k') | experimental/PdfViewer/SkPdfFont.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 // TODO(edisonn): this file not commented much on purpose.
9 // It will probably need heavy refactoring soon anyway to support all encodings, fonts and
10 // proper text sizing and spacing
11
12 #ifndef SkPdfFont_DEFINED
13 #define SkPdfFont_DEFINED
14
15 #include "SkPdfContext.h"
16 #include "SkPdfHeaders_autogen.h"
17 #include "SkPdfMapper_autogen.h"
18 #include "SkPdfUtils.h"
19 #include "SkTypeface.h"
20 #include "SkTDict.h"
21 #include "SkUtils.h"
22
23 class SkPdfType0Font;
24 class SkPdfType1Font;
25 class SkPdfType3Font;
26 class SkPdfTrueTypeFont;
27 class SkPdfMultiMasterFont;
28 class SkPdfFont;
29
30 struct SkPdfStandardFontEntry {
31 // We don't own this pointer!
32 const char* fName;
33 bool fIsBold;
34 bool fIsItalic;
35 SkPdfStandardFontEntry()
36 : fName(NULL),
37 fIsBold(false),
38 fIsItalic(false) {}
39
40 SkPdfStandardFontEntry(const char* name, bool bold, bool italic)
41 : fName(name),
42 fIsBold(bold),
43 fIsItalic(italic) {}
44 };
45
46 SkTDict<SkPdfStandardFontEntry>& getStandardFonts();
47 SkTypeface* SkTypefaceFromPdfStandardFont(const char* fontName, bool bold, bool italic);
48 SkPdfFont* fontFromName(SkPdfNativeDoc* doc, SkPdfNativeObject* obj, const char* fontName);
49
50 struct SkUnencodedText {
51 void* text;
52 int len;
53
54 public:
55 SkUnencodedText(const SkPdfString* obj) {
56 text = (void*)obj->c_str();
57 len = (int) obj->lenstr();
58 }
59 };
60
61 struct SkDecodedText {
62 uint16_t* text;
63 int len;
64 public:
65 unsigned int operator[](int i) const { return text[i]; }
66 int size() const { return len; }
67 };
68
69 struct SkUnicodeText {
70 uint16_t* text;
71 int len;
72
73 public:
74 unsigned int operator[](int i) const { return text[i]; }
75 int size() const { return len; }
76 };
77
78 class SkPdfEncoding {
79 public:
80 virtual ~SkPdfEncoding() {}
81 virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOu t) const = 0;
82 static SkPdfEncoding* fromName(const char* name);
83 };
84
85 SkTDict<SkPdfEncoding*>& getStandardEncodings();
86
87 class SkPdfToUnicode {
88 // TODO(edisonn): hide public members
89 public:
90 unsigned short* fCMapEncoding;
91 unsigned char* fCMapEncodingFlag;
92
93 SkPdfToUnicode(SkPdfNativeDoc* parsed, SkPdfStream* stream);
94 };
95
96
97 class SkPdfIdentityHEncoding : public SkPdfEncoding {
98 public:
99 virtual ~SkPdfIdentityHEncoding() {}
100 virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOu t) const {
101 // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error?
102
103 uint16_t* text = (uint16_t*)textIn.text;
104 textOut->text = new uint16_t[textIn.len / 2];
105 textOut->len = textIn.len / 2;
106
107 for (int i = 0; i < textOut->len; i++) {
108 textOut->text[i] = ((text[i] << 8) & 0xff00) | ((text[i] >> 8) & 0x0 0ff);
109 }
110
111 return true;
112 }
113
114 static SkPdfIdentityHEncoding* instance() {
115 static SkPdfIdentityHEncoding* inst = new SkPdfIdentityHEncoding();
116 return inst;
117 }
118 };
119
120 // TODO(edisonn): using this one when no encoding is specified
121 class SkPdfDefaultEncoding : public SkPdfEncoding {
122 public:
123 virtual ~SkPdfDefaultEncoding() {}
124 virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOu t) const {
125 // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error?
126
127 unsigned char* text = (unsigned char*)textIn.text;
128 textOut->text = new uint16_t[textIn.len];
129 textOut->len = textIn.len;
130
131 for (int i = 0; i < textOut->len; i++) {
132 textOut->text[i] = text[i];
133 }
134
135 return true;
136 }
137
138 static SkPdfDefaultEncoding* instance() {
139 static SkPdfDefaultEncoding* inst = new SkPdfDefaultEncoding();
140 return inst;
141 }
142 };
143
144 class SkPdfCIDToGIDMapIdentityEncoding : public SkPdfEncoding {
145 public:
146 virtual ~SkPdfCIDToGIDMapIdentityEncoding() {}
147 virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOu t) const {
148 // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error?
149
150 uint16_t* text = (uint16_t*)textIn.text;
151 textOut->text = new uint16_t[textIn.len / 2];
152 textOut->len = textIn.len / 2;
153
154 for (int i = 0; i < textOut->len; i++) {
155 textOut->text[i] = ((text[i] << 8) & 0xff00) | ((text[i] >> 8) & 0x0 0ff);
156 }
157
158 return true;
159 }
160
161 static SkPdfCIDToGIDMapIdentityEncoding* instance() {
162 static SkPdfCIDToGIDMapIdentityEncoding* inst = new SkPdfCIDToGIDMapIden tityEncoding();
163 return inst;
164 }
165 };
166
167 class SkPdfFont {
168 public:
169 SkPdfFont* fBaseFont;
170 SkPdfEncoding* fEncoding;
171 SkPdfToUnicode* fToUnicode;
172
173
174 public:
175 SkPdfFont() : fBaseFont(NULL), fEncoding(SkPdfDefaultEncoding::instance()), fToUnicode(NULL) {}
176
177 virtual ~SkPdfFont() {
178 // TODO(edisonn): NYI (will leak for now)
179 }
180
181 const SkPdfEncoding* encoding() const {return fEncoding;}
182
183 void drawText(const SkDecodedText& text, SkPaint* paint, SkPdfContext* pdfCo ntext,
184 SkCanvas* canvas) {
185 for (int i = 0 ; i < text.size(); i++) {
186 canvas->setMatrix(pdfContext->fGraphicsState.fMatrixTm);
187 #ifdef PDF_TRACE
188 SkPoint point = SkPoint::Make(SkDoubleToScalar(0), SkDoubleToScalar( 0));
189 pdfContext->fGraphicsState.fMatrixTm.mapPoints(&point, 1);
190 printf("DrawText at (%f, %f)\n", SkScalarToDouble(point.x()),
191 SkScalarToDouble(point.y()));
192 #endif // PDF_TRACE
193
194 #ifdef PDF_TRACE_DRAWTEXT
195 SkPaint col;
196 col.setColor(SK_ColorMAGENTA);
197 SkRect rect = SkRect::MakeXYWH(SkDoubleToScalar(0.0),
198 SkDoubleToScalar(0.0),
199 SkDoubleToScalar(10.0),
200 SkDoubleToScalar(10.0));
201 canvas->save();
202 canvas->setMatrix(pdfContext->fGraphicsState.fMatrixTm);
203 canvas->drawRect(rect, col);
204 canvas->restore();
205 #endif
206 double width = drawOneChar(text[i], paint, pdfContext, canvas);
207 pdfContext->fGraphicsState.fMatrixTm.preTranslate(SkDoubleToScalar(w idth),
208 SkDoubleToScalar(0 .0));
209 }
210 }
211
212 void ToUnicode(const SkDecodedText& textIn, SkUnicodeText* textOut) const {
213 if (fToUnicode) {
214 textOut->text = new uint16_t[textIn.len];
215 textOut->len = textIn.len;
216 for (int i = 0; i < textIn.len; i++) {
217 textOut->text[i] = fToUnicode->fCMapEncoding[textIn.text[i]];
218 }
219 } else {
220 textOut->text = textIn.text;
221 textOut->len = textIn.len;
222 }
223 };
224
225 inline unsigned int ToUnicode(unsigned int ch) const {
226 if (fToUnicode && fToUnicode->fCMapEncoding) {
227 return fToUnicode->fCMapEncoding[ch];
228 } else {
229 return ch;
230 }
231 };
232
233 static SkPdfFont* fontFromPdfDictionary(SkPdfNativeDoc* doc, SkPdfFontDictio nary* dict);
234 static SkPdfFont* Default() {return fontFromName(NULL, NULL, "TimesNewRoman" );}
235
236 static SkPdfType0Font* fontFromType0FontDictionary(SkPdfNativeDoc* doc,
237 SkPdfType0FontDictionary* dict);
238 static SkPdfType1Font* fontFromType1FontDictionary(SkPdfNativeDoc* doc,
239 SkPdfType1FontDictionary* dict);
240 static SkPdfType3Font* fontFromType3FontDictionary(SkPdfNativeDoc* doc,
241 SkPdfType3FontDictionary* dict);
242 static SkPdfTrueTypeFont* fontFromTrueTypeFontDictionary(SkPdfNativeDoc* doc ,
243 SkPdfTrueTypeFontDi ctionary* dict);
244 static SkPdfMultiMasterFont* fontFromMultiMasterFontDictionary(
245 SkPdfNativeDoc* doc, SkPdfMultiMasterFontDictionary* dict);
246
247 static SkPdfFont* fontFromFontDescriptor(SkPdfNativeDoc* doc,
248 SkPdfFontDescriptorDictionary* fd,
249 bool loadFromName = true);
250
251 public:
252 virtual double drawOneChar(unsigned int ch, SkPaint* paint, SkPdfContext* pd fContext,
253 SkCanvas* canvas) = 0;
254 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) = 0;
255
256 private:
257 static SkPdfFont* fontFromPdfDictionaryOnce(SkPdfNativeDoc* doc, SkPdfFontDi ctionary* dict);
258 };
259
260 class SkPdfStandardFont : public SkPdfFont {
261 SkTypeface* fTypeface;
262
263 public:
264 SkPdfStandardFont(SkTypeface* typeface) : fTypeface(typeface) {}
265
266 public:
267 virtual double drawOneChar(unsigned int ch, SkPaint* paint, SkPdfContext* pd fContext,
268 SkCanvas* canvas) {
269 paint->setTypeface(fTypeface);
270 paint->setTextEncoding(SkPaint::kUTF8_TextEncoding);
271
272 unsigned long ch4 = ch;
273 char utf8[10];
274 size_t len = SkUTF8_FromUnichar((SkUnichar) ch4, utf8);
275
276 canvas->drawText(utf8, len, SkDoubleToScalar(0), SkDoubleToScalar(0), *p aint);
277
278 SkScalar textWidth = paint->measureText(utf8, len);
279 return SkScalarToDouble(textWidth);
280 }
281
282 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {}
283 };
284
285 class SkPdfType0Font : public SkPdfFont {
286 public:
287 SkPdfType0Font(SkPdfNativeDoc* doc, SkPdfType0FontDictionary* dict);
288
289 public:
290
291 virtual double drawOneChar(unsigned int ch, SkPaint* paint, SkPdfContext* pd fContext,
292 SkCanvas* canvas) {
293 return fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas);
294 }
295
296 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
297 }
298 };
299
300 class SkPdfType1Font : public SkPdfFont {
301 public:
302 SkPdfType1Font(SkPdfNativeDoc* doc, SkPdfType1FontDictionary* dict) {
303 if (dict->has_FontDescriptor()) {
304 fBaseFont = SkPdfFont::fontFromFontDescriptor(doc, dict->FontDescrip tor(doc));
305 } else {
306 fBaseFont = fontFromName(doc, dict, dict->BaseFont(doc).c_str());
307 }
308
309 if (dict->isEncodingAName(doc)) {
310 fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName(doc).c_s tr());
311 } else if (dict->isEncodingADictionary(doc)) {
312 //SkPdfDictionary* dictEnc = dict->getEncodingAsDictionary(doc);
313 }
314 dict->FontDescriptor(doc);
315 }
316
317 public:
318 virtual double drawOneChar(unsigned int ch, SkPaint* paint, SkPdfContext* pdfContext,
319 SkCanvas* canvas) {
320 return fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas );
321 }
322
323 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
324
325 }
326 };
327
328 class SkPdfTrueTypeFont : public SkPdfType1Font {
329 public:
330 SkPdfTrueTypeFont(SkPdfNativeDoc* doc, SkPdfTrueTypeFontDictionary* dict)
331 : SkPdfType1Font(doc, dict) {}
332 };
333
334 class SkPdfMultiMasterFont : public SkPdfType1Font {
335 public:
336 SkPdfMultiMasterFont(SkPdfNativeDoc* doc, SkPdfMultiMasterFontDictionary* di ct)
337 : SkPdfType1Font(doc, dict) {}
338 };
339 /*
340 class CIDToGIDMap {
341 virtual unsigned int map(unsigned int cid) = 0;
342 static CIDToGIDMap* fromName(const char* name);
343 };
344
345 class CIDToGIDMap_Identity {
346 virtual unsigned int map(unsigned int cid) { return cid; }
347
348 static CIDToGIDMap_Identity* instance() {
349 static CIDToGIDMap_Identity* inst = new CIDToGIDMap_Identity();
350 return inst;
351 }
352 };
353
354 CIDToGIDMap* CIDToGIDMap::fromName(const char* name) {
355 // The only one supported right now is Identity
356 if (strcmp(name, "Identity") == 0) {
357 return CIDToGIDMap_Identity::instance();
358 }
359
360 #ifdef PDF_TRACE
361 // TODO(edisonn): warning/report
362 printf("Unknown CIDToGIDMap: %s\n", name);
363 #endif
364 return NULL;
365 }
366 CIDToGIDMap* fCidToGid;
367 */
368
369 class SkPdfType3Font : public SkPdfFont {
370 struct Type3FontChar {
371 SkPdfNativeObject* fObj;
372 double fWidth;
373 };
374
375 SkPdfDictionary* fCharProcs;
376 SkPdfEncodingDictionary* fEncodingDict;
377 unsigned int fFirstChar;
378 unsigned int fLastChar;
379
380 SkRect fFontBBox;
381 SkMatrix fFonMatrix;
382
383 Type3FontChar* fChars;
384
385 public:
386 SkPdfType3Font(SkPdfNativeDoc* parsed, SkPdfType3FontDictionary* dict) {
387 fBaseFont = fontFromName(parsed, dict, dict->BaseFont(parsed).c_str());
388
389 if (dict->has_Encoding()) {
390 if (dict->isEncodingAName(parsed)) {
391 fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName(par sed).c_str());
392 } else if (dict->isEncodingAEncodingdictionary(parsed)) {
393 // No encoding.
394 fEncoding = SkPdfDefaultEncoding::instance();
395 fEncodingDict = dict->getEncodingAsEncodingdictionary(parsed);
396 }
397 }
398
399 // null?
400 fCharProcs = dict->CharProcs(parsed);
401
402 fToUnicode = NULL;
403 if (dict->has_ToUnicode()) {
404 fToUnicode = new SkPdfToUnicode(parsed, dict->ToUnicode(parsed));
405 }
406
407 fFirstChar = (unsigned int)dict->FirstChar(parsed);
408 fLastChar = (unsigned int)dict->LastChar(parsed);
409 fFonMatrix = dict->has_FontMatrix() ? dict->FontMatrix(parsed) : SkMatri x::I();
410
411 if (dict->has_FontBBox()) {
412 fFontBBox = dict->FontBBox(parsed);
413 }
414
415 fChars = new Type3FontChar[fLastChar - fFirstChar + 1];
416
417 memset(fChars, 0, sizeof(fChars[0]) * (fLastChar - fFirstChar + 1));
418
419 const SkPdfArray* widths = dict->Widths(parsed);
420 for (unsigned int i = 0 ; i < widths->size(); i++) {
421 if ((fFirstChar + i) >= fFirstChar && (fFirstChar + i) <= fLastChar) {
422 fChars[i].fWidth = (*widths)[i]->numberValue();
423 } else {
424 // TODO(edisonn): report pdf corruption
425 }
426 }
427
428 const SkPdfArray* diffs = fEncodingDict->Differences(parsed);
429 unsigned int j = fFirstChar;
430 for (unsigned int i = 0 ; i < diffs->size(); i++) {
431 if ((*diffs)[i]->isInteger()) {
432 j = (unsigned int)(*diffs)[i]->intValue();
433 } else if ((*diffs)[i]->isName()) {
434 if (j >= fFirstChar && j <= fLastChar) {
435 fChars[j - fFirstChar].fObj = fCharProcs->get((*diffs)[i]);
436 } else {
437 // TODO(edisonn): report pdf corruption
438 }
439 j++;
440 } else {
441 // TODO(edisonn): report bad pdf
442 }
443 }
444 }
445
446 public:
447 virtual double drawOneChar(unsigned int ch, SkPaint* paint, SkPdfContext* pd fContext,
448 SkCanvas* canvas) {
449 if (ch < fFirstChar || ch > fLastChar || !fChars[ch - fFirstChar].fObj) {
450 return fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canv as);
451 }
452
453 #ifdef PDF_TRACE
454 printf("Type 3 char to unicode: %c\n", ToUnicode(ch));
455 if (ToUnicode(ch) == 'A') {
456 printf("break;\n");
457 }
458 #endif
459
460 // TODO(edisonn): is it better to resolve the reference at load time, or now?
461 doType3Char(pdfContext,
462 canvas,
463 pdfContext->fPdfDoc->resolveReference(fChars[ch - fFirstChar ].fObj),
464 fFontBBox,
465 fFonMatrix,
466 pdfContext->fGraphicsState.fCurFontSize);
467
468 // TODO(edisonn): verify/test translate code, not tested yet
469 pdfContext->fGraphicsState.fMatrixTm.preTranslate(
470 SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSize *
471 fChars[ch - fFirstChar].fWidth),
472 SkDoubleToScalar(0.0));
473 return fChars[ch - fFirstChar].fWidth;
474 }
475
476 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {}
477 };
478
479 #endif // SkPdfFont_DEFINED
OLDNEW
« no previous file with comments | « experimental/PdfViewer/SkPdfConfig.h ('k') | experimental/PdfViewer/SkPdfFont.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698