[q-lang-cvs] q/modules/magick magick.c,1.30,1.31 magick.q,1.28,1.29
Brought to you by:
agraef
From: <ag...@us...> - 2003-12-31 05:37:55
|
Update of /cvsroot/q-lang/q/modules/magick In directory sc8-pr-cvs1:/tmp/cvs-serv15199 Modified Files: magick.c magick.q Log Message: added draw info stuff, finishing touches Index: magick.c =================================================================== RCS file: /cvsroot/q-lang/q/modules/magick/magick.c,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** magick.c 31 Dec 2003 01:47:52 -0000 1.30 --- magick.c 31 Dec 2003 05:37:52 -0000 1.31 *************** *** 124,127 **** --- 124,147 ---- } + static inline expr mkbool(int val) + { + if (val) + return mktrue; + else + return mkfalse; + } + + static inline int isbool(expr x, int *val) + { + if (istrue(x)) { + *val = 1; + return 1; + } else if (isfalse(x)) { + *val = 0; + return 1; + } else + return 0; + } + /* ByteStr data structure, see clib.c */ *************** *** 137,141 **** if (argc != 0) return __FAIL; return mktuplel ! (61, mkuint(NoCompression), mkuint(BZipCompression), --- 157,161 ---- if (argc != 0) return __FAIL; return mktuplel ! (72, mkuint(NoCompression), mkuint(BZipCompression), *************** *** 148,151 **** --- 168,183 ---- mkuint(ZipCompression), + mkuint(ForgetGravity), + mkuint(NorthWestGravity), + mkuint(NorthGravity), + mkuint(NorthEastGravity), + mkuint(WestGravity), + mkuint(CenterGravity), + mkuint(EastGravity), + mkuint(SouthWestGravity), + mkuint(SouthGravity), + mkuint(SouthEastGravity), + mkuint(StaticGravity), + mkuint(PointFilter), mkuint(BoxFilter), *************** *** 469,472 **** --- 501,515 ---- } + static inline expr mkpixel(PixelPacket *pixel) + { + bstr_t *m; + if (!(m = malloc(sizeof(bstr_t))) || !(m->v = malloc(8))) { + if (m) free(m); return __ERROR; + } + m->size = 8; + get_pixels(m->v, pixel, 1, 1); + return mkobj(type(ByteStr), m); + } + /* parse info tuples */ *************** *** 538,541 **** --- 581,793 ---- } + FUNCTION(magick,draw_info,argc,argv) + { + Image *img; + DrawInfo *draw_info; + if (argc == 1 && isobj(argv[0], type(Image), (void**)&img) && + (draw_info = get_draw_info(img))) { + expr font, tile; + if (draw_info->font) + font = mkstr(strdup(draw_info->font)); + else + font = mkvoid; + if (draw_info->tile) + tile = mkobj(type(Image), ReferenceImage(draw_info->tile)); + else + tile = mkvoid; + return mktuplel(11, font, + mkfloat(draw_info->pointsize), + mkuint(draw_info->gravity), + mkpixel(&draw_info->fill), + mkpixel(&draw_info->stroke), + mkpixel(&draw_info->undercolor), + mkpixel(&draw_info->border_color), + mkfloat(draw_info->stroke_width), + mkbool(draw_info->stroke_antialias), + mkbool(draw_info->text_antialias), + tile); + } else + return __FAIL; + } + + FUNCTION(magick,type_metrics,argc,argv) + { + Image *img; + DrawInfo *draw_info; + if (argc == 1 && isobj(argv[0], type(Image), (void**)&img) && + (draw_info = get_draw_info(img))) { + TypeMetric metrics; + if (GetTypeMetrics(img, draw_info, &metrics)) + return mktuplel(9, mkfloat(metrics.pixels_per_em.x), + mkfloat(metrics.pixels_per_em.y), + mkfloat(metrics.ascent), + mkfloat(metrics.descent), + mkfloat(metrics.width), + mkfloat(metrics.height), + mkfloat(metrics.max_advance), + mkfloat(metrics.underline_position), + mkfloat(metrics.underline_thickness)); + else + return __FAIL; + } else + return __FAIL; + } + + FUNCTION(magick,set_draw_font,argc,argv) + { + Image *img; + DrawInfo *draw_info; + char *font; + if (argc == 2 && isobj(argv[0], type(Image), (void**)&img) && + (draw_info = get_draw_info(img)) && isstr(argv[1], &font) && + CloneString(&draw_info->font, font)) + return mkvoid; + else + return __FAIL; + } + + FUNCTION(magick,set_draw_pointsize,argc,argv) + { + Image *img; + DrawInfo *draw_info; + double val; + if (argc == 2 && isobj(argv[0], type(Image), (void**)&img) && + (draw_info = get_draw_info(img)) && + (isfloat(argv[1], &val) || ismpz_float(argv[1], &val))) { + draw_info->pointsize = val; + return mkvoid; + } else + return __FAIL; + } + + FUNCTION(magick,set_draw_gravity,argc,argv) + { + Image *img; + DrawInfo *draw_info; + unsigned long val; + if (argc == 2 && isobj(argv[0], type(Image), (void**)&img) && + (draw_info = get_draw_info(img)) && isuint(argv[1], &val)) { + draw_info->gravity = val; + return mkvoid; + } else + return __FAIL; + } + + FUNCTION(magick,set_draw_fill,argc,argv) + { + Image *img; + DrawInfo *draw_info; + bstr_t *m; + if (argc == 2 && isobj(argv[0], type(Image), (void**)&img) && + (draw_info = get_draw_info(img)) && + isobj(argv[1], type(ByteStr), (void**)&m) && m->size == 8) { + set_pixels(&draw_info->fill, m->v, 1, img->matte); + return mkvoid; + } else + return __FAIL; + } + + FUNCTION(magick,set_draw_stroke,argc,argv) + { + Image *img; + DrawInfo *draw_info; + bstr_t *m; + if (argc == 2 && isobj(argv[0], type(Image), (void**)&img) && + (draw_info = get_draw_info(img)) && + isobj(argv[1], type(ByteStr), (void**)&m) && m->size == 8) { + set_pixels(&draw_info->stroke, m->v, 1, img->matte); + return mkvoid; + } else + return __FAIL; + } + + FUNCTION(magick,set_draw_undercolor,argc,argv) + { + Image *img; + DrawInfo *draw_info; + bstr_t *m; + if (argc == 2 && isobj(argv[0], type(Image), (void**)&img) && + (draw_info = get_draw_info(img)) && + isobj(argv[1], type(ByteStr), (void**)&m) && m->size == 8) { + set_pixels(&draw_info->undercolor, m->v, 1, img->matte); + return mkvoid; + } else + return __FAIL; + } + + FUNCTION(magick,set_draw_border_color,argc,argv) + { + Image *img; + DrawInfo *draw_info; + bstr_t *m; + if (argc == 2 && isobj(argv[0], type(Image), (void**)&img) && + (draw_info = get_draw_info(img)) && + isobj(argv[1], type(ByteStr), (void**)&m) && m->size == 8) { + set_pixels(&draw_info->border_color, m->v, 1, img->matte); + return mkvoid; + } else + return __FAIL; + } + + FUNCTION(magick,set_draw_stroke_width,argc,argv) + { + Image *img; + DrawInfo *draw_info; + double val; + if (argc == 2 && isobj(argv[0], type(Image), (void**)&img) && + (draw_info = get_draw_info(img)) && + (isfloat(argv[1], &val) || ismpz_float(argv[1], &val))) { + draw_info->stroke_width = val; + return mkvoid; + } else + return __FAIL; + } + + FUNCTION(magick,set_draw_stroke_antialias,argc,argv) + { + Image *img; + DrawInfo *draw_info; + int val; + if (argc == 2 && isobj(argv[0], type(Image), (void**)&img) && + (draw_info = get_draw_info(img)) && isbool(argv[1], &val)) { + draw_info->stroke_antialias = val; + return mkvoid; + } else + return __FAIL; + } + + FUNCTION(magick,set_draw_text_antialias,argc,argv) + { + Image *img; + DrawInfo *draw_info; + int val; + if (argc == 2 && isobj(argv[0], type(Image), (void**)&img) && + (draw_info = get_draw_info(img)) && isbool(argv[1], &val)) { + draw_info->text_antialias = val; + return mkvoid; + } else + return __FAIL; + } + + FUNCTION(magick,set_draw_tile,argc,argv) + { + Image *img, *tile; + DrawInfo *draw_info; + if (argc == 2 && isobj(argv[0], type(Image), (void**)&img) && + (draw_info = get_draw_info(img)) && + isobj(argv[1], type(Image), (void**)&tile)) { + /* we better clone the image here, to avoid nasty circular references */ + tile = CloneImage(tile, 0, 0, 1, &exception); + if (check_exception(&exception)) + return mkapp(mksym(sym(magick_error)), mkstr(strdup(msg))); + else if (tile) + draw_info->tile = tile; + else + return __FAIL; + return mkvoid; + } else + return __FAIL; + } + FUNCTION(magick,image_background_color,argc,argv) { *************** *** 751,755 **** return mkapp(mksym(sym(magick_error)), mkstr(strdup(msg))); else ! return res?mktrue:mkfalse; } else return __FAIL; --- 1003,1007 ---- return mkapp(mksym(sym(magick_error)), mkstr(strdup(msg))); else ! return mkbool(res); } else return __FAIL; *************** *** 764,768 **** return mkapp(mksym(sym(magick_error)), mkstr(strdup(msg))); else ! return res?mktrue:mkfalse; } else return __FAIL; --- 1016,1020 ---- return mkapp(mksym(sym(magick_error)), mkstr(strdup(msg))); else ! return mkbool(res); } else return __FAIL; *************** *** 777,781 **** return mkapp(mksym(sym(magick_error)), mkstr(strdup(msg))); else ! return res?mktrue:mkfalse; } else return __FAIL; --- 1029,1033 ---- return mkapp(mksym(sym(magick_error)), mkstr(strdup(msg))); else ! return mkbool(res); } else return __FAIL; *************** *** 790,794 **** return mkapp(mksym(sym(magick_error)), mkstr(strdup(msg))); else ! return res?mktrue:mkfalse; } else return __FAIL; --- 1042,1046 ---- return mkapp(mksym(sym(magick_error)), mkstr(strdup(msg))); else ! return mkbool(res); } else return __FAIL; *************** *** 1210,1225 **** } else return __FAIL; - } - - static inline int isbool(expr x, int *val) - { - if (istrue(x)) { - *val = 1; - return 1; - } else if (isfalse(x)) { - *val = 0; - return 1; - } else - return 0; } --- 1462,1465 ---- Index: magick.q =================================================================== RCS file: /cvsroot/q-lang/q/modules/magick/magick.q,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** magick.q 31 Dec 2003 01:47:52 -0000 1.28 --- magick.q 31 Dec 2003 05:37:52 -0000 1.29 *************** *** 26,30 **** an image, davanced image manipulation and effect functions, and drawing primitives. As the external pixel representation is the same as that of the ! GGI module, GGI visuals can be employed to actually display the images. */ import clib; --- 26,31 ---- an image, davanced image manipulation and effect functions, and drawing primitives. As the external pixel representation is the same as that of the ! GGI module, it is easy to exchange pixel data with GGI visuals to actually ! display the images. */ import clib; *************** *** 46,49 **** --- 47,54 ---- NONE, BZIP, FAX, GROUP4, JPEG, LOSSLESS, LZW, RLE, ZIP, + /* Gravity types used by the DRAW_INFO structure. */ + FORGET, NORTH_WEST, NORTH, NORTH_EAST, WEST, CENTER, EAST, SOUTH_WEST, + SOUTH, SOUTH_EAST, STATIC, + /* Filter types for the resize function. */ POINT_FILTER, BOX_FILTER, TRIANGLE_FILTER, HERMITE_FILTER, *************** *** 66,69 **** --- 71,77 ---- def (NONE, BZIP, FAX, GROUP4, JPEG, LOSSLESS, LZW, RLE, ZIP, + FORGET, NORTH_WEST, NORTH, NORTH_EAST, WEST, CENTER, EAST, SOUTH_WEST, + SOUTH, SOUTH_EAST, STATIC, + POINT_FILTER, BOX_FILTER, TRIANGLE_FILTER, HERMITE_FILTER, HANNING_FILTER, HAMMING_FILTER, BLACKMAN_FILTER, GAUSSIAN_FILTER, *************** *** 192,211 **** image_matte IMG, image_magick IMG; ! image_width IMG = W where (W,H,O,D,A,M) = image_info IMG; ! image_height IMG = H where (W,H,O,D,A,M) = image_info IMG; ! image_offset IMG = O where (W,H,O,D,A,M) = image_info IMG; ! image_depth IMG = D where (W,H,O,D,A,M) = image_info IMG; ! image_matte IMG = A where (W,H,O,D,A,M) = image_info IMG; ! image_magick IMG = M where (W,H,O,D,A,M) = image_info IMG; ! /* The DRAW_INFO structure of an image summarizes various properties which ! control the rendering of graphics primitives with the draw function. It can ! be retrieved and changed with the following operations. */ ! // TODO: ! //public extern draw_info IMG, set_draw_info IMG INFO; ! /* A few other properties can be retrieved and changed with the following ! operations. These properties are currently supported: - background_color, border_color, matte_color: The image background, border --- 200,299 ---- image_matte IMG, image_magick IMG; ! image_width IMG = INFO!0 where INFO:Tuple = image_info IMG; ! image_height IMG = INFO!1 where INFO:Tuple = image_info IMG; ! image_offset IMG = INFO!2 where INFO:Tuple = image_info IMG; ! image_depth IMG = INFO!3 where INFO:Tuple = image_info IMG; ! image_matte IMG = INFO!4 where INFO:Tuple = image_info IMG; ! image_magick IMG = INFO!5 where INFO:Tuple = image_info IMG; ! /* Image attributes related to drawing are kept in a separate DRAW_INFO ! structure which has the following fields: ! - FONT: A string, the name of the font to be used for drawing text. ! - POINTSIZE: Integer or floating point number, the font size. ! ! - GRAVITY: The default gravity of rendered text. Can be any of the gravity ! values listed in the manifest constants section. ! ! - FILL, STROKE, UNDERCOLOR: Pixel values specifying the default colors for ! the graphics primitives. The FILL color is used for the interior, STROKE ! for the outline of graphic objects; use FILL = magick_pixel "none" if no ! filling is desired. UNDERCOLOR determines the color for underlining text. ! ! - BORDER_COLOR: Pixel value, determines the border color for flood fill ! operations. ! ! - STROKE_WIDTH: Integer or floating point value, the linewidth of outlines ! drawn with the graphic primitives. ! ! - STROKE_ANTIALIAS, TEXT_ANTIALIAS: Two flags (either true or false), ! indicating whether to perform antialiasing when rendering text and other ! graphic objects. ! ! - TILE: An image to be tiled when filling a graphic object, () if none. ! ! The DRAW_INFO structure and its members can be accessed with the operations ! listed below. */ ! ! /* FIXME: What about the other font properties (family, style, stretch, ! weight, alignment) and rendering attributes (gradients, fill rule, ! linecaps/-joins, miterlimit, dash offset and pattern) which are ! undocumented but can be found in libMagick's DrawInfo struct? */ ! ! public extern draw_info IMG; ! ! public draw_font IMG, draw_pointsize IMG, draw_gravity IMG, draw_fill IMG, ! draw_stroke IMG, draw_undercolor IMG, draw_border_color IMG, ! draw_stroke_width IMG, draw_stroke_antialias IMG, draw_text_antialias IMG, ! draw_tile IMG; ! ! draw_font IMG = INFO!0 where INFO:Tuple = draw_info IMG; ! draw_pointsize IMG = INFO!1 where INFO:Tuple = draw_info IMG; ! draw_gravity IMG = INFO!2 where INFO:Tuple = draw_info IMG; ! draw_fill IMG = INFO!3 where INFO:Tuple = draw_info IMG; ! draw_stroke IMG = INFO!4 where INFO:Tuple = draw_info IMG; ! draw_undercolor IMG = INFO!5 where INFO:Tuple = draw_info IMG; ! draw_border_color IMG = INFO!6 where INFO:Tuple = draw_info IMG; ! draw_stroke_width IMG = INFO!7 where INFO:Tuple = draw_info IMG; ! draw_stroke_antialias IMG ! = INFO!8 where INFO:Tuple = draw_info IMG; ! draw_text_antialias IMG = INFO!9 where INFO:Tuple = draw_info IMG; ! draw_tile IMG = INFO!10 where INFO:Tuple = draw_info IMG; ! ! public extern set_draw_font IMG FONT, ! set_draw_pointsize IMG POINTSIZE, ! set_draw_gravity IMG GRAVITY, ! set_draw_fill IMG FILL, ! set_draw_stroke IMG STROKE, ! set_draw_undercolor IMG UNDERCOLOR, ! set_draw_border_color IMG BORDER_COLOR, ! set_draw_stroke_width IMG STROKE_WIDTH, ! set_draw_stroke_antialias IMG STROKE_ANTIALIAS, ! set_draw_text_antialias IMG TEXT_ANTIALIAS, ! set_draw_tile IMG TILE; ! ! /* To provide support for laying out text in an image, the type_metrics ! function gives access to the type metrics of the current font set on an ! image. It returns a tuple with the following information: ! ! - PPEM_X, PPEM_Y: pixels per em, character width and height in pixels ! ! - ASCENT, DESCENT: ascent and descent of the font ! ! - WIDTH, HEIGHT: text width and height ! ! - ADVANCE: maximum horizontal advance ! ! - UNDERLINE_POSITION, UNDERLINE_THICKNESS: underline position and ! thickness ! ! Note that all figures are in pixel units. Since fractional font sizes are ! supported, the values are reported as floating point numbers. */ ! ! public extern type_metrics IMG; ! ! /* A few other image properties can be retrieved and changed with the ! operations listed below. The following properties are currently supported: - background_color, border_color, matte_color: The image background, border *************** *** 245,259 **** list of an image, specify () as the VAL parameter of set_image_attr. Otherwise the given value is added to the attribute (an existing value is ! *not* overridden automatically). Attributes used by ImageMagick include ! "comment", "label" and "signature". In particular, the "label" attribute is ! useful with the montage operation (see below). */ public extern image_attr IMG KEY, set_image_attr IMG KEY VAL; ! /* Convenience functions to access the "label" attribute. */ public image_label IMG, set_image_label IMG LABEL; ! image_label IMG:Image = LABEL where LABEL:String = image_attr IMG "label"; set_image_label IMG:Image LABEL:String = set_image_attr IMG "label" () || --- 333,357 ---- list of an image, specify () as the VAL parameter of set_image_attr. Otherwise the given value is added to the attribute (an existing value is ! *not* overridden automatically, you first have to set the attribute to () ! to accomplish this). Attributes used by ImageMagick include "comment", ! "label" and "signature". In particular, the "label" attribute is useful ! with the montage operation (see below). */ public extern image_attr IMG KEY, set_image_attr IMG KEY VAL; ! /* Convenience functions to access the "comment" and "label" attributes. */ ! ! public image_comment IMG, set_image_comment IMG COMMENT; ! ! image_comment IMG:Image = COMMENT ! where COMMENT:String = image_attr IMG "comment"; ! set_image_comment IMG:Image COMMENT:String ! = set_image_attr IMG "comment" () || ! set_image_attr IMG "comment" COMMENT; public image_label IMG, set_image_label IMG LABEL; ! image_label IMG:Image = LABEL ! where LABEL:String = image_attr IMG "label"; set_image_label IMG:Image LABEL:String = set_image_attr IMG "label" () || *************** *** 374,380 **** unchanged. ! Most operations have the same name as in the C API (without the Image ! suffix), with the following exceptions: `FlipImage' and `FlopImage' are ! named `flipy' and `flipx', and `RaiseImage' is named `button'. A note on parameters: IMG always denotes a singleton input image, IMGS an --- 472,480 ---- unchanged. ! Most operations have the same name as in the C API (without the `Image' ! suffix), with the following exceptions: (1) `FlipImage' and `FlopImage' are ! named `flipy' and `flipx'. (Or was it the other way round? Go figure. ;-) ! (2) `RaiseImage' is named `button' (that's more suggestive, too, and btw a ! `raise' function is already in clib, so we don't want to abuse that name). A note on parameters: IMG always denotes a singleton input image, IMGS an *************** *** 389,392 **** --- 489,496 ---- various algorithms. These are explained in more detail in the ImageMagick manual. */ + + /* FIXME: Some of the stuff below really needs further documentation. For the + time being, please take a look at what the corresponding C or Perl + functions, or ImageMagick command line options do. */ /* Quantization. */ |