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_Pixmap
*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
,
259 GP_HLine(win
, 0, w
, center_y
, gray
);
260 GP_HLine(win
, 0, w
, center_y
-yradius
, darkgray
);
261 GP_HLine(win
, 0, w
, center_y
+yradius
, darkgray
);
262 GP_VLine(win
, center_x
, 0, h
, gray
);
263 GP_VLine(win
, center_x
-xradius
, 0, h
, darkgray
);
264 GP_VLine(win
, center_x
+xradius
, 0, h
, darkgray
);
268 const char *title
= NULL
;
271 draw_testing_triangle(center_x
, center_y
, xradius
, yradius
);
275 draw_testing_circle(center_x
, center_y
, xradius
, yradius
);
279 draw_testing_ring(center_x
, center_y
, xradius
, yradius
);
283 draw_testing_ellipse(center_x
, center_y
, xradius
, yradius
);
286 case SHAPE_RECTANGLE
:
287 draw_testing_rectangle(center_x
, center_y
, xradius
, yradius
);
291 draw_testing_tetragon(center_x
, center_y
, xradius
, yradius
);
295 draw_testing_polygon(center_x
, center_y
, xradius
, yradius
);
299 draw_testing_arc(center_x
, center_y
, xradius
, yradius
);
304 GP_Text(win
, &style
, 16, 16, GP_ALIGN_RIGHT
|GP_VALIGN_BELOW
,
305 white
, black
, title
);
307 GP_BackendFlip(backend
);
310 static void xradius_add(int xradius_add
)
312 if (xradius
+ xradius_add
> 1 &&
313 xradius
+ xradius_add
< (int)GP_PixmapW(win
))
314 xradius
+= xradius_add
;
318 static void yradius_add(int yradius_add
)
320 if (yradius
+ yradius_add
> 1 &&
321 yradius
+ yradius_add
< (int)GP_PixmapH(win
))
322 yradius
+= yradius_add
;
325 static void xcenter_add(int xcenter_add
)
327 if (center_x
+ xcenter_add
> 1 &&
328 center_x
+ xcenter_add
< (int)GP_PixmapW(win
)/2)
329 center_x
+= xcenter_add
;
332 static void ycenter_add(int ycenter_add
)
334 if (center_y
+ ycenter_add
> 1 &&
335 center_y
+ ycenter_add
< (int)GP_PixmapH(win
)/2)
336 center_y
+= ycenter_add
;
339 void event_loop(void)
346 GP_BackendWaitEvent(backend
, &ev
);
350 shift_pressed
= GP_EventGetKey(&ev
, GP_KEY_LEFT_SHIFT
) ||
351 GP_EventGetKey(&ev
, GP_KEY_RIGHT_SHIFT
);
355 if (ev
.code
!= GP_EV_KEY_DOWN
)
358 switch (ev
.val
.key
.key
) {
360 win
->x_swap
= !win
->x_swap
;
363 win
->y_swap
= !win
->y_swap
;
366 win
->axes_swap
= !win
->axes_swap
;
367 center_x
= GP_PixmapW(win
) / 2;
368 center_y
= GP_PixmapH(win
) / 2;
372 if (!fill
&& !outline
)
379 if (!fill
&& outline
== 0)
383 show_axes
= !show_axes
;
411 if (shape
> SHAPE_LAST
)
415 if (xradius
> yradius
)
436 case GP_KEY_PAGE_DOWN
:
441 GP_BackendExit(backend
);
449 GP_BackendExit(backend
);
452 case GP_EV_SYS_RESIZE
:
453 GP_BackendResizeAck(backend
);
454 win
= backend
->pixmap
;
455 center_x
= GP_PixmapW(win
) / 2;
456 center_y
= GP_PixmapH(win
) / 2;
466 void print_instructions(void)
468 printf("Use the following keys to control the test:\n");
469 printf(" Esc ................. exit\n");
470 printf(" Space ............... change shapes\n");
471 printf(" O ................... draw outlines (none/before/after fill)\n");
472 printf(" F ................... toggle filling\n");
473 printf(" A ................... show/hide axes\n");
474 printf(" X ................... mirror X\n");
475 printf(" Y ................... mirror Y\n");
476 printf(" R ................... reverse X and Y\n");
477 printf(" left/right .......... increase/decrease horizontal radius\n");
478 printf(" up/down ............. increase/decrease vertical radius\n");
479 printf(" shift + left/right .. increase/decrease horizontal center\n");
480 printf(" shift + up/down ..... increase/decrease vertical center\n");
481 printf(" PgUp/PgDn ........... increase/decrease both radii\n");
482 printf(" = ................... reset radii to the same value\n");
483 printf(" 1/2/3 ............... choose shape variant (if applicable)\n");
486 int main(int argc
, char *argv
[])
488 const char *backend_opts
= "X11";
491 while ((opt
= getopt(argc
, argv
, "b:")) != -1) {
494 backend_opts
= optarg
;
497 fprintf(stderr
, "Invalid paramter '%c'\n", opt
);
501 backend
= GP_BackendInit(backend_opts
, "Shapetest");
503 if (backend
== NULL
) {
504 fprintf(stderr
, "Failed to initalize backend '%s'\n",
509 win
= backend
->pixmap
;
511 center_x
= win
->w
/ 2;
512 center_y
= win
->h
/ 2;
514 /* Load colors compatible with the display */
515 black
= GP_RGBToPixmapPixel(0x00, 0x00, 0x00, win
);
516 white
= GP_RGBToPixmapPixel(0xff, 0xff, 0xff, win
);
517 yellow
= GP_RGBToPixmapPixel(0xff, 0xff, 0x00, win
);
518 green
= GP_RGBToPixmapPixel(0x00, 0xff, 0x00, win
);
519 red
= GP_RGBToPixmapPixel(0xff, 0x00, 0x00, win
);
520 gray
= GP_RGBToPixmapPixel(0xbe, 0xbe, 0xbe, win
);
521 darkgray
= GP_RGBToPixmapPixel(0x7f, 0x7f, 0x7f, win
);
523 print_instructions();