1cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com/*
2cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * Copyright 2013 Google Inc.
3cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com *
4cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * Use of this source code is governed by a BSD-style license that can be
5cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * found in the LICENSE file.
6cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com */
7cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com
8d03c2c732e2e914f8429cfc8b077a7b9b853dd8eedisonn@google.com// TODO(edisonn): this file not commented much on purpose.
9d03c2c732e2e914f8429cfc8b077a7b9b853dd8eedisonn@google.com// It will probably need heavy refactoring soon anyway to support all encodings, fonts and
10d03c2c732e2e914f8429cfc8b077a7b9b853dd8eedisonn@google.com// proper text sizing and spacing
11d03c2c732e2e914f8429cfc8b077a7b9b853dd8eedisonn@google.com
12cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com#ifndef SkPdfFont_DEFINED
13cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com#define SkPdfFont_DEFINED
141be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
15d906702f7812807d79eeaba65acff62235990b64scroggo@google.com#include "SkPdfContext.h"
161be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com#include "SkPdfHeaders_autogen.h"
173aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com#include "SkPdfMapper_autogen.h"
18b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com#include "SkPdfUtils.h"
19e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com#include "SkTypeface.h"
20063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com#include "SkTDict.h"
21e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com#include "SkUtils.h"
221be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
231be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfType0Font;
241be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfType1Font;
251be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfType3Font;
261be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfTrueTypeFont;
271be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfMultiMasterFont;
281be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfFont;
291be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
301be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comstruct SkPdfStandardFontEntry {
31596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com    // We don't own this pointer!
321be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    const char* fName;
331be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    bool fIsBold;
341be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    bool fIsItalic;
35596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com    SkPdfStandardFontEntry()
36596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com    : fName(NULL),
37596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com      fIsBold(false),
38596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com      fIsItalic(false) {}
39596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com
40596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com    SkPdfStandardFontEntry(const char* name, bool bold, bool italic)
41596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com        : fName(name),
42596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com          fIsBold(bold),
43596d2e26cdaa80f8721ba6b6eedf09227524f5d1edisonn@google.com          fIsItalic(italic) {}
441be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
451be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
46063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.comSkTDict<SkPdfStandardFontEntry>& getStandardFonts();
471be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comSkTypeface* SkTypefaceFromPdfStandardFont(const char* fontName, bool bold, bool italic);
483aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comSkPdfFont* fontFromName(SkPdfNativeDoc* doc, SkPdfNativeObject* obj, const char* fontName);
491be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
501be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comstruct SkUnencodedText {
511be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    void* text;
521be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    int len;
531be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
541be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
553aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com    SkUnencodedText(const SkPdfString* obj) {
563aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com        text = (void*)obj->c_str();
575f008652f69ce7809b920b9fa573bc72216acd51scroggo@google.com        len = (int) obj->lenstr();
581be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
591be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
601be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
611be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comstruct SkDecodedText {
621be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    uint16_t* text;
631be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    int len;
64b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.compublic:
65b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    unsigned int operator[](int i) const { return text[i]; }
66b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    int size() const { return len; }
671be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
681be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
691be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comstruct SkUnicodeText {
701be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    uint16_t* text;
711be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    int len;
721be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
731be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
741be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    unsigned int operator[](int i) const { return text[i]; }
751be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    int size() const { return len; }
761be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
771be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
781be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfEncoding {
791be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
809615f8dbf19be50c419759920e7595bcf7e5350amtklein@google.com    virtual ~SkPdfEncoding() {}
811be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const = 0;
82b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    static SkPdfEncoding* fromName(const char* name);
83b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com};
84b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
85063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.comSkTDict<SkPdfEncoding*>& getStandardEncodings();
86b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
87b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.comclass SkPdfToUnicode {
88b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    // TODO(edisonn): hide public members
89b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.compublic:
90b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    unsigned short* fCMapEncoding;
91b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    unsigned char* fCMapEncodingFlag;
92b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
933aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    SkPdfToUnicode(SkPdfNativeDoc* parsed, SkPdfStream* stream);
941be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
951be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
96b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
971be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfIdentityHEncoding : public SkPdfEncoding {
981be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
999615f8dbf19be50c419759920e7595bcf7e5350amtklein@google.com    virtual ~SkPdfIdentityHEncoding() {}
1001be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const {
1011be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error?
1021be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
1031be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        uint16_t* text = (uint16_t*)textIn.text;
1041be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        textOut->text = new uint16_t[textIn.len / 2];
1051be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        textOut->len = textIn.len / 2;
1061be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
1071be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        for (int i = 0; i < textOut->len; i++) {
1081be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com            textOut->text[i] = ((text[i] << 8) & 0xff00) | ((text[i] >> 8) & 0x00ff);
1091be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        }
1101be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
1111be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        return true;
1121be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
1131be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
1141be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    static SkPdfIdentityHEncoding* instance() {
1151be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        static SkPdfIdentityHEncoding* inst = new SkPdfIdentityHEncoding();
1161be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        return inst;
1171be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
1181be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
1191be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
1206e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com// TODO(edisonn): using this one when no encoding is specified
1216e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.comclass SkPdfDefaultEncoding : public SkPdfEncoding {
1226e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.compublic:
1239615f8dbf19be50c419759920e7595bcf7e5350amtklein@google.com    virtual ~SkPdfDefaultEncoding() {}
1246e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com    virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const {
1256e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error?
1266e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com
1276e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        unsigned char* text = (unsigned char*)textIn.text;
1286e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        textOut->text = new uint16_t[textIn.len];
1296e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        textOut->len = textIn.len;
1306e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com
1316e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        for (int i = 0; i < textOut->len; i++) {
1326e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com            textOut->text[i] = text[i];
1336e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        }
1346e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com
1356e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        return true;
1366e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com    }
1376e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com
1386e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com    static SkPdfDefaultEncoding* instance() {
1396e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        static SkPdfDefaultEncoding* inst = new SkPdfDefaultEncoding();
1406e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        return inst;
1416e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com    }
1426e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com};
143b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
144b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.comclass SkPdfCIDToGIDMapIdentityEncoding : public SkPdfEncoding {
145b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.compublic:
1469615f8dbf19be50c419759920e7595bcf7e5350amtklein@google.com    virtual ~SkPdfCIDToGIDMapIdentityEncoding() {}
147b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    virtual bool decodeText(const SkUnencodedText& textIn, SkDecodedText* textOut) const {
148b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        // TODO(edisonn): SkASSERT(textIn.len % 2 == 0); or report error?
149b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
150571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        uint16_t* text = (uint16_t*)textIn.text;
151571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        textOut->text = new uint16_t[textIn.len / 2];
152571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        textOut->len = textIn.len / 2;
153b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
154b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        for (int i = 0; i < textOut->len; i++) {
155571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            textOut->text[i] = ((text[i] << 8) & 0xff00) | ((text[i] >> 8) & 0x00ff);
156b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
157b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
158b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        return true;
159b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    }
160b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
161b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    static SkPdfCIDToGIDMapIdentityEncoding* instance() {
162b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        static SkPdfCIDToGIDMapIdentityEncoding* inst = new SkPdfCIDToGIDMapIdentityEncoding();
163b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        return inst;
164b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    }
165b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com};
166b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
1671be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfFont {
1681be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
1691be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    SkPdfFont* fBaseFont;
1701be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    SkPdfEncoding* fEncoding;
171b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    SkPdfToUnicode* fToUnicode;
172b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
1731be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
1741be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
1756e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com    SkPdfFont() : fBaseFont(NULL), fEncoding(SkPdfDefaultEncoding::instance()), fToUnicode(NULL) {}
1761be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
1777ee12ca99f4ac0aadb8c4d29ae793c411faf73dbedisonn@google.com    virtual ~SkPdfFont() {
1787ee12ca99f4ac0aadb8c4d29ae793c411faf73dbedisonn@google.com        // TODO(edisonn): NYI (will leak for now)
1797ee12ca99f4ac0aadb8c4d29ae793c411faf73dbedisonn@google.com    }
1807ee12ca99f4ac0aadb8c4d29ae793c411faf73dbedisonn@google.com
1811be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    const SkPdfEncoding* encoding() const {return fEncoding;}
1821be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
183e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com    void drawText(const SkDecodedText& text, SkPaint* paint, SkPdfContext* pdfContext,
184e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                  SkCanvas* canvas) {
1851be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        for (int i = 0 ; i < text.size(); i++) {
186e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com            canvas->setMatrix(pdfContext->fGraphicsState.fMatrixTm);
187e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com#ifdef PDF_TRACE
188e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com            SkPoint point = SkPoint::Make(SkDoubleToScalar(0), SkDoubleToScalar(0));
189e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com            pdfContext->fGraphicsState.fMatrixTm.mapPoints(&point, 1);
190e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com            printf("DrawText at (%f, %f)\n", SkScalarToDouble(point.x()),
191e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                                             SkScalarToDouble(point.y()));
192e57c62d039cbd67a4e52776b3e95c5d002b818d2edisonn@google.com#endif  // PDF_TRACE
1933aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com
1943aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com#ifdef PDF_TRACE_DRAWTEXT
1953aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            SkPaint col;
1963aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            col.setColor(SK_ColorMAGENTA);
197e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com            SkRect rect = SkRect::MakeXYWH(SkDoubleToScalar(0.0),
198e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                                           SkDoubleToScalar(0.0),
199e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                                           SkDoubleToScalar(10.0),
200e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                                           SkDoubleToScalar(10.0));
2013aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            canvas->save();
2023aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            canvas->setMatrix(pdfContext->fGraphicsState.fMatrixTm);
2033aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            canvas->drawRect(rect, col);
2043aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            canvas->restore();
2053aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com#endif
2066e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com            double width = drawOneChar(text[i], paint, pdfContext, canvas);
207e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com            pdfContext->fGraphicsState.fMatrixTm.preTranslate(SkDoubleToScalar(width),
208e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                                                              SkDoubleToScalar(0.0));
2091be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        }
2101be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
2111be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
212b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    void ToUnicode(const SkDecodedText& textIn, SkUnicodeText* textOut) const {
213b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        if (fToUnicode) {
214b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            textOut->text = new uint16_t[textIn.len];
215b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            textOut->len = textIn.len;
216b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            for (int i = 0; i < textIn.len; i++) {
217b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com                textOut->text[i] = fToUnicode->fCMapEncoding[textIn.text[i]];
218b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            }
219b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        } else {
220b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            textOut->text = textIn.text;
221b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            textOut->len = textIn.len;
222b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
223b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    };
224b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
225b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    inline unsigned int ToUnicode(unsigned int ch) const {
226f68aed33819cbc98a95edeadde1da9303eca7fb2edisonn@google.com        if (fToUnicode && fToUnicode->fCMapEncoding) {
227b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            return fToUnicode->fCMapEncoding[ch];
228b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        } else {
229b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            return ch;
230b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
2311be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    };
2321be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2333aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    static SkPdfFont* fontFromPdfDictionary(SkPdfNativeDoc* doc, SkPdfFontDictionary* dict);
234571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    static SkPdfFont* Default() {return fontFromName(NULL, NULL, "TimesNewRoman");}
2351be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
236e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com    static SkPdfType0Font* fontFromType0FontDictionary(SkPdfNativeDoc* doc,
237e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                                                       SkPdfType0FontDictionary* dict);
238e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com    static SkPdfType1Font* fontFromType1FontDictionary(SkPdfNativeDoc* doc,
239e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                                                       SkPdfType1FontDictionary* dict);
240e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com    static SkPdfType3Font* fontFromType3FontDictionary(SkPdfNativeDoc* doc,
241e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                                                       SkPdfType3FontDictionary* dict);
242e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com    static SkPdfTrueTypeFont* fontFromTrueTypeFontDictionary(SkPdfNativeDoc* doc,
243e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                                                             SkPdfTrueTypeFontDictionary* dict);
244e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com    static SkPdfMultiMasterFont* fontFromMultiMasterFontDictionary(
245e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com            SkPdfNativeDoc* doc, SkPdfMultiMasterFontDictionary* dict);
246e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com
247e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com    static SkPdfFont* fontFromFontDescriptor(SkPdfNativeDoc* doc,
248e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                                             SkPdfFontDescriptorDictionary* fd,
249e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                                             bool loadFromName = true);
2506e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com
2511be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
252e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com    virtual double drawOneChar(unsigned int ch, SkPaint* paint, SkPdfContext* pdfContext,
253e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                               SkCanvas* canvas) = 0;
2541be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    virtual void afterWord(SkPaint* paint, SkMatrix* matrix) = 0;
255571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
256571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comprivate:
2573aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    static SkPdfFont* fontFromPdfDictionaryOnce(SkPdfNativeDoc* doc, SkPdfFontDictionary* dict);
2581be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
2591be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2601be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfStandardFont : public SkPdfFont {
2611be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    SkTypeface* fTypeface;
2621be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2631be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
2641be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    SkPdfStandardFont(SkTypeface* typeface) : fTypeface(typeface) {}
2651be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2661be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
267e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com    virtual double drawOneChar(unsigned int ch, SkPaint* paint, SkPdfContext* pdfContext,
268e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                               SkCanvas* canvas) {
2691be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        paint->setTypeface(fTypeface);
2701be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        paint->setTextEncoding(SkPaint::kUTF8_TextEncoding);
2711be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2721be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        unsigned long ch4 = ch;
2731be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        char utf8[10];
2745f008652f69ce7809b920b9fa573bc72216acd51scroggo@google.com        size_t len = SkUTF8_FromUnichar((SkUnichar) ch4, utf8);
2751be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2761be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        canvas->drawText(utf8, len, SkDoubleToScalar(0), SkDoubleToScalar(0), *paint);
2771be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2781be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com        SkScalar textWidth = paint->measureText(utf8, len);
2796e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        return SkScalarToDouble(textWidth);
2801be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
2811be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2821be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {}
2831be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
2841be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2851be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfType0Font : public SkPdfFont {
2861be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
2873aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    SkPdfType0Font(SkPdfNativeDoc* doc, SkPdfType0FontDictionary* dict);
2881be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2891be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
2901be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
291e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com    virtual double drawOneChar(unsigned int ch, SkPaint* paint, SkPdfContext* pdfContext,
292e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                               SkCanvas* canvas) {
2936e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        return fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas);
2941be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
2951be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
2961be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
2971be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
2981be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
2991be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
3001be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfType1Font : public SkPdfFont {
3011be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
3023aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    SkPdfType1Font(SkPdfNativeDoc* doc, SkPdfType1FontDictionary* dict) {
3036e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        if (dict->has_FontDescriptor()) {
304571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            fBaseFont = SkPdfFont::fontFromFontDescriptor(doc, dict->FontDescriptor(doc));
3056e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        } else {
306571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            fBaseFont = fontFromName(doc, dict, dict->BaseFont(doc).c_str());
3076e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        }
3083aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com
3093aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com        if (dict->isEncodingAName(doc)) {
3103aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName(doc).c_str());
3113aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com        } else if (dict->isEncodingADictionary(doc)) {
3123aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            //SkPdfDictionary* dictEnc = dict->getEncodingAsDictionary(doc);
3133aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com        }
3143aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com        dict->FontDescriptor(doc);
3151be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
3161be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
3171be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
318e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com      virtual double drawOneChar(unsigned int ch, SkPaint* paint, SkPdfContext* pdfContext,
319e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                                 SkCanvas* canvas) {
3206e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com          return fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas);
3211be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com      }
3221be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
3231be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com      virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {
3241be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
3251be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com      }
3261be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
3271be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
3286e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.comclass SkPdfTrueTypeFont : public SkPdfType1Font {
3291be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
330e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com    SkPdfTrueTypeFont(SkPdfNativeDoc* doc, SkPdfTrueTypeFontDictionary* dict)
331e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com            : SkPdfType1Font(doc, dict) {}
3326e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com};
3331be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
3346e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.comclass SkPdfMultiMasterFont : public SkPdfType1Font {
3351be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
336e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com    SkPdfMultiMasterFont(SkPdfNativeDoc* doc, SkPdfMultiMasterFontDictionary* dict)
337e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com            : SkPdfType1Font(doc, dict) {}
3381be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
339b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com/*
340b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.comclass CIDToGIDMap {
341b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    virtual unsigned int map(unsigned int cid) = 0;
342b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    static CIDToGIDMap* fromName(const char* name);
343b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com};
344b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
345b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.comclass CIDToGIDMap_Identity {
346b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    virtual unsigned int map(unsigned int cid) { return cid; }
347b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
348b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    static CIDToGIDMap_Identity* instance() {
349b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        static CIDToGIDMap_Identity* inst = new CIDToGIDMap_Identity();
350b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        return inst;
351b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    }
352b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com};
353b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
354b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.comCIDToGIDMap* CIDToGIDMap::fromName(const char* name) {
355b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    // The only one supported right now is Identity
356b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    if (strcmp(name, "Identity") == 0) {
357b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        return CIDToGIDMap_Identity::instance();
358b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    }
359b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
360b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com#ifdef PDF_TRACE
361b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    // TODO(edisonn): warning/report
362b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    printf("Unknown CIDToGIDMap: %s\n", name);
363b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com#endif
364b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    return NULL;
365b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com}
366b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.comCIDToGIDMap* fCidToGid;
367b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com*/
3681be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
3691be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.comclass SkPdfType3Font : public SkPdfFont {
370b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    struct Type3FontChar {
3713aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com        SkPdfNativeObject* fObj;
372b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        double fWidth;
373b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    };
374b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
375b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    SkPdfDictionary* fCharProcs;
376b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    SkPdfEncodingDictionary* fEncodingDict;
377b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    unsigned int fFirstChar;
378b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    unsigned int fLastChar;
379b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
380b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    SkRect fFontBBox;
381b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    SkMatrix fFonMatrix;
382b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
383b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com    Type3FontChar* fChars;
384b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
3851be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
3863aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    SkPdfType3Font(SkPdfNativeDoc* parsed, SkPdfType3FontDictionary* dict) {
387571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        fBaseFont = fontFromName(parsed, dict, dict->BaseFont(parsed).c_str());
388b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
389b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        if (dict->has_Encoding()) {
390571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            if (dict->isEncodingAName(parsed)) {
391571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                 fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName(parsed).c_str());
392571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            } else if (dict->isEncodingAEncodingdictionary(parsed)) {
3932fd5d36ea6e134647aae0fbd35195500723851c3edisonn@google.com                 // No encoding.
3942fd5d36ea6e134647aae0fbd35195500723851c3edisonn@google.com                 fEncoding = SkPdfDefaultEncoding::instance();
395571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                 fEncodingDict = dict->getEncodingAsEncodingdictionary(parsed);
396b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            }
397b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
398b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
399b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        // null?
400571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        fCharProcs = dict->CharProcs(parsed);
401b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
402b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        fToUnicode = NULL;
403b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        if (dict->has_ToUnicode()) {
404571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            fToUnicode = new SkPdfToUnicode(parsed, dict->ToUnicode(parsed));
405b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
406b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
407a3356fce903ff75dc332b53dd3a860ba810b9519edisonn@google.com        fFirstChar = (unsigned int)dict->FirstChar(parsed);
408a3356fce903ff75dc332b53dd3a860ba810b9519edisonn@google.com        fLastChar = (unsigned int)dict->LastChar(parsed);
409571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        fFonMatrix = dict->has_FontMatrix() ? dict->FontMatrix(parsed) : SkMatrix::I();
410b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
411571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (dict->has_FontBBox()) {
412571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            fFontBBox = dict->FontBBox(parsed);
413b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
414b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
415b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        fChars = new Type3FontChar[fLastChar - fFirstChar + 1];
416b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
417b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        memset(fChars, 0, sizeof(fChars[0]) * (fLastChar - fFirstChar + 1));
418b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
419571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        const SkPdfArray* widths = dict->Widths(parsed);
420571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        for (unsigned int i = 0 ; i < widths->size(); i++) {
421ac4bedcb1098416e46f1907b03878787df6342ceedisonn@google.com            if ((fFirstChar + i) >= fFirstChar && (fFirstChar + i) <= fLastChar) {
422ac4bedcb1098416e46f1907b03878787df6342ceedisonn@google.com                fChars[i].fWidth = (*widths)[i]->numberValue();
423ac4bedcb1098416e46f1907b03878787df6342ceedisonn@google.com            } else {
424ac4bedcb1098416e46f1907b03878787df6342ceedisonn@google.com                // TODO(edisonn): report pdf corruption
425b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            }
426b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
427b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
428571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        const SkPdfArray* diffs = fEncodingDict->Differences(parsed);
429571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        unsigned int j = fFirstChar;
430571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        for (unsigned int i = 0 ; i < diffs->size(); i++) {
431571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            if ((*diffs)[i]->isInteger()) {
432a3356fce903ff75dc332b53dd3a860ba810b9519edisonn@google.com                j = (unsigned int)(*diffs)[i]->intValue();
433571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            } else if ((*diffs)[i]->isName()) {
434ac4bedcb1098416e46f1907b03878787df6342ceedisonn@google.com                if (j >= fFirstChar && j <= fLastChar) {
435ac4bedcb1098416e46f1907b03878787df6342ceedisonn@google.com                    fChars[j - fFirstChar].fObj = fCharProcs->get((*diffs)[i]);
436ac4bedcb1098416e46f1907b03878787df6342ceedisonn@google.com                } else {
437ac4bedcb1098416e46f1907b03878787df6342ceedisonn@google.com                    // TODO(edisonn): report pdf corruption
438b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com                }
439b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com                j++;
440b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            } else {
441ac4bedcb1098416e46f1907b03878787df6342ceedisonn@google.com                // TODO(edisonn): report bad pdf
442b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            }
443b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
4441be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
4451be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
4461be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.compublic:
447e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com    virtual double drawOneChar(unsigned int ch, SkPaint* paint, SkPdfContext* pdfContext,
448e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                               SkCanvas* canvas) {
449b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        if (ch < fFirstChar || ch > fLastChar || !fChars[ch - fFirstChar].fObj) {
4506e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com            return fBaseFont->drawOneChar(ToUnicode(ch), paint, pdfContext, canvas);
451b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
452b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com
453b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com#ifdef PDF_TRACE
454b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        printf("Type 3 char to unicode: %c\n", ToUnicode(ch));
455b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        if (ToUnicode(ch) == 'A') {
456b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com            printf("break;\n");
457b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com        }
458b857a0c7de8cffb09281fa59591649fb1db6ad0aedisonn@google.com#endif
4591be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
460571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        // TODO(edisonn): is it better to resolve the reference at load time, or now?
461e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com        doType3Char(pdfContext,
462e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                    canvas,
463e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                    pdfContext->fPdfDoc->resolveReference(fChars[ch - fFirstChar].fObj),
464e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                    fFontBBox,
465e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                    fFonMatrix,
466e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                    pdfContext->fGraphicsState.fCurFontSize);
4671be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
4686e49c345b132ca55830c7dad746108cd3624eb8bedisonn@google.com        // TODO(edisonn): verify/test translate code, not tested yet
469e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com        pdfContext->fGraphicsState.fMatrixTm.preTranslate(
470e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSize *
471e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                                     fChars[ch - fFirstChar].fWidth),
472e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                SkDoubleToScalar(0.0));
473571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fChars[ch - fFirstChar].fWidth;
4741be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com    }
4751be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
476e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com    virtual void afterWord(SkPaint* paint, SkMatrix* matrix) {}
4771be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com};
4781be794fad6bef2b1ab98158bd3ad68dc4a52dbf6edisonn@google.com
479cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com#endif  // SkPdfFont_DEFINED
480