Index: trunk/src/pixmap_pcb.c =================================================================== --- trunk/src/pixmap_pcb.c (revision 36074) +++ trunk/src/pixmap_pcb.c (revision 36075) @@ -31,6 +31,8 @@ #include #include +#include +#include #include "pixmap_pcb.h" #include "obj_common.h" @@ -89,48 +91,123 @@ rnd_pixmap_t *pcb_pixmap_alloc_insert_transformed(pcb_pixmap_hash_t *pmhash, rnd_pixmap_t *ipm, rnd_angle_t rot, int xmirror, int ymirror) { - rnd_pixmap_t *pm; + rnd_pixmap_t *opm; pcb_xform_mx_t mx = PCB_XFORM_MX_IDENT; - long n, len; - int x, y, ix, iy, ox, oy; - unsigned char *ip, *op; + long n, len, icx, icy, ocx, ocy, xo, yo, end; + unsigned char *o, *i; + double cs, sn, rotr; if ((rot == 0) && !xmirror && !ymirror) return ipm; /* xformed == neutral */ - pm = calloc(sizeof(rnd_pixmap_t), 1); + opm = calloc(sizeof(rnd_pixmap_t), 1); if (ipm->has_transp) { - pm->tr = ipm->tr; - pm->tg = ipm->tg; - pm->tb = ipm->tb; + opm->tr = ipm->tr; + opm->tg = ipm->tg; + opm->tb = ipm->tb; } else - pm->tr = pm->tg = pm->tb = 127; - pm->neutral_oid = ipm->neutral_oid; - pm->tr_rot = rot; - pm->tr_xmirror = xmirror; - pm->tr_ymirror = ymirror; - pm->tr_xscale = 1.0; - pm->tr_yscale = 1.0; - pm->has_transp = 1; + opm->tr = opm->tg = opm->tb = 127; + opm->neutral_oid = ipm->neutral_oid; + opm->tr_rot = rot; + opm->tr_xmirror = xmirror; + opm->tr_ymirror = ymirror; + opm->tr_xscale = 1.0; + opm->tr_yscale = 1.0; + opm->has_transp = 1; TODO("gfx: apply mirrors"); pcb_xform_mx_rotate(mx, rot); + opm->sx = pcb_xform_x(mx, (ipm->sx/2)+1, (ipm->sy/2)+1) * 2; + opm->sy = pcb_xform_y(mx, -(ipm->sx/2)-1, (ipm->sy/2)-1) * 2; - pm->sx = pcb_xform_x(mx, (ipm->sx/2)+1, (ipm->sy/2)+1) * 2; - pm->sy = pcb_xform_y(mx, -(ipm->sx/2)-1, (ipm->sy/2)-1) * 2; - /* alloc and fill with transparent */ - len = pm->sx * pm->sy * 3; - pm->p = malloc(len); + len = opm->sx * opm->sy * 3; + opm->p = malloc(len); for(n = 0; n < len; n += 3) { - pm->p[n+0] = pm->tr; - pm->p[n+1] = pm->tg; - pm->p[n+2] = pm->tb + ROT_DEBUG; + opm->p[n+0] = opm->tr; + opm->p[n+1] = opm->tg; + opm->p[n+2] = opm->tb + ROT_DEBUG; } + + /* center points */ + icx = ipm->sx/2; + icy = ipm->sy/2; + ocx = opm->sx/2; + ocy = opm->sy/2; + + rotr = rot / RND_RAD_TO_DEG; + cs = cos(rotr); + sn = sin(rotr); + + end = opm->sx * opm->sy; + + for(n = 0, o = opm->p, xo = yo = 0; n < end; n++, o+=3) { + int oor = 0; + long ixi, iyi; + double XO = xo - ocx, YO = yo - ocy, XI, YI; + + /* rotate */ + XI = icx + (cs * XO - sn * YO); + YI = icy + (sn * XO + cs * YO); + + /* get final input pixel address, clamp */ + ixi = rnd_round(XI); iyi = rnd_round(ipm->sy - YI); + if ((ixi < 0) || (iyi < 0) || (ixi >= ipm->sx) || (iyi >= ipm->sy)) + oor = 1; + else + i = ipm->p + (ixi + iyi * ipm->sx) * 3; + + if (oor) { + /* out pixel is transparent if out-of-range or input pixel is transparent */ + o[0] = opm->tr; + o[1] = opm->tg; + o[2] = opm->tb; + } + else { + o[0] = i[0]; + o[1] = i[1]; + o[2] = i[2]; + } + + xo++; + if (xo >= opm->sx) { + xo = 0; + yo++; + } + +#if 0 + if (n%4 == 0) { + o[0] = 100; + if (oor) + o[1] = 200; + } +#endif + +#if 0 + if ((n % dst->sx) == 0) printf("\n"); + printf("%d", i[0]/64); +#endif + } + + + + + + + + + + + + + + + +#if 0 ip = ipm->p; for(y = 0; y < ipm->sy; y++) { iy = y - ipm->sy/2; @@ -146,10 +223,11 @@ op[2] = ip[2]; } } +#endif TODO("create the transformed version if not in the cache already (by headers)"); - return pm; + return opm; } void pcb_pixmap_init(void)