Add:graphics_win32:Added win32 graphics
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Sun, 19 Oct 2008 07:59:52 +0000 (07:59 +0000)
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Sun, 19 Oct 2008 07:59:52 +0000 (07:59 +0000)
git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@1505 ffa7fe5e-494d-0410-b361-a75ebd5db220

navit/navit/graphics/win32/graphics_win32.c [new file with mode: 0644]
navit/navit/graphics/win32/resources/resource.h [new file with mode: 0644]
navit/navit/graphics/win32/win32_gui.h [new file with mode: 0644]
navit/navit/graphics/win32/xpm2bmp.c [new file with mode: 0644]
navit/navit/graphics/win32/xpm2bmp.h [new file with mode: 0644]

diff --git a/navit/navit/graphics/win32/graphics_win32.c b/navit/navit/graphics/win32/graphics_win32.c
new file mode 100644 (file)
index 0000000..a9112ad
--- /dev/null
@@ -0,0 +1,774 @@
+#include <windows.h>
+#include <wingdi.h>
+#include <glib.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "debug.h"
+#include "point.h"
+#include "graphics.h"
+#include "color.h"
+#include "plugin.h"
+#include "win32_gui.h"
+#include "xpm2bmp.h"
+
+#ifndef GET_WHEEL_DELTA_WPARAM
+       #define GET_WHEEL_DELTA_WPARAM(wParam)  ((short)HIWORD(wParam))
+#endif
+
+
+static GHashTable *image_cache_hash = NULL;
+
+
+HFONT EzCreateFont (HDC hdc, TCHAR * szFaceName, int iDeciPtHeight,
+                    int iDeciPtWidth, int iAttributes, BOOL fLogRes) ;
+
+#define EZ_ATTR_BOLD          1
+#define EZ_ATTR_ITALIC        2
+#define EZ_ATTR_UNDERLINE     4
+#define EZ_ATTR_STRIKEOUT     8
+
+HFONT EzCreateFont (HDC hdc, TCHAR * szFaceName, int iDeciPtHeight,
+                    int iDeciPtWidth, int iAttributes, BOOL fLogRes)
+{
+     FLOAT      cxDpi, cyDpi ;
+     HFONT      hFont ;
+     LOGFONT    lf ;
+     POINT      pt ;
+     TEXTMETRIC tm ;
+
+     SaveDC (hdc) ;
+
+     SetGraphicsMode (hdc, GM_ADVANCED) ;
+     ModifyWorldTransform (hdc, NULL, MWT_IDENTITY) ;
+     SetViewportOrgEx (hdc, 0, 0, NULL) ;
+     SetWindowOrgEx   (hdc, 0, 0, NULL) ;
+
+     if (fLogRes)
+     {
+          cxDpi = (FLOAT) GetDeviceCaps (hdc, LOGPIXELSX) ;
+          cyDpi = (FLOAT) GetDeviceCaps (hdc, LOGPIXELSY) ;
+     }
+     else
+     {
+          cxDpi = (FLOAT) (25.4 * GetDeviceCaps (hdc, HORZRES) /
+                                        GetDeviceCaps (hdc, HORZSIZE)) ;
+
+          cyDpi = (FLOAT) (25.4 * GetDeviceCaps (hdc, VERTRES) /
+                                        GetDeviceCaps (hdc, VERTSIZE)) ;
+     }
+
+     pt.x = (int) (iDeciPtWidth  * cxDpi / 72) ;
+     pt.y = (int) (iDeciPtHeight * cyDpi / 72) ;
+
+     DPtoLP (hdc, &pt, 1) ;
+     lf.lfHeight         = - (int) (fabs (pt.y) / 10.0 + 0.5) ;
+     lf.lfWidth          = 0 ;
+     lf.lfEscapement     = 0 ;
+     lf.lfOrientation    = 0 ;
+     lf.lfWeight         = iAttributes & EZ_ATTR_BOLD      ? 700 : 0 ;
+     lf.lfItalic         = iAttributes & EZ_ATTR_ITALIC    ?   1 : 0 ;
+     lf.lfUnderline      = iAttributes & EZ_ATTR_UNDERLINE ?   1 : 0 ;
+     lf.lfStrikeOut      = iAttributes & EZ_ATTR_STRIKEOUT ?   1 : 0 ;
+     lf.lfCharSet        = DEFAULT_CHARSET ;
+     lf.lfOutPrecision   = 0 ;
+     lf.lfClipPrecision  = 0 ;
+     lf.lfQuality        = 0 ;
+     lf.lfPitchAndFamily = 0 ;
+
+     lstrcpy (lf.lfFaceName, szFaceName) ;
+
+     hFont = CreateFontIndirect (&lf) ;
+
+     if (iDeciPtWidth != 0)
+     {
+          hFont = (HFONT) SelectObject (hdc, hFont) ;
+
+          GetTextMetrics (hdc, &tm) ;
+
+          DeleteObject (SelectObject (hdc, hFont)) ;
+
+          lf.lfWidth = (int) (tm.tmAveCharWidth *
+                                        fabs (pt.x) / fabs (pt.y) + 0.5) ;
+
+          hFont = CreateFontIndirect (&lf) ;
+     }
+
+     RestoreDC (hdc, -1) ;
+     return hFont ;
+}
+
+struct graphics_image_priv {
+       PXPM2BMP pxpm;
+};
+
+
+void ErrorExit(LPTSTR lpszFunction)
+{
+    // Retrieve the system error message for the last-error code
+
+    LPVOID lpMsgBuf;
+    LPVOID lpDisplayBuf;
+    DWORD dw = GetLastError();
+
+    FormatMessage(
+        FORMAT_MESSAGE_ALLOCATE_BUFFER |
+        FORMAT_MESSAGE_FROM_SYSTEM |
+        FORMAT_MESSAGE_IGNORE_INSERTS,
+        NULL,
+        dw,
+        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+        (LPTSTR) &lpMsgBuf,
+        0, NULL );
+
+    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
+        (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR));
+    sprintf((LPTSTR)lpDisplayBuf, TEXT("%s failed with error %d: %s"), lpszFunction, dw, lpMsgBuf);
+
+    printf( "%s\n", lpDisplayBuf );
+    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
+
+    LocalFree(lpMsgBuf);
+    LocalFree(lpDisplayBuf);
+    ExitProcess(dw);
+}
+
+
+
+struct graphics_gc_priv {
+       HWND hwnd;
+       int  line_width;
+       COLORREF fg_color;
+       COLORREF bg_color;
+       struct graphics_priv *gr;
+};
+
+
+//struct graphics_priv *g_gra;
+
+static HDC hMemDC;
+static HBITMAP hBitmap;
+static HBITMAP hOldBitmap;
+
+// Fills the region 'rgn' in graded colours
+static void MakeMemoryDC(HANDLE hWnd, HDC hdc )
+{
+       if ( hMemDC )
+       {
+               if ( hOldBitmap )
+               {
+                       SelectObject( hMemDC, hOldBitmap );
+                       DeleteObject( hBitmap );
+                       hBitmap = NULL;
+                       hOldBitmap = NULL;
+               }
+       }
+
+       // Creates memory DC
+       hMemDC = CreateCompatibleDC(hdc);
+       if ( hMemDC )
+       {
+               RECT rectRgn;
+               GetClientRect( hWnd, &rectRgn );
+
+               int Width = rectRgn.right - rectRgn.left;
+               int Height = rectRgn.bottom - rectRgn.top;
+               printf( "resize memDC to: %d %d \n", Width, Height );
+
+               hBitmap = CreateCompatibleBitmap(hdc, Width, Height );
+
+               if ( hBitmap )
+               {
+                       hOldBitmap = (HBITMAP) SelectObject( hMemDC, hBitmap);
+               }
+       }
+}
+
+static void HandleButtonClick( struct graphics_priv *gra_priv, int updown, int button, long lParam )
+{
+       int xPos = LOWORD(lParam);
+       int yPos = HIWORD(lParam);
+
+       if (gra_priv->button_callback )
+       {
+               struct point pt = {xPos, yPos};
+               (*gra_priv->button_callback)(gra_priv->button_callback_data, updown, button, &pt);
+       }
+}
+
+static LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
+{
+
+//if ( Message != 15 )
+//printf( "CHILD %d %d %d \n", Message, wParam, lParam );
+
+       struct graphics_priv* gra_priv = (struct graphics_priv*)GetWindowLongPtr( hwnd , DWLP_USER );
+
+       switch(Message)
+       {
+               case WM_CREATE:
+               {
+                       HDC hdc;
+                       hdc = GetDC( hwnd );
+                       MakeMemoryDC(hwnd, hdc );
+                       ReleaseDC( hwnd, hdc );
+               }
+               break;
+               case WM_COMMAND:
+                       switch(LOWORD(wParam))
+                       {
+                               case WM_USER + 1:
+                               break;
+                       }
+               break;
+               case WM_CLOSE:
+                       DestroyWindow(hwnd);
+               break;
+               case WM_USER+1:
+                       if ( gra_priv )
+                       {
+                               RECT rc ;
+                               HDC hdc;
+
+                               GetClientRect( hwnd, &rc );
+                               gra_priv->width = rc.right;
+                               gra_priv->height = rc.bottom;
+
+                               hdc = GetDC( hwnd );
+                               MakeMemoryDC(hwnd, hdc );
+                               ReleaseDC( hwnd, hdc );
+                               (*gra_priv->resize_callback)(gra_priv->resize_callback_data, gra_priv->width, gra_priv->height);
+                       }
+               break;
+
+               case WM_SIZE:
+               /*
+                       if ( gra_priv )
+                       {
+                               //graphics = GetWindowLong( hwnd, DWL_USER, 0 );
+
+
+                               {
+                                       HDC hdc;
+                                       hdc = GetDC( hwnd );
+                                       MakeMemoryDC(hwnd, hdc );
+                                       ReleaseDC( hwnd, hdc );
+                               }
+                               (*gra_priv->resize_callback)(gra_priv->resize_callback_data, gra_priv->width, gra_priv->height);
+
+
+                       }
+                       */
+                       if ( gra_priv )
+                       {
+                               gra_priv->width = LOWORD( lParam );
+                               gra_priv->height  = HIWORD( lParam );
+                               printf( "resize gfx to: %d %d \n", gra_priv->width, gra_priv->height );
+                       }
+               break;
+               case WM_DESTROY:
+                       PostQuitMessage(0);
+                       exit( 0 );
+               break;
+               case WM_PAINT:
+                       if ( gra_priv )
+                       {
+                               HDC hdc = GetDC(hwnd );
+                               if ( hMemDC )
+                               {
+                                       BitBlt( hdc, 0, 0, gra_priv->width , gra_priv->height, hMemDC, 0, 0, SRCCOPY );
+                               }
+                               ReleaseDC( hwnd, hdc );
+                       }
+               break;
+               case WM_MOUSEMOVE:
+               {
+                       int xPos = LOWORD(lParam);
+                       int yPos = HIWORD(lParam);
+                       struct point pt = {xPos, yPos};
+
+                       // printf( "WM_MOUSEMOVE: %d %d \n", xPos, yPos );
+                       (*gra_priv->motion_callback)(gra_priv->motion_callback_data, &pt);
+               }
+
+               break;
+
+               case WM_LBUTTONDOWN:
+                       HandleButtonClick( gra_priv,1, 1,lParam );
+               break;
+               case WM_LBUTTONUP:
+                       HandleButtonClick( gra_priv, 0, 1,lParam );
+               break;
+               case WM_RBUTTONDOWN:
+                       HandleButtonClick( gra_priv, 1, 3,lParam );
+               break;
+               case WM_RBUTTONUP:
+                       HandleButtonClick( gra_priv, 0, 3,lParam );
+               break;
+
+               default:
+                       return DefWindowProc(hwnd, Message, wParam, lParam);
+       }
+       return 0;
+}
+
+
+static const char g_szClassName[] = "NAVGRA";
+
+HANDLE CreateGraphicsWindows( struct graphics_priv* gr )
+{
+       WNDCLASSEX wc;
+       HWND hwnd;
+    RECT rcParent;
+
+       wc.cbSize                = sizeof(WNDCLASSEX);
+       wc.style                 = 0;
+       wc.lpfnWndProc   = WndProc;
+       wc.cbClsExtra    = 0;
+       wc.cbWndExtra    = 64;
+       wc.hInstance     = NULL;
+       wc.hIcon                 = NULL;
+       wc.hCursor               = LoadCursor(NULL, IDC_ARROW);
+       wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+       wc.lpszMenuName  = NULL;
+       wc.lpszClassName = g_szClassName;
+       wc.hIconSm               = NULL;
+
+
+       HANDLE hdl = gr->wnd_parent_handle;
+       GetClientRect( gr->wnd_parent_handle,&rcParent);
+
+       if(!RegisterClassEx(&wc))
+       {
+               ErrorExit( "Window Registration Failed!" );
+               return NULL;
+       }
+
+       gr->width = rcParent.right - rcParent.left;
+       gr->height  = rcParent.bottom - rcParent.top;
+
+       hwnd = CreateWindow(    g_szClassName,
+                                                       "",
+                                                       WS_CHILD  ,
+                                                       0,
+                                                       0,
+                                                       gr->width,
+                                                       gr->height,
+                                                       gr->wnd_parent_handle,
+                                                       (HMENU)ID_CHILD_GFX,
+                                                       NULL,
+                                                       NULL);
+
+       if(hwnd == NULL)
+       {
+               ErrorExit( "Window Creation Failed!" );
+               return NULL;
+       }
+
+       SetWindowLongPtr( hwnd , DWLP_USER, gr );
+
+       ShowWindow( hwnd, TRUE );
+       UpdateWindow( hwnd );
+
+       gr->wnd_handle = hwnd;
+
+       PostMessage( gr->wnd_parent_handle, WM_USER + 1, 0, 0 );
+
+       return hwnd;
+}
+
+
+
+static void graphics_destroy(struct graphics_priv *gr)
+{
+       g_free( gr );
+}
+
+
+static void gc_destroy(struct graphics_gc_priv *gc)
+{
+       g_free( gc );
+}
+
+static void gc_set_linewidth(struct graphics_gc_priv *gc, int w)
+{
+       gc->line_width = w;
+}
+
+static void gc_set_dashes(struct graphics_gc_priv *gc, unsigned char *dash_list, int n)
+{
+//     gdk_gc_set_dashes(gc->gc, 0, (gint8 *)dash_list, n);
+//     gdk_gc_set_line_attributes(gc->gc, 1, GDK_LINE_ON_OFF_DASH, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+}
+
+
+
+static void gc_set_color(struct graphics_gc_priv *gc, struct color *c, int fg)
+{
+
+       gc->fg_color = RGB( c->r, c->g, c->b );
+}
+
+static void gc_set_foreground(struct graphics_gc_priv *gc, struct color *c)
+{
+       gc->fg_color = RGB( c->r, c->g, c->b );
+}
+
+static void gc_set_background(struct graphics_gc_priv *gc, struct color *c)
+{
+       gc->bg_color = RGB( c->r, c->g, c->b );
+       if ( hMemDC )
+               SetBkColor( hMemDC, gc->bg_color );
+
+}
+
+static struct graphics_gc_methods gc_methods = {
+       gc_destroy,
+       gc_set_linewidth,
+       gc_set_dashes,
+       gc_set_foreground,
+       gc_set_background
+};
+
+static struct graphics_gc_priv *gc_new(struct graphics_priv *gr, struct graphics_gc_methods *meth)
+{
+       struct graphics_gc_priv *gc=g_new(struct graphics_gc_priv, 1);
+       *meth=gc_methods;
+       gc->hwnd = gr->wnd_handle;
+       gc->line_width = 1;
+       gc->fg_color = RGB( 0,0,0 );
+       gc->bg_color = RGB( 255,255,255 );
+       return gc;
+}
+
+
+static void draw_lines(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)
+{
+       int i;
+       HPEN holdpen;
+       HPEN hpen;
+
+       hpen = CreatePen( PS_SOLID, gc->line_width, gc->fg_color );
+       holdpen = SelectObject( hMemDC, hpen );
+
+       SetBkColor( hMemDC, gc->bg_color );
+
+       int first = 1;
+       for ( i = 0; i< count; i++ )
+       {
+               if ( first )
+               {
+                       first = 0;
+                       MoveToEx( hMemDC, p[0].x, p[0].y, NULL );
+               }
+               else
+               {
+                       LineTo( hMemDC, p[i].x, p[i].y );
+               }
+       }
+
+       SelectObject( hMemDC, holdpen );
+       DeleteObject( hpen );
+}
+
+static void draw_polygon(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)
+{
+
+       //if (gr->mode == draw_mode_begin || gr->mode == draw_mode_end)
+       {
+               int i;
+               POINT points[ count ];
+               for ( i=0;i< count; i++ )
+               {
+                       points[i].x = p[i].x;
+                       points[i].y = p[i].y;
+               }
+               HBRUSH holdbrush;
+               HBRUSH hbrush;
+
+               SetBkColor( hMemDC, gc->bg_color );
+
+               hbrush = CreateSolidBrush( gc->fg_color );
+               holdbrush = SelectObject( hMemDC, hbrush );
+               Polygon( hMemDC, points,count );
+               SelectObject( hMemDC, holdbrush );
+               DeleteObject( hbrush );
+       }
+}
+
+
+static void draw_rectangle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int w, int h)
+{
+//     gdk_draw_rectangle(gr->drawable, gc->gc, TRUE, p->x, p->y, w, h);
+}
+
+static void draw_circle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int r)
+{
+       HDC dc = hMemDC;
+
+       HPEN holdpen;
+       HPEN hpen;
+
+       hpen = CreatePen( PS_SOLID, gc->line_width, gc->fg_color );
+       holdpen = SelectObject( dc, hpen );
+
+       SetBkColor( hMemDC, gc->bg_color );
+
+       Ellipse( dc, p->x - r, p->y -r, p->x + r, p->y + r );
+
+       SelectObject( dc, holdpen );
+       DeleteObject( hpen );
+
+//     if (gr->mode == draw_mode_begin || gr->mode == draw_mode_end)
+//             gdk_draw_arc(gr->drawable, gc->gc, FALSE, p->x-r/2, p->y-r/2, r, r, 0, 64*360);
+//     if (gr->mode == draw_mode_end || gr->mode == draw_mode_cursor)
+//             gdk_draw_arc(gr->widget->window, gc->gc, FALSE, p->x-r/2, p->y-r/2, r, r, 0, 64*360);
+}
+
+
+
+static void draw_restore(struct graphics_priv *gr, struct point *p, int w, int h)
+{
+       InvalidateRect( gr->wnd_handle, NULL, FALSE );
+}
+
+static void draw_mode(struct graphics_priv *gr, enum draw_mode_num mode)
+{
+       // printf( "set draw_mode to %d\n", (int)mode );
+
+       if ( mode == draw_mode_begin )
+       {
+               if ( gr->wnd_handle == NULL )
+               {
+                       CreateGraphicsWindows( gr );
+               }
+               if ( gr->mode != draw_mode_begin )
+               {
+                       if ( hMemDC )
+                       {
+                               RECT rcClient;
+                               HBRUSH bgBrush = CreateSolidBrush( gr->bg_color  );
+                               GetClientRect( gr->wnd_handle, &rcClient );
+                               FillRect( hMemDC, &rcClient, bgBrush );
+                               DeleteObject( bgBrush );
+                       }
+               }
+       }
+
+       // force paint
+       if (mode == draw_mode_end && gr->mode == draw_mode_begin)
+       {
+               InvalidateRect( gr->wnd_handle, NULL, FALSE );
+       }
+
+       gr->mode=mode;
+
+}
+
+
+static void * get_data(struct graphics_priv *this_, char *type)
+{
+       if ( strcmp( "wnd_parent_handle_ptr", type ) == 0 )
+       {
+               return &( this_->wnd_parent_handle );
+       }
+       if ( strcmp( "START_CLIENT", type ) == 0 )
+       {
+               CreateGraphicsWindows( this_ );
+               return NULL;
+       }
+       return NULL;
+}
+
+
+static void register_resize_callback(struct graphics_priv *this_, void (*callback)(void *data, int w, int h), void *data)
+{
+       this_->resize_callback=callback;
+       this_->resize_callback_data=data;
+}
+
+static void register_motion_callback(struct graphics_priv *this_, void (*callback)(void *data, struct point *p), void *data)
+{
+       this_->motion_callback=callback;
+       this_->motion_callback_data=data;
+}
+
+static void register_button_callback(struct graphics_priv *this_, void (*callback)(void *data, int press, int button, struct point *p), void *data)
+{
+       this_->button_callback=callback;
+       this_->button_callback_data=data;
+}
+
+static void background_gc(struct graphics_priv *gr, struct graphics_gc_priv *gc)
+{
+       RECT rcClient;
+       HBRUSH bgBrush = CreateSolidBrush( gc->bg_color  );
+       GetClientRect( gr->wnd_handle, &rcClient );
+       FillRect( hMemDC, &rcClient, bgBrush );
+       DeleteObject( bgBrush );
+       gr->bg_color = gc->bg_color;
+}
+
+struct graphics_font_priv {
+       LOGFONT lf;
+       HFONT hfont;
+       int size;
+};
+
+static void draw_text(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct graphics_gc_priv *bg, struct graphics_font_priv *font, char *text, struct point *p, int dx, int dy)
+{
+       RECT rcClient;
+       GetClientRect( gr->wnd_handle, &rcClient );
+
+       int prevBkMode = SetBkMode( hMemDC, TRANSPARENT );
+
+       if ( NULL == font->hfont )
+       {
+               font->hfont = EzCreateFont (hMemDC, TEXT ("Arial"), font->size/2, 0, 0, TRUE) ;
+               GetObject ( font->hfont, sizeof (LOGFONT), &font->lf) ;
+       }
+
+
+       double angle = -atan2( dy, dx ) * 180 / 3.14159 ;
+
+       SetTextAlign (hMemDC, TA_BASELINE) ;
+       SetViewportOrgEx (hMemDC, p->x, p->y, NULL) ;
+       font->lf.lfEscapement = font->lf.lfOrientation = ( angle * 10 ) ;
+       DeleteObject (font->hfont) ;
+
+       font->hfont = CreateFontIndirect (&font->lf);
+       HFONT hOldFont = SelectObject(hMemDC, font->hfont );
+
+       gunichar2* utf16 = NULL;
+       glong utf16_len = 0;
+
+       utf16 = g_utf8_to_utf16( text, -1, NULL, &utf16_len, NULL );
+       TextOutW(hMemDC, 0,0, utf16, (size_t)utf16_len );
+       g_free( utf16 );
+
+
+       SelectObject(hMemDC, hOldFont);
+       DeleteObject (font->hfont) ;
+
+       SetBkMode( hMemDC, prevBkMode );
+
+       SetViewportOrgEx (hMemDC, 0, 0, NULL) ;
+
+}
+
+
+
+static void font_destroy(struct graphics_font_priv *font)
+{
+       if ( font->hfont )
+       {
+               DeleteObject(font->hfont);
+       }
+       g_free(font);
+}
+
+static struct graphics_font_methods font_methods = {
+       font_destroy
+};
+
+static struct graphics_font_priv *font_new(struct graphics_priv *gr, struct graphics_font_methods *meth, int size)
+{
+       struct graphics_font_priv *font=g_new(struct graphics_font_priv, 1);
+       *meth = font_methods;
+
+       font->hfont = NULL;
+       font->size = size;
+    // FontFamily fontFamily( "Liberation Mono");
+//font( &fontFamily, size, FontStyleRegular, UnitPoint );
+       return font;
+}
+
+
+void image_cache_hash_add( const char* key, struct graphics_image_priv* val_ptr)
+{
+       if ( image_cache_hash == NULL ) {
+               image_cache_hash = g_hash_table_new(g_str_hash, g_str_equal);
+       }
+
+       if ( g_hash_table_lookup(image_cache_hash, key ) == NULL )
+       {
+               g_hash_table_insert(image_cache_hash, g_strdup( key ),  (gpointer)val_ptr );
+       }
+
+}
+
+struct graphics_image_priv* image_cache_hash_lookup( const char* key )
+{
+       struct graphics_image_priv* val_ptr = NULL;
+
+       if ( image_cache_hash != NULL )
+       {
+               val_ptr = g_hash_table_lookup(image_cache_hash, key );
+       }
+       return val_ptr;
+}
+
+
+
+static struct graphics_image_priv *image_new(struct graphics_priv *gr, struct graphics_image_methods *meth, char *name, int *w, int *h, struct point *hot)
+{
+       struct graphics_image_priv* ret;
+
+       if ( NULL == ( ret = image_cache_hash_lookup( name ) ) )
+       {
+               ret = g_new( struct graphics_image_priv, 1 );
+               printf( "loading image '%s'\n", name );
+               ret->pxpm = Xpm2bmp_new();
+               Xpm2bmp_load( ret->pxpm, name );
+               image_cache_hash_add( name, ret );
+       }
+
+       return ret;
+}
+
+static void draw_image(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, struct graphics_image_priv *img)
+{
+       Xpm2bmp_paint( img->pxpm , hMemDC, p->x, p->y );
+}
+
+static struct graphics_methods graphics_methods = {
+       graphics_destroy,
+       draw_mode,
+       draw_lines,
+       draw_polygon,
+       draw_rectangle,
+       draw_circle,
+       draw_text,
+       draw_image,
+#ifdef HAVE_IMLIB2
+       NULL, // draw_image_warp,
+#else
+       NULL,
+#endif
+       draw_restore,
+       font_new,
+       gc_new,
+       background_gc,
+       NULL, // overlay_new,
+       image_new,
+       get_data,
+       register_resize_callback,
+       register_button_callback,
+       register_motion_callback,
+};
+
+static struct graphics_priv * graphics_win32_drawing_area_new_helper(struct graphics_methods *meth)
+{
+       struct graphics_priv *this_=g_new0(struct graphics_priv,1);
+       *meth=graphics_methods;
+       this_->mode = -1;
+       return this_;
+}
+
+struct graphics_priv* win32_graphics_new( struct graphics_methods *meth, struct attr **attrs)
+{
+       struct graphics_priv* this_=graphics_win32_drawing_area_new_helper(meth);
+       return this_;
+}
diff --git a/navit/navit/graphics/win32/resources/resource.h b/navit/navit/graphics/win32/resources/resource.h
new file mode 100644 (file)
index 0000000..55bcc2d
--- /dev/null
@@ -0,0 +1,4 @@
+#include <windows.h>
+
+#define IDI_NAVIT 1100
+#define IDB_NAVITTOOLBAR 1101
diff --git a/navit/navit/graphics/win32/win32_gui.h b/navit/navit/graphics/win32/win32_gui.h
new file mode 100644 (file)
index 0000000..aa8f61a
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef WIN32_GUI_INCLUDED
+#define WIN32_GUI_INCLUDED
+
+#include "resources\resource.h"
+#include "coord.h"
+#include "point.h"
+#include "graphics.h"
+
+#define ID_CHILD_GFX 100
+#define ID_CHILD_TOOLBAR (ID_CHILD_GFX + 1)
+#define ID_CHILD_1 (ID_CHILD_TOOLBAR + 1)
+#define ID_CHILD_2 (ID_CHILD_1 + 1)
+#define ID_CHILD_3 (ID_CHILD_2 + 1)
+#define ID_CHILD_4 (ID_CHILD_4 + 1)
+
+#define ID_DISPLAY_ZOOMIN              200
+#define ID_DISPLAY_ZOOMOUT             201
+#define ID_DISPLAY_REFRESH             202
+#define ID_DISPLAY_CURSOR              203
+#define ID_DISPLAY_ORIENT              204
+
+#define ID_FILE_EXIT           9001
+#define ID_STUFF_GO            9002
+
+#define _(text) gettext(text)
+
+#define POPUP_MENU_OFFSET  4000
+
+struct statusbar_methods;
+struct menu_methods;
+struct datawindow_methods;
+struct navit;
+struct callback;
+
+
+struct menu_priv {
+       HWND wnd_handle;
+       HMENU hMenu;
+       struct callback* cb;
+};
+
+struct gui_priv {
+       struct navit *nav;
+       HANDLE  hwnd;
+};
+
+
+struct graphics_priv {
+       struct point p;
+       int width;
+       int height;
+       int library_init;
+       int visible;
+       HANDLE wnd_parent_handle;
+       HANDLE wnd_handle;
+       COLORREF bg_color;
+
+
+       void (*resize_callback)(void *data, int w, int h);
+       void *resize_callback_data;
+       void (*motion_callback)(void *data, struct point *p);
+       void *motion_callback_data;
+       void (*button_callback)(void *data, int press, int button, struct point *p);
+       void *button_callback_data;
+       enum draw_mode_num mode;
+};
+
+struct menu_priv *gui_gtk_menubar_new(struct gui_priv *gui, struct menu_methods *meth);
+struct menu_priv *gui_gtk_toolbar_new(struct gui_priv *gui, struct menu_methods *meth);
+struct statusbar_priv *gui_gtk_statusbar_new(struct gui_priv *gui, struct statusbar_methods *meth);
+struct menu_priv *gui_gtk_popup_new(struct gui_priv *gui, struct menu_methods *meth);
+struct datawindow_priv *gui_gtk_datawindow_new(struct gui_priv *gui, char *name, struct callback *click, struct callback *close, struct datawindow_methods *meth);
+
+struct graphics_priv* win32_graphics_new( struct graphics_methods *meth, struct attr **attrs);
+
+#endif
diff --git a/navit/navit/graphics/win32/xpm2bmp.c b/navit/navit/graphics/win32/xpm2bmp.c
new file mode 100644 (file)
index 0000000..3c60c15
--- /dev/null
@@ -0,0 +1,588 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <windows.h>
+#include <wingdi.h>
+#include "Xpm2bmp.h"
+
+#define _DBG
+
+// function prototypes
+static int CreateBitmapFromXpm( const char* filename, PXPM2BMP pXpm2bmp );
+
+// typedefs
+static XPMCOLORENTRY theRGBRecords[] =
+{
+    {"ALICEBLUE", 240, 248, 255},
+    {"ANTIQUEWHITE", 250, 235, 215},
+    {"AQUAMARINE", 50, 191, 193},
+    {"AZURE", 240, 255, 255},
+    {"BEIGE", 245, 245, 220},
+    {"BISQUE", 255, 228, 196},
+    {"BLACK", 0, 0, 0},
+    {"BLANCHEDALMOND", 255, 235, 205},
+    {"BLUE", 0, 0, 255},
+    {"BLUEVIOLET", 138, 43, 226},
+    {"BROWN", 165, 42, 42},
+    {"BURLYWOOD", 222, 184, 135},
+    {"CADETBLUE", 95, 146, 158},
+    {"CHARTREUSE", 127, 255, 0},
+    {"CHOCOLATE", 210, 105, 30},
+    {"CORAL", 255, 114, 86},
+    {"CORNFLOWERBLUE", 34, 34, 152},
+    {"CORNSILK", 255, 248, 220},
+    {"CYAN", 0, 255, 255},
+    {"DARKGOLDENROD", 184, 134, 11},
+    {"DARKGREEN", 0, 86, 45},
+    {"DARKKHAKI", 189, 183, 107},
+    {"DARKOLIVEGREEN", 85, 86, 47},
+    {"DARKORANGE", 255, 140, 0},
+    {"DARKORCHID", 139, 32, 139},
+    {"DARKSALMON", 233, 150, 122},
+    {"DARKSEAGREEN", 143, 188, 143},
+    {"DARKSLATEBLUE", 56, 75, 102},
+    {"DARKSLATEGRAY", 47, 79, 79},
+    {"DARKTURQUOISE", 0, 166, 166},
+    {"DARKVIOLET", 148, 0, 211},
+    {"DEEPPINK", 255, 20, 147},
+    {"DEEPSKYBLUE", 0, 191, 255},
+    {"DIMGRAY", 84, 84, 84},
+    {"DODGERBLUE", 30, 144, 255},
+    {"FIREBRICK", 142, 35, 35},
+    {"FLORALWHITE", 255, 250, 240},
+    {"FORESTGREEN", 80, 159, 105},
+    {"GAINSBORO", 220, 220, 220},
+    {"GHOSTWHITE", 248, 248, 255},
+    {"GOLD", 218, 170, 0},
+    {"GOLDENROD", 239, 223, 132},
+    {"GRAY", 126, 126, 126},
+    {"GRAY0", 0, 0, 0},
+    {"GRAY1", 3, 3, 3},
+    {"GRAY10", 26, 26, 26},
+    {"GRAY100", 255, 255, 255},
+    {"GRAY11", 28, 28, 28},
+    {"GRAY12", 31, 31, 31},
+    {"GRAY13", 33, 33, 33},
+    {"GRAY14", 36, 36, 36},
+    {"GRAY15", 38, 38, 38},
+    {"GRAY16", 41, 41, 41},
+    {"GRAY17", 43, 43, 43},
+    {"GRAY18", 46, 46, 46},
+    {"GRAY19", 48, 48, 48},
+    {"GRAY2", 5, 5, 5},
+    {"GRAY20", 51, 51, 51},
+    {"GRAY21", 54, 54, 54},
+    {"GRAY22", 56, 56, 56},
+    {"GRAY23", 59, 59, 59},
+    {"GRAY24", 61, 61, 61},
+    {"GRAY25", 64, 64, 64},
+    {"GRAY26", 66, 66, 66},
+    {"GRAY27", 69, 69, 69},
+    {"GRAY28", 71, 71, 71},
+    {"GRAY29", 74, 74, 74},
+    {"GRAY3", 8, 8, 8},
+    {"GRAY30", 77, 77, 77},
+    {"GRAY31", 79, 79, 79},
+    {"GRAY32", 82, 82, 82},
+    {"GRAY33", 84, 84, 84},
+    {"GRAY34", 87, 87, 87},
+    {"GRAY35", 89, 89, 89},
+    {"GRAY36", 92, 92, 92},
+    {"GRAY37", 94, 94, 94},
+    {"GRAY38", 97, 97, 97},
+    {"GRAY39", 99, 99, 99},
+    {"GRAY4", 10, 10, 10},
+    {"GRAY40", 102, 102, 102},
+    {"GRAY41", 105, 105, 105},
+    {"GRAY42", 107, 107, 107},
+    {"GRAY43", 110, 110, 110},
+    {"GRAY44", 112, 112, 112},
+    {"GRAY45", 115, 115, 115},
+    {"GRAY46", 117, 117, 117},
+    {"GRAY47", 120, 120, 120},
+    {"GRAY48", 122, 122, 122},
+    {"GRAY49", 125, 125, 125},
+    {"GRAY5", 13, 13, 13},
+    {"GRAY50", 127, 127, 127},
+    {"GRAY51", 130, 130, 130},
+    {"GRAY52", 133, 133, 133},
+    {"GRAY53", 135, 135, 135},
+    {"GRAY54", 138, 138, 138},
+    {"GRAY55", 140, 140, 140},
+    {"GRAY56", 143, 143, 143},
+    {"GRAY57", 145, 145, 145},
+    {"GRAY58", 148, 148, 148},
+    {"GRAY59", 150, 150, 150},
+    {"GRAY6", 15, 15, 15},
+    {"GRAY60", 153, 153, 153},
+    {"GRAY61", 156, 156, 156},
+    {"GRAY62", 158, 158, 158},
+    {"GRAY63", 161, 161, 161},
+    {"GRAY64", 163, 163, 163},
+    {"GRAY65", 166, 166, 166},
+    {"GRAY66", 168, 168, 168},
+    {"GRAY67", 171, 171, 171},
+    {"GRAY68", 173, 173, 173},
+    {"GRAY69", 176, 176, 176},
+    {"GRAY7", 18, 18, 18},
+    {"GRAY70", 179, 179, 179},
+    {"GRAY71", 181, 181, 181},
+    {"GRAY72", 184, 184, 184},
+    {"GRAY73", 186, 186, 186},
+    {"GRAY74", 189, 189, 189},
+    {"GRAY75", 191, 191, 191},
+    {"GRAY76", 194, 194, 194},
+    {"GRAY77", 196, 196, 196},
+    {"GRAY78", 199, 199, 199},
+    {"GRAY79", 201, 201, 201},
+    {"GRAY8", 20, 20, 20},
+    {"GRAY80", 204, 204, 204},
+    {"GRAY81", 207, 207, 207},
+    {"GRAY82", 209, 209, 209},
+    {"GRAY83", 212, 212, 212},
+    {"GRAY84", 214, 214, 214},
+    {"GRAY85", 217, 217, 217},
+    {"GRAY86", 219, 219, 219},
+    {"GRAY87", 222, 222, 222},
+    {"GRAY88", 224, 224, 224},
+    {"GRAY89", 227, 227, 227},
+    {"GRAY9", 23, 23, 23},
+    {"GRAY90", 229, 229, 229},
+    {"GRAY91", 232, 232, 232},
+    {"GRAY92", 235, 235, 235},
+    {"GRAY93", 237, 237, 237},
+    {"GRAY94", 240, 240, 240},
+    {"GRAY95", 242, 242, 242},
+    {"GRAY96", 245, 245, 245},
+    {"GRAY97", 247, 247, 247},
+    {"GRAY98", 250, 250, 250},
+    {"GRAY99", 252, 252, 252},
+    {"GREEN", 0, 255, 0},
+    {"GREENYELLOW", 173, 255, 47},
+    {"HONEYDEW", 240, 255, 240},
+    {"HOTPINK", 255, 105, 180},
+    {"INDIANRED", 107, 57, 57},
+    {"IVORY", 255, 255, 240},
+    {"KHAKI", 179, 179, 126},
+    {"LAVENDER", 230, 230, 250},
+    {"LAVENDERBLUSH", 255, 240, 245},
+    {"LAWNGREEN", 124, 252, 0},
+    {"LEMONCHIFFON", 255, 250, 205},
+    {"LIGHTBLUE", 176, 226, 255},
+    {"LIGHTCORAL", 240, 128, 128},
+    {"LIGHTCYAN", 224, 255, 255},
+    {"LIGHTGOLDENROD", 238, 221, 130},
+    {"LIGHTGOLDENRODYELLOW", 250, 250, 210},
+    {"LIGHTGRAY", 168, 168, 168},
+    {"LIGHTPINK", 255, 182, 193},
+    {"LIGHTSALMON", 255, 160, 122},
+    {"LIGHTSEAGREEN", 32, 178, 170},
+    {"LIGHTSKYBLUE", 135, 206, 250},
+    {"LIGHTSLATEBLUE", 132, 112, 255},
+    {"LIGHTSLATEGRAY", 119, 136, 153},
+    {"LIGHTSTEELBLUE", 124, 152, 211},
+    {"LIGHTYELLOW", 255, 255, 224},
+    {"LIMEGREEN", 0, 175, 20},
+    {"LINEN", 250, 240, 230},
+    {"MAGENTA", 255, 0, 255},
+    {"MAROON", 143, 0, 82},
+    {"MEDIUMAQUAMARINE", 0, 147, 143},
+    {"MEDIUMBLUE", 50, 50, 204},
+    {"MEDIUMFORESTGREEN", 50, 129, 75},
+    {"MEDIUMGOLDENROD", 209, 193, 102},
+    {"MEDIUMORCHID", 189, 82, 189},
+    {"MEDIUMPURPLE", 147, 112, 219},
+    {"MEDIUMSEAGREEN", 52, 119, 102},
+    {"MEDIUMSLATEBLUE", 106, 106, 141},
+    {"MEDIUMSPRINGGREEN", 35, 142, 35},
+    {"MEDIUMTURQUOISE", 0, 210, 210},
+    {"MEDIUMVIOLETRED", 213, 32, 121},
+    {"MIDNIGHTBLUE", 47, 47, 100},
+    {"MINTCREAM", 245, 255, 250},
+    {"MISTYROSE", 255, 228, 225},
+    {"MOCCASIN", 255, 228, 181},
+    {"NAVAJOWHITE", 255, 222, 173},
+    {"NAVY", 35, 35, 117},
+    {"NAVYBLUE", 35, 35, 117},
+    {"OLDLACE", 253, 245, 230},
+    {"OLIVEDRAB", 107, 142, 35},
+    {"ORANGE", 255, 135, 0},
+    {"ORANGERED", 255, 69, 0},
+    {"ORCHID", 239, 132, 239},
+    {"PALEGOLDENROD", 238, 232, 170},
+    {"PALEGREEN", 115, 222, 120},
+    {"PALETURQUOISE", 175, 238, 238},
+    {"PALEVIOLETRED", 219, 112, 147},
+    {"PAPAYAWHIP", 255, 239, 213},
+    {"PEACHPUFF", 255, 218, 185},
+    {"PERU", 205, 133, 63},
+    {"PINK", 255, 181, 197},
+    {"PLUM", 197, 72, 155},
+    {"POWDERBLUE", 176, 224, 230},
+    {"PURPLE", 160, 32, 240},
+    {"RED", 255, 0, 0},
+    {"ROSYBROWN", 188, 143, 143},
+    {"ROYALBLUE", 65, 105, 225},
+    {"SADDLEBROWN", 139, 69, 19},
+    {"SALMON", 233, 150, 122},
+    {"SANDYBROWN", 244, 164, 96},
+    {"SEAGREEN", 82, 149, 132},
+    {"SEASHELL", 255, 245, 238},
+    {"SIENNA", 150, 82, 45},
+    {"SKYBLUE", 114, 159, 255},
+    {"SLATEBLUE", 126, 136, 171},
+    {"SLATEGRAY", 112, 128, 144},
+    {"SNOW", 255, 250, 250},
+    {"SPRINGGREEN", 65, 172, 65},
+    {"STEELBLUE", 84, 112, 170},
+    {"TAN", 222, 184, 135},
+    {"THISTLE", 216, 191, 216},
+    {"TOMATO", 255, 99, 71},
+    {"TRANSPARENT", 0, 0, 1},
+    {"TURQUOISE", 25, 204, 223},
+    {"VIOLET", 156, 62, 206},
+    {"VIOLETRED", 243, 62, 150},
+    {"WHEAT", 245, 222, 179},
+    {"WHITE", 255, 255, 255},
+    {"WHITESMOKE", 245, 245, 245},
+    {"YELLOW", 255, 255, 0},
+    {"YELLOWGREEN", 50, 216, 56}
+};
+
+
+PXPM2BMP Xpm2bmp_new()
+{
+       PXPM2BMP preturn = (PXPM2BMP)calloc( sizeof( XPM2BMP ) , 1 );
+       return preturn;
+}
+
+
+int Xpm2bmp_load( PXPM2BMP pXpm2bmp, const char* filename )
+{
+       return CreateBitmapFromXpm( filename, pXpm2bmp );
+}
+
+int Xpm2bmp_paint( PXPM2BMP pXpm2bmp, HDC hdc, int x1,int y1 )
+{
+       StretchDIBits(hdc,
+                                       x1, y1, pXpm2bmp->size_x, pXpm2bmp->size_y,
+                                       0, 0, pXpm2bmp->size_x, pXpm2bmp->size_y,
+                                       pXpm2bmp->wimage_data_trans,
+                                       (BITMAPINFO *)pXpm2bmp->bmih_trans,
+                                       DIB_RGB_COLORS,
+                                       SRCAND );
+
+       StretchDIBits(hdc,
+                                       x1, y1, pXpm2bmp->size_x, pXpm2bmp->size_y,
+                                       0, 0, pXpm2bmp->size_x, pXpm2bmp->size_y,
+                                       pXpm2bmp->wimage_data,
+                                       (BITMAPINFO *)pXpm2bmp->bmih,
+                                       DIB_RGB_COLORS,
+                                       SRCPAINT );
+
+       return 0;
+}
+
+static int parse_line_values( const char* line, PXPM2BMP pXpm2bmp )
+{
+       int return_value = 0;
+       char* parse_line = (char*)line;
+       char* tok;
+       int value_pos = 0;
+
+       parse_line = strchr( parse_line, '"' );
+       parse_line++;
+
+       tok = strtok( parse_line, " \t\n" );
+
+       while ( tok != 0 )
+       {
+               int val = atoi( tok );
+               switch ( value_pos )
+               {
+                       case 0: pXpm2bmp->size_x = val; break;
+                       case 1: pXpm2bmp->size_y = val; break;
+                       case 2: pXpm2bmp->colors = val; break;
+                       case 3: pXpm2bmp->chars_per_pixel = val; break;
+                       case 4: pXpm2bmp->hotspot_x = val; break;
+                       case 5: pXpm2bmp->hotspot_y = val; break;
+               }
+               tok = strtok( NULL, " \t" );
+               value_pos ++;
+
+       }
+
+       return return_value;
+}
+
+static int hex2int( char c )
+{
+       if ((c >= '0') && (c <='9' )) return c - '0';
+       if ((c >= 'A') && (c <= 'F')) return c - 'A' + 10;
+       if ((c >= 'a') && (c <= 'f')) return c - 'a' + 10;
+       return -1;
+}
+
+static DWORD string2hex16( const char* str )
+{
+       int i1 = hex2int( str[0] );
+       int i2 = hex2int( str[1] );
+       if ( ( i1 >= 0 ) && ( i2 >= 0 ) )
+               return i1*16+i2;
+       return -1;
+}
+
+static int parse_color_values( const char* line, PXPM2BMP pXpm2bmp )
+{
+       int return_value = 0;
+       char* cq    = strchr( line, '"' );
+       char* cchar = strchr(  cq+pXpm2bmp->chars_per_pixel+1, 'c' );
+       char* chash = strchr(  cq+pXpm2bmp->chars_per_pixel+1, '#' );
+       char* qe    = strchr(  cq+pXpm2bmp->chars_per_pixel+1, '"' );
+
+       cq++;
+
+       if ( cq )
+       {
+               memcpy( pXpm2bmp->color_entires[ pXpm2bmp-> color_entires_size].color_str, cq, pXpm2bmp->chars_per_pixel + 1 );
+               pXpm2bmp->color_entires[ pXpm2bmp-> color_entires_size].color_str[ pXpm2bmp->chars_per_pixel ] = '\0';
+
+
+               if ( cchar && chash && qe)
+               {
+                       chash++;
+                       *qe = 0;
+                       int len = strlen( chash );
+
+                       pXpm2bmp->color_entires[ pXpm2bmp->color_entires_size].r = string2hex16( &chash[0] );
+                       pXpm2bmp->color_entires[ pXpm2bmp->color_entires_size].g = string2hex16( &chash[len / 3] );
+                       pXpm2bmp->color_entires[ pXpm2bmp->color_entires_size].b = string2hex16( &chash[len * 2 / 3] );
+#ifdef _DBG
+printf( "adding color %s => %d RGB %x %x %x to index %d\n",
+                       line,
+                       pXpm2bmp->color_entires_size,
+                       pXpm2bmp->color_entires[ pXpm2bmp->color_entires_size].r,
+                       pXpm2bmp->color_entires[ pXpm2bmp->color_entires_size].g,
+                       pXpm2bmp->color_entires[ pXpm2bmp->color_entires_size].b,
+                       pXpm2bmp->color_entires_size );
+#endif
+               }
+               else
+               {
+                       int q;
+                       char *start = cchar + 1;
+                       char *end = start;
+
+                       while ( *start != 0 )
+                       {
+                               if ( ( *start != '\t' ) &&  ( *start != ' ' ) )
+                               {
+                                       break;
+                               }
+                               start++;
+                       }
+
+                       end = start;
+                       while ( *end != 0 )
+                       {
+                               if ( ( *end == '\t' ) ||  ( *end == ' ' ) ||  ( *end == '"' ))
+                               {
+                                       *end = 0;
+                               }
+                               end++;
+                       }
+
+                       start = _strupr( start );
+
+                       for ( q=0; q < sizeof( theRGBRecords ) / sizeof( theRGBRecords[0] ); q++ )
+                       {
+
+                               if ( 0 == strcmp( start, theRGBRecords[q].color_str  ) )
+                               {
+                                       pXpm2bmp->color_entires[ pXpm2bmp->color_entires_size].r = theRGBRecords[q].r;
+                                       pXpm2bmp->color_entires[ pXpm2bmp->color_entires_size].g = theRGBRecords[q].g;
+                                       pXpm2bmp->color_entires[ pXpm2bmp->color_entires_size].b = theRGBRecords[q].b;
+                               }
+                       }
+                       if ( 0 == strcmp( start, "NONE" ) )
+                       {
+                               pXpm2bmp->color_entires[ pXpm2bmp->color_entires_size].r = 255;
+                               pXpm2bmp->color_entires[ pXpm2bmp->color_entires_size].g = 0;
+                               pXpm2bmp->color_entires[ pXpm2bmp->color_entires_size].b = 255;
+                       }
+               }
+       }
+       pXpm2bmp->color_entires_size++;
+
+       return return_value;
+}
+
+static int vv = 0;
+
+static int parse_pixel_line_values( const char* line, PXPM2BMP pXpm2bmp, unsigned char* pixel_data, unsigned char* pixel_data_trans )
+{
+       int return_value = 0;
+       int i,j;
+
+
+       char* cq    = strchr( line, '"' );
+       int pix_idx = 0;
+       int size_x = pXpm2bmp->size_x;
+       int len = strlen( cq );
+
+       cq++;
+
+       if ( len > pXpm2bmp->chars_per_pixel * size_x )
+       {
+               for ( i=0; i< size_x; i++ )
+               {
+                       int found = 0;
+                       char* cmp = &cq[ i * pXpm2bmp->chars_per_pixel];
+
+                       for ( j=0; j< pXpm2bmp-> color_entires_size; j++ )
+                       {
+                               if ( strncmp( cmp, pXpm2bmp->color_entires[ j ].color_str, pXpm2bmp->chars_per_pixel ) == 0 )
+                               {
+                                       int r = pXpm2bmp->color_entires[ j ].r;
+                                       int g = pXpm2bmp->color_entires[ j ].g;
+                                       int b = pXpm2bmp->color_entires[ j ].b;
+
+                                       if ( ( r == 255 ) && ( g == 0 ) && ( r == 255 ) )
+                                       {
+                                               r=g=b=0;
+                                               pixel_data_trans[ pix_idx ] = 255;
+                                               pixel_data_trans[ pix_idx+1 ] = 255;
+                                               pixel_data_trans[ pix_idx+2 ] = 255;
+                                       }
+                                       else
+                                       {
+                                               pixel_data_trans[ pix_idx ] = 0;
+                                               pixel_data_trans[ pix_idx+1 ] = 0;
+                                               pixel_data_trans[ pix_idx+2 ] = 0;
+                                       }
+
+                                       // pixel_data[ pix_idx++ ] = pXpm2bmp->color_entires[ j ].r;
+                                       // pixel_data[ pix_idx++ ] = pXpm2bmp->color_entires[ j ].g;
+                                       // pixel_data[ pix_idx++ ] = pXpm2bmp->color_entires[ j ].b;
+                                       pixel_data[ pix_idx++ ] = b;
+                                       pixel_data[ pix_idx++ ] = g;
+                                       pixel_data[ pix_idx++ ] = r;
+                                       found = 1;
+                                       vv++;
+                                       break;
+                               }
+                       }
+                       if ( !found )
+                       {
+                               fprintf( stderr, "XPMLIB: error color not found\n" );
+                       }
+
+               }
+       }
+       else
+       {
+               return_value = -1;
+               fprintf( stderr, "XPMLIB: invalid line length\n" );
+       }
+       return return_value;
+}
+
+
+static int CreateBitmapFromXpm( const char* filename, PXPM2BMP pXpm2bmp )
+{
+       int return_val = 0;
+    unsigned char i, row;
+       char line[ 1024   ];
+       int nbytes ;
+       FILE* file_xpm = fopen( filename, "r" );
+
+       int phase = 0;
+       row = 0;
+
+       if ( file_xpm )
+       {
+               while ( fgets(line, sizeof( line ), file_xpm ) )
+               {
+#ifdef _DBG
+                       printf( "PARSING: %s\n", line );
+#endif
+                       if ( line[ 0 ] != '"' )
+                               continue;
+
+                       switch ( phase )
+                       {
+                               case 0:
+                                       parse_line_values( line, pXpm2bmp );
+#ifdef _DBG
+                                       printf( "size_x %d\n", pXpm2bmp->size_x );
+                                       printf( "size_y %d\n", pXpm2bmp->size_y );
+#endif
+                                       phase = 1;
+
+                                       pXpm2bmp->color_entires_size = 0;
+                                       nbytes = ( pXpm2bmp->chars_per_pixel + 1 ) * pXpm2bmp->colors;
+
+                                       pXpm2bmp->color_entires = calloc( sizeof( XPMCOLORENTRY ), pXpm2bmp->colors + 100 );
+                                       pXpm2bmp->color_entires[0].color_str = calloc( nbytes, pXpm2bmp->colors );
+                                       for ( i = 1; i< pXpm2bmp->colors; i++ )
+                                       {
+                                               pXpm2bmp->color_entires[i].color_str = pXpm2bmp->color_entires[0].color_str + ( pXpm2bmp->chars_per_pixel + 1 ) * i;
+                                       }
+
+                                       if (!(pXpm2bmp->dib = (unsigned char *)malloc(sizeof(BITMAPINFOHEADER) + pXpm2bmp->size_x * pXpm2bmp->size_y * 3)))
+                                       {
+                                               return 4;
+                                       }
+                                       if (!(pXpm2bmp->dib_trans = (unsigned char *)calloc(sizeof(BITMAPINFOHEADER) + pXpm2bmp->size_x * pXpm2bmp->size_y * 3,1)))
+                                       {
+                                               return 4;
+                                       }
+
+                                       memset(pXpm2bmp->dib, 0, sizeof(BITMAPINFOHEADER));
+                                       pXpm2bmp->bmih = (BITMAPINFOHEADER *)pXpm2bmp->dib;
+                                       pXpm2bmp->bmih->biSize = sizeof(BITMAPINFOHEADER);
+                                       pXpm2bmp->bmih->biWidth = pXpm2bmp->size_x;
+                                       pXpm2bmp->bmih->biHeight = -((long)pXpm2bmp->size_y);
+                                       pXpm2bmp->bmih->biPlanes = 1;
+                                       pXpm2bmp->bmih->biBitCount = 24;
+                                       pXpm2bmp->bmih->biCompression = 0;
+                                       pXpm2bmp->wimage_data = pXpm2bmp->dib + sizeof(BITMAPINFOHEADER);
+
+
+                                       pXpm2bmp->bmih_trans = (BITMAPINFOHEADER *)pXpm2bmp->dib_trans;
+                                       pXpm2bmp->bmih_trans->biSize = sizeof(BITMAPINFOHEADER);
+                                       pXpm2bmp->bmih_trans->biWidth = pXpm2bmp->size_x;
+                                       pXpm2bmp->bmih_trans->biHeight = -((long)pXpm2bmp->size_y);
+                                       pXpm2bmp->bmih_trans->biPlanes = 1;
+                                       pXpm2bmp->bmih_trans->biBitCount = 24;
+                                       pXpm2bmp->bmih_trans->biCompression = 0;
+                                       pXpm2bmp->wimage_data_trans = pXpm2bmp->dib_trans + sizeof(BITMAPINFOHEADER);
+//                                     memset( pXpm2bmp->wimage_data_trans, 255, 5* 22 * 3 );
+
+                               break;
+                               case 1:
+                                       parse_color_values( line, pXpm2bmp  );
+                                       if ( pXpm2bmp->color_entires_size >= pXpm2bmp->colors )
+                                       {
+                                               phase = 2;
+                                       }
+
+                               break;
+                               case 2:
+                                       parse_pixel_line_values( line, pXpm2bmp,
+                                       pXpm2bmp->wimage_data + row * pXpm2bmp->size_x * 3,
+                                       pXpm2bmp->wimage_data_trans + row * pXpm2bmp->size_x * 3 );
+
+                                       row++;
+                                       if ( row >= pXpm2bmp->size_y )
+                                       {
+                                               phase = 3;
+                                       }
+                               break;
+                       }
+
+               }
+
+               fclose( file_xpm );
+       }
+       return return_val;
+}
diff --git a/navit/navit/graphics/win32/xpm2bmp.h b/navit/navit/graphics/win32/xpm2bmp.h
new file mode 100644 (file)
index 0000000..2fa028f
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef Xpm2BMP_H_INCLUDED
+#define Xpm2BMP_H_INCLUDED
+
+#include <windows.h>
+#include "wingdi.h"
+
+typedef struct XPMCOLORENTRY_TAG
+{
+       char* color_str;
+       unsigned long r;
+       unsigned long g;
+       unsigned long b;
+} XPMCOLORENTRY, *PXPMCOLORENTRY;
+
+typedef struct XPM2BMP_TAG
+{
+       unsigned short size_x;
+       unsigned short size_y;
+       unsigned short colors;
+       unsigned short pixels;
+       unsigned short chars_per_pixel;
+       unsigned short hotspot_x;
+       unsigned short hotspot_y;
+
+       int color_entires_size;
+       PXPMCOLORENTRY color_entires;
+
+       unsigned char *dib;
+       unsigned char *wimage_data;
+       BITMAPINFOHEADER *bmih;
+
+       unsigned char *dib_trans;
+       unsigned char *wimage_data_trans;
+       BITMAPINFOHEADER *bmih_trans;
+
+} XPM2BMP, *PXPM2BMP;
+
+
+PXPM2BMP Xpm2bmp_new();
+int Xpm2bmp_load( PXPM2BMP pXpm2bmp, const char* filename );
+int Xpm2bmp_paint( PXPM2BMP pXpm2bmp, HDC hdc, int x1,int y1 );
+
+
+#endif // Xpm2BMP_H_INCLUDED