Merge branch 'master' of git.cairographics.org:/git/cairo into cairo

This commit is contained in:
Carl Worth 2006-12-14 21:10:21 -08:00
commit fa618df6e2
3 changed files with 72 additions and 45 deletions

View file

@ -1481,19 +1481,21 @@ _cairo_win32_surface_show_glyphs (void *surface,
WORD glyph_buf_stack[STACK_GLYPH_SIZE];
WORD *glyph_buf = glyph_buf_stack;
int dx_buf_stack[STACK_GLYPH_SIZE];
int *dx_buf = dx_buf_stack;
int dxy_buf_stack[2 * STACK_GLYPH_SIZE];
int *dxy_buf = dxy_buf_stack;
BOOL win_result = 0;
int i;
double last_y = glyphs[0].y;
int i, j;
cairo_solid_pattern_t *solid_pattern;
COLORREF color;
int output_count = 0;
cairo_matrix_t device_to_logical;
int start_x, start_y;
double user_x, user_y;
int logical_x, logical_y;
/* We can only handle win32 fonts */
if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_WIN32)
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -1531,59 +1533,68 @@ _cairo_win32_surface_show_glyphs (void *surface,
if (num_glyphs > STACK_GLYPH_SIZE) {
glyph_buf = (WORD *)malloc(num_glyphs * sizeof(WORD));
dx_buf = (int *)malloc(num_glyphs * sizeof(int));
dxy_buf = (int *)malloc(num_glyphs * 2 * sizeof(int));
}
for (i = 0; i < num_glyphs; ++i) {
output_count++;
/* It is vital that dx values for dxy_buf are calculated from the delta of
* _logical_ x coordinates (not user x coordinates) or else the sum of all
* previous dx values may start to diverge from the current glyph's x
* coordinate due to accumulated rounding error. As a result strings could
* be painted shorter or longer than expected. */
glyph_buf[i] = (WORD) glyphs[i].index;
if (i == num_glyphs - 1)
dx_buf[i] = 0;
else
dx_buf[i] = _cairo_lround ((glyphs[i+1].x - glyphs[i].x) *
WIN32_FONT_LOGICAL_SCALE);
user_x = glyphs[0].x;
user_y = glyphs[0].y;
if (i == num_glyphs - 1 || glyphs[i].y != glyphs[i+1].y) {
const int offset = (i - output_count) + 1;
double user_x = glyphs[offset].x;
double user_y = last_y;
int logical_x, logical_y;
cairo_matrix_transform_point(&device_to_logical,
&user_x, &user_y);
cairo_matrix_transform_point(&device_to_logical,
&user_x, &user_y);
logical_x = _cairo_lround (user_x);
logical_y = _cairo_lround (user_y);
logical_x = _cairo_lround (user_x);
logical_y = _cairo_lround (user_y);
start_x = logical_x;
start_y = logical_y;
win_result = ExtTextOutW(dst->dc,
logical_x,
logical_y,
ETO_GLYPH_INDEX,
NULL,
glyph_buf + offset,
output_count,
dx_buf + offset);
if (!win_result) {
_cairo_win32_print_gdi_error("_cairo_win32_surface_show_glyphs(ExtTextOutW failed)");
goto FAIL;
}
for (i = 0, j = 0; i < num_glyphs; ++i, j = 2 * i) {
glyph_buf[i] = (WORD) glyphs[i].index;
if (i == num_glyphs - 1) {
dxy_buf[j] = 0;
dxy_buf[j+1] = 0;
} else {
double next_user_x = glyphs[i+1].x;
double next_user_y = glyphs[i+1].y;
int next_logical_x, next_logical_y;
output_count = 0;
cairo_matrix_transform_point(&device_to_logical,
&next_user_x, &next_user_y);
if (i < num_glyphs - 1)
last_y = glyphs[i+1].y;
} else {
last_y = glyphs[i].y;
}
next_logical_x = _cairo_lround (next_user_x);
next_logical_y = _cairo_lround (next_user_y);
dxy_buf[j] = _cairo_lround ((next_logical_x - logical_x) * WIN32_FONT_LOGICAL_SCALE);
dxy_buf[j+1] = _cairo_lround ((logical_y - start_y) * WIN32_FONT_LOGICAL_SCALE);
logical_x = next_logical_x;
logical_y = next_logical_y;
}
}
win_result = ExtTextOutW(dst->dc,
start_x,
start_y,
ETO_GLYPH_INDEX | ETO_PDY,
NULL,
glyph_buf,
num_glyphs,
dxy_buf);
if (!win_result) {
_cairo_win32_print_gdi_error("_cairo_win32_surface_show_glyphs(ExtTextOutW failed)");
}
FAIL:
RestoreDC(dst->dc, -1);
if (glyph_buf != glyph_buf_stack) {
free(glyph_buf);
free(dx_buf);
free(dxy_buf);
}
return (win_result) ? CAIRO_STATUS_SUCCESS : CAIRO_INT_STATUS_UNSUPPORTED;
}

View file

@ -40,6 +40,16 @@
#if CAIRO_HAS_WIN32_SURFACE
#define WIN32_LEAN_AND_MEAN
/* We require Windows 2000 features. Although we don't use them here, things
* should still work if this header file ends up being the one to include
* windows.h into a source file, so: */
#if !defined(WINVER) || (WINVER < 0x0500)
# define WINVER 0x0500
#endif
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
# define _WIN32_WINNT 0x0500
#endif
#include <windows.h>
CAIRO_BEGIN_DECLS

View file

@ -149,8 +149,14 @@ CAIRO_BEGIN_DECLS
#if !defined(CAIRO_MUTEX_DECLARE) && defined CAIRO_HAS_WIN32_SURFACE
# define WIN32_LEAN_AND_MEAN
# ifndef WINVER
# define WINVER 0xFFFFF /* use newest and greatest */
/* We require Windows 2000 features. Although we don't use them here, things
* should still work if this header file ends up being the one to include
* windows.h into a source file, so: */
# if !defined(WINVER) || (WINVER < 0x0500)
# define WINVER 0x0500
# endif
# if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
# define _WIN32_WINNT 0x0500
# endif
# include <windows.h>
/* the real initialization must take place in DllMain */