Contents of /trunk/gimp/patches/gimp-2.6.11-poppler018.patch
Parent Directory | Revision Log
Revision 1597 -
(show 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 | 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 |