Method: Magick::Draw#annotate

Defined in:
ext/RMagick/rmdraw.c

#annotate(image_arg, width_arg, height_arg, x_arg, y_arg, text) ⇒ Magick::Draw

Annotates an image with text.

  • Additional Draw attribute methods may be called in the optional block, which is executed in the context of an Draw object.



816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
# File 'ext/RMagick/rmdraw.c', line 816

VALUE Draw_annotate(
                   VALUE self,
                   VALUE image_arg,
                   VALUE width_arg,
                   VALUE height_arg,
                   VALUE x_arg,
                   VALUE y_arg,
                   VALUE text)
{
    Draw *draw;
    Image *image;
    unsigned long width, height;
    long x, y;
    AffineMatrix keep;
    char geometry_str[100];
    char *embed_text;
#if defined(IMAGEMAGICK_7)
    ExceptionInfo *exception;
#endif

    // Save the affine matrix in case it is modified by
    // Draw#rotation=
    TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
    keep = draw->info->affine;

    image_arg = rm_cur_image(image_arg);
    image = rm_check_frozen(image_arg);

    // If we have an optional parm block, run it in self's context,
    // allowing the app a chance to modify the object's attributes
    if (rb_block_given_p())
    {
        rb_yield(self);
    }

    // Translate & store in Draw structure
    embed_text = StringValueCStr(text);
#if defined(IMAGEMAGICK_7)
    exception = AcquireExceptionInfo();
    draw->info->text = InterpretImageProperties(NULL, image, embed_text, exception);
    if (rm_should_raise_exception(exception, RetainExceptionRetention))
    {
        if (draw->info->text)
        {
            magick_free(draw->info->text);
        }
        rm_raise_exception(exception);
    }
#else
    draw->info->text = InterpretImageProperties(NULL, image, embed_text);
#endif
    if (!draw->info->text)
    {
#if defined(IMAGEMAGICK_7)
        DestroyExceptionInfo(exception);
#endif
        rb_raise(rb_eArgError, "no text");
    }

    // Create geometry string, copy to Draw structure, overriding
    // any previously existing value.
    width  = NUM2ULONG(width_arg);
    height = NUM2ULONG(height_arg);
    x      = NUM2LONG(x_arg);
    y      = NUM2LONG(y_arg);

    if (width == 0 && height == 0)
    {
        snprintf(geometry_str, sizeof(geometry_str), "%+ld%+ld", x, y);
    }

    // WxH is non-zero
    else
    {
        snprintf(geometry_str, sizeof(geometry_str), "%lux%lu%+ld%+ld", width, height, x, y);
    }

    magick_clone_string(&draw->info->geometry, geometry_str);

#if defined(IMAGEMAGICK_7)
    GVL_STRUCT_TYPE(AnnotateImage) args = { image, draw->info, exception };
#else
    GVL_STRUCT_TYPE(AnnotateImage) args = { image, draw->info };
#endif
    CALL_FUNC_WITHOUT_GVL(GVL_FUNC(AnnotateImage), &args);

    magick_free(draw->info->text);
    draw->info->text = NULL;
    draw->info->affine = keep;

#if defined(IMAGEMAGICK_7)
    CHECK_EXCEPTION();
    DestroyExceptionInfo(exception);
#else
    rm_check_image_exception(image, RetainOnError);
#endif

    return self;
}