blob: a3f0d3659672fe1be7b23af657bd9f82fb3ce619 [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
10#include "SkUtils.h"
edisonn@google.comb857a0c2013-06-25 20:45:40 +000011#include "SkPdfBasics.h"
12#include "SkPdfUtils.h"
13
edisonn@google.com1be794f2013-06-21 21:43:09 +000014
15class SkPdfType0Font;
16class SkPdfType1Font;
17class SkPdfType3Font;
18class SkPdfTrueTypeFont;
19class SkPdfCIDFont;
20class SkPdfMultiMasterFont;
21class SkPdfFont;
22
23
24struct SkPdfStandardFontEntry {
25 const char* fName;
26 bool fIsBold;
27 bool fIsItalic;
28};
29
30std::map<std::string, SkPdfStandardFontEntry>& getStandardFonts();
31SkTypeface* SkTypefaceFromPdfStandardFont(const char* fontName, bool bold, bool italic);
32SkPdfFont* SkPdfFontFromName(SkPdfObject* obj, const char* fontName);
33
34struct SkUnencodedText {
35 void* text;
36 int len;
37
38public:
39 SkUnencodedText(const SkPdfObject* obj) {
40 text = (void*)obj->podofo()->GetString().GetString();
41 len = obj->podofo()->GetString().GetLength();
42 }
43};
44
45struct SkDecodedText {
46 uint16_t* text;
47 int len;
edisonn@google.comb857a0c2013-06-25 20:45:40 +000048public:
49 unsigned int operator[](int i) const { return text[i]; }
50 int size() const { return len; }
edisonn@google.com1be794f2013-06-21 21:43:09 +000051};
52
53struct SkUnicodeText {
54 uint16_t* text;
55 int len;
56
57public:
58 unsigned int operator[](int i) const { return text[i]; }
59 int size() const { return len; }
60};
61
62class SkPdfEncoding {
63public:
64 virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const = 0;
edisonn@google.comb857a0c2013-06-25 20:45:40 +000065 static SkPdfEncoding* fromName(const char* name);
edisonn@google.com1be794f2013-06-21 21:43:09 +000066};
67
edisonn@google.comb857a0c2013-06-25 20:45:40 +000068std::map<std::string, SkPdfEncoding*>& getStandardEncodings();
69
70class SkPdfToUnicode {
71 // TODO(edisonn): hide public members
72public:
73 unsigned short* fCMapEncoding;
74 unsigned char* fCMapEncodingFlag;
75
76 SkPdfToUnicode(const SkPdfStream* stream);
77};
78
79
edisonn@google.com1be794f2013-06-21 21:43:09 +000080class SkPdfIdentityHEncoding : public SkPdfEncoding {
81public:
82 virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const {
83 // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error?
84
85 uint16_t* text = (uint16_t*)textIn.text;
86 textOut->text = new uint16_t[textIn.len / 2];
87 textOut->len = textIn.len / 2;
88
89 for (int i = 0; i < textOut->len; i++) {
90 textOut->text[i] = ((text[i] << 8) & 0xff00) | ((text[i] >> 8) & 0x00ff);
91 }
92
93 return true;
94 }
95
96 static SkPdfIdentityHEncoding* instance() {
97 static SkPdfIdentityHEncoding* inst = new SkPdfIdentityHEncoding();
98 return inst;
99 }
100};
101
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000102
103class SkPdfCIDToGIDMapIdentityEncoding : public SkPdfEncoding {
104public:
105 virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const {
106 // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error?
107
108 unsigned char* text = (unsigned char*)textIn.text;
109 textOut->text = new uint16_t[textIn.len];
110 textOut->len = textIn.len;
111
112 for (int i = 0; i < textOut->len; i++) {
113 textOut->text[i] = text[i];
114 }
115
116 return true;
117 }
118
119 static SkPdfCIDToGIDMapIdentityEncoding* instance() {
120 static SkPdfCIDToGIDMapIdentityEncoding* inst = new SkPdfCIDToGIDMapIdentityEncoding();
121 return inst;
122 }
123};
124
edisonn@google.com1be794f2013-06-21 21:43:09 +0000125class SkPdfFont {
126public:
127 SkPdfFont* fBaseFont;
128 SkPdfEncoding* fEncoding;
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000129 SkPdfToUnicode* fToUnicode;
130
edisonn@google.com1be794f2013-06-21 21:43:09 +0000131
132public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000133 SkPdfFont() : fBaseFont(NULL), fEncoding(NULL), fToUnicode(NULL) {}
edisonn@google.com1be794f2013-06-21 21:43:09 +0000134
135 const SkPdfEncoding* encoding() const {return fEncoding;}
136
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000137 void drawText(const SkDecodedText& text, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000138 for (int i = 0 ; i < text.size(); i++) {
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000139 drawOneChar(text[i], paint, pdfContext, canvas, matrix);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000140 }
141 }
142
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000143 void ToUnicode(const SkDecodedText& textIn, SkUnicodeText* textOut) const {
144 if (fToUnicode) {
145 textOut->text = new uint16_t[textIn.len];
146 textOut->len = textIn.len;
147 for (int i = 0; i < textIn.len; i++) {
148 textOut->text[i] = fToUnicode->fCMapEncoding[textIn.text[i]];
149 }
150 } else {
151 textOut->text = textIn.text;
152 textOut->len = textIn.len;
153 }
154 };
155
156 inline unsigned int ToUnicode(unsigned int ch) const {
157 if (fToUnicode) {
158 return fToUnicode->fCMapEncoding[ch];
159 } else {
160 return ch;
161 }
edisonn@google.com1be794f2013-06-21 21:43:09 +0000162 };
163
164 static SkPdfFont* fontFromPdfDictionary(SkPdfFontDictionary* dict);
165 static SkPdfFont* Default() {return SkPdfFontFromName(NULL, "TimesNewRoman");}
166
167 static SkPdfType0Font* fontFromType0FontDictionary(SkPdfType0FontDictionary* dict);
168 static SkPdfType1Font* fontFromType1FontDictionary(SkPdfType1FontDictionary* dict);
169 static SkPdfType3Font* fontFromType3FontDictionary(SkPdfType3FontDictionary* dict);
170 static SkPdfTrueTypeFont* fontFromTrueTypeFontDictionary(SkPdfTrueTypeFontDictionary* dict);
171 static SkPdfCIDFont* fontFromCIDFontDictionary(SkPdfCIDFontDictionary* dict);
172 static SkPdfMultiMasterFont* fontFromMultiMasterFontDictionary(SkPdfMultiMasterFontDictionary* dict);
173
174public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000175 virtual void drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) = 0;
edisonn@google.com1be794f2013-06-21 21:43:09 +0000176 virtual void afterChar(SkPaint* paint, SkMatrix* matrix) = 0;
177 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) = 0;
178};
179
180class SkPdfStandardFont : public SkPdfFont {
181 SkTypeface* fTypeface;
182
183public:
184 SkPdfStandardFont(SkTypeface* typeface) : fTypeface(typeface) {}
185
186public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000187 virtual void drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000188 paint->setTypeface(fTypeface);
189 paint->setTextEncoding(SkPaint::kUTF8_TextEncoding);
190
191 unsigned long ch4 = ch;
192 char utf8[10];
193 int len = SkUTF8_FromUnichar(ch4, utf8);
194
195 canvas->drawText(utf8, len, SkDoubleToScalar(0), SkDoubleToScalar(0), *paint);
196
197 SkScalar textWidth = paint->measureText(utf8, len);
198 matrix->preTranslate(textWidth, SkDoubleToScalar(0.0));
199 }
200
201 virtual void afterChar(SkPaint* paint, SkMatrix* matrix) {}
202 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {}
203};
204
edisonn@google.com1be794f2013-06-21 21:43:09 +0000205class SkPdfType0Font : public SkPdfFont {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000206public:
207 SkPdfType0Font(SkPdfType0FontDictionary* dict);
208
209public:
edisonn@google.com1be794f2013-06-21 21:43:09 +0000210
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000211 virtual void drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) {
212 fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas, matrix);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000213 }
214
215 virtual void afterChar(SkPaint* paint, SkMatrix* matrix) {
216
217 }
218
219 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000220 }
221};
222
223class SkPdfTrueTypeFont : public SkPdfFont {
224public:
225 SkPdfTrueTypeFont(SkPdfTrueTypeFontDictionary* dict) {
226 fBaseFont = SkPdfFontFromName(dict, dict->BaseFont().c_str());
227 }
228
229public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000230 virtual void drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000231
232 }
233
234 virtual void afterChar(SkPaint* paint, SkMatrix* matrix) {
235
236 }
237
238 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
239
240 }
241};
242
243
244class SkPdfType1Font : public SkPdfFont {
245public:
246 SkPdfType1Font(SkPdfType1FontDictionary* dict) {
247 fBaseFont = SkPdfFontFromName(dict, dict->BaseFont().c_str());
248 }
249
250
251public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000252 virtual void drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000253
254 }
255
256 virtual void afterChar(SkPaint* paint, SkMatrix* matrix) {
257
258 }
259
260 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
261
262 }
263 };
264
265
266class SkPdfCIDFont : public SkPdfFont {
267public:
268 SkPdfCIDFont(SkPdfCIDFontDictionary* dict) {
269 fBaseFont = SkPdfFontFromName(dict, dict->BaseFont().c_str());
270 }
271
272public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000273 virtual void drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000274
275 }
276
277 virtual void afterChar(SkPaint* paint, SkMatrix* matrix) {
278
279 }
280
281 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
282
283 }
284};
285
286class SkPdfMultiMasterFont : public SkPdfFont {
287public:
288 SkPdfMultiMasterFont(SkPdfMultiMasterFontDictionary* dict) {
289 fBaseFont = SkPdfFontFromName(dict, dict->BaseFont().c_str());
290 }
291
292public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000293 virtual void drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000294
295 }
296
297 virtual void afterChar(SkPaint* paint, SkMatrix* matrix) {
298
299 }
300
301 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
302
303 }
304};
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000305/*
306class CIDToGIDMap {
307 virtual unsigned int map(unsigned int cid) = 0;
308 static CIDToGIDMap* fromName(const char* name);
309};
310
311class CIDToGIDMap_Identity {
312 virtual unsigned int map(unsigned int cid) { return cid; }
313
314 static CIDToGIDMap_Identity* instance() {
315 static CIDToGIDMap_Identity* inst = new CIDToGIDMap_Identity();
316 return inst;
317 }
318};
319
320CIDToGIDMap* CIDToGIDMap::fromName(const char* name) {
321 // The only one supported right now is Identity
322 if (strcmp(name, "Identity") == 0) {
323 return CIDToGIDMap_Identity::instance();
324 }
325
326#ifdef PDF_TRACE
327 // TODO(edisonn): warning/report
328 printf("Unknown CIDToGIDMap: %s\n", name);
329#endif
330 return NULL;
331}
332CIDToGIDMap* fCidToGid;
333*/
edisonn@google.com1be794f2013-06-21 21:43:09 +0000334
335class SkPdfType3Font : public SkPdfFont {
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000336 struct Type3FontChar {
337 SkPdfObject* fObj;
338 double fWidth;
339 };
340
341 SkPdfDictionary* fCharProcs;
342 SkPdfEncodingDictionary* fEncodingDict;
343 unsigned int fFirstChar;
344 unsigned int fLastChar;
345
346 SkRect fFontBBox;
347 SkMatrix fFonMatrix;
348
349 Type3FontChar* fChars;
350
edisonn@google.com1be794f2013-06-21 21:43:09 +0000351public:
352 SkPdfType3Font(SkPdfType3FontDictionary* dict) {
353 fBaseFont = SkPdfFontFromName(dict, dict->BaseFont().c_str());
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000354
355 if (dict->has_Encoding()) {
356 if (dict->isEncodingAName()) {
357 fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName().c_str());
358 } else if (dict->isEncodingAEncodingdictionary()) {
359 // technically, there is no encoding.
360 fEncoding = SkPdfCIDToGIDMapIdentityEncoding::instance();
361 fEncodingDict = dict->getEncodingAsEncodingdictionary();
362 }
363 }
364
365 // null?
366 fCharProcs = dict->CharProcs();
367
368 fToUnicode = NULL;
369 if (dict->has_ToUnicode()) {
370 fToUnicode = new SkPdfToUnicode(dict->ToUnicode());
371 }
372
373 fFirstChar = dict->FirstChar();
374 fLastChar = dict->LastChar();
375 fFonMatrix = dict->has_FontMatrix() ? *dict->FontMatrix() : SkMatrix::I();
376
377 if (dict->FontBBox()) {
378 fFontBBox = *dict->FontBBox();
379 }
380
381 fChars = new Type3FontChar[fLastChar - fFirstChar + 1];
382
383 memset(fChars, 0, sizeof(fChars[0]) * (fLastChar - fFirstChar + 1));
384
385
386 SkPdfArray* widths = dict->Widths();
387 for (int i = 0 ; i < widths->size(); i++) {
388 if ((fFirstChar + i) < fFirstChar || (fFirstChar + i) > fLastChar) {
389 printf("break; error 1\n");
390 }
391 fChars[i].fWidth = (*widths)[i]->asNumber()->value();
392 }
393
394 SkPdfArray* diffs = fEncodingDict->Differences();
395 int j = fFirstChar;
396 for (int i = 0 ; i < diffs->size(); i++) {
397 if ((*diffs)[i]->asInteger()) {
398 j = (*diffs)[i]->asInteger()->value();
399 } else if ((*diffs)[i]->asName()) {
400 if (j < fFirstChar || j > fLastChar) {
401 printf("break; error 2\n");
402 }
403 fChars[j - fFirstChar].fObj = fCharProcs->get((*diffs)[i]->asName()->value().c_str());
404 j++;
405 } else {
406 // err
407 }
408 }
edisonn@google.com1be794f2013-06-21 21:43:09 +0000409 }
410
411public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000412 virtual void drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas, SkMatrix* matrix) {
413 if (ch < fFirstChar || ch > fLastChar || !fChars[ch - fFirstChar].fObj) {
414 fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas, matrix);
415 return;
416 }
edisonn@google.com1be794f2013-06-21 21:43:09 +0000417
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000418#ifdef PDF_TRACE
419 printf("Type 3 char to unicode: %c\n", ToUnicode(ch));
420 if (ToUnicode(ch) == 'A') {
421 printf("break;\n");
422 }
423#endif
424
425 doType3Char(pdfContext, canvas, fChars[ch - fFirstChar].fObj, fFontBBox, fFonMatrix, pdfContext->fGraphicsState.fCurFontSize);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000426 }
427
428 virtual void afterChar(SkPaint* paint, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000429 }
430
431 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
432
433 }
434};
435
436#endif // __DEFINED__SkPdfFont