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
Hi!
Tried python 2.5.1 on my old ppc iBook and got this trace:
DIR /libs
DIR /libs/core
GEN ../../include/core/GP_Convert_Scale.gen.h
Traceback (most recent call last):
File "../../pylib/bin/generate_file.py", line 34, in <module>
main(options, args)
File "../../pylib/bin/generate_file.py", line 25, in main
env = render_utils.create_environment(config, options.templates)
File "/home/metan/Devel/gfxprim/pylib/gfxprim/render_utils.py", line 19, in create_environment
loader = jinja2.FileSystemLoader(template_dir))
TypeError: __init__() got an unexpected keyword argument 'line_comment_prefix'
make[1]: *** [core] Error 2
make: *** [libs] Error 2
Any ideas?
--
metan
1
0
[repo.or.cz] gfxprim.git branch generate updated: 62a9833d1129677535724b6ec7c6f0e89a97abdd
by metan 16 Aug '11
by metan 16 Aug '11
16 Aug '11
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, generate has been updated
via 62a9833d1129677535724b6ec7c6f0e89a97abdd (commit)
via 4052dab476c13bb0fcf9cc83d30ba06609481642 (commit)
from d3954003b5befd6bffb6f94106bae1c25185ab93 (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/62a9833d1129677535724b6ec7c6f0e89a97…
commit 62a9833d1129677535724b6ec7c6f0e89a97abdd
Merge: d395400 4052dab
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Tue Aug 16 01:26:57 2011 +0200
Merge /home/metan/Prog/gfxprim into generate
http://repo.or.cz/w/gfxprim.git/commit/4052dab476c13bb0fcf9cc83d30ba0660948…
commit 4052dab476c13bb0fcf9cc83d30ba06609481642
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Tue Aug 16 01:26:02 2011 +0200
First version of GFXprim input events.
diff --git a/include/GP.h b/include/GP.h
index 90777f3..14acffc 100644
--- a/include/GP.h
+++ b/include/GP.h
@@ -16,10 +16,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
+ * Copyright (C) 2009-2011 Jiri "BlueBear" Dluhos *
* <jiri.bluebear.dluhos(a)gmail.com> *
* *
- * Copyright (C) 2009-2010 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -38,4 +38,7 @@
/* backends */
#include "backends/GP_Backend.h"
+/* input and events */
+#include "input/GP_Event.h"
+
#endif /* GP_H */
diff --git a/include/core/GP_Common.h b/include/core/GP_Common.h
index 39b9ea9..23e5527 100644
--- a/include/core/GP_Common.h
+++ b/include/core/GP_Common.h
@@ -50,6 +50,14 @@
})
/*
+ * Returns absolute value.
+ */
+#define GP_ABS(a) ({ + typeof(a) _a = a; + _a > 0 ? _a : -_a; +})
+
+/*
* The standard likely() and unlikely() used in Kernel
*/
#ifndef likely
diff --git a/include/input/GP_Event.h b/include/input/GP_Event.h
index f2531d6..dff17af 100644
--- a/include/input/GP_Event.h
+++ b/include/input/GP_Event.h
@@ -16,110 +16,331 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
- * <jiri.bluebear.dluhos(a)gmail.com> *
- * *
- * Copyright (C) 2009-2010 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
/*
- This interface is modeled after linux input event system.
+ Gfxprim event layer.
+
+ Events are lowlever interfaace to input devices (human interface).
+
+ - Events are notifications that something has changed, eg. button pressed
+ - Each event carries some information about global state
*/
#ifndef GP_EVENT_H
#define GP_EVENT_H
-/* events */
-
-typedef enum GP_EventType {
- GP_EVENT_KEY = 0x01, /* key up/down event */
- GP_EVENT_REL = 0x02, /* relative XY event */
- GP_EVENT_ABS = 0x03, /* absolute XY value */
-} GP_EventType;
-
-/* subevents */
-
-typedef enum GP_EventKeyType {
- GP_KEY_UP = 0x00,
- GP_KEY_DOWN = 0x01,
-} GP_EventKeyType;
-
-typedef enum GP_EventRelType {
- GP_REL_MOVE = 0x00,
- GP_REL_BTN_UP = 0x01,
- GP_REL_BTN_DOWN = 0x02,
- GP_REL_WHEEL = 0x03,
-} GP_EventRelType;
-
-typedef enum GP_EventAbsType {
- GP_ABS_MOVE = 0x00,
- GP_ABS_PEN_UP = 0x01,
- GP_ABS_PEN_DOWN = 0x02,
-} GP_EventAbsType;
-
-/* data structures */
-
-typedef struct GP_EventAbs {
- /* event type */
- GP_EventType type;
- /* device id */
- int dev_id;
- /* possition */
- int x;
- int y;
- /* size */
- int w;
- int h;
-} GP_EventAbs;
-
-typedef struct GP_EventRel {
- GP_EventType type;
- /* device id */
- int dev_id;
- /* possition */
- int x;
- int y;
- /* relative movement */
- int rx;
- int ry;
- int rwheel;
- /* size */
- int w;
- int h;
-} GP_EventRel;
-
-typedef struct GP_EventKey {
- /* event type */
- GP_EventType type;
- /* device id */
- int dev_id;
- /* key */
- int key;
-} GP_EventKey;
+#include <stdint.h>
+#include <sys/time.h>
+
+#define GP_EVENT_QUEUE_SIZE 32
+
+enum GP_EventType {
+ GP_EV_KEY = 1, /* key/button press event */
+ GP_EV_REL = 2, /* relative event */
+ GP_EV_ABS = 3, /* absolute event */
+ GP_EV_MAX = 3, /* maximum, greater values are free */
+};
+
+enum GP_EventKeyCode {
+ GP_EV_KEY_UP = 0,
+ GP_EV_KEY_DOWN = 1,
+ GP_EV_KEY_REPEAT = 2,
+};
+
+/*
+ * This is 1:1 to linux kernel input subsystem.
+ */
+enum GP_EventKeyValue {
+ GP_KEY_ESC = 1,
+ GP_KEY_1 = 2,
+ GP_KEY_2 = 3,
+ GP_KEY_3 = 4,
+ GP_KEY_4 = 5,
+ GP_KEY_5 = 6,
+ GP_KEY_6 = 7,
+ GP_KEY_7 = 8,
+ GP_KEY_8 = 9,
+ GP_KEY_9 = 10,
+ GP_KEY_0 = 11,
+ GP_KEY_MINUS = 12,
+ GP_KEY_EQUAL = 13,
+ GP_KEY_BACKSPACE = 14,
+ GP_KEY_TAB = 15,
+ GP_KEY_Q = 16,
+ GP_KEY_W = 17,
+ GP_KEY_E = 18,
+ GP_KEY_R = 19,
+ GP_KEY_T = 20,
+ GP_KEY_Y = 21,
+ GP_KEY_U = 22,
+ GP_KEY_I = 23,
+ GP_KEY_O = 24,
+ GP_KEY_P = 25,
+ GP_KEY_LEFT_BRACE = 26,
+ GP_KEY_RIGHT_BRACE = 27,
+ GP_KEY_ENTER = 28,
+ GP_KEY_LEFT_CTRL = 29,
+ GP_KEY_A = 30,
+ GP_KEY_S = 31,
+ GP_KEY_D = 32,
+ GP_KEY_F = 33,
+ GP_KEY_G = 34,
+ GP_KEY_H = 35,
+ GP_KEY_J = 36,
+ GP_KEY_K = 37,
+ GP_KEY_L = 38,
+ GP_KEY_SEMICOLON = 39,
+ GP_KEY_APOSTROPHE = 40,
+ GP_KEY_GRAVE = 41,
+ GP_KEY_LEFT_SHIFT = 42,
+ GP_KEY_BACKSLASH = 43,
+ GP_KEY_Z = 44,
+ GP_KEY_X = 45,
+ GP_KEY_C = 46,
+ GP_KEY_V = 47,
+ GP_KEY_B = 48,
+ GP_KEY_N = 49,
+ GP_KEY_M = 50,
+ GP_KEY_COMMA = 51,
+ GP_KEY_DOT = 52,
+ GP_KEY_SLASH = 53,
+ GP_KEY_RIGHT_SHIFT = 54,
+ GP_KEY_KP_ASTERISK = 55,
+ GP_KEY_LEFT_ALT = 56,
+ GP_KEY_SPACE = 57,
+ GP_KEY_CAPS_LOCK = 58,
+ GP_KEY_F1 = 59,
+ GP_KEY_F2 = 60,
+ GP_KEY_F3 = 61,
+ GP_KEY_F4 = 62,
+ GP_KEY_F5 = 63,
+ GP_KEY_F6 = 64,
+ GP_KEY_F7 = 65,
+ GP_KEY_F8 = 66,
+ GP_KEY_F9 = 67,
+ GP_KEY_F10 = 68,
+ GP_KEY_NUM_LOCK = 69,
+ GP_KEY_SCROLL_LOCK = 70,
+ GP_KEY_KP_7 = 71,
+ GP_KEY_KP_8 = 72,
+ GP_KEY_KP_9 = 73,
+ GP_KEY_KP_MINUS = 74,
+ GP_KEY_KP_4 = 75,
+ GP_KEY_KP_5 = 76,
+ GP_KEY_KP_6 = 77,
+ GP_KEY_KP_PLUS = 78,
+ GP_KEY_KP_1 = 79,
+ GP_KEY_KP_2 = 80,
+ GP_KEY_KP_3 = 81,
+ GP_KEY_KP_0 = 82,
+ GP_KEY_KP_DOT = 83,
+
+ GP_KEY_F11 = 87,
+ GP_KEY_F12 = 88,
+
+ GP_KEY_KP_ENTER = 96,
+ GP_KEY_RIGHT_CTRL = 97,
+ GP_KEY_KP_SLASH = 98,
+ GP_KEY_SYSRQ = 99,
+ GP_KEY_RIGHT_ALT = 100,
+
+ GP_KEY_HOME = 102,
+ GP_KEY_UP = 103,
+ GP_KEY_PAGE_UP = 104,
+ GP_KEY_LEFT = 105,
+ GP_KEY_RIGHT = 106,
+ GP_KEY_END = 107,
+ GP_KEY_DOWN = 108,
+ GP_KEY_PAGE_DOWN = 109,
+ GP_KEY_INSERT = 110,
+ GP_KEY_DELETE = 111,
+
+ GP_KEY_KP_EQUAL = 117,
+ GP_KEY_KP_PLUS_MINUS = 118,
+ GP_KEY_PAUSE = 119,
+
+ GP_KEY_KP_COMMA = 121,
+
+ GP_KEY_LEFT_META = 125,
+ GP_KEY_RIGHT_META = 126,
+ GP_KEY_COMPOSE = 127,
-typedef union GP_EventPtr {
- GP_EventAbs *abs;
- GP_EventRel *rel;
- GP_EventKey *key;
-} GP_EventPtr;
+ GP_KEY_F13 = 183,
+ GP_KEY_F14 = 184,
+ GP_KEY_F15 = 185,
+ GP_KEY_F16 = 186,
+ GP_KEY_F17 = 187,
+ GP_KEY_F18 = 188,
+ GP_KEY_F19 = 189,
+ GP_KEY_F20 = 190,
+ GP_KEY_F21 = 191,
+ GP_KEY_F22 = 192,
+ GP_KEY_F23 = 193,
+ GP_KEY_F24 = 194,
-typedef struct GP_Time {
- long sec;
- long usec;
-} GP_Time;
+ /* Common Buttons */
+ GP_BTN_0 = 0x100,
+ GP_BTN_1 = 0x101,
+ GP_BTN_2 = 0x102,
+ GP_BTN_3 = 0x103,
+ GP_BTN_4 = 0x104,
+ GP_BTN_5 = 0x105,
+ GP_BTN_6 = 0x106,
+ GP_BTN_7 = 0x107,
+ GP_BTN_8 = 0x108,
+ GP_BTN_9 = 0x109,
+
+ /* Mouse Buttons */
+ GP_BTN_LEFT = 0x110,
+ GP_BTN_RIGHT = 0x111,
+ GP_BTN_MIDDLE = 0x112,
+ GP_BTN_SIDE = 0x113,
+ GP_BTN_EXTRA = 0x114,
+ GP_BTN_FORWARD = 0x115,
+ GP_BTN_BACK = 0x116,
+ GP_BTN_TASK = 0x117,
+};
+
+enum GP_EventRelCode {
+ GP_EV_REL_POS = 0,
+ GP_EV_REL_WHEEL = 1,
+};
+
+enum GP_EventAbsCode {
+ GP_EV_ABS_POS = 0,
+};
+
+struct GP_EventPosRel {
+ int32_t rx;
+ int32_t ry;
+};
+
+struct GP_EventPosAbs {
+ uint32_t x, x_max; /* the x is between 0 and x_max */
+ uint32_t y, y_max;
+ uint32_t pressure, pressure_max;
+};
+
+struct GP_EventKey {
+ uint32_t key;
+ char ascii;
+};
+
+union GP_EventValue {
+ /* generic one integer value */
+ int32_t val;
+ /* key */
+ struct GP_EventKey key;
+ /* possition */
+ struct GP_EventPosRel rel;
+ struct GP_EventPosAbs abs;
+};
typedef struct GP_Event {
- /* GP_EventType */
- int type;
- /* GP_Event???Type */
- int stype;
- /* time */
- GP_Time time;
- /* event data */
- GP_EventPtr data;
+ /* event */
+ uint16_t type;
+ uint32_t code;
+ union GP_EventValue val;
+
+ /* input device id */
+ uint32_t dev_id;
+
+ /* event timestamp */
+ struct timeval time;
+
+ /*
+ * Cursor possition, possition on screen accumulated
+ * from all pointer devices
+ */
+ uint32_t cursor_x;
+ uint32_t cursor_y;
+
+ /*
+ * Bitmap of pressed keys including mouse buttons
+ * accumulated for all input devices.
+ */
+ uint8_t keys_pressed[36];
} GP_Event;
+/*
+ * Sets global screen size.
+ */
+void GP_EventSetScreenSize(uint32_t w, uint32_t h);
+
+/*
+ * Sets global cursor possition, doesn't generate event.
+ *
+ * Use for initial cursor placement.
+ */
+void GP_EventSetScreenCursor(uint32_t x, uint32_t y);
+
+/*
+ * Returns number of queued events.
+ */
+uint32_t GP_EventQueued(void);
+
+/*
+ * Dump event into stdout.
+ */
+void GP_EventDump(struct GP_Event *ev);
+
+/*
+ * Returns human-readable key name.
+ */
+const char *GP_EventKeyName(enum GP_EventKeyValue key);
+
+/*
+ * Fills event and returns true. Retuns false if queue is empty.
+ */
+int GP_EventGet(struct GP_Event *ev);
+
+/*
+ * Inject event that moves cursor by rx and ry.
+ */
+void GP_EventPushRel(int32_t rx, int32_t ry, struct timeval *time);
+
+/*
+ * Inject absolute event.
+ */
+void GP_EventPushAbs(uint32_t x, uint32_t y, uint32_t pressure,
+ uint32_t x_max, uint32_t y_max, uint32_t pressure_max,
+ struct timeval *time);
+
+/*
+ * Inject event that changes key state.
+ */
+void GP_EventPushKey(uint32_t key, uint8_t code, struct timeval *time);
+
+/*
+ * Inject common event.
+ */
+void GP_EventPush(uint16_t type, uint32_t code, int32_t value,
+ struct timeval *time);
+
+/*
+ * Helpers for setting/getting key bits.
+ */
+static inline void GP_EventSetKey(struct GP_Event *ev,
+ uint32_t key)
+{
+ ev->keys_pressed[(key)/8] |= 1<<((key)%8);
+}
+
+static inline int GP_EventGetKey(struct GP_Event *ev,
+ uint32_t key)
+{
+ return !!(ev->keys_pressed[(key)/8] & ~(1<<((key)%8)));
+}
+
+static inline void GP_EventResetKey(struct GP_Event *ev,
+ uint32_t key)
+{
+ ev->keys_pressed[(key)/8] |= 1<<((key)%8);
+}
+
#endif /* GP_EVENT_H */
diff --git a/libs/input/GP_Event.c b/include/input/GP_InputDriverSDL.h
similarity index 82%
copy from libs/input/GP_Event.c
copy to include/input/GP_InputDriverSDL.h
index fdbeb21..01269a9 100644
--- a/libs/input/GP_Event.c
+++ b/include/input/GP_InputDriverSDL.h
@@ -16,12 +16,24 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
- * <jiri.bluebear.dluhos(a)gmail.com> *
- * *
- * Copyright (C) 2009-2010 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
-#include "GP_Event.h"
+/*
+
+
+ */
+
+#ifndef GP_INPUT_DRIVER_SDL_H
+#define GP_INPUT_DRIVER_SDL_H
+
+#include <stdint.h>
+#include <SDL/SDL.h>
+
+/*
+ * Converts SDL event to GFXprim evevt and puts it into the queue.
+ */
+void GP_InputDriverSDLEventPut(SDL_Event *ev);
+#endif /* GP_INPUT_DRIVER_SDL_H */
diff --git a/libs/input/GP_Event.c b/libs/input/GP_Event.c
index fdbeb21..5e87a04 100644
--- a/libs/input/GP_Event.c
+++ b/libs/input/GP_Event.c
@@ -16,12 +16,277 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
- * <jiri.bluebear.dluhos(a)gmail.com> *
- * *
- * Copyright (C) 2009-2010 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "GP_Common.h"
#include "GP_Event.h"
+/* Screen size for clipping the cursor possition */
+static uint32_t screen_w = 0, screen_h = 0;
+
+/* Event queue */
+static uint32_t queue_first = 0, queue_last = 0;
+static struct GP_Event event_queue[GP_EVENT_QUEUE_SIZE];
+
+/* Global input state */
+static struct GP_Event cur_state = {.cursor_x = 0, .cursor_y = 0};
+
+static char *key_names[] = {
+ "Reserved", "Escape", "1", "2", "3",
+ "4", "5", "6", "7", "8",
+ "9", "0", "Minus", "Equal", "BackSpace",
+ "Tab", "Q", "W", "E", "R",
+ "T", "Y", "U", "I", "O",
+ "P", "LeftBrace", "RightBrace", "Enter", "LeftCtrl",
+ "A", "S", "D", "F", "G",
+ "H", "J", "K", "L", "Semicolon",
+ "Apostrophe", "Grave", "LeftShift", "BackSlash", "Z",
+ "X", "C", "V", "B", "N",
+ "M", "Comma", "Dot", "Slash", "RightShift",
+ "KP Asterisk", "LeftAlt", "Space", "CapsLock", "F1",
+ "F2", "F3", "F4", "F5", "F6",
+ "F7", "F8", "F9", "F10", "NumLock",
+ "ScrollLock", "KP 7", "KP 8", "KP 9", "KP Minus",
+ "KP 4", "KP 5", "KP 6", "KP Plus", "KP 1",
+ "KP 2", "KP 3", "KP 0", "KP Dot", "?",
+ "?", "?", "F11", "F12", "?",
+ "?", "?", "?", "?", "?",
+ "?", "KP Enter", "RightCtrl", "KP Slash", "SysRq",
+ "RightAlt", "?", "Home", "Up", "PageUp",
+ "Left", "Right", "End", "Down", "PageDown",
+ "Insert", "Delete", "?", "?", "?",
+ "?", "?", "KP Equal", "KP PlusMinus", "Pause",
+ "?", "KP Comma", "?", "?", "?",
+ "LeftMeta", "RightMeta", "Compose",
+};
+
+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;
+}
+
+void GP_EventSetScreenCursor(uint32_t x, uint32_t y)
+{
+ cur_state.cursor_x = x;
+ cur_state.cursor_y = y;
+}
+
+uint32_t GP_EventQueued(void)
+{
+ if (queue_first <= queue_last)
+ return queue_last - queue_first;
+
+ return GP_EVENT_QUEUE_SIZE - (queue_last - queue_first);
+}
+
+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;
+}
+
+const char *GP_EventKeyName(enum GP_EventKeyValue key)
+{
+ if (key < key_names_size)
+ return key_names[key];
+
+ switch (key) {
+ case GP_BTN_LEFT:
+ return "LeftButton";
+ case GP_BTN_RIGHT:
+ return "RightButton";
+ case GP_BTN_MIDDLE:
+ return "MiddleButton";
+ default:
+ return "Unknown";
+ };
+
+}
+
+static void dump_rel(struct GP_Event *ev)
+{
+ printf("EVENT REL ");
+
+ switch (ev->code) {
+ case GP_EV_REL_POS:
+ printf("POSSITION %u %un", ev->cursor_x, ev->cursor_y);
+ break;
+ case GP_EV_REL_WHEEL:
+ printf("WHEEL %in", ev->val.val);
+ break;
+ }
+}
+
+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("EVENT KEY %i (Key%s) %sn",
+ ev->val.key.key, name, ev->code ? "down" : "up");
+
+}
+
+void GP_EventDump(struct GP_Event *ev)
+{
+ switch (ev->type) {
+ case GP_EV_KEY:
+ dump_key(ev);
+ break;
+ case GP_EV_REL:
+ dump_rel(ev);
+ break;
+ case GP_EV_ABS:
+ printf("EVENT ABSn");
+ break;
+ }
+}
+
+static void event_put(struct GP_Event *ev)
+{
+ uint32_t next = (queue_last + 1) % GP_EVENT_QUEUE_SIZE;
+
+ if (next == queue_first) {
+ fprintf(stderr, "Event queue full, dropping eventn");
+ return;
+ }
+
+ event_queue[queue_last] = *ev;
+ queue_last = next;
+}
+
+static void set_time(struct timeval *time)
+{
+ if (time == NULL)
+ gettimeofday(&cur_state.time, NULL);
+ else
+ cur_state.time = *time;
+}
+
+static uint32_t clip_rel(uint32_t val, uint32_t max, int32_t rel)
+{
+ if (rel < 0) {
+ if (val < GP_ABS(rel))
+ return 0;
+ else
+ return val + rel;
+ }
+
+ if (val + rel >= max)
+ return max - 1;
+
+ return val + rel;
+}
+
+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;
+
+ cur_state.val.rel.rx = rx;
+ 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);
+
+ /* put it into queue */
+ event_put(&cur_state);
+}
+
+void GP_EventPushAbs(uint32_t x, uint32_t y, uint32_t pressure,
+ uint32_t x_max, uint32_t y_max, uint32_t pressure_max,
+ struct timeval *time)
+{
+ /* event header */
+ cur_state.type = GP_EV_ABS;
+ cur_state.code = GP_EV_REL_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;
+
+ set_time(time);
+
+ /* set global cursor */
+ cur_state.cursor_x = x * screen_w / x_max;
+ cur_state.cursor_y = y * screen_h / y_max;
+
+ /* put it into queue */
+ event_put(&cur_state);
+}
+
+void GP_EventPushKey(uint32_t key, uint8_t code, struct timeval *time)
+{
+ switch (code) {
+ case GP_EV_KEY_UP:
+ GP_EventResetKey(&cur_state, key);
+ break;
+ case GP_EV_KEY_DOWN:
+ GP_EventSetKey(&cur_state, key);
+ break;
+ case GP_EV_KEY_REPEAT:
+ break;
+ default:
+ fprintf(stderr, "Invalid key event code %un", code);
+ return;
+ }
+
+ /* event header */
+ cur_state.type = GP_EV_KEY;
+ cur_state.code = code;
+ cur_state.val.key.key = key;
+ //TODO cur_state.val.key.ascii
+
+ set_time(time);
+
+ /* put it into queue */
+ event_put(&cur_state);
+}
+
+void GP_EventPush(uint16_t type, uint32_t code, int32_t value,
+ struct timeval *time)
+{
+ switch (type) {
+ case GP_EV_KEY:
+ GP_EventPushKey(code, value, time);
+ break;
+ default:
+ cur_state.type = type;
+ cur_state.code = code;
+ cur_state.val.val = value;
+
+ set_time(time);
+
+ event_put(&cur_state);
+ }
+}
diff --git a/libs/input/GP_InputDriverSDL.c b/libs/input/GP_InputDriverSDL.c
new file mode 100644
index 0000000..3e7f5d1
--- /dev/null
+++ b/libs/input/GP_InputDriverSDL.c
@@ -0,0 +1,138 @@
+/*****************************************************************************
+ * 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-2011 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+
+#include "GP_Event.h"
+#include "GP_InputDriverSDL.h"
+
+/* SDL ascii mapped keys */
+static uint16_t keysym_table1[] = {
+ 0, 0, 0, 0,
+ 0, 0, 0, GP_KEY_BACKSPACE,
+ GP_KEY_TAB, 0, 0, 0,
+ GP_KEY_ENTER, 0, 0, 0,
+ 0, 0, GP_KEY_PAUSE, 0,
+ 0, 0, 0, 0,
+ 0, 0, GP_KEY_ESC, 0,
+ 0, 0, 0, GP_KEY_SPACE,
+ 0, 0, 0, 0,
+ 0, 0, GP_KEY_APOSTROPHE, 0,
+ 0, 0, 0, GP_KEY_COMMA,
+ GP_KEY_MINUS, GP_KEY_DOT, GP_KEY_SLASH, GP_KEY_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, 0, GP_KEY_SEMICOLON, 0,
+ GP_KEY_EQUAL, 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, GP_KEY_LEFT_BRACE, GP_KEY_BACKSLASH,
+ GP_KEY_RIGHT_BRACE, 0, 0, GP_KEY_GRAVE,
+ GP_KEY_A, GP_KEY_B, GP_KEY_C, GP_KEY_D,
+ GP_KEY_E, GP_KEY_F, GP_KEY_G, GP_KEY_H,
+ GP_KEY_I, GP_KEY_J, GP_KEY_K, GP_KEY_L,
+ GP_KEY_M, GP_KEY_N, GP_KEY_O, GP_KEY_P,
+ GP_KEY_Q, GP_KEY_R, GP_KEY_S, GP_KEY_T,
+ GP_KEY_U, GP_KEY_V, GP_KEY_W, GP_KEY_X,
+ GP_KEY_Y, GP_KEY_Z, 0, 0,
+ 0, 0, GP_KEY_DELETE,
+};
+
+static const uint16_t keysym_table1_size = sizeof(keysym_table1)/2;
+
+/* keypad and function keys starting at 256 */
+static uint16_t keysym_table2[] = {
+ GP_KEY_KP_0, GP_KEY_KP_1, GP_KEY_KP_2, GP_KEY_KP_3,
+ GP_KEY_KP_4, GP_KEY_KP_5, GP_KEY_KP_6, GP_KEY_KP_7,
+ GP_KEY_KP_8, GP_KEY_KP_9, GP_KEY_KP_DOT, GP_KEY_KP_SLASH,
+ GP_KEY_KP_ASTERISK, GP_KEY_KP_MINUS, GP_KEY_KP_PLUS, GP_KEY_KP_ENTER,
+ GP_KEY_KP_EQUAL, GP_KEY_UP, GP_KEY_DOWN, GP_KEY_RIGHT,
+ GP_KEY_LEFT, GP_KEY_INSERT, GP_KEY_HOME, GP_KEY_END,
+ GP_KEY_PAGE_UP, GP_KEY_PAGE_DOWN, 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_F11, GP_KEY_F12, GP_KEY_F13, GP_KEY_F14,
+ GP_KEY_F15, 0, 0, 0,
+ GP_KEY_NUM_LOCK, GP_KEY_CAPS_LOCK, GP_KEY_SCROLL_LOCK, GP_KEY_RIGHT_SHIFT,
+ GP_KEY_LEFT_SHIFT, GP_KEY_RIGHT_CTRL, GP_KEY_LEFT_CTRL, GP_KEY_RIGHT_ALT,
+ GP_KEY_LEFT_ALT, 0, 0, GP_KEY_LEFT_META,
+ GP_KEY_RIGHT_META, 0, 0, 0,
+ GP_KEY_SYSRQ, 0, 0, GP_KEY_COMPOSE,
+};
+
+static const uint16_t keysym_table2_size = sizeof(keysym_table2)/2;
+
+void GP_InputDriverSDLEventPut(SDL_Event *ev)
+{
+ uint16_t keysym;
+ uint32_t key = 0;
+
+ switch (ev->type) {
+ case SDL_MOUSEMOTION:
+ GP_EventPushRel(ev->motion.xrel, ev->motion.yrel, NULL);
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ case SDL_MOUSEBUTTONUP:
+ switch (ev->button.button) {
+ case 1:
+ key = GP_BTN_LEFT;
+ break;
+ case 2:
+ key = GP_BTN_MIDDLE;
+ break;
+ case 3:
+ key = GP_BTN_RIGHT;
+ break;
+ default:
+ return;
+ }
+
+ GP_EventPush(GP_EV_KEY, key, ev->button.state, NULL);
+ break;
+ case SDL_KEYDOWN:
+ case SDL_KEYUP:
+ keysym = ev->key.keysym.sym;
+
+ if (keysym > 0 && keysym <= keysym_table1_size)
+ key = keysym_table1[keysym - 1];
+
+ if (keysym > 255 && keysym <= 255 + keysym_table2_size)
+ key = keysym_table2[keysym - 256];
+
+ if (key == 0) {
+ fprintf(stderr, "Unmapped SDL keysym %un", keysym);
+ return;
+ }
+
+ printf("*** KEYSYM %u KEY %un", keysym, key);
+
+ GP_EventPushKey(key, ev->key.state, NULL);
+ break;
+ case SDL_VIDEORESIZE:
+ break;
+ case SDL_QUIT:
+ break;
+ }
+}
diff --git a/libs/input/Makefile b/libs/input/Makefile
index 0dcb208..afadcd1 100644
--- a/libs/input/Makefile
+++ b/libs/input/Makefile
@@ -1,5 +1,6 @@
TOPDIR=../..
CSOURCES=$(shell ls *.c)
+INCLUDE=core
LIBNAME=input
include $(TOPDIR)/include.mk
include $(TOPDIR)/lib.mk
diff --git a/tests/SDL/Makefile b/tests/SDL/Makefile
index e186c7a..0c908f2 100644
--- a/tests/SDL/Makefile
+++ b/tests/SDL/Makefile
@@ -6,7 +6,7 @@ INCLUDE=core gfx SDL backends
LDLIBS+=-lGP -L$(TOPDIR)/build/ -lGP_SDL -lSDL
APPS=pixeltest fileview fonttest linetest randomshapetest shapetest sierpinsky- symbolstest textaligntest trianglefps
+ symbolstest textaligntest trianglefps input
include $(TOPDIR)/include.mk
include $(TOPDIR)/app.mk
diff --git a/tests/SDL/input.c b/tests/SDL/input.c
new file mode 100644
index 0000000..7ff2dc5
--- /dev/null
+++ b/tests/SDL/input.c
@@ -0,0 +1,182 @@
+/*****************************************************************************
+ * 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-2010 Jiri "BlueBear" Dluhos *
+ * <jiri.bluebear.dluhos(a)gmail.com> *
+ * *
+ * Copyright (C) 2009-2010 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <SDL/SDL.h>
+
+#include "GP.h"
+#include "GP_SDL.h"
+
+/* The surface used as a display (in fact it is a software surface). */
+SDL_Surface *display = NULL;
+GP_Context context;
+
+/* Timer used for refreshing the display */
+SDL_TimerID timer;
+
+/* An event used for signaling that the timer was triggered. */
+SDL_UserEvent timer_event;
+
+/* Values for color pixels in display format. */
+GP_Pixel red_pixel, green_pixel, blue_pixel, white_pixel;
+
+Uint32 timer_callback(__attribute__((unused)) Uint32 interval,
+ __attribute__((unused)) void *param)
+{
+ timer_event.type = SDL_USEREVENT;
+ SDL_PushEvent((SDL_Event *) &timer_event);
+ return 30;
+}
+
+void draw_pixel(void)
+{
+// GP_Color pixel, conv;
+ int x = random() % 320;
+ int y = random() % 240;
+
+// pixel = GP_GetPixel(&context, x, y);
+
+ GP_PutPixel(&context, x, y, green_pixel);
+
+ /* TODO: we cannot switch like this
+ we need either to convert blue
+ and others into Context format
+ at the very beginning, or make
+ a copy to convert it and match
+ agains what we get from GP_GetPixel
+
+ if (pixel == blue) {
+ GP_PutPixel(&context, x, y, green);
+ }
+ else if (pixel == red) {
+ GP_PutPixel(&context, x, y, white);
+ }
+ else {
+ if (x < 160) {
+ GP_PutPixel(&context, x, y, blue);
+ } else {
+ GP_PutPixel(&context, x, y, red);
+ }
+ } */
+}
+
+void draw_pixels(void)
+{
+ SDL_LockSurface(display);
+
+ /* Draw some pixels (exact number is not important). */
+ int i;
+ for (i = 0; i < 30; i++)
+ draw_pixel();
+
+ SDL_UnlockSurface(display);
+}
+
+void event_loop(void)
+{
+ SDL_Event event;
+
+ while (SDL_WaitEvent(&event) > 0) {
+ GP_InputDriverSDLEventPut(&event);
+
+ while (GP_EventQueued()) {
+ GP_Event ev;
+
+ GP_EventGet(&ev);
+ GP_EventDump(&ev);
+
+ if (ev.type == GP_EV_KEY &&
+ ev.val.key.key == GP_KEY_ESC)
+ exit(0);
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ int display_bpp = 0;
+
+ int i;
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-16") == 0) {
+ display_bpp = 16;
+ } else if (strcmp(argv[i], "-24") == 0) {
+ display_bpp = 24;
+ }
+ }
+
+ /* Initialize SDL */
+ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) {
+ fprintf(stderr, "Could not initialize SDL: %sn", SDL_GetError());
+ return 1;
+ }
+
+ /* Create a window with a software back surface */
+ display = SDL_SetVideoMode(320, 240, display_bpp, SDL_SWSURFACE);
+ if (display == NULL) {
+ fprintf(stderr, "Could not open display: %sn", SDL_GetError());
+ goto fail;
+ }
+
+ GP_EventSetScreenSize(320, 240);
+
+ /* Print basic information about the surface */
+ printf("Display surface properties:n");
+ printf(" width: %4d, height: %4d, pitch: %4dn",
+ display->w, display->h, display->pitch);
+ printf(" bits per pixel: %2d, bytes per pixel: %2dn",
+ display->format->BitsPerPixel, display->format->BytesPerPixel);
+
+ /* Set up a clipping rectangle to test proper clipping of pixels */
+ SDL_Rect clip_rect = {10, 10, 300, 220};
+ SDL_SetClipRect(display, &clip_rect);
+
+ GP_SDL_ContextFromSurface(&context, display);
+
+ /* Load pixel values compatible with the display. */
+ red_pixel = GP_ColorToPixel(&context, GP_COL_RED);
+ green_pixel = GP_ColorToPixel(&context, GP_COL_GREEN);
+ blue_pixel = GP_ColorToPixel(&context, GP_COL_BLUE);
+ white_pixel = GP_ColorToPixel(&context, GP_COL_WHITE);
+
+ /* Set up the refresh timer */
+ timer = SDL_AddTimer(30, timer_callback, NULL);
+ if (timer == 0) {
+ fprintf(stderr, "Could not set up timer: %sn", SDL_GetError());
+ goto fail;
+ }
+
+ /* Enter the event loop */
+ event_loop();
+
+ /* We're done */
+ SDL_Quit();
+ return 0;
+
+fail:
+ SDL_Quit();
+ return 1;
+}
-----------------------------------------------------------------------
Summary of changes:
include/GP.h | 7 +-
include/core/GP_Common.h | 8 +
include/input/GP_Event.h | 399 +++++++++++++++-----
.../{core/GP_Types.h => input/GP_InputDriverSDL.h} | 20 +-
libs/input/GP_Event.c | 273 +++++++++++++-
libs/input/GP_InputDriverSDL.c | 138 +++++++
libs/input/Makefile | 1 +
tests/SDL/Makefile | 2 +-
tests/SDL/{pixeltest.c => input.c} | 20 +-
9 files changed, 756 insertions(+), 112 deletions(-)
copy include/{core/GP_Types.h => input/GP_InputDriverSDL.h} (87%)
create mode 100644 libs/input/GP_InputDriverSDL.c
copy tests/SDL/{pixeltest.c => input.c} (95%)
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 generate updated: d3954003b5befd6bffb6f94106bae1c25185ab93
by gavento 16 Aug '11
by gavento 16 Aug '11
16 Aug '11
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, generate has been updated
via d3954003b5befd6bffb6f94106bae1c25185ab93 (commit)
via e6e4bd2d38903632e1b0e255e6c9afcd62b5622a (commit)
via 00b47c68244ad4286267fd11514baebf286f686d (commit)
via f701e7653f842a98bdd0b32dac7318af8e49bf32 (commit)
via 6307b2d10257649177470bce95638a3284684bdd (commit)
from 59ca35df4a090bfb9ba4e17504263512e3225eef (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/d3954003b5befd6bffb6f94106bae1c25185…
commit d3954003b5befd6bffb6f94106bae1c25185ab93
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Tue Aug 16 00:07:21 2011 +0200
Fixed pointer types in Put/GetPixel. Fix pixel offset.
diff --git a/include/core/GP_GetPutPixel.gen.h.t b/include/core/GP_GetPutPixel.gen.h.t
index 1ee473c..26a73d7 100644
--- a/include/core/GP_GetPutPixel.gen.h.t
+++ b/include/core/GP_GetPutPixel.gen.h.t
@@ -16,7 +16,7 @@ struct GP_Context;
* macro to get address of pixel in a {{ ps.suffix }} context
*/
#define GP_PIXEL_ADDR_{{ ps.suffix }}(context, x, y) - ((context)->pixels + (context)->bytes_per_row * (y) + {{ ps.size // 8 }} * (x))
+ ((GP_Pixel*)(((void*)((context)->pixels)) + (context)->bytes_per_row * (y) + ({{ ps.size }} * (x)) / 8))
/*
* macro to get bit-offset of pixel in {{ ps.suffix }} context
@@ -29,7 +29,7 @@ struct GP_Context;
%% if ps.size < 8
(((x) % {{ 8 // ps.size }}) * {{ ps.size }})
%% else
- (((x) * {{ ps.size }}) / 8)
+ (({{ ps.size }} * (x)) % 8)
%% endif
%% else
%% if ps.size < 8
http://repo.or.cz/w/gfxprim.git/commit/e6e4bd2d38903632e1b0e255e6c9afcd62b5…
commit e6e4bd2d38903632e1b0e255e6c9afcd62b5622a
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Mon Aug 15 21:05:12 2011 +0200
Minor replacement by GP_PIXEL_BITS
diff --git a/include/core/GP_Pixel.h b/include/core/GP_Pixel.h
index 45bcf19..fb38acb 100644
--- a/include/core/GP_Pixel.h
+++ b/include/core/GP_Pixel.h
@@ -106,9 +106,9 @@ typedef struct {
GP_BIT_ENDIAN bit_endian; /* Order of pixels in a byte */
uint8_t numchannels; /* Number of channels */
/* String describing the bit-representaton (as in "RRRRRGGGGGGBBBBB")*/
- const char bitmap[sizeof(GP_Pixel) * 8 + 1];
+ const char bitmap[GP_PIXEL_BITS + 1];
/* Individual channels */
- const GP_PixelTypeChannel channels[GP_PIXELTYPE_MAX_CHANNELS];
+ const GP_PixelTypeChannel channels[GP_PIXELTYPE_MAX_CHANNELS];
} GP_PixelTypeDescription;
/*
http://repo.or.cz/w/gfxprim.git/commit/00b47c68244ad4286267fd11514baebf286f…
commit 00b47c68244ad4286267fd11514baebf286f686d
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Mon Aug 15 20:14:24 2011 +0200
test running: remove verbose mode
(all errors still printed)
diff --git a/tests.mk b/tests.mk
index d18d86a..39f0835 100644
--- a/tests.mk
+++ b/tests.mk
@@ -49,7 +49,7 @@ endif # TESTSUITE
tests: $(TESTS)
runtests: tests
- for test in $(TESTS); do LD_LIBRARY_PATH=../../build ./"$$test" -v ; done
+ for test in $(TESTS); do LD_LIBRARY_PATH=../../build ./"$$test"; done
# WARN: avoid double includion?
include $(TOPDIR)/gen.mk
http://repo.or.cz/w/gfxprim.git/commit/f701e7653f842a98bdd0b32dac7318af8e49…
commit f701e7653f842a98bdd0b32dac7318af8e49bf32
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Mon Aug 15 20:13:20 2011 +0200
Fix test: remove suspicious aliasing
diff --git a/tests/core/GP_Common.test.c b/tests/core/GP_Common.test.c
index 0fe2b1f..9695d93 100644
--- a/tests/core/GP_Common.test.c
+++ b/tests/core/GP_Common.test.c
@@ -29,7 +29,7 @@
* Demo ("testing" ;-) tests for GP_Common.h
*/
-GP_SUITE(GP_Common)
+GP_SUITE(GP_Common)
GP_TEST(min_max)
{
@@ -56,17 +56,19 @@ GP_TEST(set_bits)
uint16_t *y = (uint16_t*) &x;
GP_CLEAR_BITS(3, 4, x);
fail_unless(x == 0x89A84);
- GP_SET_BITS_OR(10, x, 0x0000000);
+ GP_SET_BITS_OR(10, x, 0x0000000);
fail_unless(x == 0x89A84);
- GP_SET_BITS(24, 18, x, 0x42F1);
+ GP_SET_BITS(24, 18, x, 0x42F1);
fail_unless(x == 0xF1089A84);
/* Check that only uint16_t is affected */
- GP_SET_BITS(0, 24, *y, 0x100F000LL);
+/* TODO: Fix aliasing problems with this test
+ GP_SET_BITS(0, 24, *y, 0x100F000LL);
# if __BYTE_ORDER == __BIG_ENDIAN
fail_unless(x == 0xF108F000);
# else
fail_unless(x == 0x100F9A84);
-# endif
+# endif
+*/
}
GP_ENDTEST
http://repo.or.cz/w/gfxprim.git/commit/6307b2d10257649177470bce95638a328468…
commit 6307b2d10257649177470bce95638a3284684bdd
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Mon Aug 15 20:12:48 2011 +0200
Fix test: RGB888 byte order
diff --git a/tests/core/GP_Convert.test.c b/tests/core/GP_Convert.test.c
index 3f80a3a..19e8f9d 100644
--- a/tests/core/GP_Convert.test.c
+++ b/tests/core/GP_Convert.test.c
@@ -16,7 +16,7 @@ GP_TEST(BasicPixelConversions)
p1 = GP_RGBAToPixel(0, 0, 0, 0, GP_PIXEL_RGBA8888);
fail_unless(p1 == 0x0);
p1 = GP_RGBToPixel(0x12, 0x34, 0x56, GP_PIXEL_RGB888);
- fail_unless(p1 == 0x563412);
+ fail_unless(p1 == 0x123456);
GP_CHECK_EqualColors(p1, GP_PIXEL_RGB888, p1, GP_PIXEL_RGB888);
p1 = GP_RGB888ToPixel(GP_RGBToPixel(0x12, 0x34, 0x56, GP_PIXEL_RGB888), GP_PIXEL_V4);
-----------------------------------------------------------------------
Summary of changes:
include/core/GP_GetPutPixel.gen.h.t | 4 ++--
include/core/GP_Pixel.h | 4 ++--
tests.mk | 2 +-
tests/core/GP_Common.test.c | 12 +++++++-----
tests/core/GP_Convert.test.c | 2 +-
5 files changed, 13 insertions(+), 11 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
Hi,
As in every project, documentation of GfxPrim is lagging behind the
code. Lately, I grew very fond of in-header documentation for
individual functions and structures, as that is much easier to keep up
to date and with just a little in-code documentation, keeping the two
in sync is a hassle.
How could we easily and simply do some doctext extraction?
I thought about several ways:
* Doxygen. I have no experience with it and it seems to be a bit too
involved for us, but it is an option.
* Some home-grown AsciiDoc extraction from comments. Could specify the
target file in the tag, these could be included by regular docs.
Example:
/* SOME_SPECIAL_TAG target_file
* int f(int x)
* Does useful things
* More asciidoc markup
*/
int f(int x) {return 0;}
* Some other tool (mkdoc, doxygen (parsing only) + breathe + sphinx,
whatever you prefer)
The main idea is to avoid duplication, keep information together,
simplify doc writing and stale data spotting and updating.
What do you think?
Tomas
2
1
Hi!
As you may know the default type resulting from divison in python changed from
int to float which results in type errors in GP_Convert_Scale.gen.h.t. The new
integer division is no done by // which doesn't work in older python versions.
I suppose we need to add explicit rounding to places when integer division is
expected.
--
metan
2
2
[repo.or.cz] gfxprim.git branch generate updated: 59ca35df4a090bfb9ba4e17504263512e3225eef
by gavento 13 Aug '11
by gavento 13 Aug '11
13 Aug '11
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, generate has been updated
via 59ca35df4a090bfb9ba4e17504263512e3225eef (commit)
from 88d3600064fa5461ea1aeb818349e8b7ab910283 (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/59ca35df4a090bfb9ba4e17504263512e322…
commit 59ca35df4a090bfb9ba4e17504263512e3225eef
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Sat Aug 13 18:16:47 2011 +0200
Make generating python2.4 compatible, add bython binary variable
diff --git a/config.mk b/config.mk
index eb23555..962c414 100644
--- a/config.mk
+++ b/config.mk
@@ -5,5 +5,10 @@ LDLIBS+=-ldl
# path to local module directory
PYLIBSDIR=$(TOPDIR)/pylib
+# Python binary/version
+PYTHON_BIN=python
+# To test with other python versions (example):
+#PYTHON_BIN=${TOPDIR}/virtualpy2.4/bin/python
+
# Command to run Python with pylib/ modules
-PYTHON=PYTHONPATH=$$PYTHONPATH:${PYLIBSDIR} python -Werror
+PYTHON=PYTHONPATH=$$PYTHONPATH:${PYLIBSDIR} ${PYTHON_BIN} -Werror
diff --git a/pylib/gfxprim/gfxprimconfig.py b/pylib/gfxprim/gfxprimconfig.py
index fd9088b..33c03f9 100644
--- a/pylib/gfxprim/gfxprimconfig.py
+++ b/pylib/gfxprim/gfxprimconfig.py
@@ -32,7 +32,8 @@ class GfxPrimConfig(object):
self.pixelsizes = pixelsizes
assert isinstance(self.pixelsizes, list)
assert self.pixel_size in [i.size for i in self.pixelsizes]
- assert all((i.size <= self.pixel_size for i in self.pixelsizes))
+ for i in self.pixelsizes:
+ assert i.size <= self.pixel_size
# Set of all encountered channel names
self.channels = set()
diff --git a/pylib/gfxprim/pixeltype.py b/pylib/gfxprim/pixeltype.py
index e2389a0..fb2744f 100644
--- a/pylib/gfxprim/pixeltype.py
+++ b/pylib/gfxprim/pixeltype.py
@@ -52,7 +52,9 @@ class PixelType(object):
return (self.name == "UNKNOWN")
def is_rgb(self):
- return all((i in self.chans for i in 'RGB'))
+ for i in 'RGB':
+ if i not in self.chans: return False
+ return True
def is_gray(self):
return ('V' in self.chans)
-----------------------------------------------------------------------
Summary of changes:
config.mk | 7 ++++++-
pylib/gfxprim/gfxprimconfig.py | 3 ++-
pylib/gfxprim/pixeltype.py | 4 +++-
3 files changed, 11 insertions(+), 3 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 generate updated: 88d3600064fa5461ea1aeb818349e8b7ab910283
by gavento 13 Aug '11
by gavento 13 Aug '11
13 Aug '11
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, generate has been updated
via 88d3600064fa5461ea1aeb818349e8b7ab910283 (commit)
via d2b4b9318df648e5d8808992883beae29c7d60f7 (commit)
via b887026dd72c650c80b7ad6cbb0b0fb50ad3056f (commit)
via 02fa5eb389d00cf1a270cdb0db51fae380d31d28 (commit)
via bd6e88a5eb71e27afd0f16d24ec008d5d04d9b9e (commit)
from 0acddf9bde07520ba408dbf0772c84d02bc074ba (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/88d3600064fa5461ea1aeb818349e8b7ab91…
commit 88d3600064fa5461ea1aeb818349e8b7ab910283
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Sat Aug 13 18:01:02 2011 +0200
Fix a varname typo
diff --git a/pylib/gfxprim/render_utils.py b/pylib/gfxprim/render_utils.py
index 2be8f46..12e2472 100644
--- a/pylib/gfxprim/render_utils.py
+++ b/pylib/gfxprim/render_utils.py
@@ -36,7 +36,7 @@ def render_file(env, source, result):
try:
source_text = source_file.read()
finally:
- source_text.close()
+ source_file.close()
# Hack to preserve empty lines before %% line_statement
source_text = re.sub("nn[ t]*%%", "n{{''}}n%%", source_text)
@@ -53,7 +53,7 @@ def render_file(env, source, result):
try:
result_file.write(result_text)
finally:
- resulf_file.close()
+ result_file.close()
def load_gfxprimconfig(config_file = None):
http://repo.or.cz/w/gfxprim.git/commit/d2b4b9318df648e5d8808992883beae29c7d…
commit d2b4b9318df648e5d8808992883beae29c7d60f7
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Sat Aug 13 17:26:01 2011 +0200
Remove "with .. as" statement from .py
diff --git a/pylib/gfxprim/render_utils.py b/pylib/gfxprim/render_utils.py
index 6c3d430..2be8f46 100644
--- a/pylib/gfxprim/render_utils.py
+++ b/pylib/gfxprim/render_utils.py
@@ -32,8 +32,11 @@ def create_environment(config, template_dir):
def render_file(env, source, result):
- with open(source) as source_file:
+ source_file = open(source)
+ try:
source_text = source_file.read()
+ finally:
+ source_text.close()
# Hack to preserve empty lines before %% line_statement
source_text = re.sub("nn[ t]*%%", "n{{''}}n%%", source_text)
@@ -46,8 +49,11 @@ def render_file(env, source, result):
header_guard = os.path.split(result)[1].upper().replace('.', '_').replace('-', '_'),
)
- with open(result, "w") as result_file:
+ result_file = open(result, "w")
+ try:
result_file.write(result_text)
+ finally:
+ resulf_file.close()
def load_gfxprimconfig(config_file = None):
http://repo.or.cz/w/gfxprim.git/commit/b887026dd72c650c80b7ad6cbb0b0fb50ad3…
commit b887026dd72c650c80b7ad6cbb0b0fb50ad3056f
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Sat Aug 13 17:22:59 2011 +0200
Add filename info to template generation
diff --git a/pylib/gfxprim/render_utils.py b/pylib/gfxprim/render_utils.py
index e383619..6c3d430 100644
--- a/pylib/gfxprim/render_utils.py
+++ b/pylib/gfxprim/render_utils.py
@@ -21,7 +21,7 @@ def create_environment(config, template_dir):
env.globals['pixelsizes'] = config.pixelsizes
env.globals['pixeltypes'] = config.pixeltypes
env.globals['pixeltypes_dict'] = config.pixeltypes_dict
- env.globals['gfxprim_config'] = config
+ env.globals['config'] = config
from gfxprim.pixelsize import LE, BE
env.globals['LE'] = LE
env.globals['BE'] = BE
@@ -38,6 +38,7 @@ def render_file(env, source, result):
source_text = re.sub("nn[ t]*%%", "n{{''}}n%%", source_text)
tmpl = env.from_string(source_text)
+ tmpl.filename = source
result_text = tmpl.render(
date = time.ctime(),
target = result,
http://repo.or.cz/w/gfxprim.git/commit/02fa5eb389d00cf1a270cdb0db51fae380d3…
commit 02fa5eb389d00cf1a270cdb0db51fae380d31d28
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Sat Aug 13 17:22:10 2011 +0200
Remove a float division causing a DeprecationWarning
diff --git a/include/core/GP_Convert_Scale.gen.h.t b/include/core/GP_Convert_Scale.gen.h.t
index 86c43b0..c358576 100644
--- a/include/core/GP_Convert_Scale.gen.h.t
+++ b/include/core/GP_Convert_Scale.gen.h.t
@@ -3,7 +3,7 @@
{% block descr %}Fast value scaling macros{% endblock %}
{% macro multcoef(s1, s2) -%}
-(0{% for i in range((s2+s1-1)/s1) %}+{{ 2**(i*s1) }}{% endfor %})
+(0{% for i in range((s2 + s1 - 1) // s1) %}+{{ 2 ** (i * s1) }}{% endfor %})
{%- endmacro %}
%% block body
http://repo.or.cz/w/gfxprim.git/commit/bd6e88a5eb71e27afd0f16d24ec008d5d04d…
commit bd6e88a5eb71e27afd0f16d24ec008d5d04d9b9e
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Sat Aug 13 17:21:07 2011 +0200
Make Python warnings in code generation errors
diff --git a/config.mk b/config.mk
index d9a784d..eb23555 100644
--- a/config.mk
+++ b/config.mk
@@ -6,4 +6,4 @@ LDLIBS+=-ldl
PYLIBSDIR=$(TOPDIR)/pylib
# Command to run Python with pylib/ modules
-PYTHON=PYTHONPATH=$$PYTHONPATH:${PYLIBSDIR} python
+PYTHON=PYTHONPATH=$$PYTHONPATH:${PYLIBSDIR} python -Werror
-----------------------------------------------------------------------
Summary of changes:
config.mk | 2 +-
include/core/GP_Convert_Scale.gen.h.t | 2 +-
pylib/gfxprim/render_utils.py | 13 ++++++++++---
3 files changed, 12 insertions(+), 5 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 generate updated: 0acddf9bde07520ba408dbf0772c84d02bc074ba
by gavento 08 Aug '11
by gavento 08 Aug '11
08 Aug '11
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, generate has been updated
via 0acddf9bde07520ba408dbf0772c84d02bc074ba (commit)
via cb0e0b9b7a723b92deb33de3dab9f0077e69be0b (commit)
via ffa0e5910b52a5fe361e1bc5753665fec90a8db4 (commit)
via cfe11b6f6f3c41d3ff6c18d90efdd2615a5e858a (commit)
via 35f5e233c07862deeb53bdf9407e2f83eaa15887 (commit)
via 7ab0524f10cef16426c70802884bee6cda23d116 (commit)
via 89d7a5aa051caddcd3d17d27e17d7d4f4b9661fa (commit)
via 938956d49a3627c5fe31c4fcf2ceeae5877fd11b (commit)
via 58f99bbee8cf3eac5142540013c8309267b8f55d (commit)
via 27781b18ae400421700a31d6b1ed37d836c47f22 (commit)
from 1cd5016b247b64d2d0b7b7c6791d5f730248ec64 (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/0acddf9bde07520ba408dbf0772c84d02bc0…
commit 0acddf9bde07520ba408dbf0772c84d02bc074ba
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Mon Aug 8 14:06:16 2011 +0200
Update generating scripts
diff --git a/gen.mk b/gen.mk
index c5586c6..41ad5f5 100644
--- a/gen.mk
+++ b/gen.mk
@@ -37,14 +37,15 @@ TEMPLATE_DIR=$(TOPDIR)/pylib/templates/
#
# ALL templates and potential generated files (not generated automatically)
-#
+# NOTE: Currently unused
+#
ALL_TEMPLATES=$(shell find $(TOPDIR) -name '*.t')
ALL_GENERATED=$(basename $(ALL_TEMPLATES))
#
# And clean them
#
-CLEAN+=$(ALL_GENERATED)
+CLEAN+=$(GENSOURCES) $(RGENHEADERS)
#
# Generated files depend on python generators and the template
diff --git a/pylib/bin/generate_file.py b/pylib/bin/generate_file.py
index bd0ddf1..b8b6b12 100644
--- a/pylib/bin/generate_file.py
+++ b/pylib/bin/generate_file.py
@@ -22,7 +22,8 @@ def main(options, args):
config = render_utils.load_gfxprimconfig(options.config)
assert config
log.info("Rendering template %s to %s", args[0], args[1])
- render_utils.render_file(args[0], args[1], config, options.templates)
+ env = render_utils.create_environment(config, options.templates)
+ render_utils.render_file(env, args[0], args[1])
if __name__ == '__main__':
diff --git a/pylib/gfxprim/render_utils.py b/pylib/gfxprim/render_utils.py
index a9590e0..e383619 100644
--- a/pylib/gfxprim/render_utils.py
+++ b/pylib/gfxprim/render_utils.py
@@ -31,8 +31,7 @@ def create_environment(config, template_dir):
return env
-def render_file(source, result, config, template_dir):
- env = create_environment(config, template_dir)
+def render_file(env, source, result):
with open(source) as source_file:
source_text = source_file.read()
# Hack to preserve empty lines before %% line_statement
http://repo.or.cz/w/gfxprim.git/commit/cb0e0b9b7a723b92deb33de3dab9f0077e69…
commit cb0e0b9b7a723b92deb33de3dab9f0077e69be0b
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Mon Aug 8 14:05:41 2011 +0200
Move test generation to template system, cleanup
diff --git a/pylib/bin/generate_collected_tests.py b/pylib/bin/generate_collected_tests.py
new file mode 100644
index 0000000..4038bd8
--- /dev/null
+++ b/pylib/bin/generate_collected_tests.py
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+#
+# Script generating collected_tests.gen.c
+#
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+#
+
+from gfxprim import render_utils, test_collection
+import jinja2
+import logging as log
+from optparse import OptionParser
+
+template_file = "collected_tests.c.t"
+
+parser = OptionParser(usage="usage: %prog [options] <scan_dir> <output_file>")
+parser.add_option("-t", "--templates", dest="templates",
+ help="Directory with templates.", default=".")
+parser.add_option("-c", "--config", dest="config",
+ help="GfxPrim config file.", default=None)
+
+def main(options, args):
+ config = render_utils.load_gfxprimconfig(options.config)
+ assert config
+ log.info("Scanning dir %s for tests, generating %s", args[0], args[1])
+ env = render_utils.create_environment(config, options.templates)
+ env.globals['suites'] = test_collection.collect_suites(args[0])
+ render_utils.render_file(env, options.templates + '/' + template_file, args[1])
+
+
+if __name__ == '__main__':
+ log.debug("Jinja version %s", jinja2.__version__)
+ (options, args) = parser.parse_args()
+ if len(args) != 2:
+ parser.error()
+ main(options, args)
diff --git a/pylib/gfxprim/generators/__init__.py b/pylib/gfxprim/generators/__init__.py
deleted file mode 100644
index 431c9ef..0000000
--- a/pylib/gfxprim/generators/__init__.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# gfxprim.generate - global config and its loading
-#
-
-import os
-import sys
-
-# Global config instance
-
-config = None
-
-
-def load_gfxprim_config(config_file = None):
- """Initialize GfxPrimConfig from a given or guessed config file.
- Looks for the file by parameter, in env['PIXELTYPE_DEFS'] and
- in dir(__file__)/../../../gfxprim_config.py, in that order.
- """
-
- if not config_file:
- config_file = os.environ.get("PIXELTYPE_DEFS", None)
- if not config_file:
- path = os.path.dirname(os.path.abspath(__file__))
- config_file = os.path.abspath(
- os.path.join(path, "..", "..", "..", "gfxprim_config.py"))
- if not os.path.exists(config_file):
- sys.stderr.write("WARNING: GfxPrimConfig file %s not found!n" %
- config_file)
-
- global config
- assert not config
- from gfxprim.generators.pixeltype import PixelType
- from gfxprim.generators.gfxprimconfig import GfxPrimConfig
- l = {"PixelType": PixelType, "GfxPrimConfig": GfxPrimConfig}
- execfile(config_file, globals(), l)
- config = l["config"]
- assert config
diff --git a/pylib/gfxprim/generators/core/__init__.py b/pylib/gfxprim/generators/core/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/pylib/gfxprim/generators/core/gen_blit.py b/pylib/gfxprim/generators/core/gen_blit.py
deleted file mode 100644
index 0e3196b..0000000
--- a/pylib/gfxprim/generators/core/gen_blit.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# Module generating C source and headers for various PixelTypes
-# - submodule for blit and friends
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
-
-from gfxprim.generators.utils import *
-
-
-## all generated direct blits, for generating GP_Blit() and others
-generated_blits = []
-
-
-# TODO: adapt for both bit-endianness (in-byte prefix and suffix)
-# WARN: assuming little-endian in sub-byte pixels order (probably)
-def gen_blit_same_t(size, size_suffix, header, code):
- """Generate a function blitting the same type of pixel.
- Only depends on bpp (bit size), size_suffix must be
- of form 8BPP, 2BPP_LE and the like.
- """
-
- header.rbody(
- "n/*** Blit preserving type, variant for {{ size_suffix }} ***n"
- " * Assumes the contexts to be of the right types and sizesn"
- " * Ignores transformations and clipping */nn"
- "void GP_Blit_{{ size_suffix }}(const GP_Context *c1, GP_Coord x1, GP_Coord y1, GP_Size w, GP_Size h,n"
- " GP_Context *c2, GP_Coord x2, GP_Coord y2);n",
- size=size, size_suffix=size_suffix)
-
- code.rbody(
- "n/*** Blit preservimg type, variant for {{ size_suffix }} ***/n"
- "void GP_Blit_{{ size_suffix }}(const GP_Context *c1, GP_Coord x1, GP_Coord y1, GP_Size w, GP_Size h,n"
- " GP_Context *c2, GP_Coord x2, GP_Coord y2)n"
- "{n"
- " if (unlikely(w == 0 || h == 0)) return;nn"
- " /* Special case - copy whole line-block with one memcpy() */n"
- " if ((x1 == 0) && (x2 == 0) && (w == c1->w) && (c1->w == c2->w) &&n"
- " (c1->bytes_per_row == c2->bytes_per_row)) {n"
- " memcpy(c2->pixels + c2->bytes_per_row * y2,n"
- " c1->pixels + c1->bytes_per_row * y1,n"
- " c1->bytes_per_row * h);n"
- " return;n"
- " }nn"
- "{% if size>=8 %}"
- " /* General case - memcpy() each horizontal line */n"
- " for (GP_Size i = 0; i < h; i++)n"
- " memcpy(GP_PIXEL_ADDR_{{ size_suffix }}(c2, x2, y2 + i), n"
- " GP_PIXEL_ADDR_{{ size_suffix }}(c1, x2, y2 + i),n"
- " {{ size/8 }} * w);n"
- "{% else %}" # subtle - rectangles may not be byte aligned in the same way
- " /* Alignment (index) of first bits in the first byte */n"
- " int al1 = GP_PIXEL_ADDR_OFFSET_{{ size_suffix }}(x1);n"
- " int al2 = GP_PIXEL_ADDR_OFFSET_{{ size_suffix }}(x2);n"
- " /* Special case of the same alignment and width >=2 bytes */n"
- " if ((al1 == al2) && (w * {{ size }} >= 16)) {n"
- " /* Number of bits in the last partial byte */n"
- " int end_al = GP_PIXEL_ADDR_OFFSET_{{ size_suffix }}(x1 + w);n"
- " GP_ASSERT(({{ size }} * w - al1 - end_al) % 8 == 0);n"
- " int copy_size = ({{ size }} * w - al1 - end_al) / 8;n"
- " /* First and last byte incident to the line */n"
- " uint8_t *p1 = GP_PIXEL_ADDR_{{ size_suffix }}(c1, x1, y1);n"
- " uint8_t *p2 = GP_PIXEL_ADDR_{{ size_suffix }}(c2, x2, y2);n"
- " uint8_t *end_p1 = GP_PIXEL_ADDR_{{ size_suffix }}(c1, x1 + w - 1, y1);n"
- " uint8_t *end_p2 = GP_PIXEL_ADDR_{{ size_suffix }}(c2, x2 + w - 1, y2);n"
- " for (GP_Size i = 0; i < h; i++) {n"
- " if (al1 != 0)n"
- " GP_SET_BITS(al1, 8-al1, *p2, GP_GET_BITS(al1, 8-al1, *p1));n"
- " memcpy(p2+(al1!=0), p1+(al1!=0), copy_size);n"
- " if (end_al != 0)n"
- " GP_SET_BITS(0, end_al, *end_p2, GP_GET_BITS(0, end_al, *end_p1));n"
- " p1 += c1->bytes_per_row;n"
- " end_p1 += c1->bytes_per_row;n"
- " p2 += c2->bytes_per_row;n"
- " end_p2 += c2->bytes_per_row;n"
- " }n"
- " } else /* Different bit-alignment, can't use memcpy() */n"
- " GP_Blit_Naive(c1, x1, y1, w, h, c2, x2, y2);n"
- "{% endif %}"
- "}n", size=size, size_suffix=size_suffix)
-
diff --git a/pylib/gfxprim/generators/core/gen_convert.py b/pylib/gfxprim/generators/core/gen_convert.py
deleted file mode 100644
index f128824..0000000
--- a/pylib/gfxprim/generators/core/gen_convert.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# Module generating C source and headers for various PixelType conversions
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
-
-from gfxprim.generators.pixeltype import pixeltypes, channels
-from gfxprim.generators.utils import hmask
-
-def gen_fixedtype_to_type(fixedtype, header, code):
- "Generate functions converting a fixed PixelType to any other"
- "Does not work on palette types at all (yet)"
- code.rbody(
- "GP_Pixel GP_{{ f.name }}ToPixel(GP_Pixel pixel, GP_PixelType type)n"
- "{n"
- " GP_Pixel p = 0;n"
- " switch(type) {n"
- "{% for tf in types %}"
- "{% if tf.number == 0 %}"
- " case GP_PIXEL_UNKNOWN:n"
- " GP_ABORT("Cannot convert to GP_PIXEL_UNKNOWN");n"
- " break;n"
- "{% elif tf.is_palette() %}"
- " case GP_PIXEL_{{ tf.name }}:n"
- " GP_ABORT("Cannot convert to palette type {{ tf.name }}");n"
- " break;n"
- "{% else %}"
- " case GP_PIXEL_{{ tf.name }}:n"
- " GP_Pixel_{{ f.name }}_TO_{{ tf.name }}(pixel, p);n"
- " break;n"
- "{% endif %}"
- "{% endfor %}"
- " default:n"
- " GP_ABORT("Unknown PixelType %ud", type);n"
- " }n"
- " return p;n"
- "}nn", f=fixedtype, types=pixeltypes.values())
-
-def gen_type_to_fixedtype(fixedtype, header, code):
- "Generate functions converting to a fixed PixelType from any other"
- "Does not work on palette types at all (yet)"
- code.rbody(
- "GP_Pixel GP_PixelTo{{ f.name }}(GP_Pixel pixel, GP_PixelType type)n"
- "{n"
- " GP_Pixel p = 0;n"
- " switch(type) {n"
- "{% for sf in types %}"
- "{% if sf.number == 0 %}"
- " case GP_PIXEL_UNKNOWN:n"
- " GP_ABORT("Cannot convert from GP_PIXEL_UNKNOWN");n"
- " break;n"
- "{% elif sf.is_palette() %}"
- " case GP_PIXEL_{{ sf.name }}:n"
- " GP_ABORT("Cannot convert from palette type {{ sf.name }} (yet)");n"
- " break;n"
- "{% else %}"
- " case GP_PIXEL_{{ sf.name }}:n"
- " GP_Pixel_{{ sf.name }}_TO_{{ f.name }}(pixel, p);n"
- " break;n"
- "{% endif %}"
- "{% endfor %}"
- " default:n"
- " GP_ABORT("Unknown PixelType %u", type);n"
- " }n"
- " return p;n"
- "}nn", f=fixedtype, types=pixeltypes.values())
-
-def gen_convert_to(f1, f2, header, code):
- "Generate a macro converting from f1 to f2"
- "This function supports only RGBVA types (no palettes"
- allowed_chansets = [ set(list(s)) for s in ['RGB', 'RGBA', 'V', 'VA'] ]
- assert(set(f1.chans.keys()) in allowed_chansets)
- assert(set(f2.chans.keys()) in allowed_chansets)
-
- header.rbody(
- "n/*** {{ f1.name }} -> {{ f2.name }} ***n"
- " * macro storing p1 ({{ f1.name }} at bit-offset o1) in p2 ({{ f2.name }} at bit-offset o2),n"
- " * the relevant part of p2 is assumed to be clear (zero) */nn"
- "#define GP_Pixel_{{ f1.name }}_TO_{{ f2.name }}_OFFSET(p1, o1, p2, o2) do {
"
-
- ## set each of <TARGET> channels
- "{% for c2 in f2.chanslist %}"
-
- # case 1: just copy a channel
- "{%- if c2[0] in f1.chans.keys() %}{% set c1 = f1.chans[c2[0]] %}"
- " /* {{ c2[0] }}:={{ c1[0] }} */ GP_SET_BITS({{c2[1]}}+o2, {{c2[2]}}, p2,
"
- " GP_SCALE_VAL_{{c1[2]}}_{{c2[2]}}(GP_GET_BITS({{c1[1]}}+o1, {{c1[2]}}, p1)));
"
-
- # case 2: set A to full opacity (not present in source)
- "{% elif c2[0]=='A' %}"
- " /* A:={{ hmask(c2[2]) }} */GP_SET_BITS({{c2[1]}}+o2, {{c2[2]}}, p2, {{ hmask(c2[2]) }});
"
-
- # case 3: calculate V as average of RGB
- "{% elif c2[0]=='V' and set('RGB').issubset(set(f1.chans.keys())) %}"
- " /* V:=RGB_avg */ GP_SET_BITS({{c2[1]}}+o2, {{c2[2]}}, p2, (
"
- "{% for c1 in [f1.chans['R'], f1.chans['G'], f1.chans['B']] %}"
- " /* {{c1[0]}} */ GP_SCALE_VAL_{{c1[2]}}_{{c2[2]}}(GP_GET_BITS({{c1[1]}}+o1, {{c1[2]}}, p1)) +
"
- "{% endfor %}"
- " 0)/3);
"
-
- #- case 4: set each RGB to V
- "{% elif c2[0] in 'RGB' and 'V' in f1.chans.keys() %}{% set c1 = f1.chans['V'] %}"
- " /* {{ c2[0] }}:=V */ GP_SET_BITS({{c2[1]}}+o2, {{c2[2]}}, p2,
"
- " GP_SCALE_VAL_{{c1[2]}}_{{c2[2]}}(GP_GET_BITS({{c1[1]}}+o1, {{c1[2]}}, p1)));
"
-
- # invalid mapping (there should be none, but who knows ...)
- "{% else %} {{ raise(Error('channel conversion' +f1.name+ ' to ' +f2.name+ ' not supported')) }}"
-
- # end of the loop
- "{% endif %}"
- "{% endfor %}"
- "} while (0)nn"
-
- # add version without offsets
- "/* a version without offsets */n"
- "#define GP_Pixel_{{ f1.name }}_TO_{{ f2.name }}(p1, p2) "
- "GP_Pixel_{{ f1.name }}_TO_{{ f2.name }}_OFFSET(p1, 0, p2, 0)n",
- f1=f1, f2=f2, hmask=hmask, set=set)
-
diff --git a/pylib/gfxprim/generators/core/gen_getputpixel.py b/pylib/gfxprim/generators/core/gen_getputpixel.py
deleted file mode 100644
index 14e455d..0000000
--- a/pylib/gfxprim/generators/core/gen_getputpixel.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Module generating C source and headers for get/putpixel
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
-# 2011 - Cyril Hrubis <metan(a)ucw.cz>
-
-from gfxprim.generators.utils import *
-
-def gen_get_pixel_addr_bpp(size, size_suffix, header):
- "Generate GP_PIXEL_ADDR_<size_suffix> and _OFFSET_<size_suffix> macros"
- bit_endian = size_suffix[-2:]
- if size < 8:
- assert bit_endian in ['LE', 'BE']
- header.rbody(
- "/* macro to get address of pixel in a {{ size_suffix }} context */n"
- "#define GP_PIXEL_ADDR_{{ size_suffix }}(context, x, y)
"
- " ((context)->pixels + (context)->bytes_per_row * (y) + {{ size//8 }} * (x))n"
- "/* macro to get bit-offset of pixel in {{ size_suffix }} context */n"
- "{% if size >= 8 %}"
- "#define GP_PIXEL_ADDR_OFFSET_{{ size_suffix }}(x) (0)n"
- "{% else %}" # bit_endian matters
- "{% if bit_endian=='LE' %}"
- "#define GP_PIXEL_ADDR_OFFSET_{{ size_suffix }}(x)
"
- " (((x) % {{ 8//size }}) * {{ size }})n"
- "{% else %}"
- "#define GP_PIXEL_ADDR_OFFSET_{{ size_suffix }}(x)
"
- " ({{ 8-size }} - ((x) % {{ 8//size }}) * {{ size }})n"
- "{% endif %}"
- "{% endif %}",
- size=size, size_suffix=size_suffix, bit_endian=bit_endian)
-
-def gen_getpixel_bpp(size, size_suffix, header):
- "Generate code for GetPixel_Raw_xBPP, no clipping or transform. "
- "Only depends on bpp (bit size), size_suffix must be "
- "of form 8BPP, 2BPP_LE and the like."
- header.rbody(
- "n/*** GP_GetPixel for {{ size_suffix }} ***/n"
- "static inline GP_Pixel GP_GetPixel_Raw_{{ size_suffix }}(const GP_Context *c, int x, int y)n"
- "{n"
- " return GP_GET_BITS(GP_PIXEL_ADDR_OFFSET_{{ size_suffix }}(x), {{ size }},n"
- " *(GP_PIXEL_ADDR_{{ size_suffix}}(c, x, y)));n"
- "}nn", size=size, size_suffix=size_suffix)
-
-def gen_putpixel_bpp(size, size_suffix, header):
- "Generate code for PutPixel_Raw_xBPP, no clipping or transform. "
- "Only depends on bpp (bit size), size_suffix must be "
- "of form 8BPP, 2BPP_LE and the like."
- header.rbody(
- "n/*** GP_PutPixel for {{ size_suffix }} ***/n"
- "static inline void GP_PutPixel_Raw_{{ size_suffix }}(GP_Context *c, int x, int y, GP_Pixel p)n"
- "{n"
- " GP_SET_BITS(GP_PIXEL_ADDR_OFFSET_{{ size_suffix }}(x) , {{ size }},n"
- " *(GP_PIXEL_ADDR_{{ size_suffix}}(c, x, y)), p);n"
- "}nn", size=size, size_suffix=size_suffix)
diff --git a/pylib/gfxprim/generators/core/gen_pixeltype.py b/pylib/gfxprim/generators/core/gen_pixeltype.py
deleted file mode 100644
index 942a1a2..0000000
--- a/pylib/gfxprim/generators/core/gen_pixeltype.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# Module generating C source and headers for various PixelTypes
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
-
-from gfxprim.generators.pixeltype import pixeltypes, channels
-from gfxprim.generators.utils import j2render as r, hmask
-
-
-def str_start(ptype):
- "Return a visual separator starting `ptype`-related defs"
- return ("n/*************************************************************n"
- " * Pixel type " + ptype.name + "n */n")
-
-def str_description(ptype):
- "Return a short C comment describing the PixelType"
- return r(
- "/* Automatically generated code for pixel type {{ f.name }}n"
- " *n"
- " * Size (bpp): {{ f.size }} ({{ f.size_suffix }})n"
- "{% if f.size<8 %} * Bit endian: {{ f.bit_endian }}n{% endif %}"
- " * Pixel structure: {{ ''.join(f.bits) }}n"
- " * Channels: n"
- "{% for c in f.chanslist %}"
- " * {{ c[0] }} offset:{{ c[1] }} size:{{ c[2] }}n"
- "{% endfor %}"
- " */n", f=ptype)
-
-def gen_GP_PixelType(header, code):
- "Generates definition of GP_PixelType enum"
- pt_by_num = sorted([(t.number, t) for t in pixeltypes.values()])
- sorted_pts = [t[1] for t in pt_by_num]
- pt_max = len(sorted_pts)
- header.rbody(
- "/* List of all known pixel types */n"
- "typedef enum GP_PixelType {n"
- "{% for t in sorted_pts %}"
- " GP_PIXEL_{{ t.name }} = {{ t.number }},n"
- "{% endfor %}"
- " GP_PIXEL_MAX = {{ pt_max }},n"
- "} GP_PixelType;n", sorted_pts=sorted_pts, pt_max=pt_max)
-
-def gen_GP_PixelTypes(header, code):
- "Generate the const structure GP_PixelTypes describing all the PixelTypes"
- pt_by_num = sorted([(t.number, t) for t in pixeltypes.values()])
- sorted_pts = [t[1] for t in pt_by_num]
- code.rbody(
- "/* Description of all known pixel types */n"
- "const GP_PixelTypeDescription const GP_PixelTypes [] = {n"
- "{% for t in sorted_pts %}"
- " /* GP_PIXEL_{{ t.name }} */ {n"
- " .type = GP_PIXEL_{{ t.name }},n"
- ' .name = "{{ t.name }}",n'
- ' .size = {{ t.size }},n'
- ' .bit_endian = GP_BIT_ENDIAN_{{ t.bit_endian }},'
- '{% if t.size>=8 %} /* IGNORED for this type */{% endif %}n'
- ' .numchannels = {{ len(t.chanslist) }},n'
- ' .bitmap = "{{ t.bits|join("") }}",n'
- ' .channels = {n'
- '{% for c in t.chanslist %}'
- ' { .name = "{{ c[0] }}", .offset = {{ c[1] }}, .size = {{ c[2] }} },n'
- '{% endfor %}'
- ' } },n'
- '{% endfor %}'
- '};n', sorted_pts=sorted_pts, len=len)
-
-def gen_print(ptype, header, code):
- "Generate a GP_PixelSNPrint_<TYPE> function (source and header)"
- header.rbody(
- "/* snprintf a human readable value of pixel type {{ f.name }} */n"
- "void GP_PixelSNPrint_{{ f.name }}(char *buf, size_t len, GP_Pixel p);n", f=ptype)
- code.rbody(
- "/* snprintf a human readable value of pixel type {{f.name}} */n"
- "void GP_PixelSNPrint_{{ f.name }}(char *buf, size_t len, GP_Pixel p)n"
- "{n"
- ' snprintf(buf, len, "<{{ f.name }} 0x%0{{ (f.size+3)//4 }}x{% for c in f.chanslist %} {{ c[0] }}=%d{% endfor %}>",n'
- " GP_GET_BITS(0, {{ f.size }}, p)"
- "{% for c in f.chanslist %}"
- ",n GP_GET_BITS({{ c[1] }}, {{ c[2] }}, p)"
- "{% endfor %});n"
- "}n", f=ptype)
-
-def gen_get_chs(ptype, header, code):
- "Generate GP_Pixel_GET_<CHAN>_<TYPE> macros"
- header.rbody(
- "/* macros to get channels of pixel type {{ f.name }} */n"
- "{% for c in f.chanslist %}"
- "#define GP_Pixel_GET_{{ c[0] }}_{{ f.name }}(p) (GP_GET_BITS({{ c[1] }}, {{ c[2] }}, (p)))n"
- "{% endfor %}", f=ptype)
-
-def gen_create(ptype, header, code):
- "Generate GP_Pixel_CREATE_<TYPE> macros"
- header.rbody(
- "/* macros to create GP_Pixel of pixel type {{ f.name }} directly from given values.n"
- " * The values are NOT clipped to actual value ranges.*/n"
- "#define GP_Pixel_CREATE_{{ f.name }}({{ args }}) (0
"
- "{% for c in f.chanslist %}"
- " + (({{ c[0] }}) << {{ c[1] }})
"
- "{% endfor %}"
- " )n", f=ptype, args=', '.join([c[0] for c in ptype.chanslist]))
-
-def gen_get_pixel_addr(ptype, header, code):
- "Generate GP_PIXEL_ADDR_<TYPE> and _OFFSET_<TYPE> macros"
- header.rbody(
- "/* macro to get address of pixel {{ f.name }} in a context */n"
- "#define GP_PIXEL_ADDR_{{ f.name }}(context, x, y) GP_PIXEL_ADDR_{{ f.size_suffix }}(context, x, y)n"
- "/* macro to get bit-offset of pixel {{ f.name }} */n"
- "#define GP_PIXEL_ADDR_OFFSET_{{ f.name }}(x)
"
- " GP_PIXEL_ADDR_OFFSET_{{ f.size_suffix }}(x)n",
- f=ptype)
-
diff --git a/pylib/gfxprim/generators/generator.py b/pylib/gfxprim/generators/generator.py
deleted file mode 100644
index ca6df56..0000000
--- a/pylib/gfxprim/generators/generator.py
+++ /dev/null
@@ -1,151 +0,0 @@
-#
-# gfxprim.generators.generator - Base and C (.c/.h) classes for code generators
-#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
-#
-
-import os
-import time
-import logging as log
-from gfxprim.generators.utils import j2render
-
-
-# List of known CodeGenerator instances
-
-known_generators = []
-
-
-class CodeGenerator(object):
- """Args:
- fname (required) - name of the generated file (without path)
- fdir ('') - directory prefix to match
- generating_f (None) - user function called in generate(), should generate content
- register (False) - if true, register in global generator list
- """
- generator_attributes__ = ['generating_f', 'register']
-
- def __init__(self, **kwargs):
- self.name = kwargs.pop('name')
- self.fdir, self.fname = os.path.split(self.name)
- self.generating_f = None
- self.register = False
- self.head = []
- self.body = []
- self.foot = []
- self.setargs(**kwargs)
- if kwargs:
- log.fatal('Unknown arguments to CodeGenerator: %s' % str(kwargs.keys()))
-
- def setargs(self, **kwargs):
- for i in self.generator_attributes__:
- if i in kwargs:
- self.__setattr__(i, kwargs.pop(i))
-
- def matches_path(self, path):
- return path.endswith(self.name)
-
- def r(self, s, *args, **kwargs):
- return j2render(s, g=self, *args, **kwargs)
-
- def rhead(self, *args, **kwargs):
- self.head.append(self.r(*args, **kwargs))
-
- def rbody(self, *args, **kwargs):
- self.body.append(self.r(*args, **kwargs))
-
- def rfoot(self, *args, **kwargs):
- self.foot.append(self.r(*args, **kwargs))
-
- def generate(self, run_gen_base=True):
- self.head = []
- self.body = []
- self.foot = []
- if run_gen_base:
- self.gen_base()
- # Run user-specified generation f
- if self.generating_f:
- f, pos, params = self.generating_f
- args = [self if i == pos else global_null_generator
- for i in range(params)]
- f(*args)
- return ''.join(self.head + self.body + self.foot)
-
- def gen_base(self):
- "Fill basic subclass-dependent content into head/body/foot"
- pass
-
-
-class NullGenerator(CodeGenerator):
- def rhead(self, *args, **kwargs): pass
- def rbody(self, *args, **kwargs): pass
- def rfoot(self, *args, **kwargs): pass
- def generate(self, *args, **kwargs): return ''
- def r(self, *args, **kwargs): return ''
-
-global_null_generator = NullGenerator(name='null_generator')
-
-
-class CCodeGenerator(CodeGenerator):
- """Args:
- authors ([]) - list of author credits
- descr ("") - (multiline) file description
- """
- generator_attributes__ = (['authors', 'descr'] +
- CodeGenerator.generator_attributes__)
-
- def __init__(self, **kwargs):
- self.authors = []
- self.descr = ""
- super(CCodeGenerator, self).__init__(**kwargs)
-
- def gen_base(self):
- super(CCodeGenerator, self).gen_base()
- self.head.append(self.r(
- "/*n"
- " * {{ g.fname }}n"
- " *n"
- " * GENERATED on {{ date }} by generator "{{ g.name }}"n"
- " * DO NOT MODIFY THIS FILE DIRECTLY!n"
- " *n"
- "{% if g.descr %}"
- " * {{ g.descr }}n *n"
- "{% endif %}"
- "{% for a in g.authors %}"
- " * {{ a }}n"
- "{% endfor %}"
- " */nn", date = time.ctime()))
-
-
-class CSourceGenerator(CCodeGenerator):
- def __init__(self, **kwargs):
- super(CSourceGenerator, self).__init__(**kwargs)
-
-
-class CHeaderGenerator(CCodeGenerator):
- def __init__(self, **kwargs):
- super(CHeaderGenerator, self).__init__(**kwargs)
- self.hdef = ('GP_HEADER_' +
- self.name.replace('.', '_').replace('/', '_').upper())
-
- def gen_base(self):
- super(CHeaderGenerator, self).gen_base()
- self.head.append(self.r(
- "#ifndef {{ g.hdef }}n"
- "#define {{ g.hdef }}nn"))
- self.foot.append(self.r(
- "#endif /* {{ g.hdef }} */n"))
-
-
-def generator(*args, **kwargs):
- """Decorate functions to be content-creator for given generators.
- By default also registers the generator to pool of known generators.
- """
- register = kwargs.pop('register', True)
- def decorate(f):
- for i in range(len(args)):
- kwargs['generating_f'] = (f, i, len(args))
- args[i].setargs(**kwargs)
- if register:
- known_generators.append(args[i])
- return f
- return decorate
diff --git a/pylib/gfxprim/generators/make_collected_tests.py b/pylib/gfxprim/generators/make_collected_tests.py
deleted file mode 100644
index 04af1eb..0000000
--- a/pylib/gfxprim/generators/make_collected_tests.py
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/usr/bin/python
-#
-# Script generating collected_tests.gen.c
-#
-# Scrapes the target directory for .test.c files, looks for
-# GP_TEST and GP_SUITE macros and generates code creating all the
-# tests and the suite
-#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
-#
-
-
-# Also fixed in tests.mk
-collected_tests_file = 'collected_tests.gen.c'
-
-import os
-import re
-import glob
-import logging as log
-from gfxprim.generators.generator import *
-
-
-def warn(msg, fname=None, line=None):
- "Warning including file and line info"
- assert fname
- loc = "[%s] " % fname
- if line:
- loc = "[%s:%d] " % (fname, line)
- log.warning(loc + msg)
-
-
-testfile_patterns = ['*.test.c', '*.test.gen.c']
-
-# {"suitename":["testname":{test_parameters}]}
-suites = {}
-
-suite_re = re.compile("A\s*GP_SUITE\((.*)\)\s*Z")
-test_re = re.compile("A\s*GP_TEST\((.*)\)\s*Z")
-
-
-@generator(CHeaderGenerator(name = collected_tests_file),
- descr = 'Code creating the tests and suites for tests collected '
- 'from .test.c files',
- authors = ["2011 - Tomas Gavenciak <gavento(a)ucw.cz>"])
-def tests_collected_tests(c):
- fnames = []
- for pat in testfile_patterns:
- fnames += glob.fnmatch.filter(os.listdir(c.fdir or '.'), pat)
- for fn in fnames:
- dirfn = os.path.join(c.fdir, fn)
- with open(dirfn, 'rt') as f:
- find_tests(f, fn)
- if not fnames:
- warn('No .test.c files found in "%s".' % c.fdir)
- if not suites:
- warn('No suites found, generating empty testsuite.')
-
- c.rhead("#include <check.h>nn")
-
- for suite, tests in suites.iteritems():
- c.rbody(
- "/****************************************************************n"
- " * Suite {{ suite }}n"
- " */nn", suite=suite)
- for t in tests:
- assert ('loop_start' in t) == ('loop_end' in t)
- c.rbody(
- "/*n"
- " * Test {{ suite }}/{{ t['name'] }} defined in {{ t['fname'] }}:{{ t['line'] }}n"
- " */nn"
- "void GP_TEST_{{ t['name'] }}(int);nn"
- "TCase *GP_TC_{{ suite }}_{{ t['name'] }}() {n"
- " TCase *tc = tcase_create("{{ t['name'] }}");n"
- " _tcase_add_test(tc, GP_TEST_{{ t['name'] }}, "{{ t['name'] }}", "
- "{{ t.get('expect_signal', 0) }}, {{ t.get('expect_exit', 0) }}, "
- "{{ t.get('loop_start', 0) }}, {{ t.get('loop_end', 1) }});n"
- " return tc;n}nn", t=t, suite=suite)
- # TODO: Handle special test requirements (timing, fixture, ...)
-
- c.rbody(
- "Suite *GP_TS_{{ suite }}() {n"
- " Suite *s = suite_create("{{ suite }}");n"
- "{% for t in tests %}"
- " suite_add_tcase(s, GP_TC_{{ suite }}_{{ t['name'] }}());n"
- "{% endfor %}"
- " return s;n}nn", tests=tests, suite=suite)
-
- # Once for all suites
- c.rbody(
- "/****************************************************************n"
- " * Create and add all suites to a SRunnern"
- " */nn"
- "void GP_AddSuitesToSRunner(SRunner *sr) {n"
- "{% for s in suites %}"
- " srunner_add_suite(sr, GP_TS_{{ s }}());n"
- "{% endfor %}"
- "}nn", suites=suites)
-
-
-def find_GP_directive(name, regexp, l, fname='unknown', line=0):
- "Looks for a given GP_* directive, parses args if any, "
- "retuns (name, dict_of_args) or (None, None) if not found."
- if name in l:
- m = regexp.search(l)
- if not m:
- warn("found unsuitable %s directive, ignoring." % name, fname, line)
- else:
- d = m.groups()[0].split(',', 1)
- args = {}
- if len(d)>1:
- try:
- s = 'dict( ' + d[1].strip(" tn"") + ' )'
- args = eval(s)
- except:
- log.fatal("error parsing arguments: %r" % s, fname, line)
- return d[0].strip(), args
- return None, None
-
-
-def find_tests(f, fname):
- "Finds all tests in a file."
- suite = None
- ls = f.readlines()
- for i in range(len(ls)):
- l = ls[i]
- # Look for suite declaration
- name, args = find_GP_directive("GP_SUITE", suite_re, l, fname=fname, line=i)
- if name:
- suite = name
- if args:
- warn("suite should have no arguments other than name.", fname, i)
- suites.setdefault(name, [])
- # Look for suite declaration
- name, args = find_GP_directive("GP_TEST", test_re, l, fname=fname, line=i)
- if name:
- test_suite = suite
- if 'suite' in args:
- test_suite = args['suite']
- if not test_suite:
- test_suite = 'default'
- warn("no suite defined before test %s, using %r." % (name, test_suite), fname, i)
- args['name'] = name
- args['fname'] = fname
- args['line'] = i
- suites.setdefault(test_suite, [])
- suites[test_suite].append(args)
-
diff --git a/pylib/gfxprim/generators/utils.py b/pylib/gfxprim/generators/utils.py
deleted file mode 100644
index 15d7013..0000000
--- a/pylib/gfxprim/generators/utils.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# gfxprim.generators.utils - Module with templates and tools for writing
-# generated code, especially C source and headers.
-#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
-#
-
-
-import jinja2
-import logging as log
-
-def j2render(tmpl, **kw):
- "Internal helper to render jinja2 templates (with StrictUndefined)"
- t2 = tmpl.rstrip('n') # Jinja strips the last 'n', so add these later
- return jinja2.Template(t2, undefined=jinja2.StrictUndefined).render(**kw) + - tmpl[len(t2):]
-
-
-def load_generators():
- "Load all modules containig generators to allow them to register"
- # TODO: write proper discovery
- import gfxprim.generators.make_collected_tests
- import gfxprim.generators.core.make_GP_Pixel
- import gfxprim.generators.core.make_GP_Blit
- import gfxprim.generators.core.make_GP_Convert
-
-
-def generate_file(fname):
- "Function trying to generate file `fname` using matching known generator."
- from gfxprim.generators.generator import known_generators
- matches = []
- for k in known_generators:
- if k.matches_path(fname):
- matches.append(k)
- if len(matches) == 0:
- log.fatal("No known generators match '%s'" % (fname,))
- if len(matches) > 1:
- log.fatal("Multiple generators match '%s': %s" % (fname, str(matches)))
- s = matches[0].generate()
- with open(fname, "wt") as f:
- f.write(s)
-
-
-def hmask(bits):
- "Helper returning hex mask for that many bits"
- return hex((1<<bits)-1).rstrip('L')
diff --git a/pylib/gfxprim/test_collection.py b/pylib/gfxprim/test_collection.py
new file mode 100644
index 0000000..db3b5b2
--- /dev/null
+++ b/pylib/gfxprim/test_collection.py
@@ -0,0 +1,96 @@
+#
+# Scrapes the target directory for .test.c files, looks for
+# GP_TEST and GP_SUITE macros and generates code creating all the
+# tests and the suite
+#
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+#
+
+import os
+import re
+import glob
+import logging as log
+from gfxprim.render_utils import create_environment, render_file
+
+testfile_patterns = ['*.test.c', '*.test.gen.c']
+
+suite_re = re.compile("A\s*GP_SUITE\((.*)\)\s*Z")
+test_re = re.compile("A\s*GP_TEST\((.*)\)\s*Z")
+
+# Also fixed in tests.mk
+collected_tests_file = 'collected_tests.gen.c'
+
+# suites is a dict of tests:
+# {"suitename": [Test]}
+
+# Test is a dict:
+# {"attribute": val}
+# attributes are:
+# name, fname, line
+
+def find_tests(fname, suites):
+ "Finds all tests in a file, extend suites."
+ suite = None
+ f = open(fname, 'rt')
+ ls = list(f.readlines())
+ f.close()
+ for i in range(len(ls)):
+ l = ls[i]
+ # Look for suite declaration
+ name, args = find_GP_directive("GP_SUITE", suite_re, l, fname=fname, line=i)
+ if name:
+ if args:
+ log.warn("suite should have no arguments other than name.", fname, i)
+ suites.setdefault(name, [])
+ suite = name
+ # Look for test declaration
+ name, args = find_GP_directive("GP_TEST", test_re, l, fname=fname, line=i)
+ if name:
+ test_suite = suite
+ if 'suite' in args:
+ test_suite = args['suite']
+ if not test_suite:
+ test_suite = 'default'
+ log.warn("No suite defined before test %s, using %r." % (name, test_suite), fname, i)
+ args['name'] = name
+ args['fname'] = fname
+ args['line'] = i
+ assert ('loop_start' in args) == ('loop_end' in args)
+ suites.setdefault(test_suite, [])
+ suites[test_suite].append(args)
+
+
+def collect_suites(fdir):
+ fnames = []
+ suites = {}
+ for pat in testfile_patterns:
+ fnames += glob.fnmatch.filter(os.listdir(fdir), pat)
+ for fn in fnames:
+ find_tests(os.path.join(fdir, fn), suites)
+ if not fnames:
+ log.warn('No .test.c files found in "%s".', fdir)
+ if not suites:
+ log.warn('No suites found, generating an empty testsuite.')
+ return suites
+
+
+def find_GP_directive(name, regexp, l, fname='unknown', line=0):
+ "Looks for a given GP_* directive, parses args if any, "
+ "retuns (name, dict_of_args) or (None, None) if not found."
+ if name in l:
+ m = regexp.search(l)
+ if not m:
+ warn("found unsuitable %s directive, ignoring." % name, fname, line)
+ else:
+ d = m.groups()[0].split(',', 1)
+ args = {}
+ if len(d)>1:
+ try:
+ s = 'dict( ' + d[1].strip(" tn"") + ' )'
+ args = eval(s)
+ except:
+ log.fatal("error parsing arguments: %r" % s, fname, line)
+ return d[0].strip(), args
+ return None, None
+
+
diff --git a/pylib/templates/collected_tests.c.t b/pylib/templates/collected_tests.c.t
new file mode 100644
index 0000000..cd24232
--- /dev/null
+++ b/pylib/templates/collected_tests.c.t
@@ -0,0 +1,55 @@
+%% extends "base.c.t"
+
+%% block descr
+Code creating the tests and suites for tests collected from .test.c files.
+%% endblock
+
+%% block body
+
+#include <check.h>
+
+%% for suite, tests in suites.items()
+
+/****************************************************************
+ * Suite {{ suite }}
+ */
+
+%% for t in tests
+/*
+ * Test {{ suite }}/{{ t['name'] }} defined in {{ t['fname'] }}:{{ t['line'] }}
+ */
+
+void GP_TEST_{{ t['name'] }}(int);
+
+## TODO: Handle special test requirements (timing, fixture, ...)
+TCase *GP_TC_{{ suite }}_{{ t['name'] }}()
+{
+ TCase *tc = tcase_create("{{ t['name'] }}");
+ _tcase_add_test(tc, GP_TEST_{{ t['name'] }}, "{{ t['name'] }}",
+ {{ t.get('expect_signal', 0) }}, {{ t.get('expect_exit', 0) }},
+ {{ t.get('loop_start', 0) }}, {{ t.get('loop_end', 1) }});
+ return tc;
+}
+
+%% endfor
+
+Suite *GP_TS_{{ suite }}() {
+ Suite *s = suite_create("{{ suite }}");
+%% for t in tests
+ suite_add_tcase(s, GP_TC_{{ suite }}_{{ t['name'] }}());
+%% endfor
+ return s;
+}
+
+%% endfor
+
+/****************************************************************
+ * Create and add all suites to a SRunner
+ */
+void GP_AddSuitesToSRunner(SRunner *sr) {
+%% for suite, tests in suites.items()
+ srunner_add_suite(sr, GP_TS_{{ suite }}());
+%% endfor
+}
+
+%% endblock body
diff --git a/tests.mk b/tests.mk
index e4cf3bb..d18d86a 100644
--- a/tests.mk
+++ b/tests.mk
@@ -19,11 +19,18 @@ CSOURCES+=${GP_TESTLIB_SRCS}
# generated suite creation code
TESTSUITE_GEN=collected_tests.gen.c # also fixed in the code generator
-GENSOURCES+=${TESTSUITE_GEN}
+CLEAN+=${TESTSUITE_GEN}
${TESTSUITE_GEN}: $(filter-out ${TESTSUITE_GEN},${GENSOURCES}) ${GENHEADERS}
+ifdef VERBOSE
+ ${PYTHON} ${TOPDIR}/pylib/bin/generate_collected_tests.py -t $(TEMPLATE_DIR) "." "$@"
+else
+ @echo "TSTS $@"
+ @${PYTHON} ${TOPDIR}/pylib/bin/generate_collected_tests.py -t $(TEMPLATE_DIR) "." "$@"
+endif
+
-TESTSUITE_SRCS=$(wildcard *.test.c) ${GENSOURCES} ${GENHEADERS} ${GP_TESTLIB_SRCS}
+TESTSUITE_SRCS=$(wildcard *.test.c) ${GENSOURCES} ${GENHEADERS} ${GP_TESTLIB_SRCS} ${TESTSUITE_GEN}
INCLUDE+=../tests/common
TESTSUITE_OBJS=$(patsubst %.c,%.o,$(TESTSUITE_SRCS))
CLEAN+=${TESTSUITE} ${TESTSUITE_OBJS}
http://repo.or.cz/w/gfxprim.git/commit/ffa0e5910b52a5fe361e1bc5753665fec90a…
commit ffa0e5910b52a5fe361e1bc5753665fec90a8db4
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Mon Aug 8 10:40:58 2011 +0200
Modifications to templating library, extensions
diff --git a/pylib/gfxprim/pixelsize.py b/pylib/gfxprim/pixelsize.py
index 1586250..88f7364 100644
--- a/pylib/gfxprim/pixelsize.py
+++ b/pylib/gfxprim/pixelsize.py
@@ -15,6 +15,7 @@ class PixelSize(object):
self.bit_endian = bit_endian
assert self.bit_endian in [None, LE, BE]
assert (bit_endian is not None) == self.needs_bit_endian()
+ self.bit_endian_const = "GP_BIT_ENDIAN_" + (self.bit_endian or LE)
self.suffix = suffix
if not self.suffix:
diff --git a/pylib/gfxprim/pixeltype.py b/pylib/gfxprim/pixeltype.py
index 5cf356e..e2389a0 100644
--- a/pylib/gfxprim/pixeltype.py
+++ b/pylib/gfxprim/pixeltype.py
@@ -39,7 +39,7 @@ class PixelType(object):
"Check PixelType compatibility with given GfxPrimConfig."
# all types except UNKNOWN must have one of these sizes
- if self.name != "UNKNOWN":
+ if not self.is_unknown():
assert(self.pixelsize in config.pixelsizes)
def __str__(self):
@@ -47,3 +47,16 @@ class PixelType(object):
def is_palette(self):
return ('P' in self.chans)
+
+ def is_unknown(self):
+ return (self.name == "UNKNOWN")
+
+ def is_rgb(self):
+ return all((i in self.chans for i in 'RGB'))
+
+ def is_gray(self):
+ return ('V' in self.chans)
+
+ def is_alpha(self):
+ return ('A' in self.chans)
+
diff --git a/pylib/gfxprim/render_utils.py b/pylib/gfxprim/render_utils.py
index 1051f3c..a9590e0 100644
--- a/pylib/gfxprim/render_utils.py
+++ b/pylib/gfxprim/render_utils.py
@@ -8,15 +8,26 @@ import os
import time
import re
+def template_error(s, *args):
+ raise Exception(s, *args)
+
def create_environment(config, template_dir):
env = jinja2.Environment(
line_statement_prefix = "%%",
+ line_comment_prefix = "##",
undefined = jinja2.StrictUndefined,
loader = jinja2.FileSystemLoader(template_dir))
env.globals['undefined'] = jinja2.StrictUndefined()
env.globals['pixelsizes'] = config.pixelsizes
env.globals['pixeltypes'] = config.pixeltypes
+ env.globals['pixeltypes_dict'] = config.pixeltypes_dict
env.globals['gfxprim_config'] = config
+ from gfxprim.pixelsize import LE, BE
+ env.globals['LE'] = LE
+ env.globals['BE'] = BE
+ env.globals['len'] = len
+ env.globals['error'] = template_error
+ env.globals['hex'] = lambda(x): hex(x).rstrip('L')
return env
diff --git a/pylib/templates/base.h.t b/pylib/templates/base.h.t
index 8eb9140..8f60d6a 100644
--- a/pylib/templates/base.h.t
+++ b/pylib/templates/base.h.t
@@ -1,4 +1,4 @@
-%% extends "body.c.h"
+%% extends "base.c.t"
%% block pre_body_guard
#ifndef {{ header_guard }}
http://repo.or.cz/w/gfxprim.git/commit/cfe11b6f6f3c41d3ff6c18d90efdd2615a5e…
commit cfe11b6f6f3c41d3ff6c18d90efdd2615a5e858a
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Mon Aug 8 10:39:12 2011 +0200
Finished moving and cleaning templates from .py to .t
Refactoring time!
Also simplified and minor fixes along the way
Test generation partially WIP
diff --git a/include/core/GP_Blit.gen.h.t b/include/core/GP_Blit.gen.h.t
new file mode 100644
index 0000000..cc1cc6e
--- /dev/null
+++ b/include/core/GP_Blit.gen.h.t
@@ -0,0 +1,16 @@
+%% extends "base.h.t"
+
+{% block descr %}Specialized blit functions and macros.{% endblock %}
+
+%% block body
+
+%% for ps in pixelsizes
+/*** Blit preserving type for {{ ps.suffix }} ***
+ * Assumes the contexts to be of the right types and sizes
+ * Ignores transformations and clipping */
+void GP_Blit_{{ ps.suffix }}(const GP_Context *c1, GP_Coord x1, GP_Coord y1, GP_Size w, GP_Size h,
+ GP_Context *c2, GP_Coord x2, GP_Coord y2);
+
+%% endfor
+
+%% endblock body
diff --git a/include/core/GP_Convert.gen.h.t b/include/core/GP_Convert.gen.h.t
new file mode 100644
index 0000000..2b4681a
--- /dev/null
+++ b/include/core/GP_Convert.gen.h.t
@@ -0,0 +1,86 @@
+%% extends "base.h.t"
+
+{% block descr %}Convert PixelType values macros and functions{% endblock %}
+
+
+%% macro GP_Pixel_TYPE_TO_TYPE(pt1, pt2)
+/*** {{ pt1.name }} -> {{ pt2.name }} ***
+ * macro reads p1 ({{ pt1.name }} at bit-offset o1)
+ * and writes to p2 ({{ pt2.name }} at bit-offset o2)
+ * the relevant part of p2 is assumed to be cleared (zero) */
+#define GP_Pixel_{{ pt1.name }}_TO_{{ pt2.name }}_OFFSET(p1, o1, p2, o2) do { +%% for c2 in pt2.chanslist
+{# case 1: just copy a channel -#}
+%% if c2[0] in pt1.chans.keys()
+%% set c1 = pt1.chans[c2[0]]
+ /* {{ c2[0] }}:={{ c1[0] }} */ GP_SET_BITS({{c2[1]}}+o2, {{c2[2]}}, p2,+ GP_SCALE_VAL_{{c1[2]}}_{{c2[2]}}(GP_GET_BITS({{c1[1]}}+o1, {{c1[2]}}, p1))); +{# case 2: set A to full opacity (not present in source) -#}
+%% elif c2[0]=='A'
+ /* A:={{ hex(c2[2]) }} */GP_SET_BITS({{c2[1]}}+o2, {{c2[2]}}, p2, {{ hex(c2[2]) }}); +{# case 3: calculate V as average of RGB -#}
+%% elif c2[0]=='V' and pt1.is_rgb()
+ /* V:=RGB_avg */ GP_SET_BITS({{c2[1]}}+o2, {{c2[2]}}, p2, ( +%% for c1 in [pt1.chans['R'], pt1.chans['G'], pt1.chans['B']]
+ /* {{c1[0]}} */ GP_SCALE_VAL_{{c1[2]}}_{{c2[2]}}(GP_GET_BITS({{c1[1]}}+o1, {{c1[2]}}, p1)) + +%% endfor
+ 0)/3);+{# case 4: set each RGB to V -#}
+%% elif c2[0] in 'RGB' and pt1.is_gray()
+%% set c1 = pt1.chans['V']
+ /* {{ c2[0] }}:=V */ GP_SET_BITS({{c2[1]}}+o2, {{c2[2]}}, p2,+ GP_SCALE_VAL_{{c1[2]}}_{{c2[2]}}(GP_GET_BITS({{c1[1]}}+o1, {{c1[2]}}, p1))); +{# case 5: invalid mapping -#}
+%% else
+{{ error('Channel conversion ' + pt1.name + ' to ' + pt2.name + ' not supported.') }}
+%% endif
+%% endfor
+} while (0)
+
+/* a version without offsets */
+#define GP_Pixel_{{ pt1.name }}_TO_{{ pt2.name }}(p1, p2) + GP_Pixel_{{ pt1.name }}_TO_{{ pt2.name }}_OFFSET(p1, 0, p2, 0)
+
+%% endmacro
+
+
+%% block body
+#include "GP_Common.h"
+#include "GP_Context.h"
+#include "GP_Pixel.h"
+
+##
+## Loop around "central" pixel types
+##
+%% for pt in [pixeltypes_dict['RGB888'], pixeltypes_dict['RGBA8888']]
+%% for i in pixeltypes
+%% if not i.is_unknown()
+%% if not i.is_palette()
+{{ GP_Pixel_TYPE_TO_TYPE(pt, i) }}
+%% if i.name not in ['RGB888', 'RGBA8888']
+{{ GP_Pixel_TYPE_TO_TYPE(i, pt) }}
+%% endif
+%% endif
+%% endif
+%% endfor
+
+/*
+ * Convert {{ pt.name }} to any other PixelType
+ * Does not work on palette types at all (yet)
+ */
+GP_Pixel GP_{{ pt.name }}ToPixel(GP_Pixel pixel, GP_PixelType type);
+
+/*
+ * Function converting to {{ pt.name }} from any other PixelType
+ * Does not work on palette types at all (yet)
+ */
+GP_Pixel GP_PixelTo{{ pt.name }}(GP_Pixel pixel, GP_PixelType type);
+
+%% endfor
+
+/* Experimental macros testing generated scripts */
+{{ GP_Pixel_TYPE_TO_TYPE(pixeltypes_dict['RGB565'], pixeltypes_dict['RGBA8888']) }}
+{{ GP_Pixel_TYPE_TO_TYPE(pixeltypes_dict['RGBA8888'], pixeltypes_dict['V2']) }}
+{{ GP_Pixel_TYPE_TO_TYPE(pixeltypes_dict['VA12'], pixeltypes_dict['RGBA8888']) }}
+
+%% endblock body
diff --git a/include/core/GP_Convert_Scale.gen.h.t b/include/core/GP_Convert_Scale.gen.h.t
new file mode 100644
index 0000000..86c43b0
--- /dev/null
+++ b/include/core/GP_Convert_Scale.gen.h.t
@@ -0,0 +1,28 @@
+%% extends "base.h.t"
+
+{% block descr %}Fast value scaling macros{% endblock %}
+
+{% macro multcoef(s1, s2) -%}
+(0{% for i in range((s2+s1-1)/s1) %}+{{ 2**(i*s1) }}{% endfor %})
+{%- endmacro %}
+
+%% block body
+/*
+ * Helper macros to transfer s1-bit value to s2-bit value.
+ * Efficient and accurate for both up- and downscaling.
+ * WARNING: GP_SCALE_VAL requires constants numbers as first two parameters
+ */
+
+#define GP_SCALE_VAL(s1, s2, val) ( GP_SCALE_VAL_##s1##_##s2(val) )
+
+%% for s1 in range(1,9)
+%% for s2 in range(1,9)
+%% if s2>s1
+#define GP_SCALE_VAL_{{s1}}_{{s2}}(val) (((val) * {{ multcoef(s1, s2) }}) >> {{ (-s2) % s1 }})
+%% else
+#define GP_SCALE_VAL_{{s1}}_{{s2}}(val) ((val) >> {{ s1 - s2 }})
+%% endif
+%% endfor
+%% endfor
+
+%% endblock body
diff --git a/include/core/GP_GetPutPixel.gen.h.t b/include/core/GP_GetPutPixel.gen.h.t
new file mode 100644
index 0000000..1ee473c
--- /dev/null
+++ b/include/core/GP_GetPutPixel.gen.h.t
@@ -0,0 +1,63 @@
+%% extends "base.h.t"
+
+%% block descr
+Access pixel bytes, Get and PutPixel
+Do not include directly, use GP_Pixel.h
+%% endblock
+
+%% block body
+
+#include "GP_Common.h"
+
+struct GP_Context;
+
+%% for ps in pixelsizes
+/*
+ * macro to get address of pixel in a {{ ps.suffix }} context
+ */
+#define GP_PIXEL_ADDR_{{ ps.suffix }}(context, x, y) + ((context)->pixels + (context)->bytes_per_row * (y) + {{ ps.size // 8 }} * (x))
+
+/*
+ * macro to get bit-offset of pixel in {{ ps.suffix }} context
+ */
+#define GP_PIXEL_ADDR_OFFSET_{{ ps.suffix }}(x) +%% if not ps.needs_bit_endian()
+ (0)
+%% else
+%% if ps.bit_endian == LE
+%% if ps.size < 8
+ (((x) % {{ 8 // ps.size }}) * {{ ps.size }})
+%% else
+ (((x) * {{ ps.size }}) / 8)
+%% endif
+%% else
+%% if ps.size < 8
+ ({{ 8 - ps.size }} - ((x) % {{ 8 // ps.size }}) * {{ ps.size }})
+%% else
+ {{ error('Insanity check: big bit-endian with >8 bpp. Are you sure?') }}
+%% endif
+%% endif
+%% endif
+
+/*
+ * GP_GetPixel for {{ ps.suffix }}
+ */
+static inline GP_Pixel GP_GetPixel_Raw_{{ ps.suffix }}(const GP_Context *c, int x, int y)
+{
+ return GP_GET_BITS(GP_PIXEL_ADDR_OFFSET_{{ ps.suffix }}(x), {{ ps.size }},
+ *(GP_PIXEL_ADDR_{{ ps.suffix}}(c, x, y)));
+}
+
+/*
+ * GP_PutPixel for {{ ps.suffix }}
+ */
+static inline void GP_PutPixel_Raw_{{ ps.suffix }}(GP_Context *c, int x, int y, GP_Pixel p)
+{
+ GP_SET_BITS(GP_PIXEL_ADDR_OFFSET_{{ ps.suffix }}(x), {{ ps.size }},
+ *(GP_PIXEL_ADDR_{{ ps.suffix}}(c, x, y)), p);
+}
+
+%% endfor
+
+%% endblock body
diff --git a/include/core/GP_Pixel.gen.h.t b/include/core/GP_Pixel.gen.h.t
new file mode 100644
index 0000000..a71c461
--- /dev/null
+++ b/include/core/GP_Pixel.gen.h.t
@@ -0,0 +1,83 @@
+%% extends "base.h.t"
+
+%% block descr
+Pixel type definitions and functions
+Do not include directly, use GP_Pixel.h
+%% endblock
+
+%% block body
+
+/*
+ * List of all known pixel types
+ */
+typedef enum GP_PixelType {
+%% for pt in pixeltypes
+ GP_PIXEL_{{ pt.name }},
+%% endfor
+ GP_PIXEL_MAX,
+} GP_PixelType;
+
+%% for pt in pixeltypes
+%% if not pt.is_unknown()
+/* Automatically generated code for pixel type {{ pt.name }}
+ *
+ * Size (bpp): {{ pt.pixelsize.size }} ({{ pt.pixelsize.suffix }})
+ * Bit endian: {{ pt.pixelsize.bit_endian_const }}
+ * Pixel structure: {{ pt.bits|join("") }}
+ * Channels:
+%% for c in pt.chanslist
+ * {{ c[0] }} offset:{{ c[1] }} size:{{ c[2] }}
+%% endfor
+ */
+
+/*
+ * snprintf a human readable value of pixel type {{ pt.name }}
+ */
+void GP_PixelSNPrint_{{ pt.name }}(char *buf, size_t len, GP_Pixel p);
+
+/*
+ * macros to get channels of pixel type {{ pt.name }}
+ */
+%% for c in pt.chanslist
+#define GP_Pixel_GET_{{ c[0] }}_{{ pt.name }}(p) (GP_GET_BITS({{ c[1] }}, {{ c[2] }}, (p)))
+%% endfor
+
+/*
+ * macros to get address and bit-offset of a pixel {{ pt.name }} in a context
+ */
+#define GP_PIXEL_ADDR_{{ pt.name }}(context, x, y) GP_PIXEL_ADDR_{{ pt.pixelsize.suffix }}(context, x, y)
+#define GP_PIXEL_ADDR_OFFSET_{{ pt.name }}(x) GP_PIXEL_ADDR_OFFSET_{{ pt.pixelsize.suffix }}(x)
+
+/*
+ * macros to create GP_Pixel of pixel type {{ pt.name }} directly from given values.
+ * The values MUST be already clipped/converted to relevant value ranges.
+ */
+#define GP_Pixel_CREATE_{{ pt.name }}({{ pt.chanslist[0][0] }}{% for c in pt.chanslist[1:] %}, {{ c[0] }}{% endfor %}) (0+%% for c in pt.chanslist
+ + (({{ c[0] }}) << {{ c[1] }}) +%% endfor
+ )
+
+%% endif
+%% endfor
+
+/*
+ * macros for branching on PixelType (similar to GP_FnPerBpp macros)
+ */
+
+%% for r in ['', 'return ']
+#define GP_FN_{% if r %}RET_{% endif %}PER_PIXELTYPE(FN_NAME, type, ...)+ switch (type) { +%% for pt in pixeltypes
+%% if not pt.is_unknown()
+ case GP_PIXEL_{{ pt.name }}:+ {{ r }}FN_NAME{{'##'}}_{{ pt.name }}(__VA_ARGS__);+ break;+%% endif
+%% endfor
+ default: GP_ABORT("Invalid PixelType %d", type);+ }
+
+%% endfor
+
+%% endblock body
diff --git a/libs/core/GP_Blit.gen.c.t b/libs/core/GP_Blit.gen.c.t
new file mode 100644
index 0000000..39f839d
--- /dev/null
+++ b/libs/core/GP_Blit.gen.c.t
@@ -0,0 +1,69 @@
+%% extends "base.c.t"
+
+{% block descr %}Specialized blit functions and macros.{% endblock %}
+
+%% block body
+#include <stdio.h>
+#include <string.h>
+#include "GP_Pixel.h"
+#include "GP.h"
+#include "GP_Context.h"
+#include "GP_Blit.h"
+
+%% for ps in pixelsizes
+/*** Blit preservimg PixelType, variant for {{ ps.suffix }} ***/
+void GP_Blit_{{ ps.suffix }}(const GP_Context *c1, GP_Coord x1, GP_Coord y1, GP_Size w, GP_Size h,
+ GP_Context *c2, GP_Coord x2, GP_Coord y2)
+{
+ if (unlikely(w == 0 || h == 0)) return;
+
+ /* Special case - copy whole line-block with one memcpy() */
+ if ((x1 == 0) && (x2 == 0) && (w == c1->w) && (c1->w == c2->w) &&
+ (c1->bytes_per_row == c2->bytes_per_row)) {
+ memcpy(c2->pixels + c2->bytes_per_row * y2,
+ c1->pixels + c1->bytes_per_row * y1,
+ c1->bytes_per_row * h);
+ return;
+ }
+
+%% if not ps.needs_bit_endian()
+ /* General case - memcpy() each horizontal line */
+ for (GP_Size i = 0; i < h; i++)
+ memcpy(GP_PIXEL_ADDR_{{ ps.suffix }}(c2, x2, y2 + i),
+ GP_PIXEL_ADDR_{{ ps.suffix }}(c1, x2, y2 + i),
+ {{ ps.size/8 }} * w);
+%% else
+ /* Rectangles may not be bit-aligned in the same way! */
+ /* Alignment (index) of first bits in the first byte */
+ int al1 = GP_PIXEL_ADDR_OFFSET_{{ ps.suffix }}(x1);
+ int al2 = GP_PIXEL_ADDR_OFFSET_{{ ps.suffix }}(x2);
+ /* Special case of the same alignment and width >=2 bytes */
+ if ((al1 == al2) && (w * {{ ps.size }} >= 16)) {
+ /* Number of bits in the last partial byte */
+ int end_al = GP_PIXEL_ADDR_OFFSET_{{ ps.suffix }}(x1 + w);
+ GP_ASSERT(({{ ps.size }} * w - al1 - end_al) % 8 == 0);
+ int copy_size = ({{ ps.size }} * w - al1 - end_al) / 8;
+ /* First and last byte incident to the line */
+ uint8_t *p1 = GP_PIXEL_ADDR_{{ ps.suffix }}(c1, x1, y1);
+ uint8_t *p2 = GP_PIXEL_ADDR_{{ ps.suffix }}(c2, x2, y2);
+ uint8_t *end_p1 = GP_PIXEL_ADDR_{{ ps.suffix }}(c1, x1 + w - 1, y1);
+ uint8_t *end_p2 = GP_PIXEL_ADDR_{{ ps.suffix }}(c2, x2 + w - 1, y2);
+ for (GP_Size i = 0; i < h; i++) {
+ if (al1 != 0)
+ GP_SET_BITS(al1, 8-al1, *p2, GP_GET_BITS(al1, 8-al1, *p1));
+ memcpy(p2+(al1!=0), p1+(al1!=0), copy_size);
+ if (end_al != 0)
+ GP_SET_BITS(0, end_al, *end_p2, GP_GET_BITS(0, end_al, *end_p1));
+ p1 += c1->bytes_per_row;
+ end_p1 += c1->bytes_per_row;
+ p2 += c2->bytes_per_row;
+ end_p2 += c2->bytes_per_row;
+ }
+ } else /* Different bit-alignment, can't use memcpy() */
+ GP_Blit_Naive(c1, x1, y1, w, h, c2, x2, y2);
+%% endif
+}
+
+
+%% endfor
+%% endblock body
diff --git a/libs/core/GP_Convert.gen.c.t b/libs/core/GP_Convert.gen.c.t
new file mode 100644
index 0000000..8b65a75
--- /dev/null
+++ b/libs/core/GP_Convert.gen.c.t
@@ -0,0 +1,70 @@
+%% extends "base.c.t"
+
+{% block descr %}Convert PixelType values macros and functions{% endblock %}
+
+%% block body
+
+#include "GP_Convert.h"
+
+##
+## Loop around "central" pixel types
+##
+%% for pt in [pixeltypes_dict['RGB888'], pixeltypes_dict['RGBA8888']]
+
+GP_Pixel GP_{{ pt.name }}ToPixel(GP_Pixel pixel, GP_PixelType type)
+{
+ GP_Pixel p = 0;
+ switch(type) {
+%% for tf in pixeltypes
+%% if tf.is_unknown()
+ case GP_PIXEL_UNKNOWN:
+ GP_ABORT("Cannot convert {{ pt.name }} to GP_PIXEL_UNKNOWN");
+ break;
+%% elif tf.is_palette()
+ case GP_PIXEL_{{ tf.name }}:
+ GP_ABORT("Cannot convert {{ pt.name }} to palette type {{ tf.name }}");
+ break;
+%% else
+ case GP_PIXEL_{{ tf.name }}:
+ GP_Pixel_{{ pt.name }}_TO_{{ tf.name }}(pixel, p);
+ break;
+%% endif
+%% endfor
+ default:
+ GP_ABORT("Unknown PixelType %ud", type);
+ }
+ return p;
+}
+
+
+GP_Pixel GP_PixelTo{{ pt.name }}(GP_Pixel pixel, GP_PixelType type)
+{
+ GP_Pixel p = 0;
+ switch(type) {
+%% for sf in pixeltypes
+%% if sf.is_unknown()
+ case GP_PIXEL_UNKNOWN:
+ GP_ABORT("Cannot convert from GP_PIXEL_UNKNOWN");
+ break;
+%% elif sf.is_palette()
+ case GP_PIXEL_{{ sf.name }}:
+ GP_ABORT("Cannot convert from palette type {{ sf.name }} (yet)");
+ break;
+%% else
+ case GP_PIXEL_{{ sf.name }}:
+ GP_Pixel_{{ sf.name }}_TO_{{ pt.name }}(pixel, p);
+ break;
+%% endif
+%% endfor
+ default:
+ GP_ABORT("Unknown PixelType %u", type);
+ }
+ return p;
+}
+
+##
+## Loop arpund "central" pixel types
+##
+%% endfor
+
+%% endblock body
diff --git a/libs/core/GP_Pixel.gen.c.t b/libs/core/GP_Pixel.gen.c.t
new file mode 100644
index 0000000..e0cf7c0
--- /dev/null
+++ b/libs/core/GP_Pixel.gen.c.t
@@ -0,0 +1,45 @@
+%% extends "base.c.t"
+
+%% block descr
+Pixel type definitions and functions
+Do not include directly, use GP_Pixel.h
+%% endblock
+
+%% block body
+#include <stdio.h>
+#include "GP_Pixel.h"
+
+/*
+ * Description of all known pixel types
+ */
+const GP_PixelTypeDescription const GP_PixelTypes [] = {
+%% for pt in pixeltypes
+ /* GP_PIXEL_{{ pt.name }} */ {
+ .type = GP_PIXEL_{{ pt.name }},
+ .name = "{{ pt.name }}",
+ .size = {{ pt.pixelsize.size }},
+ .bit_endian = {{ pt.pixelsize.bit_endian_const }},
+ .numchannels = {{ len(pt.chanslist) }},
+ .bitmap = "{{ pt.bits|join("") }}",
+ .channels = {
+%% for c in pt.chanslist
+ { .name = "{{ c[0] }}", .offset = {{ c[1] }}, .size = {{ c[2] }} },
+%% endfor
+ } },
+%% endfor
+};
+
+%% for pt in pixeltypes
+%% if not pt.is_unknown()
+/*
+ * snprintf a human readable value of pixel type {{pt.name}}
+ */
+void GP_PixelSNPrint_{{ pt.name }}(char *buf, size_t len, GP_Pixel p)
+{
+ snprintf(buf, len, "<{{ pt.name }} 0x%0{{ (pt.pixelsize.size+3)//4 }}x{% for c in pt.chanslist %} {{ c[0] }}=%d{% endfor %}>",
+ GP_GET_BITS(0, {{ pt.pixelsize.size }}, p){% for c in pt.chanslist %}, GP_GET_BITS({{ c[1] }}, {{ c[2] }}, p){% endfor %});
+}
+
+%% endif
+%% endfor
+%% endblock body
diff --git a/pylib/gfxprim/generators/core/make_GP_Blit.py b/pylib/gfxprim/generators/core/make_GP_Blit.py
deleted file mode 100644
index b10c927..0000000
--- a/pylib/gfxprim/generators/core/make_GP_Blit.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/python
-#
-# Generators for GP_Pixel_Blit.gen.c and GP_Pixel_Blit.gen.h
-#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
-#
-
-from gfxprim.generators.generator import *
-from gfxprim.generators.pixeltype import *
-from gfxprim.generators.core.gen_pixeltype import *
-from gfxprim.generators.core.gen_blit import *
-
-@generator(CHeaderGenerator(name='GP_Blit.gen.h'),
- CSourceGenerator(name='GP_Blit.gen.c'),
- descr = 'specialized blit functions and macros',
- authors = ["2011 - Tomas Gavenciak <gavento(a)ucw.cz>"])
-def core_GP_Blit_gen(h, c):
- c.rhead(
- '#include <stdio.h>n'
- '#include <string.h>n'
- '#include "GP_Pixel.h"n'
- '#include "GP.h"n'
- '#include "GP_Context.h"n'
- '#include "GP_Blit.h"n'
- )
-
- for bpp in bitsizes:
- for bit_endian in bit_endians:
- if (bpp < 8) or (bit_endian == bit_endians[0]):
- gen_blit_same_t(bpp, get_size_suffix(bpp, bit_endian), h, c)
-
diff --git a/pylib/gfxprim/generators/core/make_GP_Convert.py b/pylib/gfxprim/generators/core/make_GP_Convert.py
deleted file mode 100644
index 99e4d0b..0000000
--- a/pylib/gfxprim/generators/core/make_GP_Convert.py
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/python
-#
-# Script generating:
-#
-# GP_Convert.gen.c, GP_Convert.gen.h
-# GP_Convert_Scale.gen.h
-#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
-#
-
-from gfxprim.generators.generator import *
-from gfxprim.generators.pixeltype import *
-from gfxprim.generators.core.gen_convert import *
-
-
-@generator(CHeaderGenerator(name = 'GP_Convert_Scale.gen.h'),
- descr = 'Fast value scaling macros',
- authors = ["2011 - Tomas Gavenciak <gavento(a)ucw.cz>"])
-def core_GP_Pixel_Scale_gen(h):
- h.rhead(
- "/* helper macros to transfer s1-bit value to s2-bit valuen"
- " * NOTE: efficient and accurate for both up- and downscaling,n"
- " * WARNING: GP_SCALE_VAL requires constants numbers as first two parametersn"
- " */n"
- "#define GP_SCALE_VAL(s1, s2, val) ( GP_SCALE_VAL_##s1##_##s2(val) )nn"
-
- "{% for s1 in range(1,9) %}{% for s2 in range(1,9) %}"
- "{% if s2>s1 %}"
- "#define GP_SCALE_VAL_{{s1}}_{{s2}}(val) (((val) * {{ multcoef(s1, s2) }}) >> {{ (-s2) % s1 }})n"
- "{% else %}"
- "#define GP_SCALE_VAL_{{s1}}_{{s2}}(val) ((val) >> {{ s1 - s2 }})n"
- "{% endif %}"
- "{% endfor %}{% endfor %}", multcoef = lambda s1,s2: hex(sum([1<<(i*s1) for i in range((s2+s1-1)/s1)]))
- )
-
-
-@generator(CHeaderGenerator(name = 'GP_Convert.gen.h'),
- CSourceGenerator(name = 'GP_Convert.gen.c'),
- descr = 'Convert PixelType values macros and functions',
- authors = ["2011 - Tomas Gavenciak <gavento(a)ucw.cz>"])
-def core_GP_Convert_gen_h(h, c):
- h.rhead('#include "GP_Common.h"n');
- h.rhead('#include "GP_Context.h"n');
- h.rhead('#include "GP_Pixel.h"nn');
-
- c.rhead('#include "GP_Convert.h"nn');
-
- ## two base types for conversions
- for bt in [pixeltypes['RGB888'], pixeltypes['RGBA8888']]:
- gen_fixedtype_to_type(bt, h, c)
- gen_type_to_fixedtype(bt, h, c)
- ## Conversion macros
- for t in pixeltypes.values():
- if not t.is_palette() and t.number != 0:
- gen_convert_to(t, bt, h, c)
- gen_convert_to(bt, t, h, c)
-
- ## Just experimental conversion macros
- gen_convert_to(pixeltypes['RGB565'], pixeltypes['RGBA8888'], h, c)
- gen_convert_to(pixeltypes['RGBA8888'], pixeltypes['V2'], h, c)
- gen_convert_to(pixeltypes['VA12'], pixeltypes['RGBA8888'], h, c)
-
-
-@generator(CSourceGenerator(name = 'GP_Convert.test.gen.c'),
- descr = 'GP_Convert tests',
- authors = ["2011 - Tomas Gavenciak <gavento(a)ucw.cz>"])
-def core_GP_Convert_gen_h(c):
- c.rhead('#include "GP_Tests.h"n')
- c.rhead('#include "GP_Convert.h"n')
- c.rhead('#include "GP_TestingCore.h"nn')
- c.rhead('GP_SUITE(GP_Convert)nn')
- for t in pixeltypes.values():
- if not t.is_palette() and t.number != 0:
- c.rbody(
- 'GP_TEST(GP_ConvertPixel_for_{{ t.name }}, "loop_start=0, loop_end=4")n'
- '{n'
- ' GP_Pixel p1 = GP_RandomColor(GP_PIXEL_{{ t.name }});n'
- ' GP_Pixel p2 = GP_ConvertPixel(p1, GP_PIXEL_{{ t.name }}, GP_PIXEL_RGBA8888);n'
- ' GP_Pixel p3 = GP_ConvertPixel(p2, GP_PIXEL_RGBA8888, GP_PIXEL_{{ t.name }});n'
- ' GP_CHECK_EqualColors(p1, GP_PIXEL_{{ t.name }}, p3, GP_PIXEL_{{ t.name }});n'
- ' GP_CHECK_EqualColors(p1, GP_PIXEL_{{ t.name }}, p2, GP_PIXEL_RGBA8888);n'
- '}n'
- 'GP_ENDTESTnn', t=t)
- c.rbody(
- 'GP_TEST(WhiteStaysWhite_via_{{ t.name }}, "loop_start=0, loop_end=4")n'
- '{n'
- ' GP_Pixel p1 = GP_RGBToPixel(255, 255, 255, GP_PIXEL_RGB888);n'
- ' GP_Pixel p2 = GP_RGB888ToPixel(p1, GP_PIXEL_{{ t.name }});n'
- ' GP_Pixel p3 = GP_PixelToRGB888(p2, GP_PIXEL_{{ t.name }});n'
- ' GP_CHECK_EqualColors(p1, GP_PIXEL_RGB888, p3, GP_PIXEL_RGB888);n'
- '}n'
- 'GP_ENDTESTnn', t=t)
- c.rbody(
- 'GP_TEST(BlackStaysBlack_via_{{ t.name }}, "loop_start=0, loop_end=4")n'
- '{n'
- ' GP_Pixel p1 = GP_RGBToPixel(0, 0, 0, GP_PIXEL_RGB888);n'
- ' GP_Pixel p2 = GP_RGB888ToPixel(p1, GP_PIXEL_{{ t.name }});n'
- ' GP_Pixel p3 = GP_PixelToRGB888(p2, GP_PIXEL_{{ t.name }});n'
- ' GP_CHECK_EqualColors(p1, GP_PIXEL_RGB888, p3, GP_PIXEL_RGB888);n'
- '}n'
- 'GP_ENDTESTnn', t=t)
diff --git a/pylib/gfxprim/generators/core/make_GP_Pixel.py b/pylib/gfxprim/generators/core/make_GP_Pixel.py
deleted file mode 100644
index c7f7ee1..0000000
--- a/pylib/gfxprim/generators/core/make_GP_Pixel.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/python
-#
-# Script generating:
-#
-# GP_Pixel.gen.c, GP_Pixel.gen.h
-# GP_Pixel_Access.gen.h
-#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
-#
-
-from gfxprim.generators.generator import *
-from gfxprim.generators.pixeltype import *
-from gfxprim.generators.core.gen_pixeltype import *
-from gfxprim.generators.core.gen_getputpixel import *
-
-@generator(CHeaderGenerator(name='GP_Pixel.gen.h'),
- CSourceGenerator(name='GP_Pixel.gen.c'),
- descr = 'Pixel type definitions and functionsnDo not include directly, use GP_Pixel.h',
- authors = ["2011 - Tomas Gavenciak <gavento(a)ucw.cz>"])
-def core_GP_Pixel_gen(h, c):
- c.rhead(
- '#include <stdio.h>n'
- '#include "GP_Pixel.h"nn')
-
- ## Enum of types
- gen_GP_PixelType(h, c)
-
- ## PixelType parameters in C
- gen_GP_PixelTypes(h, c)
-
- ## List of types
- for t in pixeltypes.values():
- if t.name != 'UNKNOWN':
- h.rbody(str_start(t))
- h.rbody(str_description(t))
- c.rbody(str_start(t))
- c.rbody(str_description(t))
-
- gen_print(t, h, c)
- gen_get_chs(t, h, c)
- gen_get_pixel_addr(t, h, c)
- gen_create(t, h, c)
-
- ## FnPerPixelType and FnRetPerPixelType
- for r in ['', 'return ']:
- h.rbody(
- 'n/* Macro for branching on PixelType (similar to GP_FnPerBpp macros) */n'
- '#define GP_FN_{% if r %}RET_{% endif %}PER_PIXELTYPE(FN_NAME, type, ...)
'
- ' switch (type) {
'
- '{% for t in types %}{% if t.number != 0 %}'
- ' case GP_PIXEL_{{ t.name }}:
'
- ' {{ r }}FN_NAME##_{{ t.name }}(__VA_ARGS__);
'
- ' break;
'
- '{% endif %}{% endfor %}'
- ' default: GP_ABORT("Invalid PixelType %d", type);
'
- ' }nn', types=pixeltypes.values(), r=r)
-
-@generator(CHeaderGenerator(name = 'GP_GetPutPixel.gen.h'),
- descr = 'Access pixel bytes, Get and PutPixelnDo not include directly, use GP_Pixel.h',
- authors = ["2011 - Tomas Gavenciak <gavento(a)ucw.cz>"])
-def core_GP_Pixel_Scale_gen(h):
- h.rhead('#include "GP_Common.h"nn');
- h.rhead('struct GP_Context;nn');
- # Per-bpp adress/offset macros
- for bpp in bitsizes:
- for bit_endian in bit_endians:
- if (bpp < 8) or (bit_endian == bit_endians[0]):
- gen_get_pixel_addr_bpp(bpp, get_size_suffix(bpp, bit_endian), h)
-
- # Per-bpp adress/offset macros
- for bpp in bitsizes:
- for bit_endian in bit_endians:
- if (bpp < 8) or (bit_endian == bit_endians[0]):
- gen_getpixel_bpp(bpp, get_size_suffix(bpp, bit_endian), h)
- gen_putpixel_bpp(bpp, get_size_suffix(bpp, bit_endian), h)
-
diff --git a/pylib/templates/base.test.c.t b/pylib/templates/base.test.c.t
new file mode 100644
index 0000000..45d729f
--- /dev/null
+++ b/pylib/templates/base.test.c.t
@@ -0,0 +1,47 @@
+%% extends "base.c.t"
+
+
+%% macro test(name, opts="")
+GP_TEST({{ name }}, "{{ opts }}")
+{
+{{ caller() }}
+}
+GP_ENDTEST
+
+%% endmacro
+
+
+%% macro test_for_all_pixeltypes(name, opts="",
+ palette=True, unknown=False, rgb=True,
+ alpha=True, gray=True)
+%% for pt in pixeltypes
+%% if unknown or not pt.is_unknown()
+%% if palette or not pt.is_palette()
+%% if rgb or not pt.is_rgb()
+%% if alpha or not pt.is_alpha()
+%% if gray or not pt.is_gray()
+GP_TEST({{ name }}_{{ pt.name }}, "{{ opts }}")
+{
+{{ caller(pt) }}
+}
+GP_ENDTEST
+
+%% endif
+%% endif
+%% endif
+%% endif
+%% endif
+%% endfor
+%% endmacro
+
+
+%% macro test_for_all_pixelsizes(name, opts="")
+%% for ps in pixelsizes
+GP_TEST({{ name }}_{{ ps.suffix }}, "{{ opts }}")
+{
+{{ caller(ps) }}
+}
+GP_ENDTEST
+
+%% endfor
+%% endmacro
diff --git a/tests/core/GP_Blit.test.c b/tests/core/GP_Blit.test.c
new file mode 100644
index 0000000..cc20992
--- /dev/null
+++ b/tests/core/GP_Blit.test.c
@@ -0,0 +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) 2011 Tomas Gavenciak <gavento(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#include <GP_Tests.h>
+#include <GP_Common.h>
+#include <unistd.h>
+
+GP_SUITE(GP_Blit)
+
diff --git a/tests/core/GP_Convert.test.gen.c.t b/tests/core/GP_Convert.test.gen.c.t
new file mode 100644
index 0000000..e8180a9
--- /dev/null
+++ b/tests/core/GP_Convert.test.gen.c.t
@@ -0,0 +1,38 @@
+%% extends "base.test.c.t"
+
+%% block body
+#include "GP_Tests.h"
+#include "GP_Convert.h"
+#include "GP_TestingCore.h"
+
+GP_SUITE(GP_Convert)
+
+%% call(pt) test_for_all_pixeltypes("GP_ConvertPixel_for",
+ opts="loop_start=0, loop_end=4",
+ palette=False)
+ GP_Pixel p1 = GP_RandomColor(GP_PIXEL_{{ pt.name }});
+ GP_Pixel p2 = GP_ConvertPixel(p1, GP_PIXEL_{{ pt.name }}, GP_PIXEL_RGBA8888);
+ GP_Pixel p3 = GP_ConvertPixel(p2, GP_PIXEL_RGBA8888, GP_PIXEL_{{ pt.name }});
+ GP_CHECK_EqualColors(p1, GP_PIXEL_{{ pt.name }}, p3, GP_PIXEL_{{ pt.name }});
+ GP_CHECK_EqualColors(p1, GP_PIXEL_{{ pt.name }}, p2, GP_PIXEL_RGBA8888);
+%% endcall
+
+%% call(pt) test_for_all_pixeltypes("WhiteStaysWhite_via",
+ opts="loop_start=0, loop_end=4",
+ palette=False)
+ GP_Pixel p1 = GP_RGBToPixel(255, 255, 255, GP_PIXEL_RGB888);
+ GP_Pixel p2 = GP_RGB888ToPixel(p1, GP_PIXEL_{{ pt.name }});
+ GP_Pixel p3 = GP_PixelToRGB888(p2, GP_PIXEL_{{ pt.name }});
+ GP_CHECK_EqualColors(p1, GP_PIXEL_RGB888, p3, GP_PIXEL_RGB888);
+%% endcall
+
+%% call(pt) test_for_all_pixeltypes("BlackStaysBlack_via",
+ opts="loop_start=0, loop_end=4",
+ palette=False)
+ GP_Pixel p1 = GP_RGBToPixel(0, 0, 0, GP_PIXEL_RGB888);
+ GP_Pixel p2 = GP_RGB888ToPixel(p1, GP_PIXEL_{{ pt.name }});
+ GP_Pixel p3 = GP_PixelToRGB888(p2, GP_PIXEL_{{ pt.name }});
+ GP_CHECK_EqualColors(p1, GP_PIXEL_RGB888, p3, GP_PIXEL_RGB888);
+%% endcall
+
+%% endblock body
http://repo.or.cz/w/gfxprim.git/commit/35f5e233c07862deeb53bdf9407e2f83eaa1…
commit 35f5e233c07862deeb53bdf9407e2f83eaa15887
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Mon Aug 8 01:12:30 2011 +0200
Add note about "no bit-endian" value
diff --git a/include/core/GP_Pixel.h b/include/core/GP_Pixel.h
index 99793f1..45bcf19 100644
--- a/include/core/GP_Pixel.h
+++ b/include/core/GP_Pixel.h
@@ -62,12 +62,13 @@ typedef uint32_t GP_Pixel;
* used in a one bit variable in GP_Context
*/
-typedef enum {
- /* less significant bits contain pixels with lower indices */
+typedef enum {
+ /* less significant bits contain pixels with lower indices */
+ /* also used for irrelevant bit-endian */
GP_BIT_ENDIAN_LE = 0,
- /* more significant bits contain pixels with lower indices */
- GP_BIT_ENDIAN_BE,
-} GP_BIT_ENDIAN;
+ /* more significant bits contain pixels with lower indices */
+ GP_BIT_ENDIAN_BE,
+} GP_BIT_ENDIAN;
/*
* Description of one channel
http://repo.or.cz/w/gfxprim.git/commit/7ab0524f10cef16426c70802884bee6cda23…
commit 7ab0524f10cef16426c70802884bee6cda23d116
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Sun Aug 7 19:11:58 2011 +0200
Makesystem fix
diff --git a/gen.mk b/gen.mk
index ebb8e75..c5586c6 100644
--- a/gen.mk
+++ b/gen.mk
@@ -49,7 +49,7 @@ CLEAN+=$(ALL_GENERATED)
#
# Generated files depend on python generators and the template
#
-$(GENSOURCES) $(GENHEADERS): %: %.t $(PYTHON_FILES)
+$(GENSOURCES) $(RGENHEADERS): %: %.t $(PYTHON_FILES)
ifdef VERBOSE
${PYTHON} ${TOPDIR}/pylib/bin/generate_file.py -t $(TEMPLATE_DIR) "$@.t" "$@"
else
http://repo.or.cz/w/gfxprim.git/commit/89d7a5aa051caddcd3d17d27e17d7d4f4b96…
commit 89d7a5aa051caddcd3d17d27e17d7d4f4b9661fa
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Sat Aug 6 22:25:34 2011 +0200
Adapted make system to templates
diff --git a/gen.mk b/gen.mk
index 5df5588..ebb8e75 100644
--- a/gen.mk
+++ b/gen.mk
@@ -14,7 +14,7 @@ GENSOURCES=
endif
#
-# Headers goes into include/core/
+# Headers go into include/core/
#
INCLUDE_PREFIX=$(TOPDIR)/include/$(LIBNAME)/
RGENHEADERS=$(addprefix $(INCLUDE_PREFIX),$(GENHEADERS))
@@ -28,27 +28,32 @@ CSOURCES+=$(GENSOURCES)
# Make the genrated headers actually build
#
all: $(RGENHEADERS)
-
$(CSOURCES): $(RGENHEADERS)
#
-# And clean them
+# Base common templates location
+#
+TEMPLATE_DIR=$(TOPDIR)/pylib/templates/
+
+#
+# ALL templates and potential generated files (not generated automatically)
#
-CLEAN+=$(GENSOURCES) $(RGENHEADERS)
+ALL_TEMPLATES=$(shell find $(TOPDIR) -name '*.t')
+ALL_GENERATED=$(basename $(ALL_TEMPLATES))
#
-# Currently, just depend on all python files
+# And clean them
#
-GENERATORS=$(PYTHON_FILES)
+CLEAN+=$(ALL_GENERATED)
#
-# Generated files depend on python generators and libs
+# Generated files depend on python generators and the template
#
-%.gen.c %.gen.h: $(GENERATORS)
+$(GENSOURCES) $(GENHEADERS): %: %.t $(PYTHON_FILES)
ifdef VERBOSE
- ${PYTHON} ${TOPDIR}/pylib/bin/generate_file.py "$@"
+ ${PYTHON} ${TOPDIR}/pylib/bin/generate_file.py -t $(TEMPLATE_DIR) "$@.t" "$@"
else
@echo "GEN $@"
- @${PYTHON} ${TOPDIR}/pylib/bin/generate_file.py "$@"
+ @${PYTHON} ${TOPDIR}/pylib/bin/generate_file.py -t $(TEMPLATE_DIR) "$@.t" "$@"
endif
http://repo.or.cz/w/gfxprim.git/commit/938956d49a3627c5fe31c4fcf2ceeae5877f…
commit 938956d49a3627c5fe31c4fcf2ceeae5877fd11b
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Sat Aug 6 15:28:13 2011 +0200
Generators changed to templates
Now, the templates are just ordinary files with jinja2 markup
diff --git a/gfxprim_config.py b/gfxprim_config.py
index 157f93c..174f82d 100644
--- a/gfxprim_config.py
+++ b/gfxprim_config.py
@@ -12,6 +12,21 @@
# so a complete recompilation is required after any change.
#
+# Declared pixel sizes:
+PS_1BPP_LE = PixelSize(1, bit_endian=LE)
+PS_1BPP_BE = PixelSize(1, bit_endian=BE)
+PS_2BPP_LE = PixelSize(2, bit_endian=LE)
+PS_2BPP_BE = PixelSize(2, bit_endian=BE)
+PS_4BPP_LE = PixelSize(4, bit_endian=LE)
+PS_4BPP_BE = PixelSize(4, bit_endian=BE)
+PS_8BPP = PixelSize(8)
+PS_16BPP = PixelSize(16)
+PS_24BPP = PixelSize(24)
+PS_32BPP = PixelSize(32)
+# Experimental:
+PS_19BPP_LE = PixelSize(19, bit_endian=LE)
+
+
config = GfxPrimConfig(
# C name and bit-size of the GP_pixel type
@@ -19,36 +34,36 @@ config = GfxPrimConfig(
pixel_size = 32,
# List of pixel sizes (bpp), explicit on purpose
- sizes = [1, 2, 4, 8, 16, 32]
-
- # bit endians to generate, keep this fixed to LE, BE for now
- bit_endians = ['LE', 'BE']
+ pixelsizes = [PS_1BPP_LE, PS_1BPP_BE, PS_2BPP_LE, PS_2BPP_BE, PS_4BPP_LE, PS_4BPP_BE,
+ PS_8BPP, PS_16BPP, PS_24BPP, PS_32BPP,
+ PS_19BPP_LE,
+ ],
# List of PixelTypes, order defines the numbering.
# The "Undefined" type is added automatically.
- types = [
+ pixeltypes = [
#
# Standard RGB types
#
- PixelType(name='RGBx8888', size=32, chanslist=[
+ PixelType(name='RGBx8888', pixelsize=PS_32BPP, chanslist=[
('R', 16, 8),
('G', 8, 8),
('B', 0, 8)]),
- PixelType(name='RGBA8888', size=32, chanslist=[
+ PixelType(name='RGBA8888', pixelsize=PS_32BPP, chanslist=[
('R', 24, 8),
('G', 16, 8),
('B', 8, 8),
('A', 0, 8)]),
- PixelType(name='RGB888', size=24, chanslist=[
+ PixelType(name='RGB888', pixelsize=PS_24BPP, chanslist=[
('R', 16, 8),
('G', 8, 8),
('B', 0, 8)]),
- PixelType(name='RGB565', size=16, chanslist=[
+ PixelType(name='RGB565', pixelsize=PS_16BPP, chanslist=[
('R', 11, 5),
('G', 5, 6),
('B', 0, 5)]),
@@ -57,36 +72,36 @@ config = GfxPrimConfig(
# Palette types
#
- PixelType(name='P2', size=2, bit_endian='LE', chanslist=[
+ PixelType(name='P2', pixelsize=PS_2BPP_LE, chanslist=[
('P', 0, 2)]),
- PixelType(name='P4', size=4, bit_endian='LE', chanslist=[
+ PixelType(name='P4', pixelsize=PS_4BPP_LE, chanslist=[
('P', 0, 4)]),
- PixelType(name='P8', size=8, bit_endian='LE', chanslist=[
+ PixelType(name='P8', pixelsize=PS_8BPP, chanslist=[
('P', 0, 8)]),
#
# Gray-only pixel types
#
- PixelType(name='V1', size=1, bit_endian='LE', chanslist=[
+ PixelType(name='V1', pixelsize=PS_1BPP_LE, chanslist=[
('V', 0, 1)]),
- PixelType(name='V2', size=2, bit_endian='LE', chanslist=[
+ PixelType(name='V2', pixelsize=PS_2BPP_LE, chanslist=[
('V', 0, 2)]),
- PixelType(name='V4', size=4, bit_endian='LE', chanslist=[
+ PixelType(name='V4', pixelsize=PS_4BPP_LE, chanslist=[
('V', 0, 4)]),
- PixelType(name='V8', size=8, bit_endian='LE', chanslist=[
+ PixelType(name='V8', pixelsize=PS_8BPP, chanslist=[
('V', 0, 8)]),
#
# Experiments
#
- PixelType(name='VA12', size=4, bit_endian='BE', chanslist=[
+ PixelType(name='VA12', pixelsize=PS_4BPP_BE, chanslist=[
('A', 1, 2),
('V', 3, 1)]),
]
diff --git a/pylib/bin/generate_file.py b/pylib/bin/generate_file.py
index 40ce75c..bd0ddf1 100644
--- a/pylib/bin/generate_file.py
+++ b/pylib/bin/generate_file.py
@@ -6,20 +6,28 @@
# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
#
-import sys
-from gfxprim.generators import utils
-from gfxprim import die
+from gfxprim import render_utils
+import jinja2
+import logging as log
+from optparse import OptionParser
-usage = """Usage: %s [files_to_generate...]
-The files are matched only based on path suffixes, but written to given paths.
-"""
-def main():
- utils.load_generators()
- if len(sys.argv) <= 1:
- die(usage)
- for f in sys.argv[1:]:
- utils.generate_file(f)
+parser = OptionParser(usage="usage: %prog [options] <template> <output>")
+parser.add_option("-t", "--templates", dest="templates",
+ help="Directory with templates.", default=".")
+parser.add_option("-c", "--config", dest="config",
+ help="GfxPrim config file.", default=None)
+
+def main(options, args):
+ config = render_utils.load_gfxprimconfig(options.config)
+ assert config
+ log.info("Rendering template %s to %s", args[0], args[1])
+ render_utils.render_file(args[0], args[1], config, options.templates)
+
if __name__ == '__main__':
- main()
+ log.debug("Jinja version %s", jinja2.__version__)
+ (options, args) = parser.parse_args()
+ if len(args) != 2:
+ parser.error()
+ main(options, args)
diff --git a/pylib/gfxprim/generators/gfxprimconfig.py b/pylib/gfxprim/generators/gfxprimconfig.py
deleted file mode 100644
index 18d6df4..0000000
--- a/pylib/gfxprim/generators/gfxprimconfig.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#
-# gfxprim.generators.gfxprimconfig - Class for (global) GfxPrim configuration
-#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
-
-import os
-import logging as log
-from gfxprim.generators.pixeltype import PixelType
-
-class GfxPrimConfig(object):
- def __init__(self, pixel_type = None, pixel_size=None, sizes=None,
- bit_endians=None, types=None):
-
- self.pixel_type = pixel_type
- assert self.pixel_type
- assert isinstance(self.pixel_type, str)
-
- self.pixel_size = pixel_size
- assert isinstance(self.pixel_size, int)
- assert self.pixel_size % 8 == 0
- assert self.pixel_size > 0
-
- # Allowed bit-sizes of pixel types
- self.sizes = sizes
- assert isinstance(self.sizes, list)
- assert self.pixel_size in self.sizes
- assert all(( isinstance(i, int) and i > 0 and i <= self.pixel_size
- for i in self.sizes))
-
- # bit_endian values
- self.bit_endians = bit_endians
- assert isinstance(self.bit_endians, list)
- assert all(( i in ["LE", "BE"] for i in self.bit_endians))
-
- # Set of all encountered channel names
- self.channels = set()
-
- # Dictionary of all pixeltypes { name : PixelType }
- self.types_dict = {}
- # List of all PixelTypes in order. "Unknown" must be first.
- self.types = []
-
- self.add_pixeltype(PixelType("UNKNOWN", 0, [], bit_endian=bit_endians[0]))
- if types:
- for t in types:
- self.add_pixeltype(t)
-
- def add_pixeltype(self, pixeltype):
- "Add a PixelType and check its against the config"
-
- assert pixeltype not in self.types
- self.types.append(pixeltype)
- assert pixeltype.name not in self.types_dict
- self.types_dict[pixeltype.name] = pixeltype
- self.channels.update(set(pixeltype.chans.keys()))
- try:
- pixeltype.check_config(self)
- except AssertionError:
- log.error("Error checking PixelType %sn" % pixeltype.name)
-
diff --git a/pylib/gfxprim/generators/pixeltype.py b/pylib/gfxprim/generators/pixeltype.py
deleted file mode 100644
index b79f08f..0000000
--- a/pylib/gfxprim/generators/pixeltype.py
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# gfxprim.generators.pixeltype - Module with PixelType descrition class
-#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
-#
-
-import re
-
-
-def get_size_suffix(bpp, bit_endian):
- "Create pixel-size suffix (like 16BPP or 4BPP_LE)"
-
- size_suffix = '%dBPP' % (bpp)
- if bpp % 8 != 0:
- assert bit_endian
- if bit_endian:
- size_suffix += '_' + bit_endian
- return size_suffix
-
-
-class PixelType(object):
- """Representation of one GP_PixelType"""
-
- def __init__(self, name, size, chanslist, bit_endian=None):
- """`name` must be a valid C identifier
- `size` is type bit-width
- `bit_endian` is required in 1,2,4 BPP types to determine the order of
- pixels in a byte, either 'BE' or 'LE'
- `chanslist` is a list of triplets describing individual channels as
- [ (`chan_name`, `bit_offset`, `bit_size`) ]
- where `chan_name` is usually one of: R, G, B,
- V (value, used for grayscale), A (opacity)
- """
- assert re.match('A[A-Za-z][A-Za-z0-9_]*Z', name)
- self.name = name
- self.chanslist = chanslist
- self.chans = dict() # { chan_name: (offset, size) }
- self.size = size
- self.bit_endian = bit_endian
-
- if self.size == 0:
- self.size_suffix = "INVALID"
- else:
- self.size_suffix = get_size_suffix(self.size, self.bit_endian)
-
- # Verify channel bits for overlaps
- # also builds a bit-map of the PixelType
- self.bits = ['x']*size
- for c in chanslist:
- assert c[0] not in self.chans.keys()
- self.chans[c[0]] = c
- for i in range(c[1], c[1] + c[2]):
- assert(i<self.size)
- assert(self.bits[i]=='x')
- self.bits[i] = c[0]
-
- def valid_for_config(self, config):
- "Check PixelType compatibility with given GfxPrimConfig."
-
- # all types except UNKNOWN=0 must have one of these sizes
- if self.name != "UNKNOWN":
- assert(self.size in config.sizes)
-
- # bit_endian matters only for non-multiple-of-8 bpp
- if self.size % 8 != 0 or self.bit_endian is not None:
- assert self.bit_endian in config.bit_endians
-
- def __str__(self):
- return "<PixelType " + self.name + ">"
-
- def is_palette(self):
- return ('P' in self.chans)
-
diff --git a/pylib/gfxprim/gfxprimconfig.py b/pylib/gfxprim/gfxprimconfig.py
new file mode 100644
index 0000000..fd9088b
--- /dev/null
+++ b/pylib/gfxprim/gfxprimconfig.py
@@ -0,0 +1,62 @@
+#
+# gfxprim.generators.gfxprimconfig - Class for (global) GfxPrim configuration
+#
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+
+import os
+import logging as log
+from gfxprim.pixeltype import PixelType
+from gfxprim.pixelsize import PixelSize
+
+class GfxPrimConfig(object):
+ def __init__(self, pixel_type = None, pixel_size=None, pixelsizes=None,
+ pixeltypes=None):
+ """Initialize GfxPrim code generation config
+
+ pixel_type: name of C type for a pixel value
+ pixel_size: number of bits of pixel_type
+ pixelsizes: list of generated and allowed PixelSizes
+ pixeltypes: list of generated PixelTypes, not incl. UNKNOWN
+ """
+
+ self.pixel_type = pixel_type
+ assert self.pixel_type
+ assert isinstance(self.pixel_type, str)
+
+ self.pixel_size = pixel_size
+ assert isinstance(self.pixel_size, int)
+ assert self.pixel_size % 8 == 0
+ assert self.pixel_size > 0
+
+ # Allowed bit-sizes of pixel types
+ self.pixelsizes = pixelsizes
+ assert isinstance(self.pixelsizes, list)
+ assert self.pixel_size in [i.size for i in self.pixelsizes]
+ assert all((i.size <= self.pixel_size for i in self.pixelsizes))
+
+ # Set of all encountered channel names
+ self.channels = set()
+
+ # Dictionary of all pixeltypes { name : PixelType }
+ self.pixeltypes_dict = {}
+ # List of all PixelTypes in order. "Unknown" MUST be first.
+ self.pixeltypes = []
+
+ self.add_pixeltype(PixelType("UNKNOWN", PixelSize(0), []))
+ if pixeltypes:
+ for t in pixeltypes:
+ self.add_pixeltype(t)
+
+ def add_pixeltype(self, pixeltype):
+ "Add a PixelType and check its against the config"
+
+ assert pixeltype not in self.pixeltypes
+ self.pixeltypes.append(pixeltype)
+ assert pixeltype.name not in self.pixeltypes_dict
+ self.pixeltypes_dict[pixeltype.name] = pixeltype
+ self.channels.update(set(pixeltype.chans.keys()))
+ try:
+ pixeltype.valid_for_config(self)
+ except AssertionError:
+ log.error("Error checking PixelType %sn" % pixeltype.name)
+
diff --git a/pylib/gfxprim/pixelsize.py b/pylib/gfxprim/pixelsize.py
new file mode 100644
index 0000000..1586250
--- /dev/null
+++ b/pylib/gfxprim/pixelsize.py
@@ -0,0 +1,38 @@
+#
+# gfxprim.pixelsize
+#
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+#
+
+LE = "LE"
+BE = "BE"
+
+class PixelSize(object):
+ def __init__(self, size, bit_endian=None, suffix=None):
+ self.size = size
+ assert self.size >= 0
+
+ self.bit_endian = bit_endian
+ assert self.bit_endian in [None, LE, BE]
+ assert (bit_endian is not None) == self.needs_bit_endian()
+
+ self.suffix = suffix
+ if not self.suffix:
+ if self.size == 0:
+ self.suffix = "INVALID"
+ else:
+ if bit_endian:
+ self.suffix = '%dBPP_%s' % (size, bit_endian)
+ else:
+ self.suffix = '%dBPP' % (size,)
+
+ def needs_bit_endian(self):
+ return (self.size % 8) != 0
+
+ def description(self):
+ if self.bit_endian:
+ return "pixel size %d, bit endian %s, suffix %s" % (self.size,
+ self.bit_endian, self.suffix)
+ else:
+ return "pixel size %d, suffix %s" % (self.size, self.suffix)
+
diff --git a/pylib/gfxprim/pixeltype.py b/pylib/gfxprim/pixeltype.py
new file mode 100644
index 0000000..5cf356e
--- /dev/null
+++ b/pylib/gfxprim/pixeltype.py
@@ -0,0 +1,49 @@
+#
+# gfxprim.pixeltype - Module with PixelType descrition class
+#
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+#
+
+import re
+from gfxprim.pixelsize import PixelSize
+
+class PixelType(object):
+ """Representation of one GP_PixelType"""
+
+ def __init__(self, name, pixelsize, chanslist):
+ """`name` must be a valid C identifier
+ `pixelsize` is an instance of PixelSize
+ `chanslist` is a list of triplets describing individual channels as
+ [ (`chan_name`, `bit_offset`, `bit_size`) ]
+ where `chan_name` is usually one of: R, G, B,
+ V (value, used for grayscale), A (opacity)
+ """
+ assert re.match('A[A-Za-z][A-Za-z0-9_]*Z', name)
+ self.name = name
+ self.chanslist = chanslist
+ self.chans = dict() # { chan_name: (offset, size) }
+ self.pixelsize = pixelsize
+
+ # Verify channel bits for overlaps
+ # also builds a bit-map of the PixelType
+ self.bits = ['x'] * pixelsize.size
+ for c in chanslist:
+ assert c[0] not in self.chans.keys()
+ self.chans[c[0]] = c
+ for i in range(c[1], c[1] + c[2]):
+ assert(i < self.pixelsize.size)
+ assert(self.bits[i] == 'x')
+ self.bits[i] = c[0]
+
+ def valid_for_config(self, config):
+ "Check PixelType compatibility with given GfxPrimConfig."
+
+ # all types except UNKNOWN must have one of these sizes
+ if self.name != "UNKNOWN":
+ assert(self.pixelsize in config.pixelsizes)
+
+ def __str__(self):
+ return "<PixelType " + self.name + ">"
+
+ def is_palette(self):
+ return ('P' in self.chans)
diff --git a/pylib/gfxprim/render_utils.py b/pylib/gfxprim/render_utils.py
new file mode 100644
index 0000000..1051f3c
--- /dev/null
+++ b/pylib/gfxprim/render_utils.py
@@ -0,0 +1,73 @@
+#
+# gfxprim.render_utils
+#
+
+import jinja2
+import logging as log
+import os
+import time
+import re
+
+def create_environment(config, template_dir):
+ env = jinja2.Environment(
+ line_statement_prefix = "%%",
+ undefined = jinja2.StrictUndefined,
+ loader = jinja2.FileSystemLoader(template_dir))
+ env.globals['undefined'] = jinja2.StrictUndefined()
+ env.globals['pixelsizes'] = config.pixelsizes
+ env.globals['pixeltypes'] = config.pixeltypes
+ env.globals['gfxprim_config'] = config
+ return env
+
+
+def render_file(source, result, config, template_dir):
+ env = create_environment(config, template_dir)
+ with open(source) as source_file:
+ source_text = source_file.read()
+ # Hack to preserve empty lines before %% line_statement
+ source_text = re.sub("nn[ t]*%%", "n{{''}}n%%", source_text)
+
+ tmpl = env.from_string(source_text)
+ result_text = tmpl.render(
+ date = time.ctime(),
+ target = result,
+ template = source,
+ header_guard = + os.path.split(result)[1].upper().replace('.', '_').replace('-', '_'),
+ )
+ with open(result, "w") as result_file:
+ result_file.write(result_text)
+
+
+def load_gfxprimconfig(config_file = None):
+ """Initialize GfxPrimConfig from a given or guessed config file.
+ Looks for the file by parameter, in env['PIXELTYPE_DEFS'] and
+ in dir(__file__)/../../gfxprim_config.py, in that order.
+
+ Returns GfxPrimConfig or None on error
+ """
+
+ if not config_file:
+ config_file = os.environ.get("PIXELTYPE_DEFS", None)
+ if not config_file:
+ path = os.path.dirname(os.path.abspath(__file__))
+ config_file = os.path.abspath(
+ os.path.join(path, "..", "..", "gfxprim_config.py"))
+ if not os.path.exists(config_file):
+ log.error("WARNING: GfxPrimConfig file %s not found!n",
+ config_file)
+ return None
+
+ from gfxprim.pixeltype import PixelType
+ from gfxprim.pixelsize import PixelSize, LE, BE
+ from gfxprim.gfxprimconfig import GfxPrimConfig
+ l = {"PixelType": PixelType,
+ "PixelSize": PixelSize,
+ "LE": LE,
+ "BE": BE,
+ "GfxPrimConfig": GfxPrimConfig
+ }
+ execfile(config_file, globals(), l)
+ config = l["config"]
+ return config
+
diff --git a/pylib/templates/base.c.t b/pylib/templates/base.c.t
new file mode 100644
index 0000000..57c957a
--- /dev/null
+++ b/pylib/templates/base.c.t
@@ -0,0 +1,15 @@
+/*
+ * {{ target }}
+ *
+ * GENERATED on {{ date }} from {{ template }}
+ * DO NOT MODIFY THIS FILE DIRECTLY!
+ *
+ * {% block descr %}{% endblock %}
+ */
+
+%% block pre_body_guard
+%% endblock pre_body_guard
+%% block body
+%% endblock body
+%% block post_body_guard
+%% endblock post_body_guard
diff --git a/pylib/templates/base.h.t b/pylib/templates/base.h.t
new file mode 100644
index 0000000..8eb9140
--- /dev/null
+++ b/pylib/templates/base.h.t
@@ -0,0 +1,11 @@
+%% extends "body.c.h"
+
+%% block pre_body_guard
+#ifndef {{ header_guard }}
+#define {{ header_guard }}
+
+%% endblock pre_body_guard
+
+%% block post_body_guard
+#endif /* {{ header_guard }} */
+%% endblock post_body_guard
http://repo.or.cz/w/gfxprim.git/commit/58f99bbee8cf3eac5142540013c8309267b8…
commit 58f99bbee8cf3eac5142540013c8309267b8f55d
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Mon Aug 1 22:43:27 2011 +0200
Whitespace/style cleanup, replace die with logging
diff --git a/pylib/bin/generate_file.py b/pylib/bin/generate_file.py
index 086f801..40ce75c 100644
--- a/pylib/bin/generate_file.py
+++ b/pylib/bin/generate_file.py
@@ -3,7 +3,7 @@
# Main source file generating script
# Collects all known file generators from the generators/ directory
#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
#
import sys
diff --git a/pylib/gfxprim/README b/pylib/gfxprim/README
index 17c8d28..2b7baf7 100644
--- a/pylib/gfxprim/README
+++ b/pylib/gfxprim/README
@@ -21,7 +21,7 @@ typedef enum GP_PixelType {
--------------------------------------------------------------------------------
void GP_Pixel_Print_<TYPE>(GP_Pixel p);
-#define GP_Pixel_GET_<CHAN>_<TYPE>(p)
+#define GP_Pixel_GET_<CHAN>_<TYPE>(p)
--------------------------------------------------------------------------------
.For each pixel type TYPE, pixel adress and bit-offset:
@@ -80,7 +80,7 @@ GP_Pixel_Scale.gen.h
GP_Blit.gen.[ch]
~~~~~~~~~~~~~~~~~~~~~~
-TODO: Blitting magic
+TODO: Blitting magic
.Blits within PixelTypes (defined only by bpp):
diff --git a/pylib/gfxprim/__init__.py b/pylib/gfxprim/__init__.py
index 7b3b919..a5fe956 100644
--- a/pylib/gfxprim/__init__.py
+++ b/pylib/gfxprim/__init__.py
@@ -1,16 +1,4 @@
-# GfxPrim auxiliary libraries
-# Contains C code-generation
+# GfxPrim auxiliary libraries for C-code generation
#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
#
-
-import sys
-
-def die(msg):
- "Exit(1) with a message."
- if not msg.endswith('n'):
- msg += 'n'
- sys.stderr.write(msg)
- sys.exit(1)
-
-
diff --git a/pylib/gfxprim/generators/__init__.py b/pylib/gfxprim/generators/__init__.py
index bffe6ea..431c9ef 100644
--- a/pylib/gfxprim/generators/__init__.py
+++ b/pylib/gfxprim/generators/__init__.py
@@ -1,7 +1,9 @@
#
-# gfxprim.generate
+# gfxprim.generate - global config and its loading
#
+import os
+import sys
# Global config instance
@@ -10,22 +12,25 @@ config = None
def load_gfxprim_config(config_file = None):
"""Initialize GfxPrimConfig from a given or guessed config file.
- Looks for the file by parameter, in env['PIXELTYPE_DEFS'] and
+ Looks for the file by parameter, in env['PIXELTYPE_DEFS'] and
in dir(__file__)/../../../gfxprim_config.py, in that order.
"""
- if not defs_file:
- defs_file = os.environ.get("PIXELTYPE_DEFS", None)
- if not defs_file:
+
+ if not config_file:
+ config_file = os.environ.get("PIXELTYPE_DEFS", None)
+ if not config_file:
path = os.path.dirname(os.path.abspath(__file__))
- defs_file = os.path.abspath(
+ config_file = os.path.abspath(
os.path.join(path, "..", "..", "..", "gfxprim_config.py"))
- if not os.path.exists(defs_file):
- sys.stderr.write("WARNING: GfxPrimConfig file %s not found!n" % defs_file)
+ if not os.path.exists(config_file):
+ sys.stderr.write("WARNING: GfxPrimConfig file %s not found!n" %
+ config_file)
- from gfxprim.generate.pixeltype import PixelType
- from gfxprim.generate.gfxprimconfig import GfxPrimConfig
+ global config
+ assert not config
+ from gfxprim.generators.pixeltype import PixelType
+ from gfxprim.generators.gfxprimconfig import GfxPrimConfig
l = {"PixelType": PixelType, "GfxPrimConfig": GfxPrimConfig}
- execfile(defs_file, globals(), l)
-
+ execfile(config_file, globals(), l)
config = l["config"]
assert config
diff --git a/pylib/gfxprim/generators/core/gen_blit.py b/pylib/gfxprim/generators/core/gen_blit.py
index 78be0f8..0e3196b 100644
--- a/pylib/gfxprim/generators/core/gen_blit.py
+++ b/pylib/gfxprim/generators/core/gen_blit.py
@@ -1,18 +1,21 @@
# Module generating C source and headers for various PixelTypes
# - submodule for blit and friends
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
from gfxprim.generators.utils import *
+
## all generated direct blits, for generating GP_Blit() and others
generated_blits = []
+
# TODO: adapt for both bit-endianness (in-byte prefix and suffix)
# WARN: assuming little-endian in sub-byte pixels order (probably)
def gen_blit_same_t(size, size_suffix, header, code):
- "Generate a function blitting the same type of pixel."
- "Only depends on bpp (bit size), size_suffix must be"
- "of form 8BPP, 2BPP_LE and the like."
+ """Generate a function blitting the same type of pixel.
+ Only depends on bpp (bit size), size_suffix must be
+ of form 8BPP, 2BPP_LE and the like.
+ """
header.rbody(
"n/*** Blit preserving type, variant for {{ size_suffix }} ***n"
diff --git a/pylib/gfxprim/generators/core/gen_convert.py b/pylib/gfxprim/generators/core/gen_convert.py
index 84c2b69..f128824 100644
--- a/pylib/gfxprim/generators/core/gen_convert.py
+++ b/pylib/gfxprim/generators/core/gen_convert.py
@@ -1,5 +1,5 @@
# Module generating C source and headers for various PixelType conversions
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
from gfxprim.generators.pixeltype import pixeltypes, channels
from gfxprim.generators.utils import hmask
@@ -18,7 +18,7 @@ def gen_fixedtype_to_type(fixedtype, header, code):
" GP_ABORT("Cannot convert to GP_PIXEL_UNKNOWN");n"
" break;n"
"{% elif tf.is_palette() %}"
- " case GP_PIXEL_{{ tf.name }}:n"
+ " case GP_PIXEL_{{ tf.name }}:n"
" GP_ABORT("Cannot convert to palette type {{ tf.name }}");n"
" break;n"
"{% else %}"
@@ -47,7 +47,7 @@ def gen_type_to_fixedtype(fixedtype, header, code):
" GP_ABORT("Cannot convert from GP_PIXEL_UNKNOWN");n"
" break;n"
"{% elif sf.is_palette() %}"
- " case GP_PIXEL_{{ sf.name }}:n"
+ " case GP_PIXEL_{{ sf.name }}:n"
" GP_ABORT("Cannot convert from palette type {{ sf.name }} (yet)");n"
" break;n"
"{% else %}"
@@ -74,40 +74,40 @@ def gen_convert_to(f1, f2, header, code):
" * macro storing p1 ({{ f1.name }} at bit-offset o1) in p2 ({{ f2.name }} at bit-offset o2),n"
" * the relevant part of p2 is assumed to be clear (zero) */nn"
"#define GP_Pixel_{{ f1.name }}_TO_{{ f2.name }}_OFFSET(p1, o1, p2, o2) do {
"
-
+
## set each of <TARGET> channels
"{% for c2 in f2.chanslist %}"
-
- # case 1: just copy a channel
+
+ # case 1: just copy a channel
"{%- if c2[0] in f1.chans.keys() %}{% set c1 = f1.chans[c2[0]] %}"
" /* {{ c2[0] }}:={{ c1[0] }} */ GP_SET_BITS({{c2[1]}}+o2, {{c2[2]}}, p2,
"
" GP_SCALE_VAL_{{c1[2]}}_{{c2[2]}}(GP_GET_BITS({{c1[1]}}+o1, {{c1[2]}}, p1)));
"
-
+
# case 2: set A to full opacity (not present in source)
"{% elif c2[0]=='A' %}"
" /* A:={{ hmask(c2[2]) }} */GP_SET_BITS({{c2[1]}}+o2, {{c2[2]}}, p2, {{ hmask(c2[2]) }});
"
-
- # case 3: calculate V as average of RGB
+
+ # case 3: calculate V as average of RGB
"{% elif c2[0]=='V' and set('RGB').issubset(set(f1.chans.keys())) %}"
" /* V:=RGB_avg */ GP_SET_BITS({{c2[1]}}+o2, {{c2[2]}}, p2, (
"
"{% for c1 in [f1.chans['R'], f1.chans['G'], f1.chans['B']] %}"
" /* {{c1[0]}} */ GP_SCALE_VAL_{{c1[2]}}_{{c2[2]}}(GP_GET_BITS({{c1[1]}}+o1, {{c1[2]}}, p1)) +
"
"{% endfor %}"
" 0)/3);
"
-
- #- case 4: set each RGB to V
+
+ #- case 4: set each RGB to V
"{% elif c2[0] in 'RGB' and 'V' in f1.chans.keys() %}{% set c1 = f1.chans['V'] %}"
" /* {{ c2[0] }}:=V */ GP_SET_BITS({{c2[1]}}+o2, {{c2[2]}}, p2,
"
" GP_SCALE_VAL_{{c1[2]}}_{{c2[2]}}(GP_GET_BITS({{c1[1]}}+o1, {{c1[2]}}, p1)));
"
-
- # invalid mapping (there should be none, but who knows ...)
+
+ # invalid mapping (there should be none, but who knows ...)
"{% else %} {{ raise(Error('channel conversion' +f1.name+ ' to ' +f2.name+ ' not supported')) }}"
-
+
# end of the loop
"{% endif %}"
"{% endfor %}"
"} while (0)nn"
-
+
# add version without offsets
"/* a version without offsets */n"
"#define GP_Pixel_{{ f1.name }}_TO_{{ f2.name }}(p1, p2) "
diff --git a/pylib/gfxprim/generators/core/gen_getputpixel.py b/pylib/gfxprim/generators/core/gen_getputpixel.py
index f360ec0..14e455d 100644
--- a/pylib/gfxprim/generators/core/gen_getputpixel.py
+++ b/pylib/gfxprim/generators/core/gen_getputpixel.py
@@ -1,6 +1,6 @@
# Module generating C source and headers for get/putpixel
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
-# 2011 - Cyril Hrubis <metan(a)ucw.cz>
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+# 2011 - Cyril Hrubis <metan(a)ucw.cz>
from gfxprim.generators.utils import *
diff --git a/pylib/gfxprim/generators/core/gen_pixeltype.py b/pylib/gfxprim/generators/core/gen_pixeltype.py
index 680a476..942a1a2 100644
--- a/pylib/gfxprim/generators/core/gen_pixeltype.py
+++ b/pylib/gfxprim/generators/core/gen_pixeltype.py
@@ -1,5 +1,5 @@
# Module generating C source and headers for various PixelTypes
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
from gfxprim.generators.pixeltype import pixeltypes, channels
from gfxprim.generators.utils import j2render as r, hmask
@@ -28,7 +28,7 @@ def gen_GP_PixelType(header, code):
"Generates definition of GP_PixelType enum"
pt_by_num = sorted([(t.number, t) for t in pixeltypes.values()])
sorted_pts = [t[1] for t in pt_by_num]
- pt_max = len(sorted_pts)
+ pt_max = len(sorted_pts)
header.rbody(
"/* List of all known pixel types */n"
"typedef enum GP_PixelType {n"
diff --git a/pylib/gfxprim/generators/core/make_GP_Blit.py b/pylib/gfxprim/generators/core/make_GP_Blit.py
index 03057b0..b10c927 100644
--- a/pylib/gfxprim/generators/core/make_GP_Blit.py
+++ b/pylib/gfxprim/generators/core/make_GP_Blit.py
@@ -2,7 +2,7 @@
#
# Generators for GP_Pixel_Blit.gen.c and GP_Pixel_Blit.gen.h
#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
#
from gfxprim.generators.generator import *
diff --git a/pylib/gfxprim/generators/core/make_GP_Convert.py b/pylib/gfxprim/generators/core/make_GP_Convert.py
index 03b682c..99e4d0b 100644
--- a/pylib/gfxprim/generators/core/make_GP_Convert.py
+++ b/pylib/gfxprim/generators/core/make_GP_Convert.py
@@ -5,7 +5,7 @@
# GP_Convert.gen.c, GP_Convert.gen.h
# GP_Convert_Scale.gen.h
#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
#
from gfxprim.generators.generator import *
@@ -42,7 +42,7 @@ def core_GP_Convert_gen_h(h, c):
h.rhead('#include "GP_Common.h"n');
h.rhead('#include "GP_Context.h"n');
h.rhead('#include "GP_Pixel.h"nn');
-
+
c.rhead('#include "GP_Convert.h"nn');
## two base types for conversions
@@ -54,7 +54,7 @@ def core_GP_Convert_gen_h(h, c):
if not t.is_palette() and t.number != 0:
gen_convert_to(t, bt, h, c)
gen_convert_to(bt, t, h, c)
-
+
## Just experimental conversion macros
gen_convert_to(pixeltypes['RGB565'], pixeltypes['RGBA8888'], h, c)
gen_convert_to(pixeltypes['RGBA8888'], pixeltypes['V2'], h, c)
diff --git a/pylib/gfxprim/generators/core/make_GP_Pixel.py b/pylib/gfxprim/generators/core/make_GP_Pixel.py
index fd5b16c..c7f7ee1 100644
--- a/pylib/gfxprim/generators/core/make_GP_Pixel.py
+++ b/pylib/gfxprim/generators/core/make_GP_Pixel.py
@@ -5,7 +5,7 @@
# GP_Pixel.gen.c, GP_Pixel.gen.h
# GP_Pixel_Access.gen.h
#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
#
from gfxprim.generators.generator import *
@@ -66,7 +66,7 @@ def core_GP_Pixel_Scale_gen(h):
for bit_endian in bit_endians:
if (bpp < 8) or (bit_endian == bit_endians[0]):
gen_get_pixel_addr_bpp(bpp, get_size_suffix(bpp, bit_endian), h)
-
+
# Per-bpp adress/offset macros
for bpp in bitsizes:
for bit_endian in bit_endians:
diff --git a/pylib/gfxprim/generators/generator.py b/pylib/gfxprim/generators/generator.py
index df2e8c9..ca6df56 100644
--- a/pylib/gfxprim/generators/generator.py
+++ b/pylib/gfxprim/generators/generator.py
@@ -1,24 +1,29 @@
#
-# Module with templates and tools for writing generated code,
-# especially C source and headers
+# gfxprim.generators.generator - Base and C (.c/.h) classes for code generators
#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
#
-import sys, os, time
-from gfxprim import die
+import os
+import time
+import logging as log
from gfxprim.generators.utils import j2render
+
# List of known CodeGenerator instances
+
known_generators = []
+
class CodeGenerator(object):
- "Args:n"
- "fname (required) - name of the generated file (without path)n"
- "fdir ('') - directory prefix to matchn"
- "generating_f (None) - user function called in generate(), should generate contentn"
- "register (False) - if true, register in global generator listn"
+ """Args:
+ fname (required) - name of the generated file (without path)
+ fdir ('') - directory prefix to match
+ generating_f (None) - user function called in generate(), should generate content
+ register (False) - if true, register in global generator list
+ """
generator_attributes__ = ['generating_f', 'register']
+
def __init__(self, **kwargs):
self.name = kwargs.pop('name')
self.fdir, self.fname = os.path.split(self.name)
@@ -29,20 +34,28 @@ class CodeGenerator(object):
self.foot = []
self.setargs(**kwargs)
if kwargs:
- die('Unknown arguments to CodeGenerator: %s' & str(kwargs.keys()))
+ log.fatal('Unknown arguments to CodeGenerator: %s' % str(kwargs.keys()))
+
def setargs(self, **kwargs):
for i in self.generator_attributes__:
- if i in kwargs: self.__setattr__(i, kwargs.pop(i))
+ if i in kwargs:
+ self.__setattr__(i, kwargs.pop(i))
+
def matches_path(self, path):
return path.endswith(self.name)
+
def r(self, s, *args, **kwargs):
return j2render(s, g=self, *args, **kwargs)
+
def rhead(self, *args, **kwargs):
self.head.append(self.r(*args, **kwargs))
+
def rbody(self, *args, **kwargs):
self.body.append(self.r(*args, **kwargs))
+
def rfoot(self, *args, **kwargs):
self.foot.append(self.r(*args, **kwargs))
+
def generate(self, run_gen_base=True):
self.head = []
self.body = []
@@ -52,13 +65,16 @@ class CodeGenerator(object):
# Run user-specified generation f
if self.generating_f:
f, pos, params = self.generating_f
- args = [self if i == pos else global_null_generator for i in range(params)]
+ args = [self if i == pos else global_null_generator
+ for i in range(params)]
f(*args)
return ''.join(self.head + self.body + self.foot)
+
def gen_base(self):
"Fill basic subclass-dependent content into head/body/foot"
pass
+
class NullGenerator(CodeGenerator):
def rhead(self, *args, **kwargs): pass
def rbody(self, *args, **kwargs): pass
@@ -68,15 +84,20 @@ class NullGenerator(CodeGenerator):
global_null_generator = NullGenerator(name='null_generator')
+
class CCodeGenerator(CodeGenerator):
- "Args:n"
- "authors ([]) - list of author creditsn"
- "descr ("") - (multiline) file descriptionn"
- generator_attributes__ = ['authors', 'descr'] + CodeGenerator.generator_attributes__
+ """Args:
+ authors ([]) - list of author credits
+ descr ("") - (multiline) file description
+ """
+ generator_attributes__ = (['authors', 'descr'] +
+ CodeGenerator.generator_attributes__)
+
def __init__(self, **kwargs):
self.authors = []
self.descr = ""
super(CCodeGenerator, self).__init__(**kwargs)
+
def gen_base(self):
super(CCodeGenerator, self).gen_base()
self.head.append(self.r(
@@ -94,14 +115,18 @@ class CCodeGenerator(CodeGenerator):
"{% endfor %}"
" */nn", date = time.ctime()))
+
class CSourceGenerator(CCodeGenerator):
def __init__(self, **kwargs):
super(CSourceGenerator, self).__init__(**kwargs)
+
class CHeaderGenerator(CCodeGenerator):
def __init__(self, **kwargs):
super(CHeaderGenerator, self).__init__(**kwargs)
- self.hdef = 'GP_HEADER_' + self.name.replace('.', '_').replace('/', '_').upper()
+ self.hdef = ('GP_HEADER_' +
+ self.name.replace('.', '_').replace('/', '_').upper())
+
def gen_base(self):
super(CHeaderGenerator, self).gen_base()
self.head.append(self.r(
@@ -110,15 +135,17 @@ class CHeaderGenerator(CCodeGenerator):
self.foot.append(self.r(
"#endif /* {{ g.hdef }} */n"))
+
def generator(*args, **kwargs):
- "Decorate functions to be content-creator for given generators.n"
- "By default also registers the generator to pool of known generators."
+ """Decorate functions to be content-creator for given generators.
+ By default also registers the generator to pool of known generators.
+ """
register = kwargs.pop('register', True)
def decorate(f):
for i in range(len(args)):
kwargs['generating_f'] = (f, i, len(args))
args[i].setargs(**kwargs)
if register:
- known_generators.append(args[i])
+ known_generators.append(args[i])
return f
return decorate
diff --git a/pylib/gfxprim/generators/gfxprimconfig.py b/pylib/gfxprim/generators/gfxprimconfig.py
index 60546d0..18d6df4 100644
--- a/pylib/gfxprim/generators/gfxprimconfig.py
+++ b/pylib/gfxprim/generators/gfxprimconfig.py
@@ -1,13 +1,15 @@
#
-# gfxprimconfig.py - Class for (global) GfxPrim configuration
+# gfxprim.generators.gfxprimconfig - Class for (global) GfxPrim configuration
#
# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
-import re, os, sys
-
+import os
+import logging as log
+from gfxprim.generators.pixeltype import PixelType
+
class GfxPrimConfig(object):
def __init__(self, pixel_type = None, pixel_size=None, sizes=None,
- bit_endians=None, types=[]):
+ bit_endians=None, types=None):
self.pixel_type = pixel_type
assert self.pixel_type
@@ -37,10 +39,11 @@ class GfxPrimConfig(object):
self.types_dict = {}
# List of all PixelTypes in order. "Unknown" must be first.
self.types = []
-
+
self.add_pixeltype(PixelType("UNKNOWN", 0, [], bit_endian=bit_endians[0]))
- for t in types:
- self.add_pixeltype(t)
+ if types:
+ for t in types:
+ self.add_pixeltype(t)
def add_pixeltype(self, pixeltype):
"Add a PixelType and check its against the config"
@@ -53,5 +56,5 @@ class GfxPrimConfig(object):
try:
pixeltype.check_config(self)
except AssertionError:
- sys.stderr.write("Error checking PixelType %sn" % pixeltype.name)
+ log.error("Error checking PixelType %sn" % pixeltype.name)
diff --git a/pylib/gfxprim/generators/make_collected_tests.py b/pylib/gfxprim/generators/make_collected_tests.py
index d690dac..04af1eb 100644
--- a/pylib/gfxprim/generators/make_collected_tests.py
+++ b/pylib/gfxprim/generators/make_collected_tests.py
@@ -2,38 +2,42 @@
#
# Script generating collected_tests.gen.c
#
-# Scrapes the target directory for .test.c files, looks for
-# GP_TEST and GP_SUITE macros and generates code creating all the
+# Scrapes the target directory for .test.c files, looks for
+# GP_TEST and GP_SUITE macros and generates code creating all the
# tests and the suite
#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
#
+
# Also fixed in tests.mk
collected_tests_file = 'collected_tests.gen.c'
-import os, re, glob
+import os
+import re
+import glob
+import logging as log
from gfxprim.generators.generator import *
-def warn(msg_s, fname=None, line=None):
- msg('W', msg_s, fname, line)
-def msg(prefix, msg_s, fname=None, line=None):
- s = '[' + prefix
- if fname:
- s += ' ' + fname
- if line:
- s += ':%d'%line
- s += '] '
- sys.stderr.write(s + msg_s + 'n')
+def warn(msg, fname=None, line=None):
+ "Warning including file and line info"
+ assert fname
+ loc = "[%s] " % fname
+ if line:
+ loc = "[%s:%d] " % (fname, line)
+ log.warning(loc + msg)
+
testfile_patterns = ['*.test.c', '*.test.gen.c']
-suites = {} # {"suitename":["testname":{test_parameters}]}
+# {"suitename":["testname":{test_parameters}]}
+suites = {}
suite_re = re.compile("A\s*GP_SUITE\((.*)\)\s*Z")
test_re = re.compile("A\s*GP_TEST\((.*)\)\s*Z")
+
@generator(CHeaderGenerator(name = collected_tests_file),
descr = 'Code creating the tests and suites for tests collected '
'from .test.c files',
@@ -50,7 +54,7 @@ def tests_collected_tests(c):
warn('No .test.c files found in "%s".' % c.fdir)
if not suites:
warn('No suites found, generating empty testsuite.')
-
+
c.rhead("#include <check.h>nn")
for suite, tests in suites.iteritems():
@@ -92,6 +96,7 @@ def tests_collected_tests(c):
"{% endfor %}"
"}nn", suites=suites)
+
def find_GP_directive(name, regexp, l, fname='unknown', line=0):
"Looks for a given GP_* directive, parses args if any, "
"retuns (name, dict_of_args) or (None, None) if not found."
@@ -107,10 +112,11 @@ def find_GP_directive(name, regexp, l, fname='unknown', line=0):
s = 'dict( ' + d[1].strip(" tn"") + ' )'
args = eval(s)
except:
- die("error parsing arguments: %r" % s, fname, line)
+ log.fatal("error parsing arguments: %r" % s, fname, line)
return d[0].strip(), args
return None, None
+
def find_tests(f, fname):
"Finds all tests in a file."
suite = None
diff --git a/pylib/gfxprim/generators/pixeltype.py b/pylib/gfxprim/generators/pixeltype.py
index 18531fa..b79f08f 100644
--- a/pylib/gfxprim/generators/pixeltype.py
+++ b/pylib/gfxprim/generators/pixeltype.py
@@ -1,23 +1,19 @@
#
-# gfxprim.pixeltype - Module with PixelType descrition class
+# gfxprim.generators.pixeltype - Module with PixelType descrition class
#
# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
#
import re
-import os
-import sys
-import gfxprim
-from gfxprim import die
-def get_size_suffix(self.bpp, bit_endian):
+def get_size_suffix(bpp, bit_endian):
"Create pixel-size suffix (like 16BPP or 4BPP_LE)"
- assert bpp in self.sizes
- assert bit_endian in self.bit_endians
size_suffix = '%dBPP' % (bpp)
- if bpp < 8:
+ if bpp % 8 != 0:
+ assert bit_endian
+ if bit_endian:
size_suffix += '_' + bit_endian
return size_suffix
@@ -30,14 +26,14 @@ class PixelType(object):
`size` is type bit-width
`bit_endian` is required in 1,2,4 BPP types to determine the order of
pixels in a byte, either 'BE' or 'LE'
- `chanslist` is a list of triplets describing individual channels as
+ `chanslist` is a list of triplets describing individual channels as
[ (`chan_name`, `bit_offset`, `bit_size`) ]
where `chan_name` is usually one of: R, G, B,
V (value, used for grayscale), A (opacity)
"""
assert re.match('A[A-Za-z][A-Za-z0-9_]*Z', name)
- self.name = name
- self.chanslist = chanslist
+ self.name = name
+ self.chanslist = chanslist
self.chans = dict() # { chan_name: (offset, size) }
self.size = size
self.bit_endian = bit_endian
@@ -49,14 +45,14 @@ class PixelType(object):
# Verify channel bits for overlaps
# also builds a bit-map of the PixelType
- self.bits = ['x']*size
+ self.bits = ['x']*size
for c in chanslist:
assert c[0] not in self.chans.keys()
self.chans[c[0]] = c
- for i in range(c[1],c[1]+c[2]):
- assert(i<self.size)
- assert(self.bits[i]=='x')
- self.bits[i] = c[0]
+ for i in range(c[1], c[1] + c[2]):
+ assert(i<self.size)
+ assert(self.bits[i]=='x')
+ self.bits[i] = c[0]
def valid_for_config(self, config):
"Check PixelType compatibility with given GfxPrimConfig."
@@ -66,8 +62,8 @@ class PixelType(object):
assert(self.size in config.sizes)
# bit_endian matters only for non-multiple-of-8 bpp
- if size % 8 != 0 or bit_endian is not None:
- assert bit_endian in config.bit_endians
+ if self.size % 8 != 0 or self.bit_endian is not None:
+ assert self.bit_endian in config.bit_endians
def __str__(self):
return "<PixelType " + self.name + ">"
diff --git a/pylib/gfxprim/generators/utils.py b/pylib/gfxprim/generators/utils.py
index fe5abb4..15d7013 100644
--- a/pylib/gfxprim/generators/utils.py
+++ b/pylib/gfxprim/generators/utils.py
@@ -1,17 +1,20 @@
-# Module with templates and tools for writing generated code,
-# especially C source and headers
#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+# gfxprim.generators.utils - Module with templates and tools for writing
+# generated code, especially C source and headers.
#
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+#
+
-import sys, os, time
-import jinja2
-from gfxprim import die
+import jinja2
+import logging as log
def j2render(tmpl, **kw):
"Internal helper to render jinja2 templates (with StrictUndefined)"
t2 = tmpl.rstrip('n') # Jinja strips the last 'n', so add these later
- return jinja2.Template(t2, undefined=jinja2.StrictUndefined).render(**kw) + tmpl[len(t2):]
+ return jinja2.Template(t2, undefined=jinja2.StrictUndefined).render(**kw) + + tmpl[len(t2):]
+
def load_generators():
"Load all modules containig generators to allow them to register"
@@ -20,23 +23,24 @@ def load_generators():
import gfxprim.generators.core.make_GP_Pixel
import gfxprim.generators.core.make_GP_Blit
import gfxprim.generators.core.make_GP_Convert
- pass
+
def generate_file(fname):
- from gfxprim.generators.generator import known_generators
"Function trying to generate file `fname` using matching known generator."
+ from gfxprim.generators.generator import known_generators
matches = []
for k in known_generators:
if k.matches_path(fname):
matches.append(k)
if len(matches) == 0:
- die("No known generators match '%s'" % (fname,))
+ log.fatal("No known generators match '%s'" % (fname,))
if len(matches) > 1:
- die("Multiple generators match '%s': %s" % (fname, str(matches)))
+ log.fatal("Multiple generators match '%s': %s" % (fname, str(matches)))
s = matches[0].generate()
with open(fname, "wt") as f:
f.write(s)
-def hmask(bits):
+
+def hmask(bits):
"Helper returning hex mask for that many bits"
return hex((1<<bits)-1).rstrip('L')
diff --git a/pylib/gfxprim/pylint.conf b/pylib/gfxprim/pylint.conf
new file mode 100644
index 0000000..0fd9fb9
--- /dev/null
+++ b/pylib/gfxprim/pylint.conf
@@ -0,0 +1,236 @@
+[MASTER]
+
+# Specify a configuration file.
+#rcfile=
+
+# Python code to execute, usually for sys.path manipulation such as
+# pygtk.require().
+#init-hook=
+
+# Profiled execution.
+profile=no
+
+# Add <file or directory> to the black list. It should be a base name, not a
+# path. You may set this option multiple times.
+ignore=CVS
+
+# Pickle collected data for later comparisons.
+persistent=yes
+
+# List of plugins (as comma separated values of python modules names) to load,
+# usually to register additional checkers.
+load-plugins=
+
+
+[MESSAGES CONTROL]
+
+# Enable the message, report, category or checker with the given id(s). You can
+# either give multiple identifier separated by comma (,) or put this option
+# multiple time.
+#enable=
+
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifier separated by comma (,) or put this option
+# multiple time.
+disable=C0111,C0103
+
+
+[REPORTS]
+
+# Set the output format. Available formats are text, parseable, colorized, msvs
+# (visual studio) and html
+output-format=text
+
+# Include message's id in output
+include-ids=no
+
+# Put messages in a separate file for each module / package specified on the
+# command line instead of printing them on stdout. Reports (if any) will be
+# written in a file name "pylint_global.[txt|html]".
+files-output=no
+
+# Tells whether to display a full report or only the messages
+reports=no
+
+# Python expression which should return a note less than 10 (10 is the highest
+# note). You have access to the variables errors warning, statement which
+# respectively contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (R0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+# Add a comment according to your evaluation note. This is used by the global
+# evaluation report (R0004).
+comment=no
+
+
+[SIMILARITIES]
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+# Ignore docstrings when computing similarities.
+ignore-docstrings=yes
+
+
+[MISCELLANEOUS]
+
+# List of note tags to take in consideration, separated by a comma.
+notes=FIXME,XXX,TODO
+
+
+[VARIABLES]
+
+# Tells whether we should check for unused import in __init__ files.
+init-import=no
+
+# A regular expression matching names used for dummy variables (i.e. not used).
+dummy-variables-rgx=_|dummy
+
+# List of additional names supposed to be defined in builtins. Remember that
+# you should avoid to define new builtins when possible.
+additional-builtins=
+
+
+[FORMAT]
+
+# Maximum number of characters on a single line.
+max-line-length=80
+
+# Maximum number of lines in a module
+max-module-lines=1000
+
+# String used as indentation unit. This is usually " " (4 spaces) or "t" (1
+# tab).
+indent-string=' '
+
+
+[TYPECHECK]
+
+# Tells whether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+# List of classes names for which member attributes should not be checked
+# (useful for classes with attributes dynamically set).
+ignored-classes=SQLObject
+
+# When zope mode is activated, add a predefined set of Zope acquired attributes
+# to generated-members.
+zope=no
+
+# List of members which are set dynamically and missed by pylint inference
+# system, and so shouldn't trigger E0201 when accessed.
+generated-members=REQUEST,acl_users,aq_parent
+
+
+[BASIC]
+
+# Required attributes for module, separated by a comma
+required-attributes=
+
+# List of builtins function names that should not be used, separated by a comma
+bad-functions=map,filter,apply,input
+
+# Regular expression which should only match correct module names
+module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
+
+# Regular expression which should only match correct module level names
+const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
+
+# Regular expression which should only match correct class names
+class-rgx=[A-Z_][a-zA-Z0-9]+$
+
+# Regular expression which should only match correct function names
+function-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct method names
+method-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct instance attribute names
+attr-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct argument names
+argument-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct variable names
+variable-rgx=[a-z_][a-z0-9_]{1,30}$
+
+# Regular expression which should only match correct list comprehension /
+# generator expression variable names
+inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
+
+# Good variable names which should always be accepted, separated by a comma
+good-names=i,j,k,ex,Run,_
+
+# Bad variable names which should always be refused, separated by a comma
+bad-names=foo,bar,baz,toto,tutu,tata
+
+# Regular expression which should only match functions or classes name which do
+# not require a docstring
+no-docstring-rgx=__.*__
+
+
+[IMPORTS]
+
+# Deprecated modules which should not be used, separated by a comma
+deprecated-modules=regsub,string,TERMIOS,Bastion,rexec
+
+# Create a graph of every (i.e. internal and external) dependencies in the
+# given file (report RP0402 must not be disabled)
+import-graph=
+
+# Create a graph of external dependencies in the given file (report RP0402 must
+# not be disabled)
+ext-import-graph=
+
+# Create a graph of internal dependencies in the given file (report RP0402 must
+# not be disabled)
+int-import-graph=
+
+
+[CLASSES]
+
+# List of interface methods to ignore, separated by a comma. This is used for
+# instance to not check methods defines in Zope's Interface base class.
+ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
+
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,__new__,setUp
+
+
+[DESIGN]
+
+# Maximum number of arguments for function / method
+max-args=8
+
+# Argument names that match this expression will be ignored. Default to name
+# with leading underscore
+ignored-argument-names=_.*
+
+# Maximum number of locals for function / method body
+max-locals=15
+
+# Maximum number of return / yield for function / method body
+max-returns=6
+
+# Maximum number of branch for function / method body
+max-branchs=12
+
+# Maximum number of statements in function / method body
+max-statements=50
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=12
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=2
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=20
http://repo.or.cz/w/gfxprim.git/commit/27781b18ae400421700a31d6b1ed37d836c4…
commit 27781b18ae400421700a31d6b1ed37d836c47f22
Author: Tomas Gavenciak <gavento(a)ucw.cz>
Date: Mon Aug 1 21:39:01 2011 +0200
First batch of gen config changes
diff --git a/gfxprim_config.py b/gfxprim_config.py
new file mode 100644
index 0000000..157f93c
--- /dev/null
+++ b/gfxprim_config.py
@@ -0,0 +1,93 @@
+#
+# gfxprim_config.py - module configuring GfxPrim code generation and
+# known PixelTypes
+#
+
+#
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+# 2011 - Cyril Hrubis <metan(a)ucw.cz>
+#
+# This file is sourced by all the generating scripts.
+# Moreover, the generated files are sourced by almost all Gfxprim sources,
+# so a complete recompilation is required after any change.
+#
+
+config = GfxPrimConfig(
+
+ # C name and bit-size of the GP_pixel type
+ pixel_type = "uint32_t",
+ pixel_size = 32,
+
+ # List of pixel sizes (bpp), explicit on purpose
+ sizes = [1, 2, 4, 8, 16, 32]
+
+ # bit endians to generate, keep this fixed to LE, BE for now
+ bit_endians = ['LE', 'BE']
+
+ # List of PixelTypes, order defines the numbering.
+ # The "Undefined" type is added automatically.
+ types = [
+
+ #
+ # Standard RGB types
+ #
+
+ PixelType(name='RGBx8888', size=32, chanslist=[
+ ('R', 16, 8),
+ ('G', 8, 8),
+ ('B', 0, 8)]),
+
+ PixelType(name='RGBA8888', size=32, chanslist=[
+ ('R', 24, 8),
+ ('G', 16, 8),
+ ('B', 8, 8),
+ ('A', 0, 8)]),
+
+ PixelType(name='RGB888', size=24, chanslist=[
+ ('R', 16, 8),
+ ('G', 8, 8),
+ ('B', 0, 8)]),
+
+ PixelType(name='RGB565', size=16, chanslist=[
+ ('R', 11, 5),
+ ('G', 5, 6),
+ ('B', 0, 5)]),
+
+ #
+ # Palette types
+ #
+
+ PixelType(name='P2', size=2, bit_endian='LE', chanslist=[
+ ('P', 0, 2)]),
+
+ PixelType(name='P4', size=4, bit_endian='LE', chanslist=[
+ ('P', 0, 4)]),
+
+ PixelType(name='P8', size=8, bit_endian='LE', chanslist=[
+ ('P', 0, 8)]),
+
+ #
+ # Gray-only pixel types
+ #
+
+ PixelType(name='V1', size=1, bit_endian='LE', chanslist=[
+ ('V', 0, 1)]),
+
+ PixelType(name='V2', size=2, bit_endian='LE', chanslist=[
+ ('V', 0, 2)]),
+
+ PixelType(name='V4', size=4, bit_endian='LE', chanslist=[
+ ('V', 0, 4)]),
+
+ PixelType(name='V8', size=8, bit_endian='LE', chanslist=[
+ ('V', 0, 8)]),
+
+ #
+ # Experiments
+ #
+
+ PixelType(name='VA12', size=4, bit_endian='BE', chanslist=[
+ ('A', 1, 2),
+ ('V', 3, 1)]),
+ ]
+ )
diff --git a/pylib/gfxprim/generators/__init__.py b/pylib/gfxprim/generators/__init__.py
index e69de29..bffe6ea 100644
--- a/pylib/gfxprim/generators/__init__.py
+++ b/pylib/gfxprim/generators/__init__.py
@@ -0,0 +1,31 @@
+#
+# gfxprim.generate
+#
+
+
+# Global config instance
+
+config = None
+
+
+def load_gfxprim_config(config_file = None):
+ """Initialize GfxPrimConfig from a given or guessed config file.
+ Looks for the file by parameter, in env['PIXELTYPE_DEFS'] and
+ in dir(__file__)/../../../gfxprim_config.py, in that order.
+ """
+ if not defs_file:
+ defs_file = os.environ.get("PIXELTYPE_DEFS", None)
+ if not defs_file:
+ path = os.path.dirname(os.path.abspath(__file__))
+ defs_file = os.path.abspath(
+ os.path.join(path, "..", "..", "..", "gfxprim_config.py"))
+ if not os.path.exists(defs_file):
+ sys.stderr.write("WARNING: GfxPrimConfig file %s not found!n" % defs_file)
+
+ from gfxprim.generate.pixeltype import PixelType
+ from gfxprim.generate.gfxprimconfig import GfxPrimConfig
+ l = {"PixelType": PixelType, "GfxPrimConfig": GfxPrimConfig}
+ execfile(defs_file, globals(), l)
+
+ config = l["config"]
+ assert config
diff --git a/pylib/gfxprim/generators/gfxprimconfig.py b/pylib/gfxprim/generators/gfxprimconfig.py
new file mode 100644
index 0000000..60546d0
--- /dev/null
+++ b/pylib/gfxprim/generators/gfxprimconfig.py
@@ -0,0 +1,57 @@
+#
+# gfxprimconfig.py - Class for (global) GfxPrim configuration
+#
+# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+
+import re, os, sys
+
+class GfxPrimConfig(object):
+ def __init__(self, pixel_type = None, pixel_size=None, sizes=None,
+ bit_endians=None, types=[]):
+
+ self.pixel_type = pixel_type
+ assert self.pixel_type
+ assert isinstance(self.pixel_type, str)
+
+ self.pixel_size = pixel_size
+ assert isinstance(self.pixel_size, int)
+ assert self.pixel_size % 8 == 0
+ assert self.pixel_size > 0
+
+ # Allowed bit-sizes of pixel types
+ self.sizes = sizes
+ assert isinstance(self.sizes, list)
+ assert self.pixel_size in self.sizes
+ assert all(( isinstance(i, int) and i > 0 and i <= self.pixel_size
+ for i in self.sizes))
+
+ # bit_endian values
+ self.bit_endians = bit_endians
+ assert isinstance(self.bit_endians, list)
+ assert all(( i in ["LE", "BE"] for i in self.bit_endians))
+
+ # Set of all encountered channel names
+ self.channels = set()
+
+ # Dictionary of all pixeltypes { name : PixelType }
+ self.types_dict = {}
+ # List of all PixelTypes in order. "Unknown" must be first.
+ self.types = []
+
+ self.add_pixeltype(PixelType("UNKNOWN", 0, [], bit_endian=bit_endians[0]))
+ for t in types:
+ self.add_pixeltype(t)
+
+ def add_pixeltype(self, pixeltype):
+ "Add a PixelType and check its against the config"
+
+ assert pixeltype not in self.types
+ self.types.append(pixeltype)
+ assert pixeltype.name not in self.types_dict
+ self.types_dict[pixeltype.name] = pixeltype
+ self.channels.update(set(pixeltype.chans.keys()))
+ try:
+ pixeltype.check_config(self)
+ except AssertionError:
+ sys.stderr.write("Error checking PixelType %sn" % pixeltype.name)
+
diff --git a/pylib/gfxprim/generators/pixeltype.py b/pylib/gfxprim/generators/pixeltype.py
index 92586ab..18531fa 100644
--- a/pylib/gfxprim/generators/pixeltype.py
+++ b/pylib/gfxprim/generators/pixeltype.py
@@ -1,35 +1,21 @@
-# Module with PixelType descrition class
+#
+# gfxprim.pixeltype - Module with PixelType descrition class
+#
# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
+#
-# pixel format:
-# type
-# - PAL
-# - HSVRGBA
-# per chan
-# name, pos, size
-# bitwidth
-# name
-
-import re, os, sys
+import re
+import os
+import sys
import gfxprim
from gfxprim import die
-## *Global* dictionary of all pixeltypes { name : PixelType }
-pixeltypes = {}
-
-## *Global* set of all encountered channel names
-channels = set()
-
-## Allowed bit-sizes of pixels
-bitsizes = [1,2,4,8,16,24,32]
-## bit_endian values
-bit_endians = ['LE', 'BE']
+def get_size_suffix(self.bpp, bit_endian):
+ "Create pixel-size suffix (like 16BPP or 4BPP_LE)"
-## Create pixel-size suffix (16BPP or 4BPP_LE)
-def get_size_suffix(bpp, bit_endian):
- assert bpp in bitsizes
- assert bit_endian in bit_endians
+ assert bpp in self.sizes
+ assert bit_endian in self.bit_endians
size_suffix = '%dBPP' % (bpp)
if bpp < 8:
size_suffix += '_' + bit_endian
@@ -38,28 +24,22 @@ def get_size_suffix(bpp, bit_endian):
class PixelType(object):
"""Representation of one GP_PixelType"""
- def __init__(self, name, size, chanslist, number=None, bit_endian=None):
+
+ def __init__(self, name, size, chanslist, bit_endian=None):
"""`name` must be a valid C identifier
- `size` is in bits, allowed are 1, 2, 4, 8, 16, 24, 32
- `bit_endian` is order of 1,2,4BPP pixels in a byte, either 'BE' or 'LE'
+ `size` is type bit-width
+ `bit_endian` is required in 1,2,4 BPP types to determine the order of
+ pixels in a byte, either 'BE' or 'LE'
`chanslist` is a list of triplets describing individual channels as
- [ (`chan_name`, `bit_offset`, `bit_size`) ]
- `chan_name` is usually one of: R, G, B, V (value, used for grayscale), A (opacity)
- `number` is auto-assigned (internal use only)
+ [ (`chan_name`, `bit_offset`, `bit_size`) ]
+ where `chan_name` is usually one of: R, G, B,
+ V (value, used for grayscale), A (opacity)
"""
assert re.match('A[A-Za-z][A-Za-z0-9_]*Z', name)
self.name = name
self.chanslist = chanslist
self.chans = dict() # { chan_name: (offset, size) }
- # all types except UNKNOWN=0 must have one of these sizes
- if number is not 0:
- assert(size in bitsizes)
self.size = size
-
- # bit_endian matters only for 1,2,4bpp
- if size>=8 and bit_endian is None:
- bit_endian = bit_endians[0]
- assert bit_endian in bit_endians
self.bit_endian = bit_endian
if self.size == 0:
@@ -67,12 +47,6 @@ class PixelType(object):
else:
self.size_suffix = get_size_suffix(self.size, self.bit_endian)
- # Numbering from 1
- if number is not None:
- self.number = number
- else:
- self.number = max([ptype.number for ptype in pixeltypes.values()] + [0]) + 1
-
# Verify channel bits for overlaps
# also builds a bit-map of the PixelType
self.bits = ['x']*size
@@ -84,9 +58,16 @@ class PixelType(object):
assert(self.bits[i]=='x')
self.bits[i] = c[0]
- assert self.name not in pixeltypes.keys()
- pixeltypes[self.name] = self
- channels.update(set(self.chans.keys()))
+ def valid_for_config(self, config):
+ "Check PixelType compatibility with given GfxPrimConfig."
+
+ # all types except UNKNOWN=0 must have one of these sizes
+ if self.name != "UNKNOWN":
+ assert(self.size in config.sizes)
+
+ # bit_endian matters only for non-multiple-of-8 bpp
+ if size % 8 != 0 or bit_endian is not None:
+ assert bit_endian in config.bit_endians
def __str__(self):
return "<PixelType " + self.name + ">"
@@ -94,27 +75,3 @@ class PixelType(object):
def is_palette(self):
return ('P' in self.chans)
-def load_pixeltypes(defs_file = None):
- "Initialize pixeltypes by loading the defs file.n"
- "Looks for the file by parameter, env['PIXELTYPE_DEFS'] and "
- "in dir(__file__)/../../pixeltypes.py, in that order.n"
- "PixelType UNKNOWN is not defined here."
- if not defs_file:
- defs_file = os.environ.get('PIXELTYPE_DEFS', None)
- if not defs_file:
- path = os.path.dirname(os.path.abspath(__file__))
- defs_file = os.path.join(path, '..', '..', 'pixeltypes.py')
- execfile(defs_file)
-
-def __init__():
- "Initialize PixelType UNKNOWN.n"
- "Currently also reads PIXELTYPE_DEFS, but that may change!"
- if 0 not in pixeltypes:
- PixelType("UNKNOWN", 0, [], bit_endian=bit_endians[0], number=0)
- load_pixeltypes()
- # check if some types were loaded
- if len(pixeltypes) <= 1:
- sys.stderr.write("WARNING: no PixelTypes were loaded.")
-
-__init__()
-
diff --git a/pylib/pixeltypes.py b/pylib/pixeltypes.py
deleted file mode 100644
index b035b6a..0000000
--- a/pylib/pixeltypes.py
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# pixeltypes.py - module defining known PixelTypes
-#
-
-#
-# 2011 - Tomas Gavenciak <gavento(a)ucw.cz>
-# 2011 - Cyril Hrubis <metan(a)ucw.cz>
-#
-# Every call to PixelType defines one new GP_PixelType, order defines
-# the numbering. Undefined type is defined automatically.
-# No other functionality than PixelType() should be defined here.
-#
-# This file is sourced by all the generating scripts.
-# Moreover, the generated files are sourced by almost all Gfxprim sources,
-# a complete recompilation is required after any change.
-#
-
-#
-# Standard RGB types
-#
-
-PixelType(name='RGBx8888', size=32, chanslist=[
- ('R', 16, 8),
- ('G', 8, 8),
- ('B', 0, 8)])
-
-
-PixelType(name='RGBA8888', size=32, chanslist=[
- ('R', 24, 8),
- ('G', 16, 8),
- ('B', 8, 8),
- ('A', 0, 8)])
-
-
-PixelType(name='RGB888', size=24, chanslist=[
- ('R', 16, 8),
- ('G', 8, 8),
- ('B', 0, 8)])
-
-
-PixelType(name='RGB565', size=16, chanslist=[
- ('R', 11, 5),
- ('G', 5, 6),
- ('B', 0, 5)])
-
-#
-# Palette types
-#
-
-PixelType(name='P2', size=2, bit_endian='LE', chanslist=[
- ('P', 0, 2)])
-
-
-PixelType(name='P4', size=4, bit_endian='LE', chanslist=[
- ('P', 0, 4)])
-
-
-PixelType(name='P8', size=8, bit_endian='LE', chanslist=[
- ('P', 0, 8)])
-
-#
-# Gray-only pixel types
-#
-
-PixelType(name='V1', size=1, bit_endian='LE', chanslist=[
- ('V', 0, 1)])
-
-
-PixelType(name='V2', size=2, bit_endian='LE', chanslist=[
- ('V', 0, 2)])
-
-
-PixelType(name='V4', size=4, bit_endian='LE', chanslist=[
- ('V', 0, 4)])
-
-
-PixelType(name='V8', size=8, bit_endian='LE', chanslist=[
- ('V', 0, 8)])
-
-
-#
-# Experiments
-#
-
-PixelType(name='VA12', size=4, bit_endian='BE', chanslist=[
- ('A', 1, 2),
- ('V', 3, 1)])
-
-----------------------------------------------------------------------
Summary of changes:
gen.mk | 26 ++-
gfxprim_config.py | 108 ++++++++++
include/core/GP_Blit.gen.h.t | 16 ++
include/core/GP_Convert.gen.h.t | 86 ++++++++
include/core/GP_Convert_Scale.gen.h.t | 28 +++
include/core/GP_GetPutPixel.gen.h.t | 63 ++++++
include/core/GP_Pixel.gen.h.t | 83 ++++++++
include/core/GP_Pixel.h | 11 +-
libs/core/GP_Blit.gen.c.t | 69 +++++++
libs/core/GP_Convert.gen.c.t | 70 +++++++
libs/core/GP_Pixel.gen.c.t | 45 ++++
pylib/bin/generate_collected_tests.py | 35 ++++
pylib/bin/generate_file.py | 37 ++--
pylib/gfxprim/README | 4 +-
pylib/gfxprim/__init__.py | 16 +--
pylib/gfxprim/generators/core/gen_blit.py | 75 -------
pylib/gfxprim/generators/core/gen_convert.py | 116 -----------
pylib/gfxprim/generators/core/gen_getputpixel.py | 52 -----
pylib/gfxprim/generators/core/gen_pixeltype.py | 109 ----------
pylib/gfxprim/generators/core/make_GP_Blit.py | 31 ---
pylib/gfxprim/generators/core/make_GP_Convert.py | 101 ---------
pylib/gfxprim/generators/core/make_GP_Pixel.py | 76 -------
pylib/gfxprim/generators/generator.py | 124 -----------
pylib/gfxprim/generators/make_collected_tests.py | 141 -------------
pylib/gfxprim/generators/pixeltype.py | 120 -----------
pylib/gfxprim/generators/utils.py | 42 ----
pylib/gfxprim/gfxprimconfig.py | 62 ++++++
pylib/gfxprim/pixelsize.py | 39 ++++
pylib/gfxprim/pixeltype.py | 62 ++++++
pylib/gfxprim/pylint.conf | 236 ++++++++++++++++++++++
pylib/gfxprim/render_utils.py | 83 ++++++++
pylib/gfxprim/test_collection.py | 96 +++++++++
pylib/pixeltypes.py | 88 --------
pylib/templates/base.c.t | 15 ++
pylib/templates/base.h.t | 11 +
pylib/templates/base.test.c.t | 47 +++++
pylib/templates/collected_tests.c.t | 55 +++++
tests.mk | 11 +-
LICENSE => tests/core/GP_Blit.test.c | 12 +-
tests/core/GP_Convert.test.gen.c.t | 38 ++++
40 files changed, 1413 insertions(+), 1126 deletions(-)
create mode 100644 gfxprim_config.py
create mode 100644 include/core/GP_Blit.gen.h.t
create mode 100644 include/core/GP_Convert.gen.h.t
create mode 100644 include/core/GP_Convert_Scale.gen.h.t
create mode 100644 include/core/GP_GetPutPixel.gen.h.t
create mode 100644 include/core/GP_Pixel.gen.h.t
create mode 100644 libs/core/GP_Blit.gen.c.t
create mode 100644 libs/core/GP_Convert.gen.c.t
create mode 100644 libs/core/GP_Pixel.gen.c.t
create mode 100644 pylib/bin/generate_collected_tests.py
delete mode 100644 pylib/gfxprim/generators/__init__.py
delete mode 100644 pylib/gfxprim/generators/core/__init__.py
delete mode 100644 pylib/gfxprim/generators/core/gen_blit.py
delete mode 100644 pylib/gfxprim/generators/core/gen_convert.py
delete mode 100644 pylib/gfxprim/generators/core/gen_getputpixel.py
delete mode 100644 pylib/gfxprim/generators/core/gen_pixeltype.py
delete mode 100644 pylib/gfxprim/generators/core/make_GP_Blit.py
delete mode 100644 pylib/gfxprim/generators/core/make_GP_Convert.py
delete mode 100644 pylib/gfxprim/generators/core/make_GP_Pixel.py
delete mode 100644 pylib/gfxprim/generators/generator.py
delete mode 100644 pylib/gfxprim/generators/make_collected_tests.py
delete mode 100644 pylib/gfxprim/generators/pixeltype.py
delete mode 100644 pylib/gfxprim/generators/utils.py
create mode 100644 pylib/gfxprim/gfxprimconfig.py
create mode 100644 pylib/gfxprim/pixelsize.py
create mode 100644 pylib/gfxprim/pixeltype.py
create mode 100644 pylib/gfxprim/pylint.conf
create mode 100644 pylib/gfxprim/render_utils.py
create mode 100644 pylib/gfxprim/test_collection.py
delete mode 100644 pylib/pixeltypes.py
create mode 100644 pylib/templates/base.c.t
create mode 100644 pylib/templates/base.h.t
create mode 100644 pylib/templates/base.test.c.t
create mode 100644 pylib/templates/collected_tests.c.t
copy LICENSE => tests/core/GP_Blit.test.c (84%)
create mode 100644 tests/core/GP_Convert.test.gen.c.t
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 generate updated: 1cd5016b247b64d2d0b7b7c6791d5f730248ec64
by metan 30 Jul '11
by metan 30 Jul '11
30 Jul '11
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, generate has been updated
via 1cd5016b247b64d2d0b7b7c6791d5f730248ec64 (commit)
via ff97808f33bff1007d84a1d4899363b62d2ac2f3 (commit)
from 24db76060a41a8d3abb75c57e552d9a784bf5948 (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/1cd5016b247b64d2d0b7b7c6791d5f730248…
commit 1cd5016b247b64d2d0b7b7c6791d5f730248ec64
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jul 29 21:24:06 2011 +0000
Updated docs to match the code.
diff --git a/doc/Makefile b/doc/Makefile
index 4307a8c..fd95a7b 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -1,6 +1,7 @@
all: api.html
-api.html: general.txt api.txt context.txt loaders.txt filters.txt
+api.html: general.txt api.txt context.txt loaders.txt filters.txt + basic_types.txt drawing_api.txt
asciidoc -a toc api.txt
api.pdf: api.txt
diff --git a/doc/basic_types.txt b/doc/basic_types.txt
index 9bcba9e..efc9c7b 100644
--- a/doc/basic_types.txt
+++ b/doc/basic_types.txt
@@ -3,7 +3,8 @@ Basic types
Return Code
~~~~~~~~~~~
-Basically each gfxprim function returns one of following return codes:
+Some gfxprim function returns one of following return codes (may be removed in
+future):
[source,c]
--------------------------------------------------------------------------------
@@ -29,74 +30,51 @@ Return codes could be translated into an error messages.
const char *GP_RetCodeName(GP_RetCode code);
--------------------------------------------------------------------------------
+Coord and Size
+~~~~~~~~~~~~~~
+For drawing API there are two integer types defined the 'GP_Coord' for
+coordinates and 'GP_Size' for size, length or so.
+
+
Color and pixel types
~~~~~~~~~~~~~~~~~~~~~
-The color, in gfxprim is abstract value that represents color in some format,
-while pixel is color in format of the target bitmap.
-
-Color and pixel types could be converted between each other but certain
-conversions lose information.
+The color, in gfxprim is enumeration of symbolic color names while pixel is
+integer value or you may say color in format of the target bitmap.
-Color types are defined in 'core/GP_Color.h' and pixels in 'core/GP_Pixel.h'.
-The color is union of structures so that is easy to manipulate with each color
-types, the pixel is basically sequence of bytes stored in long enough integer
-number.
+Color could be converted into given pixel type which will result in integer
+value suitable for usage with drawing functions. The color could be also
+converted to color name (C string in English language) and C string may be
+matched against table of color names.
-Before drawing a shape into a bitmap, color must be converted into pixel as
-all drawing functions takes pixel rather than color.
+As all drawing functions works with pixel rather than color the color must be
+converted before using function to draw a shape into a bitmap.
-The color types:
+The color is defined as follows:
[source,c]
--------------------------------------------------------------------------------
-typedef enum GP_ColorType {
- GP_NOCOLOR = 0,
- GP_COLNAME,
- GP_PALETTE,
- GP_PAL4,
- GP_PAL8,
- GP_G1,
- GP_G2,
- GP_G4,
- GP_G8,
- GP_RGB555,
- GP_RGB565,
- GP_RGB666,
- GP_RGB888,
- GP_RGBA8888,
- GP_COLMAX,
-} GP_ColorType;
+typedef enum GP_Color {
+ GP_COL_INVALID = -1,
+ GP_COL_BLACK,
+ ...
+} GP_Color;
--------------------------------------------------------------------------------
-Predefined names are provided for the most basic colors:
+Color and Pixel conversion functions, the last one returns 'true' in case of
+successful match and conversion and false otherwise.
[source,c]
--------------------------------------------------------------------------------
-typedef enum GP_ColorName {
- GP_COL_BLACK,
- GP_COL_RED,
- GP_COL_GREEN,
- GP_COL_BLUE,
- GP_COL_YELLOW,
- GP_COL_BROWN,
- GP_COL_ORANGE,
- GP_COL_GRAY_DARK,
- GP_COL_GRAY_LIGHT,
- GP_COL_PURPLE,
- GP_COL_WHITE,
- GP_COL_MAX,
-} GP_ColorName;
---------------------------------------------------------------------------------
+#include <core/GP_Color.h>
-To convert color to context pixel type use:
+GP_Pixel GP_ColorToPixel(GP_Context *context, GP_Color color);
-[source,c]
---------------------------------------------------------------------------------
-GP_RetCode GP_ColorToPixel(struct GP_Context *context, GP_Color color,
- GP_Pixel *pixel);
+GP_Color GP_ColorNameToColor(const char *color_name);
+
+const char *GP_ColorToColorName(GP_Color color);
-GP_RetCode GP_ColorNameToPixel(struct GP_Context *context, GP_ColorName name,
- GP_Pixel *pixel);
+bool GP_ColorNameToPixel(GP_Context *context, const char *color_name,
+ GP_Pixel *pixel);
--------------------------------------------------------------------------------
diff --git a/doc/context.txt b/doc/context.txt
index b3156a0..42c9f8c 100644
--- a/doc/context.txt
+++ b/doc/context.txt
@@ -20,25 +20,21 @@ typedef struct GP_Context {
int axes_swap:1; /* Context rotation and mirroring */
int x_swap:1;
int y_swap:1;
-
- uint32_t clip_w_min; /* Clipping rectanle */
- uint32_t clip_w_max;
- uint32_t clip_h_min;
- uint32_t clip_h_max;
} GP_Context;
-------------------------------------------------------------------------------
-The 'GP_Context' holds metadata needed for bitmaps. The values of pixels
+The 'GP_Context' holds meta-data needed for bitmaps. The values of pixels
are stored as bitmap lines (aligned to bytes) in one dimensional array.
-The addres of pixel could be determined by GP_PIXEL_ADDRESS(context, x, y)
-which returns byte aligned addres for the pixel.
+The address of pixel could be determined by GP_PIXEL_ADDRESS(context, x, y)
+which returns byte aligned address for the pixel.
Rotation
^^^^^^^^
+All gfx functions does honor rotation and mirroring. If you really need drawing
+primitives without it use variants with _Raw suffix.
-Rotation and mirroring is honored only by functions starting with extra T.
-So GP_TLine() is equal to GP_Line(), when all axes_sawp, x_swap and y_swap are
-set to zero.
+So GP_Line() is equal to GP_Line_Raw(), when all axes_swap, x_swap and y_swap
+are set to zero.
There are various macros for transforming coordinates and sizes in
'core/GP_Transform.h'.
@@ -47,13 +43,6 @@ There are various macros for transforming coordinates and sizes in
* *GP_TRANSFORM_RECT(x, y, w, h)*
* *GP_RETRANSFORM_POINT(x, y)*
-Clipping rectangle
-^^^^^^^^^^^^^^^^^^
-
-All drawing functions honor the clipping rectangle, eg. no pixels are put,
-even when the coordinates are inside the bitmap, if they are outside of
-clipping rectangle.
-
Functions
~~~~~~~~~
@@ -63,12 +52,10 @@ Functions
uint32_t GP_ContextW(struct GP_Context *context);
uint32_t GP_ContextH(struct GP_Context *context);
-uint32_t GP_TContextW(struct GP_Context *context);
-uint32_t GP_TContextH(struct GP_Context *context);
-------------------------------------------------------------------------------
-Functions to get context width and height. Functions with 'T' prefix do honour
-rotation flags (swaps W and H if axes_swap is set).
+Functions to get context width and height that do honor rotation flags (swaps
+W and H if axes_swap is set).
[source,c]
-------------------------------------------------------------------------------
@@ -88,7 +75,7 @@ counter clock wise.
GP_Context *GP_ContextAlloc(uint32_t w, uint32_t h, GP_PixelType type);
-------------------------------------------------------------------------------
-Allocates and initalizes the 'GP_Context' structure. The size for pixels is
+Allocates and initializes the 'GP_Context' structure. The size for pixels is
computed from width, height and pixel type. Moreover the rotation flags are
set to zero and clipping rectangle is set to whole bitmap.
@@ -110,9 +97,9 @@ Free the context allocated memory.
GP_Context *GP_ContextCopy(GP_Context *context, int flag);
-------------------------------------------------------------------------------
-Copy a context. Allocates and initalizes a 'GP_Context'. If flag is set to
-GP_CONTEXT_WITH_PIXELS, the actuall bitmap is copied from contex to newly
-allocated context, otherwise only context metadata are copied.
+Copy a context. Allocates and initializes a 'GP_Context'. If flag is set to
+GP_CONTEXT_WITH_PIXELS, the actual bitmap is copied from context to newly
+allocated context, otherwise only context meta-data are copied.
The newly created context should be later freed with 'GP_ContextFree()'.
diff --git a/doc/drawing_api.txt b/doc/drawing_api.txt
index 707ad71..6cfd7e8 100644
--- a/doc/drawing_api.txt
+++ b/doc/drawing_api.txt
@@ -9,42 +9,46 @@ Fill
void GP_Fill(GP_Context *context, GP_Pixel pixel);
--------------------------------------------------------------------------------
-Fills the context bitmap, respecting the clipping rect. This has the same effect
-as calling 'GP_FillRect(context, 0, 0, context->w, context->h, pixel)'.
-
-This functions doesn't have rotate friendly variant.
+Fills the context bitmap. This has the same effect as calling
+'GP_FillRect(context, 0, 0, context->w, context->h, pixel)'.
Lines
~~~~~
[source,c]
--------------------------------------------------------------------------------
-void GP_HLineXXY(GP_Context *context, int x0, int x1, int y, GP_Pixel pixel);
+void GP_HLineXXY(GP_Context *context, GP_Coord x0, GP_Coord x1, GP_Coord y,
+ GP_Pixel pixel);
-void GP_HLineXYW(GP_Context *context, int x, int y, unsigned int w,
+void GP_HLineXYW(GP_Context *context, GP_Coord x, GP_Coord y, GP_Size w,
GP_Pixel pixel);
-void GP_HLine(GP_Context *context, int x0, int x1, int y, GP_Pixel pixel);
+void GP_HLine(GP_Context *context, GP_Coord x0, GP_Coord x1, GP_Coord y,
+ GP_Pixel pixel);
--------------------------------------------------------------------------------
-Draws a horizontal line. The 'GP_HLine()' function is an alias for 'GP_HLineXXY()'.
+Draws a horizontal line. The 'GP_HLine()' function is an alias for
+'GP_HLineXXY()'.
[source,c]
--------------------------------------------------------------------------------
-void GP_VLineXYY(GP_Context *context, int x, int y0, int y1, GP_Pixel pixel);
+void GP_VLineXYY(GP_Context *context, GP_Coord x, GP_Coord y0, GP_Coord y1,
+ GP_Pixel pixel);
-void GP_VLineXYH(GP_Context *context, int x, int y,
- unsigned int height, GP_Pixel pixel);
+void GP_VLineXYH(GP_Context *context, GP_Coord x, GP_Coord y, GP_Size h,
+ GP_Pixel pixel);
-void GP_VLine(GP_Context *context, int x, int y0, int y1, GP_Pixel pixel);
+void GP_VLine(GP_Context *context, GP_Coord x, GP_Coord y0, GP_Coord y1,
+ GP_Pixel pixel);
--------------------------------------------------------------------------------
-Draws a vertical line. The 'GP_VLine()' function is an alias for 'GP_VLineXYY()'.
+Draws a vertical line. The 'GP_VLine()' function is an alias for
+'GP_VLineXYY()'.
[source,c]
--------------------------------------------------------------------------------
-void GP_Line(GP_Context *context, int x0, int y0, int x1, int y1,
- GP_Pixel pixel);
+void GP_Line(GP_Context *context, GP_Coord x0, GP_Coord y0,
+ GP_Coord x1, GP_Coord y1, GP_Pixel pixel);
--------------------------------------------------------------------------------
Draws a line from (x0, y0) to (x1, y1), inclusive.
@@ -54,35 +58,56 @@ Circles
[source,c]
--------------------------------------------------------------------------------
-void GP_Circle(GP_Context *context, int xcenter, int ycenter,
- unsigned int r, GP_Pixel pixel);
+void GP_Circle(GP_Context *context, GP_Coord xcenter, GP_Coord ycenter,
+ GP_Size r, GP_Pixel pixel);
--------------------------------------------------------------------------------
Draws a circle.
[source,c]
--------------------------------------------------------------------------------
-void GP_FillCircle(GP_Context *context, int xcenter, int ycenter,
- unsigned int r, GP_Pixel pixel);
+void GP_FillCircle(GP_Context *context, GP_Coord xcenter, GP_Coord ycenter,
+ GP_Size r, GP_Pixel pixel);
--------------------------------------------------------------------------------
Draws a filled circle.
+Rings
+~~~~~
+[source,c]
+--------------------------------------------------------------------------------
+void GP_Ring(GP_Context *context, GP_Coord xcenter, GP_Coord ycenter,
+ GP_Size r1, GP_Size r2, GP_Pixel pixel);
+--------------------------------------------------------------------------------
+
+Draws a ring.
+
+[source,c]
+--------------------------------------------------------------------------------
+void GP_FillRing(GP_Context *context, GP_Coord xcenter, GP_Coord ycenter,
+ GP_Size r1, GP_Size r2, GP_Pixel pixel);
+--------------------------------------------------------------------------------
+
+Draws a filled ring.
+
+The smaller of r1 and r2 is used for inner radius and bigger one for outer
+radius.
+
Ellipses
~~~~~~~~
[source,c]
--------------------------------------------------------------------------------
-void GP_Ellipse(GP_Context *context, int xcenter, int ycenter,
- unsigned int a, unsigned int b, GP_Pixel pixel);
+void GP_Ellipse(GP_Context *context, GP_Coord xcenter, GP_Coord ycenter,
+ GP_Size a, GP_Size b, GP_Pixel pixel);
--------------------------------------------------------------------------------
Draws an ellipse.
[source,c]
--------------------------------------------------------------------------------
-void GP_FillEllipse(GP_Context *context, int xcenter, int ycenter,
- unsigned int a, unsigned int b, GP_Pixel pixel);
+void GP_FillEllipse(GP_Context *context, GP_Coord xcenter, GP_Coord ycenter,
+ GP_Size a, GP_Size b, GP_Pixel pixel);
--------------------------------------------------------------------------------
Draws a filled ellipse.
@@ -92,16 +117,18 @@ Triangles
[source,c]
--------------------------------------------------------------------------------
-void GP_Triangle(GP_Context *context, int x0, int y0, int x1, int y1,
- int x2, int y2, GP_Pixel pixel);
+void GP_Triangle(GP_Context *context, GP_Coord x0, GP_Coord y0,
+ GP_Coord x1, GP_Coord y1, GP_Coord x2, GP_Coord y2,
+ GP_Pixel pixel);
--------------------------------------------------------------------------------
Draws a triangle.
[source,c]
--------------------------------------------------------------------------------
-void GP_FillTriangle(GP_Context *context, int x0, int y0, int x1, int y1,
- int x2, int y2, GP_Pixel pixel);
+void GP_FillTriangle(GP_Context *context, GP_Coord x0, GP_Coord y0,
+ GP_Coord x1, GP_Coord y1, GP_Coord x2, GP_Coord y2,
+ GP_Pixel pixel);
--------------------------------------------------------------------------------
Draws a filled triangle.
@@ -111,34 +138,36 @@ Rects
[source,c]
--------------------------------------------------------------------------------
-void GP_RectXYXY(GP_Context *context, int x0, int y0, int x1, int y1,
- GP_Pixel pixel);
+void GP_RectXYXY(GP_Context *context, GP_Coord x0, GP_Coord y0,
+ GP_Coord x1, GP_Coord y1, GP_Pixel pixel);
-void GP_RectXYWH(GP_Context *context, int x, int y,
- unsigned int w, unsigned int h, GP_Pixel pixel);
+void GP_RectXYWH(GP_Context *context, GP_Coord x, GP_Coord y,
+ GP_Size w, GP_Size h, GP_Pixel pixel);
-void GP_Rect(GP_Context *context, int x0, int y0, int x1, int y1,
- GP_Pixel pixel);
+void GP_Rect(GP_Context *context, GP_Coord x0, GP_Coord y0,
+ GP_Coord x1, GP_Coord y1, GP_Pixel pixel);
--------------------------------------------------------------------------------
Draws a rectangle.
+
The 'GP_RectXYXY()' expects two corner points (x0, y0), and (x1, y1).
The 'GP_RectXYWH()' expects a corner point (x0, y0), width and height.
The 'GP_Rect()' function is an alias for 'GP_RectXYXY()'.
[source,c]
--------------------------------------------------------------------------------
-void GP_FillRectXYXY(GP_Context *context, int x0, int y0, int x1, int y1,
- GP_Pixel pixel);
+void GP_FillRectXYXY(GP_Context *context, GP_Coord x0, GP_Coord y0,
+ GP_Coord x1, GP_Coord y1, GP_Pixel pixel);
-void GP_FillRectXYWH(GP_Context *context, int x, int y,
- unsigned int w, unsigned int h, GP_Pixel pixel);
+void GP_FillRectXYWH(GP_Context *context, GP_Coord x, GP_Coord y,
+ GP_Size w, GP_Size h, GP_Pixel pixel);
-void GP_FillRect(GP_Context *context, int x0, int y0, int x1, int y1,
- GP_Pixel pixel);
+void GP_FillRect(GP_Context *context, GP_Coord x0, GP_Coord y0,
+ GP_Coord x1, GP_Coord y1, GP_Pixel pixel);
--------------------------------------------------------------------------------
Draws a filled rectangle.
+
The 'GP_RectXYXY' fills an area between corner points (x0, y0) and (x1, y1),
inclusive.
The 'GP_RectXYWH' fills an area starting from (x0, y0) with specified width
@@ -150,16 +179,18 @@ Tetragons
[source,c]
--------------------------------------------------------------------------------
-void GP_Tetragon(GP_Context *context, int x0, int y0, int x1, int y1,
- int x2, int y2, int x3, int y3, GP_Pixel pixel);
+void GP_Tetragon(GP_Context *context, GP_Coord x0, GP_Coord y0,
+ GP_Coord x1, GP_Coord y1, GP_Coord x2, GP_Coord y2,
+ GP_Coord x3, GP_Coord y3, GP_Pixel pixel);
--------------------------------------------------------------------------------
Draws a tetragon.
[source,c]
--------------------------------------------------------------------------------
-void GP_FillTetragon(GP_Context *context, int x0, int y0, int x1, int y1,
- int x2, int y2, int x3, int y3, GP_Pixel pixel);
+void GP_FillTetragon(GP_Context *context, GP_Coord x0, GP_Coord y0,
+ GP_Coord x1, GP_Coord y1, GP_Coord x2, GP_Coord y2,
+ GP_Coord x3, GP_Coord y3, GP_Pixel pixel);
--------------------------------------------------------------------------------
Draws a filled tetragon.
diff --git a/doc/filters.txt b/doc/filters.txt
index 707a621..d741abb 100644
--- a/doc/filters.txt
+++ b/doc/filters.txt
@@ -1,7 +1,7 @@
Context filters
---------------
-Pixel filters for 'GP_Context'.
+Pixel filters for 'GP_Context'. The context filter is basially an function that modifies context somehow (may even allocate new context to store result).
Rotation
~~~~~~~~
@@ -13,8 +13,7 @@ Rotation
GP_RetCode GP_MirrorH(GP_Context *context);
-------------------------------------------------------------------------------
-Mirrors context pixels horizontaly and updates the context metadata (mirrors
-cliping rectangle too).
+Mirrors context pixels horizontaly and updates the context metadata.
[source,c]
-------------------------------------------------------------------------------
@@ -23,8 +22,7 @@ cliping rectangle too).
GP_RetCode GP_MirrorV(GP_Context *context);
-------------------------------------------------------------------------------
-Mirrors context pixels verticaly and updates the context metadata (mirrors
-cliping rectangle too).
+Mirrors context pixels verticaly and updates the context metadata.
[source,c]
-------------------------------------------------------------------------------
@@ -33,8 +31,7 @@ cliping rectangle too).
GP_RetCode GP_RotateCW(GP_Context *context);
-------------------------------------------------------------------------------
-Rotates context clock wise and updates the context metadata (rotates cliping
-rectangle too).
+Rotates context clock wise and updates the context metadata.
[source,c]
-------------------------------------------------------------------------------
@@ -43,6 +40,5 @@ rectangle too).
GP_RetCode GP_RotateCCW(GP_Context *context);
-------------------------------------------------------------------------------
-Rotates context counter clock wise and updates the context metadata (rotates
-cliping rectangle too).
+Rotates context counter clock wise and updates the context metadata.
http://repo.or.cz/w/gfxprim.git/commit/ff97808f33bff1007d84a1d4899363b62d2a…
commit ff97808f33bff1007d84a1d4899363b62d2ac2f3
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Jul 29 19:18:57 2011 +0000
Minor core and gfx cleanup.
diff --git a/include/core/GP_Color.h b/include/core/GP_Color.h
index 8bda861..a636cd0 100644
--- a/include/core/GP_Color.h
+++ b/include/core/GP_Color.h
@@ -25,7 +25,8 @@
/*
- Color.
+ Color is enumeration of color names which may be converted into pixel values
+ in desired pixel format.
*/
@@ -54,18 +55,19 @@ typedef enum GP_Color {
/*
* Converts Color to Pixel
*/
-GP_Pixel GP_ColorToPixel(GP_Context *context, GP_Color col);
+GP_Pixel GP_ColorToPixel(GP_Context *context, GP_Color color);
/*
* Converts Color name to Color.
*/
GP_Color GP_ColorNameToColor(const char *color_name);
-const char *GP_ColorToColorName(GP_Color col);
+const char *GP_ColorToColorName(GP_Color color);
/*
* Converts Color name to Pixel.
*/
-GP_Pixel GP_ColorNameToPixel(GP_Context *context, const char *color_name);
+bool GP_ColorNameToPixel(GP_Context *context, const char *color_name,
+ GP_Pixel *pixel);
#endif /* GP_COLOR_H */
diff --git a/include/core/GP_Context.h b/include/core/GP_Context.h
index 4bffd66..cf65432 100644
--- a/include/core/GP_Context.h
+++ b/include/core/GP_Context.h
@@ -46,10 +46,10 @@ typedef struct GP_Context {
/* image orientation. Most common is landscape (0, 0, 0),
* portrait with normal topleft corner is (1, 0, 0).
*/
- uint8_t axes_swap:1; /* swap axes so that x is y and y is x */
- uint8_t x_swap:1; /* swap direction on x */
- uint8_t y_swap:1; /* swap direction on y */
- uint8_t bit_endian:1; /* GP_BIT_ENDIAN */
+ uint8_t axes_swap:1; /* swap axes so that x is y and y is x */
+ uint8_t x_swap:1; /* swap direction on x */
+ uint8_t y_swap:1; /* swap direction on y */
+ uint8_t bit_endian:1; /* GP_BIT_ENDIAN */
} GP_Context;
/* Returns the pixel type used by the context. */
diff --git a/include/gfx/GP_VLine.h b/include/gfx/GP_VLine.h
index ea5a576..f4c5d1e 100644
--- a/include/gfx/GP_VLine.h
+++ b/include/gfx/GP_VLine.h
@@ -34,11 +34,11 @@ void GP_VLineXYY(GP_Context *context, GP_Coord x, GP_Coord y0,
void GP_VLineXYY_Raw(GP_Context *context, GP_Coord x, GP_Coord y0,
GP_Coord y1, GP_Pixel pixel);
-void GP_VLineXYH(GP_Context *context, GP_Coord x, GP_Coord y,
- GP_Size height, GP_Pixel pixel);
+void GP_VLineXYH(GP_Context *context, GP_Coord x, GP_Coord y, GP_Size h,
+ GP_Pixel pixel);
-void GP_VLineXYH_Raw(GP_Context *context, GP_Coord x, GP_Coord y,
- GP_Size height, GP_Pixel pixel);
+void GP_VLineXYH_Raw(GP_Context *context, GP_Coord x, GP_Coord y, GP_Size h,
+ GP_Pixel pixel);
/* default argument set is XYY */
static inline void GP_VLine(GP_Context *context, GP_Coord x,
diff --git a/libs/core/GP_Color.c b/libs/core/GP_Color.c
index b6981d9..06a2791 100644
--- a/libs/core/GP_Color.c
+++ b/libs/core/GP_Color.c
@@ -87,12 +87,15 @@ const char *GP_ColorToColorName(GP_Color col)
return color_names[col];
}
-GP_Pixel GP_ColorNameToPixel(GP_Context *context, const char *color_name)
+bool GP_ColorNameToPixel(GP_Context *context, const char *color_name,
+ GP_Pixel *pixel)
{
GP_Color col = GP_ColorNameToColor(color_name);
- if (col < 0)
- return 0;
+ if (col == GP_COL_INVALID)
+ return false;
- return GP_ColorToPixel(context, col);
+ *pixel = GP_ColorToPixel(context, col);
+
+ return true;
}
diff --git a/libs/gfx/GP_VLine.c b/libs/gfx/GP_VLine.c
index 4fdb319..e6d7f01 100644
--- a/libs/gfx/GP_VLine.c
+++ b/libs/gfx/GP_VLine.c
@@ -40,14 +40,14 @@ void GP_VLineXYY_Raw(GP_Context *context, GP_Coord x, GP_Coord y0,
GP_FN_PER_BPP_CONTEXT(GP_VLine, context, context, x, y0, y1, pixel);
}
-void GP_VLineXYH_Raw(GP_Context *context, GP_Coord x, GP_Coord y,
- GP_Size height, GP_Pixel pixel)
+void GP_VLineXYH_Raw(GP_Context *context, GP_Coord x, GP_Coord y, GP_Size h,
+ GP_Pixel pixel)
{
/* zero height: do not draw anything */
- if (height == 0)
+ if (h == 0)
return;
- GP_VLineXYY(context, x, y, y + height - 1, pixel);
+ GP_VLineXYY(context, x, y, y + h - 1, pixel);
}
void GP_VLineXYY(GP_Context *context, GP_Coord x, GP_Coord y0,
@@ -68,12 +68,12 @@ void GP_VLineXYY(GP_Context *context, GP_Coord x, GP_Coord y0,
}
}
-void GP_VLineXYH(GP_Context *context, GP_Coord x, GP_Coord y,
- GP_Size height, GP_Pixel pixel)
+void GP_VLineXYH(GP_Context *context, GP_Coord x, GP_Coord y, GP_Size h,
+ GP_Pixel pixel)
{
/* zero height: do not draw anything */
- if (height == 0)
+ if (h == 0)
return;
- GP_VLineXYY(context, x, y, y + height - 1, pixel);
+ GP_VLineXYY(context, x, y, y + h - 1, pixel);
}
-----------------------------------------------------------------------
Summary of changes:
doc/Makefile | 3 +-
doc/basic_types.txt | 84 ++++++++++++--------------------
doc/context.txt | 39 +++++----------
doc/drawing_api.txt | 117 ++++++++++++++++++++++++++++----------------
doc/filters.txt | 14 ++----
include/core/GP_Color.h | 10 ++--
include/core/GP_Context.h | 8 ++--
include/gfx/GP_VLine.h | 8 ++--
libs/core/GP_Color.c | 11 +++--
libs/gfx/GP_VLine.c | 16 +++---
10 files changed, 154 insertions(+), 156 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 generate updated: 24db76060a41a8d3abb75c57e552d9a784bf5948
by metan 25 Jul '11
by metan 25 Jul '11
25 Jul '11
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, generate has been updated
via 24db76060a41a8d3abb75c57e552d9a784bf5948 (commit)
from 8a21bc6f957aa940853da65d443afdb21be9b891 (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/24db76060a41a8d3abb75c57e552d9a784bf…
commit 24db76060a41a8d3abb75c57e552d9a784bf5948
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Jul 25 14:47:44 2011 +0200
Removed clipping rectangle in preparation for subcontext.
diff --git a/include/core/GP_Clip.h b/include/core/GP_Clip.h
deleted file mode 100644
index a6e5261..0000000
--- a/include/core/GP_Clip.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*****************************************************************************
- * 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-2010 Jiri "BlueBear" Dluhos *
- * <jiri.bluebear.dluhos(a)gmail.com> *
- * *
- * Copyright (C) 2009-2010 Cyril Hrubis <metan(a)ucw.cz> *
- * *
- *****************************************************************************/
-
-#ifndef GP_CLIP_H
-#define GP_CLIP_H
-
-/*
- * Clipping rectanle mirroring and rotations.
- */
-#define GP_MIRROR_V_CLIP(context) do { - typeof(context->clip_w_min) _clip_w_min = context->clip_w_min; - - context->clip_w_min = context->w - context->clip_w_max; - context->clip_w_max = context->w - _clip_w_min; -} while (0)
-
-#define GP_MIRROR_H_CLIP(context) do { - typeof(context->clip_h_min) _clip_h_min = context->clip_h_min; - - context->clip_h_min = context->h - context->clip_h_max; - context->clip_h_max = context->h - _clip_h_min; -} while (0)
-
-#define GP_SWAP_CLIPS(context) do { - GP_SWAP(context->clip_w_min, context->clip_h_min); - GP_SWAP(context->clip_w_max, context->clip_h_max); -} while (0)
-
-#endif /* GP_CLIP_H */
diff --git a/include/core/GP_Context.h b/include/core/GP_Context.h
index 2e640da..4bffd66 100644
--- a/include/core/GP_Context.h
+++ b/include/core/GP_Context.h
@@ -16,10 +16,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
+ * Copyright (C) 2009-2011 Jiri "BlueBear" Dluhos *
* <jiri.bluebear.dluhos(a)gmail.com> *
* *
- * Copyright (C) 2009-2010 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -38,8 +38,8 @@ typedef struct GP_Context {
uint8_t *pixels; /* pointer to image pixels */
uint8_t bpp; /* values: 1, 2, 4, 8, 16, 24, 32 */
uint32_t bytes_per_row;
- uint32_t w; /* width */
- uint32_t h; /* height */
+ uint32_t w; /* width in pixels */
+ uint32_t h; /* height in pixels */
GP_PixelType pixel_type; /* hardware pixel format */
@@ -50,12 +50,6 @@ typedef struct GP_Context {
uint8_t x_swap:1; /* swap direction on x */
uint8_t y_swap:1; /* swap direction on y */
uint8_t bit_endian:1; /* GP_BIT_ENDIAN */
-
- /* clipping rectangle; drawing functions only affect the inside */
- uint32_t clip_w_min;
- uint32_t clip_w_max;
- uint32_t clip_h_min;
- uint32_t clip_h_max;
} GP_Context;
/* Returns the pixel type used by the context. */
@@ -82,22 +76,14 @@ static inline GP_PixelType GP_GetContextPixelType(const GP_Context *context)
GP_CHECK(context->pixels, "invalid context: NULL image pointer"); GP_CHECK(context->bpp <= 32, "invalid context: unsupported bits-per-pixel count"); GP_CHECK(context->w > 0 && context->h > 0, "invalid context: invalid image size"); - GP_CHECK(context->clip_w_min <= context->clip_w_max - && context->clip_h_min <= context->clip_h_max, - "invalid context: invalid clipping rectangle"); - GP_CHECK(context->clip_w_max < context->w - && context->clip_h_max < context->h, - "invalid context: clipping rectangle larger than image"); } while (0)
/*
- * Is true, when pixel is clipped.
+ * Is true, when pixel is clipped out of context.
*/
#define GP_PIXEL_IS_CLIPPED(context, x, y) - (x < (int) context->clip_w_min - || x > (int) context->clip_w_max - || y < (int) context->clip_h_min - || y > (int) context->clip_h_max) + ((x) < 0 || x >= (int) context->w + || (y) < 0 || y >= (int) context->h)
/*
* Allocate context.
diff --git a/libs/SDL/GP_SDL_Context.c b/libs/SDL/GP_SDL_Context.c
index e8b7500..3378d3b 100644
--- a/libs/SDL/GP_SDL_Context.c
+++ b/libs/SDL/GP_SDL_Context.c
@@ -57,11 +57,5 @@ GP_RetCode GP_SDL_ContextFromSurface(GP_Context *context, SDL_Surface *surf)
context->x_swap = 0;
context->y_swap = 0;
- /* clipping */
- context->clip_h_min = surf->clip_rect.y;
- context->clip_h_max = surf->clip_rect.y + surf->clip_rect.h - 1;
- context->clip_w_min = surf->clip_rect.x;
- context->clip_w_max = surf->clip_rect.x + surf->clip_rect.w - 1;
-
return GP_ESUCCESS;
}
diff --git a/libs/backends/GP_Backend_SDL.c b/libs/backends/GP_Backend_SDL.c
index c3fd9ac..a0a40e6 100644
--- a/libs/backends/GP_Backend_SDL.c
+++ b/libs/backends/GP_Backend_SDL.c
@@ -77,12 +77,6 @@ inline GP_RetCode GP_SDL_ContextFromSurface(
context->x_swap = 0;
context->y_swap = 0;
- /* clipping */
- context->clip_h_min = surf->clip_rect.y;
- context->clip_h_max = surf->clip_rect.y + surf->clip_rect.h - 1;
- context->clip_w_min = surf->clip_rect.x;
- context->clip_w_max = surf->clip_rect.x + surf->clip_rect.w - 1;
-
return GP_ESUCCESS;
}
diff --git a/libs/core/GP_Context.c b/libs/core/GP_Context.c
index 1660d25..58c6a0b 100644
--- a/libs/core/GP_Context.c
+++ b/libs/core/GP_Context.c
@@ -16,10 +16,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
+ * Copyright (C) 2009-2011 Jiri "BlueBear" Dluhos *
* <jiri.bluebear.dluhos(a)gmail.com> *
* *
- * Copyright (C) 2009-2010 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -63,12 +63,6 @@ GP_Context *GP_ContextCopy(GP_Context *context, int flag)
new->y_swap = context->y_swap;
new->x_swap = context->x_swap;
- /* clipping */
- new->clip_w_min = context->clip_w_min;
- new->clip_w_max = context->clip_w_max;
- new->clip_h_min = context->clip_h_min;
- new->clip_h_max = context->clip_h_max;
-
return new;
}
@@ -102,12 +96,6 @@ GP_Context *GP_ContextAlloc(uint32_t w, uint32_t h, GP_PixelType type)
context->y_swap = 0;
context->x_swap = 0;
- /* clipping */
- context->clip_w_min = 0;
- context->clip_w_max = w - 1;
- context->clip_h_min = 0;
- context->clip_h_max = h - 1;
-
return context;
}
diff --git a/libs/core/GP_GetPutPixel.c b/libs/core/GP_GetPutPixel.c
index 9cac910..774be54 100644
--- a/libs/core/GP_GetPutPixel.c
+++ b/libs/core/GP_GetPutPixel.c
@@ -34,6 +34,6 @@ GP_Pixel GP_GetPixel(const GP_Context *context, int x, int y)
void GP_PutPixel(GP_Context *context, int x, int y, GP_Pixel p)
{
GP_TRANSFORM_POINT(context, x, y);
- if (! GP_PIXEL_IS_CLIPPED(context, x, y))
+ if (!GP_PIXEL_IS_CLIPPED(context, x, y))
GP_PutPixel_Raw(context, x, y, p);
}
diff --git a/libs/filters/GP_Rotate.c b/libs/filters/GP_Rotate.c
index adb0ce2..6967514 100644
--- a/libs/filters/GP_Rotate.c
+++ b/libs/filters/GP_Rotate.c
@@ -51,8 +51,6 @@ GP_RetCode GP_MirrorH(GP_Context *context)
memcpy(l2, buf, bpr);
}
- GP_MIRROR_H_CLIP(context);
-
return GP_ESUCCESS;
}
diff --git a/libs/filters/algo/GP_MirrorV.algo.h b/libs/filters/algo/GP_MirrorV.algo.h
index 3ea1438..6555700 100644
--- a/libs/filters/algo/GP_MirrorV.algo.h
+++ b/libs/filters/algo/GP_MirrorV.algo.h
@@ -16,16 +16,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
+ * Copyright (C) 2009-2011 Jiri "BlueBear" Dluhos *
* <jiri.bluebear.dluhos(a)gmail.com> *
* *
- * Copyright (C) 2009-2010 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
-#include "core/GP_Clip.h"
-
#define DEF_MIRRORV_FN(FN_NAME, CONTEXT_T, PIXEL_T, PUTPIXEL, GETPIXEL) void FN_NAME(CONTEXT_T context) { @@ -41,6 +39,4 @@ void FN_NAME(CONTEXT_T context) PUTPIXEL(context, xm, y, tmp); } } -- GP_MIRROR_V_CLIP(context); }
diff --git a/libs/filters/algo/GP_Rotate.algo.h b/libs/filters/algo/GP_Rotate.algo.h
index e6ea14d..bc7528d 100644
--- a/libs/filters/algo/GP_Rotate.algo.h
+++ b/libs/filters/algo/GP_Rotate.algo.h
@@ -16,14 +16,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
+ * Copyright (C) 2009-2011 Jiri "BlueBear" Dluhos *
* <jiri.bluebear.dluhos(a)gmail.com> *
* *
- * Copyright (C) 2009-2010 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
-#include "core/GP_Clip.h"
#include "core/GP_Common.h"
#include "core/GP_Context.h"
@@ -52,9 +51,6 @@ GP_RetCode FN_NAME(CONTEXT_T context) GP_ContextFree(tmp); - GP_SWAP_CLIPS(context); - GP_MIRROR_H_CLIP(context); - return GP_ESUCCESS; }
@@ -83,8 +79,5 @@ GP_RetCode FN_NAME(CONTEXT_T context) GP_ContextFree(tmp); - GP_SWAP_CLIPS(context); - GP_MIRROR_V_CLIP(context); - return GP_ESUCCESS; }
diff --git a/libs/gfx/algo/Circle.algo.h b/libs/gfx/algo/Circle.algo.h
index 96eb3b4..f5f5acc 100644
--- a/libs/gfx/algo/Circle.algo.h
+++ b/libs/gfx/algo/Circle.algo.h
@@ -16,10 +16,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
+ * Copyright (C) 2009-2011 Jiri "BlueBear" Dluhos *
* <jiri.bluebear.dluhos(a)gmail.com> *
* *
- * Copyright (C) 2009-2010 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
diff --git a/libs/gfx/algo/HLine.algo.h b/libs/gfx/algo/HLine.algo.h
index a62ae50..91dd35f 100644
--- a/libs/gfx/algo/HLine.algo.h
+++ b/libs/gfx/algo/HLine.algo.h
@@ -16,10 +16,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
+ * Copyright (C) 2009-2011 Jiri "BlueBear" Dluhos *
* <jiri.bluebear.dluhos(a)gmail.com> *
* *
- * Copyright (C) 2009-2010 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -28,16 +28,14 @@
/* Ensures that coordinates are in correct order, and clips them.
* Exits immediately if the line is completely clipped out.
*/
-#define ORDER_AND_CLIP_COORDS do { - if (x0 > x1) GP_SWAP(x0, x1); - if (y < (int) context->clip_h_min - || y > (int) context->clip_h_max - || x0 > (int) context->clip_w_max - || x1 < (int) context->clip_w_min) { - return; - } - x0 = GP_MAX(x0, (int) context->clip_w_min); - x1 = GP_MIN(x1, (int) context->clip_w_max); +#define ORDER_AND_CLIP_COORDS do { + if (x0 > x1) + GP_SWAP(x0, x1); + if (y < 0 || y >= (int) context->h || + x1 < 0 || x0 >= (int) context->w) + return; + x0 = GP_MAX(x0, 0); + x1 = GP_MIN(x1, (int) context->w - 1); } while (0)
/*
diff --git a/libs/gfx/algo/VLine.algo.h b/libs/gfx/algo/VLine.algo.h
index daa6f9d..b33a448 100644
--- a/libs/gfx/algo/VLine.algo.h
+++ b/libs/gfx/algo/VLine.algo.h
@@ -16,10 +16,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
+ * Copyright (C) 2009-2011 Jiri "BlueBear" Dluhos *
* <jiri.bluebear.dluhos(a)gmail.com> *
* *
- * Copyright (C) 2009-2010 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -28,16 +28,14 @@
/* Ensures that coordinates are in correct order, and clips them.
* Exits immediately if the line is completely clipped out.
*/
-#define ORDER_AND_CLIP_COORDS do { - if (y0 > y1) GP_SWAP(y0, y1); - if (x < (int) context->clip_w_min - || x > (int) context->clip_w_max - || y1 < (int) context->clip_h_min - || y0 > (int) context->clip_h_max) { - return; - } - y0 = GP_MAX(y0, (int) context->clip_h_min); - y1 = GP_MIN(y1, (int) context->clip_h_max); +#define ORDER_AND_CLIP_COORDS do { + if (y0 > y1) + GP_SWAP(y0, y1); + if (x < 0 || x >= (int) context->w || + y1 < 0 || y0 >= (int) context->h) + return; + y0 = GP_MAX(y0, 0); + y1 = GP_MIN(y1, (int) context->h - 1); } while (0)
/*
-----------------------------------------------------------------------
Summary of changes:
include/core/GP_Clip.h | 51 -----------------------------------
include/core/GP_Context.h | 28 +++++--------------
libs/SDL/GP_SDL_Context.c | 6 ----
libs/backends/GP_Backend_SDL.c | 6 ----
libs/core/GP_Context.c | 16 +---------
libs/core/GP_GetPutPixel.c | 2 +-
libs/filters/GP_Rotate.c | 2 -
libs/filters/algo/GP_MirrorV.algo.h | 8 +----
libs/filters/algo/GP_Rotate.algo.h | 11 +------
libs/gfx/algo/Circle.algo.h | 4 +-
libs/gfx/algo/HLine.algo.h | 22 +++++++--------
libs/gfx/algo/VLine.algo.h | 22 +++++++--------
12 files changed, 36 insertions(+), 142 deletions(-)
delete mode 100644 include/core/GP_Clip.h
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