aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--experimental/PdfViewer/SkPdfBasics.h6
-rw-r--r--experimental/PdfViewer/SkPdfFont.cpp2
-rw-r--r--experimental/PdfViewer/SkPdfFont.h2
-rw-r--r--experimental/PdfViewer/SkPdfRenderer.cpp107
-rw-r--r--experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp4
-rw-r--r--experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp4
-rw-r--r--experimental/PdfViewer/pdfparser/native/SkPdfObject.h2
-rw-r--r--experimental/PdfViewer/spec2def.py53
-rw-r--r--gyp/pdfviewer.gyp2
9 files changed, 163 insertions, 19 deletions
diff --git a/experimental/PdfViewer/SkPdfBasics.h b/experimental/PdfViewer/SkPdfBasics.h
index 74ab9e68d9..30c92b63ec 100644
--- a/experimental/PdfViewer/SkPdfBasics.h
+++ b/experimental/PdfViewer/SkPdfBasics.h
@@ -189,7 +189,8 @@ blend mode name or array (PDF 1.4) The current blend mode to be used in t
transparency group XObject (see Section 7.5.5, “Transparency
Group XObjects”). Initial value: Normal.
*/
- SkXfermode::Mode fBlendMode;
+ SkXfermode::Mode fBlendModes[256];
+ int fBlendModesLength;
/*
soft mask dictionary (PDF 1.4) A soft-mask dictionary (see “Soft-Mask Dictionaries” on
@@ -327,7 +328,8 @@ smoothness number (PDF 1.3) The precision with which col
fAlphaSource = false;
fDashArrayLength = 0;
fDashPhase = 0;
- fBlendMode = SkXfermode::kSrc_Mode; // PDF: Normal Blend mode
+ fBlendModesLength = 1;
+ fBlendModes[0] = SkXfermode::kSrc_Mode; // PDF: Normal Blend mode
}
// TODO(edisonn): make two functons instead, stroking and non stoking, avoid branching
diff --git a/experimental/PdfViewer/SkPdfFont.cpp b/experimental/PdfViewer/SkPdfFont.cpp
index 0a8420c84b..ac96f02efa 100644
--- a/experimental/PdfViewer/SkPdfFont.cpp
+++ b/experimental/PdfViewer/SkPdfFont.cpp
@@ -308,7 +308,7 @@ SkPdfMultiMasterFont* SkPdfFont::fontFromMultiMasterFontDictionary(SkNativeParse
static int skstoi(const SkPdfObject* str) {
// TODO(edisonn): report err of it is not a (hex) string
int ret = 0;
- for (unsigned int i = 0 ; i < str->len(); i++) {
+ for (unsigned int i = 0 ; i < str->lenstr(); i++) {
ret = (ret << 8) + ((unsigned char*)str->c_str())[i];
}
// TODO(edisonn): character larger than 0x0000ffff not supported right now.
diff --git a/experimental/PdfViewer/SkPdfFont.h b/experimental/PdfViewer/SkPdfFont.h
index 4929a80749..58c91b6271 100644
--- a/experimental/PdfViewer/SkPdfFont.h
+++ b/experimental/PdfViewer/SkPdfFont.h
@@ -47,7 +47,7 @@ struct SkUnencodedText {
public:
SkUnencodedText(const SkPdfString* obj) {
text = (void*)obj->c_str();
- len = obj->len();
+ len = obj->lenstr();
}
};
diff --git a/experimental/PdfViewer/SkPdfRenderer.cpp b/experimental/PdfViewer/SkPdfRenderer.cpp
index e7bfdb6c6d..e2805c74f8 100644
--- a/experimental/PdfViewer/SkPdfRenderer.cpp
+++ b/experimental/PdfViewer/SkPdfRenderer.cpp
@@ -668,6 +668,11 @@ static PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, SkPdfT
// TODO(edisonn): iterate smart on the stream even if it is compressed, tokenize it as we go.
// For this PdfContentsTokenizer needs to be extended.
+ // This is a group?
+ if (skobj->has_Group()) {
+ //TransparencyGroupDictionary* ...
+ }
+
SkPdfStream* stream = (SkPdfStream*)skobj;
SkPdfNativeTokenizer* tokenizer =
@@ -1582,20 +1587,112 @@ void skpdfGraphicsStateApplyFont(PdfContext* pdfContext, SkPdfArray* fontAndSize
skpdfGraphicsStateApplyFontCore(pdfContext, fontAndSize->objAtAIndex(0), fontAndSize->objAtAIndex(1)->numberValue());
}
+SkTDict<SkXfermode::Mode> gPdfBlendModes(20);
+
+class InitBlendModes {
+public:
+ InitBlendModes() {
+ // TODO(edisonn): use the python code generator?
+ // TABLE 7.2 Standard separable blend modes
+ gPdfBlendModes.set("Normal", SkXfermode::kSrc_Mode);
+ gPdfBlendModes.set("Multiply", SkXfermode::kMultiply_Mode);
+ gPdfBlendModes.set("Screen", SkXfermode::kScreen_Mode);
+ gPdfBlendModes.set("Overlay", SkXfermode::kOverlay_Mode);
+ gPdfBlendModes.set("Darken", SkXfermode::kDarken_Mode);
+ gPdfBlendModes.set("Lighten", SkXfermode::kLighten_Mode);
+ gPdfBlendModes.set("ColorDodge", SkXfermode::kColorDodge_Mode);
+ gPdfBlendModes.set("ColorBurn", SkXfermode::kColorBurn_Mode);
+ gPdfBlendModes.set("HardLight", SkXfermode::kHardLight_Mode);
+ gPdfBlendModes.set("SoftLight", SkXfermode::kSoftLight_Mode);
+ gPdfBlendModes.set("Difference", SkXfermode::kDifference_Mode);
+ gPdfBlendModes.set("Exclusion", SkXfermode::kExclusion_Mode);
+
+ // TABLE 7.3 Standard nonseparable blend modes
+ gPdfBlendModes.set("Hue", SkXfermode::kHue_Mode);
+ gPdfBlendModes.set("Saturation", SkXfermode::kSaturation_Mode);
+ gPdfBlendModes.set("Color", SkXfermode::kColor_Mode);
+ gPdfBlendModes.set("Luminosity", SkXfermode::kLuminosity_Mode);
+ }
+};
+
+InitBlendModes _gDummyInniter;
+
+SkXfermode::Mode xferModeFromBlendMode(const char* blendMode, size_t len) {
+ SkXfermode::Mode mode = (SkXfermode::Mode)(SkXfermode::kLastMode + 1);
+ if (gPdfBlendModes.find(blendMode, len, &mode)) {
+ return mode;
+ }
+
+ return (SkXfermode::Mode)(SkXfermode::kLastMode + 1);
+}
+
void skpdfGraphicsStateApplyBM_name(PdfContext* pdfContext, const std::string& blendMode) {
- // TODO(edisonn): verify input
+ SkXfermode::Mode mode = xferModeFromBlendMode(blendMode.c_str(), blendMode.length());
+ if (mode <= SkXfermode::kLastMode) {
+ pdfContext->fGraphicsState.fBlendModesLength = 1;
+ pdfContext->fGraphicsState.fBlendModes[0] = mode;
+ } else {
+ // TODO(edisonn): report unknown blend mode
+ }
}
void skpdfGraphicsStateApplyBM_array(PdfContext* pdfContext, SkPdfArray* blendModes) {
- // TODO(edisonn): verify input
-}
+ if (!blendModes || blendModes->isArray() || blendModes->size() == 0 || blendModes->size() > 256) {
+ // TODO(edisonn): report error/warning
+ return;
+ }
+ SkXfermode::Mode modes[256];
+ int cnt = blendModes->size();
+ for (int i = 0; i < cnt; i++) {
+ SkPdfObject* name = blendModes->objAtAIndex(i);
+ if (!name->isName()) {
+ // TODO(edisonn): report error/warning
+ return;
+ }
+ SkXfermode::Mode mode = xferModeFromBlendMode(name->c_str(), name->lenstr());
+ if (mode > SkXfermode::kLastMode) {
+ // TODO(edisonn): report error/warning
+ return;
+ }
+ }
-void skpdfGraphicsStateApplySMask_name(PdfContext* pdfContext, const std::string& sMask) {
- // TODO(edisonn): verify input
+ pdfContext->fGraphicsState.fBlendModesLength = cnt;
+ for (int i = 0; i < cnt; i++) {
+ pdfContext->fGraphicsState.fBlendModes[i] = modes[i];
+ }
}
void skpdfGraphicsStateApplySMask_dict(PdfContext* pdfContext, SkPdfDictionary* sMask) {
// TODO(edisonn): verify input
+ if (pdfContext->fPdfDoc->mapper()->mapSoftMaskDictionary(sMask)) {
+ //SkPdfSoftMaskDictionary* smd = (SkPdfSoftMaskDictionary*)sMask;
+ // TODO(edisonn): load soft mask
+ } else if (pdfContext->fPdfDoc->mapper()->mapSoftMaskImageDictionary(sMask)) {
+ SkPdfSoftMaskImageDictionary* smid = (SkPdfSoftMaskImageDictionary*)sMask;
+ pdfContext->fGraphicsState.fSMask = getImageFromObject(pdfContext, smid, true);
+ } else {
+ // TODO (edisonn): report error/warning
+ }
+}
+
+void skpdfGraphicsStateApplySMask_name(PdfContext* pdfContext, const std::string& sMask) {
+ //Next, get the ExtGState Dictionary from the Resource Dictionary:
+ SkPdfDictionary* extGStateDictionary = pdfContext->fGraphicsState.fResources->ExtGState(pdfContext->fPdfDoc);
+
+ if (extGStateDictionary == NULL) {
+#ifdef PDF_TRACE
+ printf("ExtGState is NULL!\n");
+#endif
+ // TODO (edisonn): report error/warning
+ return;
+ }
+
+ SkPdfObject* obj = pdfContext->fPdfDoc->resolveReference(extGStateDictionary->get(sMask.c_str()));
+ if (!obj || !obj->isDictionary()) {
+ // TODO (edisonn): report error/warning
+ return;
+ }
+ skpdfGraphicsStateApplySMask_dict(pdfContext, obj->asDictionary());
}
void skpdfGraphicsStateApplyAIS(PdfContext* pdfContext, bool alphaSource) {
diff --git a/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp b/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp
index 8f92a0fcfe..8892ee2643 100644
--- a/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp
+++ b/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp
@@ -196,7 +196,7 @@ const unsigned char* SkNativeParsedPDF::readCrossReferenceSection(const unsigned
token.reset();
current = nextObject(0, current, trailerEnd, &token, NULL, NULL);
- if (!token.isKeyword() || token.len() != 1 || (*token.c_str() != 'f' && *token.c_str() != 'n')) {
+ if (!token.isKeyword() || token.lenstr() != 1 || (*token.c_str() != 'f' && *token.c_str() != 'n')) {
// TODO(edisonn): report/warning
return current;
}
@@ -215,7 +215,7 @@ long SkNativeParsedPDF::readTrailer(const unsigned char* trailerStart, const uns
const unsigned char* current =
nextObject(0, trailerStart, trailerEnd, &trailerKeyword, NULL, NULL);
- if (!trailerKeyword.isKeyword() || strlen("trailer") != trailerKeyword.len() ||
+ if (!trailerKeyword.isKeyword() || strlen("trailer") != trailerKeyword.lenstr() ||
strncmp(trailerKeyword.c_str(), "trailer", strlen("trailer")) != 0) {
// TODO(edisonn): report warning, rebuild trailer from objects.
return -1;
diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp b/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp
index bc3a3faa79..41bd92d170 100644
--- a/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp
+++ b/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp
@@ -927,7 +927,7 @@ bool SkPdfNativeTokenizer::readTokenCore(PdfToken* token) {
// If it is a keyword, we will only get the pointer of the string
if (obj.type() == SkPdfObject::kKeyword_PdfObjectType) {
token->fKeyword = obj.c_str();
- token->fKeywordLength = obj.len();
+ token->fKeywordLength = obj.lenstr();
token->fType = kKeyword_TokenType;
} else {
SkPdfObject* pobj = fAllocator->allocObject();
@@ -1062,7 +1062,7 @@ SkPdfImageDictionary* SkPdfNativeTokenizer::readInlineImage() {
SkPdfObject* key = fAllocator->allocObject();
fUncompressedStream = nextObject(0, fUncompressedStream, fUncompressedStreamEnd, key, fAllocator, fDoc);
- if (key->isKeyword() && key->len() == 2 && key->c_str()[0] == 'I' && key->c_str()[1] == 'D') { // ID
+ if (key->isKeyword() && key->lenstr() == 2 && key->c_str()[0] == 'I' && key->c_str()[1] == 'D') { // ID
fUncompressedStream = readInlineImageStream(0, fUncompressedStream, fUncompressedStreamEnd, inlineImage, fDoc);
return inlineImage;
} else {
diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfObject.h b/experimental/PdfViewer/pdfparser/native/SkPdfObject.h
index 5525f7baf9..9df9a239e6 100644
--- a/experimental/PdfViewer/pdfparser/native/SkPdfObject.h
+++ b/experimental/PdfViewer/pdfparser/native/SkPdfObject.h
@@ -131,7 +131,7 @@ public:
}
}
- size_t len() const {
+ size_t lenstr() const {
switch (fObjectType) {
case kString_PdfObjectType:
case kHexString_PdfObjectType:
diff --git a/experimental/PdfViewer/spec2def.py b/experimental/PdfViewer/spec2def.py
index 0f9d684cee..f1ab8a7f16 100644
--- a/experimental/PdfViewer/spec2def.py
+++ b/experimental/PdfViewer/spec2def.py
@@ -116,9 +116,9 @@ tableToClassName = {
'TABLE 6.5': ['Type10HalftoneDictionary', 'Additional entries specific to a type 10 halftone dictionary'],
'TABLE 6.6': ['Type16HalftoneDictionary', 'Additional entries specific to a type 16 halftone dictionary'],
'TABLE 6.7': ['Type5HalftoneDictionary', 'Entries in a type 5 halftone dictionary'],
-'TABLE 7.10': ['SoftMaskDictionary', 'Entries in a soft-mask dictionary'],
-'TABLE 7.12': ['SoftMaskImageDictionary', 'Additional entry in a soft-mask image dictionary'],
-'TABLE 7.13': ['TransparencyGroupDictionary', 'Additional entries specific to a transparency group attributes dictionary'],
+'TABLE 7.10': ['SoftMaskDictionary', 'Entries in a soft-mask dictionary', '', {'S': '[datatypes.PdfName(\'Alpha\'), datatypes.PdfName(\'Luminosity\')]'}],
+'TABLE 7.12': ['SoftMaskImageDictionary', 'Additional entry in a soft-mask image dictionary', 'ImageDictionary', {'Subtype': '[datatypes.PdfName(\'Image\')]', 'ColorSpace': '[datatypes.PdfName(\'DeviceGray\'), datatypes.PdfName(\'Gray\')]'}],
+'TABLE 7.13': ['TransparencyGroupDictionary', 'Additional entries specific to a transparency group attributes dictionary', 'XObjectDictionary', {'S': '[datatypes.PdfName(\'Transparency\')]'}],
'TABLE 8.1': ['ViewerPreferencesDictionary', 'Entries in a viewer preferences dictionary'],
'TABLE 8.3': ['OutlineDictionary', 'Entries in the outline dictionary'],
'TABLE 8.4': ['OutlineItemDictionary', 'Entries in an outline item dictionary'],
@@ -222,6 +222,9 @@ tableToClassName = {
'TABLE 9.49': ['OpiVersionDictionary', 'Entry in an OPI version dictionary'],
}
+classTree = {
+}
+
def buildKnownDictionaries():
global tableToClassName
global knownTypes
@@ -297,6 +300,9 @@ def commitRow(fspecPy):
global emitedDitionaryName
global table
global tableToClassName
+ global classTree
+ global tableKey
+
if columnValues == None:
return
@@ -392,10 +398,13 @@ def commitRow(fspecPy):
emitedDitionaryName = tableToClassName[tableKey][0]
comment = fix(tableToClassName[tableKey][1])
+
if len(tableToClassName[tableKey]) >= 3 and tableToClassName[tableKey][2] != '':
fspecPy.write(' pdfspec.addClass(\'' + emitedDitionaryName + '\', \'' + tableToClassName[tableKey][2] + '\', \'' + comment + '\')\\\n')
+ classTree[emitedDitionaryName] = [tableToClassName[tableKey][2], {}]
else:
fspecPy.write(' pdfspec.addClass(\'' + emitedDitionaryName + '\', \'Dictionary\', \'' + comment + '\')\\\n')
+ classTree[emitedDitionaryName] = ['Dictionary', {}]
if len(tableToClassName[tableKey]) >= 4 and columnValues[0] in tableToClassName[tableKey][3]:
required = True
@@ -409,6 +418,12 @@ def commitRow(fspecPy):
fspecPy.write(' .name(\'' + columnValues[0] + '\')\\\n')
fspecPy.write(' .type(\'' + columnValues[1] + '\')\\\n')
fspecPy.write(' .comment(\'' + columnValues[2] + '\')\\\n')
+
+ classTree[emitedDitionaryName][1][columnValues[0]] = ' .field(\'' + columnValues[0] + '\')\\\n' + \
+ ' .name(\'' + columnValues[0] + '\')\\\n' + \
+ ' .type(\'' + columnValues[1] + '\')\\\n' + \
+ ' .comment(\'\')\\\n'
+
if len(tableToClassName[tableKey]) >= 4 and columnValues[0] in tableToClassName[tableKey][3]:
fspecPy.write(' .must(' + tableToClassName[tableKey][3][columnValues[0]] + ')\\\n')
@@ -461,11 +476,39 @@ def rebaseTable(fspecPy, line):
def stopTable(fspecPy):
global tableHeaderFound
global emitedDitionaryName
-
+ global tableKey
+ global classTree
+
if not inTable():
return
commitRow(fspecPy)
+
+ #print tableKey
+
+ # TODO(edisonn): iterate on all requited key in the def, and if not on the definition, get definition from parent and export them
+ if len(tableToClassName[tableKey]) >= 4:
+ for field in tableToClassName[tableKey][3]:
+ #print field
+ if not field in classTree[emitedDitionaryName][1]:
+ fieldDef = ''
+ searchKey = classTree[emitedDitionaryName][0]
+ while searchKey != 'Dictionary' and (not field in classTree[searchKey][1]):
+ searchKey = classTree[searchKey][0]
+
+ if searchKey != 'Dictionary' and (field in classTree[searchKey][1]):
+ #print tableToClassName[tableKey][3][field]
+ #print classTree[searchKey][1][field]
+ # TODO(edisonns): hack - for required fields, they need to be downgraded to only a type
+ classTree[searchKey][1][field] = classTree[searchKey][1][field].replace(' or array', '')
+ classTree[searchKey][1][field] = classTree[searchKey][1][field].replace(' or distionary', '')
+ fspecPy.write(' .required(\'NULL\')\\\n')
+ fspecPy.write(classTree[searchKey][1][field])
+ fspecPy.write(' .must(' + tableToClassName[tableKey][3][field] + ')\\\n')
+ fspecPy.write(' .done().done()\\\n')
+ else:
+ print 'ERROR' + tableKey + '.' + field;
+
tableHeaderFound = False
emitedDitionaryName = ''
fspecPy.write(' .done()\n')
@@ -569,7 +612,7 @@ def processLineCore(fspecPy, line):
return False
if first != '' and second != '' and third[0] != '(':
- stopTable()
+ stopTable(fspecPy)
return False
if first == '' and second != '' and second[0] == ' ':
diff --git a/gyp/pdfviewer.gyp b/gyp/pdfviewer.gyp
index ad6f92f4db..8552f3be3a 100644
--- a/gyp/pdfviewer.gyp
+++ b/gyp/pdfviewer.gyp
@@ -55,6 +55,8 @@
],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/native/autogen/SkPdfEnums_autogen.h',
+ '<(SHARED_INTERMEDIATE_DIR)/native/autogen/SkPdfMapper_autogen.h',
+ '<(SHARED_INTERMEDIATE_DIR)/native/autogen/SkPdfHeaders_autogen.h',
'<(SHARED_INTERMEDIATE_DIR)/native/autogen/SkPdfMapper_autogen.cpp',
'<(SHARED_INTERMEDIATE_DIR)/native/autogen/SkPdfHeaders_autogen.cpp',
# TODO(edisonn): ok, there are many more files here, which we should list but since