blob: 3c850a63a421c05aa9782e66e84dca01b3c6e9b6 [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"
edisonn@google.com3aac1f92013-07-02 22:42:53 +00005#include "SkPdfMapper_autogen.h"
edisonn@google.com1be794f2013-06-21 21:43:09 +00006
edisonn@google.com131d4ee2013-06-26 17:48:12 +00007#include "SkTypeface.h"
edisonn@google.com1be794f2013-06-21 21:43:09 +00008#include "SkUtils.h"
edisonn@google.com3aa35552013-08-14 18:26:20 +00009#include "SkPdfGraphicsState.h"
edisonn@google.comb857a0c2013-06-25 20:45:40 +000010#include "SkPdfUtils.h"
edisonn@google.com063d7072013-08-16 15:05:08 +000011#include "SkTDict.h"
edisonn@google.com1be794f2013-06-21 21:43:09 +000012
13class SkPdfType0Font;
14class SkPdfType1Font;
15class SkPdfType3Font;
16class SkPdfTrueTypeFont;
edisonn@google.com1be794f2013-06-21 21:43:09 +000017class SkPdfMultiMasterFont;
18class SkPdfFont;
19
edisonn@google.com1be794f2013-06-21 21:43:09 +000020struct SkPdfStandardFontEntry {
edisonn@google.com596d2e22013-07-10 17:44:55 +000021 // We don't own this pointer!
edisonn@google.com1be794f2013-06-21 21:43:09 +000022 const char* fName;
23 bool fIsBold;
24 bool fIsItalic;
edisonn@google.com596d2e22013-07-10 17:44:55 +000025 SkPdfStandardFontEntry()
26 : fName(NULL),
27 fIsBold(false),
28 fIsItalic(false) {}
29
30 SkPdfStandardFontEntry(const char* name, bool bold, bool italic)
31 : fName(name),
32 fIsBold(bold),
33 fIsItalic(italic) {}
edisonn@google.com1be794f2013-06-21 21:43:09 +000034};
35
edisonn@google.com063d7072013-08-16 15:05:08 +000036SkTDict<SkPdfStandardFontEntry>& getStandardFonts();
edisonn@google.com1be794f2013-06-21 21:43:09 +000037SkTypeface* SkTypefaceFromPdfStandardFont(const char* fontName, bool bold, bool italic);
edisonn@google.com3aa35552013-08-14 18:26:20 +000038SkPdfFont* fontFromName(SkPdfNativeDoc* doc, SkPdfNativeObject* obj, const char* fontName);
edisonn@google.com1be794f2013-06-21 21:43:09 +000039
40struct SkUnencodedText {
41 void* text;
42 int len;
43
44public:
edisonn@google.com3aac1f92013-07-02 22:42:53 +000045 SkUnencodedText(const SkPdfString* obj) {
46 text = (void*)obj->c_str();
edisonn@google.come878e722013-07-29 19:10:58 +000047 len = obj->lenstr();
edisonn@google.com1be794f2013-06-21 21:43:09 +000048 }
49};
50
51struct SkDecodedText {
52 uint16_t* text;
53 int len;
edisonn@google.comb857a0c2013-06-25 20:45:40 +000054public:
55 unsigned int operator[](int i) const { return text[i]; }
56 int size() const { return len; }
edisonn@google.com1be794f2013-06-21 21:43:09 +000057};
58
59struct SkUnicodeText {
60 uint16_t* text;
61 int len;
62
63public:
64 unsigned int operator[](int i) const { return text[i]; }
65 int size() const { return len; }
66};
67
68class SkPdfEncoding {
69public:
70 virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const = 0;
edisonn@google.comb857a0c2013-06-25 20:45:40 +000071 static SkPdfEncoding* fromName(const char* name);
edisonn@google.com1be794f2013-06-21 21:43:09 +000072};
73
edisonn@google.com063d7072013-08-16 15:05:08 +000074SkTDict<SkPdfEncoding*>& getStandardEncodings();
edisonn@google.comb857a0c2013-06-25 20:45:40 +000075
76class SkPdfToUnicode {
edisonn@google.com3aa35552013-08-14 18:26:20 +000077 SkPdfNativeDoc* fParsed;
edisonn@google.comb857a0c2013-06-25 20:45:40 +000078 // TODO(edisonn): hide public members
79public:
80 unsigned short* fCMapEncoding;
81 unsigned char* fCMapEncodingFlag;
82
edisonn@google.com3aa35552013-08-14 18:26:20 +000083 SkPdfToUnicode(SkPdfNativeDoc* parsed, SkPdfStream* stream);
edisonn@google.comb857a0c2013-06-25 20:45:40 +000084};
85
86
edisonn@google.com1be794f2013-06-21 21:43:09 +000087class SkPdfIdentityHEncoding : public SkPdfEncoding {
88public:
89 virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const {
90 // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error?
91
92 uint16_t* text = (uint16_t*)textIn.text;
93 textOut->text = new uint16_t[textIn.len / 2];
94 textOut->len = textIn.len / 2;
95
96 for (int i = 0; i < textOut->len; i++) {
97 textOut->text[i] = ((text[i] << 8) & 0xff00) | ((text[i] >> 8) & 0x00ff);
98 }
99
100 return true;
101 }
102
103 static SkPdfIdentityHEncoding* instance() {
104 static SkPdfIdentityHEncoding* inst = new SkPdfIdentityHEncoding();
105 return inst;
106 }
107};
108
edisonn@google.com6e49c342013-06-27 20:03:43 +0000109// TODO(edisonn): using this one when no encoding is specified
110class SkPdfDefaultEncoding : public SkPdfEncoding {
111public:
112 virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const {
113 // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error?
114
115 unsigned char* text = (unsigned char*)textIn.text;
116 textOut->text = new uint16_t[textIn.len];
117 textOut->len = textIn.len;
118
119 for (int i = 0; i < textOut->len; i++) {
120 textOut->text[i] = text[i];
121 }
122
123 return true;
124 }
125
126 static SkPdfDefaultEncoding* instance() {
127 static SkPdfDefaultEncoding* inst = new SkPdfDefaultEncoding();
128 return inst;
129 }
130};
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000131
132class SkPdfCIDToGIDMapIdentityEncoding : public SkPdfEncoding {
133public:
134 virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const {
135 // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error?
136
edisonn@google.com571c70b2013-07-10 17:09:50 +0000137 uint16_t* text = (uint16_t*)textIn.text;
138 textOut->text = new uint16_t[textIn.len / 2];
139 textOut->len = textIn.len / 2;
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000140
141 for (int i = 0; i < textOut->len; i++) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000142 textOut->text[i] = ((text[i] << 8) & 0xff00) | ((text[i] >> 8) & 0x00ff);
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000143 }
144
145 return true;
146 }
147
148 static SkPdfCIDToGIDMapIdentityEncoding* instance() {
149 static SkPdfCIDToGIDMapIdentityEncoding* inst = new SkPdfCIDToGIDMapIdentityEncoding();
150 return inst;
151 }
152};
153
edisonn@google.com1be794f2013-06-21 21:43:09 +0000154class SkPdfFont {
155public:
156 SkPdfFont* fBaseFont;
157 SkPdfEncoding* fEncoding;
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000158 SkPdfToUnicode* fToUnicode;
159
edisonn@google.com1be794f2013-06-21 21:43:09 +0000160
161public:
edisonn@google.com6e49c342013-06-27 20:03:43 +0000162 SkPdfFont() : fBaseFont(NULL), fEncoding(SkPdfDefaultEncoding::instance()), fToUnicode(NULL) {}
edisonn@google.com1be794f2013-06-21 21:43:09 +0000163
edisonn@google.com7ee12ca2013-08-05 18:18:06 +0000164 virtual ~SkPdfFont() {
165 // TODO(edisonn): NYI (will leak for now)
166 }
167
edisonn@google.com1be794f2013-06-21 21:43:09 +0000168 const SkPdfEncoding* encoding() const {return fEncoding;}
169
edisonn@google.com3aa35552013-08-14 18:26:20 +0000170 void drawText(const SkDecodedText& text, SkPaint* paint, SkPdfContext* pdfContext, SkCanvas* canvas) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000171 for (int i = 0 ; i < text.size(); i++) {
edisonn@google.come57c62d2013-08-07 18:04:15 +0000172 canvas->setMatrix(pdfContext->fGraphicsState.fMatrixTm);
173#ifdef PDF_TRACE
174 SkPoint point = SkPoint::Make(SkDoubleToScalar(0), SkDoubleToScalar(0));
175 pdfContext->fGraphicsState.fMatrixTm.mapPoints(&point, 1);
176 printf("DrawText at (%f, %f)\n", SkScalarToDouble(point.x()), SkScalarToDouble(point.y()));
177#endif // PDF_TRACE
edisonn@google.com3aa35552013-08-14 18:26:20 +0000178
179#ifdef PDF_TRACE_DRAWTEXT
180 SkPaint col;
181 col.setColor(SK_ColorMAGENTA);
182 SkRect rect = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0), SkDoubleToScalar(10.0), SkDoubleToScalar(10.0));
183 canvas->save();
184 canvas->setMatrix(pdfContext->fGraphicsState.fMatrixTm);
185 canvas->drawRect(rect, col);
186 canvas->restore();
187#endif
edisonn@google.com6e49c342013-06-27 20:03:43 +0000188 double width = drawOneChar(text[i], paint, pdfContext, canvas);
189 pdfContext->fGraphicsState.fMatrixTm.preTranslate(SkDoubleToScalar(width), SkDoubleToScalar(0.0));
edisonn@google.com1be794f2013-06-21 21:43:09 +0000190 }
191 }
192
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000193 void ToUnicode(const SkDecodedText& textIn, SkUnicodeText* textOut) const {
194 if (fToUnicode) {
195 textOut->text = new uint16_t[textIn.len];
196 textOut->len = textIn.len;
197 for (int i = 0; i < textIn.len; i++) {
198 textOut->text[i] = fToUnicode->fCMapEncoding[textIn.text[i]];
199 }
200 } else {
201 textOut->text = textIn.text;
202 textOut->len = textIn.len;
203 }
204 };
205
206 inline unsigned int ToUnicode(unsigned int ch) const {
207 if (fToUnicode) {
208 return fToUnicode->fCMapEncoding[ch];
209 } else {
210 return ch;
211 }
edisonn@google.com1be794f2013-06-21 21:43:09 +0000212 };
213
edisonn@google.com3aa35552013-08-14 18:26:20 +0000214 static SkPdfFont* fontFromPdfDictionary(SkPdfNativeDoc* doc, SkPdfFontDictionary* dict);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000215 static SkPdfFont* Default() {return fontFromName(NULL, NULL, "TimesNewRoman");}
edisonn@google.com1be794f2013-06-21 21:43:09 +0000216
edisonn@google.com3aa35552013-08-14 18:26:20 +0000217 static SkPdfType0Font* fontFromType0FontDictionary(SkPdfNativeDoc* doc, SkPdfType0FontDictionary* dict);
218 static SkPdfType1Font* fontFromType1FontDictionary(SkPdfNativeDoc* doc, SkPdfType1FontDictionary* dict);
219 static SkPdfType3Font* fontFromType3FontDictionary(SkPdfNativeDoc* doc, SkPdfType3FontDictionary* dict);
220 static SkPdfTrueTypeFont* fontFromTrueTypeFontDictionary(SkPdfNativeDoc* doc, SkPdfTrueTypeFontDictionary* dict);
221 static SkPdfMultiMasterFont* fontFromMultiMasterFontDictionary(SkPdfNativeDoc* doc, SkPdfMultiMasterFontDictionary* dict);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000222
edisonn@google.com3aa35552013-08-14 18:26:20 +0000223 static SkPdfFont* fontFromFontDescriptor(SkPdfNativeDoc* doc, SkPdfFontDescriptorDictionary* fd, bool loadFromName = true);
edisonn@google.com6e49c342013-06-27 20:03:43 +0000224
edisonn@google.com1be794f2013-06-21 21:43:09 +0000225public:
edisonn@google.com3aa35552013-08-14 18:26:20 +0000226 virtual double drawOneChar(unsigned int ch, SkPaint* paint, SkPdfContext* pdfContext, SkCanvas* canvas) = 0;
edisonn@google.com1be794f2013-06-21 21:43:09 +0000227 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) = 0;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000228
229private:
edisonn@google.com3aa35552013-08-14 18:26:20 +0000230 static SkPdfFont* fontFromPdfDictionaryOnce(SkPdfNativeDoc* doc, SkPdfFontDictionary* dict);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000231};
232
233class SkPdfStandardFont : public SkPdfFont {
234 SkTypeface* fTypeface;
235
236public:
237 SkPdfStandardFont(SkTypeface* typeface) : fTypeface(typeface) {}
238
239public:
edisonn@google.com3aa35552013-08-14 18:26:20 +0000240 virtual double drawOneChar(unsigned int ch, SkPaint* paint, SkPdfContext* pdfContext, SkCanvas* canvas) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000241 paint->setTypeface(fTypeface);
242 paint->setTextEncoding(SkPaint::kUTF8_TextEncoding);
243
244 unsigned long ch4 = ch;
245 char utf8[10];
246 int len = SkUTF8_FromUnichar(ch4, utf8);
247
248 canvas->drawText(utf8, len, SkDoubleToScalar(0), SkDoubleToScalar(0), *paint);
249
250 SkScalar textWidth = paint->measureText(utf8, len);
edisonn@google.com6e49c342013-06-27 20:03:43 +0000251 return SkScalarToDouble(textWidth);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000252 }
253
edisonn@google.com1be794f2013-06-21 21:43:09 +0000254 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {}
255};
256
edisonn@google.com1be794f2013-06-21 21:43:09 +0000257class SkPdfType0Font : public SkPdfFont {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000258public:
edisonn@google.com3aa35552013-08-14 18:26:20 +0000259 SkPdfType0Font(SkPdfNativeDoc* doc, SkPdfType0FontDictionary* dict);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000260
261public:
edisonn@google.com1be794f2013-06-21 21:43:09 +0000262
edisonn@google.com3aa35552013-08-14 18:26:20 +0000263 virtual double drawOneChar(unsigned int ch, SkPaint* paint, SkPdfContext* pdfContext, SkCanvas* canvas) {
edisonn@google.com6e49c342013-06-27 20:03:43 +0000264 return fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000265 }
266
267 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000268 }
269};
270
edisonn@google.com1be794f2013-06-21 21:43:09 +0000271class SkPdfType1Font : public SkPdfFont {
272public:
edisonn@google.com3aa35552013-08-14 18:26:20 +0000273 SkPdfType1Font(SkPdfNativeDoc* doc, SkPdfType1FontDictionary* dict) {
edisonn@google.com6e49c342013-06-27 20:03:43 +0000274 if (dict->has_FontDescriptor()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000275 fBaseFont = SkPdfFont::fontFromFontDescriptor(doc, dict->FontDescriptor(doc));
edisonn@google.com6e49c342013-06-27 20:03:43 +0000276 } else {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000277 fBaseFont = fontFromName(doc, dict, dict->BaseFont(doc).c_str());
edisonn@google.com6e49c342013-06-27 20:03:43 +0000278 }
edisonn@google.com3aa35552013-08-14 18:26:20 +0000279
280 if (dict->isEncodingAName(doc)) {
281 fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName(doc).c_str());
282 } else if (dict->isEncodingADictionary(doc)) {
283 //SkPdfDictionary* dictEnc = dict->getEncodingAsDictionary(doc);
284 }
285 dict->FontDescriptor(doc);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000286 }
287
edisonn@google.com1be794f2013-06-21 21:43:09 +0000288public:
edisonn@google.com3aa35552013-08-14 18:26:20 +0000289 virtual double drawOneChar(unsigned int ch, SkPaint* paint, SkPdfContext* pdfContext, SkCanvas* canvas) {
edisonn@google.com6e49c342013-06-27 20:03:43 +0000290 return fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000291 }
292
293 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
294
295 }
edisonn@google.com6e49c342013-06-27 20:03:43 +0000296};
edisonn@google.com1be794f2013-06-21 21:43:09 +0000297
edisonn@google.com6e49c342013-06-27 20:03:43 +0000298class SkPdfTrueTypeFont : public SkPdfType1Font {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000299public:
edisonn@google.com3aa35552013-08-14 18:26:20 +0000300 SkPdfTrueTypeFont(SkPdfNativeDoc* doc, SkPdfTrueTypeFontDictionary* dict) : SkPdfType1Font(doc, dict) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000301 }
302};
303
edisonn@google.com6e49c342013-06-27 20:03:43 +0000304class SkPdfMultiMasterFont : public SkPdfType1Font {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000305public:
edisonn@google.com3aa35552013-08-14 18:26:20 +0000306 SkPdfMultiMasterFont(SkPdfNativeDoc* doc, SkPdfMultiMasterFontDictionary* dict) : SkPdfType1Font(doc, dict) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000307 }
308};
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000309/*
310class CIDToGIDMap {
311 virtual unsigned int map(unsigned int cid) = 0;
312 static CIDToGIDMap* fromName(const char* name);
313};
314
315class CIDToGIDMap_Identity {
316 virtual unsigned int map(unsigned int cid) { return cid; }
317
318 static CIDToGIDMap_Identity* instance() {
319 static CIDToGIDMap_Identity* inst = new CIDToGIDMap_Identity();
320 return inst;
321 }
322};
323
324CIDToGIDMap* CIDToGIDMap::fromName(const char* name) {
325 // The only one supported right now is Identity
326 if (strcmp(name, "Identity") == 0) {
327 return CIDToGIDMap_Identity::instance();
328 }
329
330#ifdef PDF_TRACE
331 // TODO(edisonn): warning/report
332 printf("Unknown CIDToGIDMap: %s\n", name);
333#endif
334 return NULL;
335}
336CIDToGIDMap* fCidToGid;
337*/
edisonn@google.com1be794f2013-06-21 21:43:09 +0000338
339class SkPdfType3Font : public SkPdfFont {
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000340 struct Type3FontChar {
edisonn@google.com3aa35552013-08-14 18:26:20 +0000341 SkPdfNativeObject* fObj;
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000342 double fWidth;
343 };
344
345 SkPdfDictionary* fCharProcs;
346 SkPdfEncodingDictionary* fEncodingDict;
347 unsigned int fFirstChar;
348 unsigned int fLastChar;
349
350 SkRect fFontBBox;
351 SkMatrix fFonMatrix;
352
353 Type3FontChar* fChars;
354
edisonn@google.com1be794f2013-06-21 21:43:09 +0000355public:
edisonn@google.com3aa35552013-08-14 18:26:20 +0000356 SkPdfType3Font(SkPdfNativeDoc* parsed, SkPdfType3FontDictionary* dict) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000357 fBaseFont = fontFromName(parsed, dict, dict->BaseFont(parsed).c_str());
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000358
359 if (dict->has_Encoding()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000360 if (dict->isEncodingAName(parsed)) {
361 fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName(parsed).c_str());
362 } else if (dict->isEncodingAEncodingdictionary(parsed)) {
edisonn@google.com2fd5d362013-07-23 19:43:48 +0000363 // No encoding.
364 fEncoding = SkPdfDefaultEncoding::instance();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000365 fEncodingDict = dict->getEncodingAsEncodingdictionary(parsed);
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000366 }
367 }
368
369 // null?
edisonn@google.com571c70b2013-07-10 17:09:50 +0000370 fCharProcs = dict->CharProcs(parsed);
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000371
372 fToUnicode = NULL;
373 if (dict->has_ToUnicode()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000374 fToUnicode = new SkPdfToUnicode(parsed, dict->ToUnicode(parsed));
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000375 }
376
edisonn@google.coma3356fc2013-07-10 18:20:06 +0000377 fFirstChar = (unsigned int)dict->FirstChar(parsed);
378 fLastChar = (unsigned int)dict->LastChar(parsed);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000379 fFonMatrix = dict->has_FontMatrix() ? dict->FontMatrix(parsed) : SkMatrix::I();
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000380
edisonn@google.com571c70b2013-07-10 17:09:50 +0000381 if (dict->has_FontBBox()) {
382 fFontBBox = dict->FontBBox(parsed);
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000383 }
384
385 fChars = new Type3FontChar[fLastChar - fFirstChar + 1];
386
387 memset(fChars, 0, sizeof(fChars[0]) * (fLastChar - fFirstChar + 1));
388
edisonn@google.com571c70b2013-07-10 17:09:50 +0000389 const SkPdfArray* widths = dict->Widths(parsed);
390 for (unsigned int i = 0 ; i < widths->size(); i++) {
edisonn@google.comac4bedc2013-07-25 21:40:23 +0000391 if ((fFirstChar + i) >= fFirstChar && (fFirstChar + i) <= fLastChar) {
392 fChars[i].fWidth = (*widths)[i]->numberValue();
393 } else {
394 // TODO(edisonn): report pdf corruption
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000395 }
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000396 }
397
edisonn@google.com571c70b2013-07-10 17:09:50 +0000398 const SkPdfArray* diffs = fEncodingDict->Differences(parsed);
399 unsigned int j = fFirstChar;
400 for (unsigned int i = 0 ; i < diffs->size(); i++) {
401 if ((*diffs)[i]->isInteger()) {
edisonn@google.coma3356fc2013-07-10 18:20:06 +0000402 j = (unsigned int)(*diffs)[i]->intValue();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000403 } else if ((*diffs)[i]->isName()) {
edisonn@google.comac4bedc2013-07-25 21:40:23 +0000404 if (j >= fFirstChar && j <= fLastChar) {
405 fChars[j - fFirstChar].fObj = fCharProcs->get((*diffs)[i]);
406 } else {
407 // TODO(edisonn): report pdf corruption
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000408 }
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000409 j++;
410 } else {
edisonn@google.comac4bedc2013-07-25 21:40:23 +0000411 // TODO(edisonn): report bad pdf
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000412 }
413 }
edisonn@google.com1be794f2013-06-21 21:43:09 +0000414 }
415
416public:
edisonn@google.com3aa35552013-08-14 18:26:20 +0000417 virtual double drawOneChar(unsigned int ch, SkPaint* paint, SkPdfContext* pdfContext, SkCanvas* canvas) {
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000418 if (ch < fFirstChar || ch > fLastChar || !fChars[ch - fFirstChar].fObj) {
edisonn@google.com6e49c342013-06-27 20:03:43 +0000419 return fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas);
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000420 }
edisonn@google.com1be794f2013-06-21 21:43:09 +0000421
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000422#ifdef PDF_TRACE
423 printf("Type 3 char to unicode: %c\n", ToUnicode(ch));
424 if (ToUnicode(ch) == 'A') {
425 printf("break;\n");
426 }
427#endif
428
edisonn@google.com571c70b2013-07-10 17:09:50 +0000429 // TODO(edisonn): is it better to resolve the reference at load time, or now?
430 doType3Char(pdfContext, canvas, pdfContext->fPdfDoc->resolveReference(fChars[ch - fFirstChar].fObj), fFontBBox, fFonMatrix, pdfContext->fGraphicsState.fCurFontSize);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000431
edisonn@google.com6e49c342013-06-27 20:03:43 +0000432 // TODO(edisonn): verify/test translate code, not tested yet
433 pdfContext->fGraphicsState.fMatrixTm.preTranslate(SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSize * fChars[ch - fFirstChar].fWidth),
434 SkDoubleToScalar(0.0));
edisonn@google.com571c70b2013-07-10 17:09:50 +0000435 return fChars[ch - fFirstChar].fWidth;
edisonn@google.com1be794f2013-06-21 21:43:09 +0000436 }
437
438 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
439
440 }
441};
442
443#endif // __DEFINED__SkPdfFont