1 /*	Public domain	*/
2 
3 /*
4  * Primitive GUI rendering routines.
5  */
6 
7 #ifndef _AGAR_GUI_PRIMITIVE_H_
8 #define _AGAR_GUI_PRIMITIVE_H_
9 
10 #include <agar/gui/widget.h>
11 
12 #include <agar/gui/begin.h>
13 
14 __BEGIN_DECLS
15 /* Increment individual RGB components of a pixel. */
16 /* XXX TODO use SIMD where available */
17 static __inline__ AG_Color
AG_ColorShift(AG_Color C,Sint8 * shift)18 AG_ColorShift(AG_Color C, Sint8 *shift)
19 {
20 	int r = C.r + shift[0];
21 	int g = C.g + shift[1];
22 	int b = C.b + shift[2];
23 
24 	if (r > 255) { r = 255; } else if (r < 0) { r = 0; }
25 	if (g > 255) { g = 255; } else if (g < 0) { g = 0; }
26 	if (b > 255) { b = 255; } else if (b < 0) { b = 0; }
27 
28 	C.r = (Uint8)r;
29 	C.g = (Uint8)g;
30 	C.b = (Uint8)b;
31 	return (C);
32 }
33 
34 /*
35  * Calls to rendering routines implemented by the underlying driver.
36  */
37 
38 /* Write a pixel (AG_Color argument) */
39 static __inline__ void
AG_PutPixel(void * obj,int x,int y,AG_Color C)40 AG_PutPixel(void *obj, int x, int y, AG_Color C)
41 {
42 	AG_Widget *wid = (AG_Widget *)obj;
43 
44 	wid->drvOps->putPixel(wid->drv,
45 	    wid->rView.x1 + x,
46 	    wid->rView.y1 + y,
47 	    C);
48 }
49 
50 /* Write a pixel (32-bit videoFmt argument) */
51 static __inline__ void
AG_PutPixel32(void * obj,int x,int y,Uint32 c)52 AG_PutPixel32(void *obj, int x, int y, Uint32 c)
53 {
54 	AG_Widget *wid = (AG_Widget *)obj;
55 
56 	wid->drvOps->putPixel32(wid->drv,
57 	    wid->rView.x1 + x,
58 	    wid->rView.y1 + y,
59 	    c);
60 }
61 
62 /* Write a pixel (RGB arguments) */
63 static __inline__ void
AG_PutPixelRGB(void * obj,int x,int y,Uint8 r,Uint8 g,Uint8 b)64 AG_PutPixelRGB(void *obj, int x, int y, Uint8 r, Uint8 g, Uint8 b)
65 {
66 	AG_Widget *wid = (AG_Widget *)obj;
67 
68 	wid->drvOps->putPixelRGB(wid->drv,
69 	    wid->rView.x1 + x,
70 	    wid->rView.y1 + y,
71 	    r,g,b);
72 }
73 
74 /* Blend a pixel (AG_Color argument) */
75 static __inline__ void
AG_BlendPixel(void * obj,int x,int y,AG_Color C,AG_BlendFn fnSrc)76 AG_BlendPixel(void *obj, int x, int y, AG_Color C, AG_BlendFn fnSrc)
77 {
78 	AG_Widget *wid = (AG_Widget *)obj;
79 
80 	wid->drvOps->blendPixel(wid->drv,
81 	    wid->rView.x1 + x,
82 	    wid->rView.y1 + y,
83 	    C, fnSrc, AG_ALPHA_ZERO);
84 }
85 
86 /* Blend a pixel (32-bit agSurfaceFmt argument) */
87 static __inline__ void
AG_BlendPixel32(void * obj,int x,int y,Uint32 px,AG_BlendFn fnSrc)88 AG_BlendPixel32(void *obj, int x, int y, Uint32 px, AG_BlendFn fnSrc)
89 {
90 	AG_Widget *wid = (AG_Widget *)obj;
91 	AG_Color C = AG_GetColorRGBA(px, agSurfaceFmt);
92 
93 	wid->drvOps->blendPixel(wid->drv,
94 	    wid->rView.x1 + x,
95 	    wid->rView.y1 + y,
96 	    C, fnSrc, AG_ALPHA_ZERO);
97 }
98 
99 /* Blend a pixel (RGBA arguments) */
100 static __inline__ void
AG_BlendPixelRGBA(void * obj,int x,int y,Uint8 c[4],AG_BlendFn fnSrc)101 AG_BlendPixelRGBA(void *obj, int x, int y, Uint8 c[4], AG_BlendFn fnSrc)
102 {
103 	AG_Widget *wid = (AG_Widget *)obj;
104 
105 	wid->drvOps->blendPixel(wid->drv,
106 	    wid->rView.x1 + x,
107 	    wid->rView.y1 + y,
108 	    AG_ColorRGBA(c[0],c[1],c[2],c[3]),
109 	    fnSrc, AG_ALPHA_ZERO);
110 }
111 
112 /* Render a line from two endpoints. */
113 static __inline__ void
AG_DrawLine(void * obj,int x1,int y1,int x2,int y2,AG_Color C)114 AG_DrawLine(void *obj, int x1, int y1, int x2, int y2, AG_Color C)
115 {
116 	AG_Widget *wid = (AG_Widget *)obj;
117 
118 	wid->drvOps->drawLine(wid->drv,
119 	    wid->rView.x1 + x1,
120 	    wid->rView.y1 + y1,
121 	    wid->rView.x1 + x2,
122 	    wid->rView.y1 + y2,
123 	    C);
124 }
125 
126 /* Render a horizontal line. */
127 static __inline__ void
AG_DrawLineH(void * obj,int x1,int x2,int y,AG_Color C)128 AG_DrawLineH(void *obj, int x1, int x2, int y, AG_Color C)
129 {
130 	AG_Widget *wid = (AG_Widget *)obj;
131 
132 	wid->drvOps->drawLineH(wid->drv,
133 	    wid->rView.x1 + x1,
134 	    wid->rView.x1 + x2,
135 	    wid->rView.y1 + y,
136 	    C);
137 }
138 
139 /* Render a vertical line. */
140 static __inline__ void
AG_DrawLineV(void * obj,int x,int y1,int y2,AG_Color C)141 AG_DrawLineV(void *obj, int x, int y1, int y2, AG_Color C)
142 {
143 	AG_Widget *wid = (AG_Widget *)obj;
144 
145 	wid->drvOps->drawLineV(wid->drv,
146 	    wid->rView.x1 + x,
147 	    wid->rView.y1 + y1,
148 	    wid->rView.y1 + y2,
149 	    C);
150 }
151 
152 /* Render a line with blending. */
153 static __inline__ void
AG_DrawLineBlended(void * obj,int x1,int y1,int x2,int y2,AG_Color C,AG_BlendFn fnSrc)154 AG_DrawLineBlended(void *obj, int x1, int y1, int x2, int y2, AG_Color C,
155     AG_BlendFn fnSrc)
156 {
157 	AG_Widget *wid = (AG_Widget *)obj;
158 
159 	wid->drvOps->drawLineBlended(wid->drv,
160 	    wid->rView.x1 + x1,
161 	    wid->rView.y1 + y1,
162 	    wid->rView.x1 + x2,
163 	    wid->rView.y1 + y2,
164 	    C, fnSrc, AG_ALPHA_ZERO);
165 }
166 
167 /* Render an arrow pointing up. */
168 static __inline__ void
AG_DrawArrowUp(void * obj,int x0,int y0,int h,AG_Color c1,AG_Color c2)169 AG_DrawArrowUp(void *obj, int x0, int y0, int h, AG_Color c1, AG_Color c2)
170 {
171 	AG_Widget *wid = (AG_Widget *)obj;
172 	AG_Color c[2];
173 
174 	c[0] = c1;
175 	c[1] = c2;
176 	wid->drvOps->drawArrowUp(wid->drv,
177 	    wid->rView.x1 + x0,
178 	    wid->rView.y1 + y0,
179 	    h, c);
180 }
181 
182 /* Render an arrow pointing down. */
183 static __inline__ void
AG_DrawArrowDown(void * obj,int x0,int y0,int h,AG_Color c1,AG_Color c2)184 AG_DrawArrowDown(void *obj, int x0, int y0, int h, AG_Color c1, AG_Color c2)
185 {
186 	AG_Widget *wid = (AG_Widget *)obj;
187 	AG_Color c[2];
188 
189 	c[0] = c1;
190 	c[1] = c2;
191 	wid->drvOps->drawArrowDown(wid->drv,
192 	    wid->rView.x1 + x0,
193 	    wid->rView.y1 + y0,
194 	    h, c);
195 }
196 
197 /* Render an arrow pointing left. */
198 static __inline__ void
AG_DrawArrowLeft(void * obj,int x0,int y0,int h,AG_Color c1,AG_Color c2)199 AG_DrawArrowLeft(void *obj, int x0, int y0, int h, AG_Color c1, AG_Color c2)
200 {
201 	AG_Widget *wid = (AG_Widget *)obj;
202 	AG_Color c[2];
203 
204 	c[0] = c1;
205 	c[1] = c2;
206 	wid->drvOps->drawArrowLeft(wid->drv,
207 	    wid->rView.x1 + x0,
208 	    wid->rView.y1 + y0,
209 	    h, c);
210 }
211 
212 /* Render an arrow pointing right. */
213 static __inline__ void
AG_DrawArrowRight(void * obj,int x0,int y0,int h,AG_Color c1,AG_Color c2)214 AG_DrawArrowRight(void *obj, int x0, int y0, int h, AG_Color c1, AG_Color c2)
215 {
216 	AG_Widget *wid = (AG_Widget *)obj;
217 	AG_Color c[2];
218 
219 	c[0] = c1;
220 	c[1] = c2;
221 	wid->drvOps->drawArrowRight(wid->drv,
222 	    wid->rView.x1 + x0,
223 	    wid->rView.y1 + y0,
224 	    h, c);
225 }
226 
227 /* Render a 3D-style box with rounded edges. */
228 static __inline__ void
AG_DrawBoxRounded(void * obj,AG_Rect r,int z,int rad,AG_Color cBg)229 AG_DrawBoxRounded(void *obj, AG_Rect r, int z, int rad, AG_Color cBg)
230 {
231 	AG_Widget *wid = (AG_Widget *)obj;
232 	AG_Color c[3];
233 
234 	AG_WidgetOffsetRect(wid, &r);
235 
236 	c[0] = AG_ColorShift(cBg, (z<0) ? agSunkColorShift : agRaisedColorShift);
237 	c[1] = AG_ColorShift(c[0], (z<0) ? agLowColorShift : agHighColorShift);
238 	c[2] = AG_ColorShift(c[0], (z<0) ? agHighColorShift : agLowColorShift);
239 	wid->drvOps->drawBoxRounded(wid->drv, r, z, rad, c);
240 }
241 
242 /* Render a 3D-style box with rounded top edges. */
243 static __inline__ void
AG_DrawBoxRoundedTop(void * obj,AG_Rect r,int z,int rad,AG_Color cBg)244 AG_DrawBoxRoundedTop(void *obj, AG_Rect r, int z, int rad, AG_Color cBg)
245 {
246 	AG_Widget *wid = (AG_Widget *)obj;
247 	AG_Color c[3];
248 
249 	AG_WidgetOffsetRect(wid, &r);
250 	c[0] = cBg;
251 	c[1] = AG_ColorShift(c[0], (z<0)?agLowColorShift:agHighColorShift);
252 	c[2] = AG_ColorShift(c[0], (z<0)?agHighColorShift:agLowColorShift);
253 	wid->drvOps->drawBoxRoundedTop(wid->drv, r, z, rad, c);
254 }
255 
256 /* Render a circle of specified radius. */
257 static __inline__ void
AG_DrawCircle(void * obj,int x,int y,int r,AG_Color c)258 AG_DrawCircle(void *obj, int x, int y, int r, AG_Color c)
259 {
260 	AG_Widget *wid = (AG_Widget *)obj;
261 
262 	wid->drvOps->drawCircle(wid->drv,
263 	    wid->rView.x1 + x,
264 	    wid->rView.y1 + y,
265 	    r, c);
266 }
267 
268 /* Render a circle of specified radius. */
269 static __inline__ void
AG_DrawCircleFilled(void * obj,int x,int y,int r,AG_Color c)270 AG_DrawCircleFilled(void *obj, int x, int y, int r, AG_Color c)
271 {
272 	AG_Widget *wid = (AG_Widget *)obj;
273 
274 	wid->drvOps->drawCircleFilled(wid->drv,
275 	    wid->rView.x1 + x,
276 	    wid->rView.y1 + y,
277 	    r, c);
278 }
279 
280 /* Render a filled rectangle (opaque or transparent). */
281 static __inline__ void
AG_DrawRect(void * obj,AG_Rect r,AG_Color c)282 AG_DrawRect(void *obj, AG_Rect r, AG_Color c)
283 {
284 	AG_Widget *wid = (AG_Widget *)obj;
285 
286 	AG_WidgetOffsetRect(wid, &r);
287 	if (c.a < AG_ALPHA_OPAQUE) {
288 		wid->drvOps->drawRectBlended(wid->drv, r, c,
289 		    AG_ALPHA_SRC, AG_ALPHA_ONE_MINUS_SRC);
290 	} else {
291 		wid->drvOps->drawRectFilled(wid->drv, r, c);
292 	}
293 }
294 
295 /* Render a filled rectangle (opaque). */
296 static __inline__ void
AG_DrawRectFilled(void * obj,AG_Rect r,AG_Color c)297 AG_DrawRectFilled(void *obj, AG_Rect r, AG_Color c)
298 {
299 	AG_Widget *wid = (AG_Widget *)obj;
300 
301 	AG_WidgetOffsetRect(wid, &r);
302 	wid->drvOps->drawRectFilled(wid->drv, r, c);
303 }
304 
305 /* Render a filled rectangle (transparent). */
306 static __inline__ void
AG_DrawRectBlended(void * obj,AG_Rect r,AG_Color c,AG_BlendFn fnSrc)307 AG_DrawRectBlended(void *obj, AG_Rect r, AG_Color c, AG_BlendFn fnSrc)
308 {
309 	AG_Widget *wid = (AG_Widget *)obj;
310 
311 	AG_WidgetOffsetRect(wid, &r);
312 	wid->drvOps->drawRectBlended(wid->drv, r, c,
313 	    fnSrc, AG_ALPHA_ONE_MINUS_SRC);
314 }
315 
316 /* Render a filled rectangle with dithering. */
317 static __inline__ void
AG_DrawRectDithered(void * obj,AG_Rect r,AG_Color c)318 AG_DrawRectDithered(void *obj, AG_Rect r, AG_Color c)
319 {
320 	AG_Widget *wid = (AG_Widget *)obj;
321 
322 	AG_WidgetOffsetRect(wid, &r);
323 	wid->drvOps->drawRectDithered(wid->drv, r, c);
324 }
325 
326 
327 /* Render a 3D-style frame. */
328 static __inline__ void
AG_DrawFrame(void * obj,AG_Rect r,int z,AG_Color cBase)329 AG_DrawFrame(void *obj, AG_Rect r, int z, AG_Color cBase)
330 {
331 	AG_Widget *wid = (AG_Widget *)obj;
332 	AG_Driver *drv = wid->drv;
333 	AG_DriverClass *drvOps = wid->drvOps;
334 	AG_Color c[2];
335 	int y2, x2;
336 
337 	AG_WidgetOffsetRect(wid, &r);
338 	c[0] = AG_ColorShift(cBase, (z<0)?agLowColorShift:agHighColorShift);
339 	c[1] = AG_ColorShift(cBase, (z<0)?agHighColorShift:agLowColorShift);
340 	x2 = r.x+r.w - 1;
341 	y2 = r.y+r.h - 1;
342 
343 	if (c[0].a < AG_ALPHA_OPAQUE) {
344 		drvOps->drawLineBlended(drv, r.x, r.y, x2,  r.y, c[0], AG_ALPHA_SRC, AG_ALPHA_ZERO);
345 		drvOps->drawLineBlended(drv, r.x, r.y, r.x, y2,  c[0], AG_ALPHA_SRC, AG_ALPHA_ZERO);
346 	} else {
347 		drvOps->drawLineH(drv, r.x, x2,  r.y, c[0]);
348 		drvOps->drawLineV(drv, r.x, r.y, y2,  c[0]);
349 	}
350 	if (c[1].a < AG_ALPHA_OPAQUE) {
351 		drvOps->drawLineBlended(drv, r.x, y2,  x2, y2, c[1], AG_ALPHA_SRC, AG_ALPHA_ZERO);
352 		drvOps->drawLineBlended(drv, x2,  r.y, x2, y2, c[1], AG_ALPHA_SRC, AG_ALPHA_ZERO);
353 	} else {
354 		drvOps->drawLineH(drv, r.x, x2,  y2, c[1]);
355 		drvOps->drawLineV(drv, x2,  r.y, y2, c[1]);
356 	}
357 }
358 
359 /*
360  * Miscellaneous, utility rendering routines.
361  */
362 
363 /* Render a 3D-style box. */
364 static __inline__ void
AG_DrawBox(void * obj,AG_Rect r,int z,AG_Color c)365 AG_DrawBox(void *obj, AG_Rect r, int z, AG_Color c)
366 {
367 	AG_Widget *wid = (AG_Widget *)obj;
368 	AG_Driver *drv = wid->drv;
369 	AG_Rect rOffs;
370 
371 	c = AG_ColorShift(c, (z < 0) ? agSunkColorShift : agRaisedColorShift);
372 	rOffs = r;
373 	AG_WidgetOffsetRect(wid, &rOffs);
374 	if (c.a < AG_ALPHA_OPAQUE) {
375 		wid->drvOps->drawRectBlended(drv, rOffs, c,
376 		    AG_ALPHA_SRC, AG_ALPHA_ONE_MINUS_SRC);
377 	} else {
378 		wid->drvOps->drawRectFilled(drv, rOffs, c);
379 	}
380 	AG_DrawFrame(wid, r, z, c);
381 }
382 
383 /* Render a 3D-style box with disabled control-style dithering. */
384 static __inline__ void
AG_DrawBoxDisabled(void * obj,AG_Rect r,int z,AG_Color cBox,AG_Color cDither)385 AG_DrawBoxDisabled(void *obj, AG_Rect r, int z, AG_Color cBox, AG_Color cDither)
386 {
387 	AG_Widget *wid = (AG_Widget *)obj;
388 	AG_Rect rOffs;
389 
390 	cDither = AG_ColorShift(cDither, (z < 0) ? agSunkColorShift : agRaisedColorShift);
391 	rOffs = r;
392 	AG_WidgetOffsetRect(wid, &rOffs);
393 	wid->drvOps->drawRectFilled(wid->drv, rOffs, cBox);
394 	AG_DrawFrame(wid, r, z, cBox);
395 	wid->drvOps->drawRectDithered(wid->drv, rOffs, cDither);
396 }
397 
398 /* Render 3D-style frame using a specific blending mode. */
399 static __inline__ void
AG_DrawFrameBlended(void * obj,AG_Rect r,AG_Color C,AG_BlendFn fnSrc)400 AG_DrawFrameBlended(void *obj, AG_Rect r, AG_Color C, AG_BlendFn fnSrc)
401 {
402 	AG_Widget *wid = (AG_Widget *)obj;
403 	AG_Driver *drv = wid->drv;
404 	AG_DriverClass *drvOps = wid->drvOps;
405 	int x2, y2;
406 
407 	AG_WidgetOffsetRect(wid, &r);
408 	x2 = r.x+r.w - 1;
409 	y2 = r.y+r.h - 1;
410 	drvOps->drawLineBlended(drv, r.x, r.y, x2,  r.y, C, fnSrc, AG_ALPHA_ZERO);
411 	drvOps->drawLineBlended(drv, r.x, r.y, r.x, y2,  C, fnSrc, AG_ALPHA_ZERO);
412 	drvOps->drawLineBlended(drv, r.x, y2,  x2,  y2,  C, fnSrc, AG_ALPHA_ZERO);
413 	drvOps->drawLineBlended(drv, x2,  r.y, x2,  y2,  C, fnSrc, AG_ALPHA_ZERO);
414 }
415 
416 /* Render a rectangle outline. */
417 static __inline__ void
AG_DrawRectOutline(void * obj,AG_Rect r,AG_Color c)418 AG_DrawRectOutline(void *obj, AG_Rect r, AG_Color c)
419 {
420 	AG_Widget *wid = (AG_Widget *)obj;
421 	AG_Driver *drv = wid->drv;
422 	AG_DriverClass *drvOps = wid->drvOps;
423 	int x2, y2;
424 
425 	AG_WidgetOffsetRect(wid, &r);
426 	x2 = r.x+r.w - 1;
427 	y2 = r.y+r.h - 1;
428 	if (c.a < AG_ALPHA_OPAQUE) {
429 		drvOps->drawLineBlended(drv, r.x, r.y, x2,  r.y, c, AG_ALPHA_SRC, AG_ALPHA_ZERO);
430 		drvOps->drawLineBlended(drv, r.x, r.y, x2,  y2,  c, AG_ALPHA_SRC, AG_ALPHA_ZERO);
431 		drvOps->drawLineBlended(drv, r.x, r.y, r.x, y2,  c, AG_ALPHA_SRC, AG_ALPHA_ZERO);
432 		drvOps->drawLineBlended(drv, x2,  r.y, r.x, y2,  c, AG_ALPHA_SRC, AG_ALPHA_ZERO);
433 	} else {
434 		drvOps->drawLineH(drv, r.x, x2,  r.y, c);
435 		drvOps->drawLineH(drv, r.x, x2,  y2,  c);
436 		drvOps->drawLineV(drv, r.x, r.y, y2,  c);
437 		drvOps->drawLineV(drv, x2,  r.y, y2,  c);
438 	}
439 }
440 
441 /* Render a [+] sign. */
442 static __inline__ void
AG_DrawPlus(void * obj,AG_Rect r,AG_Color C,AG_BlendFn fnSrc)443 AG_DrawPlus(void *obj, AG_Rect r, AG_Color C, AG_BlendFn fnSrc)
444 {
445 	AG_Widget *wid = (AG_Widget *)obj;
446 	AG_Driver *drv = wid->drv;
447 	int x1, y1;
448 
449 	AG_WidgetOffsetRect(wid, &r);
450 	x1 = r.x + r.w/2;
451 	y1 = r.y + r.h/2;
452 	wid->drvOps->drawLineBlended(drv, x1,  r.y, x1,      r.y+r.h, C, fnSrc, AG_ALPHA_ZERO);
453 	wid->drvOps->drawLineBlended(drv, r.x, y1,  r.x+r.w, y1,      C, fnSrc, AG_ALPHA_ZERO);
454 }
455 
456 /* Render a [-] sign. */
457 static __inline__ void
AG_DrawMinus(void * obj,AG_Rect r,AG_Color C,AG_BlendFn fnSrc)458 AG_DrawMinus(void *obj, AG_Rect r, AG_Color C, AG_BlendFn fnSrc)
459 {
460 	AG_Widget *wid = (AG_Widget *)obj;
461 	int x, y;
462 
463 	AG_WidgetOffsetRect(wid, &r);
464 	x = r.x + r.w/2;
465 	y = r.y + r.h/2;
466 	wid->drvOps->drawLineBlended(wid->drv, x,y, r.x+r.w, y, C, fnSrc, AG_ALPHA_ZERO);
467 }
468 
469 /* Render a 3D-style line. */
470 static __inline__ void
AG_DrawLine2(void * obj,int x1,int y1,int x2,int y2,AG_Color color)471 AG_DrawLine2(void *obj, int x1, int y1, int x2, int y2, AG_Color color)
472 {
473 	AG_Widget *wid = (AG_Widget *)obj;
474 
475 	x1 += wid->rView.x1;
476 	y1 += wid->rView.y1;
477 	x2 += wid->rView.x1;
478 	y2 += wid->rView.y1;
479 	wid->drvOps->drawLine(wid->drv, x1, y1, x2, y2,
480 	    AG_ColorShift(color, agHighColorShift));
481 	wid->drvOps->drawLine(wid->drv, x1+1, y1+1, x2+1, y2+1,
482 	    AG_ColorShift(color, agLowColorShift));
483 }
484 
485 /* Render a gimp-style background tiling. */
486 static __inline__ void
AG_DrawTiling(void * obj,AG_Rect r,int tsz,int offs,AG_Color c1,AG_Color c2)487 AG_DrawTiling(void *obj, AG_Rect r, int tsz, int offs, AG_Color c1, AG_Color c2)
488 {
489 	AG_Widget *wid = (AG_Widget *)obj;
490 	AG_Driver *drv = wid->drv;
491 	int alt1 = 0, alt2 = 0;
492 	AG_Rect rt;
493 
494 	AG_WidgetOffsetRect(wid, &r);
495 
496 	rt.w = tsz;
497 	rt.h = tsz;
498 
499 	/* XXX inelegant */
500 	for (rt.y = r.y-tsz+offs;
501 	     rt.y < r.y+r.h;
502 	     rt.y += tsz) {
503 		for (rt.x = r.x-tsz+offs;
504 		     rt.x < r.x+r.w;
505 		     rt.x += tsz) {
506 			if (alt1++ == 1) {
507 				wid->drvOps->drawRectFilled(drv, rt, c1);
508 				alt1 = 0;
509 			} else {
510 				wid->drvOps->drawRectFilled(drv, rt, c2);
511 			}
512 		}
513 		if (alt2++ == 1) {
514 			alt2 = 0;
515 		}
516 		alt1 = alt2;
517 	}
518 }
519 __END_DECLS
520 
521 #include <agar/gui/close.h>
522 #endif	/* _AGAR_GUI_PRIMITIVE_H_ */
523