Gfxprim
Threads by month
- ----- 2026 -----
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- 929 discussions
[repo.or.cz] gfxprim.git branch master updated: c3fb40e752939f3ef6d3194f29613ed9c2f4d0dc
by metan 09 Feb '13
by metan 09 Feb '13
09 Feb '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via c3fb40e752939f3ef6d3194f29613ed9c2f4d0dc (commit)
via 17c1de1de50338ab954d6b62e41ed55ff77c7484 (commit)
via ea2c59ddb80527d69107808dfe0d5a56a4609894 (commit)
from ff0dc088ad0e31060e426df42bb3913ffed3cab3 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/c3fb40e752939f3ef6d3194f29613ed9c2f4…
commit c3fb40e752939f3ef6d3194f29613ed9c2f4d0dc
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Feb 9 19:34:07 2013 +0100
input: X11: Load some KeyCodes dynamically.
The X11 KeyCodes are not carved into the
stone. As a matter of fact some of the
keys are mapped differently on my iBook.
Now we load part of the translation table
dynamically based on X keysyms.
diff --git a/include/input/GP_InputDriverX11.h b/include/input/GP_InputDriverX11.h
index 87d4030..4c6df2c 100644
--- a/include/input/GP_InputDriverX11.h
+++ b/include/input/GP_InputDriverX11.h
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -32,6 +32,11 @@
#include <X11/Xlib.h>
/*
+ * Loads X11 KeyCode translation table.
+ */
+void GP_InputDriverX11Init(Display *dpy);
+
+/*
* Converts X11 event to GFXprim event and puts it into the queue.
*/
void GP_InputDriverX11EventPut(XEvent *ev, int w, int h);
diff --git a/libs/backends/GP_X11.c b/libs/backends/GP_X11.c
index 9d5a3e1..2dd17a0 100644
--- a/libs/backends/GP_X11.c
+++ b/libs/backends/GP_X11.c
@@ -811,6 +811,9 @@ GP_Backend *GP_BackendX11Init(const char *display, int x, int y,
if (x11->dpy == NULL)
goto err0;
+ /* Initialized key translation table */
+ GP_InputDriverX11Init(x11->dpy);
+
//XSynchronize(x11->dpy, True);
x11->scr = DefaultScreen(x11->dpy);
diff --git a/libs/input/GP_Event.c b/libs/input/GP_Event.c
index 7a5364a..0d638e9 100644
--- a/libs/input/GP_Event.c
+++ b/libs/input/GP_Event.c
@@ -98,6 +98,12 @@ const char *GP_EventKeyName(enum GP_EventKeyValue key)
return "MiddleButton";
case GP_BTN_PEN:
return "Pen";
+ case GP_KEY_NEXTSONG:
+ return "NextSong";
+ case GP_KEY_PREVIOUSSONG:
+ return "PreviousSong";
+ case GP_KEY_PLAYPAUSE:
+ return "PlayPause";
default:
return "Unknown";
};
diff --git a/libs/input/GP_InputDriverX11.c b/libs/input/GP_InputDriverX11.c
index 2b537fa..7874588 100644
--- a/libs/input/GP_InputDriverX11.c
+++ b/libs/input/GP_InputDriverX11.c
@@ -16,60 +16,201 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
#include "../../config.h"
#include "core/GP_Debug.h"
+#include "core/GP_Common.h"
#include "GP_Event.h"
#ifdef HAVE_LIBX11
+#include <X11/keysym.h>
+#include <X11/XF86keysym.h>
+
#include "GP_InputDriverX11.h"
/* X11 keycodes */
static uint16_t keycode_table[] = {
- GP_KEY_ESC, GP_KEY_1, GP_KEY_2, GP_KEY_3,
+ 0, GP_KEY_1, GP_KEY_2, GP_KEY_3,
GP_KEY_4, GP_KEY_5, GP_KEY_6, GP_KEY_7,
GP_KEY_8, GP_KEY_9, GP_KEY_0, GP_KEY_MINUS,
- GP_KEY_EQUAL, GP_KEY_BACKSPACE, GP_KEY_TAB, GP_KEY_Q,
+ GP_KEY_EQUAL, 0, 0, GP_KEY_Q,
GP_KEY_W, GP_KEY_E, GP_KEY_R, GP_KEY_T,
GP_KEY_Y, GP_KEY_U, GP_KEY_I, GP_KEY_O,
GP_KEY_P, GP_KEY_LEFT_BRACE, GP_KEY_RIGHT_BRACE, GP_KEY_ENTER,
- GP_KEY_LEFT_CTRL, GP_KEY_A, GP_KEY_S, GP_KEY_D,
+ 0, GP_KEY_A, GP_KEY_S, GP_KEY_D,
GP_KEY_F, GP_KEY_G, GP_KEY_H, GP_KEY_J,
GP_KEY_K, GP_KEY_L, GP_KEY_SEMICOLON, GP_KEY_APOSTROPHE,
- GP_KEY_GRAVE, GP_KEY_LEFT_SHIFT, GP_KEY_BACKSLASH, GP_KEY_Z,
+ GP_KEY_GRAVE, 0, GP_KEY_BACKSLASH, GP_KEY_Z,
GP_KEY_X, GP_KEY_C, GP_KEY_V, GP_KEY_B,
GP_KEY_N, GP_KEY_M, GP_KEY_COMMA, GP_KEY_DOT,
- GP_KEY_SLASH, GP_KEY_RIGHT_SHIFT, GP_KEY_KP_ASTERISK, GP_KEY_LEFT_ALT,
- GP_KEY_SPACE, GP_KEY_CAPS_LOCK, GP_KEY_F1, GP_KEY_F2,
+ GP_KEY_SLASH, 0, 0, 0,
+ GP_KEY_SPACE, 0, GP_KEY_F1, GP_KEY_F2,
GP_KEY_F3, GP_KEY_F4, GP_KEY_F5, GP_KEY_F6,
GP_KEY_F7, GP_KEY_F8, GP_KEY_F9, GP_KEY_F10,
- GP_KEY_NUM_LOCK, GP_KEY_SCROLL_LOCK, GP_KEY_KP_7, GP_KEY_KP_8,
- GP_KEY_KP_9, GP_KEY_KP_MINUS, GP_KEY_KP_4, GP_KEY_KP_5,
- GP_KEY_KP_6, GP_KEY_KP_PLUS, GP_KEY_KP_1, GP_KEY_KP_2,
- GP_KEY_KP_3, GP_KEY_KP_0, GP_KEY_KP_DOT, 0,
+ GP_KEY_NUM_LOCK, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
0, 0, GP_KEY_F11, GP_KEY_F12,
0, 0, 0, 0,
- 0, 0, 0, GP_KEY_KP_ENTER,
- GP_KEY_RIGHT_CTRL, GP_KEY_KP_SLASH, GP_KEY_SYSRQ, GP_KEY_RIGHT_ALT,
- 0, GP_KEY_HOME, GP_KEY_UP, GP_KEY_PAGE_UP,
- GP_KEY_LEFT, GP_KEY_RIGHT, GP_KEY_END, GP_KEY_DOWN,
- GP_KEY_PAGE_DOWN, GP_KEY_INSERT, GP_KEY_DELETE, 0,
- GP_KEY_MUTE, GP_KEY_VOLUMEDOWN, GP_KEY_VOLUMEUP, 0,
- 0, 0, GP_KEY_PAUSE, 0,
0, 0, 0, 0,
- GP_KEY_LEFT_META, GP_KEY_RIGHT_META, GP_KEY_COMPOSE,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+};
+
+/* X11 KeySyms to load dynamically */
+struct keytable {
+ uint32_t x_keysym;
+ uint16_t key;
+};
+
+static const struct keytable sym_to_key[] = {
+ /* Cursor control */
+ {XK_Up, GP_KEY_UP},
+ {XK_Down, GP_KEY_DOWN},
+ {XK_Left, GP_KEY_LEFT},
+ {XK_Right, GP_KEY_RIGHT},
+ {XK_Home, GP_KEY_HOME},
+ {XK_Page_Up, GP_KEY_PAGE_UP},
+ {XK_Page_Down, GP_KEY_PAGE_DOWN},
+ {XK_End, GP_KEY_END},
+
+ /* TTY Keys */
+ {XK_BackSpace, GP_KEY_BACKSPACE},
+ {XK_Tab, GP_KEY_TAB},
+ {XK_Escape, GP_KEY_ESC},
+ {XK_Delete, GP_KEY_DELETE},
+ {XK_Insert, GP_KEY_INSERT},
+ {XK_Sys_Req, GP_KEY_SYSRQ},
+ {XK_Pause, GP_KEY_PAUSE},
+ {XK_Scroll_Lock, GP_KEY_SCROLL_LOCK},
+
+ /* Modifiers */
+ {XK_Shift_L, GP_KEY_LEFT_SHIFT},
+ {XK_Shift_R, GP_KEY_RIGHT_SHIFT},
+ {XK_Alt_L, GP_KEY_LEFT_ALT},
+ {XK_Alt_R, GP_KEY_RIGHT_ALT},
+ {XK_Control_L, GP_KEY_RIGHT_CTRL},
+ {XK_Control_R, GP_KEY_LEFT_CTRL},
+ {XK_Caps_Lock, GP_KEY_CAPS_LOCK},
+ {XK_Super_L, GP_KEY_LEFT_META},
+ {XK_Super_R, GP_KEY_RIGHT_META},
+ {XK_Menu, GP_KEY_COMPOSE},
+
+ /* keypad */
+ {XK_KP_Enter, GP_KEY_KP_ENTER},
+ {XK_KP_0, GP_KEY_KP_0},
+ {XK_KP_1, GP_KEY_KP_1},
+ {XK_KP_2, GP_KEY_KP_2},
+ {XK_KP_3, GP_KEY_KP_3},
+ {XK_KP_4, GP_KEY_KP_4},
+ {XK_KP_5, GP_KEY_KP_5},
+ {XK_KP_6, GP_KEY_KP_6},
+ {XK_KP_7, GP_KEY_KP_7},
+ {XK_KP_8, GP_KEY_KP_8},
+ {XK_KP_9, GP_KEY_KP_9},
+ {XK_KP_Add, GP_KEY_KP_PLUS},
+ {XK_KP_Subtract, GP_KEY_KP_MINUS},
+ {XK_KP_Decimal, GP_KEY_KP_DOT},
+ {XK_KP_Divide, GP_KEY_KP_SLASH},
+ {XK_KP_Multiply, GP_KEY_KP_ASTERISK},
+
+ /* Multimedia */
+ {XF86XK_AudioLowerVolume, GP_KEY_VOLUMEDOWN},
+ {XF86XK_AudioRaiseVolume, GP_KEY_VOLUMEUP},
+ {XF86XK_AudioMute, GP_KEY_MUTE},
+ {XF86XK_AudioNext, GP_KEY_NEXTSONG},
+ {XF86XK_AudioPrev, GP_KEY_PREVIOUSSONG},
+ {XF86XK_AudioPlay, GP_KEY_PLAYPAUSE},
};
-static const uint16_t keycode_table_size = sizeof(keycode_table)/2;
+static void init_table(Display *dpy)
+{
+ GP_DEBUG(1, "Initializing X11 KeyCode table");
+
+ unsigned int i;
+
+ for (i = 0; i < GP_ARRAY_SIZE(sym_to_key); i++) {
+ unsigned int keycode;
+
+ keycode = XKeysymToKeycode(dpy, sym_to_key[i].x_keysym);
+
+ if (keycode == 0) {
+ GP_DEBUG(1, "KeySym '%s' (%u) not defined",
+ XKeysymToString(sym_to_key[i].x_keysym),
+ sym_to_key[i].x_keysym);
+ continue;
+ }
+
+ GP_DEBUG(3, "Mapping Key '%s' KeySym '%s' (%u) to KeyCode %u",
+ GP_EventKeyName(sym_to_key[i].key),
+ XKeysymToString(sym_to_key[i].x_keysym),
+ sym_to_key[i].x_keysym,
+ keycode);
+
+ if (keycode - 9 >= GP_ARRAY_SIZE(keycode_table)) {
+ GP_WARN("Key '%s' keycode %u out of table",
+ GP_EventKeyName(sym_to_key[i].key), keycode);
+ continue;
+ }
+
+ if (keycode_table[keycode - 9]) {
+ GP_WARN("Key '%s' keycode %u collides with key '%s'",
+ GP_EventKeyName(sym_to_key[i].key), keycode,
+ GP_EventKeyName(keycode_table[keycode - 9]));
+ continue;
+ }
+
+ keycode_table[keycode - 9] = sym_to_key[i].key;
+ }
+}
+
+static unsigned int get_key(unsigned int xkey)
+{
+ unsigned int key = 0;
+
+ if (xkey > 8 && xkey - 9 <= GP_ARRAY_SIZE(keycode_table))
+ key = keycode_table[xkey - 9];
+
+ if (key == 0)
+ GP_WARN("Unmapped X11 keycode 0x%02x %u", xkey, xkey);
+
+ return key;
+}
+
+void GP_InputDriverX11Init(Display *dpy)
+{
+ init_table(dpy);
+}
void GP_InputDriverX11EventPut(XEvent *ev, int w, int h)
{
- int key = 0, keycode, press = 0;
+ int key = 0, press = 0;
switch (ev->type) {
case ButtonPress:
@@ -95,7 +236,7 @@ void GP_InputDriverX11EventPut(XEvent *ev, int w, int h)
GP_EventPush(GP_EV_REL, GP_EV_REL_WHEEL, -1, NULL);
return;
}
-
+
if (key == 0) {
GP_WARN("Unmapped X11 button %02x",
ev->xbutton.button);
@@ -120,16 +261,11 @@ void GP_InputDriverX11EventPut(XEvent *ev, int w, int h)
case KeyPress:
press = 1;
case KeyRelease:
- keycode = ev->xkey.keycode;
-
- if (keycode > 8 && keycode - 9 <= keycode_table_size)
- key = keycode_table[keycode - 9];
+ key = get_key(ev->xkey.keycode);
- if (key == 0) {
- GP_WARN("Unmapped X11 keycode %02x", keycode);
+ if (key == 0)
return;
- }
-
+
GP_EventPushKey(key, press, NULL);
break;
/* events from WM */
http://repo.or.cz/w/gfxprim.git/commit/17c1de1de50338ab954d6b62e41ed55ff77c…
commit 17c1de1de50338ab954d6b62e41ed55ff77c7484
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Feb 9 19:29:19 2013 +0100
core: Add GP_ARRAY_SIZE() to GP_Common.c
diff --git a/include/core/GP_Common.h b/include/core/GP_Common.h
index 1352c76..8718054 100644
--- a/include/core/GP_Common.h
+++ b/include/core/GP_Common.h
@@ -19,7 +19,7 @@
* Copyright (C) 2009-2012 Jiri "BlueBear" Dluhos *
* <jiri.bluebear.dluhos(a)gmail.com> *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -76,6 +76,8 @@
(_a > 0) ? 1 : ((_a < 0) ? -1 : 0); })
+#define GP_ARRAY_SIZE(array) (sizeof(array) / sizeof(*array))
+
#endif /* __cplusplus */
/*
diff --git a/libs/input/GP_InputDriverX11.c b/libs/input/GP_InputDriverX11.c
index 992cbfc..2b537fa 100644
--- a/libs/input/GP_InputDriverX11.c
+++ b/libs/input/GP_InputDriverX11.c
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
http://repo.or.cz/w/gfxprim.git/commit/ea2c59ddb80527d69107808dfe0d5a56a460…
commit ea2c59ddb80527d69107808dfe0d5a56a4609894
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Feb 2 14:12:34 2013 +0100
input: Create EventQeueue.
This commit mostly shuffles code from GP_Event
to GP_EventQueue in preparation for per window
input queue.
diff --git a/include/input/GP_Event.h b/include/input/GP_Event.h
index ef21afb..c985cad 100644
--- a/include/input/GP_Event.h
+++ b/include/input/GP_Event.h
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
diff --git a/include/input/GP_EventQueue.h b/include/input/GP_EventQueue.h
new file mode 100644
index 0000000..df5067b
--- /dev/null
+++ b/include/input/GP_EventQueue.h
@@ -0,0 +1,103 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+/*
+
+ Event Queue.
+
+ This API is internally used by backends to store input events and is not
+ supposed to be used directly.
+
+ */
+
+#ifndef INPUT_GP_EVENT_QUEUE_H
+#define INPUT_GP_EVENT_QUEUE_H
+
+#include "input/GP_Event.h"
+
+typedef struct GP_EventQueue {
+ /* screen size */
+ unsigned int screen_w;
+ unsigned int screen_h;
+
+ /* event queue */
+ unsigned int queue_first;
+ unsigned int queue_last;
+ unsigned int queue_size;
+ struct GP_Event cur_state;
+ struct GP_Event events[GP_EVENT_QUEUE_SIZE];
+} GP_EventQueue;
+
+#define GP_EVENT_QUEUE_DECLARE(name, scr_w, scr_h) + struct GP_EventQueue name = { + .screen_w = scr_w, + .screen_h = scr_h, + + .queue_first = 0, + .queue_last = 0, + .queue_size = GP_EVENT_QUEUE_SIZE, + .cur_state = {.cursor_x = scr_w / 2, + .cursor_y = scr_h / 2} + }
+
+/*
+ * Initializes event queue passed as a pointer. The events array must be
+ * queue_size long.
+ *
+ * If queue_size is set to zero, default value is expected.
+ */
+void GP_EventQueueInit(struct GP_EventQueue *self,
+ unsigned int screen_w, unsigned int screen_h,
+ unsigned int queue_size);
+
+/*
+ * Allocates and initializes event queue.
+ *
+ * If queue_size is set to zero, default value is used.
+ */
+struct GP_EventQueue *GP_EventQueueAlloc(unsigned int screen_w,
+ unsigned int screen_h,
+ unsigned int queue_size);
+
+void GP_EventQueueFree(struct GP_EventQueue *self);
+
+/*
+ * Sets screen (window) size.
+ */
+void GP_EventQueueSetScreenSize(struct GP_EventQueue *self,
+ unsigned int w, unsigned int h);
+
+/*
+ * Sets cursor postion.
+ */
+void GP_EventQueueSetCursorPosition(struct GP_EventQueue *self,
+ unsigned int x, unsigned int y);
+
+
+unsigned int GP_EventQueueEventsQueued(struct GP_EventQueue *self);
+
+unsigned int GP_EventQueueGetEvent(struct GP_EventQueue *self,
+ struct GP_Event *ev);
+
+void GP_EventQueuePutEvent(struct GP_EventQueue *self, struct GP_Event *ev);
+
+#endif /* INPUT_GP_EVENT_QUEUE_H */
diff --git a/libs/input/GP_Event.c b/libs/input/GP_Event.c
index 9066540..7a5364a 100644
--- a/libs/input/GP_Event.c
+++ b/libs/input/GP_Event.c
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -27,17 +27,11 @@
#include <core/GP_Debug.h>
#include <core/GP_Common.h>
-#include "GP_Event.h"
-
-/* Screen size for clipping the cursor position */
-static uint32_t screen_w = 0, screen_h = 0;
+#include <input/GP_EventQueue.h>
-/* Event queue */
-static uint32_t queue_first = 0, queue_last = 0;
-static struct GP_Event event_queue[GP_EVENT_QUEUE_SIZE];
+#include "GP_Event.h"
-/* Global input state */
-static struct GP_Event cur_state = {.cursor_x = 0, .cursor_y = 0};
+static GP_EVENT_QUEUE_DECLARE(event_queue, 0, 0);
static char *key_names[] = {
"Reserved", "Escape", "1", "2", "3",
@@ -72,41 +66,22 @@ static uint16_t key_names_size = sizeof(key_names)/sizeof(void*);
void GP_EventSetScreenSize(uint32_t w, uint32_t h)
{
- screen_w = w;
- screen_h = h;
-
- /* clip cursor */
- if (cur_state.cursor_x >= w)
- cur_state.cursor_x = w - 1;
-
- if (cur_state.cursor_y >= h)
- cur_state.cursor_y = h - 1;
+ GP_EventQueueSetScreenSize(&event_queue, w, h);
}
void GP_EventSetScreenCursor(uint32_t x, uint32_t y)
{
- cur_state.cursor_x = x;
- cur_state.cursor_y = y;
+ GP_EventQueueSetCursorPosition(&event_queue, x, y);
}
unsigned int GP_EventsQueued(void)
{
- if (queue_first <= queue_last)
- return queue_last - queue_first;
-
- return GP_EVENT_QUEUE_SIZE - (queue_last - queue_first);
+ return GP_EventQueueEventsQueued(&event_queue);
}
int GP_EventGet(struct GP_Event *ev)
{
- if (queue_first == queue_last)
- return 0;
-
- *ev = event_queue[queue_first];
-
- queue_first = (queue_first + 1) % GP_EVENT_QUEUE_SIZE;
-
- return 1;
+ return GP_EventQueueGetEvent(&event_queue, ev);
}
const char *GP_EventKeyName(enum GP_EventKeyValue key)
@@ -199,23 +174,15 @@ void GP_EventDump(struct GP_Event *ev)
static void event_put(struct GP_Event *ev)
{
- uint32_t next = (queue_last + 1) % GP_EVENT_QUEUE_SIZE;
-
- if (next == queue_first) {
- GP_WARN("Event queue full, dropping event.");
- return;
- }
-
- event_queue[queue_last] = *ev;
- queue_last = next;
+ GP_EventQueuePutEvent(&event_queue, ev);
}
static void set_time(struct timeval *time)
{
if (time == NULL)
- gettimeofday(&cur_state.time, NULL);
+ gettimeofday(&event_queue.cur_state.time, NULL);
else
- cur_state.time = *time;
+ event_queue.cur_state.time = *time;
}
static uint32_t clip_rel(uint32_t val, uint32_t max, int32_t rel)
@@ -235,13 +202,13 @@ static uint32_t clip_rel(uint32_t val, uint32_t max, int32_t rel)
void GP_EventPushRelTo(uint32_t x, uint32_t y, struct timeval *time)
{
- if (x > screen_w || y > screen_h) {
+ if (x > event_queue.screen_w || y > event_queue.screen_h) {
GP_WARN("x > screen_w or y > screen_h, forgot to set screen size?");
return;
}
- int32_t rx = x - cur_state.cursor_x;
- int32_t ry = y - cur_state.cursor_y;
+ int32_t rx = x - event_queue.cur_state.cursor_x;
+ int32_t ry = y - event_queue.cur_state.cursor_y;
GP_EventPushRel(rx, ry, time);
}
@@ -249,20 +216,20 @@ void GP_EventPushRelTo(uint32_t x, uint32_t y, struct timeval *time)
void GP_EventPushRel(int32_t rx, int32_t ry, struct timeval *time)
{
/* event header */
- cur_state.type = GP_EV_REL;
- cur_state.code = GP_EV_REL_POS;
+ event_queue.cur_state.type = GP_EV_REL;
+ event_queue.cur_state.code = GP_EV_REL_POS;
- cur_state.val.rel.rx = rx;
- cur_state.val.rel.ry = ry;
+ event_queue.cur_state.val.rel.rx = rx;
+ event_queue.cur_state.val.rel.ry = ry;
set_time(time);
/* move the global cursor */
- cur_state.cursor_x = clip_rel(cur_state.cursor_x, screen_w, rx);
- cur_state.cursor_y = clip_rel(cur_state.cursor_y, screen_h, ry);
+ event_queue.cur_state.cursor_x = clip_rel(event_queue.cur_state.cursor_x, event_queue.screen_w, rx);
+ event_queue.cur_state.cursor_y = clip_rel(event_queue.cur_state.cursor_y, event_queue.screen_h, ry);
/* put it into queue */
- event_put(&cur_state);
+ event_put(&event_queue.cur_state);
}
void GP_EventPushAbs(uint32_t x, uint32_t y, uint32_t pressure,
@@ -270,14 +237,14 @@ void GP_EventPushAbs(uint32_t x, uint32_t y, uint32_t pressure,
struct timeval *time)
{
/* event header */
- cur_state.type = GP_EV_ABS;
- cur_state.code = GP_EV_ABS_POS;
- cur_state.val.abs.x = x;
- cur_state.val.abs.y = y;
- cur_state.val.abs.pressure = pressure;
- cur_state.val.abs.x_max = x_max;
- cur_state.val.abs.y_max = y_max;
- cur_state.val.abs.pressure_max = pressure_max;
+ event_queue.cur_state.type = GP_EV_ABS;
+ event_queue.cur_state.code = GP_EV_ABS_POS;
+ event_queue.cur_state.val.abs.x = x;
+ event_queue.cur_state.val.abs.y = y;
+ event_queue.cur_state.val.abs.pressure = pressure;
+ event_queue.cur_state.val.abs.x_max = x_max;
+ event_queue.cur_state.val.abs.y_max = y_max;
+ event_queue.cur_state.val.abs.pressure_max = pressure_max;
set_time(time);
@@ -285,30 +252,29 @@ void GP_EventPushAbs(uint32_t x, uint32_t y, uint32_t pressure,
* Set global cursor, the packet could be partial, eg. update only x or
* only y. In such case x_max or y_max is zero.
*/
-
if (x_max != 0)
- cur_state.cursor_x = x * (screen_w - 1) / x_max;
+ event_queue.cur_state.cursor_x = x * (event_queue.screen_w - 1) / x_max;
if (y_max != 0)
- cur_state.cursor_y = y * (screen_h - 1) / y_max;
+ event_queue.cur_state.cursor_y = y * (event_queue.screen_h - 1) / y_max;
/* put it into queue */
- event_put(&cur_state);
+ event_put(&event_queue.cur_state);
}
void GP_EventPushResize(uint32_t w, uint32_t h, struct timeval *time)
{
/* event header */
- cur_state.type = GP_EV_SYS;
- cur_state.code = GP_EV_SYS_RESIZE;
+ event_queue.cur_state.type = GP_EV_SYS;
+ event_queue.cur_state.code = GP_EV_SYS_RESIZE;
- cur_state.val.sys.w = w;
- cur_state.val.sys.h = h;
+ event_queue.cur_state.val.sys.w = w;
+ event_queue.cur_state.val.sys.h = h;
set_time(time);
/* put it into queue */
- event_put(&cur_state);
+ event_put(&event_queue.cur_state);
}
static char keys_to_ascii[] = {
@@ -356,10 +322,10 @@ void GP_EventPushKey(uint32_t key, uint8_t code, struct timeval *time)
{
switch (code) {
case GP_EV_KEY_UP:
- GP_EventResetKey(&cur_state, key);
+ GP_EventResetKey(&event_queue.cur_state, key);
break;
case GP_EV_KEY_DOWN:
- GP_EventSetKey(&cur_state, key);
+ GP_EventSetKey(&event_queue.cur_state, key);
break;
case GP_EV_KEY_REPEAT:
break;
@@ -369,15 +335,15 @@ void GP_EventPushKey(uint32_t key, uint8_t code, struct timeval *time)
}
/* event header */
- cur_state.type = GP_EV_KEY;
- cur_state.code = code;
- cur_state.val.key.key = key;
- key_to_ascii(&cur_state);
+ event_queue.cur_state.type = GP_EV_KEY;
+ event_queue.cur_state.code = code;
+ event_queue.cur_state.val.key.key = key;
+ key_to_ascii(&event_queue.cur_state);
set_time(time);
/* put it into queue */
- event_put(&cur_state);
+ event_put(&event_queue.cur_state);
}
void GP_EventPush(uint16_t type, uint32_t code, int32_t value,
@@ -388,12 +354,12 @@ void GP_EventPush(uint16_t type, uint32_t code, int32_t value,
GP_EventPushKey(code, value, time);
break;
default:
- cur_state.type = type;
- cur_state.code = code;
- cur_state.val.val = value;
+ event_queue.cur_state.type = type;
+ event_queue.cur_state.code = code;
+ event_queue.cur_state.val.val = value;
set_time(time);
- event_put(&cur_state);
+ event_put(&event_queue.cur_state);
}
}
diff --git a/libs/input/GP_EventQueue.c b/libs/input/GP_EventQueue.c
new file mode 100644
index 0000000..7c962f1
--- /dev/null
+++ b/libs/input/GP_EventQueue.c
@@ -0,0 +1,130 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#include "core/GP_Debug.h"
+
+#include "input/GP_EventQueue.h"
+
+void GP_EventQueueInit(struct GP_EventQueue *self,
+ unsigned int screen_w, unsigned int screen_h,
+ unsigned int queue_size)
+{
+ self->screen_w = screen_w;
+ self->screen_h = screen_h;
+
+ self->cur_state.cursor_x = screen_w / 2;
+ self->cur_state.cursor_y = screen_h / 2;
+
+ self->queue_first = 0;
+ self->queue_last = 0;
+ self->queue_size = queue_size;
+}
+
+struct GP_EventQueue *GP_EventQueueAlloc(unsigned int screen_w,
+ unsigned int screen_h,
+ unsigned int queue_size)
+{
+ size_t size;
+ struct GP_EventQueue *new;
+
+ size = sizeof(struct GP_EventQueue) +
+ (queue_size - GP_EVENT_QUEUE_SIZE) * sizeof(struct GP_Event);
+
+ new = malloc(size);
+
+ if (new == NULL) {
+ GP_WARN("Malloc failed :(");
+ return NULL;
+ }
+
+ GP_EventQueueInit(new, screen_w, screen_h, queue_size);
+
+ return new;
+}
+
+void GP_EventQueueFree(struct GP_EventQueue *self)
+{
+ free(self);
+}
+
+void GP_EventQueueSetScreenSize(struct GP_EventQueue *self,
+ unsigned int w, unsigned int h)
+{
+ GP_DEBUG(1, "Resizing input queue screen to %ux%u", w, h);
+
+ self->screen_w = w;
+ self->screen_h = h;
+
+ /* clip cursor */
+ if (self->cur_state.cursor_x >= w)
+ self->cur_state.cursor_x = w - 1;
+
+ if (self->cur_state.cursor_y >= h)
+ self->cur_state.cursor_y = h - 1;
+}
+
+void GP_EventQueueSetCursorPosition(struct GP_EventQueue *self,
+ unsigned int x, unsigned int y)
+{
+ if (x >= self->screen_w || y >= self->screen_h) {
+ GP_WARN("Attempt to set cursor %u,%u out of the screen %ux%u",
+ x, y, self->screen_w, self->screen_h);
+ return;
+ }
+
+ self->cur_state.cursor_x = x;
+ self->cur_state.cursor_y = y;
+}
+
+unsigned int GP_EventQueueEventsQueued(struct GP_EventQueue *self)
+{
+ if (self->queue_first <= self->queue_last)
+ return self->queue_last - self->queue_first;
+
+ return self->queue_size - (self->queue_last - self->queue_first);
+}
+
+unsigned int GP_EventQueueGetEvent(struct GP_EventQueue *self,
+ struct GP_Event *ev)
+{
+ if (self->queue_first == self->queue_last)
+ return 0;
+
+ *ev = self->events[self->queue_first];
+
+ self->queue_first = (self->queue_first + 1) % self->queue_size;
+
+ return 1;
+}
+
+void GP_EventQueuePutEvent(struct GP_EventQueue *self, struct GP_Event *ev)
+{
+ unsigned int next = (self->queue_last + 1) % self->queue_size;
+
+ if (next == self->queue_first) {
+ GP_WARN("Event queue full, dropping event.");
+ return;
+ }
+
+ self->events[self->queue_last] = *ev;
+ self->queue_last = next;
+}
diff --git a/libs/input/GP_InputDriverX11.c b/libs/input/GP_InputDriverX11.c
index 2b537fa..992cbfc 100644
--- a/libs/input/GP_InputDriverX11.c
+++ b/libs/input/GP_InputDriverX11.c
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
-----------------------------------------------------------------------
Summary of changes:
include/core/GP_Common.h | 4 +-
include/input/GP_Event.h | 2 +-
include/input/GP_EventQueue.h | 103 +++++++++++++++++++
include/input/GP_InputDriverX11.h | 7 +-
libs/backends/GP_X11.c | 3 +
libs/input/GP_Event.c | 136 ++++++++++---------------
libs/input/GP_EventQueue.c | 130 ++++++++++++++++++++++++
libs/input/GP_InputDriverX11.c | 196 +++++++++++++++++++++++++++++++------
8 files changed, 466 insertions(+), 115 deletions(-)
create mode 100644 include/input/GP_EventQueue.h
create mode 100644 libs/input/GP_EventQueue.c
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: ff0dc088ad0e31060e426df42bb3913ffed3cab3
by metan 31 Jan '13
by metan 31 Jan '13
31 Jan '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via ff0dc088ad0e31060e426df42bb3913ffed3cab3 (commit)
from 7c52b64476504ecd7788a3ad4f59ac6af996751e (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/ff0dc088ad0e31060e426df42bb3913ffed3…
commit ff0dc088ad0e31060e426df42bb3913ffed3cab3
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Thu Jan 31 11:35:52 2013 +0100
input: Map mute + volume multimedia keys.
More to come.
diff --git a/include/input/GP_Event.h b/include/input/GP_Event.h
index 162a5d2..ef21afb 100644
--- a/include/input/GP_Event.h
+++ b/include/input/GP_Event.h
@@ -163,6 +163,10 @@ enum GP_EventKeyValue {
GP_KEY_INSERT = 110,
GP_KEY_DELETE = 111,
+ GP_KEY_MUTE = 113,
+ GP_KEY_VOLUMEDOWN = 114,
+ GP_KEY_VOLUMEUP = 115,
+
GP_KEY_KP_EQUAL = 117,
GP_KEY_KP_PLUS_MINUS = 118,
GP_KEY_PAUSE = 119,
@@ -173,6 +177,10 @@ enum GP_EventKeyValue {
GP_KEY_RIGHT_META = 126,
GP_KEY_COMPOSE = 127,
+ GP_KEY_NEXTSONG = 163,
+ GP_KEY_PLAYPAUSE = 164,
+ GP_KEY_PREVIOUSSONG = 165,
+
GP_KEY_F13 = 183,
GP_KEY_F14 = 184,
GP_KEY_F15 = 185,
diff --git a/libs/input/GP_Event.c b/libs/input/GP_Event.c
index 13c400b..9066540 100644
--- a/libs/input/GP_Event.c
+++ b/libs/input/GP_Event.c
@@ -62,8 +62,8 @@ static char *key_names[] = {
"?", "KP Enter", "RightCtrl", "KP Slash", "SysRq",
"RightAlt", "?", "Home", "Up", "PageUp",
"Left", "Right", "End", "Down", "PageDown",
- "Insert", "Delete", "?", "?", "?",
- "?", "?", "KP Equal", "KP PlusMinus", "Pause",
+ "Insert", "Delete", "?", "Mute", "VolumeDown",
+ "VolumeUp", "?", "KP Equal", "KP PlusMinus", "Pause",
"?", "KP Comma", "?", "?", "?",
"LeftMeta", "RightMeta", "Compose",
};
@@ -149,12 +149,8 @@ static void dump_key(struct GP_Event *ev)
{
const char *name = GP_EventKeyName(ev->val.key.key);
- if (ev->val.key.key < key_names_size)
- name = key_names[ev->val.key.key];
-
printf("Key %i (Key%s) %sn",
ev->val.key.key, name, ev->code ? "down" : "up");
-
}
static void dump_abs(struct GP_Event *ev)
diff --git a/libs/input/GP_InputDriverX11.c b/libs/input/GP_InputDriverX11.c
index a1702a2..2b537fa 100644
--- a/libs/input/GP_InputDriverX11.c
+++ b/libs/input/GP_InputDriverX11.c
@@ -59,7 +59,7 @@ static uint16_t keycode_table[] = {
0, GP_KEY_HOME, GP_KEY_UP, GP_KEY_PAGE_UP,
GP_KEY_LEFT, GP_KEY_RIGHT, GP_KEY_END, GP_KEY_DOWN,
GP_KEY_PAGE_DOWN, GP_KEY_INSERT, GP_KEY_DELETE, 0,
- 0, 0, 0, 0,
+ GP_KEY_MUTE, GP_KEY_VOLUMEDOWN, GP_KEY_VOLUMEUP, 0,
0, 0, GP_KEY_PAUSE, 0,
0, 0, 0, 0,
GP_KEY_LEFT_META, GP_KEY_RIGHT_META, GP_KEY_COMPOSE,
-----------------------------------------------------------------------
Summary of changes:
include/input/GP_Event.h | 8 ++++++++
libs/input/GP_Event.c | 8 ++------
libs/input/GP_InputDriverX11.c | 2 +-
3 files changed, 11 insertions(+), 7 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 7c52b64476504ecd7788a3ad4f59ac6af996751e
by metan 30 Jan '13
by metan 30 Jan '13
30 Jan '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 7c52b64476504ecd7788a3ad4f59ac6af996751e (commit)
via a3408f4de5a85d72c3c5439f68c459c1d328201b (commit)
from ff6f39694f9b44497c6ec7f4d3b9c27ab180510a (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/7c52b64476504ecd7788a3ad4f59ac6af996…
commit 7c52b64476504ecd7788a3ad4f59ac6af996751e
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Wed Jan 30 16:53:27 2013 +0100
doc: input: Add keyboard layout description.
diff --git a/doc/input.txt b/doc/input.txt
index f48f24d..6bfdbb9 100644
--- a/doc/input.txt
+++ b/doc/input.txt
@@ -148,6 +148,14 @@ events has no value at all.
value mapped to ASCII if conversion is applicable otherwise it's set to
zero. You should consult the header 'input/GP_Event.h' for the comprehensive
list of key values.
++
+This image shows GFXprim key names without the 'GP_KEY_' prefix (Click for a
+higher resolution). So for example 'LEFTSHIFT' on the image is
+'GP_KEY_LEFT_SHIFT'.
++
+[[Keyboard Layout]]
+.GFXprim key names without the 'GP_KEY_' prefix.
+image::keyboard.svg["Keyboard Layout",width=800,link="keyboard.svg"]
* And finally the system event is used with 'GP_EV_SYS_RESIZE' and informs you
of the new window size.
diff --git a/doc/keyboard.svg b/doc/keyboard.svg
new file mode 100644
index 0000000..e0b4bfe
--- /dev/null
+++ b/doc/keyboard.svg
@@ -0,0 +1,2150 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="1117.7699"
+ height="310.99835"
+ viewBox="0 0 1119.1689 310.19056"
+ id="svg2"
+ xml:space="preserve"
+ style="fill-rule:evenodd"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="keyboard.svg"><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1366"
+ inkscape:window-height="768"
+ id="namedview484"
+ showgrid="false"
+ fit-margin-top="30"
+ fit-margin-left="30"
+ fit-margin-right="30"
+ fit-margin-bottom="30"
+ inkscape:zoom="4.630266"
+ inkscape:cx="777.80818"
+ inkscape:cy="240.82316"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg2" /><metadata
+ id="metadata872"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+ id="defs4"><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutM"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.4,0.4)"
+ id="path4359"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutS"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.2,0.2)"
+ id="path4362"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutL"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.8,0.8)"
+ id="path4356"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="Arrow1Lend"
+ style="overflow:visible"><path
+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+ transform="matrix(-0.8,0,0,-0.8,-10,0)"
+ id="path4216"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="Arrow2Lend"
+ style="overflow:visible"><path
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
+ id="path4234"
+ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="Arrow2Lstart"
+ style="overflow:visible"><path
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="matrix(1.1,0,0,1.1,1.1,0)"
+ id="path4231"
+ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+ inkscape:connector-curvature="0" /></marker><style
+ type="text/css"
+ id="style6" /><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutSU"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.2,0.2)"
+ id="path5625"
+ style="fill:#2b2828;fill-rule:evenodd;stroke:#2b2828;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutSU-2"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.2,0.2)"
+ id="path5625-2"
+ style="fill:#2b2828;fill-rule:evenodd;stroke:#2b2828;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutSI"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.2,0.2)"
+ id="path6762"
+ style="fill:#2b2828;fill-rule:evenodd;stroke:#2b2828;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutMu"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.4,0.4)"
+ id="path10716"
+ style="fill:#2b2828;fill-rule:evenodd;stroke:#2b2828;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutMY"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.4,0.4)"
+ id="path10719"
+ style="fill:#2b2828;fill-rule:evenodd;stroke:#2b2828;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutM1"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.4,0.4)"
+ id="path11856"
+ style="fill:#2b2828;fill-rule:evenodd;stroke:#2b2828;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutM1-2"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.4,0.4)"
+ id="path11856-5"
+ style="fill:#2b2828;fill-rule:evenodd;stroke:#2b2828;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutM1-6"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.4,0.4)"
+ id="path11856-54"
+ style="fill:#2b2828;fill-rule:evenodd;stroke:#2b2828;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutM1-4"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.4,0.4)"
+ id="path11856-9"
+ style="fill:#2b2828;fill-rule:evenodd;stroke:#2b2828;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutM1-1"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.4,0.4)"
+ id="path11856-97"
+ style="fill:#2b2828;fill-rule:evenodd;stroke:#2b2828;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutM1-64"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.4,0.4)"
+ id="path11856-3"
+ style="fill:#2b2828;fill-rule:evenodd;stroke:#2b2828;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutM1-5"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.4,0.4)"
+ id="path11856-55"
+ style="fill:#2b2828;fill-rule:evenodd;stroke:#2b2828;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutM1-9"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.4,0.4)"
+ id="path11856-0"
+ style="fill:#2b2828;fill-rule:evenodd;stroke:#2b2828;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutM1-17"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.4,0.4)"
+ id="path11856-4"
+ style="fill:#2b2828;fill-rule:evenodd;stroke:#2b2828;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker><marker
+ refX="0"
+ refY="0"
+ orient="auto"
+ id="TriangleOutMF"
+ style="overflow:visible"><path
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ transform="scale(0.4,0.4)"
+ id="path3528"
+ style="fill:#2b2828;fill-rule:evenodd;stroke:#2b2828;stroke-width:1pt;marker-start:none"
+ inkscape:connector-curvature="0" /></marker></defs><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none"
+ id="path11"
+ d="m 34.593833,93.265198 30,0 c 1.5,0 4.49999,1.5 4.49999,4.5 l 0,25.499992 c 0,3 -2.99999,4.5 -4.49999,4.5 l -30,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-25.499992 c 0,-3 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none"
+ id="path13"
+ d="m 79.593823,93.265198 30.000007,0 c 3,0 4.5,1.5 4.5,4.5 l 0,25.499992 c 0,3 -1.5,4.5 -4.5,4.5 l -29.999997,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-25.499992 c 0,-3 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none"
+ id="path15"
+ d="m 123.09383,93.265198 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,25.499992 c 0,3 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -3,-1.5 -3,-4.5 l 0,-25.499992 c 0,-3 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none"
+ id="path17"
+ d="m 168.09384,93.265198 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,25.499992 c 0,3 -1.5,4.5 -4.5,4.5 l -30,0 c -3,0 -4.50001,-1.5 -4.50001,-4.5 l 0,-25.499992 c 0,-3 1.50001,-4.5 4.50001,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none"
+ id="path19"
+ d="m 213.09384,93.265198 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,25.499992 c 0,3 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-4.5 l 0,-25.499992 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none"
+ id="path21"
+ d="m 258.09384,93.265198 28.5,0 c 3,0 4.5,1.5 4.5,4.5 l 0,25.499992 c 0,3 -1.5,4.5 -4.5,4.5 l -28.5,0 c -1.5,0 -4.5,-1.5 -4.5,-4.5 l 0,-25.499992 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none"
+ id="path23"
+ d="m 301.59384,93.265198 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,25.499992 c 0,3 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-4.5 l 0,-25.499992 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none"
+ id="path25"
+ d="m 346.59384,93.265198 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,25.499992 c 0,3 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-4.5 l 0,-25.499992 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none"
+ id="path27"
+ d="m 391.59384,93.265198 28.5,0 c 3,0 4.5,1.5 4.5,4.5 l 0,25.499992 c 0,3 -1.5,4.5 -4.5,4.5 l -28.5,0 c -1.5,0 -4.5,-1.5 -4.5,-4.5 l 0,-25.499992 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none"
+ id="path29"
+ d="m 435.09384,93.265198 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,25.499992 c 0,3 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-4.5 l 0,-25.499992 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none"
+ id="path31"
+ d="m 480.09384,93.265198 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,25.499992 c 0,3 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-4.5 l 0,-25.499992 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:none;stroke-width:0;fill-opacity:1"
+ id="path33"
+ d="m 528.21596,93.265198 30,0 c 1.5,0 3,1.5 3,4.5 l 0,25.499992 c 0,3 -1.5,4.5 -3,4.5 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-4.5 l 0,-25.499992 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:none;stroke-width:0;fill-opacity:1"
+ id="path35"
+ d="m 573.15885,93.265198 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,25.499992 c 0,3 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -3,-1.5 -3,-4.5 l 0,-25.499992 c 0,-3 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path37"
+ d="m 615.39785,93.265198 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,25.499992 c 0,3 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -3,-1.5 -3,-4.5 l 0,-25.499992 c 0,-3 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path39"
+ d="m 658.47542,93.265198 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,25.499992 c 0,3 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -3,-1.5 -3,-4.5 l 0,-25.499992 c 0,-3 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path41"
+ d="m 106.59383,130.76519 28.5,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.49999 -4.5,4.49999 l -28.5,0 c -1.5,0 -4.5,-2.99999 -4.5,-4.49999 l 0,-27 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path43"
+ d="m 150.09383,130.76519 30.00001,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.49999 -4.5,4.49999 l -30.00001,0 c -1.5,0 -4.5,-2.99999 -4.5,-4.49999 l 0,-27 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path45"
+ d="m 195.09384,130.76519 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.49999 -4.5,4.49999 l -30,0 c -1.5,0 -4.5,-2.99999 -4.5,-4.49999 l 0,-27 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path47"
+ d="m 240.09384,130.76519 28.5,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.49999 -4.5,4.49999 l -28.5,0 c -1.5,0 -4.5,-2.99999 -4.5,-4.49999 l 0,-27 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path49"
+ d="m 283.59384,130.76519 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.49999 -4.5,4.49999 l -30,0 c -1.5,0 -3,-2.99999 -3,-4.49999 l 0,-27 c 0,-3 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path51"
+ d="m 328.59384,130.76519 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.49999 -4.5,4.49999 l -30,0 c -1.5,0 -3,-2.99999 -3,-4.49999 l 0,-27 c 0,-3 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path53"
+ d="m 373.59384,130.76519 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.49999 -4.5,4.49999 l -30,0 c -1.5,0 -3,-2.99999 -3,-4.49999 l 0,-27 c 0,-3 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path55"
+ d="m 417.09384,130.76519 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.49999 -4.5,4.49999 l -30,0 c -1.5,0 -3,-2.99999 -3,-4.49999 l 0,-27 c 0,-3 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path57"
+ d="m 462.09384,130.76519 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.49999 -4.5,4.49999 l -30,0 c -1.5,0 -3,-2.99999 -3,-4.49999 l 0,-27 c 0,-3 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path59"
+ d="m 507.09384,130.76519 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.49999 -4.5,4.49999 l -30,0 c -1.5,0 -3,-2.99999 -3,-4.49999 l 0,-27 c 0,-3 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path61"
+ d="m 552.09384,130.76519 28.5,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.49999 -4.5,4.49999 l -28.5,0 c -1.5,0 -3,-2.99999 -3,-4.49999 l 0,-27 c 0,-3 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path63"
+ d="m 595.59384,130.76519 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.49999 -4.5,4.49999 l -30,0 c -1.5,0 -3,-2.99999 -3,-4.49999 l 0,-27 c 0,-3 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path65"
+ d="m 118.59383,169.76518 28.5,0 c 1.5,0 4.5,1.5 4.5,3 l 0,28.5 c 0,1.5 -3,3 -4.5,3 l -28.5,0 c -3,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 1.5,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path67"
+ d="m 162.09383,169.76518 30.00001,0 c 1.5,0 4.5,1.5 4.5,3 l 0,28.5 c 0,1.5 -3,3 -4.5,3 l -30.00001,0 c -3,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 1.5,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path69"
+ d="m 207.09384,169.76518 30,0 c 3,0 4.5,1.5 4.5,3 l 0,28.5 c 0,1.5 -1.5,3 -4.5,3 l -30,0 c -3,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 1.5,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path71"
+ d="m 252.09384,169.76518 28.5,0 c 3,0 4.5,1.5 4.5,3 l 0,28.5 c 0,1.5 -1.5,3 -4.5,3 l -28.5,0 c -3,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 1.5,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path73"
+ d="m 295.59384,169.76518 30,0 c 3,0 4.5,1.5 4.5,3 l 0,28.5 c 0,1.5 -1.5,3 -4.5,3 l -30,0 c -3,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 1.5,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path75"
+ d="m 340.59384,169.76518 30,0 c 3,0 4.5,1.5 4.5,3 l 0,28.5 c 0,1.5 -1.5,3 -4.5,3 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 3,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path77"
+ d="m 385.59384,169.76518 28.5,0 c 3,0 4.5,1.5 4.5,3 l 0,28.5 c 0,1.5 -1.5,3 -4.5,3 l -28.5,0 c -1.5,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 3,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path79"
+ d="m 429.09384,169.76518 30,0 c 3,0 4.5,1.5 4.5,3 l 0,28.5 c 0,1.5 -1.5,3 -4.5,3 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 3,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path81"
+ d="m 474.09384,169.76518 30,0 c 3,0 4.5,1.5 4.5,3 l 0,28.5 c 0,1.5 -1.5,3 -4.5,3 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 3,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path83"
+ d="m 519.1154,169.76518 30,0 c 3,0 4.5,1.5 4.5,3 l 0,28.5 c 0,1.5 -1.5,3 -4.5,3 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 3,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path85"
+ d="m 562.59384,169.76518 30,0 c 3,0 4.5,1.5 4.5,3 l 0,28.5 c 0,1.5 -1.5,3 -4.5,3 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 3,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path87"
+ d="m 133.59383,207.26518 31.50001,0 c 1.5,0 3,3 3,4.5 l 0,25.5 c 0,3 -1.5,4.5 -3,4.5 l -31.50001,0 c -1.5,0 -3,-1.5 -3,-4.5 l 0,-25.5 c 0,-1.5 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path89"
+ d="m 178.59384,207.26518 31.5,0 c 1.5,0 3,3 3,4.5 l 0,25.5 c 0,3 -1.5,4.5 -3,4.5 l -31.5,0 c -1.5,0 -3,-1.5 -3,-4.5 l 0,-25.5 c 0,-1.5 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path91"
+ d="m 223.59384,207.26518 31.5,0 c 1.5,0 3,3 3,4.5 l 0,25.5 c 0,3 -1.5,4.5 -3,4.5 l -31.5,0 c -1.5,0 -3,-1.5 -3,-4.5 l 0,-25.5 c 0,-1.5 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path93"
+ d="m 313.59384,207.26518 30,0 c 1.5,0 3,3 3,4.5 l 0,25.5 c 0,3 -1.5,4.5 -3,4.5 l -30,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-25.5 c 0,-1.5 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path95"
+ d="m 359.20546,207.8768 30,0 c 1.5,0 3,3 3,4.5 l 0,25.5 c 0,3 -1.5,4.5 -3,4.5 l -30,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-25.5 c 0,-1.5 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path97"
+ d="m 403.59384,207.26518 28.5,0 c 1.5,0 3,3 3,4.5 l 0,25.5 c 0,3 -1.5,4.5 -3,4.5 l -28.5,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-25.5 c 0,-1.5 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path99"
+ d="m 447.09384,207.26518 30,0 c 1.5,0 3,3 3,4.5 l 0,25.5 c 0,3 -1.5,4.5 -3,4.5 l -30,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-25.5 c 0,-1.5 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path101"
+ d="m 492.09384,207.26518 30,0 c 1.5,0 3,3 3,4.5 l 0,25.5 c 0,3 -1.5,4.5 -3,4.5 l -30,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-25.5 c 0,-1.5 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path103"
+ d="m 536.91599,207.26518 28.5,0 c 1.5,0 3,3 3,4.5 l 0,25.5 c 0,3 -1.5,4.5 -3,4.5 l -28.5,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-25.5 c 0,-1.5 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;fill-opacity:1;stroke:none"
+ id="path105"
+ d="m 34.593833,31.765198 30,0 c 1.5,0 4.49999,1.5 4.49999,4.5 l 0,27 c 0,1.5 -2.99999,4.5 -4.49999,4.5 l -30,0 c -3,0 -4.5,-3 -4.5,-4.5 l 0,-27 c 0,-3 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path107"
+ d="m 123.09383,31.765198 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -3,-3 -3,-4.5 l 0,-27 c 0,-3 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path109"
+ d="m 168.09384,31.765198 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.5 -4.5,4.5 l -30,0 c -3,0 -4.50001,-3 -4.50001,-4.5 l 0,-27 c 0,-3 1.50001,-4.5 4.50001,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path111"
+ d="m 213.09384,31.765198 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -4.5,-3 -4.5,-4.5 l 0,-27 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path113"
+ d="m 258.09384,31.765198 28.5,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.5 -4.5,4.5 l -28.5,0 c -1.5,0 -4.5,-3 -4.5,-4.5 l 0,-27 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;fill-opacity:1;stroke:none"
+ id="path115"
+ d="m 324.09384,30.265198 30,0 c 1.5,0 3,3 3,4.5 l 0,27 c 0,3 -1.5,4.5 -3,4.5 l -30,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-1.5 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;fill-opacity:1;stroke:none"
+ id="path117"
+ d="m 369.09384,30.265198 30,0 c 1.5,0 3,3 3,4.5 l 0,27 c 0,3 -1.5,4.5 -3,4.5 l -30,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-1.5 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;fill-opacity:1;stroke:none"
+ id="path119"
+ d="m 412.59384,30.265198 30,0 c 1.5,0 3,3 3,4.5 l 0,27 c 0,3 -1.5,4.5 -3,4.5 l -30,0 c -1.5,0 -3,-1.5 -3,-4.5 l 0,-27 c 0,-1.5 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;fill-opacity:1;stroke:none"
+ id="path121"
+ d="m 457.59384,30.265198 30,0 c 1.5,0 3,3 3,4.5 l 0,27 c 0,3 -1.5,4.5 -3,4.5 l -30,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-1.5 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path123"
+ d="m 523.59384,30.265198 30,0 c 1.5,0 3,3 3,4.5 l 0,27 c 0,3 -1.5,4.5 -3,4.5 l -30,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-1.5 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path125"
+ d="m 567.09384,30.265198 30,0 c 1.5,0 3,3 3,4.5 l 0,27 c 0,3 -1.5,4.5 -3,4.5 l -30,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-1.5 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path127"
+ d="m 612.09384,30.265198 30,0 c 1.5,0 3,3 3,4.5 l 0,27 c 0,3 -1.5,4.5 -3,4.5 l -30,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-1.5 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path129"
+ d="m 657.09384,30.265198 30,0 c 1.5,0 3,3 3,4.5 l 0,27 c 0,3 -1.5,4.5 -3,4.5 l -30,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-1.5 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:none;stroke-width:0;fill-opacity:1"
+ id="path131"
+ d="m 745.59384,93.265198 30,0 c 1.5,0 3,1.5 3,3 l 0,26.999992 c 0,1.5 -1.5,3 -3,3 l -30,0 c -3,0 -4.5,-1.5 -4.5,-3 l 0,-26.999992 c 0,-1.5 1.5,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:none;stroke-width:0;fill-opacity:1"
+ id="path133"
+ d="m 790.59384,93.265198 30,0 c 1.5,0 3,1.5 3,3 l 0,26.999992 c 0,1.5 -1.5,3 -3,3 l -30,0 c -3,0 -4.5,-1.5 -4.5,-3 l 0,-26.999992 c 0,-1.5 1.5,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:none;stroke-width:0;fill-opacity:1"
+ id="path135"
+ d="m 835.59384,93.265198 28.5,0 c 1.5,0 3,1.5 3,3 l 0,26.999992 c 0,1.5 -1.5,3 -3,3 l -28.5,0 c -3,0 -4.5,-1.5 -4.5,-3 l 0,-26.999992 c 0,-1.5 1.5,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;fill-opacity:1;stroke:none;stroke-width:1.50187731000000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path137"
+ d="m 742.59384,30.265198 30,0 c 3,0 4.5,3 4.5,4.5 l 0,27 c 0,3 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-1.5 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;fill-opacity:1;stroke:none;stroke-width:1.50187731000000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path139"
+ d="m 787.59384,30.265198 30,0 c 3,0 4.5,3 4.5,4.5 l 0,27 c 0,3 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-1.5 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;fill-opacity:1;stroke:none;stroke-width:1.50187731000000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path141"
+ d="m 832.59384,30.265198 28.5,0 c 3,0 4.5,3 4.5,4.5 l 0,27 c 0,3 -1.5,4.5 -4.5,4.5 l -28.5,0 c -1.5,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-1.5 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:none;stroke-width:0;fill-opacity:1"
+ id="path143"
+ d="m 745.59384,129.26519 30,0 c 1.5,0 3,3 3,4.5 l 0,27 c 0,3 -1.5,4.49999 -3,4.49999 l -30,0 c -3,0 -4.5,-1.49999 -4.5,-4.49999 l 0,-27 c 0,-1.5 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:none;stroke-width:0;fill-opacity:1"
+ id="path145"
+ d="m 790.59384,129.26519 30,0 c 1.5,0 3,3 3,4.5 l 0,27 c 0,3 -1.5,4.49999 -3,4.49999 l -30,0 c -3,0 -4.5,-1.49999 -4.5,-4.49999 l 0,-27 c 0,-1.5 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:none;stroke-width:0;fill-opacity:1"
+ id="path147"
+ d="m 835.59384,129.26519 28.5,0 c 1.5,0 3,3 3,4.5 l 0,27 c 0,3 -1.5,4.49999 -3,4.49999 l -28.5,0 c -3,0 -4.5,-1.49999 -4.5,-4.49999 l 0,-27 c 0,-1.5 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:none;stroke-width:0;fill-opacity:1"
+ id="path149"
+ d="m 745.59384,244.76518 30,0 c 1.5,0 3,1.5 3,3 l 0,28.5 c 0,1.5 -1.5,3 -3,3 l -30,0 c -3,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 1.5,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;fill-opacity:1;stroke:none"
+ id="path151"
+ d="m 790.45048,244.76518 30,0 c 1.5,0 3,1.5 3,3 l 0,28.5 c 0,1.5 -1.5,3 -3,3 l -30,0 c -3,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 1.5,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:none;stroke-width:0;fill-opacity:1"
+ id="path153"
+ d="m 835.59384,244.76518 28.5,0 c 1.5,0 3,1.5 3,3 l 0,28.5 c 0,1.5 -1.5,3 -3,3 l -28.5,0 c -3,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 1.5,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;fill-opacity:1;stroke:none"
+ id="path155"
+ d="m 790.59384,206.77726 30,0 c 1.5,0 3,1.5 3,4.5 l 0,25.5 c 0,1.5 -1.5,4.5 -3,4.5 l -30,0 c -3,0 -4.5,-3 -4.5,-4.5 l 0,-25.5 c 0,-3 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path157"
+ d="m 921.111,93.265198 30,0 c 3,0 4.5,1.5 4.5,3 l 0,26.999992 c 0,1.5 -1.5,3 -4.5,3 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-3 l 0,-26.999992 c 0,-1.5 3,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path159"
+ d="m 966.09384,93.265198 28.5,0 c 3,0 4.5,1.5 4.5,3 l 0,26.999992 c 0,1.5 -1.5,3 -4.5,3 l -28.5,0 c -1.5,0 -4.5,-1.5 -4.5,-3 l 0,-26.999992 c 0,-1.5 3,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path161"
+ d="m 1009.5938,93.265198 30,0 c 3,0 4.5,1.5 4.5,3 l 0,26.999992 c 0,1.5 -1.5,3 -4.5,3 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-3 l 0,-26.999992 c 0,-1.5 3,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path163"
+ d="m 921.09384,129.26519 30,0 c 3,0 4.5,3 4.5,4.5 l 0,27 c 0,3 -1.5,4.49999 -4.5,4.49999 l -30,0 c -1.5,0 -4.5,-1.49999 -4.5,-4.49999 l 0,-27 c 0,-1.5 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path165"
+ d="m 966.09384,129.26519 28.5,0 c 3,0 4.5,3 4.5,4.5 l 0,27 c 0,3 -1.5,4.49999 -4.5,4.49999 l -28.5,0 c -1.5,0 -4.5,-1.49999 -4.5,-4.49999 l 0,-27 c 0,-1.5 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path167"
+ d="m 1009.5938,129.26519 30,0 c 3,0 4.5,3 4.5,4.5 l 0,27 c 0,3 -1.5,4.49999 -4.5,4.49999 l -30,0 c -1.5,0 -4.5,-1.49999 -4.5,-4.49999 l 0,-27 c 0,-1.5 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path169"
+ d="m 921.09384,168.26518 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,3 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path171"
+ d="m 966.09384,168.26518 28.5,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,3 -1.5,4.5 -4.5,4.5 l -28.5,0 c -1.5,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path173"
+ d="m 1009.5938,168.26518 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,3 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path175"
+ d="m 921.09384,207.26518 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,25.5 c 0,1.5 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -4.5,-3 -4.5,-4.5 l 0,-25.5 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path177"
+ d="m 966.09384,207.26518 28.5,0 c 3,0 4.5,1.5 4.5,4.5 l 0,25.5 c 0,1.5 -1.5,4.5 -4.5,4.5 l -28.5,0 c -1.5,0 -4.5,-3 -4.5,-4.5 l 0,-25.5 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path179"
+ d="m 1009.5938,207.26518 30,0 c 3,0 4.5,1.5 4.5,4.5 l 0,25.5 c 0,1.5 -1.5,4.5 -4.5,4.5 l -30,0 c -1.5,0 -4.5,-3 -4.5,-4.5 l 0,-25.5 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path181"
+ d="m 1009.5938,244.76518 30,0 c 3,0 4.5,1.5 4.5,3 l 0,28.5 c 0,1.5 -1.5,3 -4.5,3 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 3,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path183"
+ d="m 1054.5938,93.265198 30,0 c 3,0 4.5,1.5 4.5,3 l 0,26.999992 c 0,1.5 -1.5,3 -4.5,3 l -30,0 c -1.5,0 -4.5,-1.5 -4.5,-3 l 0,-26.999992 c 0,-1.5 3,-3 4.5,-3 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path185"
+ d="m 207.09384,244.76518 -16.5,0 c -3,0 -4.5,1.5 -4.5,4.5 l 0,27 c 0,3 1.5,4.5 4.5,4.5 l 16.5,0 252,0 27,0 c 0,0 1.5,-1.5 1.5,-4.5 l 0,-27 c 0,-3 -1.5,-4.5 -1.5,-4.5 l -27,0 -252,0 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path187"
+ d="m 550.69124,244.76518 28.5,0 c 1.5,0 3,1.5 3,4.5 l 0,27 c 0,3 -1.5,4.5 -3,4.5 l -28.5,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-3 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path189"
+ d="m 594.09384,244.76518 30,0 c 1.5,0 3,1.5 3,4.5 l 0,27 c 0,3 -1.5,4.5 -3,4.5 l -30,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-3 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path191"
+ d="m 1089.0938,133.76519 c 0,-1.5 -1.5,-4.5 -4.5,-4.5 l -30,0 c -1.5,0 -4.5,3 -4.5,4.5 l 0,65.99999 c 0,3 3,4.5 4.5,4.5 l 30,0 c 3,0 4.5,-1.5 4.5,-4.5 l 0,-65.99999 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path193"
+ d="m 1089.0938,211.76518 c 0,-3 -1.5,-4.5 -4.5,-4.5 l -30,0 c -1.5,0 -4.5,1.5 -4.5,4.5 l 0,64.5 c 0,1.5 3,3 4.5,3 l 30,0 c 3,0 4.5,-1.5 4.5,-3 l 0,-64.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path195"
+ d="m 267.09384,207.26518 31.5,0 c 1.5,0 3,3 3,4.5 l 0,25.5 c 0,3 -1.5,4.5 -3,4.5 l -31.5,0 c 0,0 -1.5,-1.5 -1.5,-4.5 l 0,-25.5 c 0,-1.5 1.5,-4.5 1.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path197"
+ d="m 34.593833,166.76518 c -3,0 -4.5,-2.99999 -4.5,-4.49999 l 0,-27 c 0,-3 1.5,-4.5 4.5,-4.5 l 56.99999,0 c 3,0 4.500005,1.5 4.500005,4.5 l 0,27 c 0,1.5 -1.500005,4.49999 -4.500005,4.49999 l -56.99999,0 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;fill-opacity:1;stroke:#202326;stroke-width:0"
+ id="path199"
+ d="m 34.593833,204.52862 c -1.5,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 3,-3 4.5,-3 l 67.499997,0 c 3,0 6,1.5 6,3 l 0,28.5 c 0,1.5 -3,3 -6,3 l -67.499997,0 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#c8c8c8;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path373"
+ d="m 921.09384,279.26518 c -1.5,0 -4.5,-1.5 -4.5,-3 l 0,-28.5 c 0,-1.5 3,-3 4.5,-3 l 73.5,0 c 3,0 4.5,1.5 4.5,3 l 0,28.5 c 0,1.5 -1.5,3 -4.5,3 l -73.5,0 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#2b2828;stroke-width:0"
+ id="path407"
+ d="m 738.09384,54.265198 39,0" /><path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#2b2828;stroke-width:0"
+ id="path417"
+ d="m 828.09384,52.765198 37.5,0" /><path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#2b2828;stroke-width:0"
+ id="path547"
+ d="m 682.59384,108.2652 -16.5,0" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path551"
+ d="m 579.09384,241.76518 c -1.5,0 -3,-1.5 -3,-4.5 l 0,-25.5 c 0,-1.5 1.5,-4.5 3,-4.5 l 109.5,0 c 3,0 4.5,3 4.5,4.5 l 0,25.5 c 0,3 -1.5,4.5 -4.5,4.5 l -109.5,0 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path553"
+ d="m 633.09384,169.76518 -25.5,0 c -3,0 -4.5,1.5 -4.5,3 l 0,28.5 c 0,1.5 1.5,3 4.5,3 l 81,0 c 3,0 4.5,-1.5 4.5,-3 l 0,-65.99999 c 0,-3 -1.5,-4.5 -4.5,-4.5 l -46.5,0 c -3,0 -4.5,1.5 -4.5,4.5 l 0,29.99999 c 0,3 0,4.5 -4.5,4.5 l 0,0 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path559"
+ d="m 639.09384,244.76518 49.5,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,3 -1.5,4.5 -4.5,4.5 l -49.5,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-3 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path561"
+ d="m 34.593833,241.76518 c -1.5,0 -4.5,-1.5 -4.5,-4.5 0,-7.5 0,-16.5 0,-25.5 0,-1.5 3,-4.5 4.5,-4.5 22.5,0 61.499995,0 85.499997,0 1.5,0 3,3 3,4.5 0,9 0,18 0,25.5 0,3 -1.5,4.5 -3,4.5 -24.000002,0 -62.999997,0 -85.499997,0 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path563"
+ d="m 34.593833,244.76518 44.99999,0 c 1.5,0 3,1.5 3,4.5 l 0,27 c 0,3 -1.5,4.5 -3,4.5 l -44.99999,0 c -3,0 -4.5,-1.5 -4.5,-4.5 l 0,-27 c 0,-3 1.5,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path565"
+ d="m 94.593823,244.76518 28.500007,0 c 3,0 4.5,1.5 4.5,4.5 l 0,27 c 0,1.5 -1.5,4.5 -4.5,4.5 l -28.499997,0 c -1.5,0 -4.5,-3 -4.5,-4.5 l 0,-27 c 0,-3 3,-4.5 4.5,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path567"
+ d="m 138.09383,244.76518 37.50001,0 c 1.5,0 3,1.5 3,4.5 l 0,27 c 0,1.5 -1.5,4.5 -3,4.5 l -37.50001,0 c -1.5,0 -3,-3 -3,-4.5 l 0,-27 c 0,-3 1.5,-4.5 3,-4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#2b2828;stroke-width:0"
+ id="path625"
+ d="m 45.093833,214.76518 -6,6 3,0 0,12 7.5,0 0,-12 3,0 -7.5,-6 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#2b2828;stroke-width:0"
+ id="path631"
+ d="m 589.59384,214.76518 -6,6 3,0 0,12 6,0 0,-12 3,0 -6,-6 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#2b2828;stroke-width:0"
+ id="path741"
+ d="m 943.59384,186.26518 -15,0" /><path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#2b2828;stroke-width:0"
+ id="path745"
+ d="m 981.09384,216.26518 0,15" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#2b2828"
+ id="path829"
+ d="m 927.09384,55.765198 10.5,0 0,-4.5 -10.5,0 0,4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#2b2828;stroke-width:0"
+ id="path831"
+ d="m 927.09384,55.765198 10.5,0 0,-4.5 -10.5,0 0,4.5 z" /><g
+ id="g833"
+ transform="matrix(1.1618355,0,0,1.160175,475.45134,-171.46635)"><text
+ style="font-size:8px;font-weight:normal;fill:#2b2828;font-family:Arial"
+ id="text835"
+ y="192"
+ x="400">Num</text>
+</g><g
+ id="g837"
+ transform="matrix(1.1618355,0,0,1.160175,475.45134,-161.0886)"><text
+ style="font-size:8px;font-weight:normal;fill:#2b2828;font-family:Arial"
+ id="text839"
+ y="192"
+ x="400">Lock</text>
+</g><path
+ inkscape:connector-curvature="0"
+ style="fill:#2b2828"
+ id="path841"
+ d="m 988.59384,55.765198 10.5,0 0,-4.5 -10.5,0 0,4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#2b2828;stroke-width:0"
+ id="path843"
+ d="m 988.59384,55.765198 10.5,0 0,-4.5 -10.5,0 0,4.5 z" /><g
+ id="g845"
+ transform="matrix(1.1618355,0,0,1.160175,537.80334,-171.46635)"><text
+ style="font-size:8px;font-weight:normal;fill:#2b2828;font-family:Arial"
+ id="text847"
+ y="192"
+ x="400">Caps</text>
+</g><g
+ id="g849"
+ transform="matrix(1.1618355,0,0,1.160175,537.80334,-161.0886)"><text
+ style="font-size:8px;font-weight:normal;fill:#2b2828;font-family:Arial"
+ id="text851"
+ y="192"
+ x="400">Lock</text>
+</g><path
+ inkscape:connector-curvature="0"
+ style="fill:#2b2828"
+ id="path853"
+ d="m 1050.0938,55.765198 10.5,0 0,-4.5 -10.5,0 0,4.5 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#2b2828;stroke-width:0"
+ id="path855"
+ d="m 1050.0938,55.765198 10.5,0 0,-4.5 -10.5,0 0,4.5 z" /><g
+ id="g857"
+ transform="matrix(1.1618355,0,0,1.160175,598.67184,-171.46635)"><text
+ style="font-size:8px;font-weight:normal;fill:#2b2828;font-family:Arial"
+ id="text859"
+ y="192"
+ x="400">Scroll</text>
+</g><g
+ id="g861"
+ transform="matrix(1.1618355,0,0,1.160175,598.67184,-161.0886)"><text
+ style="font-size:8px;font-weight:normal;fill:#2b2828;font-family:Arial"
+ id="text863"
+ y="192"
+ x="400">Lock</text>
+</g><path
+ inkscape:connector-curvature="0"
+ style="fill:#969696;stroke:#202326;stroke-width:0;fill-opacity:1"
+ id="path865"
+ d="m 498.09384,244.76518 36,0 c 1.5,0 3,1.5 3,4.5 l 0,27 c 0,1.5 -1.5,4.5 -3,4.5 l -36,0 c -1.5,0 -3,-3 -3,-4.5 l 0,-27 c 0,-3 1.5,-4.5 3,-4.5 z" /><text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="523.65094"
+ y="114.15989"
+ id="text4350"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4352"
+ x="523.65094"
+ y="114.15989"
+ style="font-size:10.01251602px">MINUS</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="569.93738"
+ y="113.49989"
+ id="text4354"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4356"
+ x="569.93738"
+ y="113.49989"
+ style="font-size:10.01251602px">EQUAL</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="631.25299"
+ y="107.90206"
+ id="text4358"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4360"
+ x="631.25299"
+ y="107.90206"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">BACK</tspan><tspan
+ sodipodi:role="line"
+ x="631.25299"
+ y="120.41771"
+ id="tspan4362"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">SLASH</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="674.23523"
+ y="107.90206"
+ id="text4364"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4366"
+ x="674.23523"
+ y="107.90206"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">BACK</tspan><tspan
+ sodipodi:role="line"
+ x="674.23523"
+ y="120.41771"
+ id="tspan4368"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">SPACE</tspan></text>
+<flowRoot
+ xml:space="preserve"
+ id="flowRoot4370"
+ style="font-size:14px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ transform="matrix(1.0012516,0,0,1.0012516,0,-0.59851904)"><flowRegion
+ id="flowRegion4372"><rect
+ id="rect4374"
+ width="13.8221"
+ height="16.413744"
+ x="796.49854"
+ y="219.42694" /></flowRegion><flowPara
+ id="flowPara4376">UP</flowPara></flowRoot><text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="796.85291"
+ y="227.60596"
+ id="text4378"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4380"
+ x="796.85291"
+ y="227.60596"
+ style="font-size:10.01251602px">UP</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:10.01251602px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="786.57721"
+ y="265.65988"
+ id="text4382"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4384"
+ x="786.57721"
+ y="265.65988">DOWN</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="831.22485"
+ y="265.65988"
+ id="text4386"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4388"
+ x="831.22485"
+ y="265.65988"
+ style="font-size:10.01251602px">RIGHT</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="745.96417"
+ y="265.66476"
+ id="text4390"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4392"
+ x="745.96417"
+ y="265.66476"
+ style="font-size:10.01251602px">LEFT</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="30.930361"
+ y="114.15989"
+ id="text4394"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4396"
+ x="30.930361"
+ y="114.15989"
+ style="font-size:10.01251602px">GRAVE</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="48.559547"
+ y="153.8746"
+ id="text4398"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4400"
+ x="48.559547"
+ y="153.8746">TAB</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="53.872166"
+ y="184.6655"
+ id="text4402"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4404"
+ x="53.872166"
+ y="184.6655"
+ style="font-size:10.01251602px">CAPS</tspan><tspan
+ sodipodi:role="line"
+ x="53.872166"
+ y="197.18114"
+ id="tspan4406"
+ style="font-size:10.01251602px">LOCK</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="76.258942"
+ y="221.83604"
+ id="text4408"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4410"
+ x="76.258942"
+ y="221.83604"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">LEFT</tspan><tspan
+ sodipodi:role="line"
+ x="76.258942"
+ y="234.35168"
+ id="tspan4412"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">SHIFT</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="42.099949"
+ y="260.08606"
+ id="text4414"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4416"
+ x="42.099949"
+ y="260.08606"
+ style="font-size:10.01251602px">LEFT</tspan><tspan
+ sodipodi:role="line"
+ x="42.099949"
+ y="272.60172"
+ id="tspan4418"
+ style="font-size:10.01251602px">CTRL</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="156.40872"
+ y="260.15695"
+ id="text4420"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4422"
+ x="156.40872"
+ y="260.15695"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">LEFT</tspan><tspan
+ sodipodi:role="line"
+ x="156.40872"
+ y="272.67261"
+ id="tspan4424"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">ALT</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="311.95728"
+ y="267.86774"
+ id="text4426"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4428"
+ x="311.95728"
+ y="267.86774">SPACE</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="114.88912"
+ y="152.94374"
+ id="text4430"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4432"
+ x="114.88912"
+ y="152.94374">Q</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="157.37325"
+ y="153.8746"
+ id="text4434"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4436"
+ x="157.37325"
+ y="153.8746">W</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="205.17607"
+ y="153.8746"
+ id="text4438"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4440"
+ x="205.17607"
+ y="153.8746">E</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="248.44389"
+ y="153.8746"
+ id="text4442"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4444"
+ x="248.44389"
+ y="153.8746">R</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="294.56638"
+ y="153.8746"
+ id="text4446"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4448"
+ x="294.56638"
+ y="153.8746">T</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="339.26865"
+ y="153.8746"
+ id="text4450"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4452"
+ x="339.26865"
+ y="153.8746">Y</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="383.65265"
+ y="153.77536"
+ id="text4454"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4456"
+ x="383.65265"
+ y="153.77536">U</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="430.2395"
+ y="153.8746"
+ id="text4458"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4460"
+ x="430.2395"
+ y="153.8746">I</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="471.88913"
+ y="153.86775"
+ id="text4462"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4464"
+ x="471.88913"
+ y="153.86775">O</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="517.35114"
+ y="153.8746"
+ id="text4466"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4468"
+ x="517.35114"
+ y="153.8746">P</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="634.15875"
+ y="221.90205"
+ id="text4470"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4472"
+ x="634.15875"
+ y="221.90205"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">RIGHT</tspan><tspan
+ sodipodi:role="line"
+ x="634.15875"
+ y="234.41769"
+ id="tspan4474"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">SHIFT</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="515.65875"
+ y="260.22293"
+ id="text4476"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4478"
+ x="515.65875"
+ y="260.22293"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">RIGHT</tspan><tspan
+ sodipodi:role="line"
+ x="515.65875"
+ y="272.73859"
+ id="tspan4480"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">ALT</tspan></text>
+<flowRoot
+ xml:space="preserve"
+ id="flowRoot4482"
+ style="fill:black;stroke:none;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;font-family:Sans;font-style:normal;font-weight:bold;font-size:14px;line-height:125%;letter-spacing:0px;word-spacing:0px;-inkscape-font-specification:Sans Bold"><flowRegion
+ id="flowRegion4484"><rect
+ id="rect4486"
+ width="47.51347"
+ height="23.324795"
+ x="496.73172"
+ y="261.75711" /></flowRegion><flowPara
+ id="flowPara4488" /></flowRoot><flowRoot
+ xml:space="preserve"
+ id="flowRoot4490"
+ style="fill:black;stroke:none;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;font-family:Sans;font-style:normal;font-weight:bold;font-size:14px;line-height:125%;letter-spacing:0px;word-spacing:0px;-inkscape-font-specification:Sans Bold"><flowRegion
+ id="flowRegion4492"><rect
+ id="rect4494"
+ width="49.24123"
+ height="19.005388"
+ x="501.91501"
+ y="265.21265" /></flowRegion><flowPara
+ id="flowPara4496" /></flowRoot><text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="663.40875"
+ y="260.15204"
+ id="text4498"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4500"
+ x="663.40875"
+ y="260.15204"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">RIGHT</tspan><tspan
+ sodipodi:role="line"
+ x="663.40875"
+ y="272.66769"
+ id="tspan4502"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">CTRL</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="127.41957"
+ y="192.12459"
+ id="text4504"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4506"
+ x="127.41957"
+ y="192.12459">A</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="172.05629"
+ y="192.11775"
+ id="text4508"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4510"
+ x="172.05629"
+ y="192.11775">S</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="215.99883"
+ y="192.12459"
+ id="text4512"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4514"
+ x="215.99883"
+ y="192.12459">D</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="261.50137"
+ y="192.12459"
+ id="text4516"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4518"
+ x="261.50137"
+ y="192.12459">F</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="305.00873"
+ y="192.11775"
+ id="text4520"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4522"
+ x="305.00873"
+ y="192.11775">G</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="349.72812"
+ y="192.12459"
+ id="text4524"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4526"
+ x="349.72812"
+ y="192.12459">H</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="398.27646"
+ y="190.72147"
+ id="text4528"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4530"
+ x="398.27646"
+ y="190.72147">J</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="437.80716"
+ y="192.12459"
+ id="text4532"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4534"
+ x="437.80716"
+ y="192.12459">K</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="484.17609"
+ y="192.12459"
+ id="text4536"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4538"
+ x="484.17609"
+ y="192.12459">L</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="144.2618"
+ y="229.62459"
+ id="text4540"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4542"
+ x="144.2618"
+ y="229.62459">Z</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="188.94696"
+ y="229.62459"
+ id="text4544"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4546"
+ x="188.94696"
+ y="229.62459">X</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="234.29945"
+ y="229.61775"
+ id="text4548"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4550"
+ x="234.29945"
+ y="229.61775">C</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="278.16959"
+ y="229.62459"
+ id="text4552"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4554"
+ x="278.16959"
+ y="229.62459">V</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="322.35114"
+ y="229.62459"
+ id="text4556"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4558"
+ x="322.35114"
+ y="229.62459">B</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="367.58972"
+ y="230.23622"
+ id="text4560"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4562"
+ x="367.58972"
+ y="230.23622">N</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="410.12271"
+ y="229.62459"
+ id="text4564"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4566"
+ x="410.12271"
+ y="229.62459">M</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="621.96155"
+ y="191.69684"
+ id="text4568"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4570"
+ x="621.96155"
+ y="191.69684">ENTER</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="567.00342"
+ y="146.08606"
+ id="text4572"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4574"
+ x="567.00342"
+ y="146.08606"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">LEFT</tspan><tspan
+ sodipodi:role="line"
+ x="567.00342"
+ y="158.6017"
+ id="tspan4576"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">BRACE</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="611.25342"
+ y="146.15205"
+ id="text4578"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4580"
+ x="611.25342"
+ y="146.15205"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">RIGHT</tspan><tspan
+ sodipodi:role="line"
+ x="611.25342"
+ y="158.66769"
+ id="tspan4582"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">BRACE</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="534.33051"
+ y="184.40205"
+ id="text4584"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4586"
+ x="534.33051"
+ y="184.40205"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">SEMI-</tspan><tspan
+ sodipodi:role="line"
+ x="534.33051"
+ y="196.91769"
+ id="tspan4588"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">COLON</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="577.71429"
+ y="184.66336"
+ id="text4590"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4592"
+ x="577.71429"
+ y="184.66336"
+ style="font-size:9.0112648px;text-align:center;text-anchor:middle">APHOS-</tspan><tspan
+ sodipodi:role="line"
+ x="577.71429"
+ y="195.92744"
+ id="tspan4594"
+ style="font-size:9.0112648px;text-align:center;text-anchor:middle">TROPHE</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="441.56339"
+ y="227.79541"
+ id="text4596"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4598"
+ x="441.56339"
+ y="227.79541"
+ style="font-size:9.0112648px">COMMA</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="494.08731"
+ y="228.15987"
+ id="text4600"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4602"
+ x="494.08731"
+ y="228.15987"
+ style="font-size:10.01251602px">DOT</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="532.05072"
+ y="228.15987"
+ id="text4604"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4606"
+ x="532.05072"
+ y="228.15987"
+ style="font-size:10.01251602px">SLASH</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="89.409126"
+ y="115.62461"
+ id="text4608"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4610"
+ x="89.409126"
+ y="115.62461">1</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="134.02188"
+ y="115.71701"
+ id="text4612"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4614"
+ x="134.02188"
+ y="115.71701">2</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="178.30611"
+ y="115.61777"
+ id="text4616"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4618"
+ x="178.30611"
+ y="115.61777">3</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="223.22398"
+ y="115.62461"
+ id="text4620"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4622"
+ x="223.22398"
+ y="115.62461">4</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="267.4158"
+ y="115.52536"
+ id="text4624"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4626"
+ x="267.4158"
+ y="115.52536">5</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="311.65897"
+ y="115.61092"
+ id="text4628"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4630"
+ x="311.65897"
+ y="115.61092">6</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="356.80612"
+ y="115.62461"
+ id="text4632"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4634"
+ x="356.80612"
+ y="115.62461">7</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="400.97397"
+ y="115.61777"
+ id="text4636"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4638"
+ x="400.97397"
+ y="115.61777">8</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="445.3027"
+ y="115.61092"
+ id="text4640"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4642"
+ x="445.3027"
+ y="115.61092">9</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="490.21713"
+ y="115.61777"
+ id="text4644"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4646"
+ x="490.21713"
+ y="115.61777">0</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="34.412743"
+ y="54.867767"
+ id="text4648"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4650"
+ x="34.412743"
+ y="54.867767">ESC</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="129.01514"
+ y="54.874611"
+ id="text4652"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4654"
+ x="129.01514"
+ y="54.874611">F1</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="173.39177"
+ y="54.967014"
+ id="text4656"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4658"
+ x="173.39177"
+ y="54.967014">F2</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="218.34044"
+ y="54.867767"
+ id="text4660"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4662"
+ x="218.34044"
+ y="54.867767">F3</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="262.35431"
+ y="54.874611"
+ id="text4664"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4666"
+ x="262.35431"
+ y="54.874611">F4</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="328.522"
+ y="53.275368"
+ id="text4668"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4670"
+ x="328.522"
+ y="53.275368">F5</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="373.40906"
+ y="53.360924"
+ id="text4672"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4674"
+ x="373.40906"
+ y="53.360924">F6</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="417.84042"
+ y="53.374611"
+ id="text4676"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4678"
+ x="417.84042"
+ y="53.374611">F7</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="461.96722"
+ y="53.367767"
+ id="text4680"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4682"
+ x="461.96722"
+ y="53.367767">F8</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="527.9809"
+ y="53.360924"
+ id="text4684"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4686"
+ x="527.9809"
+ y="53.360924">F9</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="566.49469"
+ y="53.367767"
+ id="text4688"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4690"
+ x="566.49469"
+ y="53.367767">F10</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="611.64185"
+ y="53.374611"
+ id="text4692"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4694"
+ x="611.64185"
+ y="53.374611">F11</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="656.76849"
+ y="53.467014"
+ id="text4696"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan4698"
+ x="656.76849"
+ y="53.467014">F12</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="787.89636"
+ y="113.40989"
+ id="text3394"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3396"
+ x="787.89636"
+ y="113.40989"
+ style="font-size:10.01251602px">HOME</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="740.84229"
+ y="150.5498"
+ id="text3398"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3400"
+ x="740.84229"
+ y="150.5498"
+ style="font-size:9.0112648px">DELETE</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="792.87329"
+ y="150.91476"
+ id="text3402"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3404"
+ x="792.87329"
+ y="150.91476"
+ style="font-size:10.01251602px">END</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="741.33289"
+ y="113.04542"
+ id="text3406"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3408"
+ x="741.33289"
+ y="113.04542"
+ style="font-size:9.0112648px">INSERT</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="849.00342"
+ y="107.15206"
+ id="text3410"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3412"
+ x="849.00342"
+ y="107.15206"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">PAGE</tspan><tspan
+ sodipodi:role="line"
+ x="849.00342"
+ y="119.66771"
+ id="tspan3414"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">UP</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="849.09875"
+ y="144.65205"
+ id="text3416"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3418"
+ x="849.09875"
+ y="144.65205"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">PAGE</tspan><tspan
+ sodipodi:role="line"
+ x="849.09875"
+ y="157.16769"
+ id="tspan3420"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">DOWN</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="108.40627"
+ y="260.15695"
+ id="text3422"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3424"
+ x="108.40627"
+ y="260.15695"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">LEFT</tspan><tspan
+ sodipodi:role="line"
+ x="108.40627"
+ y="272.67261"
+ id="tspan3426"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">META</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="563.7561"
+ y="260.22293"
+ id="text3428"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3430"
+ x="563.7561"
+ y="260.22293"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">RIGHT</tspan><tspan
+ sodipodi:role="line"
+ x="563.7561"
+ y="272.73859"
+ id="tspan3432"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">META</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="593.37152"
+ y="260.15204"
+ id="text3434"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3436"
+ x="593.37152"
+ y="260.15204"
+ style="font-size:10.01251602px">COM-</tspan><tspan
+ sodipodi:role="line"
+ x="593.37152"
+ y="272.66769"
+ style="font-size:10.01251602px"
+ id="tspan3438">POSE</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="738.53436"
+ y="51.249886"
+ id="text3440"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ x="738.53436"
+ y="51.249886"
+ id="tspan3444"
+ style="font-size:10.01251602px">SYSRQ</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="936.03027"
+ y="150.91476"
+ id="text3448"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ x="936.03027"
+ y="150.91476"
+ id="tspan3452"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">KP 7</tspan></text>
+<flowRoot
+ xml:space="preserve"
+ id="flowRoot3454"
+ style="fill:black;stroke:none;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;font-family:Sans;font-style:normal;font-weight:bold;font-size:14px;line-height:125%;letter-spacing:0px;word-spacing:0px;-inkscape-font-specification:Sans Bold"><flowRegion
+ id="flowRegion3456"><rect
+ id="rect3458"
+ width="17.277626"
+ height="18.141506"
+ x="921.32935"
+ y="139.94986" /></flowRegion><flowPara
+ id="flowPara3460"></flowPara></flowRoot><flowRoot
+ xml:space="preserve"
+ id="flowRoot3462"
+ style="fill:black;stroke:none;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;font-family:Sans;font-style:normal;font-weight:bold;font-size:14px;line-height:125%;letter-spacing:0px;word-spacing:0px;-inkscape-font-specification:Sans Bold"><flowRegion
+ id="flowRegion3464"><rect
+ id="rect3466"
+ width="26.780319"
+ height="23.756735"
+ x="913.98639"
+ y="138.22211" /></flowRegion><flowPara
+ id="flowPara3468"></flowPara></flowRoot><text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="967.42242"
+ y="150.90988"
+ id="text3472"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3474"
+ x="967.42242"
+ y="150.90988"
+ style="font-size:10.01251602px">KP 8</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="1011.6821"
+ y="150.90498"
+ id="text3476"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3478"
+ x="1011.6821"
+ y="150.90498"
+ style="font-size:10.01251602px">KP 9</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="1069.5033"
+ y="107.08607"
+ id="text3480"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3482"
+ x="1069.5033"
+ y="107.08607"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">KP</tspan><tspan
+ sodipodi:role="line"
+ x="1069.5033"
+ y="119.60172"
+ id="tspan3484"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">MINUS</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="923.09174"
+ y="189.91476"
+ id="text3486"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3488"
+ x="923.09174"
+ y="189.91476"
+ style="font-size:10.01251602px">KP 4</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="967.46155"
+ y="189.84387"
+ id="text3490"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3492"
+ x="967.46155"
+ y="189.84387"
+ style="font-size:10.01251602px">KP 5</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="1011.6308"
+ y="189.90498"
+ id="text3494"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3496"
+ x="1011.6308"
+ y="189.90498"
+ style="font-size:10.01251602px">KP 6</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="1069.5033"
+ y="164.08606"
+ id="text3498"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3500"
+ x="1069.5033"
+ y="164.08606"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">KP</tspan><tspan
+ sodipodi:role="line"
+ x="1069.5033"
+ y="176.6017"
+ id="tspan3502"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">PLUS</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="923.20667"
+ y="228.16476"
+ id="text3504"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3506"
+ x="923.20667"
+ y="228.16476"
+ style="font-size:10.01251602px">KP 1</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="967.54706"
+ y="228.23076"
+ id="text3508"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3510"
+ x="967.54706"
+ y="228.23076"
+ style="font-size:10.01251602px">KP 2</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="1011.7604"
+ y="228.15987"
+ id="text3512"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3514"
+ x="1011.7604"
+ y="228.15987"
+ style="font-size:10.01251602px">KP 3</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="944.8515"
+ y="265.65988"
+ id="text3516"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3518"
+ x="944.8515"
+ y="265.65988"
+ style="font-size:10.01251602px">KP 0</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="1024.1587"
+ y="259.33606"
+ id="text3520"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3522"
+ x="1024.1587"
+ y="259.33606"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">KP</tspan><tspan
+ sodipodi:role="line"
+ x="1024.1587"
+ y="271.85172"
+ id="tspan3524"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">DOT</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="1069.2321"
+ y="240.65694"
+ id="text3526"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3528"
+ x="1069.2321"
+ y="240.65694"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">KP</tspan><tspan
+ sodipodi:role="line"
+ x="1069.2321"
+ y="253.17258"
+ id="tspan3530"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">ENTER</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="1024.8204"
+ y="101.72194"
+ id="text3532"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3534"
+ x="1024.8204"
+ y="101.72194"
+ style="font-size:9.0112648px;text-align:center;text-anchor:middle">KP</tspan><tspan
+ sodipodi:role="line"
+ x="1024.8204"
+ y="112.98602"
+ id="tspan3536"
+ style="font-size:9.0112648px;text-align:center;text-anchor:middle">ASTE-</tspan><tspan
+ sodipodi:role="line"
+ x="1024.8204"
+ y="124.2501"
+ style="font-size:9.0112648px;text-align:center;text-anchor:middle"
+ id="tspan3538">RISK</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="980.44897"
+ y="107.08607"
+ id="text3540"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3542"
+ x="980.44897"
+ y="107.08607"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">KP</tspan><tspan
+ sodipodi:role="line"
+ x="980.44897"
+ y="119.60172"
+ id="tspan3544"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">SLASH</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="935.50232"
+ y="107.08607"
+ id="text3546"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3548"
+ x="935.50232"
+ y="107.08607"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">NUM</tspan><tspan
+ sodipodi:role="line"
+ x="935.50232"
+ y="119.60172"
+ id="tspan3550"
+ style="font-size:10.01251602px;text-align:center;text-anchor:middle">LOCK</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="802.39142"
+ y="45.91338"
+ id="text3552"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3554"
+ x="802.39142"
+ y="45.91338"
+ style="font-size:9.0112648px;text-align:center;text-anchor:middle">SCROLL</tspan><tspan
+ sodipodi:role="line"
+ x="802.39142"
+ y="57.17746"
+ id="tspan3556"
+ style="font-size:9.0112648px;text-align:center;text-anchor:middle">LOCK</tspan></text>
+<text
+ xml:space="preserve"
+ style="font-size:14.01752281px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+ x="828.73285"
+ y="51.909889"
+ id="text3558"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3560"
+ x="828.73285"
+ y="51.909889"
+ style="font-size:10.01251602px">PAUSE</tspan></text>
+</svg>
No newline at end of file
http://repo.or.cz/w/gfxprim.git/commit/a3408f4de5a85d72c3c5439f68c459c1d328…
commit a3408f4de5a85d72c3c5439f68c459c1d328201b
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Wed Jan 30 16:52:58 2013 +0100
input: X11: Fill the gaps in keyboard mapping.
diff --git a/libs/input/GP_InputDriverX11.c b/libs/input/GP_InputDriverX11.c
index a63896c..a1702a2 100644
--- a/libs/input/GP_InputDriverX11.c
+++ b/libs/input/GP_InputDriverX11.c
@@ -44,21 +44,25 @@ static uint16_t keycode_table[] = {
GP_KEY_GRAVE, GP_KEY_LEFT_SHIFT, GP_KEY_BACKSLASH, GP_KEY_Z,
GP_KEY_X, GP_KEY_C, GP_KEY_V, GP_KEY_B,
GP_KEY_N, GP_KEY_M, GP_KEY_COMMA, GP_KEY_DOT,
- GP_KEY_SLASH, GP_KEY_RIGHT_SHIFT, 0, GP_KEY_LEFT_ALT,
+ GP_KEY_SLASH, GP_KEY_RIGHT_SHIFT, GP_KEY_KP_ASTERISK, GP_KEY_LEFT_ALT,
GP_KEY_SPACE, GP_KEY_CAPS_LOCK, GP_KEY_F1, GP_KEY_F2,
GP_KEY_F3, GP_KEY_F4, GP_KEY_F5, GP_KEY_F6,
GP_KEY_F7, GP_KEY_F8, GP_KEY_F9, GP_KEY_F10,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
+ GP_KEY_NUM_LOCK, GP_KEY_SCROLL_LOCK, GP_KEY_KP_7, GP_KEY_KP_8,
+ GP_KEY_KP_9, GP_KEY_KP_MINUS, GP_KEY_KP_4, GP_KEY_KP_5,
+ GP_KEY_KP_6, GP_KEY_KP_PLUS, GP_KEY_KP_1, GP_KEY_KP_2,
+ GP_KEY_KP_3, GP_KEY_KP_0, GP_KEY_KP_DOT, 0,
0, 0, GP_KEY_F11, GP_KEY_F12,
0, 0, 0, 0,
- 0, 0, 0, 0,
- GP_KEY_RIGHT_CTRL, 0, /* PRINTSCREEN */0, GP_KEY_RIGHT_ALT,
+ 0, 0, 0, GP_KEY_KP_ENTER,
+ GP_KEY_RIGHT_CTRL, GP_KEY_KP_SLASH, GP_KEY_SYSRQ, GP_KEY_RIGHT_ALT,
0, GP_KEY_HOME, GP_KEY_UP, GP_KEY_PAGE_UP,
GP_KEY_LEFT, GP_KEY_RIGHT, GP_KEY_END, GP_KEY_DOWN,
- GP_KEY_PAGE_DOWN, 0, GP_KEY_DELETE,
+ GP_KEY_PAGE_DOWN, GP_KEY_INSERT, GP_KEY_DELETE, 0,
+ 0, 0, 0, 0,
+ 0, 0, GP_KEY_PAUSE, 0,
+ 0, 0, 0, 0,
+ GP_KEY_LEFT_META, GP_KEY_RIGHT_META, GP_KEY_COMPOSE,
};
static const uint16_t keycode_table_size = sizeof(keycode_table)/2;
-----------------------------------------------------------------------
Summary of changes:
doc/input.txt | 8 +
doc/keyboard.svg | 2150 ++++++++++++++++++++++++++++++++++++++++
libs/input/GP_InputDriverX11.c | 20 +-
3 files changed, 2170 insertions(+), 8 deletions(-)
create mode 100644 doc/keyboard.svg
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: ff6f39694f9b44497c6ec7f4d3b9c27ab180510a
by metan 30 Jan '13
by metan 30 Jan '13
30 Jan '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via ff6f39694f9b44497c6ec7f4d3b9c27ab180510a (commit)
via 3f9f0c9b1e899fb28031ea3f11671f9bce3c1caa (commit)
from 5109c64bfb2ac61e8fe89114c3843c0782e22543 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/ff6f39694f9b44497c6ec7f4d3b9c27ab180…
commit ff6f39694f9b44497c6ec7f4d3b9c27ab180510a
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Wed Jan 30 13:34:20 2013 +0100
spiv: A few fixes for -zf (fixed zoom mode).
diff --git a/demos/spiv/spiv.c b/demos/spiv/spiv.c
index 6059199..f681b1a 100644
--- a/demos/spiv/spiv.c
+++ b/demos/spiv/spiv.c
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -528,15 +528,10 @@ static void show_image(struct loader_params *params, const char *path)
}
}
-static void zoom_offset_horiz(struct loader_params *params, int size)
+static void set_zoom_offset(struct loader_params *params, int dx, int dy)
{
- params->zoom_x_offset += size;
- show_image(params, NULL);
-}
-
-static void zoom_offset_vert(struct loader_params *params, int size)
-{
- params->zoom_y_offset += size;
+ params->zoom_x_offset += dx;
+ params->zoom_y_offset += dy;
show_image(params, NULL);
}
@@ -863,7 +858,6 @@ int main(int argc, char *argv[])
GP_Fill(context, black_pixel);
GP_BackendFlip(backend);
-
struct image_list *list = image_list_create((const char**)argv + optind);
params.show_progress_once = 1;
@@ -892,6 +886,12 @@ int main(int argc, char *argv[])
if (ev.val.val < 0)
goto prev;
break;
+ case GP_EV_REL_POS:
+ if (GP_EventGetKey(&ev, GP_BTN_LEFT))
+ set_zoom_offset(¶ms,
+ ev.val.rel.rx,
+ ev.val.rel.ry);
+ break;
}
break;
case GP_EV_KEY:
@@ -992,12 +992,12 @@ int main(int argc, char *argv[])
next:
case GP_KEY_RIGHT:
if (shift_flag) {
- zoom_offset_horiz(¶ms, 10);
+ set_zoom_offset(¶ms, 10, 0);
break;
}
case GP_KEY_UP:
if (shift_flag) {
- zoom_offset_vert(¶ms, -10);
+ set_zoom_offset(¶ms, 0, -10);
break;
}
case GP_KEY_SPACE:
@@ -1007,12 +1007,12 @@ int main(int argc, char *argv[])
prev:
case GP_KEY_LEFT:
if (shift_flag) {
- zoom_offset_horiz(¶ms, -10);
+ set_zoom_offset(¶ms, -10, 0);
break;
}
case GP_KEY_DOWN:
if (shift_flag) {
- zoom_offset_vert(¶ms, 10);
+ set_zoom_offset(¶ms, 0, 10);
break;
}
case GP_KEY_BACKSPACE:
@@ -1047,9 +1047,11 @@ int main(int argc, char *argv[])
resize_backend(¶ms, 9, shift_flag);
break;
case GP_KEY_DOT:
+ params.show_progress_once = 1;
zoom_mul(¶ms, 1.5);
break;
case GP_KEY_COMMA:
+ params.show_progress_once = 1;
zoom_mul(¶ms, 1/1.5);
break;
}
@@ -1062,6 +1064,7 @@ int main(int argc, char *argv[])
GP_BackendResizeAck(backend);
GP_Fill(backend->context, 0);
params.show_progress_once = 1;
+ GP_EventSetScreenSize(ev.val.sys.w, ev.val.sys.h);
show_image(¶ms, NULL);
break;
case GP_EV_SYS_QUIT:
http://repo.or.cz/w/gfxprim.git/commit/3f9f0c9b1e899fb28031ea3f11671f9bce3c…
commit 3f9f0c9b1e899fb28031ea3f11671f9bce3c1caa
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Wed Jan 30 13:32:34 2013 +0100
spiv: image_cache: Store at least one image.
This fixes memory leaks and crashes when
image is too big to be stored in image
cache maximal size.
diff --git a/demos/spiv/image_cache.c b/demos/spiv/image_cache.c
index 00712c9..496489e 100644
--- a/demos/spiv/image_cache.c
+++ b/demos/spiv/image_cache.c
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -229,8 +229,12 @@ int image_cache_put(struct image_cache *self, GP_Context *ctx, const char *path,
size = image_size2(ctx, path);
- if (assert_size(self, size))
- return 1;
+ /*
+ * We try to create room for the image. If this fails we add the image
+ * anyway because we need to store it while we are showing it (and it
+ * will be removed from cache by next image for sure).
+ */
+ assert_size(self, size);
struct image *img = malloc(sizeof(struct image) + strlen(path) + 1);
-----------------------------------------------------------------------
Summary of changes:
demos/spiv/image_cache.c | 10 +++++++---
demos/spiv/spiv.c | 31 +++++++++++++++++--------------
2 files changed, 24 insertions(+), 17 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 5109c64bfb2ac61e8fe89114c3843c0782e22543
by metan 29 Jan '13
by metan 29 Jan '13
29 Jan '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 5109c64bfb2ac61e8fe89114c3843c0782e22543 (commit)
from 1a93c45d484a05a1e5e8ca1cf1a0046e10d3398d (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/5109c64bfb2ac61e8fe89114c3843c0782e2…
commit 5109c64bfb2ac61e8fe89114c3843c0782e22543
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Tue Jan 29 22:43:35 2013 +0100
demos: Start bogoman.
diff --git a/demos/Makefile b/demos/Makefile
index ec4885b..1943f91 100644
--- a/demos/Makefile
+++ b/demos/Makefile
@@ -1,3 +1,3 @@
TOPDIR=..
-SUBDIRS=grinder spiv particle ttf2img c_simple
+SUBDIRS=grinder spiv particle ttf2img c_simple bogoman
include $(TOPDIR)/post.mk
diff --git a/demos/bogoman/Makefile b/demos/bogoman/Makefile
new file mode 100644
index 0000000..e90de8e
--- /dev/null
+++ b/demos/bogoman/Makefile
@@ -0,0 +1,15 @@
+TOPDIR=../..
+
+CSOURCES=$(shell echo *.c)
+
+INCLUDE=
+LDFLAGS+=-L$(TOPDIR)/build/
+LDLIBS+=`$(TOPDIR)/gfxprim-config --libs --libs-backends`
+
+APPS=bogoman
+
+bogoman: bogoman_map.o bogoman_debug.o bogoman_loader.o bogoman_render.o
+
+include $(TOPDIR)/pre.mk
+include $(TOPDIR)/app.mk
+include $(TOPDIR)/post.mk
diff --git a/demos/bogoman/bogoman.c b/demos/bogoman/bogoman.c
new file mode 100644
index 0000000..f6f969b
--- /dev/null
+++ b/demos/bogoman/bogoman.c
@@ -0,0 +1,149 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#include <GP.h>
+
+#include "bogoman_debug.h"
+#include "bogoman_map.h"
+#include "bogoman_loader.h"
+#include "bogoman_render.h"
+
+#define ELEM_SIZE 33
+
+static void save_png(struct bogoman_map *map, unsigned int elem_size,
+ const char *filename)
+{
+ GP_Context *ctx;
+ unsigned int rx, ry;
+
+ rx = elem_size * map->w;
+ ry = elem_size * map->h;
+
+ ctx = GP_ContextAlloc(rx, ry, GP_PIXEL_RGB888);
+
+ if (ctx == NULL)
+ return;
+
+ struct bogoman_render render = {
+ .map = map,
+ .map_x_offset = 0,
+ .map_y_offset = 0,
+ .ctx = ctx,
+ .map_elem_size = elem_size,
+ };
+
+ bogoman_render(&render, BOGOMAN_RENDER_ALL);
+
+ GP_SavePNG(ctx, filename, NULL);
+ GP_ContextFree(ctx);
+}
+
+static struct GP_Backend *backend;
+
+static void event_loop(struct bogoman_map *map)
+{
+ while (GP_EventsQueued()) {
+ GP_Event ev;
+
+ GP_EventGet(&ev);
+
+ switch (ev.type) {
+ case GP_EV_KEY:
+ if (ev.code != GP_EV_KEY_DOWN)
+ break;
+
+ switch (ev.val.val) {
+ case GP_KEY_ESC:
+ GP_BackendExit(backend);
+ exit(0);
+ break;
+ case GP_KEY_RIGHT:
+ bogoman_map_player_move(map, 1, 0);
+ break;
+ case GP_KEY_LEFT:
+ bogoman_map_player_move(map, -1, 0);
+ break;
+ case GP_KEY_UP:
+ bogoman_map_player_move(map, 0, -1);
+ break;
+ case GP_KEY_DOWN:
+ bogoman_map_player_move(map, 0, 1);
+ break;
+ }
+ break;
+ }
+ }
+
+
+}
+
+int main(int argc, char *argv[])
+{
+ struct bogoman_map *map;
+
+ bogoman_set_dbg_level(10);
+
+ if (argc > 1)
+ map = bogoman_load(argv[1]);
+ else
+ map = bogoman_load("map.txt");
+
+ if (map == NULL) {
+ fprintf(stderr, "Failed to load map");
+ return 1;
+ }
+
+ bogoman_map_dump(map);
+
+ unsigned int cw = map->w * ELEM_SIZE;
+ unsigned int ch = map->h * ELEM_SIZE;
+
+ backend = GP_BackendX11Init(NULL, 0, 0, cw, ch, "Bogoman", 0);
+
+ if (backend == NULL) {
+ fprintf(stderr, "Failed to initialize backend");
+ return 1;
+ }
+
+ struct bogoman_render render = {
+ .map = map,
+ .map_x_offset = 0,
+ .map_y_offset = 0,
+ .ctx = backend->context,
+ .map_elem_size = ELEM_SIZE,
+ };
+
+ bogoman_render(&render, BOGOMAN_RENDER_ALL);
+ GP_BackendFlip(backend);
+
+ for (;;) {
+ GP_BackendPoll(backend);
+ event_loop(map);
+
+ bogoman_render(&render, BOGOMAN_RENDER_DIRTY);
+ GP_BackendFlip(backend);
+
+ usleep(100000);
+ }
+
+ return 0;
+}
diff --git a/demos/bogoman/bogoman_common.h b/demos/bogoman/bogoman_common.h
new file mode 100644
index 0000000..39367a5
--- /dev/null
+++ b/demos/bogoman/bogoman_common.h
@@ -0,0 +1,37 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#ifndef __BOGOMAN_COMMON_H__
+#define __BOGOMAN_COMMON_H__
+
+#define SWAP(a, b) do { + typeof(a) tmp = b; + b = a; + a = tmp; +} while (0)
+
+#define SIGN(a) ({ + typeof(a) tmp = a; + (tmp < 0) ? -1 : (tmp > 0) ? 1 : 0; +})
+
+#endif /* __BOGOMAN_COMMON_H__ */
diff --git a/demos/bogoman/bogoman_debug.c b/demos/bogoman/bogoman_debug.c
new file mode 100644
index 0000000..d5ee213
--- /dev/null
+++ b/demos/bogoman/bogoman_debug.c
@@ -0,0 +1,51 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "bogoman_debug.h"
+
+static unsigned int dbg_level = 0;
+
+void bogoman_dbg_print(unsigned int level, const char *file, const char *fn,
+ unsigned int line, const char *fmt, ...)
+{
+ if (level > dbg_level)
+ return;
+
+ if (level == 0)
+ fprintf(stderr, "WARNING: %s:%s:%int", file, fn, line);
+ else
+ fprintf(stderr, "DEBUG %i:%s:%s:%i:nt", level, file, fn, line);
+
+ va_list va;
+
+ va_start(va, fmt);
+ vfprintf(stderr, fmt, va);
+ va_end(va);
+}
+
+void bogoman_set_dbg_level(unsigned int level)
+{
+ dbg_level = level;
+}
diff --git a/demos/bogoman/bogoman_debug.h b/demos/bogoman/bogoman_debug.h
new file mode 100644
index 0000000..b84729a
--- /dev/null
+++ b/demos/bogoman/bogoman_debug.h
@@ -0,0 +1,39 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#ifndef __BOGOMAN_DEBUG_H__
+#define __BOGOMAN_DEBUG_H__
+
+#define DEBUG(level, ...) + bogoman_dbg_print(level, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+
+#define WARN(...) + bogoman_dbg_print(0, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+
+
+void bogoman_dbg_print(unsigned int level, const char *file, const char *fn,
+ unsigned int line, const char *fmt, ...)
+ __attribute__ ((format (printf, 5, 6)));
+
+void bogoman_set_dbg_level(unsigned int level);
+
+#endif /* __BOGOMAN_DEBUG_H__ */
diff --git a/demos/bogoman/bogoman_loader.c b/demos/bogoman/bogoman_loader.c
new file mode 100644
index 0000000..e1f3eed
--- /dev/null
+++ b/demos/bogoman/bogoman_loader.c
@@ -0,0 +1,220 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "bogoman_debug.h"
+#include "bogoman_common.h"
+#include "bogoman_loader.h"
+
+/*
+ * Counts map w and h by reading number of lines and maximal size of line till
+ * first empty line or EOF.
+ */
+static void get_map_info(FILE *f, unsigned int *w, unsigned int *h)
+{
+ unsigned int curw = 0;
+ int ch;
+
+ *w = 0;
+ *h = 0;
+
+ while ((ch = getc(f)) != EOF) {
+ switch (ch) {
+ case 'n':
+ if (*w < curw)
+ *w = curw;
+
+ if (curw == 0) {
+ rewind(f);
+ return;
+ }
+
+ curw = 0;
+ (*h)++;
+ break;
+ default:
+ curw++;
+ }
+ }
+
+ rewind(f);
+}
+
+static enum bogoman_map_elem_id id_from_char(const char ch)
+{
+ switch (ch) {
+ case ' ':
+ return BOGOMAN_NONE;
+ case '@':
+ return BOGOMAN_PLAYER;
+ case '-':
+ case '|':
+ case '+':
+ case '/':
+ case '\':
+ return BOGOMAN_WALL;
+ case '$':
+ return BOGOMAN_DIAMOND;
+ case 'M':
+ return BOGOMAN_MOVEABLE;
+ case 'E':
+ return BOGOMAN_EDIBLE;
+ }
+
+ WARN("Unknown map character '%c'", ch);
+
+ return BOGOMAN_NONE;
+}
+
+#define LINE_MAX 256
+
+struct line {
+ unsigned int len;
+ unsigned char line[LINE_MAX];
+};
+
+static void get_line(FILE *f, struct line *l)
+{
+ int ch;
+
+ l->len = 0;
+
+ while ((ch = getc(f)) != EOF) {
+ switch (ch) {
+ case 'n':
+ return;
+ default:
+ l->line[l->len++] = id_from_char(ch);
+ break;
+ }
+ }
+}
+
+static void load_map(FILE *f, struct bogoman_map *map)
+{
+ struct line line_a, line_b;
+ struct line *line_cur, *line_next;
+ unsigned int y = 0;
+ unsigned int player_found = 0;
+
+ line_cur = &line_a;
+ line_next = &line_b;
+
+ get_line(f, line_cur);
+ get_line(f, line_next);
+
+ while (line_cur->len != 0) {
+ unsigned int x;
+
+ for (x = 0; x < line_cur->len; x++) {
+ struct bogoman_map_elem *elem;
+
+ elem = bogoman_get_map_elem(map, x, y);
+
+ elem->id = line_cur->line[x];
+
+ switch (elem->id) {
+ /* Compute wall continuations */
+ case BOGOMAN_WALL:
+ if (x > 0 &&
+ line_cur->line[x - 1] == BOGOMAN_WALL)
+ elem->flags |= BOGOMAN_WALL_LEFT;
+
+ if (x + 1 < line_cur->len &&
+ line_cur->line[x + 1] == BOGOMAN_WALL)
+ elem->flags |= BOGOMAN_WALL_RIGHT;
+
+ if (y > 0 &&
+ bogoman_map_is_id(map, x, y-1, BOGOMAN_WALL))
+ elem->flags |= BOGOMAN_WALL_UP;
+
+ if (x < line_next->len &&
+ line_next->line[x] == BOGOMAN_WALL)
+ elem->flags |= BOGOMAN_WALL_DOWN;
+
+ break;
+ case BOGOMAN_PLAYER:
+ if (player_found)
+ WARN("Duplicated player at %ux%u previously at %ux%un",
+ x, y, map->player_x, map->player_y);
+
+ map->player_x = x;
+ map->player_y = y;
+
+ player_found = 1;
+ break;
+ case BOGOMAN_DIAMOND:
+ map->diamonds_total++;
+ break;
+ default:
+ break;
+ }
+ }
+
+ SWAP(line_cur, line_next);
+ get_line(f, line_next);
+ y++;
+ }
+
+ if (!player_found)
+ WARN("No player found in mapn");
+}
+
+struct bogoman_map *bogoman_load(const char *path)
+{
+ FILE *f = fopen(path, "r");
+
+ if (f == NULL)
+ return NULL;
+
+ unsigned int w, h;
+
+ get_map_info(f, &w, &h);
+
+ DEBUG(1, "Have map %ux%un", w, h);
+
+ struct bogoman_map *map;
+ size_t map_size;
+
+ map_size = sizeof(struct bogoman_map) +
+ w * h * sizeof(struct bogoman_map_elem);
+
+ map = malloc(map_size);
+
+ if (map == NULL)
+ goto err0;
+
+ memset(map, 0, map_size);
+
+ map->w = w;
+ map->h = h;
+
+ load_map(f, map);
+
+ return map;
+err0:
+ fclose(f);
+ return NULL;
+}
diff --git a/demos/bogoman/bogoman_loader.h b/demos/bogoman/bogoman_loader.h
new file mode 100644
index 0000000..027efd4
--- /dev/null
+++ b/demos/bogoman/bogoman_loader.h
@@ -0,0 +1,30 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#ifndef __BOGOMAN_LOADER_H__
+#define __BOGOMAN_LOADER_H__
+
+#include "bogoman_map.h"
+
+struct bogoman_map *bogoman_load(const char *path);
+
+#endif /* __BOGOMAN_LOADER_H__ */
diff --git a/demos/bogoman/bogoman_map.c b/demos/bogoman/bogoman_map.c
new file mode 100644
index 0000000..2f62c64
--- /dev/null
+++ b/demos/bogoman/bogoman_map.c
@@ -0,0 +1,245 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#include <stdio.h>
+
+#include "bogoman_common.h"
+#include "bogoman_debug.h"
+
+#include "bogoman_map.h"
+
+static void print_wall(struct bogoman_map_elem *elem)
+{
+ switch (elem->flags) {
+ case BOGOMAN_WALL_LEFT:
+ case BOGOMAN_WALL_RIGHT:
+ case BOGOMAN_WALL_LEFT | BOGOMAN_WALL_RIGHT:
+ printf("-");
+ break;
+ case BOGOMAN_WALL_UP:
+ case BOGOMAN_WALL_DOWN:
+ case BOGOMAN_WALL_UP | BOGOMAN_WALL_DOWN:
+ printf("|");
+ break;
+ case BOGOMAN_WALL_UP | BOGOMAN_WALL_RIGHT:
+ case BOGOMAN_WALL_DOWN | BOGOMAN_WALL_LEFT:
+ printf("\");
+ break;
+ case BOGOMAN_WALL_UP | BOGOMAN_WALL_LEFT:
+ case BOGOMAN_WALL_DOWN | BOGOMAN_WALL_RIGHT:
+ printf("/");
+ break;
+ default:
+ printf("+");
+ break;
+ }
+}
+
+void bogoman_map_dump(struct bogoman_map *map)
+{
+ unsigned int x, y;
+
+ for (y = 0; y < map->h; y++) {
+ for (x = 0; x < map->w; x++) {
+ struct bogoman_map_elem *elem;
+
+ elem = bogoman_get_map_elem(map, x, y);
+
+ switch (elem->id) {
+ case BOGOMAN_NONE:
+ printf(" ");
+ break;
+ case BOGOMAN_PLAYER:
+ printf("@");
+ break;
+ case BOGOMAN_DIAMOND:
+ printf("$");
+ break;
+ case BOGOMAN_MOVEABLE:
+ printf("M");
+ break;
+ case BOGOMAN_EDIBLE:
+ printf("E");
+ break;
+ case BOGOMAN_WALL:
+ print_wall(elem);
+ break;
+ }
+ }
+
+ printf("n");
+ }
+
+ printf("Player at %ux%u diamonds total %un",
+ map->player_x, map->player_y, map->diamonds_total);
+}
+
+static void copy_block(struct bogoman_map *map,
+ int dst_x, int dst_y,
+ int src_x, int src_y)
+{
+ struct bogoman_map_elem *src, *dst;
+
+ src = bogoman_get_map_elem(map, src_x, src_y);
+ dst = bogoman_get_map_elem(map, dst_x, dst_y);
+
+ *dst = *src;
+
+ dst->dirty = 1;
+}
+
+static void clear_block(struct bogoman_map *map,
+ unsigned int x, unsigned int y)
+{
+ struct bogoman_map_elem *block;
+
+ block = bogoman_get_map_elem(map, x, y);
+
+ block->id = BOGOMAN_NONE;
+ block->dirty = 1;
+}
+
+/*
+ * Removes diamond when player has stepped on it.
+ */
+static void move_get_diamond(struct bogoman_map *map,
+ unsigned int x, unsigned int y)
+{
+ clear_block(map, x, y);
+
+ map->player_diamonds++;
+
+ DEBUG(1, "Diamond taken, yet to collect %un",
+ map->diamonds_total - map->player_diamonds);
+}
+
+/*
+ * Moves block to empty space, only one of dx or dy can be set
+ * to nonzero value and the value could only be 1 or -1.
+ */
+static int try_move_block(struct bogoman_map *map,
+ int x, int y, int dx, int dy)
+{
+ struct bogoman_map_elem *elem = bogoman_get_map_elem(map, x, y);
+
+ int new_x = (int)x + dx;
+ int new_y = (int)y + dy;
+
+ if (bogoman_coord_in_map(map, new_x, new_y)) {
+
+ if (!bogoman_is_empty(map, new_x, new_y))
+ return 0;
+
+ copy_block(map, new_x, new_y, x, y);
+ } else {
+ DEBUG(1, "Block moved out of screen %ux%u -> %ix%i",
+ x, y, new_x, new_y);
+ }
+
+ clear_block(map, x, y);
+ return 1;
+}
+
+void bogoman_map_player_move(struct bogoman_map *map, int x, int y)
+{
+ if (x != 0 && y != 0) {
+ WARN("Player can move only in one directionn");
+ return;
+ }
+
+ int new_x = map->player_x + x;
+ int new_y = map->player_y + y;
+
+ if (new_x < 0 || new_x >= (int)map->w ||
+ new_y < 0 || new_y >= (int)map->h) {
+ WARN("Player can move only in screen got %ix%in",
+ new_x, new_y);
+ return;
+ }
+
+ int player_x = map->player_x;
+ int player_y = map->player_y;
+
+ DEBUG(1, "Player %ix%i -> %ix%in", player_x, player_y, new_x, new_y);
+
+ while (player_x != new_x || player_y != new_y) {
+ int dx = SIGN(new_x - player_x);
+ int dy = SIGN(new_y - player_y);
+
+ int px = map->player_x + dx;
+ int py = map->player_y + dy;
+
+ switch (bogoman_get_map_elem_id(map, px, py)) {
+ case BOGOMAN_NONE:
+ break;
+ case BOGOMAN_DIAMOND:
+ move_get_diamond(map, px, py);
+ break;
+ case BOGOMAN_MOVEABLE:
+ if (!try_move_block(map, px, py, dx, dy))
+ goto finish_move;
+ break;
+ case BOGOMAN_EDIBLE:
+ clear_block(map, px, py);
+ break;
+ default:
+ goto finish_move;
+ }
+
+ player_x = px;
+ player_y = py;
+ }
+
+ /* Update the map */
+ struct bogoman_map_elem *player, *space;
+
+finish_move:
+
+ player = bogoman_get_map_elem(map, map->player_x, map->player_y);
+ space = bogoman_get_map_elem(map, player_x, player_y);
+
+ *player = map->under_player;
+ map->under_player = *space;
+ space->id = BOGOMAN_PLAYER;
+
+ map->player_x = player_x;
+ map->player_y = player_y;
+
+ /* turn on dirty flags */
+ player->dirty = 1;
+ space->dirty = 1;
+}
+
+void bogoman_map_timer_tick(struct bogoman_map *map)
+{
+ unsigned int x, y;
+
+ for (y = 0; y < map->h; y++) {
+ for (x = 0; x < map->w; x++) {
+ struct bogoman_map_elem *elem;
+
+ elem = bogoman_get_map_elem(map, x, y);
+
+ //TODO
+ }
+ }
+}
diff --git a/demos/bogoman/bogoman_map.h b/demos/bogoman/bogoman_map.h
new file mode 100644
index 0000000..b178dcf
--- /dev/null
+++ b/demos/bogoman/bogoman_map.h
@@ -0,0 +1,124 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#ifndef __BOGOMAN_MAP_H__
+#define __BOGOMAN_MAP_H__
+
+enum bogoman_map_elem_id {
+ /* empty walkable space */
+ BOGOMAN_NONE = 0x00,
+ /* player */
+ BOGOMAN_PLAYER = 0x01,
+ /* wall */
+ BOGOMAN_WALL = 0x02,
+ /* diamons to collect */
+ BOGOMAN_DIAMOND = 0x03,
+ /* like a wall but player moveable */
+ BOGOMAN_MOVEABLE = 0x04,
+ /* like a diamond but doesn't counts to points */
+ BOGOMAN_EDIBLE = 0x05,
+
+ BOGOMAN_MAX = BOGOMAN_EDIBLE,
+};
+
+/*
+ * Wall cal be applied as bitflags. Each bitflag determines wall continuation
+ * in particular direction.
+ */
+enum bogoman_wall_flags {
+ BOGOMAN_WALL_LEFT = 0x01,
+ BOGOMAN_WALL_RIGHT = 0x02,
+ BOGOMAN_WALL_UP = 0x04,
+ BOGOMAN_WALL_DOWN = 0x08,
+};
+
+struct bogoman_map_elem {
+ unsigned char id;
+ unsigned char flags;
+
+ /* the element changed, needs to be redrawn */
+ unsigned char dirty:1;
+};
+
+struct bogoman_map {
+ unsigned int w;
+ unsigned int h;
+
+ unsigned int diamonds_total;
+
+ /* player data */
+ unsigned int player_x;
+ unsigned int player_y;
+ unsigned int player_diamonds;
+ /* used to save element player steps on */
+ struct bogoman_map_elem under_player;
+
+ struct bogoman_map_elem map[];
+};
+
+static inline struct bogoman_map_elem *
+ bogoman_get_map_elem(struct bogoman_map *map,
+ unsigned int x, unsigned int y)
+{
+ return &(map->map[x + y * map->w]);
+}
+
+static inline enum bogoman_map_elem_id
+ bogoman_get_map_elem_id(struct bogoman_map *map,
+ unsigned int x, unsigned int y)
+{
+ struct bogoman_map_elem *elem = bogoman_get_map_elem(map, x, y);
+
+ return elem->id;
+}
+
+static inline int bogoman_map_is_id(struct bogoman_map *map,
+ unsigned int x, unsigned int y,
+ enum bogoman_map_elem_id id)
+{
+ struct bogoman_map_elem *elem = bogoman_get_map_elem(map, x, y);
+
+ return elem->id == id;
+}
+
+static inline int bogoman_coord_in_map(struct bogoman_map *map, int x, int y)
+{
+ return (x >= 0) && ((unsigned)x < map->w) &&
+ (y >= 0) && ((unsigned)y < map->w);
+}
+
+static inline int bogoman_is_empty(struct bogoman_map *map,
+ unsigned int x, unsigned int y)
+{
+ return bogoman_get_map_elem_id(map, x, y) == BOGOMAN_NONE;
+}
+
+void bogoman_map_player_move(struct bogoman_map *map, int x, int y);
+
+void bogoman_map_timer_tick(struct bogoman_map *map);
+
+/*
+ * Dumps map into the stdout.
+ */
+void bogoman_map_dump(struct bogoman_map *map);
+
+#endif /* __BOGOMAN_MAP_H__ */
diff --git a/demos/bogoman/bogoman_render.c b/demos/bogoman/bogoman_render.c
new file mode 100644
index 0000000..43a09bd
--- /dev/null
+++ b/demos/bogoman/bogoman_render.c
@@ -0,0 +1,198 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#include <GP.h>
+
+#include "bogoman_map.h"
+#include "bogoman_debug.h"
+
+#include "bogoman_render.h"
+
+struct render_colors {
+ /* global background */
+ GP_Pixel bg;
+
+ /* player color */
+ GP_Pixel player;
+
+ /* frames around things */
+ GP_Pixel frames;
+
+ /* diamod color */
+ GP_Pixel diamond;
+
+ /* wall color */
+ GP_Pixel wall;
+
+ /* moveable color */
+ GP_Pixel moveable;
+
+ /* edible color */
+ GP_Pixel edible;
+};
+
+static struct render_colors colors;
+
+static void init_colors(GP_Context *ctx, struct render_colors *colors)
+{
+ colors->bg = GP_RGBToContextPixel(0xee, 0xee, 0xee, ctx);
+ colors->player = GP_RGBToContextPixel(0x00, 0xee, 0x00, ctx);
+ colors->frames = GP_RGBToContextPixel(0x00, 0x00, 0x00, ctx);
+ colors->diamond = GP_RGBToContextPixel(0x00, 0x00, 0xee, ctx);
+ colors->wall = GP_RGBToContextPixel(0x66, 0x66, 0x66, ctx);
+ colors->moveable = GP_RGBToContextPixel(0xff, 0xff, 0x60, ctx);
+ colors->edible = GP_RGBToContextPixel(0xff, 0x7f, 0x50, ctx);
+}
+
+static void render_none(struct bogoman_render *render,
+ unsigned int x, unsigned int y,
+ struct bogoman_map_elem *elem)
+{
+ unsigned int w = render->map_elem_size;
+
+ (void) elem;
+
+ GP_FillRectXYWH(render->ctx, x, y, w, w, colors.bg);
+}
+
+static void render_player(struct bogoman_render *render,
+ unsigned int x, unsigned int y,
+ struct bogoman_map_elem *elem)
+{
+ unsigned int w = render->map_elem_size;
+
+ (void) elem;
+
+ GP_FillRectXYWH(render->ctx, x, y, w, w, colors.bg);
+ GP_FillCircle(render->ctx, x + w/2, y + w/2, w/2 - 1, colors.player);
+ GP_Circle(render->ctx, x + w/2, y + w/2, w/2 - 1, colors.frames);
+}
+
+static void render_wall(struct bogoman_render *render,
+ unsigned int x, unsigned int y,
+ struct bogoman_map_elem *elem)
+{
+ unsigned int w = render->map_elem_size;
+
+ GP_FillRectXYWH(render->ctx, x, y, w, w, colors.wall);
+
+ if (!(elem->flags & BOGOMAN_WALL_LEFT))
+ GP_VLineXYH(render->ctx, x, y, w, colors.frames);
+
+ if (!(elem->flags & BOGOMAN_WALL_RIGHT))
+ GP_VLineXYH(render->ctx, x + w - 1, y, w, colors.frames);
+
+ if (!(elem->flags & BOGOMAN_WALL_UP))
+ GP_HLineXYW(render->ctx, x, y, w, colors.frames);
+
+ if (!(elem->flags & BOGOMAN_WALL_DOWN))
+ GP_HLineXYW(render->ctx, x, y + w - 1, w, colors.frames);
+}
+
+static void render_diamond(struct bogoman_render *render,
+ unsigned int x, unsigned int y,
+ struct bogoman_map_elem *elem)
+{
+ unsigned int w = render->map_elem_size;
+
+ GP_FillRectXYWH(render->ctx, x, y, w, w, colors.bg);
+
+ GP_FillTetragon(render->ctx, x + w/2, y, x + w - 1, y + w/2,
+ x + w/2, y + w - 1, x, y + w/2, colors.diamond);
+
+ GP_Tetragon(render->ctx, x + w/2, y, x + w - 1, y + w/2,
+ x + w/2, y + w - 1, x, y + w/2, colors.frames);
+}
+
+static void render_moveable(struct bogoman_render *render,
+ unsigned int x, unsigned int y,
+ struct bogoman_map_elem *elem)
+{
+ unsigned int w = render->map_elem_size;
+
+ GP_FillRectXYWH(render->ctx, x, y, w, w, colors.bg);
+
+ GP_FillRectXYWH(render->ctx, x + 1, y + 1, w - 2, w - 2, colors.moveable);
+ GP_RectXYWH(render->ctx, x + 1, y + 1, w - 2, w - 2, colors.frames);
+}
+
+static void render_edible(struct bogoman_render *render,
+ unsigned int x, unsigned int y,
+ struct bogoman_map_elem *elem)
+{
+ unsigned int w = render->map_elem_size;
+
+ GP_FillRectXYWH(render->ctx, x, y, w, w, colors.bg);
+
+ GP_FillRectXYWH(render->ctx, x + 1, y + 1, w - 2, w - 2, colors.edible);
+}
+
+static void (*renders[])(struct bogoman_render *render,
+ unsigned int x, unsigned int y,
+ struct bogoman_map_elem *elem) =
+{
+ render_none,
+ render_player,
+ render_wall,
+ render_diamond,
+ render_moveable,
+ render_edible,
+};
+
+static void render_elem(struct bogoman_render *render,
+ unsigned int x, unsigned int y,
+ int flags)
+{
+ struct bogoman_map_elem *elem;
+ unsigned int cx, cy;
+
+ elem = bogoman_get_map_elem(render->map, x, y);
+
+ if (elem->dirty) {
+ elem->dirty = 0;
+ } else {
+ if (flags & BOGOMAN_RENDER_DIRTY)
+ return;
+ }
+
+ cx = (x - render->map_x_offset) * render->map_elem_size;
+ cy = (y - render->map_y_offset) * render->map_elem_size;
+
+ if (elem->id > BOGOMAN_MAX)
+ WARN("Invalid elem ID %u at %ux%un", elem->id, x, y);
+ else
+ renders[elem->id](render, cx, cy, elem);
+}
+
+void bogoman_render(struct bogoman_render *render, int flags)
+{
+ unsigned int x, y;
+
+ //TODO: Hack
+ init_colors(render->ctx, &colors);
+
+ for (y = render->map_x_offset; y < render->map->h; y++) {
+ for (x = render->map_x_offset; x < render->map->w; x++) {
+ render_elem(render, x, y, flags);
+ }
+ }
+}
diff --git a/demos/bogoman/bogoman_render.h b/demos/bogoman/bogoman_render.h
new file mode 100644
index 0000000..72c6a48
--- /dev/null
+++ b/demos/bogoman/bogoman_render.h
@@ -0,0 +1,52 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#ifndef __BOGOMAN_RENDER_H__
+#define __BOGOMAN_RENDER_H__
+
+struct bogoman_map;
+struct GP_Context;
+
+struct bogoman_render {
+ /* both in map elements */
+ unsigned int map_x_offset;
+ unsigned int map_y_offset;
+
+ /* current map */
+ struct bogoman_map *map;
+
+ /* context to be used for rendering */
+ struct GP_Context *ctx;
+
+ /* elem size in pixels */
+ unsigned int map_elem_size;
+};
+
+enum bogonam_render_flags {
+ /* renders all map elements, not only dirty ones */
+ BOGOMAN_RENDER_ALL = 0x00,
+ BOGOMAN_RENDER_DIRTY = 0x01,
+};
+
+void bogoman_render(struct bogoman_render *render, int flags);
+
+#endif /* __BOGOMAN_RENDER_H__ */
diff --git a/demos/bogoman/levels/01-warmup.txt b/demos/bogoman/levels/01-warmup.txt
new file mode 100644
index 0000000..f0cc034
--- /dev/null
+++ b/demos/bogoman/levels/01-warmup.txt
@@ -0,0 +1,7 @@
+/-------+| M$$$M |
+|M$M$M$M|
+|$M$@$M$|
+|M$M$M$M|
+| M$$$M |
+-------/
diff --git a/demos/bogoman/map.txt b/demos/bogoman/map.txt
new file mode 100644
index 0000000..337d07c
--- /dev/null
+++ b/demos/bogoman/map.txt
@@ -0,0 +1,8 @@
++---------+ +----+
+| | | | | $ |
+| +----+ |
+| E @ |
++--M----------------+
+| M |
+| |$|$|$| |
++----------+-+-+-+--+
diff --git a/demos/bogoman/runtest.sh b/demos/bogoman/runtest.sh
new file mode 100755
index 0000000..0794707
--- /dev/null
+++ b/demos/bogoman/runtest.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+#
+# Run dynamically linked test.
+#
+
+PROG="$1"
+shift
+
+LD_LIBRARY_PATH=../../build/ ./$PROG "$@"
-----------------------------------------------------------------------
Summary of changes:
demos/Makefile | 2 +-
demos/{spiv => bogoman}/Makefile | 6 +-
demos/bogoman/bogoman.c | 149 ++++++++++++
.../GP_Filter.h => demos/bogoman/bogoman_common.h | 26 +-
.../bogoman/bogoman_debug.c | 44 ++--
.../bogoman/bogoman_debug.h | 32 +--
demos/bogoman/bogoman_loader.c | 220 ++++++++++++++++++
.../histogram.h => bogoman/bogoman_loader.h} | 12 +-
demos/bogoman/bogoman_map.c | 245 ++++++++++++++++++++
demos/bogoman/bogoman_map.h | 124 ++++++++++
demos/bogoman/bogoman_render.c | 198 ++++++++++++++++
.../bogoman/bogoman_render.h | 53 +++--
demos/bogoman/levels/01-warmup.txt | 7 +
demos/bogoman/map.txt | 8 +
demos/{c_simple => bogoman}/runtest.sh | 0
15 files changed, 1036 insertions(+), 90 deletions(-)
copy demos/{spiv => bogoman}/Makefile (52%)
create mode 100644 demos/bogoman/bogoman.c
copy include/filters/GP_Filter.h => demos/bogoman/bogoman_common.h (80%)
copy libs/filters/GP_Cubic.gen.c.t => demos/bogoman/bogoman_debug.c (74%)
copy libs/filters/GP_Cubic.gen.c.t => demos/bogoman/bogoman_debug.h (74%)
create mode 100644 demos/bogoman/bogoman_loader.c
copy demos/{grinder/histogram.h => bogoman/bogoman_loader.h} (87%)
create mode 100644 demos/bogoman/bogoman_map.c
create mode 100644 demos/bogoman/bogoman_map.h
create mode 100644 demos/bogoman/bogoman_render.c
copy libs/filters/GP_Cubic.gen.c.t => demos/bogoman/bogoman_render.h (73%)
create mode 100644 demos/bogoman/levels/01-warmup.txt
create mode 100644 demos/bogoman/map.txt
copy demos/{c_simple => bogoman}/runtest.sh (100%)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 1a93c45d484a05a1e5e8ca1cf1a0046e10d3398d
by gavento 28 Jan '13
by gavento 28 Jan '13
28 Jan '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 1a93c45d484a05a1e5e8ca1cf1a0046e10d3398d (commit)
via da7cdf406b3451c27801c4ba68ac29aa1891a209 (commit)
via 312c163a2316d0fa6c514fc0950d4bb788dee1b0 (commit)
via 8ef914015870e89225900ea789da4f5741c444b4 (commit)
via 90e74e126ba3bba072eea0456d5c3823a4617821 (commit)
via a6c7bce8c64deb55ce270f8e40435de0ef08ca3f (commit)
via 1606dfcb1db856a2e8f23bcb137c9a5b99310d06 (commit)
via 0072fbd406ab3fca61423ffe37672ac9091912f3 (commit)
from b1fbf0820773aebe6c2c0d79d5ea71417e3ec754 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/1a93c45d484a05a1e5e8ca1cf1a0046e10d3…
commit 1a93c45d484a05a1e5e8ca1cf1a0046e10d3398d
Merge: da7cdf4 b1fbf08
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Mon Jan 28 09:05:18 2013 +0100
Merge branch 'master' of ssh://repo.or.cz/srv/git/gfxprim
http://repo.or.cz/w/gfxprim.git/commit/da7cdf406b3451c27801c4ba68ac29aa1891…
commit da7cdf406b3451c27801c4ba68ac29aa1891a209
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Sun Jan 27 16:58:06 2013 +0100
pylib: tests: Clean up gfx tests
diff --git a/tests/pylib/test_gfx.py b/tests/pylib/test_gfx.py
index 87289f9..e502e22 100644
--- a/tests/pylib/test_gfx.py
+++ b/tests/pylib/test_gfx.py
@@ -22,31 +22,31 @@ def test_gfx_submodule_has_C():
# These set the param types of the functions in GFX
gfx_params = {
- 'ArcSegment': 'CCCCCFFP',
- 'Circle': 'CCCP',
- 'Ellipse': 'CCCCP',
+ 'ArcSegment': 'IIIIIFFP',
+ 'Circle': 'IIIP',
+ 'Ellipse': 'IIIIP',
'Fill': 'P',
- 'FillCircle': 'CCCP',
- 'FillEllipse': 'CCCCP',
+ 'FillCircle': 'IIIP',
+ 'FillEllipse': 'IIIIP',
'FillPolygon': None,
- 'FillRect': 'CCCCP',
+ 'FillRect': 'IIIIP',
'FillRect_AA': 'FFFFP',
- 'FillRing': 'CCCCP',
- 'FillSymbol': '0CCCCP',
- 'FillTetragon': 'CCCCCCCCP',
- 'FillTriangle': 'CCCCCCP',
- 'HLine': 'CCCP',
+ 'FillRing': 'IIIIP',
+ 'FillSymbol': '0IIIIP',
+ 'FillTetragon': 'IIIIIIIIP',
+ 'FillTriangle': 'IIIIIIP',
+ 'HLine': 'IIIP',
'HLineAA': 'FFFP',
- 'Line': 'CCCCP',
+ 'Line': 'IIIIP',
'LineAA': 'FFFFP',
'Polygon': None,
'PutPixelAA': 'FFP',
- 'Rect': 'CCCCP',
- 'Ring': 'CCCCP',
- 'Symbol': '0CCCCP',
- 'Tetragon': 'CCCCCCCCP',
- 'Triangle': 'CCCCCCP',
- 'VLine': 'CCCP',
+ 'Rect': 'IIIIP',
+ 'Ring': 'IIIIP',
+ 'Symbol': '0IIIIP',
+ 'Tetragon': 'IIIIIIIIP',
+ 'Triangle': 'IIIIIIP',
+ 'VLine': 'IIIP',
'VLineAA': 'FFFP',
}
@@ -58,23 +58,35 @@ def test_all_methods_are_known():
if name[0] != '_' and name not in ['C', 'ctx']:
assert name in gfx_params
+def gen_dummy_args(params):
+ """
+ Generate dummy parameter tuple according to characters in the given string.
-@for_each_case(gfx_params, _filter=(lambda(n, params): params is not None))
-def test_method_callable(n, params):
- "Call with dummy parameters"
- c = Context(10, 10, 1)
+ 0 - 0
+ S - String ("")
+ I - Int (1)
+ F - Float (0.5)
+ P - Pixel (0)
+ """
args = []
for t in params:
if t == '0':
args.append(0)
- elif t == 'C':
+ elif t == 'I':
args.append(1)
elif t == 'P':
args.append(0)
elif t == 'F':
args.append(0.5)
+ elif t == 'S':
+ args.append("")
else:
assert False
- print args
- c.gfx.__getattribute__(n)(*tuple(args))
+ return tuple(args)
+
+@for_each_case(gfx_params, _filter=(lambda(n, params): params is not None))
+def test_method_callable(n, params):
+ "Call with dummy parameters"
+ c = Context(10, 10, 1)
+ c.gfx.__getattribute__(n)(*gen_dummy_args(params))
http://repo.or.cz/w/gfxprim.git/commit/312c163a2316d0fa6c514fc0950d4bb788de…
commit 312c163a2316d0fa6c514fc0950d4bb788dee1b0
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Sun Jan 27 15:23:23 2013 +0100
pylib: tests: Unit tests for gfx submodule
diff --git a/tests/pylib/test_gfx.py b/tests/pylib/test_gfx.py
new file mode 100644
index 0000000..87289f9
--- /dev/null
+++ b/tests/pylib/test_gfx.py
@@ -0,0 +1,80 @@
+"core.Context tests"
+
+from unittest import SkipTest
+from testutils import *
+
+from gfxprim.core import Context
+from gfxprim import gfx
+
+
+def test_gfx_submodule_loads():
+ "gfx is present in a Context"
+ c = Context(1, 1, 1)
+ assert c.gfx
+
+
+def test_gfx_submodule_has_C():
+ "gfx contains C"
+ c = Context(1, 1, 1)
+ assert c.gfx.C
+ assert gfx.C
+
+
+# These set the param types of the functions in GFX
+gfx_params = {
+ 'ArcSegment': 'CCCCCFFP',
+ 'Circle': 'CCCP',
+ 'Ellipse': 'CCCCP',
+ 'Fill': 'P',
+ 'FillCircle': 'CCCP',
+ 'FillEllipse': 'CCCCP',
+ 'FillPolygon': None,
+ 'FillRect': 'CCCCP',
+ 'FillRect_AA': 'FFFFP',
+ 'FillRing': 'CCCCP',
+ 'FillSymbol': '0CCCCP',
+ 'FillTetragon': 'CCCCCCCCP',
+ 'FillTriangle': 'CCCCCCP',
+ 'HLine': 'CCCP',
+ 'HLineAA': 'FFFP',
+ 'Line': 'CCCCP',
+ 'LineAA': 'FFFFP',
+ 'Polygon': None,
+ 'PutPixelAA': 'FFP',
+ 'Rect': 'CCCCP',
+ 'Ring': 'CCCCP',
+ 'Symbol': '0CCCCP',
+ 'Tetragon': 'CCCCCCCCP',
+ 'Triangle': 'CCCCCCP',
+ 'VLine': 'CCCP',
+ 'VLineAA': 'FFFP',
+ }
+
+
+def test_all_methods_are_known():
+ "All methods of gfx submodule have known param types in this test"
+ c = Context(1, 1, 1)
+ for name in dir(c.gfx):
+ if name[0] != '_' and name not in ['C', 'ctx']:
+ assert name in gfx_params
+
+
+@for_each_case(gfx_params, _filter=(lambda(n, params): params is not None))
+def test_method_callable(n, params):
+ "Call with dummy parameters"
+ c = Context(10, 10, 1)
+ args = []
+ for t in params:
+ if t == '0':
+ args.append(0)
+ elif t == 'C':
+ args.append(1)
+ elif t == 'P':
+ args.append(0)
+ elif t == 'F':
+ args.append(0.5)
+ else:
+ assert False
+ print args
+ c.gfx.__getattribute__(n)(*tuple(args))
+
http://repo.or.cz/w/gfxprim.git/commit/8ef914015870e89225900ea789da4f5741c4…
commit 8ef914015870e89225900ea789da4f5741c444b4
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Sun Jan 27 15:13:24 2013 +0100
pylib: test: Remove old @alltypes implementations
diff --git a/tests/pylib/testutils.py b/tests/pylib/testutils.py
index e0ded8d..6c7ee5f 100644
--- a/tests/pylib/testutils.py
+++ b/tests/pylib/testutils.py
@@ -8,35 +8,6 @@ __all__ = ["alltypes", "for_each_case",
"RandomizeContext", "ContextRand"]
-def alltypes_generator(_filter=None):
- def decorate(f):
- def gen():
- for t in core.PixelTypes[1:]:
- if (_filter is None) or _filter(t):
- yield f, t
- gen.__name__ = f.__name__
- return gen
- return decorate
-
-
-def alltypes_new_functions(_filter=None):
- def decorate(f):
- for t in core.PixelTypes[1:]:
- if (_filter is None) or _filter(t):
- nf = (lambda tt: (lambda: f(tt)))(t)
- nf.__name__ = f.__name__ + "_" + t.name
- nf.__module__ = f.__module__
- nf.__doc__ = "%s<%s:%s>"% (
- f.__doc__ + " " if f.__doc__ else "",
- nf.__module__, nf.__name__)
- f.__globals__[nf.__name__] = nf
- return None
- return decorate
-
-# Switch to alltypes_new_functions by default
-#alltypes = alltypes_new_functions
-
-
def alltypes(_filter=None):
"""
Creates one test for each PixelType (except INVALID).
@@ -87,6 +58,7 @@ def ContextRand(w, h, t, seed=None):
RandomizeContext(c, seed)
return c
+
def RandomizeContext(c, seed=None):
"""Fill Context with pseudorandom data.
http://repo.or.cz/w/gfxprim.git/commit/90e74e126ba3bba072eea0456d5c3823a461…
commit 90e74e126ba3bba072eea0456d5c3823a4617821
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Sun Jan 27 15:12:02 2013 +0100
pylib: test: Add universal test generator, use for @alltypes
diff --git a/tests/pylib/testutils.py b/tests/pylib/testutils.py
index 8c0b6fe..e0ded8d 100644
--- a/tests/pylib/testutils.py
+++ b/tests/pylib/testutils.py
@@ -4,7 +4,8 @@ from random import Random
from gfxprim import core
-__all__ = ["alltypes", "RandomizeContext", "ContextRand"]
+__all__ = ["alltypes", "for_each_case",
+ "RandomizeContext", "ContextRand"]
def alltypes_generator(_filter=None):
@@ -32,9 +33,51 @@ def alltypes_new_functions(_filter=None):
return None
return decorate
-
# Switch to alltypes_new_functions by default
-alltypes = alltypes_new_functions
+#alltypes = alltypes_new_functions
+
+
+def alltypes(_filter=None):
+ """
+ Creates one test for each PixelType (except INVALID).
+ The pixeltype is given to the test function and the name
+ is appended to its name and docstring.
+ """
+ flt = lambda n, t: _filter(t)
+ return for_each_case(dict([(t.name, t) for t in core.PixelTypes[1:]]),
+ givename=False, _filter=(flt if _filter else None))
+
+
+def for_each_case(cases, givename=True, _filter=None):
+ """
+ Creates one test for each of `cases`.
+
+ Cases is either list of strings or or string dict (with any values).
+ The test is then given (name) for list or (name, value) for dict,
+ or just (value) if givename=False.
+
+ Optional _filter is called with (name) or (name, value) for dict to
+ determine which values to use (ret. True -> include).
+ """
+ def decorate(f):
+ for n in cases:
+ assert isinstance(n, str)
+ if isinstance(cases, dict):
+ if givename:
+ nf = (lambda nn, nv: (lambda: f(nn, nv)))(n, cases[n])
+ else:
+ nf = (lambda nv: (lambda: f(nv)))(cases[n])
+ else: # assume a list or a tuple
+ nf = (lambda nn: (lambda: f(nn)))(n)
+ nf.__name__ = f.__name__ + "_" + n
+ nf.__module__ = f.__module__
+ nf.__doc__ = "%s<%s:%s>"% (
+ f.__doc__ + " " if f.__doc__ else "",
+ nf.__module__, nf.__name__)
+ f.__globals__[nf.__name__] = nf
+ return None
+ return decorate
+
### core.Context helpers
http://repo.or.cz/w/gfxprim.git/commit/a6c7bce8c64deb55ce270f8e40435de0ef08…
commit a6c7bce8c64deb55ce270f8e40435de0ef08ca3f
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Sun Jan 27 13:32:49 2013 +0100
pywrap: gfx: Submodule bindings for gfxprim.gfx
diff --git a/pylib/gfxprim/gfx/__init__.py b/pylib/gfxprim/gfx/__init__.py
index c80ae6a..62ce4f0 100644
--- a/pylib/gfxprim/gfx/__init__.py
+++ b/pylib/gfxprim/gfx/__init__.py
@@ -1,27 +1,53 @@
-from . import gfx_c
+"""
+Module extending the Context class with .gfx submodule and its drawing functions.
+
+Use as in "import gfxprim.gfx; context_foo.gfx.Line(...)"
+"""
+
+# Import the SWIG wrapper
+
+from . import c_gfx
+
+
+# Constants module
from . import C
+
def _init(module):
+ "Extend Context with gfx submodule"
+ from ..utils import extend, add_swig_getmethod, add_swig_setmethod
+ from ..core import Context as _context
+
+ # New Context submodule
+
+ class GfxSubmodule(object):
+ def __init__(self, ctx):
+ self.ctx = ctx
+ self.C = C
+
+ _context._submodules['gfx'] = GfxSubmodule
# Imports from the SWIG module
+ from ..utils import import_members, extend_submodule
import re
def strip_GP(s):
return re.sub('^GP_', '', s)
- # Import constants from the SWIG module
- from ..utils import import_members
- const_regexes = ['^GP_[A-Z0-9_]*$']
- import_members(gfx_c, C, include=const_regexes, sub=strip_GP)
-
- # Import functions from the SWIG module
- import_members(gfx_c, module, sub=strip_GP,
- exclude=const_regexes + [
- '.*_Raw',
- '^w+_swigregister$',
- '^gfxprim$',
- '^_w+$'])
+ const_regexes = [
+ '^GP_[A-Z0-9_]*$',
+ ]
+ import_members(c_gfx, C, include=const_regexes, sub=strip_GP)
+
+ for name in [
+ 'ArcSegment', 'Circle', 'Ellipse', 'Fill', 'FillCircle', 'FillEllipse',
+ 'FillPolygon', 'FillRect', 'FillRect_AA', 'FillRing', 'FillSymbol',
+ 'FillTetragon', 'FillTriangle', 'HLine', 'HLineAA', 'Line', 'LineAA',
+ 'Polygon', 'PutPixelAA', 'Rect', 'Ring', 'Symbol', 'Tetragon',
+ 'Triangle', 'VLine', 'VLineAA']:
+ extend_submodule(GfxSubmodule, name, c_gfx.__getattribute__('GP_' + name))
+
_init(locals())
del _init
diff --git a/pylib/gfxprim/gfx/gfx.i b/pylib/gfxprim/gfx/gfx.i
index eb684da..881d2ca 100644
--- a/pylib/gfxprim/gfx/gfx.i
+++ b/pylib/gfxprim/gfx/gfx.i
@@ -1,5 +1,5 @@
%include "../common.i"
-%module(package="gfxprim.gfx") gfx_c
+%module(package="gfxprim.gfx") c_gfx
%{
#include "gfx/GP_Gfx.h"
http://repo.or.cz/w/gfxprim.git/commit/1606dfcb1db856a2e8f23bcb137c9a5b9931…
commit 1606dfcb1db856a2e8f23bcb137c9a5b99310d06
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Sun Jan 27 13:31:38 2013 +0100
pywrap: Add submodule extending method, improve existing
diff --git a/pylib/gfxprim/utils.py b/pylib/gfxprim/utils.py
index 5dc6dab..4040a25 100644
--- a/pylib/gfxprim/utils.py
+++ b/pylib/gfxprim/utils.py
@@ -13,17 +13,34 @@ def extend(cls, name=None):
return decf
-def extend_direct(cls, name, call, doc, swig_doc=True):
- "Decorator extending a class with a function"
+def extend_direct(cls, name, call, doc=None, swig_doc=True):
+ "Extend a class with a function. The first arg will be `self`."
def method(*args, **kwargs):
return call(*args, **kwargs)
method.__name__ = name
- method.__doc__ = doc.strip() + 'n'
+ if doc:
+ method.__doc__ = doc.strip() + 'n'
+ else:
+ method.__doc__ = ""
if swig_doc:
- method.__doc__ = call.__doc__ + 'nn' + doc.strip() + 'n'
+ method.__doc__ = call.__doc__ + 'nn' + method.__doc__
type.__setattr__(cls, name, method)
+def extend_submodule(module, name, call, doc=None, swig_doc=True):
+ "Extending a submodule with a function. The first arg will be `self.ctx`."
+ def method(self, *args, **kwargs):
+ return call(self.ctx, *args, **kwargs)
+ method.__name__ = name
+ if doc:
+ method.__doc__ = doc.strip() + 'n'
+ else:
+ method.__doc__ = ""
+ if swig_doc:
+ method.__doc__ = call.__doc__ + 'nn' + method.__doc__
+ type.__setattr__(module, name, method)
+
+
def add_swig_getmethod(cls, name=None):
"Decorator to add a property get method to a SWIG-defined class"
def decf(method):
http://repo.or.cz/w/gfxprim.git/commit/0072fbd406ab3fca61423ffe37672ac90919…
commit 0072fbd406ab3fca61423ffe37672ac9091912f3
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Sun Jan 27 13:31:07 2013 +0100
pywrap: Fix a typo
diff --git a/pylib/gfxprim/core/__init__.py b/pylib/gfxprim/core/__init__.py
index f9db954..9ad8eea 100644
--- a/pylib/gfxprim/core/__init__.py
+++ b/pylib/gfxprim/core/__init__.py
@@ -29,7 +29,7 @@ def _init(module):
_ptdescr = c_core.GP_PixelTypeDescription
- # String representation of
+ # String representation of a Context
@extend(_ptdescr, name='__str__')
@extend(_ptdescr, name='__repr__')
-----------------------------------------------------------------------
Summary of changes:
pylib/gfxprim/core/__init__.py | 2 +-
pylib/gfxprim/gfx/__init__.py | 52 +++++++++++++++++------
pylib/gfxprim/gfx/gfx.i | 2 +-
pylib/gfxprim/utils.py | 25 +++++++++--
tests/pylib/test_gfx.py | 92 ++++++++++++++++++++++++++++++++++++++++
tests/pylib/testutils.py | 61 ++++++++++++++++----------
6 files changed, 192 insertions(+), 42 deletions(-)
create mode 100644 tests/pylib/test_gfx.py
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: b1fbf0820773aebe6c2c0d79d5ea71417e3ec754
by metan 27 Jan '13
by metan 27 Jan '13
27 Jan '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via b1fbf0820773aebe6c2c0d79d5ea71417e3ec754 (commit)
from 6b41a423d6fe40825bbd57f9900df5c767d30e11 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/b1fbf0820773aebe6c2c0d79d5ea71417e3e…
commit b1fbf0820773aebe6c2c0d79d5ea71417e3ec754
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Jan 27 15:10:29 2013 +0100
backends: SDL: Add resize event notification.
diff --git a/libs/backends/GP_SDL.c b/libs/backends/GP_SDL.c
index d3afcca..951511f 100644
--- a/libs/backends/GP_SDL.c
+++ b/libs/backends/GP_SDL.c
@@ -19,7 +19,7 @@
* Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
* <jiri.bluebear.dluhos(a)gmail.com> *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -30,6 +30,7 @@
#ifdef HAVE_LIBSDL
#include "input/GP_InputDriverSDL.h"
+#include "input/GP_Input.h"
#include "GP_Backend.h"
#include "GP_SDL.h"
@@ -149,6 +150,9 @@ static int sdl_set_attributes(struct GP_Backend *self __attribute__((unused)),
if (w != 0 && h != 0) {
sdl_surface = SDL_SetVideoMode(w, h, 0, sdl_flags);
context_from_surface(&context, sdl_surface);
+
+ /* Send event that resize was finished */
+ GP_EventPushResize(w, h, NULL);
}
SDL_mutexV(mutex);
-----------------------------------------------------------------------
Summary of changes:
libs/backends/GP_SDL.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 6b41a423d6fe40825bbd57f9900df5c767d30e11
by metan 27 Jan '13
by metan 27 Jan '13
27 Jan '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 6b41a423d6fe40825bbd57f9900df5c767d30e11 (commit)
from 28f97c18a478cfe9e9144c3b9c151c1f784887d1 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/6b41a423d6fe40825bbd57f9900df5c767d3…
commit 6b41a423d6fe40825bbd57f9900df5c767d30e11
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Jan 27 14:02:29 2013 +0100
filters: Add missing GPL headers.
diff --git a/libs/filters/GP_Cubic.gen.c.t b/libs/filters/GP_Cubic.gen.c.t
index 4d66517..e5f5cf4 100644
--- a/libs/filters/GP_Cubic.gen.c.t
+++ b/libs/filters/GP_Cubic.gen.c.t
@@ -1,3 +1,25 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
%% extends "base.c.t"
{% block descr %}Table for fixed point cubic coeficients for A=0.5{% endblock %}
diff --git a/libs/filters/GP_FloydSteinberg.gen.c.t b/libs/filters/GP_FloydSteinberg.gen.c.t
index df22cfb..e10a326 100644
--- a/libs/filters/GP_FloydSteinberg.gen.c.t
+++ b/libs/filters/GP_FloydSteinberg.gen.c.t
@@ -1,3 +1,25 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
%% extends "common.c.t"
{% block descr %}Floyd Steinberg dithering RGB888 -> any pixel{% endblock %}
diff --git a/libs/filters/GP_GaussianNoise.gen.c.t b/libs/filters/GP_GaussianNoise.gen.c.t
index 1d8c8a6..bc37bdf 100644
--- a/libs/filters/GP_GaussianNoise.gen.c.t
+++ b/libs/filters/GP_GaussianNoise.gen.c.t
@@ -1,3 +1,25 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
%% extends "filter.c.t"
{% block descr %}Gaussian Noise{% endblock %}
diff --git a/libs/filters/GP_HilbertPeano.gen.c.t b/libs/filters/GP_HilbertPeano.gen.c.t
index 2157580..f718105 100644
--- a/libs/filters/GP_HilbertPeano.gen.c.t
+++ b/libs/filters/GP_HilbertPeano.gen.c.t
@@ -1,3 +1,26 @@
+
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
%% extends "base.c.t"
{% block descr %}Hilbert Peano dithering RGB888 -> any pixel{% endblock %}
diff --git a/libs/filters/GP_Histogram.gen.c.t b/libs/filters/GP_Histogram.gen.c.t
index cd519d6..a71a644 100644
--- a/libs/filters/GP_Histogram.gen.c.t
+++ b/libs/filters/GP_Histogram.gen.c.t
@@ -1,8 +1,28 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
%% extends "filter.stats.c.t"
-%% block descr
-Histogram filter -- Compute image histogram.
-%% endblock
+{% block descr %}Histogram filter -- Compute image histogram{% endblock %}
%% block body
diff --git a/libs/filters/GP_MirrorV.gen.c.t b/libs/filters/GP_MirrorV.gen.c.t
index 03f4bb6..b2d4b86 100644
--- a/libs/filters/GP_MirrorV.gen.c.t
+++ b/libs/filters/GP_MirrorV.gen.c.t
@@ -1,8 +1,28 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
%% extends "base.c.t"
-%% block descr
-Vertical Mirror alogorithm
-%% endblock
+{% block descr %}Vertical Mirror alogorithm{% endblock %}
%% block body
@@ -51,4 +71,5 @@ int GP_FilterMirrorV_Raw(const GP_Context *src, GP_Context *dst,
GP_FN_RET_PER_BPP_CONTEXT(GP_MirrorV_Raw, src, src, dst, callback);
return 1;
}
+
%% endblock body
diff --git a/libs/filters/GP_ResizeCubic.gen.c.t b/libs/filters/GP_ResizeCubic.gen.c.t
index d8400d5..a515a2d 100644
--- a/libs/filters/GP_ResizeCubic.gen.c.t
+++ b/libs/filters/GP_ResizeCubic.gen.c.t
@@ -1,3 +1,25 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
%% extends "filter.c.t"
{% block descr %}Cubic resampling{% endblock %}
diff --git a/libs/filters/GP_ResizeNN.gen.c.t b/libs/filters/GP_ResizeNN.gen.c.t
index cf364a0..65d12bb 100644
--- a/libs/filters/GP_ResizeNN.gen.c.t
+++ b/libs/filters/GP_ResizeNN.gen.c.t
@@ -1,3 +1,25 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
%% extends "filter.c.t"
{% block descr %}Nearest Neighbour resampling{% endblock %}
diff --git a/libs/filters/GP_Rotate.gen.c.t b/libs/filters/GP_Rotate.gen.c.t
index ee6e6a4..709a60d 100644
--- a/libs/filters/GP_Rotate.gen.c.t
+++ b/libs/filters/GP_Rotate.gen.c.t
@@ -1,8 +1,28 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
%% extends "base.c.t"
-%% block descr
-Vertical Mirror alogorithm
-%% endblock
+{% block descr %}Vertical Mirror alogorithm{% endblock %}
%% block body
-----------------------------------------------------------------------
Summary of changes:
libs/filters/GP_Cubic.gen.c.t | 22 ++++++++++++++++++++++
libs/filters/GP_FloydSteinberg.gen.c.t | 22 ++++++++++++++++++++++
libs/filters/GP_GaussianNoise.gen.c.t | 22 ++++++++++++++++++++++
libs/filters/GP_HilbertPeano.gen.c.t | 23 +++++++++++++++++++++++
libs/filters/GP_Histogram.gen.c.t | 26 +++++++++++++++++++++++---
libs/filters/GP_MirrorV.gen.c.t | 27 ++++++++++++++++++++++++---
libs/filters/GP_ResizeCubic.gen.c.t | 22 ++++++++++++++++++++++
libs/filters/GP_ResizeNN.gen.c.t | 22 ++++++++++++++++++++++
libs/filters/GP_Rotate.gen.c.t | 26 +++++++++++++++++++++++---
9 files changed, 203 insertions(+), 9 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 28f97c18a478cfe9e9144c3b9c151c1f784887d1
by metan 26 Jan '13
by metan 26 Jan '13
26 Jan '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 28f97c18a478cfe9e9144c3b9c151c1f784887d1 (commit)
via 52a9dbdc6a7f20fabdcbe29d4ed576624e11351d (commit)
from ccc06e628a27ed616222e32e32f0378644e0aae0 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/28f97c18a478cfe9e9144c3b9c151c1f7848…
commit 28f97c18a478cfe9e9144c3b9c151c1f784887d1
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jan 26 16:52:03 2013 +0100
tests: framework: New python runtests script.
Now the json result files are collected correctly.
diff --git a/tests/core/runtest.sh b/tests/core/runtest.sh
deleted file mode 100755
index 7e20739..0000000
--- a/tests/core/runtest.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-
-#
-# By default the glibc __libc_message() writes to /dev/tty before calling
-# the abort(). Exporting this macro makes it to use stderr instead.
-#
-# The main usage of the function are malloc assertions, so this makes us catch
-# the malloc error message by catching stderr output.
-#
-export LIBC_FATAL_STDERR_=1
-
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./WritePixel_testsuite.gen "$@"
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./Context "$@"
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./GetPutPixel.gen "$@"
diff --git a/tests/core/test_list.txt b/tests/core/test_list.txt
new file mode 100644
index 0000000..458f6e4
--- /dev/null
+++ b/tests/core/test_list.txt
@@ -0,0 +1,4 @@
+# Core testsuite
+WritePixel_testsuite.gen
+Context
+GetPutPixel.gen
diff --git a/tests/gfx/runtest.sh b/tests/gfx/runtest.sh
deleted file mode 100755
index 2dc6ddf..0000000
--- a/tests/gfx/runtest.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/sh
-
-#
-# By default the glibc __libc_message() writes to /dev/tty before calling
-# the abort(). Exporting this macro makes it to use stderr instead.
-#
-# The main usage of the function are malloc assertions, so this makes us catch
-# the malloc error message by catching stderr output.
-#
-export LIBC_FATAL_STDERR_=1
-
-#LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./gfx_benchmark "$@"
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./HLine "$@"
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./VLine "$@"
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./Line "$@"
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./Circle "$@"
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./FillCircle "$@"
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./Ellipse "$@"
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./CircleSeg "$@"
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./Polygon "$@"
-
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./PutPixelAA "$@"
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./HLineAA "$@"
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./LineAA "$@"
diff --git a/tests/gfx/test_list.txt b/tests/gfx/test_list.txt
new file mode 100644
index 0000000..0368b0f
--- /dev/null
+++ b/tests/gfx/test_list.txt
@@ -0,0 +1,14 @@
+# GFX test list
+
+HLine
+VLine
+Line
+Circle
+FillCircle
+Ellipse
+CircleSeg
+Polygon
+
+PutPixelAA
+HLineAA
+LineAA
diff --git a/tests/loaders/runtest.sh b/tests/loaders/runtest.sh
deleted file mode 100755
index e92c0c4..0000000
--- a/tests/loaders/runtest.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-
-#
-# By default the glibc __libc_message() writes to /dev/tty before calling
-# the abort(). Exporting this macro makes it to use stderr instead.
-#
-# The main usage of the function are malloc assertions, so this makes us catch
-# the malloc error message by catching stderr output.
-#
-export LIBC_FATAL_STDERR_=1
-
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./loaders_suite "$@"
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./PNG "$@"
diff --git a/tests/loaders/test_list.txt b/tests/loaders/test_list.txt
new file mode 100644
index 0000000..f4a8fe1
--- /dev/null
+++ b/tests/loaders/test_list.txt
@@ -0,0 +1,3 @@
+# Loaders testsuite
+loaders_suite
+PNG
diff --git a/tests/runtests.py b/tests/runtests.py
new file mode 100755
index 0000000..9f3704e
--- /dev/null
+++ b/tests/runtests.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+#
+# This is a simple glue script to run the tests and collect the results
+#
+
+#
+# We expect simple structure i.e. the tests_dir contains directories with
+# tests, each directory that contains tests has test_list.txt with a list of
+# tests to run. The structure is then mirrored in the results_dir filled with
+# json logs.
+#
+
+import os
+import datetime
+
+#
+# Relative path to root directory containing tests
+#
+tests_dir='.'
+
+#
+# Results directory prefix
+#
+results_dir='results'
+
+#
+# Relative path to the directory with GP libraries to run tests against
+#
+build_dir='../../build'
+
+#
+# By default the glibc __libc_message() writes to /dev/tty before calling
+# the abort(). Exporting this macro makes it to use stderr instead.
+#
+# The main usage of the function are malloc assertions, so this makes us catch
+# the malloc error message by catching stderr output.
+#
+runline_prep='export LIBC_FATAL_STDERR_=1;'
+
+#
+# Relative path, from the current directory, to the framework preload library.
+#
+framework_lib='framework/libtst_preload.so'
+
+debug = 0
+
+def globpath(path):
+ return os.getcwd() + '/' + path
+
+#
+# Reads test_list.txt test file and executes tests one after another
+#
+def run_test(resdir, tstdir, runtest):
+ f = open(runtest, 'r')
+ lines = f.readlines()
+ f.close()
+
+ for line in lines:
+ # ignore comments
+ if (line[0] == '#'):
+ continue
+ # and blanks
+ if (line.isspace()):
+ continue
+
+ line = line.strip();
+
+ #
+ # This is a little hairy but what it does is to constructs correct
+ # paths to preload and dynamic libraries and runs the test.
+ #
+ runline = runline_prep + ' '
+ runline += 'export LD_PRELOAD="' + globpath(framework_lib) + '"; '
+ runline += 'export LD_LIBRARY_PATH="' + globpath(build_dir) + '"; '
+ runline += 'cd ' + tstdir + ' && ./' + line + ' -o "' + globpath(resdir) + '"'
+
+ if debug >= 2:
+ print(" LINE: %s" % runline)
+
+ os.system(runline)
+
+#
+# Discovers tests in directories.
+#
+def run_tests(resdir, testsdir):
+
+ if debug >= 1:
+ print('Looking for tests in "%s"' % testsdir)
+
+ for root, dirs, _ in os.walk(testsdir):
+ for name in dirs:
+
+ path = root + '/' + name
+
+ if debug >= 2:
+ print('Looking into dir "%s"' % path)
+
+ runtest = path + '/test_list.txt'
+
+ if (os.access(runtest, os.R_OK)):
+ # Create result directory
+ curresdir = resdir + '/' + name
+ os.mkdir(curresdir)
+ # Run tests
+ run_test(curresdir, path, runtest)
+
+def main():
+ now = datetime.datetime.now()
+ resdir = '%s_%i-%02i-%02i_%02i-%02i-%02i' % (results_dir, now.year, now.month,
+ now.day, now.hour, now.minute, now.second)
+ print('Creating result directory "%s"' % resdir)
+ os.mkdir(resdir)
+
+ run_tests(resdir, tests_dir)
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/runtests.sh b/tests/runtests.sh
deleted file mode 100755
index f15668b..0000000
--- a/tests/runtests.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-
-DIRS="core loaders gfx"
-
-for i in $DIRS; do
- cd $i
- ./runtest.sh $@
- cd ..
-done
http://repo.or.cz/w/gfxprim.git/commit/52a9dbdc6a7f20fabdcbe29d4ed576624e11…
commit 52a9dbdc6a7f20fabdcbe29d4ed576624e11351d
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jan 26 16:40:27 2013 +0100
tests: framework: Add log output dir option.
diff --git a/tests/framework/tst_main.c b/tests/framework/tst_main.c
index d1c6474..a45b2c6 100644
--- a/tests/framework/tst_main.c
+++ b/tests/framework/tst_main.c
@@ -30,6 +30,7 @@ extern const struct tst_suite tst_suite;
/* defined in tst_suite.c */
extern int tst_suite_verbose;
+extern const char *tst_log_dir;
void print_help(void)
{
@@ -38,6 +39,7 @@ void print_help(void)
fprintf(stderr, "-l list all testsn");
fprintf(stderr, "-t name runs single test by namen");
fprintf(stderr, "-v turns on verbose moden");
+ fprintf(stderr, "-o test log output dirn");
fprintf(stderr, "without any option, all tests are executedn");
}
@@ -45,7 +47,7 @@ int main(int argc, char *argv[])
{
int opt;
- while ((opt = getopt(argc, argv, "hlt:v")) != -1) {
+ while ((opt = getopt(argc, argv, "hlo:t:v")) != -1) {
switch (opt) {
case 'l':
tst_list_suite(&tst_suite);
@@ -62,6 +64,9 @@ int main(int argc, char *argv[])
case 'v':
tst_suite_verbose = 1;
break;
+ case 'o':
+ tst_log_dir = optarg;
+ break;
default:
print_help();
return 1;
diff --git a/tests/framework/tst_suite.c b/tests/framework/tst_suite.c
index 924be43..2bb8455 100644
--- a/tests/framework/tst_suite.c
+++ b/tests/framework/tst_suite.c
@@ -36,6 +36,7 @@
#define NAME_PADD 35
int tst_suite_verbose = 0;
+const char *tst_log_dir = NULL;
static void test_job_report(const struct tst_job *job)
{
@@ -127,7 +128,8 @@ static int run_test(const struct tst_test *test, FILE *json)
* child and parent and the lines in the resulting
* file would be repeated several times.
*/
- fflush(json);
+ if (json)
+ fflush(json);
tst_job_run(&job);
tst_job_wait(&job);
@@ -135,7 +137,8 @@ static int run_test(const struct tst_test *test, FILE *json)
/* report result into stdout */
test_job_report(&job);
- tst_log_append(&job, json);
+ if (json)
+ tst_log_append(&job, json);
/* Free the test message store */
tst_msg_clear(&job.store);
@@ -152,8 +155,14 @@ void tst_run_suite(const struct tst_suite *suite, const char *tst_name)
fprintf(stderr, "Running e[1;37m%se[0mnn", suite->suite_name);
- //TODO:
- FILE *json = tst_log_open(suite, "log.json");
+ FILE *json = NULL;
+
+ if (tst_log_dir) {
+ char buf[512];
+ snprintf(buf, sizeof(buf), "%s/%s.json",
+ tst_log_dir, suite->suite_name);
+ json = tst_log_open(suite, buf);
+ }
for (i = 0; suite->tests[i].name != NULL; i++) {
if (tst_name == NULL || !strcmp(tst_name, suite->tests[i].name)) {
@@ -165,7 +174,8 @@ void tst_run_suite(const struct tst_suite *suite, const char *tst_name)
}
}
- tst_log_close(json);
+ if (json)
+ tst_log_close(json);
float percents;
-----------------------------------------------------------------------
Summary of changes:
tests/core/runtest.sh | 14 -----
tests/core/test_list.txt | 4 ++
tests/framework/tst_main.c | 7 ++-
tests/framework/tst_suite.c | 20 ++++++--
tests/gfx/runtest.sh | 24 ---------
tests/gfx/test_list.txt | 14 +++++
tests/loaders/runtest.sh | 13 -----
tests/loaders/test_list.txt | 3 +
tests/runtests.py | 117 +++++++++++++++++++++++++++++++++++++++++++
tests/runtests.sh | 9 ---
10 files changed, 159 insertions(+), 66 deletions(-)
delete mode 100755 tests/core/runtest.sh
create mode 100644 tests/core/test_list.txt
delete mode 100755 tests/gfx/runtest.sh
create mode 100644 tests/gfx/test_list.txt
delete mode 100755 tests/loaders/runtest.sh
create mode 100644 tests/loaders/test_list.txt
create mode 100755 tests/runtests.py
delete mode 100755 tests/runtests.sh
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: ccc06e628a27ed616222e32e32f0378644e0aae0
by metan 26 Jan '13
by metan 26 Jan '13
26 Jan '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via ccc06e628a27ed616222e32e32f0378644e0aae0 (commit)
via 72671e58dfa51460b3328d901326fe217f0c2f8c (commit)
from 1d8b9f67ffd1b38ef96f2b19ced13fba548c6fcb (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/ccc06e628a27ed616222e32e32f0378644e0…
commit ccc06e628a27ed616222e32e32f0378644e0aae0
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jan 26 00:33:38 2013 +0100
demos: Add GP_HLineAA demo.
diff --git a/demos/c_simple/Makefile b/demos/c_simple/Makefile
index cb6fe82..782eee2 100644
--- a/demos/c_simple/Makefile
+++ b/demos/c_simple/Makefile
@@ -18,7 +18,7 @@ APPS=backend_example loaders_example loaders filters_symmetry gfx_koch virtual_backend_example meta_data meta_data_dump tmp_file showimage v4l2_show v4l2_grab convolution weighted_median shapetest koch input_example fileview linetest randomshapetest fonttest- loaders_register blittest textaligntest abort
+ loaders_register blittest textaligntest abort sin_AA
ifeq ($(HAVE_LIBSDL),yes)
APPS+=SDL_glue
diff --git a/demos/c_simple/sin_AA.c b/demos/c_simple/sin_AA.c
new file mode 100644
index 0000000..94b3563
--- /dev/null
+++ b/demos/c_simple/sin_AA.c
@@ -0,0 +1,126 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+/*
+
+ Simple example that shows HLineAA() usage.
+
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include <GP.h>
+
+static void redraw(GP_Context *context)
+{
+ static float param = 1;
+ static float param2 = 0.01;
+ static int flag = 1;
+ GP_Pixel b = GP_RGBToContextPixel(0xbe, 0xbe, 0x9e, context);
+ unsigned int y;
+
+ GP_Fill(context, b);
+
+ for (y = 0; y < context->w; y++) {
+ GP_Coord x0, x1, l1, l2;
+
+ x0 = (context->w)<<7;
+ x1 = (context->w)<<7;
+
+ l1 = (context->w)<<5;
+ l2 = (context->w)<<3;
+
+ GP_Pixel p = GP_RGBToContextPixel(120 - 3 * param, abs(40 * param), 0, context);
+
+ l2 *= 4.00 * y / context->h;
+
+ l1 *= param;
+
+ x0 += l1 * sin(param2 * y) + l2;
+ x1 -= l1 * cos(param2 * y) + l2;
+
+ GP_HLineAA(context, x0, x1, y<<8, p);
+ }
+
+ if (flag) {
+ param -= 0.02;
+
+ if (param <= -2.40) {
+ flag = 0;
+ param2 += 0.01;
+
+ if (param2 > 0.02)
+ param2 = 0.01;
+ }
+ } else {
+ param += 0.02;
+
+ if (param >= 2.40)
+ flag = 1;
+ }
+}
+
+int main(void)
+{
+ GP_Backend *backend;
+ static int pause_flag = 0;
+
+ /* Initalize backend */
+ backend = GP_BackendX11Init(NULL, 0, 0, 800, 600, "sin AA", 0);
+
+ if (backend == NULL) {
+ fprintf(stderr, "Failed to initalize backendn");
+ return 1;
+ }
+
+ /* Wait for events */
+ for (;;) {
+ if (!pause_flag) {
+ redraw(backend->context);
+ GP_BackendFlip(backend);
+ }
+
+ GP_BackendPoll(backend);
+
+ GP_Event ev;
+
+ while (GP_EventGet(&ev)) {
+ if (ev.type == GP_EV_KEY && ev.code == GP_EV_KEY_DOWN) {
+ switch (ev.val.val) {
+ case GP_KEY_ESC:
+ case GP_KEY_Q:
+ GP_BackendExit(backend);
+ return 0;
+ case GP_KEY_P:
+ pause_flag = !pause_flag;
+ break;
+ }
+ }
+ }
+
+ usleep(10000);
+ }
+
+ return 0;
+}
http://repo.or.cz/w/gfxprim.git/commit/72671e58dfa51460b3328d901326fe217f0c…
commit 72671e58dfa51460b3328d901326fe217f0c2f8c
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Jan 26 00:24:51 2013 +0100
gfx: Fix typos in previous commit.
diff --git a/libs/gfx/GP_HLineAA.gen.c.t b/libs/gfx/GP_HLineAA.gen.c.t
index dac3b8d..8d3240d 100644
--- a/libs/gfx/GP_HLineAA.gen.c.t
+++ b/libs/gfx/GP_HLineAA.gen.c.t
@@ -57,7 +57,7 @@ void GP_HLineAA_Raw(GP_Context *context, GP_Coord x0, GP_Coord x1,
GP_Coord int_x1 = TO_X_E(x1);
GP_Coord int_y = GP_FP_FLOOR_TO_INT(y);
- printf("%f %f %f -> %i %i %in", GP_FP_TO_FLOAT(x0), GP_FP_TO_FLOAT(x1), GP_FP_TO_FLOAT(y), int_x0, int_x1, int_y);
+// printf("%f %f %f -> %i %i %in", GP_FP_TO_FLOAT(x0), GP_FP_TO_FLOAT(x1), GP_FP_TO_FLOAT(y), int_x0, int_x1, int_y);
/* Draw the four starting and ending pixels */
unsigned int perc;
@@ -72,7 +72,7 @@ void GP_HLineAA_Raw(GP_Context *context, GP_Coord x0, GP_Coord x1,
GP_MixPixel_Raw_Clipped(context, int_x0, int_y+1, pixel, perc);
if (int_x0 != int_x1) {
- w = GP_FP_RFRAC(x0 + GP_FP_1_2);
+ w = GP_FP_FRAC(x1 + GP_FP_1_2);
perc = FP_TO_PERC(GP_FP_MUL(GP_FP_RFRAC(y), w));
GP_MixPixel_Raw_Clipped(context, int_x1, int_y, pixel, perc);
-----------------------------------------------------------------------
Summary of changes:
demos/c_simple/Makefile | 2 +-
demos/c_simple/{showimage.c => sin_AA.c} | 96 ++++++++++++++++++++++--------
libs/gfx/GP_HLineAA.gen.c.t | 4 +-
3 files changed, 73 insertions(+), 29 deletions(-)
copy demos/c_simple/{showimage.c => sin_AA.c} (57%)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0