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)); |
} |
} |