| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- #include "PdfObject.h"
- #include "MuException.h"
- #include "Vcclr.h"
- #pragma region pdf-object.c
- typedef enum pdf_objkind_e {
- PDF_INT = 'i',
- PDF_REAL = 'f',
- PDF_STRING = 's',
- PDF_NAME = 'n',
- PDF_ARRAY = 'a',
- PDF_DICT = 'd',
- PDF_INDIRECT = 'r'
- } pdf_objkind;
- #pragma endregion
- using namespace System;
- using namespace System::Runtime::InteropServices;
- using namespace MuPDF;
- // hack: this method hacks into mupdf/pdf-object.c and provides direct type kind info of a PdfObject
- Kind PdfObject::TypeKind::get() {
- if (_obj == PDF_NULL) {
- return Kind::Null;
- }
- if (_obj == PDF_TRUE || _obj == PDF_FALSE) {
- return Kind::Boolean;
- }
- if (_obj < PDF_LIMIT) {
- return Kind::Name;
- }
- switch (_obj->kind) {
- case PDF_INT: return Kind::Integer;
- case PDF_REAL: return Kind::Float;
- case PDF_STRING: return Kind::String;
- case PDF_NAME: return Kind::Name;
- case PDF_ARRAY: return Kind::Array;
- case PDF_DICT: return pdf_is_stream(_ctx, _obj) ? Kind::Stream : Kind::Dictionary;
- case PDF_INDIRECT: return Kind::Reference;
- }
- return Kind::Unknown;
- };
- PdfObject^ PdfObject::Wrap(pdf_obj* obj) {
- if (obj == PDF_NULL) {
- return (PdfObject^)PdfNull::Instance;
- }
- if (obj == PDF_TRUE) {
- return (PdfObject^)PdfBoolean::True;
- }
- if (obj == PDF_FALSE) {
- return (PdfObject^)PdfBoolean::False;
- }
- if (obj < PDF_LIMIT) {
- return gcnew PdfName(obj);
- }
- switch (obj->kind) {
- case PDF_INT: return gcnew PdfInteger(obj);
- case PDF_REAL: return gcnew PdfFloat(obj);
- case PDF_STRING: return gcnew PdfString(obj);
- case PDF_NAME: return gcnew PdfName(obj);
- case PDF_ARRAY: return gcnew PdfArray(obj);
- case PDF_DICT: return pdf_is_stream(Context::Ptr, obj) ? gcnew PdfStream(obj) : gcnew PdfDictionary(obj);
- case PDF_INDIRECT: return gcnew PdfReference(obj);
- }
- throw gcnew MuException("Invalid object kind: " + obj->kind.ToString());
- }
- bool PdfObject::Equals(PdfObject^ other) {
- return other && pdf_objcmp(_ctx, Ptr, other->Ptr) == 0;
- }
- pdf_obj* PdfContainer::NewPdfString(String^ text) {
- array<unsigned char>^ b;
- pin_ptr<unsigned char> pb;
- for each (auto ch in text) {
- if (ch > 127) {
- int l = (text->Length + 1) << 1;
- b = gcnew array<unsigned char>(l);
- b[0] = 0xFF;
- b[1] = 0xFE;
- pin_ptr<const wchar_t> ps = PtrToStringChars(text);
- pb = &b[2];
- memcpy(pb, ps, l - 2);
- goto MAKE_STRING;
- }
- }
- b = AsciiEncoding->GetBytes(text);
- MAKE_STRING:
- pb = &b[0];
- return pdf_new_string(Ctx, (const char*)(void*)pb, b->Length);
- }
- PdfObject^ PdfDictionary::Locate(...array<PdfNames>^ names) {
- auto ctx = Ctx;
- auto obj = Ptr;
- int length = names->Length;
- if (length == 0) {
- goto RETURN_NULL;
- }
- int i;
- for (i = 0; i < length - 1; i++) {
- obj = pdf_dict_get(ctx, obj, (pdf_obj*)names[i]);
- if (!obj) {
- goto RETURN_NULL;
- }
- obj = pdf_resolve_indirect_chain(ctx, obj);
- if (pdf_is_dict(ctx, obj) == false) {
- goto RETURN_NULL;
- }
- }
- return Wrap(pdf_resolve_indirect_chain(ctx, pdf_dict_get(ctx, obj, (pdf_obj*)names[i])));
- RETURN_NULL:
- return (PdfObject^)PdfNull::Instance;
- }
- array<Byte>^ PdfString::GetBytes() {
- size_t l;
- auto b = pdf_to_string(Ctx, Ptr, &l);
- array<Byte>^ r = gcnew array<Byte>(l);
- memcpy(&r, b, l);
- return r;
- }
- String^ PdfString::DecodePdfString() {
- size_t l;
- auto b = pdf_to_string(Ctx, Ptr, &l);
- if (b[0] == (char)254 && b[1] == (char)255) {
- return gcnew String(b, 2, l - 2, Encoding::BigEndianUnicode);
- }
- if (b[0] == (char)255 && b[1] == (char)254) {
- return gcnew String(b, 2, l - 2, Encoding::Unicode);
- }
- // PDFENCODE
- auto chars = new Char[l];
- for (size_t i = 0; i < l; i++) {
- chars[i] = fz_unicode_from_pdf_doc_encoding[b[i]];
- }
- return gcnew String(chars, 0, l);
- }
- String^ PdfString::Value::get() {
- return _string ? _string : (_string = DecodePdfString());
- }
- void PdfStream::SetBytes(array<Byte>^ data, bool isCompressed) {
- auto ctx = Ctx;
- pin_ptr<Byte> d = &data[0];
- fz_buffer* b = fz_new_buffer_from_copied_data(ctx, d, data->Length);
- pdf_update_stream(ctx, pdf_pin_document(ctx, Ptr), Ptr, b, isCompressed);
- fz_free(ctx, b);
- }
|