Import win32 dwrite font backend from

https://hg.mozilla.org/mozilla-central/file/7338d7d940913147f8a1b1e8bd2b25ab255f4373/gfx/cairo/cairo/src

and add to the meson build. I've omitted the
cairo_surface_set_subpixel_antialiasing() API and its use in quartz
and dwrite. Not sure if that is needed.

It compiles. Not tested.
This commit is contained in:
Adrian Johnson 2021-08-08 10:44:19 +09:30
parent 1a799577b2
commit 90ca635472
12 changed files with 2020 additions and 8 deletions

View file

@ -1,4 +1,4 @@
project('cairo', 'c',
project('cairo', 'c', 'cpp',
meson_version: '>= 0.56.0',
version: run_command(find_program('version.py'), check: true).stdout().strip(),
default_options: ['warning_level=2'],
@ -501,6 +501,21 @@ if host_machine.system() == 'windows'
'deps': win32_extra_deps,
}
]
cpp_compiler = meson.get_compiler('cpp')
direct2d_dep = cpp_compiler.find_library('d2d1', required: false)
dwrite_dep = cpp_compiler.find_library('dwrite', required: false)
direct2d_header = cpp_compiler.has_header('d2d1.h')
dwrite_header = cpp_compiler.has_header('dwrite.h')
if direct2d_dep.found() and dwrite_dep.found() and direct2d_header and dwrite_header
feature_conf.set('CAIRO_HAS_DWRITE_FONT', 1)
built_features += [{
'name': 'cairo-win32-dwrite-font',
'description': 'Microsoft Windows DWrite font backend',
'deps': [dwrite_dep, direct2d_dep],
}]
endif
endif
# GL / GLESV2 / GLESV3 are mutually exclusive
@ -941,6 +956,7 @@ summary({
'FreeType': feature_conf.get('CAIRO_HAS_FT_FONT', 0) == 1,
'Fontconfig': feature_conf.get('CAIRO_HAS_FC_FONT', 0) == 1,
'Win32': feature_conf.get('CAIRO_HAS_WIN32_FONT', 0) == 1,
'Win32 DWrite': feature_conf.get('CAIRO_HAS_DWRITE_FONT', 0) == 1,
'Quartz': feature_conf.get('CAIRO_HAS_QUARTZ_FONT', 0) == 1,
}, section: 'Font Backends', bool_yn: true)

View file

@ -69,9 +69,15 @@ cairo_win32_surface_create_with_dib (cairo_format_t format,
cairo_public HDC
cairo_win32_surface_get_dc (cairo_surface_t *surface);
cairo_public HDC
cairo_win32_get_dc_with_clip (cairo_t *cr);
cairo_public cairo_surface_t *
cairo_win32_surface_get_image (cairo_surface_t *surface);
cairo_public cairo_status_t
cairo_win32_surface_get_size (const cairo_surface_t *surface, int *width, int *height);
#if CAIRO_HAS_WIN32_FONT
/*
@ -105,8 +111,33 @@ cairo_public void
cairo_win32_scaled_font_get_device_to_logical (cairo_scaled_font_t *scaled_font,
cairo_matrix_t *device_to_logical);
cairo_public BYTE
cairo_win32_get_system_text_quality (void);
#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);
void
cairo_dwrite_scaled_font_set_force_GDI_classic (cairo_scaled_font_t *dwrite_scaled_font, cairo_bool_t allowed);
cairo_bool_t
cairo_dwrite_scaled_font_get_force_GDI_classic (cairo_scaled_font_t *dwrite_scaled_font);
void
cairo_dwrite_set_cleartype_params (FLOAT gamma, FLOAT contrast, FLOAT level, int geometry, int mode);
int
cairo_dwrite_get_cleartype_rendering_mode ();
#endif /* CAIRO_HAS_DWRITE_FONT */
CAIRO_END_DECLS
#else /* CAIRO_HAS_WIN32_SURFACE */

View file

@ -1545,6 +1545,7 @@ cairo_font_face_status (cairo_font_face_t *font_face);
* @CAIRO_FONT_TYPE_QUARTZ: The font is of type Quartz (Since: 1.6, in 1.2 and
* 1.4 it was named CAIRO_FONT_TYPE_ATSUI)
* @CAIRO_FONT_TYPE_USER: The font was create using cairo's user font api (Since: 1.8)
* @CAIRO_FONT_TYPE_DWRITE: The font is of type Win32 DWrite (Since: 1.18)
*
* #cairo_font_type_t is used to describe the type of a given font
* face or scaled font. The font types are also known as "font
@ -1581,7 +1582,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

View file

@ -177,6 +177,9 @@ cairo_feature_sources = {
'cairo-win32-font': [
'win32/cairo-win32-font.c',
],
'cairo-win32-dwrite-font': [
'win32/cairo-dwrite-font.cpp',
],
'cairo-gl': [
'cairo-gl-composite.c',
'cairo-gl-device.c',

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,229 @@
/* -*- 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_1.h>
#include <d2d1.h>
// DirectWrite is not available on all platforms.
typedef HRESULT (WINAPI*DWriteCreateFactoryFunc)(
DWRITE_FACTORY_TYPE factoryType,
REFIID iid,
IUnknown **factory
);
/* cairo_scaled_font_t implementation */
struct _cairo_dwrite_scaled_font {
cairo_scaled_font_t base;
cairo_matrix_t mat;
cairo_matrix_t mat_inverse;
cairo_antialias_t antialias_mode;
DWRITE_MEASURING_MODE measuring_mode;
enum TextRenderingState {
TEXT_RENDERING_UNINITIALIZED,
TEXT_RENDERING_NO_CLEARTYPE,
TEXT_RENDERING_NORMAL,
TEXT_RENDERING_GDI_CLASSIC
};
TextRenderingState rendering_mode;
};
typedef struct _cairo_dwrite_scaled_font cairo_dwrite_scaled_font_t;
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;
}
static IDWriteRenderingParams *RenderingParams(cairo_dwrite_scaled_font_t::TextRenderingState mode)
{
if (!mDefaultRenderingParams ||
!mForceGDIClassicRenderingParams ||
!mCustomClearTypeRenderingParams)
{
CreateRenderingParams();
}
IDWriteRenderingParams *params;
if (mode == cairo_dwrite_scaled_font_t::TEXT_RENDERING_NO_CLEARTYPE) {
params = mDefaultRenderingParams;
} else if (mode == cairo_dwrite_scaled_font_t::TEXT_RENDERING_GDI_CLASSIC && mRenderingMode < 0) {
params = mForceGDIClassicRenderingParams;
} else {
params = mCustomClearTypeRenderingParams;
}
if (params) {
params->AddRef();
}
return params;
}
static void SetRenderingParams(FLOAT aGamma,
FLOAT aEnhancedContrast,
FLOAT aClearTypeLevel,
int aPixelGeometry,
int aRenderingMode)
{
mGamma = aGamma;
mEnhancedContrast = aEnhancedContrast;
mClearTypeLevel = aClearTypeLevel;
mPixelGeometry = aPixelGeometry;
mRenderingMode = aRenderingMode;
// discard any current RenderingParams objects
if (mCustomClearTypeRenderingParams) {
mCustomClearTypeRenderingParams->Release();
mCustomClearTypeRenderingParams = NULL;
}
if (mForceGDIClassicRenderingParams) {
mForceGDIClassicRenderingParams->Release();
mForceGDIClassicRenderingParams = NULL;
}
if (mDefaultRenderingParams) {
mDefaultRenderingParams->Release();
mDefaultRenderingParams = NULL;
}
}
static int GetClearTypeRenderingMode() {
return mRenderingMode;
}
private:
static void CreateRenderingParams();
static IDWriteFactory *mFactoryInstance;
static IDWriteFontCollection *mSystemCollection;
static IDWriteRenderingParams *mDefaultRenderingParams;
static IDWriteRenderingParams *mCustomClearTypeRenderingParams;
static IDWriteRenderingParams *mForceGDIClassicRenderingParams;
static FLOAT mGamma;
static FLOAT mEnhancedContrast;
static FLOAT mClearTypeLevel;
static int mPixelGeometry;
static int mRenderingMode;
};
class AutoDWriteGlyphRun : public DWRITE_GLYPH_RUN
{
static const int kNumAutoGlyphs = 256;
public:
AutoDWriteGlyphRun() {
glyphCount = 0;
}
~AutoDWriteGlyphRun() {
if (glyphCount > kNumAutoGlyphs) {
delete[] glyphIndices;
delete[] glyphAdvances;
delete[] glyphOffsets;
}
}
void allocate(int aNumGlyphs) {
glyphCount = aNumGlyphs;
if (aNumGlyphs <= kNumAutoGlyphs) {
glyphIndices = &mAutoIndices[0];
glyphAdvances = &mAutoAdvances[0];
glyphOffsets = &mAutoOffsets[0];
} else {
glyphIndices = new UINT16[aNumGlyphs];
glyphAdvances = new FLOAT[aNumGlyphs];
glyphOffsets = new DWRITE_GLYPH_OFFSET[aNumGlyphs];
}
}
private:
DWRITE_GLYPH_OFFSET mAutoOffsets[kNumAutoGlyphs];
FLOAT mAutoAdvances[kNumAutoGlyphs];
UINT16 mAutoIndices[kNumAutoGlyphs];
};
/* cairo_font_face_t implementation */
struct _cairo_dwrite_font_face {
cairo_font_face_t base;
IDWriteFont *font;
IDWriteFontFace *dwriteface;
};
typedef struct _cairo_dwrite_font_face cairo_dwrite_font_face_t;
DWRITE_MATRIX _cairo_dwrite_matrix_from_matrix(const cairo_matrix_t *matrix);
// This will initialize a DWrite glyph run from cairo glyphs and a scaled_font.
void
_cairo_dwrite_glyph_run_from_glyphs(cairo_glyph_t *glyphs,
int num_glyphs,
cairo_dwrite_scaled_font_t *scaled_font,
AutoDWriteGlyphRun *run,
cairo_bool_t *transformed);

View file

@ -168,7 +168,7 @@ _create_dc_and_bitmap (cairo_win32_display_surface_t *surface,
case CAIRO_FORMAT_RGB30:
case CAIRO_FORMAT_RGB96F:
case CAIRO_FORMAT_RGBA128F:
ASSERT_NOT_REACHED;
ASSERT_NOT_REACHED;
/* We can't create real RGB24 bitmaps because something seems to
* break if we do, especially if we don't set up an image
* fallback. It could be a bug with using a 24bpp pixman image

View file

@ -286,8 +286,8 @@ _have_cleartype_quality (void)
version_info.dwMinorVersion >= 1)); /* XP or newer */
}
static BYTE
_get_system_quality (void)
BYTE
cairo_win32_get_system_text_quality (void)
{
BOOL font_smoothing;
UINT smoothing_type;
@ -354,7 +354,7 @@ _win32_scaled_font_create (LOGFONTW *logfont,
* here is the hint_metrics options.
*/
if (options->antialias == CAIRO_ANTIALIAS_DEFAULT)
f->quality = _get_system_quality ();
f->quality = cairo_win32_get_system_text_quality ();
else {
switch (options->antialias) {
case CAIRO_ANTIALIAS_NONE:

View file

@ -251,7 +251,7 @@ _cairo_win32_printing_surface_acquire_image_pattern (
case CAIRO_PATTERN_TYPE_MESH:
default:
ASSERT_NOT_REACHED;
break;
return CAIRO_INT_STATUS_UNSUPPORTED;
}
_cairo_pattern_init_for_surface (image_pattern, &image->base);
@ -1818,6 +1818,7 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
cairo_solid_pattern_t clear;
cairo_composite_rectangles_t extents;
cairo_bool_t overlap;
cairo_scaled_font_t *local_scaled_font = NULL;
status = _cairo_composite_rectangles_init_for_glyphs (&extents,
&surface->win32.base,
@ -1861,6 +1862,13 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
}
#endif
#if CAIRO_HAS_DWRITE_FONT
if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_DWRITE) {
status = _cairo_win32_printing_surface_analyze_operation (surface, op, source, &extents.bounded);
goto cleanup_composite;
}
#endif
/* For non win32 fonts we need to check that each glyph has a
* path available. If a path is not available,
* _cairo_scaled_glyph_lookup() will return
@ -1901,6 +1909,23 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
source = opaque;
}
#if CAIRO_HAS_DWRITE_FONT
/* For a printer, the dwrite path is not desirable as it goes through the
* bitmap-blitting GDI interop route. Better to create a win32 (GDI) font
* so that ExtTextOut can be used, giving the printer driver the chance
* to do the right thing with the text.
*/
if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_DWRITE) {
status = _cairo_dwrite_scaled_font_create_win32_scaled_font (scaled_font, &local_scaled_font);
if (status == CAIRO_STATUS_SUCCESS) {
scaled_font = local_scaled_font;
} else {
/* Reset status; we'll fall back to drawing glyphs as paths */
status = CAIRO_STATUS_SUCCESS;
}
}
#endif
#if CAIRO_HAS_WIN32_FONT
if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_WIN32 &&
source->type == CAIRO_PATTERN_TYPE_SOLID)
@ -1960,6 +1985,10 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
cleanup_composite:
_cairo_composite_rectangles_fini (&extents);
if (local_scaled_font)
cairo_scaled_font_destroy (local_scaled_font);
return status;
}
@ -2193,6 +2222,12 @@ cairo_win32_printing_surface_create (HDC hdc)
return paginated;
}
cairo_bool_t
_cairo_surface_is_win32_printing (const cairo_surface_t *surface)
{
return surface->backend && surface->backend->type == CAIRO_SURFACE_TYPE_WIN32_PRINTING;
}
static const cairo_surface_backend_t cairo_win32_printing_surface_backend = {
CAIRO_SURFACE_TYPE_WIN32_PRINTING,
_cairo_win32_printing_surface_finish,

View file

@ -53,6 +53,8 @@
#define WIN32_FONT_LOGICAL_SCALE 32
CAIRO_BEGIN_DECLS
/* Surface DC flag values */
enum {
/* If this is a surface created for printing or not */
@ -199,6 +201,12 @@ _cairo_win32_gdi_compositor_get (void);
cairo_status_t
_cairo_win32_print_gdi_error (const char *context);
cairo_bool_t
_cairo_surface_is_win32 (const cairo_surface_t *surface);
cairo_bool_t
_cairo_surface_is_win32_printing (const cairo_surface_t *surface);
cairo_private void
_cairo_win32_display_surface_discard_fallback (cairo_win32_display_surface_t *surface);
@ -245,4 +253,23 @@ _cairo_win32_scaled_font_is_type1 (cairo_scaled_font_t *scaled_font);
cairo_bool_t
_cairo_win32_scaled_font_is_bitmap (cairo_scaled_font_t *scaled_font);
#ifdef CAIRO_HAS_DWRITE_FONT
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_clip_t *clip);
cairo_int_status_t
_cairo_dwrite_scaled_font_create_win32_scaled_font (cairo_scaled_font_t *scaled_font,
cairo_scaled_font_t **new_font);
#endif /* CAIRO_HAS_DWRITE_FONT */
CAIRO_END_DECLS
#endif /* CAIRO_WIN32_PRIVATE_H */

View file

@ -0,0 +1,178 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* Cairo - a vector graphics library with display and print output
*
* Copyright <A9> 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_WIN32_REFPTR_H
#define CAIRO_WIN32_REFPTR_H
template<typename T> class TemporaryRef;
/**
* RefPtr points to a refcounted thing that has AddRef and Release
* methods to increase/decrease the refcount, respectively. After a
* RefPtr<T> is assigned a T*, the T* can be used through the RefPtr
* as if it were a T*.
*
* A RefPtr can forget its underlying T*, which results in the T*
* being wrapped in a temporary object until the T* is either
* re-adopted from or released by the temporary.
*/
template<typename T>
class RefPtr
{
// To allow them to use unref()
friend class TemporaryRef<T>;
struct dontRef {};
public:
RefPtr() : ptr(0) { }
RefPtr(const RefPtr& o) : ptr(ref(o.ptr)) {}
RefPtr(const TemporaryRef<T>& o) : ptr(o.drop()) {}
RefPtr(T* t) : ptr(ref(t)) {}
template<typename U>
RefPtr(const RefPtr<U>& o) : ptr(ref(o.get())) {}
~RefPtr() { unref(ptr); }
RefPtr& operator=(const RefPtr& o) {
assign(ref(o.ptr));
return *this;
}
RefPtr& operator=(const TemporaryRef<T>& o) {
assign(o.drop());
return *this;
}
RefPtr& operator=(T* t) {
assign(ref(t));
return *this;
}
template<typename U>
RefPtr& operator=(const RefPtr<U>& o) {
assign(ref(o.get()));
return *this;
}
TemporaryRef<T> forget() {
T* tmp = ptr;
ptr = 0;
return TemporaryRef<T>(tmp, dontRef());
}
T* get() const { return ptr; }
operator T*() const { return ptr; }
T* operator->() const { return ptr; }
T& operator*() const { return *ptr; }
template<typename U>
operator TemporaryRef<U>() { return TemporaryRef<U>(ptr); }
/**
* WARNING for ease of use, passing a reference will release/clear out ptr!
* We null out the ptr before returning its address so people passing byref
* as input will most likely get functions returning errors rather than accessing
* freed memory. Further more accessing it after this point if it hasn't
* been set will produce a null pointer dereference.
*/
T** operator&()
{
if (ptr) {
ptr->Release();
ptr = NULL;
}
return &ptr;
}
private:
void assign(T* t) {
unref(ptr);
ptr = t;
}
T* ptr;
static inline T* ref(T* t) {
if (t) {
t->AddRef();
}
return t;
}
static inline void unref(T* t) {
if (t) {
t->Release();
}
}
};
/**
* TemporaryRef<T> represents an object that holds a temporary
* reference to a T. TemporaryRef objects can't be manually ref'd or
* unref'd (being temporaries, not lvalues), so can only relinquish
* references to other objects, or unref on destruction.
*/
template<typename T>
class TemporaryRef
{
// To allow it to construct TemporaryRef from a bare T*
friend class RefPtr<T>;
typedef typename RefPtr<T>::dontRef dontRef;
public:
TemporaryRef(T* t) : ptr(RefPtr<T>::ref(t)) {}
TemporaryRef(const TemporaryRef& o) : ptr(o.drop()) {}
template<typename U>
TemporaryRef(const TemporaryRef<U>& o) : ptr(o.drop()) {}
~TemporaryRef() { RefPtr<T>::unref(ptr); }
T* drop() const {
T* tmp = ptr;
ptr = 0;
return tmp;
}
private:
TemporaryRef(T* t, const dontRef&) : ptr(t) {}
mutable T* ptr;
TemporaryRef();
TemporaryRef& operator=(const TemporaryRef&);
};
#endif

View file

@ -48,6 +48,7 @@
#include "cairoint.h"
#include "cairo-backend-private.h"
#include "cairo-default-context-private.h"
#include "cairo-error-private.h"
#include "cairo-image-surface-private.h"
@ -170,6 +171,46 @@ cairo_win32_surface_get_dc (cairo_surface_t *surface)
return NULL;
}
HDC
cairo_win32_get_dc_with_clip (cairo_t *cr)
{
cairo_surface_t *surface = cairo_get_target (cr);
if (cr->backend->type == CAIRO_TYPE_DEFAULT) {
cairo_default_context_t *c = (cairo_default_context_t *) cr;
cairo_clip_t *clip = _cairo_clip_copy (_cairo_gstate_get_clip (c->gstate));
if (_cairo_surface_is_win32 (surface)) {
cairo_win32_display_surface_t *winsurf = (cairo_win32_display_surface_t *) surface;
_cairo_win32_display_surface_set_clip (winsurf, clip);
_cairo_clip_destroy (clip);
return winsurf->win32.dc;
}
if (_cairo_surface_is_paginated (surface)) {
cairo_surface_t *target;
target = _cairo_paginated_surface_get_target (surface);
if (_cairo_surface_is_win32_printing (target)) {
cairo_status_t status;
cairo_win32_printing_surface_t *psurf = (cairo_win32_printing_surface_t *) target;
status = _cairo_surface_clipper_set_clip (&psurf->clipper, clip);
_cairo_clip_destroy (clip);
if (status)
return NULL;
return psurf->win32.dc;
}
}
_cairo_clip_destroy (clip);
}
return NULL;
}
/**
* _cairo_surface_is_win32:
* @surface: a #cairo_surface_t
@ -178,7 +219,7 @@ cairo_win32_surface_get_dc (cairo_surface_t *surface)
*
* Return value: %TRUE if the surface is an win32 surface
**/
static inline cairo_bool_t
cairo_bool_t
_cairo_surface_is_win32 (const cairo_surface_t *surface)
{
/* _cairo_surface_nil sets a NULL backend so be safe */
@ -219,6 +260,16 @@ _cairo_win32_surface_emit_glyphs (cairo_win32_surface_t *dst,
cairo_scaled_font_t *scaled_font,
cairo_bool_t glyph_indexing)
{
#if CAIRO_HAS_DWRITE_FONT
if (scaled_font->backend->type == CAIRO_FONT_TYPE_DWRITE) {
if (!glyph_indexing) return CAIRO_INT_STATUS_UNSUPPORTED;
// FIXME: fake values for params that aren't currently passed in here
cairo_operator_t op = CAIRO_OPERATOR_SOURCE;
cairo_clip_t *clip = NULL;
return _cairo_dwrite_show_glyphs_on_surface (dst, op, source, glyphs, num_glyphs, scaled_font, clip /* , glyph_indexing */ );
}
#endif
#if CAIRO_HAS_WIN32_FONT
WORD glyph_buf_stack[STACK_GLYPH_SIZE];
WORD *glyph_buf = glyph_buf_stack;
@ -335,3 +386,17 @@ _cairo_win32_surface_emit_glyphs (cairo_win32_surface_t *dst,
#endif
}
#undef STACK_GLYPH_SIZE
cairo_status_t
cairo_win32_surface_get_size (const cairo_surface_t *surface, int *width, int *height)
{
if (surface->type != CAIRO_SURFACE_TYPE_WIN32)
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
const cairo_win32_surface_t *winsurface = (const cairo_win32_surface_t *) surface;
*width = winsurface->extents.width;
*height = winsurface->extents.height;
return CAIRO_STATUS_SUCCESS;
}