[cairo] "operator" keyword in libcairo
Maarten Breddels
dmon at xs4all.nl
Sat Jan 1 14:05:27 PST 2005
Chris wrote:
>On Wed, 2004-12-29 at 04:36 +0100, Maarten Breddels wrote:
>
>
>>I never had a problem with it, using the compiler from visual studio 6
>>and 7(.NET) the compiler does have a "c-mode", i'm not sure if it
>>automaticly does that when compiling .c files, but cairo compiles ok here.
>>
>>
>
>Yep, it finally started working here. I have no idea why it wasn't
>working before. I didn't change the project settings so I don't know
>why it had a problem. Probably something I did while trying to get
>everything to compile.
>
>Are you successfully using Cairo in Windows? Most of the Cairo stuff
>seems to compile, but it did require some minor changes. The fontconfig
>stuff is horrible and took a lot of work to get compiled. After all
>that I can't get anything to work though.
>
>
Yes, i replaced FcPattern with char*, and did some minor changes in
cairo_ft_font.c
I've attached a diff, and two file, cairo_win32.c contains some code
from fontconfig, FcUtf8ToUcs4(.), and some pragma's to export the
symbols for use with a dll, cairo_win32_surface.c, really simple win32
backend, which blits the image to the window, usefull for testing only i
guess. Hope it will work for you, let me know.
-Maarten Breddels
>I'm going to try the precompiled fontconfig from Tor Lillqvist to see if
>that helps.
>
>
>
-------------- next part --------------
Index: src/cairo.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.h,v
retrieving revision 1.62
diff -r1.62 cairo.h
161a162,169
> #ifdef CAIRO_HAS_WIN32_SURFACE
>
> void
> cairo_set_target_win32 (cairo_t *cr,
> char * title,
> int width, int height);
> #endif
>
497a506,527
> #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
>
512a543
> #endif /* WIN32 */
790a822,830
> #ifdef CAIRO_HAS_WIN32_SURFACE
>
> cairo_surface_t *
> cairo_win32_surface_create (char* title,
> int width, int height);
>
> #endif /* CAIRO_HAS_WIN32_SURFACE */
>
>
Index: src/cairo_ft_font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_ft_font.c,v
retrieving revision 1.28
diff -r1.28 cairo_ft_font.c
33a34,37
> #ifdef WIN32
> #include <windows.h>
> #endif
>
86a91,142
> #ifdef WIN32
> static ft_font_val_t *
> _create_from_library_and_pattern (FT_Library ft_library, const char *pattern)
> {
> ft_font_val_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);
> //printf("pattern: %s\n", pattern);
> if (face == NULL)
> {
> retvalue = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_QUERY_VALUE, ®key);
> if(retvalue != ERROR_SUCCESS)
> return NULL;
> retvalue = RegQueryValueEx(regkey, "Fonts", 0, ®keytype, &dirname[0], &dirnamelength);
> if(retvalue != ERROR_SUCCESS)
> return NULL;
> sprintf(filename, "%s\\%s.ttf", dirname, pattern);
> //printf("filename: %s\n", filename);
> open_res = FT_New_Face (ft_library, filename, 0, &face);
> RegCloseKey(regkey);
> if(face == NULL)
> {
> sprintf(filename, "%s\\%s.ttf", dirname, "verdana");
> //printf("filename: %s\n", filename);
> open_res = FT_New_Face (ft_library, filename, 0, &face);
> if(face == NULL)
> return NULL;
> }
> }
> //f = (ft_font_val_t *) cairo_ft_font_create_for_ft_face (face);
>
> //f->ft_library = ft_library;
> //f->owns_ft_library = 0;
>
> //f->owns_face = owns_face;
> f = _create_from_face (face, owns_face);
>
> return (ft_font_val_t *) f;
>
> }
> #else
139c195
<
---
> #endif
150a207,209
> #ifdef WIN32
> char *pattern;
> #else
151a211
> #endif
162a223,225
> #ifdef WIN32
> char *pattern;
> #else
163a227
> #endif
186a251,254
> #ifdef WIN32
> /* FIXME: some str->hash algo needed */
> return (unsigned long)key;
> #else
187a256
> #endif
199c268,270
<
---
> #ifdef WIN32
> return strcmp(a->pattern, b->pattern);
> #else
200a272
> #endif
216c288,290
<
---
> #ifdef WIN32
> entry->key.pattern = strdup(k->pattern);
> #else
217a292
> #endif
224a300,305
> if(entry->val == NULL)
> {
> /* XXX: free entry->key.pattern */
> free(entry);
> return CAIRO_STATUS_NULL_POINTER; /* XXX: not really a good error status */
> }
235a317,319
> #ifdef WIN32
> free(e->key.pattern);
> #else
236a321
> #endif
299a385,471
> #ifdef WIN32
> static cairo_unscaled_font_t *
> _cairo_ft_font_create (const char *family,
> cairo_font_slant_t slant,
> cairo_font_weight_t weight)
> {
> cairo_status_t status;
> cairo_ft_font_t *font = NULL;
> int fcslant;
> int fcweight;
> cairo_cache_t *cache;
> cairo_ft_cache_entry_t *entry;
> cairo_ft_cache_key_t key;
>
> key.pattern = strdup(family);
> if (key.pattern == NULL)
> goto FAIL;
>
> font = malloc (sizeof (cairo_ft_font_t));
> if (font == NULL)
> goto FREE_PATTERN;
>
> switch (weight)
> {
> case CAIRO_FONT_WEIGHT_BOLD:
> fcweight = FC_WEIGHT_BOLD;
> break;
> case CAIRO_FONT_WEIGHT_NORMAL:
> default:
> fcweight = FC_WEIGHT_MEDIUM;
> break;
> }
>
> switch (slant)
> {
> case CAIRO_FONT_SLANT_ITALIC:
> fcslant = FC_SLANT_ITALIC;
> break;
> case CAIRO_FONT_SLANT_OBLIQUE:
> fcslant = FC_SLANT_OBLIQUE;
> break;
> case CAIRO_FONT_SLANT_NORMAL:
> default:
> fcslant = FC_SLANT_ROMAN;
> break;
> }
>
> /*
> FcPatternAddString (key.pattern, FC_FAMILY, family);
> FcPatternAddInteger (key.pattern, FC_SLANT, fcslant);
> FcPatternAddInteger (key.pattern, FC_WEIGHT, fcweight);
> */
>
> if (_cairo_unscaled_font_init (&font->base, &cairo_ft_font_backend))
> goto FREE_PATTERN;
>
> _lock_global_ft_cache ();
> cache = _get_global_ft_cache ();
> if (cache == NULL) {
> _unlock_global_ft_cache ();
> goto FREE_PATTERN;
> }
>
> status = _cairo_cache_lookup (cache, &key, (void **) &entry);
> _unlock_global_ft_cache ();
>
> if (status)
> goto FREE_PATTERN;
>
> font->pattern = strdup(entry->key.pattern);
> if (font->pattern == NULL)
> goto FREE_PATTERN;
>
> font->val = entry->val;
> _reference_font_val (font->val);
>
> return &font->base;
>
> FREE_PATTERN:
> free(key.pattern);
>
> FAIL:
> return NULL;
>
> }
>
> #else
383c555
<
---
> #endif
393a566,568
> #ifdef WIN32
> free(font->pattern);
> #else
394a570
> #endif
1017a1194,1258
> #ifdef WIN32
> cairo_font_t *
> cairo_ft_font_create (FT_Library ft_library, const char *pattern)
> {
> cairo_font_scale_t scale;
> cairo_font_t *scaled;
> cairo_ft_font_t *f = NULL;
> ft_font_val_t *v = NULL;
> #ifdef WIN32
> char *dup;
> #else
> FcPattern *dup;
> #endif
>
> scale.matrix[0][0] = 1.;
> scale.matrix[0][1] = 0.;
> scale.matrix[1][0] = 0.;
> scale.matrix[1][1] = 1.;
>
> scaled = malloc (sizeof (cairo_font_t));
> if (scaled == NULL)
> goto FAIL;
>
> #ifdef WIN32
> dup = strdup(pattern);
> #else
> dup = FcPatternDuplicate(pattern);
> #endif
> if (dup == NULL)
> goto FREE_SCALED;
>
> v = _create_from_library_and_pattern (ft_library, pattern);
> if (v == NULL)
> goto FREE_PATTERN;
>
> f = malloc (sizeof(cairo_ft_font_t));
> if (f == NULL)
> goto FREE_VAL;
>
> if (_cairo_unscaled_font_init (&f->base, &cairo_ft_font_backend))
> goto FREE_VAL;
>
> f->pattern = dup;
> f->val = v;
>
> _cairo_font_init (scaled, &scale, &f->base);
>
> return scaled;
>
> FREE_VAL:
> _destroy_font_val (v);
>
> FREE_PATTERN:
> #ifdef WIN32
> free(dup);
> #else
> FcPatternDestroy (dup);
> #endif
>
> FREE_SCALED:
> free (scaled);
>
> FAIL:
> return NULL;
> }
1018a1260
> #else
1070a1313
> #endif
1125a1369,1371
> #ifdef WIN32
> char*
> #else
1126a1373
> #endif
Index: src/cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.78
diff -r1.78 cairoint.h
701a702,704
> #ifdef WIN32
> #define CAIRO_FONT_FAMILY_DEFAULT "times"
> #else
702a706,707
> #endif
>
-------------- 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_GLITZ_SURFACE
#pragma comment(linker, "/EXPORT:_cairo_set_target_glitz")
#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_GLITZ_SURFACE
#pragma comment(linker, "/EXPORT:_cairo_glitz_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,
};
More information about the cairo
mailing list