[cairo] Cairo on win32

Maarten Breddels dmon at xs4all.nl
Wed May 26 14:07:35 PDT 2004


I read on the Dia thread that Hans Breuer also got cairo working on
win32. Nonetheless I hereby send a small diff and 2 files. I don't care
which patch gets into the cvs, i'd just like to see cairo on win32.

The diff includes a change to the freetype backend, instead of the
FcPattern argument, the font create function takes a filename as
argument, or a part of the filename(<windows font dir>\<pattern>.ttf),
where the <windows font dir> is taken from the registry. In cairoint.h I
changed the default font to 'times', (so it will load
'c:\windows\fonts\times.ttf').
The file cairo_win32.c includes the function FcUtf8ToUcs4 taken from
fontconfig (is this ok?) since it's needed in cairo_ft_font.c but
fontconfig isn't linked to . It also includes a load of #pragma
directives to export the symbols for building a DLL. This avoids adding
(ugly) dsa __declspec(dllexport)'s to cairo.h. This approach gives an
advantage over an '.DEF' file, because symbols are exported
conditionally, depending on CAIRO_HAS_PS_SURFACE etc.
cairo_win32_surface.c implements a simple surface for displaying on a
window, usefull for playing around with cairo on windows.

-Maarten
-------------- next part --------------
/* Taken from fcstr.c (fontconfig) */

/*
 * $RCSId: xc/lib/fontconfig/src/fcstr.c,v 1.10 2002/08/31 22:17:32 keithp Exp $
 *
 * Copyright © 2000 Keith Packard
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Keith Packard not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Keith Packard makes no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */
 
#include "cairo-features.h"

typedef unsigned char	FcChar8;
typedef unsigned short	FcChar16;
typedef unsigned int	FcChar32; 

int
FcUtf8ToUcs4 (const FcChar8 *src_orig,
	      FcChar32	    *dst,
	      int	    len)
{
    const FcChar8   *src = src_orig;
    FcChar8	    s;
    int		    extra;
    FcChar32	    result;

    if (len == 0)
	return 0;
    
    s = *src++;
    len--;
    
    if (!(s & 0x80))
    {
	result = s;
	extra = 0;
    } 
    else if (!(s & 0x40))
    {
	return -1;
    }
    else if (!(s & 0x20))
    {
	result = s & 0x1f;
	extra = 1;
    }
    else if (!(s & 0x10))
    {
	result = s & 0xf;
	extra = 2;
    }
    else if (!(s & 0x08))
    {
	result = s & 0x07;
	extra = 3;
    }
    else if (!(s & 0x04))
    {
	result = s & 0x03;
	extra = 4;
    }
    else if ( ! (s & 0x02))
    {
	result = s & 0x01;
	extra = 5;
    }
    else
    {
	return -1;
    }
    if (extra > len)
	return -1;
    
    while (extra--)
    {
	result <<= 6;
	s = *src++;
	
	if ((s & 0xc0) != 0x80)
	    return -1;
	
	result |= s & 0x3f;
    }
    *dst = result;
    return src - src_orig;
} 

/* export symbols, for cairo.dll only */

#pragma comment(linker, "/EXPORT:_cairo_create")
#pragma comment(linker, "/EXPORT:_cairo_reference")
#pragma comment(linker, "/EXPORT:_cairo_destroy")
#pragma comment(linker, "/EXPORT:_cairo_save")
#pragma comment(linker, "/EXPORT:_cairo_restore")
#pragma comment(linker, "/EXPORT:_cairo_copy")
#pragma comment(linker, "/EXPORT:_cairo_set_target_surface")
#pragma comment(linker, "/EXPORT:_cairo_set_target_image")

#ifdef CAIRO_HAS_PS_SURFACE
#pragma comment(linker, "/EXPORT:_cairo_set_target_ps")
#endif

#ifdef CAIRO_HAS_PNG_SURFACE
#pragma comment(linker, "/EXPORT:_cairo_set_target_png")
#endif

#ifdef CAIRO_HAS_GL_SURFACE
#pragma comment(linker, "/EXPORT:_cairo_set_target_gl")
#endif

#ifdef CAIRO_HAS_WIN32_SURFACE
#pragma comment(linker, "/EXPORT:_cairo_set_target_win32")
#endif

#pragma comment(linker, "/EXPORT:_cairo_set_operator")
#pragma comment(linker, "/EXPORT:_cairo_set_rgb_color")
#pragma comment(linker, "/EXPORT:_cairo_set_pattern")
#pragma comment(linker, "/EXPORT:_cairo_set_alpha")
#pragma comment(linker, "/EXPORT:_cairo_set_tolerance")
#pragma comment(linker, "/EXPORT:_cairo_set_fill_rule")
#pragma comment(linker, "/EXPORT:_cairo_set_line_width")
#pragma comment(linker, "/EXPORT:_cairo_set_line_cap")
#pragma comment(linker, "/EXPORT:_cairo_set_line_join")
#pragma comment(linker, "/EXPORT:_cairo_set_dash")
#pragma comment(linker, "/EXPORT:_cairo_set_miter_limit")
#pragma comment(linker, "/EXPORT:_cairo_set_line_cap")

#pragma comment(linker, "/EXPORT:_cairo_translate")
#pragma comment(linker, "/EXPORT:_cairo_scale")
#pragma comment(linker, "/EXPORT:_cairo_rotate")

#pragma comment(linker, "/EXPORT:_cairo_concat_matrix")
#pragma comment(linker, "/EXPORT:_cairo_set_matrix")
#pragma comment(linker, "/EXPORT:_cairo_default_matrix")
#pragma comment(linker, "/EXPORT:_cairo_identity_matrix")
#pragma comment(linker, "/EXPORT:_cairo_transform_point")
#pragma comment(linker, "/EXPORT:_cairo_transform_distance")
#pragma comment(linker, "/EXPORT:_cairo_inverse_transform_point")
#pragma comment(linker, "/EXPORT:_cairo_inverse_transform_distance")

#pragma comment(linker, "/EXPORT:_cairo_new_path")
#pragma comment(linker, "/EXPORT:_cairo_move_to")
#pragma comment(linker, "/EXPORT:_cairo_line_to")
#pragma comment(linker, "/EXPORT:_cairo_curve_to")
#pragma comment(linker, "/EXPORT:_cairo_arc")
#pragma comment(linker, "/EXPORT:_cairo_arc_negative")
#pragma comment(linker, "/EXPORT:_cairo_rel_move_to")
#pragma comment(linker, "/EXPORT:_cairo_rel_line_to")
#pragma comment(linker, "/EXPORT:_cairo_rel_curve_to")
#pragma comment(linker, "/EXPORT:_cairo_rectangle")
#pragma comment(linker, "/EXPORT:_cairo_close_path")

#pragma comment(linker, "/EXPORT:_cairo_stroke")
#pragma comment(linker, "/EXPORT:_cairo_fill")
#pragma comment(linker, "/EXPORT:_cairo_copy_page")
#pragma comment(linker, "/EXPORT:_cairo_show_page")
#pragma comment(linker, "/EXPORT:_cairo_in_stroke")
#pragma comment(linker, "/EXPORT:_cairo_in_fill")
#pragma comment(linker, "/EXPORT:_cairo_stroke_extents")
#pragma comment(linker, "/EXPORT:_cairo_fill_extents")

#pragma comment(linker, "/EXPORT:_cairo_init_clip")
#pragma comment(linker, "/EXPORT:_cairo_clip")
#pragma comment(linker, "/EXPORT:_cairo_select_font")
#pragma comment(linker, "/EXPORT:_cairo_scale_font")
#pragma comment(linker, "/EXPORT:_cairo_transform_font")
#pragma comment(linker, "/EXPORT:_cairo_show_text")
#pragma comment(linker, "/EXPORT:_cairo_show_glyphs")
#pragma comment(linker, "/EXPORT:_cairo_current_font")
#pragma comment(linker, "/EXPORT:_cairo_current_font_extents")
#pragma comment(linker, "/EXPORT:_cairo_set_font")
#pragma comment(linker, "/EXPORT:_cairo_text_extents")
#pragma comment(linker, "/EXPORT:_cairo_glyph_extents")
#pragma comment(linker, "/EXPORT:_cairo_text_path")
#pragma comment(linker, "/EXPORT:_cairo_glyph_path")
#pragma comment(linker, "/EXPORT:_cairo_font_reference")
#pragma comment(linker, "/EXPORT:_cairo_font_destroy")
#pragma comment(linker, "/EXPORT:_cairo_font_set_transform")
#pragma comment(linker, "/EXPORT:_cairo_font_current_transform")

#pragma comment(linker, "/EXPORT:_cairo_ft_font_create")
#pragma comment(linker, "/EXPORT:_cairo_ft_font_create_for_ft_face")

#if 0
/* hmm, this function doesn't exist, but __cairo_ft_font_destroy does */
#pragma comment(linker, "/EXPORT:_cairo_ft_font_destroy")
#endif

#pragma comment(linker, "/EXPORT:_cairo_ft_font_face")
#pragma comment(linker, "/EXPORT:_cairo_ft_font_pattern")

#pragma comment(linker, "/EXPORT:_cairo_show_surface")
#pragma comment(linker, "/EXPORT:_cairo_current_operator")
#pragma comment(linker, "/EXPORT:_cairo_current_rgb_color")
#pragma comment(linker, "/EXPORT:_cairo_current_pattern")
#pragma comment(linker, "/EXPORT:_cairo_current_alpha")
#pragma comment(linker, "/EXPORT:_cairo_current_tolerance")
#pragma comment(linker, "/EXPORT:_cairo_current_point")
#pragma comment(linker, "/EXPORT:_cairo_current_fill_rule")
#pragma comment(linker, "/EXPORT:_cairo_current_line_width")
#pragma comment(linker, "/EXPORT:_cairo_current_line_cap")
#pragma comment(linker, "/EXPORT:_cairo_current_line_join")
#pragma comment(linker, "/EXPORT:_cairo_current_rgb_color")
#pragma comment(linker, "/EXPORT:_cairo_current_miter_limit")
#pragma comment(linker, "/EXPORT:_cairo_current_matrix")
#pragma comment(linker, "/EXPORT:_cairo_current_target_surface")
#pragma comment(linker, "/EXPORT:_cairo_current_path")
#pragma comment(linker, "/EXPORT:_cairo_current_path_flat")

#pragma comment(linker, "/EXPORT:_cairo_status")
#pragma comment(linker, "/EXPORT:_cairo_status_string")

#pragma comment(linker, "/EXPORT:_cairo_surface_create_for_image")
#pragma comment(linker, "/EXPORT:_cairo_surface_create_similar")
#pragma comment(linker, "/EXPORT:_cairo_surface_reference")
#pragma comment(linker, "/EXPORT:_cairo_surface_destroy")
#pragma comment(linker, "/EXPORT:_cairo_surface_set_repeat")
#pragma comment(linker, "/EXPORT:_cairo_surface_set_matrix")
#pragma comment(linker, "/EXPORT:_cairo_surface_get_matrix")
#pragma comment(linker, "/EXPORT:_cairo_surface_set_filter")
#pragma comment(linker, "/EXPORT:_cairo_surface_get_filter")

#pragma comment(linker, "/EXPORT:_cairo_image_surface_create")
#pragma comment(linker, "/EXPORT:_cairo_image_surface_create_for_data")
#pragma comment(linker, "/EXPORT:_cairo_pattern_create_for_surface")
#pragma comment(linker, "/EXPORT:_cairo_pattern_create_linear")
#pragma comment(linker, "/EXPORT:_cairo_pattern_create_radial")
#pragma comment(linker, "/EXPORT:_cairo_pattern_reference")
#pragma comment(linker, "/EXPORT:_cairo_pattern_destroy")
#pragma comment(linker, "/EXPORT:_cairo_pattern_add_color_stop")
#pragma comment(linker, "/EXPORT:_cairo_pattern_set_matrix")
#pragma comment(linker, "/EXPORT:_cairo_pattern_get_matrix")
#pragma comment(linker, "/EXPORT:_cairo_pattern_set_extend")
#pragma comment(linker, "/EXPORT:_cairo_pattern_get_extend")
#pragma comment(linker, "/EXPORT:_cairo_pattern_set_filter")
#pragma comment(linker, "/EXPORT:_cairo_pattern_get_filter")

#ifdef CAIRO_HAS_PS_SURFACE
#pragma comment(linker, "/EXPORT:_cairo_ps_surface_create")
#endif

#ifdef CAIRO_HAS_PNG_SURFACE
#pragma comment(linker, "/EXPORT:_cairo_png_surface_create")
#endif

#ifdef CAIRO_HAS_GL_SURFACE
#pragma comment(linker, "/EXPORT:_cairo_gl_surface_create")
#endif

#ifdef CAIRO_HAS_WIN32_SURFACE
#pragma comment(linker, "/EXPORT:_cairo_win32_surface_create")
#endif

#pragma comment(linker, "/EXPORT:_cairo_matrix_create")
#pragma comment(linker, "/EXPORT:_cairo_matrix_destroy")
#pragma comment(linker, "/EXPORT:_cairo_matrix_copy")
#pragma comment(linker, "/EXPORT:_cairo_matrix_set_identity")
#pragma comment(linker, "/EXPORT:_cairo_matrix_set_affine")
#pragma comment(linker, "/EXPORT:_cairo_matrix_get_affine")
#pragma comment(linker, "/EXPORT:_cairo_matrix_translate")
#pragma comment(linker, "/EXPORT:_cairo_matrix_scale")
#pragma comment(linker, "/EXPORT:_cairo_matrix_rotate")
#pragma comment(linker, "/EXPORT:_cairo_matrix_invert")
#pragma comment(linker, "/EXPORT:_cairo_matrix_multiply")
#pragma comment(linker, "/EXPORT:_cairo_matrix_transform_distance")
#pragma comment(linker, "/EXPORT:_cairo_matrix_transform_point")
-------------- next part --------------
/*
 * Author: Maarten A. Breddels <dmon at xs4all dot nl>
 */

#include "cairoint.h"
#include <windows.h>

static const cairo_surface_backend_t cairo_win32_surface_backend;
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

cairo_surface_t *
cairo_win32_surface_create (char* title,
			 int width, int height);

void
cairo_set_target_win32 (cairo_t	*cr,
		     char	*title,
		     int width, int height)
{
    cairo_surface_t *surface;

    surface = cairo_win32_surface_create (title,
				       width, height);
    if (surface == NULL) {
	cr->status = CAIRO_STATUS_NO_MEMORY;
	return;
    }

    cairo_set_target_surface (cr, surface);

    /* cairo_set_target_surface takes a reference, so we must destroy ours */
    cairo_surface_destroy (surface);
}

typedef struct cairo_win32_surface {
    cairo_surface_t base;

    /* win32-specific fields */
    WNDCLASSEX wc;
	HWND hwnd;


    int width;
    int height;
	char* title;

	HBITMAP dib;
	void* dib_surface;
	HDC cdc; // offscreen display

    //int pages;
    cairo_image_surface_t *image;
} cairo_win32_surface_t;


static void
_cairo_win32_surface_erase (cairo_win32_surface_t *surface);

cairo_surface_t *
cairo_win32_surface_create (char* title,
			 int width, int height)
{
    cairo_win32_surface_t *surface;
	char *classname;
	BITMAPINFO bitmap_info;
	HDC hdc;
	RECT clientsize;
	int clientwidth, clientheight;



	surface = malloc (sizeof (cairo_win32_surface_t));
    if (surface == NULL)
	return NULL;

    _cairo_surface_init (&surface->base, &cairo_win32_surface_backend);

    surface->width = width;
    surface->height = height;
	surface->title = title;

	classname = "cairo win32 surface";
	surface->wc.cbSize = sizeof(WNDCLASSEX);
	surface->wc.style = CS_HREDRAW | CS_VREDRAW; //CS_OWNDC
	surface->wc.lpfnWndProc = WndProc;
	surface->wc.cbClsExtra = 4; // for surface storage pointer
	surface->wc.cbWndExtra = 0;
	surface->wc.hInstance = GetModuleHandle(NULL);
	surface->wc.hIcon = NULL;
	surface->wc.hCursor = NULL;
	surface->wc.hbrBackground = NULL;
	surface->wc.lpszMenuName = NULL;
	surface->wc.lpszClassName = classname;
	surface->wc.hIconSm = NULL;
		
	if(!RegisterClassEx(&surface->wc))
		return NULL;
	surface->hwnd = CreateWindow( classname, title, 
								WS_OVERLAPPEDWINDOW,
								-1, -1,
								width,
								height,
								NULL, NULL,
								surface->wc.hInstance, NULL );
	GetClientRect(surface->hwnd, &clientsize);
	clientwidth = clientsize.right - clientsize.left;
	clientheight = clientsize.bottom - clientsize.top;
	SetWindowPos(surface->hwnd, 0, 0, 0, width + width-clientwidth, height + height-clientheight, SWP_NOMOVE|SWP_NOZORDER);
	if(surface->hwnd == 0)
		return NULL;
	SetClassLong(surface->hwnd, 0, (LONG)surface);

	bitmap_info.bmiHeader.biBitCount = 32;
	bitmap_info.bmiHeader.biSize			 = sizeof(BITMAPINFOHEADER);
	bitmap_info.bmiHeader.biWidth		 = width;
	bitmap_info.bmiHeader.biHeight		 = -height;
	bitmap_info.bmiHeader.biPlanes		 = 1;
	bitmap_info.bmiHeader.biBitCount		 = 32;
	bitmap_info.bmiHeader.biCompression   = BI_RGB;
	bitmap_info.bmiHeader.biSizeImage     = width * height * 4;
	bitmap_info.bmiHeader.biXPelsPerMeter = 2100;
	bitmap_info.bmiHeader.biYPelsPerMeter = 2100;
	bitmap_info.bmiHeader.biClrUsed		 = 0;
	bitmap_info.bmiHeader.biClrImportant  = 0;

	hdc = GetDC(surface->hwnd);
	if(!hdc)
		return NULL;
	surface->dib = CreateDIBSection(hdc, &bitmap_info, DIB_RGB_COLORS, &surface->dib_surface, NULL, 0);
	if(!surface->dib)
		return NULL;
	surface->cdc = CreateCompatibleDC(hdc);
	if(!surface->cdc)
		return NULL;
	SelectObject(surface->cdc, surface->dib);
	if(!ReleaseDC(surface->hwnd, hdc))
		return NULL;

	//last_win32_cairo_surface = surface;

    //surface->file = file;

    //surface->pages = 0;

	surface->image = (cairo_image_surface_t *)
	cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
    memset(surface->image->data, 0, surface->image->stride * surface->image->height);
    if (surface->image == NULL) {
	free (surface);
	return NULL;
    }

    //_cairo_ps_surface_erase (surface);

    /* Document header */
    /*fprintf (file,
	     "%%!PS-Adobe-3.0\n"
	     "%%%%Creator: Cairo (http://cairographics.org)\n");
    fprintf (file,
	     "%%%%CreationDate: %s",
	     ctime (&now));
    fprintf (file,
	     "%%%%Copyright: 2003 Carl Worth and Keith Packard\n");
    fprintf (file,
	     "%%%%BoundingBox: %d %d %d %d\n",
	     0, 0, (int) (surface->width_inches * 72.0), (int) (surface->height_inches * 72.0));
    /* The "/FlateDecode filter" currently used is a feature of LanguageLevel 3 */
    /*fprintf (file,
	     "%%%%DocumentData: Clean7Bit\n"
	     "%%%%LanguageLevel: 3\n");
    fprintf (file,
	     "%%%%Orientation: Portrait\n"
	     "%%%%EndComments\n");*/

    return &surface->base;
}

static cairo_surface_t *
_cairo_win32_surface_create_similar (void		*abstract_src,
				 cairo_format_t	format,
				 int		width,
				 int		height)
{
    return NULL;
}

static void
_cairo_win32_surface_destroy (void *abstract_surface)
{
    cairo_win32_surface_t *surface = abstract_surface;

	DestroyWindow(surface->hwnd);
    cairo_surface_destroy (&surface->image->base);

    free (surface);
}

static void
_cairo_win32_surface_erase (cairo_win32_surface_t *surface)
{
    cairo_color_t transparent;

    _cairo_color_init (&transparent);
    _cairo_color_set_rgb (&transparent, 0., 0., 0.);
    _cairo_color_set_alpha (&transparent, 0.);
    _cairo_surface_fill_rectangle (&surface->image->base,
				   CAIRO_OPERATOR_SRC,
				   &transparent,
				   0, 0,
				   surface->image->width,
				   surface->image->height);
}

/* XXX: We should re-work this interface to return both X/Y ppi values. */
static double
_cairo_win32_surface_pixels_per_inch (void *abstract_surface)
{
    cairo_win32_surface_t *surface = abstract_surface;

    //return surface->y_ppi;
	return 72; // TODO, does win32 api give this information ?
}

static cairo_image_surface_t *
_cairo_win32_surface_get_image (void *abstract_surface)
{
    cairo_win32_surface_t *surface = abstract_surface;

    cairo_surface_reference (&surface->image->base);

    return surface->image;
}


static cairo_status_t
_cairo_win32_surface_set_image (void			*abstract_surface,
			     cairo_image_surface_t	*image)
{
    cairo_win32_surface_t *surface = abstract_surface;

    if (image == surface->image)
	return CAIRO_STATUS_SUCCESS;

    /* XXX: Need to call _cairo_image_surface_set_image here, but it's
       not implemented yet. */

    return CAIRO_INT_STATUS_UNSUPPORTED;
}

static cairo_status_t
_cairo_win32_surface_set_matrix (void		*abstract_surface,
			      cairo_matrix_t	*matrix)
{
    cairo_win32_surface_t *surface = abstract_surface;

    return _cairo_image_surface_set_matrix (surface->image, matrix);
}

static cairo_status_t
_cairo_win32_surface_set_filter (void		*abstract_surface,
			      cairo_filter_t	filter)
{
    cairo_win32_surface_t *surface = abstract_surface;

    return _cairo_image_surface_set_filter (surface->image, filter);
}

static cairo_status_t
_cairo_win32_surface_set_repeat (void		*abstract_surface,
			      int		repeat)
{
    cairo_win32_surface_t *surface = abstract_surface;

    return _cairo_image_surface_set_repeat (surface->image, repeat);
}

static cairo_int_status_t
_cairo_win32_surface_composite (cairo_operator_t	operator,
			     cairo_surface_t	*generic_src,
			     cairo_surface_t	*generic_mask,
			     void		*abstract_dst,
			     int		src_x,
			     int		src_y,
			     int		mask_x,
			     int		mask_y,
			     int		dst_x,
			     int		dst_y,
			     unsigned int	width,
			     unsigned int	height)
{
    return CAIRO_INT_STATUS_UNSUPPORTED;
}

static cairo_int_status_t
_cairo_win32_surface_fill_rectangles (void			*abstract_surface,
				   cairo_operator_t	operator,
				   const cairo_color_t	*color,
				   cairo_rectangle_t	*rects,
				   int			num_rects)
{
    return CAIRO_INT_STATUS_UNSUPPORTED;
}


static cairo_int_status_t
_cairo_win32_surface_composite_trapezoids (cairo_operator_t	operator,
					cairo_surface_t		*generic_src,
					void			*abstract_dst,
					int			x_src,
					int			y_src,
					cairo_trapezoid_t	*traps,
					int			num_traps)
{
    return CAIRO_INT_STATUS_UNSUPPORTED;
}

static cairo_int_status_t
_cairo_win32_surface_copy_page (void *abstract_surface)
{
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
    cairo_win32_surface_t *surface = abstract_surface;
	int y;
	
	for(y = 0; y < surface->height; y++)
    {
		memcpy(((unsigned char*)surface->dib_surface) + y * surface->width * 4, ((unsigned char*)surface->image->data) + y * surface->image->stride,  surface->width * 4);
    }
    return status;
}


static cairo_int_status_t
_cairo_win32_surface_show_page (void *abstract_surface)
{
    cairo_int_status_t status;
    cairo_win32_surface_t *surface = abstract_surface;
	int exit = 0;
	MSG msg;
	HDC hdc;

	ShowWindow(surface->hwnd, SW_SHOWDEFAULT);
    status = _cairo_win32_surface_copy_page (surface);
    if (status)
	return status;
	GdiFlush(); // Let gdi know we updated the dib surface
	hdc = GetDC(surface->hwnd);
	BitBlt(hdc, 0, 0, surface->width, surface->height, surface->cdc, 0, 0, SRCCOPY);
	ReleaseDC(surface->hwnd, hdc);

	while(GetMessage(&msg, NULL, 0, 0) == 1)
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

    _cairo_win32_surface_erase (surface);

    return CAIRO_STATUS_SUCCESS;
}

LRESULT  handle_win32_event(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, cairo_win32_surface_t *surface)
{
	HDC hdc;
	switch( msg )
	{
		case WM_PAINT:
			if(GetUpdateRect(hwnd, NULL, 0)) // check to see if we need to update
			{
				hdc = GetDC(surface->hwnd);
				BitBlt(hdc, 0, 0, surface->width, surface->height, surface->cdc, 0, 0, SRCCOPY);
				ReleaseDC(surface->hwnd, hdc);
				ValidateRect(hwnd, NULL); // validates the whole paint region
			}
			return 0;
		case WM_CLOSE:
			ShowWindow(hwnd, SW_HIDE);
			PostQuitMessage(0);
			return 0;
	}
	return DefWindowProc( hwnd, msg, wParam, lParam );		
}

LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	cairo_win32_surface_t *surface = (cairo_win32_surface_t*)GetClassLong(hWnd, 0);
	if(surface)
	{
		return handle_win32_event(hWnd, msg, wParam, lParam, surface);
	}
	else
	{
		return DefWindowProc( hWnd, msg, wParam, lParam );;
	}
}

static cairo_int_status_t
_cairo_win32_surface_set_clip_region (void *abstract_surface,
				   pixman_region16_t *region)
{
    cairo_win32_surface_t *surface = abstract_surface;

    return _cairo_image_surface_set_clip_region (surface->image, region);
}

static cairo_int_status_t
_cairo_win32_surface_create_pattern (void *abstract_surface,
                                  cairo_pattern_t *pattern,
                                  cairo_box_t *extents)
{
    return CAIRO_INT_STATUS_UNSUPPORTED;
}

static const cairo_surface_backend_t cairo_win32_surface_backend = {
    _cairo_win32_surface_create_similar,
    _cairo_win32_surface_destroy,
    _cairo_win32_surface_pixels_per_inch,
    _cairo_win32_surface_get_image,
    _cairo_win32_surface_set_image,
    _cairo_win32_surface_set_matrix,
    _cairo_win32_surface_set_filter,
    _cairo_win32_surface_set_repeat,
    _cairo_win32_surface_composite,
    _cairo_win32_surface_fill_rectangles,
    _cairo_win32_surface_composite_trapezoids,
    _cairo_win32_surface_copy_page,
    _cairo_win32_surface_show_page,
    _cairo_win32_surface_set_clip_region,
    _cairo_win32_surface_create_pattern,
};
-------------- next part --------------
Index: cairo.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.h,v
retrieving revision 1.55
diff -r1.55 cairo.h
152a153,160
> #ifdef CAIRO_HAS_WIN32_SURFACE
> 
> void
> cairo_set_target_win32 (cairo_t	*cr,
> 		     char * title,
> 		     int width, int height);
> #endif
> 
488a497,518
> #ifdef WIN32
> 
> #include <ft2build.h>
> #include FT_FREETYPE_H
> 
> cairo_font_t *
> cairo_ft_font_create (FT_Library ft_library, const char *pattern);
> 
> cairo_font_t *
> cairo_ft_font_create_for_ft_face (FT_Face face);
> 
> void
> cairo_ft_font_destroy (cairo_font_t *ft_font);
> 
> FT_Face
> cairo_ft_font_face (cairo_font_t *ft_font);
> 
> char *
> cairo_ft_font_pattern (cairo_font_t  *ft_font);
> 
> #else
> 
506a537
> #endif /* WIN32 */
784a816,824
> #ifdef CAIRO_HAS_WIN32_SURFACE
> 
> cairo_surface_t *
> cairo_win32_surface_create (char* title,
> 			 int width, int height);
> 
> #endif /* CAIRO_HAS_WIN32_SURFACE */
> 
> 
Index: cairo_ft_font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_ft_font.c,v
retrieving revision 1.23
diff -r1.23 cairo_ft_font.c
25a26
> 
33a35,38
> #ifdef WIN32
> #include <windows.h>
> #endif
> 
42c47,49
< 
---
> #ifdef WIN32
> 	char* pattern;
> #else
43a51
> #endif
52a61,102
> #ifdef WIN32
> cairo_font_t *
> cairo_ft_font_create (FT_Library ft_library, const char *pattern)
> {
>     cairo_ft_font_t *f = NULL;
>     char filename[1024*2];
>     char dirname[1024];
>     FT_Face face = NULL;
>     int owns_face = 0;
>     int open_res = 0;
> 	DWORD regkeytype;
> 	DWORD dirnamelength = 1024;
> 	LONG retvalue;
> 	HKEY regkey;
> 
>     owns_face = 1;
> 
>     open_res = FT_New_Face (ft_library, pattern, 0, &face);
>     if (face == NULL)
> 	{
> 		retvalue = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_QUERY_VALUE, &regkey);
> 		if(retvalue != ERROR_SUCCESS)
> 	        return NULL;
> 		retvalue = RegQueryValueEx(regkey, "Fonts", 0, &regkeytype, &dirname[0], &dirnamelength);
> 		if(retvalue != ERROR_SUCCESS)
> 	        return NULL;
> 		sprintf(filename, "%s\\%s.ttf", dirname, pattern);
> 	    open_res = FT_New_Face (ft_library, filename, 0, &face);
> 		if(face == NULL)
> 			return NULL;
> 		RegCloseKey(regkey);
> 	}
>     f = (cairo_ft_font_t *) cairo_ft_font_create_for_ft_face (face);
> 
>     f->ft_library = ft_library;
>     f->owns_ft_library = 0;
> 
>     f->owns_face = owns_face;
> 
>     return (cairo_font_t *) f;
> }
> #else
102a153
> #endif
114a166,168
> #ifdef WIN32
> char *
> #else
115a170
> #endif
127a183,221
> #ifdef WIN32
> 
> static cairo_font_t *
> _cairo_ft_font_create (const char           *family, 
>                        cairo_font_slant_t   slant, 
>                        cairo_font_weight_t  weight)
> {
>     cairo_ft_font_t *ft_font = NULL;
>     cairo_font_t *font = NULL;
>     FT_Library ft_library;
>     FT_Error error;
> 
>     error = FT_Init_FreeType (&ft_library);
>     if (error) {
>     	return NULL;
>     }
> 
> 	font = cairo_ft_font_create (ft_library, family);
> 	
>     if (font == NULL)
>     {
>         FT_Done_FreeType(ft_library);
> 	    return NULL;
>     }
> 
>     ft_font = (cairo_ft_font_t *) font;
> 
>     ft_font->owns_ft_library = 1;
> 
>     FT_Set_Char_Size (ft_font->face,
>                       DOUBLE_TO_26_6 (1.0),
>                       DOUBLE_TO_26_6 (1.0),
>                       0, 0);
>   
>     return font;  
> }
> 
> #else
> 
196a291,293
> #endif /* WIN32 */
> 
> 
209a307,310
> #ifdef WIN32
> 	if (font_new != NULL && font->pattern != NULL)
> 		font_new->pattern = font->pattern;
> #else
211a313
> #endif
226a329
> #ifndef WIN32
228a332
> #endif
Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.64
diff -r1.64 cairoint.h
543a544,546
> #ifdef WIN32
> #define CAIRO_FONT_FAMILY_DEFAULT  "times"
> #else
544a548,549
> #endif
> 


More information about the cairo mailing list