blob: 85b9fc41fbaadf7b1fab7a8d63eea329e099fc26 [file] [log] [blame]
edisonn@google.com1be794f2013-06-21 21:43:09 +00001#ifndef __DEFINED__SkPdfFont
2#define __DEFINED__SkPdfFont
3
4#include "SkPdfHeaders_autogen.h"
5#include "SkPdfPodofoMapper_autogen.h"
6
7#include <map>
8#include <string>
9
edisonn@google.com131d4ee2013-06-26 17:48:12 +000010#include "SkTypeface.h"
edisonn@google.com1be794f2013-06-21 21:43:09 +000011#include "SkUtils.h"
edisonn@google.comb857a0c2013-06-25 20:45:40 +000012#include "SkPdfBasics.h"
13#include "SkPdfUtils.h"
14
edisonn@google.com1be794f2013-06-21 21:43:09 +000015
16class SkPdfType0Font;
17class SkPdfType1Font;
18class SkPdfType3Font;
19class SkPdfTrueTypeFont;
20class SkPdfCIDFont;
21class SkPdfMultiMasterFont;
22class SkPdfFont;
23
24
25struct SkPdfStandardFontEntry {
26 const char* fName;
27 bool fIsBold;
28 bool fIsItalic;
29};
30
31std::map<std::string, SkPdfStandardFontEntry>& getStandardFonts();
32SkTypeface* SkTypefaceFromPdfStandardFont(const char* fontName, bool bold, bool italic);
33SkPdfFont* SkPdfFontFromName(SkPdfObject* obj, const char* fontName);
34
35struct SkUnencodedText {
36 void* text;
37 int len;
38
39public:
40 SkUnencodedText(const SkPdfObject* obj) {
41 text = (void*)obj->podofo()->GetString().GetString();
42 len = obj->podofo()->GetString().GetLength();
43 }
44};
45
46struct SkDecodedText {
47 uint16_t* text;
48 int len;
edisonn@google.comb857a0c2013-06-25 20:45:40 +000049public:
50 unsigned int operator[](int i) const { return text[i]; }
51 int size() const { return len; }
edisonn@google.com1be794f2013-06-21 21:43:09 +000052};
53
54struct SkUnicodeText {
55 uint16_t* text;
56 int len;
57
58public:
59 unsigned int operator[](int i) const { return text[i]; }
60 int size() const { return len; }
61};
62
63class SkPdfEncoding {
64public:
65 virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const = 0;
edisonn@google.comb857a0c2013-06-25 20:45:40 +000066 static SkPdfEncoding* fromName(const char* name);
edisonn@google.com1be794f2013-06-21 21:43:09 +000067};
68
edisonn@google.comb857a0c2013-06-25 20:45:40 +000069std::map<std::string, SkPdfEncoding*>& getStandardEncodings();
70
71class SkPdfToUnicode {
72 // TODO(edisonn): hide public members
73public:
74 unsigned short* fCMapEncoding;
75 unsigned char* fCMapEncodingFlag;
76
77 SkPdfToUnicode(const SkPdfStream* stream);
78};
79
80
edisonn@google.com1be794f2013-06-21 21:43:09 +000081class SkPdfIdentityHEncoding : public SkPdfEncoding {
82public:
83 virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const {
84 // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error?
85
86 uint16_t* text = (uint16_t*)textIn.text;
87 textOut->text = new uint16_t[textIn.len / 2];
88 textOut->len = textIn.len / 2;
89
90 for (int i = 0; i < textOut->len; i++) {
91 textOut->text[i] = ((text[i] << 8) & 0xff00) | ((text[i] >> 8) & 0x00ff);
92 }
93
94 return true;
95 }
96
97 static SkPdfIdentityHEncoding* instance() {
98 static SkPdfIdentityHEncoding* inst = new SkPdfIdentityHEncoding();
99 return inst;
100 }
101};
102
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000103
104class SkPdfCIDToGIDMapIdentityEncoding : public SkPdfEncoding {
105public:
106 virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const {
107 // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error?
108
109 unsigned char* text = (unsigned char*)textIn.text;
110 textOut->text = new uint16_t[textIn.len];
111 textOut->len = textIn.len;
112
113 for (int i = 0; i < textOut->len; i++) {
114 textOut->text[i] = text[i];
115 }
116
117 return true;
118 }
119
120 static SkPdfCIDToGIDMapIdentityEncoding* instance() {
121 static SkPdfCIDToGIDMapIdentityEncoding* inst = new SkPdfCIDToGIDMapIdentityEncoding();
122 return inst;
123 }
124};
125
edisonn@google.com1be794f2013-06-21 21:43:09 +0000126class SkPdfFont {
127public:
128 SkPdfFont* fBaseFont;
129 SkPdfEncoding* fEncoding;
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000130 SkPdfToUnicode* fToUnicode;
131
edisonn@google.com1be794f2013-06-21 21:43:09 +0000132
133public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000134 SkPdfFont() : fBaseFont(NULL), fEncoding(NULL), fToUnicode(NULL) {}
edisonn@google.com1be794f2013-06-21 21:43:09 +0000135
136 const SkPdfEncoding* encoding() const {return fEncoding;}
137
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000138 void drawText(const SkDecodedText& text, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000139 for (int i = 0 ; i < text.size(); i++) {
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000140 drawOneChar(text[i], paint, pdfContext, canvas, matrix);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000141 }
142 }
143
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000144 void ToUnicode(const SkDecodedText& textIn, SkUnicodeText* textOut) const {
145 if (fToUnicode) {
146 textOut->text = new uint16_t[textIn.len];
147 textOut->len = textIn.len;
148 for (int i = 0; i < textIn.len; i++) {
149 textOut->text[i] = fToUnicode->fCMapEncoding[textIn.text[i]];
150 }
151 } else {
152 textOut->text = textIn.text;
153 textOut->len = textIn.len;
154 }
155 };
156
157 inline unsigned int ToUnicode(unsigned int ch) const {
158 if (fToUnicode) {
159 return fToUnicode->fCMapEncoding[ch];
160 } else {
161 return ch;
162 }
edisonn@google.com1be794f2013-06-21 21:43:09 +0000163 };
164
165 static SkPdfFont* fontFromPdfDictionary(SkPdfFontDictionary* dict);
166 static SkPdfFont* Default() {return SkPdfFontFromName(NULL, "TimesNewRoman");}
167
168 static SkPdfType0Font* fontFromType0FontDictionary(SkPdfType0FontDictionary* dict);
169 static SkPdfType1Font* fontFromType1FontDictionary(SkPdfType1FontDictionary* dict);
170 static SkPdfType3Font* fontFromType3FontDictionary(SkPdfType3FontDictionary* dict);
171 static SkPdfTrueTypeFont* fontFromTrueTypeFontDictionary(SkPdfTrueTypeFontDictionary* dict);
172 static SkPdfCIDFont* fontFromCIDFontDictionary(SkPdfCIDFontDictionary* dict);
173 static SkPdfMultiMasterFont* fontFromMultiMasterFontDictionary(SkPdfMultiMasterFontDictionary* dict);
174
175public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000176 virtual void drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) = 0;
edisonn@google.com1be794f2013-06-21 21:43:09 +0000177 virtual void afterChar(SkPaint* paint, SkMatrix* matrix) = 0;
178 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) = 0;
179};
180
181class SkPdfStandardFont : public SkPdfFont {
182 SkTypeface* fTypeface;
183
184public:
185 SkPdfStandardFont(SkTypeface* typeface) : fTypeface(typeface) {}
186
187public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000188 virtual void drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000189 paint->setTypeface(fTypeface);
190 paint->setTextEncoding(SkPaint::kUTF8_TextEncoding);
191
192 unsigned long ch4 = ch;
193 char utf8[10];
194 int len = SkUTF8_FromUnichar(ch4, utf8);
195
196 canvas->drawText(utf8, len, SkDoubleToScalar(0), SkDoubleToScalar(0), *paint);
197
198 SkScalar textWidth = paint->measureText(utf8, len);
199 matrix->preTranslate(textWidth, SkDoubleToScalar(0.0));
200 }
201
202 virtual void afterChar(SkPaint* paint, SkMatrix* matrix) {}
203 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {}
204};
205
edisonn@google.com1be794f2013-06-21 21:43:09 +0000206class SkPdfType0Font : public SkPdfFont {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000207public:
208 SkPdfType0Font(SkPdfType0FontDictionary* dict);
209
210public:
edisonn@google.com1be794f2013-06-21 21:43:09 +0000211
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000212 virtual void drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) {
213 fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas, matrix);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000214 }
215
216 virtual void afterChar(SkPaint* paint, SkMatrix* matrix) {
217
218 }
219
220 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000221 }
222};
223
224class SkPdfTrueTypeFont : public SkPdfFont {
225public:
226 SkPdfTrueTypeFont(SkPdfTrueTypeFontDictionary* dict) {
227 fBaseFont = SkPdfFontFromName(dict, dict->BaseFont().c_str());
228 }
229
230public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000231 virtual void drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000232
233 }
234
235 virtual void afterChar(SkPaint* paint, SkMatrix* matrix) {
236
237 }
238
239 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
240
241 }
242};
243
244
245class SkPdfType1Font : public SkPdfFont {
246public:
247 SkPdfType1Font(SkPdfType1FontDictionary* dict) {
248 fBaseFont = SkPdfFontFromName(dict, dict->BaseFont().c_str());
249 }
250
251
252public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000253 virtual void drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000254
255 }
256
257 virtual void afterChar(SkPaint* paint, SkMatrix* matrix) {
258
259 }
260
261 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
262
263 }
264 };
265
266
267class SkPdfCIDFont : public SkPdfFont {
268public:
269 SkPdfCIDFont(SkPdfCIDFontDictionary* dict) {
270 fBaseFont = SkPdfFontFromName(dict, dict->BaseFont().c_str());
271 }
272
273public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000274 virtual void drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000275
276 }
277
278 virtual void afterChar(SkPaint* paint, SkMatrix* matrix) {
279
280 }
281
282 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
283
284 }
285};
286
287class SkPdfMultiMasterFont : public SkPdfFont {
288public:
289 SkPdfMultiMasterFont(SkPdfMultiMasterFontDictionary* dict) {
290 fBaseFont = SkPdfFontFromName(dict, dict->BaseFont().c_str());
291 }
292
293public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000294 virtual void drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000295
296 }
297
298 virtual void afterChar(SkPaint* paint, SkMatrix* matrix) {
299
300 }
301
302 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
303
304 }
305};
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000306/*
307class CIDToGIDMap {
308 virtual unsigned int map(unsigned int cid) = 0;
309 static CIDToGIDMap* fromName(const char* name);
310};
311
312class CIDToGIDMap_Identity {
313 virtual unsigned int map(unsigned int cid) { return cid; }
314
315 static CIDToGIDMap_Identity* instance() {
316 static CIDToGIDMap_Identity* inst = new CIDToGIDMap_Identity();
317 return inst;
318 }
319};
320
321CIDToGIDMap* CIDToGIDMap::fromName(const char* name) {
322 // The only one supported right now is Identity
323 if (strcmp(name, "Identity") == 0) {
324 return CIDToGIDMap_Identity::instance();
325 }
326
327#ifdef PDF_TRACE
328 // TODO(edisonn): warning/report
329 printf("Unknown CIDToGIDMap: %s\n", name);
330#endif
331 return NULL;
332}
333CIDToGIDMap* fCidToGid;
334*/
edisonn@google.com1be794f2013-06-21 21:43:09 +0000335
336class SkPdfType3Font : public SkPdfFont {
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000337 struct Type3FontChar {
338 SkPdfObject* fObj;
339 double fWidth;
340 };
341
342 SkPdfDictionary* fCharProcs;
343 SkPdfEncodingDictionary* fEncodingDict;
344 unsigned int fFirstChar;
345 unsigned int fLastChar;
346
347 SkRect fFontBBox;
348 SkMatrix fFonMatrix;
349
350 Type3FontChar* fChars;
351
edisonn@google.com1be794f2013-06-21 21:43:09 +0000352public:
353 SkPdfType3Font(SkPdfType3FontDictionary* dict) {
354 fBaseFont = SkPdfFontFromName(dict, dict->BaseFont().c_str());
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000355
356 if (dict->has_Encoding()) {
357 if (dict->isEncodingAName()) {
358 fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName().c_str());
359 } else if (dict->isEncodingAEncodingdictionary()) {
360 // technically, there is no encoding.
361 fEncoding = SkPdfCIDToGIDMapIdentityEncoding::instance();
362 fEncodingDict = dict->getEncodingAsEncodingdictionary();
363 }
364 }
365
366 // null?
367 fCharProcs = dict->CharProcs();
368
369 fToUnicode = NULL;
370 if (dict->has_ToUnicode()) {
371 fToUnicode = new SkPdfToUnicode(dict->ToUnicode());
372 }
373
374 fFirstChar = dict->FirstChar();
375 fLastChar = dict->LastChar();
376 fFonMatrix = dict->has_FontMatrix() ? *dict->FontMatrix() : SkMatrix::I();
377
378 if (dict->FontBBox()) {
379 fFontBBox = *dict->FontBBox();
380 }
381
382 fChars = new Type3FontChar[fLastChar - fFirstChar + 1];
383
384 memset(fChars, 0, sizeof(fChars[0]) * (fLastChar - fFirstChar + 1));
385
386
387 SkPdfArray* widths = dict->Widths();
388 for (int i = 0 ; i < widths->size(); i++) {
389 if ((fFirstChar + i) < fFirstChar || (fFirstChar + i) > fLastChar) {
390 printf("break; error 1\n");
391 }
392 fChars[i].fWidth = (*widths)[i]->asNumber()->value();
393 }
394
395 SkPdfArray* diffs = fEncodingDict->Differences();
396 int j = fFirstChar;
397 for (int i = 0 ; i < diffs->size(); i++) {
398 if ((*diffs)[i]->asInteger()) {
399 j = (*diffs)[i]->asInteger()->value();
400 } else if ((*diffs)[i]->asName()) {
401 if (j < fFirstChar || j > fLastChar) {
402 printf("break; error 2\n");
403 }
404 fChars[j - fFirstChar].fObj = fCharProcs->get((*diffs)[i]->asName()->value().c_str());
405 j++;
406 } else {
407 // err
408 }
409 }
edisonn@google.com1be794f2013-06-21 21:43:09 +0000410 }
411
412public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000413 virtual void drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) {
414 if (ch < fFirstChar || ch > fLastChar || !fChars[ch - fFirstChar].fObj) {
415 fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas, matrix);
416 return;
417 }
edisonn@google.com1be794f2013-06-21 21:43:09 +0000418
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000419#ifdef PDF_TRACE
420 printf("Type 3 char to unicode: %c\n", ToUnicode(ch));
421 if (ToUnicode(ch) == 'A') {
422 printf("break;\n");
423 }
424#endif
425
426 doType3Char(pdfContext, canvas, fChars[ch - fFirstChar].fObj, fFontBBox, fFonMatrix, pdfContext->fGraphicsState.fCurFontSize);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000427 }
428
429 virtual void afterChar(SkPaint* paint, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000430 }
431
432 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
433
434 }
435};
436
437#endif // __DEFINED__SkPdfFont