/packages/x11/drawing.scm

https://github.com/glycerine/rscheme · Scheme · 278 lines · 241 code · 36 blank · 1 comment · 22 complexity · c8133e6167e8b69305a2008c71c551f0 MD5 · raw file

  1. (define-class <X-drawing-context> (<object>)
  2. x-display-ptr
  3. x-window-id
  4. xid
  5. origin-x
  6. origin-y
  7. x-window
  8. origin
  9. clip-rect)
  10. ;;
  11. (define-X-glue (fill-rectangle (ctx <X-drawing-context>)
  12. (rect <rect>))
  13. {
  14. XFillRectangle( ctx_dsp, ctx_win, ctx_gc,
  15. RECT_X(rect) + ctx_origin_x,
  16. RECT_Y(rect) + ctx_origin_y,
  17. RECT_W(rect), RECT_H(rect) );
  18. RETURN0();
  19. })
  20. (define-X-glue (draw-rectangle (ctx <X-drawing-context>)
  21. (rect <rect>))
  22. {
  23. XDrawRectangle( ctx_dsp, ctx_win, ctx_gc,
  24. RECT_X(rect) + ctx_origin_x,
  25. RECT_Y(rect) + ctx_origin_y,
  26. RECT_W(rect), RECT_H(rect) );
  27. RETURN0();
  28. })
  29. (define-X-glue (draw-line (ctx <X-drawing-context>)
  30. (from <point>)
  31. (to <point>))
  32. {
  33. XDrawLine( ctx_dsp, ctx_win, ctx_gc,
  34. POINT_X(from) + ctx_origin_x,
  35. POINT_Y(from) + ctx_origin_y,
  36. POINT_X(to) + ctx_origin_x,
  37. POINT_Y(to) + ctx_origin_y );
  38. RETURN0();
  39. })
  40. (define-X-glue (draw-box (ctx <X-drawing-context>)
  41. (frame <rect>)
  42. (edge_info <raw-string>)
  43. (colors <vector>))
  44. {
  45. unsigned char edge;
  46. unsigned char *info = edge_info;
  47. color_t c, prev;
  48. int x = RECT_X(frame) + ctx_origin_x;
  49. int y = RECT_Y(frame) + ctx_origin_y;
  50. int w = RECT_W(frame);
  51. int h = RECT_H(frame);
  52. prev = 0xFFFFFFFF; /* impossible color */
  53. while (1)
  54. {
  55. edge = *info++;
  56. c = fx2int( gvec_read( colors, SLOT(*info++ - '0') ) );
  57. if (c != prev)
  58. {
  59. XSetForeground( ctx_dsp, ctx_gc, c );
  60. prev = c;
  61. }
  62. switch (edge)
  63. {
  64. case '.':
  65. goto box_done;
  66. case 't':
  67. XFillRectangle( ctx_dsp, ctx_win, ctx_gc, x, y, w, 1 );
  68. y++;
  69. h--;
  70. break;
  71. case 'b':
  72. h--;
  73. XFillRectangle( ctx_dsp, ctx_win, ctx_gc, x, y+h, w, 1 );
  74. break;
  75. case 'l':
  76. XFillRectangle( ctx_dsp, ctx_win, ctx_gc, x, y, 1, h );
  77. x++;
  78. w--;
  79. break;
  80. case 'r':
  81. w--;
  82. XFillRectangle( ctx_dsp, ctx_win, ctx_gc, x+w, y, 1, h );
  83. break;
  84. }
  85. }
  86. box_done:
  87. XFillRectangle( ctx_dsp, ctx_win, ctx_gc, x, y, w, h );
  88. RETURN0();
  89. })
  90. (define-X-glue (set-tiled (ctx <X-drawing-context>) (tile <X-pixmap>))
  91. {
  92. XSetTile( ctx_dsp, ctx_gc, tile_xid );
  93. RETURN0();
  94. })
  95. (define-X-glue (set-stipple (ctx <X-drawing-context>) (stipple <X-pixmap>))
  96. {
  97. XSetStipple( ctx_dsp, ctx_gc, stipple_xid );
  98. RETURN0();
  99. })
  100. (define-X-glue (set-tile-origin (ctx <X-drawing-context>) (at <point>))
  101. {
  102. XSetTSOrigin( ctx_dsp, ctx_gc,
  103. POINT_X(at) + ctx_origin_x,
  104. POINT_Y(at) + ctx_origin_y );
  105. RETURN0();
  106. })
  107. (define-X-glue (set-clip-mask (ctx <X-drawing-context>)
  108. (mask <X-pixmap>)
  109. (at <point>))
  110. {
  111. XSetClipMask( ctx_dsp, ctx_gc, mask_xid );
  112. XSetClipOrigin( ctx_dsp, ctx_gc,
  113. POINT_X(at) + ctx_origin_x,
  114. POINT_Y(at) + ctx_origin_y );
  115. RETURN0();
  116. })
  117. (define-X-glue (set-no-clip-mask (ctx <X-drawing-context>))
  118. {
  119. XSetClipMask( ctx_dsp, ctx_gc, None );
  120. RETURN0();
  121. })
  122. (define-X-glue (set-foreground (ctx <X-drawing-context>)
  123. (color <raw-int>))
  124. {
  125. XSetForeground( ctx_dsp, ctx_gc, color );
  126. RETURN0();
  127. })
  128. (define-X-glue (set-background (ctx <X-drawing-context>)
  129. (color <raw-int>))
  130. {
  131. XSetBackground( ctx_dsp, ctx_gc, color );
  132. RETURN0();
  133. })
  134. (define-X-glue (copy-area (from <X-drawable>)
  135. (from_rect <rect>)
  136. (to <X-drawing-context>)
  137. (to_point <point>))
  138. {
  139. XCopyArea( to_dsp, from_xid, to_win, to_gc,
  140. RECT_X(from_rect),
  141. RECT_Y(from_rect),
  142. RECT_W(from_rect),
  143. RECT_H(from_rect),
  144. POINT_X(to_point) + to_origin_x,
  145. POINT_Y(to_point) + to_origin_y );
  146. RETURN0();
  147. })
  148. (define-X-glue (set-fill-style (ctx <X-drawing-context>) style)
  149. literals: ('FillSolid
  150. 'FillOpaqueStippled
  151. 'FillStippled
  152. 'FillTiled)
  153. {
  154. int style_choice = FillSolid;
  155. if (EQ(style,LITERAL(1)))
  156. style_choice = FillOpaqueStippled;
  157. else if (EQ(style,LITERAL(2)))
  158. style_choice = FillStippled;
  159. else if (EQ(style,LITERAL(3)))
  160. style_choice = FillTiled;
  161. XSetFillStyle( ctx_dsp, ctx_gc, style_choice );
  162. RETURN0();
  163. })
  164. (define-method initialize ((self <X-drawing-context>))
  165. (set-origin! self (make <point>
  166. x: 0
  167. y: 0))
  168. (set-clip-rect! self (make-rect -8000 -8000 16000 16000))
  169. self)
  170. (define-X-glue (create-drawing-context (window <X-drawable>))
  171. literals: ((& <X-drawing-context>)
  172. (& initialize))
  173. {
  174. obj gc;
  175. GC the_gc;
  176. the_gc = XCreateGC( window_dsp, window_xid, 0, 0 );
  177. gc = alloc( SLOT(8), TLREF(0) );
  178. gvec_write_fresh( gc, SLOT(0), gvec_read( raw_window, SLOT(0) ) );
  179. gvec_write_fresh( gc, SLOT(1), gvec_read( raw_window, SLOT(1) ) );
  180. gvec_write_fresh( gc, SLOT(2), RAW_PTR_TO_OBJ(the_gc) );
  181. gvec_write_fresh( gc, SLOT(3), ZERO );
  182. gvec_write_fresh( gc, SLOT(4), ZERO );
  183. gvec_write_fresh( gc, SLOT(5), raw_window );
  184. gvec_write_fresh( gc, SLOT(6), UNINITIALIZED_OBJ );
  185. gvec_write_fresh( gc, SLOT(7), UNINITIALIZED_OBJ );
  186. REG0 = gc;
  187. APPLY(1, TLREF(1));
  188. })
  189. (define-X-glue (set-dashes (ctx <X-drawing-context>)
  190. (dash_offset <raw-int>)
  191. (dashes <vector>))
  192. {
  193. char dash_list[10];
  194. int i, n;
  195. n = SIZEOF_PTR( dashes ) / SLOT(1);
  196. if (n > 10)
  197. n = 10;
  198. for (i=0; i<n; i++)
  199. dash_list[i] = fx2int( gvec_read( dashes, SLOT(i) ) );
  200. XSetDashes( ctx_dsp, ctx_gc, dash_offset, dash_list, n );
  201. RETURN0();
  202. })
  203. (define-X-glue (set-line-attributes (ctx <X-drawing-context>)
  204. (line_width <raw-int>)
  205. line_style
  206. cap_style
  207. join_style)
  208. literals: ('LineSolid
  209. 'LineOnOffDash
  210. 'LineDoubleDash
  211. 'CapButt
  212. 'CapNotLast
  213. 'CapRound
  214. 'CapProjecting
  215. 'JoinMiter
  216. 'JoinRound
  217. 'JoinBevel)
  218. {
  219. int line_style_choice, cap_style_choice, join_style_choice;
  220. line_style_choice = LineSolid;
  221. if (EQ(line_style,LITERAL(1)))
  222. line_style_choice = LineOnOffDash;
  223. else if (EQ(line_style,LITERAL(2)))
  224. line_style_choice = LineDoubleDash;
  225. cap_style_choice = CapButt;
  226. if (EQ(cap_style,LITERAL(4)))
  227. cap_style_choice = CapNotLast;
  228. else if (EQ(cap_style,LITERAL(5)))
  229. cap_style_choice = CapRound;
  230. else if (EQ(cap_style,LITERAL(6)))
  231. cap_style_choice = CapProjecting;
  232. join_style_choice = JoinMiter;
  233. if (EQ(join_style,LITERAL(8)))
  234. join_style_choice = JoinRound;
  235. else if (EQ(join_style,LITERAL(9)))
  236. join_style_choice = JoinBevel;
  237. XSetLineAttributes( ctx_dsp, ctx_gc, line_width,
  238. line_style_choice,
  239. cap_style_choice,
  240. join_style_choice );
  241. RETURN0();
  242. })