1 /*****************************************************************************
2 * This file is part of gfxprim library. *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
19 * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
20 * <jiri.bluebear.dluhos@gmail.com> *
22 * Copyright (C) 2009-2013 Cyril Hrubis <metan@ucw.cz> *
24 *****************************************************************************/
31 static GP_Context
*win
;
32 static GP_Backend
*backend
;
34 /* Basic colors in display-specific format. */
35 static GP_Pixel black
, white
, yellow
, green
, red
, gray
, darkgray
;
37 /* Radius of the shape being drawn */
38 static int xradius
= 5;
39 static int yradius
= 5;
41 /* Draw outline? 0=none, 1=before filling, 2=after filling */
42 static int outline
= 0;
48 static int show_axes
= 1;
50 /* Shape to be drawn */
52 #define SHAPE_TRIANGLE 1
53 #define SHAPE_CIRCLE 2
55 #define SHAPE_ELLIPSE 4
56 #define SHAPE_RECTANGLE 5
57 #define SHAPE_TETRAGON 6
58 #define SHAPE_POLYGON 7
61 static int shape
= SHAPE_FIRST
;
63 /* Variants in coordinates, if applicable */
64 static int variant
= 1;
66 /* center of drawing */
70 void draw_testing_triangle(int x
, int y
, int xradius
, int yradius
)
72 int x0
, y0
, x1
, y1
, x2
, y2
;
95 x2
= x
- xradius
+ xradius
/8;
109 /* draw the three vertices green; they should never be visible
110 * because the red triangle should cover them; if they are visible,
111 * it means we don't draw to the end */
112 GP_PutPixel(win
, x0
, y0
, green
);
113 GP_PutPixel(win
, x1
, y1
, green
);
114 GP_PutPixel(win
, x2
, y2
, green
);
117 GP_Triangle(win
, x0
, y0
, x1
, y1
, x2
, y2
, yellow
);
120 GP_FillTriangle(win
, x0
, y0
, x1
, y1
, x2
, y2
, red
);
123 GP_Triangle(win
, x0
, y0
, x1
, y1
, x2
, y2
, white
);
126 void draw_testing_circle(int x
, int y
, int xradius
,
127 __attribute__((unused
)) int yradius
)
130 GP_Circle(win
, x
, y
, xradius
, yellow
);
133 GP_FillCircle(win
, x
, y
, xradius
, red
);
136 GP_Circle(win
, x
, y
, xradius
, white
);
139 void draw_testing_ring(int x
, int y
, int xradius
,
140 __attribute__((unused
)) int yradius
)
143 GP_Ring(win
, x
, y
, xradius
, yradius
, yellow
);
146 GP_FillRing(win
, x
, y
, xradius
, yradius
, red
);
149 GP_Ring(win
, x
, y
, xradius
, yradius
, white
);
152 void draw_testing_ellipse(int x
, int y
, int xradius
, int yradius
)
155 GP_Ellipse(win
, x
, y
, xradius
, yradius
, yellow
);
158 GP_FillEllipse(win
, x
, y
, xradius
, yradius
, red
);
161 GP_Ellipse(win
, x
, y
, xradius
, yradius
, white
);
164 void draw_testing_arc(int x
, int y
, int xradius
, int yradius
)
166 GP_ArcSegment(win
, x
, y
, xradius
, yradius
, -1,
167 M_PI
- M_PI
/8.0, M_PI
/4.0, red
);
170 void draw_testing_rectangle(int x
, int y
, int xradius
, int yradius
)
172 int x0
= x
- xradius
, y0
= y
- yradius
;
173 int x1
= x
+ xradius
, y1
= y
+ yradius
;
176 GP_Rect(win
, x0
, y0
, x1
, y1
, yellow
);
179 GP_FillRect(win
, x0
, y0
, x1
, y1
, red
);
182 GP_Rect(win
, x0
, y0
, x1
, y1
, white
);
185 void draw_testing_tetragon(int x
, int y
, int xradius
, int yradius
)
187 int x0
= x
- xradius
, y0
= y
- yradius
;
188 int x1
= x
+ xradius
, y1
= y
;
189 int x2
= x
+ xradius
, y2
= y
+ yradius
/2;
190 int x3
= x
, y3
= y
+ yradius
;
193 GP_Tetragon(win
, x0
, y0
, x1
, y1
, x2
, y2
, x3
, y3
, yellow
);
196 GP_FillTetragon(win
, x0
, y0
, x1
, y1
, x2
, y2
, x3
, y3
, red
);
199 GP_Tetragon(win
, x0
, y0
, x1
, y1
, x2
, y2
, x3
, y3
, white
);
202 void draw_testing_polygon(int x
, int y
, int xradius
, int yradius
)
205 unsigned int edges
= 7;
210 xy
[2] = x
+ 3 * xradius
/ 4;
211 xy
[3] = y
+ yradius
/ 4;
213 xy
[4] = x
+ 3 * xradius
/ 4;
214 xy
[5] = y
+ 3 * yradius
/ 4;
216 xy
[6] = x
+ xradius
/ 4;
217 xy
[7] = y
+ 3 * yradius
/ 4;
222 xy
[10] = x
- xradius
;
225 xy
[12] = x
- 3 * xradius
/ 4;
226 xy
[13] = y
- yradius
/ 4;
229 GP_Polygon(win
, edges
, xy
, yellow
);
232 GP_FillPolygon(win
, edges
, xy
, red
);
235 GP_Polygon(win
, edges
, xy
, white
);
238 void redraw_screen(void)
241 /* text style for the label */
242 GP_TextStyle style
= {
243 .font
= &GP_DefaultConsoleFont
,
254 GP_HLine(win
, 0, win
->w
, center_y
, gray
);
255 GP_HLine(win
, 0, win
->w
, center_y
-yradius
, darkgray
);
256 GP_HLine(win
, 0, win
->w
, center_y
+yradius
, darkgray
);
257 GP_VLine(win
, center_x
, 0, win
->h
, gray
);
258 GP_VLine(win
, center_x
-xradius
, 0, win
->h
, darkgray
);
259 GP_VLine(win
, center_x
+xradius
, 0, win
->h
, darkgray
);
263 const char *title
= NULL
;
266 draw_testing_triangle(center_x
, center_y
, xradius
, yradius
);
270 draw_testing_circle(center_x
, center_y
, xradius
, yradius
);
274 draw_testing_ring(center_x
, center_y
, xradius
, yradius
);
278 draw_testing_ellipse(center_x
, center_y
, xradius
, yradius
);
281 case SHAPE_RECTANGLE
:
282 draw_testing_rectangle(center_x
, center_y
, xradius
, yradius
);
286 draw_testing_tetragon(center_x
, center_y
, xradius
, yradius
);
290 draw_testing_polygon(center_x
, center_y
, xradius
, yradius
);
294 draw_testing_arc(center_x
, center_y
, xradius
, yradius
);
299 GP_Text(win
, &style
, 16, 16, GP_ALIGN_RIGHT
|GP_VALIGN_BELOW
,
300 white
, black
, title
);
302 GP_BackendFlip(backend
);
305 static void xradius_add(int xradius_add
)
307 if (xradius
+ xradius_add
> 1 &&
308 xradius
+ xradius_add
< (int)win
->w
)
309 xradius
+= xradius_add
;
313 static void yradius_add(int yradius_add
)
315 if (yradius
+ yradius_add
> 1 &&
316 yradius
+ yradius_add
< (int)win
->h
)
317 yradius
+= yradius_add
;
320 static void xcenter_add(int xcenter_add
)
322 if (center_x
+ xcenter_add
> 1 &&
323 center_x
+ xcenter_add
< (int)win
->w
/2)
324 center_x
+= xcenter_add
;
327 static void ycenter_add(int ycenter_add
)
329 if (center_y
+ ycenter_add
> 1 &&
330 center_y
+ ycenter_add
< (int)win
->h
/2)
331 center_y
+= ycenter_add
;
334 void event_loop(void)
341 GP_BackendWaitEvent(backend
, &ev
);
345 shift_pressed
= GP_EventGetKey(&ev
, GP_KEY_LEFT_SHIFT
) ||
346 GP_EventGetKey(&ev
, GP_KEY_RIGHT_SHIFT
);
350 if (ev
.code
!= GP_EV_KEY_DOWN
)
353 switch (ev
.val
.key
.key
) {
355 win
->x_swap
= !win
->x_swap
;
358 win
->y_swap
= !win
->y_swap
;
361 win
->axes_swap
= !win
->axes_swap
;
362 GP_SWAP(win
->w
, win
->h
);
366 if (!fill
&& !outline
)
373 if (!fill
&& outline
== 0)
377 show_axes
= !show_axes
;
405 if (shape
> SHAPE_LAST
)
409 if (xradius
> yradius
)
430 case GP_KEY_PAGE_DOWN
:
435 GP_BackendExit(backend
);
443 GP_BackendExit(backend
);
446 case GP_EV_SYS_RESIZE
:
447 GP_BackendResizeAck(backend
);
448 center_x
= backend
->context
->w
/ 2;
449 center_y
= backend
->context
->h
/ 2;
459 void print_instructions(void)
461 printf("Use the following keys to control the test:\n");
462 printf(" Esc ................. exit\n");
463 printf(" Space ............... change shapes\n");
464 printf(" O ................... draw outlines (none/before/after fill)\n");
465 printf(" F ................... toggle filling\n");
466 printf(" A ................... show/hide axes\n");
467 printf(" X ................... mirror X\n");
468 printf(" Y ................... mirror Y\n");
469 printf(" R ................... reverse X and Y\n");
470 printf(" left/right .......... increase/decrease horizontal radius\n");
471 printf(" up/down ............. increase/decrease vertical radius\n");
472 printf(" shift + left/right .. increase/decrease horizontal center\n");
473 printf(" shift + up/down ..... increase/decrease vertical center\n");
474 printf(" PgUp/PgDn ........... increase/decrease both radii\n");
475 printf(" = ................... reset radii to the same value\n");
476 printf(" 1/2/3 ............... choose shape variant (if applicable)\n");
479 int main(int argc
, char *argv
[])
481 const char *backend_opts
= "X11";
484 while ((opt
= getopt(argc
, argv
, "b:")) != -1) {
487 backend_opts
= optarg
;
490 fprintf(stderr
, "Invalid paramter '%c'\n", opt
);
494 backend
= GP_BackendInit(backend_opts
, "Shapetest");
496 if (backend
== NULL
) {
497 fprintf(stderr
, "Failed to initalize backend '%s'\n",
502 win
= backend
->context
;
504 center_x
= win
->w
/ 2;
505 center_y
= win
->h
/ 2;
507 /* Load colors compatible with the display */
508 black
= GP_ColorToContextPixel(GP_COL_BLACK
, win
);
509 white
= GP_ColorToContextPixel(GP_COL_WHITE
, win
);
510 yellow
= GP_ColorToContextPixel(GP_COL_YELLOW
, win
);
511 green
= GP_ColorToContextPixel(GP_COL_GREEN
, win
);
512 red
= GP_ColorToContextPixel(GP_COL_RED
, win
);
513 gray
= GP_ColorToContextPixel(GP_COL_GRAY_LIGHT
, win
);
514 darkgray
= GP_ColorToContextPixel(GP_COL_GRAY_DARK
, win
);
516 print_instructions();