mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-04-23 00:30:47 +02:00
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:
parent
1a799577b2
commit
90ca635472
12 changed files with 2020 additions and 8 deletions
18
meson.build
18
meson.build
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
1426
src/win32/cairo-dwrite-font.cpp
Normal file
1426
src/win32/cairo-dwrite-font.cpp
Normal file
File diff suppressed because it is too large
Load diff
229
src/win32/cairo-dwrite-private.hpp
Normal file
229
src/win32/cairo-dwrite-private.hpp
Normal 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);
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
178
src/win32/cairo-win32-refptr.hpp
Normal file
178
src/win32/cairo-win32-refptr.hpp
Normal 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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue