caption.c revision e67f43f8af5feb0f08d04b14dce7ccc162973715
1ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj/*
2ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3752f90673ebbb6b2f55fc5e46606dea371313713sewardj%                                                                             %
4ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj%                                                                             %
5ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj%                                                                             %
6f8ed9d874a7b8651654591c68c6d431c758d787csewardj%               CCCC   AAA   PPPP   TTTTT  IIIII   OOO   N   N                %
7752f90673ebbb6b2f55fc5e46606dea371313713sewardj%              C      A   A  P   P    T      I    O   O  NN  N                %
8752f90673ebbb6b2f55fc5e46606dea371313713sewardj%              C      AAAAA  PPPP     T      I    O   O  N N N                %
9f8ed9d874a7b8651654591c68c6d431c758d787csewardj%              C      A   A  P        T      I    O   O  N  NN                %
10752f90673ebbb6b2f55fc5e46606dea371313713sewardj%               CCCC  A   A  P        T    IIIII   OOO   N   N                %
11752f90673ebbb6b2f55fc5e46606dea371313713sewardj%                                                                             %
127bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj%                                                                             %
13752f90673ebbb6b2f55fc5e46606dea371313713sewardj%                             Read Text Caption.                              %
14752f90673ebbb6b2f55fc5e46606dea371313713sewardj%                                                                             %
15752f90673ebbb6b2f55fc5e46606dea371313713sewardj%                              Software Design                                %
16752f90673ebbb6b2f55fc5e46606dea371313713sewardj%                                John Cristy                                  %
177bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj%                               February 2002                                 %
18752f90673ebbb6b2f55fc5e46606dea371313713sewardj%                                                                             %
19752f90673ebbb6b2f55fc5e46606dea371313713sewardj%                                                                             %
20752f90673ebbb6b2f55fc5e46606dea371313713sewardj%  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization      %
21752f90673ebbb6b2f55fc5e46606dea371313713sewardj%  dedicated to making software imaging solutions freely available.           %
22752f90673ebbb6b2f55fc5e46606dea371313713sewardj%                                                                             %
23752f90673ebbb6b2f55fc5e46606dea371313713sewardj%  You may not use this file except in compliance with the License.  You may  %
24752f90673ebbb6b2f55fc5e46606dea371313713sewardj%  obtain a copy of the License at                                            %
25752f90673ebbb6b2f55fc5e46606dea371313713sewardj%                                                                             %
267bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj%    http://www.imagemagick.org/script/license.php                            %
277bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj%                                                                             %
28752f90673ebbb6b2f55fc5e46606dea371313713sewardj%  Unless required by applicable law or agreed to in writing, software        %
29f8ed9d874a7b8651654591c68c6d431c758d787csewardj%  distributed under the License is distributed on an "AS IS" BASIS,          %
30f8ed9d874a7b8651654591c68c6d431c758d787csewardj%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
31f8ed9d874a7b8651654591c68c6d431c758d787csewardj%  See the License for the specific language governing permissions and        %
32f8ed9d874a7b8651654591c68c6d431c758d787csewardj%  limitations under the License.                                             %
33f8ed9d874a7b8651654591c68c6d431c758d787csewardj%                                                                             %
34f8ed9d874a7b8651654591c68c6d431c758d787csewardj%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35f8ed9d874a7b8651654591c68c6d431c758d787csewardj%
36887a11a609f3e61d2ae8fe4e67f176207715da7esewardj%
37887a11a609f3e61d2ae8fe4e67f176207715da7esewardj*/
38ac9af021b93dfe6f35c01d9c6fd15a3d67685843sewardj
39887a11a609f3e61d2ae8fe4e67f176207715da7esewardj/*
40ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj  Include declarations.
4157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj*/
42ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj#include "MagickCore/studio.h"
4357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include "MagickCore/annotate.h"
4457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include "MagickCore/artifact.h"
4557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include "MagickCore/blob.h"
4657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include "MagickCore/blob-private.h"
4757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include "MagickCore/composite-private.h"
4857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include "MagickCore/draw.h"
4957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include "MagickCore/draw-private.h"
5057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include "MagickCore/exception.h"
5157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include "MagickCore/exception-private.h"
5257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include "MagickCore/image.h"
53dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#include "MagickCore/image-private.h"
54dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#include "MagickCore/list.h"
55dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#include "MagickCore/magick.h"
56dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#include "MagickCore/memory_.h"
5757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include "MagickCore/module.h"
58dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#include "MagickCore/option.h"
5957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include "MagickCore/property.h"
60dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#include "MagickCore/quantum-private.h"
6157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include "MagickCore/static.h"
62dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#include "MagickCore/string_.h"
63dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#include "MagickCore/string-private.h"
64dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj#include "MagickCore/utility.h"
65dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj
6657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/*
6757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%                                                                             %
6957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%                                                                             %
7057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%                                                                             %
7157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%   R e a d C A P T I O N I m a g e                                           %
7257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%                                                                             %
7357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%                                                                             %
7457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%                                                                             %
7557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%
7757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%  ReadCAPTIONImage() reads a CAPTION image file and returns it.  It
7857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%  allocates the memory necessary for the new Image structure and returns a
7957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%  pointer to the new image.
8057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%
8157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%  The format of the ReadCAPTIONImage method is:
8257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%
8357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%      Image *ReadCAPTIONImage(const ImageInfo *image_info,
8457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%        ExceptionInfo *exception)
8557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%
8657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%  A description of each parameter follows:
8757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%
8857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%    o image_info: the image info.
8957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%
9057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%    o exception: return any errors or warnings in this structure.
9157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%
9257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj*/
93dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjstatic Image *ReadCAPTIONImage(const ImageInfo *image_info,
94dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj  ExceptionInfo *exception)
95dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj{
96dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj  char
97dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj    *caption,
9857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    geometry[MaxTextExtent],
9957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    *property,
10057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    *text;
10157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
10257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  const char
10357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    *gravity,
10457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    *option;
10557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
10657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  DrawInfo
1072f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj    *draw_info;
10857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
10957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  Image
11057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    *image;
11157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
11257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  MagickBooleanType
11357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    status;
11457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
11557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  register ssize_t
11657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    i;
11757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
11857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  size_t
11957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    height,
12057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    width;
12157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
12257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  TypeMetric
12357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    metrics;
12457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
12557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  /*
12657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    Initialize Image structure.
12757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  */
12857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  assert(image_info != (const ImageInfo *) NULL);
12957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  assert(image_info->signature == MagickSignature);
13057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  if (image_info->debug != MagickFalse)
13157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
13257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      image_info->filename);
13357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  assert(exception != (ExceptionInfo *) NULL);
13457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  assert(exception->signature == MagickSignature);
13557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  image=AcquireImage(image_info,exception);
13657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  (void) ResetImagePage(image,"0x0+0+0");
13757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  /*
13857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    Format caption.
13957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  */
14057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  option=GetImageOption(image_info,"filename");
14157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  if (option == (const char *) NULL)
14257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    property=InterpretImageProperties((ImageInfo *) image_info,image,
14357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      image_info->filename,exception);
14457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  else
14557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    if (LocaleNCompare(option,"caption:",8) == 0)
14657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      property=InterpretImageProperties((ImageInfo *) image_info,image,option+8,
14757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        exception);
14857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    else
14957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      property=InterpretImageProperties((ImageInfo *) image_info,image,option,
1502f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj        exception);
15157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  (void) SetImageProperty(image,"caption",property,exception);
15257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  property=DestroyString(property);
15357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  caption=ConstantString(GetImageProperty(image,"caption",exception));
15457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
15557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  (void) CloneString(&draw_info->text,caption);
15657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  gravity=GetImageOption(image_info,"gravity");
15757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  if (gravity != (char *) NULL)
15857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    draw_info->gravity=(GravityType) ParseCommandOption(MagickGravityOptions,
15957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      MagickFalse,gravity);
16057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  if (image->columns == 0)
16157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    {
16257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      text=AcquireString(caption);
16357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      i=FormatMagickCaption(image,draw_info,MagickFalse,&metrics,&text,
16457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        exception);
16557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      (void) CloneString(&draw_info->text,text);
16657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      text=DestroyString(text);
16757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      (void) FormatLocaleString(geometry,MaxTextExtent,"%+g%+g",
16857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        -metrics.bounds.x1,metrics.ascent);
16957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      if (draw_info->gravity == UndefinedGravity)
170dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj        (void) CloneString(&draw_info->geometry,geometry);
17157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
17257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      width=(size_t) floor(metrics.width+draw_info->stroke_width+0.5);
17357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      image->columns=width;
17457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    }
17557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  if (image->rows == 0)
17657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    {
17757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      text=AcquireString(caption);
17857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      i=FormatMagickCaption(image,draw_info,MagickFalse,&metrics,&text,
17957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        exception);
18057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      (void) CloneString(&draw_info->text,text);
18157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      text=DestroyString(text);
18257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      (void) FormatLocaleString(geometry,MaxTextExtent,"%+g%+g",
18357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        -metrics.bounds.x1,metrics.ascent);
18457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      if (draw_info->gravity == UndefinedGravity)
18557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        (void) CloneString(&draw_info->geometry,geometry);
18657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
18757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      image->rows=(size_t) ((i+1)*(metrics.ascent-metrics.descent+
188ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj        draw_info->interline_spacing+draw_info->stroke_width)+0.5);
189ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj    }
190ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj  if (fabs(image_info->pointsize) < MagickEpsilon)
191496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj    {
192496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj      double
193496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj        high,
194496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj        low;
195496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj
196496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj      /*
197496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj        Auto fit text into bounding box.
198496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj      */
199496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj      for ( ; ; draw_info->pointsize*=2.0)
200496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj      {
201496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj        text=AcquireString(caption);
202496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj        i=FormatMagickCaption(image,draw_info,MagickFalse,&metrics,&text,
203496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj          exception);
204dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj        (void) CloneString(&draw_info->text,text);
205496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj        text=DestroyString(text);
206f6c8ebf1294fea43756683ba7089b746168abb8esewardj        (void) FormatLocaleString(geometry,MaxTextExtent,"%+g%+g",
207f6c8ebf1294fea43756683ba7089b746168abb8esewardj          -metrics.bounds.x1,metrics.ascent);
208496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj        if (draw_info->gravity == UndefinedGravity)
209dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj          (void) CloneString(&draw_info->geometry,geometry);
210496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj        status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
211f6c8ebf1294fea43756683ba7089b746168abb8esewardj        width=(size_t) floor(metrics.width+draw_info->stroke_width+0.5);
212f6c8ebf1294fea43756683ba7089b746168abb8esewardj        height=(size_t) floor(metrics.height+draw_info->stroke_width+0.5);
213496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj        if ((width >= image->columns) && (height >= image->rows))
214496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj          break;
215c97096c44637ae5775ed305b19f16f0b505f17d8sewardj        if ((width >= (image->columns << 1)) || (height >= (image->rows << 1)))
216e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj          break;
21757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      }
21857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      high=draw_info->pointsize;
219e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj      for (low=1.0; (high-low) > 1.0; )
220c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      {
221c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj        draw_info->pointsize=(low+high)/2.0;
222c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj        text=AcquireString(caption);
223c9a43665879a03886b27a65b68af2a2c11b04f59sewardj        i=FormatMagickCaption(image,draw_info,MagickFalse,&metrics,&text,
224c9a43665879a03886b27a65b68af2a2c11b04f59sewardj          exception);
225c9a43665879a03886b27a65b68af2a2c11b04f59sewardj        (void) CloneString(&draw_info->text,text);
226c9a43665879a03886b27a65b68af2a2c11b04f59sewardj        text=DestroyString(text);
2279b96767debeeb1f78378f0e7e295fe6762c64002sewardj        (void) FormatLocaleString(geometry,MaxTextExtent,"%+g%+g",
228c9a43665879a03886b27a65b68af2a2c11b04f59sewardj          -metrics.bounds.x1,metrics.ascent);
229c9a43665879a03886b27a65b68af2a2c11b04f59sewardj        if (draw_info->gravity == UndefinedGravity)
2302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj          (void) CloneString(&draw_info->geometry,geometry);
231c9a43665879a03886b27a65b68af2a2c11b04f59sewardj        status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
232d1725d18b61bf7912a9099686179faef5815dba1sewardj        width=(size_t) floor(metrics.width+draw_info->stroke_width+0.5);
233e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj        height=(size_t) floor(metrics.height+draw_info->stroke_width+0.5);
234e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj        if ((width <= image->columns) && (height <= image->rows))
23557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj          low=draw_info->pointsize+1.0;
23635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj        else
23757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj          high=draw_info->pointsize-1.0;
23857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      }
23957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      for (draw_info->pointsize=(low+high)/2.0; (high-low) > 1.0; )
240c97096c44637ae5775ed305b19f16f0b505f17d8sewardj      {
241e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj        text=AcquireString(caption);
242af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj        i=FormatMagickCaption(image,draw_info,MagickFalse,&metrics,&text,
243af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj          exception);
24457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        (void) CloneString(&draw_info->text,text);
245af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj        text=DestroyString(text);
246af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj        (void) FormatLocaleString(geometry,MaxTextExtent,"%+g%+g",
247c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj          -metrics.bounds.x1,metrics.ascent);
248c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj        if (draw_info->gravity == UndefinedGravity)
249af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj          (void) CloneString(&draw_info->geometry,geometry);
250af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj        status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
251af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj        width=(size_t) floor(metrics.width+draw_info->stroke_width+0.5);
252af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj        height=(size_t) floor(metrics.height+draw_info->stroke_width+0.5);
253c97096c44637ae5775ed305b19f16f0b505f17d8sewardj        if ((width <= image->columns) && (height <= image->rows))
254ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj          break;
25557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        draw_info->pointsize--;
25657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      }
25757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      draw_info->pointsize--;
258ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj    }
259c9a43665879a03886b27a65b68af2a2c11b04f59sewardj  (void) CloneString(&draw_info->text,caption);
260c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj  i=FormatMagickCaption(image,draw_info,MagickFalse,&metrics,&caption,
261c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    exception);
262c9a43665879a03886b27a65b68af2a2c11b04f59sewardj  if (SetImageBackgroundColor(image,exception) == MagickFalse)
263c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    {
264c9a43665879a03886b27a65b68af2a2c11b04f59sewardj      image=DestroyImageList(image);
2652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj      return((Image *) NULL);
2662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj    }
2672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj  /*
2681e6ad745ebafd0524da1da27a4b85524fa84f777sewardj    Draw caption.
2691e6ad745ebafd0524da1da27a4b85524fa84f777sewardj  */
2701e6ad745ebafd0524da1da27a4b85524fa84f777sewardj  (void) CloneString(&draw_info->text,caption);
27157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
27257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj  if ((draw_info->gravity != UndefinedGravity) &&
273207557ab2ea38239b670785c976b89d50bbb0eccsewardj      (draw_info->direction != RightToLeftDirection))
274ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj    image->page.x=(ssize_t) (metrics.bounds.x1-draw_info->stroke_width/2.0);
275ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj  else
27657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    {
27757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj      (void) FormatLocaleString(geometry,MaxTextExtent,"%+g%+g",
27857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        -metrics.bounds.x1+draw_info->stroke_width/2.0,metrics.ascent+
27957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        draw_info->stroke_width/2.0);
280ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj      if (draw_info->direction == RightToLeftDirection)
281e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj        (void) FormatLocaleString(geometry,MaxTextExtent,"%+g%+g",
282ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj          image->columns-(metrics.bounds.x2+draw_info->stroke_width/2.0),
283ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj          metrics.ascent+draw_info->stroke_width/2.0);
284ba99931f6dfa264d7bc7c3845a46fc955ab56d93sewardj      draw_info->geometry=AcquireString(geometry);
285c97096c44637ae5775ed305b19f16f0b505f17d8sewardj    }
286c97096c44637ae5775ed305b19f16f0b505f17d8sewardj  status=AnnotateImage(image,draw_info,exception);
287c97096c44637ae5775ed305b19f16f0b505f17d8sewardj  draw_info=DestroyDrawInfo(draw_info);
288c97096c44637ae5775ed305b19f16f0b505f17d8sewardj  caption=DestroyString(caption);
2892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj  if (status == MagickFalse)
2902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj    {
291a58ea668d4725b87a146cf43cc48b8ea6ead84casewardj      image=DestroyImageList(image);
29217442fe8094d0f82266e5a05509f62cac8f7539esewardj      return((Image *) NULL);
29357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    }
294ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj  return(GetFirstImageInList(image));
295ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj}
296ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj
297ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj/*
29857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
299ba99931f6dfa264d7bc7c3845a46fc955ab56d93sewardj%                                                                             %
30017442fe8094d0f82266e5a05509f62cac8f7539esewardj%                                                                             %
30117442fe8094d0f82266e5a05509f62cac8f7539esewardj%                                                                             %
30217442fe8094d0f82266e5a05509f62cac8f7539esewardj%   R e g i s t e r C A P T I O N I m a g e                                   %
30317442fe8094d0f82266e5a05509f62cac8f7539esewardj%                                                                             %
3042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj%                                                                             %
3052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj%                                                                             %
30617442fe8094d0f82266e5a05509f62cac8f7539esewardj%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
30717442fe8094d0f82266e5a05509f62cac8f7539esewardj%
3081e6ad745ebafd0524da1da27a4b85524fa84f777sewardj%  RegisterCAPTIONImage() adds attributes for the CAPTION image format to
309c97096c44637ae5775ed305b19f16f0b505f17d8sewardj%  the list of supported formats.  The attributes include the image format
31057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%  tag, a method to read and/or write the format, whether the format
311dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj%  supports the saving of more than one frame to the same file or blob,
312695cff9303ef5dc8079117acfd632b44edb1f010sewardj%  whether the format supports native in-memory I/O, and a brief
31357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%  description of the format.
31435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj%
31557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%  The format of the RegisterCAPTIONImage method is:
31657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%
3174345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj%      size_t RegisterCAPTIONImage(void)
318ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj%
319c97096c44637ae5775ed305b19f16f0b505f17d8sewardj*/
3208ea867b06de73d909c29e243407713c291c8414esewardjModuleExport size_t RegisterCAPTIONImage(void)
3218ea867b06de73d909c29e243407713c291c8414esewardj{
3228ea867b06de73d909c29e243407713c291c8414esewardj  MagickInfo
32377352545d8416a36a4e6310aaea6b0205508aea2sewardj    *entry;
3248ea867b06de73d909c29e243407713c291c8414esewardj
32503d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj  entry=SetMagickInfo("CAPTION");
32603d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj  entry->decoder=(DecodeImageHandler *) ReadCAPTIONImage;
32703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj  entry->description=ConstantString("Caption");
32803d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj  entry->adjoin=MagickFalse;
32943c56461a667ca81fe29f1db01450d6ff1d62949sewardj  entry->module=ConstantString("CAPTION");
33043c56461a667ca81fe29f1db01450d6ff1d62949sewardj  (void) RegisterMagickInfo(entry);
33143c56461a667ca81fe29f1db01450d6ff1d62949sewardj  return(MagickImageCoderSignature);
33243c56461a667ca81fe29f1db01450d6ff1d62949sewardj}
33343c56461a667ca81fe29f1db01450d6ff1d62949sewardj
33443c56461a667ca81fe29f1db01450d6ff1d62949sewardj/*
33543c56461a667ca81fe29f1db01450d6ff1d62949sewardj%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3368ea867b06de73d909c29e243407713c291c8414esewardj%                                                                             %
3378ea867b06de73d909c29e243407713c291c8414esewardj%                                                                             %
3388ea867b06de73d909c29e243407713c291c8414esewardj%                                                                             %
3392d49b43ae3dd3756ed6a6d7a66b54c7bd7e03af6sewardj%   U n r e g i s t e r C A P T I O N I m a g e                               %
3402d49b43ae3dd3756ed6a6d7a66b54c7bd7e03af6sewardj%                                                                             %
3412d49b43ae3dd3756ed6a6d7a66b54c7bd7e03af6sewardj%                                                                             %
3422d49b43ae3dd3756ed6a6d7a66b54c7bd7e03af6sewardj%                                                                             %
3438ea867b06de73d909c29e243407713c291c8414esewardj%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3448ea867b06de73d909c29e243407713c291c8414esewardj%
3458ea867b06de73d909c29e243407713c291c8414esewardj%  UnregisterCAPTIONImage() removes format registrations made by the
34657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%  CAPTION module from the list of supported formats.
3472d49b43ae3dd3756ed6a6d7a66b54c7bd7e03af6sewardj%
3488ea867b06de73d909c29e243407713c291c8414esewardj%  The format of the UnregisterCAPTIONImage method is:
34957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj%
350dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj%      UnregisterCAPTIONImage(void)
3518ea867b06de73d909c29e243407713c291c8414esewardj%
35257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj*/
3538ea867b06de73d909c29e243407713c291c8414esewardjModuleExport void UnregisterCAPTIONImage(void)
3548ea867b06de73d909c29e243407713c291c8414esewardj{
3558ea867b06de73d909c29e243407713c291c8414esewardj  (void) UnregisterMagickInfo("CAPTION");
3562d3f77c12d2911173fd182d0b6e954196dee9135sewardj}
3572d3f77c12d2911173fd182d0b6e954196dee9135sewardj