SkPdfNativeObject.h revision d761e3295c10e467d5ae4a5f52ad80c85b656e23
102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#ifndef EXPERIMENTAL_PDFVIEWER_PDFPARSER_NATIVE_SKPDFOBJECT_H_ 202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#define EXPERIMENTAL_PDFVIEWER_PDFPARSER_NATIVE_SKPDFOBJECT_H_ 302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <stdint.h> 502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <string.h> 602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include <string> 702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include "SkTDArray.h" 802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include "SkTDict.h" 902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include "SkRect.h" 1002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include "SkMatrix.h" 1102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include "SkString.h" 1202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 1302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include "SkPdfNYI.h" 1402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#include "SkPdfConfig.h" 1502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 1602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectclass SkPdfDictionary; 1702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectclass SkPdfStream; 1802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectclass SkPdfAllocator; 1902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 2002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project// TODO(edisonn): macro it and move it to utils 2102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source ProjectSkMatrix SkMatrixFromPdfMatrix(double array[6]); 2202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 2302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 2402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#define kFilteredStreamBit 0 2502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project#define kUnfilteredStreamBit 1 2602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 2702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 2802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectclass SkPdfObject { 2902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project public: 3002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project enum ObjectType { 3102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project kInvalid_PdfObjectType, 3202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 3302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project kBoolean_PdfObjectType, 3402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project kInteger_PdfObjectType, 3502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project kReal_PdfObjectType, 3602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project kString_PdfObjectType, 3702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project kHexString_PdfObjectType, 3802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project kName_PdfObjectType, 3902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project kKeyword_PdfObjectType, 4002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project //kStream_PdfObjectType, // attached to a Dictionary 4102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project kArray_PdfObjectType, 4202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project kDictionary_PdfObjectType, 4302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project kNull_PdfObjectType, 4402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 4502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // TODO(edisonn): after the pdf has been loaded completely, resolve all references 4602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // try the same thing with delayed loaded ... 4702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project kReference_PdfObjectType, 4802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 4902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project kUndefined_PdfObjectType, // per 1.4 spec, if the same key appear twice in the dictionary, the value is undefined 5002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project }; 5102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 5202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectprivate: 5302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project struct NotOwnedString { 5402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project unsigned char* fBuffer; 5502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project size_t fBytes; 5602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project }; 5702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 5802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project struct Reference { 5902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project unsigned int fId; 6002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project unsigned int fGen; 6102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project }; 6202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 6302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // TODO(edisonn): add stream start, stream end, where stream is weither the file 6402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // or decoded/filtered pdf stream 6502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 6602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // TODO(edisonn): add warning/report per object 6702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // TODO(edisonn): add flag fUsed, to be used once the parsing is complete, 6802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // so we could show what parts have been proccessed, ignored, or generated errors 6902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 7002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project ObjectType fObjectType; 7102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 7202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project union { 7302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project bool fBooleanValue; 7402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project int64_t fIntegerValue; 7502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // TODO(edisonn): double, float? typedefed 7602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project double fRealValue; 7702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project NotOwnedString fStr; 7802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 7902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // TODO(edisonn): make sure the foorprint of fArray and fMap is small, otherwise, use pointers, or classes with up to 8 bytes in footprint 8002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project SkTDArray<SkPdfObject*>* fArray; 8102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project Reference fRef; 8202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project }; 8302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project SkTDict<SkPdfObject*>* fMap; 8402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project void* fData; 8502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 8602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 8702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Projectpublic: 8802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 8902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project SkPdfObject() : fObjectType(kInvalid_PdfObjectType), fMap(NULL), fData(NULL) {} 9002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 9102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project inline void* data() { 9202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project return fData; 9302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 9402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 9502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project inline void setData(void* data) { 9602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project fData = data; 9702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 9802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 9902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project// ~SkPdfObject() { 10002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project// //reset(); must be called manually! 10102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project// } 10202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 10302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project void reset() { 10402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project switch (fObjectType) { 10502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project case kArray_PdfObjectType: 10602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project delete fArray; 10702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project break; 10802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 10902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project case kDictionary_PdfObjectType: 11002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project delete fMap; 11102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project break; 11202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 11302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project default: 11402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project break; 11502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 11602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project fObjectType = kInvalid_PdfObjectType; 11702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 11802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 11902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project ObjectType type() { return fObjectType; } 12002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 12102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project const char* c_str() const { 12202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project switch (fObjectType) { 12302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project case kString_PdfObjectType: 12402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project case kHexString_PdfObjectType: 12502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project case kKeyword_PdfObjectType: 12602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project return (const char*)fStr.fBuffer; 12702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 12802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project default: 12902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // TODO(edisonn): report/warning 13002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project return NULL; 13102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 13202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 13302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 13402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project size_t len() const { 13502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project switch (fObjectType) { 13602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project case kString_PdfObjectType: 13702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project case kHexString_PdfObjectType: 13802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project case kKeyword_PdfObjectType: 13902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project return fStr.fBytes; 14002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 14102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project default: 14202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // TODO(edisonn): report/warning 14302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project return 0; 14402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 14502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 14602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 14702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 14802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // TODO(edisonn): NYI 14902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project SkPdfDate& dateValue() const { 15002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static SkPdfDate nyi; 15102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project return nyi; 15202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 15302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 15402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // TODO(edisonn): NYI 15502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project SkPdfFunction& functionValue() const { 15602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static SkPdfFunction nyi; 15702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project return nyi; 15802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 15902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 16002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // TODO(edisonn): NYI 16102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project SkPdfFileSpec& fileSpecValue() const { 16202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static SkPdfFileSpec nyi; 16302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project return nyi; 16402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 16502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 16602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // TODO(edisonn): NYI 16702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project SkPdfTree& treeValue() const { 16802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static SkPdfTree nyi; 16902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project return nyi; 17002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 17102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 17202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 17302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static void makeBoolean(bool value, SkPdfObject* obj) { 17402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); 17502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 17602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project obj->fObjectType = kBoolean_PdfObjectType; 17702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project obj->fBooleanValue = value; 17802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 17902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 18002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static SkPdfObject makeBoolean(bool value) { 18102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project SkPdfObject obj; 18202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project obj.fObjectType = kBoolean_PdfObjectType; 18302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project obj.fBooleanValue = value; 18402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project return obj; 18502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 18602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 18702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static void makeInteger(int64_t value, SkPdfObject* obj) { 18802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); 18902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 19002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project obj->fObjectType = kInteger_PdfObjectType; 19102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project obj->fIntegerValue = value; 19202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 19302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 19402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static void makeReal(double value, SkPdfObject* obj) { 19502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); 19602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 19702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project obj->fObjectType = kReal_PdfObjectType; 19802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project obj->fRealValue = value; 19902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 20002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 20102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static void makeNull(SkPdfObject* obj) { 20202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); 20302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 20402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project obj->fObjectType = kNull_PdfObjectType; 20502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 20602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 20702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static SkPdfObject makeNull() { 20802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project SkPdfObject obj; 20902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project obj.fObjectType = kNull_PdfObjectType; 21002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project return obj; 21102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 21202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 21302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static SkPdfObject kNull; 21402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 21502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static void makeNumeric(unsigned char* start, unsigned char* end, SkPdfObject* obj) { 21602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); 21702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 21802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // TODO(edisonn): NYI properly 21902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // if has dot (impl), or exceeds max int, is real, otherwise is int 22002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project bool isInt = true; 22102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project for (unsigned char* current = start; current < end; current++) { 22202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project if (*current == '.') { 22302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project isInt = false; 22402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project break; 22502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 22602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project // TODO(edisonn): report parse issue with numbers like "24asdasd123" 22702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 22802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project if (isInt) { 22902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project makeInteger(atol((const char*)start), obj); 23002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } else { 23102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project makeReal(atof((const char*)start), obj); 23202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 23302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 23402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 23502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static void makeReference(unsigned int id, unsigned int gen, SkPdfObject* obj) { 23602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); 23702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 23802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project obj->fObjectType = kReference_PdfObjectType; 23902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project obj->fRef.fId = id; 24002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project obj->fRef.fGen = gen; 24102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 24202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 24302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 24402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static void makeString(unsigned char* start, SkPdfObject* obj) { 24502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project makeStringCore(start, strlen((const char*)start), obj, kString_PdfObjectType); 24602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 24702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 24802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static void makeString(unsigned char* start, unsigned char* end, SkPdfObject* obj) { 24902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project makeStringCore(start, end - start, obj, kString_PdfObjectType); 25002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 25102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 25202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static void makeString(unsigned char* start, size_t bytes, SkPdfObject* obj) { 25302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project makeStringCore(start, bytes, obj, kString_PdfObjectType); 25402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 25502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 25602fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 25702fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static void makeHexString(unsigned char* start, SkPdfObject* obj) { 25802fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project makeStringCore(start, strlen((const char*)start), obj, kHexString_PdfObjectType); 25902fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 26002fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 26102fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static void makeHexString(unsigned char* start, unsigned char* end, SkPdfObject* obj) { 26202fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project makeStringCore(start, end - start, obj, kHexString_PdfObjectType); 26302fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project } 26402fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project 26502fb0aca1189a2c1fd20806c588e9ee80d9755f8The Android Open Source Project static void makeHexString(unsigned char* start, size_t bytes, SkPdfObject* obj) { 266 makeStringCore(start, bytes, obj, kHexString_PdfObjectType); 267 } 268 269 270 static void makeName(unsigned char* start, SkPdfObject* obj) { 271 makeStringCore(start, strlen((const char*)start), obj, kName_PdfObjectType); 272 } 273 274 static void makeName(unsigned char* start, unsigned char* end, SkPdfObject* obj) { 275 makeStringCore(start, end - start, obj, kName_PdfObjectType); 276 } 277 278 static void makeName(unsigned char* start, size_t bytes, SkPdfObject* obj) { 279 makeStringCore(start, bytes, obj, kName_PdfObjectType); 280 } 281 282 283 static void makeKeyword(unsigned char* start, SkPdfObject* obj) { 284 makeStringCore(start, strlen((const char*)start), obj, kKeyword_PdfObjectType); 285 } 286 287 static void makeKeyword(unsigned char* start, unsigned char* end, SkPdfObject* obj) { 288 makeStringCore(start, end - start, obj, kKeyword_PdfObjectType); 289 } 290 291 static void makeKeyword(unsigned char* start, size_t bytes, SkPdfObject* obj) { 292 makeStringCore(start, bytes, obj, kKeyword_PdfObjectType); 293 } 294 295 296 297 // TODO(edisonn): make the functions to return SkPdfArray, move these functions in SkPdfArray 298 static void makeEmptyArray(SkPdfObject* obj) { 299 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); 300 301 obj->fObjectType = kArray_PdfObjectType; 302 obj->fArray = new SkTDArray<SkPdfObject*>(); 303 // return (SkPdfArray*)obj; 304 } 305 306 bool appendInArray(SkPdfObject* obj) { 307 SkASSERT(fObjectType == kArray_PdfObjectType); 308 if (fObjectType != kArray_PdfObjectType) { 309 // TODO(edisonn): report err 310 return false; 311 } 312 313 fArray->push(obj); 314 return true; 315 } 316 317 size_t size() const { 318 SkASSERT(fObjectType == kArray_PdfObjectType); 319 320 return fArray->count(); 321 } 322 323 SkPdfObject* objAtAIndex(int i) { 324 SkASSERT(fObjectType == kArray_PdfObjectType); 325 326 return (*fArray)[i]; 327 } 328 329 SkPdfObject* removeLastInArray() { 330 SkASSERT(fObjectType == kArray_PdfObjectType); 331 332 SkPdfObject* ret = NULL; 333 fArray->pop(&ret); 334 335 return ret; 336 } 337 338 339 const SkPdfObject* objAtAIndex(int i) const { 340 SkASSERT(fObjectType == kArray_PdfObjectType); 341 342 return (*fArray)[i]; 343 } 344 345 SkPdfObject* operator[](int i) { 346 SkASSERT(fObjectType == kArray_PdfObjectType); 347 348 return (*fArray)[i]; 349 } 350 351 const SkPdfObject* operator[](int i) const { 352 SkASSERT(fObjectType == kArray_PdfObjectType); 353 354 return (*fArray)[i]; 355 } 356 357 358 // TODO(edisonn): make the functions to return SkPdfDictionary, move these functions in SkPdfDictionary 359 static void makeEmptyDictionary(SkPdfObject* obj) { 360 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); 361 362 obj->fObjectType = kDictionary_PdfObjectType; 363 obj->fMap = new SkTDict<SkPdfObject*>(1); 364 obj->fStr.fBuffer = NULL; 365 obj->fStr.fBytes = 0; 366 } 367 368 // TODO(edisonn): get all the possible names from spec, and compute a hash function 369 // that would create no overlaps in the same dictionary 370 // or build a tree of chars that when followed goes to a unique id/index/hash 371 // TODO(edisonn): generate constants like kDictFoo, kNameDict_name 372 // which will be used in code 373 // add function SkPdfFastNameKey key(const char* key); 374 // TODO(edisonn): setting the same key twike, will make the value undefined! 375 bool set(SkPdfObject* key, SkPdfObject* value) { 376 SkASSERT(fObjectType == kDictionary_PdfObjectType); 377 SkASSERT(key->fObjectType == kName_PdfObjectType); 378 379 if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionary_PdfObjectType) { 380 // TODO(edisonn): report err 381 return false; 382 } 383 384 // we rewrite all delimiters and white spaces with '\0', so we expect the end of name to be '\0' 385 SkASSERT(key->fStr.fBuffer[key->fStr.fBytes] == '\0'); 386 387 return set(key->fStr.fBuffer, key->fStr.fBytes, value); 388 } 389 390 bool set(const char* key, SkPdfObject* value) { 391 return set((const unsigned char*)key, strlen(key), value); 392 } 393 394 bool set(const unsigned char* key, size_t len, SkPdfObject* value) { 395 SkASSERT(fObjectType == kDictionary_PdfObjectType); 396 397 if (fObjectType != kDictionary_PdfObjectType) { 398 // TODO(edisonn): report err 399 return false; 400 } 401 402 return fMap->set((const char*)key, len, value); 403 } 404 405 SkPdfObject* get(SkPdfObject* key) { 406 SkASSERT(fObjectType == kDictionary_PdfObjectType); 407 SkASSERT(key->fObjectType == kName_PdfObjectType); 408 409 if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionary_PdfObjectType) { 410 // TODO(edisonn): report err 411 return NULL; 412 } 413 414 SkASSERT(key->fStr.fBuffer[key->fStr.fBytes] == '\0'); 415 416 return get(key->fStr.fBuffer, key->fStr.fBytes); 417 } 418 419 SkPdfObject* get(const char* key) { 420 return get((const unsigned char*)key, strlen(key)); 421 } 422 423 SkPdfObject* get(const unsigned char* key, size_t len) { 424 SkASSERT(fObjectType == kDictionary_PdfObjectType); 425 SkASSERT(key); 426 if (fObjectType != kDictionary_PdfObjectType) { 427 // TODO(edisonn): report err 428 return NULL; 429 } 430 SkPdfObject* ret = NULL; 431 fMap->find((const char*)key, len, &ret); 432 return ret; 433 } 434 435 const SkPdfObject* get(SkPdfObject* key) const { 436 SkASSERT(fObjectType == kDictionary_PdfObjectType); 437 SkASSERT(key->fObjectType == kName_PdfObjectType); 438 439 if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionary_PdfObjectType) { 440 // TODO(edisonn): report err 441 return NULL; 442 } 443 444 SkASSERT(key->fStr.fBuffer[key->fStr.fBytes] == '\0'); 445 446 return get(key->fStr.fBuffer, key->fStr.fBytes); 447 } 448 449 const SkPdfObject* get(const char* key) const { 450 return get((const unsigned char*)key, strlen(key)); 451 } 452 453 const SkPdfObject* get(const unsigned char* key, size_t len) const { 454 SkASSERT(fObjectType == kDictionary_PdfObjectType); 455 SkASSERT(key); 456 if (fObjectType != kDictionary_PdfObjectType) { 457 // TODO(edisonn): report err 458 return NULL; 459 } 460 SkPdfObject* ret = NULL; 461 fMap->find((const char*)key, len, &ret); 462 return ret; 463 } 464 465 const SkPdfObject* get(const char* key, const char* abr) const { 466 const SkPdfObject* ret = get(key); 467 // TODO(edisonn): / is a valid name, and it might be an abreviation, so "" should not be like NULL 468 // make this distiontion in generator, and remove "" from condition 469 if (ret != NULL || abr == NULL || *abr == '\0') { 470 return ret; 471 } 472 return get(abr); 473 } 474 475 SkPdfObject* get(const char* key, const char* abr) { 476 SkPdfObject* ret = get(key); 477 // TODO(edisonn): / is a valid name, and it might be an abreviation, so "" should not be like NULL 478 // make this distiontion in generator, and remove "" from condition 479 if (ret != NULL || abr == NULL || *abr == '\0') { 480 return ret; 481 } 482 return get(abr); 483 } 484 485 SkPdfDictionary* asDictionary() { 486 SkASSERT(isDictionary()); 487 if (!isDictionary()) { 488 return NULL; 489 } 490 return (SkPdfDictionary*) this; 491 } 492 493 const SkPdfDictionary* asDictionary() const { 494 SkASSERT(isDictionary()); 495 if (!isDictionary()) { 496 return NULL; 497 } 498 return (SkPdfDictionary*) this; 499 } 500 501 502 bool isReference() const { 503 return fObjectType == kReference_PdfObjectType; 504 } 505 506 bool isBoolean() const { 507 return fObjectType == kBoolean_PdfObjectType; 508 } 509 510 bool isInteger() const { 511 return fObjectType == kInteger_PdfObjectType; 512 } 513private: 514 bool isReal() const { 515 return fObjectType == kReal_PdfObjectType; 516 } 517public: 518 bool isNumber() const { 519 return fObjectType == kInteger_PdfObjectType || fObjectType == kReal_PdfObjectType; 520 } 521 522 bool isKeywordReference() const { 523 return fObjectType == kKeyword_PdfObjectType && fStr.fBytes == 1 && fStr.fBuffer[0] == 'R'; 524 } 525 526 bool isKeyword() const { 527 return fObjectType == kKeyword_PdfObjectType; 528 } 529 530 bool isName() const { 531 return fObjectType == kName_PdfObjectType; 532 } 533 534 bool isName(const char* name) const { 535 return fObjectType == kName_PdfObjectType && fStr.fBytes == strlen(name) && strncmp((const char*)fStr.fBuffer, name, fStr.fBytes) == 0; 536 } 537 538 bool isArray() const { 539 return fObjectType == kArray_PdfObjectType; 540 } 541 542 bool isDate() const { 543 return fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType; 544 } 545 546 bool isDictionary() const { 547 return fObjectType == kDictionary_PdfObjectType; 548 } 549 550 bool isFunction() const { 551 return false; // NYI 552 } 553 554 bool isRectangle() const { 555 return fObjectType == kArray_PdfObjectType && fArray->count() == 4; // NYI + and elems are numbers 556 } 557 558 // TODO(edisonn): has stream .. or is stream ... TBD 559 bool hasStream() const { 560 return isDictionary() && fStr.fBuffer != NULL; 561 } 562 563 // TODO(edisonn): has stream .. or is stream ... TBD 564 const SkPdfStream* getStream() const { 565 return hasStream() ? (const SkPdfStream*)this : NULL; 566 } 567 568 SkPdfStream* getStream() { 569 return hasStream() ? (SkPdfStream*)this : NULL; 570 } 571 572 bool isAnyString() const { 573 return fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType; 574 } 575 576 bool isMatrix() const { 577 return fObjectType == kArray_PdfObjectType && fArray->count() == 6; // NYI + and elems are numbers 578 } 579 580 inline int64_t intValue() const { 581 SkASSERT(fObjectType == kInteger_PdfObjectType); 582 583 if (fObjectType != kInteger_PdfObjectType) { 584 // TODO(edisonn): log err 585 return 0; 586 } 587 return fIntegerValue; 588 } 589private: 590 inline double realValue() const { 591 SkASSERT(fObjectType == kReal_PdfObjectType); 592 593 if (fObjectType != kReal_PdfObjectType) { 594 // TODO(edisonn): log err 595 return 0; 596 } 597 return fRealValue; 598 } 599public: 600 inline double numberValue() const { 601 SkASSERT(isNumber()); 602 603 if (!isNumber()) { 604 // TODO(edisonn): log err 605 return 0; 606 } 607 return fObjectType == kReal_PdfObjectType ? fRealValue : fIntegerValue; 608 } 609 610 int referenceId() const { 611 SkASSERT(fObjectType == kReference_PdfObjectType); 612 return fRef.fId; 613 } 614 615 int referenceGeneration() const { 616 SkASSERT(fObjectType == kReference_PdfObjectType); 617 return fRef.fGen; 618 } 619 620 inline const char* nameValue() const { 621 SkASSERT(fObjectType == kName_PdfObjectType); 622 623 if (fObjectType != kName_PdfObjectType) { 624 // TODO(edisonn): log err 625 return ""; 626 } 627 return (const char*)fStr.fBuffer; 628 } 629 630 inline const char* stringValue() const { 631 SkASSERT(fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType); 632 633 if (fObjectType != kString_PdfObjectType && fObjectType != kHexString_PdfObjectType) { 634 // TODO(edisonn): log err 635 return ""; 636 } 637 return (const char*)fStr.fBuffer; 638 } 639 640 // TODO(edisonn): nameValue2 and stringValue2 are used to make code generation easy, 641 // but it is not a performat way to do it, since it will create an extra copy 642 // remove these functions and make code generated faster 643 inline std::string nameValue2() const { 644 SkASSERT(fObjectType == kName_PdfObjectType); 645 646 if (fObjectType != kName_PdfObjectType) { 647 // TODO(edisonn): log err 648 return ""; 649 } 650 return (const char*)fStr.fBuffer; 651 } 652 653 inline std::string stringValue2() const { 654 SkASSERT(fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType); 655 656 if (fObjectType != kString_PdfObjectType && fObjectType != kHexString_PdfObjectType) { 657 // TODO(edisonn): log err 658 return ""; 659 } 660 return (const char*)fStr.fBuffer; 661 } 662 663 inline bool boolValue() const { 664 SkASSERT(fObjectType == kBoolean_PdfObjectType); 665 666 if (fObjectType == kBoolean_PdfObjectType) { 667 // TODO(edisonn): log err 668 return false; 669 } 670 return fBooleanValue; 671 } 672 673 SkRect rectangleValue() const { 674 SkASSERT(isRectangle()); 675 if (!isRectangle()) { 676 return SkRect::MakeEmpty(); 677 } 678 679 double array[4]; 680 for (int i = 0; i < 4; i++) { 681 // TODO(edisonn): version where we could resolve references? 682 const SkPdfObject* elem = objAtAIndex(i); 683 if (elem == NULL || !elem->isNumber()) { 684 // TODO(edisonn): report error 685 return SkRect::MakeEmpty(); 686 } 687 array[i] = elem->numberValue(); 688 } 689 690 return SkRect::MakeLTRB(SkDoubleToScalar(array[0]), 691 SkDoubleToScalar(array[1]), 692 SkDoubleToScalar(array[2]), 693 SkDoubleToScalar(array[3])); 694 } 695 696 SkMatrix matrixValue() const { 697 SkASSERT(isMatrix()); 698 if (!isMatrix()) { 699 return SkMatrix::I(); 700 } 701 702 double array[6]; 703 for (int i = 0; i < 6; i++) { 704 // TODO(edisonn): version where we could resolve references? 705 const SkPdfObject* elem = objAtAIndex(i); 706 if (elem == NULL || !elem->isNumber()) { 707 // TODO(edisonn): report error 708 return SkMatrix::I(); 709 } 710 array[i] = elem->numberValue(); 711 } 712 713 return SkMatrixFromPdfMatrix(array); 714 } 715 716 bool filterStream(SkPdfAllocator* allocator); 717 718 719 bool GetFilteredStreamRef(unsigned char** buffer, size_t* len, SkPdfAllocator* allocator) { 720 // TODO(edisonn): add params that couls let the last filter in place if it is jpeg or png to fast load images 721 if (!hasStream()) { 722 return false; 723 } 724 725 filterStream(allocator); 726 727 if (buffer) { 728 *buffer = fStr.fBuffer; 729 } 730 731 if (len) { 732 *len = fStr.fBytes >> 1; // last bit 733 } 734 735 return true; 736 } 737 738 bool isStreamFiltered() const { 739 return hasStream() && ((fStr.fBytes & 1) == kFilteredStreamBit); 740 } 741 742 bool GetUnfilteredStreamRef(unsigned char** buffer, size_t* len) const { 743 if (isStreamFiltered()) { 744 return false; 745 } 746 747 if (!hasStream()) { 748 return false; 749 } 750 751 if (buffer) { 752 *buffer = fStr.fBuffer; 753 } 754 755 if (len) { 756 *len = fStr.fBytes >> 1; // remove slast bit 757 } 758 759 return true; 760 } 761 762 bool addStream(unsigned char* buffer, size_t len) { 763 SkASSERT(!hasStream()); 764 SkASSERT(isDictionary()); 765 766 if (!isDictionary() || hasStream()) { 767 return false; 768 } 769 770 fStr.fBuffer = buffer; 771 fStr.fBytes = (len << 2) + kUnfilteredStreamBit; 772 773 return true; 774 } 775 776 SkString toString() { 777 SkString str; 778 switch (fObjectType) { 779 case kInvalid_PdfObjectType: 780 str.append("Invalid"); 781 break; 782 783 case kBoolean_PdfObjectType: 784 str.appendf("Boolean: %s", fBooleanValue ? "true" : "false"); 785 break; 786 787 case kInteger_PdfObjectType: 788 str.appendf("Integer: %i", (int)fIntegerValue); 789 break; 790 791 case kReal_PdfObjectType: 792 str.appendf("Real: %f", fRealValue); 793 break; 794 795 case kString_PdfObjectType: 796 str.appendf("String, len() = %u: ", (unsigned int)fStr.fBytes); 797 str.append((const char*)fStr.fBuffer, fStr.fBytes); 798 break; 799 800 case kHexString_PdfObjectType: 801 str.appendf("HexString, len() = %u: ", (unsigned int)fStr.fBytes); 802 str.append((const char*)fStr.fBuffer, fStr.fBytes); 803 break; 804 805 case kName_PdfObjectType: 806 str.appendf("Name, len() = %u: ", (unsigned int)fStr.fBytes); 807 str.append((const char*)fStr.fBuffer, fStr.fBytes); 808 break; 809 810 case kKeyword_PdfObjectType: 811 str.appendf("Keyword, len() = %u: ", (unsigned int)fStr.fBytes); 812 str.append((const char*)fStr.fBuffer, fStr.fBytes); 813 break; 814 815 case kArray_PdfObjectType: 816 str.append("Array, size() = %i [", size()); 817 for (unsigned int i = 0; i < size(); i++) { 818 str.append(objAtAIndex(i)->toString()); 819 } 820 str.append("]"); 821 break; 822 823 case kDictionary_PdfObjectType: 824 // TODO(edisonn): NYI 825 str.append("Dictionary: NYI"); 826 if (hasStream()) { 827 str.append(" HAS_STREAM"); 828 } 829 break; 830 831 case kNull_PdfObjectType: 832 str = "NULL"; 833 break; 834 835 case kReference_PdfObjectType: 836 str.appendf("Reference: %i %i", fRef.fId, fRef.fGen); 837 break; 838 839 case kUndefined_PdfObjectType: 840 str = "Undefined"; 841 break; 842 843 default: 844 str = "Internal Error Object Type"; 845 break; 846 } 847 848 return str; 849 } 850 851private: 852 static void makeStringCore(unsigned char* start, SkPdfObject* obj, ObjectType type) { 853 makeStringCore(start, strlen((const char*)start), obj, type); 854 } 855 856 static void makeStringCore(unsigned char* start, unsigned char* end, SkPdfObject* obj, ObjectType type) { 857 makeStringCore(start, end - start, obj, type); 858 } 859 860 static void makeStringCore(unsigned char* start, size_t bytes, SkPdfObject* obj, ObjectType type) { 861 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType); 862 863 obj->fObjectType = type; 864 obj->fStr.fBuffer = start; 865 obj->fStr.fBytes = bytes; 866 } 867 868 bool applyFilter(const char* name, SkPdfAllocator* allocator); 869 bool applyFlateDecodeFilter(SkPdfAllocator* allocator); 870 bool applyDCTDecodeFilter(SkPdfAllocator* allocator); 871}; 872 873class SkPdfStream : public SkPdfObject {}; 874class SkPdfArray : public SkPdfObject {}; 875class SkPdfString : public SkPdfObject {}; 876class SkPdfHexString : public SkPdfObject {}; 877class SkPdfInteger : public SkPdfObject {}; 878class SkPdfReal : public SkPdfObject {}; 879class SkPdfNumber : public SkPdfObject {}; 880 881class SkPdfName : public SkPdfObject { 882 SkPdfName() : SkPdfObject() { 883 SkPdfObject::makeName((unsigned char*)"", this); 884 } 885public: 886 SkPdfName(char* name) : SkPdfObject() { 887 this->makeName((unsigned char*)name, this); 888 } 889}; 890 891#endif // EXPERIMENTAL_PDFVIEWER_PDFPARSER_NATIVE_SKPDFOBJECT_H_ 892