1 | #include "mupdf/fitz.h" |
2 | #include "xps-imp.h" |
3 | |
4 | #include <string.h> |
5 | |
6 | static fz_image * |
7 | xps_load_image(fz_context *ctx, xps_document *doc, xps_part *part) |
8 | { |
9 | return fz_new_image_from_buffer(ctx, part->data); |
10 | } |
11 | |
12 | /* FIXME: area unused! */ |
13 | static void |
14 | xps_paint_image_brush(fz_context *ctx, xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, |
15 | fz_xml *root, void *vimage) |
16 | { |
17 | fz_image *image = vimage; |
18 | float xs, ys; |
19 | |
20 | if (image->xres == 0 || image->yres == 0) |
21 | return; |
22 | xs = image->w * 96 / image->xres; |
23 | ys = image->h * 96 / image->yres; |
24 | ctm = fz_pre_scale(ctm, xs, ys); |
25 | fz_fill_image(ctx, doc->dev, image, ctm, doc->opacity[doc->opacity_top], fz_default_color_params); |
26 | } |
27 | |
28 | static void |
29 | xps_find_image_brush_source_part(fz_context *ctx, xps_document *doc, char *base_uri, fz_xml *root, xps_part **image_part, xps_part **profile_part) |
30 | { |
31 | char *image_source_att; |
32 | char buf[1024]; |
33 | char partname[1024]; |
34 | char *image_name; |
35 | char *profile_name; |
36 | char *p; |
37 | |
38 | image_source_att = fz_xml_att(root, "ImageSource" ); |
39 | if (!image_source_att) |
40 | fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find image source attribute" ); |
41 | |
42 | /* "{ColorConvertedBitmap /Resources/Image.tiff /Resources/Profile.icc}" */ |
43 | if (strstr(image_source_att, "{ColorConvertedBitmap" ) == image_source_att) |
44 | { |
45 | image_name = NULL; |
46 | profile_name = NULL; |
47 | |
48 | fz_strlcpy(buf, image_source_att, sizeof buf); |
49 | p = strchr(buf, ' '); |
50 | if (p) |
51 | { |
52 | image_name = p + 1; |
53 | p = strchr(p + 1, ' '); |
54 | if (p) |
55 | { |
56 | *p = 0; |
57 | profile_name = p + 1; |
58 | p = strchr(p + 1, '}'); |
59 | if (p) |
60 | *p = 0; |
61 | } |
62 | } |
63 | } |
64 | else |
65 | { |
66 | image_name = image_source_att; |
67 | profile_name = NULL; |
68 | } |
69 | |
70 | if (!image_name) |
71 | fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find image source" ); |
72 | |
73 | if (image_part) |
74 | { |
75 | xps_resolve_url(ctx, doc, partname, base_uri, image_name, sizeof partname); |
76 | *image_part = xps_read_part(ctx, doc, partname); |
77 | } |
78 | |
79 | if (profile_part) |
80 | { |
81 | if (profile_name) |
82 | { |
83 | xps_resolve_url(ctx, doc, partname, base_uri, profile_name, sizeof partname); |
84 | *profile_part = xps_read_part(ctx, doc, partname); |
85 | } |
86 | else |
87 | *profile_part = NULL; |
88 | } |
89 | } |
90 | |
91 | void |
92 | xps_parse_image_brush(fz_context *ctx, xps_document *doc, fz_matrix ctm, fz_rect area, |
93 | char *base_uri, xps_resource *dict, fz_xml *root) |
94 | { |
95 | xps_part *part = NULL; |
96 | fz_image *image = NULL; |
97 | |
98 | fz_try(ctx) |
99 | { |
100 | xps_find_image_brush_source_part(ctx, doc, base_uri, root, &part, NULL); |
101 | } |
102 | fz_catch(ctx) |
103 | { |
104 | if (fz_caught(ctx) == FZ_ERROR_TRYLATER) |
105 | { |
106 | if (doc->cookie) |
107 | doc->cookie->incomplete = 1; |
108 | } |
109 | else |
110 | fz_warn(ctx, "cannot find image source" ); |
111 | return; |
112 | } |
113 | |
114 | fz_try(ctx) |
115 | { |
116 | image = xps_load_image(ctx, doc, part); |
117 | } |
118 | fz_always(ctx) |
119 | { |
120 | xps_drop_part(ctx, doc, part); |
121 | } |
122 | fz_catch(ctx) |
123 | { |
124 | fz_warn(ctx, "cannot decode image resource" ); |
125 | return; |
126 | } |
127 | |
128 | fz_try(ctx) |
129 | xps_parse_tiling_brush(ctx, doc, ctm, area, base_uri, dict, root, xps_paint_image_brush, image); |
130 | fz_always(ctx) |
131 | fz_drop_image(ctx, image); |
132 | fz_catch(ctx) |
133 | fz_rethrow(ctx); |
134 | } |
135 | |