Bug 527707. Cairo DirectWrite and Direct2D Backends. r=jrmuizel
This commit is contained in:
Родитель
bb009c36f8
Коммит
795f71a1c9
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче