source: ImageMagick/trunk/coders/caption.c @ 8020

Revision 8020, 12.3 KB checked in by cristy, 12 months ago (diff)
Line 
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%                                                                             %
4%                                                                             %
5%                                                                             %
6%               CCCC   AAA   PPPP   TTTTT  IIIII   OOO   N   N                %
7%              C      A   A  P   P    T      I    O   O  NN  N                %
8%              C      AAAAA  PPPP     T      I    O   O  N N N                %
9%              C      A   A  P        T      I    O   O  N  NN                %
10%               CCCC  A   A  P        T    IIIII   OOO   N   N                %
11%                                                                             %
12%                                                                             %
13%                             Read Text Caption.                              %
14%                                                                             %
15%                              Software Design                                %
16%                                John Cristy                                  %
17%                               February 2002                                 %
18%                                                                             %
19%                                                                             %
20%  Copyright 1999-2012 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"
43#include "MagickCore/annotate.h"
44#include "MagickCore/blob.h"
45#include "MagickCore/blob-private.h"
46#include "MagickCore/composite-private.h"
47#include "MagickCore/draw.h"
48#include "MagickCore/draw-private.h"
49#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"
55#include "MagickCore/memory_.h"
56#include "MagickCore/module.h"
57#include "MagickCore/option.h"
58#include "MagickCore/property.h"
59#include "MagickCore/quantum-private.h"
60#include "MagickCore/static.h"
61#include "MagickCore/string_.h"
62#include "MagickCore/string-private.h"
63#include "MagickCore/utility.h"
64
65/*
66%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
67%                                                                             %
68%                                                                             %
69%                                                                             %
70%   R e a d C A P T I O N I m a g e                                           %
71%                                                                             %
72%                                                                             %
73%                                                                             %
74%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75%
76%  ReadCAPTIONImage() reads a CAPTION image file and returns it.  It
77%  allocates the memory necessary for the new Image structure and returns a
78%  pointer to the new image.
79%
80%  The format of the ReadCAPTIONImage method is:
81%
82%      Image *ReadCAPTIONImage(const ImageInfo *image_info,
83%        ExceptionInfo *exception)
84%
85%  A description of each parameter follows:
86%
87%    o image_info: the image info.
88%
89%    o exception: return any errors or warnings in this structure.
90%
91*/
92static Image *ReadCAPTIONImage(const ImageInfo *image_info,
93  ExceptionInfo *exception)
94{
95  char
96    *caption,
97    geometry[MaxTextExtent],
98    *property;
99
100  const char
101    *gravity,
102    *option;
103
104  DrawInfo
105    *draw_info;
106
107  Image
108    *image;
109
110  MagickBooleanType
111    status;
112
113  register ssize_t
114    i;
115
116  size_t
117    height,
118    width;
119
120  TypeMetric
121    metrics;
122
123  /*
124    Initialize Image structure.
125  */
126  assert(image_info != (const ImageInfo *) NULL);
127  assert(image_info->signature == MagickSignature);
128  if (image_info->debug != MagickFalse)
129    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
130      image_info->filename);
131  assert(exception != (ExceptionInfo *) NULL);
132  assert(exception->signature == MagickSignature);
133  image=AcquireImage(image_info,exception);
134  if (image->columns == 0)
135    ThrowReaderException(OptionError,"MustSpecifyImageSize");
136  (void) ResetImagePage(image,"0x0+0+0");
137  /*
138    Format caption.
139  */
140  option=GetImageOption(image_info,"filename");
141  if (option == (const char *) NULL)
142    property=InterpretImageProperties(image_info,image,image_info->filename,
143      exception);
144  else
145    if (LocaleNCompare(option,"caption:",8) == 0)
146      property=InterpretImageProperties(image_info,image,option+8,exception);
147    else
148      property=InterpretImageProperties(image_info,image,option,exception);
149  (void) SetImageProperty(image,"caption",property,exception);
150  property=DestroyString(property);
151  caption=ConstantString(GetImageProperty(image,"caption",exception));
152  draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
153  (void) CloneString(&draw_info->text,caption);
154  gravity=GetImageOption(image_info,"gravity");
155  if (gravity != (char *) NULL)
156    draw_info->gravity=(GravityType) ParseCommandOption(MagickGravityOptions,
157      MagickFalse,gravity);
158  if ((*caption != '\0') && (image->rows != 0) &&
159      (image_info->pointsize == 0.0))
160    {
161      char
162        *text;
163
164      /*
165        Scale text up to fit bounding box.
166      */
167      for ( ; ; )
168      {
169        text=AcquireString(caption);
170        i=FormatMagickCaption(image,draw_info,MagickFalse,&metrics,&text,
171          exception);
172        (void) CloneString(&draw_info->text,text);
173        text=DestroyString(text);
174        (void) FormatLocaleString(geometry,MaxTextExtent,"%+g%+g",
175          -metrics.bounds.x1,metrics.ascent);
176        if (draw_info->gravity == UndefinedGravity)
177          (void) CloneString(&draw_info->geometry,geometry);
178        status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
179        (void) status;
180        width=(size_t) floor(metrics.width+draw_info->stroke_width+0.5);
181        height=(size_t) floor(metrics.height+draw_info->stroke_width+0.5);
182        if ((width > image->columns) || (height > image->rows))
183          break;
184        draw_info->pointsize*=2.0;
185      }
186      draw_info->pointsize/=2.0;
187      /*
188        Scale text down to fit bounding box.
189      */
190      for ( ; ; )
191      {
192        text=AcquireString(caption);
193        i=FormatMagickCaption(image,draw_info,MagickFalse,&metrics,&text,
194          exception);
195        (void) CloneString(&draw_info->text,text);
196        text=DestroyString(text);
197        (void) FormatLocaleString(geometry,MaxTextExtent,"%+g%+g",
198          -metrics.bounds.x1,metrics.ascent);
199        if (draw_info->gravity == UndefinedGravity)
200          (void) CloneString(&draw_info->geometry,geometry);
201        status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
202        width=(size_t) floor(metrics.width+draw_info->stroke_width+0.5);
203        height=(size_t) floor(metrics.height+draw_info->stroke_width+0.5);
204        if ((width > image->columns) || (height > image->rows))
205          break;
206        draw_info->pointsize++;
207      }
208      draw_info->pointsize--;
209    }
210  i=FormatMagickCaption(image,draw_info,MagickTrue,&metrics,&caption,exception);
211  if (image->rows == 0)
212    image->rows=(size_t) ((i+1)*(metrics.ascent-metrics.descent+
213      draw_info->interline_spacing+draw_info->stroke_width)+0.5);
214  if (image->rows == 0)
215    image->rows=(size_t) ((i+1)*draw_info->pointsize+
216      draw_info->interline_spacing+draw_info->stroke_width+0.5);
217  if (SetImageBackgroundColor(image,exception) == MagickFalse)
218    {
219      image=DestroyImageList(image);
220      return((Image *) NULL);
221    }
222  /*
223    Draw caption.
224  */
225  (void) CloneString(&draw_info->text,caption);
226  status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
227  if ((draw_info->gravity != UndefinedGravity) &&
228      (draw_info->direction != RightToLeftDirection))
229    image->page.x=(ssize_t) (metrics.bounds.x1-draw_info->stroke_width/2.0);
230  else
231    {
232      (void) FormatLocaleString(geometry,MaxTextExtent,"%+g%+g",
233        -metrics.bounds.x1+draw_info->stroke_width/2.0,metrics.ascent+
234        draw_info->stroke_width/2.0);
235      if (draw_info->direction == RightToLeftDirection)
236        (void) FormatLocaleString(geometry,MaxTextExtent,"%+g%+g",
237          image->columns-(metrics.bounds.x2+draw_info->stroke_width/2.0),
238          metrics.ascent+draw_info->stroke_width/2.0);
239      draw_info->geometry=AcquireString(geometry);
240    }
241  status=AnnotateImage(image,draw_info,exception);
242  draw_info=DestroyDrawInfo(draw_info);
243  caption=DestroyString(caption);
244  if (status == MagickFalse)
245    {
246      image=DestroyImageList(image);
247      return((Image *) NULL);
248    }
249  return(GetFirstImageInList(image));
250}
251
252/*
253%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
254%                                                                             %
255%                                                                             %
256%                                                                             %
257%   R e g i s t e r C A P T I O N I m a g e                                   %
258%                                                                             %
259%                                                                             %
260%                                                                             %
261%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
262%
263%  RegisterCAPTIONImage() adds attributes for the CAPTION image format to
264%  the list of supported formats.  The attributes include the image format
265%  tag, a method to read and/or write the format, whether the format
266%  supports the saving of more than one frame to the same file or blob,
267%  whether the format supports native in-memory I/O, and a brief
268%  description of the format.
269%
270%  The format of the RegisterCAPTIONImage method is:
271%
272%      size_t RegisterCAPTIONImage(void)
273%
274*/
275ModuleExport size_t RegisterCAPTIONImage(void)
276{
277  MagickInfo
278    *entry;
279
280  entry=SetMagickInfo("CAPTION");
281  entry->decoder=(DecodeImageHandler *) ReadCAPTIONImage;
282  entry->description=ConstantString("Caption");
283  entry->adjoin=MagickFalse;
284  entry->module=ConstantString("CAPTION");
285  (void) RegisterMagickInfo(entry);
286  return(MagickImageCoderSignature);
287}
288
289/*
290%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
291%                                                                             %
292%                                                                             %
293%                                                                             %
294%   U n r e g i s t e r C A P T I O N I m a g e                               %
295%                                                                             %
296%                                                                             %
297%                                                                             %
298%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
299%
300%  UnregisterCAPTIONImage() removes format registrations made by the
301%  CAPTION module from the list of supported formats.
302%
303%  The format of the UnregisterCAPTIONImage method is:
304%
305%      UnregisterCAPTIONImage(void)
306%
307*/
308ModuleExport void UnregisterCAPTIONImage(void)
309{
310  (void) UnregisterMagickInfo("CAPTION");
311}
Note: See TracBrowser for help on using the repository browser.