X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/01b84320060a72aec230c31033d54258c4135a08..4326b23a38b971802036792fd8af38076f1c3fae:/Imager.xs diff --git a/Imager.xs b/Imager.xs index 94c4325f..d1512c0c 100644 --- a/Imager.xs +++ b/Imager.xs @@ -1,3 +1,4 @@ +#define PERL_NO_GET_CONTEXT #ifdef __cplusplus extern "C" { #endif @@ -18,6 +19,7 @@ extern "C" { #include "dynaload.h" #include "regmach.h" #include "imextdef.h" +#include "imextpltypes.h" #if i_int_hlines_testing() #include "imageri.h" @@ -27,6 +29,7 @@ extern "C" { /* These functions are all shared - then comes platform dependant code */ static int getstr(void *hv_t,char *key,char **store) { + dTHX; SV** svpp; HV* hv=(HV*)hv_t; @@ -41,6 +44,7 @@ static int getstr(void *hv_t,char *key,char **store) { } static int getint(void *hv_t,char *key,int *store) { + dTHX; SV** svpp; HV* hv=(HV*)hv_t; @@ -54,6 +58,7 @@ static int getint(void *hv_t,char *key,int *store) { } static int getdouble(void *hv_t,char* key,double *store) { + dTHX; SV** svpp; HV* hv=(HV*)hv_t; @@ -66,6 +71,7 @@ static int getdouble(void *hv_t,char* key,double *store) { } static int getvoid(void *hv_t,char* key,void **store) { + dTHX; SV** svpp; HV* hv=(HV*)hv_t; @@ -80,6 +86,7 @@ static int getvoid(void *hv_t,char* key,void **store) { } static int getobj(void *hv_t,char *key,char *type,void **store) { + dTHX; SV** svpp; HV* hv=(HV*)hv_t; @@ -103,6 +110,7 @@ static int getobj(void *hv_t,char *key,char *type,void **store) { UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj}; void my_SvREFCNT_dec(void *p) { + dTHX; SvREFCNT_dec((SV*)p); } @@ -121,6 +129,7 @@ typedef struct i_reader_data_tag /* used by functions that want callbacks */ static int read_callback(char *userdata, char *buffer, int need, int want) { + dTHX; i_reader_data *rd = (i_reader_data *)userdata; int count; int result; @@ -172,6 +181,7 @@ typedef struct /* used by functions that want callbacks */ static int write_callback(char *userdata, char const *data, int size) { + dTHX; i_writer_data *wd = (i_writer_data *)userdata; int count; int success; @@ -243,6 +253,7 @@ Low-level function to call the perl writer callback. */ static ssize_t call_writer(struct cbdata *cbd, void const *buf, size_t size) { + dTHX; int count; int success; SV *sv; @@ -277,6 +288,7 @@ static ssize_t call_writer(struct cbdata *cbd, void const *buf, size_t size) { static ssize_t call_reader(struct cbdata *cbd, void *buf, size_t size, size_t maxread) { + dTHX; int count; int result; SV *data; @@ -323,6 +335,7 @@ static ssize_t call_reader(struct cbdata *cbd, void *buf, size_t size, } static ssize_t write_flush(struct cbdata *cbd) { + dTHX; ssize_t result; if (cbd->used) { @@ -336,6 +349,7 @@ static ssize_t write_flush(struct cbdata *cbd) { } static off_t io_seeker(void *p, off_t offset, int whence) { + dTHX; struct cbdata *cbd = p; int count; off_t result; @@ -380,6 +394,7 @@ static off_t io_seeker(void *p, off_t offset, int whence) { } static ssize_t io_writer(void *p, void const *data, size_t size) { + dTHX; struct cbdata *cbd = p; /* printf("io_writer(%p, %p, %u)\n", p, data, size); */ @@ -413,6 +428,7 @@ static ssize_t io_writer(void *p, void const *data, size_t size) { static ssize_t io_reader(void *p, void *data, size_t size) { + dTHX; struct cbdata *cbd = p; ssize_t total; char *out = data; /* so we can do pointer arithmetic */ @@ -471,6 +487,7 @@ io_reader(void *p, void *data, size_t size) { } static int io_closer(void *p) { + dTHX; struct cbdata *cbd = p; if (cbd->writing && cbd->used > 0) { @@ -499,6 +516,7 @@ static int io_closer(void *p) { } static void io_destroyer(void *p) { + dTHX; struct cbdata *cbd = p; SvREFCNT_dec(cbd->writecb); @@ -541,9 +559,7 @@ static struct value_name make_color_names[] = static struct value_name translate_names[] = { -#ifdef HAVE_LIBGIF { "giflib", pt_giflib, }, -#endif { "closest", pt_closest, }, { "perturb", pt_perturb, }, { "errdiff", pt_errdiff, }, @@ -573,7 +589,8 @@ static struct value_name orddith_names[] = }; /* look through the hash for quantization options */ -static void handle_quant_opts(i_quantize *quant, HV *hv) +static void +ip_handle_quant_opts(pTHX_ i_quantize *quant, HV *hv) { /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/ SV **sv; @@ -624,7 +641,7 @@ static void handle_quant_opts(i_quantize *quant, HV *hv) } } } - quant->make_colors = mc_addi; + quant->make_colors = mc_median_cut; sv = hv_fetch(hv, "make_colors", 11, 0); if (sv && *sv && (str = SvPV(*sv, len))) { quant->make_colors = @@ -704,14 +721,16 @@ static void handle_quant_opts(i_quantize *quant, HV *hv) quant->perturb = SvIV(*sv); } -static void cleanup_quant_opts(i_quantize *quant) { +static void +ip_cleanup_quant_opts(pTHX_ i_quantize *quant) { myfree(quant->mc_colors); if (quant->ed_map) myfree(quant->ed_map); } /* copies the color map from the hv into the colors member of the HV */ -static void copy_colors_back(HV *hv, i_quantize *quant) { +static void +ip_copy_colors_back(pTHX_ HV *hv, i_quantize *quant) { SV **sv; AV *av; int i; @@ -719,14 +738,12 @@ static void copy_colors_back(HV *hv, i_quantize *quant) { sv = hv_fetch(hv, "colors", 6, 0); if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) { - SV *ref; - av = newAV(); - ref = newRV_inc((SV*) av); - sv = hv_store(hv, "colors", 6, ref, 0); - } - else { - av = (AV *)SvRV(*sv); + /* nothing to do */ + return; } + + av = (AV *)SvRV(*sv); + av_clear(av); av_extend(av, quant->mc_count+1); for (i = 0; i < quant->mc_count; ++i) { i_color *in = quant->mc_colors+i; @@ -734,15 +751,13 @@ static void copy_colors_back(HV *hv, i_quantize *quant) { work = sv_newmortal(); sv_setref_pv(work, "Imager::Color", (void *)c); SvREFCNT_inc(work); - if (!av_store(av, i, work)) { - SvREFCNT_dec(work); - } + av_push(av, work); } } /* loads the segments of a fountain fill into an array */ static i_fountain_seg * -load_fount_segs(AV *asegs, int *count) { +load_fount_segs(pTHX_ AV *asegs, int *count) { /* Each element of segs must contain: [ start, middle, end, c0, c1, segtype, colortrans ] start, middle, end are doubles from 0 to 1 @@ -877,6 +892,8 @@ i_int_hlines_DESTROY(i_int_hlines *hlines) { myfree(hlines); } +#define i_int_hlines_CLONE_SKIP(cls) 1 + static int seg_compare(const void *vleft, const void *vright) { const i_int_hline_seg *left = vleft; const i_int_hline_seg *right = vright; @@ -886,6 +903,7 @@ static int seg_compare(const void *vleft, const void *vright) { static SV * i_int_hlines_dump(i_int_hlines *hlines) { + dTHX; SV *dump = newSVpvf("start_y: %d limit_y: %d start_x: %d limit_x: %d\n", hlines->start_y, hlines->limit_y, hlines->start_x, hlines->limit_x); int y; @@ -912,6 +930,18 @@ i_int_hlines_dump(i_int_hlines *hlines) { #endif +static im_pl_ext_funcs im_perl_funcs = +{ + IMAGER_PL_API_VERSION, + IMAGER_PL_API_LEVEL, + ip_handle_quant_opts, + ip_cleanup_quant_opts, + ip_copy_colors_back +}; + +#define PERL_PL_SET_GLOBAL_CALLBACKS \ + sv_setiv(get_sv(PERL_PL_FUNCTION_TABLE_NAME, 1), PTR2IV(&im_perl_funcs)); + #ifdef IMEXIF_ENABLE #define i_exif_enabled() 1 #else @@ -921,6 +951,9 @@ i_int_hlines_dump(i_int_hlines *hlines) { /* trying to use more C style names, map them here */ #define i_io_DESTROY(ig) io_glue_destroy(ig) +#define i_img_get_width(im) ((im)->xsize) +#define i_img_get_height(im) ((im)->ysize) + MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_ Imager::Color @@ -1237,6 +1270,13 @@ void i_io_DESTROY(ig) Imager::IO ig +int +i_io_CLONE_SKIP(...) + CODE: + RETVAL = 1; + OUTPUT: + RETVAL + MODULE = Imager PACKAGE = Imager PROTOTYPES: ENABLE @@ -1287,9 +1327,13 @@ i_sametype_chans(im, x, y, channels) int channels void -i_init_log(name,level) - char* name +i_init_log(name_sv,level) + SV* name_sv int level + PREINIT: + const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL; + CODE: + i_init_log(name, level); void i_log_entry(string,level) @@ -1343,6 +1387,34 @@ i_img_getdata(im) sv_2mortal(newSVpv((char *)im->idata, im->bytes)) : &PL_sv_undef); +IV +i_img_get_width(im) + Imager::ImgRaw im + +IV +i_img_get_height(im) + Imager::ImgRaw im + + +void +i_img_is_monochrome(im) + Imager::ImgRaw im + PREINIT: + int zero_is_white; + int result; + PPCODE: + result = i_img_is_monochrome(im, &zero_is_white); + if (result) { + if (GIMME_V == G_ARRAY) { + EXTEND(SP, 2); + PUSHs(&PL_sv_yes); + PUSHs(sv_2mortal(newSViv(zero_is_white))); + } + else { + EXTEND(SP, 1); + PUSHs(&PL_sv_yes); + } + } void i_line(im,x1,y1,x2,y2,val,endp) @@ -1440,6 +1512,41 @@ i_circle_aa(im,x,y,rad,val) float rad Imager::Color val +int +i_circle_out(im,x,y,rad,val) + Imager::ImgRaw im + i_img_dim x + i_img_dim y + i_img_dim rad + Imager::Color val + +int +i_circle_out_aa(im,x,y,rad,val) + Imager::ImgRaw im + i_img_dim x + i_img_dim y + i_img_dim rad + Imager::Color val + +int +i_arc_out(im,x,y,rad,d1,d2,val) + Imager::ImgRaw im + i_img_dim x + i_img_dim y + i_img_dim rad + float d1 + float d2 + Imager::Color val + +int +i_arc_out_aa(im,x,y,rad,d1,d2,val) + Imager::ImgRaw im + i_img_dim x + i_img_dim y + i_img_dim rad + float d1 + float d2 + Imager::Color val void @@ -1477,7 +1584,7 @@ i_bezier_multi(im,xc,yc,val) myfree(y); -void +int i_poly_aa(im,xc,yc,val) Imager::ImgRaw im Imager::Color val @@ -1489,7 +1596,7 @@ i_poly_aa(im,xc,yc,val) SV *sv1; SV *sv2; int i; - PPCODE: + CODE: ICL_info(val); if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n"); if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n"); @@ -1507,11 +1614,13 @@ i_poly_aa(im,xc,yc,val) x[i]=(double)SvNV(sv1); y[i]=(double)SvNV(sv2); } - i_poly_aa(im,len,x,y,val); + RETVAL = i_poly_aa(im,len,x,y,val); myfree(x); myfree(y); + OUTPUT: + RETVAL -void +int i_poly_aa_cfill(im,xc,yc,fill) Imager::ImgRaw im Imager::FillHandle fill @@ -1523,7 +1632,7 @@ i_poly_aa_cfill(im,xc,yc,fill) SV *sv1; SV *sv2; int i; - PPCODE: + CODE: if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n"); if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n"); if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n"); @@ -1540,9 +1649,11 @@ i_poly_aa_cfill(im,xc,yc,fill) x[i]=(double)SvNV(sv1); y[i]=(double)SvNV(sv2); } - i_poly_aa_cfill(im,len,x,y,fill); + RETVAL = i_poly_aa_cfill(im,len,x,y,fill); myfree(x); myfree(y); + OUTPUT: + RETVAL @@ -1617,6 +1728,75 @@ i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy) int src_maxx int src_maxy +undef_int +i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0) + Imager::ImgRaw out + Imager::ImgRaw src + int out_left + int out_top + int src_left + int src_top + int width + int height + int combine + double opacity + +undef_int +i_compose_mask(out, src, mask, out_left, out_top, src_left, src_top, mask_left, mask_top, width, height, combine = ic_normal, opacity = 0.0) + Imager::ImgRaw out + Imager::ImgRaw src + Imager::ImgRaw mask + int out_left + int out_top + int src_left + int src_top + int mask_left + int mask_top + int width + int height + int combine + double opacity + +Imager::ImgRaw +i_combine(src_av, channels_av = NULL) + AV *src_av + AV *channels_av + PREINIT: + i_img **imgs = NULL; + STRLEN in_count; + int *channels = NULL; + int i; + SV **psv; + IV tmp; + CODE: + in_count = av_len(src_av) + 1; + if (in_count > 0) { + imgs = mymalloc(sizeof(i_img*) * in_count); + channels = mymalloc(sizeof(int) * in_count); + for (i = 0; i < in_count; ++i) { + psv = av_fetch(src_av, i, 0); + if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) { + myfree(imgs); + myfree(channels); + croak("imgs must contain only images"); + } + tmp = SvIV((SV*)SvRV(*psv)); + imgs[i] = INT2PTR(i_img*, tmp); + if (channels_av && + (psv = av_fetch(channels_av, i, 0)) != NULL && + *psv) { + channels[i] = SvIV(*psv); + } + else { + channels[i] = 0; + } + } + } + RETVAL = i_combine(imgs, channels, in_count); + myfree(imgs); + myfree(channels); + OUTPUT: + RETVAL undef_int i_flipxy(im, direction) @@ -1709,45 +1889,40 @@ i_unsharp_mask(im,stdev,scale) float stdev double scale -void -i_conv(im,pcoef) - Imager::ImgRaw im - PREINIT: - float* coeff; - int len; - AV* av; - SV* sv1; - int i; - PPCODE: - if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n"); - if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n"); - av=(AV*)SvRV(ST(1)); - len=av_len(av)+1; - coeff=mymalloc( len*sizeof(float) ); - for(i=0;ifunction_list[i].name != NULL) { + while( functions[i].name != NULL) { EXTEND(SP,1); - PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0))); + PUSHs(sv_2mortal(newSVpv(functions[i].name,0))); EXTEND(SP,1); - PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0))); + PUSHs(sv_2mortal(newSVpv(functions[i++].pcode,0))); } - void DSO_call(handle,func_index,hv) void* handle @@ -3466,8 +3016,6 @@ DSO_call(handle,func_index,hv) if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n"); DSO_call( (DSO_handle *)handle,func_index,hv); - - SV * i_get_pixel(im, x, y) Imager::ImgRaw im @@ -3514,13 +3062,14 @@ i_img_to_pal(src, quant) croak("i_img_to_pal: second argument must be a hash ref"); hv = (HV *)SvRV(ST(1)); memset(&quant, 0, sizeof(quant)); + quant.version = 1; quant.mc_size = 256; - handle_quant_opts(&quant, hv); + ip_handle_quant_opts(aTHX_ &quant, hv); RETVAL = i_img_to_pal(src, &quant); if (RETVAL) { - copy_colors_back(hv, &quant); + ip_copy_colors_back(aTHX_ hv, &quant); } - cleanup_quant_opts(&quant); + ip_cleanup_quant_opts(aTHX_ &quant); OUTPUT: RETVAL @@ -3774,9 +3323,111 @@ i_gsamp(im, l, r, y, ...) } } - -Imager::ImgRaw -i_img_masked_new(targ, mask, x, y, w, h) +undef_neg_int +i_gsamp_bits(im, l, r, y, bits, target, offset, ...) + Imager::ImgRaw im + int l + int r + int y + int bits + AV *target + int offset + PREINIT: + int *chans; + int chan_count; + unsigned *data; + int count, i; + CODE: + i_clear_error(); + if (items < 8) + croak("No channel numbers supplied to g_samp()"); + if (l < r) { + chan_count = items - 7; + chans = mymalloc(sizeof(int) * chan_count); + for (i = 0; i < chan_count; ++i) + chans[i] = SvIV(ST(i+7)); + data = mymalloc(sizeof(unsigned) * (r-l) * chan_count); + count = i_gsamp_bits(im, l, r, y, data, chans, chan_count, bits); + myfree(chans); + for (i = 0; i < count; ++i) { + av_store(target, i+offset, newSVuv(data[i])); + } + myfree(data); + RETVAL = count; + } + else { + RETVAL = 0; + } + OUTPUT: + RETVAL + +undef_neg_int +i_psamp_bits(im, l, y, bits, channels_sv, data_av, data_offset = 0, pixel_count = -1) + Imager::ImgRaw im + int l + int y + int bits + SV *channels_sv + AV *data_av + int data_offset + int pixel_count + PREINIT: + int chan_count; + int *channels; + int data_count; + int data_used; + unsigned *data; + int i; + CODE: + i_clear_error(); + if (SvOK(channels_sv)) { + AV *channels_av; + if (!SvROK(channels_sv) || SvTYPE(SvRV(channels_sv)) != SVt_PVAV) { + croak("channels is not an array ref"); + } + channels_av = (AV *)SvRV(channels_sv); + chan_count = av_len(channels_av) + 1; + if (chan_count < 1) { + croak("i_psamp_bits: no channels provided"); + } + channels = mymalloc(sizeof(int) * chan_count); + for (i = 0; i < chan_count; ++i) + channels[i] = SvIV(*av_fetch(channels_av, i, 0)); + } + else { + chan_count = im->channels; + channels = NULL; + } + + data_count = av_len(data_av) + 1; + if (data_offset < 0) { + croak("data_offset must by non-negative"); + } + if (data_offset > data_count) { + croak("data_offset greater than number of samples supplied"); + } + if (pixel_count == -1 || + data_offset + pixel_count * chan_count > data_count) { + pixel_count = (data_count - data_offset) / chan_count; + } + + data_used = pixel_count * chan_count; + data = mymalloc(sizeof(unsigned) * data_count); + for (i = 0; i < data_used; ++i) + data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0)); + + RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels, + chan_count, bits); + + if (data) + myfree(data); + if (channels) + myfree(channels); + OUTPUT: + RETVAL + +Imager::ImgRaw +i_img_masked_new(targ, mask, x, y, w, h) Imager::ImgRaw targ int x int y @@ -3966,6 +3617,7 @@ i_glin(im, l, r, y) PPCODE: if (l < r) { vals = mymalloc((r-l) * sizeof(i_color)); + memset(vals, 0, (r-l) * sizeof(i_color)); count = i_glin(im, l, r, y, vals); if (GIMME_V == G_ARRAY) { EXTEND(SP, count); @@ -3994,9 +3646,14 @@ i_glinf(im, l, r, y) PREINIT: i_fcolor *vals; int count, i; + i_fcolor zero; PPCODE: + for (i = 0; i < MAXCHANNELS; ++i) + zero.channel[i] = 0; if (l < r) { vals = mymalloc((r-l) * sizeof(i_fcolor)); + for (i = 0; i < r-l; ++i) + vals[i] = zero; count = i_glinf(im, l, r, y, vals); if (GIMME_V == G_ARRAY) { EXTEND(SP, count); @@ -4192,426 +3849,7 @@ i_tags_count(im) OUTPUT: RETVAL -#ifdef HAVE_WIN32 - -void -i_wf_bbox(face, size, text_sv, utf8=0) - char *face - int size - SV *text_sv - int utf8 - PREINIT: - int cords[BOUNDING_BOX_COUNT]; - int rc, i; - char const *text; - STRLEN text_len; - PPCODE: - text = SvPV(text_sv, text_len); -#ifdef SvUTF8 - if (SvUTF8(text_sv)) - utf8 = 1; -#endif - if (rc = i_wf_bbox(face, size, text, text_len, cords, utf8)) { - EXTEND(SP, rc); - for (i = 0; i < rc; ++i) - PUSHs(sv_2mortal(newSViv(cords[i]))); - } - -undef_int -i_wf_text(face, im, tx, ty, cl, size, text_sv, align, aa, utf8 = 0) - char *face - Imager::ImgRaw im - int tx - int ty - Imager::Color cl - int size - SV *text_sv - int align - int aa - int utf8 - PREINIT: - char const *text; - STRLEN text_len; - CODE: - text = SvPV(text_sv, text_len); -#ifdef SvUTF8 - if (SvUTF8(text_sv)) - utf8 = 1; -#endif - RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, text_len, - align, aa, utf8); - OUTPUT: - RETVAL - -undef_int -i_wf_cp(face, im, tx, ty, channel, size, text_sv, align, aa, utf8 = 0) - char *face - Imager::ImgRaw im - int tx - int ty - int channel - int size - SV *text_sv - int align - int aa - int utf8 - PREINIT: - char const *text; - STRLEN text_len; - CODE: - text = SvPV(text_sv, text_len); -#ifdef SvUTF8 - if (SvUTF8(text_sv)) - utf8 = 1; -#endif - RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, text_len, - align, aa, utf8); - OUTPUT: - RETVAL - -undef_int -i_wf_addfont(font) - char *font - -#endif - -#ifdef HAVE_FT2 - -MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_ - -#define FT2_DESTROY(font) i_ft2_destroy(font) - -void -FT2_DESTROY(font) - Imager::Font::FT2 font - -MODULE = Imager PACKAGE = Imager::Font::FreeType2 - -Imager::Font::FT2 -i_ft2_new(name, index) - char *name - int index - -undef_int -i_ft2_setdpi(font, xdpi, ydpi) - Imager::Font::FT2 font - int xdpi - int ydpi - -void -i_ft2_getdpi(font) - Imager::Font::FT2 font - PREINIT: - int xdpi, ydpi; - CODE: - if (i_ft2_getdpi(font, &xdpi, &ydpi)) { - EXTEND(SP, 2); - PUSHs(sv_2mortal(newSViv(xdpi))); - PUSHs(sv_2mortal(newSViv(ydpi))); - } - -undef_int -i_ft2_sethinting(font, hinting) - Imager::Font::FT2 font - int hinting - -undef_int -i_ft2_settransform(font, matrix) - Imager::Font::FT2 font - PREINIT: - double matrix[6]; - int len; - AV *av; - SV *sv1; - int i; - CODE: - if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV) - croak("i_ft2_settransform: parameter 2 must be an array ref\n"); - av=(AV*)SvRV(ST(1)); - len=av_len(av)+1; - if (len > 6) - len = 6; - for (i = 0; i < len; ++i) { - sv1=(*(av_fetch(av,i,0))); - matrix[i] = SvNV(sv1); - } - for (; i < 6; ++i) - matrix[i] = 0; - RETVAL = i_ft2_settransform(font, matrix); - OUTPUT: - RETVAL - -void -i_ft2_bbox(font, cheight, cwidth, text_sv, utf8) - Imager::Font::FT2 font - double cheight - double cwidth - SV *text_sv - int utf8 - PREINIT: - int bbox[BOUNDING_BOX_COUNT]; - int i; - char *text; - STRLEN text_len; - int rc; - PPCODE: - text = SvPV(text_sv, text_len); -#ifdef SvUTF8 - if (SvUTF8(text_sv)) - utf8 = 1; -#endif - rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8); - if (rc) { - EXTEND(SP, rc); - for (i = 0; i < rc; ++i) - PUSHs(sv_2mortal(newSViv(bbox[i]))); - } - -void -i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8) - Imager::Font::FT2 font - double cheight - double cwidth - char *text - int vlayout - int utf8 - PREINIT: - int bbox[8]; - int i; - PPCODE: -#ifdef SvUTF8 - if (SvUTF8(ST(3))) - utf8 = 1; -#endif - if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout, - utf8, bbox)) { - EXTEND(SP, 8); - for (i = 0; i < 8; ++i) - PUSHs(sv_2mortal(newSViv(bbox[i]))); - } - -undef_int -i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8) - Imager::Font::FT2 font - Imager::ImgRaw im - int tx - int ty - Imager::Color cl - double cheight - double cwidth - int align - int aa - int vlayout - int utf8 - PREINIT: - char *text; - STRLEN len; - CODE: -#ifdef SvUTF8 - if (SvUTF8(ST(7))) { - utf8 = 1; - } -#endif - text = SvPV(ST(7), len); - RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, - len, align, aa, vlayout, utf8); - OUTPUT: - RETVAL - -undef_int -i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text_sv, align, aa, vlayout, utf8) - Imager::Font::FT2 font - Imager::ImgRaw im - int tx - int ty - int channel - double cheight - double cwidth - SV *text_sv - int align - int aa - int vlayout - int utf8 - PREINIT: - char const *text; - STRLEN len; - CODE: -#ifdef SvUTF8 - if (SvUTF8(ST(7))) - utf8 = 1; -#endif - text = SvPV(text_sv, len); - RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, - len, align, aa, vlayout, 1); - OUTPUT: - RETVAL - -void -ft2_transform_box(font, x0, x1, x2, x3) - Imager::Font::FT2 font - int x0 - int x1 - int x2 - int x3 - PREINIT: - int box[4]; - PPCODE: - box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3; - ft2_transform_box(font, box); - EXTEND(SP, 4); - PUSHs(sv_2mortal(newSViv(box[0]))); - PUSHs(sv_2mortal(newSViv(box[1]))); - PUSHs(sv_2mortal(newSViv(box[2]))); - PUSHs(sv_2mortal(newSViv(box[3]))); - -void -i_ft2_has_chars(handle, text_sv, utf8) - Imager::Font::FT2 handle - SV *text_sv - int utf8 - PREINIT: - char *text; - STRLEN len; - char *work; - int count; - int i; - PPCODE: -#ifdef SvUTF8 - if (SvUTF8(text_sv)) - utf8 = 1; -#endif - text = SvPV(text_sv, len); - work = mymalloc(len); - count = i_ft2_has_chars(handle, text, len, utf8, work); - if (GIMME_V == G_ARRAY) { - EXTEND(SP, count); - for (i = 0; i < count; ++i) { - PUSHs(sv_2mortal(newSViv(work[i]))); - } - } - else { - EXTEND(SP, 1); - PUSHs(sv_2mortal(newSVpv(work, count))); - } - myfree(work); - -void -i_ft2_face_name(handle) - Imager::Font::FT2 handle - PREINIT: - char name[255]; - int len; - PPCODE: - len = i_ft2_face_name(handle, name, sizeof(name)); - if (len) { - EXTEND(SP, 1); - PUSHs(sv_2mortal(newSVpv(name, 0))); - } - -undef_int -i_ft2_can_face_name() - -void -i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1) - Imager::Font::FT2 handle - SV *text_sv - int utf8 - int reliable_only - PREINIT: - char const *text; - STRLEN work_len; - int len; - char name[255]; - PPCODE: -#ifdef SvUTF8 - if (SvUTF8(text_sv)) - utf8 = 1; -#endif - text = SvPV(text_sv, work_len); - len = work_len; - while (len) { - unsigned long ch; - if (utf8) { - ch = i_utf8_advance(&text, &len); - if (ch == ~0UL) { - i_push_error(0, "invalid UTF8 character"); - break; - } - } - else { - ch = *text++; - --len; - } - EXTEND(SP, 1); - if (i_ft2_glyph_name(handle, ch, name, sizeof(name), - reliable_only)) { - PUSHs(sv_2mortal(newSVpv(name, 0))); - } - else { - PUSHs(&PL_sv_undef); - } - } - -int -i_ft2_can_do_glyph_names() - -int -i_ft2_face_has_glyph_names(handle) - Imager::Font::FT2 handle - -int -i_ft2_is_multiple_master(handle) - Imager::Font::FT2 handle - -void -i_ft2_get_multiple_masters(handle) - Imager::Font::FT2 handle - PREINIT: - i_font_mm mm; - int i; - PPCODE: - if (i_ft2_get_multiple_masters(handle, &mm)) { - EXTEND(SP, 2+mm.num_axis); - PUSHs(sv_2mortal(newSViv(mm.num_axis))); - PUSHs(sv_2mortal(newSViv(mm.num_designs))); - for (i = 0; i < mm.num_axis; ++i) { - AV *av = newAV(); - SV *sv; - av_extend(av, 3); - sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name)); - SvREFCNT_inc(sv); - av_store(av, 0, sv); - sv = newSViv(mm.axis[i].minimum); - SvREFCNT_inc(sv); - av_store(av, 1, sv); - sv = newSViv(mm.axis[i].maximum); - SvREFCNT_inc(sv); - av_store(av, 2, sv); - PUSHs(newRV_noinc((SV *)av)); - } - } - -undef_int -i_ft2_set_mm_coords(handle, ...) - Imager::Font::FT2 handle - PROTOTYPE: DISABLE - PREINIT: - long *coords; - int ix_coords, i; - CODE: - /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so - transfer the array manually */ - ix_coords = items-1; - coords = mymalloc(sizeof(long) * ix_coords); - for (i = 0; i < ix_coords; ++i) { - coords[i] = (long)SvIV(ST(1+i)); - } - RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords); - myfree(coords); - OUTPUT: - RETVAL -#endif MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_ @@ -4619,6 +3857,13 @@ void IFILL_DESTROY(fill) Imager::FillHandle fill +int +IFILL_CLONE_SKIP(...) + CODE: + RETVAL = 1; + OUTPUT: + RETVAL + MODULE = Imager PACKAGE = Imager Imager::FillHandle @@ -4744,7 +3989,12 @@ SV * i_int_hlines_dump(hlines) Imager::Internal::Hlines hlines +int +i_int_hlines_CLONE_SKIP(cls) + SV *cls + #endif BOOT: PERL_SET_GLOBAL_CALLBACKS; + PERL_PL_SET_GLOBAL_CALLBACKS; \ No newline at end of file