Bug 527707. Cairo DirectWrite and Direct2D Backends. r=jrmuizel

This commit is contained in:
Bas Schouten 2010-01-22 15:38:31 -05:00
Родитель bb009c36f8
Коммит 795f71a1c9
12 изменённых файлов: 4096 добавлений и 127 удалений

Просмотреть файл

@ -154,6 +154,12 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
CSRCS += cairo-win32-surface.c
ifndef WINCE
ifdef MOZ_ENABLE_DWRITE_FONT
CPPSRCS += cairo-dwrite-font.cpp
endif
ifdef MOZ_ENABLE_D2D_SURFACE
CPPSRCS += cairo-d2d-surface.cpp
endif
CSRCS += cairo-win32-font.c
else
CSRCS += cairo-ddraw-surface.c

Просмотреть файл

@ -0,0 +1,216 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* Cairo - a vector graphics library with display and print output
*
* Copyright © 2010 Mozilla Foundation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is the Mozilla Foundation
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*/
#ifndef CAIRO_D2D_PRIVATE_H
#define CAIRO_D2D_PRIVATE_H
#ifdef CAIRO_HAS_D2D_SURFACE
#include <windows.h>
#include <d2d1.h>
#include <d3d10.h>
#include <dxgi.h>
extern "C" {
#include "cairoint.h"
}
struct _cairo_d2d_surface {
cairo_surface_t base;
/** Render target of the texture we render to */
ID2D1RenderTarget *rt;
/** Surface containing our backstore */
ID3D10Resource *surface;
/**
* Surface used to temporarily store our surface if a bitmap isn't available
* straight from our render target surface.
*/
ID3D10Texture2D *bufferTexture;
/** Backbuffer surface hwndrt renders to (NULL if not a window surface) */
IDXGISurface *backBuf;
/** Bitmap shared with texture and rendered to by rt */
ID2D1Bitmap *surfaceBitmap;
/** Swap chain holding our backbuffer (NULL if not a window surface) */
IDXGISwapChain *dxgiChain;
/** Window handle of the window we belong to */
HWND hwnd;
/** Format of the surface */
cairo_format_t format;
/** Geometry used for clipping when complex clipping is required */
ID2D1Geometry *clipMask;
/** Clip rectangle for axis aligned rectangular clips */
D2D1_RECT_F *clipRect;
/** Clip layer used for pushing geometry clip mask */
ID2D1Layer *clipLayer;
/** Mask layer used by surface_mask to push opacity masks */
ID2D1Layer *maskLayer;
/** Layer used for clipping when tiling - lazily initialized */
ID2D1Layer *tilingLayer;
/** If this layer currently is clipping, used to prevent excessive push/pops */
bool clipping;
/** Brush used for bitmaps */
ID2D1BitmapBrush *bitmapBrush;
/** Brush used for solid colors */
ID2D1SolidColorBrush *solidColorBrush;
/** Indicates if our render target is currently in drawing mode */
bool isDrawing;
/** Indicates if text rendering is initialized */
bool textRenderingInit;
};
typedef struct _cairo_d2d_surface cairo_d2d_surface_t;
typedef HRESULT (WINAPI*D2D1CreateFactoryFunc)(
__in D2D1_FACTORY_TYPE factoryType,
__in REFIID iid,
__in_opt CONST D2D1_FACTORY_OPTIONS *pFactoryOptions,
__out void **factory
);
typedef HRESULT (WINAPI*D3D10CreateDevice1Func)(
IDXGIAdapter *pAdapter,
D3D10_DRIVER_TYPE DriverType,
HMODULE Software,
UINT Flags,
D3D10_FEATURE_LEVEL1 HardwareLevel,
UINT SDKVersion,
ID3D10Device1 **ppDevice
);
class D2DSurfFactory
{
public:
static ID2D1Factory *Instance()
{
if (!mFactoryInstance) {
D2D1CreateFactoryFunc createD2DFactory = (D2D1CreateFactoryFunc)
GetProcAddress(LoadLibraryW(L"d2d1.dll"), "D2D1CreateFactory");
if (createD2DFactory) {
D2D1_FACTORY_OPTIONS options;
#ifdef DEBUG
options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
#else
options.debugLevel = D2D1_DEBUG_LEVEL_NONE;
#endif
createD2DFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
__uuidof(ID2D1Factory),
&options,
(void**)&mFactoryInstance);
}
}
return mFactoryInstance;
}
private:
static ID2D1Factory *mFactoryInstance;
};
/**
* On usage of D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS:
* documentation on D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
* can be misleading. In fact, that flag gives no such indication. I pointed this
* out to Bas in my email. However, Microsoft is in fact using this flag to
* indicate "light weight" DX applications. By light weight they are essentially
* referring to applications that are not games. The idea is that when you create
* a DX game, the driver assumes that you will pretty much have a single instance
* and therefore it doesn't try to hold back when it comes to GPU resource
* allocation as long as it can crank out performance. In other words, the
* priority in regular DX applications is to make that one application run as fast
* as you can. For "light weight" applications, including D2D applications, the
* priorities are a bit different. Now you are no longer going to have a single
* (or very few) instances. You can have a lot of them (say, for example, a
* separate DX context/device per browser tab). In such cases, the GPU resource
* allocation scheme changes.
*/
class D3D10Factory
{
public:
static ID3D10Device1 *Device()
{
if (!mDeviceInstance) {
D3D10CreateDevice1Func createD3DDevice = (D3D10CreateDevice1Func)
GetProcAddress(LoadLibraryA("d3d10_1.dll"), "D3D10CreateDevice1");
if (createD3DDevice) {
HRESULT hr = createD3DDevice(
NULL,
D3D10_DRIVER_TYPE_HARDWARE,
NULL,
D3D10_CREATE_DEVICE_BGRA_SUPPORT |
D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
D3D10_FEATURE_LEVEL_10_1,
D3D10_1_SDK_VERSION,
&mDeviceInstance);
if (FAILED(hr)) {
HRESULT hr = createD3DDevice(
NULL,
D3D10_DRIVER_TYPE_HARDWARE,
NULL,
D3D10_CREATE_DEVICE_BGRA_SUPPORT |
D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
D3D10_FEATURE_LEVEL_10_0,
D3D10_1_SDK_VERSION,
&mDeviceInstance);
if (FAILED(hr)) {
/* TODO: D3D10Level9 might be slower than GDI */
HRESULT hr = createD3DDevice(
NULL,
D3D10_DRIVER_TYPE_HARDWARE,
NULL,
D3D10_CREATE_DEVICE_BGRA_SUPPORT |
D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
D3D10_FEATURE_LEVEL_9_3,
D3D10_1_SDK_VERSION,
&mDeviceInstance);
}
}
}
mDeviceInstance->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP);
}
return mDeviceInstance;
}
private:
static ID3D10Device1 *mDeviceInstance;
};
ID2D1Brush*
_cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf,
const cairo_pattern_t *pattern,
unsigned int lastrun,
unsigned int *runs_remaining,
bool *pushed_clip,
bool unique = false);
#endif /* CAIRO_HAS_D2D_SURFACE */
#endif /* CAIRO_D2D_PRIVATE_H */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,107 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* Cairo - a vector graphics library with display and print output
*
* Copyright © 2010 Mozilla Foundation
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is the Mozilla Foundation
*
* Contributor(s):
* Bas Schouten <bschouten@mozilla.com>
*/
#include <dwrite.h>
#include <D2d1.h>
// DirectWrite is not available on all platforms.
typedef HRESULT (WINAPI*DWriteCreateFactoryFunc)(
__in DWRITE_FACTORY_TYPE factoryType,
__in REFIID iid,
__out IUnknown **factory
);
class DWriteFactory
{
public:
static IDWriteFactory *Instance()
{
if (!mFactoryInstance) {
DWriteCreateFactoryFunc createDWriteFactory = (DWriteCreateFactoryFunc)
GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory");
if (createDWriteFactory) {
HRESULT hr = createDWriteFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&mFactoryInstance));
assert(SUCCEEDED(hr));
}
}
return mFactoryInstance;
}
static IDWriteFontCollection *SystemCollection()
{
if (!mSystemCollection) {
if (Instance()) {
HRESULT hr = Instance()->GetSystemFontCollection(&mSystemCollection);
assert(SUCCEEDED(hr));
}
}
return mSystemCollection;
}
static IDWriteFontFamily *FindSystemFontFamily(const WCHAR *aFamilyName)
{
UINT32 idx;
BOOL found;
if (!SystemCollection()) {
return NULL;
}
SystemCollection()->FindFamilyName(aFamilyName, &idx, &found);
if (!found) {
return NULL;
}
IDWriteFontFamily *family;
SystemCollection()->GetFontFamily(idx, &family);
return family;
}
private:
static IDWriteFactory *mFactoryInstance;
static IDWriteFontCollection *mSystemCollection;
};
cairo_int_status_t
cairo_dwrite_show_glyphs_on_d2d_surface(void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_rectangle_int_t *extents);

Просмотреть файл

@ -89,6 +89,10 @@
@WIN32_FONT_FEATURE@
@WIN32_DWRITE_FONT_FEATURE@
@WIN32_D2D_SURFACE_FEATURE@
@QUARTZ_FONT_FEATURE@
@PNG_FUNCTIONS_FEATURE@

Просмотреть файл

@ -50,6 +50,7 @@
#define CAIRO_FIXED_ONE ((cairo_fixed_t)(1 << CAIRO_FIXED_FRAC_BITS))
#define CAIRO_FIXED_ONE_DOUBLE ((double)(1 << CAIRO_FIXED_FRAC_BITS))
#define CAIRO_FIXED_ONE_FLOAT ((float)(1 << CAIRO_FIXED_FRAC_BITS))
#define CAIRO_FIXED_EPSILON ((cairo_fixed_t)(1))
#define CAIRO_FIXED_FRAC_MASK (((cairo_fixed_unsigned_t)(-1)) >> (CAIRO_FIXED_BITS - CAIRO_FIXED_FRAC_BITS))
@ -141,6 +142,12 @@ _cairo_fixed_to_double (cairo_fixed_t f)
return ((double) f) / CAIRO_FIXED_ONE_DOUBLE;
}
static inline float
_cairo_fixed_to_float (cairo_fixed_t f)
{
return ((float) f) / CAIRO_FIXED_ONE_FLOAT;
}
static inline int
_cairo_fixed_is_integer (cairo_fixed_t f)
{

Просмотреть файл

@ -220,4 +220,19 @@ inline BOOL ModifyWorldTransform(HDC hdc, CONST XFORM * lpxf, DWORD mode) { retu
#endif
#ifdef CAIRO_HAS_DWRITE_FONT
CAIRO_BEGIN_DECLS
cairo_public cairo_int_status_t
cairo_dwrite_show_glyphs_on_surface(void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_rectangle_int_t *extents);
CAIRO_END_DECLS
#endif /* CAIRO_HAS_DWRITE_FONT */
#endif /* CAIRO_WIN32_PRIVATE_H */

Просмотреть файл

@ -1651,144 +1651,150 @@ _cairo_win32_surface_show_glyphs (void *surface,
cairo_rectangle_int_t *extents)
{
#if defined(CAIRO_HAS_WIN32_FONT) && !defined(WINCE)
cairo_win32_surface_t *dst = surface;
if (scaled_font->backend->type == CAIRO_FONT_TYPE_DWRITE) {
#ifdef CAIRO_HAS_DWRITE_FONT
return cairo_dwrite_show_glyphs_on_surface(surface, op, source, glyphs, num_glyphs, scaled_font, extents);
#endif
} else {
cairo_win32_surface_t *dst = surface;
WORD glyph_buf_stack[STACK_GLYPH_SIZE];
WORD *glyph_buf = glyph_buf_stack;
int dxy_buf_stack[2 * STACK_GLYPH_SIZE];
int *dxy_buf = dxy_buf_stack;
WORD glyph_buf_stack[STACK_GLYPH_SIZE];
WORD *glyph_buf = glyph_buf_stack;
int dxy_buf_stack[2 * STACK_GLYPH_SIZE];
int *dxy_buf = dxy_buf_stack;
BOOL win_result = 0;
int i, j;
BOOL win_result = 0;
int i, j;
cairo_solid_pattern_t *solid_pattern;
COLORREF color;
cairo_solid_pattern_t *solid_pattern;
COLORREF color;
cairo_matrix_t device_to_logical;
cairo_matrix_t device_to_logical;
int start_x, start_y;
double user_x, user_y;
int logical_x, logical_y;
unsigned int glyph_index_option;
int start_x, start_y;
double user_x, user_y;
int logical_x, logical_y;
unsigned int glyph_index_option;
/* We can only handle win32 fonts */
if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_WIN32)
return CAIRO_INT_STATUS_UNSUPPORTED;
/* We can only handle win32 fonts */
if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_WIN32)
return CAIRO_INT_STATUS_UNSUPPORTED;
/* We can only handle opaque solid color sources */
if (!_cairo_pattern_is_opaque_solid(source))
return CAIRO_INT_STATUS_UNSUPPORTED;
/* We can only handle opaque solid color sources */
if (!_cairo_pattern_is_opaque_solid(source))
return CAIRO_INT_STATUS_UNSUPPORTED;
/* We can only handle operator SOURCE or OVER with the destination
* having no alpha */
if ((op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_OVER) ||
(dst->format != CAIRO_FORMAT_RGB24))
return CAIRO_INT_STATUS_UNSUPPORTED;
/* We can only handle operator SOURCE or OVER with the destination
* having no alpha */
if ((op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_OVER) ||
(dst->format != CAIRO_FORMAT_RGB24))
return CAIRO_INT_STATUS_UNSUPPORTED;
/* If we have a fallback mask clip set on the dst, we have
* to go through the fallback path, but only if we're not
* doing this for printing */
if (dst->base.clip &&
!(dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) &&
(dst->base.clip->mode != CAIRO_CLIP_MODE_REGION ||
dst->base.clip->surface != NULL))
return CAIRO_INT_STATUS_UNSUPPORTED;
/* If we have a fallback mask clip set on the dst, we have
* to go through the fallback path, but only if we're not
* doing this for printing */
if (dst->base.clip &&
!(dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) &&
(dst->base.clip->mode != CAIRO_CLIP_MODE_REGION ||
dst->base.clip->surface != NULL))
return CAIRO_INT_STATUS_UNSUPPORTED;
solid_pattern = (cairo_solid_pattern_t *)source;
color = RGB(((int)solid_pattern->color.red_short) >> 8,
((int)solid_pattern->color.green_short) >> 8,
((int)solid_pattern->color.blue_short) >> 8);
solid_pattern = (cairo_solid_pattern_t *)source;
color = RGB(((int)solid_pattern->color.red_short) >> 8,
((int)solid_pattern->color.green_short) >> 8,
((int)solid_pattern->color.blue_short) >> 8);
cairo_win32_scaled_font_get_device_to_logical(scaled_font, &device_to_logical);
cairo_win32_scaled_font_get_device_to_logical(scaled_font, &device_to_logical);
SaveDC(dst->dc);
SaveDC(dst->dc);
cairo_win32_scaled_font_select_font(scaled_font, dst->dc);
SetTextColor(dst->dc, color);
SetTextAlign(dst->dc, TA_BASELINE | TA_LEFT);
SetBkMode(dst->dc, TRANSPARENT);
cairo_win32_scaled_font_select_font(scaled_font, dst->dc);
SetTextColor(dst->dc, color);
SetTextAlign(dst->dc, TA_BASELINE | TA_LEFT);
SetBkMode(dst->dc, TRANSPARENT);
if (num_glyphs > STACK_GLYPH_SIZE) {
glyph_buf = (WORD *) _cairo_malloc_ab (num_glyphs, sizeof(WORD));
dxy_buf = (int *) _cairo_malloc_abc (num_glyphs, sizeof(int), 2);
}
if (num_glyphs > STACK_GLYPH_SIZE) {
glyph_buf = (WORD *) _cairo_malloc_ab (num_glyphs, sizeof(WORD));
dxy_buf = (int *) _cairo_malloc_abc (num_glyphs, sizeof(int), 2);
/* 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. */
user_x = glyphs[0].x;
user_y = glyphs[0].y;
cairo_matrix_transform_point(&device_to_logical,
&user_x, &user_y);
logical_x = _cairo_lround (user_x);
logical_y = _cairo_lround (user_y);
start_x = logical_x;
start_y = logical_y;
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;
cairo_matrix_transform_point(&device_to_logical,
&next_user_x, &next_user_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);
dxy_buf[j+1] = _cairo_lround (logical_y - next_logical_y);
/* note that GDI coordinate system is inverted */
logical_x = next_logical_x;
logical_y = next_logical_y;
}
}
/* Using glyph indices for a Type 1 font does not work on a
* printer DC. The win32 printing surface will convert the the
* glyph indices of Type 1 fonts to the unicode values.
*/
if ((dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) &&
_cairo_win32_scaled_font_is_type1 (scaled_font))
{
glyph_index_option = 0;
}
else
{
glyph_index_option = ETO_GLYPH_INDEX;
}
win_result = ExtTextOutW(dst->dc,
start_x,
start_y,
glyph_index_option | ETO_PDY,
NULL,
glyph_buf,
num_glyphs,
dxy_buf);
if (!win_result) {
_cairo_win32_print_gdi_error("_cairo_win32_surface_show_glyphs(ExtTextOutW failed)");
}
RestoreDC(dst->dc, -1);
if (glyph_buf != glyph_buf_stack) {
free(glyph_buf);
free(dxy_buf);
}
return (win_result) ? CAIRO_STATUS_SUCCESS : CAIRO_INT_STATUS_UNSUPPORTED;
}
/* 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. */
user_x = glyphs[0].x;
user_y = glyphs[0].y;
cairo_matrix_transform_point(&device_to_logical,
&user_x, &user_y);
logical_x = _cairo_lround (user_x);
logical_y = _cairo_lround (user_y);
start_x = logical_x;
start_y = logical_y;
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;
cairo_matrix_transform_point(&device_to_logical,
&next_user_x, &next_user_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);
dxy_buf[j+1] = _cairo_lround (logical_y - next_logical_y);
/* note that GDI coordinate system is inverted */
logical_x = next_logical_x;
logical_y = next_logical_y;
}
}
/* Using glyph indices for a Type 1 font does not work on a
* printer DC. The win32 printing surface will convert the the
* glyph indices of Type 1 fonts to the unicode values.
*/
if ((dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) &&
_cairo_win32_scaled_font_is_type1 (scaled_font))
{
glyph_index_option = 0;
}
else
{
glyph_index_option = ETO_GLYPH_INDEX;
}
win_result = ExtTextOutW(dst->dc,
start_x,
start_y,
glyph_index_option | ETO_PDY,
NULL,
glyph_buf,
num_glyphs,
dxy_buf);
if (!win_result) {
_cairo_win32_print_gdi_error("_cairo_win32_surface_show_glyphs(ExtTextOutW failed)");
}
RestoreDC(dst->dc, -1);
if (glyph_buf != glyph_buf_stack) {
free(glyph_buf);
free(dxy_buf);
}
return (win_result) ? CAIRO_STATUS_SUCCESS : CAIRO_INT_STATUS_UNSUPPORTED;
#else
return CAIRO_INT_STATUS_UNSUPPORTED;
#endif

Просмотреть файл

@ -109,6 +109,63 @@ cairo_win32_scaled_font_get_device_to_logical (cairo_scaled_font_t *scaled_font,
#endif /* CAIRO_HAS_WIN32_FONT */
#if CAIRO_HAS_DWRITE_FONT
/*
* Win32 DirectWrite font support
*/
cairo_public cairo_font_face_t *
cairo_dwrite_font_face_create_for_dwrite_fontface(void *dwrite_font, void *dwrite_font_face);
#endif /* CAIRO_HAS_DWRITE_FONT */
#if CAIRO_HAS_D2D_SURFACE
/**
* Create a D2D surface for an HWND
*
* \param wnd Handle for the window
* \return New cairo surface
*/
cairo_public cairo_surface_t *
cairo_d2d_surface_create_for_hwnd(HWND wnd);
/**
* Create a D2D surface of a certain size.
*
* \param format Cairo format of the surface
* \param width Width of the surface
* \param height Height of the surface
* \return New cairo surface
*/
cairo_public cairo_surface_t *
cairo_d2d_surface_create(cairo_format_t format,
int width,
int height);
/**
* Present the backbuffer for a surface create for an HWND. This needs
* to be called when the owner of the original window surface wants to
* actually present the executed drawing operations to the screen.
*
* \param surface D2D surface.
*/
void cairo_d2d_present_backbuffer(cairo_surface_t *surface);
/**
* Scroll the surface, this only moves the surface graphics, it does not
* actually scroll child windows or anything like that. Nor does it invalidate
* that area of the window.
*
* \param surface The d2d surface this operation should apply to.
* \param x The x delta for the movement
* \param y The y delta for the movement
* \param clip The clip rectangle, the is the 'part' of the surface that needs
* scrolling.
*/
void cairo_d2d_scroll(cairo_surface_t *surface, int x, int y, cairo_rectangle_t *clip);
#endif
CAIRO_END_DECLS
#else /* CAIRO_HAS_WIN32_SURFACE */

Просмотреть файл

@ -1307,7 +1307,8 @@ typedef enum _cairo_font_type {
CAIRO_FONT_TYPE_FT,
CAIRO_FONT_TYPE_WIN32,
CAIRO_FONT_TYPE_QUARTZ,
CAIRO_FONT_TYPE_USER
CAIRO_FONT_TYPE_USER,
CAIRO_FONT_TYPE_DWRITE
} cairo_font_type_t;
cairo_public cairo_font_type_t
@ -1934,7 +1935,8 @@ typedef enum _cairo_surface_type {
CAIRO_SURFACE_TYPE_SCRIPT,
CAIRO_SURFACE_TYPE_QT,
CAIRO_SURFACE_TYPE_META,
CAIRO_SURFACE_TYPE_DDRAW
CAIRO_SURFACE_TYPE_DDRAW,
CAIRO_SURFACE_TYPE_D2D
} cairo_surface_type_t;
cairo_public cairo_surface_type_t

Просмотреть файл

@ -555,6 +555,12 @@ extern const cairo_private struct _cairo_font_face_backend _cairo_win32_font_fac
#endif
#if CAIRO_HAS_DWRITE_FONT
extern const cairo_private struct _cairo_font_face_backend _cairo_dwrite_font_face_backend;
#endif
#if CAIRO_HAS_QUARTZ_FONT
extern const cairo_private struct _cairo_font_face_backend _cairo_quartz_font_face_backend;
@ -1008,7 +1014,12 @@ typedef struct _cairo_traps {
#define CAIRO_FT_FONT_FAMILY_DEFAULT ""
#define CAIRO_USER_FONT_FAMILY_DEFAULT "@cairo:"
#if CAIRO_HAS_WIN32_FONT
#if CAIRO_HAS_DWRITE_FONT
#define CAIRO_FONT_FAMILY_DEFAULT CAIRO_WIN32_FONT_FAMILY_DEFAULT
#define CAIRO_FONT_FACE_BACKEND_DEFAULT &_cairo_dwrite_font_face_backend
#elif CAIRO_HAS_WIN32_FONT
#define CAIRO_FONT_FAMILY_DEFAULT CAIRO_WIN32_FONT_FAMILY_DEFAULT
#define CAIRO_FONT_FACE_BACKEND_DEFAULT &_cairo_win32_font_face_backend
@ -2621,7 +2632,7 @@ cairo_private int
_cairo_ucs4_to_utf8 (uint32_t unicode,
char *utf8);
#if CAIRO_HAS_WIN32_FONT || CAIRO_HAS_QUARTZ_FONT || CAIRO_HAS_PDF_OPERATORS
#if CAIRO_HAS_WIN32_FONT || CAIRO_HAS_QUARTZ_FONT || CAIRO_HAS_PDF_OPERATORS || CAIRO_HAS_DW_FONT
# define CAIRO_HAS_UTF8_TO_UTF16 1
#endif
#if CAIRO_HAS_UTF8_TO_UTF16