X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=MagickCore%2Fannotate.c;h=378b994d1ac2b06b294804606677982da0f52952;hb=17f11b056210f082a6d0e54ac5d68e6d72fa76b2;hp=f2e2e23a1c793c8840ce0a293db293a2bb1e65ef;hpb=ec061ec752ff58a96a5de680b18e43fb8beea7c0;p=imagemagick diff --git a/MagickCore/annotate.c b/MagickCore/annotate.c index f2e2e23a1..378b994d1 100644 --- a/MagickCore/annotate.c +++ b/MagickCore/annotate.c @@ -13,11 +13,11 @@ % MagickCore Image Annotation Methods % % % % Software Design % -% John Cristy % +% Cristy % % July 1992 % % % % % -% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization % +% Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization % % dedicated to making software imaging solutions freely available. % % % % You may not use this file except in compliance with the License. You may % @@ -47,14 +47,17 @@ #include "MagickCore/annotate-private.h" #include "MagickCore/attribute.h" #include "MagickCore/cache-view.h" +#include "MagickCore/channel.h" #include "MagickCore/client.h" #include "MagickCore/color.h" #include "MagickCore/color-private.h" +#include "MagickCore/colorspace-private.h" #include "MagickCore/composite.h" #include "MagickCore/composite-private.h" #include "MagickCore/constitute.h" #include "MagickCore/draw.h" #include "MagickCore/draw-private.h" +#include "MagickCore/enhance.h" #include "MagickCore/exception.h" #include "MagickCore/exception-private.h" #include "MagickCore/gem.h" @@ -77,12 +80,10 @@ #include "MagickCore/xwindow.h" #include "MagickCore/xwindow-private.h" #if defined(MAGICKCORE_FREETYPE_DELEGATE) -#if defined(__MINGW32__) +#if defined(__MINGW32__) || defined(__MINGW64__) # undef interface #endif -#if defined(MAGICKCORE_HAVE_FT2BUILD_H) -# include -#endif +#include #if defined(FT_FREETYPE_H) # include FT_FREETYPE_H #else @@ -144,7 +145,8 @@ static MagickBooleanType */ MagickPrivate MagickBooleanType AnnotateComponentGenesis(void) { - AcquireSemaphoreInfo(&annotate_semaphore); + if (annotate_semaphore == (SemaphoreInfo *) NULL) + annotate_semaphore=AcquireSemaphoreInfo(); return(MagickTrue); } @@ -169,8 +171,8 @@ MagickPrivate MagickBooleanType AnnotateComponentGenesis(void) MagickPrivate void AnnotateComponentTerminus(void) { if (annotate_semaphore == (SemaphoreInfo *) NULL) - AcquireSemaphoreInfo(&annotate_semaphore); - DestroySemaphoreInfo(&annotate_semaphore); + ActivateSemaphoreInfo(&annotate_semaphore); + RelinquishSemaphoreInfo(&annotate_semaphore); } /* @@ -188,27 +190,53 @@ MagickPrivate void AnnotateComponentTerminus(void) % any of the following bits of information about the image by embedding % the appropriate special characters: % -% %b file size in bytes. -% %c comment. -% %d directory in which the image resides. -% %e extension of the image file. -% %f original filename of the image. -% %h height of image. -% %i filename of the image. -% %k number of unique colors. -% %l image label. -% %m image file format. -% %n number of images in a image sequence. -% %o output image filename. -% %p page number of the image. -% %q image depth (8 or 16). -% %q image depth (8 or 16). -% %s image scene number. -% %t image filename without any extension. -% %u a unique temporary filename. -% %w image width. -% %x x resolution of the image. -% %y y resolution of the image. +% \n newline +% \r carriage return +% < less-than character. +% > greater-than character. +% & ampersand character. +% %% a percent sign +% %b file size of image read in +% %c comment meta-data property +% %d directory component of path +% %e filename extension or suffix +% %f filename (including suffix) +% %g layer canvas page geometry (equivalent to "%Wx%H%X%Y") +% %h current image height in pixels +% %i image filename (note: becomes output filename for "info:") +% %k CALCULATED: number of unique colors +% %l label meta-data property +% %m image file format (file magic) +% %n number of images in current image sequence +% %o output filename (used for delegates) +% %p index of image in current image list +% %q quantum depth (compile-time constant) +% %r image class and colorspace +% %s scene number (from input unless re-assigned) +% %t filename without directory or extension (suffix) +% %u unique temporary filename (used for delegates) +% %w current width in pixels +% %x x resolution (density) +% %y y resolution (density) +% %z image depth (as read in unless modified, image save depth) +% %A image transparency channel enabled (true/false) +% %C image compression type +% %D image GIF dispose method +% %G original image size (%wx%h; before any resizes) +% %H page (canvas) height +% %M Magick filename (original file exactly as given, including read mods) +% %O page (canvas) offset ( = %X%Y ) +% %P page (canvas) size ( = %Wx%H ) +% %Q image compression quality ( 0 = default ) +% %S ?? scenes ?? +% %T image time delay (in centi-seconds) +% %U image resolution units +% %W page (canvas) width +% %X page (canvas) x offset (including sign) +% %Y page (canvas) y offset (including sign) +% %Z unique filename (used for delegates) +% %@ CALCULATED: trim bounding box (without actually trimming) +% %# CALCULATED: 'signature' hash of image values % % The format of the AnnotateImage method is: % @@ -290,6 +318,8 @@ MagickExport MagickBooleanType AnnotateImage(Image *image, } if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) return(MagickFalse); + if (IsGrayColorspace(image->colorspace) != MagickFalse) + (void) SetImageColorspace(image,sRGBColorspace,exception); status=MagickTrue; for (i=0; textlist[i] != (char *) NULL; i++) { @@ -356,7 +386,6 @@ MagickExport MagickBooleanType AnnotateImage(Image *image, (number_lines-1.0)*height)/2.0; break; } - case StaticGravity: case CenterGravity: { offset.x=(geometry.width == 0 ? -1.0 : 1.0)*annotate_info->affine.tx+ @@ -461,7 +490,7 @@ MagickExport MagickBooleanType AnnotateImage(Image *image, undercolor_info->affine.tx=offset.x-draw_info->affine.ry*metrics.ascent; undercolor_info->affine.ty=offset.y-draw_info->affine.sy*metrics.ascent; (void) FormatLocaleString(primitive,MaxTextExtent, - "rectangle 0,0 %g,%.20g",metrics.origin.x,(double) height); + "rectangle -0.5,-0.5 %g,%.20g",metrics.origin.x,(double) height); (void) CloneString(&undercolor_info->primitive,primitive); (void) DrawImage(image,undercolor_info,exception); (void) DestroyDrawInfo(undercolor_info); @@ -584,7 +613,7 @@ MagickExport ssize_t FormatMagickCaption(Image *image,DrawInfo *draw_info, status=GetTypeMetrics(image,draw_info,metrics,exception); if (status == MagickFalse) break; - width=(size_t) floor(metrics->width+0.5); + width=(size_t) floor(metrics->width+draw_info->stroke_width+0.5); if ((width <= image->columns) || (strcmp(text,draw_info->text) == 0)) continue; (void) strcpy(text,draw_info->text); @@ -1074,7 +1103,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, encoding_type; FT_Error - status; + ft_status; FT_Face face; @@ -1098,6 +1127,9 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, glyph, last_glyph; + MagickBooleanType + status; + PointInfo point, resolution; @@ -1125,8 +1157,8 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, /* Initialize Truetype library. */ - status=FT_Init_FreeType(&library); - if (status != 0) + ft_status=FT_Init_FreeType(&library); + if (ft_status != 0) ThrowBinaryException(TypeError,"UnableToInitializeFreetypeLibrary", image->filename); args.flags=FT_OPEN_PATHNAME; @@ -1138,9 +1170,9 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, else args.pathname=ConstantString(draw_info->font+1); face=(FT_Face) NULL; - status=FT_Open_Face(library,&args,(long) draw_info->face,&face); + ft_status=FT_Open_Face(library,&args,(long) draw_info->face,&face); args.pathname=DestroyString(args.pathname); - if (status != 0) + if (ft_status != 0) { (void) FT_Done_FreeType(library); (void) ThrowMagickException(exception,GetMagickModule(),TypeError, @@ -1151,9 +1183,9 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, (IsPathAccessible(draw_info->metrics) != MagickFalse)) (void) FT_Attach_File(face,draw_info->metrics); encoding_type=ft_encoding_unicode; - status=FT_Select_Charmap(face,encoding_type); - if ((status != 0) && (face->num_charmaps != 0)) - status=FT_Set_Charmap(face,face->charmaps[0]); + ft_status=FT_Select_Charmap(face,encoding_type); + if ((ft_status != 0) && (face->num_charmaps != 0)) + ft_status=FT_Set_Charmap(face,face->charmaps[0]); if (encoding != (const char *) NULL) { if (LocaleCompare(encoding,"AdobeCustom") == 0) @@ -1186,9 +1218,13 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, encoding_type=ft_encoding_unicode; if (LocaleCompare(encoding,"Wansung") == 0) encoding_type=ft_encoding_wansung; - status=FT_Select_Charmap(face,encoding_type); - if (status != 0) - ThrowBinaryException(TypeError,"UnrecognizedFontEncoding",encoding); + ft_status=FT_Select_Charmap(face,encoding_type); + if (ft_status != 0) + { + (void) FT_Done_Face(face); + (void) FT_Done_FreeType(library); + ThrowBinaryException(TypeError,"UnrecognizedFontEncoding",encoding); + } } /* Set text size. @@ -1209,7 +1245,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, if ((flags & SigmaValue) == 0) resolution.y=resolution.x; } - status=FT_Set_Char_Size(face,(FT_F26Dot6) (64.0*draw_info->pointsize), + ft_status=FT_Set_Char_Size(face,(FT_F26Dot6) (64.0*draw_info->pointsize), (FT_F26Dot6) (64.0*draw_info->pointsize),(FT_UInt) resolution.x, (FT_UInt) resolution.y); metrics->pixels_per_em.x=face->size->metrics.x_ppem; @@ -1246,6 +1282,16 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, draw_info->encoding != (char *) NULL ? draw_info->encoding : "none", draw_info->pointsize); flags=FT_LOAD_NO_BITMAP; + if (draw_info->text_antialias == MagickFalse) + flags|=FT_LOAD_TARGET_MONO; + else + { +#if defined(FT_LOAD_TARGET_LIGHT) + flags|=FT_LOAD_TARGET_LIGHT; +#elif defined(FT_LOAD_TARGET_LCD) + flags|=FT_LOAD_TARGET_LCD; +#endif + } value=GetImageProperty(image,"type:hinting",exception); if ((value != (const char *) NULL) && (LocaleCompare(value,"off") == 0)) flags|=FT_LOAD_NO_HINTING; @@ -1272,7 +1318,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, { if (image->storage_class != DirectClass) (void) SetImageStorageClass(image,DirectClass,exception); - if (image->matte == MagickFalse) + if (image->alpha_trait == UndefinedPixelTrait) (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception); } direction=1.0; @@ -1292,6 +1338,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, if (utf8 != (unsigned char *) NULL) p=(char *) utf8; } + status=MagickTrue; for (code=0; GetUTFCode(p) != 0; p+=GetUTFOctets(p)) { /* @@ -1302,30 +1349,28 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, glyph.id=FT_Get_Char_Index(face,'?'); if ((glyph.id != 0) && (last_glyph.id != 0)) { - if (fabs(draw_info->kerning) >= MagickEpsilon) - origin.x+=(FT_Pos) (64.0*direction*draw_info->kerning); - else - if (FT_HAS_KERNING(face)) - { - FT_Vector - kerning; + if (FT_HAS_KERNING(face)) + { + FT_Vector + kerning; - status=FT_Get_Kerning(face,last_glyph.id,glyph.id, - ft_kerning_default,&kerning); - if (status == 0) - origin.x+=(FT_Pos) (direction*kerning.x); - } - } + ft_status=FT_Get_Kerning(face,last_glyph.id,glyph.id, + ft_kerning_default,&kerning); + if (ft_status == 0) + origin.x+=(FT_Pos) (direction*kerning.x); + } + origin.x+=(FT_Pos) (64.0*direction*draw_info->kerning); + } glyph.origin=origin; - status=FT_Load_Glyph(face,glyph.id,flags); - if (status != 0) + ft_status=FT_Load_Glyph(face,glyph.id,flags); + if (ft_status != 0) continue; - status=FT_Get_Glyph(face->glyph,&glyph.image); - if (status != 0) + ft_status=FT_Get_Glyph(face->glyph,&glyph.image); + if (ft_status != 0) continue; - status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)->outline, + ft_status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)->outline, &bounds); - if (status != 0) + if (ft_status != 0) continue; if ((p == draw_info->text) || (bounds.xMin < metrics->bounds.x1)) metrics->bounds.x1=(double) bounds.xMin; @@ -1335,23 +1380,25 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, metrics->bounds.x2=(double) bounds.xMax; if ((p == draw_info->text) || (bounds.yMax > metrics->bounds.y2)) metrics->bounds.y2=(double) bounds.yMax; - if (draw_info->render != MagickFalse) - if ((draw_info->stroke.alpha != TransparentAlpha) || - (draw_info->stroke_pattern != (Image *) NULL)) - { - /* - Trace the glyph. - */ - annotate_info->affine.tx=glyph.origin.x/64.0; - annotate_info->affine.ty=glyph.origin.y/64.0; - (void) FT_Outline_Decompose(&((FT_OutlineGlyph) glyph.image)-> - outline,&OutlineMethods,annotate_info); + if ((draw_info->stroke.alpha != TransparentAlpha) || + (draw_info->stroke_pattern != (Image *) NULL)) + { + if ((status != MagickFalse) && (draw_info->render != MagickFalse)) + { + /* + Trace the glyph. + */ + annotate_info->affine.tx=glyph.origin.x/64.0; + annotate_info->affine.ty=glyph.origin.y/64.0; + (void) FT_Outline_Decompose(&((FT_OutlineGlyph) glyph.image)-> + outline,&OutlineMethods,annotate_info); + } } FT_Vector_Transform(&glyph.origin,&affine); (void) FT_Glyph_Transform(glyph.image,&affine,&glyph.origin); - status=FT_Glyph_To_Bitmap(&glyph.image,ft_render_mode_normal, + ft_status=FT_Glyph_To_Bitmap(&glyph.image,ft_render_mode_normal, (FT_Vector *) NULL,MagickTrue); - if (status != 0) + if (ft_status != 0) continue; bitmap=(FT_BitmapGlyph) glyph.image; point.x=offset->x+bitmap->left; @@ -1363,17 +1410,13 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, CacheView *image_view; - MagickBooleanType - status; - register unsigned char *p; /* Rasterize the glyph. */ - status=MagickTrue; - image_view=AcquireCacheView(image); + image_view=AcquireAuthenticCacheView(image,exception); p=bitmap->bitmap.buffer; for (y=0; y < (ssize_t) bitmap->bitmap.rows; y++) { @@ -1381,7 +1424,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, active, sync; - MagickRealType + double fill_opacity; PixelInfo @@ -1424,7 +1467,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, continue; } if (bitmap->bitmap.pixel_mode != ft_pixel_mode_mono) - fill_opacity=(MagickRealType) (p[n])/(bitmap->bitmap.num_grays-1); + fill_opacity=(double) (p[n])/(bitmap->bitmap.num_grays-1); else fill_opacity=((p[(x >> 3)+y*bitmap->bitmap.pitch] & (1 << (~x & 0x07)))) == 0 ? 0.0 : 1.0; @@ -1434,10 +1477,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, q=GetCacheViewAuthenticPixels(image_view,x_offset,y_offset,1,1, exception); if (q == (Quantum *) NULL) - { - q+=GetPixelChannels(image); - continue; - } + continue; GetPixelInfo(image,&fill_color); (void) GetFillColor(draw_info,x_offset,y_offset,&fill_color, exception); @@ -1480,7 +1520,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, if ((draw_info->stroke.alpha != TransparentAlpha) || (draw_info->stroke_pattern != (Image *) NULL)) { - if (draw_info->render != MagickFalse) + if ((status != MagickFalse) && (draw_info->render != MagickFalse)) { /* Draw text stroke. @@ -1497,19 +1537,19 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, */ glyph.id=FT_Get_Char_Index(face,'_'); glyph.origin=origin; - status=FT_Load_Glyph(face,glyph.id,flags); - if (status == 0) + ft_status=FT_Load_Glyph(face,glyph.id,flags); + if (ft_status == 0) { - status=FT_Get_Glyph(face->glyph,&glyph.image); - if (status == 0) + ft_status=FT_Get_Glyph(face->glyph,&glyph.image); + if (ft_status == 0) { - status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)-> + ft_status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)-> outline,&bounds); - if (status == 0) + if (ft_status == 0) { FT_Vector_Transform(&glyph.origin,&affine); (void) FT_Glyph_Transform(glyph.image,&affine,&glyph.origin); - status=FT_Glyph_To_Bitmap(&glyph.image,ft_render_mode_normal, + ft_status=FT_Glyph_To_Bitmap(&glyph.image,ft_render_mode_normal, (FT_Vector *) NULL,MagickTrue); bitmap=(FT_BitmapGlyph) glyph.image; if (bitmap->left > metrics->width) @@ -1519,6 +1559,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, FT_Done_Glyph(glyph.image); } metrics->width-=metrics->bounds.x1/64.0; + metrics->width+=annotate_info->stroke_width; metrics->bounds.x1/=64.0; metrics->bounds.y1/=64.0; metrics->bounds.x2/=64.0; @@ -1531,7 +1572,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, annotate_info=DestroyDrawInfo(annotate_info); (void) FT_Done_Face(face); (void) FT_Done_FreeType(library); - return(MagickTrue); + return(status); } #else static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, @@ -1539,9 +1580,9 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, TypeMetric *metrics,ExceptionInfo *exception) { (void) ThrowMagickException(exception,GetMagickModule(), - MissingDelegateWarning,"DelegateLibrarySupportNotBuiltIn","`%s' (Freetype)", + MissingDelegateWarning,"DelegateLibrarySupportNotBuiltIn","'%s' (Freetype)", draw_info->font != (char *) NULL ? draw_info->font : "none"); - return(RenderPostscript(image,draw_info,offset,metrics)); + return(RenderPostscript(image,draw_info,offset,metrics,exception)); } #endif @@ -1647,6 +1688,9 @@ static MagickBooleanType RenderPostscript(Image *image, register ssize_t i; + size_t + length; + ssize_t y; @@ -1683,7 +1727,8 @@ static MagickBooleanType RenderPostscript(Image *image, (fabs(draw_info->affine.ry) < MagickEpsilon) ? MagickTrue : MagickFalse; extent.x=0.0; extent.y=0.0; - for (i=0; i <= (ssize_t) (strlen(draw_info->text)+2); i++) + length=strlen(draw_info->text); + for (i=0; i <= (ssize_t) (length+2); i++) { point.x=fabs(draw_info->affine.sx*i*draw_info->pointsize+ draw_info->affine.ry*2.0*draw_info->pointsize); @@ -1732,6 +1777,7 @@ static MagickBooleanType RenderPostscript(Image *image, (void) RelinquishUniqueFileResource(filename); if (annotate_image == (Image *) NULL) return(MagickFalse); + (void) NegateImage(annotate_image,MagickFalse,exception); resolution.x=DefaultResolution; resolution.y=DefaultResolution; if (draw_info->density != (char *) NULL) @@ -1799,13 +1845,13 @@ static MagickBooleanType RenderPostscript(Image *image, /* Render fill color. */ - if (image->matte == MagickFalse) + if (image->alpha_trait == UndefinedPixelTrait) (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception); - if (annotate_image->matte == MagickFalse) + if (annotate_image->alpha_trait == UndefinedPixelTrait) (void) SetImageAlphaChannel(annotate_image,OpaqueAlphaChannel, exception); fill_color=draw_info->fill; - annotate_view=AcquireCacheView(annotate_image); + annotate_view=AcquireAuthenticCacheView(annotate_image,exception); for (y=0; y < (ssize_t) annotate_image->rows; y++) { register ssize_t @@ -1821,9 +1867,8 @@ static MagickBooleanType RenderPostscript(Image *image, for (x=0; x < (ssize_t) annotate_image->columns; x++) { (void) GetFillColor(draw_info,x,y,&fill_color,exception); - SetPixelAlpha(annotate_image,ClampToQuantum((((MagickRealType) - GetPixelIntensity(annotate_image,q)*fill_color.alpha)/ - QuantumRange)),q); + SetPixelAlpha(annotate_image,ClampToQuantum((((double) QuantumScale* + GetPixelIntensity(annotate_image,q)*fill_color.alpha))),q); SetPixelRed(annotate_image,fill_color.red,q); SetPixelGreen(annotate_image,fill_color.green,q); SetPixelBlue(annotate_image,fill_color.blue,q); @@ -1834,7 +1879,7 @@ static MagickBooleanType RenderPostscript(Image *image, break; } annotate_view=DestroyCacheView(annotate_view); - (void) CompositeImage(image,OverCompositeOp,annotate_image, + (void) CompositeImage(image,annotate_image,OverCompositeOp,MagickTrue, (ssize_t) ceil(offset->x-0.5),(ssize_t) ceil(offset->y-(metrics->ascent+ metrics->descent)-0.5),exception); } @@ -1874,214 +1919,16 @@ static MagickBooleanType RenderPostscript(Image *image, % o exception: return any errors or warnings in this structure. % */ -#if defined(MAGICKCORE_X11_DELEGATE) static MagickBooleanType RenderX11(Image *image,const DrawInfo *draw_info, const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception) { MagickBooleanType status; - static DrawInfo - cache_info; - - static Display - *display = (Display *) NULL; - - static XAnnotateInfo - annotate_info; - - static XFontStruct - *font_info; - - static XPixelInfo - pixel; - - static XResourceInfo - resource_info; - - static XrmDatabase - resource_database; - - static XStandardColormap - *map_info; - - static XVisualInfo - *visual_info; - - size_t - height, - width; - if (annotate_semaphore == (SemaphoreInfo *) NULL) - AcquireSemaphoreInfo(&annotate_semaphore); + ActivateSemaphoreInfo(&annotate_semaphore); LockSemaphoreInfo(annotate_semaphore); - if (display == (Display *) NULL) - { - const char - *client_name; - - ImageInfo - *image_info; - - /* - Open X server connection. - */ - display=XOpenDisplay(draw_info->server_name); - if (display == (Display *) NULL) - { - ThrowXWindowException(XServerError,"UnableToOpenXServer", - draw_info->server_name); - return(MagickFalse); - } - /* - Get user defaults from X resource database. - */ - (void) XSetErrorHandler(XError); - image_info=AcquireImageInfo(); - client_name=GetClientName(); - resource_database=XGetResourceDatabase(display,client_name); - XGetResourceInfo(image_info,resource_database,client_name,&resource_info); - resource_info.close_server=MagickFalse; - resource_info.colormap=PrivateColormap; - resource_info.font=AcquireString(draw_info->font); - resource_info.background_color=AcquireString("#ffffffffffff"); - resource_info.foreground_color=AcquireString("#000000000000"); - map_info=XAllocStandardColormap(); - if (map_info == (XStandardColormap *) NULL) - { - ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed", - image->filename); - return(MagickFalse); - } - /* - Initialize visual info. - */ - visual_info=XBestVisualInfo(display,map_info,&resource_info); - if (visual_info == (XVisualInfo *) NULL) - { - ThrowXWindowException(XServerError,"UnableToGetVisual", - image->filename); - return(MagickFalse); - } - map_info->colormap=(Colormap) NULL; - pixel.pixels=(unsigned long *) NULL; - /* - Initialize Standard Colormap info. - */ - XGetMapInfo(visual_info,XDefaultColormap(display,visual_info->screen), - map_info); - XGetPixelInfo(display,visual_info,map_info,&resource_info,(Image *) NULL, - &pixel); - pixel.annotate_context=XDefaultGC(display,visual_info->screen); - /* - Initialize font info. - */ - font_info=XBestFont(display,&resource_info,MagickFalse); - if (font_info == (XFontStruct *) NULL) - { - ThrowXWindowException(XServerError,"UnableToLoadFont", - draw_info->font); - return(MagickFalse); - } - if ((map_info == (XStandardColormap *) NULL) || - (visual_info == (XVisualInfo *) NULL) || - (font_info == (XFontStruct *) NULL)) - { - XFreeResources(display,visual_info,map_info,&pixel,font_info, - &resource_info,(XWindowInfo *) NULL); - ThrowXWindowException(XServerError,"UnableToLoadFont", - image->filename); - return(MagickFalse); - } - cache_info=(*draw_info); - } + status=XRenderImage(image,draw_info,offset,metrics,exception); UnlockSemaphoreInfo(annotate_semaphore); - /* - Initialize annotate info. - */ - XGetAnnotateInfo(&annotate_info); - annotate_info.stencil=ForegroundStencil; - if (cache_info.font != draw_info->font) - { - /* - Type name has changed. - */ - (void) XFreeFont(display,font_info); - (void) CloneString(&resource_info.font,draw_info->font); - font_info=XBestFont(display,&resource_info,MagickFalse); - if (font_info == (XFontStruct *) NULL) - { - ThrowXWindowException(XServerError,"UnableToLoadFont", - draw_info->font); - return(MagickFalse); - } - } - if (image->debug != MagickFalse) - (void) LogMagickEvent(AnnotateEvent,GetMagickModule(), - "Font %s; pointsize %g",draw_info->font != (char *) NULL ? - draw_info->font : "none",draw_info->pointsize); - cache_info=(*draw_info); - annotate_info.font_info=font_info; - annotate_info.text=(char *) draw_info->text; - annotate_info.width=(unsigned int) XTextWidth(font_info,draw_info->text, - (int) strlen(draw_info->text)); - annotate_info.height=(unsigned int) font_info->ascent+font_info->descent; - metrics->pixels_per_em.x=(double) font_info->max_bounds.width; - metrics->pixels_per_em.y=(double) font_info->ascent+font_info->descent; - metrics->ascent=(double) font_info->ascent+4; - metrics->descent=(double) (-font_info->descent); - metrics->width=annotate_info.width/ExpandAffine(&draw_info->affine); - metrics->height=font_info->ascent+font_info->descent; - metrics->max_advance=(double) font_info->max_bounds.width; - metrics->bounds.x1=0.0; - metrics->bounds.y1=metrics->descent; - metrics->bounds.x2=metrics->ascent+metrics->descent; - metrics->bounds.y2=metrics->ascent+metrics->descent; - metrics->underline_position=(-2.0); - metrics->underline_thickness=1.0; - if (draw_info->render == MagickFalse) - return(MagickTrue); - if (draw_info->fill.alpha == TransparentAlpha) - return(MagickTrue); - /* - Render fill color. - */ - width=annotate_info.width; - height=annotate_info.height; - if ((fabs(draw_info->affine.rx) >= MagickEpsilon) || - (fabs(draw_info->affine.ry) >= MagickEpsilon)) - { - if ((fabs(draw_info->affine.sx-draw_info->affine.sy) < MagickEpsilon) && - (fabs(draw_info->affine.rx+draw_info->affine.ry) < MagickEpsilon)) - annotate_info.degrees=(double) (180.0/MagickPI)* - atan2(draw_info->affine.rx,draw_info->affine.sx); - } - (void) FormatLocaleString(annotate_info.geometry,MaxTextExtent, - "%.20gx%.20g%+.20g%+.20g",(double) width,(double) height, - ceil(offset->x-0.5),ceil(offset->y-metrics->ascent-metrics->descent+ - draw_info->interline_spacing-0.5)); - pixel.pen_color.red=ScaleQuantumToShort(draw_info->fill.red); - pixel.pen_color.green=ScaleQuantumToShort(draw_info->fill.green); - pixel.pen_color.blue=ScaleQuantumToShort(draw_info->fill.blue); - status=XAnnotateImage(display,&pixel,&annotate_info,image,exception); - if (status == 0) - { - ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed", - image->filename); - return(MagickFalse); - } - return(MagickTrue); -} -#else -static MagickBooleanType RenderX11(Image *image,const DrawInfo *draw_info, - const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception) -{ - (void) draw_info; - (void) offset; - (void) metrics; - (void) ThrowMagickException(exception,GetMagickModule(), - MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (X11)", - image->filename); - return(MagickFalse); + return(status); } -#endif