SkPdfFont.h revision 6e49c345b132ca55830c7dad746108cd3624eb8b
1#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 "SkTypeface.h" 11#include "SkUtils.h" 12#include "SkPdfBasics.h" 13#include "SkPdfUtils.h" 14 15 16class SkPdfType0Font; 17class SkPdfType1Font; 18class SkPdfType3Font; 19class SkPdfTrueTypeFont; 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* fontFromName(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; 48public: 49 unsigned int operator[](int i) const { return text[i]; } 50 int size() const { return len; } 51}; 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; 65 static SkPdfEncoding* fromName(const char* name); 66}; 67 68std::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 80class 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 102// TODO(edisonn): using this one when no encoding is specified 103class SkPdfDefaultEncoding : 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 SkPdfDefaultEncoding* instance() { 120 static SkPdfDefaultEncoding* inst = new SkPdfDefaultEncoding(); 121 return inst; 122 } 123}; 124 125class SkPdfCIDToGIDMapIdentityEncoding : public SkPdfEncoding { 126public: 127 virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const { 128 // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error? 129 130 unsigned char* text = (unsigned char*)textIn.text; 131 textOut->text = new uint16_t[textIn.len]; 132 textOut->len = textIn.len; 133 134 for (int i = 0; i < textOut->len; i++) { 135 textOut->text[i] = text[i]; 136 } 137 138 return true; 139 } 140 141 static SkPdfCIDToGIDMapIdentityEncoding* instance() { 142 static SkPdfCIDToGIDMapIdentityEncoding* inst = new SkPdfCIDToGIDMapIdentityEncoding(); 143 return inst; 144 } 145}; 146 147class SkPdfFont { 148public: 149 SkPdfFont* fBaseFont; 150 SkPdfEncoding* fEncoding; 151 SkPdfToUnicode* fToUnicode; 152 153 154public: 155 SkPdfFont() : fBaseFont(NULL), fEncoding(SkPdfDefaultEncoding::instance()), fToUnicode(NULL) {} 156 157 const SkPdfEncoding* encoding() const {return fEncoding;} 158 159 void drawText(const SkDecodedText& text, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas) { 160 for (int i = 0 ; i < text.size(); i++) { 161 double width = drawOneChar(text[i], paint, pdfContext, canvas); 162 pdfContext->fGraphicsState.fMatrixTm.preTranslate(SkDoubleToScalar(width), SkDoubleToScalar(0.0)); 163 canvas->translate(SkDoubleToScalar(width), SkDoubleToScalar(0.0)); 164 } 165 } 166 167 void ToUnicode(const SkDecodedText& textIn, SkUnicodeText* textOut) const { 168 if (fToUnicode) { 169 textOut->text = new uint16_t[textIn.len]; 170 textOut->len = textIn.len; 171 for (int i = 0; i < textIn.len; i++) { 172 textOut->text[i] = fToUnicode->fCMapEncoding[textIn.text[i]]; 173 } 174 } else { 175 textOut->text = textIn.text; 176 textOut->len = textIn.len; 177 } 178 }; 179 180 inline unsigned int ToUnicode(unsigned int ch) const { 181 if (fToUnicode) { 182 return fToUnicode->fCMapEncoding[ch]; 183 } else { 184 return ch; 185 } 186 }; 187 188 static SkPdfFont* fontFromPdfDictionary(SkPdfFontDictionary* dict); 189 static SkPdfFont* Default() {return fontFromName(NULL, "TimesNewRoman");} 190 191 static SkPdfType0Font* fontFromType0FontDictionary(SkPdfType0FontDictionary* dict); 192 static SkPdfType1Font* fontFromType1FontDictionary(SkPdfType1FontDictionary* dict); 193 static SkPdfType3Font* fontFromType3FontDictionary(SkPdfType3FontDictionary* dict); 194 static SkPdfTrueTypeFont* fontFromTrueTypeFontDictionary(SkPdfTrueTypeFontDictionary* dict); 195 static SkPdfMultiMasterFont* fontFromMultiMasterFontDictionary(SkPdfMultiMasterFontDictionary* dict); 196 197 static SkPdfFont* fontFromFontDescriptor(SkPdfFontDescriptorDictionary* fd, bool loadFromName = true); 198 199public: 200 virtual double drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas) = 0; 201 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) = 0; 202}; 203 204class SkPdfStandardFont : public SkPdfFont { 205 SkTypeface* fTypeface; 206 207public: 208 SkPdfStandardFont(SkTypeface* typeface) : fTypeface(typeface) {} 209 210public: 211 virtual double drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas) { 212 paint->setTypeface(fTypeface); 213 paint->setTextEncoding(SkPaint::kUTF8_TextEncoding); 214 215 unsigned long ch4 = ch; 216 char utf8[10]; 217 int len = SkUTF8_FromUnichar(ch4, utf8); 218 219 canvas->drawText(utf8, len, SkDoubleToScalar(0), SkDoubleToScalar(0), *paint); 220 221 SkScalar textWidth = paint->measureText(utf8, len); 222 return SkScalarToDouble(textWidth); 223 } 224 225 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {} 226}; 227 228class SkPdfType0Font : public SkPdfFont { 229public: 230 SkPdfType0Font(SkPdfType0FontDictionary* dict); 231 232public: 233 234 virtual double drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas) { 235 return fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas); 236 } 237 238 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) { 239 } 240}; 241 242class SkPdfType1Font : public SkPdfFont { 243public: 244 SkPdfType1Font(SkPdfType1FontDictionary* dict) { 245 if (dict->has_FontDescriptor()) { 246 fBaseFont = SkPdfFont::fontFromFontDescriptor(dict->FontDescriptor()); 247 } else { 248 fBaseFont = fontFromName(dict, dict->BaseFont().c_str()); 249 } 250 } 251 252public: 253 virtual double drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas) { 254 return fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas); 255 } 256 257 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) { 258 259 } 260}; 261 262class SkPdfTrueTypeFont : public SkPdfType1Font { 263public: 264 SkPdfTrueTypeFont(SkPdfTrueTypeFontDictionary* dict) : SkPdfType1Font(dict) { 265 } 266}; 267 268class SkPdfMultiMasterFont : public SkPdfType1Font { 269public: 270 SkPdfMultiMasterFont(SkPdfMultiMasterFontDictionary* dict) : SkPdfType1Font(dict) { 271 } 272}; 273/* 274class CIDToGIDMap { 275 virtual unsigned int map(unsigned int cid) = 0; 276 static CIDToGIDMap* fromName(const char* name); 277}; 278 279class CIDToGIDMap_Identity { 280 virtual unsigned int map(unsigned int cid) { return cid; } 281 282 static CIDToGIDMap_Identity* instance() { 283 static CIDToGIDMap_Identity* inst = new CIDToGIDMap_Identity(); 284 return inst; 285 } 286}; 287 288CIDToGIDMap* CIDToGIDMap::fromName(const char* name) { 289 // The only one supported right now is Identity 290 if (strcmp(name, "Identity") == 0) { 291 return CIDToGIDMap_Identity::instance(); 292 } 293 294#ifdef PDF_TRACE 295 // TODO(edisonn): warning/report 296 printf("Unknown CIDToGIDMap: %s\n", name); 297#endif 298 return NULL; 299} 300CIDToGIDMap* fCidToGid; 301*/ 302 303class SkPdfType3Font : public SkPdfFont { 304 struct Type3FontChar { 305 SkPdfObject* fObj; 306 double fWidth; 307 }; 308 309 SkPdfDictionary* fCharProcs; 310 SkPdfEncodingDictionary* fEncodingDict; 311 unsigned int fFirstChar; 312 unsigned int fLastChar; 313 314 SkRect fFontBBox; 315 SkMatrix fFonMatrix; 316 317 Type3FontChar* fChars; 318 319public: 320 SkPdfType3Font(SkPdfType3FontDictionary* dict) { 321 fBaseFont = fontFromName(dict, dict->BaseFont().c_str()); 322 323 if (dict->has_Encoding()) { 324 if (dict->isEncodingAName()) { 325 fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName().c_str()); 326 } else if (dict->isEncodingAEncodingdictionary()) { 327 // technically, there is no encoding. 328 fEncoding = SkPdfCIDToGIDMapIdentityEncoding::instance(); 329 fEncodingDict = dict->getEncodingAsEncodingdictionary(); 330 } 331 } 332 333 // null? 334 fCharProcs = dict->CharProcs(); 335 336 fToUnicode = NULL; 337 if (dict->has_ToUnicode()) { 338 fToUnicode = new SkPdfToUnicode(dict->ToUnicode()); 339 } 340 341 fFirstChar = dict->FirstChar(); 342 fLastChar = dict->LastChar(); 343 fFonMatrix = dict->has_FontMatrix() ? *dict->FontMatrix() : SkMatrix::I(); 344 345 if (dict->FontBBox()) { 346 fFontBBox = *dict->FontBBox(); 347 } 348 349 fChars = new Type3FontChar[fLastChar - fFirstChar + 1]; 350 351 memset(fChars, 0, sizeof(fChars[0]) * (fLastChar - fFirstChar + 1)); 352 353 354 SkPdfArray* widths = dict->Widths(); 355 for (int i = 0 ; i < widths->size(); i++) { 356 if ((fFirstChar + i) < fFirstChar || (fFirstChar + i) > fLastChar) { 357 printf("break; error 1\n"); 358 } 359 fChars[i].fWidth = (*widths)[i]->asNumber()->value(); 360 } 361 362 SkPdfArray* diffs = fEncodingDict->Differences(); 363 int j = fFirstChar; 364 for (int i = 0 ; i < diffs->size(); i++) { 365 if ((*diffs)[i]->asInteger()) { 366 j = (*diffs)[i]->asInteger()->value(); 367 } else if ((*diffs)[i]->asName()) { 368 if (j < fFirstChar || j > fLastChar) { 369 printf("break; error 2\n"); 370 } 371 fChars[j - fFirstChar].fObj = fCharProcs->get((*diffs)[i]->asName()->value().c_str()); 372 j++; 373 } else { 374 // err 375 } 376 } 377 } 378 379public: 380 virtual double drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas) { 381 if (ch < fFirstChar || ch > fLastChar || !fChars[ch - fFirstChar].fObj) { 382 return fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas); 383 } 384 385#ifdef PDF_TRACE 386 printf("Type 3 char to unicode: %c\n", ToUnicode(ch)); 387 if (ToUnicode(ch) == 'A') { 388 printf("break;\n"); 389 } 390#endif 391 392 doType3Char(pdfContext, canvas, fChars[ch - fFirstChar].fObj, fFontBBox, fFonMatrix, pdfContext->fGraphicsState.fCurFontSize); 393 394 // TODO(edisonn): verify/test translate code, not tested yet 395 pdfContext->fGraphicsState.fMatrixTm.preTranslate(SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSize * fChars[ch - fFirstChar].fWidth), 396 SkDoubleToScalar(0.0)); 397 } 398 399 virtual void afterWord(SkPaint* paint, SkMatrix* matrix) { 400 401 } 402}; 403 404#endif // __DEFINED__SkPdfFont 405