aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform
diff options
context:
space:
mode:
authormaxim-yurchuk <maxim-yurchuk@yandex-team.com>2024-10-09 12:29:46 +0300
committermaxim-yurchuk <maxim-yurchuk@yandex-team.com>2024-10-09 13:14:22 +0300
commit9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80 (patch)
treea8fb3181d5947c0d78cf402aa56e686130179049 /contrib/python/matplotlib/py2/extern/agg24-svn/src/platform
parenta44b779cd359f06c3ebbef4ec98c6b38609d9d85 (diff)
downloadydb-9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80.tar.gz
publishFullContrib: true for ydb
<HIDDEN_URL> commit_hash:c82a80ac4594723cebf2c7387dec9c60217f603e
Diffstat (limited to 'contrib/python/matplotlib/py2/extern/agg24-svn/src/platform')
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp977
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp990
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp1601
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp298
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp1053
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp708
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp1655
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp631
8 files changed, 7913 insertions, 0 deletions
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp
new file mode 100644
index 0000000000..b14d09cd1c
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp
@@ -0,0 +1,977 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// class platform_support
+//
+//----------------------------------------------------------------------------
+
+#include "platform/agg_platform_support.h"
+#include "util/agg_color_conv_rgb8.h"
+
+#include <sys/time.h>
+#include <cstring>
+
+#include <classes/requester.h>
+#include <classes/window.h>
+#include <datatypes/pictureclass.h>
+#include <proto/exec.h>
+#include <proto/datatypes.h>
+#include <proto/dos.h>
+#include <proto/graphics.h>
+#include <proto/intuition.h>
+#include <proto/keymap.h>
+#include <proto/Picasso96API.h>
+#include <proto/utility.h>
+
+Library* DataTypesBase = 0;
+Library* GraphicsBase = 0;
+Library* IntuitionBase = 0;
+Library* KeymapBase = 0;
+Library* P96Base = 0;
+
+DataTypesIFace* IDataTypes = 0;
+GraphicsIFace* IGraphics = 0;
+IntuitionIFace* IIntuition = 0;
+KeymapIFace* IKeymap = 0;
+P96IFace* IP96 = 0;
+
+Class* RequesterClass = 0;
+Class* WindowClass = 0;
+
+
+namespace agg
+{
+ void handle_idcmp(Hook* hook, APTR win, IntuiMessage* msg);
+
+ //------------------------------------------------------------------------
+ class platform_specific
+ {
+ public:
+ platform_specific(platform_support& support, pix_format_e format,
+ bool flip_y);
+ ~platform_specific();
+ bool handle_input();
+ bool load_img(const char* file, unsigned idx, rendering_buffer* rbuf);
+ bool create_img(unsigned idx, rendering_buffer* rbuf, unsigned width,
+ unsigned height);
+ bool make_bitmap();
+ public:
+ platform_support& m_support;
+ RGBFTYPE m_ftype;
+ pix_format_e m_format;
+ unsigned m_bpp;
+ BitMap* m_bitmap;
+ bool m_flip_y;
+ uint16 m_width;
+ uint16 m_height;
+ APTR m_window_obj;
+ Window* m_window;
+ Hook* m_idcmp_hook;
+ unsigned m_input_flags;
+ bool m_dragging;
+ double m_start_time;
+ uint16 m_last_key;
+ BitMap* m_img_bitmaps[platform_support::max_images];
+ };
+
+ //------------------------------------------------------------------------
+ platform_specific::platform_specific(platform_support& support,
+ pix_format_e format, bool flip_y) :
+ m_support(support),
+ m_ftype(RGBFB_NONE),
+ m_format(format),
+ m_bpp(0),
+ m_bitmap(0),
+ m_flip_y(flip_y),
+ m_width(0),
+ m_height(0),
+ m_window_obj(0),
+ m_window(0),
+ m_idcmp_hook(0),
+ m_input_flags(0),
+ m_dragging(false),
+ m_start_time(0.0),
+ m_last_key(0)
+ {
+ switch ( format )
+ {
+ case pix_format_gray8:
+ // Not supported.
+ break;
+ case pix_format_rgb555:
+ m_ftype = RGBFB_R5G5B5;
+ m_bpp = 15;
+ break;
+ case pix_format_rgb565:
+ m_ftype = RGBFB_R5G6B5;
+ m_bpp = 16;
+ break;
+ case pix_format_rgb24:
+ m_ftype = RGBFB_R8G8B8;
+ m_bpp = 24;
+ break;
+ case pix_format_bgr24:
+ m_ftype = RGBFB_B8G8R8;
+ m_bpp = 24;
+ break;
+ case pix_format_bgra32:
+ m_ftype = RGBFB_B8G8R8A8;
+ m_bpp = 32;
+ break;
+ case pix_format_abgr32:
+ m_ftype = RGBFB_A8B8G8R8;
+ m_bpp = 32;
+ break;
+ case pix_format_argb32:
+ m_ftype = RGBFB_A8R8G8B8;
+ m_bpp = 32;
+ break;
+ case pix_format_rgba32:
+ m_ftype = RGBFB_R8G8B8A8;
+ m_bpp = 32;
+ break;
+ }
+
+ for ( unsigned i = 0; i < platform_support::max_images; ++i )
+ {
+ m_img_bitmaps[i] = 0;
+ }
+ }
+
+ //------------------------------------------------------------------------
+ platform_specific::~platform_specific()
+ {
+ IIntuition->DisposeObject(m_window_obj);
+
+ IP96->p96FreeBitMap(m_bitmap);
+
+ for ( unsigned i = 0; i < platform_support::max_images; ++i )
+ {
+ IP96->p96FreeBitMap(m_img_bitmaps[i]);
+ }
+
+ if ( m_idcmp_hook != 0 )
+ {
+ IExec->FreeSysObject(ASOT_HOOK, m_idcmp_hook);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ bool platform_specific::handle_input()
+ {
+ int16 code = 0;
+ uint32 result = 0;
+ Object* obj = reinterpret_cast<Object*>(m_window_obj);
+
+ while ( (result = IIntuition->IDoMethod(obj, WM_HANDLEINPUT,
+ &code)) != WMHI_LASTMSG )
+ {
+ switch ( result & WMHI_CLASSMASK )
+ {
+ case WMHI_CLOSEWINDOW:
+ return true;
+ break;
+ case WMHI_INTUITICK:
+ if ( !m_support.wait_mode() )
+ {
+ m_support.on_idle();
+ }
+ break;
+ case WMHI_NEWSIZE:
+ if ( make_bitmap() )
+ {
+ m_support.trans_affine_resizing(m_width, m_height);
+ m_support.on_resize(m_width, m_height);
+ m_support.force_redraw();
+ }
+ break;
+ }
+ }
+
+ return false;
+ }
+
+ //------------------------------------------------------------------------
+ bool platform_specific::load_img(const char* file, unsigned idx,
+ rendering_buffer* rbuf)
+ {
+ if ( m_img_bitmaps[idx] != 0 )
+ {
+ IP96->p96FreeBitMap(m_img_bitmaps[idx]);
+ m_img_bitmaps[idx] = 0;
+ }
+
+ bool result = false;
+
+ Object* picture = IDataTypes->NewDTObject(const_cast<STRPTR>(file),
+ DTA_GroupID, GID_PICTURE,
+ PDTA_DestMode, PMODE_V43,
+ PDTA_Remap, FALSE,
+ TAG_END);
+ if ( picture != 0 )
+ {
+ gpLayout layout;
+ layout.MethodID = DTM_PROCLAYOUT;
+ layout.gpl_GInfo = 0;
+ layout.gpl_Initial = 1;
+ ULONG loaded = IDataTypes->DoDTMethodA(picture, 0, 0,
+ reinterpret_cast<Msg>(&layout));
+ if ( loaded != 0 )
+ {
+ BitMap* src_bitmap = 0;
+ IDataTypes->GetDTAttrs(picture,
+ PDTA_ClassBitMap, &src_bitmap,
+ TAG_END);
+
+ bool supported = false;
+
+ RGBFTYPE ftype = static_cast<RGBFTYPE>(IP96->p96GetBitMapAttr(
+ src_bitmap, P96BMA_RGBFORMAT));
+
+ switch ( ftype )
+ {
+ case RGBFB_R8G8B8:
+ supported = true;
+ break;
+ default:
+ m_support.message("File uses unsupported graphics mode.");
+ break;
+ }
+
+ if ( supported ) {
+ uint16 width = IP96->p96GetBitMapAttr(src_bitmap,
+ P96BMA_WIDTH);
+ uint16 height = IP96->p96GetBitMapAttr(src_bitmap,
+ P96BMA_HEIGHT);
+
+ m_img_bitmaps[idx] = IP96->p96AllocBitMap(width, height,
+ m_bpp, BMF_USERPRIVATE, 0, m_ftype);
+ if ( m_img_bitmaps[idx] != 0 )
+ {
+ int8u* buf = reinterpret_cast<int8u*>(
+ IP96->p96GetBitMapAttr(m_img_bitmaps[idx],
+ P96BMA_MEMORY));
+ int bpr = IP96->p96GetBitMapAttr(m_img_bitmaps[idx],
+ P96BMA_BYTESPERROW);
+ int stride = (m_flip_y) ? -bpr : bpr;
+ rbuf->attach(buf, width, height, stride);
+
+ // P96 sets the alpha to zero so it can't be used to
+ // color convert true color modes.
+ if ( m_bpp == 32 )
+ {
+ RenderInfo ri;
+ int32 lock = IP96->p96LockBitMap(src_bitmap,
+ reinterpret_cast<uint8*>(&ri),
+ sizeof(RenderInfo));
+
+ rendering_buffer rbuf_src;
+ rbuf_src.attach(
+ reinterpret_cast<int8u*>(ri.Memory),
+ width, height, (m_flip_y) ?
+ -ri.BytesPerRow : ri.BytesPerRow);
+
+ switch ( m_format )
+ {
+ case pix_format_bgra32:
+ color_conv(rbuf, &rbuf_src,
+ color_conv_rgb24_to_bgra32());
+ break;
+ case pix_format_abgr32:
+ color_conv(rbuf, &rbuf_src,
+ color_conv_rgb24_to_abgr32());
+ break;
+ case pix_format_argb32:
+ color_conv(rbuf, &rbuf_src,
+ color_conv_rgb24_to_argb32());
+ break;
+ case pix_format_rgba32:
+ color_conv(rbuf, &rbuf_src,
+ color_conv_rgb24_to_rgba32());
+ break;
+ }
+
+ IP96->p96UnlockBitMap(src_bitmap, lock);
+ }
+ else
+ {
+ IGraphics->BltBitMap(src_bitmap, 0, 0,
+ m_img_bitmaps[idx], 0, 0, width, height,
+ ABC|ABNC, 0xFF, 0);
+ }
+
+ result = true;
+ }
+ }
+ }
+ }
+
+ IGraphics->WaitBlit();
+ IDataTypes->DisposeDTObject(picture);
+
+ return result;
+ }
+
+ //------------------------------------------------------------------------
+ bool platform_specific::create_img(unsigned idx, rendering_buffer* rbuf,
+ unsigned width, unsigned height)
+ {
+ if ( m_img_bitmaps[idx] != 0 )
+ {
+ IP96->p96FreeBitMap(m_img_bitmaps[idx]);
+ m_img_bitmaps[idx] = 0;
+ }
+
+ m_img_bitmaps[idx] = IP96->p96AllocBitMap(width, height,
+ m_bpp, BMF_USERPRIVATE, m_bitmap, m_ftype);
+ if ( m_img_bitmaps[idx] != 0 )
+ {
+ int8u* buf = reinterpret_cast<int8u*>(
+ IP96->p96GetBitMapAttr(m_img_bitmaps[idx],
+ P96BMA_MEMORY));
+ int bpr = IP96->p96GetBitMapAttr(m_img_bitmaps[idx],
+ P96BMA_BYTESPERROW);
+ int stride = (m_flip_y) ? -bpr : bpr;
+
+ rbuf->attach(buf, width, height, stride);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ //------------------------------------------------------------------------
+ bool platform_specific::make_bitmap()
+ {
+ uint32 width = 0;
+ uint32 height = 0;
+ IIntuition->GetWindowAttrs(m_window,
+ WA_InnerWidth, &width,
+ WA_InnerHeight, &height,
+ TAG_END);
+
+ BitMap* bm = IP96->p96AllocBitMap(width, height, m_bpp,
+ BMF_USERPRIVATE|BMF_CLEAR, 0, m_ftype);
+ if ( bm == 0 )
+ {
+ return false;
+ }
+
+ int8u* buf = reinterpret_cast<int8u*>(
+ IP96->p96GetBitMapAttr(bm, P96BMA_MEMORY));
+ int bpr = IP96->p96GetBitMapAttr(bm, P96BMA_BYTESPERROW);
+ int stride = (m_flip_y) ? -bpr : bpr;
+
+ m_support.rbuf_window().attach(buf, width, height, stride);
+
+ if ( m_bitmap != 0 )
+ {
+ IP96->p96FreeBitMap(m_bitmap);
+ m_bitmap = 0;
+ }
+
+ m_bitmap = bm;
+ m_width = width;
+ m_height = height;
+
+ return true;
+ }
+
+ //------------------------------------------------------------------------
+ platform_support::platform_support(pix_format_e format, bool flip_y) :
+ m_specific(new platform_specific(*this, 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)
+ {
+ std::strncpy(m_caption, "Anti-Grain Geometry", 256);
+ }
+
+ //------------------------------------------------------------------------
+ platform_support::~platform_support()
+ {
+ delete m_specific;
+ }
+
+ //------------------------------------------------------------------------
+ void platform_support::caption(const char* cap)
+ {
+ std::strncpy(m_caption, cap, 256);
+ if ( m_specific->m_window != 0 )
+ {
+ const char* ignore = reinterpret_cast<const char*>(-1);
+ IIntuition->SetWindowAttr(m_specific->m_window,
+ WA_Title, m_caption, sizeof(char*));
+ }
+ }
+
+ //------------------------------------------------------------------------
+ void platform_support::start_timer()
+ {
+ timeval tv;
+ gettimeofday(&tv, 0);
+ m_specific->m_start_time = tv.tv_secs + tv.tv_micro/1e6;
+ }
+
+ //------------------------------------------------------------------------
+ double platform_support::elapsed_time() const
+ {
+ timeval tv;
+ gettimeofday(&tv, 0);
+ double end_time = tv.tv_secs + tv.tv_micro/1e6;
+
+ double elasped_seconds = end_time - m_specific->m_start_time;
+ double elasped_millis = elasped_seconds*1e3;
+
+ return elasped_millis;
+ }
+
+ //------------------------------------------------------------------------
+ void* platform_support::raw_display_handler()
+ {
+ return 0; // Not available.
+ }
+
+ //------------------------------------------------------------------------
+ void platform_support::message(const char* msg)
+ {
+ APTR req = IIntuition->NewObject(RequesterClass, 0,
+ REQ_TitleText, "Anti-Grain Geometry",
+ REQ_Image, REQIMAGE_INFO,
+ REQ_BodyText, msg,
+ REQ_GadgetText, "_Ok",
+ TAG_END);
+ if ( req == 0 )
+ {
+ IDOS->Printf("Message: %s\n", msg);
+ return;
+ }
+
+ orRequest reqmsg;
+ reqmsg.MethodID = RM_OPENREQ;
+ reqmsg.or_Attrs = 0;
+ reqmsg.or_Window = m_specific->m_window;
+ reqmsg.or_Screen = 0;
+
+ IIntuition->IDoMethodA(reinterpret_cast<Object*>(req),
+ reinterpret_cast<Msg>(&reqmsg));
+ IIntuition->DisposeObject(req);
+ }
+
+ //------------------------------------------------------------------------
+ bool platform_support::init(unsigned width, unsigned height,
+ unsigned flags)
+ {
+ if( m_specific->m_ftype == RGBFB_NONE )
+ {
+ message("Unsupported mode requested.");
+ return false;
+ }
+
+ m_window_flags = flags;
+
+ m_specific->m_idcmp_hook = reinterpret_cast<Hook*>(
+ IExec->AllocSysObjectTags(ASOT_HOOK,
+ ASOHOOK_Entry, handle_idcmp,
+ ASOHOOK_Data, this,
+ TAG_END));
+ if ( m_specific->m_idcmp_hook == 0 )
+ {
+ return false;
+ }
+
+ m_specific->m_window_obj = IIntuition->NewObject(WindowClass, 0,
+ WA_Title, m_caption,
+ WA_AutoAdjustDClip, TRUE,
+ WA_InnerWidth, width,
+ WA_InnerHeight, height,
+ WA_Activate, TRUE,
+ WA_SmartRefresh, TRUE,
+ WA_NoCareRefresh, TRUE,
+ WA_CloseGadget, TRUE,
+ WA_DepthGadget, TRUE,
+ WA_SizeGadget, (flags & agg::window_resize) ? TRUE : FALSE,
+ WA_DragBar, TRUE,
+ WA_AutoAdjust, TRUE,
+ WA_ReportMouse, TRUE,
+ WA_RMBTrap, TRUE,
+ WA_MouseQueue, 1,
+ WA_IDCMP,
+ IDCMP_NEWSIZE |
+ IDCMP_MOUSEBUTTONS |
+ IDCMP_MOUSEMOVE |
+ IDCMP_RAWKEY |
+ IDCMP_INTUITICKS,
+ WINDOW_IDCMPHook, m_specific->m_idcmp_hook,
+ WINDOW_IDCMPHookBits,
+ IDCMP_MOUSEBUTTONS |
+ IDCMP_MOUSEMOVE |
+ IDCMP_RAWKEY,
+ TAG_END);
+ if ( m_specific->m_window_obj == 0 )
+ {
+ return false;
+ }
+
+ Object* obj = reinterpret_cast<Object*>(m_specific->m_window_obj);
+ m_specific->m_window =
+ reinterpret_cast<Window*>(IIntuition->IDoMethod(obj, WM_OPEN));
+ if ( m_specific->m_window == 0 )
+ {
+ return false;
+ }
+
+ RGBFTYPE ftype = static_cast<RGBFTYPE>(IP96->p96GetBitMapAttr(
+ m_specific->m_window->RPort->BitMap, P96BMA_RGBFORMAT));
+
+ switch ( ftype )
+ {
+ case RGBFB_A8R8G8B8:
+ case RGBFB_B8G8R8A8:
+ case RGBFB_R5G6B5PC:
+ break;
+ default:
+ message("Unsupported screen mode.\n");
+ return false;
+ }
+
+ if ( !m_specific->make_bitmap() )
+ {
+ return false;
+ }
+
+ m_initial_width = width;
+ m_initial_height = height;
+
+ on_init();
+ on_resize(width, height);
+ force_redraw();
+
+ return true;
+ }
+
+ //------------------------------------------------------------------------
+ int platform_support::run()
+ {
+ uint32 window_mask = 0;
+ IIntuition->GetAttr(WINDOW_SigMask, m_specific->m_window_obj,
+ &window_mask);
+ uint32 wait_mask = window_mask | SIGBREAKF_CTRL_C;
+
+ bool done = false;
+
+ while ( !done )
+ {
+ uint32 sig_mask = IExec->Wait(wait_mask);
+ if ( sig_mask & SIGBREAKF_CTRL_C )
+ {
+ done = true;
+ }
+ else
+ {
+ done = m_specific->handle_input();
+ }
+ }
+
+ return 0;
+ }
+
+ //------------------------------------------------------------------------
+ const char* platform_support::img_ext() const
+ {
+ return ".bmp";
+ }
+
+ //------------------------------------------------------------------------
+ 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 )
+ {
+ static char fn[1024];
+ std::strncpy(fn, file, 1024);
+ int len = std::strlen(fn);
+ if ( len < 4 || std::strcmp(fn + len - 4, ".bmp") != 0 )
+ {
+ std::strncat(fn, ".bmp", 1024);
+ }
+
+ return m_specific->load_img(fn, idx, &m_rbuf_img[idx]);
+ }
+
+ return false;
+ }
+
+ //------------------------------------------------------------------------
+ bool platform_support::save_img(unsigned idx, const char* file)
+ {
+ message("Not supported");
+ return false;
+ }
+
+ //------------------------------------------------------------------------
+ bool platform_support::create_img(unsigned idx, unsigned width,
+ unsigned height)
+ {
+ if ( idx < max_images )
+ {
+ if ( width == 0 )
+ {
+ width = m_specific->m_width;
+ }
+
+ if ( height == 0 )
+ {
+ height = m_specific->m_height;
+ }
+
+ return m_specific->create_img(idx, &m_rbuf_img[idx], width,
+ height);
+ }
+
+ return false;
+ }
+
+ //------------------------------------------------------------------------
+ void platform_support::force_redraw()
+ {
+ on_draw();
+ update_window();
+ }
+
+ //------------------------------------------------------------------------
+ void platform_support::update_window()
+ {
+ // Note this function does automatic color conversion.
+ IGraphics->BltBitMapRastPort(m_specific->m_bitmap, 0, 0,
+ m_specific->m_window->RPort, m_specific->m_window->BorderLeft,
+ m_specific->m_window->BorderTop, m_specific->m_width,
+ m_specific->m_height, ABC|ABNC);
+ }
+
+ //------------------------------------------------------------------------
+ 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 handle_idcmp(Hook* hook, APTR obj, IntuiMessage* msg)
+ {
+ platform_support* app =
+ reinterpret_cast<platform_support*>(hook->h_Data);
+ Window* window = app->m_specific->m_window;
+
+ int16 x = msg->MouseX - window->BorderLeft;
+
+ int16 y = 0;
+ if ( app->flip_y() )
+ {
+ y = window->Height - window->BorderBottom - msg->MouseY;
+ }
+ else
+ {
+ y = msg->MouseY - window->BorderTop;
+ }
+
+ switch ( msg->Class )
+ {
+ case IDCMP_MOUSEBUTTONS:
+ if ( msg->Code & IECODE_UP_PREFIX )
+ {
+ if ( msg->Code == SELECTUP )
+ {
+ app->m_specific->m_input_flags = mouse_left;
+ app->m_specific->m_dragging = false;
+ }
+ else if ( msg->Code == MENUUP )
+ {
+ app->m_specific->m_input_flags = mouse_right;
+ app->m_specific->m_dragging = false;
+ }
+ else
+ {
+ return;
+ }
+
+
+ if ( app->m_ctrls.on_mouse_button_up(x, y) )
+ {
+ app->on_ctrl_change();
+ app->force_redraw();
+ }
+
+ app->on_mouse_button_up(x, y, app->m_specific->m_input_flags);
+ }
+ else
+ {
+ if ( msg->Code == SELECTDOWN )
+ {
+ app->m_specific->m_input_flags = mouse_left;
+ app->m_specific->m_dragging = true;
+ }
+ else if ( msg->Code == MENUDOWN )
+ {
+ app->m_specific->m_input_flags = mouse_right;
+ app->m_specific->m_dragging = true;
+ }
+ else
+ {
+ return;
+ }
+
+ app->m_ctrls.set_cur(x, y);
+ if ( app->m_ctrls.on_mouse_button_down(x, y) )
+ {
+ app->on_ctrl_change();
+ app->force_redraw();
+ }
+ else
+ {
+ if ( app->m_ctrls.in_rect(x, y) )
+ {
+ if ( app->m_ctrls.set_cur(x, y) )
+ {
+ app->on_ctrl_change();
+ app->force_redraw();
+ }
+ }
+ else
+ {
+ app->on_mouse_button_down(x, y,
+ app->m_specific->m_input_flags);
+ }
+ }
+ }
+ break;
+ case IDCMP_MOUSEMOVE:
+ if ( app->m_specific->m_dragging ) {
+ if ( app->m_ctrls.on_mouse_move(x, y,
+ app->m_specific->m_input_flags & mouse_left) != 0 )
+ {
+ app->on_ctrl_change();
+ app->force_redraw();
+ }
+ else
+ {
+ if ( !app->m_ctrls.in_rect(x, y) )
+ {
+ app->on_mouse_move(x, y,
+ app->m_specific->m_input_flags);
+ }
+ }
+ }
+ break;
+ case IDCMP_RAWKEY:
+ {
+ static InputEvent ie = { 0 };
+ ie.ie_Class = IECLASS_RAWKEY;
+ ie.ie_Code = msg->Code;
+ ie.ie_Qualifier = msg->Qualifier;
+
+ static const unsigned BUF_SIZE = 16;
+ static char key_buf[BUF_SIZE];
+ int16 num_chars = IKeymap->MapRawKey(&ie, key_buf, BUF_SIZE, 0);
+
+ uint32 code = 0x00000000;
+ switch ( num_chars )
+ {
+ case 1:
+ code = key_buf[0];
+ break;
+ case 2:
+ code = key_buf[0]<<8 | key_buf[1];
+ break;
+ case 3:
+ code = key_buf[0]<<16 | key_buf[1]<<8 | key_buf[2];
+ break;
+ }
+
+ uint16 key_code = 0;
+
+ if ( num_chars == 1 )
+ {
+ if ( code >= IECODE_ASCII_FIRST && code <= IECODE_ASCII_LAST )
+ {
+ key_code = code;
+ }
+ }
+
+ if ( key_code == 0 )
+ {
+ switch ( code )
+ {
+ case 0x00000008: key_code = key_backspace; break;
+ case 0x00000009: key_code = key_tab; break;
+ case 0x0000000D: key_code = key_return; break;
+ case 0x0000001B: key_code = key_escape; break;
+ case 0x0000007F: key_code = key_delete; break;
+ case 0x00009B41:
+ case 0x00009B54: key_code = key_up; break;
+ case 0x00009B42:
+ case 0x00009B53: key_code = key_down; break;
+ case 0x00009B43:
+ case 0x009B2040: key_code = key_right; break;
+ case 0x00009B44:
+ case 0x009B2041: key_code = key_left; break;
+ case 0x009B307E: key_code = key_f1; break;
+ case 0x009B317E: key_code = key_f2; break;
+ case 0x009B327E: key_code = key_f3; break;
+ case 0x009B337E: key_code = key_f4; break;
+ case 0x009B347E: key_code = key_f5; break;
+ case 0x009B357E: key_code = key_f6; break;
+ case 0x009B367E: key_code = key_f7; break;
+ case 0x009B377E: key_code = key_f8; break;
+ case 0x009B387E: key_code = key_f9; break;
+ case 0x009B397E: key_code = key_f10; break;
+ case 0x009B3F7E: key_code = key_scrollock; break;
+ }
+ }
+
+ if ( ie.ie_Code & IECODE_UP_PREFIX )
+ {
+ if ( app->m_specific->m_last_key != 0 )
+ {
+ bool left = (key_code == key_left) ? true : false;
+ bool right = (key_code == key_right) ? true : false;
+ bool down = (key_code == key_down) ? true : false;
+ bool up = (key_code == key_up) ? true : false;
+
+ if ( app->m_ctrls.on_arrow_keys(left, right, down, up) )
+ {
+ app->on_ctrl_change();
+ app->force_redraw();
+ }
+ else
+ {
+ app->on_key(x, y, app->m_specific->m_last_key, 0);
+ }
+
+ app->m_specific->m_last_key = 0;
+ }
+ }
+ else
+ {
+ app->m_specific->m_last_key = key_code;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+int agg_main(int argc, char* argv[]);
+bool open_libs();
+void close_libs();
+
+//----------------------------------------------------------------------------
+bool open_libs()
+{
+ DataTypesBase = IExec->OpenLibrary("datatypes.library", 51);
+ GraphicsBase = IExec->OpenLibrary("graphics.library", 51);
+ IntuitionBase = IExec->OpenLibrary("intuition.library", 51);
+ KeymapBase = IExec->OpenLibrary("keymap.library", 51);
+ P96Base = IExec->OpenLibrary("Picasso96API.library", 2);
+
+ IDataTypes = reinterpret_cast<DataTypesIFace*>(
+ IExec->GetInterface(DataTypesBase, "main", 1, 0));
+ IGraphics = reinterpret_cast<GraphicsIFace*>(
+ IExec->GetInterface(GraphicsBase, "main", 1, 0));
+ IIntuition = reinterpret_cast<IntuitionIFace*>(
+ IExec->GetInterface(IntuitionBase, "main", 1, 0));
+ IKeymap = reinterpret_cast<KeymapIFace*>(
+ IExec->GetInterface(KeymapBase, "main", 1, 0));
+ IP96 = reinterpret_cast<P96IFace*>(
+ IExec->GetInterface(P96Base, "main", 1, 0));
+
+ if ( IDataTypes == 0 ||
+ IGraphics == 0 ||
+ IIntuition == 0 ||
+ IKeymap == 0 ||
+ IP96 == 0 )
+ {
+ close_libs();
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+//----------------------------------------------------------------------------
+void close_libs()
+{
+ IExec->DropInterface(reinterpret_cast<Interface*>(IP96));
+ IExec->DropInterface(reinterpret_cast<Interface*>(IKeymap));
+ IExec->DropInterface(reinterpret_cast<Interface*>(IIntuition));
+ IExec->DropInterface(reinterpret_cast<Interface*>(IGraphics));
+ IExec->DropInterface(reinterpret_cast<Interface*>(IDataTypes));
+
+ IExec->CloseLibrary(P96Base);
+ IExec->CloseLibrary(KeymapBase);
+ IExec->CloseLibrary(IntuitionBase);
+ IExec->CloseLibrary(GraphicsBase);
+ IExec->CloseLibrary(DataTypesBase);
+}
+
+//----------------------------------------------------------------------------
+int main(int argc, char* argv[])
+{
+ if ( !open_libs() ) {
+ IDOS->Printf("Can't open libraries.\n");
+ return -1;
+ }
+
+ ClassLibrary* requester =
+ IIntuition->OpenClass("requester.class", 51, &RequesterClass);
+ ClassLibrary* window =
+ IIntuition->OpenClass("window.class", 51, &WindowClass);
+ if ( requester == 0 || window == 0 )
+ {
+ IDOS->Printf("Can't open classes.\n");
+ IIntuition->CloseClass(requester);
+ IIntuition->CloseClass(window);
+ close_libs();
+ return -1;
+ }
+
+ int rc = agg_main(argc, argv);
+
+ IIntuition->CloseClass(window);
+ IIntuition->CloseClass(requester);
+ close_libs();
+
+ return rc;
+}
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp
new file mode 100644
index 0000000000..078e141ccb
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp
@@ -0,0 +1,990 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: superstippi@gmx.de
+//----------------------------------------------------------------------------
+//
+// class platform_support
+//
+//----------------------------------------------------------------------------
+
+#include <new>
+#include <stdio.h>
+
+#include <Alert.h>
+#include <Application.h>
+#include <Bitmap.h>
+#include <Message.h>
+#include <MessageRunner.h>
+#include <Messenger.h>
+#include <Path.h>
+#include <Roster.h>
+#include <TranslationUtils.h>
+#include <View.h>
+#include <Window.h>
+
+#include <string.h>
+#include "platform/agg_platform_support.h"
+#include "util/agg_color_conv_rgb8.h"
+
+using std::nothrow;
+
+
+static void
+attach_buffer_to_BBitmap(agg::rendering_buffer& buffer, BBitmap* bitmap, bool flipY)
+{
+ uint8* bits = (uint8*)bitmap->Bits();
+ uint32 width = bitmap->Bounds().IntegerWidth() + 1;
+ uint32 height = bitmap->Bounds().IntegerHeight() + 1;
+ int32 bpr = bitmap->BytesPerRow();
+ if (flipY) {
+// XXX: why don't I have to do this?!?
+// bits += bpr * (height - 1);
+ bpr = -bpr;
+ }
+ buffer.attach(bits, width, height, bpr);
+}
+
+
+static color_space
+pix_format_to_color_space(agg::pix_format_e format)
+{
+ color_space bitmapFormat = B_NO_COLOR_SPACE;
+ switch (format) {
+ case agg::pix_format_rgb555:
+
+ bitmapFormat = B_RGB15;
+ break;
+
+ case agg::pix_format_rgb565:
+
+ bitmapFormat = B_RGB16;
+ break;
+
+ case agg::pix_format_rgb24:
+ case agg::pix_format_bgr24:
+
+ bitmapFormat = B_RGB24;
+ break;
+
+ case agg::pix_format_rgba32:
+ case agg::pix_format_argb32:
+ case agg::pix_format_abgr32:
+ case agg::pix_format_bgra32:
+
+ bitmapFormat = B_RGBA32;
+ break;
+ }
+ return bitmapFormat;
+}
+
+
+// #pragma mark -
+
+
+class AGGView : public BView {
+ public:
+ AGGView(BRect frame, agg::platform_support* agg,
+ agg::pix_format_e format, bool flipY);
+ virtual ~AGGView();
+
+ virtual void AttachedToWindow();
+ virtual void DetachedFromWindow();
+
+ virtual void MessageReceived(BMessage* message);
+ virtual void Draw(BRect updateRect);
+ virtual void FrameResized(float width, float height);
+
+ virtual void KeyDown(const char* bytes, int32 numBytes);
+
+ virtual void MouseDown(BPoint where);
+ virtual void MouseMoved(BPoint where, uint32 transit,
+ const BMessage* dragMesage);
+ virtual void MouseUp(BPoint where);
+
+ BBitmap* Bitmap() const;
+
+ uint8 LastKeyDown() const;
+ uint32 MouseButtons();
+
+ void Update();
+ void ForceRedraw();
+
+ unsigned GetKeyFlags();
+
+ private:
+ BBitmap* fBitmap;
+ agg::pix_format_e fFormat;
+ bool fFlipY;
+
+ agg::platform_support* fAGG;
+
+ uint32 fMouseButtons;
+ int32 fMouseX;
+ int32 fMouseY;
+
+ uint8 fLastKeyDown;
+
+ bool fRedraw;
+
+ BMessageRunner* fPulse;
+ bigtime_t fLastPulse;
+ bool fEnableTicks;
+};
+
+AGGView::AGGView(BRect frame,
+ agg::platform_support* agg,
+ agg::pix_format_e format,
+ bool flipY)
+ : BView(frame, "AGG View", B_FOLLOW_ALL,
+ B_FRAME_EVENTS | B_WILL_DRAW),
+ fFormat(format),
+ fFlipY(flipY),
+
+ fAGG(agg),
+
+ fMouseButtons(0),
+ fMouseX(-1),
+ fMouseY(-1),
+
+ fLastKeyDown(0),
+
+ fRedraw(true),
+
+ fPulse(NULL),
+ fLastPulse(0),
+ fEnableTicks(true)
+{
+ SetViewColor(B_TRANSPARENT_32_BIT);
+
+ frame.OffsetTo(0.0, 0.0);
+ fBitmap = new BBitmap(frame, 0, pix_format_to_color_space(fFormat));
+ if (fBitmap->IsValid()) {
+ attach_buffer_to_BBitmap(fAGG->rbuf_window(), fBitmap, fFlipY);
+ } else {
+ delete fBitmap;
+ fBitmap = NULL;
+ }
+}
+
+
+AGGView::~AGGView()
+{
+ delete fBitmap;
+ delete fPulse;
+}
+
+
+void
+AGGView::AttachedToWindow()
+{
+ BMessage message('tick');
+ BMessenger target(this, Looper());
+ delete fPulse;
+// BScreen screen;
+// TODO: calc screen retrace
+ fPulse = new BMessageRunner(target, &message, 40000);
+
+ // make sure we call this once
+ fAGG->on_resize(Bounds().IntegerWidth() + 1,
+ Bounds().IntegerHeight() + 1);
+ MakeFocus();
+}
+
+
+void
+AGGView::DetachedFromWindow()
+{
+ delete fPulse;
+ fPulse = NULL;
+}
+
+
+void
+AGGView::MessageReceived(BMessage* message)
+{
+ bigtime_t now = system_time();
+ switch (message->what) {
+ case 'tick':
+ // drop messages that have piled up
+ if (/*now - fLastPulse > 30000*/fEnableTicks) {
+ fLastPulse = now;
+ if (!fAGG->wait_mode())
+ fAGG->on_idle();
+ Window()->PostMessage('entk', this);
+ fEnableTicks = false;
+ } else {
+// printf("dropping tick message (%lld)\n", now - fLastPulse);
+ }
+ break;
+ case 'entk':
+ fEnableTicks = true;
+ if (now - fLastPulse > 30000) {
+ fLastPulse = now;
+ if (!fAGG->wait_mode())
+ fAGG->on_idle();
+ }
+ break;
+ default:
+ BView::MessageReceived(message);
+ break;
+ }
+}
+
+
+void
+AGGView::Draw(BRect updateRect)
+{
+ if (fBitmap) {
+ if (fRedraw) {
+ fAGG->on_draw();
+ fRedraw = false;
+ }
+ if (fFormat == agg::pix_format_bgra32) {
+ DrawBitmap(fBitmap, updateRect, updateRect);
+ } else {
+ BBitmap* bitmap = new BBitmap(fBitmap->Bounds(), 0, B_RGBA32);
+
+ agg::rendering_buffer rbufSrc;
+ attach_buffer_to_BBitmap(rbufSrc, fBitmap, false);
+
+ agg::rendering_buffer rbufDst;
+ attach_buffer_to_BBitmap(rbufDst, bitmap, false);
+
+ switch(fFormat) {
+ case agg::pix_format_rgb555:
+ agg::color_conv(&rbufDst, &rbufSrc,
+ agg::color_conv_rgb555_to_bgra32());
+ break;
+ case agg::pix_format_rgb565:
+ agg::color_conv(&rbufDst, &rbufSrc,
+ agg::color_conv_rgb565_to_bgra32());
+ break;
+ case agg::pix_format_rgb24:
+ agg::color_conv(&rbufDst, &rbufSrc,
+ agg::color_conv_rgb24_to_bgra32());
+ break;
+ case agg::pix_format_bgr24:
+ agg::color_conv(&rbufDst, &rbufSrc,
+ agg::color_conv_bgr24_to_bgra32());
+ break;
+ case agg::pix_format_rgba32:
+ agg::color_conv(&rbufDst, &rbufSrc,
+ agg::color_conv_rgba32_to_bgra32());
+ break;
+ case agg::pix_format_argb32:
+ agg::color_conv(&rbufDst, &rbufSrc,
+ agg::color_conv_argb32_to_bgra32());
+ break;
+ case agg::pix_format_abgr32:
+ agg::color_conv(&rbufDst, &rbufSrc,
+ agg::color_conv_abgr32_to_bgra32());
+ break;
+ case agg::pix_format_bgra32:
+ agg::color_conv(&rbufDst, &rbufSrc,
+ agg::color_conv_bgra32_to_bgra32());
+ break;
+ }
+ DrawBitmap(bitmap, updateRect, updateRect);
+ delete bitmap;
+ }
+ } else {
+ FillRect(updateRect);
+ }
+}
+
+
+void
+AGGView::FrameResized(float width, float height)
+{
+ BRect r(0.0, 0.0, width, height);
+ BBitmap* bitmap = new BBitmap(r, 0, pix_format_to_color_space(fFormat));
+ if (bitmap->IsValid()) {
+ delete fBitmap;
+ fBitmap = bitmap;
+ attach_buffer_to_BBitmap(fAGG->rbuf_window(), fBitmap, fFlipY);
+
+ fAGG->trans_affine_resizing((int)width + 1,
+ (int)height + 1);
+
+ // pass the event on to AGG
+ fAGG->on_resize((int)width + 1, (int)height + 1);
+
+ fRedraw = true;
+ Invalidate();
+ } else
+ delete bitmap;
+}
+
+
+void
+AGGView::KeyDown(const char* bytes, int32 numBytes)
+{
+ if (bytes && numBytes > 0) {
+ fLastKeyDown = bytes[0];
+
+ bool left = false;
+ bool up = false;
+ bool right = false;
+ bool down = false;
+
+ switch (fLastKeyDown) {
+
+ case B_LEFT_ARROW:
+ left = true;
+ break;
+
+ case B_UP_ARROW:
+ up = true;
+ break;
+
+ case B_RIGHT_ARROW:
+ right = true;
+ break;
+
+ case B_DOWN_ARROW:
+ down = true;
+ break;
+ }
+
+/* case key_f2:
+fAGG->copy_window_to_img(agg::platform_support::max_images - 1);
+fAGG->save_img(agg::platform_support::max_images - 1, "screenshot");
+break;
+}*/
+
+
+ if (fAGG->m_ctrls.on_arrow_keys(left, right, down, up)) {
+ fAGG->on_ctrl_change();
+ fAGG->force_redraw();
+ } else {
+ fAGG->on_key(fMouseX, fMouseY, fLastKeyDown, GetKeyFlags());
+ }
+// fAGG->on_key(fMouseX, fMouseY, fLastKeyDown, GetKeyFlags());
+
+ }
+}
+
+
+void
+AGGView::MouseDown(BPoint where)
+{
+ BMessage* currentMessage = Window()->CurrentMessage();
+ if (currentMessage) {
+ if (currentMessage->FindInt32("buttons", (int32*)&fMouseButtons) < B_OK)
+ fMouseButtons = B_PRIMARY_MOUSE_BUTTON;
+ } else
+ fMouseButtons = B_PRIMARY_MOUSE_BUTTON;
+
+ fMouseX = (int)where.x;
+ fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y;
+
+ // pass the event on to AGG
+ if (fMouseButtons == B_PRIMARY_MOUSE_BUTTON) {
+ // left mouse button -> see if to handle in controls
+ fAGG->m_ctrls.set_cur(fMouseX, fMouseY);
+ if (fAGG->m_ctrls.on_mouse_button_down(fMouseX, fMouseY)) {
+ fAGG->on_ctrl_change();
+ fAGG->force_redraw();
+ } else {
+ if (fAGG->m_ctrls.in_rect(fMouseX, fMouseY)) {
+ if (fAGG->m_ctrls.set_cur(fMouseX, fMouseY)) {
+ fAGG->on_ctrl_change();
+ fAGG->force_redraw();
+ }
+ } else {
+ fAGG->on_mouse_button_down(fMouseX, fMouseY, GetKeyFlags());
+ }
+ }
+ } else if (fMouseButtons & B_SECONDARY_MOUSE_BUTTON) {
+ // right mouse button -> simple
+ fAGG->on_mouse_button_down(fMouseX, fMouseY, GetKeyFlags());
+ }
+ SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
+}
+
+
+void
+AGGView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMesage)
+{
+ // workarround missed mouse up events
+ // (if we react too slowly, app_server might have dropped events)
+ BMessage* currentMessage = Window()->CurrentMessage();
+ int32 buttons = 0;
+ if (currentMessage->FindInt32("buttons", &buttons) < B_OK) {
+ buttons = 0;
+ }
+ if (!buttons)
+ MouseUp(where);
+
+ fMouseX = (int)where.x;
+ fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y;
+
+ // pass the event on to AGG
+ if (fAGG->m_ctrls.on_mouse_move(fMouseX, fMouseY,
+ (GetKeyFlags() & agg::mouse_left) != 0)) {
+ fAGG->on_ctrl_change();
+ fAGG->force_redraw();
+ } else {
+ if (!fAGG->m_ctrls.in_rect(fMouseX, fMouseY)) {
+ fAGG->on_mouse_move(fMouseX, fMouseY, GetKeyFlags());
+ }
+ }
+}
+
+
+void
+AGGView::MouseUp(BPoint where)
+{
+ fMouseX = (int)where.x;
+ fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y;
+
+ // pass the event on to AGG
+ if (fMouseButtons == B_PRIMARY_MOUSE_BUTTON) {
+ fMouseButtons = 0;
+
+ if (fAGG->m_ctrls.on_mouse_button_up(fMouseX, fMouseY)) {
+ fAGG->on_ctrl_change();
+ fAGG->force_redraw();
+ }
+ fAGG->on_mouse_button_up(fMouseX, fMouseY, GetKeyFlags());
+ } else if (fMouseButtons == B_SECONDARY_MOUSE_BUTTON) {
+ fMouseButtons = 0;
+
+ fAGG->on_mouse_button_up(fMouseX, fMouseY, GetKeyFlags());
+ }
+}
+
+
+BBitmap*
+AGGView::Bitmap() const
+{
+ return fBitmap;
+}
+
+
+uint8
+AGGView::LastKeyDown() const
+{
+ return fLastKeyDown;
+}
+
+
+uint32
+AGGView::MouseButtons()
+{
+ uint32 buttons = 0;
+ if (LockLooper()) {
+ buttons = fMouseButtons;
+ UnlockLooper();
+ }
+ return buttons;
+}
+
+
+void
+AGGView::Update()
+{
+ // trigger display update
+ if (LockLooper()) {
+ Invalidate();
+ UnlockLooper();
+ }
+}
+
+
+void
+AGGView::ForceRedraw()
+{
+ // force a redraw (fRedraw = true;)
+ // and trigger display update
+ if (LockLooper()) {
+ fRedraw = true;
+ Invalidate();
+ UnlockLooper();
+ }
+}
+
+
+unsigned
+AGGView::GetKeyFlags()
+{
+ uint32 buttons = fMouseButtons;
+ uint32 mods = modifiers();
+ unsigned flags = 0;
+ if (buttons & B_PRIMARY_MOUSE_BUTTON) flags |= agg::mouse_left;
+ if (buttons & B_SECONDARY_MOUSE_BUTTON) flags |= agg::mouse_right;
+ if (mods & B_SHIFT_KEY) flags |= agg::kbd_shift;
+ if (mods & B_COMMAND_KEY) flags |= agg::kbd_ctrl;
+ return flags;
+}
+
+// #pragma mark -
+
+
+class AGGWindow : public BWindow {
+ public:
+ AGGWindow()
+ : BWindow(BRect(-50.0, -50.0, -10.0, -10.0),
+ "AGG Application", B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS)
+ {
+ }
+
+ virtual bool QuitRequested()
+ {
+ be_app->PostMessage(B_QUIT_REQUESTED);
+ return true;
+ }
+
+ bool Init(BRect frame, agg::platform_support* agg, agg::pix_format_e format,
+ bool flipY, uint32 flags)
+ {
+ MoveTo(frame.LeftTop());
+ ResizeTo(frame.Width(), frame.Height());
+
+ SetFlags(flags);
+
+ frame.OffsetTo(0.0, 0.0);
+ fView = new AGGView(frame, agg, format, flipY);
+ AddChild(fView);
+
+ return fView->Bitmap() != NULL;
+ }
+
+
+ AGGView* View() const
+ {
+ return fView;
+ }
+ private:
+ AGGView* fView;
+};
+
+// #pragma mark -
+
+
+class AGGApplication : public BApplication {
+ public:
+ AGGApplication()
+ : BApplication("application/x-vnd.AGG-AGG")
+ {
+ fWindow = new AGGWindow();
+ }
+
+ virtual void ReadyToRun()
+ {
+ if (fWindow) {
+ fWindow->Show();
+ }
+ }
+
+ virtual bool Init(agg::platform_support* agg, int width, int height,
+ agg::pix_format_e format, bool flipY, uint32 flags)
+ {
+ BRect r(50.0, 50.0,
+ 50.0 + width - 1.0,
+ 50.0 + height - 1.0);
+ uint32 windowFlags = B_ASYNCHRONOUS_CONTROLS;
+ if (!(flags & agg::window_resize))
+ windowFlags |= B_NOT_RESIZABLE;
+
+ return fWindow->Init(r, agg, format, flipY, windowFlags);;
+ }
+
+
+ AGGWindow* Window() const
+ {
+ return fWindow;
+ }
+
+ private:
+ AGGWindow* fWindow;
+};
+
+
+// #pragma mark -
+
+
+namespace agg
+{
+
+class platform_specific {
+ public:
+ platform_specific(agg::platform_support* agg,
+ agg::pix_format_e format, bool flip_y)
+ : fAGG(agg),
+ fApp(NULL),
+ fFormat(format),
+ fFlipY(flip_y),
+ fTimerStart(system_time())
+ {
+ memset(fImages, 0, sizeof(fImages));
+ fApp = new AGGApplication();
+ fAppPath[0] = 0;
+ // figure out where we're running from
+ app_info info;
+ status_t ret = fApp->GetAppInfo(&info);
+ if (ret >= B_OK) {
+ BPath path(&info.ref);
+ ret = path.InitCheck();
+ if (ret >= B_OK) {
+ ret = path.GetParent(&path);
+ if (ret >= B_OK) {
+ sprintf(fAppPath, "%s", path.Path());
+ } else {
+ fprintf(stderr, "getting app parent folder failed: %s\n", strerror(ret));
+ }
+ } else {
+ fprintf(stderr, "making app path failed: %s\n", strerror(ret));
+ }
+ } else {
+ fprintf(stderr, "GetAppInfo() failed: %s\n", strerror(ret));
+ }
+ }
+ ~platform_specific()
+ {
+ for (int32 i = 0; i < agg::platform_support::max_images; i++)
+ delete fImages[i];
+ delete fApp;
+ }
+
+ bool Init(int width, int height, unsigned flags)
+ {
+ return fApp->Init(fAGG, width, height, fFormat, fFlipY, flags);
+ }
+
+ int Run()
+ {
+ status_t ret = B_NO_INIT;
+ if (fApp) {
+ fApp->Run();
+ ret = B_OK;
+ }
+ return ret;
+ }
+
+ void SetTitle(const char* title)
+ {
+ if (fApp && fApp->Window() && fApp->Window()->Lock()) {
+ fApp->Window()->SetTitle(title);
+ fApp->Window()->Unlock();
+ }
+ }
+ void StartTimer()
+ {
+ fTimerStart = system_time();
+ }
+ double ElapsedTime() const
+ {
+ return (system_time() - fTimerStart) / 1000.0;
+ }
+
+ void ForceRedraw()
+ {
+ fApp->Window()->View()->ForceRedraw();
+ }
+ void UpdateWindow()
+ {
+ fApp->Window()->View()->Update();
+ }
+
+
+ agg::platform_support* fAGG;
+ AGGApplication* fApp;
+ agg::pix_format_e fFormat;
+ bool fFlipY;
+ bigtime_t fTimerStart;
+ BBitmap* fImages[agg::platform_support::max_images];
+
+ char fAppPath[B_PATH_NAME_LENGTH];
+ char fFilePath[B_PATH_NAME_LENGTH];
+};
+
+
+ //------------------------------------------------------------------------
+ platform_support::platform_support(pix_format_e format, bool flip_y) :
+ m_specific(new platform_specific(this, format, flip_y)),
+ m_format(format),
+ m_bpp(32/*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, "Anti-Grain Geometry Application");
+ }
+
+
+ //------------------------------------------------------------------------
+ platform_support::~platform_support()
+ {
+ delete m_specific;
+ }
+
+ //------------------------------------------------------------------------
+ void platform_support::caption(const char* cap)
+ {
+ strcpy(m_caption, cap);
+ m_specific->SetTitle(cap);
+ }
+
+ //------------------------------------------------------------------------
+ void platform_support::start_timer()
+ {
+ m_specific->StartTimer();
+ }
+
+ //------------------------------------------------------------------------
+ double platform_support::elapsed_time() const
+ {
+ return m_specific->ElapsedTime();
+ }
+
+ //------------------------------------------------------------------------
+ void* platform_support::raw_display_handler()
+ {
+ // TODO: if we ever support BDirectWindow here, that would
+ // be the frame buffer pointer with offset to the window top left
+ return NULL;
+ }
+
+ //------------------------------------------------------------------------
+ void platform_support::message(const char* msg)
+ {
+ BAlert* alert = new BAlert("AGG Message", msg, "Ok");
+ alert->Go(/*NULL*/);
+ }
+
+
+ //------------------------------------------------------------------------
+ bool platform_support::init(unsigned width, unsigned height, unsigned flags)
+ {
+ m_initial_width = width;
+ m_initial_height = height;
+ m_window_flags = flags;
+
+ if (m_specific->Init(width, height, flags)) {
+ on_init();
+ return true;
+ }
+
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ int platform_support::run()
+ {
+ return m_specific->Run();
+ }
+
+
+ //------------------------------------------------------------------------
+ const char* platform_support::img_ext() const { return ".ppm"; }
+
+
+ const char* platform_support::full_file_name(const char* file_name)
+ {
+ sprintf(m_specific->fFilePath, "%s/%s", m_specific->fAppPath, file_name);
+ return m_specific->fFilePath;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool platform_support::load_img(unsigned idx, const char* file)
+ {
+ if (idx < max_images)
+ {
+ char path[B_PATH_NAME_LENGTH];
+ sprintf(path, "%s/%s%s", m_specific->fAppPath, file, img_ext());
+ BBitmap* transBitmap = BTranslationUtils::GetBitmap(path);
+ if (transBitmap && transBitmap->IsValid()) {
+ if(transBitmap->ColorSpace() != B_RGB32 && transBitmap->ColorSpace() != B_RGBA32) {
+ // ups we got a smart ass Translator making our live harder
+ delete transBitmap;
+ return false;
+ }
+
+ color_space format = B_RGB24;
+
+ switch (m_format) {
+ case pix_format_gray8:
+ format = B_GRAY8;
+ break;
+ case pix_format_rgb555:
+ format = B_RGB15;
+ break;
+ case pix_format_rgb565:
+ format = B_RGB16;
+ break;
+ case pix_format_rgb24:
+ format = B_RGB24_BIG;
+ break;
+ case pix_format_bgr24:
+ format = B_RGB24;
+ break;
+ case pix_format_abgr32:
+ case pix_format_argb32:
+ case pix_format_bgra32:
+ format = B_RGB32;
+ break;
+ case pix_format_rgba32:
+ format = B_RGB32_BIG;
+ break;
+ }
+ BBitmap* bitmap = new (nothrow) BBitmap(transBitmap->Bounds(), 0, format);
+ if (!bitmap || !bitmap->IsValid()) {
+ fprintf(stderr, "failed to allocate temporary bitmap!\n");
+ delete transBitmap;
+ delete bitmap;
+ return false;
+ }
+
+ delete m_specific->fImages[idx];
+
+ rendering_buffer rbuf_tmp;
+ attach_buffer_to_BBitmap(rbuf_tmp, transBitmap, m_flip_y);
+
+ m_specific->fImages[idx] = bitmap;
+
+ attach_buffer_to_BBitmap(m_rbuf_img[idx], bitmap, m_flip_y);
+
+ rendering_buffer* dst = &m_rbuf_img[idx];
+
+ switch(m_format)
+ {
+ case pix_format_gray8:
+ return false;
+// color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray8()); break;
+ break;
+
+ case pix_format_rgb555:
+ color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb555()); break;
+ break;
+
+ case pix_format_rgb565:
+ color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb565()); break;
+ break;
+
+ case pix_format_rgb24:
+ color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb24()); break;
+ break;
+
+ case pix_format_bgr24:
+ color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgr24()); break;
+ break;
+
+ case pix_format_abgr32:
+ color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_abgr32()); break;
+ break;
+
+ case pix_format_argb32:
+ color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_argb32()); break;
+ break;
+
+ case pix_format_bgra32:
+ color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgra32()); break;
+ break;
+
+ case pix_format_rgba32:
+ color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgba32()); break;
+ break;
+ }
+ delete transBitmap;
+
+ return true;
+
+ } else {
+ fprintf(stderr, "failed to load bitmap: '%s'\n", full_file_name(file));
+ }
+ }
+ return false;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool platform_support::save_img(unsigned idx, const char* file)
+ {
+ // TODO: implement using BTranslatorRoster and friends
+ return false;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool platform_support::create_img(unsigned idx, unsigned width, unsigned height)
+ {
+ if(idx < max_images)
+ {
+ if(width == 0) width = m_specific->fApp->Window()->View()->Bitmap()->Bounds().IntegerWidth() + 1;
+ if(height == 0) height = m_specific->fApp->Window()->View()->Bitmap()->Bounds().IntegerHeight() + 1;
+ BBitmap* bitmap = new BBitmap(BRect(0.0, 0.0, width - 1, height - 1), 0, B_RGBA32);;
+ if (bitmap && bitmap->IsValid()) {
+ delete m_specific->fImages[idx];
+ m_specific->fImages[idx] = bitmap;
+ attach_buffer_to_BBitmap(m_rbuf_img[idx], bitmap, m_flip_y);
+ return true;
+ } else {
+ delete bitmap;
+ }
+ }
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ void platform_support::force_redraw()
+ {
+ m_specific->ForceRedraw();
+ }
+
+
+
+ //------------------------------------------------------------------------
+ void platform_support::update_window()
+ {
+ m_specific->UpdateWindow();
+ }
+
+
+ //------------------------------------------------------------------------
+ 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) {}
+}
+
+
+
+
+
+
+//----------------------------------------------------------------------------
+int agg_main(int argc, char* argv[]);
+
+
+
+int
+main(int argc, char* argv[])
+{
+ return agg_main(argc, argv);
+}
+
+
+
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp
new file mode 100644
index 0000000000..46b874d738
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp
@@ -0,0 +1,1601 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// class platform_support. X11 version.
+//
+//----------------------------------------------------------------------------
+
+#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 "agg_basics.h"
+#include "agg_pixfmt_gray.h"
+#include "agg_pixfmt_rgb.h"
+#include "agg_pixfmt_rgba.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_wait_mode;
+ clock_t m_sw_start;
+ };
+
+
+
+ //------------------------------------------------------------------------
+ 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_wait_mode(true)
+ {
+ 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:
+ case pix_format_sgray8:
+ m_bpp = 8;
+ break;
+
+ case pix_format_gray16:
+ m_bpp = 16;
+ break;
+
+ case pix_format_gray32:
+ m_bpp = 32;
+ break;
+
+ case pix_format_rgb565:
+ case pix_format_rgb555:
+ m_bpp = 16;
+ break;
+
+ case pix_format_rgb24:
+ case pix_format_bgr24:
+ case pix_format_srgb24:
+ case pix_format_sbgr24:
+ m_bpp = 24;
+ break;
+
+ case pix_format_bgra32:
+ case pix_format_abgr32:
+ case pix_format_argb32:
+ case pix_format_rgba32:
+ case pix_format_sbgra32:
+ case pix_format_sabgr32:
+ case pix_format_sargb32:
+ case pix_format_srgba32:
+ m_bpp = 32;
+ break;
+
+ case pix_format_rgb48:
+ case pix_format_bgr48:
+ m_bpp = 48;
+ break;
+
+ case pix_format_bgra64:
+ case pix_format_abgr64:
+ case pix_format_argb64:
+ case pix_format_rgba64:
+ m_bpp = 64;
+ break;
+
+ case pix_format_rgb96:
+ case pix_format_bgr96:
+ m_bpp = 96;
+ break;
+
+ case pix_format_bgra128:
+ case pix_format_abgr128:
+ case pix_format_argb128:
+ case pix_format_rgba128:
+ m_bpp = 128;
+ break;
+ }
+ m_sw_start = clock();
+ }
+
+ //------------------------------------------------------------------------
+ platform_specific::~platform_specific()
+ {
+ }
+
+ //------------------------------------------------------------------------
+ void platform_specific::caption(const char* capt)
+ {
+ XTextProperty tp;
+ tp.value = (unsigned char *)capt;
+ tp.encoding = XA_WM_NAME;
+ tp.format = 8;
+ tp.nitems = strlen(capt);
+ XSetWMName(m_display, m_window, &tp);
+ XStoreName(m_display, m_window, capt);
+ XSetIconName(m_display, m_window, capt);
+ XSetWMIconName(m_display, m_window, &tp);
+ }
+
+
+ //------------------------------------------------------------------------
+ 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_sgray8: convert<pixfmt_srgba32, pixfmt_sgray8>(&rbuf_tmp, src); break;
+ case pix_format_gray8: convert<pixfmt_srgba32, pixfmt_gray8>(&rbuf_tmp, src); break;
+ case pix_format_gray16: convert<pixfmt_srgba32, pixfmt_gray16>(&rbuf_tmp, src); break;
+ case pix_format_gray32: convert<pixfmt_srgba32, pixfmt_gray32>(&rbuf_tmp, src); 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_srgb24: convert<pixfmt_srgba32, pixfmt_srgb24>(&rbuf_tmp, src); break;
+ case pix_format_sbgr24: convert<pixfmt_srgba32, pixfmt_sbgr24>(&rbuf_tmp, src); break;
+ case pix_format_rgb24: convert<pixfmt_srgba32, pixfmt_rgb24>(&rbuf_tmp, src); break;
+ case pix_format_bgr24: convert<pixfmt_srgba32, pixfmt_bgr24>(&rbuf_tmp, src); break;
+ case pix_format_srgba32: convert<pixfmt_srgba32, pixfmt_srgba32>(&rbuf_tmp, src); break;
+ case pix_format_sargb32: convert<pixfmt_srgba32, pixfmt_sargb32>(&rbuf_tmp, src); break;
+ case pix_format_sabgr32: convert<pixfmt_srgba32, pixfmt_sabgr32>(&rbuf_tmp, src); break;
+ case pix_format_sbgra32: convert<pixfmt_srgba32, pixfmt_sbgra32>(&rbuf_tmp, src); break;
+ case pix_format_rgba32: convert<pixfmt_srgba32, pixfmt_rgba32>(&rbuf_tmp, src); break;
+ case pix_format_argb32: convert<pixfmt_srgba32, pixfmt_argb32>(&rbuf_tmp, src); break;
+ case pix_format_abgr32: convert<pixfmt_srgba32, pixfmt_abgr32>(&rbuf_tmp, src); break;
+ case pix_format_bgra32: convert<pixfmt_srgba32, pixfmt_bgra32>(&rbuf_tmp, src); break;
+ case pix_format_rgb48: convert<pixfmt_srgba32, pixfmt_rgb48>(&rbuf_tmp, src); break;
+ case pix_format_bgr48: convert<pixfmt_srgba32, pixfmt_bgr48>(&rbuf_tmp, src); break;
+ case pix_format_rgba64: convert<pixfmt_srgba32, pixfmt_rgba64>(&rbuf_tmp, src); break;
+ case pix_format_argb64: convert<pixfmt_srgba32, pixfmt_argb64>(&rbuf_tmp, src); break;
+ case pix_format_abgr64: convert<pixfmt_srgba32, pixfmt_abgr64>(&rbuf_tmp, src); break;
+ case pix_format_bgra64: convert<pixfmt_srgba32, pixfmt_bgra64>(&rbuf_tmp, src); break;
+ case pix_format_rgb96: convert<pixfmt_srgba32, pixfmt_rgb96>(&rbuf_tmp, src); break;
+ case pix_format_bgr96: convert<pixfmt_srgba32, pixfmt_bgr96>(&rbuf_tmp, src); break;
+ case pix_format_rgba128: convert<pixfmt_srgba32, pixfmt_rgba128>(&rbuf_tmp, src); break;
+ case pix_format_argb128: convert<pixfmt_srgba32, pixfmt_argb128>(&rbuf_tmp, src); break;
+ case pix_format_abgr128: convert<pixfmt_srgba32, pixfmt_abgr128>(&rbuf_tmp, src); break;
+ case pix_format_bgra128: convert<pixfmt_srgba32, pixfmt_bgra128>(&rbuf_tmp, src); break;
+ }
+ break;
+
+ case pix_format_abgr32:
+ switch(m_format)
+ {
+ default: break;
+ case pix_format_sgray8: convert<pixfmt_sabgr32, pixfmt_sgray8>(&rbuf_tmp, src); break;
+ case pix_format_gray8: convert<pixfmt_sabgr32, pixfmt_gray8>(&rbuf_tmp, src); break;
+ case pix_format_gray16: convert<pixfmt_sabgr32, pixfmt_gray16>(&rbuf_tmp, src); break;
+ case pix_format_gray32: convert<pixfmt_sabgr32, pixfmt_gray32>(&rbuf_tmp, src); 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_srgb24: convert<pixfmt_sabgr32, pixfmt_srgb24>(&rbuf_tmp, src); break;
+ case pix_format_sbgr24: convert<pixfmt_sabgr32, pixfmt_sbgr24>(&rbuf_tmp, src); break;
+ case pix_format_rgb24: convert<pixfmt_sabgr32, pixfmt_rgb24>(&rbuf_tmp, src); break;
+ case pix_format_bgr24: convert<pixfmt_sabgr32, pixfmt_bgr24>(&rbuf_tmp, src); break;
+ case pix_format_srgba32: convert<pixfmt_sabgr32, pixfmt_srgba32>(&rbuf_tmp, src); break;
+ case pix_format_sargb32: convert<pixfmt_sabgr32, pixfmt_sargb32>(&rbuf_tmp, src); break;
+ case pix_format_sabgr32: convert<pixfmt_sabgr32, pixfmt_sabgr32>(&rbuf_tmp, src); break;
+ case pix_format_sbgra32: convert<pixfmt_sabgr32, pixfmt_sbgra32>(&rbuf_tmp, src); break;
+ case pix_format_rgba32: convert<pixfmt_sabgr32, pixfmt_rgba32>(&rbuf_tmp, src); break;
+ case pix_format_argb32: convert<pixfmt_sabgr32, pixfmt_argb32>(&rbuf_tmp, src); break;
+ case pix_format_abgr32: convert<pixfmt_sabgr32, pixfmt_abgr32>(&rbuf_tmp, src); break;
+ case pix_format_bgra32: convert<pixfmt_sabgr32, pixfmt_bgra32>(&rbuf_tmp, src); break;
+ case pix_format_rgb48: convert<pixfmt_sabgr32, pixfmt_rgb48>(&rbuf_tmp, src); break;
+ case pix_format_bgr48: convert<pixfmt_sabgr32, pixfmt_bgr48>(&rbuf_tmp, src); break;
+ case pix_format_rgba64: convert<pixfmt_sabgr32, pixfmt_rgba64>(&rbuf_tmp, src); break;
+ case pix_format_argb64: convert<pixfmt_sabgr32, pixfmt_argb64>(&rbuf_tmp, src); break;
+ case pix_format_abgr64: convert<pixfmt_sabgr32, pixfmt_abgr64>(&rbuf_tmp, src); break;
+ case pix_format_bgra64: convert<pixfmt_sabgr32, pixfmt_bgra64>(&rbuf_tmp, src); break;
+ case pix_format_rgb96: convert<pixfmt_sabgr32, pixfmt_rgb96>(&rbuf_tmp, src); break;
+ case pix_format_bgr96: convert<pixfmt_sabgr32, pixfmt_bgr96>(&rbuf_tmp, src); break;
+ case pix_format_rgba128: convert<pixfmt_sabgr32, pixfmt_rgba128>(&rbuf_tmp, src); break;
+ case pix_format_argb128: convert<pixfmt_sabgr32, pixfmt_argb128>(&rbuf_tmp, src); break;
+ case pix_format_abgr128: convert<pixfmt_sabgr32, pixfmt_abgr128>(&rbuf_tmp, src); break;
+ case pix_format_bgra128: convert<pixfmt_sabgr32, pixfmt_bgra128>(&rbuf_tmp, src); break;
+ }
+ break;
+
+ case pix_format_argb32:
+ switch(m_format)
+ {
+ default: break;
+ case pix_format_sgray8: convert<pixfmt_sargb32, pixfmt_sgray8>(&rbuf_tmp, src); break;
+ case pix_format_gray8: convert<pixfmt_sargb32, pixfmt_gray8>(&rbuf_tmp, src); break;
+ case pix_format_gray16: convert<pixfmt_sargb32, pixfmt_gray16>(&rbuf_tmp, src); break;
+ case pix_format_gray32: convert<pixfmt_sargb32, pixfmt_gray32>(&rbuf_tmp, src); 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_srgb24: convert<pixfmt_sargb32, pixfmt_srgb24>(&rbuf_tmp, src); break;
+ case pix_format_sbgr24: convert<pixfmt_sargb32, pixfmt_sbgr24>(&rbuf_tmp, src); break;
+ case pix_format_rgb24: convert<pixfmt_sargb32, pixfmt_rgb24>(&rbuf_tmp, src); break;
+ case pix_format_bgr24: convert<pixfmt_sargb32, pixfmt_bgr24>(&rbuf_tmp, src); break;
+ case pix_format_srgba32: convert<pixfmt_sargb32, pixfmt_srgba32>(&rbuf_tmp, src); break;
+ case pix_format_sargb32: convert<pixfmt_sargb32, pixfmt_sargb32>(&rbuf_tmp, src); break;
+ case pix_format_sabgr32: convert<pixfmt_sargb32, pixfmt_sabgr32>(&rbuf_tmp, src); break;
+ case pix_format_sbgra32: convert<pixfmt_sargb32, pixfmt_sbgra32>(&rbuf_tmp, src); break;
+ case pix_format_rgba32: convert<pixfmt_sargb32, pixfmt_rgba32>(&rbuf_tmp, src); break;
+ case pix_format_argb32: convert<pixfmt_sargb32, pixfmt_argb32>(&rbuf_tmp, src); break;
+ case pix_format_abgr32: convert<pixfmt_sargb32, pixfmt_abgr32>(&rbuf_tmp, src); break;
+ case pix_format_bgra32: convert<pixfmt_sargb32, pixfmt_bgra32>(&rbuf_tmp, src); break;
+ case pix_format_rgb48: convert<pixfmt_sargb32, pixfmt_rgb48>(&rbuf_tmp, src); break;
+ case pix_format_bgr48: convert<pixfmt_sargb32, pixfmt_bgr48>(&rbuf_tmp, src); break;
+ case pix_format_rgba64: convert<pixfmt_sargb32, pixfmt_rgba64>(&rbuf_tmp, src); break;
+ case pix_format_argb64: convert<pixfmt_sargb32, pixfmt_argb64>(&rbuf_tmp, src); break;
+ case pix_format_abgr64: convert<pixfmt_sargb32, pixfmt_abgr64>(&rbuf_tmp, src); break;
+ case pix_format_bgra64: convert<pixfmt_sargb32, pixfmt_bgra64>(&rbuf_tmp, src); break;
+ case pix_format_rgb96: convert<pixfmt_sargb32, pixfmt_rgb96>(&rbuf_tmp, src); break;
+ case pix_format_bgr96: convert<pixfmt_sargb32, pixfmt_bgr96>(&rbuf_tmp, src); break;
+ case pix_format_rgba128: convert<pixfmt_sargb32, pixfmt_rgba128>(&rbuf_tmp, src); break;
+ case pix_format_argb128: convert<pixfmt_sargb32, pixfmt_argb128>(&rbuf_tmp, src); break;
+ case pix_format_abgr128: convert<pixfmt_sargb32, pixfmt_abgr128>(&rbuf_tmp, src); break;
+ case pix_format_bgra128: convert<pixfmt_sargb32, pixfmt_bgra128>(&rbuf_tmp, src); break;
+ }
+ break;
+
+ case pix_format_bgra32:
+ switch(m_format)
+ {
+ default: break;
+ case pix_format_sgray8: convert<pixfmt_sbgra32, pixfmt_sgray8>(&rbuf_tmp, src); break;
+ case pix_format_gray8: convert<pixfmt_sbgra32, pixfmt_gray8>(&rbuf_tmp, src); break;
+ case pix_format_gray16: convert<pixfmt_sbgra32, pixfmt_gray16>(&rbuf_tmp, src); break;
+ case pix_format_gray32: convert<pixfmt_sbgra32, pixfmt_gray32>(&rbuf_tmp, src); 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_srgb24: convert<pixfmt_sbgra32, pixfmt_srgb24>(&rbuf_tmp, src); break;
+ case pix_format_sbgr24: convert<pixfmt_sbgra32, pixfmt_sbgr24>(&rbuf_tmp, src); break;
+ case pix_format_rgb24: convert<pixfmt_sbgra32, pixfmt_rgb24>(&rbuf_tmp, src); break;
+ case pix_format_bgr24: convert<pixfmt_sbgra32, pixfmt_bgr24>(&rbuf_tmp, src); break;
+ case pix_format_srgba32: convert<pixfmt_sbgra32, pixfmt_srgba32>(&rbuf_tmp, src); break;
+ case pix_format_sargb32: convert<pixfmt_sbgra32, pixfmt_sargb32>(&rbuf_tmp, src); break;
+ case pix_format_sabgr32: convert<pixfmt_sbgra32, pixfmt_sabgr32>(&rbuf_tmp, src); break;
+ case pix_format_sbgra32: convert<pixfmt_sbgra32, pixfmt_sbgra32>(&rbuf_tmp, src); break;
+ case pix_format_rgba32: convert<pixfmt_sbgra32, pixfmt_rgba32>(&rbuf_tmp, src); break;
+ case pix_format_argb32: convert<pixfmt_sbgra32, pixfmt_argb32>(&rbuf_tmp, src); break;
+ case pix_format_abgr32: convert<pixfmt_sbgra32, pixfmt_abgr32>(&rbuf_tmp, src); break;
+ case pix_format_bgra32: convert<pixfmt_sbgra32, pixfmt_bgra32>(&rbuf_tmp, src); break;
+ case pix_format_rgb48: convert<pixfmt_sbgra32, pixfmt_rgb48>(&rbuf_tmp, src); break;
+ case pix_format_bgr48: convert<pixfmt_sbgra32, pixfmt_bgr48>(&rbuf_tmp, src); break;
+ case pix_format_rgba64: convert<pixfmt_sbgra32, pixfmt_rgba64>(&rbuf_tmp, src); break;
+ case pix_format_argb64: convert<pixfmt_sbgra32, pixfmt_argb64>(&rbuf_tmp, src); break;
+ case pix_format_abgr64: convert<pixfmt_sbgra32, pixfmt_abgr64>(&rbuf_tmp, src); break;
+ case pix_format_bgra64: convert<pixfmt_sbgra32, pixfmt_bgra64>(&rbuf_tmp, src); break;
+ case pix_format_rgb96: convert<pixfmt_sbgra32, pixfmt_rgb96>(&rbuf_tmp, src); break;
+ case pix_format_bgr96: convert<pixfmt_sbgra32, pixfmt_bgr96>(&rbuf_tmp, src); break;
+ case pix_format_rgba128: convert<pixfmt_sbgra32, pixfmt_rgba128>(&rbuf_tmp, src); break;
+ case pix_format_argb128: convert<pixfmt_sbgra32, pixfmt_argb128>(&rbuf_tmp, src); break;
+ case pix_format_abgr128: convert<pixfmt_sbgra32, pixfmt_abgr128>(&rbuf_tmp, src); break;
+ case pix_format_bgra128: convert<pixfmt_sbgra32, pixfmt_bgra128>(&rbuf_tmp, src); 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;
+
+//printf("depth=%d, red=%08x, green=%08x, blue=%08x\n",
+// m_specific->m_depth,
+// m_specific->m_visual->red_mask,
+// m_specific->m_visual->green_mask,
+// m_specific->m_visual->blue_mask);
+
+
+// // NOT COMPLETED YET!
+// // Try to find an appropriate Visual if the default doesn't fit.
+// if(m_specific->m_depth < 15 ||
+// r_mask == 0 || g_mask == 0 || b_mask == 0)
+// {
+//
+// // This is an attempt to find an appropriate Visual if
+// // the default one doesn't match the minumum requirements
+// static int depth[] = { 32, 24, 16, 15 };
+// int i;
+// for(int i = 0; i < 4; i++)
+// {
+// XVisualInfo vi;
+// if(XMatchVisualInfo(m_specific->m_display,
+// m_specific->m_screen,
+// depth[i],
+// TrueColor,
+// &vi))
+// {
+// // printf("TrueColor depth=%d, red=%08x, green=%08x, blue=%08x, bits=%d\n",
+// // vi.depth,
+// // vi.visual->red_mask,
+// // vi.visual->green_mask,
+// // vi.visual->blue_mask,
+// // vi.bits_per_rgb);
+// m_specific->m_depth = vi.depth;
+// m_specific->m_visual = vi.visual;
+// r_mask = m_specific->m_visual->red_mask;
+// g_mask = m_specific->m_visual->green_mask;
+// b_mask = m_specific->m_visual->blue_mask;
+// break;
+// }
+// if(XMatchVisualInfo(m_specific->m_display,
+// m_specific->m_screen,
+// depth[i],
+// DirectColor,
+// &vi))
+// {
+// // printf("DirectColor depth=%d, red=%08x, green=%08x, blue=%08x, bits=%d\n",
+// // vi.depth,
+// // vi.visual->red_mask,
+// // vi.visual->green_mask,
+// // vi.visual->blue_mask,
+// // vi.bits_per_rgb);
+// m_specific->m_depth = vi.depth;
+// m_specific->m_visual = vi.visual;
+// r_mask = m_specific->m_visual->red_mask;
+// g_mask = m_specific->m_visual->green_mask;
+// b_mask = m_specific->m_visual->blue_mask;
+// break;
+// }
+// }
+// }
+
+ 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", r_mask, g_mask, 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()
+ {
+ 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)
+ {
+ 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;
+ XNextEvent(m_specific->m_display, &x_event);
+
+ // 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 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_sgray8:
+ convert<pixfmt_sgray8, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_gray8:
+ convert<pixfmt_gray8, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_gray16:
+ convert<pixfmt_gray16, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_gray32:
+ convert<pixfmt_gray32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ 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_sbgr24:
+ convert<pixfmt_sbgr24, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_rgb24:
+ convert<pixfmt_rgb24, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_bgr24:
+ convert<pixfmt_bgr24, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_srgba32:
+ convert<pixfmt_srgba32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_sargb32:
+ convert<pixfmt_sargb32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_sbgra32:
+ convert<pixfmt_sbgra32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_sabgr32:
+ convert<pixfmt_sabgr32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_rgba32:
+ convert<pixfmt_rgba32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_argb32:
+ convert<pixfmt_argb32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_bgra32:
+ convert<pixfmt_bgra32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_abgr32:
+ convert<pixfmt_abgr32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_rgb48:
+ convert<pixfmt_rgb48, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_bgr48:
+ convert<pixfmt_bgr48, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_rgba64:
+ convert<pixfmt_rgba64, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_argb64:
+ convert<pixfmt_argb64, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_bgra64:
+ convert<pixfmt_bgra64, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_abgr64:
+ convert<pixfmt_abgr64, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_rgb96:
+ convert<pixfmt_rgb96, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_bgr96:
+ convert<pixfmt_bgr96, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_rgba128:
+ convert<pixfmt_rgba128, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_argb128:
+ convert<pixfmt_argb128, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_bgra128:
+ convert<pixfmt_bgra128, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ break;
+
+ case pix_format_abgr128:
+ convert<pixfmt_abgr128, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img);
+ 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)
+ {
+ case pix_format_sgray8:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sgray8>());
+ break;
+
+ case pix_format_gray8:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_gray8>());
+ break;
+
+ case pix_format_gray16:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_gray16>());
+ break;
+
+ case pix_format_gray32:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_gray32>());
+ break;
+
+ 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_sbgr24:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sbgr24>());
+ break;
+
+ case pix_format_srgb24:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_srgb24>());
+ break;
+
+ case pix_format_bgr24:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgr24>());
+ break;
+
+ case pix_format_rgb24:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgb24>());
+ break;
+
+ case pix_format_srgba32:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_srgba32>());
+ break;
+
+ case pix_format_sargb32:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sargb32>());
+ break;
+
+ case pix_format_sbgra32:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sbgra32>());
+ break;
+
+ case pix_format_sabgr32:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sabgr32>());
+ break;
+
+ case pix_format_rgba32:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgba32>());
+ break;
+
+ case pix_format_argb32:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_argb32>());
+ break;
+
+ case pix_format_bgra32:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgra32>());
+ break;
+
+ case pix_format_abgr32:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_abgr32>());
+ break;
+
+ case pix_format_bgr48:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgr48>());
+ break;
+
+ case pix_format_rgb48:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgb48>());
+ break;
+
+ case pix_format_rgba64:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgba64>());
+ break;
+
+ case pix_format_argb64:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_argb64>());
+ break;
+
+ case pix_format_bgra64:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgra64>());
+ break;
+
+ case pix_format_abgr64:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_abgr64>());
+ break;
+
+ case pix_format_bgr96:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgr96>());
+ break;
+
+ case pix_format_rgb96:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgb96>());
+ break;
+
+ case pix_format_rgba128:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgba128>());
+ break;
+
+ case pix_format_argb128:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_argb128>());
+ break;
+
+ case pix_format_bgra128:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgra128>());
+ break;
+
+ case pix_format_abgr128:
+ color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_abgr128>());
+ 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) {}
+
+
+
+}
+
+
+int agg_main(int argc, char* argv[]);
+
+
+int main(int argc, char* argv[])
+{
+ return agg_main(argc, argv);
+}
+
+
+
+
+
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp
new file mode 100644
index 0000000000..dc85fd69ff
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp
@@ -0,0 +1,298 @@
+//----------------------------------------------------------------------------
+//
+//----------------------------------------------------------------------------
+// Contact: mcseemagg@yahoo.com
+// baer@karto.baug.ethz.ch
+//----------------------------------------------------------------------------
+//
+// class pixel_map
+//
+//----------------------------------------------------------------------------
+
+#include <string.h>
+#include <Carbon.h>
+#include <QuickTimeComponents.h>
+#include <ImageCompression.h>
+#include "platform/mac/agg_mac_pmap.h"
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ //------------------------------------------------------------------------
+ pixel_map::~pixel_map()
+ {
+ destroy();
+ }
+
+
+ //------------------------------------------------------------------------
+ pixel_map::pixel_map() :
+ m_pmap(0),
+ m_buf(0),
+ m_bpp(0),
+ m_img_size(0)
+
+ {
+ }
+
+
+ //------------------------------------------------------------------------
+ void pixel_map::destroy()
+ {
+ delete[] m_buf;
+ m_buf = NULL;
+ if (m_pmap != nil)
+ {
+ DisposeGWorld(m_pmap);
+ m_pmap = nil;
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ void pixel_map::create(unsigned width,
+ unsigned height,
+ org_e org,
+ unsigned clear_val)
+ {
+ destroy();
+ if(width == 0) width = 1;
+ if(height == 0) height = 1;
+ m_bpp = org;
+
+ Rect r;
+ int row_bytes = calc_row_len (width, m_bpp);
+ MacSetRect(&r, 0, 0, width, height);
+ m_buf = new unsigned char[m_img_size = row_bytes * height];
+ // The Quicktime version for creating GWorlds is more flexible than the classical function.
+ QTNewGWorldFromPtr (&m_pmap, m_bpp, &r, nil, nil, 0, m_buf, row_bytes);
+
+ // create_gray_scale_palette(m_pmap); I didn't care about gray scale palettes so far.
+ if(clear_val <= 255)
+ {
+ memset(m_buf, clear_val, m_img_size);
+ }
+ }
+
+
+
+ //------------------------------------------------------------------------
+ void pixel_map::clear(unsigned clear_val)
+ {
+ if(m_buf) memset(m_buf, clear_val, m_img_size);
+ }
+
+
+ //static
+ //This function is just copied from the Win32 plattform support.
+ //Is also seems to be appropriate for MacOS as well, but it is not
+ //thouroughly tested so far.
+ //------------------------------------------------------------------------
+
+ unsigned pixel_map::calc_row_len(unsigned width, unsigned bits_per_pixel)
+ {
+ unsigned n = width;
+ unsigned k;
+
+ switch(bits_per_pixel)
+ {
+ case 1: k = n;
+ n = n >> 3;
+ if(k & 7) n++;
+ break;
+
+ case 4: k = n;
+ n = n >> 1;
+ if(k & 3) n++;
+ break;
+
+ case 8:
+ break;
+
+ case 16: n = n << 1;
+ break;
+
+ case 24: n = (n << 1) + n;
+ break;
+
+ case 32: n = n << 2;
+ break;
+
+ default: n = 0;
+ break;
+ }
+ return ((n + 3) >> 2) << 2;
+ }
+
+
+
+
+ //------------------------------------------------------------------------
+ void pixel_map::draw(WindowRef window, const Rect *device_rect, const Rect *pmap_rect) const
+ {
+ if(m_pmap == nil || m_buf == NULL) return;
+
+ PixMapHandle pm = GetGWorldPixMap (m_pmap);
+ CGrafPtr port = GetWindowPort (window);
+ Rect dest_rect;
+
+ // Again, I used the Quicktime version.
+ // Good old 'CopyBits' does better interpolation when scaling
+ // but does not support all pixel depths.
+ MacSetRect (&dest_rect, 0, 0, this->width(), this->height());
+ ImageDescriptionHandle image_description;
+ MakeImageDescriptionForPixMap (pm, &image_description);
+ if (image_description != nil)
+ {
+ DecompressImage (GetPixBaseAddr (pm), image_description, GetPortPixMap (port), nil, &dest_rect, ditherCopy, nil);
+ DisposeHandle ((Handle) image_description);
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ void pixel_map::draw(WindowRef window, int x, int y, double scale) const
+ {
+ if(m_pmap == nil || m_buf == NULL) return;
+ unsigned width = (unsigned)(this->width() * scale);
+ unsigned height = (unsigned)(this->height() * scale);
+ Rect rect;
+ SetRect (&rect, x, y, x + width, y + height);
+ draw(window, &rect);
+ }
+
+
+
+ //------------------------------------------------------------------------
+ void pixel_map::blend(WindowRef window, const Rect *device_rect, const Rect *bmp_rect) const
+ {
+ draw (window, device_rect, bmp_rect); // currently just mapped to drawing method
+ }
+
+
+ //------------------------------------------------------------------------
+ void pixel_map::blend(WindowRef window, int x, int y, double scale) const
+ {
+ draw(window, x, y, scale); // currently just mapped to drawing method
+ }
+
+
+ // I let Quicktime handle image import since it supports most popular
+ // image formats such as:
+ // *.psd, *.bmp, *.tif, *.png, *.jpg, *.gif, *.pct, *.pcx
+ //------------------------------------------------------------------------
+ bool pixel_map::load_from_qt(const char *filename)
+ {
+ FSSpec fss;
+ OSErr err;
+
+ // get file specification to application directory
+ err = HGetVol(nil, &fss.vRefNum, &fss.parID);
+ if (err == noErr)
+ {
+ CopyCStringToPascal(filename, fss.name);
+ GraphicsImportComponent gi;
+ err = GetGraphicsImporterForFile (&fss, &gi);
+ if (err == noErr)
+ {
+ ImageDescriptionHandle desc;
+ GraphicsImportGetImageDescription(gi, &desc);
+// For simplicity, all images are currently converted to 32 bit.
+ // create an empty pixelmap
+ short depth = 32;
+ create ((**desc).width, (**desc).height, (org_e)depth, 0xff);
+ DisposeHandle ((Handle)desc);
+ // let Quicktime draw to pixelmap
+ GraphicsImportSetGWorld(gi, m_pmap, nil);
+ GraphicsImportDraw(gi);
+// Well, this is a hack. The graphics importer sets the alpha channel of the pixelmap to 0x00
+// for imported images without alpha channel but this would cause agg to draw an invisible image.
+ // set alpha channel to 0xff
+ unsigned char * buf = m_buf;
+ for (unsigned int size = 0; size < m_img_size; size += 4)
+ {
+ *buf = 0xff;
+ buf += 4;
+ }
+ }
+ }
+ return err == noErr;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool pixel_map::save_as_qt(const char *filename) const
+ {
+ FSSpec fss;
+ OSErr err;
+
+ // get file specification to application directory
+ err = HGetVol(nil, &fss.vRefNum, &fss.parID);
+ if (err == noErr)
+ {
+ GraphicsExportComponent ge;
+ CopyCStringToPascal(filename, fss.name);
+ // I decided to use PNG as output image file type.
+ // There are a number of other available formats.
+ // Should I check the file suffix to choose the image file format?
+ err = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypePNG, &ge);
+ if (err == noErr)
+ {
+ err = GraphicsExportSetInputGWorld(ge, m_pmap);
+ if (err == noErr)
+ {
+ err = GraphicsExportSetOutputFile (ge, &fss);
+ if (err == noErr)
+ {
+ GraphicsExportDoExport(ge, nil);
+ }
+ }
+ CloseComponent(ge);
+ }
+ }
+
+ return err == noErr;
+ }
+
+ //------------------------------------------------------------------------
+ unsigned char* pixel_map::buf()
+ {
+ return m_buf;
+ }
+
+ //------------------------------------------------------------------------
+ unsigned pixel_map::width() const
+ {
+ if(m_pmap == nil) return 0;
+ PixMapHandle pm = GetGWorldPixMap (m_pmap);
+ Rect bounds;
+ GetPixBounds (pm, &bounds);
+ return bounds.right - bounds.left;
+ }
+
+ //------------------------------------------------------------------------
+ unsigned pixel_map::height() const
+ {
+ if(m_pmap == nil) return 0;
+ PixMapHandle pm = GetGWorldPixMap (m_pmap);
+ Rect bounds;
+ GetPixBounds (pm, &bounds);
+ return bounds.bottom - bounds.top;
+ }
+
+ //------------------------------------------------------------------------
+ int pixel_map::row_bytes() const
+ {
+ if(m_pmap == nil) return 0;
+ PixMapHandle pm = GetGWorldPixMap (m_pmap);
+ return calc_row_len(width(), GetPixDepth(pm));
+ }
+
+
+
+}
+
+
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp
new file mode 100644
index 0000000000..f518dbe1f2
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp
@@ -0,0 +1,1053 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
+// Copyright (C) 2003 Hansruedi Baer (MacOS support)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+// baer@karto.baug.eth.ch
+//----------------------------------------------------------------------------
+//
+// class platform_support
+//
+//----------------------------------------------------------------------------
+//
+// Note:
+// I tried to retain the original structure for the Win32 platform as far
+// as possible. Currently, not all features are implemented but the examples
+// should work properly.
+// HB
+//----------------------------------------------------------------------------
+
+#include <Carbon.h>
+#if defined(__MWERKS__)
+#include "console.h"
+#endif
+#include <string.h>
+#include <unistd.h>
+#include "platform/agg_platform_support.h"
+#include "platform/mac/agg_mac_pmap.h"
+#include "util/agg_color_conv_rgb8.h"
+
+
+namespace agg
+{
+
+pascal OSStatus DoWindowClose (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus DoWindowDrawContent (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus DoAppQuit (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus DoMouseDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus DoMouseUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus DoMouseDragged (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus DoKeyDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus DoKeyUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal void DoPeriodicTask (EventLoopTimerRef theTimer, void* userData);
+
+
+ //------------------------------------------------------------------------
+ class platform_specific
+ {
+ public:
+ platform_specific(pix_format_e format, bool flip_y);
+
+ void create_pmap(unsigned width, unsigned height,
+ rendering_buffer* wnd);
+
+ void display_pmap(WindowRef window, const rendering_buffer* src);
+ bool load_pmap(const char* fn, unsigned idx,
+ rendering_buffer* dst);
+
+ bool save_pmap(const char* fn, unsigned idx,
+ const rendering_buffer* src);
+
+ unsigned translate(unsigned keycode);
+
+ pix_format_e m_format;
+ pix_format_e m_sys_format;
+ bool m_flip_y;
+ unsigned m_bpp;
+ unsigned m_sys_bpp;
+ WindowRef m_window;
+ pixel_map m_pmap_window;
+ pixel_map m_pmap_img[platform_support::max_images];
+ unsigned m_keymap[256];
+ unsigned m_last_translated_key;
+ int m_cur_x;
+ int m_cur_y;
+ unsigned m_input_flags;
+ bool m_redraw_flag;
+ UnsignedWide m_sw_freq;
+ UnsignedWide m_sw_start;
+ };
+
+
+ //------------------------------------------------------------------------
+ platform_specific::platform_specific(pix_format_e format, bool flip_y) :
+ m_format(format),
+ m_sys_format(pix_format_undefined),
+ m_flip_y(flip_y),
+ m_bpp(0),
+ m_sys_bpp(0),
+ m_window(nil),
+ m_last_translated_key(0),
+ m_cur_x(0),
+ m_cur_y(0),
+ m_input_flags(0),
+ m_redraw_flag(true)
+ {
+ memset(m_keymap, 0, sizeof(m_keymap));
+
+ //Keyboard input is not yet fully supported nor tested
+ //m_keymap[VK_PAUSE] = key_pause;
+ m_keymap[kClearCharCode] = key_clear;
+
+ //m_keymap[VK_NUMPAD0] = key_kp0;
+ //m_keymap[VK_NUMPAD1] = key_kp1;
+ //m_keymap[VK_NUMPAD2] = key_kp2;
+ //m_keymap[VK_NUMPAD3] = key_kp3;
+ //m_keymap[VK_NUMPAD4] = key_kp4;
+ //m_keymap[VK_NUMPAD5] = key_kp5;
+ //m_keymap[VK_NUMPAD6] = key_kp6;
+ //m_keymap[VK_NUMPAD7] = key_kp7;
+ //m_keymap[VK_NUMPAD8] = key_kp8;
+ //m_keymap[VK_NUMPAD9] = key_kp9;
+ //m_keymap[VK_DECIMAL] = key_kp_period;
+ //m_keymap[VK_DIVIDE] = key_kp_divide;
+ //m_keymap[VK_MULTIPLY] = key_kp_multiply;
+ //m_keymap[VK_SUBTRACT] = key_kp_minus;
+ //m_keymap[VK_ADD] = key_kp_plus;
+
+ m_keymap[kUpArrowCharCode] = key_up;
+ m_keymap[kDownArrowCharCode] = key_down;
+ m_keymap[kRightArrowCharCode] = key_right;
+ m_keymap[kLeftArrowCharCode] = key_left;
+ //m_keymap[VK_INSERT] = key_insert;
+ m_keymap[kDeleteCharCode] = key_delete;
+ m_keymap[kHomeCharCode] = key_home;
+ m_keymap[kEndCharCode] = key_end;
+ m_keymap[kPageUpCharCode] = key_page_up;
+ m_keymap[kPageDownCharCode] = key_page_down;
+
+ //m_keymap[VK_F1] = key_f1;
+ //m_keymap[VK_F2] = key_f2;
+ //m_keymap[VK_F3] = key_f3;
+ //m_keymap[VK_F4] = key_f4;
+ //m_keymap[VK_F5] = key_f5;
+ //m_keymap[VK_F6] = key_f6;
+ //m_keymap[VK_F7] = key_f7;
+ //m_keymap[VK_F8] = key_f8;
+ //m_keymap[VK_F9] = key_f9;
+ //m_keymap[VK_F10] = key_f10;
+ //m_keymap[VK_F11] = key_f11;
+ //m_keymap[VK_F12] = key_f12;
+ //m_keymap[VK_F13] = key_f13;
+ //m_keymap[VK_F14] = key_f14;
+ //m_keymap[VK_F15] = key_f15;
+
+ //m_keymap[VK_NUMLOCK] = key_numlock;
+ //m_keymap[VK_CAPITAL] = key_capslock;
+ //m_keymap[VK_SCROLL] = key_scrollock;
+
+ switch(m_format)
+ {
+ case pix_format_gray8:
+ m_sys_format = pix_format_gray8;
+ m_bpp = 8;
+ m_sys_bpp = 8;
+ break;
+
+ case pix_format_rgb565:
+ case pix_format_rgb555:
+ m_sys_format = pix_format_rgb555;
+ m_bpp = 16;
+ m_sys_bpp = 16;
+ break;
+
+ case pix_format_rgb24:
+ case pix_format_bgr24:
+ m_sys_format = pix_format_rgb24;
+ m_bpp = 24;
+ m_sys_bpp = 24;
+ break;
+
+ case pix_format_bgra32:
+ case pix_format_abgr32:
+ case pix_format_argb32:
+ case pix_format_rgba32:
+ m_sys_format = pix_format_argb32;
+ m_bpp = 32;
+ m_sys_bpp = 32;
+ break;
+ }
+ ::Microseconds(&m_sw_freq);
+ ::Microseconds(&m_sw_start);
+ }
+
+
+ //------------------------------------------------------------------------
+ void platform_specific::create_pmap(unsigned width,
+ unsigned height,
+ rendering_buffer* wnd)
+ {
+ m_pmap_window.create(width, height, org_e(m_bpp));
+ wnd->attach(m_pmap_window.buf(),
+ m_pmap_window.width(),
+ m_pmap_window.height(),
+ m_flip_y ?
+ -m_pmap_window.row_bytes() :
+ m_pmap_window.row_bytes());
+ }
+
+
+ //------------------------------------------------------------------------
+ void platform_specific::display_pmap(WindowRef window, const rendering_buffer* src)
+ {
+ if(m_sys_format == m_format)
+ {
+ m_pmap_window.draw(window);
+ }
+ else
+ {
+ pixel_map pmap_tmp;
+ pmap_tmp.create(m_pmap_window.width(),
+ m_pmap_window.height(),
+ org_e(m_sys_bpp));
+
+ rendering_buffer rbuf_tmp;
+ rbuf_tmp.attach(pmap_tmp.buf(),
+ pmap_tmp.width(),
+ pmap_tmp.height(),
+ m_flip_y ?
+ -pmap_tmp.row_bytes() :
+ pmap_tmp.row_bytes());
+
+ switch(m_format)
+ {
+ case pix_format_gray8:
+ return;
+
+ case pix_format_rgb565:
+ color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555());
+ break;
+
+ case pix_format_bgr24:
+ color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb24());
+ 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;
+
+ case pix_format_rgba32:
+ color_conv(&rbuf_tmp, src, color_conv_rgba32_to_argb32());
+ break;
+ }
+ pmap_tmp.draw(window);
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ bool platform_specific::save_pmap(const char* fn, unsigned idx,
+ const rendering_buffer* src)
+ {
+ if(m_sys_format == m_format)
+ {
+ return m_pmap_img[idx].save_as_qt(fn);
+ }
+ else
+ {
+ pixel_map pmap_tmp;
+ pmap_tmp.create(m_pmap_img[idx].width(),
+ m_pmap_img[idx].height(),
+ org_e(m_sys_bpp));
+
+ rendering_buffer rbuf_tmp;
+ rbuf_tmp.attach(pmap_tmp.buf(),
+ pmap_tmp.width(),
+ pmap_tmp.height(),
+ m_flip_y ?
+ -pmap_tmp.row_bytes() :
+ pmap_tmp.row_bytes());
+ switch(m_format)
+ {
+ case pix_format_gray8:
+ return false;
+
+ 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_bgr24());
+ break;
+
+ case pix_format_abgr32:
+ color_conv(&rbuf_tmp, src, color_conv_abgr32_to_bgra32());
+ break;
+
+ case pix_format_argb32:
+ color_conv(&rbuf_tmp, src, color_conv_argb32_to_bgra32());
+ break;
+
+ case pix_format_rgba32:
+ color_conv(&rbuf_tmp, src, color_conv_rgba32_to_bgra32());
+ break;
+ }
+ return pmap_tmp.save_as_qt(fn);
+ }
+ return true;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool platform_specific::load_pmap(const char* fn, unsigned idx,
+ rendering_buffer* dst)
+ {
+ pixel_map pmap_tmp;
+ if(!pmap_tmp.load_from_qt(fn)) return false;
+
+ rendering_buffer rbuf_tmp;
+ rbuf_tmp.attach(pmap_tmp.buf(),
+ pmap_tmp.width(),
+ pmap_tmp.height(),
+ m_flip_y ?
+ -pmap_tmp.row_bytes() :
+ pmap_tmp.row_bytes());
+
+ m_pmap_img[idx].create(pmap_tmp.width(),
+ pmap_tmp.height(),
+ org_e(m_bpp),
+ 0);
+
+ dst->attach(m_pmap_img[idx].buf(),
+ m_pmap_img[idx].width(),
+ m_pmap_img[idx].height(),
+ m_flip_y ?
+ -m_pmap_img[idx].row_bytes() :
+ m_pmap_img[idx].row_bytes());
+
+ switch(m_format)
+ {
+ case pix_format_gray8:
+ return false;
+ break;
+
+ case pix_format_rgb555:
+ switch(pmap_tmp.bpp())
+ {
+ case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb555()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgb555()); break;
+ case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgb555()); break;
+ }
+ break;
+
+ case pix_format_rgb565:
+ switch(pmap_tmp.bpp())
+ {
+ case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb565()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgb565()); break;
+ case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgb565()); break;
+ }
+ break;
+
+ case pix_format_rgb24:
+ switch(pmap_tmp.bpp())
+ {
+ case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb24()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgb24()); break;
+ case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgb24()); break;
+ }
+ break;
+
+ case pix_format_bgr24:
+ switch(pmap_tmp.bpp())
+ {
+ case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgr24()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_bgr24()); break;
+ case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_bgr24()); break;
+ }
+ break;
+
+ case pix_format_abgr32:
+ switch(pmap_tmp.bpp())
+ {
+ case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_abgr32()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_abgr32()); break;
+ case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_abgr32()); break;
+ }
+ break;
+
+ case pix_format_argb32:
+ switch(pmap_tmp.bpp())
+ {
+ case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_argb32()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_argb32()); break;
+ case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_argb32()); break;
+ }
+ break;
+
+ case pix_format_bgra32:
+ switch(pmap_tmp.bpp())
+ {
+ case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgra32()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_bgra32()); break;
+ case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_bgra32()); break;
+ }
+ break;
+
+ case pix_format_rgba32:
+ switch(pmap_tmp.bpp())
+ {
+ case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgba32()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgba32()); break;
+ case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgba32()); break;
+ }
+ break;
+ }
+
+ return true;
+ }
+
+
+
+
+
+
+
+
+ //------------------------------------------------------------------------
+ unsigned platform_specific::translate(unsigned keycode)
+ {
+ return m_last_translated_key = (keycode > 255) ? 0 : m_keymap[keycode];
+ }
+
+
+
+ //------------------------------------------------------------------------
+ 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, "Anti-Grain Geometry Application");
+ }
+
+
+ //------------------------------------------------------------------------
+ platform_support::~platform_support()
+ {
+ delete m_specific;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ void platform_support::caption(const char* cap)
+ {
+ strcpy(m_caption, cap);
+ if(m_specific->m_window)
+ {
+ SetWindowTitleWithCFString (m_specific->m_window, CFStringCreateWithCStringNoCopy (nil, cap, kCFStringEncodingASCII, nil));
+ }
+ }
+
+
+
+ //------------------------------------------------------------------------
+ static unsigned get_key_flags(UInt32 wflags)
+ {
+ unsigned flags = 0;
+
+ if(wflags & shiftKey) flags |= kbd_shift;
+ if(wflags & controlKey) flags |= kbd_ctrl;
+
+ return flags;
+ }
+
+
+ //------------------------------------------------------------------------
+ void platform_support::message(const char* msg)
+ {
+ SInt16 item;
+ Str255 p_msg;
+
+ ::CopyCStringToPascal (msg, p_msg);
+ ::StandardAlert (kAlertPlainAlert, (const unsigned char*) "\013AGG Message", p_msg, NULL, &item);
+ //::StandardAlert (kAlertPlainAlert, (const unsigned char*) "\pAGG Message", p_msg, NULL, &item);
+ }
+
+
+ //------------------------------------------------------------------------
+ void platform_support::start_timer()
+ {
+ ::Microseconds (&(m_specific->m_sw_start));
+ }
+
+
+ //------------------------------------------------------------------------
+ double platform_support::elapsed_time() const
+ {
+ UnsignedWide stop;
+ ::Microseconds(&stop);
+ return double(stop.lo -
+ m_specific->m_sw_start.lo) * 1e6 /
+ double(m_specific->m_sw_freq.lo);
+ }
+
+
+ //------------------------------------------------------------------------
+ bool platform_support::init(unsigned width, unsigned height, unsigned flags)
+ {
+ if(m_specific->m_sys_format == pix_format_undefined)
+ {
+ return false;
+ }
+
+ m_window_flags = flags;
+
+ // application
+ EventTypeSpec eventType;
+ EventHandlerUPP handlerUPP;
+
+ eventType.eventClass = kEventClassApplication;
+ eventType.eventKind = kEventAppQuit;
+
+ handlerUPP = NewEventHandlerUPP(DoAppQuit);
+
+ InstallApplicationEventHandler (handlerUPP, 1, &eventType, nil, nil);
+
+ eventType.eventClass = kEventClassMouse;
+ eventType.eventKind = kEventMouseDown;
+ handlerUPP = NewEventHandlerUPP(DoMouseDown);
+ InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil);
+
+ eventType.eventKind = kEventMouseUp;
+ handlerUPP = NewEventHandlerUPP(DoMouseUp);
+ InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil);
+
+ eventType.eventKind = kEventMouseDragged;
+ handlerUPP = NewEventHandlerUPP(DoMouseDragged);
+ InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil);
+
+ eventType.eventClass = kEventClassKeyboard;
+ eventType.eventKind = kEventRawKeyDown;
+ handlerUPP = NewEventHandlerUPP(DoKeyDown);
+ InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil);
+
+ eventType.eventKind = kEventRawKeyUp;
+ handlerUPP = NewEventHandlerUPP(DoKeyUp);
+ InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil);
+
+ eventType.eventKind = kEventRawKeyRepeat;
+ handlerUPP = NewEventHandlerUPP(DoKeyDown); // 'key repeat' is translated to 'key down'
+ InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil);
+
+ WindowAttributes windowAttrs;
+ Rect bounds;
+
+ // window
+ windowAttrs = kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute;
+ SetRect (&bounds, 0, 0, width, height);
+ OffsetRect (&bounds, 100, 100);
+ CreateNewWindow (kDocumentWindowClass, windowAttrs, &bounds, &m_specific->m_window);
+
+ if(m_specific->m_window == nil)
+ {
+ return false;
+ }
+
+ // I assume the text is ASCII.
+ // Change to kCFStringEncodingMacRoman, kCFStringEncodingISOLatin1, kCFStringEncodingUTF8 or what else you need.
+ SetWindowTitleWithCFString (m_specific->m_window, CFStringCreateWithCStringNoCopy (nil, m_caption, kCFStringEncodingASCII, nil));
+
+ eventType.eventClass = kEventClassWindow;
+ eventType.eventKind = kEventWindowClose;
+
+ handlerUPP = NewEventHandlerUPP(DoWindowClose);
+ InstallWindowEventHandler (m_specific->m_window, handlerUPP, 1, &eventType, this, NULL);
+
+ eventType.eventKind = kEventWindowDrawContent;
+ handlerUPP = NewEventHandlerUPP(DoWindowDrawContent);
+ InstallWindowEventHandler (m_specific->m_window, handlerUPP, 1, &eventType, this, NULL);
+
+ // Periodic task
+ // Instead of an idle function I use the Carbon event timer.
+ // You may decide to change the wait value which is currently 50 milliseconds.
+ EventLoopRef mainLoop;
+ EventLoopTimerUPP timerUPP;
+ EventLoopTimerRef theTimer;
+
+ mainLoop = GetMainEventLoop();
+ timerUPP = NewEventLoopTimerUPP (DoPeriodicTask);
+ InstallEventLoopTimer (mainLoop, 0, 50 * kEventDurationMillisecond, timerUPP, this, &theTimer);
+
+ m_specific->create_pmap(width, height, &m_rbuf_window);
+ m_initial_width = width;
+ m_initial_height = height;
+ on_init();
+ on_resize(width, height);
+ m_specific->m_redraw_flag = true;
+
+ ShowWindow (m_specific->m_window);
+ SetPortWindowPort (m_specific->m_window);
+
+ return true;
+ }
+
+
+ //------------------------------------------------------------------------
+ int platform_support::run()
+ {
+
+ RunApplicationEventLoop ();
+ return true;
+ }
+
+
+ //------------------------------------------------------------------------
+ const char* platform_support::img_ext() const { return ".bmp"; }
+
+ //------------------------------------------------------------------------
+ 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 fn[1024];
+ strcpy(fn, file);
+ int len = strlen(fn);
+#if defined(__MWERKS__)
+ if(len < 4 || stricmp(fn + len - 4, ".BMP") != 0)
+#else
+ if(len < 4 || strncasecmp(fn + len - 4, ".BMP", 4) != 0)
+#endif
+ {
+ strcat(fn, ".bmp");
+ }
+ return m_specific->load_pmap(fn, idx, &m_rbuf_img[idx]);
+ }
+ return true;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool platform_support::save_img(unsigned idx, const char* file)
+ {
+ if(idx < max_images)
+ {
+ char fn[1024];
+ strcpy(fn, file);
+ int len = strlen(fn);
+#if defined(__MWERKS__)
+ if(len < 4 || stricmp(fn + len - 4, ".BMP") != 0)
+#else
+ if(len < 4 || strncasecmp(fn + len - 4, ".BMP", 4) != 0)
+#endif
+ {
+ strcat(fn, ".bmp");
+ }
+ return m_specific->save_pmap(fn, idx, &m_rbuf_img[idx]);
+ }
+ return true;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool platform_support::create_img(unsigned idx, unsigned width, unsigned height)
+ {
+ if(idx < max_images)
+ {
+ if(width == 0) width = m_specific->m_pmap_window.width();
+ if(height == 0) height = m_specific->m_pmap_window.height();
+ m_specific->m_pmap_img[idx].create(width, height, org_e(m_specific->m_bpp));
+ m_rbuf_img[idx].attach(m_specific->m_pmap_img[idx].buf(),
+ m_specific->m_pmap_img[idx].width(),
+ m_specific->m_pmap_img[idx].height(),
+ m_flip_y ?
+ -m_specific->m_pmap_img[idx].row_bytes() :
+ m_specific->m_pmap_img[idx].row_bytes());
+ return true;
+ }
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ void platform_support::force_redraw()
+ {
+ Rect bounds;
+
+ m_specific->m_redraw_flag = true;
+ // on_ctrl_change ();
+ on_draw();
+
+ SetRect(&bounds, 0, 0, m_rbuf_window.width(), m_rbuf_window.height());
+ InvalWindowRect(m_specific->m_window, &bounds);
+ }
+
+
+
+ //------------------------------------------------------------------------
+ void platform_support::update_window()
+ {
+ m_specific->display_pmap(m_specific->m_window, &m_rbuf_window);
+ }
+
+
+ //------------------------------------------------------------------------
+ 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) {}
+
+
+//------------------------------------------------------------------------
+pascal OSStatus DoWindowClose (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+ userData;
+
+ QuitApplicationEventLoop ();
+
+ return CallNextEventHandler (nextHandler, theEvent);
+}
+
+
+//------------------------------------------------------------------------
+pascal OSStatus DoAppQuit (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+ userData;
+
+ return CallNextEventHandler (nextHandler, theEvent);
+}
+
+
+//------------------------------------------------------------------------
+pascal OSStatus DoMouseDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+ Point wheresMyMouse;
+ UInt32 modifier;
+
+ GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &wheresMyMouse);
+ GlobalToLocal (&wheresMyMouse);
+ GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier);
+
+ platform_support * app = reinterpret_cast<platform_support*>(userData);
+
+ app->m_specific->m_cur_x = wheresMyMouse.h;
+ if(app->flip_y())
+ {
+ app->m_specific->m_cur_y = app->rbuf_window().height() - wheresMyMouse.v;
+ }
+ else
+ {
+ app->m_specific->m_cur_y = wheresMyMouse.v;
+ }
+ app->m_specific->m_input_flags = mouse_left | get_key_flags(modifier);
+
+ app->m_ctrls.set_cur(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y);
+ if(app->m_ctrls.on_mouse_button_down(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y))
+ {
+ app->on_ctrl_change();
+ app->force_redraw();
+ }
+ else
+ {
+ if(app->m_ctrls.in_rect(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y))
+ {
+ if(app->m_ctrls.set_cur(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y))
+ {
+ app->on_ctrl_change();
+ app->force_redraw();
+ }
+ }
+ else
+ {
+ app->on_mouse_button_down(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y,
+ app->m_specific->m_input_flags);
+ }
+ }
+
+ return CallNextEventHandler (nextHandler, theEvent);
+}
+
+
+//------------------------------------------------------------------------
+pascal OSStatus DoMouseUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+ Point wheresMyMouse;
+ UInt32 modifier;
+
+ GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &wheresMyMouse);
+ GlobalToLocal (&wheresMyMouse);
+ GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier);
+
+ platform_support * app = reinterpret_cast<platform_support*>(userData);
+
+ app->m_specific->m_cur_x = wheresMyMouse.h;
+ if(app->flip_y())
+ {
+ app->m_specific->m_cur_y = app->rbuf_window().height() - wheresMyMouse.v;
+ }
+ else
+ {
+ app->m_specific->m_cur_y = wheresMyMouse.v;
+ }
+ app->m_specific->m_input_flags = mouse_left | get_key_flags(modifier);
+
+ if(app->m_ctrls.on_mouse_button_up(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y))
+ {
+ app->on_ctrl_change();
+ app->force_redraw();
+ }
+ app->on_mouse_button_up(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y,
+ app->m_specific->m_input_flags);
+
+ return CallNextEventHandler (nextHandler, theEvent);
+}
+
+
+//------------------------------------------------------------------------
+pascal OSStatus DoMouseDragged (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+ Point wheresMyMouse;
+ UInt32 modifier;
+
+ GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &wheresMyMouse);
+ GlobalToLocal (&wheresMyMouse);
+ GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier);
+
+ platform_support * app = reinterpret_cast<platform_support*>(userData);
+
+ app->m_specific->m_cur_x = wheresMyMouse.h;
+ if(app->flip_y())
+ {
+ app->m_specific->m_cur_y = app->rbuf_window().height() - wheresMyMouse.v;
+ }
+ else
+ {
+ app->m_specific->m_cur_y = wheresMyMouse.v;
+ }
+ app->m_specific->m_input_flags = mouse_left | get_key_flags(modifier);
+
+
+ if(app->m_ctrls.on_mouse_move(
+ app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y,
+ (app->m_specific->m_input_flags & mouse_left) != 0))
+ {
+ app->on_ctrl_change();
+ app->force_redraw();
+ }
+ else
+ {
+ app->on_mouse_move(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y,
+ app->m_specific->m_input_flags);
+ }
+
+ return CallNextEventHandler (nextHandler, theEvent);
+}
+
+
+//------------------------------------------------------------------------
+pascal OSStatus DoKeyDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+ char key_code;
+ UInt32 modifier;
+
+ GetEventParameter (theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &key_code);
+ GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier);
+
+ platform_support * app = reinterpret_cast<platform_support*>(userData);
+
+ app->m_specific->m_last_translated_key = 0;
+ switch(modifier)
+ {
+ case controlKey:
+ app->m_specific->m_input_flags |= kbd_ctrl;
+ break;
+
+ case shiftKey:
+ app->m_specific->m_input_flags |= kbd_shift;
+ break;
+
+ default:
+ app->m_specific->translate(key_code);
+ break;
+ }
+
+ if(app->m_specific->m_last_translated_key)
+ {
+ bool left = false;
+ bool up = false;
+ bool right = false;
+ bool down = false;
+
+ switch(app->m_specific->m_last_translated_key)
+ {
+ case key_left:
+ left = true;
+ break;
+
+ case key_up:
+ up = true;
+ break;
+
+ case key_right:
+ right = true;
+ break;
+
+ case key_down:
+ down = true;
+ break;
+
+ //On a Mac, screenshots are handled by the system.
+ case key_f2:
+ app->copy_window_to_img(agg::platform_support::max_images - 1);
+ app->save_img(agg::platform_support::max_images - 1, "screenshot");
+ break;
+ }
+
+
+ if(app->m_ctrls.on_arrow_keys(left, right, down, up))
+ {
+ app->on_ctrl_change();
+ app->force_redraw();
+ }
+ else
+ {
+ app->on_key(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y,
+ app->m_specific->m_last_translated_key,
+ app->m_specific->m_input_flags);
+ }
+ }
+
+ return CallNextEventHandler (nextHandler, theEvent);
+}
+
+
+//------------------------------------------------------------------------
+pascal OSStatus DoKeyUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+ char key_code;
+ UInt32 modifier;
+
+ GetEventParameter (theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &key_code);
+ GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier);
+
+ platform_support * app = reinterpret_cast<platform_support*>(userData);
+
+ app->m_specific->m_last_translated_key = 0;
+ switch(modifier)
+ {
+ case controlKey:
+ app->m_specific->m_input_flags &= ~kbd_ctrl;
+ break;
+
+ case shiftKey:
+ app->m_specific->m_input_flags &= ~kbd_shift;
+ break;
+ }
+
+ return CallNextEventHandler (nextHandler, theEvent);
+}
+
+
+//------------------------------------------------------------------------
+pascal OSStatus DoWindowDrawContent (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
+{
+ platform_support * app = reinterpret_cast<platform_support*>(userData);
+
+ if(app)
+ {
+ if(app->m_specific->m_redraw_flag)
+ {
+ app->on_draw();
+ app->m_specific->m_redraw_flag = false;
+ }
+ app->m_specific->display_pmap(app->m_specific->m_window, &app->rbuf_window());
+ }
+
+ return CallNextEventHandler (nextHandler, theEvent);
+}
+
+
+//------------------------------------------------------------------------
+pascal void DoPeriodicTask (EventLoopTimerRef theTimer, void* userData)
+{
+ platform_support * app = reinterpret_cast<platform_support*>(userData);
+
+ if(!app->wait_mode())
+ app->on_idle();
+}
+
+
+}
+
+
+
+
+//----------------------------------------------------------------------------
+int agg_main(int argc, char* argv[]);
+
+
+// Hm. Classic MacOS does not know command line input.
+// CodeWarrior provides a way to mimic command line input.
+// The function 'ccommand' can be used to get the command
+// line arguments.
+//----------------------------------------------------------------------------
+int main(int argc, char* argv[])
+{
+#if defined(__MWERKS__)
+ // argc = ccommand (&argv);
+#endif
+
+ // Check if we are launched by double-clicking under OSX
+ // Get rid of extra argument, this will confuse the standard argument parsing
+ // calls used in the examples to get the name of the image file to be used
+ if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
+ argc = 1;
+ }
+
+launch:
+ return agg_main(argc, argv);
+} \ No newline at end of file
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp
new file mode 100644
index 0000000000..28c6436baa
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp
@@ -0,0 +1,708 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// class platform_support. SDL version.
+//
+//----------------------------------------------------------------------------
+
+#include <string.h>
+#include "platform/agg_platform_support.h"
+#include "SDL.h"
+#include "SDL_byteorder.h"
+
+
+namespace agg
+{
+
+ //------------------------------------------------------------------------
+ class platform_specific
+ {
+ public:
+ platform_specific(pix_format_e format, bool flip_y);
+ ~platform_specific();
+
+ pix_format_e m_format;
+ pix_format_e m_sys_format;
+ bool m_flip_y;
+ unsigned m_bpp;
+ unsigned m_sys_bpp;
+ unsigned m_rmask;
+ unsigned m_gmask;
+ unsigned m_bmask;
+ unsigned m_amask;
+ bool m_update_flag;
+ bool m_resize_flag;
+ bool m_initialized;
+ SDL_Surface* m_surf_screen;
+ SDL_Surface* m_surf_window;
+ SDL_Surface* m_surf_img[platform_support::max_images];
+ int m_cur_x;
+ int m_cur_y;
+ int m_sw_start;
+ };
+
+
+
+ //------------------------------------------------------------------------
+ platform_specific::platform_specific(pix_format_e format, bool flip_y) :
+ m_format(format),
+ m_sys_format(pix_format_undefined),
+ m_flip_y(flip_y),
+ m_bpp(0),
+ m_sys_bpp(0),
+ m_update_flag(true),
+ m_resize_flag(true),
+ m_initialized(false),
+ m_surf_screen(0),
+ m_surf_window(0),
+ m_cur_x(0),
+ m_cur_y(0)
+ {
+ memset(m_surf_img, 0, sizeof(m_surf_img));
+
+ switch(m_format)
+ {
+ case pix_format_gray8:
+ m_bpp = 8;
+ break;
+
+ case pix_format_rgb565:
+ m_rmask = 0xF800;
+ m_gmask = 0x7E0;
+ m_bmask = 0x1F;
+ m_amask = 0;
+ m_bpp = 16;
+ break;
+
+ case pix_format_rgb555:
+ m_rmask = 0x7C00;
+ m_gmask = 0x3E0;
+ m_bmask = 0x1F;
+ m_amask = 0;
+ m_bpp = 16;
+ break;
+
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ case pix_format_rgb24:
+ m_rmask = 0xFF;
+ m_gmask = 0xFF00;
+ m_bmask = 0xFF0000;
+ m_amask = 0;
+ m_bpp = 24;
+ break;
+
+ case pix_format_bgr24:
+ m_rmask = 0xFF0000;
+ m_gmask = 0xFF00;
+ m_bmask = 0xFF;
+ m_amask = 0;
+ m_bpp = 24;
+ break;
+
+ case pix_format_bgra32:
+ m_rmask = 0xFF0000;
+ m_gmask = 0xFF00;
+ m_bmask = 0xFF;
+ m_amask = 0xFF000000;
+ m_bpp = 32;
+ break;
+
+ case pix_format_abgr32:
+ m_rmask = 0xFF000000;
+ m_gmask = 0xFF0000;
+ m_bmask = 0xFF00;
+ m_amask = 0xFF;
+ m_bpp = 32;
+ break;
+
+ case pix_format_argb32:
+ m_rmask = 0xFF00;
+ m_gmask = 0xFF0000;
+ m_bmask = 0xFF000000;
+ m_amask = 0xFF;
+ m_bpp = 32;
+ break;
+
+ case pix_format_rgba32:
+ m_rmask = 0xFF;
+ m_gmask = 0xFF00;
+ m_bmask = 0xFF0000;
+ m_amask = 0xFF000000;
+ m_bpp = 32;
+ break;
+#else //SDL_BIG_ENDIAN (PPC)
+ case pix_format_rgb24:
+ m_rmask = 0xFF0000;
+ m_gmask = 0xFF00;
+ m_bmask = 0xFF;
+ m_amask = 0;
+ m_bpp = 24;
+ break;
+
+ case pix_format_bgr24:
+ m_rmask = 0xFF;
+ m_gmask = 0xFF00;
+ m_bmask = 0xFF0000;
+ m_amask = 0;
+ m_bpp = 24;
+ break;
+
+ case pix_format_bgra32:
+ m_rmask = 0xFF00;
+ m_gmask = 0xFF0000;
+ m_bmask = 0xFF000000;
+ m_amask = 0xFF;
+ m_bpp = 32;
+ break;
+
+ case pix_format_abgr32:
+ m_rmask = 0xFF;
+ m_gmask = 0xFF00;
+ m_bmask = 0xFF0000;
+ m_amask = 0xFF000000;
+ m_bpp = 32;
+ break;
+
+ case pix_format_argb32:
+ m_rmask = 0xFF0000;
+ m_gmask = 0xFF00;
+ m_bmask = 0xFF;
+ m_amask = 0xFF000000;
+ m_bpp = 32;
+ break;
+
+ case pix_format_rgba32:
+ m_rmask = 0xFF000000;
+ m_gmask = 0xFF0000;
+ m_bmask = 0xFF00;
+ m_amask = 0xFF;
+ m_bpp = 32;
+ break;
+#endif
+ }
+ }
+
+ //------------------------------------------------------------------------
+ platform_specific::~platform_specific()
+ {
+ int i;
+ for(i = platform_support::max_images - 1; i >= 0; --i)
+ {
+ if(m_surf_img[i]) SDL_FreeSurface(m_surf_img[i]);
+ }
+ if(m_surf_window) SDL_FreeSurface(m_surf_window);
+ if(m_surf_screen) SDL_FreeSurface(m_surf_screen);
+ }
+
+
+
+ //------------------------------------------------------------------------
+ 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)
+ {
+ SDL_Init(SDL_INIT_VIDEO);
+ strcpy(m_caption, "Anti-Grain Geometry Application");
+ }
+
+
+ //------------------------------------------------------------------------
+ platform_support::~platform_support()
+ {
+ delete m_specific;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ void platform_support::caption(const char* cap)
+ {
+ strcpy(m_caption, cap);
+ if(m_specific->m_initialized)
+ {
+ SDL_WM_SetCaption(cap, 0);
+ }
+ }
+
+
+
+
+
+ //------------------------------------------------------------------------
+ bool platform_support::init(unsigned width, unsigned height, unsigned flags)
+ {
+ m_window_flags = flags;
+ unsigned wflags = SDL_SWSURFACE;
+
+ if(m_window_flags & window_hw_buffer)
+ {
+ wflags = SDL_HWSURFACE;
+ }
+
+ if(m_window_flags & window_resize)
+ {
+ wflags |= SDL_RESIZABLE;
+ }
+
+ if(m_specific->m_surf_screen) SDL_FreeSurface(m_specific->m_surf_screen);
+
+ m_specific->m_surf_screen = SDL_SetVideoMode(width, height, m_bpp, wflags);
+ if(m_specific->m_surf_screen == 0)
+ {
+ fprintf(stderr,
+ "Unable to set %dx%d %d bpp video: %s\n",
+ width,
+ height,
+ m_bpp,
+ ::SDL_GetError());
+ return false;
+ }
+
+ SDL_WM_SetCaption(m_caption, 0);
+
+ if(m_specific->m_surf_window) SDL_FreeSurface(m_specific->m_surf_window);
+
+ m_specific->m_surf_window =
+ SDL_CreateRGBSurface(SDL_HWSURFACE,
+ m_specific->m_surf_screen->w,
+ m_specific->m_surf_screen->h,
+ m_specific->m_surf_screen->format->BitsPerPixel,
+ m_specific->m_rmask,
+ m_specific->m_gmask,
+ m_specific->m_bmask,
+ m_specific->m_amask);
+
+ if(m_specific->m_surf_window == 0)
+ {
+ fprintf(stderr,
+ "Unable to create image buffer %dx%d %d bpp: %s\n",
+ width,
+ height,
+ m_bpp,
+ SDL_GetError());
+ return false;
+ }
+
+ m_rbuf_window.attach((unsigned char*)m_specific->m_surf_window->pixels,
+ m_specific->m_surf_window->w,
+ m_specific->m_surf_window->h,
+ m_flip_y ? -m_specific->m_surf_window->pitch :
+ m_specific->m_surf_window->pitch);
+
+ if(!m_specific->m_initialized)
+ {
+ m_initial_width = width;
+ m_initial_height = height;
+ on_init();
+ m_specific->m_initialized = true;
+ }
+ on_resize(m_rbuf_window.width(), m_rbuf_window.height());
+ m_specific->m_update_flag = true;
+ return true;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ void platform_support::update_window()
+ {
+ SDL_BlitSurface(m_specific->m_surf_window, 0, m_specific->m_surf_screen, 0);
+ SDL_UpdateRect(m_specific->m_surf_screen, 0, 0, 0, 0);
+ }
+
+
+ //------------------------------------------------------------------------
+ int platform_support::run()
+ {
+ SDL_Event event;
+ bool ev_flag = false;
+
+ for(;;)
+ {
+ if(m_specific->m_update_flag)
+ {
+ on_draw();
+ update_window();
+ m_specific->m_update_flag = false;
+ }
+
+ ev_flag = false;
+ if(m_wait_mode)
+ {
+ SDL_WaitEvent(&event);
+ ev_flag = true;
+ }
+ else
+ {
+ if(SDL_PollEvent(&event))
+ {
+ ev_flag = true;
+ }
+ else
+ {
+ on_idle();
+ }
+ }
+
+ if(ev_flag)
+ {
+ if(event.type == SDL_QUIT)
+ {
+ break;
+ }
+
+ int y;
+ unsigned flags = 0;
+
+ switch (event.type)
+ {
+ case SDL_VIDEORESIZE:
+ if(!init(event.resize.w, event.resize.h, m_window_flags)) return false;
+ on_resize(m_rbuf_window.width(), m_rbuf_window.height());
+ trans_affine_resizing(event.resize.w, event.resize.h);
+ m_specific->m_update_flag = true;
+ break;
+
+ case SDL_KEYDOWN:
+ {
+ flags = 0;
+ if(event.key.keysym.mod & KMOD_SHIFT) flags |= kbd_shift;
+ if(event.key.keysym.mod & KMOD_CTRL) flags |= kbd_ctrl;
+
+ bool left = false;
+ bool up = false;
+ bool right = false;
+ bool down = false;
+
+ switch(event.key.keysym.sym)
+ {
+ case key_left:
+ left = true;
+ break;
+
+ case key_up:
+ up = true;
+ break;
+
+ case key_right:
+ right = true;
+ break;
+
+ case key_down:
+ down = true;
+ break;
+ }
+
+ if(m_ctrls.on_arrow_keys(left, right, down, up))
+ {
+ on_ctrl_change();
+ force_redraw();
+ }
+ else
+ {
+ on_key(m_specific->m_cur_x,
+ m_specific->m_cur_y,
+ event.key.keysym.sym,
+ flags);
+ }
+ }
+ break;
+
+ case SDL_MOUSEMOTION:
+ y = m_flip_y ?
+ m_rbuf_window.height() - event.motion.y :
+ event.motion.y;
+
+ m_specific->m_cur_x = event.motion.x;
+ m_specific->m_cur_y = y;
+ flags = 0;
+ if(event.motion.state & SDL_BUTTON_LMASK) flags |= mouse_left;
+ if(event.motion.state & SDL_BUTTON_RMASK) flags |= mouse_right;
+
+ if(m_ctrls.on_mouse_move(m_specific->m_cur_x,
+ m_specific->m_cur_y,
+ (flags & mouse_left) != 0))
+ {
+ on_ctrl_change();
+ force_redraw();
+ }
+ else
+ {
+ on_mouse_move(m_specific->m_cur_x,
+ m_specific->m_cur_y,
+ flags);
+ }
+ SDL_Event eventtrash;
+ while (SDL_PeepEvents(&eventtrash, 1, SDL_GETEVENT, SDL_EVENTMASK(SDL_MOUSEMOTION))!=0){;}
+ break;
+
+ case SDL_MOUSEBUTTONDOWN:
+ y = m_flip_y
+ ? m_rbuf_window.height() - event.button.y
+ : event.button.y;
+
+ m_specific->m_cur_x = event.button.x;
+ m_specific->m_cur_y = y;
+ flags = 0;
+ switch(event.button.button)
+ {
+ case SDL_BUTTON_LEFT:
+ {
+ flags = mouse_left;
+
+if(m_ctrls.on_mouse_button_down(m_specific->m_cur_x,
+ m_specific->m_cur_y))
+ {
+ m_ctrls.set_cur(m_specific->m_cur_x,
+ m_specific->m_cur_y);
+ on_ctrl_change();
+ force_redraw();
+ }
+ else
+ {
+ if(m_ctrls.in_rect(m_specific->m_cur_x,
+ m_specific->m_cur_y))
+ {
+ if(m_ctrls.set_cur(m_specific->m_cur_x,
+ m_specific->m_cur_y))
+ {
+ on_ctrl_change();
+ force_redraw();
+ }
+ }
+ else
+ {
+ on_mouse_button_down(m_specific->m_cur_x,
+ m_specific->m_cur_y,
+ flags);
+ }
+ }
+ }
+ break;
+ case SDL_BUTTON_RIGHT:
+ flags = mouse_right;
+ on_mouse_button_down(m_specific->m_cur_x,
+ m_specific->m_cur_y,
+ flags);
+ break;
+ } //switch(event.button.button)
+ break;
+
+ case SDL_MOUSEBUTTONUP:
+ y = m_flip_y
+ ? m_rbuf_window.height() - event.button.y
+ : event.button.y;
+
+ m_specific->m_cur_x = event.button.x;
+ m_specific->m_cur_y = y;
+ flags = 0;
+ if(m_ctrls.on_mouse_button_up(m_specific->m_cur_x,
+ m_specific->m_cur_y))
+ {
+ on_ctrl_change();
+ force_redraw();
+ }
+ on_mouse_button_up(m_specific->m_cur_x,
+ m_specific->m_cur_y,
+ flags);
+ break;
+ }
+ }
+ }
+ return 0;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ const char* platform_support::img_ext() const { return ".bmp"; }
+
+ //------------------------------------------------------------------------
+ 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)
+ {
+ if(m_specific->m_surf_img[idx]) SDL_FreeSurface(m_specific->m_surf_img[idx]);
+
+ char fn[1024];
+ strcpy(fn, file);
+ int len = strlen(fn);
+ if(len < 4 || strcmp(fn + len - 4, ".bmp") != 0)
+ {
+ strcat(fn, ".bmp");
+ }
+
+ SDL_Surface* tmp_surf = SDL_LoadBMP(fn);
+ if (tmp_surf == 0)
+ {
+ fprintf(stderr, "Couldn't load %s: %s\n", fn, SDL_GetError());
+ return false;
+ }
+
+ SDL_PixelFormat format;
+ format.palette = 0;
+ format.BitsPerPixel = m_bpp;
+ format.BytesPerPixel = m_bpp >> 8;
+ format.Rmask = m_specific->m_rmask;
+ format.Gmask = m_specific->m_gmask;
+ format.Bmask = m_specific->m_bmask;
+ format.Amask = m_specific->m_amask;
+ format.Rshift = 0;
+ format.Gshift = 0;
+ format.Bshift = 0;
+ format.Ashift = 0;
+ format.Rloss = 0;
+ format.Gloss = 0;
+ format.Bloss = 0;
+ format.Aloss = 0;
+ format.colorkey = 0;
+ format.alpha = 0;
+
+ m_specific->m_surf_img[idx] =
+ SDL_ConvertSurface(tmp_surf,
+ &format,
+ SDL_SWSURFACE);
+
+ SDL_FreeSurface(tmp_surf);
+
+ if(m_specific->m_surf_img[idx] == 0) return false;
+
+ m_rbuf_img[idx].attach((unsigned char*)m_specific->m_surf_img[idx]->pixels,
+ m_specific->m_surf_img[idx]->w,
+ m_specific->m_surf_img[idx]->h,
+ m_flip_y ? -m_specific->m_surf_img[idx]->pitch :
+ m_specific->m_surf_img[idx]->pitch);
+ return true;
+
+ }
+ return false;
+ }
+
+
+
+
+ //------------------------------------------------------------------------
+ bool platform_support::save_img(unsigned idx, const char* file)
+ {
+ if(idx < max_images && m_specific->m_surf_img[idx])
+ {
+ char fn[1024];
+ strcpy(fn, file);
+ int len = strlen(fn);
+ if(len < 4 || strcmp(fn + len - 4, ".bmp") != 0)
+ {
+ strcat(fn, ".bmp");
+ }
+ return SDL_SaveBMP(m_specific->m_surf_img[idx], fn) == 0;
+ }
+ return false;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool platform_support::create_img(unsigned idx, unsigned width, unsigned height)
+ {
+ if(idx < max_images)
+ {
+
+ if(m_specific->m_surf_img[idx]) SDL_FreeSurface(m_specific->m_surf_img[idx]);
+
+ m_specific->m_surf_img[idx] =
+ SDL_CreateRGBSurface(SDL_SWSURFACE,
+ width,
+ height,
+ m_specific->m_surf_screen->format->BitsPerPixel,
+ m_specific->m_rmask,
+ m_specific->m_gmask,
+ m_specific->m_bmask,
+ m_specific->m_amask);
+ if(m_specific->m_surf_img[idx] == 0)
+ {
+ fprintf(stderr, "Couldn't create image: %s\n", SDL_GetError());
+ return false;
+ }
+
+ m_rbuf_img[idx].attach((unsigned char*)m_specific->m_surf_img[idx]->pixels,
+ m_specific->m_surf_img[idx]->w,
+ m_specific->m_surf_img[idx]->h,
+ m_flip_y ? -m_specific->m_surf_img[idx]->pitch :
+ m_specific->m_surf_img[idx]->pitch);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ //------------------------------------------------------------------------
+ void platform_support::start_timer()
+ {
+ m_specific->m_sw_start = SDL_GetTicks();
+ }
+
+ //------------------------------------------------------------------------
+ double platform_support::elapsed_time() const
+ {
+ int stop = SDL_GetTicks();
+ return double(stop - m_specific->m_sw_start);
+ }
+
+ //------------------------------------------------------------------------
+ void platform_support::message(const char* msg)
+ {
+ fprintf(stderr, "%s\n", msg);
+ }
+
+ //------------------------------------------------------------------------
+ void platform_support::force_redraw()
+ {
+ m_specific->m_update_flag = true;
+ }
+
+
+ //------------------------------------------------------------------------
+ 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) {}
+
+
+}
+
+
+int agg_main(int argc, char* argv[]);
+
+int main(int argc, char* argv[])
+{
+ return agg_main(argc, argv);
+}
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp
new file mode 100644
index 0000000000..ea9123802f
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp
@@ -0,0 +1,1655 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// class platform_support
+//
+//----------------------------------------------------------------------------
+
+#include <windows.h>
+#include <string.h>
+#include "platform/agg_platform_support.h"
+#include "platform/win32/agg_win32_bmp.h"
+#include "util/agg_color_conv.h"
+#include "util/agg_color_conv_rgb8.h"
+#include "util/agg_color_conv_rgb16.h"
+#include "agg_pixfmt_gray.h"
+#include "agg_pixfmt_rgb.h"
+#include "agg_pixfmt_rgba.h"
+
+
+namespace agg
+{
+
+ //------------------------------------------------------------------------
+ HINSTANCE g_windows_instance = 0;
+ int g_windows_cmd_show = 0;
+
+
+ //------------------------------------------------------------------------
+ class platform_specific
+ {
+ public:
+ platform_specific(pix_format_e format, bool flip_y);
+
+ void create_pmap(unsigned width, unsigned height,
+ rendering_buffer* wnd);
+
+ void display_pmap(HDC dc, const rendering_buffer* src);
+ bool load_pmap(const char* fn, unsigned idx,
+ rendering_buffer* dst);
+
+ bool save_pmap(const char* fn, unsigned idx,
+ const rendering_buffer* src);
+
+ unsigned translate(unsigned keycode);
+
+ pix_format_e m_format;
+ pix_format_e m_sys_format;
+ bool m_flip_y;
+ unsigned m_bpp;
+ unsigned m_sys_bpp;
+ HWND m_hwnd;
+ pixel_map m_pmap_window;
+ pixel_map m_pmap_img[platform_support::max_images];
+ unsigned m_keymap[256];
+ unsigned m_last_translated_key;
+ int m_cur_x;
+ int m_cur_y;
+ unsigned m_input_flags;
+ bool m_redraw_flag;
+ HDC m_current_dc;
+ LARGE_INTEGER m_sw_freq;
+ LARGE_INTEGER m_sw_start;
+ };
+
+
+ //------------------------------------------------------------------------
+ platform_specific::platform_specific(pix_format_e format, bool flip_y) :
+ m_format(format),
+ m_sys_format(pix_format_undefined),
+ m_flip_y(flip_y),
+ m_bpp(0),
+ m_sys_bpp(0),
+ m_hwnd(0),
+ m_last_translated_key(0),
+ m_cur_x(0),
+ m_cur_y(0),
+ m_input_flags(0),
+ m_redraw_flag(true),
+ m_current_dc(0)
+ {
+ memset(m_keymap, 0, sizeof(m_keymap));
+
+ m_keymap[VK_PAUSE] = key_pause;
+ m_keymap[VK_CLEAR] = key_clear;
+
+ m_keymap[VK_NUMPAD0] = key_kp0;
+ m_keymap[VK_NUMPAD1] = key_kp1;
+ m_keymap[VK_NUMPAD2] = key_kp2;
+ m_keymap[VK_NUMPAD3] = key_kp3;
+ m_keymap[VK_NUMPAD4] = key_kp4;
+ m_keymap[VK_NUMPAD5] = key_kp5;
+ m_keymap[VK_NUMPAD6] = key_kp6;
+ m_keymap[VK_NUMPAD7] = key_kp7;
+ m_keymap[VK_NUMPAD8] = key_kp8;
+ m_keymap[VK_NUMPAD9] = key_kp9;
+ m_keymap[VK_DECIMAL] = key_kp_period;
+ m_keymap[VK_DIVIDE] = key_kp_divide;
+ m_keymap[VK_MULTIPLY] = key_kp_multiply;
+ m_keymap[VK_SUBTRACT] = key_kp_minus;
+ m_keymap[VK_ADD] = key_kp_plus;
+
+ m_keymap[VK_UP] = key_up;
+ m_keymap[VK_DOWN] = key_down;
+ m_keymap[VK_RIGHT] = key_right;
+ m_keymap[VK_LEFT] = key_left;
+ m_keymap[VK_INSERT] = key_insert;
+ m_keymap[VK_DELETE] = key_delete;
+ m_keymap[VK_HOME] = key_home;
+ m_keymap[VK_END] = key_end;
+ m_keymap[VK_PRIOR] = key_page_up;
+ m_keymap[VK_NEXT] = key_page_down;
+
+ m_keymap[VK_F1] = key_f1;
+ m_keymap[VK_F2] = key_f2;
+ m_keymap[VK_F3] = key_f3;
+ m_keymap[VK_F4] = key_f4;
+ m_keymap[VK_F5] = key_f5;
+ m_keymap[VK_F6] = key_f6;
+ m_keymap[VK_F7] = key_f7;
+ m_keymap[VK_F8] = key_f8;
+ m_keymap[VK_F9] = key_f9;
+ m_keymap[VK_F10] = key_f10;
+ m_keymap[VK_F11] = key_f11;
+ m_keymap[VK_F12] = key_f12;
+ m_keymap[VK_F13] = key_f13;
+ m_keymap[VK_F14] = key_f14;
+ m_keymap[VK_F15] = key_f15;
+
+ m_keymap[VK_NUMLOCK] = key_numlock;
+ m_keymap[VK_CAPITAL] = key_capslock;
+ m_keymap[VK_SCROLL] = key_scrollock;
+
+
+ switch(m_format)
+ {
+ case pix_format_bw:
+ m_sys_format = pix_format_bw;
+ m_bpp = 1;
+ m_sys_bpp = 1;
+ break;
+
+ case pix_format_gray8:
+ case pix_format_sgray8:
+ m_sys_format = pix_format_sgray8;
+ m_bpp = 8;
+ m_sys_bpp = 8;
+ break;
+
+ case pix_format_gray16:
+ m_sys_format = pix_format_sgray8;
+ m_bpp = 16;
+ m_sys_bpp = 8;
+ break;
+
+ case pix_format_gray32:
+ m_sys_format = pix_format_sgray8;
+ m_bpp = 32;
+ m_sys_bpp = 8;
+ break;
+
+ case pix_format_rgb565:
+ case pix_format_rgb555:
+ m_sys_format = pix_format_rgb555;
+ m_bpp = 16;
+ m_sys_bpp = 16;
+ break;
+
+ case pix_format_rgbAAA:
+ case pix_format_bgrAAA:
+ case pix_format_rgbBBA:
+ case pix_format_bgrABB:
+ m_sys_format = pix_format_bgr24;
+ m_bpp = 32;
+ m_sys_bpp = 24;
+ break;
+
+ case pix_format_rgb24:
+ case pix_format_bgr24:
+ case pix_format_srgb24:
+ case pix_format_sbgr24:
+ m_sys_format = pix_format_sbgr24;
+ m_bpp = 24;
+ m_sys_bpp = 24;
+ break;
+
+ case pix_format_rgb48:
+ case pix_format_bgr48:
+ m_sys_format = pix_format_sbgr24;
+ m_bpp = 48;
+ m_sys_bpp = 24;
+ break;
+
+ case pix_format_rgb96:
+ case pix_format_bgr96:
+ m_sys_format = pix_format_sbgr24;
+ m_bpp = 96;
+ m_sys_bpp = 24;
+ break;
+
+ case pix_format_bgra32:
+ case pix_format_abgr32:
+ case pix_format_argb32:
+ case pix_format_rgba32:
+ case pix_format_sbgra32:
+ case pix_format_sabgr32:
+ case pix_format_sargb32:
+ case pix_format_srgba32:
+ m_sys_format = pix_format_sbgr24;
+ m_bpp = 32;
+ m_sys_bpp = 24;
+ break;
+
+ case pix_format_bgra64:
+ case pix_format_abgr64:
+ case pix_format_argb64:
+ case pix_format_rgba64:
+ m_sys_format = pix_format_sbgr24;
+ m_bpp = 64;
+ m_sys_bpp = 24;
+ break;
+
+ case pix_format_bgra128:
+ case pix_format_abgr128:
+ case pix_format_argb128:
+ case pix_format_rgba128:
+ m_sys_format = pix_format_sbgr24;
+ m_bpp = 128;
+ m_sys_bpp = 24;
+ break;
+
+ }
+ ::QueryPerformanceFrequency(&m_sw_freq);
+ ::QueryPerformanceCounter(&m_sw_start);
+ }
+
+
+ //------------------------------------------------------------------------
+ void platform_specific::create_pmap(unsigned width,
+ unsigned height,
+ rendering_buffer* wnd)
+ {
+ m_pmap_window.create(width, height, org_e(m_bpp));
+ wnd->attach(m_pmap_window.buf(),
+ m_pmap_window.width(),
+ m_pmap_window.height(),
+ m_flip_y ?
+ m_pmap_window.stride() :
+ -m_pmap_window.stride());
+ }
+
+
+ //------------------------------------------------------------------------
+ static void convert_pmap(rendering_buffer* dst,
+ const rendering_buffer* src,
+ pix_format_e format)
+ {
+ switch(format)
+ {
+ case pix_format_gray8:
+ convert<pixfmt_sgray8, pixfmt_gray8>(dst, src);
+ break;
+
+ case pix_format_gray16:
+ convert<pixfmt_sgray8, pixfmt_gray16>(dst, src);
+ break;
+
+ case pix_format_gray32:
+ convert<pixfmt_sgray8, pixfmt_gray32>(dst, src);
+ break;
+
+ case pix_format_rgb565:
+ color_conv(dst, src, color_conv_rgb565_to_rgb555());
+ break;
+
+ case pix_format_rgbAAA:
+ color_conv(dst, src, color_conv_rgbAAA_to_bgr24());
+ break;
+
+ case pix_format_bgrAAA:
+ color_conv(dst, src, color_conv_bgrAAA_to_bgr24());
+ break;
+
+ case pix_format_rgbBBA:
+ color_conv(dst, src, color_conv_rgbBBA_to_bgr24());
+ break;
+
+ case pix_format_bgrABB:
+ color_conv(dst, src, color_conv_bgrABB_to_bgr24());
+ break;
+
+ case pix_format_srgb24:
+ color_conv(dst, src, color_conv_rgb24_to_bgr24());
+ break;
+
+ case pix_format_rgb24:
+ convert<pixfmt_sbgr24, pixfmt_rgb24>(dst, src);
+ break;
+
+ case pix_format_bgr24:
+ convert<pixfmt_sbgr24, pixfmt_bgr24>(dst, src);
+ break;
+
+ case pix_format_rgb48:
+ convert<pixfmt_sbgr24, pixfmt_rgb48>(dst, src);
+ break;
+
+ case pix_format_bgr48:
+ convert<pixfmt_sbgr24, pixfmt_bgr48>(dst, src);
+ break;
+
+ case pix_format_bgra32:
+ convert<pixfmt_sbgr24, pixfmt_bgrx32>(dst, src);
+ break;
+
+ case pix_format_abgr32:
+ convert<pixfmt_sbgr24, pixfmt_xbgr32>(dst, src);
+ break;
+
+ case pix_format_argb32:
+ convert<pixfmt_sbgr24, pixfmt_xrgb32>(dst, src);
+ break;
+
+ case pix_format_rgba32:
+ convert<pixfmt_sbgr24, pixfmt_rgbx32>(dst, src);
+ break;
+
+ case pix_format_sbgra32:
+ convert<pixfmt_sbgr24, pixfmt_sbgrx32>(dst, src);
+ break;
+
+ case pix_format_sabgr32:
+ convert<pixfmt_sbgr24, pixfmt_sxbgr32>(dst, src);
+ break;
+
+ case pix_format_sargb32:
+ convert<pixfmt_sbgr24, pixfmt_sxrgb32>(dst, src);
+ break;
+
+ case pix_format_srgba32:
+ convert<pixfmt_sbgr24, pixfmt_srgbx32>(dst, src);
+ break;
+
+ case pix_format_bgra64:
+ convert<pixfmt_sbgr24, pixfmt_bgrx64>(dst, src);
+ break;
+
+ case pix_format_abgr64:
+ convert<pixfmt_sbgr24, pixfmt_xbgr64>(dst, src);
+ break;
+
+ case pix_format_argb64:
+ convert<pixfmt_sbgr24, pixfmt_xrgb64>(dst, src);
+ break;
+
+ case pix_format_rgba64:
+ convert<pixfmt_sbgr24, pixfmt_rgbx64>(dst, src);
+ break;
+
+ case pix_format_rgb96:
+ convert<pixfmt_sbgr24, pixfmt_rgb96>(dst, src);
+ break;
+
+ case pix_format_bgr96:
+ convert<pixfmt_sbgr24, pixfmt_bgr96>(dst, src);
+ break;
+
+ case pix_format_bgra128:
+ convert<pixfmt_sbgr24, pixfmt_bgrx128>(dst, src);
+ break;
+
+ case pix_format_abgr128:
+ convert<pixfmt_sbgr24, pixfmt_xbgr128>(dst, src);
+ break;
+
+ case pix_format_argb128:
+ convert<pixfmt_sbgr24, pixfmt_xrgb128>(dst, src);
+ break;
+
+ case pix_format_rgba128:
+ convert<pixfmt_sbgr24, pixfmt_rgbx128>(dst, src);
+ break;
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ void platform_specific::display_pmap(HDC dc, const rendering_buffer* src)
+ {
+ if(m_sys_format == m_format)
+ {
+ m_pmap_window.draw(dc);
+ }
+ else
+ {
+ pixel_map pmap_tmp;
+ pmap_tmp.create(m_pmap_window.width(),
+ m_pmap_window.height(),
+ org_e(m_sys_bpp));
+
+ rendering_buffer rbuf_tmp;
+ rbuf_tmp.attach(pmap_tmp.buf(),
+ pmap_tmp.width(),
+ pmap_tmp.height(),
+ m_flip_y ?
+ pmap_tmp.stride() :
+ -pmap_tmp.stride());
+
+ convert_pmap(&rbuf_tmp, src, m_format);
+ pmap_tmp.draw(dc);
+ }
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool platform_specific::save_pmap(const char* fn, unsigned idx,
+ const rendering_buffer* src)
+ {
+ if(m_sys_format == m_format)
+ {
+ return m_pmap_img[idx].save_as_bmp(fn);
+ }
+
+ pixel_map pmap_tmp;
+ pmap_tmp.create(m_pmap_img[idx].width(),
+ m_pmap_img[idx].height(),
+ org_e(m_sys_bpp));
+
+ rendering_buffer rbuf_tmp;
+ rbuf_tmp.attach(pmap_tmp.buf(),
+ pmap_tmp.width(),
+ pmap_tmp.height(),
+ m_flip_y ?
+ pmap_tmp.stride() :
+ -pmap_tmp.stride());
+
+ convert_pmap(&rbuf_tmp, src, m_format);
+ return pmap_tmp.save_as_bmp(fn);
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool platform_specific::load_pmap(const char* fn, unsigned idx,
+ rendering_buffer* dst)
+ {
+ pixel_map pmap_tmp;
+ if(!pmap_tmp.load_from_bmp(fn)) return false;
+
+ rendering_buffer rbuf_tmp;
+ rbuf_tmp.attach(pmap_tmp.buf(),
+ pmap_tmp.width(),
+ pmap_tmp.height(),
+ m_flip_y ?
+ pmap_tmp.stride() :
+ -pmap_tmp.stride());
+
+ m_pmap_img[idx].create(pmap_tmp.width(),
+ pmap_tmp.height(),
+ org_e(m_bpp),
+ 0);
+
+ dst->attach(m_pmap_img[idx].buf(),
+ m_pmap_img[idx].width(),
+ m_pmap_img[idx].height(),
+ m_flip_y ?
+ m_pmap_img[idx].stride() :
+ -m_pmap_img[idx].stride());
+
+ switch(m_format)
+ {
+ case pix_format_sgray8:
+ switch(pmap_tmp.bpp())
+ {
+ //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_gray8()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_gray8()); break;
+ //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray8()); break;
+ }
+ break;
+
+ case pix_format_gray8:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_gray8, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+
+ case pix_format_gray16:
+ switch(pmap_tmp.bpp())
+ {
+ //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_gray16()); break;
+ case 24: convert<pixfmt_gray16, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray16()); break;
+ }
+ break;
+
+ case pix_format_gray32:
+ switch(pmap_tmp.bpp())
+ {
+ //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_gray32()); break;
+ case 24: convert<pixfmt_gray32, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray32()); break;
+ }
+ break;
+
+ case pix_format_rgb555:
+ switch(pmap_tmp.bpp())
+ {
+ case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb555()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgb555()); break;
+ case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb555()); break;
+ }
+ break;
+
+ case pix_format_rgb565:
+ switch(pmap_tmp.bpp())
+ {
+ case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb565()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgb565()); break;
+ case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb565()); break;
+ }
+ break;
+
+ case pix_format_srgb24:
+ switch(pmap_tmp.bpp())
+ {
+ case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb24()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgb24()); break;
+ case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb24()); break;
+ }
+ break;
+
+ case pix_format_sbgr24:
+ switch(pmap_tmp.bpp())
+ {
+ case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgr24()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_bgr24()); break;
+ case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgr24()); break;
+ }
+ break;
+
+ case pix_format_rgb24:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_rgb24, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+
+ case pix_format_bgr24:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_bgr24, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+
+ case pix_format_rgb48:
+ switch(pmap_tmp.bpp())
+ {
+ //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb48()); break;
+ case 24: convert<pixfmt_rgb48, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb48()); break;
+ }
+ break;
+
+ case pix_format_bgr48:
+ switch(pmap_tmp.bpp())
+ {
+ //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgr48()); break;
+ case 24: convert<pixfmt_bgr48, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgr48()); break;
+ }
+ break;
+
+ case pix_format_sabgr32:
+ switch(pmap_tmp.bpp())
+ {
+ case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_abgr32()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_abgr32()); break;
+ case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_abgr32()); break;
+ }
+ break;
+
+ case pix_format_sargb32:
+ switch(pmap_tmp.bpp())
+ {
+ case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_argb32()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_argb32()); break;
+ case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_argb32()); break;
+ }
+ break;
+
+ case pix_format_sbgra32:
+ switch(pmap_tmp.bpp())
+ {
+ case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgra32()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_bgra32()); break;
+ case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgra32()); break;
+ }
+ break;
+
+ case pix_format_srgba32:
+ switch(pmap_tmp.bpp())
+ {
+ case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgba32()); break;
+ case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgba32()); break;
+ case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgba32()); break;
+ }
+ break;
+
+ case pix_format_abgr32:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_abgr32, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+
+ case pix_format_argb32:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_argb32, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+
+ case pix_format_bgra32:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_bgra32, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+
+ case pix_format_rgba32:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_rgba32, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+
+ case pix_format_abgr64:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_abgr64, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+
+ case pix_format_argb64:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_argb64, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+
+ case pix_format_bgra64:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_bgra64, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+
+ case pix_format_rgba64:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_rgba64, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+
+ case pix_format_rgb96:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_rgb96, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+
+ case pix_format_bgr96:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_bgr96, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+
+ case pix_format_abgr128:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_abgr128, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+
+ case pix_format_argb128:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_argb128, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+
+ case pix_format_bgra128:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_bgra128, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+
+ case pix_format_rgba128:
+ switch(pmap_tmp.bpp())
+ {
+ case 24: convert<pixfmt_rgba128, pixfmt_sbgr24>(dst, &rbuf_tmp); break;
+ }
+ break;
+ }
+
+ return true;
+ }
+
+
+
+
+
+
+
+
+ //------------------------------------------------------------------------
+ unsigned platform_specific::translate(unsigned keycode)
+ {
+ return m_last_translated_key = (keycode > 255) ? 0 : m_keymap[keycode];
+ }
+
+
+
+ //------------------------------------------------------------------------
+ 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, "Anti-Grain Geometry Application");
+ }
+
+
+ //------------------------------------------------------------------------
+ platform_support::~platform_support()
+ {
+ delete m_specific;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ void platform_support::caption(const char* cap)
+ {
+ strcpy(m_caption, cap);
+ if(m_specific->m_hwnd)
+ {
+ SetWindowText(m_specific->m_hwnd, m_caption);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ void platform_support::start_timer()
+ {
+ ::QueryPerformanceCounter(&(m_specific->m_sw_start));
+ }
+
+ //------------------------------------------------------------------------
+ double platform_support::elapsed_time() const
+ {
+ LARGE_INTEGER stop;
+ ::QueryPerformanceCounter(&stop);
+ return double(stop.QuadPart -
+ m_specific->m_sw_start.QuadPart) * 1000.0 /
+ double(m_specific->m_sw_freq.QuadPart);
+ }
+
+
+
+ //------------------------------------------------------------------------
+ static unsigned get_key_flags(int wflags)
+ {
+ unsigned flags = 0;
+ if(wflags & MK_LBUTTON) flags |= mouse_left;
+ if(wflags & MK_RBUTTON) flags |= mouse_right;
+ if(wflags & MK_SHIFT) flags |= kbd_shift;
+ if(wflags & MK_CONTROL) flags |= kbd_ctrl;
+ return flags;
+ }
+
+
+ void* platform_support::raw_display_handler()
+ {
+ return m_specific->m_current_dc;
+ }
+
+
+ //------------------------------------------------------------------------
+ LRESULT CALLBACK window_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+ {
+ PAINTSTRUCT ps;
+ HDC paintDC;
+
+
+ void* user_data = reinterpret_cast<void*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
+ platform_support* app = 0;
+
+ if(user_data)
+ {
+ app = reinterpret_cast<platform_support*>(user_data);
+ }
+
+ if(app == 0)
+ {
+ if(msg == WM_DESTROY)
+ {
+ ::PostQuitMessage(0);
+ return 0;
+ }
+ return ::DefWindowProc(hWnd, msg, wParam, lParam);
+ }
+
+ HDC dc = ::GetDC(app->m_specific->m_hwnd);
+ app->m_specific->m_current_dc = dc;
+ LRESULT ret = 0;
+
+ switch(msg)
+ {
+ //--------------------------------------------------------------------
+ case WM_CREATE:
+ break;
+
+ //--------------------------------------------------------------------
+ case WM_SIZE:
+ app->m_specific->create_pmap(LOWORD(lParam),
+ HIWORD(lParam),
+ &app->rbuf_window());
+
+ app->trans_affine_resizing(LOWORD(lParam), HIWORD(lParam));
+ app->on_resize(LOWORD(lParam), HIWORD(lParam));
+ app->force_redraw();
+ break;
+
+ //--------------------------------------------------------------------
+ case WM_ERASEBKGND:
+ break;
+
+ //--------------------------------------------------------------------
+ case WM_LBUTTONDOWN:
+ ::SetCapture(app->m_specific->m_hwnd);
+ app->m_specific->m_cur_x = int16(LOWORD(lParam));
+ if(app->flip_y())
+ {
+ app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam));
+ }
+ else
+ {
+ app->m_specific->m_cur_y = int16(HIWORD(lParam));
+ }
+ app->m_specific->m_input_flags = mouse_left | get_key_flags(wParam);
+
+ app->m_ctrls.set_cur(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y);
+ if(app->m_ctrls.on_mouse_button_down(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y))
+ {
+ app->on_ctrl_change();
+ app->force_redraw();
+ }
+ else
+ {
+ if(app->m_ctrls.in_rect(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y))
+ {
+ if(app->m_ctrls.set_cur(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y))
+ {
+ app->on_ctrl_change();
+ app->force_redraw();
+ }
+ }
+ else
+ {
+ app->on_mouse_button_down(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y,
+ app->m_specific->m_input_flags);
+ }
+ }
+/*
+ if(!app->wait_mode())
+ {
+ app->on_idle();
+ }
+*/
+ break;
+
+ //--------------------------------------------------------------------
+ case WM_LBUTTONUP:
+ ::ReleaseCapture();
+ app->m_specific->m_cur_x = int16(LOWORD(lParam));
+ if(app->flip_y())
+ {
+ app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam));
+ }
+ else
+ {
+ app->m_specific->m_cur_y = int16(HIWORD(lParam));
+ }
+ app->m_specific->m_input_flags = mouse_left | get_key_flags(wParam);
+
+ if(app->m_ctrls.on_mouse_button_up(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y))
+ {
+ app->on_ctrl_change();
+ app->force_redraw();
+ }
+ app->on_mouse_button_up(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y,
+ app->m_specific->m_input_flags);
+/*
+ if(!app->wait_mode())
+ {
+ app->on_idle();
+ }
+*/
+ break;
+
+
+ //--------------------------------------------------------------------
+ case WM_RBUTTONDOWN:
+ ::SetCapture(app->m_specific->m_hwnd);
+ app->m_specific->m_cur_x = int16(LOWORD(lParam));
+ if(app->flip_y())
+ {
+ app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam));
+ }
+ else
+ {
+ app->m_specific->m_cur_y = int16(HIWORD(lParam));
+ }
+ app->m_specific->m_input_flags = mouse_right | get_key_flags(wParam);
+ app->on_mouse_button_down(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y,
+ app->m_specific->m_input_flags);
+/*
+ if(!app->wait_mode())
+ {
+ app->on_idle();
+ }
+*/
+ break;
+
+ //--------------------------------------------------------------------
+ case WM_RBUTTONUP:
+ ::ReleaseCapture();
+ app->m_specific->m_cur_x = int16(LOWORD(lParam));
+ if(app->flip_y())
+ {
+ app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam));
+ }
+ else
+ {
+ app->m_specific->m_cur_y = int16(HIWORD(lParam));
+ }
+ app->m_specific->m_input_flags = mouse_right | get_key_flags(wParam);
+ app->on_mouse_button_up(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y,
+ app->m_specific->m_input_flags);
+/*
+ if(!app->wait_mode())
+ {
+ app->on_idle();
+ }
+*/
+ break;
+
+ //--------------------------------------------------------------------
+ case WM_MOUSEMOVE:
+ app->m_specific->m_cur_x = int16(LOWORD(lParam));
+ if(app->flip_y())
+ {
+ app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam));
+ }
+ else
+ {
+ app->m_specific->m_cur_y = int16(HIWORD(lParam));
+ }
+ app->m_specific->m_input_flags = get_key_flags(wParam);
+
+
+ if(app->m_ctrls.on_mouse_move(
+ app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y,
+ (app->m_specific->m_input_flags & mouse_left) != 0))
+ {
+ app->on_ctrl_change();
+ app->force_redraw();
+ }
+ else
+ {
+ if(!app->m_ctrls.in_rect(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y))
+ {
+ app->on_mouse_move(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y,
+ app->m_specific->m_input_flags);
+ }
+ }
+/*
+ if(!app->wait_mode())
+ {
+ app->on_idle();
+ }
+*/
+ break;
+
+ //--------------------------------------------------------------------
+ case WM_SYSKEYDOWN:
+ case WM_KEYDOWN:
+ app->m_specific->m_last_translated_key = 0;
+ switch(wParam)
+ {
+ case VK_CONTROL:
+ app->m_specific->m_input_flags |= kbd_ctrl;
+ break;
+
+ case VK_SHIFT:
+ app->m_specific->m_input_flags |= kbd_shift;
+ break;
+
+ default:
+ app->m_specific->translate(wParam);
+ break;
+ }
+
+ if(app->m_specific->m_last_translated_key)
+ {
+ bool left = false;
+ bool up = false;
+ bool right = false;
+ bool down = false;
+
+ switch(app->m_specific->m_last_translated_key)
+ {
+ 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:
+ app->copy_window_to_img(agg::platform_support::max_images - 1);
+ app->save_img(agg::platform_support::max_images - 1, "screenshot");
+ break;
+ }
+
+ if(app->window_flags() & window_process_all_keys)
+ {
+ app->on_key(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y,
+ app->m_specific->m_last_translated_key,
+ app->m_specific->m_input_flags);
+ }
+ else
+ {
+ if(app->m_ctrls.on_arrow_keys(left, right, down, up))
+ {
+ app->on_ctrl_change();
+ app->force_redraw();
+ }
+ else
+ {
+ app->on_key(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y,
+ app->m_specific->m_last_translated_key,
+ app->m_specific->m_input_flags);
+ }
+ }
+ }
+/*
+ if(!app->wait_mode())
+ {
+ app->on_idle();
+ }
+*/
+ break;
+
+ //--------------------------------------------------------------------
+ case WM_SYSKEYUP:
+ case WM_KEYUP:
+ app->m_specific->m_last_translated_key = 0;
+ switch(wParam)
+ {
+ case VK_CONTROL:
+ app->m_specific->m_input_flags &= ~kbd_ctrl;
+ break;
+
+ case VK_SHIFT:
+ app->m_specific->m_input_flags &= ~kbd_shift;
+ break;
+ }
+ break;
+
+ //--------------------------------------------------------------------
+ case WM_CHAR:
+ case WM_SYSCHAR:
+ if(app->m_specific->m_last_translated_key == 0)
+ {
+ app->on_key(app->m_specific->m_cur_x,
+ app->m_specific->m_cur_y,
+ wParam,
+ app->m_specific->m_input_flags);
+ }
+ break;
+
+ //--------------------------------------------------------------------
+ case WM_PAINT:
+ paintDC = ::BeginPaint(hWnd, &ps);
+ app->m_specific->m_current_dc = paintDC;
+ if(app->m_specific->m_redraw_flag)
+ {
+ app->on_draw();
+ app->m_specific->m_redraw_flag = false;
+ }
+ app->m_specific->display_pmap(paintDC, &app->rbuf_window());
+ app->on_post_draw(paintDC);
+ app->m_specific->m_current_dc = 0;
+ ::EndPaint(hWnd, &ps);
+ break;
+
+ //--------------------------------------------------------------------
+ case WM_COMMAND:
+ break;
+
+ //--------------------------------------------------------------------
+ case WM_DESTROY:
+ ::PostQuitMessage(0);
+ break;
+
+ //--------------------------------------------------------------------
+ default:
+ ret = ::DefWindowProc(hWnd, msg, wParam, lParam);
+ break;
+ }
+ app->m_specific->m_current_dc = 0;
+ ::ReleaseDC(app->m_specific->m_hwnd, dc);
+ return ret;
+ }
+
+
+ //------------------------------------------------------------------------
+ void platform_support::message(const char* msg)
+ {
+ ::MessageBox(m_specific->m_hwnd, msg, "AGG Message", MB_OK);
+ }
+
+
+ //------------------------------------------------------------------------
+ bool platform_support::init(unsigned width, unsigned height, unsigned flags)
+ {
+ if(m_specific->m_sys_format == pix_format_undefined)
+ {
+ return false;
+ }
+
+ m_window_flags = flags;
+
+ int wflags = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
+
+ WNDCLASS wc;
+ wc.lpszClassName = "AGGAppClass";
+ wc.lpfnWndProc = window_proc;
+ wc.style = wflags;
+ wc.hInstance = g_windows_instance;
+ wc.hIcon = LoadIcon(0, IDI_APPLICATION);
+ wc.hCursor = LoadCursor(0, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ wc.lpszMenuName = "AGGAppMenu";
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ ::RegisterClass(&wc);
+
+ wflags = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
+
+ if(m_window_flags & window_resize)
+ {
+ wflags |= WS_THICKFRAME | WS_MAXIMIZEBOX;
+ }
+
+ m_specific->m_hwnd = ::CreateWindow("AGGAppClass",
+ m_caption,
+ wflags,
+ 100,
+ 100,
+ width,
+ height,
+ 0,
+ 0,
+ g_windows_instance,
+ 0);
+
+ if(m_specific->m_hwnd == 0)
+ {
+ return false;
+ }
+
+
+ RECT rct;
+ ::GetClientRect(m_specific->m_hwnd, &rct);
+
+ ::MoveWindow(m_specific->m_hwnd, // handle to window
+ 100, // horizontal position
+ 100, // vertical position
+ width + (width - (rct.right - rct.left)),
+ height + (height - (rct.bottom - rct.top)),
+ FALSE);
+
+ ::SetWindowLongPtr(m_specific->m_hwnd, GWLP_USERDATA, (LONG)this);
+ m_specific->create_pmap(width, height, &m_rbuf_window);
+ m_initial_width = width;
+ m_initial_height = height;
+ on_init();
+ m_specific->m_redraw_flag = true;
+ ::ShowWindow(m_specific->m_hwnd, g_windows_cmd_show);
+ return true;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ int platform_support::run()
+ {
+ MSG msg;
+
+ for(;;)
+ {
+ if(m_wait_mode)
+ {
+ if(!::GetMessage(&msg, 0, 0, 0))
+ {
+ break;
+ }
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+ }
+ else
+ {
+ if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
+ {
+ ::TranslateMessage(&msg);
+ if(msg.message == WM_QUIT)
+ {
+ break;
+ }
+ ::DispatchMessage(&msg);
+ }
+ else
+ {
+ on_idle();
+ }
+ }
+ }
+ return (int)msg.wParam;
+ }
+
+
+ //------------------------------------------------------------------------
+ const char* platform_support::img_ext() const { return ".bmp"; }
+
+
+ //------------------------------------------------------------------------
+ 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 fn[1024];
+ strcpy(fn, file);
+ int len = strlen(fn);
+ if(len < 4 || _stricmp(fn + len - 4, ".BMP") != 0)
+ {
+ strcat(fn, ".bmp");
+ }
+ return m_specific->load_pmap(fn, idx, &m_rbuf_img[idx]);
+ }
+ return true;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool platform_support::save_img(unsigned idx, const char* file)
+ {
+ if(idx < max_images)
+ {
+ char fn[1024];
+ strcpy(fn, file);
+ int len = strlen(fn);
+ if(len < 4 || _stricmp(fn + len - 4, ".BMP") != 0)
+ {
+ strcat(fn, ".bmp");
+ }
+ return m_specific->save_pmap(fn, idx, &m_rbuf_img[idx]);
+ }
+ return true;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool platform_support::create_img(unsigned idx, unsigned width, unsigned height)
+ {
+ if(idx < max_images)
+ {
+ if(width == 0) width = m_specific->m_pmap_window.width();
+ if(height == 0) height = m_specific->m_pmap_window.height();
+ m_specific->m_pmap_img[idx].create(width, height, org_e(m_specific->m_bpp));
+ m_rbuf_img[idx].attach(m_specific->m_pmap_img[idx].buf(),
+ m_specific->m_pmap_img[idx].width(),
+ m_specific->m_pmap_img[idx].height(),
+ m_flip_y ?
+ m_specific->m_pmap_img[idx].stride() :
+ -m_specific->m_pmap_img[idx].stride());
+ return true;
+ }
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ void platform_support::force_redraw()
+ {
+ m_specific->m_redraw_flag = true;
+ ::InvalidateRect(m_specific->m_hwnd, 0, FALSE);
+ }
+
+
+
+ //------------------------------------------------------------------------
+ void platform_support::update_window()
+ {
+ HDC dc = ::GetDC(m_specific->m_hwnd);
+ m_specific->display_pmap(dc, &m_rbuf_window);
+ ::ReleaseDC(m_specific->m_hwnd, dc);
+ }
+
+
+ //------------------------------------------------------------------------
+ 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) {}
+}
+
+
+
+
+namespace agg
+{
+ // That's ridiculous. I have to parse the command line by myself
+ // because Windows doesn't provide a method of getting the command
+ // line arguments in a form of argc, argv. Of course, there's
+ // CommandLineToArgv() but first, it returns Unicode that I don't
+ // need to deal with, but most of all, it's not compatible with Win98.
+ //-----------------------------------------------------------------------
+ class tokenizer
+ {
+ public:
+ enum sep_flag
+ {
+ single,
+ multiple,
+ whole_str
+ };
+
+ struct token
+ {
+ const char* ptr;
+ unsigned len;
+ };
+
+ public:
+ tokenizer(const char* sep,
+ const char* trim=0,
+ const char* quote="\"",
+ char mask_chr='\\',
+ sep_flag sf=multiple);
+
+ void set_str(const char* str);
+ token next_token();
+
+ private:
+ int check_chr(const char *str, char chr);
+
+ private:
+ const char* m_src_string;
+ int m_start;
+ const char* m_sep;
+ const char* m_trim;
+ const char* m_quote;
+ char m_mask_chr;
+ unsigned m_sep_len;
+ sep_flag m_sep_flag;
+ };
+
+
+
+ //-----------------------------------------------------------------------
+ inline void tokenizer::set_str(const char* str)
+ {
+ m_src_string = str;
+ m_start = 0;
+ }
+
+
+ //-----------------------------------------------------------------------
+ inline int tokenizer::check_chr(const char *str, char chr)
+ {
+ return int(strchr(str, chr));
+ }
+
+
+ //-----------------------------------------------------------------------
+ tokenizer::tokenizer(const char* sep,
+ const char* trim,
+ const char* quote,
+ char mask_chr,
+ sep_flag sf) :
+ m_src_string(0),
+ m_start(0),
+ m_sep(sep),
+ m_trim(trim),
+ m_quote(quote),
+ m_mask_chr(mask_chr),
+ m_sep_len(sep ? strlen(sep) : 0),
+ m_sep_flag(sep ? sf : single)
+ {
+ }
+
+
+ //-----------------------------------------------------------------------
+ tokenizer::token tokenizer::next_token()
+ {
+ unsigned count = 0;
+ char quote_chr = 0;
+ token tok;
+
+ tok.ptr = 0;
+ tok.len = 0;
+ if(m_src_string == 0 || m_start == -1) return tok;
+
+ const char *pstr = m_src_string + m_start;
+
+ if(*pstr == 0)
+ {
+ m_start = -1;
+ return tok;
+ }
+
+ int sep_len = 1;
+ if(m_sep_flag == whole_str) sep_len = m_sep_len;
+
+ if(m_sep_flag == multiple)
+ {
+ //Pass all the separator symbols at the begin of the string
+ while(*pstr && check_chr(m_sep, *pstr))
+ {
+ ++pstr;
+ ++m_start;
+ }
+ }
+
+ if(*pstr == 0)
+ {
+ m_start = -1;
+ return tok;
+ }
+
+ for(count = 0;; ++count)
+ {
+ char c = *pstr;
+ int found = 0;
+
+ //We are outside of qotation: find one of separator symbols
+ if(quote_chr == 0)
+ {
+ if(sep_len == 1)
+ {
+ found = check_chr(m_sep, c);
+ }
+ else
+ {
+ found = strncmp(m_sep, pstr, m_sep_len) == 0;
+ }
+ }
+
+ ++pstr;
+
+ if(c == 0 || found)
+ {
+ if(m_trim)
+ {
+ while(count &&
+ check_chr(m_trim, m_src_string[m_start]))
+ {
+ ++m_start;
+ --count;
+ }
+
+ while(count &&
+ check_chr(m_trim, m_src_string[m_start + count - 1]))
+ {
+ --count;
+ }
+ }
+
+ tok.ptr = m_src_string + m_start;
+ tok.len = count;
+
+ //Next time it will be the next separator character
+ //But we must check, whether it is NOT the end of the string.
+ m_start += count;
+ if(c)
+ {
+ m_start += sep_len;
+ if(m_sep_flag == multiple)
+ {
+ //Pass all the separator symbols
+ //after the end of the string
+ while(check_chr(m_sep, m_src_string[m_start]))
+ {
+ ++m_start;
+ }
+ }
+ }
+ break;
+ }
+
+ //Switch quote. If it is not a quote yet, try to check any of
+ //quote symbols. Otherwise quote must be finished with quote_symb
+ if(quote_chr == 0)
+ {
+ if(check_chr(m_quote, c))
+ {
+ quote_chr = c;
+ continue;
+ }
+ }
+ else
+ {
+ //We are inside quote: pass all the mask symbols
+ if(m_mask_chr && c == m_mask_chr)
+ {
+ if(*pstr)
+ {
+ ++count;
+ ++pstr;
+ }
+ continue;
+ }
+ if(c == quote_chr)
+ {
+ quote_chr = 0;
+ continue;
+ }
+ }
+ }
+ return tok;
+ }
+
+
+}
+
+
+
+//----------------------------------------------------------------------------
+int agg_main(int argc, char* argv[]);
+
+
+
+//----------------------------------------------------------------------------
+int PASCAL WinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpszCmdLine,
+ int nCmdShow)
+{
+ agg::g_windows_instance = hInstance;
+ agg::g_windows_cmd_show = nCmdShow;
+
+ char* argv_str = new char [strlen(lpszCmdLine) + 3];
+ char* argv_ptr = argv_str;
+
+ char* argv[64];
+ memset(argv, 0, sizeof(argv));
+
+ agg::tokenizer cmd_line(" ", "\"' ", "\"'", '\\', agg::tokenizer::multiple);
+ cmd_line.set_str(lpszCmdLine);
+
+ int argc = 0;
+ argv[argc++] = argv_ptr;
+ *argv_ptr++ = 0;
+
+ while(argc < 64)
+ {
+ agg::tokenizer::token tok = cmd_line.next_token();
+ if(tok.ptr == 0) break;
+ if(tok.len)
+ {
+ memcpy(argv_ptr, tok.ptr, tok.len);
+ argv[argc++] = argv_ptr;
+ argv_ptr += tok.len;
+ *argv_ptr++ = 0;
+ }
+ }
+
+ int ret = agg_main(argc, argv);
+ delete [] argv_str;
+
+ return ret;
+}
+
+
+
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp
new file mode 100644
index 0000000000..8c3bdc83fd
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp
@@ -0,0 +1,631 @@
+//----------------------------------------------------------------------------
+//
+//----------------------------------------------------------------------------
+// Contact: mcseemagg@yahoo.com
+//----------------------------------------------------------------------------
+//
+// class pixel_map
+//
+//----------------------------------------------------------------------------
+
+#include "platform/win32/agg_win32_bmp.h"
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ //------------------------------------------------------------------------
+ pixel_map::~pixel_map()
+ {
+ destroy();
+ }
+
+
+ //------------------------------------------------------------------------
+ pixel_map::pixel_map() :
+ m_bmp(0),
+ m_buf(0),
+ m_bpp(0),
+ m_is_internal(false),
+ m_img_size(0),
+ m_full_size(0)
+
+ {
+ }
+
+
+ //------------------------------------------------------------------------
+ void pixel_map::destroy()
+ {
+ if(m_bmp && m_is_internal) delete [] (unsigned char*)m_bmp;
+ m_bmp = 0;
+ m_is_internal = false;
+ m_buf = 0;
+ }
+
+
+ //------------------------------------------------------------------------
+ void pixel_map::create(unsigned width,
+ unsigned height,
+ org_e org,
+ unsigned clear_val)
+ {
+ destroy();
+ if(width == 0) width = 1;
+ if(height == 0) height = 1;
+ m_bpp = org;
+ create_from_bmp(create_bitmap_info(width, height, m_bpp));
+ create_gray_scale_palette(m_bmp);
+ m_is_internal = true;
+ if(clear_val <= 255)
+ {
+ memset(m_buf, clear_val, m_img_size);
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ HBITMAP pixel_map::create_dib_section(HDC h_dc,
+ unsigned width,
+ unsigned height,
+ org_e org,
+ unsigned clear_val)
+ {
+ destroy();
+ if(width == 0) width = 1;
+ if(height == 0) height = 1;
+ m_bpp = org;
+ HBITMAP h_bitmap = create_dib_section_from_args(h_dc, width, height, m_bpp);
+ create_gray_scale_palette(m_bmp);
+ m_is_internal = true;
+ if(clear_val <= 255)
+ {
+ memset(m_buf, clear_val, m_img_size);
+ }
+ return h_bitmap;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ void pixel_map::clear(unsigned clear_val)
+ {
+ if(m_buf) memset(m_buf, clear_val, m_img_size);
+ }
+
+
+ //------------------------------------------------------------------------
+ void pixel_map::attach_to_bmp(BITMAPINFO *bmp)
+ {
+ if(bmp)
+ {
+ destroy();
+ create_from_bmp(bmp);
+ m_is_internal = false;
+ }
+ }
+
+
+
+ //static
+ //------------------------------------------------------------------------
+ unsigned pixel_map::calc_full_size(BITMAPINFO *bmp)
+ {
+ if(bmp == 0) return 0;
+
+ return sizeof(BITMAPINFOHEADER) +
+ sizeof(RGBQUAD) * calc_palette_size(bmp) +
+ bmp->bmiHeader.biSizeImage;
+ }
+
+ //static
+ //------------------------------------------------------------------------
+ unsigned pixel_map::calc_header_size(BITMAPINFO *bmp)
+ {
+ if(bmp == 0) return 0;
+ return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * calc_palette_size(bmp);
+ }
+
+
+ //static
+ //------------------------------------------------------------------------
+ unsigned pixel_map::calc_palette_size(unsigned clr_used, unsigned bits_per_pixel)
+ {
+ int palette_size = 0;
+
+ if(bits_per_pixel <= 8)
+ {
+ palette_size = clr_used;
+ if(palette_size == 0)
+ {
+ palette_size = 1 << bits_per_pixel;
+ }
+ }
+ return palette_size;
+ }
+
+ //static
+ //------------------------------------------------------------------------
+ unsigned pixel_map::calc_palette_size(BITMAPINFO *bmp)
+ {
+ if(bmp == 0) return 0;
+ return calc_palette_size(bmp->bmiHeader.biClrUsed, bmp->bmiHeader.biBitCount);
+ }
+
+
+ //static
+ //------------------------------------------------------------------------
+ unsigned char * pixel_map::calc_img_ptr(BITMAPINFO *bmp)
+ {
+ if(bmp == 0) return 0;
+ return ((unsigned char*)bmp) + calc_header_size(bmp);
+ }
+
+ //static
+ //------------------------------------------------------------------------
+ BITMAPINFO* pixel_map::create_bitmap_info(unsigned width,
+ unsigned height,
+ unsigned bits_per_pixel)
+ {
+ unsigned line_len = calc_row_len(width, bits_per_pixel);
+ unsigned img_size = line_len * height;
+ unsigned rgb_size = calc_palette_size(0, bits_per_pixel) * sizeof(RGBQUAD);
+ unsigned full_size = sizeof(BITMAPINFOHEADER) + rgb_size + img_size;
+
+ BITMAPINFO *bmp = (BITMAPINFO *) new unsigned char[full_size];
+
+ bmp->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmp->bmiHeader.biWidth = width;
+ bmp->bmiHeader.biHeight = height;
+ bmp->bmiHeader.biPlanes = 1;
+ bmp->bmiHeader.biBitCount = (unsigned short)bits_per_pixel;
+ bmp->bmiHeader.biCompression = 0;
+ bmp->bmiHeader.biSizeImage = img_size;
+ bmp->bmiHeader.biXPelsPerMeter = 0;
+ bmp->bmiHeader.biYPelsPerMeter = 0;
+ bmp->bmiHeader.biClrUsed = 0;
+ bmp->bmiHeader.biClrImportant = 0;
+
+ return bmp;
+ }
+
+
+ //static
+ //------------------------------------------------------------------------
+ void pixel_map::create_gray_scale_palette(BITMAPINFO *bmp)
+ {
+ if(bmp == 0) return;
+
+ unsigned rgb_size = calc_palette_size(bmp);
+ RGBQUAD *rgb = (RGBQUAD*)(((unsigned char*)bmp) + sizeof(BITMAPINFOHEADER));
+ unsigned brightness;
+ unsigned i;
+
+ for(i = 0; i < rgb_size; i++)
+ {
+ brightness = (255 * i) / (rgb_size - 1);
+ rgb->rgbBlue =
+ rgb->rgbGreen =
+ rgb->rgbRed = (unsigned char)brightness;
+ rgb->rgbReserved = 0;
+ rgb++;
+ }
+ }
+
+
+
+ //static
+ //------------------------------------------------------------------------
+ unsigned pixel_map::calc_row_len(unsigned width, unsigned bits_per_pixel)
+ {
+ unsigned n = width;
+ unsigned k;
+
+ switch(bits_per_pixel)
+ {
+ case 1: k = n;
+ n = n >> 3;
+ if(k & 7) n++;
+ break;
+
+ case 4: k = n;
+ n = n >> 1;
+ if(k & 3) n++;
+ break;
+
+ case 8:
+ break;
+
+ case 16: n *= 2;
+ break;
+
+ case 24: n *= 3;
+ break;
+
+ case 32: n *= 4;
+ break;
+
+ case 48: n *= 6;
+ break;
+
+ case 64: n *= 8;
+ break;
+
+ case 96: n *= 12;
+ break;
+
+ case 128: n *= 16;
+ break;
+
+ default: n = 0;
+ break;
+ }
+ return ((n + 3) >> 2) << 2;
+ }
+
+
+
+
+
+ //------------------------------------------------------------------------
+ void pixel_map::draw(HDC h_dc, const RECT *device_rect, const RECT *bmp_rect) const
+ {
+ if(m_bmp == 0 || m_buf == 0) return;
+
+ unsigned bmp_x = 0;
+ unsigned bmp_y = 0;
+ unsigned bmp_width = m_bmp->bmiHeader.biWidth;
+ unsigned bmp_height = m_bmp->bmiHeader.biHeight;
+ unsigned dvc_x = 0;
+ unsigned dvc_y = 0;
+ unsigned dvc_width = m_bmp->bmiHeader.biWidth;
+ unsigned dvc_height = m_bmp->bmiHeader.biHeight;
+
+ if(bmp_rect)
+ {
+ bmp_x = bmp_rect->left;
+ bmp_y = bmp_rect->top;
+ bmp_width = bmp_rect->right - bmp_rect->left;
+ bmp_height = bmp_rect->bottom - bmp_rect->top;
+ }
+
+ dvc_x = bmp_x;
+ dvc_y = bmp_y;
+ dvc_width = bmp_width;
+ dvc_height = bmp_height;
+
+ if(device_rect)
+ {
+ dvc_x = device_rect->left;
+ dvc_y = device_rect->top;
+ dvc_width = device_rect->right - device_rect->left;
+ dvc_height = device_rect->bottom - device_rect->top;
+ }
+
+ if(dvc_width != bmp_width || dvc_height != bmp_height)
+ {
+ ::SetStretchBltMode(h_dc, COLORONCOLOR);
+ ::StretchDIBits(
+ h_dc, // handle of device context
+ dvc_x, // x-coordinate of upper-left corner of source rect.
+ dvc_y, // y-coordinate of upper-left corner of source rect.
+ dvc_width, // width of source rectangle
+ dvc_height, // height of source rectangle
+ bmp_x,
+ bmp_y, // x, y -coordinates of upper-left corner of dest. rect.
+ bmp_width, // width of destination rectangle
+ bmp_height, // height of destination rectangle
+ m_buf, // address of bitmap bits
+ m_bmp, // address of bitmap data
+ DIB_RGB_COLORS, // usage
+ SRCCOPY // raster operation code
+ );
+ }
+ else
+ {
+ ::SetDIBitsToDevice(
+ h_dc, // handle to device context
+ dvc_x, // x-coordinate of upper-left corner of
+ dvc_y, // y-coordinate of upper-left corner of
+ dvc_width, // source rectangle width
+ dvc_height, // source rectangle height
+ bmp_x, // x-coordinate of lower-left corner of
+ bmp_y, // y-coordinate of lower-left corner of
+ 0, // first scan line in array
+ bmp_height, // number of scan lines
+ m_buf, // address of array with DIB bits
+ m_bmp, // address of structure with bitmap info.
+ DIB_RGB_COLORS // RGB or palette indexes
+ );
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ void pixel_map::draw(HDC h_dc, int x, int y, double scale) const
+ {
+ if(m_bmp == 0 || m_buf == 0) return;
+
+ unsigned width = unsigned(m_bmp->bmiHeader.biWidth * scale);
+ unsigned height = unsigned(m_bmp->bmiHeader.biHeight * scale);
+ RECT rect;
+ rect.left = x;
+ rect.top = y;
+ rect.right = x + width;
+ rect.bottom = y + height;
+ draw(h_dc, &rect);
+ }
+
+
+
+
+ //------------------------------------------------------------------------
+ void pixel_map::blend(HDC h_dc, const RECT *device_rect, const RECT *bmp_rect) const
+ {
+#if !defined(AGG_BMP_ALPHA_BLEND)
+ draw(h_dc, device_rect, bmp_rect);
+ return;
+#else
+ if(m_bpp != 32)
+ {
+ draw(h_dc, device_rect, bmp_rect);
+ return;
+ }
+
+ if(m_bmp == 0 || m_buf == 0) return;
+
+ unsigned bmp_x = 0;
+ unsigned bmp_y = 0;
+ unsigned bmp_width = m_bmp->bmiHeader.biWidth;
+ unsigned bmp_height = m_bmp->bmiHeader.biHeight;
+ unsigned dvc_x = 0;
+ unsigned dvc_y = 0;
+ unsigned dvc_width = m_bmp->bmiHeader.biWidth;
+ unsigned dvc_height = m_bmp->bmiHeader.biHeight;
+
+ if(bmp_rect)
+ {
+ bmp_x = bmp_rect->left;
+ bmp_y = bmp_rect->top;
+ bmp_width = bmp_rect->right - bmp_rect->left;
+ bmp_height = bmp_rect->bottom - bmp_rect->top;
+ }
+
+ dvc_x = bmp_x;
+ dvc_y = bmp_y;
+ dvc_width = bmp_width;
+ dvc_height = bmp_height;
+
+ if(device_rect)
+ {
+ dvc_x = device_rect->left;
+ dvc_y = device_rect->top;
+ dvc_width = device_rect->right - device_rect->left;
+ dvc_height = device_rect->bottom - device_rect->top;
+ }
+
+ HDC mem_dc = ::CreateCompatibleDC(h_dc);
+ void* buf = 0;
+ HBITMAP bmp = ::CreateDIBSection(
+ mem_dc,
+ m_bmp,
+ DIB_RGB_COLORS,
+ &buf,
+ 0,
+ 0
+ );
+ memcpy(buf, m_buf, m_bmp->bmiHeader.biSizeImage);
+
+ HBITMAP temp = (HBITMAP)::SelectObject(mem_dc, bmp);
+
+ BLENDFUNCTION blend;
+ blend.BlendOp = AC_SRC_OVER;
+ blend.BlendFlags = 0;
+
+#if defined(AC_SRC_ALPHA)
+ blend.AlphaFormat = AC_SRC_ALPHA;
+//#elif defined(AC_SRC_NO_PREMULT_ALPHA)
+// blend.AlphaFormat = AC_SRC_NO_PREMULT_ALPHA;
+#else
+#error "No appropriate constant for alpha format. Check version of wingdi.h, There must be AC_SRC_ALPHA or AC_SRC_NO_PREMULT_ALPHA"
+#endif
+
+ blend.SourceConstantAlpha = 255;
+ ::AlphaBlend(
+ h_dc,
+ dvc_x,
+ dvc_y,
+ dvc_width,
+ dvc_height,
+ mem_dc,
+ bmp_x,
+ bmp_y,
+ bmp_width,
+ bmp_height,
+ blend
+ );
+
+ ::SelectObject(mem_dc, temp);
+ ::DeleteObject(bmp);
+ ::DeleteObject(mem_dc);
+#endif //defined(AGG_BMP_ALPHA_BLEND)
+ }
+
+
+ //------------------------------------------------------------------------
+ void pixel_map::blend(HDC h_dc, int x, int y, double scale) const
+ {
+ if(m_bmp == 0 || m_buf == 0) return;
+ unsigned width = unsigned(m_bmp->bmiHeader.biWidth * scale);
+ unsigned height = unsigned(m_bmp->bmiHeader.biHeight * scale);
+ RECT rect;
+ rect.left = x;
+ rect.top = y;
+ rect.right = x + width;
+ rect.bottom = y + height;
+ blend(h_dc, &rect);
+ }
+
+
+ //------------------------------------------------------------------------
+ bool pixel_map::load_from_bmp(FILE *fd)
+ {
+ BITMAPFILEHEADER bmf;
+ BITMAPINFO *bmi = 0;
+ unsigned bmp_size;
+
+ fread(&bmf, sizeof(bmf), 1, fd);
+ if(bmf.bfType != 0x4D42) goto bmperr;
+
+ bmp_size = bmf.bfSize - sizeof(BITMAPFILEHEADER);
+
+ bmi = (BITMAPINFO*) new unsigned char [bmp_size];
+ if(fread(bmi, 1, bmp_size, fd) != bmp_size) goto bmperr;
+ destroy();
+ m_bpp = bmi->bmiHeader.biBitCount;
+ create_from_bmp(bmi);
+ m_is_internal = 1;
+ return true;
+
+ bmperr:
+ if(bmi) delete [] (unsigned char*) bmi;
+ return false;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool pixel_map::load_from_bmp(const char *filename)
+ {
+ FILE *fd = fopen(filename, "rb");
+ bool ret = false;
+ if(fd)
+ {
+ ret = load_from_bmp(fd);
+ fclose(fd);
+ }
+ return ret;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool pixel_map::save_as_bmp(FILE *fd) const
+ {
+ if(m_bmp == 0) return 0;
+
+ BITMAPFILEHEADER bmf;
+
+ bmf.bfType = 0x4D42;
+ bmf.bfOffBits = calc_header_size(m_bmp) + sizeof(bmf);
+ bmf.bfSize = bmf.bfOffBits + m_img_size;
+ bmf.bfReserved1 = 0;
+ bmf.bfReserved2 = 0;
+
+ fwrite(&bmf, sizeof(bmf), 1, fd);
+ fwrite(m_bmp, m_full_size, 1, fd);
+ return true;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool pixel_map::save_as_bmp(const char *filename) const
+ {
+ FILE *fd = fopen(filename, "wb");
+ bool ret = false;
+ if(fd)
+ {
+ ret = save_as_bmp(fd);
+ fclose(fd);
+ }
+ return ret;
+ }
+
+
+ //------------------------------------------------------------------------
+ unsigned char* pixel_map::buf()
+ {
+ return m_buf;
+ }
+
+ //------------------------------------------------------------------------
+ unsigned pixel_map::width() const
+ {
+ return m_bmp->bmiHeader.biWidth;
+ }
+
+ //------------------------------------------------------------------------
+ unsigned pixel_map::height() const
+ {
+ return m_bmp->bmiHeader.biHeight;
+ }
+
+ //------------------------------------------------------------------------
+ int pixel_map::stride() const
+ {
+ return calc_row_len(m_bmp->bmiHeader.biWidth,
+ m_bmp->bmiHeader.biBitCount);
+ }
+
+
+ //private
+ //------------------------------------------------------------------------
+ void pixel_map::create_from_bmp(BITMAPINFO *bmp)
+ {
+ if(bmp)
+ {
+ m_img_size = calc_row_len(bmp->bmiHeader.biWidth,
+ bmp->bmiHeader.biBitCount) *
+ bmp->bmiHeader.biHeight;
+
+ m_full_size = calc_full_size(bmp);
+ m_bmp = bmp;
+ m_buf = calc_img_ptr(bmp);
+ }
+ }
+
+
+ //private
+ //------------------------------------------------------------------------
+ HBITMAP pixel_map::create_dib_section_from_args(HDC h_dc,
+ unsigned width,
+ unsigned height,
+ unsigned bits_per_pixel)
+ {
+ unsigned line_len = calc_row_len(width, bits_per_pixel);
+ unsigned img_size = line_len * height;
+ unsigned rgb_size = calc_palette_size(0, bits_per_pixel) * sizeof(RGBQUAD);
+ unsigned full_size = sizeof(BITMAPINFOHEADER) + rgb_size;
+
+ BITMAPINFO *bmp = (BITMAPINFO *) new unsigned char[full_size];
+
+ bmp->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmp->bmiHeader.biWidth = width;
+ bmp->bmiHeader.biHeight = height;
+ bmp->bmiHeader.biPlanes = 1;
+ bmp->bmiHeader.biBitCount = (unsigned short)bits_per_pixel;
+ bmp->bmiHeader.biCompression = 0;
+ bmp->bmiHeader.biSizeImage = img_size;
+ bmp->bmiHeader.biXPelsPerMeter = 0;
+ bmp->bmiHeader.biYPelsPerMeter = 0;
+ bmp->bmiHeader.biClrUsed = 0;
+ bmp->bmiHeader.biClrImportant = 0;
+
+ void* img_ptr = 0;
+ HBITMAP h_bitmap = ::CreateDIBSection(h_dc, bmp, DIB_RGB_COLORS, &img_ptr, NULL, 0);
+
+ if(img_ptr)
+ {
+ m_img_size = calc_row_len(width, bits_per_pixel) * height;
+ m_full_size = 0;
+ m_bmp = bmp;
+ m_buf = (unsigned char *) img_ptr;
+ }
+
+ return h_bitmap;
+ }
+}
+
+
+