Merge branch 'agg-canvas' into agg-cpp-native - gsl-shell.git - gsl-shell

index : gsl-shell.git
gsl-shell
summary refs log tree commit diff
path: root/agg-plot
diff options
context:
space:
mode:
authorfrancesco-ST <francesco.abbate@st.com>2010年07月16日 13:35:58 +0200
committerfrancesco-ST <francesco.abbate@st.com>2010年07月16日 13:35:58 +0200
commit990d860748748a2ef39856c1e3f93089f316110c (patch)
tree48126771627c072990dcb4a756891e87b6b119b4 /agg-plot
parente3aa215ce35cc6952dd90cf55c7cd627d9be2a5f (diff)
parent4a52c75c22bb6ccffa25bb296ad0e5fda7742027 (diff)
downloadgsl-shell-990d860748748a2ef39856c1e3f93089f316110c.tar.gz
Merge branch 'agg-canvas' into agg-cpp-native
Diffstat (limited to 'agg-plot')
-rw-r--r--agg-plot/Makefile 5
-rw-r--r--agg-plot/agg-parse-trans.cpp 201
-rw-r--r--agg-plot/agg-parse-trans.h 16
-rw-r--r--agg-plot/agg_platform_support_win32.cpp 4
-rw-r--r--agg-plot/agg_platform_support_x11.cpp 2522
-rw-r--r--agg-plot/colors.cpp 24
-rw-r--r--agg-plot/colors.h 5
-rw-r--r--agg-plot/lua-draw.cpp 54
-rw-r--r--agg-plot/lua-plot.cpp 232
-rw-r--r--agg-plot/plot-window.cpp 345
-rw-r--r--agg-plot/plot-window.h 16
-rw-r--r--agg-plot/trans.h 22
-rw-r--r--agg-plot/xwin-show.cpp 4
13 files changed, 1948 insertions, 1502 deletions
diff --git a/agg-plot/Makefile b/agg-plot/Makefile
index e1945ae2..de471055 100644
--- a/agg-plot/Makefile
+++ b/agg-plot/Makefile
@@ -44,7 +44,7 @@ endif
INCLUDES += $(AGG_INCLUDES) -I$(GSH_BASE_DIR) -I$(LUADIR)/src
-AGGPLOT_SRC_FILES = $(PLATSUP_SRC_FILES) utils.cpp units.cpp colors.cpp lua-draw.cpp lua-plot.cpp xwin-show.cpp
+AGGPLOT_SRC_FILES = $(PLATSUP_SRC_FILES) utils.cpp units.cpp colors.cpp lua-draw.cpp lua-plot.cpp agg-parse-trans.cpp xwin-show.cpp plot-window.cpp
AGGPLOT_OBJ_FILES := $(AGGPLOT_SRC_FILES:%.cpp=%.o)
@@ -58,9 +58,6 @@ TARGETS = libaggplot.a
all: $(TARGETS)
-#test.exe: $(AGGPLOT_OBJ_FILES)
-# gcc -o test.exe $(AGGPLOT_OBJ_FILES) $(AGG_LIBS)
-
libaggplot.a: $(AGGPLOT_OBJ_FILES)
$(AR) $@ $?
$(RANLIB) $@
diff --git a/agg-plot/agg-parse-trans.cpp b/agg-plot/agg-parse-trans.cpp
new file mode 100644
index 00000000..30657622
--- /dev/null
+++ b/agg-plot/agg-parse-trans.cpp
@@ -0,0 +1,201 @@
+
+extern "C" {
+#include "lua.h"
+#include "lauxlib.h"
+}
+
+#include "agg-parse-trans.h"
+#include "lua-cpp-utils.h"
+#include "lua-utils.h"
+#include "gs-types.h"
+#include "trans.h"
+
+struct property_reg {
+ int id;
+ const char *name;
+};
+
+struct builder_reg {
+ const char *name;
+ vertex_source *(*func)(lua_State *, int, vertex_source *);
+};
+
+static vertex_source * build_stroke (lua_State *L, int i, vertex_source *s);
+static vertex_source * build_curve (lua_State *L, int i, vertex_source *s);
+static vertex_source * build_marker (lua_State *L, int i, vertex_source *s);
+static vertex_source * build_dash (lua_State *L, int i, vertex_source *s);
+static vertex_source * build_extend (lua_State *L, int i, vertex_source *s);
+static vertex_source * build_translate (lua_State *L, int i, vertex_source *s);
+static vertex_source * build_rotate (lua_State *L, int i, vertex_source *s);
+
+struct property_reg line_cap_properties[] = {
+ {(int) agg::butt_cap, "butt" },
+ {(int) agg::square_cap, "square"},
+ {(int) agg::round_cap, "round" },
+ {0, NULL}
+};
+
+struct property_reg line_join_properties[] = {
+ {(int) agg::miter_join, "miter" },
+ {(int) agg::miter_join_revert, "miter.rev" },
+ {(int) agg::round_join, "round" },
+ {(int) agg::bevel_join, "bevel" },
+ {(int) agg::miter_join_round, "miter.round"},
+ {0, NULL}
+};
+
+const builder_reg builder_table[] = {
+ {"stroke", build_stroke },
+ {"dash", build_dash},
+ {"curve", build_curve},
+ {"marker", build_marker},
+ {"extend", build_extend},
+ {"translate", build_translate},
+ {"rotate", build_rotate},
+ {NULL, NULL}
+};
+
+static int
+property_lookup (struct property_reg *prop, const char *key)
+{
+ int default_value = prop->id;
+
+ if (key == NULL)
+ return default_value;
+
+ for ( ; prop->name; prop++)
+ {
+ if (strcmp (prop->name, key) == 0)
+ return prop->id;
+ }
+
+ return default_value;
+}
+
+vertex_source *
+build_stroke (lua_State *L, int specindex, vertex_source *obj)
+{
+ double width = mlua_named_optnumber (L, specindex, "width", 1.0);
+ const char *cap_str = mlua_named_optstring (L, specindex, "cap", NULL);
+ const char *join_str = mlua_named_optstring (L, specindex, "join", NULL);
+
+ trans::stroke *stroke = new trans::stroke(obj, width);
+
+ if (cap_str)
+ {
+ int cap = property_lookup (line_cap_properties, cap_str);
+ stroke->line_cap((agg::line_cap_e) cap);
+ }
+
+ if (join_str)
+ {
+ int join = property_lookup (line_join_properties, join_str);
+ stroke->line_join((agg::line_join_e) join);
+ }
+
+ return (vertex_source *) stroke;
+}
+
+vertex_source *
+build_curve (lua_State *L, int specindex, vertex_source *obj)
+{
+ trans::curve *c = new trans::curve(obj);
+ return (vertex_source *) c;
+}
+
+vertex_source *
+build_marker (lua_State *L, int specindex, vertex_source *obj)
+{
+ double size = mlua_named_optnumber (L, specindex, "size", 3.0);
+ return (vertex_source *) new trans::marker(obj, size);
+}
+
+vertex_source *
+build_dash (lua_State *L, int specindex, vertex_source *obj)
+{
+ double a = mlua_named_optnumber (L, specindex, "a", 10.0);
+ double b = mlua_named_optnumber (L, specindex, "b", a);
+
+ trans::dash *dash = new trans::dash(obj);
+ dash->add_dash(a, b);
+
+ return (vertex_source *) dash;
+}
+
+vertex_source *
+build_extend (lua_State *L, int specindex, vertex_source *obj)
+{
+ double width = mlua_named_optnumber (L, specindex, "width", 1.0);
+ return (vertex_source *) new trans::extend(obj, width);
+}
+
+vertex_source *
+build_translate (lua_State *L, int specindex, vertex_source *obj)
+{
+ double x = mlua_named_number (L, specindex, "x");
+ double y = mlua_named_number (L, specindex, "y");
+
+ trans::affine *t = new trans::affine(obj);
+ t->translate(x, y);
+
+ return (vertex_source *) t;
+}
+
+vertex_source *
+build_rotate (lua_State *L, int specindex, vertex_source *obj)
+{
+ double a = mlua_named_number (L, specindex, "angle");
+
+ trans::affine *t = new trans::affine(obj);
+ t->rotate(a);
+
+ return (vertex_source *) t;
+}
+
+vertex_source *
+parse_spec (lua_State *L, int specindex, vertex_source *obj)
+{
+ const char *tag;
+
+ lua_rawgeti (L, specindex, 1);
+ if (! lua_isstring (L, -1))
+ {
+ luaL_error (L, "the tag of the transformation is invalid");
+ return NULL;
+ }
+
+ tag = lua_tostring (L, -1);
+ lua_pop (L, 1);
+
+ for (const builder_reg *b = builder_table; b->name != NULL; b++)
+ {
+ if (strcmp (b->name, tag) == 0)
+ return b->func (L, specindex, obj);
+ }
+
+ luaL_error (L, "invalid trasformation tag");
+ return NULL;
+}
+
+vertex_source *
+parse_spec_pipeline (lua_State *L, int index, vertex_source *obj)
+{
+ size_t k, nb;
+
+ if (lua_type (L, index) == LUA_TTABLE)
+ nb = lua_objlen (L, index);
+ else
+ {
+ luaL_error (L, "post transform argument should be a table");
+ return NULL;
+ }
+
+ for (k = nb; k > 0; k--)
+ {
+ lua_rawgeti (L, index, k);
+ obj = parse_spec (L, index+1, obj);
+ lua_pop (L, 1);
+ }
+
+ return obj;
+}
diff --git a/agg-plot/agg-parse-trans.h b/agg-plot/agg-parse-trans.h
new file mode 100644
index 00000000..87973582
--- /dev/null
+++ b/agg-plot/agg-parse-trans.h
@@ -0,0 +1,16 @@
+#ifndef AGG_PARSE_TRANS_H
+#define AGG_PARSE_TRANS_H
+
+extern "C" {
+#include "lua.h"
+}
+
+#include "vertex-source.h"
+
+extern vertex_source * parse_spec (lua_State *L, int specindex,
+ vertex_source *obj);
+
+extern vertex_source * parse_spec_pipeline (lua_State *L, int index,
+ vertex_source *obj);
+
+#endif
diff --git a/agg-plot/agg_platform_support_win32.cpp b/agg-plot/agg_platform_support_win32.cpp
index 71589048..3a8f52a9 100644
--- a/agg-plot/agg_platform_support_win32.cpp
+++ b/agg-plot/agg_platform_support_win32.cpp
@@ -1056,8 +1056,6 @@ namespace agg
{
MSG msg;
- pthread_mutex_lock (m_specific->m_mutex);
-
for(;;)
{
if(m_wait_mode)
@@ -1093,8 +1091,6 @@ namespace agg
}
}
- pthread_mutex_unlock (m_specific->m_mutex);
-
return (int)msg.wParam;
}
diff --git a/agg-plot/agg_platform_support_x11.cpp b/agg-plot/agg_platform_support_x11.cpp
index 567f8e44..8e9152a7 100644
--- a/agg-plot/agg_platform_support_x11.cpp
+++ b/agg-plot/agg_platform_support_x11.cpp
@@ -1,1263 +1,1259 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry (AGG) - Version 2.5
-// A high quality rendering engine for C++
-// Copyright (C) 2002-2006 Maxim Shemanarev
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://antigrain.com
-//
-// AGG is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// AGG 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 General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with AGG; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-// MA 02110-1301, USA.
-//----------------------------------------------------------------------------
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <time.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/keysym.h>
-#include <pthread.h>
-#include "agg_basics.h"
-#include "util/agg_color_conv_rgb8.h"
-#include "platform/agg_platform_support.h"
-
-
-namespace agg
-{
- //------------------------------------------------------------------------
- class platform_specific
- {
- public:
- platform_specific(pix_format_e format, bool flip_y);
- ~platform_specific();
-
- void caption(const char* capt);
- void put_image(const rendering_buffer* src);
-
- pix_format_e m_format;
- pix_format_e m_sys_format;
- int m_byte_order;
- bool m_flip_y;
- unsigned m_bpp;
- unsigned m_sys_bpp;
- Display* m_display;
- int m_screen;
- int m_depth;
- Visual* m_visual;
- Window m_window;
- GC m_gc;
- XImage* m_ximg_window;
- XSetWindowAttributes m_window_attributes;
- Atom m_close_atom;
- unsigned char* m_buf_window;
- unsigned char* m_buf_img[platform_support::max_images];
- unsigned m_keymap[256];
-
- bool m_update_flag;
- bool m_resize_flag;
- bool m_initialized;
- bool m_is_mapped;
- clock_t m_sw_start;
-
- pthread_mutex_t m_mutex[1];
-
- };
-
-
-
- //------------------------------------------------------------------------
- platform_specific::platform_specific(pix_format_e format, bool flip_y) :
- m_format(format),
- m_sys_format(pix_format_undefined),
- m_byte_order(LSBFirst),
- m_flip_y(flip_y),
- m_bpp(0),
- m_sys_bpp(0),
- m_display(0),
- m_screen(0),
- m_depth(0),
- m_visual(0),
- m_window(0),
- m_gc(0),
- m_ximg_window(0),
- m_close_atom(0),
-
- m_buf_window(0),
-
- m_update_flag(true),
- m_resize_flag(true),
- m_initialized(false),
- m_is_mapped(false)
- {
- memset(m_buf_img, 0, sizeof(m_buf_img));
-
- unsigned i;
- for(i = 0; i < 256; i++)
- {
- m_keymap[i] = i;
- }
-
- m_keymap[XK_Pause&0xFF] = key_pause;
- m_keymap[XK_Clear&0xFF] = key_clear;
-
- m_keymap[XK_KP_0&0xFF] = key_kp0;
- m_keymap[XK_KP_1&0xFF] = key_kp1;
- m_keymap[XK_KP_2&0xFF] = key_kp2;
- m_keymap[XK_KP_3&0xFF] = key_kp3;
- m_keymap[XK_KP_4&0xFF] = key_kp4;
- m_keymap[XK_KP_5&0xFF] = key_kp5;
- m_keymap[XK_KP_6&0xFF] = key_kp6;
- m_keymap[XK_KP_7&0xFF] = key_kp7;
- m_keymap[XK_KP_8&0xFF] = key_kp8;
- m_keymap[XK_KP_9&0xFF] = key_kp9;
-
- m_keymap[XK_KP_Insert&0xFF] = key_kp0;
- m_keymap[XK_KP_End&0xFF] = key_kp1;
- m_keymap[XK_KP_Down&0xFF] = key_kp2;
- m_keymap[XK_KP_Page_Down&0xFF] = key_kp3;
- m_keymap[XK_KP_Left&0xFF] = key_kp4;
- m_keymap[XK_KP_Begin&0xFF] = key_kp5;
- m_keymap[XK_KP_Right&0xFF] = key_kp6;
- m_keymap[XK_KP_Home&0xFF] = key_kp7;
- m_keymap[XK_KP_Up&0xFF] = key_kp8;
- m_keymap[XK_KP_Page_Up&0xFF] = key_kp9;
- m_keymap[XK_KP_Delete&0xFF] = key_kp_period;
- m_keymap[XK_KP_Decimal&0xFF] = key_kp_period;
- m_keymap[XK_KP_Divide&0xFF] = key_kp_divide;
- m_keymap[XK_KP_Multiply&0xFF] = key_kp_multiply;
- m_keymap[XK_KP_Subtract&0xFF] = key_kp_minus;
- m_keymap[XK_KP_Add&0xFF] = key_kp_plus;
- m_keymap[XK_KP_Enter&0xFF] = key_kp_enter;
- m_keymap[XK_KP_Equal&0xFF] = key_kp_equals;
-
- m_keymap[XK_Up&0xFF] = key_up;
- m_keymap[XK_Down&0xFF] = key_down;
- m_keymap[XK_Right&0xFF] = key_right;
- m_keymap[XK_Left&0xFF] = key_left;
- m_keymap[XK_Insert&0xFF] = key_insert;
- m_keymap[XK_Home&0xFF] = key_delete;
- m_keymap[XK_End&0xFF] = key_end;
- m_keymap[XK_Page_Up&0xFF] = key_page_up;
- m_keymap[XK_Page_Down&0xFF] = key_page_down;
-
- m_keymap[XK_F1&0xFF] = key_f1;
- m_keymap[XK_F2&0xFF] = key_f2;
- m_keymap[XK_F3&0xFF] = key_f3;
- m_keymap[XK_F4&0xFF] = key_f4;
- m_keymap[XK_F5&0xFF] = key_f5;
- m_keymap[XK_F6&0xFF] = key_f6;
- m_keymap[XK_F7&0xFF] = key_f7;
- m_keymap[XK_F8&0xFF] = key_f8;
- m_keymap[XK_F9&0xFF] = key_f9;
- m_keymap[XK_F10&0xFF] = key_f10;
- m_keymap[XK_F11&0xFF] = key_f11;
- m_keymap[XK_F12&0xFF] = key_f12;
- m_keymap[XK_F13&0xFF] = key_f13;
- m_keymap[XK_F14&0xFF] = key_f14;
- m_keymap[XK_F15&0xFF] = key_f15;
-
- m_keymap[XK_Num_Lock&0xFF] = key_numlock;
- m_keymap[XK_Caps_Lock&0xFF] = key_capslock;
- m_keymap[XK_Scroll_Lock&0xFF] = key_scrollock;
-
- switch(m_format)
- {
- default: break;
- case pix_format_gray8:
- m_bpp = 8;
- break;
-
- case pix_format_rgb565:
- case pix_format_rgb555:
- m_bpp = 16;
- break;
-
- case pix_format_rgb24:
- case pix_format_bgr24:
- m_bpp = 24;
- break;
-
- case pix_format_bgra32:
- case pix_format_abgr32:
- case pix_format_argb32:
- case pix_format_rgba32:
- m_bpp = 32;
- break;
- }
- m_sw_start = clock();
-
- pthread_mutex_init (m_mutex, NULL);
- }
-
- //------------------------------------------------------------------------
- platform_specific::~platform_specific()
- {
- pthread_mutex_destroy (m_mutex);
- }
-
- //------------------------------------------------------------------------
- void platform_specific::caption(const char* capt)
- {
- // Fixed by Enno Fennema (in original AGG library)
- XStoreName(m_display, m_window, capt);
- XSetIconName(m_display, m_window, capt);
- }
-
-
- //------------------------------------------------------------------------
- void platform_specific::put_image(const rendering_buffer* src)
- {
- if(m_ximg_window == 0) return;
- m_ximg_window->data = (char*)m_buf_window;
-
- if(m_format == m_sys_format)
- {
- XPutImage(m_display,
- m_window,
- m_gc,
- m_ximg_window,
- 0, 0, 0, 0,
- src->width(),
- src->height());
- }
- else
- {
- int row_len = src->width() * m_sys_bpp / 8;
- unsigned char* buf_tmp =
- new unsigned char[row_len * src->height()];
-
- rendering_buffer rbuf_tmp;
- rbuf_tmp.attach(buf_tmp,
- src->width(),
- src->height(),
- m_flip_y ? -row_len : row_len);
-
- switch(m_sys_format)
- {
- default: break;
- case pix_format_rgb555:
- switch(m_format)
- {
- default: break;
- case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgb555()); break;
- case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555()); break;
- case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_rgb555()); break;
- case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb555()); break;
- case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_rgb555()); break;
- case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_rgb555()); break;
- case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_rgb555()); break;
- case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_rgb555()); break;
- }
- break;
-
- case pix_format_rgb565:
- switch(m_format)
- {
- default: break;
- case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgb565()); break;
- case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb565()); break;
- case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_rgb565()); break;
- case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb565()); break;
- case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_rgb565()); break;
- case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_rgb565()); break;
- case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_rgb565()); break;
- case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_rgb565()); break;
- }
- break;
-
- case pix_format_rgba32:
- switch(m_format)
- {
- default: break;
- case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgba32()); break;
- case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgba32()); break;
- case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_rgba32()); break;
- case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgba32()); break;
- case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_rgba32()); break;
- case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_rgba32()); break;
- case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_rgba32()); break;
- case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_rgba32()); break;
- }
- break;
-
- case pix_format_abgr32:
- switch(m_format)
- {
- default: break;
- case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_abgr32()); break;
- case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_abgr32()); break;
- case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_abgr32()); break;
- case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_abgr32()); break;
- case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_abgr32()); break;
- case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_abgr32()); break;
- case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_abgr32()); break;
- case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_abgr32()); break;
- }
- break;
-
- case pix_format_argb32:
- switch(m_format)
- {
- default: break;
- case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_argb32()); break;
- case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_argb32()); break;
- case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_argb32()); break;
- case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_argb32()); break;
- case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_argb32()); break;
- case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_argb32()); break;
- case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_argb32()); break;
- case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_argb32()); break;
- }
- break;
-
- case pix_format_bgra32:
- switch(m_format)
- {
- default: break;
- case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_bgra32()); break;
- case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_bgra32()); break;
- case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_bgra32()); break;
- case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_bgra32()); break;
- case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_bgra32()); break;
- case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_bgra32()); break;
- case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_bgra32()); break;
- case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_bgra32()); break;
- }
- break;
- }
-
- m_ximg_window->data = (char*)buf_tmp;
- XPutImage(m_display,
- m_window,
- m_gc,
- m_ximg_window,
- 0, 0, 0, 0,
- src->width(),
- src->height());
-
- delete [] buf_tmp;
- }
- }
-
- //------------------------------------------------------------------------
- platform_support::platform_support(pix_format_e format, bool flip_y) :
- m_specific(new platform_specific(format, flip_y)),
- m_format(format),
- m_bpp(m_specific->m_bpp),
- m_window_flags(0),
- m_wait_mode(true),
- m_flip_y(flip_y),
- m_initial_width(10),
- m_initial_height(10)
- {
- strcpy(m_caption, "AGG Application");
- }
-
- //------------------------------------------------------------------------
- platform_support::~platform_support()
- {
- delete m_specific;
- }
-
-
-
- //------------------------------------------------------------------------
- void platform_support::caption(const char* cap)
- {
- strcpy(m_caption, cap);
- if(m_specific->m_initialized)
- {
- m_specific->caption(cap);
- }
- }
-
-
- //------------------------------------------------------------------------
- enum xevent_mask_e
- {
- xevent_mask =
- PointerMotionMask|
- ButtonPressMask|
- ButtonReleaseMask|
- ExposureMask|
- KeyPressMask|
- StructureNotifyMask
- };
-
-
- //------------------------------------------------------------------------
- bool platform_support::init(unsigned width, unsigned height, unsigned flags)
- {
- m_window_flags = flags;
-
- m_specific->m_display = XOpenDisplay(NULL);
- if(m_specific->m_display == 0)
- {
- fprintf(stderr, "Unable to open DISPLAY!\n");
- return false;
- }
-
- m_specific->m_screen = XDefaultScreen(m_specific->m_display);
- m_specific->m_depth = XDefaultDepth(m_specific->m_display,
- m_specific->m_screen);
- m_specific->m_visual = XDefaultVisual(m_specific->m_display,
- m_specific->m_screen);
- unsigned long r_mask = m_specific->m_visual->red_mask;
- unsigned long g_mask = m_specific->m_visual->green_mask;
- unsigned long b_mask = m_specific->m_visual->blue_mask;
-
- if(m_specific->m_depth < 15 ||
- r_mask == 0 || g_mask == 0 || b_mask == 0)
- {
- fprintf(stderr,
- "There's no Visual compatible with minimal AGG requirements:\n"
- "At least 15-bit color depth and True- or DirectColor class.\n\n");
- XCloseDisplay(m_specific->m_display);
- return false;
- }
-
- int t = 1;
- int hw_byte_order = LSBFirst;
- if(*(char*)&t == 0) hw_byte_order = MSBFirst;
-
- // Perceive SYS-format by mask
- switch(m_specific->m_depth)
- {
- case 15:
- m_specific->m_sys_bpp = 16;
- if(r_mask == 0x7C00 && g_mask == 0x3E0 && b_mask == 0x1F)
- {
- m_specific->m_sys_format = pix_format_rgb555;
- m_specific->m_byte_order = hw_byte_order;
- }
- break;
-
- case 16:
- m_specific->m_sys_bpp = 16;
- if(r_mask == 0xF800 && g_mask == 0x7E0 && b_mask == 0x1F)
- {
- m_specific->m_sys_format = pix_format_rgb565;
- m_specific->m_byte_order = hw_byte_order;
- }
- break;
-
- case 24:
- case 32:
- m_specific->m_sys_bpp = 32;
- if(g_mask == 0xFF00)
- {
- if(r_mask == 0xFF && b_mask == 0xFF0000)
- {
- switch(m_specific->m_format)
- {
- case pix_format_rgba32:
- m_specific->m_sys_format = pix_format_rgba32;
- m_specific->m_byte_order = LSBFirst;
- break;
-
- case pix_format_abgr32:
- m_specific->m_sys_format = pix_format_abgr32;
- m_specific->m_byte_order = MSBFirst;
- break;
-
- default:
- m_specific->m_byte_order = hw_byte_order;
- m_specific->m_sys_format =
- (hw_byte_order == LSBFirst) ?
- pix_format_rgba32 :
- pix_format_abgr32;
- break;
- }
- }
-
- if(r_mask == 0xFF0000 && b_mask == 0xFF)
- {
- switch(m_specific->m_format)
- {
- case pix_format_argb32:
- m_specific->m_sys_format = pix_format_argb32;
- m_specific->m_byte_order = MSBFirst;
- break;
-
- case pix_format_bgra32:
- m_specific->m_sys_format = pix_format_bgra32;
- m_specific->m_byte_order = LSBFirst;
- break;
-
- default:
- m_specific->m_byte_order = hw_byte_order;
- m_specific->m_sys_format =
- (hw_byte_order == MSBFirst) ?
- pix_format_argb32 :
- pix_format_bgra32;
- break;
- }
- }
- }
- break;
- }
-
- if(m_specific->m_sys_format == pix_format_undefined)
- {
- fprintf(stderr,
- "RGB masks are not compatible with AGG pixel formats:\n"
- "R=%08x, R=%08x, B=%08x\n",
- (unsigned)r_mask, (unsigned)g_mask, (unsigned)b_mask);
- XCloseDisplay(m_specific->m_display);
- return false;
- }
-
-
-
- memset(&m_specific->m_window_attributes,
- 0,
- sizeof(m_specific->m_window_attributes));
-
- m_specific->m_window_attributes.border_pixel =
- XBlackPixel(m_specific->m_display, m_specific->m_screen);
-
- m_specific->m_window_attributes.background_pixel =
- XWhitePixel(m_specific->m_display, m_specific->m_screen);
-
- m_specific->m_window_attributes.override_redirect = 0;
-
- unsigned long window_mask = CWBackPixel | CWBorderPixel;
-
- m_specific->m_window =
- XCreateWindow(m_specific->m_display,
- XDefaultRootWindow(m_specific->m_display),
- 0, 0,
- width,
- height,
- 0,
- m_specific->m_depth,
- InputOutput,
- CopyFromParent,
- window_mask,
- &m_specific->m_window_attributes);
-
-
- m_specific->m_gc = XCreateGC(m_specific->m_display,
- m_specific->m_window,
- 0, 0);
- m_specific->m_buf_window =
- new unsigned char[width * height * (m_bpp / 8)];
-
- memset(m_specific->m_buf_window, 255, width * height * (m_bpp / 8));
-
- m_rbuf_window.attach(m_specific->m_buf_window,
- width,
- height,
- m_flip_y ? -width * (m_bpp / 8) : width * (m_bpp / 8));
-
- m_specific->m_ximg_window =
- XCreateImage(m_specific->m_display,
- m_specific->m_visual, //CopyFromParent,
- m_specific->m_depth,
- ZPixmap,
- 0,
- (char*)m_specific->m_buf_window,
- width,
- height,
- m_specific->m_sys_bpp,
- width * (m_specific->m_sys_bpp / 8));
- m_specific->m_ximg_window->byte_order = m_specific->m_byte_order;
-
- m_specific->caption(m_caption);
- m_initial_width = width;
- m_initial_height = height;
-
- if(!m_specific->m_initialized)
- {
- on_init();
- m_specific->m_initialized = true;
- }
-
- trans_affine_resizing(width, height);
- on_resize(width, height);
- m_specific->m_update_flag = true;
-
- XSizeHints *hints = XAllocSizeHints();
- if(hints)
- {
- if(flags & window_resize)
- {
- hints->min_width = 32;
- hints->min_height = 32;
- hints->max_width = 4096;
- hints->max_height = 4096;
- }
- else
- {
- hints->min_width = width;
- hints->min_height = height;
- hints->max_width = width;
- hints->max_height = height;
- }
- hints->flags = PMaxSize | PMinSize;
-
- XSetWMNormalHints(m_specific->m_display,
- m_specific->m_window,
- hints);
-
- XFree(hints);
- }
-
-
- XMapWindow(m_specific->m_display,
- m_specific->m_window);
-
- XSelectInput(m_specific->m_display,
- m_specific->m_window,
- xevent_mask);
-
-
- m_specific->m_close_atom = XInternAtom(m_specific->m_display,
- "WM_DELETE_WINDOW",
- false);
-
- XSetWMProtocols(m_specific->m_display,
- m_specific->m_window,
- &m_specific->m_close_atom,
- 1);
-
- return true;
- }
-
-
-
- //------------------------------------------------------------------------
- void platform_support::update_window()
- {
- if (! m_specific->m_is_mapped)
- return;
-
- m_specific->put_image(&m_rbuf_window);
-
- // When m_wait_mode is true we can discard all the events
- // came while the image is being drawn. In this case
- // the X server does not accumulate mouse motion events.
- // When m_wait_mode is false, i.e. we have some idle drawing
- // we cannot afford to miss any events
- XSync(m_specific->m_display, m_wait_mode);
- }
-
-
- //------------------------------------------------------------------------
- int platform_support::run()
- {
- pthread_mutex_lock (m_specific->m_mutex);
-
- XFlush(m_specific->m_display);
-
- bool quit = false;
- unsigned flags;
- int cur_x;
- int cur_y;
-
- while(!quit)
- {
- if(m_specific->m_update_flag && m_specific->m_is_mapped)
- {
- on_draw();
- update_window();
- m_specific->m_update_flag = false;
- }
-
- if(!m_wait_mode)
- {
- if(XPending(m_specific->m_display) == 0)
- {
- on_idle();
- continue;
- }
- }
-
- XEvent x_event;
- pthread_mutex_unlock (m_specific->m_mutex);
- XNextEvent(m_specific->m_display, &x_event);
- pthread_mutex_lock (m_specific->m_mutex);
-
- // In the Idle mode discard all intermediate MotionNotify events
- if(!m_wait_mode && x_event.type == MotionNotify)
- {
- XEvent te = x_event;
- for(;;)
- {
- if(XPending(m_specific->m_display) == 0) break;
- XNextEvent(m_specific->m_display, &te);
- if(te.type != MotionNotify) break;
- }
- x_event = te;
- }
-
- switch(x_event.type)
- {
- case MapNotify:
- {
- on_draw();
- update_window();
- m_specific->m_is_mapped = true;
- m_specific->m_update_flag = false;
- }
- break;
-
- case ConfigureNotify:
- {
- if(x_event.xconfigure.width != int(m_rbuf_window.width()) ||
- x_event.xconfigure.height != int(m_rbuf_window.height()))
- {
- int width = x_event.xconfigure.width;
- int height = x_event.xconfigure.height;
-
- delete [] m_specific->m_buf_window;
- m_specific->m_ximg_window->data = 0;
- XDestroyImage(m_specific->m_ximg_window);
-
- m_specific->m_buf_window =
- new unsigned char[width * height * (m_bpp / 8)];
-
- m_rbuf_window.attach(m_specific->m_buf_window,
- width,
- height,
- m_flip_y ?
- -width * (m_bpp / 8) :
- width * (m_bpp / 8));
-
- m_specific->m_ximg_window =
- XCreateImage(m_specific->m_display,
- m_specific->m_visual, //CopyFromParent,
- m_specific->m_depth,
- ZPixmap,
- 0,
- (char*)m_specific->m_buf_window,
- width,
- height,
- m_specific->m_sys_bpp,
- width * (m_specific->m_sys_bpp / 8));
- m_specific->m_ximg_window->byte_order = m_specific->m_byte_order;
-
- trans_affine_resizing(width, height);
- on_resize(width, height);
- on_draw();
- update_window();
- }
- }
- break;
-
- case Expose:
- m_specific->put_image(&m_rbuf_window);
- XFlush(m_specific->m_display);
- XSync(m_specific->m_display, false);
- break;
-
- case KeyPress:
- {
- KeySym key = XLookupKeysym(&x_event.xkey, 0);
- flags = 0;
- if(x_event.xkey.state & Button1Mask) flags |= mouse_left;
- if(x_event.xkey.state & Button3Mask) flags |= mouse_right;
- if(x_event.xkey.state & ShiftMask) flags |= kbd_shift;
- if(x_event.xkey.state & ControlMask) flags |= kbd_ctrl;
-
- bool left = false;
- bool up = false;
- bool right = false;
- bool down = false;
-
- switch(m_specific->m_keymap[key & 0xFF])
- {
- case key_left:
- left = true;
- break;
-
- case key_up:
- up = true;
- break;
-
- case key_right:
- right = true;
- break;
-
- case key_down:
- down = true;
- break;
-
- case key_f2:
- copy_window_to_img(max_images - 1);
- save_img(max_images - 1, "screenshot");
- break;
- }
-
- if(m_ctrls.on_arrow_keys(left, right, down, up))
- {
- on_ctrl_change();
- force_redraw();
- }
- else
- {
- on_key(x_event.xkey.x,
- m_flip_y ?
- m_rbuf_window.height() - x_event.xkey.y :
- x_event.xkey.y,
- m_specific->m_keymap[key & 0xFF],
- flags);
- }
- }
- break;
-
-
- case ButtonPress:
- {
- flags = 0;
- if(x_event.xbutton.state & ShiftMask) flags |= kbd_shift;
- if(x_event.xbutton.state & ControlMask) flags |= kbd_ctrl;
- if(x_event.xbutton.button == Button1) flags |= mouse_left;
- if(x_event.xbutton.button == Button3) flags |= mouse_right;
-
- cur_x = x_event.xbutton.x;
- cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y :
- x_event.xbutton.y;
-
- if(flags & mouse_left)
- {
- if(m_ctrls.on_mouse_button_down(cur_x, cur_y))
- {
- m_ctrls.set_cur(cur_x, cur_y);
- on_ctrl_change();
- force_redraw();
- }
- else
- {
- if(m_ctrls.in_rect(cur_x, cur_y))
- {
- if(m_ctrls.set_cur(cur_x, cur_y))
- {
- on_ctrl_change();
- force_redraw();
- }
- }
- else
- {
- on_mouse_button_down(cur_x, cur_y, flags);
- }
- }
- }
- if(flags & mouse_right)
- {
- on_mouse_button_down(cur_x, cur_y, flags);
- }
- //m_specific->m_wait_mode = m_wait_mode;
- //m_wait_mode = true;
- }
- break;
-
-
- case MotionNotify:
- {
- flags = 0;
- if(x_event.xmotion.state & Button1Mask) flags |= mouse_left;
- if(x_event.xmotion.state & Button3Mask) flags |= mouse_right;
- if(x_event.xmotion.state & ShiftMask) flags |= kbd_shift;
- if(x_event.xmotion.state & ControlMask) flags |= kbd_ctrl;
-
- cur_x = x_event.xbutton.x;
- cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y :
- x_event.xbutton.y;
-
- if(m_ctrls.on_mouse_move(cur_x, cur_y, (flags & mouse_left) != 0))
- {
- on_ctrl_change();
- force_redraw();
- }
- else
- {
- if(!m_ctrls.in_rect(cur_x, cur_y))
- {
- on_mouse_move(cur_x, cur_y, flags);
- }
- }
- }
- break;
-
- case ButtonRelease:
- {
- flags = 0;
- if(x_event.xbutton.state & ShiftMask) flags |= kbd_shift;
- if(x_event.xbutton.state & ControlMask) flags |= kbd_ctrl;
- if(x_event.xbutton.button == Button1) flags |= mouse_left;
- if(x_event.xbutton.button == Button3) flags |= mouse_right;
-
- cur_x = x_event.xbutton.x;
- cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y :
- x_event.xbutton.y;
-
- if(flags & mouse_left)
- {
- if(m_ctrls.on_mouse_button_up(cur_x, cur_y))
- {
- on_ctrl_change();
- force_redraw();
- }
- }
- if(flags & (mouse_left | mouse_right))
- {
- on_mouse_button_up(cur_x, cur_y, flags);
- }
- }
- //m_wait_mode = m_specific->m_wait_mode;
- break;
-
- case ClientMessage:
- if((x_event.xclient.format == 32) &&
- (x_event.xclient.data.l[0] == int(m_specific->m_close_atom)))
- {
- quit = true;
- }
- break;
- }
- }
-
-
- unsigned i = platform_support::max_images;
- while(i--)
- {
- if(m_specific->m_buf_img[i])
- {
- delete [] m_specific->m_buf_img[i];
- }
- }
-
- delete [] m_specific->m_buf_window;
- m_specific->m_ximg_window->data = 0;
- XDestroyImage(m_specific->m_ximg_window);
- XFreeGC(m_specific->m_display, m_specific->m_gc);
- XDestroyWindow(m_specific->m_display, m_specific->m_window);
- XCloseDisplay(m_specific->m_display);
-
- pthread_mutex_unlock (m_specific->m_mutex);
-
- return 0;
- }
-
-
-
- //------------------------------------------------------------------------
- const char* platform_support::img_ext() const { return ".ppm"; }
-
- //------------------------------------------------------------------------
- const char* platform_support::full_file_name(const char* file_name)
- {
- return file_name;
- }
-
- //------------------------------------------------------------------------
- bool platform_support::load_img(unsigned idx, const char* file)
- {
- if(idx < max_images)
- {
- char buf[1024];
- strcpy(buf, file);
- int len = strlen(buf);
- if(len < 4 || strcasecmp(buf + len - 4, ".ppm") != 0)
- {
- strcat(buf, ".ppm");
- }
-
- FILE* fd = fopen(buf, "rb");
- if(fd == 0) return false;
-
- if((len = fread(buf, 1, 1022, fd)) == 0)
- {
- fclose(fd);
- return false;
- }
- buf[len] = 0;
-
- if(buf[0] != 'P' && buf[1] != '6')
- {
- fclose(fd);
- return false;
- }
-
- char* ptr = buf + 2;
-
- while(*ptr && !isdigit(*ptr)) ptr++;
- if(*ptr == 0)
- {
- fclose(fd);
- return false;
- }
-
- unsigned width = atoi(ptr);
- if(width == 0 || width > 4096)
- {
- fclose(fd);
- return false;
- }
- while(*ptr && isdigit(*ptr)) ptr++;
- while(*ptr && !isdigit(*ptr)) ptr++;
- if(*ptr == 0)
- {
- fclose(fd);
- return false;
- }
- unsigned height = atoi(ptr);
- if(height == 0 || height > 4096)
- {
- fclose(fd);
- return false;
- }
- while(*ptr && isdigit(*ptr)) ptr++;
- while(*ptr && !isdigit(*ptr)) ptr++;
- if(atoi(ptr) != 255)
- {
- fclose(fd);
- return false;
- }
- while(*ptr && isdigit(*ptr)) ptr++;
- if(*ptr == 0)
- {
- fclose(fd);
- return false;
- }
- ptr++;
- fseek(fd, long(ptr - buf), SEEK_SET);
-
- create_img(idx, width, height);
- bool ret = true;
-
- if(m_format == pix_format_rgb24)
- {
- fread(m_specific->m_buf_img[idx], 1, width * height * 3, fd);
- }
- else
- {
- unsigned char* buf_img = new unsigned char [width * height * 3];
- rendering_buffer rbuf_img;
- rbuf_img.attach(buf_img,
- width,
- height,
- m_flip_y ?
- -width * 3 :
- width * 3);
-
- fread(buf_img, 1, width * height * 3, fd);
-
- switch(m_format)
- {
- case pix_format_rgb555:
- color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgb555());
- break;
-
- case pix_format_rgb565:
- color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgb565());
- break;
-
- case pix_format_bgr24:
- color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_bgr24());
- break;
-
- case pix_format_rgba32:
- color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgba32());
- break;
-
- case pix_format_argb32:
- color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_argb32());
- break;
-
- case pix_format_bgra32:
- color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_bgra32());
- break;
-
- case pix_format_abgr32:
- color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_abgr32());
- break;
-
- default:
- ret = false;
- }
- delete [] buf_img;
- }
-
- fclose(fd);
- return ret;
- }
- return false;
- }
-
-
-
-
- //------------------------------------------------------------------------
- bool platform_support::save_img(unsigned idx, const char* file)
- {
- if(idx < max_images && rbuf_img(idx).buf())
- {
- char buf[1024];
- strcpy(buf, file);
- int len = strlen(buf);
- if(len < 4 || strcasecmp(buf + len - 4, ".ppm") != 0)
- {
- strcat(buf, ".ppm");
- }
-
- FILE* fd = fopen(buf, "wb");
- if(fd == 0) return false;
-
- unsigned w = rbuf_img(idx).width();
- unsigned h = rbuf_img(idx).height();
-
- fprintf(fd, "P6\n%d %d\n255\n", w, h);
-
- unsigned y;
- unsigned char* tmp_buf = new unsigned char [w * 3];
- for(y = 0; y < rbuf_img(idx).height(); y++)
- {
- const unsigned char* src = rbuf_img(idx).row_ptr(m_flip_y ? h - 1 - y : y);
- switch(m_format)
- {
- default: break;
- case pix_format_rgb555:
- color_conv_row(tmp_buf, src, w, color_conv_rgb555_to_rgb24());
- break;
-
- case pix_format_rgb565:
- color_conv_row(tmp_buf, src, w, color_conv_rgb565_to_rgb24());
- break;
-
- case pix_format_bgr24:
- color_conv_row(tmp_buf, src, w, color_conv_bgr24_to_rgb24());
- break;
-
- case pix_format_rgb24:
- color_conv_row(tmp_buf, src, w, color_conv_rgb24_to_rgb24());
- break;
-
- case pix_format_rgba32:
- color_conv_row(tmp_buf, src, w, color_conv_rgba32_to_rgb24());
- break;
-
- case pix_format_argb32:
- color_conv_row(tmp_buf, src, w, color_conv_argb32_to_rgb24());
- break;
-
- case pix_format_bgra32:
- color_conv_row(tmp_buf, src, w, color_conv_bgra32_to_rgb24());
- break;
-
- case pix_format_abgr32:
- color_conv_row(tmp_buf, src, w, color_conv_abgr32_to_rgb24());
- break;
- }
- fwrite(tmp_buf, 1, w * 3, fd);
- }
- delete [] tmp_buf;
- fclose(fd);
- return true;
- }
- return false;
- }
-
-
-
- //------------------------------------------------------------------------
- bool platform_support::create_img(unsigned idx, unsigned width, unsigned height)
- {
- if(idx < max_images)
- {
- if(width == 0) width = rbuf_window().width();
- if(height == 0) height = rbuf_window().height();
- delete [] m_specific->m_buf_img[idx];
- m_specific->m_buf_img[idx] =
- new unsigned char[width * height * (m_bpp / 8)];
-
- m_rbuf_img[idx].attach(m_specific->m_buf_img[idx],
- width,
- height,
- m_flip_y ?
- -width * (m_bpp / 8) :
- width * (m_bpp / 8));
- return true;
- }
- return false;
- }
-
-
- //------------------------------------------------------------------------
- void platform_support::force_redraw()
- {
- m_specific->m_update_flag = true;
- }
-
-
- //------------------------------------------------------------------------
- void platform_support::message(const char* msg)
- {
- fprintf(stderr, "%s\n", msg);
- }
-
- //------------------------------------------------------------------------
- void platform_support::start_timer()
- {
- m_specific->m_sw_start = clock();
- }
-
- //------------------------------------------------------------------------
- double platform_support::elapsed_time() const
- {
- clock_t stop = clock();
- return double(stop - m_specific->m_sw_start) * 1000.0 / CLOCKS_PER_SEC;
- }
-
-
- //------------------------------------------------------------------------
- void platform_support::on_init() {}
- void platform_support::on_resize(int sx, int sy) {}
- void platform_support::on_idle() {}
- void platform_support::on_mouse_move(int x, int y, unsigned flags) {}
- void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {}
- void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {}
- void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {}
- void platform_support::on_ctrl_change() {}
- void platform_support::on_draw() {}
- void platform_support::on_post_draw(void* raw_handler) {}
-
-
-
-}
-
-
-void platform_support_prepare()
-{
-}
-
-void platform_support_lock(agg::platform_support *app)
-{
- pthread_mutex_lock (app->m_specific->m_mutex);
-}
-
-void platform_support_unlock(agg::platform_support *app)
-{
- pthread_mutex_unlock (app->m_specific->m_mutex);
-}
-
-bool platform_support_is_mapped(agg::platform_support *app)
-{
- return app->m_specific->m_is_mapped;
-}
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry (AGG) - Version 2.5
+// A high quality rendering engine for C++
+// Copyright (C) 2002-2006 Maxim Shemanarev
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://antigrain.com
+//
+// AGG is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// AGG 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with AGG; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+// MA 02110-1301, USA.
+//----------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <time.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+#include <pthread.h>
+#include "agg_basics.h"
+#include "util/agg_color_conv_rgb8.h"
+#include "platform/agg_platform_support.h"
+
+
+namespace agg
+{
+ //------------------------------------------------------------------------
+ class platform_specific
+ {
+ public:
+ platform_specific(pix_format_e format, bool flip_y);
+ ~platform_specific();
+
+ void caption(const char* capt);
+ void put_image(const rendering_buffer* src);
+
+ pix_format_e m_format;
+ pix_format_e m_sys_format;
+ int m_byte_order;
+ bool m_flip_y;
+ unsigned m_bpp;
+ unsigned m_sys_bpp;
+ Display* m_display;
+ int m_screen;
+ int m_depth;
+ Visual* m_visual;
+ Window m_window;
+ GC m_gc;
+ XImage* m_ximg_window;
+ XSetWindowAttributes m_window_attributes;
+ Atom m_close_atom;
+ unsigned char* m_buf_window;
+ unsigned char* m_buf_img[platform_support::max_images];
+ unsigned m_keymap[256];
+
+ bool m_update_flag;
+ bool m_resize_flag;
+ bool m_initialized;
+ bool m_is_mapped;
+ clock_t m_sw_start;
+
+ pthread_mutex_t m_mutex[1];
+
+ };
+
+
+
+ //------------------------------------------------------------------------
+ platform_specific::platform_specific(pix_format_e format, bool flip_y) :
+ m_format(format),
+ m_sys_format(pix_format_undefined),
+ m_byte_order(LSBFirst),
+ m_flip_y(flip_y),
+ m_bpp(0),
+ m_sys_bpp(0),
+ m_display(0),
+ m_screen(0),
+ m_depth(0),
+ m_visual(0),
+ m_window(0),
+ m_gc(0),
+ m_ximg_window(0),
+ m_close_atom(0),
+
+ m_buf_window(0),
+
+ m_update_flag(true),
+ m_resize_flag(true),
+ m_initialized(false),
+ m_is_mapped(false)
+ {
+ memset(m_buf_img, 0, sizeof(m_buf_img));
+
+ unsigned i;
+ for(i = 0; i < 256; i++)
+ {
+ m_keymap[i] = i;
+ }
+
+ m_keymap[XK_Pause&0xFF] = key_pause;
+ m_keymap[XK_Clear&0xFF] = key_clear;
+
+ m_keymap[XK_KP_0&0xFF] = key_kp0;
+ m_keymap[XK_KP_1&0xFF] = key_kp1;
+ m_keymap[XK_KP_2&0xFF] = key_kp2;
+ m_keymap[XK_KP_3&0xFF] = key_kp3;
+ m_keymap[XK_KP_4&0xFF] = key_kp4;
+ m_keymap[XK_KP_5&0xFF] = key_kp5;
+ m_keymap[XK_KP_6&0xFF] = key_kp6;
+ m_keymap[XK_KP_7&0xFF] = key_kp7;
+ m_keymap[XK_KP_8&0xFF] = key_kp8;
+ m_keymap[XK_KP_9&0xFF] = key_kp9;
+
+ m_keymap[XK_KP_Insert&0xFF] = key_kp0;
+ m_keymap[XK_KP_End&0xFF] = key_kp1;
+ m_keymap[XK_KP_Down&0xFF] = key_kp2;
+ m_keymap[XK_KP_Page_Down&0xFF] = key_kp3;
+ m_keymap[XK_KP_Left&0xFF] = key_kp4;
+ m_keymap[XK_KP_Begin&0xFF] = key_kp5;
+ m_keymap[XK_KP_Right&0xFF] = key_kp6;
+ m_keymap[XK_KP_Home&0xFF] = key_kp7;
+ m_keymap[XK_KP_Up&0xFF] = key_kp8;
+ m_keymap[XK_KP_Page_Up&0xFF] = key_kp9;
+ m_keymap[XK_KP_Delete&0xFF] = key_kp_period;
+ m_keymap[XK_KP_Decimal&0xFF] = key_kp_period;
+ m_keymap[XK_KP_Divide&0xFF] = key_kp_divide;
+ m_keymap[XK_KP_Multiply&0xFF] = key_kp_multiply;
+ m_keymap[XK_KP_Subtract&0xFF] = key_kp_minus;
+ m_keymap[XK_KP_Add&0xFF] = key_kp_plus;
+ m_keymap[XK_KP_Enter&0xFF] = key_kp_enter;
+ m_keymap[XK_KP_Equal&0xFF] = key_kp_equals;
+
+ m_keymap[XK_Up&0xFF] = key_up;
+ m_keymap[XK_Down&0xFF] = key_down;
+ m_keymap[XK_Right&0xFF] = key_right;
+ m_keymap[XK_Left&0xFF] = key_left;
+ m_keymap[XK_Insert&0xFF] = key_insert;
+ m_keymap[XK_Home&0xFF] = key_delete;
+ m_keymap[XK_End&0xFF] = key_end;
+ m_keymap[XK_Page_Up&0xFF] = key_page_up;
+ m_keymap[XK_Page_Down&0xFF] = key_page_down;
+
+ m_keymap[XK_F1&0xFF] = key_f1;
+ m_keymap[XK_F2&0xFF] = key_f2;
+ m_keymap[XK_F3&0xFF] = key_f3;
+ m_keymap[XK_F4&0xFF] = key_f4;
+ m_keymap[XK_F5&0xFF] = key_f5;
+ m_keymap[XK_F6&0xFF] = key_f6;
+ m_keymap[XK_F7&0xFF] = key_f7;
+ m_keymap[XK_F8&0xFF] = key_f8;
+ m_keymap[XK_F9&0xFF] = key_f9;
+ m_keymap[XK_F10&0xFF] = key_f10;
+ m_keymap[XK_F11&0xFF] = key_f11;
+ m_keymap[XK_F12&0xFF] = key_f12;
+ m_keymap[XK_F13&0xFF] = key_f13;
+ m_keymap[XK_F14&0xFF] = key_f14;
+ m_keymap[XK_F15&0xFF] = key_f15;
+
+ m_keymap[XK_Num_Lock&0xFF] = key_numlock;
+ m_keymap[XK_Caps_Lock&0xFF] = key_capslock;
+ m_keymap[XK_Scroll_Lock&0xFF] = key_scrollock;
+
+ switch(m_format)
+ {
+ default: break;
+ case pix_format_gray8:
+ m_bpp = 8;
+ break;
+
+ case pix_format_rgb565:
+ case pix_format_rgb555:
+ m_bpp = 16;
+ break;
+
+ case pix_format_rgb24:
+ case pix_format_bgr24:
+ m_bpp = 24;
+ break;
+
+ case pix_format_bgra32:
+ case pix_format_abgr32:
+ case pix_format_argb32:
+ case pix_format_rgba32:
+ m_bpp = 32;
+ break;
+ }
+ m_sw_start = clock();
+
+ pthread_mutex_init (m_mutex, NULL);
+ }
+
+ //------------------------------------------------------------------------
+ platform_specific::~platform_specific()
+ {
+ pthread_mutex_destroy (m_mutex);
+ }
+
+ //------------------------------------------------------------------------
+ void platform_specific::caption(const char* capt)
+ {
+ // Fixed by Enno Fennema (in original AGG library)
+ XStoreName(m_display, m_window, capt);
+ XSetIconName(m_display, m_window, capt);
+ }
+
+
+ //------------------------------------------------------------------------
+ void platform_specific::put_image(const rendering_buffer* src)
+ {
+ if(m_ximg_window == 0) return;
+ m_ximg_window->data = (char*)m_buf_window;
+
+ if(m_format == m_sys_format)
+ {
+ XPutImage(m_display,
+ m_window,
+ m_gc,
+ m_ximg_window,
+ 0, 0, 0, 0,
+ src->width(),
+ src->height());
+ }
+ else
+ {
+ int row_len = src->width() * m_sys_bpp / 8;
+ unsigned char* buf_tmp =
+ new unsigned char[row_len * src->height()];
+
+ rendering_buffer rbuf_tmp;
+ rbuf_tmp.attach(buf_tmp,
+ src->width(),
+ src->height(),
+ m_flip_y ? -row_len : row_len);
+
+ switch(m_sys_format)
+ {
+ default: break;
+ case pix_format_rgb555:
+ switch(m_format)
+ {
+ default: break;
+ case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgb555()); break;
+ case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555()); break;
+ case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_rgb555()); break;
+ case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb555()); break;
+ case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_rgb555()); break;
+ case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_rgb555()); break;
+ case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_rgb555()); break;
+ case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_rgb555()); break;
+ }
+ break;
+
+ case pix_format_rgb565:
+ switch(m_format)
+ {
+ default: break;
+ case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgb565()); break;
+ case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb565()); break;
+ case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_rgb565()); break;
+ case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb565()); break;
+ case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_rgb565()); break;
+ case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_rgb565()); break;
+ case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_rgb565()); break;
+ case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_rgb565()); break;
+ }
+ break;
+
+ case pix_format_rgba32:
+ switch(m_format)
+ {
+ default: break;
+ case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgba32()); break;
+ case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgba32()); break;
+ case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_rgba32()); break;
+ case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgba32()); break;
+ case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_rgba32()); break;
+ case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_rgba32()); break;
+ case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_rgba32()); break;
+ case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_rgba32()); break;
+ }
+ break;
+
+ case pix_format_abgr32:
+ switch(m_format)
+ {
+ default: break;
+ case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_abgr32()); break;
+ case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_abgr32()); break;
+ case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_abgr32()); break;
+ case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_abgr32()); break;
+ case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_abgr32()); break;
+ case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_abgr32()); break;
+ case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_abgr32()); break;
+ case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_abgr32()); break;
+ }
+ break;
+
+ case pix_format_argb32:
+ switch(m_format)
+ {
+ default: break;
+ case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_argb32()); break;
+ case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_argb32()); break;
+ case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_argb32()); break;
+ case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_argb32()); break;
+ case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_argb32()); break;
+ case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_argb32()); break;
+ case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_argb32()); break;
+ case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_argb32()); break;
+ }
+ break;
+
+ case pix_format_bgra32:
+ switch(m_format)
+ {
+ default: break;
+ case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_bgra32()); break;
+ case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_bgra32()); break;
+ case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_bgra32()); break;
+ case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_bgra32()); break;
+ case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_bgra32()); break;
+ case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_bgra32()); break;
+ case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_bgra32()); break;
+ case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_bgra32()); break;
+ }
+ break;
+ }
+
+ m_ximg_window->data = (char*)buf_tmp;
+ XPutImage(m_display,
+ m_window,
+ m_gc,
+ m_ximg_window,
+ 0, 0, 0, 0,
+ src->width(),
+ src->height());
+
+ delete [] buf_tmp;
+ }
+ }
+
+ //------------------------------------------------------------------------
+ platform_support::platform_support(pix_format_e format, bool flip_y) :
+ m_specific(new platform_specific(format, flip_y)),
+ m_format(format),
+ m_bpp(m_specific->m_bpp),
+ m_window_flags(0),
+ m_wait_mode(true),
+ m_flip_y(flip_y),
+ m_initial_width(10),
+ m_initial_height(10)
+ {
+ strcpy(m_caption, "AGG Application");
+ }
+
+ //------------------------------------------------------------------------
+ platform_support::~platform_support()
+ {
+ delete m_specific;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ void platform_support::caption(const char* cap)
+ {
+ strcpy(m_caption, cap);
+ if(m_specific->m_initialized)
+ {
+ m_specific->caption(cap);
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ enum xevent_mask_e
+ {
+ xevent_mask =
+ PointerMotionMask|
+ ButtonPressMask|
+ ButtonReleaseMask|
+ ExposureMask|
+ KeyPressMask|
+ StructureNotifyMask
+ };
+
+
+ //------------------------------------------------------------------------
+ bool platform_support::init(unsigned width, unsigned height, unsigned flags)
+ {
+ m_window_flags = flags;
+
+ m_specific->m_display = XOpenDisplay(NULL);
+ if(m_specific->m_display == 0)
+ {
+ fprintf(stderr, "Unable to open DISPLAY!\n");
+ return false;
+ }
+
+ m_specific->m_screen = XDefaultScreen(m_specific->m_display);
+ m_specific->m_depth = XDefaultDepth(m_specific->m_display,
+ m_specific->m_screen);
+ m_specific->m_visual = XDefaultVisual(m_specific->m_display,
+ m_specific->m_screen);
+ unsigned long r_mask = m_specific->m_visual->red_mask;
+ unsigned long g_mask = m_specific->m_visual->green_mask;
+ unsigned long b_mask = m_specific->m_visual->blue_mask;
+
+ if(m_specific->m_depth < 15 ||
+ r_mask == 0 || g_mask == 0 || b_mask == 0)
+ {
+ fprintf(stderr,
+ "There's no Visual compatible with minimal AGG requirements:\n"
+ "At least 15-bit color depth and True- or DirectColor class.\n\n");
+ XCloseDisplay(m_specific->m_display);
+ return false;
+ }
+
+ int t = 1;
+ int hw_byte_order = LSBFirst;
+ if(*(char*)&t == 0) hw_byte_order = MSBFirst;
+
+ // Perceive SYS-format by mask
+ switch(m_specific->m_depth)
+ {
+ case 15:
+ m_specific->m_sys_bpp = 16;
+ if(r_mask == 0x7C00 && g_mask == 0x3E0 && b_mask == 0x1F)
+ {
+ m_specific->m_sys_format = pix_format_rgb555;
+ m_specific->m_byte_order = hw_byte_order;
+ }
+ break;
+
+ case 16:
+ m_specific->m_sys_bpp = 16;
+ if(r_mask == 0xF800 && g_mask == 0x7E0 && b_mask == 0x1F)
+ {
+ m_specific->m_sys_format = pix_format_rgb565;
+ m_specific->m_byte_order = hw_byte_order;
+ }
+ break;
+
+ case 24:
+ case 32:
+ m_specific->m_sys_bpp = 32;
+ if(g_mask == 0xFF00)
+ {
+ if(r_mask == 0xFF && b_mask == 0xFF0000)
+ {
+ switch(m_specific->m_format)
+ {
+ case pix_format_rgba32:
+ m_specific->m_sys_format = pix_format_rgba32;
+ m_specific->m_byte_order = LSBFirst;
+ break;
+
+ case pix_format_abgr32:
+ m_specific->m_sys_format = pix_format_abgr32;
+ m_specific->m_byte_order = MSBFirst;
+ break;
+
+ default:
+ m_specific->m_byte_order = hw_byte_order;
+ m_specific->m_sys_format =
+ (hw_byte_order == LSBFirst) ?
+ pix_format_rgba32 :
+ pix_format_abgr32;
+ break;
+ }
+ }
+
+ if(r_mask == 0xFF0000 && b_mask == 0xFF)
+ {
+ switch(m_specific->m_format)
+ {
+ case pix_format_argb32:
+ m_specific->m_sys_format = pix_format_argb32;
+ m_specific->m_byte_order = MSBFirst;
+ break;
+
+ case pix_format_bgra32:
+ m_specific->m_sys_format = pix_format_bgra32;
+ m_specific->m_byte_order = LSBFirst;
+ break;
+
+ default:
+ m_specific->m_byte_order = hw_byte_order;
+ m_specific->m_sys_format =
+ (hw_byte_order == MSBFirst) ?
+ pix_format_argb32 :
+ pix_format_bgra32;
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ if(m_specific->m_sys_format == pix_format_undefined)
+ {
+ fprintf(stderr,
+ "RGB masks are not compatible with AGG pixel formats:\n"
+ "R=%08x, R=%08x, B=%08x\n",
+ (unsigned)r_mask, (unsigned)g_mask, (unsigned)b_mask);
+ XCloseDisplay(m_specific->m_display);
+ return false;
+ }
+
+
+
+ memset(&m_specific->m_window_attributes,
+ 0,
+ sizeof(m_specific->m_window_attributes));
+
+ m_specific->m_window_attributes.border_pixel =
+ XBlackPixel(m_specific->m_display, m_specific->m_screen);
+
+ m_specific->m_window_attributes.background_pixel =
+ XWhitePixel(m_specific->m_display, m_specific->m_screen);
+
+ m_specific->m_window_attributes.override_redirect = 0;
+
+ unsigned long window_mask = CWBackPixel | CWBorderPixel;
+
+ m_specific->m_window =
+ XCreateWindow(m_specific->m_display,
+ XDefaultRootWindow(m_specific->m_display),
+ 0, 0,
+ width,
+ height,
+ 0,
+ m_specific->m_depth,
+ InputOutput,
+ CopyFromParent,
+ window_mask,
+ &m_specific->m_window_attributes);
+
+
+ m_specific->m_gc = XCreateGC(m_specific->m_display,
+ m_specific->m_window,
+ 0, 0);
+ m_specific->m_buf_window =
+ new unsigned char[width * height * (m_bpp / 8)];
+
+ memset(m_specific->m_buf_window, 255, width * height * (m_bpp / 8));
+
+ m_rbuf_window.attach(m_specific->m_buf_window,
+ width,
+ height,
+ m_flip_y ? -width * (m_bpp / 8) : width * (m_bpp / 8));
+
+ m_specific->m_ximg_window =
+ XCreateImage(m_specific->m_display,
+ m_specific->m_visual, //CopyFromParent,
+ m_specific->m_depth,
+ ZPixmap,
+ 0,
+ (char*)m_specific->m_buf_window,
+ width,
+ height,
+ m_specific->m_sys_bpp,
+ width * (m_specific->m_sys_bpp / 8));
+ m_specific->m_ximg_window->byte_order = m_specific->m_byte_order;
+
+ m_specific->caption(m_caption);
+ m_initial_width = width;
+ m_initial_height = height;
+
+ if(!m_specific->m_initialized)
+ {
+ on_init();
+ m_specific->m_initialized = true;
+ }
+
+ trans_affine_resizing(width, height);
+ on_resize(width, height);
+ m_specific->m_update_flag = true;
+
+ XSizeHints *hints = XAllocSizeHints();
+ if(hints)
+ {
+ if(flags & window_resize)
+ {
+ hints->min_width = 32;
+ hints->min_height = 32;
+ hints->max_width = 4096;
+ hints->max_height = 4096;
+ }
+ else
+ {
+ hints->min_width = width;
+ hints->min_height = height;
+ hints->max_width = width;
+ hints->max_height = height;
+ }
+ hints->flags = PMaxSize | PMinSize;
+
+ XSetWMNormalHints(m_specific->m_display,
+ m_specific->m_window,
+ hints);
+
+ XFree(hints);
+ }
+
+
+ XMapWindow(m_specific->m_display,
+ m_specific->m_window);
+
+ XSelectInput(m_specific->m_display,
+ m_specific->m_window,
+ xevent_mask);
+
+
+ m_specific->m_close_atom = XInternAtom(m_specific->m_display,
+ "WM_DELETE_WINDOW",
+ false);
+
+ XSetWMProtocols(m_specific->m_display,
+ m_specific->m_window,
+ &m_specific->m_close_atom,
+ 1);
+
+ return true;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ void platform_support::update_window()
+ {
+ if (! m_specific->m_is_mapped)
+ return;
+
+ m_specific->put_image(&m_rbuf_window);
+
+ // When m_wait_mode is true we can discard all the events
+ // came while the image is being drawn. In this case
+ // the X server does not accumulate mouse motion events.
+ // When m_wait_mode is false, i.e. we have some idle drawing
+ // we cannot afford to miss any events
+ XSync(m_specific->m_display, m_wait_mode);
+ }
+
+
+ //------------------------------------------------------------------------
+ int platform_support::run()
+ {
+ XFlush(m_specific->m_display);
+
+ bool quit = false;
+ unsigned flags;
+ int cur_x;
+ int cur_y;
+
+ while(!quit)
+ {
+ if(m_specific->m_update_flag && m_specific->m_is_mapped)
+ {
+ on_draw();
+ update_window();
+ m_specific->m_update_flag = false;
+ }
+
+ if(!m_wait_mode)
+ {
+ if(XPending(m_specific->m_display) == 0)
+ {
+ on_idle();
+ continue;
+ }
+ }
+
+ XEvent x_event;
+ pthread_mutex_unlock (m_specific->m_mutex);
+ XNextEvent(m_specific->m_display, &x_event);
+ pthread_mutex_lock (m_specific->m_mutex);
+
+ // In the Idle mode discard all intermediate MotionNotify events
+ if(!m_wait_mode && x_event.type == MotionNotify)
+ {
+ XEvent te = x_event;
+ for(;;)
+ {
+ if(XPending(m_specific->m_display) == 0) break;
+ XNextEvent(m_specific->m_display, &te);
+ if(te.type != MotionNotify) break;
+ }
+ x_event = te;
+ }
+
+ switch(x_event.type)
+ {
+ case MapNotify:
+ {
+ on_draw();
+ update_window();
+ m_specific->m_is_mapped = true;
+ m_specific->m_update_flag = false;
+ }
+ break;
+
+ case ConfigureNotify:
+ {
+ if(x_event.xconfigure.width != int(m_rbuf_window.width()) ||
+ x_event.xconfigure.height != int(m_rbuf_window.height()))
+ {
+ int width = x_event.xconfigure.width;
+ int height = x_event.xconfigure.height;
+
+ delete [] m_specific->m_buf_window;
+ m_specific->m_ximg_window->data = 0;
+ XDestroyImage(m_specific->m_ximg_window);
+
+ m_specific->m_buf_window =
+ new unsigned char[width * height * (m_bpp / 8)];
+
+ m_rbuf_window.attach(m_specific->m_buf_window,
+ width,
+ height,
+ m_flip_y ?
+ -width * (m_bpp / 8) :
+ width * (m_bpp / 8));
+
+ m_specific->m_ximg_window =
+ XCreateImage(m_specific->m_display,
+ m_specific->m_visual, //CopyFromParent,
+ m_specific->m_depth,
+ ZPixmap,
+ 0,
+ (char*)m_specific->m_buf_window,
+ width,
+ height,
+ m_specific->m_sys_bpp,
+ width * (m_specific->m_sys_bpp / 8));
+ m_specific->m_ximg_window->byte_order = m_specific->m_byte_order;
+
+ trans_affine_resizing(width, height);
+ on_resize(width, height);
+ on_draw();
+ update_window();
+ }
+ }
+ break;
+
+ case Expose:
+ m_specific->put_image(&m_rbuf_window);
+ XFlush(m_specific->m_display);
+ XSync(m_specific->m_display, false);
+ break;
+
+ case KeyPress:
+ {
+ KeySym key = XLookupKeysym(&x_event.xkey, 0);
+ flags = 0;
+ if(x_event.xkey.state & Button1Mask) flags |= mouse_left;
+ if(x_event.xkey.state & Button3Mask) flags |= mouse_right;
+ if(x_event.xkey.state & ShiftMask) flags |= kbd_shift;
+ if(x_event.xkey.state & ControlMask) flags |= kbd_ctrl;
+
+ bool left = false;
+ bool up = false;
+ bool right = false;
+ bool down = false;
+
+ switch(m_specific->m_keymap[key & 0xFF])
+ {
+ case key_left:
+ left = true;
+ break;
+
+ case key_up:
+ up = true;
+ break;
+
+ case key_right:
+ right = true;
+ break;
+
+ case key_down:
+ down = true;
+ break;
+
+ case key_f2:
+ copy_window_to_img(max_images - 1);
+ save_img(max_images - 1, "screenshot");
+ break;
+ }
+
+ if(m_ctrls.on_arrow_keys(left, right, down, up))
+ {
+ on_ctrl_change();
+ force_redraw();
+ }
+ else
+ {
+ on_key(x_event.xkey.x,
+ m_flip_y ?
+ m_rbuf_window.height() - x_event.xkey.y :
+ x_event.xkey.y,
+ m_specific->m_keymap[key & 0xFF],
+ flags);
+ }
+ }
+ break;
+
+
+ case ButtonPress:
+ {
+ flags = 0;
+ if(x_event.xbutton.state & ShiftMask) flags |= kbd_shift;
+ if(x_event.xbutton.state & ControlMask) flags |= kbd_ctrl;
+ if(x_event.xbutton.button == Button1) flags |= mouse_left;
+ if(x_event.xbutton.button == Button3) flags |= mouse_right;
+
+ cur_x = x_event.xbutton.x;
+ cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y :
+ x_event.xbutton.y;
+
+ if(flags & mouse_left)
+ {
+ if(m_ctrls.on_mouse_button_down(cur_x, cur_y))
+ {
+ m_ctrls.set_cur(cur_x, cur_y);
+ on_ctrl_change();
+ force_redraw();
+ }
+ else
+ {
+ if(m_ctrls.in_rect(cur_x, cur_y))
+ {
+ if(m_ctrls.set_cur(cur_x, cur_y))
+ {
+ on_ctrl_change();
+ force_redraw();
+ }
+ }
+ else
+ {
+ on_mouse_button_down(cur_x, cur_y, flags);
+ }
+ }
+ }
+ if(flags & mouse_right)
+ {
+ on_mouse_button_down(cur_x, cur_y, flags);
+ }
+ //m_specific->m_wait_mode = m_wait_mode;
+ //m_wait_mode = true;
+ }
+ break;
+
+
+ case MotionNotify:
+ {
+ flags = 0;
+ if(x_event.xmotion.state & Button1Mask) flags |= mouse_left;
+ if(x_event.xmotion.state & Button3Mask) flags |= mouse_right;
+ if(x_event.xmotion.state & ShiftMask) flags |= kbd_shift;
+ if(x_event.xmotion.state & ControlMask) flags |= kbd_ctrl;
+
+ cur_x = x_event.xbutton.x;
+ cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y :
+ x_event.xbutton.y;
+
+ if(m_ctrls.on_mouse_move(cur_x, cur_y, (flags & mouse_left) != 0))
+ {
+ on_ctrl_change();
+ force_redraw();
+ }
+ else
+ {
+ if(!m_ctrls.in_rect(cur_x, cur_y))
+ {
+ on_mouse_move(cur_x, cur_y, flags);
+ }
+ }
+ }
+ break;
+
+ case ButtonRelease:
+ {
+ flags = 0;
+ if(x_event.xbutton.state & ShiftMask) flags |= kbd_shift;
+ if(x_event.xbutton.state & ControlMask) flags |= kbd_ctrl;
+ if(x_event.xbutton.button == Button1) flags |= mouse_left;
+ if(x_event.xbutton.button == Button3) flags |= mouse_right;
+
+ cur_x = x_event.xbutton.x;
+ cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y :
+ x_event.xbutton.y;
+
+ if(flags & mouse_left)
+ {
+ if(m_ctrls.on_mouse_button_up(cur_x, cur_y))
+ {
+ on_ctrl_change();
+ force_redraw();
+ }
+ }
+ if(flags & (mouse_left | mouse_right))
+ {
+ on_mouse_button_up(cur_x, cur_y, flags);
+ }
+ }
+ //m_wait_mode = m_specific->m_wait_mode;
+ break;
+
+ case ClientMessage:
+ if((x_event.xclient.format == 32) &&
+ (x_event.xclient.data.l[0] == int(m_specific->m_close_atom)))
+ {
+ quit = true;
+ }
+ break;
+ }
+ }
+
+
+ unsigned i = platform_support::max_images;
+ while(i--)
+ {
+ if(m_specific->m_buf_img[i])
+ {
+ delete [] m_specific->m_buf_img[i];
+ }
+ }
+
+ delete [] m_specific->m_buf_window;
+ m_specific->m_ximg_window->data = 0;
+ XDestroyImage(m_specific->m_ximg_window);
+ XFreeGC(m_specific->m_display, m_specific->m_gc);
+ XDestroyWindow(m_specific->m_display, m_specific->m_window);
+ XCloseDisplay(m_specific->m_display);
+
+ return 0;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ const char* platform_support::img_ext() const { return ".ppm"; }
+
+ //------------------------------------------------------------------------
+ const char* platform_support::full_file_name(const char* file_name)
+ {
+ return file_name;
+ }
+
+ //------------------------------------------------------------------------
+ bool platform_support::load_img(unsigned idx, const char* file)
+ {
+ if(idx < max_images)
+ {
+ char buf[1024];
+ strcpy(buf, file);
+ int len = strlen(buf);
+ if(len < 4 || strcasecmp(buf + len - 4, ".ppm") != 0)
+ {
+ strcat(buf, ".ppm");
+ }
+
+ FILE* fd = fopen(buf, "rb");
+ if(fd == 0) return false;
+
+ if((len = fread(buf, 1, 1022, fd)) == 0)
+ {
+ fclose(fd);
+ return false;
+ }
+ buf[len] = 0;
+
+ if(buf[0] != 'P' && buf[1] != '6')
+ {
+ fclose(fd);
+ return false;
+ }
+
+ char* ptr = buf + 2;
+
+ while(*ptr && !isdigit(*ptr)) ptr++;
+ if(*ptr == 0)
+ {
+ fclose(fd);
+ return false;
+ }
+
+ unsigned width = atoi(ptr);
+ if(width == 0 || width > 4096)
+ {
+ fclose(fd);
+ return false;
+ }
+ while(*ptr && isdigit(*ptr)) ptr++;
+ while(*ptr && !isdigit(*ptr)) ptr++;
+ if(*ptr == 0)
+ {
+ fclose(fd);
+ return false;
+ }
+ unsigned height = atoi(ptr);
+ if(height == 0 || height > 4096)
+ {
+ fclose(fd);
+ return false;
+ }
+ while(*ptr && isdigit(*ptr)) ptr++;
+ while(*ptr && !isdigit(*ptr)) ptr++;
+ if(atoi(ptr) != 255)
+ {
+ fclose(fd);
+ return false;
+ }
+ while(*ptr && isdigit(*ptr)) ptr++;
+ if(*ptr == 0)
+ {
+ fclose(fd);
+ return false;
+ }
+ ptr++;
+ fseek(fd, long(ptr - buf), SEEK_SET);
+
+ create_img(idx, width, height);
+ bool ret = true;
+
+ if(m_format == pix_format_rgb24)
+ {
+ fread(m_specific->m_buf_img[idx], 1, width * height * 3, fd);
+ }
+ else
+ {
+ unsigned char* buf_img = new unsigned char [width * height * 3];
+ rendering_buffer rbuf_img;
+ rbuf_img.attach(buf_img,
+ width,
+ height,
+ m_flip_y ?
+ -width * 3 :
+ width * 3);
+
+ fread(buf_img, 1, width * height * 3, fd);
+
+ switch(m_format)
+ {
+ case pix_format_rgb555:
+ color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgb555());
+ break;
+
+ case pix_format_rgb565:
+ color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgb565());
+ break;
+
+ case pix_format_bgr24:
+ color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_bgr24());
+ break;
+
+ case pix_format_rgba32:
+ color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgba32());
+ break;
+
+ case pix_format_argb32:
+ color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_argb32());
+ break;
+
+ case pix_format_bgra32:
+ color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_bgra32());
+ break;
+
+ case pix_format_abgr32:
+ color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_abgr32());
+ break;
+
+ default:
+ ret = false;
+ }
+ delete [] buf_img;
+ }
+
+ fclose(fd);
+ return ret;
+ }
+ return false;
+ }
+
+
+
+
+ //------------------------------------------------------------------------
+ bool platform_support::save_img(unsigned idx, const char* file)
+ {
+ if(idx < max_images && rbuf_img(idx).buf())
+ {
+ char buf[1024];
+ strcpy(buf, file);
+ int len = strlen(buf);
+ if(len < 4 || strcasecmp(buf + len - 4, ".ppm") != 0)
+ {
+ strcat(buf, ".ppm");
+ }
+
+ FILE* fd = fopen(buf, "wb");
+ if(fd == 0) return false;
+
+ unsigned w = rbuf_img(idx).width();
+ unsigned h = rbuf_img(idx).height();
+
+ fprintf(fd, "P6\n%d %d\n255\n", w, h);
+
+ unsigned y;
+ unsigned char* tmp_buf = new unsigned char [w * 3];
+ for(y = 0; y < rbuf_img(idx).height(); y++)
+ {
+ const unsigned char* src = rbuf_img(idx).row_ptr(m_flip_y ? h - 1 - y : y);
+ switch(m_format)
+ {
+ default: break;
+ case pix_format_rgb555:
+ color_conv_row(tmp_buf, src, w, color_conv_rgb555_to_rgb24());
+ break;
+
+ case pix_format_rgb565:
+ color_conv_row(tmp_buf, src, w, color_conv_rgb565_to_rgb24());
+ break;
+
+ case pix_format_bgr24:
+ color_conv_row(tmp_buf, src, w, color_conv_bgr24_to_rgb24());
+ break;
+
+ case pix_format_rgb24:
+ color_conv_row(tmp_buf, src, w, color_conv_rgb24_to_rgb24());
+ break;
+
+ case pix_format_rgba32:
+ color_conv_row(tmp_buf, src, w, color_conv_rgba32_to_rgb24());
+ break;
+
+ case pix_format_argb32:
+ color_conv_row(tmp_buf, src, w, color_conv_argb32_to_rgb24());
+ break;
+
+ case pix_format_bgra32:
+ color_conv_row(tmp_buf, src, w, color_conv_bgra32_to_rgb24());
+ break;
+
+ case pix_format_abgr32:
+ color_conv_row(tmp_buf, src, w, color_conv_abgr32_to_rgb24());
+ break;
+ }
+ fwrite(tmp_buf, 1, w * 3, fd);
+ }
+ delete [] tmp_buf;
+ fclose(fd);
+ return true;
+ }
+ return false;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool platform_support::create_img(unsigned idx, unsigned width, unsigned height)
+ {
+ if(idx < max_images)
+ {
+ if(width == 0) width = rbuf_window().width();
+ if(height == 0) height = rbuf_window().height();
+ delete [] m_specific->m_buf_img[idx];
+ m_specific->m_buf_img[idx] =
+ new unsigned char[width * height * (m_bpp / 8)];
+
+ m_rbuf_img[idx].attach(m_specific->m_buf_img[idx],
+ width,
+ height,
+ m_flip_y ?
+ -width * (m_bpp / 8) :
+ width * (m_bpp / 8));
+ return true;
+ }
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ void platform_support::force_redraw()
+ {
+ m_specific->m_update_flag = true;
+ }
+
+
+ //------------------------------------------------------------------------
+ void platform_support::message(const char* msg)
+ {
+ fprintf(stderr, "%s\n", msg);
+ }
+
+ //------------------------------------------------------------------------
+ void platform_support::start_timer()
+ {
+ m_specific->m_sw_start = clock();
+ }
+
+ //------------------------------------------------------------------------
+ double platform_support::elapsed_time() const
+ {
+ clock_t stop = clock();
+ return double(stop - m_specific->m_sw_start) * 1000.0 / CLOCKS_PER_SEC;
+ }
+
+
+ //------------------------------------------------------------------------
+ void platform_support::on_init() {}
+ void platform_support::on_resize(int sx, int sy) {}
+ void platform_support::on_idle() {}
+ void platform_support::on_mouse_move(int x, int y, unsigned flags) {}
+ void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {}
+ void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {}
+ void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {}
+ void platform_support::on_ctrl_change() {}
+ void platform_support::on_draw() {}
+ void platform_support::on_post_draw(void* raw_handler) {}
+
+
+
+}
+
+
+void platform_support_prepare()
+{
+}
+
+void platform_support_lock(agg::platform_support *app)
+{
+ pthread_mutex_lock (app->m_specific->m_mutex);
+}
+
+void platform_support_unlock(agg::platform_support *app)
+{
+ pthread_mutex_unlock (app->m_specific->m_mutex);
+}
+
+bool platform_support_is_mapped(agg::platform_support *app)
+{
+ return app->m_specific->m_is_mapped;
+}
diff --git a/agg-plot/colors.cpp b/agg-plot/colors.cpp
index e4ea0807..1b16be47 100644
--- a/agg-plot/colors.cpp
+++ b/agg-plot/colors.cpp
@@ -50,3 +50,27 @@ rgba8_push_lookup (lua_State *L, const char *color_str)
return new(L, GS_RGBA_COLOR) agg::rgba8(r, g, b, a);
}
+
+agg::rgba8 *
+color_arg_lookup (lua_State *L, int index)
+{
+ agg::rgba8 *c;
+
+ if (lua_isnil (L, index))
+ {
+ c = rgba8_push_default (L);
+ lua_replace (L, index);
+ }
+ else if (lua_isstring (L, index))
+ {
+ const char *cstr = lua_tostring (L, index);
+ c = rgba8_push_lookup (L, cstr);
+ lua_replace (L, index);
+ }
+ else
+ {
+ c = (agg::rgba8 *) gs_check_userdata (L, index, GS_RGBA_COLOR);
+ }
+
+ return c;
+}
diff --git a/agg-plot/colors.h b/agg-plot/colors.h
index 6add76f2..6e9263d6 100644
--- a/agg-plot/colors.h
+++ b/agg-plot/colors.h
@@ -8,7 +8,8 @@ extern "C" {
#include "defs.h"
#include "agg_color_rgba.h"
-extern agg::rgba8 * rgba8_push_lookup(lua_State *L, const char *color_str);
-extern agg::rgba8 * rgba8_push_default(lua_State *L);
+extern agg::rgba8 * rgba8_push_lookup (lua_State *L, const char *color_str);
+extern agg::rgba8 * rgba8_push_default (lua_State *L);
+extern agg::rgba8 * color_arg_lookup (lua_State *L, int index);
#endif
diff --git a/agg-plot/lua-draw.cpp b/agg-plot/lua-draw.cpp
index d812d7ea..48e9580f 100644
--- a/agg-plot/lua-draw.cpp
+++ b/agg-plot/lua-draw.cpp
@@ -45,6 +45,9 @@ static int agg_text_set_point (lua_State *L);
static int agg_text_rotate (lua_State *L);
static int agg_rgba_free (lua_State *L);
+static int agg_rgba_add (lua_State *L);
+static int agg_rgba_mul (lua_State *L);
+static int agg_rgba_set_alpha (lua_State *L);
static void path_cmd (my::path *p, int cmd, struct cmd_call_stack *stack);
@@ -74,6 +77,9 @@ static const struct luaL_Reg agg_path_methods[] = {
static const struct luaL_Reg rgba_methods[] = {
{"__gc", agg_rgba_free},
+ {"__add", agg_rgba_add },
+ {"__mul", agg_rgba_mul },
+ {"alpha", agg_rgba_set_alpha },
{NULL, NULL}
};
@@ -240,7 +246,7 @@ agg_text_new (lua_State *L)
{
double size = luaL_optnumber (L, 1, 10.0);
double width = luaL_optnumber (L, 2, 1.0);
- my::text *txt = new(L, GS_DRAW_TEXT) my::text(size, width);
+ new(L, GS_DRAW_TEXT) my::text(size, width);
return 1;
}
@@ -321,6 +327,50 @@ agg_rgb_new (lua_State *L)
}
int
+agg_rgba_set_alpha (lua_State *L)
+{
+ agg::rgba8 *c = (agg::rgba8 *) gs_check_userdata (L, 1, GS_RGBA_COLOR);
+ double a = luaL_checknumber (L, 2);
+ c->a = agg::rgba8::base_mask * a;
+ return 0;
+}
+
+int
+agg_rgba_add (lua_State *L)
+{
+ agg::rgba8 *c1 = (agg::rgba8 *) gs_check_userdata (L, 1, GS_RGBA_COLOR);
+ agg::rgba8 *c2 = (agg::rgba8 *) gs_check_userdata (L, 2, GS_RGBA_COLOR);
+
+ unsigned int r = c1->r + c2->r;
+ unsigned int g = c1->g + c2->g;
+ unsigned int b = c1->b + c2->b;
+
+ new(L, GS_RGBA_COLOR) agg::rgba8(r, g, b);
+
+ return 1;
+}
+
+int
+agg_rgba_mul (lua_State *L)
+{
+ int is = 1, ic = 2;
+
+ if (gs_is_userdata (L, 1, GS_RGBA_COLOR))
+ {
+ ic = 1;
+ is = 2;
+ }
+
+ double f = luaL_checknumber (L, is);
+ agg::rgba8 *c = (agg::rgba8 *) gs_check_userdata (L, ic, GS_RGBA_COLOR);
+
+ unsigned int r = f * c->r, g = f * c->g, b = f * c->b;
+
+ new(L, GS_RGBA_COLOR) agg::rgba8(r, g, b);
+ return 1;
+}
+
+int
agg_rgba_free (lua_State *L)
{
typedef agg::rgba8 rgba_t;
@@ -345,6 +395,8 @@ draw_register (lua_State *L)
lua_pop (L, 1);
luaL_newmetatable (L, GS_METATABLE(GS_RGBA_COLOR));
+ lua_pushvalue (L, -1);
+ lua_setfield (L, -2, "__index");
luaL_register (L, NULL, rgba_methods);
lua_pop (L, 1);
}
diff --git a/agg-plot/lua-plot.cpp b/agg-plot/lua-plot.cpp
index f0993db9..0d59a5e7 100644
--- a/agg-plot/lua-plot.cpp
+++ b/agg-plot/lua-plot.cpp
@@ -17,6 +17,7 @@ extern "C" {
#include "trans.h"
#include "colors.h"
#include "xwin-show.h"
+#include "agg-parse-trans.h"
__BEGIN_DECLS
@@ -33,25 +34,12 @@ static int agg_plot_title_get (lua_State *L);
static int agg_plot_units_set (lua_State *L);
static int agg_plot_units_get (lua_State *L);
-static vertex_source * build_stroke (lua_State *L, int index, vertex_source *obj);
-static vertex_source * build_dash (lua_State *L, int index, vertex_source *obj);
-static vertex_source * build_curve (lua_State *L, int index, vertex_source *obj);
-static vertex_source * build_marker (lua_State *L, int index, vertex_source *obj);
-static vertex_source * build_rotate (lua_State *L, int index, vertex_source *obj);
-static vertex_source * build_translate (lua_State *L, int index, vertex_source *obj);
-
-/* DEBUG DEBUG DEBUG */
-static int window_debug_list (lua_State *L);
-static int obj_getfenv (lua_State *L);
-
static const struct luaL_Reg plot_functions[] = {
{"path", agg_path_new},
{"text", agg_text_new},
{"rgba", agg_rgba_new},
{"rgb", agg_rgb_new},
{"plot", agg_plot_new},
- {"windows", window_debug_list},
- {"objgetfenv", obj_getfenv},
{NULL, NULL}
};
@@ -78,61 +66,7 @@ static const struct luaL_Reg agg_plot_properties_set[] = {
{NULL, NULL}
};
-struct property_reg {
- int id;
- const char *name;
-};
-
-struct builder_reg {
- const char *name;
- vertex_source *(*func)(lua_State *, int, vertex_source *);
-};
-
__END_DECLS
-
-
-struct property_reg line_cap_properties[] = {
- {(int) agg::butt_cap, "butt" },
- {(int) agg::square_cap, "square"},
- {(int) agg::round_cap, "round" },
- {0, NULL}
-};
-
-struct property_reg line_join_properties[] = {
- {(int) agg::miter_join, "miter" },
- {(int) agg::miter_join_revert, "miter.rev" },
- {(int) agg::round_join, "round" },
- {(int) agg::bevel_join, "bevel" },
- {(int) agg::miter_join_round, "miter.round"},
- {0, NULL}
-};
-
-const builder_reg builder_table[] = {
- {"stroke", build_stroke },
- {"dash", build_dash},
- {"curve", build_curve},
- {"marker", build_marker},
- {"translate", build_translate},
- {"rotate", build_rotate},
- {NULL, NULL}
-};
-
-static int
-property_lookup (struct property_reg *prop, const char *key)
-{
- int default_value = prop->id;
-
- if (key == NULL)
- return default_value;
-
- for ( ; prop->name; prop++)
- {
- if (strcmp (prop->name, key) == 0)
- return prop->id;
- }
-
- return default_value;
-}
void agg_plot::wait_update()
{
@@ -237,151 +171,6 @@ agg_plot_newindex (lua_State *L)
return mlua_newindex_with_properties (L, agg_plot_properties_set);
}
-vertex_source *
-build_stroke (lua_State *L, int specindex, vertex_source *obj)
-{
- double width = mlua_named_optnumber (L, specindex, "width", 1.0);
- const char *cap_str = mlua_named_optstring (L, specindex, "cap", NULL);
- const char *join_str = mlua_named_optstring (L, specindex, "join", NULL);
-
- trans::stroke *stroke = new trans::stroke(obj, width);
-
- if (cap_str)
- {
- int cap = property_lookup (line_cap_properties, cap_str);
- stroke->line_cap((agg::line_cap_e) cap);
- }
-
- if (join_str)
- {
- int join = property_lookup (line_join_properties, join_str);
- stroke->line_join((agg::line_join_e) join);
- }
-
- return (vertex_source *) stroke;
-}
-
-vertex_source *
-build_curve (lua_State *L, int specindex, vertex_source *obj)
-{
- trans::curve *c = new trans::curve(obj);
- return (vertex_source *) c;
-}
-
-vertex_source *
-build_marker (lua_State *L, int specindex, vertex_source *obj)
-{
- double size = mlua_named_optnumber (L, specindex, "size", 3.0);
- return (vertex_source *) new trans::marker(obj, size);
-}
-
-vertex_source *
-build_dash (lua_State *L, int specindex, vertex_source *obj)
-{
- double a = mlua_named_optnumber (L, specindex, "a", 10.0);
- double b = mlua_named_optnumber (L, specindex, "b", a);
-
- trans::dash *dash = new trans::dash(obj);
- dash->add_dash(a, b);
-
- return (vertex_source *) dash;
-}
-
-vertex_source *
-build_translate (lua_State *L, int specindex, vertex_source *obj)
-{
- double x = mlua_named_number (L, specindex, "x");
- double y = mlua_named_number (L, specindex, "y");
-
- trans::affine *t = new trans::affine(obj);
- t->translate(x, y);
-
- return (vertex_source *) t;
-}
-
-vertex_source *
-build_rotate (lua_State *L, int specindex, vertex_source *obj)
-{
- double a = mlua_named_number (L, specindex, "angle");
-
- trans::affine *t = new trans::affine(obj);
- t->rotate(a);
-
- return (vertex_source *) t;
-}
-
-vertex_source *
-parse_spec (lua_State *L, int specindex, vertex_source *obj)
-{
- const char *tag;
-
- lua_rawgeti (L, specindex, 1);
- if (! lua_isstring (L, -1))
- {
- luaL_error (L, "the tag of the transformation is invalid");
- return NULL;
- }
-
- tag = lua_tostring (L, -1);
- lua_pop (L, 1);
-
- for (const builder_reg *b = builder_table; b->name != NULL; b++)
- {
- if (strcmp (b->name, tag) == 0)
- return b->func (L, specindex, obj);
- }
-
- luaL_error (L, "invalid trasformation tag");
- return NULL;
-}
-
-vertex_source *
-lparse_spec_pipeline (lua_State *L, int index, vertex_source *obj)
-{
- size_t k, nb;
-
- if (lua_type (L, index) == LUA_TTABLE)
- nb = lua_objlen (L, index);
- else
- {
- luaL_error (L, "post transform argument should be a table");
- return NULL;
- }
-
- for (k = nb; k > 0; k--)
- {
- lua_rawgeti (L, index, k);
- obj = parse_spec (L, index+1, obj);
- lua_pop (L, 1);
- }
-
- return obj;
-}
-
-static agg::rgba8 *
-color_arg_lookup (lua_State *L, int index)
-{
- agg::rgba8 *c;
-
- if (lua_isnil (L, index))
- {
- c = rgba8_push_default (L);
- lua_replace (L, index);
- }
- else if (lua_isstring (L, index))
- {
- const char *cstr = lua_tostring (L, index);
- c = rgba8_push_lookup (L, cstr);
- lua_replace (L, index);
- }
- else
- {
- c = check_agg_rgba8 (L, index);
- }
-
- return c;
-}
-
static int
agg_plot_add_gener (lua_State *L, bool as_line)
{
@@ -401,7 +190,7 @@ agg_plot_add_gener (lua_State *L, bool as_line)
if (narg > 4)
{
- curr = lparse_spec_pipeline (L, 5, curr);
+ curr = parse_spec_pipeline (L, 5, curr);
lua_pop (L, 1);
}
@@ -412,7 +201,7 @@ agg_plot_add_gener (lua_State *L, bool as_line)
if (narg > 3)
{
- curr = lparse_spec_pipeline (L, 4, curr);
+ curr = parse_spec_pipeline (L, 4, curr);
lua_pop (L, 1);
}
@@ -469,6 +258,7 @@ agg_plot_show (lua_State *L)
pthread_attr_destroy (attr);
mlua_window_unref(L, p->id);
p->id = -1;
+ AGG_UNLOCK();
return luaL_error(L, "error creating thread.");
}
@@ -481,20 +271,6 @@ agg_plot_show (lua_State *L)
return 0;
}
-int
-window_debug_list(lua_State *L)
-{
- lua_getfield (L, LUA_REGISTRYINDEX, "GSL.windows");
- return 1;
-}
-
-int
-obj_getfenv(lua_State *L)
-{
- lua_getfenv (L, 1);
- return 1;
-}
-
void
plot_register (lua_State *L)
{
diff --git a/agg-plot/plot-window.cpp b/agg-plot/plot-window.cpp
new file mode 100644
index 00000000..d16688b3
--- /dev/null
+++ b/agg-plot/plot-window.cpp
@@ -0,0 +1,345 @@
+
+extern "C" {
+#include "lua.h"
+#include "lauxlib.h"
+}
+
+#include "platform/agg_platform_support.h"
+
+#include "defs.h"
+#include "resource-manager.h"
+#include "gsl-shell.h"
+#include "plot-window.h"
+#include "agg-parse-trans.h"
+#include "lua-cpp-utils.h"
+#include "lua-utils.h"
+#include "lua-draw.h"
+#include "gs-types.h"
+#include "colors.h"
+#include "canvas.h"
+#include "trans.h"
+
+extern void platform_support_prepare ();
+extern void platform_support_lock (agg::platform_support *app);
+extern void platform_support_unlock (agg::platform_support *app);
+extern bool platform_support_is_mapped (agg::platform_support *app);
+
+
+__BEGIN_DECLS
+
+static void * win_thread_function (void *_win);
+
+static int plot_window_new (lua_State *L);
+static int plot_window_free (lua_State *L);
+static int plot_window_index (lua_State *L);
+static int plot_window_draw (lua_State *L);
+static int plot_window_clear (lua_State *L);
+static int plot_window_update (lua_State *L);
+static int plot_window_size (lua_State *L);
+static int plot_window_set_transform (lua_State *L);
+
+static const struct luaL_Reg plotwin_functions[] = {
+ {"window", plot_window_new},
+ {NULL, NULL}
+};
+
+static const struct luaL_Reg plot_window_methods[] = {
+ {"__gc", plot_window_free},
+ {"__index", plot_window_index},
+ {NULL, NULL}
+};
+
+static const struct luaL_Reg plot_window_methods_protected[] = {
+ {"draw", plot_window_draw},
+ {"clear", plot_window_clear},
+ {"update", plot_window_update},
+ {"size", plot_window_size},
+ {"transform", plot_window_set_transform},
+ {NULL, NULL}
+};
+
+__END_DECLS
+
+class plot_window : public agg::platform_support {
+private:
+ canvas *m_canvas;
+ agg::rgba m_bgcolor;
+
+public:
+ agg::trans_affine m_trans;
+
+ enum win_status_e { not_ready, starting, running, error, closed };
+
+ int id;
+ enum win_status_e status;
+
+ plot_window(agg::rgba& bgcol) :
+ agg::platform_support(agg::pix_format_bgr24, true),
+ m_canvas(NULL), m_bgcolor(bgcol), m_trans(), id(-1), status(not_ready)
+ { };
+
+ virtual ~plot_window()
+ {
+ if (m_canvas)
+ delete m_canvas;
+ };
+
+ virtual void on_init();
+ virtual void on_resize(int sx, int sy);
+
+ void start();
+ void clear() { if (m_canvas) m_canvas->clear(); };
+
+ bool draw(vertex_source *obj, agg::rgba8 *color)
+ {
+ if (! m_canvas)
+ return false;
+
+ m_canvas->draw(*obj, *color);
+ return true;
+ };
+
+ void set_transform(double sx, double sy, double x0, double y0)
+ {
+ m_trans = agg::trans_affine(sx, 0.0, 0.0, sy, x0, y0);
+ };
+
+ static plot_window *check (lua_State *L, int index);
+};
+
+void
+plot_window::on_init()
+{
+ if (m_canvas)
+ delete m_canvas;
+
+ m_canvas = new canvas(rbuf_window(), width(), height(), m_bgcolor);
+}
+
+void
+plot_window::on_resize(int sx, int sy)
+{
+ if (m_canvas)
+ delete m_canvas;
+
+ m_canvas = new canvas(rbuf_window(), sx, sy, m_bgcolor);
+}
+
+void
+plot_window::start()
+{
+ this->caption("GSL shell plot");
+ if (this->init(480, 480, agg::window_resize))
+ {
+ this->status = plot_window::running;
+
+ this->run();
+
+ this->status = plot_window::closed;
+
+ GSL_SHELL_LOCK();
+ gsl_shell_unref_plot (this->id);
+ GSL_SHELL_UNLOCK();
+ }
+
+ platform_support_unlock (this);
+}
+
+void *
+win_thread_function (void *_win)
+{
+ platform_support_prepare();
+
+ plot_window *win = (plot_window *) _win;
+ win->start();
+ return NULL;
+}
+
+plot_window *
+plot_window::check (lua_State *L, int index)
+{
+ return (plot_window *) gs_check_userdata (L, index, GS_AGG_WINDOW);
+}
+
+int
+plot_window_new (lua_State *L)
+{
+ agg::rgba8 *c8;
+
+ if (lua_gettop (L) == 0)
+ c8 = rgba8_push_default (L);
+ else
+ c8 = color_arg_lookup (L, 1);
+
+ const double bs = (double) agg::rgba8::base_mask;
+ agg::rgba color(c8->r / bs, c8->g / bs, c8->b / bs, c8->a / bs);
+
+ plot_window *win = new(L, GS_AGG_WINDOW) plot_window(color);
+
+ win->id = mlua_window_ref(L, lua_gettop (L));
+
+ pthread_attr_t attr[1];
+ pthread_t win_thread[1];
+
+ pthread_attr_init (attr);
+ pthread_attr_setdetachstate (attr, PTHREAD_CREATE_DETACHED);
+
+ platform_support_lock (win);
+
+ if (pthread_create(win_thread, attr, win_thread_function, (void*) win))
+ {
+ mlua_window_unref(L, win->id);
+
+ pthread_attr_destroy (attr);
+ win->status = plot_window::error;
+
+ luaL_error(L, "error creating thread");
+ }
+
+ pthread_attr_destroy (attr);
+ win->status = plot_window::starting;
+
+ return 1;
+}
+
+int
+plot_window_free (lua_State *L)
+{
+ plot_window *win = plot_window::check (L, 1);
+ win->~plot_window();
+ return 0;
+}
+
+int
+plot_window_draw (lua_State *L)
+{
+ plot_window *win = plot_window::check (L, 1);
+ int narg = lua_gettop (L);
+ agg::rgba8 *color;
+
+ if (narg <= 2)
+ color = rgba8_push_default (L);
+ else
+ color = color_arg_lookup (L, 3);
+
+ vertex_source *curr = check_agg_obj (L, 2);
+
+ trans::affine *to = new trans::affine(curr);
+ to->set_matrix(win->m_trans);
+ curr = to;
+
+ if (narg > 3)
+ {
+ curr = parse_spec_pipeline (L, 4, curr);
+ lua_pop (L, 1);
+ }
+
+ bool success = win->draw(curr, color);
+
+ lua_management::dispose(curr);
+
+ if (! success)
+ return luaL_error (L, "canvas not ready");
+
+ return 0;
+}
+
+int
+plot_window_clear (lua_State *L)
+{
+ plot_window *win = plot_window::check (L, 1);
+ win->clear();
+ return 0;
+}
+
+int
+plot_window_update (lua_State *L)
+{
+ plot_window *win = plot_window::check (L, 1);
+ win->update_window();
+ return 0;
+}
+
+static int
+plot_window_index_protected (lua_State *L)
+{
+ plot_window *win = plot_window::check(L, lua_upvalueindex(2));
+
+ platform_support_lock (win);
+
+ if (win->status != plot_window::running)
+ {
+ platform_support_unlock (win);
+ return luaL_error (L, "window is not active");
+ }
+
+ int narg = lua_gettop (L);
+
+ lua_pushvalue (L, lua_upvalueindex(1));
+ lua_insert (L, 1);
+
+ if (lua_pcall (L, narg, LUA_MULTRET, 0) != 0)
+ {
+ platform_support_unlock (win);
+ return lua_error (L);
+ }
+
+ platform_support_unlock (win);
+ return lua_gettop (L);
+}
+
+int
+plot_window_index (lua_State *L)
+{
+ const char *key = luaL_checkstring (L, 2);
+
+ const struct luaL_Reg *r = mlua_find_method (plot_window_methods, key);
+ if (r)
+ {
+ lua_pushcfunction (L, r->func);
+ return 1;
+ }
+
+ r = mlua_find_method (plot_window_methods_protected, key);
+ if (r)
+ {
+ lua_pushcfunction (L, r->func);
+ lua_pushvalue (L, 1);
+ lua_pushcclosure (L, plot_window_index_protected, 2);
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+plot_window_size (lua_State *L)
+{
+ plot_window *win = plot_window::check(L, 1);
+ lua_pushinteger (L, win->width());
+ lua_pushinteger (L, win->height());
+ return 2;
+}
+
+int
+plot_window_set_transform (lua_State *L)
+{
+ plot_window *win = plot_window::check(L, 1);
+ double sx = luaL_checknumber (L, 2);
+ double sy = luaL_checknumber (L, 3);
+ double x0 = luaL_optnumber (L, 4, 0.0);
+ double y0 = luaL_optnumber (L, 5, 0.0);
+ win->set_transform(sx, sy, x0, y0);
+ return 0;
+}
+
+void
+plot_window_register (lua_State *L)
+{
+ luaL_newmetatable (L, GS_METATABLE(GS_AGG_WINDOW));
+ luaL_register (L, NULL, plot_window_methods);
+ lua_pop (L, 1);
+
+ /* gsl module registration */
+ luaL_register (L, NULL, plotwin_functions);
+}
diff --git a/agg-plot/plot-window.h b/agg-plot/plot-window.h
new file mode 100644
index 00000000..18a21a0a
--- /dev/null
+++ b/agg-plot/plot-window.h
@@ -0,0 +1,16 @@
+#ifndef PLOT_WINDOW_H
+#define PLOT_WINDOW_H
+
+__BEGIN_DECLS
+#include "lua.h"
+__END_DECLS
+
+#include "defs.h"
+
+__BEGIN_DECLS
+
+extern void plot_window_register (lua_State *L);
+
+__END_DECLS
+
+#endif
diff --git a/agg-plot/trans.h b/agg-plot/trans.h
index 6110263d..35dec2a7 100644
--- a/agg-plot/trans.h
+++ b/agg-plot/trans.h
@@ -6,6 +6,7 @@
#include "agg_conv_curve.h"
#include "agg_conv_dash.h"
#include "agg_conv_transform.h"
+#include "agg_conv_contour.h"
#include "agg_vcgen_markers_term.h"
#include "agg_arrowhead.h"
#include "agg_bounding_rect.h"
@@ -59,6 +60,7 @@ typedef vs_trans_proxy<agg::conv_stroke<vertex_source> > vs_stroke;
typedef vs_trans_proxy<agg::conv_curve<vertex_source> > vs_curve;
typedef vs_trans_proxy<agg::conv_dash<vertex_source> > vs_dash;
typedef vs_trans_proxy<agg::conv_transform<vertex_source> > vs_transform;
+typedef vs_trans_proxy<agg::conv_contour<vertex_source> > vs_contour;
namespace trans {
@@ -127,6 +129,24 @@ namespace trans {
m_source->apply_transform(m, as);
};
};
+
+ class extend : public vs_contour {
+ public:
+ typedef agg::conv_contour<vertex_source> base_type;
+
+ extend(vertex_source* src, double width): vs_contour(src)
+ {
+ base_type& v = self();
+ v.width(width);
+ v.auto_detect_orientation(true);
+ };
+
+ virtual void apply_transform(agg::trans_affine& m, double as)
+ {
+ m_output.approximation_scale(as);
+ m_source->apply_transform(m, as);
+ };
+ };
class resize : public vs_transform {
agg::trans_affine m_matrix;
@@ -161,6 +181,8 @@ namespace trans {
const trans_affine& rotate(double a) { return m_matrix.rotate(a); };
const trans_affine& translate(double x, double y) { return m_matrix.translate(x, y); };
+
+ void set_matrix(const agg::trans_affine& m) { m_matrix = m; };
};
}
diff --git a/agg-plot/xwin-show.cpp b/agg-plot/xwin-show.cpp
index 25cd6bee..f96c401c 100644
--- a/agg-plot/xwin-show.cpp
+++ b/agg-plot/xwin-show.cpp
@@ -77,6 +77,8 @@ xwin_thread_function (void *_plot)
the_application app(agg::pix_format_bgr24, flip_y, p);
app.caption("GSL shell plot");
+ platform_support_lock (&app);
+
if(app.init(780, 400, agg::window_resize))
{
p->window = (void *) &app;
@@ -95,5 +97,7 @@ xwin_thread_function (void *_plot)
GSL_SHELL_UNLOCK();
}
+ platform_support_unlock (&app);
+
return NULL;
}
generated by cgit v1.2.3 (git 2.39.1) at 2025年09月19日 02:55:10 +0000

AltStyle によって変換されたページ (->オリジナル) /