~ubuntu-branches/ubuntu/oneiric/imagemagick/oneiric-updates

« back to all changes in this revision

Viewing changes to magick/annotate.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2011-06-15 11:05:28 UTC
  • mfrom: (6.2.11 sid)
  • Revision ID: james.westby@ubuntu.com-20110615110528-08jgo07a4846xh8d
Tags: 8:6.6.0.4-3ubuntu1
* Resynchronise with Debian (LP: #797595).  Remaining changes:
  - Make ufraw-batch (universe) a suggestion instead of a recommendation.
  - Make debian/rules install target depend on check; they cannot reliably
    be run in parallel.
  - Don't set MAKEFLAGS in debian/rules; just pass it to the build.

Show diffs side-by-side

added added

removed removed

Lines of Context:
181
181
  RectangleInfo
182
182
    geometry;
183
183
 
184
 
  register ssize_t
 
184
  register long
185
185
    i;
186
186
 
187
187
  size_t
190
190
  TypeMetric
191
191
    metrics;
192
192
 
193
 
  size_t
 
193
  unsigned long
194
194
    height,
195
195
    number_lines;
196
196
 
211
211
  for (i=1; textlist[i] != (char *) NULL; i++)
212
212
    if (strlen(textlist[i]) > length)
213
213
      length=strlen(textlist[i]);
214
 
  number_lines=(size_t) i;
 
214
  number_lines=(unsigned long) i;
215
215
  annotate=CloneDrawInfo((ImageInfo *) NULL,draw_info);
216
216
  annotate_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
217
217
  SetGeometry(image,&geometry);
234
234
    annotate_info->affine.ty=geometry_info.psi-image->page.y;
235
235
    (void) CloneString(&annotate->text,textlist[i]);
236
236
    (void) GetTypeMetrics(image,annotate,&metrics);
237
 
    height=(ssize_t) (metrics.ascent-metrics.descent+
 
237
    height=(long) (metrics.ascent-metrics.descent+
238
238
      draw_info->interline_spacing+0.5);
239
239
    switch (annotate->gravity)
240
240
    {
395
395
        undercolor_info->affine.tx=offset.x-draw_info->affine.ry*metrics.ascent;
396
396
        undercolor_info->affine.ty=offset.y-draw_info->affine.sy*metrics.ascent;
397
397
        (void) FormatMagickString(primitive,MaxTextExtent,
398
 
          "rectangle 0,0 %g,%.20g",metrics.origin.x,(double) height);
 
398
          "rectangle 0,0 %g,%lu",metrics.origin.x,height);
399
399
        (void) CloneString(&undercolor_info->primitive,primitive);
400
400
        (void) DrawImage(image,undercolor_info);
401
401
        (void) DestroyDrawInfo(undercolor_info);
460
460
%
461
461
%  The format of the FormatMagickCaption method is:
462
462
%
463
 
%      ssize_t FormatMagickCaption(Image *image,DrawInfo *draw_info,
 
463
%      long FormatMagickCaption(Image *image,DrawInfo *draw_info,
464
464
%        TypeMetric *metrics,char **caption)
465
465
%
466
466
%  A description of each parameter follows.
474
474
%    o metrics: Return the font metrics in this structure.
475
475
%
476
476
*/
477
 
MagickExport ssize_t FormatMagickCaption(Image *image,DrawInfo *draw_info,
 
477
MagickExport long FormatMagickCaption(Image *image,DrawInfo *draw_info,
478
478
  TypeMetric *metrics,char **caption)
479
479
{
480
480
  MagickBooleanType
485
485
    *q,
486
486
    *s;
487
487
 
488
 
  register ssize_t
 
488
  register long
489
489
    i;
490
490
 
491
 
  size_t
 
491
  unsigned long
492
492
    width;
493
493
 
494
494
  q=draw_info->text;
497
497
  {
498
498
    if (IsUTFSpace(GetUTFCode(p)) != MagickFalse)
499
499
      s=p;
500
 
    for (i=0; i < (ssize_t) GetUTFOctets(p); i++)
 
500
    for (i=0; i < (long) GetUTFOctets(p); i++)
501
501
      *q++=(*(p+i));
502
502
    *q='\0';
503
503
    status=GetTypeMetrics(image,draw_info,metrics);
504
504
    if (status == MagickFalse)
505
505
      break;
506
 
    width=(size_t) floor(metrics->width+0.5);
 
506
    width=(unsigned long) (metrics->width+0.5);
507
507
    if (GetUTFCode(p) != '\n')
508
508
      if (width <= image->columns)
509
509
        continue;
524
524
        char
525
525
          *target;
526
526
 
527
 
        ssize_t
 
527
        long
528
528
          n;
529
529
 
530
530
        /*
608
608
  MagickBooleanType
609
609
    status;
610
610
 
611
 
  register ssize_t
 
611
  register long
612
612
    i;
613
613
 
614
614
  TypeMetric
647
647
    if (extent.width > metrics->width)
648
648
      *metrics=extent;
649
649
  }
650
 
  metrics->height=(double) (i*(size_t) (metrics->ascent-
 
650
  metrics->height=(double) (i*(unsigned long) (metrics->ascent-
651
651
    metrics->descent+0.5)+(i-1)*draw_info->interline_spacing);
652
652
  /*
653
653
    Relinquish resources.
817
817
          TypeWarning,"UnableToReadFont","`%s'",draw_info->family);
818
818
    }
819
819
  if (type_info == (const TypeInfo *) NULL)
820
 
    type_info=GetTypeInfoByFamily("Arial",draw_info->style,
821
 
      draw_info->stretch,draw_info->weight,&image->exception);
822
 
  if (type_info == (const TypeInfo *) NULL)
823
 
    type_info=GetTypeInfoByFamily("Helvetica",draw_info->style,
824
 
      draw_info->stretch,draw_info->weight,&image->exception);
825
 
  if (type_info == (const TypeInfo *) NULL)
826
 
    type_info=GetTypeInfoByFamily("Century Schoolbook",draw_info->style,
 
820
    type_info=GetTypeInfoByFamily("arial",draw_info->style,
 
821
      draw_info->stretch,draw_info->weight,&image->exception);
 
822
  if (type_info == (const TypeInfo *) NULL)
 
823
    type_info=GetTypeInfoByFamily("helvetica",draw_info->style,
827
824
      draw_info->stretch,draw_info->weight,&image->exception);
828
825
  if (type_info == (const TypeInfo *) NULL)
829
826
    type_info=GetTypeInfoByFamily((const char *) NULL,draw_info->style,
830
827
      draw_info->stretch,draw_info->weight,&image->exception);
831
828
  if (type_info == (const TypeInfo *) NULL)
832
 
    type_info=GetTypeInfo("*",&image->exception);
833
 
  if (type_info == (const TypeInfo *) NULL)
834
829
    {
835
830
      status=RenderFreetype(image,draw_info,draw_info->encoding,offset,metrics);
836
831
      return(status);
880
875
*/
881
876
 
882
877
#if defined(MAGICKCORE_FREETYPE_DELEGATE)
883
 
 
884
878
static int TraceCubicBezier(FT_Vector *p,FT_Vector *q,FT_Vector *to,
885
879
  DrawInfo *draw_info)
886
880
{
968
962
  const char
969
963
    *value;
970
964
 
971
 
  double
972
 
    direction;
973
 
 
974
965
  DrawInfo
975
966
    *annotate_info;
976
967
 
1008
999
    glyph,
1009
1000
    last_glyph;
1010
1001
 
1011
 
  ssize_t
 
1002
  long
1012
1003
    code,
1013
1004
    y;
1014
1005
 
1029
1020
      0, 0
1030
1021
    };
1031
1022
 
1032
 
  unsigned char
1033
 
    *utf8;
1034
 
 
1035
1023
  /*
1036
1024
    Initialize Truetype library.
1037
1025
  */
1048
1036
    else
1049
1037
      args.pathname=ConstantString(draw_info->font+1);
1050
1038
  face=(FT_Face) NULL;
1051
 
  status=FT_Open_Face(library,&args,(long) draw_info->face,&face);
 
1039
  status=FT_Open_Face(library,&args,draw_info->face,&face);
1052
1040
  args.pathname=DestroyString(args.pathname);
1053
1041
  if (status != 0)
1054
1042
    {
1185
1173
      if (image->matte == MagickFalse)
1186
1174
        (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
1187
1175
    }
1188
 
  direction=1.0;
1189
 
  if (draw_info->direction == RightToLeftDirection)
1190
 
    direction=(-1.0);
1191
1176
  point.x=0.0;
1192
1177
  point.y=0.0;
 
1178
  code=0;
1193
1179
  for (p=draw_info->text; GetUTFCode(p) != 0; p+=GetUTFOctets(p))
1194
1180
    if (GetUTFCode(p) < 0)
1195
1181
      break;
1196
 
  utf8=(unsigned char *) NULL;
1197
1182
  if (GetUTFCode(p) == 0)
1198
 
    p=draw_info->text;
 
1183
    for (p=draw_info->text; GetUTFCode(p) != 0; p+=GetUTFOctets(p))
 
1184
    {
 
1185
      /*
 
1186
        Render UTF-8 sequence.
 
1187
      */
 
1188
      glyph.id=FT_Get_Char_Index(face,GetUTFCode(p));
 
1189
      if (glyph.id == 0)
 
1190
        glyph.id=FT_Get_Char_Index(face,'?');
 
1191
      if ((glyph.id != 0) && (last_glyph.id != 0))
 
1192
        {
 
1193
          if (draw_info->kerning != 0.0)
 
1194
            origin.x+=64.0*draw_info->kerning;
 
1195
          else
 
1196
            if (FT_HAS_KERNING(face))
 
1197
              {
 
1198
                FT_Vector
 
1199
                  kerning;
 
1200
 
 
1201
                status=FT_Get_Kerning(face,last_glyph.id,glyph.id,
 
1202
                  ft_kerning_default,&kerning);
 
1203
                if (status == 0)
 
1204
                  origin.x+=kerning.x;
 
1205
              }
 
1206
          }
 
1207
      glyph.origin=origin;
 
1208
      status=FT_Load_Glyph(face,glyph.id,flags);
 
1209
      if (status != 0)
 
1210
        continue;
 
1211
      status=FT_Get_Glyph(face->glyph,&glyph.image);
 
1212
      if (status != 0)
 
1213
        continue;
 
1214
      status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)->outline,
 
1215
        &bounds);
 
1216
      if (status != 0)
 
1217
        continue;
 
1218
      if ((p == draw_info->text) || (bounds.xMin < metrics->bounds.x1))
 
1219
        metrics->bounds.x1=bounds.xMin;
 
1220
      if ((p == draw_info->text) || (bounds.yMin < metrics->bounds.y1))
 
1221
        metrics->bounds.y1=bounds.yMin;
 
1222
      if ((p == draw_info->text) || (bounds.xMax > metrics->bounds.x2))
 
1223
        metrics->bounds.x2=bounds.xMax;
 
1224
      if ((p == draw_info->text) || (bounds.yMax > metrics->bounds.y2))
 
1225
        metrics->bounds.y2=bounds.yMax;
 
1226
      if (draw_info->render != MagickFalse)
 
1227
        if ((draw_info->stroke.opacity != TransparentOpacity) ||
 
1228
            (draw_info->stroke_pattern != (Image *) NULL))
 
1229
          {
 
1230
            /*
 
1231
              Trace the glyph.
 
1232
            */
 
1233
            annotate_info->affine.tx=glyph.origin.x/64.0;
 
1234
            annotate_info->affine.ty=glyph.origin.y/64.0;
 
1235
            (void) FT_Outline_Decompose(&((FT_OutlineGlyph) glyph.image)->
 
1236
              outline,&OutlineMethods,annotate_info);
 
1237
          }
 
1238
      FT_Vector_Transform(&glyph.origin,&affine);
 
1239
      (void) FT_Glyph_Transform(glyph.image,&affine,&glyph.origin);
 
1240
      status=FT_Glyph_To_Bitmap(&glyph.image,ft_render_mode_normal,
 
1241
        (FT_Vector *) NULL,MagickTrue);
 
1242
      if (status != 0)
 
1243
        continue;
 
1244
      bitmap=(FT_BitmapGlyph) glyph.image;
 
1245
      point.x=offset->x+bitmap->left;
 
1246
      point.y=offset->y-bitmap->top;
 
1247
      if (draw_info->render != MagickFalse)
 
1248
        {
 
1249
          CacheView
 
1250
            *image_view;
 
1251
 
 
1252
          ExceptionInfo
 
1253
            *exception;
 
1254
 
 
1255
          MagickBooleanType
 
1256
            status;
 
1257
 
 
1258
          /*
 
1259
            Rasterize the glyph.
 
1260
          */
 
1261
          status=MagickTrue;
 
1262
          exception=(&image->exception);
 
1263
          image_view=AcquireCacheView(image);
 
1264
          for (y=0; y < (long) bitmap->bitmap.rows; y++)
 
1265
          {
 
1266
            long
 
1267
              x_offset,
 
1268
              y_offset;
 
1269
 
 
1270
            MagickBooleanType
 
1271
              active,
 
1272
              sync;
 
1273
 
 
1274
            MagickRealType
 
1275
              fill_opacity;
 
1276
 
 
1277
            PixelPacket
 
1278
              fill_color;
 
1279
 
 
1280
            register long
 
1281
              x;
 
1282
 
 
1283
            register PixelPacket
 
1284
              *restrict q;
 
1285
 
 
1286
            register unsigned char
 
1287
              *p;
 
1288
 
 
1289
            if (status == MagickFalse)
 
1290
              continue;
 
1291
            x_offset=(long) (point.x+0.5);
 
1292
            y_offset=(long) (point.y+y+0.5);
 
1293
            if ((y_offset < 0) || (y_offset >= (long) image->rows))
 
1294
              continue;
 
1295
            q=(PixelPacket *) NULL;
 
1296
            if ((x_offset < 0) || (x_offset >= (long) image->columns))
 
1297
              active=MagickFalse;
 
1298
            else
 
1299
              {
 
1300
                q=GetCacheViewAuthenticPixels(image_view,x_offset,y_offset,
 
1301
                  bitmap->bitmap.width,1,exception);
 
1302
                active=q != (PixelPacket *) NULL ? MagickTrue : MagickFalse;
 
1303
              }
 
1304
            p=bitmap->bitmap.buffer+y*bitmap->bitmap.width;
 
1305
            for (x=0; x < (long) bitmap->bitmap.width; x++)
 
1306
            {
 
1307
              x_offset++;
 
1308
              if ((*p == 0) || (x_offset < 0) ||
 
1309
                  (x_offset >= (long) image->columns))
 
1310
                {
 
1311
                  p++;
 
1312
                  q++;
 
1313
                  continue;
 
1314
                }
 
1315
              fill_opacity=(MagickRealType) (*p)/(bitmap->bitmap.num_grays-1);
 
1316
              if (draw_info->text_antialias == MagickFalse)
 
1317
                fill_opacity=fill_opacity >= 0.5 ? 1.0 : 0.0;
 
1318
              if (active == MagickFalse)
 
1319
                q=GetCacheViewAuthenticPixels(image_view,x_offset,y_offset,1,1,
 
1320
                  exception);
 
1321
              if (q == (PixelPacket *) NULL)
 
1322
                {
 
1323
                  p++;
 
1324
                  q++;
 
1325
                  continue;
 
1326
                }
 
1327
              (void) GetFillColor(draw_info,x_offset,y_offset,&fill_color);
 
1328
              fill_opacity=QuantumRange-fill_opacity*(QuantumRange-
 
1329
                fill_color.opacity);
 
1330
              MagickCompositeOver(&fill_color,fill_opacity,q,q->opacity,q);
 
1331
              if (active == MagickFalse)
 
1332
                {
 
1333
                  sync=SyncCacheViewAuthenticPixels(image_view,exception);
 
1334
                  if (sync == MagickFalse)
 
1335
                    status=MagickFalse;
 
1336
                }
 
1337
              p++;
 
1338
              q++;
 
1339
            }
 
1340
            sync=SyncCacheViewAuthenticPixels(image_view,exception);
 
1341
            if (sync == MagickFalse)
 
1342
              status=MagickFalse;
 
1343
          }
 
1344
          image_view=DestroyCacheView(image_view);
 
1345
        }
 
1346
      if ((bitmap->left+bitmap->bitmap.width) > metrics->width)
 
1347
        metrics->width=bitmap->left+bitmap->bitmap.width;
 
1348
      if ((draw_info->interword_spacing != 0.0) &&
 
1349
          (IsUTFSpace(GetUTFCode(p)) != MagickFalse) &&
 
1350
          (IsUTFSpace(code) == MagickFalse))
 
1351
        origin.x+=64.0*draw_info->interword_spacing;
 
1352
      else
 
1353
        origin.x+=face->glyph->advance.x;
 
1354
      metrics->origin.x=origin.x;
 
1355
      metrics->origin.y=origin.y;
 
1356
      if (last_glyph.id != 0)
 
1357
        FT_Done_Glyph(last_glyph.image);
 
1358
      last_glyph=glyph;
 
1359
      code=GetUTFCode(p);
 
1360
    }
1199
1361
  else
 
1362
    for (p=draw_info->text; *p != 0; p++)
1200
1363
    {
1201
 
      utf8=ConvertLatin1ToUTF8((unsigned char *) draw_info->text);
1202
 
      if (utf8 != (unsigned char *) NULL)
1203
 
        p=(char *) utf8;
1204
 
    }
1205
 
  for (code=0; GetUTFCode(p) != 0; p+=GetUTFOctets(p))
1206
 
  {
1207
 
    /*
1208
 
      Render UTF-8 sequence.
1209
 
    */
1210
 
    glyph.id=FT_Get_Char_Index(face,GetUTFCode(p));
1211
 
    if (glyph.id == 0)
1212
 
      glyph.id=FT_Get_Char_Index(face,'?');
1213
 
    if ((glyph.id != 0) && (last_glyph.id != 0))
1214
 
      {
1215
 
        if (draw_info->kerning != 0.0)
1216
 
          origin.x+=64.0*direction*draw_info->kerning;
1217
 
        else
1218
 
          if (FT_HAS_KERNING(face))
1219
 
            {
1220
 
              FT_Vector
1221
 
                kerning;
1222
 
 
1223
 
              status=FT_Get_Kerning(face,last_glyph.id,glyph.id,
1224
 
                ft_kerning_default,&kerning);
1225
 
              if (status == 0)
1226
 
                origin.x+=direction*kerning.x;
1227
 
            }
1228
 
        }
1229
 
    glyph.origin=origin;
1230
 
    status=FT_Load_Glyph(face,glyph.id,flags);
1231
 
    if (status != 0)
1232
 
      continue;
1233
 
    status=FT_Get_Glyph(face->glyph,&glyph.image);
1234
 
    if (status != 0)
1235
 
      continue;
1236
 
    status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)->outline,
1237
 
      &bounds);
1238
 
    if (status != 0)
1239
 
      continue;
1240
 
    if ((p == draw_info->text) || (bounds.xMin < metrics->bounds.x1))
1241
 
      metrics->bounds.x1=bounds.xMin;
1242
 
    if ((p == draw_info->text) || (bounds.yMin < metrics->bounds.y1))
1243
 
      metrics->bounds.y1=bounds.yMin;
1244
 
    if ((p == draw_info->text) || (bounds.xMax > metrics->bounds.x2))
1245
 
      metrics->bounds.x2=bounds.xMax;
1246
 
    if ((p == draw_info->text) || (bounds.yMax > metrics->bounds.y2))
1247
 
      metrics->bounds.y2=bounds.yMax;
1248
 
    if (draw_info->render != MagickFalse)
1249
 
      if ((draw_info->stroke.opacity != TransparentOpacity) ||
1250
 
          (draw_info->stroke_pattern != (Image *) NULL))
1251
 
        {
 
1364
      /*
 
1365
        Render Latin-1 sequence.
 
1366
      */
 
1367
      glyph.id=FT_Get_Char_Index(face,(unsigned char) *p);
 
1368
      if (glyph.id == 0)
 
1369
        glyph.id=FT_Get_Char_Index(face,'?');
 
1370
      if ((glyph.id != 0) && (last_glyph.id != 0))
 
1371
        {
 
1372
          if (draw_info->kerning != 0.0)
 
1373
            origin.x+=64.0*draw_info->kerning;
 
1374
          else
 
1375
            if (FT_HAS_KERNING(face))
 
1376
              {
 
1377
                FT_Vector
 
1378
                  kerning;
 
1379
 
 
1380
                status=FT_Get_Kerning(face,last_glyph.id,glyph.id,
 
1381
                  ft_kerning_default,&kerning);
 
1382
                if (status == 0)
 
1383
                  origin.x+=kerning.x;
 
1384
              }
 
1385
          }
 
1386
      glyph.origin=origin;
 
1387
      status=FT_Load_Glyph(face,glyph.id,flags);
 
1388
      if (status != 0)
 
1389
        continue;
 
1390
      status=FT_Get_Glyph(face->glyph,&glyph.image);
 
1391
      if (status != 0)
 
1392
        continue;
 
1393
      status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)->outline,
 
1394
        &bounds);
 
1395
      if (status != 0)
 
1396
        continue;
 
1397
      if ((p == draw_info->text) || (bounds.xMin < metrics->bounds.x1))
 
1398
        metrics->bounds.x1=bounds.xMin;
 
1399
      if ((p == draw_info->text) || (bounds.yMin < metrics->bounds.y1))
 
1400
        metrics->bounds.y1=bounds.yMin;
 
1401
      if ((p == draw_info->text) || (bounds.xMax > metrics->bounds.x2))
 
1402
        metrics->bounds.x2=bounds.xMax;
 
1403
      if ((p == draw_info->text) || (bounds.yMax > metrics->bounds.y2))
 
1404
        metrics->bounds.y2=bounds.yMax;
 
1405
      if (draw_info->render != MagickFalse)
 
1406
        if ((draw_info->stroke.opacity != TransparentOpacity) ||
 
1407
            (draw_info->stroke_pattern != (Image *) NULL))
 
1408
          {
 
1409
            /*
 
1410
              Trace the glyph.
 
1411
            */
 
1412
            annotate_info->affine.tx=glyph.origin.x/64.0;
 
1413
            annotate_info->affine.ty=glyph.origin.y/64.0;
 
1414
            (void) FT_Outline_Decompose(&((FT_OutlineGlyph) glyph.image)->
 
1415
              outline,&OutlineMethods,annotate_info);
 
1416
          }
 
1417
      FT_Vector_Transform(&glyph.origin,&affine);
 
1418
      (void) FT_Glyph_Transform(glyph.image,&affine,&glyph.origin);
 
1419
      status=FT_Glyph_To_Bitmap(&glyph.image,ft_render_mode_normal,
 
1420
        (FT_Vector *) NULL,MagickTrue);
 
1421
      if (status != 0)
 
1422
        continue;
 
1423
      bitmap=(FT_BitmapGlyph) glyph.image;
 
1424
      point.x=offset->x+bitmap->left;
 
1425
      point.y=offset->y-bitmap->top;
 
1426
      if (draw_info->render != MagickFalse)
 
1427
        {
 
1428
          CacheView
 
1429
            *image_view;
 
1430
 
 
1431
          ExceptionInfo
 
1432
            *exception;
 
1433
 
 
1434
          MagickBooleanType
 
1435
            status;
 
1436
 
1252
1437
          /*
1253
 
            Trace the glyph.
 
1438
            Rasterize the glyph.
1254
1439
          */
1255
 
          annotate_info->affine.tx=glyph.origin.x/64.0;
1256
 
          annotate_info->affine.ty=glyph.origin.y/64.0;
1257
 
          (void) FT_Outline_Decompose(&((FT_OutlineGlyph) glyph.image)->
1258
 
            outline,&OutlineMethods,annotate_info);
1259
 
        }
1260
 
    FT_Vector_Transform(&glyph.origin,&affine);
1261
 
    (void) FT_Glyph_Transform(glyph.image,&affine,&glyph.origin);
1262
 
    status=FT_Glyph_To_Bitmap(&glyph.image,ft_render_mode_normal,
1263
 
      (FT_Vector *) NULL,MagickTrue);
1264
 
    if (status != 0)
1265
 
      continue;
1266
 
    bitmap=(FT_BitmapGlyph) glyph.image;
1267
 
    point.x=offset->x+bitmap->left;
1268
 
    point.y=offset->y-bitmap->top;
1269
 
    if (draw_info->render != MagickFalse)
1270
 
      {
1271
 
        CacheView
1272
 
          *image_view;
1273
 
 
1274
 
        ExceptionInfo
1275
 
          *exception;
1276
 
 
1277
 
        MagickBooleanType
1278
 
          status;
1279
 
 
1280
 
        /*
1281
 
          Rasterize the glyph.
1282
 
        */
1283
 
        status=MagickTrue;
1284
 
        exception=(&image->exception);
1285
 
        image_view=AcquireCacheView(image);
1286
 
        for (y=0; y < (ssize_t) bitmap->bitmap.rows; y++)
1287
 
        {
1288
 
          MagickBooleanType
1289
 
            active,
1290
 
            sync;
1291
 
 
1292
 
          MagickRealType
1293
 
            fill_opacity;
1294
 
 
1295
 
          PixelPacket
1296
 
            fill_color;
1297
 
 
1298
 
          register ssize_t
1299
 
            x;
1300
 
 
1301
 
          register PixelPacket
1302
 
            *restrict q;
1303
 
 
1304
 
          register unsigned char
1305
 
            *p;
1306
 
 
1307
 
          ssize_t
1308
 
            x_offset,
1309
 
            y_offset;
1310
 
 
1311
 
          if (status == MagickFalse)
1312
 
            continue;
1313
 
          x_offset=(ssize_t) ceil(point.x-0.5);
1314
 
          y_offset=(ssize_t) ceil(point.y+y-0.5);
1315
 
          if ((y_offset < 0) || (y_offset >= (ssize_t) image->rows))
1316
 
            continue;
1317
 
          q=(PixelPacket *) NULL;
1318
 
          if ((x_offset < 0) || (x_offset >= (ssize_t) image->columns))
1319
 
            active=MagickFalse;
1320
 
          else
 
1440
          status=MagickTrue;
 
1441
          exception=(&image->exception);
 
1442
          image_view=AcquireCacheView(image);
 
1443
          for (y=0; y < (long) bitmap->bitmap.rows; y++)
 
1444
          {
 
1445
            long
 
1446
              x_offset,
 
1447
              y_offset;
 
1448
 
 
1449
            MagickBooleanType
 
1450
              active,
 
1451
              sync;
 
1452
 
 
1453
            MagickRealType
 
1454
              fill_opacity;
 
1455
 
 
1456
            PixelPacket
 
1457
              fill_color;
 
1458
 
 
1459
            register long
 
1460
              x;
 
1461
 
 
1462
            register PixelPacket
 
1463
              *restrict q;
 
1464
 
 
1465
            register unsigned char
 
1466
              *p;
 
1467
 
 
1468
            if (status == MagickFalse)
 
1469
              continue;
 
1470
            x_offset=(long) (point.x+0.5);
 
1471
            y_offset=(long) (point.y+y+0.5);
 
1472
            if ((y_offset < 0) || (y_offset >= (long) image->rows))
 
1473
              continue;
 
1474
            q=(PixelPacket *) NULL;
 
1475
            if ((x_offset < 0) || (x_offset >= (long) image->columns))
 
1476
              active=MagickFalse;
 
1477
            else
 
1478
              {
 
1479
                q=GetCacheViewAuthenticPixels(image_view,x_offset,y_offset,
 
1480
                  bitmap->bitmap.width,1,exception);
 
1481
                active=q != (PixelPacket *) NULL ? MagickTrue : MagickFalse;
 
1482
              }
 
1483
            p=bitmap->bitmap.buffer+y*bitmap->bitmap.width;
 
1484
            for (x=0; x < (long) bitmap->bitmap.width; x++)
1321
1485
            {
1322
 
              q=GetCacheViewAuthenticPixels(image_view,x_offset,y_offset,
1323
 
                bitmap->bitmap.width,1,exception);
1324
 
              active=q != (PixelPacket *) NULL ? MagickTrue : MagickFalse;
 
1486
              x_offset++;
 
1487
              if ((*p == 0) || (x_offset < 0) ||
 
1488
                  (x_offset >= (long) image->columns))
 
1489
                {
 
1490
                  p++;
 
1491
                  q++;
 
1492
                  continue;
 
1493
                }
 
1494
              fill_opacity=(MagickRealType) (*p)/(bitmap->bitmap.num_grays-1);
 
1495
              if (draw_info->text_antialias == MagickFalse)
 
1496
                fill_opacity=fill_opacity >= 0.5 ? 1.0 : 0.0;
 
1497
              if (active == MagickFalse)
 
1498
                q=GetCacheViewAuthenticPixels(image_view,x_offset,y_offset,1,1,
 
1499
                  exception);
 
1500
              if (q == (PixelPacket *) NULL)
 
1501
                {
 
1502
                  p++;
 
1503
                  q++;
 
1504
                  continue;
 
1505
                }
 
1506
              (void) GetFillColor(draw_info,x_offset,y_offset,&fill_color);
 
1507
              fill_opacity=QuantumRange-fill_opacity*(QuantumRange-
 
1508
                fill_color.opacity);
 
1509
              MagickCompositeOver(&fill_color,fill_opacity,q,q->opacity,q);
 
1510
              if (active == MagickFalse)
 
1511
                {
 
1512
                  sync=SyncCacheViewAuthenticPixels(image_view,exception);
 
1513
                  if (sync == MagickFalse)
 
1514
                    status=MagickFalse;
 
1515
                }
 
1516
              p++;
 
1517
              q++;
1325
1518
            }
1326
 
          p=bitmap->bitmap.buffer+y*bitmap->bitmap.width;
1327
 
          for (x=0; x < (ssize_t) bitmap->bitmap.width; x++)
1328
 
          {
1329
 
            x_offset++;
1330
 
            if ((*p == 0) || (x_offset < 0) ||
1331
 
                (x_offset >= (ssize_t) image->columns))
1332
 
              {
1333
 
                p++;
1334
 
                q++;
1335
 
                continue;
1336
 
              }
1337
 
            fill_opacity=(MagickRealType) (*p)/(bitmap->bitmap.num_grays-1);
1338
 
            if (draw_info->text_antialias == MagickFalse)
1339
 
              fill_opacity=fill_opacity >= 0.5 ? 1.0 : 0.0;
1340
 
            if (active == MagickFalse)
1341
 
              q=GetCacheViewAuthenticPixels(image_view,x_offset,y_offset,1,1,
1342
 
                exception);
1343
 
            if (q == (PixelPacket *) NULL)
1344
 
              {
1345
 
                p++;
1346
 
                q++;
1347
 
                continue;
1348
 
              }
1349
 
            (void) GetFillColor(draw_info,x_offset,y_offset,&fill_color);
1350
 
            fill_opacity=QuantumRange-fill_opacity*(QuantumRange-
1351
 
              fill_color.opacity);
1352
 
            MagickCompositeOver(&fill_color,fill_opacity,q,q->opacity,q);
1353
 
            if (active == MagickFalse)
1354
 
              {
1355
 
                sync=SyncCacheViewAuthenticPixels(image_view,exception);
1356
 
                if (sync == MagickFalse)
1357
 
                  status=MagickFalse;
1358
 
              }
1359
 
            p++;
1360
 
            q++;
 
1519
            sync=SyncCacheViewAuthenticPixels(image_view,exception);
 
1520
            if (sync == MagickFalse)
 
1521
              status=MagickFalse;
1361
1522
          }
1362
 
          sync=SyncCacheViewAuthenticPixels(image_view,exception);
1363
 
          if (sync == MagickFalse)
1364
 
            status=MagickFalse;
 
1523
          image_view=DestroyCacheView(image_view);
1365
1524
        }
1366
 
        image_view=DestroyCacheView(image_view);
1367
 
      }
1368
 
    if ((bitmap->left+bitmap->bitmap.width) > metrics->width)
1369
 
      metrics->width=bitmap->left+bitmap->bitmap.width;
1370
 
    if ((draw_info->interword_spacing != 0.0) &&
1371
 
        (IsUTFSpace(GetUTFCode(p)) != MagickFalse) &&
1372
 
        (IsUTFSpace(code) == MagickFalse))
1373
 
      origin.x+=64.0*direction*draw_info->interword_spacing;
1374
 
    else
1375
 
      origin.x+=direction*face->glyph->advance.x;
1376
 
    metrics->origin.x=origin.x;
1377
 
    metrics->origin.y=origin.y;
1378
 
    if (last_glyph.id != 0)
1379
 
      FT_Done_Glyph(last_glyph.image);
1380
 
    last_glyph=glyph;
1381
 
    code=GetUTFCode(p);
1382
 
  }
1383
 
  if (utf8 != (unsigned char *) NULL)
1384
 
    utf8=(unsigned char *) RelinquishMagickMemory(utf8);
 
1525
      if ((bitmap->left+bitmap->bitmap.width) > metrics->width)
 
1526
        metrics->width=bitmap->left+bitmap->bitmap.width;
 
1527
      if ((draw_info->interword_spacing != 0.0) &&
 
1528
          (isspace((int) ((unsigned char) *p)) != 0) &&
 
1529
          (isspace((int) code) == 0))
 
1530
        origin.x+=64.0*draw_info->interword_spacing;
 
1531
      else
 
1532
        origin.x+=face->glyph->advance.x;
 
1533
      metrics->origin.x=origin.x;
 
1534
      metrics->origin.y=origin.y;
 
1535
      if (last_glyph.id != 0)
 
1536
        FT_Done_Glyph(last_glyph.image);
 
1537
      last_glyph=glyph;
 
1538
      code=(*p);
 
1539
    }
1385
1540
  if (last_glyph.id != 0)
1386
1541
    FT_Done_Glyph(last_glyph.image);
1387
1542
  if ((draw_info->stroke.opacity != TransparentOpacity) ||
1499
1654
  register char
1500
1655
    *p;
1501
1656
 
1502
 
  register ssize_t
 
1657
  register long
1503
1658
    i;
1504
1659
 
1505
1660
  size_t
1508
1663
  escapes=0;
1509
1664
  buffer=AcquireString(text);
1510
1665
  p=buffer;
1511
 
  for (i=0; i < (ssize_t) MagickMin(strlen(text),MaxTextExtent-escapes-1); i++)
 
1666
  for (i=0; i < (long) MagickMin(strlen(text),MaxTextExtent-escapes-1); i++)
1512
1667
  {
1513
1668
    if ((text[i] == '(') || (text[i] == ')'))
1514
1669
      {
1541
1696
  int
1542
1697
    unique_file;
1543
1698
 
1544
 
  ssize_t
 
1699
  long
1545
1700
    y;
1546
1701
 
1547
1702
  MagickBooleanType
1552
1707
    point,
1553
1708
    resolution;
1554
1709
 
1555
 
  register ssize_t
 
1710
  register long
1556
1711
    i;
1557
1712
 
1558
1713
  /*
1589
1744
    MagickTrue : MagickFalse;
1590
1745
  extent.x=0.0;
1591
1746
  extent.y=0.0;
1592
 
  for (i=0; i <= (ssize_t) (strlen(draw_info->text)+2); i++)
 
1747
  for (i=0; i <= (long) (strlen(draw_info->text)+2); i++)
1593
1748
  {
1594
1749
    point.x=fabs(draw_info->affine.sx*i*draw_info->pointsize+
1595
1750
      draw_info->affine.ry*2.0*draw_info->pointsize);
1621
1776
  text=DestroyString(text);
1622
1777
  (void) fprintf(file,"showpage\n");
1623
1778
  (void) fclose(file);
1624
 
  (void) FormatMagickString(geometry,MaxTextExtent,"%.20gx%.20g+0+0!",
1625
 
    floor(extent.x+0.5),floor(extent.y+0.5));
 
1779
  (void) FormatMagickString(geometry,MaxTextExtent,"%ldx%ld+0+0!",(long)
 
1780
    (extent.x+0.5),(long) (extent.y+0.5));
1626
1781
  annotate_info=AcquireImageInfo();
1627
1782
  (void) FormatMagickString(annotate_info->filename,MaxTextExtent,"ps:%s",
1628
1783
    filename);
1660
1815
        crop_info;
1661
1816
 
1662
1817
      crop_info=GetImageBoundingBox(annotate_image,&annotate_image->exception);
1663
 
      crop_info.height=(size_t) ((resolution.y/DefaultResolution)*
 
1818
      crop_info.height=(unsigned long) ((resolution.y/DefaultResolution)*
1664
1819
        ExpandAffine(&draw_info->affine)*draw_info->pointsize+0.5);
1665
 
      crop_info.y=(ssize_t) ceil((resolution.y/DefaultResolution)*extent.y/8.0-
1666
 
        0.5);
1667
 
      (void) FormatMagickString(geometry,MaxTextExtent,
1668
 
        "%.20gx%.20g%+.20g%+.20g",(double) crop_info.width,(double)
1669
 
        crop_info.height,(double) crop_info.x,(double) crop_info.y);
 
1820
      crop_info.y=(long) ((resolution.y/DefaultResolution)*extent.y/8.0+0.5);
 
1821
      (void) FormatMagickString(geometry,MaxTextExtent,"%lux%lu%+ld%+ld",
 
1822
        crop_info.width,crop_info.height,crop_info.x,crop_info.y);
1670
1823
      (void) TransformImage(&annotate_image,geometry,(char *) NULL);
1671
1824
    }
1672
1825
  metrics->pixels_per_em.x=(resolution.y/DefaultResolution)*
1713
1866
      fill_color=draw_info->fill;
1714
1867
      exception=(&image->exception);
1715
1868
      annotate_view=AcquireCacheView(annotate_image);
1716
 
      for (y=0; y < (ssize_t) annotate_image->rows; y++)
 
1869
      for (y=0; y < (long) annotate_image->rows; y++)
1717
1870
      {
1718
 
        register ssize_t
 
1871
        register long
1719
1872
          x;
1720
1873
 
1721
1874
        register PixelPacket
1725
1878
          1,exception);
1726
1879
        if (q == (PixelPacket *) NULL)
1727
1880
          break;
1728
 
        for (x=0; x < (ssize_t) annotate_image->columns; x++)
 
1881
        for (x=0; x < (long) annotate_image->columns; x++)
1729
1882
        {
1730
1883
          (void) GetFillColor(draw_info,x,y,&fill_color);
1731
1884
          q->opacity=ClampToQuantum(QuantumRange-(((QuantumRange-
1742
1895
      }
1743
1896
      annotate_view=DestroyCacheView(annotate_view);
1744
1897
      (void) CompositeImage(image,OverCompositeOp,annotate_image,
1745
 
        (ssize_t) ceil(offset->x-0.5),(ssize_t) ceil(offset->y-(metrics->ascent+
1746
 
        metrics->descent)-0.5));
 
1898
        (long) (offset->x+0.5),(long) (offset->y-(metrics->ascent+
 
1899
        metrics->descent)+0.5));
1747
1900
    }
1748
1901
  annotate_image=DestroyImage(annotate_image);
1749
1902
  return(MagickTrue);
1813
1966
  static XVisualInfo
1814
1967
    *visual_info;
1815
1968
 
1816
 
  size_t
 
1969
  unsigned long
1817
1970
    height,
1818
1971
    width;
1819
1972
 
1957
2110
          atan2(draw_info->affine.rx,draw_info->affine.sx);
1958
2111
    }
1959
2112
  (void) FormatMagickString(annotate_info.geometry,MaxTextExtent,
1960
 
    "%.20gx%.20g%+.20g%+.20g",(double) width,(double) height,
1961
 
    ceil(offset->x-0.5),ceil(offset->y-metrics->ascent-metrics->descent+
1962
 
    draw_info->interline_spacing-0.5));
 
2113
    "%lux%lu+%ld+%ld",width,height,(long) (offset->x+0.5),
 
2114
    (long) (offset->y-metrics->ascent-metrics->descent+
 
2115
    draw_info->interline_spacing+0.5));
1963
2116
  pixel.pen_color.red=ScaleQuantumToShort(draw_info->fill.red);
1964
2117
  pixel.pen_color.green=ScaleQuantumToShort(draw_info->fill.green);
1965
2118
  pixel.pen_color.blue=ScaleQuantumToShort(draw_info->fill.blue);