blob: 506fd84fafad47e5ca9d4755fa23d372338bac83 [file] [log] [blame]
cristybd4fb6e2011-10-26 13:10:01 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% PPPP AAA N N GGGG OOO %
7% P P A A NN N G O O %
8% PPPP AAAAA N N N G GGG O O %
9% P M A A N NN G G O O %
10% P A A N N GGGG OOO %
11% %
12% %
13% Read Pango Markup Language Format %
14% %
15% Software Design %
16% John Cristy %
17% March 2012 %
18% %
19% %
20% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
21% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38
39/*
40 Include declarations.
41*/
42#include "MagickCore/studio.h"
cristy884cbde2011-10-28 14:42:14 +000043#include "MagickCore/annotate.h"
cristybd4fb6e2011-10-26 13:10:01 +000044#include "MagickCore/blob.h"
45#include "MagickCore/blob-private.h"
cristy884cbde2011-10-28 14:42:14 +000046#include "MagickCore/composite-private.h"
47#include "MagickCore/draw.h"
48#include "MagickCore/draw-private.h"
cristybd4fb6e2011-10-26 13:10:01 +000049#include "MagickCore/exception.h"
50#include "MagickCore/exception-private.h"
51#include "MagickCore/image.h"
52#include "MagickCore/image-private.h"
53#include "MagickCore/list.h"
54#include "MagickCore/magick.h"
cristy884cbde2011-10-28 14:42:14 +000055#include "MagickCore/module.h"
cristybd4fb6e2011-10-26 13:10:01 +000056#include "MagickCore/memory_.h"
57#include "MagickCore/option.h"
58#include "MagickCore/pixel-accessor.h"
cristy884cbde2011-10-28 14:42:14 +000059#include "MagickCore/property.h"
cristybd4fb6e2011-10-26 13:10:01 +000060#include "MagickCore/quantum-private.h"
61#include "MagickCore/static.h"
62#include "MagickCore/string_.h"
cristy884cbde2011-10-28 14:42:14 +000063#if defined(MAGICKCORE_PANGOFT2_DELEGATE)
cristybd4fb6e2011-10-26 13:10:01 +000064#include <pango/pango.h>
cristy884cbde2011-10-28 14:42:14 +000065#include <pango/pangoft2.h>
cristybd4fb6e2011-10-26 13:10:01 +000066#endif
67
cristy884cbde2011-10-28 14:42:14 +000068#if defined(MAGICKCORE_PANGOFT2_DELEGATE)
cristybd4fb6e2011-10-26 13:10:01 +000069/*
70%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71% %
72% %
73% %
cristy6c28ec02011-10-28 11:37:57 +000074% R e a d P A N G O I m a g e %
cristybd4fb6e2011-10-26 13:10:01 +000075% %
76% %
77% %
78%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
79%
80% ReadPANGOImage() reads an image in the Pango Markup Language Format.
81%
82% The format of the ReadPANGOImage method is:
83%
84% Image *ReadPANGOImage(const ImageInfo *image_info,
85% ExceptionInfo *exception)
86%
87% A description of each parameter follows:
88%
89% o image_info: the image info.
90%
91% o exception: return any errors or warnings in this structure.
92%
93*/
94static Image *ReadPANGOImage(const ImageInfo *image_info,
95 ExceptionInfo *exception)
96{
cristy884cbde2011-10-28 14:42:14 +000097 char
98 *caption,
99 *property;
100
101 DrawInfo
102 *draw_info;
103
104 FT_Bitmap
105 *canvas;
106
107 Image
108 *image;
109
110 MagickBooleanType
111 status;
112
113 PangoContext
114 *context;
115
116 PangoFontDescription
117 *description;
118
119 PangoFontMap
120 *fontmap;
121
122 PangoLayout
123 *layout;
124
cristy6a851052011-10-28 17:21:10 +0000125 PangoRectangle
126 extent;
127
cristy884cbde2011-10-28 14:42:14 +0000128 PixelInfo
129 fill_color;
130
131 register Quantum
132 *q;
133
134 register unsigned char
135 *p;
136
137 ssize_t
138 y;
139
140 /*
141 Initialize Image structure.
142 */
143 assert(image_info != (const ImageInfo *) NULL);
144 assert(image_info->signature == MagickSignature);
145 if (image_info->debug != MagickFalse)
146 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
147 image_info->filename);
148 assert(exception != (ExceptionInfo *) NULL);
149 assert(exception->signature == MagickSignature);
150 image=AcquireImage(image_info,exception);
cristy884cbde2011-10-28 14:42:14 +0000151 (void) ResetImagePage(image,"0x0+0+0");
cristy884cbde2011-10-28 14:42:14 +0000152 /*
153 Get context.
154 */
155 fontmap=(PangoFontMap *) pango_ft2_font_map_new();
156 pango_ft2_font_map_set_resolution((PangoFT2FontMap *) fontmap,
157 image->x_resolution,image->y_resolution);
158 pango_ft2_font_map_set_default_substitute((PangoFT2FontMap *) fontmap,NULL,
159 NULL,NULL);
160 context=pango_font_map_create_context(fontmap);
161 /*
cristy6a851052011-10-28 17:21:10 +0000162 Render caption.
163 */
164 layout=pango_layout_new(context);
165 description=pango_font_description_from_string("Arial,20");
166 pango_layout_set_font_description(layout,description);
167 pango_font_description_free(description);
168 property=InterpretImageProperties(image_info,image,image_info->filename,
169 exception);
170 (void) SetImageProperty(image,"caption",property,exception);
171 property=DestroyString(property);
172 caption=ConstantString(GetImageProperty(image,"caption",exception));
173 pango_layout_set_text(layout,caption,-1);
174 pango_layout_context_changed(layout);
175 if (image->columns == 0)
176 {
177 pango_layout_get_pixel_extents(layout,NULL,&extent);
178 image->columns=extent.x+extent.width;
179 }
180 if (image->rows == 0)
181 {
182 pango_layout_get_pixel_extents(layout,NULL,&extent);
183 image->rows=extent.y+extent.height;
184 }
185 /*
cristy884cbde2011-10-28 14:42:14 +0000186 Create canvas.
187 */
188 canvas=(FT_Bitmap *) AcquireMagickMemory(sizeof(*canvas));
189 if (canvas == (FT_Bitmap *) NULL)
190 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
191 canvas->width=image->columns;
192 canvas->pitch=(canvas->width+3) & ~3;
193 canvas->rows=image->rows;
194 canvas->buffer=(unsigned char *) AcquireQuantumMemory(canvas->pitch,
195 canvas->rows*sizeof(*canvas->buffer));
196 if (canvas->buffer == (unsigned char *) NULL)
197 {
198 canvas=(FT_Bitmap *) RelinquishMagickMemory(canvas);
199 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
200 }
201 canvas->num_grays=256;
202 canvas->pixel_mode=ft_pixel_mode_grays;
203 ResetMagickMemory(canvas->buffer,0x00,canvas->pitch*canvas->rows);
cristy884cbde2011-10-28 14:42:14 +0000204 /* wrapping: pango_layout_set_width(layout,72*image->columns); */
205 pango_ft2_render_layout(canvas,layout,0,0);
206 /*
207 Convert caption to image.
208 */
cristy6a851052011-10-28 17:21:10 +0000209 if (SetImageBackgroundColor(image,exception) == MagickFalse)
210 {
211 canvas->buffer=(unsigned char *) RelinquishMagickMemory(canvas->buffer);
212 canvas=(FT_Bitmap *) RelinquishMagickMemory(canvas);
213 caption=DestroyString(caption);
214 image=DestroyImageList(image);
215 return((Image *) NULL);
216 }
cristy884cbde2011-10-28 14:42:14 +0000217 draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
218 GetPixelInfo(image,&fill_color);
219 p=canvas->buffer;
220 for (y=0; y < (ssize_t) image->rows; y++)
221 {
222 register ssize_t
223 x;
224
225 q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
226 if (q == (Quantum *) NULL)
227 break;
228 for (x=0; x < (ssize_t) image->columns; x++)
229 {
230 MagickRealType
231 fill_opacity;
232
233 (void) GetFillColor(draw_info,x,y,&fill_color,exception);
234 fill_opacity=(*p)*fill_color.alpha/canvas->num_grays;
cristy79497822011-10-28 14:51:23 +0000235 if (draw_info->text_antialias == MagickFalse)
236 fill_opacity=fill_opacity >= 0.5 ? 1.0 : 0.0;
cristy884cbde2011-10-28 14:42:14 +0000237 CompositePixelOver(image,&fill_color,fill_opacity,q,
238 GetPixelAlpha(image,q),q);
239 p++;
240 q+=GetPixelChannels(image);
241 }
cristy6a851052011-10-28 17:21:10 +0000242 for ( ; x < (ssize_t) ((canvas->width+3) & ~3); x++)
243 p++;
cristy884cbde2011-10-28 14:42:14 +0000244 }
245 /*
246 Relinquish resources.
247 */
248 draw_info=DestroyDrawInfo(draw_info);
249 canvas->buffer=(unsigned char *) RelinquishMagickMemory(canvas->buffer);
250 canvas=(FT_Bitmap *) RelinquishMagickMemory(canvas);
251 caption=DestroyString(caption);
252 return(GetFirstImageInList(image));
cristybd4fb6e2011-10-26 13:10:01 +0000253}
254#endif
255
256/*
257%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
258% %
259% %
260% %
261% R e g i s t e r P A N G O I m a g e %
262% %
263% %
264% %
265%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
266%
267% RegisterPANGOImage() adds attributes for the Pango Markup Language format to
268% the list of supported formats. The attributes include the image format
269% tag, a method to read and/or write the format, whether the format
270% supports the saving of more than one frame to the same file or blob,
271% whether the format supports native in-memory I/O, and a brief
272% description of the format.
273%
274% The format of the RegisterPANGOImage method is:
275%
276% size_t RegisterPANGOImage(void)
277%
278*/
279ModuleExport size_t RegisterPANGOImage(void)
280{
281 MagickInfo
282 *entry;
283
284 entry=SetMagickInfo("PANGO");
cristy884cbde2011-10-28 14:42:14 +0000285#if defined(MAGICKCORE_PANGOFT2_DELEGATE)
cristybd4fb6e2011-10-26 13:10:01 +0000286 entry->decoder=(DecodeImageHandler *) ReadPANGOImage;
287#endif
288 entry->description=ConstantString("Pango Markup Language");
289 entry->adjoin=MagickFalse;
290 entry->module=ConstantString("PANGO");
291 (void) RegisterMagickInfo(entry);
292 return(MagickImageCoderSignature);
293}
294
295/*
296%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
297% %
298% %
299% %
300% U n r e g i s t e r P A N G O I m a g e %
301% %
302% %
303% %
304%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
305%
306% UnregisterPANGOImage() removes format registrations made by the Pango module
307% from the list of supported formats.
308%
309% The format of the UnregisterPANGOImage method is:
310%
311% UnregisterPANGOImage(void)
312%
313*/
314ModuleExport void UnregisterPANGOImage(void)
315{
316 (void) UnregisterMagickInfo("PANGO");
317}