diff --git CMakeLists.txt CMakeLists.txt index d59a6fc..811da4e 100644 --- CMakeLists.txt +++ CMakeLists.txt @@ -396,6 +396,7 @@ set(poppler_SRCS poppler/XpdfPluginAPI.cc poppler/Movie.cc poppler/Rendition.cc + poppler/Artwork3D.cc ) set(poppler_LIBS ${FREETYPE_LIBRARIES}) if(ENABLE_SPLASH) @@ -582,6 +583,7 @@ if(ENABLE_XPDF_HEADERS) poppler/UTF8.h poppler/XpdfPluginAPI.h poppler/Sound.h + poppler/Artwork3D.h ${CMAKE_CURRENT_BINARY_DIR}/poppler/poppler-config.h DESTINATION include/poppler) install(FILES diff --git glib/CMakeLists.txt glib/CMakeLists.txt index a40fc8a..69e9d7a 100644 --- glib/CMakeLists.txt +++ glib/CMakeLists.txt @@ -31,6 +31,7 @@ set(poppler_glib_public_headers poppler-media.h poppler.h poppler-structure-element.h + poppler-artwork3d.h ) find_program(GLIB2_MKENUMS glib-mkenums) @@ -73,6 +74,7 @@ set(poppler_glib_SRCS poppler-cached-file-loader.cc poppler-input-stream.cc poppler-structure-element.cc + poppler-artwork3d.cc ) set(poppler_glib_generated_SRCS ${CMAKE_CURRENT_BINARY_DIR}/poppler-enums.c diff --git glib/Makefile.am glib/Makefile.am index c2605cb..55cb142 100644 --- glib/Makefile.am +++ glib/Makefile.am @@ -36,6 +36,7 @@ poppler_glib_public_headers = \ poppler-media.h \ poppler-movie.h \ poppler-structure-element.h \ + poppler-artwork3d.h \ poppler.h poppler_glib_includedir = $(includedir)/poppler/glib @@ -62,6 +63,7 @@ libpoppler_glib_la_SOURCES = \ poppler-input-stream.cc \ poppler-input-stream.h \ poppler-structure-element.cc \ + poppler-artwork3d.cc \ poppler.cc \ poppler-private.h diff --git glib/poppler-annot.cc glib/poppler-annot.cc index 312aa31..6c61b4a 100644 --- glib/poppler-annot.cc +++ glib/poppler-annot.cc @@ -40,6 +40,7 @@ typedef struct _PopplerAnnotScreenClass PopplerAnnotScreenClass; typedef struct _PopplerAnnotLineClass PopplerAnnotLineClass; typedef struct _PopplerAnnotCircleClass PopplerAnnotCircleClass; typedef struct _PopplerAnnotSquareClass PopplerAnnotSquareClass; +typedef struct _PopplerAnnotArtwork3DClass PopplerAnnotArtwork3DClass; struct _PopplerAnnotClass { @@ -150,6 +151,18 @@ struct _PopplerAnnotSquareClass PopplerAnnotMarkupClass parent_class; }; +struct _PopplerAnnotArtwork3D +{ + PopplerAnnot parent_instance; + + PopplerArtwork3D *artwork3d; +}; + +struct _PopplerAnnotArtwork3DClass +{ + PopplerAnnotClass parent_class; +}; + G_DEFINE_TYPE (PopplerAnnot, poppler_annot, G_TYPE_OBJECT) G_DEFINE_TYPE (PopplerAnnotMarkup, poppler_annot_markup, POPPLER_TYPE_ANNOT) G_DEFINE_TYPE (PopplerAnnotTextMarkup, poppler_annot_text_markup, POPPLER_TYPE_ANNOT_MARKUP) @@ -161,6 +174,7 @@ G_DEFINE_TYPE (PopplerAnnotScreen, poppler_annot_screen, POPPLER_TYPE_ANNOT) G_DEFINE_TYPE (PopplerAnnotLine, poppler_annot_line, POPPLER_TYPE_ANNOT_MARKUP) G_DEFINE_TYPE (PopplerAnnotCircle, poppler_annot_circle, POPPLER_TYPE_ANNOT_MARKUP) G_DEFINE_TYPE (PopplerAnnotSquare, poppler_annot_square, POPPLER_TYPE_ANNOT_MARKUP) +G_DEFINE_TYPE (PopplerAnnotArtwork3D, poppler_annot_artwork3d, POPPLER_TYPE_ANNOT) static PopplerAnnot * _poppler_create_annot (GType annot_type, Annot *annot) @@ -533,6 +547,51 @@ _poppler_annot_movie_new (Annot *annot) } static void +poppler_annot_artwork3d_finalize (GObject *object) +{ + PopplerAnnotArtwork3D *annot_artwork3d = POPPLER_ANNOT_3D (object); + + if (annot_artwork3d->artwork3d) { + g_object_unref (annot_artwork3d->artwork3d); + annot_artwork3d->artwork3d = NULL; + } + + G_OBJECT_CLASS (poppler_annot_artwork3d_parent_class)->finalize (object); +} + +static void +poppler_annot_artwork3d_init (PopplerAnnotArtwork3D *poppler_annot) +{ +} + +static void +poppler_annot_artwork3d_class_init (PopplerAnnotArtwork3DClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = poppler_annot_artwork3d_finalize; +} + +PopplerAnnot * +_poppler_annot_artwork3d_new (Annot *annot) +{ + PopplerAnnot *poppler_annot; + Annot3D *annot3d; + + poppler_annot = _poppler_create_annot (POPPLER_TYPE_ANNOT_3D, annot); + annot3d = static_cast(poppler_annot->annot); + POPPLER_ANNOT_3D (poppler_annot)->artwork3d = _poppler_artwork3d_new (annot3d->getArtwork()); + + return poppler_annot; +} + +PopplerArtwork3D * +poppler_annot_artwork3d_get_artwork3d (PopplerAnnotArtwork3D *poppler_annot) +{ + return poppler_annot->artwork3d; +} + +static void poppler_annot_screen_finalize (GObject *object) { PopplerAnnotScreen *annot_screen = POPPLER_ANNOT_SCREEN (object); diff --git glib/poppler-annot.h glib/poppler-annot.h index 44ab5e3..24740d1 100644 --- glib/poppler-annot.h +++ glib/poppler-annot.h @@ -73,6 +73,10 @@ G_BEGIN_DECLS #define POPPLER_ANNOT_SQUARE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ANNOT_SQUARE, PopplerAnnotSquare)) #define POPPLER_IS_ANNOT_SQUARE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_ANNOT_SQUARE)) +#define POPPLER_TYPE_ANNOT_3D (poppler_annot_artwork3d_get_type ()) +#define POPPLER_ANNOT_3D(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ANNOT_3D, PopplerAnnotArtwork3D)) +#define POPPLER_IS_ANNOT_3D(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_ANNOT_3D)) + typedef enum { POPPLER_ANNOT_UNKNOWN, @@ -293,6 +297,10 @@ void poppler_annot_square_set_interior_color ( PopplerColor *poppler_color); PopplerColor *poppler_annot_square_get_interior_color (PopplerAnnotSquare *poppler_annot); +/* PopplerAnnotArtwork3D */ +GType poppler_annot_artwork3d_get_type (void) G_GNUC_CONST; +PopplerArtwork3D *poppler_annot_artwork3d_get_artwork3d (PopplerAnnotArtwork3D *poppler_annot); + G_END_DECLS #endif /* __POPPLER_ANNOT_H__ */ diff --git glib/poppler-artwork3d.cc glib/poppler-artwork3d.cc new file mode 100644 index 0000000..e322709 --- /dev/null +++ glib/poppler-artwork3d.cc @@ -0,0 +1,171 @@ +/* poppler-artwork3d.cc: glib interface to Artwork3D (adapted from poppler-media.cc) + * + * Copyright (C) 2010 Carlos Garcia Campos + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include "poppler-artwork3d.h" +#include "poppler-private.h" + +typedef struct _PopplerArtwork3DClass PopplerArtwork3DClass; + +struct _PopplerArtwork3D +{ + GObject parent_instance; + + Stream *stream; +}; + +struct _PopplerArtwork3DClass +{ + GObjectClass parent_class; +}; + +G_DEFINE_TYPE (PopplerArtwork3D, poppler_artwork3d, G_TYPE_OBJECT); + +static void +poppler_artwork3d_finalize (GObject *object) +{ + PopplerArtwork3D *artwork3d = POPPLER_ARTWORK3D (object); + + if (artwork3d->stream) { + artwork3d->stream->decRef(); + artwork3d->stream = NULL; + } + + G_OBJECT_CLASS (poppler_artwork3d_parent_class)->finalize (object); +} + +static void +poppler_artwork3d_class_init (PopplerArtwork3DClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = poppler_artwork3d_finalize; +} + +static void +poppler_artwork3d_init (PopplerArtwork3D *artwork3d) +{ +} + +PopplerArtwork3D * +_poppler_artwork3d_new (Artwork3D *poppler_artwork3d) +{ + PopplerArtwork3D *artwork3d; + + g_assert (poppler_artwork3d != NULL); + + artwork3d = POPPLER_ARTWORK3D (g_object_new (POPPLER_TYPE_ARTWORK3D, NULL)); + + artwork3d->stream = poppler_artwork3d->getStream(); + + return artwork3d; +} + +#define BUF_SIZE (1024) + +gboolean +poppler_artwork3d_save_to_callback (PopplerArtwork3D *artwork3d, + PopplerArtwork3DSaveFunc save_func, + gpointer user_data, + GError **error) +{ + gchar buf[BUF_SIZE]; + + g_return_val_if_fail (POPPLER_IS_ARTWORK3D (artwork3d), FALSE); + g_return_val_if_fail (artwork3d->stream != NULL, FALSE); + + artwork3d->stream->reset (); + + while (1) { + gsize i; + for (i = 0; i < BUF_SIZE; i++) { + buf[i] = artwork3d->stream->getChar (); + if (buf[i] == EOF) { + artwork3d->stream->close (); + return save_func (buf, i, user_data, error); + } + } + if (!save_func (buf, BUF_SIZE, user_data, error)) { + artwork3d->stream->close(); + return FALSE; + } + } + + artwork3d->stream->close (); + return TRUE; +} + +gboolean +poppler_artwork3d_save_to_file (PopplerArtwork3D *artwork3d, + const char *filename, + GError **error) +{ + gboolean result = TRUE; + FILE *f; + + g_return_val_if_fail (POPPLER_IS_ARTWORK3D (artwork3d), FALSE); + g_return_val_if_fail (artwork3d->stream != NULL, FALSE); + + f = g_fopen (filename, "wb"); + + if (f == NULL) { + gchar *display_name = g_filename_display_name (filename); + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errno), + "Failed to open '%s' for writing: %s", + display_name, + g_strerror (errno)); + g_free (display_name); + return FALSE; + } + + artwork3d->stream->reset (); + while(1) { + int data = artwork3d->stream->getChar (); + if (data == EOF) break; + if (fputc (data, f) == EOF) { + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errno), + "Error writing to 3D artwork file: %s", + g_strerror (errno)); + result = FALSE; + break; + } + } + artwork3d->stream->close (); + + if (fclose (f) < 0) + { + gchar *display_name = g_filename_display_name (filename); + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errno), + "Failed to close '%s', all data may not have been saved: %s", + display_name, + g_strerror (errno)); + g_free (display_name); + return FALSE; + } + + return result; +} diff --git glib/poppler-artwork3d.h glib/poppler-artwork3d.h new file mode 100644 index 0000000..38b98c0 --- /dev/null +++ glib/poppler-artwork3d.h @@ -0,0 +1,48 @@ +/* poppler-artwork3d.h: glib interface to Artwork3D (adapted from poppler-media.h) + * + * Copyright (C) 2010 Carlos Garcia Campos + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __POPPLER_ARTWORK3D_H__ +#define __POPPLER_ARTWORK3D_H__ + +#include +#include "poppler.h" + +G_BEGIN_DECLS + +#define POPPLER_TYPE_ARTWORK3D (poppler_artwork3d_get_type ()) +#define POPPLER_ARTWORK3D(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ARTWORK3D, PopplerArtwork3D)) +#define POPPLER_IS_ARTWORK3D(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_ARTWORK3D)) + +typedef gboolean (*PopplerArtwork3DSaveFunc) (const gchar *buf, + gsize count, + gpointer data, + GError **error); + +GType poppler_artwork3d_get_type (void) G_GNUC_CONST; +gboolean poppler_artwork3d_save_to_file (PopplerArtwork3D *artwork3d, + const char *filename, + GError **error); +gboolean poppler_artwork3d_save_to_callback (PopplerArtwork3D *artwork3d, + PopplerArtwork3DSaveFunc save_func, + gpointer user_data, + GError **error); + +G_END_DECLS + +#endif diff --git glib/poppler-page.cc glib/poppler-page.cc index 3d63bfd..00d06f1 100644 --- glib/poppler-page.cc +++ glib/poppler-page.cc @@ -1416,7 +1416,10 @@ poppler_page_get_annot_mapping (PopplerPage *page) case Annot::typeSquiggly: case Annot::typeStrikeOut: mapping->annot = _poppler_annot_text_markup_new (annot); - break; + break; + case Annot::type3D: + mapping->annot = _poppler_annot_artwork3d_new (annot); + break; default: mapping->annot = _poppler_annot_new (annot); break; diff --git glib/poppler-private.h glib/poppler-private.h index 9abdd7c..8eada2f 100644 --- glib/poppler-private.h +++ glib/poppler-private.h @@ -18,6 +18,7 @@ #include #include #include +#include #endif struct _PopplerDocument @@ -134,6 +135,8 @@ PopplerAnnot *_poppler_annot_screen_new (PopplerDocument *doc, Annot *annot PopplerAnnot *_poppler_annot_line_new (Annot *annot); PopplerAnnot *_poppler_annot_circle_new (Annot *annot); PopplerAnnot *_poppler_annot_square_new (Annot *annot); +PopplerAnnot *_poppler_annot_artwork3d_new (Annot *annot); +PopplerArtwork3D *_poppler_artwork3d_new (Artwork3D *artwork3d); char *_poppler_goo_string_to_utf8(GooString *s); gboolean _poppler_convert_pdf_date_to_gtime (GooString *date, diff --git glib/poppler.h glib/poppler.h index 1e78050..3945ca4 100644 --- glib/poppler.h +++ glib/poppler.h @@ -204,6 +204,8 @@ typedef struct _PopplerQuadrilateral PopplerQuadrilateral; typedef struct _PopplerStructureElement PopplerStructureElement; typedef struct _PopplerStructureElementIter PopplerStructureElementIter; typedef struct _PopplerTextSpan PopplerTextSpan; +typedef struct _PopplerAnnotArtwork3D PopplerAnnotArtwork3D; +typedef struct _PopplerArtwork3D PopplerArtwork3D; /** * PopplerBackend: @@ -238,5 +240,6 @@ G_END_DECLS #include "poppler-movie.h" #include "poppler-media.h" #include "poppler-structure-element.h" +#include "poppler-artwork3d.h" #endif /* __POPPLER_GLIB_H__ */ diff --git poppler/Annot.cc poppler/Annot.cc index 51a80e5..fb6fa59 100644 --- poppler/Annot.cc +++ poppler/Annot.cc @@ -73,6 +73,7 @@ #include "FileSpec.h" #include "DateInfo.h" #include "Link.h" +#include "Artwork3D.h" #include #include @@ -6601,6 +6602,8 @@ Annot3D::Annot3D(PDFDoc *docA, Dict *dict, Object *obj) : Annot3D::~Annot3D() { if (activation) delete activation; + if (artwork) + delete artwork; } void Annot3D::initialize(PDFDoc *docA, Dict* dict) { @@ -6612,6 +6615,19 @@ void Annot3D::initialize(PDFDoc *docA, Dict* dict) { activation = NULL; } obj1.free(); + + if (dict->lookup("3DD", &obj1)->isStream()) { + artwork = new Artwork3D(&obj1); + } else if(obj1.isDict()) { + Object obj2; + if (obj1.getDict()->lookup("3DD", &obj2)->isStream()) { + artwork = new Artwork3D(&obj2); + } + obj2.free(); + } else { + artwork = NULL; + } + obj1.free(); } Annot3D::Activation::Activation(Dict *dict) { @@ -6698,6 +6714,10 @@ Annot3D::Activation::Activation(Dict *dict) { obj1.free(); } +Artwork3D *Annot3D::getArtwork() const { + return artwork; +} + //------------------------------------------------------------------------ // AnnotRichMedia //------------------------------------------------------------------------ diff --git poppler/Annot.h poppler/Annot.h index 02311cb..166db7d 100644 --- poppler/Annot.h +++ poppler/Annot.h @@ -57,6 +57,7 @@ class Movie; class LinkAction; class Sound; class FileSpec; +class Artwork3D; enum AnnotLineEndingStyle { annotLineEndingSquare, // Square @@ -1403,11 +1404,14 @@ public: // getters + Artwork3D *getArtwork() const; + private: void initialize(PDFDoc *docA, Dict *dict); Activation *activation; // 3DA + Artwork3D *artwork; // 3DD }; //------------------------------------------------------------------------ diff --git poppler/Artwork3D.cc poppler/Artwork3D.cc new file mode 100644 index 0000000..9fd3514 --- /dev/null +++ poppler/Artwork3D.cc @@ -0,0 +1,62 @@ +/* Artwork3D.cc - Intermediate buffer for 3DD binary object (adapted from Sound.cc) + * Copyright (C) 2006-2007, Pino Toscano + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "Object.h" +#include "Artwork3D.h" +#include "Stream.h" + +Artwork3D::Artwork3D(Object *obj) +{ + streamObj = new Object(); + streamObj->initNull(); + obj->copy(streamObj); +} + +Artwork3D::~Artwork3D() +{ + streamObj->free(); + delete streamObj; +} + +Stream *Artwork3D::getStream() +{ + return streamObj->getStream(); +} + +Artwork3D *Artwork3D::copy() +{ + Artwork3D *newartwork = new Artwork3D(streamObj); + + return newartwork; +} + +Artwork3DKind Artwork3D::getKind() +{ + Object obj1; + streamObj->getDict()->lookup("Subtype", &obj1); + if (obj1.isName("U3D")) { + obj1.free(); + return artwork3d_U3D; + } else if (obj1.isName("PRC")) { + obj1.free(); + return artwork3d_PRC; + } + obj1.free(); + return artwork3d_UnknownKind; +} + diff --git poppler/Artwork3D.h poppler/Artwork3D.h new file mode 100644 index 0000000..379fdca --- /dev/null +++ poppler/Artwork3D.h @@ -0,0 +1,39 @@ +/* Artwork3D.h - Intermediate buffer for 3DD objects (adapted from Sound.h) + * Copyright (C) 2006-2007, Pino Toscano + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef Artwork3D_H +#define Artwork3D_H + +enum Artwork3DKind { + artwork3d_UnknownKind, + artwork3d_U3D, + artwork3d_PRC +}; + +class Artwork3D +{ + Object *streamObj; +public: + Artwork3D(Object *obj); + ~Artwork3D(); + Stream *getStream(); + Artwork3D *copy(); + Artwork3DKind getKind(); +}; + +#endif diff --git poppler/Makefile.am poppler/Makefile.am index 26cc82c..0dcb400 100644 --- poppler/Makefile.am +++ poppler/Makefile.am @@ -217,6 +217,7 @@ poppler_include_HEADERS = \ UTF.h \ UTF8.h \ XpdfPluginAPI.h \ + Artwork3d.h \ Sound.h nodist_poppler_include_HEADERS = poppler-config.h @@ -294,6 +295,7 @@ libpoppler_la_SOURCES = \ PageLabelInfo.cc \ SecurityHandler.cc \ Sound.cc \ + Artwork3D.cc \ XpdfPluginAPI.cc libpoppler_la_CPPFLAGS = \