blob: f64090aa72cb6e80de2494e54ef29328ba7c9c05 [file] [log] [blame]
#include "SkPodofoUtils.h"
#include "SkMatrix.h"
#include "SkPdfHeaders_autogen.h"
#include "SkPdfMapper_autogen.h"
#include "podofo.h"
const PoDoFo::PdfObject* resolveReferenceObject(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfObject* obj,
bool resolveOneElementArrays) {
while (obj && (obj->IsReference() || (resolveOneElementArrays &&
obj->IsArray() &&
obj->GetArray().GetSize() == 1))) {
if (obj->IsReference()) {
// We need to force the non const, the only update we will do is for recurssion checks.
PoDoFo::PdfReference& ref = (PoDoFo::PdfReference&)obj->GetReference();
obj = pdfDoc->podofo()->GetObjects().GetObject(ref);
} else {
obj = &obj->GetArray()[0];
}
}
return obj;
}
// TODO(edisonn): deal with synonyms (/BPC == /BitsPerComponent), here or in GetKey?
// Always pass long form in key, and have a map of long -> short key
bool LongFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
long* data) {
const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
dict.GetKey(PoDoFo::PdfName(key)));
if (value == NULL || !value->IsNumber()) {
return false;
}
if (data == NULL) {
return true;
}
*data = value->GetNumber();
return true;
}
bool LongFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
long* data) {
if (LongFromDictionary(pdfDoc, dict, key, data)) return true;
if (abr == NULL || *abr == '\0') return false;
return LongFromDictionary(pdfDoc, dict, abr, data);
}
bool DoubleFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
double* data) {
const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
dict.GetKey(PoDoFo::PdfName(key)));
if (value == NULL || (!value->IsReal() && !value->IsNumber())) {
return false;
}
if (data == NULL) {
return true;
}
*data = value->GetReal();
return true;
}
bool DoubleFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
double* data) {
if (DoubleFromDictionary(pdfDoc, dict, key, data)) return true;
if (abr == NULL || *abr == '\0') return false;
return DoubleFromDictionary(pdfDoc, dict, abr, data);
}
bool BoolFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
bool* data) {
const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
dict.GetKey(PoDoFo::PdfName(key)));
if (value == NULL || !value->IsBool()) {
return false;
}
if (data == NULL) {
return true;
}
*data = value->GetBool();
return true;
}
bool BoolFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
bool* data) {
if (BoolFromDictionary(pdfDoc, dict, key, data)) return true;
if (abr == NULL || *abr == '\0') return false;
return BoolFromDictionary(pdfDoc, dict, abr, data);
}
bool NameFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
std::string* data) {
const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
dict.GetKey(PoDoFo::PdfName(key)),
true);
if (value == NULL || !value->IsName()) {
return false;
}
if (data == NULL) {
return true;
}
*data = value->GetName().GetName();
return true;
}
bool NameFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
std::string* data) {
if (NameFromDictionary(pdfDoc, dict, key, data)) return true;
if (abr == NULL || *abr == '\0') return false;
return NameFromDictionary(pdfDoc, dict, abr, data);
}
bool StringFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
std::string* data) {
const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
dict.GetKey(PoDoFo::PdfName(key)),
true);
if (value == NULL || (!value->IsString() && !value->IsHexString())) {
return false;
}
if (data == NULL) {
return true;
}
*data = value->GetString().GetString();
return true;
}
bool StringFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
std::string* data) {
if (StringFromDictionary(pdfDoc, dict, key, data)) return true;
if (abr == NULL || *abr == '\0') return false;
return StringFromDictionary(pdfDoc, dict, abr, data);
}
bool SkMatrixFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
SkMatrix** matrix) {
const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
dict.GetKey(PoDoFo::PdfName(key)));
if (value == NULL || !value->IsArray()) {
return false;
}
if (value->GetArray().GetSize() != 6) {
return false;
}
double array[6];
for (int i = 0; i < 6; i++) {
const PoDoFo::PdfObject* elem = resolveReferenceObject(pdfDoc, &value->GetArray()[i]);
if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) {
return false;
}
array[i] = elem->GetReal();
}
*matrix = new SkMatrix();
**matrix = SkMatrixFromPdfMatrix(array);
return true;
}
bool SkMatrixFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
SkMatrix** data) {
if (SkMatrixFromDictionary(pdfDoc, dict, key, data)) return true;
if (abr == NULL || *abr == '\0') return false;
return SkMatrixFromDictionary(pdfDoc, dict, abr, data);
}
bool SkRectFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
SkRect** rect) {
const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
dict.GetKey(PoDoFo::PdfName(key)));
if (value == NULL || !value->IsArray()) {
return false;
}
if (value->GetArray().GetSize() != 4) {
return false;
}
double array[4];
for (int i = 0; i < 4; i++) {
const PoDoFo::PdfObject* elem = resolveReferenceObject(pdfDoc, &value->GetArray()[i]);
if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) {
return false;
}
array[i] = elem->GetReal();
}
*rect = new SkRect();
**rect = SkRect::MakeLTRB(SkDoubleToScalar(array[0]),
SkDoubleToScalar(array[1]),
SkDoubleToScalar(array[2]),
SkDoubleToScalar(array[3]));
return true;
}
bool SkRectFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
SkRect** data) {
if (SkRectFromDictionary(pdfDoc, dict, key, data)) return true;
if (abr == NULL || *abr == '\0') return false;
return SkRectFromDictionary(pdfDoc, dict, abr, data);
}
SkPdfObject* get(const SkPdfObject* obj, const char* key, const char* abr = "") {
PoDoFo::PdfObject* podofoObj = 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, &podofoObj);
SkPdfObject* ret = NULL;
obj->doc()->mapper()->mapObject(podofoObj, &ret);
return ret;
}
bool ArrayFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
SkPdfArray* data) {return false;}
bool FileSpecFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
SkPdfFileSpec* data) {return false;}
bool StreamFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
SkPdfStream** data);
bool TreeFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
SkPdfTree** data) {return false;}
bool DateFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
SkPdfDate* data) {return false;}
bool FunctionFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
SkPdfFunction* data) {return false;}
bool ArrayFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
SkPdfArray** data) {
const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
dict.GetKey(PoDoFo::PdfName(key)),
true);
if (value == NULL || !value->IsArray()) {
return false;
}
if (data == NULL) {
return true;
}
return pdfDoc->mapper()->mapArray(value, data);
}
bool ArrayFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
SkPdfArray** data) {
if (ArrayFromDictionary(pdfDoc, dict, key, data)) return true;
if (abr == NULL || *abr == '\0') return false;
return ArrayFromDictionary(pdfDoc, dict, abr, data);
}
/*
bool DictionaryFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
SkPoDoFo::PdfDictionary** data) {
const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
dict.GetKey(PoDoFo::PdfName(key)),
true);
if (value == NULL || !value->IsDictionary()) {
return false;
}
if (data == NULL) {
return true;
}
return pdfDoc->mapper()->mapDictionary(value, data);
}
bool DictionaryFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
SkPoDoFo::PdfDictionary** data) {
if (DictionaryFromDictionary(pdfDoc, dict, key, data)) return true;
if (abr == NULL || *abr == '\0') return false;
return DictionaryFromDictionary(pdfDoc, dict, abr, data);
}
*/
bool ObjectFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
PoDoFo::PdfObject** data) {
const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
dict.GetKey(PoDoFo::PdfName(key)),
true);
if (value == NULL) {
return false;
}
if (data == NULL) {
return true;
}
*data = (PoDoFo::PdfObject*)value;
return true;
}
bool ObjectFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
PoDoFo::PdfObject** data) {
if (ObjectFromDictionary(pdfDoc, dict, key, data)) return true;
if (abr == NULL || *abr == '\0') return false;
return ObjectFromDictionary(pdfDoc, dict, abr, data);
}
bool StreamFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
SkPdfStream** data) {
const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
dict.GetKey(PoDoFo::PdfName(key)),
true);
if (value == NULL) {
return false;
}
if (data == NULL) {
return true;
}
return pdfDoc->mapper()->mapStream(value, data);
}
bool StreamFromDictionary(const SkPodofoParsedPDF* pdfDoc,
const PoDoFo::PdfDictionary& dict,
const char* key,
const char* abr,
SkPdfStream** data) {
if (StreamFromDictionary(pdfDoc, dict, key, data)) return true;
if (abr == NULL || *abr == '\0') return false;
return StreamFromDictionary(pdfDoc, dict, abr, data);
}