13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               CCCC   AAA   PPPP   TTTTT  IIIII   OOO   N   N                %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%              C      A   A  P   P    T      I    O   O  NN  N                %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%              C      AAAAA  PPPP     T      I    O   O  N N N                %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%              C      A   A  P        T      I    O   O  N  NN                %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               CCCC  A   A  P        T    IIIII   OOO   N   N                %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                             Read Text Caption.                              %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              Software Design                                %
16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy%                                   Cristy                                    %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                               February 2002                                 %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
207ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy%  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  dedicated to making software imaging solutions freely available.           %
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  You may not use this file except in compliance with the License.  You may  %
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  obtain a copy of the License at                                            %
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    http://www.imagemagick.org/script/license.php                            %
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Unless required by applicable law or agreed to in writing, software        %
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  distributed under the License is distributed on an "AS IS" BASIS,          %
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  See the License for the specific language governing permissions and        %
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  limitations under the License.                                             %
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Include declarations.
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
424c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h"
434c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/annotate.h"
4476ce6e193e5a305875173a744bbd59d27ddb3148cristy#include "MagickCore/artifact.h"
454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob.h"
464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob-private.h"
478a3ce7f37eeb9deabe9134cb75cd69e7dae75301cristy#include "MagickCore/composite-private.h"
484c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/draw.h"
498a3ce7f37eeb9deabe9134cb75cd69e7dae75301cristy#include "MagickCore/draw-private.h"
504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h"
514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h"
524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image.h"
534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h"
544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/list.h"
554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/magick.h"
564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h"
578a3ce7f37eeb9deabe9134cb75cd69e7dae75301cristy#include "MagickCore/module.h"
584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/option.h"
594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/property.h"
604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum-private.h"
614c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/static.h"
624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h"
638a3ce7f37eeb9deabe9134cb75cd69e7dae75301cristy#include "MagickCore/string-private.h"
648a3ce7f37eeb9deabe9134cb75cd69e7dae75301cristy#include "MagickCore/utility.h"
653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d C A P T I O N I m a g e                                           %
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadCAPTIONImage() reads a CAPTION image file and returns it.  It
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image.
803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadCAPTIONImage method is:
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadCAPTIONImage(const ImageInfo *image_info,
843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadCAPTIONImage(const ImageInfo *image_info,
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo *exception)
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *caption,
98151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    geometry[MagickPathExtent],
9954ec42737fdec7527afa06ca95be82c8ca0bd866cristy    *property,
10054ec42737fdec7527afa06ca95be82c8ca0bd866cristy    *text;
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
103ab272ac4f115daf25c032de9dbb49a399eebe49bcristy    *gravity,
104ab272ac4f115daf25c032de9dbb49a399eebe49bcristy    *option;
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  DrawInfo
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *draw_info;
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
113a530273f6171e512ce2fba1d4e361885962e9423cristy    split,
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1234e82e51d7ebce7b4ef0f808d906124dd6f812248cristy  TypeMetric
1244e82e51d7ebce7b4ef0f808d906124dd6f812248cristy    metrics;
1254e82e51d7ebce7b4ef0f808d906124dd6f812248cristy
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize Image structure.
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
130e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
135e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
1369950d57e1124b73f684fb5946e206994cefda628cristy  image=AcquireImage(image_info,exception);
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetImagePage(image,"0x0+0+0");
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Format caption.
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
141092ec8d083fedaedfb7792995e7ea42164553cffcristy  option=GetImageOption(image_info,"filename");
142ab272ac4f115daf25c032de9dbb49a399eebe49bcristy  if (option == (const char *) NULL)
143e67f43f8af5feb0f08d04b14dce7ccc162973715cristy    property=InterpretImageProperties((ImageInfo *) image_info,image,
144e67f43f8af5feb0f08d04b14dce7ccc162973715cristy      image_info->filename,exception);
145ab272ac4f115daf25c032de9dbb49a399eebe49bcristy  else
146ab272ac4f115daf25c032de9dbb49a399eebe49bcristy    if (LocaleNCompare(option,"caption:",8) == 0)
147e67f43f8af5feb0f08d04b14dce7ccc162973715cristy      property=InterpretImageProperties((ImageInfo *) image_info,image,option+8,
148e67f43f8af5feb0f08d04b14dce7ccc162973715cristy        exception);
149ab272ac4f115daf25c032de9dbb49a399eebe49bcristy    else
150e67f43f8af5feb0f08d04b14dce7ccc162973715cristy      property=InterpretImageProperties((ImageInfo *) image_info,image,option,
151e67f43f8af5feb0f08d04b14dce7ccc162973715cristy        exception);
152d15e65928aec551b7388c2863de3e3e628e2e0ddcristy  (void) SetImageProperty(image,"caption",property,exception);
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  property=DestroyString(property);
154d15e65928aec551b7388c2863de3e3e628e2e0ddcristy  caption=ConstantString(GetImageProperty(image,"caption",exception));
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
1566fc392931fb03ddff4853716af6d51e329f59696cristy  (void) CloneString(&draw_info->text,caption);
157092ec8d083fedaedfb7792995e7ea42164553cffcristy  gravity=GetImageOption(image_info,"gravity");
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (gravity != (char *) NULL)
159042ee78fa9004bf1ac6a95f09d9d1faca631dda1cristy    draw_info->gravity=(GravityType) ParseCommandOption(MagickGravityOptions,
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MagickFalse,gravity);
161a530273f6171e512ce2fba1d4e361885962e9423cristy  split=MagickFalse;
1628db9ca45d3b9861f5b18cdc760c8e8f0f157b270cristy  if (image->columns == 0)
1638db9ca45d3b9861f5b18cdc760c8e8f0f157b270cristy    {
164e275ada1a7f4f90e73328c35e9f02464bafed8becristy      text=AcquireString(caption);
165a530273f6171e512ce2fba1d4e361885962e9423cristy      i=FormatMagickCaption(image,draw_info,split,&metrics,&text,
166e275ada1a7f4f90e73328c35e9f02464bafed8becristy        exception);
167e275ada1a7f4f90e73328c35e9f02464bafed8becristy      (void) CloneString(&draw_info->text,text);
168e275ada1a7f4f90e73328c35e9f02464bafed8becristy      text=DestroyString(text);
169151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) FormatLocaleString(geometry,MagickPathExtent,"%+g%+g",
170b05c534220753d20f28f816e99357d4a930e2a86cristy        -metrics.bounds.x1,metrics.ascent);
171e275ada1a7f4f90e73328c35e9f02464bafed8becristy      if (draw_info->gravity == UndefinedGravity)
172e275ada1a7f4f90e73328c35e9f02464bafed8becristy        (void) CloneString(&draw_info->geometry,geometry);
173b712c6e549e8dbd76a125beb14182d41cc8027eecristy      status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
174a492593efccb08b72392d64966b5c7728e56f16acristy      width=(size_t) floor(metrics.width+draw_info->stroke_width+0.5);
1758db9ca45d3b9861f5b18cdc760c8e8f0f157b270cristy      image->columns=width;
1768db9ca45d3b9861f5b18cdc760c8e8f0f157b270cristy    }
1778db9ca45d3b9861f5b18cdc760c8e8f0f157b270cristy  if (image->rows == 0)
1788db9ca45d3b9861f5b18cdc760c8e8f0f157b270cristy    {
179a530273f6171e512ce2fba1d4e361885962e9423cristy      split=MagickTrue;
180e275ada1a7f4f90e73328c35e9f02464bafed8becristy      text=AcquireString(caption);
1810daa8e788287feeedd328c9902e3c494409df7cbCristy      i=FormatMagickCaption(image,draw_info,split,&metrics,&text,exception);
182e275ada1a7f4f90e73328c35e9f02464bafed8becristy      (void) CloneString(&draw_info->text,text);
183e275ada1a7f4f90e73328c35e9f02464bafed8becristy      text=DestroyString(text);
184151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) FormatLocaleString(geometry,MagickPathExtent,"%+g%+g",
185b05c534220753d20f28f816e99357d4a930e2a86cristy        -metrics.bounds.x1,metrics.ascent);
186e275ada1a7f4f90e73328c35e9f02464bafed8becristy      if (draw_info->gravity == UndefinedGravity)
187e275ada1a7f4f90e73328c35e9f02464bafed8becristy        (void) CloneString(&draw_info->geometry,geometry);
188a492593efccb08b72392d64966b5c7728e56f16acristy      status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
189b05c534220753d20f28f816e99357d4a930e2a86cristy      image->rows=(size_t) ((i+1)*(metrics.ascent-metrics.descent+
19054ec42737fdec7527afa06ca95be82c8ca0bd866cristy        draw_info->interline_spacing+draw_info->stroke_width)+0.5);
1918db9ca45d3b9861f5b18cdc760c8e8f0f157b270cristy    }
192176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy  status=SetImageExtent(image,image->columns,image->rows,exception);
193176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy  if (status == MagickFalse)
194176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy    {
195176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy      draw_info=DestroyDrawInfo(draw_info);
196176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy      return(DestroyImageList(image));
197176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy    }
198176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy  if (SetImageBackgroundColor(image,exception) == MagickFalse)
199176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy    {
200176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy      draw_info=DestroyDrawInfo(draw_info);
201176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy      image=DestroyImageList(image);
202176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy      return((Image *) NULL);
203176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy    }
2041c122b152de9d1f967dd5243fa55f5e415fa40f3Cristy  if ((fabs(image_info->pointsize) < MagickEpsilon) && (strlen(caption) > 0))
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
206bdf24b20c5b02c773580a7b8cbf4ae8bb11ef994cristy      double
207bdf24b20c5b02c773580a7b8cbf4ae8bb11ef994cristy        high,
208bdf24b20c5b02c773580a7b8cbf4ae8bb11ef994cristy        low;
209bdf24b20c5b02c773580a7b8cbf4ae8bb11ef994cristy
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
211bdf24b20c5b02c773580a7b8cbf4ae8bb11ef994cristy        Auto fit text into bounding box.
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
2138592b059b2b4f03c0280b0e1146b225207e624f8cristy      for ( ; ; draw_info->pointsize*=2.0)
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text=AcquireString(caption);
216a530273f6171e512ce2fba1d4e361885962e9423cristy        i=FormatMagickCaption(image,draw_info,split,&metrics,&text,
2175cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy          exception);
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloneString(&draw_info->text,text);
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text=DestroyString(text);
220151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        (void) FormatLocaleString(geometry,MagickPathExtent,"%+g%+g",
221b05c534220753d20f28f816e99357d4a930e2a86cristy          -metrics.bounds.x1,metrics.ascent);
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (draw_info->gravity == UndefinedGravity)
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloneString(&draw_info->geometry,geometry);
2245cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy        status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
225bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        width=(size_t) floor(metrics.width+draw_info->stroke_width+0.5);
2264e82e51d7ebce7b4ef0f808d906124dd6f812248cristy        height=(size_t) floor(metrics.height+draw_info->stroke_width+0.5);
227071c2e261259c0957447cebc377c3fdea6f437f9cristy        if ((image->columns != 0) && (image->rows != 0))
228071c2e261259c0957447cebc377c3fdea6f437f9cristy          {
229cae9c06539e4a0ce3b21f544808bd8096a76253bcristy            if ((width >= image->columns) && (height >= image->rows))
230071c2e261259c0957447cebc377c3fdea6f437f9cristy              break;
231071c2e261259c0957447cebc377c3fdea6f437f9cristy          }
232071c2e261259c0957447cebc377c3fdea6f437f9cristy        else
233cae9c06539e4a0ce3b21f544808bd8096a76253bcristy          if (((image->columns != 0) && (width >= image->columns)) ||
234cae9c06539e4a0ce3b21f544808bd8096a76253bcristy              ((image->rows != 0) && (height >= image->rows)))
235071c2e261259c0957447cebc377c3fdea6f437f9cristy            break;
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2370839c55af3e04dec06756f60da81a58210557c29cristy      high=draw_info->pointsize;
2387426358cdb387dfd265789a728887257b9a42ff2cristy      for (low=1.0; (high-low) > 0.5; )
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
240bdf24b20c5b02c773580a7b8cbf4ae8bb11ef994cristy        draw_info->pointsize=(low+high)/2.0;
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text=AcquireString(caption);
242a530273f6171e512ce2fba1d4e361885962e9423cristy        i=FormatMagickCaption(image,draw_info,split,&metrics,&text,
2435cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy          exception);
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloneString(&draw_info->text,text);
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text=DestroyString(text);
246151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        (void) FormatLocaleString(geometry,MagickPathExtent,"%+g%+g",
247b05c534220753d20f28f816e99357d4a930e2a86cristy          -metrics.bounds.x1,metrics.ascent);
2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (draw_info->gravity == UndefinedGravity)
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloneString(&draw_info->geometry,geometry);
2505cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy        status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
251bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        width=(size_t) floor(metrics.width+draw_info->stroke_width+0.5);
2524e82e51d7ebce7b4ef0f808d906124dd6f812248cristy        height=(size_t) floor(metrics.height+draw_info->stroke_width+0.5);
253071c2e261259c0957447cebc377c3fdea6f437f9cristy        if ((image->columns != 0) && (image->rows != 0))
254071c2e261259c0957447cebc377c3fdea6f437f9cristy          {
255cae9c06539e4a0ce3b21f544808bd8096a76253bcristy            if ((width < image->columns) && (height < image->rows))
2567426358cdb387dfd265789a728887257b9a42ff2cristy              low=draw_info->pointsize+0.5;
257071c2e261259c0957447cebc377c3fdea6f437f9cristy            else
2587426358cdb387dfd265789a728887257b9a42ff2cristy              high=draw_info->pointsize-0.5;
259071c2e261259c0957447cebc377c3fdea6f437f9cristy          }
260bdf24b20c5b02c773580a7b8cbf4ae8bb11ef994cristy        else
261071c2e261259c0957447cebc377c3fdea6f437f9cristy          if (((image->columns != 0) && (width < image->columns)) ||
262071c2e261259c0957447cebc377c3fdea6f437f9cristy              ((image->rows != 0) && (height < image->rows)))
2637426358cdb387dfd265789a728887257b9a42ff2cristy            low=draw_info->pointsize+0.5;
264071c2e261259c0957447cebc377c3fdea6f437f9cristy          else
2657426358cdb387dfd265789a728887257b9a42ff2cristy            high=draw_info->pointsize-0.5;
26617386ff059907b275aeb762297179b2d26d95a33cristy      }
2677426358cdb387dfd265789a728887257b9a42ff2cristy      draw_info->pointsize=(low+high)/2.0-0.5;
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Draw caption.
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
272176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy  i=FormatMagickCaption(image,draw_info,split,&metrics,&caption,exception);
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloneString(&draw_info->text,caption);
274e9e92dd4debbaafd2c99ee9aaec315951672d415Cristy  (void) FormatLocaleString(geometry,MagickPathExtent,"%+g%+g",MagickMax(
275176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy    draw_info->direction == RightToLeftDirection ? image->columns-
276e9e92dd4debbaafd2c99ee9aaec315951672d415Cristy    metrics.bounds.x2 : -metrics.bounds.x1,0.0),draw_info->gravity ==
277176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy    UndefinedGravity ? metrics.ascent : 0.0);
278176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy  draw_info->geometry=AcquireString(geometry);
279ab272ac4f115daf25c032de9dbb49a399eebe49bcristy  status=AnnotateImage(image,draw_info,exception);
280176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy  if (image_info->pointsize == 0.0)
281176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy    {
282176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy      char
283151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        pointsize[MagickPathExtent];
284176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy
285151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) FormatLocaleString(pointsize,MagickPathExtent,"%.20g",
286176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy        draw_info->pointsize);
287176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy      (void) SetImageProperty(image,"caption:pointsize",pointsize,exception);
288176d1cd4293e7b83399eb0fb74e4622a476ef7c3cristy    }
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  draw_info=DestroyDrawInfo(draw_info);
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  caption=DestroyString(caption);
291ab272ac4f115daf25c032de9dbb49a399eebe49bcristy  if (status == MagickFalse)
292ab272ac4f115daf25c032de9dbb49a399eebe49bcristy    {
293ab272ac4f115daf25c032de9dbb49a399eebe49bcristy      image=DestroyImageList(image);
294ab272ac4f115daf25c032de9dbb49a399eebe49bcristy      return((Image *) NULL);
295ab272ac4f115daf25c032de9dbb49a399eebe49bcristy    }
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r C A P T I O N I m a g e                                   %
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterCAPTIONImage() adds attributes for the CAPTION image format to
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The attributes include the image format
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterCAPTIONImage method is:
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
319bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterCAPTIONImage(void)
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
322bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterCAPTIONImage(void)
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32706b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("CAPTION","CAPTION","Caption");
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadCAPTIONImage;
32908e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r C A P T I O N I m a g e                               %
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterCAPTIONImage() removes format registrations made by the
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  CAPTION module from the list of supported formats.
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterCAPTIONImage method is:
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterCAPTIONImage(void)
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterCAPTIONImage(void)
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("CAPTION");
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
357