1 #include "lib9.h" 2 #include "draw.h" 3 #include "tk.h" 4 #include "canvs.h" 5 6 #define O(t, e) ((long)(&((t*)0)->e)) 7 8 /* Bitmap Options (+ means implemented) 9 +anchor 10 +bitmap 11 */ 12 13 typedef struct TkCbits TkCbits; 14 struct TkCbits 15 { 16 int anchor; 17 Point anchorp; 18 Image* bitmap; 19 }; 20 21 static 22 TkOption bitopts[] = 23 { 24 "anchor", OPTstab, O(TkCbits, anchor), tkanchor, 25 "bitmap", OPTbmap, O(TkCbits, bitmap), nil, 26 nil 27 }; 28 29 static 30 TkOption itemopts[] = 31 { 32 "tags", OPTctag, O(TkCitem, tags), nil, 33 "background", OPTcolr, O(TkCitem, env), IAUX(TkCbackgnd), 34 "foreground", OPTcolr, O(TkCitem, env), IAUX(TkCforegnd), 35 nil 36 }; 37 38 void 39 tkcvsbitsize(TkCitem *i) 40 { 41 Point o; 42 int dx, dy; 43 TkCbits *b; 44 45 b = TKobj(TkCbits, i); 46 i->p.bb = bbnil; 47 if(b->bitmap == nil) 48 return; 49 50 dx = Dx(b->bitmap->r); 51 dy = Dy(b->bitmap->r); 52 53 o = tkcvsanchor(i->p.drawpt[0], dx, dy, b->anchor); 54 55 i->p.bb.min.x = o.x; 56 i->p.bb.min.y = o.y; 57 i->p.bb.max.x = o.x + dx; 58 i->p.bb.max.y = o.y + dy; 59 b->anchorp = subpt(o, i->p.drawpt[0]); 60 } 61 62 char* 63 tkcvsbitcreat(Tk* tk, char *arg, char **val) 64 { 65 char *e; 66 TkCbits *b; 67 TkCitem *i; 68 TkCanvas *c; 69 TkOptab tko[3]; 70 71 c = TKobj(TkCanvas, tk); 72 73 i = tkcnewitem(tk, TkCVbitmap, sizeof(TkCitem)+sizeof(TkCbits)); 74 if(i == nil) 75 return TkNomem; 76 77 b = TKobj(TkCbits, i); 78 79 e = tkparsepts(tk->env->top, &i->p, &arg, 0); 80 if(e != nil) { 81 tkcvsfreeitem(i); 82 return e; 83 } 84 if(i->p.npoint != 1) { 85 tkcvsfreeitem(i); 86 return TkFewpt; 87 } 88 89 tko[0].ptr = b; 90 tko[0].optab = bitopts; 91 tko[1].ptr = i; 92 tko[1].optab = itemopts; 93 tko[2].ptr = nil; 94 e = tkparse(tk->env->top, arg, tko, nil); 95 if(e != nil) { 96 tkcvsfreeitem(i); 97 return e; 98 } 99 100 e = tkcaddtag(tk, i, 1); 101 if(e != nil) { 102 tkcvsfreeitem(i); 103 return e; 104 } 105 106 tkcvsbitsize(i); 107 tkcvsappend(c, i); 108 109 tkbbmax(&c->update, &i->p.bb); 110 tkcvssetdirty(tk); 111 return tkvalue(val, "%d", i->id); 112 } 113 114 char* 115 tkcvsbitcget(TkCitem *i, char *arg, char **val) 116 { 117 TkOptab tko[3]; 118 TkCbits *b = TKobj(TkCbits, i); 119 120 tko[0].ptr = b; 121 tko[0].optab = bitopts; 122 tko[1].ptr = i; 123 tko[1].optab = itemopts; 124 tko[2].ptr = nil; 125 126 return tkgencget(tko, arg, val, i->env->top); 127 } 128 129 char* 130 tkcvsbitconf(Tk *tk, TkCitem *i, char *arg) 131 { 132 char *e; 133 TkOptab tko[3]; 134 TkCbits *b = TKobj(TkCbits, i); 135 136 tko[0].ptr = b; 137 tko[0].optab = bitopts; 138 tko[1].ptr = i; 139 tko[1].optab = itemopts; 140 tko[2].ptr = nil; 141 142 e = tkparse(tk->env->top, arg, tko, nil); 143 tkcvsbitsize(i); 144 return e; 145 } 146 147 void 148 tkcvsbitfree(TkCitem *i) 149 { 150 TkCbits *b; 151 152 b = TKobj(TkCbits, i); 153 if(b->bitmap) 154 freeimage(b->bitmap); 155 } 156 157 void 158 tkcvsbitdraw(Image *img, TkCitem *i, TkEnv *pe) 159 { 160 TkEnv *e; 161 TkCbits *b; 162 Rectangle r; 163 Image *bi; 164 165 USED(pe); 166 167 e = i->env; 168 b = TKobj(TkCbits, i); 169 170 bi = b->bitmap; 171 if(bi == nil) 172 return; 173 174 r.min = addpt(b->anchorp, i->p.drawpt[0]); 175 r.max = r.min; 176 r.max.x += Dx(bi->r); 177 r.max.y += Dy(bi->r); 178 179 if(bi->depth != 1) { 180 draw(img, r, bi, nil, ZP); 181 return; 182 } 183 gendraw(img, r, tkgc(e, TkCbackgnd), r.min, nil, ZP); 184 draw(img, r, tkgc(e, TkCforegnd), bi, ZP); 185 } 186 187 char* 188 tkcvsbitcoord(TkCitem *i, char *arg, int x, int y) 189 { 190 char *e; 191 TkCpoints p; 192 193 if(arg == nil) { 194 tkxlatepts(i->p.parampt, i->p.npoint, x, y); 195 tkxlatepts(i->p.drawpt, i->p.npoint, TKF2I(x), TKF2I(y)); 196 i->p.bb = rectaddpt(i->p.bb, Pt(TKF2I(x), TKF2I(y))); 197 } 198 else { 199 e = tkparsepts(i->env->top, &p, &arg, 0); 200 if(e != nil) 201 return e; 202 if(p.npoint != 1) { 203 tkfreepoint(&p); 204 return TkFewpt; 205 } 206 tkfreepoint(&i->p); 207 i->p = p; 208 tkcvsbitsize(i); 209 } 210 return nil; 211 } 212