diff options
author | edisonn@google.com <edisonn@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-10-11 16:17:44 +0000 |
---|---|---|
committer | edisonn@google.com <edisonn@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-10-11 16:17:44 +0000 |
commit | 2af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5df (patch) | |
tree | ba543b695e29c429b07ad56d529c7b1be27d3eed /experimental/PdfViewer | |
parent | f8a6b20e765619ee50da9d9afa7f63f9603cf260 (diff) |
pdfviewer: (more code cleanup): class documentation and comments
Review URL: https://codereview.chromium.org/27043002
git-svn-id: http://skia.googlecode.com/svn/trunk@11730 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'experimental/PdfViewer')
-rw-r--r-- | experimental/PdfViewer/SkNulCanvas.h | 6 | ||||
-rw-r--r-- | experimental/PdfViewer/SkTrackDevice.h | 6 | ||||
-rw-r--r-- | experimental/PdfViewer/SkTracker.h | 6 | ||||
-rw-r--r-- | experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.h | 59 | ||||
-rw-r--r-- | experimental/PdfViewer/pdfparser/native/SkPdfNativeObject.h | 157 | ||||
-rw-r--r-- | experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h | 102 |
6 files changed, 282 insertions, 54 deletions
diff --git a/experimental/PdfViewer/SkNulCanvas.h b/experimental/PdfViewer/SkNulCanvas.h index 1789b6f513..8ec2d32d0f 100644 --- a/experimental/PdfViewer/SkNulCanvas.h +++ b/experimental/PdfViewer/SkNulCanvas.h @@ -10,6 +10,12 @@ #include "SkCanvas.h" +/** \class SkNulCanvas + * + * Nul Canvas is a canvas that does nothing. It is used to measure the perf of just parsing + * a pdf, without actually rendering anything. + * + */ class SK_API SkNulCanvas : public SkCanvas { public: SK_DECLARE_INST_COUNT(SkNulCanvas); diff --git a/experimental/PdfViewer/SkTrackDevice.h b/experimental/PdfViewer/SkTrackDevice.h index d8cf829c06..20f9e6867e 100644 --- a/experimental/PdfViewer/SkTrackDevice.h +++ b/experimental/PdfViewer/SkTrackDevice.h @@ -11,6 +11,12 @@ #include "SkBitmapDevice.h" #include "SkTracker.h" +/** \class SkTrackDevice + * + * A Track Device is used to track that callstack of an operation that affected some pixels. + * It can be used with SampleApp to investigate bugs (CL not checked in yet). + * + */ class SkTrackDevice : public SkBitmapDevice { public: SK_DECLARE_INST_COUNT(SkTrackDevice) diff --git a/experimental/PdfViewer/SkTracker.h b/experimental/PdfViewer/SkTracker.h index fd2a2f35fd..2f10fed334 100644 --- a/experimental/PdfViewer/SkTracker.h +++ b/experimental/PdfViewer/SkTracker.h @@ -17,6 +17,12 @@ #define MAX_TRACKING_POINTS 100 +/** \class SkTracker + * + * A Tracker can be attached to a SkTrackDevice and it will store the track pixels. + * It can be used with SampleApp to investigate bugs (CL not checked in yet). + * + */ class SkTracker { public: SkTracker() : fEnabled(false) diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.h b/experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.h index 04456cc678..d8241376c1 100644 --- a/experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.h +++ b/experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.h @@ -35,44 +35,97 @@ class SkStream; // But if the pdf is missing the xref, then we will have to read most of pdf to be able to render // page 100. +/** \class SkPdfNativeDoc + * + * The SkPdfNativeDoc class is used to load a PDF in memory and it represents a PDF Document. + * + */ class SkPdfNativeDoc { private: + // Information about public objects in pdf that can be referenced with ID GEN R struct PublicObjectEntry { + // Offset in the file where the object starts. long fOffset; + + // Offset in file where the object ends. Could be used to quickly fail if there is a + // problem in pdf structure. // long endOffset; // TODO(edisonn): determine the end of the object, // to be used when the doc is corrupted, for fast failure. + + // Refered object. SkPdfNativeObject* fObj; + + // If refered object is a reference, we resolve recursively the reference until we find + // the real object. SkPdfNativeObject* fResolvedReference; + + // Used to break a recursive reference to itself. bool fIsReferenceResolved; }; public: + // TODO(edisonn) should be deprecated SkPdfNativeDoc(const char* path); + + // TODO(edisonn) should be deprecated SkPdfNativeDoc(SkStream* stream); ~SkPdfNativeDoc(); + // returns the number of pages in the pdf int pages() const; + + // returns the page resources SkPdfResourceDictionary* pageResources(int page); + + // returns the page's mediabox i points - the page physical boundaries. SkRect MediaBox(int page); + + // Returns a tokenizer of a page. The passed allocator will be used to allocate objects that + // are parsed. It should be destroyed after the tokenizer. SkPdfNativeTokenizer* tokenizerOfPage(int n, SkPdfAllocator* allocator); + // Returns a tokenizer of a pdf stream. The passed allocator will be used to allocate objects + // that are parsed. It should be destroyed after the tokenizer. SkPdfNativeTokenizer* tokenizerOfStream(SkPdfNativeObject* stream, SkPdfAllocator* allocator); + + // Returns a tokenizer of a memory buffer. The passed allocator will be used to allocate objects + // that are parsed. It should be destroyed after the tokenizer. SkPdfNativeTokenizer* tokenizerOfBuffer(const unsigned char* buffer, size_t len, SkPdfAllocator* allocator); + + //returns objects that are references and can be queried. size_t objects() const; - SkPdfNativeObject* object(int i); - SkPdfPageObjectDictionary* page(int page); + // returns an object. + // TODO(edisonn): pdf updates are not supported yet. + // add generation parameter to support page updates. + SkPdfNativeObject* object(int id /*, int generation*/ ); + + // returns the object that holds all the page informnation + // TODO(edisonn): pdf updates are not supported yet. + // add generation parameter to support page updates. + SkPdfPageObjectDictionary* page(int page/*, int generation*/); + + // TODO(edisonn): deprecate the mapper - was used when we supported multiple + // parsers (podofo) + // The mapper maps allows an object to be mapped to a different dictionary type + // and it could verify the integrity of the object. const SkPdfMapper* mapper() const; + + // Allocator of the pdf - this holds all objects that are publicly referenced + // and all the objects that they refer SkPdfAllocator* allocator() const; + // Allows a renderer to create values to be dumped on the stack for operators to process them. SkPdfReal* createReal(double value) const; SkPdfInteger* createInteger(int value) const; // the string does not own the char* SkPdfString* createString(const unsigned char* sz, size_t len) const; + // Resolve a reference object. Will recursively resolve the reference + // until a real object is found SkPdfNativeObject* resolveReference(SkPdfNativeObject* ref); // Reports an approximation of all the memory usage. @@ -82,6 +135,8 @@ private: // Takes ownership of bytes. void init(const void* bytes, size_t length); + + // loads a pdf that has missing xref void loadWithoutXRef(); const unsigned char* readCrossReferenceSection(const unsigned char* xrefStart, diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfNativeObject.h b/experimental/PdfViewer/pdfparser/native/SkPdfNativeObject.h index b9d5d03bed..6ce5622fee 100644 --- a/experimental/PdfViewer/pdfparser/native/SkPdfNativeObject.h +++ b/experimental/PdfViewer/pdfparser/native/SkPdfNativeObject.h @@ -30,6 +30,18 @@ class SkPdfAllocator; #define kUnfilteredStreamBit 1 #define kOwnedStreamBit 2 +/** \class SkPdfNativeObject + * + * The SkPdfNativeObject class is used to store a pdf object. Classes that inherit it are not + * allowed to add fields. + * + * SkPdfAllocator will allocate them in chunks and will free them in destructor. + * + * You can allocate one on the stack, as long as you call reset() at the end, and any objects it + * points to in an allocator. But if your object is a simple one, like number, then + * putting it on stack will be just fine. + * + */ class SkPdfNativeObject { public: enum ObjectType { @@ -94,13 +106,16 @@ private: void* fData; DataType fDataType; - // Keep this the last entries #ifdef PDF_TRACK_OBJECT_USAGE + // Records if the object was used during rendering/proccessing. It can be used to track + // what features are only partially implemented, by looking at what objects have not been + // accessed. mutable bool fUsed; #endif // PDF_TRACK_OBJECT_USAGE #ifdef PDF_TRACK_STREAM_OFFSETS public: + // TODO(edisonn): replace them with char* start, end - and a mechanism to register streams. int fStreamId; int fOffsetStart; int fOffsetEnd; @@ -109,12 +124,12 @@ public: public: #ifdef PDF_TRACK_STREAM_OFFSETS + // TODO(edisonn): remove these ones. int streamId() const { return fStreamId; } int offsetStart() const { return fOffsetStart; } int offsetEnd() const { return fOffsetEnd; } #endif // PDF_TRACK_STREAM_OFFSETS - SkPdfNativeObject() : fInRendering(0) , fObjectType(kInvalid_PdfObjectType) , fMap(NULL) @@ -131,30 +146,40 @@ public: #endif // PDF_TRACK_STREAM_OFFSETS {} + // Used to verify if a form is used in rendering, to check for infinite loops. bool inRendering() const { return fInRendering != 0; } void startRendering() {fInRendering = 1;} void doneRendering() {fInRendering = 0;} + // Each object can cache one entry associated with it. + // for example a SkPdfImage could cache an SkBitmap, of a SkPdfFont, could cache a SkTypeface. inline bool hasData(DataType type) { return type == fDataType; } + // returns the cached value inline void* data(DataType type) { return type == fDataType ? fData : NULL; } + // Stores something in the cache inline void setData(void* data, DataType type) { releaseData(); fDataType = type; fData = data; } + // destroys the cache void releaseData(); + // TODO(edisonn): add an assert that reset was called // ~SkPdfNativeObject() { // //reset(); must be called manually! Normally, will be called by allocator destructor. // } + // Resets a pdf object, deleting all resources directly referenced. + // It will not reset/delete indirect resources. + // (e.g. it deletes only the array holding pointers to objects, but does not del the objects) void reset() { SkPdfMarkObjectUnused(); @@ -179,12 +204,15 @@ public: releaseData(); } + // returns the object type (Null, Integer, String, Dictionary, ... ) + // It does not specify what type of dictionary we have. ObjectType type() { SkPdfMarkObjectUsed(); return fObjectType; } + // Gives quick access to the buffer's address of a string/keyword/name const char* c_str() const { SkPdfMarkObjectUsed(); @@ -201,6 +229,7 @@ public: } } + // Gives quick access to the length of a string/keyword/name size_t lenstr() const { SkPdfMarkObjectUsed(); @@ -242,8 +271,8 @@ public: return nyi; } + // Creates a Boolean object. Assumes and asserts that it was never initialized. static void makeBoolean(bool value, SkPdfNativeObject* obj) { - SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); obj->fObjectType = kBoolean_PdfObjectType; @@ -258,6 +287,7 @@ public: return obj; } + // Creates an Integer object. Assumes and asserts that it was never initialized. static void makeInteger(int64_t value, SkPdfNativeObject* obj) { SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); @@ -265,6 +295,7 @@ public: obj->fIntegerValue = value; } + // Creates a Real object. Assumes and asserts that it was never initialized. static void makeReal(double value, SkPdfNativeObject* obj) { SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); @@ -272,6 +303,7 @@ public: obj->fRealValue = value; } + // Creates a Null object. Assumes and asserts that it was never initialized. static void makeNull(SkPdfNativeObject* obj) { SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); @@ -285,8 +317,10 @@ public: return obj; } + // TODO(edisonn): this might not woirk well in Chrome static SkPdfNativeObject kNull; + // Creates a Numeric object from a string. Assumes and asserts that it was never initialized. static void makeNumeric(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) { SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); @@ -308,6 +342,7 @@ public: } } + // Creates a Reference object. Assumes and asserts that it was never initialized. static void makeReference(unsigned int id, unsigned int gen, SkPdfNativeObject* obj) { SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); @@ -316,67 +351,77 @@ public: obj->fRef.fGen = gen; } + // Creates a Reference object. Resets the object before use. static void resetAndMakeReference(unsigned int id, unsigned int gen, SkPdfNativeObject* obj) { obj->reset(); makeReference(id, gen, obj); } - + // Creates a String object. Assumes and asserts that it was never initialized. static void makeString(const unsigned char* start, SkPdfNativeObject* obj) { makeStringCore(start, strlen((const char*)start), obj, kString_PdfObjectType); } + // Creates a String object. Assumes and asserts that it was never initialized. static void makeString(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) { makeStringCore(start, end - start, obj, kString_PdfObjectType); } + // Creates a String object. Assumes and asserts that it was never initialized. static void makeString(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) { makeStringCore(start, bytes, obj, kString_PdfObjectType); } - + // Creates a HexString object. Assumes and asserts that it was never initialized. static void makeHexString(const unsigned char* start, SkPdfNativeObject* obj) { makeStringCore(start, strlen((const char*)start), obj, kHexString_PdfObjectType); } + // Creates a HexString object. Assumes and asserts that it was never initialized. static void makeHexString(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) { makeStringCore(start, end - start, obj, kHexString_PdfObjectType); } + // Creates a HexString object. Assumes and asserts that it was never initialized. static void makeHexString(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) { makeStringCore(start, bytes, obj, kHexString_PdfObjectType); } - + // Creates a Name object. Assumes and asserts that it was never initialized. static void makeName(const unsigned char* start, SkPdfNativeObject* obj) { makeStringCore(start, strlen((const char*)start), obj, kName_PdfObjectType); } + // Creates a Name object. Assumes and asserts that it was never initialized. static void makeName(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) { makeStringCore(start, end - start, obj, kName_PdfObjectType); } + // Creates a Name object. Assumes and asserts that it was never initialized. static void makeName(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) { makeStringCore(start, bytes, obj, kName_PdfObjectType); } - + // Creates a Keyword object. Assumes and asserts that it was never initialized. static void makeKeyword(const unsigned char* start, SkPdfNativeObject* obj) { makeStringCore(start, strlen((const char*)start), obj, kKeyword_PdfObjectType); } + // Creates a Keyword object. Assumes and asserts that it was never initialized. static void makeKeyword(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) { makeStringCore(start, end - start, obj, kKeyword_PdfObjectType); } + // Creates a Keyword object. Assumes and asserts that it was never initialized. static void makeKeyword(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) { makeStringCore(start, bytes, obj, kKeyword_PdfObjectType); } + // Creates an empty Array object. Assumes and asserts that it was never initialized. static void makeEmptyArray(SkPdfNativeObject* obj) { SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); @@ -384,6 +429,7 @@ public: obj->fArray = new SkTDArray<SkPdfNativeObject*>(); } + // Appends an object into the array. Assumes <this> is an array. bool appendInArray(SkPdfNativeObject* obj) { SkASSERT(fObjectType == kArray_PdfObjectType); if (fObjectType != kArray_PdfObjectType) { @@ -395,6 +441,7 @@ public: return true; } + // Returns the size of an array. size_t size() const { SkPdfMarkObjectUsed(); @@ -403,6 +450,7 @@ public: return fArray->count(); } + // Returns one object of an array, by index. SkPdfNativeObject* objAtAIndex(int i) { SkPdfMarkObjectUsed(); @@ -411,18 +459,17 @@ public: return (*fArray)[i]; } - SkPdfNativeObject* removeLastInArray() { + // Returns one object of an array, by index. + const SkPdfNativeObject* objAtAIndex(int i) const { SkPdfMarkObjectUsed(); SkASSERT(fObjectType == kArray_PdfObjectType); - SkPdfNativeObject* ret = NULL; - fArray->pop(&ret); - - return ret; + return (*fArray)[i]; } - const SkPdfNativeObject* objAtAIndex(int i) const { + // Returns one object of an array, by index. + SkPdfNativeObject* operator[](int i) { SkPdfMarkObjectUsed(); SkASSERT(fObjectType == kArray_PdfObjectType); @@ -430,7 +477,7 @@ public: return (*fArray)[i]; } - SkPdfNativeObject* operator[](int i) { + const SkPdfNativeObject* operator[](int i) const { SkPdfMarkObjectUsed(); SkASSERT(fObjectType == kArray_PdfObjectType); @@ -438,14 +485,19 @@ public: return (*fArray)[i]; } - const SkPdfNativeObject* operator[](int i) const { + // Removes the last object in the array. + SkPdfNativeObject* removeLastInArray() { SkPdfMarkObjectUsed(); SkASSERT(fObjectType == kArray_PdfObjectType); - return (*fArray)[i]; + SkPdfNativeObject* ret = NULL; + fArray->pop(&ret); + + return ret; } + // Creates an empty Dictionary object. Assumes and asserts that it was never initialized. static void makeEmptyDictionary(SkPdfNativeObject* obj) { SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); @@ -462,6 +514,8 @@ public: // which will be used in code // add function SkPdfFastNameKey key(const char* key); // TODO(edisonn): setting the same key twice, will make the value undefined! + + // this[key] = value; bool set(const SkPdfNativeObject* key, SkPdfNativeObject* value) { SkPdfMarkObjectUsed(); @@ -476,12 +530,14 @@ public: return set(key->fStr.fBuffer, key->fStr.fBytes, value); } + // this[key] = value; bool set(const char* key, SkPdfNativeObject* value) { SkPdfMarkObjectUsed(); return set((const unsigned char*)key, strlen(key), value); } + // this[key] = value; bool set(const unsigned char* key, size_t len, SkPdfNativeObject* value) { SkPdfMarkObjectUsed(); @@ -495,6 +551,7 @@ public: return fMap->set((const char*)key, len, value); } + // Returns an object from a Dictionary, identified by it's name. SkPdfNativeObject* get(const SkPdfNativeObject* key) { SkPdfMarkObjectUsed(); @@ -509,12 +566,14 @@ public: return get(key->fStr.fBuffer, key->fStr.fBytes); } + // Returns an object from a Dictionary, identified by it's name. SkPdfNativeObject* get(const char* key) { SkPdfMarkObjectUsed(); return get((const unsigned char*)key, strlen(key)); } + // Returns an object from a Dictionary, identified by it's name. SkPdfNativeObject* get(const unsigned char* key, size_t len) { SkPdfMarkObjectUsed(); @@ -537,6 +596,7 @@ public: return ret; } + // Returns an object from a Dictionary, identified by it's name. const SkPdfNativeObject* get(const SkPdfNativeObject* key) const { SkPdfMarkObjectUsed(); @@ -551,12 +611,14 @@ public: return get(key->fStr.fBuffer, key->fStr.fBytes); } + // Returns an object from a Dictionary, identified by it's name. const SkPdfNativeObject* get(const char* key) const { SkPdfMarkObjectUsed(); return get((const unsigned char*)key, strlen(key)); } + // Returns an object from a Dictionary, identified by it's name. const SkPdfNativeObject* get(const unsigned char* key, size_t len) const { SkPdfMarkObjectUsed(); @@ -579,6 +641,7 @@ public: return ret; } + // Returns an object from a Dictionary, identified by it's name. const SkPdfNativeObject* get(const char* key, const char* abr) const { SkPdfMarkObjectUsed(); @@ -590,6 +653,7 @@ public: return get(abr); } + // Returns an object from a Dictionary, identified by it's name. SkPdfNativeObject* get(const char* key, const char* abr) { SkPdfMarkObjectUsed(); @@ -601,6 +665,7 @@ public: return get(abr); } + // Casts the object to a Dictionary. Asserts if the object is not a Dictionary. SkPdfDictionary* asDictionary() { SkPdfMarkObjectUsed(); @@ -611,6 +676,7 @@ public: return (SkPdfDictionary*) this; } + // Casts the object to a Dictionary. Asserts if the object is not a Dictionary. const SkPdfDictionary* asDictionary() const { SkPdfMarkObjectUsed(); @@ -622,48 +688,58 @@ public: } + // Returns true if the object is a Reference. bool isReference() const { SkPdfMarkObjectUsed(); return fObjectType == kReference_PdfObjectType; } + // Returns true if the object is a Boolean. bool isBoolean() const { SkPdfMarkObjectUsed(); return fObjectType == kBoolean_PdfObjectType; } + // Returns true if the object is an Integer. bool isInteger() const { SkPdfMarkObjectUsed(); return fObjectType == kInteger_PdfObjectType; } + private: + // Returns true if the object is a Real number. bool isReal() const { SkPdfMarkObjectUsed(); return fObjectType == kReal_PdfObjectType; } + public: + // Returns true if the object is a Number (either Integer or Real). bool isNumber() const { SkPdfMarkObjectUsed(); return fObjectType == kInteger_PdfObjectType || fObjectType == kReal_PdfObjectType; } + // Returns true if the object is a R keyword (used to identify references, e.g. "10 3 R". bool isKeywordReference() const { SkPdfMarkObjectUsed(); return fObjectType == kKeyword_PdfObjectType && fStr.fBytes == 1 && fStr.fBuffer[0] == 'R'; } + // Returns true if the object is a Keyword. bool isKeyword() const { SkPdfMarkObjectUsed(); return fObjectType == kKeyword_PdfObjectType; } + // Returns true if the object is a given Keyword. bool isKeyword(const char* keyword) const { SkPdfMarkObjectUsed(); @@ -682,12 +758,14 @@ public: return true; } + // Returns true if the object is a Name. bool isName() const { SkPdfMarkObjectUsed(); return fObjectType == kName_PdfObjectType; } + // Returns true if the object is a given Name. bool isName(const char* name) const { SkPdfMarkObjectUsed(); @@ -696,30 +774,37 @@ public: strncmp((const char*)fStr.fBuffer, name, fStr.fBytes) == 0; } + // Returns true if the object is an Array. bool isArray() const { SkPdfMarkObjectUsed(); return fObjectType == kArray_PdfObjectType; } + // Returns true if the object is a Date. + // TODO(edisonn): NYI bool isDate() const { SkPdfMarkObjectUsed(); return fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType; } + // Returns true if the object is a Dictionary. bool isDictionary() const { SkPdfMarkObjectUsed(); return fObjectType == kDictionary_PdfObjectType; } + // Returns true if the object is a Date. + // TODO(edisonn): NYI bool isFunction() const { SkPdfMarkObjectUsed(); return false; // NYI } + // Returns true if the object is a Rectangle. bool isRectangle() const { SkPdfMarkObjectUsed(); @@ -727,38 +812,43 @@ public: return fObjectType == kArray_PdfObjectType && fArray->count() == 4; } - // TODO(edisonn): has stream .. or is stream ... TBD + // TODO(edisonn): Design: decide if we should use hasStream or isStream + // Returns true if the object has a stream associated with it. bool hasStream() const { SkPdfMarkObjectUsed(); return isDictionary() && fStr.fBuffer != NULL; } - // TODO(edisonn): has stream .. or is stream ... TBD + // Returns the stream associated with the dictionary. As of now, it casts this to Stream. const SkPdfStream* getStream() const { SkPdfMarkObjectUsed(); return hasStream() ? (const SkPdfStream*)this : NULL; } + // Returns the stream associated with the dictionary. As of now, it casts this to Stream. SkPdfStream* getStream() { SkPdfMarkObjectUsed(); return hasStream() ? (SkPdfStream*)this : NULL; } + // Returns true if the object is a String or HexString. bool isAnyString() const { SkPdfMarkObjectUsed(); return fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType; } + // Returns true if the object is a HexString. bool isHexString() const { SkPdfMarkObjectUsed(); return fObjectType == kHexString_PdfObjectType; } + // Returns true if the object is a Matrix. bool isMatrix() const { SkPdfMarkObjectUsed(); @@ -766,6 +856,7 @@ public: return fObjectType == kArray_PdfObjectType && fArray->count() == 6; } + // Returns the int value stored in the object. Assert if the object is not an Integer. inline int64_t intValue() const { SkPdfMarkObjectUsed(); @@ -777,7 +868,9 @@ public: } return fIntegerValue; } + private: + // Returns the real value stored in the object. Assert if the object is not a Real. inline double realValue() const { SkPdfMarkObjectUsed(); @@ -789,7 +882,10 @@ private: } return fRealValue; } + public: + // Returns the numeric value stored in the object. Assert if the object is not a Real + // or an Integer. inline double numberValue() const { SkPdfMarkObjectUsed(); @@ -802,6 +898,8 @@ public: return fObjectType == kReal_PdfObjectType ? fRealValue : fIntegerValue; } + // Returns the numeric value stored in the object as a scalar. Assert if the object is not + // a Realor an Integer. inline SkScalar scalarValue() const { SkPdfMarkObjectUsed(); @@ -815,6 +913,7 @@ public: SkIntToScalar(fIntegerValue); } + // Returns the id of the referenced object. Assert if the object is not a Reference. int referenceId() const { SkPdfMarkObjectUsed(); @@ -822,6 +921,7 @@ public: return fRef.fId; } + // Returns the generation of the referenced object. Assert if the object is not a Reference. int referenceGeneration() const { SkPdfMarkObjectUsed(); @@ -829,6 +929,7 @@ public: return fRef.fGen; } + // Returns the buffer of a Name object. Assert if the object is not a Name. inline const char* nameValue() const { SkPdfMarkObjectUsed(); @@ -841,6 +942,7 @@ public: return (const char*)fStr.fBuffer; } + // Returns the buffer of a (Hex)String object. Assert if the object is not a (Hex)String. inline const char* stringValue() const { SkPdfMarkObjectUsed(); @@ -853,6 +955,7 @@ public: return (const char*)fStr.fBuffer; } + // Returns the storage of any type that can hold a form of string. inline NotOwnedString strRef() { SkPdfMarkObjectUsed(); @@ -884,6 +987,7 @@ public: return SkString((const char*)fStr.fBuffer, fStr.fBytes); } + // Returns an SkString with the value of the (Hex)String object. inline SkString stringValue2() const { SkPdfMarkObjectUsed(); @@ -896,6 +1000,7 @@ public: return SkString((const char*)fStr.fBuffer, fStr.fBytes); } + // Returns the boolean of the Bool object. Assert if the object is not a Bool. inline bool boolValue() const { SkPdfMarkObjectUsed(); @@ -908,6 +1013,7 @@ public: return fBooleanValue; } + // Returns the rectangle of the Rectangle object. Assert if the object is not a Rectangle. SkRect rectangleValue() const { SkPdfMarkObjectUsed(); @@ -933,6 +1039,7 @@ public: SkDoubleToScalar(array[3])); } + // Returns the matrix of the Matrix object. Assert if the object is not a Matrix. SkMatrix matrixValue() const { SkPdfMarkObjectUsed(); @@ -955,9 +1062,13 @@ public: return SkMatrixFromPdfMatrix(array); } + // Runs all the filters of this stream, except the last one, if it is a DCT. + // Returns false on failure. bool filterStream(); - + // Runs all the filters of this stream, except the last one, if it is a DCT, a gives back + // the buffer and the length. The object continues to own the buffer. + // Returns false on failure. bool GetFilteredStreamRef(unsigned char const** buffer, size_t* len) { SkPdfMarkObjectUsed(); @@ -980,18 +1091,22 @@ public: return true; } + // Returns true if the stream is already filtered. bool isStreamFiltered() const { SkPdfMarkObjectUsed(); return hasStream() && ((fStr.fBytes & 1) == kFilteredStreamBit); } + // Returns true if this object own the buffer, or false if an Allocator own it. bool isStreamOwned() const { SkPdfMarkObjectUsed(); return hasStream() && ((fStr.fBytes & 2) == kOwnedStreamBit); } + // Gives back the original buffer and the length. The object continues to own the buffer. + // Returns false if the stream is already filtered. bool GetUnfilteredStreamRef(unsigned char const** buffer, size_t* len) const { SkPdfMarkObjectUsed(); @@ -1014,6 +1129,7 @@ public: return true; } + // Add a stream to this Dictionarry. Asserts we do not have yet a stream. bool addStream(const unsigned char* buffer, size_t len) { SkPdfMarkObjectUsed(); @@ -1059,6 +1175,7 @@ public: } } + // Returns the string representation of the object value. SkString toString(int firstRowLevel = 0, int level = 0) { SkString str; appendSpaces(&str, firstRowLevel); @@ -1186,6 +1303,8 @@ private: bool applyDCTDecodeFilter(); }; +// These classes are provided for convenience. You still have to make sure an SkPdfInteger +// is indeed an Integer. class SkPdfStream : public SkPdfNativeObject {}; class SkPdfArray : public SkPdfNativeObject {}; class SkPdfString : public SkPdfNativeObject {}; diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h b/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h index 77bd8b5a02..8ed354cfa1 100644 --- a/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h +++ b/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h @@ -8,15 +8,20 @@ #ifndef SkPdfNativeTokenizer_DEFINED #define SkPdfNativeTokenizer_DEFINED -#include "SkPdfConfig.h" +#include <math.h> +#include <string.h> +#include "SkPdfConfig.h" #include "SkTDArray.h" #include "SkTDict.h" -#include <math.h> -#include <string.h> + +// All these constants are defined by the PDF 1.4 Spec. class SkPdfDictionary; class SkPdfImageDictionary; +class SkPdfNativeDoc; +class SkPdfNativeObject; + // White Spaces #define kNUL_PdfWhiteSpace '\x00' @@ -49,7 +54,12 @@ class SkPdfImageDictionary; // 4) vector (e.f. T type[256] .. return type[ch] ... // 5) manually build the expression with least number of operators, e.g. for consecutive // chars, we can use an binary equal ignoring last bit -#define isPdfWhiteSpace(ch) (((ch)==kNUL_PdfWhiteSpace)||((ch)==kHT_PdfWhiteSpace)||((ch)==kLF_PdfWhiteSpace)||((ch)==kFF_PdfWhiteSpace)||((ch)==kCR_PdfWhiteSpace)||((ch)==kSP_PdfWhiteSpace)) +#define isPdfWhiteSpace(ch) (((ch)==kNUL_PdfWhiteSpace)|| \ + ((ch)==kHT_PdfWhiteSpace)|| \ + ((ch)==kLF_PdfWhiteSpace)|| \ + ((ch)==kFF_PdfWhiteSpace)|| \ + ((ch)==kCR_PdfWhiteSpace)|| \ + ((ch)==kSP_PdfWhiteSpace)) #define isPdfEOL(ch) (((ch)==kLF_PdfWhiteSpace)||((ch)==kCR_PdfWhiteSpace)) @@ -73,26 +83,16 @@ class SkPdfImageDictionary; const unsigned char* skipPdfWhiteSpaces(const unsigned char* buffer, const unsigned char* end); const unsigned char* endOfPdfToken(const unsigned char* start, const unsigned char* end); -// TODO(edisonn): typedef read and integer tyepes? make less readable... -//typedef double SkPdfReal; -//typedef int64_t SkPdfInteger; - -// an allocator only allocates memory, and it deletes it all when the allocator is destroyed -// this would allow us not to do any garbage collection while we parse or draw a pdf, and defere it -// while the user is looking at the image - -class SkPdfNativeObject; - -class SkPdfAllocator { #define BUFFER_SIZE 1024 - SkTDArray<SkPdfNativeObject*> fHistory; - SkTDArray<void*> fHandles; - SkPdfNativeObject* fCurrent; - int fCurrentUsed; - - SkPdfNativeObject* allocBlock(); - size_t fSizeInBytes; +/** \class SkPdfAllocator + * + * An allocator only allocates memory, and it deletes it all when the allocator is destroyed. + * This strategy would allow us not to do any garbage collection while we parse and/or render + * a pdf. + * + */ +class SkPdfAllocator { public: SkPdfAllocator() { fSizeInBytes = sizeof(*this); @@ -102,9 +102,10 @@ public: ~SkPdfAllocator(); + // Allocates an object. It will be reset automatically when ~SkPdfAllocator() is called. SkPdfNativeObject* allocObject(); - // TODO(edisonn): free this memory in destructor, track the usage? + // Allocates a buffer. It will be freed automatically when ~SkPdfAllocator() is called. void* alloc(size_t bytes) { void* data = malloc(bytes); fHandles.push(data); @@ -112,41 +113,71 @@ public: return data; } + // Returns the number of bytes used in this allocator. size_t bytesUsed() const { return fSizeInBytes; } -}; -class SkPdfNativeDoc; -const unsigned char* nextObject(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* token, SkPdfAllocator* allocator, SkPdfNativeDoc* doc); +private: + SkTDArray<SkPdfNativeObject*> fHistory; + SkTDArray<void*> fHandles; + SkPdfNativeObject* fCurrent; + int fCurrentUsed; + + SkPdfNativeObject* allocBlock(); + size_t fSizeInBytes; +}; +// Type of a parsed token. enum SkPdfTokenType { kKeyword_TokenType, kObject_TokenType, }; + +/** \struct PdfToken + * + * Stores the result of the parsing - a keyword or an object. + * + */ struct PdfToken { - const char* fKeyword; - size_t fKeywordLength; - SkPdfNativeObject* fObject; - SkPdfTokenType fType; + const char* fKeyword; + size_t fKeywordLength; + SkPdfNativeObject* fObject; + SkPdfTokenType fType; PdfToken() : fKeyword(NULL), fKeywordLength(0), fObject(NULL) {} }; +/** \class SkPdfNativeTokenizer + * + * Responsible to tokenize a stream in small tokens, eityh a keyword or an object. + * A renderer can feed on the tokens and render a pdf. + * + */ class SkPdfNativeTokenizer { public: - SkPdfNativeTokenizer(SkPdfNativeObject* objWithStream, SkPdfAllocator* allocator, SkPdfNativeDoc* doc); - SkPdfNativeTokenizer(const unsigned char* buffer, int len, SkPdfAllocator* allocator, SkPdfNativeDoc* doc); + SkPdfNativeTokenizer(SkPdfNativeObject* objWithStream, + SkPdfAllocator* allocator, SkPdfNativeDoc* doc); + SkPdfNativeTokenizer(const unsigned char* buffer, int len, + SkPdfAllocator* allocator, SkPdfNativeDoc* doc); virtual ~SkPdfNativeTokenizer(); + // Reads one token. Returns false if there are no more tokens. bool readToken(PdfToken* token); - bool readTokenCore(PdfToken* token); + + // Put back a token to be read in the nextToken read. Only one token is allowed to be put + // back. Must not necesaarely be the last token read. void PutBack(PdfToken token); + + // Reads the inline image that is present in the stream. At this point we just consumed the ID + // token already. SkPdfImageDictionary* readInlineImage(); private: + bool readTokenCore(PdfToken* token); + SkPdfNativeDoc* fDoc; SkPdfAllocator* fAllocator; @@ -159,4 +190,9 @@ private: PdfToken fPutBack; }; +const unsigned char* nextObject(const unsigned char* start, const unsigned char* end, + SkPdfNativeObject* token, + SkPdfAllocator* allocator, + SkPdfNativeDoc* doc); + #endif // SkPdfNativeTokenizer_DEFINED |