cbits.c 3.4 KB

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