aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--experimental/PdfViewer/generate_code.py24
-rw-r--r--experimental/PdfViewer/pdf_viewer_main.cpp107
-rw-r--r--experimental/PdfViewer/pdfspec_autogen.py245
-rw-r--r--experimental/PdfViewer/spec2def.py64
4 files changed, 358 insertions, 82 deletions
diff --git a/experimental/PdfViewer/generate_code.py b/experimental/PdfViewer/generate_code.py
index 5d0558b10b..00c9b45c1e 100644
--- a/experimental/PdfViewer/generate_code.py
+++ b/experimental/PdfViewer/generate_code.py
@@ -341,11 +341,12 @@ class PdfClassManager:
print(' const PdfObject* fPodofoObj;')
print
print('public:')
- print(' SkPdf' + cls.fName + '(const PdfMemDocument* podofoDoc, const PdfObject* podofoObj) : fPodofoDoc(podofoDoc), fPodofoObj(podofoObj) {}')
+ print(' SkPdf' + cls.fName + '(const PdfMemDocument* podofoDoc = NULL, const PdfObject* podofoObj = NULL) : fPodofoDoc(podofoDoc), fPodofoObj(podofoObj) {}')
+ print(' const PdfMemDocument* doc() const { return fPodofoDoc;}')
print(' const PdfObject* podofo() const { return fPodofoObj;}')
else:
print('public:')
- print(' SkPdf' + cls.fName + '(const PdfMemDocument* podofoDoc, const PdfObject* podofoObj) : SkPdf' + cls.fBase + '(podofoDoc, podofoObj) {}')
+ print(' SkPdf' + cls.fName + '(const PdfMemDocument* podofoDoc = NULL, const PdfObject* podofoObj = NULL) : SkPdf' + cls.fBase + '(podofoDoc, podofoObj) {}')
print
#check required fieds, also, there should be an internal_valid() manually wrote for complex
@@ -354,6 +355,9 @@ class PdfClassManager:
print(' virtual bool valid() const {return true;}')
print
+ print(' SkPdf' + cls.fName + '& operator=(const SkPdf' + cls.fName + '& from) {this->fPodofoDoc = from.fPodofoDoc; this->fPodofoObj = from.fPodofoObj; return *this;}')
+ print
+
for field in cls.fFields:
prop = field.fProp
if prop.fCppName != '':
@@ -392,12 +396,18 @@ class PdfClassManager:
for name in self.fClassesNamesInOrder:
cls = self.fClasses[name]
- print(' static bool map' + name + '(const PdfMemDocument& podofoDoc, const PdfObject& podofoObj, SkPdfObject** out) {')
+
+ print(' static bool map(const SkPdfObject& in, SkPdf' + name + '** out) {')
+ print(' return map(*in.doc(), *in.podofo(), out);')
+ print(' }')
+ print
+
+ print(' static bool map(const PdfMemDocument& podofoDoc, const PdfObject& podofoObj, SkPdf' + name + '** out) {')
print(' if (!isA' + name + '(podofoDoc, podofoObj)) return false;')
print
for sub in cls.fEnumSubclasses:
- print(' if (map' + enumToCls[sub].fName + '(podofoDoc, podofoObj, out)) return true;')
+ print(' if (map(podofoDoc, podofoObj, (SkPdf' + enumToCls[sub].fName + '**)out)) return true;')
print
@@ -424,11 +434,7 @@ class PdfClassManager:
print(' if (' + prop.fCppName + ' != ' + prop.fMustBe.toCpp() + ') return false;')
print
- # hack, we only care about dictionaries now, so ret tru only if there is a match
- if cntMust != 0 or len(cls.fEnumSubclasses) > 0:
- print(' return true;')
- else:
- print(' return false;')
+ print(' return true;')
print(' }')
print
diff --git a/experimental/PdfViewer/pdf_viewer_main.cpp b/experimental/PdfViewer/pdf_viewer_main.cpp
index 1b5b79b99c..5a1fcc9495 100644
--- a/experimental/PdfViewer/pdf_viewer_main.cpp
+++ b/experimental/PdfViewer/pdf_viewer_main.cpp
@@ -61,6 +61,13 @@ bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc,
const char* abr,
SkPdfDictionary** data);
+template <typename T>
+bool DictionaryFromDictionary2(const PdfMemDocument* pdfDoc,
+ const PdfDictionary& dict,
+ const char* key,
+ const char* abr,
+ T** data);
+
class SkPdfObject;
bool ObjectFromDictionary(const PdfMemDocument* pdfDoc,
const PdfDictionary& dict,
@@ -72,9 +79,13 @@ bool ObjectFromDictionary(const PdfMemDocument* pdfDoc,
#include "pdf_auto_gen.h"
/*
- * TODO(edisonn): ASAP so skp -> pdf -> png looks greap
- * - load gs/ especially smask and already known prop
- * - use transparency (I think ca and CA ops)
+ * TODO(edisonn):
+ * - encapsulate podofo in the pdf api so the skpdf does not know anything about podofo
+ * - ASAP so skp -> pdf -> png looks great
+ * - load gs/ especially smask and already known prop (skp)
+ * - use transparency (I think ca and CA ops) (skp)
+ * - all font types
+ * - word spacing
* - load font for baidu.pdf
* - load font for youtube.pdf
*/
@@ -200,7 +211,7 @@ struct PdfGraphicsState {
double fWordSpace;
double fCharSpace;
- const PdfObject* fObjectWithResources;
+ SkPdfResourceDictionary fResources;
SkBitmap fSMask;
@@ -218,7 +229,6 @@ struct PdfGraphicsState {
fTextLeading = 0;
fWordSpace = 0;
fCharSpace = 0;
- fObjectWithResources = NULL;
fHasClipPathToApply = false;
}
};
@@ -913,7 +923,7 @@ bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc,
return false;
}
- return PodofoMapper::mapDictionary(*pdfDoc, *value, (SkPdfObject**)data);
+ return PodofoMapper::map(*pdfDoc, *value, (SkPdfObject**)data);
}
bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc,
@@ -926,6 +936,32 @@ bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc,
return DictionaryFromDictionary(pdfDoc, dict, abr, data);
}
+template <typename T>
+bool DictionaryFromDictionary2(const PdfMemDocument* pdfDoc,
+ const PdfDictionary& dict,
+ const char* key,
+ SkPdfDictionary** data) {
+ const PdfObject* value = resolveReferenceObject(pdfDoc,
+ dict.GetKey(PdfName(key)),
+ true);
+ if (value == NULL || !value->IsDictionary()) {
+ return false;
+ }
+
+ return PodofoMapper::map(*pdfDoc, *value, (T**)data);
+}
+
+template <typename T>
+bool DictionaryFromDictionary2(const PdfMemDocument* pdfDoc,
+ const PdfDictionary& dict,
+ const char* key,
+ const char* abr,
+ T** data) {
+ if (DictionaryFromDictionary2<T>(pdfDoc, dict, key, data)) return true;
+ if (abr == NULL || *abr == '\0') return false;
+ return DictionaryFromDictionary2<T>(pdfDoc, dict, abr, data);
+}
+
bool ObjectFromDictionary(const PdfMemDocument* pdfDoc,
const PdfDictionary& dict,
const char* key,
@@ -936,7 +972,7 @@ bool ObjectFromDictionary(const PdfMemDocument* pdfDoc,
if (value == NULL) {
return false;
}
- return PodofoMapper::mapObject(*pdfDoc, *value, data);
+ return PodofoMapper::map(*pdfDoc, *value, data);
}
bool ObjectFromDictionary(const PdfMemDocument* pdfDoc,
@@ -950,6 +986,7 @@ bool ObjectFromDictionary(const PdfMemDocument* pdfDoc,
}
+
// TODO(edisonn): perf!!!
static SkColorTable* getGrayColortable() {
@@ -1257,20 +1294,39 @@ bool SkRectFromDictionary(PdfContext* pdfContext,
return true;
}
-PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, const PdfObject& obj) {
- if (!obj.HasStream() || obj.GetStream() == NULL || obj.GetStream()->GetLength() == 0) {
+SkPdfObject* get(const SkPdfObject* obj, const char* key, const char* abr = "") {
+ SkPdfObject* ret = NULL;
+ if (obj == NULL) return NULL;
+ const SkPdfDictionary* dict = obj->asDictionary();
+ if (dict == NULL) return NULL;
+ if (!dict->podofo()->IsDictionary()) return NULL;
+ ObjectFromDictionary(dict->doc(), dict->podofo()->GetDictionary(), key, abr, &ret);
+ return ret;
+}
+
+PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, SkPdfType1FormDictionary* skobj) {
+ if (!skobj || !skobj->podofo() || !skobj->podofo()->HasStream() || skobj->podofo()->GetStream() == NULL || skobj->podofo()->GetStream()->GetLength() == 0) {
return kOK_PdfResult;
}
PdfOp_q(pdfContext, canvas, NULL);
canvas->save();
- pdfContext->fGraphicsState.fObjectWithResources = &obj;
+ if (get(skobj, "Resources")) {
+ SkPdfResourceDictionary* res = NULL;
+
+ PodofoMapper::map(*get(skobj, "Resources"), &res);
+
+ if (res) {
+ pdfContext->fGraphicsState.fResources = *res;
+ delete res;
+ }
+ }
SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Current matrix");
SkMatrix matrix;
- if (SkMatrixFromDictionary(pdfContext, obj.GetDictionary(), "Matrix", &matrix)) {
+ if (SkMatrixFromDictionary(pdfContext, skobj->podofo()->GetDictionary(), "Matrix", &matrix)) {
pdfContext->fGraphicsState.fMatrix.preConcat(matrix);
pdfContext->fGraphicsState.fMatrixTm = pdfContext->fGraphicsState.fMatrix;
pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatrix;
@@ -1282,7 +1338,7 @@ PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, const PdfObje
canvas->setMatrix(pdfContext->fGraphicsState.fMatrix);
SkRect bbox;
- if (SkRectFromDictionary(pdfContext, obj.GetDictionary(), "BBox", &bbox)) {
+ if (SkRectFromDictionary(pdfContext, skobj->podofo()->GetDictionary(), "BBox", &bbox)) {
canvas->clipRect(bbox, SkRegion::kIntersect_Op, true); // TODO(edisonn): AA from settings.
}
@@ -1296,7 +1352,7 @@ PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, const PdfObje
// TODO(edisonn): get rid of try/catch exceptions! We should not throw on user data!
try {
- obj.GetStream()->GetFilteredCopy(&uncompressedStream, &uncompressedStreamLength);
+ skobj->podofo()->GetStream()->GetFilteredCopy(&uncompressedStream, &uncompressedStreamLength);
if (uncompressedStream != NULL && uncompressedStreamLength != 0) {
PdfContentsTokenizer tokenizer(uncompressedStream, uncompressedStreamLength);
PdfMainLooper looper(NULL, &tokenizer, pdfContext, canvas);
@@ -1347,8 +1403,8 @@ PdfResult doXObject(PdfContext* pdfContext, SkCanvas* canvas, const PdfObject& o
CheckRecursiveRendering checkRecursion(obj);
// TODO(edisonn): check type
- SkPdfObject* skobj = NULL;
- if (!PodofoMapper::mapXObjectDictionary(*pdfContext->fPdfDoc, obj, &skobj)) return kIgnoreError_PdfResult;
+ SkPdfXObjectDictionary* skobj = NULL;
+ if (!PodofoMapper::map(*pdfContext->fPdfDoc, obj, &skobj)) return kIgnoreError_PdfResult;
if (!skobj || !skobj->valid()) return kIgnoreError_PdfResult;
@@ -1359,7 +1415,7 @@ PdfResult doXObject(PdfContext* pdfContext, SkCanvas* canvas, const PdfObject& o
ret = doXObject_Image(pdfContext, canvas, skobj->asImageDictionary());
break;
case kObjectDictionaryXObjectDictionaryType1FormDictionary_SkPdfObjectType:
- ret = doXObject_Form(pdfContext, canvas, obj);//skobj->asType1FormDictionary());
+ ret = doXObject_Form(pdfContext, canvas, skobj->asType1FormDictionary());
break;
//case kObjectDictionaryXObjectPS_SkPdfObjectType:
//return doXObject_PS(skxobj.asPS());
@@ -2105,15 +2161,7 @@ PdfResult PdfOp_gs(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
std::string str;
#endif
- const PdfDictionary& pageDict = pdfContext->fGraphicsState.fObjectWithResources->GetDictionary();
-
-#ifdef PDF_TRACE
- pdfContext->fGraphicsState.fObjectWithResources->ToString(str);
- printf("Print Object with resources: %s\n", str.c_str());
-#endif
-
- const PdfObject* resources = resolveReferenceObject(pdfContext->fPdfDoc,
- pageDict.GetKey("Resources"));
+ const PdfObject* resources = pdfContext->fGraphicsState.fResources.podofo();
if (resources == NULL) {
#ifdef PDF_TRACE
@@ -2169,6 +2217,8 @@ PdfResult PdfOp_gs(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
printf("gs object value: %s\n", str.c_str());
#endif
+ SkPdfGraphicsStateDictionary gs(pdfContext->fPdfDoc, value);
+
// TODO(edisonn): now load all those properties in graphic state.
return kNYI_PdfResult;
@@ -2252,9 +2302,7 @@ PdfResult PdfOp_sh(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
PdfResult PdfOp_Do(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
PdfName name = pdfContext->fVarStack.top().GetName(); pdfContext->fVarStack.pop();
- const PdfDictionary& pageDict = pdfContext->fGraphicsState.fObjectWithResources->GetDictionary();
- const PdfObject* resources = resolveReferenceObject(pdfContext->fPdfDoc,
- pageDict.GetKey("Resources"));
+ const PdfObject* resources = pdfContext->fGraphicsState.fResources.podofo();
if (resources == NULL) {
#ifdef PDF_TRACE
@@ -2637,7 +2685,8 @@ public:
pdfContext.fPdfPage = page;
pdfContext.fPdfDoc = &doc;
pdfContext.fOriginalMatrix = SkMatrix::I();
- pdfContext.fGraphicsState.fObjectWithResources = pdfContext.fPdfPage->GetObject();
+ pdfContext.fGraphicsState.fResources = SkPdfResourceDictionary(pdfContext.fPdfDoc, resolveReferenceObject(pdfContext.fPdfDoc,
+ pdfContext.fPdfPage->GetResources()));
gPdfContext = &pdfContext;
gDumpBitmap = &bitmap;
diff --git a/experimental/PdfViewer/pdfspec_autogen.py b/experimental/PdfViewer/pdfspec_autogen.py
index b578ccc2b2..1c9267c1e7 100644
--- a/experimental/PdfViewer/pdfspec_autogen.py
+++ b/experimental/PdfViewer/pdfspec_autogen.py
@@ -916,6 +916,171 @@ def buildPdfSpec(pdfspec):
.done().done()\
.done()
+ pdfspec.addClass('GraphicsStateDictionary', 'Dictionary', 'Entries in a graphics state parameter dictionary')\
+ .optional()\
+ .field('Type')\
+ .name('Type')\
+ .type('name')\
+ .comment('(Optional) The type of PDF object that this dictionary describes; must be\nExtGState for a graphics state parameter dictionary.')\
+ .done().done()\
+ .optional()\
+ .field('LW')\
+ .name('LW')\
+ .type('number')\
+ .comment('(Optional; PDF 1.3) The line width (see "Line Width" on page 152).')\
+ .done().done()\
+ .optional()\
+ .field('LC')\
+ .name('LC')\
+ .type('integer')\
+ .comment('(Optional; PDF 1.3) The line cap style (see "Line Cap Style" on page 153).')\
+ .done().done()\
+ .optional()\
+ .field('LJ')\
+ .name('LJ')\
+ .type('integer')\
+ .comment('(Optional; PDF 1.3) The line join style (see "Line Join Style" on page 153).')\
+ .done().done()\
+ .optional()\
+ .field('ML')\
+ .name('ML')\
+ .type('number')\
+ .comment('(Optional; PDF 1.3) The miter limit (see "Miter Limit" on page 153).')\
+ .done().done()\
+ .optional()\
+ .field('D')\
+ .name('D')\
+ .type('array')\
+ .comment('(Optional; PDF 1.3) The line dash pattern, expressed as an array of the form\n[dashArray dashPhase], where dashArray is itself an array and dashPhase is an\ninteger (see "Line Dash Pattern" on page 155).')\
+ .done().done()\
+ .optional()\
+ .field('RI')\
+ .name('RI')\
+ .type('name')\
+ .comment('(Optional; PDF 1.3) The name of the rendering intent (see "Rendering\nIntents" on page 197).')\
+ .done().done()\
+ .optional()\
+ .field('OP')\
+ .name('OP')\
+ .type('boolean')\
+ .comment('(Optional) A flag specifying whether to apply overprint (see Section 4.5.6,\n"Overprint Control"). In PDF 1.2 and earlier, there is a single overprint\nparameter that applies to all painting operations. Beginning with PDF 1.3,\nthere are two separate overprint parameters: one for stroking and one for all\nother painting operations. Specifying an OP entry sets both parameters un-\nless there is also an op entry in the same graphics state parameter dictionary,\nin which case the OP entry sets only the overprint parameter for stroking.')\
+ .done().done()\
+ .optional()\
+ .field('op')\
+ .name('op')\
+ .type('boolean')\
+ .comment('(Optional; PDF 1.3) A flag specifying whether to apply overprint (see Section\n4.5.6, "Overprint Control") for painting operations other than stroking. If\nthis entry is absent, the OP entry, if any, sets this parameter.')\
+ .done().done()\
+ .optional()\
+ .field('OPM')\
+ .name('OPM')\
+ .type('integer')\
+ .comment('(Optional; PDF 1.3) The overprint mode (see Section 4.5.6, "Overprint Con-\ntrol").')\
+ .done().done()\
+ .optional()\
+ .field('Font')\
+ .name('Font')\
+ .type('array')\
+ .comment('(Optional; PDF 1.3) An array of the form [font size], where font is an indirect\nreference to a font dictionary and size is a number expressed in text space\nunits. These two objects correspond to the operands of the Tf operator (see\nSection 5.2, "Text State Parameters and Operators"); however, the first oper-\nand is an indirect object reference instead of a resource name.')\
+ .done().done()\
+ .optional()\
+ .field('BG')\
+ .name('BG')\
+ .type('function')\
+ .comment('(Optional) The black-generation function, which maps the interval [0.0 1.0]\nto the interval [0.0 1.0] (see Section 6.2.3, "Conversion from DeviceRGB to\nDeviceCMYK").')\
+ .done().done()\
+ .optional()\
+ .field('BG2')\
+ .name('BG2')\
+ .type('function or name')\
+ .comment('(Optional; PDF 1.3) Same as BG except that the value may also be the name\nDefault, denoting the black-generation function that was in effect at the start\nof the page. If both BG and BG2 are present in the same graphics state param-\neter dictionary, BG2 takes precedence.')\
+ .done().done()\
+ .optional()\
+ .field('UCR')\
+ .name('UCR')\
+ .type('function')\
+ .comment('(Optional) The undercolor-removal function, which maps the interval\n[0.0 1.0] to the interval [-1.0 1.0] (see Section 6.2.3, "Conversion from\nDeviceRGB to DeviceCMYK").')\
+ .done().done()\
+ .optional()\
+ .field('UCR2')\
+ .name('UCR2')\
+ .type('function or name')\
+ .comment('(Optional; PDF 1.3) Same as UCR except that the value may also be the name\nDefault, denoting the undercolor-removal function that was in effect at the\nstart of the page. If both UCR and UCR2 are present in the same graphics state\nparameter dictionary, UCR2 takes precedence.')\
+ .done().done()\
+ .optional()\
+ .field('TR')\
+ .name('TR')\
+ .type('function, array, or name')\
+ .comment('(Optional) The transfer function, which maps the interval [0.0 1.0] to the\ninterval [0.0 1.0] (see Section 6.3, "Transfer Functions"). The value is either\na single function (which applies to all process colorants) or an array of four\nfunctions (which apply to the process colorants individually). The name\nIdentity may be used to represent the identity function.')\
+ .done().done()\
+ .optional()\
+ .field('TR2')\
+ .name('TR2')\
+ .type('function, array, or name')\
+ .comment('(Optional; PDF 1.3) Same as TR except that the value may also be the name\nDefault, denoting the transfer function that was in effect at the start of the\npage. If both TR and TR2 are present in the same graphics state parameter dic-\ntionary, TR2 takes precedence.')\
+ .done().done()\
+ .optional()\
+ .field('HT')\
+ .name('HT')\
+ .type('dictionary, stream, or name')\
+ .comment('(Optional) The halftone dictionary or stream (see Section 6.4, "Halftones")\nor the name Default, denoting the halftone that was in effect at the start of the\npage.')\
+ .done().done()\
+ .optional()\
+ .field('FL')\
+ .name('FL')\
+ .type('number')\
+ .comment('(Optional; PDF 1.3) The flatness tolerance (see Section 6.5.1, "Flatness Toler-\nance").')\
+ .done().done()\
+ .optional()\
+ .field('SM')\
+ .name('SM')\
+ .type('number')\
+ .comment('(Optional; PDF 1.3) The smoothness tolerance (see Section 6.5.2, "Smooth-\nness Tolerance").')\
+ .done().done()\
+ .optional()\
+ .field('SA')\
+ .name('SA')\
+ .type('boolean')\
+ .comment('(Optional) A flag specifying whether to apply automatic stroke adjustment\n(see Section 6.5.4, "Automatic Stroke Adjustment").')\
+ .done().done()\
+ .optional()\
+ .field('BM')\
+ .name('BM')\
+ .type('name or array')\
+ .comment('(Optional; PDF 1.4) The current blend mode to be used in the transparent\nimaging model (see Sections 7.2.4, "Blend Mode," and 7.5.2, "Specifying\nBlending Color Space and Blend Mode").')\
+ .done().done()\
+ .optional()\
+ .field('SMask')\
+ .name('SMask')\
+ .type('dictionary or name')\
+ .comment('(Optional; PDF 1.4) The current soft mask, specifying the mask shape or\nmask opacity values to be used in the transparent imaging model (see\n"Source Shape and Opacity" on page 421 and "Mask Shape and Opacity" on\npage 443).\nNote: Although the current soft mask is sometimes referred to as a "soft clip,"\naltering it with the gs operator completely replaces the old value with the new\none, rather than intersecting the two as is done with the current clipping path\nparameter (see Section 4.4.3, "Clipping Path Operators").')\
+ .done().done()\
+ .optional()\
+ .field('CA')\
+ .name('CA')\
+ .type('number')\
+ .comment('(Optional; PDF 1.4) The current stroking alpha constant, specifying the con-\nstant shape or constant opacity value to be used for stroking operations in the\ntransparent imaging model (see "Source Shape and Opacity" on page 421\nand "Constant Shape and Opacity" on page 444).')\
+ .done().done()\
+ .optional()\
+ .field('ca')\
+ .name('ca')\
+ .type('number')\
+ .comment('(Optional; PDF 1.4) Same as CA, but for nonstroking operations.')\
+ .done().done()\
+ .optional()\
+ .field('AIS')\
+ .name('AIS')\
+ .type('boolean')\
+ .comment('(Optional; PDF 1.4) The alpha source flag ("alpha is shape"), specifying\nwhether the current soft mask and alpha constant are to be interpreted as\nshape values (true) or opacity values (false).')\
+ .done().done()\
+ .optional()\
+ .field('TK')\
+ .name('TK')\
+ .type('boolean')\
+ .comment('(Optional; PDF 1.4) The text knockout flag, which determines the behavior\nof overlapping glyphs within a text object in the transparent imaging model\n(see Section 5.2.7, "Text Knockout").')\
+ .done().done()\
+ .done()
+
pdfspec.addClass('CalgrayColorSpaceDictionary', 'Dictionary', 'Entries in a CalGray color space dictionary')\
.required('NULL')\
.field('WhitePoint')\
@@ -1435,30 +1600,6 @@ def buildPdfSpec(pdfspec):
.type('name')\
.comment('(Required in PDF 1.0; optional otherwise) The name by which this form\nXObject is referenced in the XObject subdictionary of the current resource\ndictionary (see Section 3.7.2, "Resource Dictionaries").\nNote: This entry is obsolescent and its use is no longer recommended. (See\nimplementation note 38 in Appendix H.)')\
.done().done()\
- .optional()\
- .field('LastModified')\
- .name('LastModified')\
- .type('date')\
- .comment('(Required if PieceInfo is present; optional otherwise; PDF 1.3) The date and\ntime (see Section 3.8.2, "Dates") when the form XObject\'s contents were\nmost recently modified. If a page-piece dictionary (PieceInfo) is present, the\nmodification date is used to ascertain which of the application data diction-\naries it contains correspond to the current content of the form (see Section\n9.4, "Page-Piece Dictionaries").')\
- .done().done()\
- .required('NULL')\
- .field('BBox')\
- .name('BBox')\
- .type('rectangle')\
- .comment('(Required) An array of four numbers in the form coordinate system (see\nbelow), giving the coordinates of the left, bottom, right, and top edges,\nrespectively, of the form XObject\'s bounding box. These boundaries are used\nto clip the form XObject and to determine its size for caching.')\
- .done().done()\
- .optional()\
- .field('Matrix')\
- .name('Matrix')\
- .type('array')\
- .comment('(Optional) An array of six numbers specifying the form matrix, which maps\nform space into user space (see Section 4.2.3, "Transformation Matrices").\nDefault value: the identity matrix [1 0 0 1 0 0].')\
- .done().done()\
- .optional()\
- .field('Resources')\
- .name('Resources')\
- .type('dictionary')\
- .comment('(Optional but strongly recommended; PDF 1.2) A dictionary specifying any\nresources (such as fonts and images) required by the form XObject (see Sec-\ntion 3.7, "Content Streams and Resources").\nIn PDF 1.1 and earlier, all named resources used in the form XObject must be\nincluded in the resource dictionary of each page object on which the form\nXObject appears, whether or not they also appear in the resource dictionary\nof the form XObject itself. It can be useful to specify these resources in the\nform XObject\'s own resource dictionary as well, in order to determine which\nresources are used inside the form XObject. If a resource is included in both\ndictionaries, it should have the same name in both locations.')\
- .done().done()\
.done()
pdfspec.addClass('GroupAttributesDictionary', 'Dictionary', 'Entries common to all group attributes dictionaries')\
@@ -2600,7 +2741,61 @@ def buildPdfSpec(pdfspec):
.field('Border')\
.name('Border')\
.type('array')\
- .comment('(Optional) An array specifying the characteristics of the annotation\'s border.\nThe border is specified as a "rounded rectangle."\nIn PDF 1.0, the array consists of three numbers defining the horizontal cor-\nner radius, vertical corner radius, and border width, all in default user space\nunits. If the corner radii are 0, the border has square (not rounded) corners;\nif the border width is 0, no border is drawn. (See implementation note 61 in\nAppendix H.)')\
+ .comment('(Optional) An array specifying the characteristics of the annotation\'s border.\nThe border is specified as a "rounded rectangle."\nIn PDF 1.0, the array consists of three numbers defining the horizontal cor-\nner radius, vertical corner radius, and border width, all in default user space\nunits. If the corner radii are 0, the border has square (not rounded) corners;\nif the border width is 0, no border is drawn. (See implementation note 61 in\nAppendix H.)\n In PDF 1.1, the array may have a fourth element, an optional dash array\n defining a pattern of dashes and gaps to be used in drawing the border. The\n dash array is specified in the same format as in the line dash pattern parame-\n ter of the graphics state (see "Line Dash Pattern" on page 155). For example,\n a Border value of [0 0 1 [3 2]] specifies a border 1 unit wide, with square\n corners, drawn with 3-unit dashes alternating with 2-unit gaps. Note that no\n dash phase is specified; the phase is assumed to be 0. (See implementation\n note 62 in Appendix H.)\n Note: In PDF 1.2 or later, annotations may ignore this entry and use the BS\n entry (see above) to specify their border styles instead. In PDF 1.2 and 1.3, only\n widget annotations do so; in PDF 1.4, all of the standard annotation types ex-\n cept Link (see Table 8.14 on page 499) use BS rather than Border if both are\n present. For backward compatibility, however, Border is still supported for all\n annotation types.\n Default value: [0 0 1].')\
+ .done().done()\
+ .optional()\
+ .field('AP')\
+ .name('AP')\
+ .type('dictionary')\
+ .comment('(Optional; PDF 1.2) An appearance dictionary specifying how the annotation\nis presented visually on the page (see Section 8.4.4, "Appearance Streams";\nsee also implementation note 60 in Appendix H).')\
+ .done().done()\
+ .optional()\
+ .field('AS')\
+ .name('AS')\
+ .type('name')\
+ .comment('(Required if the appearance dictionary AP contains one or more subdictionaries;\nPDF 1.2) The annotation\'s appearance state, which selects the applicable\nappearance stream from an appearance subdictionary (see Section 8.4.4,\n"Appearance Streams"; see also implementation note 60 in Appendix H).')\
+ .done().done()\
+ .optional()\
+ .field('C')\
+ .name('C')\
+ .type('array')\
+ .comment('(Optional; PDF 1.1) An array of three numbers in the range 0.0 to 1.0, repre-\nsenting the components of a color in the DeviceRGB color space. This color\nwill be used for the following purposes:\n* The background of the annotation\'s icon when closed\n* The title bar of the annotation\'s pop-up window\n* The border of a link annotation')\
+ .done().done()\
+ .optional()\
+ .field('CA')\
+ .name('CA')\
+ .type('number')\
+ .comment('(Optional; PDF 1.4) The constant opacity value to be used in painting the\nannotation (see Sections 7.1, "Overview of Transparency," and 7.2.6, "Shape\nand Opacity Computations"). This value applies to all visible elements of\nthe annotation in its closed state (including its background and border), but\nnot to the pop-up window that appears when the annotation is opened. The\nspecified value is used as the initial alpha constant (both stroking and non-\nstroking) for interpreting the annotation\'s appearance stream, if any (see\nSection 8.4.4, "Appearance Streams," and "Constant Shape and Opacity" on\npage 444). The implicit blend mode (see Section 7.2.4, "Blend Mode") is\nNormal. Default value: 1.0.\n Note: If no explicit appearance stream is defined for the annotation, it will be\n painted by implementation-dependent means that do not necessarily conform to\n the Adobe imaging model; in this case, the effect of this entry is implementation-\n dependent as well.\n Note: This entry is recognized by all of the standard annotation types listed in\n Table 8.14 on page 499 except Link, Movie, Widget, PrinterMark, and TrapNet.')\
+ .done().done()\
+ .optional()\
+ .field('T')\
+ .name('T')\
+ .type('text string')\
+ .comment('(Optional; PDF 1.1) The text label to be displayed in the title bar of the anno-\ntation\'s pop-up window when open and active.')\
+ .done().done()\
+ .optional()\
+ .field('Popup')\
+ .name('Popup')\
+ .type('dictionary')\
+ .comment('(Optional; PDF 1.3) An indirect reference to a pop-up annotation for enter-\ning or editing the text associated with this annotation.')\
+ .done().done()\
+ .optional()\
+ .field('A')\
+ .name('A')\
+ .type('dictionary')\
+ .comment('(Optional; PDF 1.1) An action to be performed when the annotation is acti-\nvated (see Section 8.5, "Actions").\nNote: This entry is not permitted in link annotations if a Dest entry is present\n(see "Link Annotations" on page 501). Also note that the A entry in movie anno-\ntations has a different meaning (see "Movie Annotations" on page 510).')\
+ .done().done()\
+ .optional()\
+ .field('AA')\
+ .name('AA')\
+ .type('dictionary')\
+ .comment('(Optional; PDF 1.2) An additional-actions dictionary defining the anno-\ntation\'s behavior in response to various trigger events (see Section 8.5.2,\n"Trigger Events"). At the time of publication, this entry is used only by wid-\nget annotations.')\
+ .done().done()\
+ .optional()\
+ .field('StructParent')\
+ .name('StructParent')\
+ .type('integer')\
+ .comment('(Required if the annotation is a structural content item; PDF 1.3) The integer\nkey of the annotation\'s entry in the structural parent tree (see "Finding Struc-\nture Elements from Content Items" on page 600).')\
.done().done()\
.done()
diff --git a/experimental/PdfViewer/spec2def.py b/experimental/PdfViewer/spec2def.py
index fe3e293d59..aa4e17795c 100644
--- a/experimental/PdfViewer/spec2def.py
+++ b/experimental/PdfViewer/spec2def.py
@@ -80,6 +80,7 @@ tableToClassName = {
'TABLE 3.33': ['EmbeddedFileStreamDictionary', 'Additional entries in an embedded file stream dictionary'],
'TABLE 3.34': ['EmbeddedFileParameterDictionary', 'Entries in an embedded file parameter dictionary'],
'TABLE 3.35': ['MacOsFileInformationDictionary', 'Entries in a Mac OS file information dictionary'],
+'TABLE 4.8': ['GraphicsStateDictionary', 'Entries in a graphics state parameter dictionary'],
'TABLE 4.13': ['CalgrayColorSpaceDictionary', 'Entries in a CalGray color space dictionary'],
'TABLE 4.14': ['CalrgbColorSpaceDictionary', 'Entries in a CalRGB color space dictionary'],
'TABLE 4.15': ['LabColorSpaceDictionary', 'Entries in a Lab color space dictionary'],
@@ -417,7 +418,9 @@ def rebaseTable(line):
global knownTypes
global columnWidth
- words = line.split()
+ line2 = line.replace(',', ' , ')
+
+ words = line2.split()
if len(words) < 3:
return False
@@ -457,7 +460,7 @@ def stopTable():
def killTable():
return
-def processLine(line):
+def processLineCore(line):
global lines
global tableLine
global tableRow
@@ -465,6 +468,8 @@ def processLine(line):
global columnValues
global mustFollowTableHeader
+ global fnewspec
+
lines = lines + 1
line = unicode(line, 'utf8')
@@ -474,31 +479,32 @@ def processLine(line):
words = line.split()
if len(words) == 0:
stopTable()
- return
+ return False
isTableHeader = re.search('^[\s]*(TABLE [0-9].[0-9][0-9]?)', striped)
if isTableHeader:
stopTable()
tableDescriptionFound(striped)
mustFollowTableHeader = True
- return
+ return False
if mustFollowTableHeader:
mustFollowTableHeader = False
if len(words) != 3:
killTable()
+ return False
# TODO(edisonn): support for generic table!
if words[0] != 'KEY' or words[1] != 'TYPE' or words[2] != 'VALUE':
killTable()
- return
+ return False
tableHasHeader()
columnWidth = [0, 0, 0]
columnWidth[0] = striped.index('TYPE')
columnWidth[1] = striped.index('VALUE') - striped.index('TYPE')
columnWidth[2] = 0
- return
+ return True
if inTable():
tableLine = tableLine + 1
@@ -506,16 +512,13 @@ def processLine(line):
second = striped[columnWidth[0] : columnWidth[0] + columnWidth[1]]
third = striped[columnWidth[0] + columnWidth[1] :]
-
-
-
if tableLine == 1:
if third[0] != '(':
killTable()
- return
+ return False
newRow(first, second, third)
- return
+ return True
if rebaseTable(striped):
first = striped[0 : columnWidth[0]]
@@ -528,43 +531,65 @@ def processLine(line):
if first == '' and second == '' and third != '':
appendRow(second, third)
- return
+ return True
if len(first.split()) > 1:
stopTable()
- return
+ return False
if first != '' and first[0] == ' ':
stopTable()
- return
+ return False
if first != '' and second != '' and third == '':
stopTable()
- return
+ return False
if first == '' and second != '' and second[0] != ' ':
if acceptType(second):
appendRow(second, third)
+ return True
else:
stopTable()
- return
+ return False
if first != '' and second != '' and third[0] != '(':
stopTable()
- return
+ return False
if first == '' and second != '' and second[0] == ' ':
stopTable()
- return
+ return False
if first != '' and second != '' and third[0] == '(':
commitRow()
newRow(first, second, third)
- return
+ return True
+
+ return False
+ return False
+
+def processLine(line):
+ global fnewspec
+
+ inSpec = processLineCore(line)
+
+ #just return, use the next lines if you wish to rewrite spec
+ return
+
+ if inSpec:
+ #resize colum with types
+ line = line[:columnWidth[0] + columnWidth[1]] + (' ' * (60 - columnWidth[1])) + line[columnWidth[0] + columnWidth[1]:]
+ line = line[:columnWidth[0]] + (' ' * (40 - columnWidth[0])) + line[columnWidth[0]:]
+
+ fnewspec.write(line)
def generateDef():
global lines
+ global fnewspec
+
+ #fnewspec = open('PdfReference-okular-2.txt', 'w')
print 'import datatypes'
print
@@ -580,6 +605,7 @@ def generateDef():
print
#print lines
+ #fnewspec.close()
if '__main__' == __name__:
sys.exit(generateDef()) \ No newline at end of file