| Index: experimental/PdfViewer/SkPdfFont.cpp | 
| =================================================================== | 
| --- experimental/PdfViewer/SkPdfFont.cpp	(revision 9879) | 
| +++ experimental/PdfViewer/SkPdfFont.cpp	(working copy) | 
| @@ -3,7 +3,7 @@ | 
|  | 
| #include "SkStream.h" | 
| #include "SkTypeface.h" | 
| -#include "SkPdfPodofoTokenizer.h" | 
| +#include "SkPdfNativeTokenizer.h" | 
|  | 
| std::map<std::string, SkPdfStandardFontEntry>& getStandardFonts() { | 
| static std::map<std::string, SkPdfStandardFontEntry> gPdfStandardFonts; | 
| @@ -149,28 +149,28 @@ | 
| return typeface; | 
| } | 
|  | 
| -SkPdfFont* SkPdfFont::fontFromFontDescriptor(SkPdfFontDescriptorDictionary* fd, bool loadFromName) { | 
| -    // TODO(edisonn): partial implementation | 
| +SkPdfFont* SkPdfFont::fontFromFontDescriptor(SkNativeParsedPDF* doc, SkPdfFontDescriptorDictionary* fd, bool loadFromName) { | 
| +    // TODO(edisonn): partial implementation ... also const handling ... | 
| // Only one, at most be available | 
| SkPdfStream* pdfStream = NULL; | 
| if (fd->has_FontFile()) { | 
| -        pdfStream = fd->FontFile(); | 
| +        pdfStream = fd->FontFile(doc); | 
| } else if (fd->has_FontFile2()) { | 
| -        pdfStream = fd->FontFile2(); | 
| +        pdfStream = fd->FontFile2(doc); | 
| } if (fd->has_FontFile3()) { | 
| -        pdfStream = fd->FontFile3(); | 
| +        pdfStream = fd->FontFile3(doc); | 
| } else { | 
| if (loadFromName) { | 
| -            return fontFromName(fd, fd->FontName().c_str()); | 
| +            return fontFromName(doc, fd, fd->FontName(doc).c_str()); | 
| } | 
| } | 
|  | 
| -    char* uncompressedStream = NULL; | 
| -    long uncompressedStreamLength = 0; | 
| +    unsigned char* uncompressedStream = NULL; | 
| +    size_t uncompressedStreamLength = 0; | 
|  | 
| // TODO(edisonn): report warning to be used in testing. | 
| if (!pdfStream || | 
| -            !pdfStream->GetFilteredCopy(&uncompressedStream, &uncompressedStreamLength) || | 
| +            !pdfStream->GetFilteredStreamRef(&uncompressedStream, &uncompressedStreamLength, doc->allocator()) || | 
| !uncompressedStream || | 
| !uncompressedStreamLength) { | 
| return NULL; | 
| @@ -189,26 +189,32 @@ | 
| return new SkPdfStandardFont(face); | 
| } | 
|  | 
| -SkPdfFont* fontFromName(SkPdfObject* obj, const char* fontName) { | 
| +SkPdfFont* fontFromName(SkNativeParsedPDF* doc, SkPdfObject* obj, const char* fontName) { | 
| SkTypeface* typeface = SkTypefaceFromPdfStandardFont(fontName, false, false); | 
| if (typeface != NULL) { | 
| return new SkPdfStandardFont(typeface); | 
| } | 
|  | 
| // TODO(edisonn): perf - make a map | 
| -    for (int i = 0 ; i < obj->doc()->objects(); i++) { | 
| -        const SkPdfObject* podofoFont = obj->doc()->object(i); | 
| -        SkPdfFontDescriptorDictionary* fd = NULL; | 
| +    for (unsigned int i = 0 ; i < doc->objects(); i++) { | 
| +        SkPdfObject* obj = doc->object(i); | 
| +        if (!obj->isDictionary()) { | 
| +            continue; | 
| +        } | 
|  | 
| -        if (obj->doc()->mapper()->mapFontDescriptorDictionary(podofoFont, &fd)) { | 
| -            if (fd->has_FontName() && fd->FontName() == fontName) { | 
| -                SkPdfFont* font = SkPdfFont::fontFromFontDescriptor(fd, false); | 
| -                if (font) { | 
| -                    return font; | 
| -                } else { | 
| -                    // failed to load font descriptor | 
| -                    break; | 
| -                } | 
| +        SkPdfFontDescriptorDictionary* fd = obj->asDictionary()->asFontDescriptorDictionary(); | 
| + | 
| +        if (!fd->valid()) { | 
| +            continue; | 
| +        } | 
| + | 
| +        if (fd->has_FontName() && fd->FontName(doc) == fontName) { | 
| +            SkPdfFont* font = SkPdfFont::fontFromFontDescriptor(doc, fd, false); | 
| +            if (font) { | 
| +                return font; | 
| +            } else { | 
| +                // failed to load font descriptor | 
| +                break; | 
| } | 
| } | 
| } | 
| @@ -217,86 +223,106 @@ | 
| return SkPdfFont::Default(); | 
| } | 
|  | 
| -SkPdfFont* SkPdfFont::fontFromPdfDictionary(SkPdfFontDictionary* dict) { | 
| -    if (dict == NULL) { | 
| -        return NULL;  // TODO(edisonn): report default one? | 
| -    } | 
| - | 
| -    switch (dict->getType()) { | 
| +SkPdfFont* SkPdfFont::fontFromPdfDictionaryOnce(SkNativeParsedPDF* doc, SkPdfFontDictionary* dict) { | 
| +    // TODO(edisonn): keep the type in a smart way in the SkPdfObject | 
| +    // 1) flag, isResolved (1bit): reset at reset, add/remove/update (array) and set(dict) | 
| +    // in a tree like structure, 3-4 bits for all the datatypes inheriting from obj (int, real, ...) | 
| +    // if is a dict, reserveve a few bytes to encode type of dict, and so on like in a tree | 
| +    // issue: type can be determined from context! atribute night be missing/wrong | 
| +    switch (doc->mapper()->mapFontDictionary(dict)) { | 
| case kType0FontDictionary_SkPdfObjectType: | 
| -            return fontFromType0FontDictionary(dict->asType0FontDictionary()); | 
| +            return fontFromType0FontDictionary(doc, dict->asType0FontDictionary()); | 
|  | 
| case kTrueTypeFontDictionary_SkPdfObjectType: | 
| -            return fontFromTrueTypeFontDictionary(dict->asTrueTypeFontDictionary()); | 
| +            return fontFromTrueTypeFontDictionary(doc, dict->asTrueTypeFontDictionary()); | 
|  | 
| case kType1FontDictionary_SkPdfObjectType: | 
| -            return fontFromType1FontDictionary(dict->asType1FontDictionary()); | 
| +            return fontFromType1FontDictionary(doc, dict->asType1FontDictionary()); | 
|  | 
| case kMultiMasterFontDictionary_SkPdfObjectType: | 
| -            return fontFromMultiMasterFontDictionary(dict->asMultiMasterFontDictionary()); | 
| +            return fontFromMultiMasterFontDictionary(doc, dict->asMultiMasterFontDictionary()); | 
|  | 
| case kType3FontDictionary_SkPdfObjectType: | 
| -            return fontFromType3FontDictionary(dict->asType3FontDictionary()); | 
| +            return fontFromType3FontDictionary(doc, dict->asType3FontDictionary()); | 
| + | 
| +        default: | 
| +            // TODO(edisonn): report error? | 
| +            return NULL; | 
| } | 
| -    return NULL;  // TODO(edisonn): report error? | 
| } | 
|  | 
| -SkPdfType0Font* SkPdfFont::fontFromType0FontDictionary(SkPdfType0FontDictionary* dict) { | 
| +SkPdfFont* SkPdfFont::fontFromPdfDictionary(SkNativeParsedPDF* doc, SkPdfFontDictionary* dict) { | 
| if (dict == NULL) { | 
| +        return NULL;  // TODO(edisonn): report default one? | 
| +    } | 
| + | 
| +    if (dict->data() == NULL) { | 
| +        dict->setData(fontFromPdfDictionaryOnce(doc, dict)); | 
| +    } | 
| +    return (SkPdfFont*)dict->data(); | 
| +} | 
| + | 
| + | 
| + | 
| +SkPdfType0Font* SkPdfFont::fontFromType0FontDictionary(SkNativeParsedPDF* doc, SkPdfType0FontDictionary* dict) { | 
| +    if (dict == NULL) { | 
| return NULL;  // default one? | 
| } | 
|  | 
| -    return new SkPdfType0Font(dict); | 
| +    return new SkPdfType0Font(doc, dict); | 
| } | 
|  | 
| -SkPdfType1Font* SkPdfFont:: fontFromType1FontDictionary(SkPdfType1FontDictionary* dict) { | 
| +SkPdfType1Font* SkPdfFont:: fontFromType1FontDictionary(SkNativeParsedPDF* doc, SkPdfType1FontDictionary* dict) { | 
| if (dict == NULL) { | 
| return NULL;  // default one? | 
| } | 
|  | 
| -    return new SkPdfType1Font(dict); | 
| +    return new SkPdfType1Font(doc, dict); | 
| } | 
|  | 
| -SkPdfType3Font* SkPdfFont::fontFromType3FontDictionary(SkPdfType3FontDictionary* dict) { | 
| +SkPdfType3Font* SkPdfFont::fontFromType3FontDictionary(SkNativeParsedPDF* doc, SkPdfType3FontDictionary* dict) { | 
| if (dict == NULL) { | 
| return NULL;  // default one? | 
| } | 
|  | 
|  | 
|  | 
| -    return new SkPdfType3Font(dict); | 
| +    return new SkPdfType3Font(doc, dict); | 
| } | 
|  | 
| -SkPdfTrueTypeFont* SkPdfFont::fontFromTrueTypeFontDictionary(SkPdfTrueTypeFontDictionary* dict) { | 
| +SkPdfTrueTypeFont* SkPdfFont::fontFromTrueTypeFontDictionary(SkNativeParsedPDF* doc, SkPdfTrueTypeFontDictionary* dict) { | 
| if (dict == NULL) { | 
| return NULL;  // default one? | 
| } | 
|  | 
| -    return new SkPdfTrueTypeFont(dict); | 
| +    return new SkPdfTrueTypeFont(doc, dict); | 
| } | 
|  | 
| -SkPdfMultiMasterFont* SkPdfFont::fontFromMultiMasterFontDictionary(SkPdfMultiMasterFontDictionary* dict) { | 
| +SkPdfMultiMasterFont* SkPdfFont::fontFromMultiMasterFontDictionary(SkNativeParsedPDF* doc, SkPdfMultiMasterFontDictionary* dict) { | 
| if (dict == NULL) { | 
| return NULL;  // default one? | 
| } | 
|  | 
| -    return new SkPdfMultiMasterFont(dict); | 
| +    return new SkPdfMultiMasterFont(doc, dict); | 
| } | 
|  | 
| -static int skstoi(const SkPdfString* str) { | 
| +static int skstoi(const SkPdfObject* str) { | 
| +    // TODO(edisonn): report err of it is not a (hex) string | 
| int ret = 0; | 
| -    for (int i = 0 ; i < str->len(); i++) { | 
| +    for (unsigned int i = 0 ; i < str->len(); i++) { | 
| ret = (ret << 8) + ((unsigned char*)str->c_str())[i]; | 
| } | 
| return ret; | 
| } | 
|  | 
| -SkPdfToUnicode::SkPdfToUnicode(const SkPdfStream* stream) { | 
| +#define tokenIsKeyword(token,keyword) (token.fType == kKeyword_TokenType && token.fKeywordLength==sizeof(keyword)-1 && strncmp(token.fKeyword, keyword, sizeof(keyword)-1) == 0) | 
| + | 
| +SkPdfToUnicode::SkPdfToUnicode(SkNativeParsedPDF* parsed, SkPdfStream* stream) : fParsed(parsed) { | 
| fCMapEncoding = NULL; | 
| fCMapEncodingFlag = NULL; | 
|  | 
| if (stream) { | 
| -        SkPdfPodofoTokenizer* tokenizer = stream->doc()->tokenizerOfStream(stream); | 
| +        SkPdfNativeTokenizer* tokenizer = fParsed->tokenizerOfStream(stream); | 
| PdfToken token; | 
|  | 
| fCMapEncoding = new unsigned short[256 * 256]; | 
| @@ -314,48 +340,50 @@ | 
|  | 
| while (tokenizer->readToken(&token)) { | 
|  | 
| -            if (token.fType == kKeyword_TokenType && strcmp(token.fKeyword, "begincodespacerange") == 0) { | 
| -                while (tokenizer->readToken(&token) && !(token.fType == kKeyword_TokenType && strcmp(token.fKeyword, "endcodespacerange") == 0)) { | 
| +            // TODO(edisonn): perf, macro that would make equal first for token.fKeywordLength with sizeof(keyword), instead od strlen, make sure it is keyword, not a char* | 
| +            if (tokenIsKeyword(token, "begincodespacerange")) { | 
| +                while (tokenizer->readToken(&token) && !tokenIsKeyword(token, "endcodespacerange")) { | 
| //                    tokenizer->PutBack(token); | 
| //                    tokenizer->readToken(&token); | 
| // TODO(edisonn): check token type! ignore/report errors. | 
| -                    int start = skstoi(token.fObject->asString()); | 
| +                    int start = skstoi(token.fObject); | 
| tokenizer->readToken(&token); | 
| -                    int end = skstoi(token.fObject->asString()); | 
| +                    int end = skstoi(token.fObject); | 
| for (int i = start; i <= end; i++) { | 
| fCMapEncodingFlag[i] |= 1; | 
| } | 
| } | 
| } | 
|  | 
| -            if (token.fType == kKeyword_TokenType && strcmp(token.fKeyword, "beginbfchar") == 0) { | 
| -                while (tokenizer->readToken(&token) && !(token.fType == kKeyword_TokenType && strcmp(token.fKeyword, "endbfchar") == 0)) { | 
| +            if (tokenIsKeyword(token, "beginbfchar")) { | 
| +                while (tokenizer->readToken(&token) && !tokenIsKeyword(token, "endbfchar")) { | 
| //                    tokenizer->PutBack(token); | 
| //                    tokenizer->readToken(&token); | 
| -                    int from = skstoi(token.fObject->asString()); | 
| +                    int from = skstoi(token.fObject); | 
| tokenizer->readToken(&token); | 
| -                    int to = skstoi(token.fObject->asString()); | 
| +                    int to = skstoi(token.fObject); | 
|  | 
| fCMapEncodingFlag[from] |= 2; | 
| fCMapEncoding[from] = to; | 
| } | 
| } | 
|  | 
| -            if (token.fType == kKeyword_TokenType && strcmp(token.fKeyword, "beginbfrange") == 0) { | 
| -                while (tokenizer->readToken(&token) && !(token.fType == kKeyword_TokenType && strcmp(token.fKeyword, "endbfrange") == 0)) { | 
| +            if (tokenIsKeyword(token, "beginbfrange")) { | 
| +                while (tokenizer->readToken(&token) && !tokenIsKeyword(token, "endbfrange")) { | 
| //                    tokenizer->PutBack(token); | 
| //                    tokenizer->readToken(&token); | 
| -                    int start = skstoi(token.fObject->asString()); | 
| +                    int start = skstoi(token.fObject); | 
| tokenizer->readToken(&token); | 
| -                    int end = skstoi(token.fObject->asString()); | 
| +                    int end = skstoi(token.fObject); | 
|  | 
|  | 
| tokenizer->readToken(&token); // [ or just an array directly? | 
| //                    tokenizer->PutBack(token); | 
|  | 
| -                    if (token.fType == kObject_TokenType && token.fObject->asString()) { | 
| +                    // TODO(edisonn): read spec: any string or only hex string? | 
| +                    if (token.fType == kObject_TokenType && token.fObject->isAnyString()) { | 
| //                        tokenizer->readToken(&token); | 
| -                        int value = skstoi(token.fObject->asString()); | 
| +                        int value = skstoi(token.fObject); | 
|  | 
| for (int i = start; i <= end; i++) { | 
| fCMapEncodingFlag[i] |= 2; | 
| @@ -365,11 +393,11 @@ | 
| } | 
|  | 
| // read one string | 
| -                    } else if (token.fType == kObject_TokenType && token.fObject->asArray()) { | 
| +                    } else if (token.fType == kObject_TokenType && token.fObject->isArray()) { | 
| //                        tokenizer->readToken(&token); | 
| -                        for (int i = 0; i < token.fObject->asArray()->size(); i++) { | 
| +                        for (unsigned int i = 0; i < token.fObject->size(); i++) { | 
| fCMapEncodingFlag[start + i] |= 2; | 
| -                            fCMapEncoding[start + i] = skstoi((*token.fObject->asArray())[i]->asString()); | 
| +                            fCMapEncoding[start + i] = skstoi((*token.fObject)[i]); | 
| } | 
| // read array | 
| } | 
| @@ -383,14 +411,14 @@ | 
| } | 
|  | 
|  | 
| -SkPdfType0Font::SkPdfType0Font(SkPdfType0FontDictionary* dict) { | 
| -    fBaseFont = fontFromName(dict, dict->BaseFont().c_str()); | 
| +SkPdfType0Font::SkPdfType0Font(SkNativeParsedPDF* doc, SkPdfType0FontDictionary* dict) { | 
| +    fBaseFont = fontFromName(doc, dict, dict->BaseFont(doc).c_str()); | 
| fEncoding = NULL; | 
|  | 
| if (dict->has_Encoding()) { | 
| -        if (dict->isEncodingAName()) { | 
| -            fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName().c_str()); | 
| -        } else if (dict->isEncodingAStream()) { | 
| +        if (dict->isEncodingAName(doc)) { | 
| +            fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName(doc).c_str()); | 
| +        } else if (dict->isEncodingAStream(doc)) { | 
| //fEncoding = loadEncodingFromStream(dict->getEncodingAsStream()); | 
| } else { | 
| // TODO(edisonn): error ... warning .. assert? | 
| @@ -398,7 +426,7 @@ | 
| } | 
|  | 
| if (dict->has_ToUnicode()) { | 
| -        fToUnicode = new SkPdfToUnicode(dict->ToUnicode()); | 
| +        fToUnicode = new SkPdfToUnicode(doc, dict->ToUnicode(doc)); | 
| } | 
| } | 
|  | 
|  |