[cairo] Win + Cario + SVG
Simon Flannery
simon_flannery at yahoo.com.au
Sun Nov 19 17:24:55 PST 2006
Not wanting to "give-up", I have researched and plugged away to produce a simple SVG loader using Cario with librsvg.
For everyone here is a possible solution that I built. Enjoy.
#include <cairo-win32.h>
#include <librsvg\rsvg.h>
#include <librsvg\rsvg-cairo.h>
#define MY_TIMER 0x01
RsvgHandle* g_my_svg = NULL;
RsvgDimensionData g_dimension = {0};
LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void Paint(HDC hdc, long width, long height);
INT WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT iCmdShow)
{
WNDCLASS window_class = {0};
window_class.style = CS_HREDRAW | CS_VREDRAW;
window_class.lpfnWndProc = WndProc;
window_class.cbClsExtra = 0;
window_class.cbWndExtra = 0;
window_class.hInstance = hInstance;
window_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
window_class.hCursor = LoadCursor(NULL, IDC_ARROW);
window_class.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
window_class.lpszMenuName = NULL;
window_class.lpszClassName = "my_svg";
RegisterClass(&window_class);
/* Compute the window size needed for the desired client area. */
RECT rect = {0, 0, 400, 400};
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE /* No menu. */);
HWND hWnd = CreateWindow("my_svg", "Simple SVG Test - Esc to quit", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);
/* Start a new timer that fires WM_TIMER events every 500 milliseconds. */
SetTimer(hWnd, MY_TIMER, 500, (TIMERPROC) NULL);
GError* pError = NULL;
/* Start the rsvg lib. */
rsvg_init();
g_my_svg = rsvg_handle_new_from_file("star.svg", &pError);
rsvg_handle_get_dimensions (g_my_svg, &g_dimension);
/* Main message loop. */
MSG message;
while (GetMessage(&message, NULL, 0, 0) != 0)
{
TranslateMessage(&message);
DispatchMessage(&message);
}
rsvg_handle_free(g_my_svg);
rsvg_term();
UnregisterClass("my_svg", hInstance);
return (int) message.wParam;
}
LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_TIMER:
InvalidateRect(hWnd, NULL, 0);
return 0;
break;
case WM_ERASEBKGND:
/* Windows wants to redraw the window background everytime the window is resized.
This prevents that to avoid flickering during resizing! */
return 0;
break;
case WM_PAINT:
{
/* Get the width and height of the window. */
RECT client;
GetClientRect(hWnd, &client);
PAINTSTRUCT ps;
HDC dc = BeginPaint(hWnd, &ps);
/* Create an offscreen buffer for painting. Althought not required,
this stops the flickering! */
HDC dcBuffer = CreateCompatibleDC(dc);
HBITMAP hBuffer = CreateCompatibleBitmap(dc, client.right, client.bottom);
/* Select the new buffer and use it for painting. */
SelectObject(dcBuffer, hBuffer);
Paint(dcBuffer, client.right, client.bottom);
/* Now copy the buffer onto the actual window. */
BitBlt(dc, 0, 0, client.right, client.bottom, dcBuffer, 0, 0, SRCCOPY);
/* Clean up. */
DeleteDC(dcBuffer);
DeleteObject(hBuffer);
EndPaint(hWnd, &ps);
return 0;
}
break;
case WM_DESTROY:
/* The user has closed the window. Stop the timer and quit the application. */
KillTimer(hWnd, MY_TIMER);
PostQuitMessage(0);
return 0;
break;
default:
break;
}
/* All other events should be handled by the default event handler. */
return DefWindowProc (hWnd, message, wParam, lParam);
}
void Paint(HDC hdc, long width, long height)
{
cairo_surface_t* surface = cairo_win32_surface_create(hdc);
cairo_t* cr = cairo_create(surface);
cairo_scale(cr, (double) width / (double) g_dimension.width, (double) height / (double) g_dimension.height);
/* Paint the background context colort white. */
cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0f);
cairo_paint(cr);
/* Apply our decal. */
rsvg_handle_render_cairo(g_my_svg, cr);
/* Force pipeline out. */
cairo_surface_flush(surface);
/* Clean up. */
cairo_destroy(cr);
cairo_surface_destroy(surface);
return;
}
Send instant messages to your online friends http://au.messenger.yahoo.com
More information about the cairo
mailing list