Annotation of /trunk/gimp/patches/gimp-2.6.11-poppler018.patch
Parent Directory | Revision Log
Revision 1597 -
(hide annotations)
(download)
Tue Dec 6 00:48:14 2011 UTC (12 years, 9 months ago) by niro
File size: 15588 byte(s)
Tue Dec 6 00:48:14 2011 UTC (12 years, 9 months ago) by niro
File size: 15588 byte(s)
-fix build against newer poppler
1 | niro | 1597 | From 69f69eed816b89be9a01a48a1f0643d1fd496118 Mon Sep 17 00:00:00 2001 |
2 | From: Nils Philippsen <nils@redhat.com> | ||
3 | Date: Fri, 6 May 2011 11:58:44 +0200 | ||
4 | Subject: [PATCH] patch: poppler-0.17 | ||
5 | |||
6 | Squashed commit of the following: | ||
7 | |||
8 | commit 529d940222dfc352d41fbf72de29134421aa4002 | ||
9 | Author: Nils Philippsen <nils@redhat.com> | ||
10 | Date: Fri May 6 11:50:30 2011 +0200 | ||
11 | |||
12 | use code based on pixbufs instead of cairo surfaces | ||
13 | |||
14 | this is done to avoid adding to libgimp, thanks to Mukund Sivaraman for | ||
15 | hints how to do this | ||
16 | |||
17 | commit f8671d8767d4cdab830dc06310e96c63a88ec0fd | ||
18 | Author: Mukund Sivaraman <muks@banu.com> | ||
19 | Date: Thu Apr 21 13:57:13 2011 +0530 | ||
20 | |||
21 | file-pdf-load: Update attribution, removing bogus copyright | ||
22 | (cherry picked from commit e999122e0b20b6ccd6bde3ce039bb64068fc0019) | ||
23 | |||
24 | commit 89a78f2590d298dac2f42e6d9a3016fc5d672c70 | ||
25 | Author: Nils Philippsen <nils@redhat.com> | ||
26 | Date: Thu Apr 21 13:52:18 2011 +0200 | ||
27 | |||
28 | file-pdf-load: Use better API + cleanups | ||
29 | |||
30 | * fixes issues with poppler 0.17 completely | ||
31 | * uses new libgimp API to pass surfaces instead of pixbufs | ||
32 | * uses GTK+ 3 API to convert surfaces to pixbufs where available | ||
33 | (backported from commit 7bdadd80ba479d6ff904e276d805e16f6b940ee2) | ||
34 | |||
35 | commit 4e92302c4a14a961f112587a0ad86696c88da2f8 | ||
36 | Author: Nils Philippsen <nils@redhat.com> | ||
37 | Date: Thu Apr 21 13:38:08 2011 +0200 | ||
38 | |||
39 | file-pdf-load: Don't use deprecated API (bug #646947) | ||
40 | |||
41 | (cherry picked from commit 9b3e1c91fd2eac69da6947ec9c7fbf10096ba237) | ||
42 | |||
43 | Conflicts: | ||
44 | |||
45 | plug-ins/common/file-pdf.c | ||
46 | --- | ||
47 | plug-ins/common/file-pdf.c | 323 ++++++++++++++++++++++++++++++++++++++------ | ||
48 | 1 files changed, 283 insertions(+), 40 deletions(-) | ||
49 | |||
50 | diff --git a/plug-ins/common/file-pdf.c b/plug-ins/common/file-pdf.c | ||
51 | index a43b459..43c2b7d 100644 | ||
52 | --- a/plug-ins/common/file-pdf.c | ||
53 | +++ b/plug-ins/common/file-pdf.c | ||
54 | @@ -4,6 +4,9 @@ | ||
55 | * | ||
56 | * Copyright (C) 2005 Nathan Summers | ||
57 | * | ||
58 | + * Some code in render_page_to_surface() borrowed from | ||
59 | + * poppler.git/glib/poppler-page.cc. | ||
60 | + * | ||
61 | * This program is free software; you can redistribute it and/or modify | ||
62 | * it under the terms of the GNU General Public License as published by | ||
63 | * the Free Software Foundation; either version 2 of the License, or | ||
64 | @@ -80,16 +83,20 @@ static gboolean load_dialog (PopplerDocument *doc, | ||
65 | static PopplerDocument * open_document (const gchar *filename, | ||
66 | GError **error); | ||
67 | |||
68 | -static GdkPixbuf * get_thumbnail (PopplerDocument *doc, | ||
69 | +static cairo_surface_t * get_thumb_surface (PopplerDocument *doc, | ||
70 | + gint page, | ||
71 | + gint preferred_size); | ||
72 | + | ||
73 | +static GdkPixbuf * get_thumb_pixbuf (PopplerDocument *doc, | ||
74 | gint page, | ||
75 | gint preferred_size); | ||
76 | |||
77 | static gint32 layer_from_pixbuf (gint32 image, | ||
78 | - const gchar *layer_name, | ||
79 | - gint position, | ||
80 | - GdkPixbuf *buf, | ||
81 | - gdouble progress_start, | ||
82 | - gdouble progress_scale); | ||
83 | + const gchar *layer_name, | ||
84 | + gint position, | ||
85 | + GdkPixbuf *pixbuf, | ||
86 | + gdouble progress_start, | ||
87 | + gdouble progress_scale); | ||
88 | |||
89 | /** | ||
90 | ** the following was formerly part of | ||
91 | @@ -433,11 +440,12 @@ run (const gchar *name, | ||
92 | } | ||
93 | else | ||
94 | { | ||
95 | - gdouble width = 0; | ||
96 | - gdouble height = 0; | ||
97 | - gdouble scale; | ||
98 | - gint32 image = -1; | ||
99 | - GdkPixbuf *pixbuf = NULL; | ||
100 | + gdouble width = 0; | ||
101 | + gdouble height = 0; | ||
102 | + gdouble scale; | ||
103 | + gint32 image = -1; | ||
104 | + gint num_pages = 0; | ||
105 | + GdkPixbuf *pixbuf = NULL; | ||
106 | |||
107 | /* Possibly retrieve last settings */ | ||
108 | gimp_get_data (LOAD_PROC, &loadvals); | ||
109 | @@ -455,7 +463,10 @@ run (const gchar *name, | ||
110 | g_object_unref (page); | ||
111 | } | ||
112 | |||
113 | - pixbuf = get_thumbnail (doc, 0, param[1].data.d_int32); | ||
114 | + num_pages = poppler_document_get_n_pages (doc); | ||
115 | + | ||
116 | + pixbuf = get_thumb_pixbuf (doc, 0, param[1].data.d_int32); | ||
117 | + | ||
118 | g_object_unref (doc); | ||
119 | } | ||
120 | |||
121 | @@ -548,6 +559,187 @@ open_document (const gchar *filename, | ||
122 | return doc; | ||
123 | } | ||
124 | |||
125 | +/* FIXME: Remove this someday when we depend fully on GTK+ >= 3 */ | ||
126 | + | ||
127 | +#if (!GTK_CHECK_VERSION (3, 0, 0)) | ||
128 | + | ||
129 | +static cairo_format_t | ||
130 | +gdk_cairo_format_for_content (cairo_content_t content) | ||
131 | +{ | ||
132 | + switch (content) | ||
133 | + { | ||
134 | + case CAIRO_CONTENT_COLOR: | ||
135 | + return CAIRO_FORMAT_RGB24; | ||
136 | + case CAIRO_CONTENT_ALPHA: | ||
137 | + return CAIRO_FORMAT_A8; | ||
138 | + case CAIRO_CONTENT_COLOR_ALPHA: | ||
139 | + default: | ||
140 | + return CAIRO_FORMAT_ARGB32; | ||
141 | + } | ||
142 | +} | ||
143 | + | ||
144 | +static cairo_surface_t * | ||
145 | +gdk_cairo_surface_coerce_to_image (cairo_surface_t *surface, | ||
146 | + cairo_content_t content, | ||
147 | + int src_x, | ||
148 | + int src_y, | ||
149 | + int width, | ||
150 | + int height) | ||
151 | +{ | ||
152 | + cairo_surface_t *copy; | ||
153 | + cairo_t *cr; | ||
154 | + | ||
155 | + copy = cairo_image_surface_create (gdk_cairo_format_for_content (content), | ||
156 | + width, | ||
157 | + height); | ||
158 | + | ||
159 | + cr = cairo_create (copy); | ||
160 | + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); | ||
161 | + cairo_set_source_surface (cr, surface, -src_x, -src_y); | ||
162 | + cairo_paint (cr); | ||
163 | + cairo_destroy (cr); | ||
164 | + | ||
165 | + return copy; | ||
166 | +} | ||
167 | + | ||
168 | +static void | ||
169 | +convert_alpha (guchar *dest_data, | ||
170 | + int dest_stride, | ||
171 | + guchar *src_data, | ||
172 | + int src_stride, | ||
173 | + int src_x, | ||
174 | + int src_y, | ||
175 | + int width, | ||
176 | + int height) | ||
177 | +{ | ||
178 | + int x, y; | ||
179 | + | ||
180 | + src_data += src_stride * src_y + src_x * 4; | ||
181 | + | ||
182 | + for (y = 0; y < height; y++) { | ||
183 | + guint32 *src = (guint32 *) src_data; | ||
184 | + | ||
185 | + for (x = 0; x < width; x++) { | ||
186 | + guint alpha = src[x] >> 24; | ||
187 | + | ||
188 | + if (alpha == 0) | ||
189 | + { | ||
190 | + dest_data[x * 4 + 0] = 0; | ||
191 | + dest_data[x * 4 + 1] = 0; | ||
192 | + dest_data[x * 4 + 2] = 0; | ||
193 | + } | ||
194 | + else | ||
195 | + { | ||
196 | + dest_data[x * 4 + 0] = (((src[x] & 0xff0000) >> 16) * 255 + alpha / 2) / alpha; | ||
197 | + dest_data[x * 4 + 1] = (((src[x] & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha; | ||
198 | + dest_data[x * 4 + 2] = (((src[x] & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha; | ||
199 | + } | ||
200 | + dest_data[x * 4 + 3] = alpha; | ||
201 | + } | ||
202 | + | ||
203 | + src_data += src_stride; | ||
204 | + dest_data += dest_stride; | ||
205 | + } | ||
206 | +} | ||
207 | + | ||
208 | +static void | ||
209 | +convert_no_alpha (guchar *dest_data, | ||
210 | + int dest_stride, | ||
211 | + guchar *src_data, | ||
212 | + int src_stride, | ||
213 | + int src_x, | ||
214 | + int src_y, | ||
215 | + int width, | ||
216 | + int height) | ||
217 | +{ | ||
218 | + int x, y; | ||
219 | + | ||
220 | + src_data += src_stride * src_y + src_x * 4; | ||
221 | + | ||
222 | + for (y = 0; y < height; y++) { | ||
223 | + guint32 *src = (guint32 *) src_data; | ||
224 | + | ||
225 | + for (x = 0; x < width; x++) { | ||
226 | + dest_data[x * 3 + 0] = src[x] >> 16; | ||
227 | + dest_data[x * 3 + 1] = src[x] >> 8; | ||
228 | + dest_data[x * 3 + 2] = src[x]; | ||
229 | + } | ||
230 | + | ||
231 | + src_data += src_stride; | ||
232 | + dest_data += dest_stride; | ||
233 | + } | ||
234 | +} | ||
235 | + | ||
236 | +/** | ||
237 | + * gdk_pixbuf_get_from_surface: | ||
238 | + * @surface: surface to copy from | ||
239 | + * @src_x: Source X coordinate within @surface | ||
240 | + * @src_y: Source Y coordinate within @surface | ||
241 | + * @width: Width in pixels of region to get | ||
242 | + * @height: Height in pixels of region to get | ||
243 | + * | ||
244 | + * Transfers image data from a #cairo_surface_t and converts it to an RGB(A) | ||
245 | + * representation inside a #GdkPixbuf. This allows you to efficiently read | ||
246 | + * individual pixels from cairo surfaces. For #GdkWindows, use | ||
247 | + * gdk_pixbuf_get_from_window() instead. | ||
248 | + * | ||
249 | + * This function will create an RGB pixbuf with 8 bits per channel. | ||
250 | + * The pixbuf will contain an alpha channel if the @surface contains one. | ||
251 | + * | ||
252 | + * Return value: (transfer full): A newly-created pixbuf with a reference | ||
253 | + * count of 1, or %NULL on error | ||
254 | + */ | ||
255 | +static GdkPixbuf * | ||
256 | +gdk_pixbuf_get_from_surface (cairo_surface_t *surface, | ||
257 | + gint src_x, | ||
258 | + gint src_y, | ||
259 | + gint width, | ||
260 | + gint height) | ||
261 | +{ | ||
262 | + cairo_content_t content; | ||
263 | + GdkPixbuf *dest; | ||
264 | + | ||
265 | + /* General sanity checks */ | ||
266 | + g_return_val_if_fail (surface != NULL, NULL); | ||
267 | + g_return_val_if_fail (width > 0 && height > 0, NULL); | ||
268 | + | ||
269 | + content = cairo_surface_get_content (surface) | CAIRO_CONTENT_COLOR; | ||
270 | + dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, | ||
271 | + !!(content & CAIRO_CONTENT_ALPHA), | ||
272 | + 8, | ||
273 | + width, height); | ||
274 | + | ||
275 | + surface = gdk_cairo_surface_coerce_to_image (surface, content, | ||
276 | + src_x, src_y, | ||
277 | + width, height); | ||
278 | + cairo_surface_flush (surface); | ||
279 | + if (cairo_surface_status (surface) || dest == NULL) | ||
280 | + { | ||
281 | + cairo_surface_destroy (surface); | ||
282 | + return NULL; | ||
283 | + } | ||
284 | + | ||
285 | + if (gdk_pixbuf_get_has_alpha (dest)) | ||
286 | + convert_alpha (gdk_pixbuf_get_pixels (dest), | ||
287 | + gdk_pixbuf_get_rowstride (dest), | ||
288 | + cairo_image_surface_get_data (surface), | ||
289 | + cairo_image_surface_get_stride (surface), | ||
290 | + 0, 0, | ||
291 | + width, height); | ||
292 | + else | ||
293 | + convert_no_alpha (gdk_pixbuf_get_pixels (dest), | ||
294 | + gdk_pixbuf_get_rowstride (dest), | ||
295 | + cairo_image_surface_get_data (surface), | ||
296 | + cairo_image_surface_get_stride (surface), | ||
297 | + 0, 0, | ||
298 | + width, height); | ||
299 | + | ||
300 | + cairo_surface_destroy (surface); | ||
301 | + return dest; | ||
302 | +} | ||
303 | + | ||
304 | +#endif | ||
305 | + | ||
306 | static gint32 | ||
307 | layer_from_pixbuf (gint32 image, | ||
308 | const gchar *layer_name, | ||
309 | @@ -566,6 +758,54 @@ layer_from_pixbuf (gint32 image, | ||
310 | return layer; | ||
311 | } | ||
312 | |||
313 | +static cairo_surface_t * | ||
314 | +render_page_to_surface (PopplerPage *page, | ||
315 | + int width, | ||
316 | + int height, | ||
317 | + double scale) | ||
318 | +{ | ||
319 | + cairo_surface_t *surface; | ||
320 | + cairo_t *cr; | ||
321 | + | ||
322 | + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); | ||
323 | + cr = cairo_create (surface); | ||
324 | + | ||
325 | + cairo_save (cr); | ||
326 | + cairo_translate (cr, 0.0, 0.0); | ||
327 | + | ||
328 | + if (scale != 1.0) | ||
329 | + cairo_scale (cr, scale, scale); | ||
330 | + | ||
331 | + poppler_page_render (page, cr); | ||
332 | + cairo_restore (cr); | ||
333 | + | ||
334 | + cairo_set_operator (cr, CAIRO_OPERATOR_DEST_OVER); | ||
335 | + cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); | ||
336 | + cairo_paint (cr); | ||
337 | + | ||
338 | + cairo_destroy (cr); | ||
339 | + | ||
340 | + return surface; | ||
341 | +} | ||
342 | + | ||
343 | +static GdkPixbuf * | ||
344 | +render_page_to_pixbuf (PopplerPage *page, | ||
345 | + int width, | ||
346 | + int height, | ||
347 | + double scale) | ||
348 | +{ | ||
349 | + GdkPixbuf *pixbuf; | ||
350 | + cairo_surface_t *surface; | ||
351 | + | ||
352 | + surface = render_page_to_surface (page, width, height, scale); | ||
353 | + pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, | ||
354 | + cairo_image_surface_get_width (surface), | ||
355 | + cairo_image_surface_get_height (surface)); | ||
356 | + cairo_surface_destroy (surface); | ||
357 | + | ||
358 | + return pixbuf; | ||
359 | +} | ||
360 | + | ||
361 | static gint32 | ||
362 | load_image (PopplerDocument *doc, | ||
363 | const gchar *filename, | ||
364 | @@ -597,7 +837,7 @@ load_image (PopplerDocument *doc, | ||
365 | gdouble page_width; | ||
366 | gdouble page_height; | ||
367 | |||
368 | - GdkPixbuf *buf; | ||
369 | + GdkPixbuf *pixbuf; | ||
370 | gint width; | ||
371 | gint height; | ||
372 | |||
373 | @@ -627,15 +867,13 @@ load_image (PopplerDocument *doc, | ||
374 | gimp_image_set_resolution (image_ID, resolution, resolution); | ||
375 | } | ||
376 | |||
377 | - buf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height); | ||
378 | - | ||
379 | - poppler_page_render_to_pixbuf (page, 0, 0, width, height, scale, 0, buf); | ||
380 | + pixbuf = render_page_to_pixbuf (page, width, height, scale); | ||
381 | |||
382 | - layer_from_pixbuf (image_ID, page_label, i, buf, | ||
383 | + layer_from_pixbuf (image_ID, page_label, i, pixbuf, | ||
384 | doc_progress, 1.0 / pages->n_pages); | ||
385 | |||
386 | g_free (page_label); | ||
387 | - g_object_unref (buf); | ||
388 | + g_object_unref(pixbuf); | ||
389 | |||
390 | doc_progress = (double) (i + 1) / pages->n_pages; | ||
391 | gimp_progress_update (doc_progress); | ||
392 | @@ -676,30 +914,22 @@ load_image (PopplerDocument *doc, | ||
393 | return image_ID; | ||
394 | } | ||
395 | |||
396 | -static GdkPixbuf * | ||
397 | -get_thumbnail (PopplerDocument *doc, | ||
398 | - gint page_num, | ||
399 | - gint preferred_size) | ||
400 | +static cairo_surface_t * | ||
401 | +get_thumb_surface (PopplerDocument *doc, | ||
402 | + gint page_num, | ||
403 | + gint preferred_size) | ||
404 | { | ||
405 | PopplerPage *page; | ||
406 | - GdkPixbuf *pixbuf; | ||
407 | + cairo_surface_t *surface; | ||
408 | |||
409 | page = poppler_document_get_page (doc, page_num); | ||
410 | |||
411 | if (! page) | ||
412 | return NULL; | ||
413 | |||
414 | - /* XXX: Remove conditional when we depend on poppler 0.8.0, but also | ||
415 | - * add configure check to make sure POPPLER_WITH_GDK is enabled! | ||
416 | - */ | ||
417 | -#ifdef POPPLER_WITH_GDK | ||
418 | - pixbuf = poppler_page_get_thumbnail_pixbuf (page); | ||
419 | -#else | ||
420 | - pixbuf = poppler_page_get_thumbnail (page); | ||
421 | -#endif | ||
422 | - | ||
423 | + surface = poppler_page_get_thumbnail (page); | ||
424 | |||
425 | - if (! pixbuf) | ||
426 | + if (! surface) | ||
427 | { | ||
428 | gdouble width; | ||
429 | gdouble height; | ||
430 | @@ -712,15 +942,28 @@ get_thumbnail (PopplerDocument *doc, | ||
431 | width *= scale; | ||
432 | height *= scale; | ||
433 | |||
434 | - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, | ||
435 | - width, height); | ||
436 | - | ||
437 | - poppler_page_render_to_pixbuf (page, | ||
438 | - 0, 0, width, height, scale, 0, pixbuf); | ||
439 | + surface = render_page_to_surface (page, width, height, scale); | ||
440 | } | ||
441 | |||
442 | g_object_unref (page); | ||
443 | |||
444 | + return surface; | ||
445 | +} | ||
446 | + | ||
447 | +static GdkPixbuf * | ||
448 | +get_thumb_pixbuf (PopplerDocument *doc, | ||
449 | + gint page_num, | ||
450 | + gint preferred_size) | ||
451 | +{ | ||
452 | + cairo_surface_t *surface; | ||
453 | + GdkPixbuf *pixbuf; | ||
454 | + | ||
455 | + surface = get_thumb_surface (doc, page_num, preferred_size); | ||
456 | + pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, | ||
457 | + cairo_image_surface_get_width (surface), | ||
458 | + cairo_image_surface_get_height (surface)); | ||
459 | + cairo_surface_destroy (surface); | ||
460 | + | ||
461 | return pixbuf; | ||
462 | } | ||
463 | |||
464 | @@ -769,8 +1012,8 @@ thumbnail_thread (gpointer data) | ||
465 | idle_data->page_no = i; | ||
466 | |||
467 | /* FIXME get preferred size from somewhere? */ | ||
468 | - idle_data->pixbuf = get_thumbnail (thread_data->document, i, | ||
469 | - THUMBNAIL_SIZE); | ||
470 | + idle_data->pixbuf = get_thumb_pixbuf (thread_data->document, i, | ||
471 | + THUMBNAIL_SIZE); | ||
472 | |||
473 | g_idle_add (idle_set_thumbnail, idle_data); | ||
474 | |||
475 | -- | ||
476 | 1.7.5 |