SkPdfFont.h revision 2fd5d36ea6e134647aae0fbd35195500723851c3
11be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com#ifndef __DEFINED__SkPdfFont
21be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com#define __DEFINED__SkPdfFont
31be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
41be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com#include "SkPdfHeaders_autogen.h"
53aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com#include "SkPdfMapper_autogen.h"
61be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
71be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com#include <map>
81be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com#include <string>
91be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
10131d4ee0eabf7b7ddb5ccf0744edb4b449226773edisonn@google.com#include "SkTypeface.h"
111be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com#include "SkUtils.h"
12b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com#include "SkPdfBasics.h"
13b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com#include "SkPdfUtils.h"
14b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
151be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
161be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfType0Font;
171be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfType1Font;
181be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfType3Font;
191be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfTrueTypeFont;
201be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfMultiMasterFont;
211be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfFont;
221be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
231be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comstruct SkPdfStandardFontEntry {
24596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com    // We don't own this pointer!
251be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    const char* fName;
261be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    bool fIsBold;
271be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    bool fIsItalic;
28596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com    SkPdfStandardFontEntry()
29596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com    : fName(NULL),
30596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com      fIsBold(false),
31596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com      fIsItalic(false) {}
32596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com
33596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com    SkPdfStandardFontEntry(const char* name, bool bold, bool italic)
34596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com        : fName(name),
35596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com          fIsBold(bold),
36596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com          fIsItalic(italic) {}
371be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
381be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
391be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comstd::map<std::string, SkPdfStandardFontEntry>& getStandardFonts();
401be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comSkTypeface* SkTypefaceFromPdfStandardFont(const char* fontName, bool bold, bool italic);
41571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comSkPdfFont* fontFromName(SkNativeParsedPDF* doc, SkPdfObject* obj, const char* fontName);
421be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
431be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comstruct SkUnencodedText {
441be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    void* text;
451be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    int len;
461be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
471be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
483aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com    SkUnencodedText(const SkPdfString* obj) {
493aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com        text = (void*)obj->c_str();
503aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com        len = obj->len();
511be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
521be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
531be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
541be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comstruct SkDecodedText {
551be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    uint16_t* text;
561be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    int len;
57b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.compublic:
58b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    unsigned int operator[](int i) const { return text[i]; }
59b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    int size() const { return len; }
601be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
611be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
621be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comstruct SkUnicodeText {
631be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    uint16_t* text;
641be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    int len;
651be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
661be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
671be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    unsigned int operator[](int i) const { return text[i]; }
681be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    int size() const { return len; }
691be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
701be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
711be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfEncoding {
721be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
731be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const = 0;
74b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    static SkPdfEncoding* fromName(const char* name);
75b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com};
76b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
77b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.comstd::map<std::string, SkPdfEncoding*>& getStandardEncodings();
78b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
79b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.comclass SkPdfToUnicode {
80571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    SkNativeParsedPDF* fParsed;
81b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    // TODO(edisonn): hide public members
82b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.compublic:
83b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    unsigned short* fCMapEncoding;
84b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    unsigned char* fCMapEncodingFlag;
85b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
86571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    SkPdfToUnicode(SkNativeParsedPDF* parsed, SkPdfStream* stream);
871be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
881be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
89b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
901be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfIdentityHEncoding : public SkPdfEncoding {
911be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
921be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const {
931be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error?
941be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
951be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        uint16_t* text = (uint16_t*)textIn.text;
961be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        textOut->text = new uint16_t[textIn.len / 2];
971be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        textOut->len = textIn.len / 2;
981be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
991be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        for (int i = 0; i < textOut->len; i++) {
1001be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com            textOut->text[i] = ((text[i] << 8) & 0xff00) | ((text[i] >> 8) & 0x00ff);
1011be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        }
1021be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
1031be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        return true;
1041be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
1051be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
1061be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    static SkPdfIdentityHEncoding* instance() {
1071be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        static SkPdfIdentityHEncoding* inst = new SkPdfIdentityHEncoding();
1081be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        return inst;
1091be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
1101be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
1111be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
1126e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com// TODO(edisonn): using this one when no encoding is specified
1136e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.comclass SkPdfDefaultEncoding : public SkPdfEncoding {
1146e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.compublic:
1156e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com    virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const {
1166e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error?
1176e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com
1186e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        unsigned char* text = (unsigned char*)textIn.text;
1196e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        textOut->text = new uint16_t[textIn.len];
1206e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        textOut->len = textIn.len;
1216e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com
1226e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        for (int i = 0; i < textOut->len; i++) {
1236e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com            textOut->text[i] = text[i];
1246e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        }
1256e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com
1266e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        return true;
1276e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com    }
1286e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com
1296e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com    static SkPdfDefaultEncoding* instance() {
1306e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        static SkPdfDefaultEncoding* inst = new SkPdfDefaultEncoding();
1316e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        return inst;
1326e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com    }
1336e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com};
134b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
135b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.comclass SkPdfCIDToGIDMapIdentityEncoding : public SkPdfEncoding {
136b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.compublic:
137b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const {
138b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error?
139b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
140571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        uint16_t* text = (uint16_t*)textIn.text;
141571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        textOut->text = new uint16_t[textIn.len / 2];
142571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        textOut->len = textIn.len / 2;
143b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
144b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        for (int i = 0; i < textOut->len; i++) {
145571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            textOut->text[i] = ((text[i] << 8) & 0xff00) | ((text[i] >> 8) & 0x00ff);
146b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
147b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
148b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        return true;
149b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    }
150b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
151b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    static SkPdfCIDToGIDMapIdentityEncoding* instance() {
152b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        static SkPdfCIDToGIDMapIdentityEncoding* inst = new SkPdfCIDToGIDMapIdentityEncoding();
153b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        return inst;
154b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    }
155b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com};
156b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
1571be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfFont {
1581be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
1591be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    SkPdfFont* fBaseFont;
1601be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    SkPdfEncoding* fEncoding;
161b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    SkPdfToUnicode* fToUnicode;
162b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
1631be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
1641be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
1656e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com    SkPdfFont() : fBaseFont(NULL), fEncoding(SkPdfDefaultEncoding::instance()), fToUnicode(NULL) {}
1661be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
1671be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    const SkPdfEncoding* encoding() const {return fEncoding;}
1681be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
1696e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com    void drawText(const SkDecodedText& text, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas) {
1701be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        for (int i = 0 ; i < text.size(); i++) {
1716e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com            double width = drawOneChar(text[i], paint, pdfContext, canvas);
1726e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com            pdfContext->fGraphicsState.fMatrixTm.preTranslate(SkDoubleToScalar(width), SkDoubleToScalar(0.0));
1736e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com            canvas->translate(SkDoubleToScalar(width), SkDoubleToScalar(0.0));
1741be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        }
1751be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
1761be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
177b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    void ToUnicode(const SkDecodedText& textIn, SkUnicodeText* textOut) const {
178b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        if (fToUnicode) {
179b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            textOut->text = new uint16_t[textIn.len];
180b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            textOut->len = textIn.len;
181b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            for (int i = 0; i < textIn.len; i++) {
182b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com                textOut->text[i] = fToUnicode->fCMapEncoding[textIn.text[i]];
183b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            }
184b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        } else {
185b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            textOut->text = textIn.text;
186b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            textOut->len = textIn.len;
187b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
188b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    };
189b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
190b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    inline unsigned int ToUnicode(unsigned int ch) const {
191b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        if (fToUnicode) {
192b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            return fToUnicode->fCMapEncoding[ch];
193b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        } else {
194b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            return ch;
195b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
1961be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    };
1971be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
198571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    static SkPdfFont* fontFromPdfDictionary(SkNativeParsedPDF* doc, SkPdfFontDictionary* dict);
199571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    static SkPdfFont* Default() {return fontFromName(NULL, NULL, "TimesNewRoman");}
2001be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
201571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    static SkPdfType0Font* fontFromType0FontDictionary(SkNativeParsedPDF* doc, SkPdfType0FontDictionary* dict);
202571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    static SkPdfType1Font* fontFromType1FontDictionary(SkNativeParsedPDF* doc, SkPdfType1FontDictionary* dict);
203571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    static SkPdfType3Font* fontFromType3FontDictionary(SkNativeParsedPDF* doc, SkPdfType3FontDictionary* dict);
204571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    static SkPdfTrueTypeFont* fontFromTrueTypeFontDictionary(SkNativeParsedPDF* doc, SkPdfTrueTypeFontDictionary* dict);
205571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    static SkPdfMultiMasterFont* fontFromMultiMasterFontDictionary(SkNativeParsedPDF* doc, SkPdfMultiMasterFontDictionary* dict);
2061be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
207571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    static SkPdfFont* fontFromFontDescriptor(SkNativeParsedPDF* doc, SkPdfFontDescriptorDictionary* fd, bool loadFromName = true);
2086e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com
2091be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
2106e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com    virtual double drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas) = 0;
2111be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    virtual void afterWord(SkPaint* paint, SkMatrix* matrix) = 0;
212571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
213571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comprivate:
214571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    static SkPdfFont* fontFromPdfDictionaryOnce(SkNativeParsedPDF* doc, SkPdfFontDictionary* dict);
2151be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
2161be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2171be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfStandardFont : public SkPdfFont {
2181be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    SkTypeface* fTypeface;
2191be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2201be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
2211be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    SkPdfStandardFont(SkTypeface* typeface) : fTypeface(typeface) {}
2221be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2231be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
2246e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com    virtual double drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas) {
2251be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        paint->setTypeface(fTypeface);
2261be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        paint->setTextEncoding(SkPaint::kUTF8_TextEncoding);
2271be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2281be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        unsigned long ch4 = ch;
2291be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        char utf8[10];
2301be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        int len = SkUTF8_FromUnichar(ch4, utf8);
2311be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2321be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        canvas->drawText(utf8, len, SkDoubleToScalar(0), SkDoubleToScalar(0), *paint);
2331be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2341be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        SkScalar textWidth = paint->measureText(utf8, len);
2356e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        return SkScalarToDouble(textWidth);
2361be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
2371be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2381be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {}
2391be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
2401be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2411be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfType0Font : public SkPdfFont {
2421be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
243571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    SkPdfType0Font(SkNativeParsedPDF* doc, SkPdfType0FontDictionary* dict);
2441be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2451be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
2461be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2476e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com    virtual double drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas) {
2486e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        return fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas);
2491be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
2501be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2511be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
2521be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
2531be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
2541be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2551be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfType1Font : public SkPdfFont {
2561be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
257571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    SkPdfType1Font(SkNativeParsedPDF* doc, SkPdfType1FontDictionary* dict) {
2586e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        if (dict->has_FontDescriptor()) {
259571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            fBaseFont = SkPdfFont::fontFromFontDescriptor(doc, dict->FontDescriptor(doc));
2606e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        } else {
261571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            fBaseFont = fontFromName(doc, dict, dict->BaseFont(doc).c_str());
2626e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        }
2631be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
2641be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2651be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
2666e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com      virtual double drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas) {
2676e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com          return fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas);
2681be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com      }
2691be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2701be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com      virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
2711be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2721be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com      }
2731be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
2741be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2756e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.comclass SkPdfTrueTypeFont : public SkPdfType1Font {
2761be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
277571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    SkPdfTrueTypeFont(SkNativeParsedPDF* doc, SkPdfTrueTypeFontDictionary* dict) : SkPdfType1Font(doc, dict) {
2781be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
2796e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com};
2801be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2816e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.comclass SkPdfMultiMasterFont : public SkPdfType1Font {
2821be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
283571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    SkPdfMultiMasterFont(SkNativeParsedPDF* doc, SkPdfMultiMasterFontDictionary* dict) : SkPdfType1Font(doc, dict) {
2841be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
2851be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
286b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com/*
287b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.comclass CIDToGIDMap {
288b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    virtual unsigned int map(unsigned int cid) = 0;
289b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    static CIDToGIDMap* fromName(const char* name);
290b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com};
291b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
292b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.comclass CIDToGIDMap_Identity {
293b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    virtual unsigned int map(unsigned int cid) { return cid; }
294b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
295b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    static CIDToGIDMap_Identity* instance() {
296b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        static CIDToGIDMap_Identity* inst = new CIDToGIDMap_Identity();
297b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        return inst;
298b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    }
299b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com};
300b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
301b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.comCIDToGIDMap* CIDToGIDMap::fromName(const char* name) {
302b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    // The only one supported right now is Identity
303b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    if (strcmp(name, "Identity") == 0) {
304b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        return CIDToGIDMap_Identity::instance();
305b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    }
306b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
307b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com#ifdef PDF_TRACE
308b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    // TODO(edisonn): warning/report
309b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    printf("Unknown CIDToGIDMap: %s\n", name);
310b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com#endif
311b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    return NULL;
312b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com}
313b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.comCIDToGIDMap* fCidToGid;
314b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com*/
3151be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
3161be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfType3Font : public SkPdfFont {
317b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    struct Type3FontChar {
318571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        const SkPdfObject* fObj;
319b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        double fWidth;
320b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    };
321b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
322b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    SkPdfDictionary* fCharProcs;
323b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    SkPdfEncodingDictionary* fEncodingDict;
324b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    unsigned int fFirstChar;
325b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    unsigned int fLastChar;
326b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
327b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    SkRect fFontBBox;
328b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    SkMatrix fFonMatrix;
329b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
330b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    Type3FontChar* fChars;
331b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
3321be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
333571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    SkPdfType3Font(SkNativeParsedPDF* parsed, SkPdfType3FontDictionary* dict) {
334571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        fBaseFont = fontFromName(parsed, dict, dict->BaseFont(parsed).c_str());
335b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
336b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        if (dict->has_Encoding()) {
337571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            if (dict->isEncodingAName(parsed)) {
338571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                 fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName(parsed).c_str());
339571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            } else if (dict->isEncodingAEncodingdictionary(parsed)) {
3402fd5d36ea6e134647aae0fbd35195500723851c3edisonn@google.com                 // No encoding.
3412fd5d36ea6e134647aae0fbd35195500723851c3edisonn@google.com                 fEncoding = SkPdfDefaultEncoding::instance();
342571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                 fEncodingDict = dict->getEncodingAsEncodingdictionary(parsed);
343b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            }
344b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
345b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
346b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        // null?
347571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        fCharProcs = dict->CharProcs(parsed);
348b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
349b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        fToUnicode = NULL;
350b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        if (dict->has_ToUnicode()) {
351571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            fToUnicode = new SkPdfToUnicode(parsed, dict->ToUnicode(parsed));
352b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
353b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
354a3356fce903ff75dc332b53dd3a860ba810b9519edisonn@google.com        fFirstChar = (unsigned int)dict->FirstChar(parsed);
355a3356fce903ff75dc332b53dd3a860ba810b9519edisonn@google.com        fLastChar = (unsigned int)dict->LastChar(parsed);
356571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        fFonMatrix = dict->has_FontMatrix() ? dict->FontMatrix(parsed) : SkMatrix::I();
357b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
358571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (dict->has_FontBBox()) {
359571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            fFontBBox = dict->FontBBox(parsed);
360b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
361b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
362b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        fChars = new Type3FontChar[fLastChar - fFirstChar + 1];
363b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
364b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        memset(fChars, 0, sizeof(fChars[0]) * (fLastChar - fFirstChar + 1));
365b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
366b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
367571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        const SkPdfArray* widths = dict->Widths(parsed);
368571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        for (unsigned int i = 0 ; i < widths->size(); i++) {
369b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            if ((fFirstChar + i) < fFirstChar || (fFirstChar + i) > fLastChar) {
370b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com                printf("break; error 1\n");
371b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            }
372571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            fChars[i].fWidth = (*widths)[i]->numberValue();
373b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
374b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
375571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        const SkPdfArray* diffs = fEncodingDict->Differences(parsed);
376571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        unsigned int j = fFirstChar;
377571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        for (unsigned int i = 0 ; i < diffs->size(); i++) {
378571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            if ((*diffs)[i]->isInteger()) {
379a3356fce903ff75dc332b53dd3a860ba810b9519edisonn@google.com                j = (unsigned int)(*diffs)[i]->intValue();
380571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            } else if ((*diffs)[i]->isName()) {
381b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com                if (j < fFirstChar || j > fLastChar) {
382b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com                    printf("break; error 2\n");
383b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com                }
3842fd5d36ea6e134647aae0fbd35195500723851c3edisonn@google.com                fChars[j - fFirstChar].fObj = fCharProcs->get((*diffs)[i]);
385b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com                j++;
386b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            } else {
387b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com                // err
388b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            }
389b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
3901be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
3911be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
3921be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
3936e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com    virtual double drawOneChar(unsigned int ch, SkPaint* paint, PdfContext* pdfContext, SkCanvas* canvas) {
394b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        if (ch < fFirstChar || ch > fLastChar || !fChars[ch - fFirstChar].fObj) {
3956e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com            return fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas);
396b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
397b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
398b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com#ifdef PDF_TRACE
399b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        printf("Type 3 char to unicode: %c\n", ToUnicode(ch));
400b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        if (ToUnicode(ch) == 'A') {
401b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            printf("break;\n");
402b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
403b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com#endif
4041be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
405571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        // TODO(edisonn): is it better to resolve the reference at load time, or now?
406571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        doType3Char(pdfContext, canvas, pdfContext->fPdfDoc->resolveReference(fChars[ch - fFirstChar].fObj), fFontBBox, fFonMatrix, pdfContext->fGraphicsState.fCurFontSize);
4071be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
4086e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        // TODO(edisonn): verify/test translate code, not tested yet
4096e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        pdfContext->fGraphicsState.fMatrixTm.preTranslate(SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSize * fChars[ch - fFirstChar].fWidth),
4106e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com                             SkDoubleToScalar(0.0));
411571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fChars[ch - fFirstChar].fWidth;
4121be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
4131be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
4141be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
4151be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
4161be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
4171be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
4181be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
4191be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com#endif  // __DEFINED__SkPdfFont
420