diff -uN bindings.orig/GNUmakefile bindings/GNUmakefile --- bindings.orig/GNUmakefile Wed Jul 20 22:05:03 2005 +++ bindings/GNUmakefile Thu Dec 14 19:38:36 2006 @@ -26,17 +26,30 @@ SUBPROJECT_NAME=bindings -bindings_CFLAGS = \ - -g +bindings_CFLAGS = -g + +bindings_OBJCFLAGS = -Wno-import bindings_C_FILES = \ poppler.c \ poppler_document.c \ poppler_page.c \ -poppler_splash_renderer.c +poppler_splash_renderer.c \ +poppler_text.c + +bindings_OBJC_FILES = \ +poppler_objc.m ifeq ($(HAVE_CAIRO), YES) bindings_C_FILES += poppler_cairo_img_renderer.c +endif + +ifeq ($(POPPLER_0_4), YES) + bindings_CFLAGS += -DPOPPLER_0_4 +endif + +ifeq ($(POPPLER_0_5), YES) + bindings_CFLAGS += -DPOPPLER_0_5 endif include $(GNUSTEP_MAKEFILES)/subproject.make diff -uN bindings.orig/poppler.cc bindings/poppler.cc --- bindings.orig/poppler.cc Wed Jul 20 22:05:03 2005 +++ bindings/poppler.cc Thu Dec 14 19:38:36 2006 @@ -88,6 +88,8 @@ { if (!globalParams) { + _poppler_objc_init(); + // fontconfig initialization if (fcConfigPath) { @@ -121,8 +123,10 @@ fflush(stderr); } - globalParams = new GlobalParams(NULL); + globalParams = new GlobalParams(); +#ifdef POPPLER_0_4 globalParams->setupBaseFontsFc(NULL); +#endif //dump_fonts(FcConfigGetCurrent()); fprintf(stderr, "poppler library initialized\n"); fflush(stderr); } diff -uN bindings.orig/poppler.h bindings/poppler.h --- bindings.orig/poppler.h Wed Jul 20 22:05:03 2005 +++ bindings/poppler.h Thu Dec 14 19:38:36 2006 @@ -26,7 +26,25 @@ int poppler_init(const unsigned char* fcConfigPath, const unsigned char* appFonts[], unsigned nappFonts); + +// synchronized access to popple library (required for +// multithreaded applications) + +void poppler_acquire_lock(void); +void poppler_release_lock(void); +#define SYNCHRONIZED(x) \ + poppler_acquire_lock(); \ + x; \ + poppler_release_lock() + +#define BEGIN_SYNCHRONIZED poppler_acquire_lock() +#define END_SYNCHRONIZED poppler_release_lock() + +// private +void _poppler_objc_init(void); + + #ifdef __cplusplus }; #endif diff -uN bindings.orig/poppler_cairo_img_renderer.cc bindings/poppler_cairo_img_renderer.cc --- bindings.orig/poppler_cairo_img_renderer.cc Wed Jul 20 22:05:03 2005 +++ bindings/poppler_cairo_img_renderer.cc Thu Dec 14 19:38:36 2006 @@ -19,28 +19,83 @@ #include #include #include "poppler_cairo_img_renderer.h" +#include "poppler.h" #include #include #include -#include +#include #define PDF_DOC(obj) static_cast(obj) #define PAGE(obj) static_cast(obj) -#define CAIRO_DEV_IMG(obj) static_cast(obj) +#define CAIRO_DEV_IMG(obj) static_cast(obj) -void* poppler_cairo_img_device_create(void) -{ - return new CairoOutputDevImage(); +#ifndef MAX +#define MAX(a,b) (((a)>(b))?(a):(b)) +#endif + +typedef struct CairoImageDev { + CairoOutputDev* device; + cairo_surface_t* surface; + unsigned char* data; +} CairoImageDev; + +static void my_poppler_cairo_prepare_dev(CairoImageDev* output_dev, Page* page, + double scale, int rotation, int transparent) +{ + int width; + int height; + + int rotate = (rotation + page->getRotate()) % 360; + + if (rotate == 90 || rotate == 270) + { +#ifdef POPPLER_0_4 + width = MAX((int)(page->getHeight() * scale + 0.5), 1); + height = MAX((int)(page->getWidth() * scale + 0.5), 1); +#endif +#ifdef POPPLER_0_5 + width = MAX((int)(page->getMediaHeight() * scale + 0.5), 1); + height = MAX((int)(page->getMediaWidth() * scale + 0.5), 1); +#endif + } + else + { +#ifdef POPPLER_0_4 + width = MAX((int)(page->getWidth() * scale + 0.5), 1); + height = MAX((int)(page->getHeight() * scale + 0.5), 1); +#endif +#ifdef POPPLER_0_5 + width = MAX((int)(page->getMediaWidth() * scale + 0.5), 1); + height = MAX((int)(page->getMediaHeight() * scale + 0.5), 1); +#endif + } + + int rowstride = width * 4; + unsigned char* data = (unsigned char*)malloc(height * rowstride); + memset(data, (transparent ? 0x00 : 0xff), height * rowstride); + + cairo_surface_t* surface = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, rowstride); + +#ifdef POPPLER_0_5 + output_dev->device->setCairo(cairo_create(surface)); +#else + output_dev->device->setSurface(surface); +#endif + output_dev->surface = surface; + output_dev->data = data; } -void poppler_splash_device_start_doc(void* output_dev, void* poppler_document) -{ - if (!output_dev || !poppler_document) - { - return; - } - - CAIRO_DEV_IMG(output_dev)->startDoc(PDF_DOC(poppler_document)->getXRef()); +void* poppler_cairo_img_device_create(void) +{ + BEGIN_SYNCHRONIZED; + CairoOutputDev* cairoDevice = new CairoOutputDev(); + CairoImageDev* imageDevice = (CairoImageDev*)malloc(sizeof(CairoImageDev)); + imageDevice->device = cairoDevice; + imageDevice->surface = NULL; + imageDevice->data = NULL; + END_SYNCHRONIZED; + + return imageDevice; } void poppler_cairo_img_device_start_doc(void* output_dev, void* poppler_document) @@ -50,7 +105,7 @@ return; } - CAIRO_DEV_IMG(output_dev)->startDoc(PDF_DOC(poppler_document)->getXRef()); + SYNCHRONIZED(CAIRO_DEV_IMG(output_dev)->device->startDoc(PDF_DOC(poppler_document)->getXRef())); } void poppler_cairo_img_device_destroy(void* output_dev) @@ -59,29 +114,38 @@ { return; } - - delete CAIRO_DEV_IMG(output_dev); + + SYNCHRONIZED(delete CAIRO_DEV_IMG(output_dev)->device); + free(CAIRO_DEV_IMG(output_dev)); } int poppler_cairo_img_device_display_slice(void* output_dev, void* poppler_page, - void* poppler_document, - float hDPI, float vDPI, int rotate, - float sliceX, float sliceY, - float sliceW, float sliceH) + void* poppler_document, + float hDPI, float vDPI, float baseDPI, + int rotate, + float sliceX, float sliceY, + float sliceW, float sliceH) { if (!output_dev || !poppler_page || !poppler_document) { return 0; } + + double scale = MAX(hDPI / baseDPI, vDPI / baseDPI); + my_poppler_cairo_prepare_dev(CAIRO_DEV_IMG(output_dev), PAGE(poppler_page), + scale, rotate, 0); - PAGE(poppler_page)->displaySlice(CAIRO_DEV_IMG(output_dev), - (double)hDPI, (double)vDPI, - rotate, - gTrue, // Crop - (int)sliceX, (int)sliceY, - (int)sliceW, (int)sliceH, - NULL, // Links - PDF_DOC(poppler_document)->getCatalog()); + SYNCHRONIZED(PAGE(poppler_page)->displaySlice(CAIRO_DEV_IMG(output_dev)->device, + (double)hDPI, (double)vDPI, + rotate, +#ifdef POPPLER_0_5 + gTrue, // use MediaBox +#endif + gTrue, // Crop + (int)sliceX, (int)sliceY, + (int)sliceW, (int)sliceH, + NULL, // Links + PDF_DOC(poppler_document)->getCatalog())); return 1; } @@ -89,26 +153,19 @@ int poppler_cairo_img_device_get_data(void* output_dev, unsigned char** data, int* width, int* height, int* rowstride) { - if (!output_dev) - { - return 0; - } - - int cairo_width, cairo_height, cairo_rowstride; - unsigned char* cairo_data = NULL; - - CAIRO_DEV_IMG(output_dev)->getBitmap(&cairo_data, &cairo_width, &cairo_height, - &cairo_rowstride); - - if (!cairo_data) + if (!output_dev || !CAIRO_DEV_IMG(output_dev)->surface || !CAIRO_DEV_IMG(output_dev)->data) { return 0; } - *data = cairo_data; - *width = cairo_width; - *height = cairo_height; - *rowstride = cairo_rowstride; + *data = CAIRO_DEV_IMG(output_dev)->data; + *width = cairo_image_surface_get_width(CAIRO_DEV_IMG(output_dev)->surface); + *height = cairo_image_surface_get_height(CAIRO_DEV_IMG(output_dev)->surface); + *rowstride = (*width) * 4; + + cairo_surface_destroy(CAIRO_DEV_IMG(output_dev)->surface); + CAIRO_DEV_IMG(output_dev)->surface = NULL; + CAIRO_DEV_IMG(output_dev)->data = NULL; // freed after poppler_cairo_img_device_get_rgb return 1; } @@ -135,5 +192,8 @@ } } + free(cairo_data); + return 1; } + diff -uN bindings.orig/poppler_cairo_img_renderer.h bindings/poppler_cairo_img_renderer.h --- bindings.orig/poppler_cairo_img_renderer.h Wed Jul 20 22:05:03 2005 +++ bindings/poppler_cairo_img_renderer.h Thu Dec 14 19:38:36 2006 @@ -28,7 +28,8 @@ void poppler_cairo_img_device_destroy(void* output_dev); int poppler_cairo_img_device_display_slice(void* output_dev, void* poppler_page, void* poppler_document, - float hDPI, float vDPI, int rotate, + float hDPI, float vDPI, float baseDPI, + int rotate, float sliceX, float sliceY, float sliceW, float sliceH); int poppler_cairo_img_device_get_data(void* output_dev, unsigned char** data, diff -uN bindings.orig/poppler_objc.m bindings/poppler_objc.m --- bindings.orig/poppler_objc.m Thu Jan 1 01:00:00 1970 +++ bindings/poppler_objc.m Thu Dec 14 19:38:37 2006 @@ -0,0 +1,36 @@ +// +// poppler_objc.m +// PopplerKit +// +// Created by Stefan Kleine Stegemann on 9/12/05. +// Copyright 2005 . All rights reserved. +// + +#import "poppler.h" +#import + +static NSLock* poppler_lock = nil; + +#define CHECK_INITIALIZED \ + if (!poppler_lock) { \ + fprintf(stderr, "poppler_lock not initialized\n"); fflush(stderr);\ + return; \ + } + + +void _poppler_objc_init(void) +{ + poppler_lock = [[NSLock alloc] init]; +} + +void poppler_acquire_lock(void) +{ + CHECK_INITIALIZED; + [poppler_lock lock]; +} + +void poppler_release_lock(void) +{ + CHECK_INITIALIZED; + [poppler_lock unlock]; +} diff -uN bindings.orig/poppler_page.cc bindings/poppler_page.cc --- bindings.orig/poppler_page.cc Wed Jul 20 22:05:03 2005 +++ bindings/poppler_page.cc Thu Dec 14 19:38:37 2006 @@ -66,7 +66,14 @@ return -1; } + +#ifdef POPPLER_0_4 return PAGE(poppler_page)->getWidth(); +#endif +#ifdef POPPLER_0_5 + return PAGE(poppler_page)->getMediaWidth(); +#endif + } double poppler_page_get_height(void* poppler_page) @@ -76,5 +83,11 @@ return -1; } +#ifdef POPPLER_0_4 return PAGE(poppler_page)->getHeight(); +#endif +#ifdef POPPLER_0_5 + return PAGE(poppler_page)->getMediaHeight(); +#endif + } diff -uN bindings.orig/poppler_splash_renderer.cc bindings/poppler_splash_renderer.cc --- bindings.orig/poppler_splash_renderer.cc Wed Jul 20 22:05:03 2005 +++ bindings/poppler_splash_renderer.cc Thu Dec 14 19:38:37 2006 @@ -19,6 +19,7 @@ #include #include #include "poppler_splash_renderer.h" +#include "poppler.h" #include #include #include @@ -31,10 +32,23 @@ #define SPLASH_BITMAP(obj) static_cast(obj) void* poppler_splash_device_create(int bg_red, int bg_green, int bg_blue) -{ - SplashColor white; - white.rgb8 = splashMakeRGB8(bg_red, bg_green, bg_blue); - return new SplashOutputDev(splashModeRGB8, gFalse, white); +{ + BEGIN_SYNCHRONIZED; + SplashColor white; +#ifdef POPPLER_0_4 + white.rgb8 = splashMakeRGB8(bg_red, bg_green, bg_blue); + void* splashDevice = new SplashOutputDev(splashModeRGB8, gFalse, white); +#endif +#ifdef POPPLER_0_5 + white[0] = bg_red; + white[1] = bg_green; + white[2] = bg_blue; + // I'm not sure what bitmapRowPad should be, 1 is just a guess. + void* splashDevice = new SplashOutputDev(splashModeRGB8, 1, gFalse, white); +#endif + END_SYNCHRONIZED; + + return splashDevice; } void poppler_splash_device_start_doc(void* output_dev, void* poppler_document) @@ -44,7 +58,7 @@ return; } - SPLASH_DEV(output_dev)->startDoc(PDF_DOC(poppler_document)->getXRef()); + SYNCHRONIZED(SPLASH_DEV(output_dev)->startDoc(PDF_DOC(poppler_document)->getXRef())); } void poppler_splash_device_destroy(void* output_dev) @@ -68,16 +82,20 @@ return 0; } - PAGE(poppler_page)->displaySlice(SPLASH_DEV(output_dev), - (double)hDPI, (double)vDPI, - rotate, - gTrue, // Crop - (int)sliceX, (int)sliceY, - (int)sliceW, (int)sliceH, - NULL, // Links - PDF_DOC(poppler_document)->getCatalog()); - - return 1; + + SYNCHRONIZED(PAGE(poppler_page)->displaySlice(SPLASH_DEV(output_dev), + (double)hDPI, (double)vDPI, + rotate, +#ifdef POPPLER_0_5 + gTrue, // useMediaBox +#endif + gTrue, // Crop + (int)sliceX, (int)sliceY, + (int)sliceW, (int)sliceH, + NULL, // Links + PDF_DOC(poppler_document)->getCatalog())); + + return 1; } int poppler_splash_device_get_bitmap(void* output_dev, void** bitmap, @@ -103,20 +121,38 @@ return 0; } +#ifdef POPPLER_0_4 SplashRGB8* rgb8; +#endif +#ifdef POPPLER_0_5 + SplashColorPtr color; +#endif unsigned char* dataPtr; +#ifdef POPPLER_0_4 rgb8 = SPLASH_BITMAP(bitmap)->getDataPtr().rgb8; +#endif +#ifdef POPPLER_0_5 + color = SPLASH_BITMAP(bitmap)->getDataPtr(); +#endif dataPtr = *data; for (int row = 0; row < SPLASH_BITMAP(bitmap)->getHeight(); row++) { for (int col = 0; col < SPLASH_BITMAP(bitmap)->getWidth(); col++) { +#ifdef POPPLER_0_4 *dataPtr++ = splashRGB8R(*rgb8); *dataPtr++ = splashRGB8G(*rgb8); *dataPtr++ = splashRGB8B(*rgb8); ++rgb8; +#endif +#ifdef POPPLER_0_5 + *dataPtr++ = splashRGB8R(color); + *dataPtr++ = splashRGB8G(++color); + *dataPtr++ = splashRGB8B(++color); + ++color; +#endif } } diff -uN bindings.orig/poppler_text.cc bindings/poppler_text.cc --- bindings.orig/poppler_text.cc Thu Jan 1 01:00:00 1970 +++ bindings/poppler_text.cc Thu Dec 14 19:38:37 2006 @@ -0,0 +1,81 @@ +/*/* +* Copyright (C) 2004 Stefan Kleine Stegemann +* +* 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 +* of the License, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "poppler_text.h" +#include "poppler.h" +#include +#include +#include + +#define PDF_DOC(obj) static_cast(obj) +#define PAGE(obj) static_cast(obj) +#define TEXT_DEV(obj) static_cast(obj) + +void* poppler_text_device_create(int use_phys_layout, int use_raw_text_order, int append) +{ + BEGIN_SYNCHRONIZED; + void* textDevice = new TextOutputDev(NULL, use_phys_layout, use_raw_text_order, append); + END_SYNCHRONIZED; + + return textDevice; +} + +void poppler_text_device_destroy(void* text_device) +{ + if (!text_device) + return; + + SYNCHRONIZED(delete TEXT_DEV(text_device)); +} + +int poppler_text_display_page(void* text_device, void* poppler_page, void* poppler_document, + float hDPI, float vDPI, int rotate, int crop) +{ + if (!text_device || !poppler_page || !poppler_document) + return 0; + + SYNCHRONIZED(PAGE(poppler_page)->display(TEXT_DEV(text_device), + hDPI, vDPI, rotate, +#ifdef POPPLER_0_5 + gTrue, // useMediaBox +#endif + crop, NULL, PDF_DOC(poppler_document)->getCatalog())); + return 1; +} + +int poppler_text_find(void* text_device, unsigned int* text_utf32, unsigned text_len, + int start_at_top, int stop_at_bottom, + int start_at_last, int stop_at_last, + double* x_min, double* y_min, double* x_max, double* y_max) +{ + if (!text_device || !text_utf32 || !text_len) + return 0; + + BEGIN_SYNCHRONIZED; + int result = TEXT_DEV(text_device)->findText(text_utf32, text_len, + start_at_top, stop_at_bottom, + start_at_last, stop_at_last, +#ifdef POPPLER_0_5 + gTrue, gFalse, +#endif + x_min, y_min, x_max, y_max); + END_SYNCHRONIZED; + + return result; +} + diff -uN bindings.orig/poppler_text.h bindings/poppler_text.h --- bindings.orig/poppler_text.h Thu Jan 1 01:00:00 1970 +++ bindings/poppler_text.h Thu Dec 14 19:38:37 2006 @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2004 Stefan Kleine Stegemann + * + * 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 + * of the License, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _H_POPPLER_TEXT +#define _H_POPPLER_TEXT + +#ifdef __cplusplus +extern "C" { +#endif + +void* poppler_text_device_create(int use_phys_layout, int use_raw_text_order, int append); +void poppler_text_device_destroy(void* text_device); +int poppler_text_display_page(void* text_device, void* poppler_page, void* poppler_document, + float hDPI, float vDPI, int rotate, int crop); +int poppler_text_find(void* text_device, unsigned int* text_utf32, unsigned text_len, + int start_at_top, int stop_at_bottom, + int start_at_last, int stop_at_last, + double* x_min, double* y_min, double* x_max, double* y_max); + +#ifdef __cplusplus +}; +#endif + +#endif +