mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-02-04 15:20:28 +01:00
src/cairo-font-options.c src/cairo.h src/cairoint.h src/Makefile.am: Add an opaque cairo_font_options_t structure.
src/cairo-font.c src/cairo.h src/cairoint.h: Add a cairo_font_options_t object to cairo_scaled_font_create(). src/cairo-surface.c src/cairoint.h: Add virtualized cairo_surface_get_font_options() to get the font options for a surface. Adapt to cairo_scaled_font_create() change. Add an implementation of get_font_options() that turns off metrics hinting. src/cairo-xlib-screen.c src/cairo-xlib-private.h: Add a "screen info" structure that holds (for now) information about the default font options for the screen. Implement get_font_options() src/cairo-ft-font.c src/cairo-ft.h: Add functions to apply a cairo_font_options_t to a FcPattern or get the load flags for a cairo_font_options_t. Adapt to font options additions. Add support for non-antialiased rendering of scalable fonts. Add support for turning off metrics hinting. Adapt to font options additions. doc/public/Makefile.am doc/public/cairo-sections.txt: Update. reviewed by: cworth
This commit is contained in:
parent
a43c9eb7b0
commit
075cf23cdc
22 changed files with 1762 additions and 195 deletions
37
ChangeLog
37
ChangeLog
|
|
@ -1,3 +1,40 @@
|
|||
2005-07-13 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
reviewed by: cworth
|
||||
|
||||
* src/cairo-font-options.c src/cairo.h src/cairoint.h
|
||||
src/Makefile.am: Add an opaque cairo_font_options_t structure.
|
||||
|
||||
* src/cairo-font.c src/cairo.h src/cairoint.h: Add a
|
||||
cairo_font_options_t object to cairo_scaled_font_create().
|
||||
|
||||
* src/cairo-surface.c src/cairoint.h: Add virtualized
|
||||
cairo_surface_get_font_options() to get the font options for
|
||||
a surface.
|
||||
|
||||
* src/cairo-gstate.c: Adapt to cairo_scaled_font_create() change.
|
||||
|
||||
* src/cairo-pdf-surface.c: Add an implementation of
|
||||
get_font_options() that turns off metrics hinting.
|
||||
|
||||
* src/cairo-xlib-screen.c src/cairo-xlib-private.h: Add
|
||||
a "screen info" structure that holds (for now) information
|
||||
about the default font options for the screen.
|
||||
|
||||
* src/cairo-xlib-surface.c: Implement get_font_options()
|
||||
|
||||
* src/cairo-ft-font.c src/cairo-ft.h: Add functions to apply
|
||||
a cairo_font_options_t to a FcPattern or get the load flags
|
||||
for a cairo_font_options_t.
|
||||
|
||||
* src/cairo-ft-font.c: Adapt to font options additions.
|
||||
Add support for non-antialiased rendering of scalable fonts.
|
||||
Add support for turning off metrics hinting.
|
||||
|
||||
* src/cairo-win32-font.c: Adapt to font options additions.
|
||||
|
||||
* doc/public/Makefile.am doc/public/cairo-sections.txt: Update.
|
||||
|
||||
2005-07-21 Carl Worth <cworth@cworth.org>
|
||||
|
||||
* src/cairo-glitz-surface.c:
|
||||
|
|
|
|||
|
|
@ -21,8 +21,11 @@ CFILE_GLOB=$(top_srcdir)/src/*.c $(top_srcdir)/src/*.h
|
|||
# Headers to ignore
|
||||
IGNORE_HFILES= \
|
||||
cairo-features.h \
|
||||
cairo-font-subset-private.h \
|
||||
cairo-ft-private.h \
|
||||
cairo-gstate-private.h \
|
||||
cairo-hash-private.h \
|
||||
cairo-meta-surface-private.h \
|
||||
cairo-path-fixed-private.h \
|
||||
cairo-private.h \
|
||||
cairo-win32-private.h \
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<SECTION>
|
||||
<FILE>cairo-ft</FILE>
|
||||
<TITLE>FreeType Fonts</TITLE>
|
||||
cairo_ft_font_options_substitute
|
||||
cairo_ft_font_face_create_for_pattern
|
||||
cairo_ft_font_face_create_for_ft_face
|
||||
cairo_ft_scaled_font_lock_face
|
||||
|
|
@ -90,6 +91,7 @@ cairo_surface_create_similar
|
|||
cairo_surface_reference
|
||||
cairo_surface_destroy
|
||||
cairo_surface_finish
|
||||
cairo_surface_get_font_options
|
||||
cairo_surface_set_user_data
|
||||
cairo_surface_get_user_data
|
||||
cairo_surface_set_device_offset
|
||||
|
|
@ -99,6 +101,8 @@ cairo_surface_set_device_offset
|
|||
<FILE>cairo-pattern</FILE>
|
||||
<TITLE>cairo_pattern_t</TITLE>
|
||||
cairo_pattern_t
|
||||
cairo_pattern_create_rgb
|
||||
cairo_pattern_create_rgba
|
||||
cairo_pattern_create_for_surface
|
||||
cairo_pattern_create_linear
|
||||
cairo_pattern_create_radial
|
||||
|
|
@ -150,6 +154,26 @@ cairo_font_extents_t
|
|||
cairo_scaled_font_extents
|
||||
cairo_text_extents_t
|
||||
cairo_scaled_font_glyph_extents
|
||||
cairo_font_options_t
|
||||
cairo_font_options_create
|
||||
cairo_font_options_copy
|
||||
cairo_font_options_destroy
|
||||
cairo_font_options_status
|
||||
cairo_font_options_merge
|
||||
cairo_font_options_hash
|
||||
cairo_font_options_equal
|
||||
cairo_antialias_t
|
||||
cairo_font_options_set_antialias
|
||||
cairo_font_options_get_antialias
|
||||
cairo_subpixel_order_t
|
||||
cairo_font_options_set_subpixel_order
|
||||
cairo_font_options_get_subpixel_order
|
||||
cairo_hint_style_t
|
||||
cairo_font_options_set_hint_style
|
||||
cairo_font_options_get_hint_style
|
||||
cairo_hint_metrics_t
|
||||
cairo_font_options_set_hint_metrics
|
||||
cairo_font_options_get_hint_metrics
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
|
@ -161,7 +185,10 @@ cairo_reference
|
|||
cairo_destroy
|
||||
cairo_save
|
||||
cairo_restore
|
||||
cairo_content_t
|
||||
CAIRO_CONTENT_VALID
|
||||
cairo_format_t
|
||||
CAIRO_FORMAT_VALID
|
||||
cairo_operator_t
|
||||
cairo_set_operator
|
||||
cairo_set_source_rgb
|
||||
|
|
@ -255,8 +282,6 @@ cairo_status_t
|
|||
cairo_status
|
||||
cairo_status_string
|
||||
cairo_status_to_string
|
||||
cairo_error_notify_func_t
|
||||
cairo_set_error_notify
|
||||
cairo_filter_t
|
||||
cairo_image_surface_create
|
||||
cairo_image_surface_create_for_data
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ Font Handling
|
|||
@font_face:
|
||||
@font_matrix:
|
||||
@ctm:
|
||||
@options:
|
||||
@Returns:
|
||||
|
||||
|
||||
|
|
@ -138,3 +139,186 @@ Font Handling
|
|||
@extents:
|
||||
|
||||
|
||||
<!-- ##### TYPEDEF cairo_font_options_t ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_font_options_create ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_font_options_copy ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@original:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_font_options_destroy ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@options:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_font_options_status ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@options:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_font_options_merge ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@options:
|
||||
@other:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_font_options_hash ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@options:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_font_options_equal ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@options:
|
||||
@other:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### ENUM cairo_antialias_t ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@CAIRO_ANTIALIAS_DEFAULT:
|
||||
@CAIRO_ANTIALIAS_NONE:
|
||||
@CAIRO_ANTIALIAS_GRAY:
|
||||
@CAIRO_ANTIALIAS_SUBPIXEL:
|
||||
|
||||
<!-- ##### FUNCTION cairo_font_options_set_antialias ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@options:
|
||||
@antialias:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_font_options_get_antialias ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@options:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### ENUM cairo_subpixel_order_t ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@CAIRO_SUBPIXEL_ORDER_DEFAULT:
|
||||
@CAIRO_SUBPIXEL_ORDER_RGB:
|
||||
@CAIRO_SUBPIXEL_ORDER_BGR:
|
||||
@CAIRO_SUBPIXEL_ORDER_VRGB:
|
||||
@CAIRO_SUBPIXEL_ORDER_VBGR:
|
||||
|
||||
<!-- ##### FUNCTION cairo_font_options_set_subpixel_order ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@options:
|
||||
@subpixel_order:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_font_options_get_subpixel_order ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@options:
|
||||
@Returns:
|
||||
<!-- # Unused Parameters # -->
|
||||
@option:
|
||||
|
||||
|
||||
<!-- ##### ENUM cairo_hint_style_t ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@CAIRO_HINT_STYLE_DEFAULT:
|
||||
@CAIRO_HINT_STYLE_NONE:
|
||||
@CAIRO_HINT_STYLE_SLIGHT:
|
||||
@CAIRO_HINT_STYLE_MEDIUM:
|
||||
@CAIRO_HINT_STYLE_FULL:
|
||||
|
||||
<!-- ##### FUNCTION cairo_font_options_set_hint_style ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@options:
|
||||
@hint_style:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_font_options_get_hint_style ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@options:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### ENUM cairo_hint_metrics_t ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@CAIRO_HINT_METRICS_DEFAULT:
|
||||
@CAIRO_HINT_METRICS_OFF:
|
||||
@CAIRO_HINT_METRICS_ON:
|
||||
|
||||
<!-- ##### FUNCTION cairo_font_options_set_hint_metrics ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@options:
|
||||
@hint_metrics:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_font_options_get_hint_metrics ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@options:
|
||||
@Returns:
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,15 @@ FreeType Fonts
|
|||
<!-- ##### SECTION Stability_Level ##### -->
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_ft_font_options_substitute ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@options:
|
||||
@pattern:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_ft_font_face_create_for_pattern ##### -->
|
||||
<para>
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,29 @@ cairo_pattern_t
|
|||
</para>
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_pattern_create_rgb ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@red:
|
||||
@green:
|
||||
@blue:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_pattern_create_rgba ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@red:
|
||||
@green:
|
||||
@blue:
|
||||
@alpha:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_pattern_create_for_surface ##### -->
|
||||
<para>
|
||||
|
||||
|
|
|
|||
|
|
@ -29,10 +29,12 @@ cairo_surface_t
|
|||
</para>
|
||||
|
||||
@other:
|
||||
@format:
|
||||
@content:
|
||||
@width:
|
||||
@height:
|
||||
@Returns:
|
||||
<!-- # Unused Parameters # -->
|
||||
@format:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_surface_reference ##### -->
|
||||
|
|
@ -60,6 +62,15 @@ cairo_surface_t
|
|||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_surface_get_font_options ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@surface:
|
||||
@options:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION cairo_surface_set_user_data ##### -->
|
||||
<para>
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,23 @@ Drawing contexts.
|
|||
@cr:
|
||||
|
||||
|
||||
<!-- ##### ENUM cairo_content_t ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@CAIRO_CONTENT_COLOR:
|
||||
@CAIRO_CONTENT_ALPHA:
|
||||
@CAIRO_CONTENT_COLOR_ALPHA:
|
||||
|
||||
<!-- ##### MACRO CAIRO_CONTENT_VALID ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@content:
|
||||
|
||||
|
||||
<!-- ##### ENUM cairo_format_t ##### -->
|
||||
<para>
|
||||
|
||||
|
|
@ -84,6 +101,14 @@ Drawing contexts.
|
|||
@CAIRO_FORMAT_A8:
|
||||
@CAIRO_FORMAT_A1:
|
||||
|
||||
<!-- ##### MACRO CAIRO_FORMAT_VALID ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@format:
|
||||
|
||||
|
||||
<!-- ##### ENUM cairo_operator_t ##### -->
|
||||
<para>
|
||||
|
||||
|
|
@ -942,7 +967,7 @@ Drawing contexts.
|
|||
@CAIRO_STATUS_INVALID_POP_GROUP:
|
||||
@CAIRO_STATUS_NO_CURRENT_POINT:
|
||||
@CAIRO_STATUS_INVALID_MATRIX:
|
||||
@CAIRO_STATUS_NO_TARGET_SURFACE:
|
||||
@CAIRO_STATUS_INVALID_STATUS:
|
||||
@CAIRO_STATUS_NULL_POINTER:
|
||||
@CAIRO_STATUS_INVALID_STRING:
|
||||
@CAIRO_STATUS_INVALID_PATH_DATA:
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ endif
|
|||
|
||||
if CAIRO_HAS_XLIB_SURFACE
|
||||
libcairo_xlib_headers = cairo-xlib.h cairo-xlib-xrender.h
|
||||
libcairo_xlib_sources = cairo-xlib-surface.c cairo-xlib-test.h
|
||||
libcairo_xlib_sources = cairo-xlib-surface.c cairo-xlib-screen.c cairo-xlib-private.h cairo-xlib-test.h
|
||||
endif
|
||||
|
||||
if CAIRO_HAS_QUARTZ_SURFACE
|
||||
|
|
@ -88,6 +88,7 @@ libcairo_la_SOURCES = \
|
|||
cairo-color.c \
|
||||
cairo-fixed.c \
|
||||
cairo-font.c \
|
||||
cairo-font-options.c \
|
||||
cairo-gstate.c \
|
||||
cairo-gstate-private.h \
|
||||
cairo-hull.c \
|
||||
|
|
|
|||
352
src/cairo-font-options.c
Normal file
352
src/cairo-font-options.c
Normal file
|
|
@ -0,0 +1,352 @@
|
|||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat Inc.
|
||||
*
|
||||
* 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 University of Southern
|
||||
* California.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Owen Taylor <otaylor@redhat.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
static const cairo_font_options_t cairo_font_options_nil = {
|
||||
CAIRO_ANTIALIAS_DEFAULT,
|
||||
CAIRO_SUBPIXEL_ORDER_DEFAULT,
|
||||
CAIRO_HINT_STYLE_DEFAULT,
|
||||
CAIRO_HINT_METRICS_DEFAULT
|
||||
};
|
||||
|
||||
/**
|
||||
* _cairo_font_options_init_default:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Initializes all fileds of the font options object to default values.
|
||||
**/
|
||||
void
|
||||
_cairo_font_options_init_default (cairo_font_options_t *options)
|
||||
{
|
||||
if (options == (cairo_font_options_t *)&cairo_font_options_nil)
|
||||
return;
|
||||
|
||||
options->antialias = CAIRO_ANTIALIAS_DEFAULT;
|
||||
options->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
|
||||
options->hint_style = CAIRO_HINT_STYLE_DEFAULT;
|
||||
options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_create:
|
||||
*
|
||||
* Allocates a new font options object with all options initialized
|
||||
* to default values.
|
||||
*
|
||||
* Return value: a newly allocated #cairo_font_options_t. Free with
|
||||
* cairo_font_options_destroy(). This function always returns a
|
||||
* valid pointer; if memory cannot be allocated, then a special
|
||||
* error object is returned where all operations on the object do nothing.
|
||||
* You can check for this with cairo_font_options_status().
|
||||
**/
|
||||
cairo_font_options_t *
|
||||
cairo_font_options_create (void)
|
||||
{
|
||||
cairo_font_options_t *options = malloc (sizeof (cairo_font_options_t));
|
||||
|
||||
if (!options)
|
||||
return (cairo_font_options_t *)&cairo_font_options_nil;
|
||||
|
||||
_cairo_font_options_init_default (options);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_copy:
|
||||
* @original: a #cairo_font_options_t
|
||||
*
|
||||
* Allocates a new font options object copying the option values from
|
||||
* @original.
|
||||
*
|
||||
* Return value: a newly allocated #cairo_font_options_t. Free with
|
||||
* cairo_font_options_destroy(). This function always returns a
|
||||
* valid pointer; if memory cannot be allocated, then a special
|
||||
* error object is returned where all operations on the object do nothing.
|
||||
* You can check for this with cairo_font_options_status().
|
||||
**/
|
||||
cairo_font_options_t *
|
||||
cairo_font_options_copy (const cairo_font_options_t *original)
|
||||
{
|
||||
cairo_font_options_t *options = malloc (sizeof (cairo_font_options_t));
|
||||
|
||||
if (!options)
|
||||
return (cairo_font_options_t *)&cairo_font_options_nil;
|
||||
|
||||
*options = *original;
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_destroy:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Destroys a #cairo_font_options_t object created with with
|
||||
* cairo_font_options_create() or cairo_font_options_copy().
|
||||
**/
|
||||
void
|
||||
cairo_font_options_destroy (cairo_font_options_t *options)
|
||||
{
|
||||
if (options == (cairo_font_options_t *)&cairo_font_options_nil)
|
||||
return;
|
||||
|
||||
free (options);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_status:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Checks whether an error has previously occurred for this
|
||||
* font options object
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_font_options_status (cairo_font_options_t *options)
|
||||
{
|
||||
if (options == (cairo_font_options_t *)&cairo_font_options_nil)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
else
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_merge:
|
||||
* @options: a #cairo_font_options_t
|
||||
* @other: another #cairo_font_options_t
|
||||
*
|
||||
* Merges non-default options from @other into @options, replacing
|
||||
* existing values. This operation can be thought of as somewhat
|
||||
* similar to compositing @other onto @options with the operation
|
||||
* of %CAIRO_OPERATION_OVER.
|
||||
**/
|
||||
void
|
||||
cairo_font_options_merge (cairo_font_options_t *options,
|
||||
const cairo_font_options_t *other)
|
||||
{
|
||||
if (options == (cairo_font_options_t *)&cairo_font_options_nil)
|
||||
return;
|
||||
|
||||
if (other->antialias != CAIRO_ANTIALIAS_DEFAULT)
|
||||
options->antialias = other->antialias;
|
||||
if (other->subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT)
|
||||
options->subpixel_order = other->subpixel_order;
|
||||
if (other->hint_style != CAIRO_HINT_STYLE_DEFAULT)
|
||||
options->hint_style = other->hint_style;
|
||||
if (other->hint_metrics != CAIRO_HINT_METRICS_DEFAULT)
|
||||
options->hint_metrics = other->hint_metrics;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_equual:
|
||||
* @options: a #cairo_font_options_t
|
||||
* @other: another #cairo_font_options_t
|
||||
*
|
||||
* Compares two font options objects for equality.
|
||||
*
|
||||
* Return value: %TRUE if all fields of the two font options objects match
|
||||
**/
|
||||
cairo_bool_t
|
||||
cairo_font_options_equal (const cairo_font_options_t *options,
|
||||
const cairo_font_options_t *other)
|
||||
{
|
||||
return (options->antialias == other->antialias &&
|
||||
options->subpixel_order == other->subpixel_order &&
|
||||
options->hint_style == other->hint_style &&
|
||||
options->hint_metrics == other->hint_metrics);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_hash:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Compute a hash for the font options object; this value will
|
||||
* be useful when storing an object containing a cairo_font_options_t
|
||||
* in a hash table.
|
||||
*
|
||||
* Return value: the hash value for the font options object.
|
||||
* The return value can be cast to a 32-bit type if a
|
||||
* 32-bit hash value is needed.
|
||||
**/
|
||||
unsigned long
|
||||
cairo_font_options_hash (const cairo_font_options_t *options)
|
||||
{
|
||||
return ((options->antialias) |
|
||||
(options->subpixel_order << 4) |
|
||||
(options->hint_style << 8) |
|
||||
(options->hint_metrics << 16));
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_set_antialias:
|
||||
* @options: a #cairo_font_options_t
|
||||
* @antialias: the new antialiasing mode
|
||||
*
|
||||
* Sets the antiliasing mode for the font options object. This
|
||||
* specifies the type of antialiasing to do when rendering text.
|
||||
**/
|
||||
void
|
||||
cairo_font_options_set_antialias (cairo_font_options_t *options,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
if (options == (cairo_font_options_t *)&cairo_font_options_nil)
|
||||
return;
|
||||
|
||||
options->antialias = antialias;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_get_antialias:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Gets the antialising mode for the font options object.
|
||||
*
|
||||
* Return value: the antialiasing mode
|
||||
**/
|
||||
cairo_antialias_t
|
||||
cairo_font_options_get_antialias (const cairo_font_options_t *options)
|
||||
{
|
||||
return options->antialias;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_set_subpixel_order:
|
||||
* @options: a #cairo_font_options_t
|
||||
* @subpixel_order: the new subpixel order
|
||||
*
|
||||
* Sets the subpixel order for the font options object. The subpixel
|
||||
* order specifies the order of color elements within each pixel on
|
||||
* the display device when rendering with an antialiasing mode of
|
||||
* %CAIRO_ANTIALIAS_SUBPIXEL. See the documentation for
|
||||
* #cairo_subpixel_order_t for full details.
|
||||
**/
|
||||
void
|
||||
cairo_font_options_set_subpixel_order (cairo_font_options_t *options,
|
||||
cairo_subpixel_order_t subpixel_order)
|
||||
{
|
||||
if (options == (cairo_font_options_t *)&cairo_font_options_nil)
|
||||
return;
|
||||
|
||||
options->subpixel_order = subpixel_order;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_get_subpixel_order:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Gets the subpixel order for the font options object.
|
||||
* See the documentation for #cairo_subpixel_order_t for full details.
|
||||
*
|
||||
* Return value: the subpixel order for the font options object
|
||||
**/
|
||||
cairo_subpixel_order_t
|
||||
cairo_font_options_get_subpixel_order (const cairo_font_options_t *options)
|
||||
{
|
||||
return options->subpixel_order;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_set_hint_style:
|
||||
* @options: a #cairo_font_options_t
|
||||
* @hint_style: the new hint style
|
||||
*
|
||||
* Sets the hint style for font outlines for the font options object.
|
||||
* This controls whether to fit font outlines to the pixel grid,
|
||||
* and if so, whether to optimize for fidelity or contrast.
|
||||
* See the documentation for #cairo_hint_style_t for full details.
|
||||
**/
|
||||
void
|
||||
cairo_font_options_set_hint_style (cairo_font_options_t *options,
|
||||
cairo_hint_style_t hint_style)
|
||||
{
|
||||
if (options == (cairo_font_options_t *)&cairo_font_options_nil)
|
||||
return;
|
||||
|
||||
options->hint_style = hint_style;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_get_hint_style:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Gets the hint style for font outlines for the font options object.
|
||||
* See the documentation for #cairo_hint_style_t for full details.
|
||||
*
|
||||
* Return value: the hint style for the font options object
|
||||
**/
|
||||
cairo_hint_style_t
|
||||
cairo_font_options_get_hint_style (const cairo_font_options_t *options)
|
||||
{
|
||||
return options->hint_style;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_set_hint_metrics:
|
||||
* @options: a #cairo_font_options_t
|
||||
* @hint_metrics: the new metrics hinting mode
|
||||
*
|
||||
* Sets the metrics hinting mode for the font options object. This
|
||||
* controls whether metrics are quantized to integer values in
|
||||
* device units.
|
||||
* See the documentation for #cairo_hint_metrics_t for full details.
|
||||
**/
|
||||
void
|
||||
cairo_font_options_set_hint_metrics (cairo_font_options_t *options,
|
||||
cairo_hint_metrics_t hint_metrics)
|
||||
{
|
||||
if (options == (cairo_font_options_t *)&cairo_font_options_nil)
|
||||
return;
|
||||
|
||||
options->hint_metrics = hint_metrics;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_font_options_get_hint_metrics:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Gets the metrics hinting mode for the font options object.
|
||||
* See the documentation for #cairo_hint_metrics_t for full details.
|
||||
*
|
||||
* Return value: the metrics hinting mode for the font options object
|
||||
**/
|
||||
cairo_hint_metrics_t
|
||||
cairo_font_options_get_hint_metrics (const cairo_font_options_t *options)
|
||||
{
|
||||
return options->hint_metrics;
|
||||
}
|
||||
|
|
@ -355,17 +355,18 @@ _cairo_simple_font_face_destroy (void *abstract_face)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_simple_font_face_create_font (void *abstract_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
cairo_scaled_font_t **scaled_font)
|
||||
_cairo_simple_font_face_create_font (void *abstract_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options,
|
||||
cairo_scaled_font_t **scaled_font)
|
||||
{
|
||||
const cairo_scaled_font_backend_t * backend = CAIRO_SCALED_FONT_BACKEND_DEFAULT;
|
||||
|
||||
cairo_simple_font_face_t *simple_face = abstract_face;
|
||||
|
||||
return backend->create (simple_face->family, simple_face->slant, simple_face->weight,
|
||||
font_matrix, ctm, scaled_font);
|
||||
font_matrix, ctm, options, scaled_font);
|
||||
}
|
||||
|
||||
static const cairo_font_face_backend_t _cairo_simple_font_face_backend = {
|
||||
|
|
@ -444,6 +445,7 @@ typedef struct {
|
|||
cairo_font_face_t *font_face;
|
||||
const cairo_matrix_t *font_matrix;
|
||||
const cairo_matrix_t *ctm;
|
||||
cairo_font_options_t options;
|
||||
} cairo_font_cache_key_t;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -554,7 +556,9 @@ _cairo_font_cache_hash (void *cache, void *key)
|
|||
sizeof(double) * 4,
|
||||
hash);
|
||||
|
||||
return hash ^ (unsigned long)k->font_face;
|
||||
return (hash ^
|
||||
(unsigned long)k->font_face ^
|
||||
cairo_font_options_hash (&k->options));
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -573,7 +577,8 @@ _cairo_font_cache_keys_equal (void *cache,
|
|||
sizeof(double) * 4) == 0 &&
|
||||
memcmp ((unsigned char *)(&a->ctm->xx),
|
||||
(unsigned char *)(&b->ctm->xx),
|
||||
sizeof(double) * 4) == 0);
|
||||
sizeof(double) * 4) == 0 &&
|
||||
cairo_font_options_equal (&a->options, &b->options));
|
||||
}
|
||||
|
||||
/* The cache lookup failed in the outer cache, so we pull
|
||||
|
|
@ -614,6 +619,7 @@ _cairo_outer_font_cache_create_entry (void *cache,
|
|||
entry->key.font_face = entry->scaled_font->font_face;
|
||||
entry->key.font_matrix = &entry->scaled_font->font_matrix;
|
||||
entry->key.ctm = &entry->scaled_font->ctm;
|
||||
entry->key.options = ((cairo_font_cache_key_t *) key)->options;
|
||||
|
||||
*return_entry = entry;
|
||||
|
||||
|
|
@ -650,6 +656,7 @@ _cairo_inner_font_cache_create_entry (void *cache,
|
|||
status = k->font_face->backend->create_font (k->font_face,
|
||||
k->font_matrix,
|
||||
k->ctm,
|
||||
&k->options,
|
||||
&entry->scaled_font);
|
||||
if (status) {
|
||||
free (entry);
|
||||
|
|
@ -663,6 +670,7 @@ _cairo_inner_font_cache_create_entry (void *cache,
|
|||
entry->key.font_face = k->font_face;
|
||||
entry->key.font_matrix = &entry->scaled_font->font_matrix;
|
||||
entry->key.ctm = &entry->scaled_font->ctm;
|
||||
entry->key.options = k->options;
|
||||
|
||||
*return_entry = entry;
|
||||
|
||||
|
|
@ -712,6 +720,8 @@ static const cairo_cache_backend_t _cairo_inner_font_cache_backend = {
|
|||
* cairo_set_font_matrix().
|
||||
* @ctm: user to device transformation matrix with which the font will
|
||||
* be used.
|
||||
* @options: options to use when getting metrics for the font and
|
||||
* rendering with it.
|
||||
*
|
||||
* Creates a #cairo_scaled_font_t object from a font face and matrices that
|
||||
* describe the size of the font and the environment in which it will
|
||||
|
|
@ -721,9 +731,10 @@ static const cairo_cache_backend_t _cairo_inner_font_cache_backend = {
|
|||
* cairo_scaled_font_destroy()
|
||||
**/
|
||||
cairo_scaled_font_t *
|
||||
cairo_scaled_font_create (cairo_font_face_t *font_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm)
|
||||
cairo_scaled_font_create (cairo_font_face_t *font_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options)
|
||||
{
|
||||
cairo_font_cache_entry_t *entry;
|
||||
cairo_font_cache_key_t key;
|
||||
|
|
@ -733,6 +744,7 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
|
|||
key.font_face = font_face;
|
||||
key.font_matrix = font_matrix;
|
||||
key.ctm = ctm;
|
||||
key.options = *options;
|
||||
|
||||
_lock_global_font_cache ();
|
||||
cache = _get_outer_font_cache ();
|
||||
|
|
|
|||
|
|
@ -51,6 +51,19 @@
|
|||
#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
|
||||
#define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0)
|
||||
|
||||
/* We pack some of our own information into the bits unused
|
||||
* by FreeType's load flags. If FreeType ever uses up all
|
||||
* the load flag bits, we'll have to do something else.
|
||||
* (probably just store what we care about in load_flags
|
||||
* then convert into FreeType terms.
|
||||
*/
|
||||
#define PRIVATE_FLAG_HINT_METRICS (0x01 << 24)
|
||||
#define PRIVATE_FLAGS_MASK (0xff << 24)
|
||||
|
||||
/* This is the max number of FT_face objects we keep open at once
|
||||
*/
|
||||
#define MAX_OPEN_FACES 10
|
||||
|
||||
/* This is the max number of FT_face objects we keep open at once
|
||||
*/
|
||||
#define MAX_OPEN_FACES 10
|
||||
|
|
@ -551,6 +564,87 @@ _cairo_ft_unscaled_font_destroy (void *abstract_font)
|
|||
}
|
||||
}
|
||||
|
||||
/* Fills in val->image with an image surface created from @bitmap
|
||||
*/
|
||||
static cairo_status_t
|
||||
_get_bitmap_surface (cairo_image_glyph_cache_entry_t *val,
|
||||
FT_Bitmap *bitmap,
|
||||
cairo_bool_t own_buffer)
|
||||
{
|
||||
int width, height, stride;
|
||||
unsigned char *data;
|
||||
int i, j;
|
||||
|
||||
width = bitmap->width;
|
||||
height = bitmap->rows;
|
||||
|
||||
if (width * height == 0) {
|
||||
if (own_buffer && bitmap->buffer)
|
||||
free (bitmap->buffer);
|
||||
|
||||
val->image = NULL;
|
||||
} else {
|
||||
switch (bitmap->pixel_mode) {
|
||||
case FT_PIXEL_MODE_MONO:
|
||||
stride = (width + 3) & ~3;
|
||||
data = calloc (stride * height, 1);
|
||||
if (!data)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
for (j = 0; j < height; j++) {
|
||||
const unsigned char *p = bitmap->buffer + j * bitmap->pitch;
|
||||
unsigned char *q = data + j * stride;
|
||||
for (i = 0; i < width; i++) {
|
||||
/* FreeType bitmaps are always stored MSB */
|
||||
unsigned char byte = p[i >> 3];
|
||||
unsigned char bit = 1 << (7 - (i % 8));
|
||||
|
||||
if (byte & bit)
|
||||
q[i] = 0xff;
|
||||
}
|
||||
}
|
||||
if (own_buffer)
|
||||
free (bitmap->buffer);
|
||||
break;
|
||||
case FT_PIXEL_MODE_GRAY:
|
||||
stride = bitmap->pitch;
|
||||
if (own_buffer) {
|
||||
data = bitmap->buffer;
|
||||
} else {
|
||||
data = malloc (stride * height);
|
||||
if (!data)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
memcpy (data, bitmap->buffer, stride * height);
|
||||
}
|
||||
break;
|
||||
case FT_PIXEL_MODE_GRAY2:
|
||||
case FT_PIXEL_MODE_GRAY4:
|
||||
/* These could be triggered by very rare types of TrueType fonts */
|
||||
case FT_PIXEL_MODE_LCD:
|
||||
case FT_PIXEL_MODE_LCD_V:
|
||||
/* These should never be triggered unless we ask for them */
|
||||
default:
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
val->image = (cairo_image_surface_t *)
|
||||
cairo_image_surface_create_for_data (data,
|
||||
CAIRO_FORMAT_A8,
|
||||
width, height, stride);
|
||||
if (val->image == NULL) {
|
||||
free (data);
|
||||
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
_cairo_image_surface_assume_ownership_of_data (val->image);
|
||||
}
|
||||
|
||||
val->size.width = width;
|
||||
val->size.height = height;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Converts an outline FT_GlyphSlot into an image
|
||||
*
|
||||
* This could go through _render_glyph_bitmap as well, letting
|
||||
|
|
@ -586,17 +680,23 @@ _render_glyph_outline (FT_Face face,
|
|||
|
||||
width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6);
|
||||
height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6);
|
||||
stride = (width + 3) & -4;
|
||||
|
||||
if (width * height == 0) {
|
||||
val->image = NULL;
|
||||
} else {
|
||||
|
||||
bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
|
||||
bitmap.num_grays = 256;
|
||||
if ((val->key.flags & FT_LOAD_MONOCHROME) != 0) {
|
||||
bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
|
||||
bitmap.num_grays = 1;
|
||||
stride = ((width + 31) & -32) >> 3;
|
||||
} else {
|
||||
bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
|
||||
bitmap.num_grays = 256;
|
||||
stride = (width + 3) & -4;
|
||||
}
|
||||
bitmap.pitch = stride;
|
||||
bitmap.width = width;
|
||||
bitmap.rows = height;
|
||||
bitmap.pitch = stride;
|
||||
bitmap.buffer = calloc (1, stride * height);
|
||||
|
||||
if (bitmap.buffer == NULL) {
|
||||
|
|
@ -609,17 +709,10 @@ _render_glyph_outline (FT_Face face,
|
|||
free (bitmap.buffer);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
val->image = (cairo_image_surface_t *)
|
||||
cairo_image_surface_create_for_data (bitmap.buffer,
|
||||
CAIRO_FORMAT_A8,
|
||||
width, height, stride);
|
||||
if (val->image == NULL) {
|
||||
free (bitmap.buffer);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
_cairo_image_surface_assume_ownership_of_data (val->image);
|
||||
|
||||
status = _get_bitmap_surface (val, &bitmap, TRUE);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -627,8 +720,6 @@ _render_glyph_outline (FT_Face face,
|
|||
* Y coordinate of the control box needs to be negated.
|
||||
*/
|
||||
|
||||
val->size.width = (unsigned short) width;
|
||||
val->size.height = (unsigned short) height;
|
||||
val->size.x = (short) (cbox.xMin >> 6);
|
||||
val->size.y = - (short) (cbox.yMax >> 6);
|
||||
|
||||
|
|
@ -655,12 +746,8 @@ _render_glyph_bitmap (FT_Face face,
|
|||
cairo_image_glyph_cache_entry_t *val)
|
||||
{
|
||||
FT_GlyphSlot glyphslot = face->glyph;
|
||||
FT_Bitmap *bitmap;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
int width, height, stride;
|
||||
unsigned char *data;
|
||||
FT_Error error;
|
||||
int i, j;
|
||||
|
||||
/* According to the FreeType docs, glyphslot->format could be
|
||||
* something other than FT_GLYPH_FORMAT_OUTLINE or
|
||||
|
|
@ -673,64 +760,8 @@ _render_glyph_bitmap (FT_Face face,
|
|||
if (error)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
bitmap = &glyphslot->bitmap;
|
||||
_get_bitmap_surface (val, &glyphslot->bitmap, FALSE);
|
||||
|
||||
width = bitmap->width;
|
||||
height = bitmap->rows;
|
||||
|
||||
if (width * height == 0) {
|
||||
val->image = NULL;
|
||||
} else {
|
||||
switch (bitmap->pixel_mode) {
|
||||
case FT_PIXEL_MODE_MONO:
|
||||
stride = (width + 3) & ~3;
|
||||
data = calloc (stride * height, 1);
|
||||
if (!data)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
for (j = 0; j < height; j++) {
|
||||
const unsigned char *p = bitmap->buffer + j * bitmap->pitch;
|
||||
unsigned char *q = data + j * stride;
|
||||
for (i = 0; i < width; i++) {
|
||||
/* FreeType bitmaps are always stored MSB */
|
||||
unsigned char byte = p[i >> 3];
|
||||
unsigned char bit = 1 << (7 - (i % 8));
|
||||
|
||||
if (byte & bit)
|
||||
q[i] = 0xff;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FT_PIXEL_MODE_GRAY:
|
||||
stride = bitmap->pitch;
|
||||
data = malloc (stride * height);
|
||||
if (!data)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
memcpy (data, bitmap->buffer, stride * height);
|
||||
break;
|
||||
case FT_PIXEL_MODE_GRAY2:
|
||||
case FT_PIXEL_MODE_GRAY4:
|
||||
/* These could be triggered by very rare types of TrueType fonts */
|
||||
case FT_PIXEL_MODE_LCD:
|
||||
case FT_PIXEL_MODE_LCD_V:
|
||||
/* These should never be triggered unless we ask for them */
|
||||
default:
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
val->image = (cairo_image_surface_t *)
|
||||
cairo_image_surface_create_for_data (data,
|
||||
CAIRO_FORMAT_A8,
|
||||
width, height, stride);
|
||||
if (val->image == NULL) {
|
||||
free (data);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
_cairo_image_surface_assume_ownership_of_data (val->image);
|
||||
}
|
||||
|
||||
val->size.width = width;
|
||||
val->size.height = height;
|
||||
val->size.x = - glyphslot->bitmap_left;
|
||||
val->size.y = - glyphslot->bitmap_top;
|
||||
|
||||
|
|
@ -875,7 +906,7 @@ _cairo_ft_unscaled_font_create_glyph (void *abstract_
|
|||
|
||||
_ft_unscaled_font_set_scale (unscaled, &val->key.scale);
|
||||
|
||||
if (FT_Load_Glyph (face, val->key.index, val->key.flags) != 0) {
|
||||
if (FT_Load_Glyph (face, val->key.index, val->key.flags & ~PRIVATE_FLAGS_MASK) != 0) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto FAIL;
|
||||
}
|
||||
|
|
@ -886,22 +917,46 @@ _cairo_ft_unscaled_font_create_glyph (void *abstract_
|
|||
*
|
||||
* Scale metrics back to glyph space from the scaled glyph space returned
|
||||
* by FreeType
|
||||
*
|
||||
* If we want hinted metrics but aren't asking for hinted glyphs from
|
||||
* FreeType, then we need to do the metric hinting ourselves.
|
||||
*/
|
||||
|
||||
val->extents.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) / unscaled->x_scale;
|
||||
val->extents.y_bearing = -DOUBLE_FROM_26_6 (metrics->horiBearingY) / unscaled->y_scale;
|
||||
|
||||
val->extents.width = DOUBLE_FROM_26_6 (metrics->width) / unscaled->x_scale;
|
||||
val->extents.height = DOUBLE_FROM_26_6 (metrics->height) / unscaled->y_scale;
|
||||
|
||||
/*
|
||||
* use untransformed advance values
|
||||
* XXX uses horizontal advance only at present;
|
||||
should provide FT_LOAD_VERTICAL_LAYOUT
|
||||
*/
|
||||
|
||||
val->extents.x_advance = DOUBLE_FROM_26_6 (face->glyph->metrics.horiAdvance) / unscaled->x_scale;
|
||||
val->extents.y_advance = 0 / unscaled->y_scale;
|
||||
|
||||
if ((val->key.flags & PRIVATE_FLAG_HINT_METRICS) &&
|
||||
(val->key.flags & FT_LOAD_NO_HINTING)) {
|
||||
FT_Pos x1, x2;
|
||||
FT_Pos y1, y2;
|
||||
FT_Pos advance;
|
||||
|
||||
x1 = (metrics->horiBearingX) & -64;
|
||||
x2 = (metrics->horiBearingX + metrics->width + 63) & -64;
|
||||
y1 = (metrics->horiBearingY) & -64;
|
||||
y2 = (metrics->horiBearingY + metrics->height + 63) & -64;
|
||||
|
||||
advance = ((metrics->horiAdvance + 32) & -64);
|
||||
|
||||
val->extents.x_bearing = DOUBLE_FROM_26_6 (x1) / unscaled->x_scale;
|
||||
val->extents.y_bearing = -DOUBLE_FROM_26_6 (y1) / unscaled->y_scale;
|
||||
|
||||
val->extents.width = DOUBLE_FROM_26_6 (x2 - x1) / unscaled->x_scale;
|
||||
val->extents.height = DOUBLE_FROM_26_6 (y2 - y1) / unscaled->y_scale;
|
||||
|
||||
/*
|
||||
* use untransformed advance values
|
||||
* XXX uses horizontal advance only at present; should provide FT_LOAD_VERTICAL_LAYOUT
|
||||
*/
|
||||
val->extents.x_advance = DOUBLE_FROM_26_6 (advance) / unscaled->x_scale;
|
||||
val->extents.y_advance = 0;
|
||||
} else {
|
||||
val->extents.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) / unscaled->x_scale;
|
||||
val->extents.y_bearing = -DOUBLE_FROM_26_6 (metrics->horiBearingY) / unscaled->y_scale;
|
||||
|
||||
val->extents.width = DOUBLE_FROM_26_6 (metrics->width) / unscaled->x_scale;
|
||||
val->extents.height = DOUBLE_FROM_26_6 (metrics->height) / unscaled->y_scale;
|
||||
|
||||
val->extents.x_advance = DOUBLE_FROM_26_6 (face->glyph->metrics.horiAdvance) / unscaled->x_scale;
|
||||
val->extents.y_advance = 0 / unscaled->y_scale;
|
||||
}
|
||||
|
||||
if (glyphslot->format == FT_GLYPH_FORMAT_OUTLINE)
|
||||
status = _render_glyph_outline (face, val);
|
||||
|
|
@ -933,23 +988,19 @@ const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend = {
|
|||
typedef struct {
|
||||
cairo_scaled_font_t base;
|
||||
int load_flags;
|
||||
cairo_font_options_t options;
|
||||
ft_unscaled_font_t *unscaled;
|
||||
} cairo_ft_scaled_font_t;
|
||||
|
||||
const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend;
|
||||
|
||||
/* for compatibility with older freetype versions */
|
||||
#ifndef FT_LOAD_TARGET_MONO
|
||||
#define FT_LOAD_TARGET_MONO FT_LOAD_MONOCHROME
|
||||
#endif
|
||||
|
||||
/* The load flags passed to FT_Load_Glyph control aspects like hinting and
|
||||
* antialiasing. Here we compute them from the fields of a FcPattern.
|
||||
*/
|
||||
static int
|
||||
_get_load_flags (FcPattern *pattern)
|
||||
_get_pattern_load_flags (FcPattern *pattern)
|
||||
{
|
||||
FcBool antialias, hinting, autohint;
|
||||
FcBool antialias, vertical_layout, hinting, autohint;
|
||||
#ifdef FC_HINT_STYLE
|
||||
int hintstyle;
|
||||
#endif
|
||||
|
|
@ -959,17 +1010,17 @@ _get_load_flags (FcPattern *pattern)
|
|||
if (FcPatternGetBool (pattern,
|
||||
FC_ANTIALIAS, 0, &antialias) != FcResultMatch)
|
||||
antialias = FcTrue;
|
||||
|
||||
|
||||
if (antialias)
|
||||
load_flags |= FT_LOAD_NO_BITMAP;
|
||||
else
|
||||
load_flags |= FT_LOAD_TARGET_MONO;
|
||||
load_flags |= FT_LOAD_MONOCHROME;
|
||||
|
||||
/* disable hinting if requested */
|
||||
if (FcPatternGetBool (pattern,
|
||||
FC_HINTING, 0, &hinting) != FcResultMatch)
|
||||
hinting = FcTrue;
|
||||
|
||||
|
||||
#ifdef FC_HINT_STYLE
|
||||
if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch)
|
||||
hintstyle = FC_HINT_FULL;
|
||||
|
|
@ -977,20 +1028,26 @@ _get_load_flags (FcPattern *pattern)
|
|||
if (!hinting || hintstyle == FC_HINT_NONE)
|
||||
load_flags |= FT_LOAD_NO_HINTING;
|
||||
|
||||
switch (hintstyle) {
|
||||
case FC_HINT_SLIGHT:
|
||||
case FC_HINT_MEDIUM:
|
||||
load_flags |= FT_LOAD_TARGET_LIGHT;
|
||||
break;
|
||||
default:
|
||||
load_flags |= FT_LOAD_TARGET_NORMAL;
|
||||
break;
|
||||
if (antialias) {
|
||||
switch (hintstyle) {
|
||||
case FC_HINT_SLIGHT:
|
||||
case FC_HINT_MEDIUM:
|
||||
load_flags |= FT_LOAD_TARGET_LIGHT;
|
||||
break;
|
||||
default:
|
||||
load_flags |= FT_LOAD_TARGET_NORMAL;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
#ifdef FT_LOAD_TARGET_MONO
|
||||
load_flags |= FT_LOAD_TARGET_MONO;
|
||||
#endif
|
||||
}
|
||||
#else /* !FC_HINT_STYLE */
|
||||
if (!hinting)
|
||||
load_flags |= FT_LOAD_NO_HINTING;
|
||||
#endif /* FC_FHINT_STYLE */
|
||||
|
||||
|
||||
/* force autohinting if requested */
|
||||
if (FcPatternGetBool (pattern,
|
||||
FC_AUTOHINT, 0, &autohint) != FcResultMatch)
|
||||
|
|
@ -999,14 +1056,51 @@ _get_load_flags (FcPattern *pattern)
|
|||
if (autohint)
|
||||
load_flags |= FT_LOAD_FORCE_AUTOHINT;
|
||||
|
||||
if (FcPatternGetBool (pattern,
|
||||
FC_VERTICAL_LAYOUT, 0, &vertical_layout) != FcResultMatch)
|
||||
vertical_layout = FcFalse;
|
||||
|
||||
if (vertical_layout)
|
||||
load_flags |= FT_LOAD_VERTICAL_LAYOUT;
|
||||
|
||||
return load_flags;
|
||||
}
|
||||
|
||||
static int
|
||||
_get_options_load_flags (const cairo_font_options_t *options)
|
||||
{
|
||||
int load_flags = 0;
|
||||
|
||||
/* disable antialiasing if requested */
|
||||
if (options->antialias == CAIRO_ANTIALIAS_NONE)
|
||||
load_flags |= FT_LOAD_TARGET_MONO;
|
||||
else
|
||||
load_flags |= FT_LOAD_NO_BITMAP;
|
||||
|
||||
/* disable hinting if requested */
|
||||
switch (options->hint_style) {
|
||||
case CAIRO_HINT_STYLE_NONE:
|
||||
load_flags |= FT_LOAD_NO_HINTING;
|
||||
break;
|
||||
case CAIRO_HINT_STYLE_SLIGHT:
|
||||
case CAIRO_HINT_STYLE_MEDIUM:
|
||||
load_flags |= FT_LOAD_TARGET_LIGHT;
|
||||
break;
|
||||
case CAIRO_HINT_STYLE_FULL:
|
||||
default:
|
||||
load_flags |= FT_LOAD_TARGET_NORMAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return load_flags;
|
||||
}
|
||||
|
||||
static cairo_scaled_font_t *
|
||||
_ft_scaled_font_create (ft_unscaled_font_t *unscaled,
|
||||
int load_flags,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm)
|
||||
_ft_scaled_font_create (ft_unscaled_font_t *unscaled,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options,
|
||||
int load_flags)
|
||||
{
|
||||
cairo_ft_scaled_font_t *f = NULL;
|
||||
|
||||
|
|
@ -1017,6 +1111,11 @@ _ft_scaled_font_create (ft_unscaled_font_t *unscaled,
|
|||
f->unscaled = unscaled;
|
||||
_cairo_unscaled_font_reference (&unscaled->base);
|
||||
|
||||
f->options = *options;
|
||||
|
||||
if (options->hint_metrics != CAIRO_HINT_METRICS_OFF)
|
||||
load_flags |= PRIVATE_FLAG_HINT_METRICS;
|
||||
|
||||
f->load_flags = load_flags;
|
||||
|
||||
_cairo_scaled_font_init (&f->base, font_matrix, ctm, &cairo_ft_scaled_font_backend);
|
||||
|
|
@ -1031,12 +1130,13 @@ _cairo_scaled_font_is_ft (cairo_scaled_font_t *scaled_font)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_ft_scaled_font_create (const char *family,
|
||||
cairo_font_slant_t slant,
|
||||
cairo_font_weight_t weight,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
cairo_scaled_font_t **font)
|
||||
_cairo_ft_scaled_font_create (const char *family,
|
||||
cairo_font_slant_t slant,
|
||||
cairo_font_weight_t weight,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options,
|
||||
cairo_scaled_font_t **font)
|
||||
{
|
||||
FcPattern *pattern, *resolved;
|
||||
ft_unscaled_font_t *unscaled;
|
||||
|
|
@ -1089,6 +1189,7 @@ _cairo_ft_scaled_font_create (const char *family,
|
|||
FcPatternAddInteger (pattern, FC_PIXEL_SIZE, sf.y_scale);
|
||||
|
||||
FcConfigSubstitute (NULL, pattern, FcMatchPattern);
|
||||
cairo_ft_font_options_substitute (options, pattern);
|
||||
FcDefaultSubstitute (pattern);
|
||||
|
||||
resolved = FcFontMatch (NULL, pattern, &result);
|
||||
|
|
@ -1099,8 +1200,9 @@ _cairo_ft_scaled_font_create (const char *family,
|
|||
if (!unscaled)
|
||||
goto FREE_RESOLVED;
|
||||
|
||||
new_font = _ft_scaled_font_create (unscaled, _get_load_flags (pattern),
|
||||
font_matrix, ctm);
|
||||
new_font = _ft_scaled_font_create (unscaled,
|
||||
font_matrix, ctm,
|
||||
options, _get_pattern_load_flags (pattern));
|
||||
_cairo_unscaled_font_destroy (&unscaled->base);
|
||||
|
||||
FcPatternDestroy (resolved);
|
||||
|
|
@ -1230,15 +1332,24 @@ _cairo_ft_scaled_font_font_extents (void *abstract_font,
|
|||
metrics = &face->size->metrics;
|
||||
|
||||
_ft_unscaled_font_set_scale (scaled_font->unscaled, &scaled_font->base.scale);
|
||||
|
||||
|
||||
/*
|
||||
* Get to unscaled metrics so that the upper level can get back to
|
||||
* user space
|
||||
*/
|
||||
extents->ascent = DOUBLE_FROM_26_6(metrics->ascender) / scaled_font->unscaled->y_scale;
|
||||
extents->descent = DOUBLE_FROM_26_6(- metrics->descender) / scaled_font->unscaled->y_scale;
|
||||
extents->height = DOUBLE_FROM_26_6(metrics->height) / scaled_font->unscaled->y_scale;
|
||||
extents->max_x_advance = DOUBLE_FROM_26_6(metrics->max_advance) / scaled_font->unscaled->x_scale;
|
||||
if (scaled_font->options.hint_metrics != CAIRO_HINT_METRICS_OFF) {
|
||||
extents->ascent = DOUBLE_FROM_26_6(metrics->ascender) / scaled_font->unscaled->y_scale;
|
||||
extents->descent = DOUBLE_FROM_26_6(- metrics->descender) / scaled_font->unscaled->y_scale;
|
||||
extents->height = DOUBLE_FROM_26_6(metrics->height) / scaled_font->unscaled->y_scale;
|
||||
extents->max_x_advance = DOUBLE_FROM_26_6(metrics->max_advance) / scaled_font->unscaled->x_scale;
|
||||
} else {
|
||||
double scale = face->units_per_EM;
|
||||
|
||||
extents->ascent = face->ascender / scale;
|
||||
extents->descent = - face->descender / scale;
|
||||
extents->height = face->height / scale;
|
||||
extents->max_x_advance = face->max_advance_width / scale;
|
||||
}
|
||||
|
||||
/* FIXME: this doesn't do vertical layout atm. */
|
||||
extents->max_y_advance = 0.0;
|
||||
|
|
@ -1688,16 +1799,32 @@ _ft_font_face_destroy (void *abstract_face)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_ft_font_face_create_font (void *abstract_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
cairo_scaled_font_t **scaled_font)
|
||||
_ft_font_face_create_font (void *abstract_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options,
|
||||
cairo_scaled_font_t **scaled_font)
|
||||
{
|
||||
ft_font_face_t *font_face = abstract_face;
|
||||
int load_flags;
|
||||
|
||||
/* The handling of font options is different depending on how the
|
||||
* font face was created. When the user creates a font face with
|
||||
* cairo_ft_font_face_create_for_ft_face(), then the load flags
|
||||
* passed in augment the load flags for the options. But for
|
||||
* cairo_ft_font_face_create_for_pattern(), the load flags are
|
||||
* derived from a pattern where the user has called
|
||||
* cairo_ft_font_options_substitute(), so *just* use those load
|
||||
* flags and ignore the options.
|
||||
*/
|
||||
if (font_face->unscaled->from_face)
|
||||
load_flags = _get_options_load_flags (options) | font_face->load_flags;
|
||||
else
|
||||
load_flags = font_face->load_flags;
|
||||
|
||||
*scaled_font = _ft_scaled_font_create (font_face->unscaled,
|
||||
font_face->load_flags,
|
||||
font_matrix, ctm);
|
||||
font_matrix, ctm,
|
||||
options, load_flags);
|
||||
if (*scaled_font)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
else
|
||||
|
|
@ -1743,6 +1870,92 @@ _ft_font_face_create (ft_unscaled_font_t *unscaled,
|
|||
|
||||
/* implement the platform-specific interface */
|
||||
|
||||
/**
|
||||
* cairo_ft_font_options_substitute:
|
||||
* @options: a #cairo_font_options_t object
|
||||
*
|
||||
* Add options to a #FcPattern based on a #cairo_font_options_t font
|
||||
* options object. Options that are already in the pattern, are not
|
||||
* overriden, so you should call this function after calling FcConfigSubstitute()
|
||||
* (the user's settings should override options based on the surface type),
|
||||
* but before calling FcDefaultSubstitute().
|
||||
**/
|
||||
void
|
||||
cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
||||
FcPattern *pattern)
|
||||
{
|
||||
FcValue v;
|
||||
|
||||
if (options->antialias != CAIRO_ANTIALIAS_DEFAULT)
|
||||
{
|
||||
if (FcPatternGet (pattern, FC_ANTIALIAS, 0, &v) == FcResultNoMatch)
|
||||
{
|
||||
FcPatternAddBool (pattern, FC_ANTIALIAS, options->antialias != CAIRO_ANTIALIAS_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (options->antialias != CAIRO_ANTIALIAS_DEFAULT)
|
||||
{
|
||||
if (FcPatternGet (pattern, FC_RGBA, 0, &v) == FcResultNoMatch)
|
||||
{
|
||||
int rgba;
|
||||
|
||||
if (options->antialias == CAIRO_ANTIALIAS_SUBPIXEL) {
|
||||
switch (options->subpixel_order) {
|
||||
case CAIRO_SUBPIXEL_ORDER_DEFAULT:
|
||||
case CAIRO_SUBPIXEL_ORDER_RGB:
|
||||
default:
|
||||
rgba = FC_RGBA_RGB;
|
||||
break;
|
||||
case CAIRO_SUBPIXEL_ORDER_BGR:
|
||||
rgba = FC_RGBA_BGR;
|
||||
break;
|
||||
case CAIRO_SUBPIXEL_ORDER_VRGB:
|
||||
rgba = FC_RGBA_VRGB;
|
||||
break;
|
||||
case CAIRO_SUBPIXEL_ORDER_VBGR:
|
||||
rgba = FC_RGBA_VBGR;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
rgba = FC_RGBA_NONE;
|
||||
}
|
||||
|
||||
FcPatternAddInteger (pattern, FC_RGBA, rgba);
|
||||
}
|
||||
}
|
||||
|
||||
if (options->hint_style != CAIRO_HINT_STYLE_DEFAULT)
|
||||
{
|
||||
if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch)
|
||||
{
|
||||
FcPatternAddBool (pattern, FC_HINTING, options->hint_style != CAIRO_HINT_STYLE_NONE);
|
||||
}
|
||||
|
||||
#ifdef FC_HINT_STYLE
|
||||
if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch)
|
||||
{
|
||||
int hint_style;
|
||||
|
||||
switch (options->hint_style) {
|
||||
case CAIRO_HINT_STYLE_SLIGHT:
|
||||
hint_style = FC_HINT_SLIGHT;
|
||||
break;
|
||||
case CAIRO_HINT_STYLE_MEDIUM:
|
||||
hint_style = FC_HINT_MEDIUM;
|
||||
break;
|
||||
case CAIRO_HINT_STYLE_FULL:
|
||||
default:
|
||||
hint_style = FC_HINT_FULL;
|
||||
break;
|
||||
}
|
||||
|
||||
FcPatternAddInteger (pattern, FC_HINT_STYLE, hint_style);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_ft_font_face_create_for_pattern:
|
||||
* @pattern: A fully resolved fontconfig
|
||||
|
|
@ -1759,6 +1972,12 @@ _ft_font_face_create (ft_unscaled_font_t *unscaled,
|
|||
* returned from cairo_font_create() is also for the FreeType backend
|
||||
* and can be used with functions such as cairo_ft_font_lock_face().
|
||||
*
|
||||
* Font rendering options are representated both here and when you
|
||||
* call cairo_scaled_font_create(). Font options that have a representation
|
||||
* in a #FcPattern must be passed in here; to modify #FcPattern
|
||||
* appropriately to reflect the options in a #cairo_font_options_t, call
|
||||
* cairo_ft_font_options_substitute().
|
||||
*
|
||||
* Return value: a newly created #cairo_font_face_t. Free with
|
||||
* cairo_font_face_destroy() when you are done using it.
|
||||
**/
|
||||
|
|
@ -1772,7 +1991,7 @@ cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
|
|||
if (unscaled == NULL)
|
||||
return NULL;
|
||||
|
||||
font_face = _ft_font_face_create (unscaled, _get_load_flags (pattern));
|
||||
font_face = _ft_font_face_create (unscaled, _get_pattern_load_flags (pattern));
|
||||
_cairo_unscaled_font_destroy (&unscaled->base);
|
||||
|
||||
return font_face;
|
||||
|
|
@ -1786,10 +2005,13 @@ cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
|
|||
* internally to Cairo, the best way to determine when it
|
||||
* is safe to free the face is to pass a
|
||||
* #cairo_destroy_func_t to cairo_font_face_set_user_data()
|
||||
* @load_flags: The flags to pass to FT_Load_Glyph when loading
|
||||
* glyphs from the font. These flags control aspects of
|
||||
* rendering such as hinting and antialiasing. See the FreeType
|
||||
* docs for full information.
|
||||
* @load_flags: flags to pass to FT_Load_Glyph when loading
|
||||
* glyphs from the font. These flags are OR'ed together with
|
||||
* the flags derived from the #cairo_font_options_t passed
|
||||
* to cairo_scaled_font_create(), so only a few values such
|
||||
* as %FT_LOAD_VERTICAL_LAYOUT, and %FT_LOAD_FORCE_AUTOHINT
|
||||
* are useful. You should not pass any of the flags affecting
|
||||
* the load target, such as %FT_LOAD_TARGET_LIGHT.
|
||||
*
|
||||
* Creates a new font face for the FreeType font backend from a pre-opened
|
||||
* FreeType face. This font can then be used with
|
||||
|
|
|
|||
|
|
@ -52,6 +52,9 @@ CAIRO_BEGIN_DECLS
|
|||
cairo_font_face_t *
|
||||
cairo_ft_font_face_create_for_pattern (FcPattern *pattern);
|
||||
|
||||
void cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
||||
FcPattern *pattern);
|
||||
|
||||
cairo_font_face_t *
|
||||
cairo_ft_font_face_create_for_ft_face (FT_Face face,
|
||||
int load_flags);
|
||||
|
|
|
|||
|
|
@ -1974,6 +1974,7 @@ static cairo_status_t
|
|||
_cairo_gstate_ensure_font (cairo_gstate_t *gstate)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_font_options_t options;
|
||||
|
||||
if (gstate->scaled_font)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
|
@ -1982,9 +1983,11 @@ _cairo_gstate_ensure_font (cairo_gstate_t *gstate)
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
cairo_surface_get_font_options (gstate->target, &options);
|
||||
gstate->scaled_font = cairo_scaled_font_create (gstate->font_face,
|
||||
&gstate->font_matrix,
|
||||
&gstate->ctm);
|
||||
&gstate->ctm,
|
||||
&options);
|
||||
|
||||
if (!gstate->scaled_font)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
|
|
|||
|
|
@ -1379,6 +1379,16 @@ _cairo_pdf_surface_intersect_clip_path (void *dst,
|
|||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_pdf_surface_get_font_options (void *abstract_surface,
|
||||
cairo_font_options_t *options)
|
||||
{
|
||||
_cairo_font_options_init_default (options);
|
||||
|
||||
cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE);
|
||||
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
|
||||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_pdf_surface_backend = {
|
||||
_cairo_pdf_surface_create_similar,
|
||||
_cairo_pdf_surface_finish,
|
||||
|
|
@ -1396,7 +1406,8 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend = {
|
|||
_cairo_pdf_surface_intersect_clip_path,
|
||||
_cairo_pdf_surface_get_extents,
|
||||
_cairo_pdf_surface_show_glyphs,
|
||||
_cairo_pdf_surface_fill_path
|
||||
_cairo_pdf_surface_fill_path,
|
||||
_cairo_pdf_surface_get_font_options
|
||||
};
|
||||
|
||||
static cairo_pdf_document_t *
|
||||
|
|
|
|||
|
|
@ -256,6 +256,33 @@ cairo_surface_set_user_data (cairo_surface_t *surface,
|
|||
key, user_data, destroy);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_surface_get_font_options:
|
||||
* @surface: a #cairo_surface_t
|
||||
* @options: a #cairo_font_options_t object into which to store
|
||||
* the retrieved options. All existing values are overwritten
|
||||
*
|
||||
* Retrieves the default font rendering options for the surface.
|
||||
* This allows display surfaces to report the correct subpixel order
|
||||
* for rendering on them, print surfaces to disable hinting of
|
||||
* metrics and so forth. The result can then be used with
|
||||
* cairo_scaled_font_create().
|
||||
**/
|
||||
void
|
||||
cairo_surface_get_font_options (cairo_surface_t *surface,
|
||||
cairo_font_options_t *options)
|
||||
{
|
||||
|
||||
if (!surface->finished && surface->backend->get_font_options) {
|
||||
surface->backend->get_font_options (surface, options);
|
||||
} else {
|
||||
options->antialias = CAIRO_ANTIALIAS_DEFAULT;
|
||||
options->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
|
||||
options->hint_style = CAIRO_HINT_STYLE_DEFAULT;
|
||||
options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_surface_set_device_offset:
|
||||
* @surface: a #cairo_surface_t
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ typedef struct {
|
|||
cairo_scaled_font_t base;
|
||||
|
||||
LOGFONTW logfont;
|
||||
cairo_font_options_t options;
|
||||
|
||||
BYTE quality;
|
||||
|
||||
|
|
@ -162,6 +163,24 @@ _compute_transform (cairo_win32_scaled_font_t *scaled_font,
|
|||
cairo_matrix_init_identity (&scaled_font->device_to_logical);
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_have_cleartype_quality (void)
|
||||
{
|
||||
OSVERSIONINFO version_info;
|
||||
|
||||
version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
|
||||
|
||||
if (!GetVersionEx (&version_info)) {
|
||||
_cairo_win32_print_gdi_error ("_have_cleartype_quality");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return (version_info.dwMajorVersion > 5 ||
|
||||
(version_info.dwMajorVersion == 5 &&
|
||||
version_info.dwMinorVersion >= 1)); /* XP or newer */
|
||||
}
|
||||
|
||||
|
||||
static BYTE
|
||||
_get_system_quality (void)
|
||||
{
|
||||
|
|
@ -169,28 +188,15 @@ _get_system_quality (void)
|
|||
|
||||
if (!SystemParametersInfo (SPI_GETFONTSMOOTHING, 0, &font_smoothing, 0)) {
|
||||
_cairo_win32_print_gdi_error ("_get_system_quality");
|
||||
return FALSE;
|
||||
return DEFAULT_QUALITY;
|
||||
}
|
||||
|
||||
if (font_smoothing) {
|
||||
OSVERSIONINFO version_info;
|
||||
|
||||
version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
|
||||
|
||||
if (!GetVersionEx (&version_info)) {
|
||||
_cairo_win32_print_gdi_error ("_get_system_quality");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (version_info.dwMajorVersion > 5 ||
|
||||
(version_info.dwMajorVersion == 5 &&
|
||||
version_info.dwMinorVersion >= 1)) { /* XP or newer */
|
||||
UINT smoothing_type;
|
||||
|
||||
if (_have_cleartype_quality ()) {
|
||||
if (!SystemParametersInfo (SPI_GETFONTSMOOTHINGTYPE,
|
||||
0, &smoothing_type, 0)) {
|
||||
_cairo_win32_print_gdi_error ("_get_system_quality");
|
||||
return FALSE;
|
||||
return DEFAULT_QUALITY;
|
||||
}
|
||||
|
||||
if (smoothing_type == FE_FONTSMOOTHINGCLEARTYPE)
|
||||
|
|
@ -204,9 +210,10 @@ _get_system_quality (void)
|
|||
}
|
||||
|
||||
static cairo_scaled_font_t *
|
||||
_win32_scaled_font_create (LOGFONTW *logfont,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm)
|
||||
_win32_scaled_font_create (LOGFONTW *logfont,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options)
|
||||
{
|
||||
cairo_win32_scaled_font_t *f;
|
||||
cairo_matrix_t scale;
|
||||
|
|
@ -216,7 +223,35 @@ _win32_scaled_font_create (LOGFONTW *logfont,
|
|||
return NULL;
|
||||
|
||||
f->logfont = *logfont;
|
||||
f->quality = _get_system_quality ();
|
||||
f->options = *options;
|
||||
|
||||
/* We don't have any control over the hinting style or subpixel
|
||||
* order in the Win32 font API, so we ignore those parts of
|
||||
* cairo_font_options_t. We use the 'antialias' field to set
|
||||
* the 'quality'.
|
||||
*
|
||||
* XXX: The other option we could pay attention to, but don't
|
||||
* here is the hint_metrics options.
|
||||
*/
|
||||
if (options->antialias == CAIRO_ANTIALIAS_DEFAULT)
|
||||
f->quality = _get_system_quality ();
|
||||
else {
|
||||
switch (options->antialias) {
|
||||
case CAIRO_ANTIALIAS_NONE:
|
||||
f->quality = NONANTIALIASED_QUALITY;
|
||||
break;
|
||||
case CAIRO_ANTIALIAS_GRAY:
|
||||
f->quality = ANTIALIASED_QUALITY;
|
||||
break;
|
||||
case CAIRO_ANTIALIAS_SUBPIXEL:
|
||||
if (_have_cleartype_quality ())
|
||||
f->quality = CLEARTYPE_QUALITY;
|
||||
else
|
||||
f->quality = ANTIALIASED_QUALITY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
f->em_square = 0;
|
||||
f->scaled_hfont = NULL;
|
||||
f->unscaled_hfont = NULL;
|
||||
|
|
@ -390,12 +425,13 @@ _cairo_win32_scaled_font_done_unscaled_font (cairo_scaled_font_t *scaled_font)
|
|||
/* implement the font backend interface */
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_win32_scaled_font_create (const char *family,
|
||||
cairo_font_slant_t slant,
|
||||
cairo_font_weight_t weight,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
cairo_scaled_font_t **scaled_font_out)
|
||||
_cairo_win32_scaled_font_create (const char *family,
|
||||
cairo_font_slant_t slant,
|
||||
cairo_font_weight_t weight,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options,
|
||||
cairo_scaled_font_t **scaled_font_out)
|
||||
{
|
||||
LOGFONTW logfont;
|
||||
cairo_scaled_font_t *scaled_font;
|
||||
|
|
@ -456,7 +492,7 @@ _cairo_win32_scaled_font_create (const char *family,
|
|||
if (!logfont.lfFaceName)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
scaled_font = _win32_scaled_font_create (&logfont, font_matrix, ctm);
|
||||
scaled_font = _win32_scaled_font_create (&logfont, font_matrix, ctm, options);
|
||||
if (!scaled_font)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
|
|
@ -1262,15 +1298,16 @@ _cairo_win32_font_face_destroy (void *abstract_face)
|
|||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_win32_font_face_create_font (void *abstract_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
cairo_scaled_font_t **font)
|
||||
_cairo_win32_font_face_create_font (void *abstract_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options,
|
||||
cairo_scaled_font_t **font)
|
||||
{
|
||||
cairo_win32_font_face_t *font_face = abstract_face;
|
||||
|
||||
*font = _win32_scaled_font_create (&font_face->logfont,
|
||||
font_matrix, ctm);
|
||||
font_matrix, ctm, options);
|
||||
if (*font)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
else
|
||||
|
|
|
|||
54
src/cairo-xlib-private.h
Normal file
54
src/cairo-xlib-private.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/* Cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* 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 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_XLIB_PRIVATE_H
|
||||
#define CAIRO_XLIB_PRIVATE_H
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-xlib.h"
|
||||
|
||||
typedef struct _cairo_xlib_screen_info cairo_xlib_screen_info_t;
|
||||
|
||||
struct _cairo_xlib_screen_info {
|
||||
cairo_xlib_screen_info_t *next;
|
||||
|
||||
Display *display;
|
||||
int screen;
|
||||
cairo_bool_t has_render;
|
||||
|
||||
cairo_font_options_t font_options;
|
||||
};
|
||||
|
||||
cairo_private cairo_xlib_screen_info_t *
|
||||
_cairo_xlib_screen_info_get (Display *display, int screen);
|
||||
|
||||
#endif /* CAIRO_XLIB_PRIVATE_H */
|
||||
345
src/cairo-xlib-screen.c
Normal file
345
src/cairo-xlib-screen.c
Normal file
|
|
@ -0,0 +1,345 @@
|
|||
/* Cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2005 Red Hat, Inc.
|
||||
*
|
||||
* 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 Red Hat, Inc.
|
||||
*
|
||||
* Partially on code from xftdpy.c
|
||||
*
|
||||
* Copyright © 2000 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cairo-xlib-private.h"
|
||||
|
||||
#include <fontconfig/fontconfig.h>
|
||||
|
||||
#include <X11/Xlibint.h> /* For XESetCloseDisplay */
|
||||
#include <X11/extensions/Xrender.h>
|
||||
|
||||
static int
|
||||
parse_boolean (const char *v)
|
||||
{
|
||||
char c0, c1;
|
||||
|
||||
c0 = *v;
|
||||
if (c0 == 't' || c0 == 'T' || c0 == 'y' || c0 == 'Y' || c0 == '1')
|
||||
return 1;
|
||||
if (c0 == 'f' || c0 == 'F' || c0 == 'n' || c0 == 'N' || c0 == '0')
|
||||
return 0;
|
||||
if (c0 == 'o')
|
||||
{
|
||||
c1 = v[1];
|
||||
if (c1 == 'n' || c1 == 'N')
|
||||
return 1;
|
||||
if (c1 == 'f' || c1 == 'F')
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
get_boolean_default (Display *dpy,
|
||||
const char *option,
|
||||
cairo_bool_t *value)
|
||||
{
|
||||
char *v;
|
||||
int i;
|
||||
|
||||
v = XGetDefault (dpy, "Xft", option);
|
||||
if (v) {
|
||||
i = parse_boolean (v);
|
||||
if (i >= 0) {
|
||||
*value = i;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
get_integer_default (Display *dpy,
|
||||
const char *option,
|
||||
int *value)
|
||||
{
|
||||
int i;
|
||||
char *v, *e;
|
||||
|
||||
v = XGetDefault (dpy, "Xft", option);
|
||||
if (v) {
|
||||
if (FcNameConstant ((FcChar8 *) v, value))
|
||||
return TRUE;
|
||||
|
||||
i = strtol (v, &e, 0);
|
||||
if (e != v)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Old versions of fontconfig didn't have these options */
|
||||
#ifndef FC_HINT_NONE
|
||||
#define FC_HINT_NONE 0
|
||||
#define FC_HINT_SLIGHT 1
|
||||
#define FC_HINT_MEDIUM 2
|
||||
#define FC_HINT_FULL 3
|
||||
#endif
|
||||
|
||||
static void
|
||||
_cairo_xlib_init_screen_font_options (cairo_xlib_screen_info_t *info)
|
||||
{
|
||||
cairo_bool_t xft_hinting;
|
||||
cairo_bool_t xft_antialias;
|
||||
int xft_hintstyle;
|
||||
int xft_rgba;
|
||||
cairo_antialias_t antialias;
|
||||
cairo_subpixel_order_t subpixel_order;
|
||||
cairo_hint_style_t hint_style;
|
||||
|
||||
if (!get_boolean_default (info->display, "antialias", &xft_antialias))
|
||||
xft_antialias = TRUE;
|
||||
|
||||
if (!get_boolean_default (info->display, "hinting", &xft_hinting))
|
||||
xft_hinting = TRUE;
|
||||
|
||||
if (!get_integer_default (info->display, "hintstyle", &xft_hintstyle))
|
||||
xft_hintstyle = FC_HINT_FULL;
|
||||
|
||||
if (!get_integer_default (info->display, "rgba", &xft_rgba))
|
||||
{
|
||||
xft_rgba = FC_RGBA_UNKNOWN;
|
||||
|
||||
#if RENDER_MAJOR > 0 || RENDER_MINOR >= 6
|
||||
if (info->has_render)
|
||||
{
|
||||
int render_order = XRenderQuerySubpixelOrder (info->display, info->screen);
|
||||
|
||||
switch (render_order)
|
||||
{
|
||||
default:
|
||||
case SubPixelUnknown:
|
||||
xft_rgba = FC_RGBA_UNKNOWN;
|
||||
break;
|
||||
case SubPixelHorizontalRGB:
|
||||
xft_rgba = FC_RGBA_RGB;
|
||||
break;
|
||||
case SubPixelHorizontalBGR:
|
||||
xft_rgba = FC_RGBA_BGR;
|
||||
break;
|
||||
case SubPixelVerticalRGB:
|
||||
xft_rgba = FC_RGBA_VRGB;
|
||||
break;
|
||||
case SubPixelVerticalBGR:
|
||||
xft_rgba = FC_RGBA_VBGR;
|
||||
break;
|
||||
case SubPixelNone:
|
||||
xft_rgba = FC_RGBA_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (xft_hinting) {
|
||||
switch (xft_hintstyle) {
|
||||
case FC_HINT_NONE:
|
||||
hint_style = CAIRO_HINT_STYLE_NONE;
|
||||
break;
|
||||
case FC_HINT_SLIGHT:
|
||||
hint_style = CAIRO_HINT_STYLE_SLIGHT;
|
||||
break;
|
||||
case FC_HINT_MEDIUM:
|
||||
hint_style = CAIRO_HINT_STYLE_MEDIUM;
|
||||
break;
|
||||
case FC_HINT_FULL:
|
||||
hint_style = CAIRO_HINT_STYLE_FULL;
|
||||
break;
|
||||
default:
|
||||
hint_style = CAIRO_HINT_STYLE_DEFAULT;
|
||||
}
|
||||
} else {
|
||||
hint_style = CAIRO_HINT_STYLE_NONE;
|
||||
}
|
||||
|
||||
switch (xft_rgba) {
|
||||
case FC_RGBA_RGB:
|
||||
subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB;
|
||||
break;
|
||||
case FC_RGBA_BGR:
|
||||
subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR;
|
||||
break;
|
||||
case FC_RGBA_VRGB:
|
||||
subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB;
|
||||
break;
|
||||
case FC_RGBA_VBGR:
|
||||
subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR;
|
||||
break;
|
||||
case FC_RGBA_UNKNOWN:
|
||||
case FC_RGBA_NONE:
|
||||
default:
|
||||
subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
|
||||
}
|
||||
|
||||
if (xft_antialias) {
|
||||
if (subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT)
|
||||
antialias = CAIRO_ANTIALIAS_GRAY;
|
||||
else
|
||||
antialias = CAIRO_ANTIALIAS_SUBPIXEL;
|
||||
} else {
|
||||
antialias = CAIRO_ANTIALIAS_NONE;
|
||||
}
|
||||
|
||||
_cairo_font_options_init_default (&info->font_options);
|
||||
cairo_font_options_set_hint_style (&info->font_options, hint_style);
|
||||
cairo_font_options_set_antialias (&info->font_options, antialias);
|
||||
cairo_font_options_set_subpixel_order (&info->font_options, subpixel_order);
|
||||
}
|
||||
|
||||
CAIRO_MUTEX_DECLARE(_xlib_screen_mutex);
|
||||
|
||||
static cairo_xlib_screen_info_t *_cairo_xlib_screen_list;
|
||||
|
||||
static int
|
||||
_cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
|
||||
{
|
||||
cairo_xlib_screen_info_t *info;
|
||||
cairo_xlib_screen_info_t **prev;
|
||||
|
||||
/*
|
||||
* Unhook from the global list
|
||||
*/
|
||||
CAIRO_MUTEX_LOCK (_xlib_screen_mutex);
|
||||
|
||||
for (prev = &_cairo_xlib_screen_list; (info = *prev); prev = &(*prev)->next) {
|
||||
if (info->display == dpy) {
|
||||
*prev = info->next;
|
||||
free (info);
|
||||
if (!*prev)
|
||||
break;
|
||||
}
|
||||
}
|
||||
CAIRO_MUTEX_UNLOCK (_xlib_screen_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
cairo_private cairo_xlib_screen_info_t *
|
||||
_cairo_xlib_screen_info_get (Display *dpy, int screen)
|
||||
{
|
||||
cairo_xlib_screen_info_t *info;
|
||||
cairo_xlib_screen_info_t **prev;
|
||||
int event_base, error_base;
|
||||
XExtCodes *codes;
|
||||
cairo_bool_t seen_display = FALSE;
|
||||
|
||||
/* There is an apparent deadlock between this mutex and the
|
||||
* mutex for the display, but it's actually safe. For the
|
||||
* app to call XCloseDisplay() while any other thread is
|
||||
* inside this function would be an error in the logic
|
||||
* app, and the CloseDisplay hook is the only other place we
|
||||
* acquire this mutex.
|
||||
*/
|
||||
CAIRO_MUTEX_LOCK (_xlib_screen_mutex);
|
||||
|
||||
for (prev = &_cairo_xlib_screen_list; (info = *prev); prev = &(*prev)->next)
|
||||
{
|
||||
if (info->display == dpy) {
|
||||
seen_display = TRUE;
|
||||
if (info->screen == screen)
|
||||
{
|
||||
/*
|
||||
* MRU the list
|
||||
*/
|
||||
if (prev != &_cairo_xlib_screen_list)
|
||||
{
|
||||
*prev = info->next;
|
||||
info->next = _cairo_xlib_screen_list;
|
||||
_cairo_xlib_screen_list = info;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (info)
|
||||
goto out;
|
||||
|
||||
info = malloc (sizeof (cairo_xlib_screen_info_t));
|
||||
if (!info)
|
||||
goto out;
|
||||
|
||||
if (!seen_display) {
|
||||
codes = XAddExtension (dpy);
|
||||
if (!codes) {
|
||||
free (info);
|
||||
info = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
XESetCloseDisplay (dpy, codes->extension, _cairo_xlib_close_display);
|
||||
}
|
||||
|
||||
info->display = dpy;
|
||||
info->screen = screen;
|
||||
info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
|
||||
(XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0));
|
||||
|
||||
_cairo_xlib_init_screen_font_options (info);
|
||||
|
||||
info->next = _cairo_xlib_screen_list;
|
||||
_cairo_xlib_screen_list = info;
|
||||
|
||||
out:
|
||||
CAIRO_MUTEX_UNLOCK (_xlib_screen_mutex);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
|
@ -38,6 +38,7 @@
|
|||
#include "cairo-xlib.h"
|
||||
#include "cairo-xlib-xrender.h"
|
||||
#include "cairo-xlib-test.h"
|
||||
#include "cairo-xlib-private.h"
|
||||
#include <X11/extensions/Xrender.h>
|
||||
|
||||
/* Xlib doesn't define a typedef, so define one ourselves */
|
||||
|
|
@ -70,6 +71,8 @@ struct _cairo_xlib_surface {
|
|||
cairo_surface_t base;
|
||||
|
||||
Display *dpy;
|
||||
cairo_xlib_screen_info_t *screen_info;
|
||||
|
||||
GC gc;
|
||||
Drawable drawable;
|
||||
Screen *screen;
|
||||
|
|
@ -1321,6 +1324,15 @@ _cairo_xlib_surface_get_extents (void *abstract_surface,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_xlib_surface_get_font_options (void *abstract_surface,
|
||||
cairo_font_options_t *options)
|
||||
{
|
||||
cairo_xlib_surface_t *surface = abstract_surface;
|
||||
|
||||
*options = surface->screen_info->font_options;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_xlib_surface_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
cairo_operator_t operator,
|
||||
|
|
@ -1351,7 +1363,9 @@ static const cairo_surface_backend_t cairo_xlib_surface_backend = {
|
|||
_cairo_xlib_surface_set_clip_region,
|
||||
NULL, /* intersect_clip_path */
|
||||
_cairo_xlib_surface_get_extents,
|
||||
_cairo_xlib_surface_show_glyphs
|
||||
_cairo_xlib_surface_show_glyphs,
|
||||
NULL, /* fill_path */
|
||||
_cairo_xlib_surface_get_font_options
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1379,6 +1393,11 @@ _cairo_xlib_surface_create_internal (Display *dpy,
|
|||
int depth)
|
||||
{
|
||||
cairo_xlib_surface_t *surface;
|
||||
cairo_xlib_screen_info_t *screen_info;
|
||||
|
||||
screen_info = _cairo_xlib_screen_info_get (dpy, DefaultScreen (dpy));
|
||||
if (!screen_info)
|
||||
return NULL;
|
||||
|
||||
surface = malloc (sizeof (cairo_xlib_surface_t));
|
||||
if (surface == NULL)
|
||||
|
|
@ -1387,6 +1406,7 @@ _cairo_xlib_surface_create_internal (Display *dpy,
|
|||
_cairo_surface_init (&surface->base, &cairo_xlib_surface_backend);
|
||||
|
||||
surface->dpy = dpy;
|
||||
surface->screen_info = screen_info;
|
||||
|
||||
surface->gc = NULL;
|
||||
surface->drawable = drawable;
|
||||
|
|
|
|||
154
src/cairo.h
154
src/cairo.h
|
|
@ -635,7 +635,148 @@ typedef enum _cairo_font_weight {
|
|||
CAIRO_FONT_WEIGHT_NORMAL,
|
||||
CAIRO_FONT_WEIGHT_BOLD
|
||||
} cairo_font_weight_t;
|
||||
|
||||
|
||||
/**
|
||||
* cairo_antialias_t:
|
||||
* @CAIRO_ANTIALIAS_DEFAULT: Use the default antialiasing for
|
||||
* the font subsystem and target device
|
||||
* @CAIRO_ANTIALIAS_NONE: Do no antialiasing of fonts; use bilevel text
|
||||
* @CAIRO_ANTIALIAS_GRAY: Perform single-color antialiasing (using
|
||||
* shades of gray for black text on a white background, for example).
|
||||
* @CAIRO_ANTIALIAS_SUBPIXEL: Perform antialiasing by taking
|
||||
* advantage of the order of subpixel elements on devices
|
||||
* such as LCD panels
|
||||
*
|
||||
* Specifies the type of antialiasing to do when rendering text.
|
||||
**/
|
||||
typedef enum _cairo_antialias {
|
||||
CAIRO_ANTIALIAS_DEFAULT,
|
||||
CAIRO_ANTIALIAS_NONE,
|
||||
CAIRO_ANTIALIAS_GRAY,
|
||||
CAIRO_ANTIALIAS_SUBPIXEL
|
||||
} cairo_antialias_t;
|
||||
|
||||
/**
|
||||
* cairo_subpixel_order_t:
|
||||
* @CAIRO_SUBPIXEL_ORDER_DEFAULT: Use the default subpixel order for
|
||||
* for the target device
|
||||
* @CAIRO_SUBPIXEL_ORDER_RGB: Subpixel elements are arranged horizontally
|
||||
* with red at the left
|
||||
* @CAIRO_SUBPIXEL_ORDER_BGR: Subpixel elements are arranged horizontally
|
||||
* with blue at the left
|
||||
* @CAIRO_SUBPIXEL_ORDER_VRGB: Subpixel elements are arranged vertically
|
||||
* with red at the top
|
||||
* @CAIRO_SUBPIXEL_ORDER_VBGR: Subpixel elements are arranged vertically
|
||||
* with blue at the top
|
||||
*
|
||||
* The subpixel order specifies the order of color elements within
|
||||
* each pixel on the display device when rendering with an
|
||||
* antialiasing mode of %CAIRO_ANTIALIAS_SUBPIXEL.
|
||||
**/
|
||||
typedef enum _cairo_subpixel_order {
|
||||
CAIRO_SUBPIXEL_ORDER_DEFAULT,
|
||||
CAIRO_SUBPIXEL_ORDER_RGB,
|
||||
CAIRO_SUBPIXEL_ORDER_BGR,
|
||||
CAIRO_SUBPIXEL_ORDER_VRGB,
|
||||
CAIRO_SUBPIXEL_ORDER_VBGR
|
||||
} cairo_subpixel_order_t;
|
||||
|
||||
/**
|
||||
* cairo_hint_style_t:
|
||||
* @CAIRO_HINT_STYLE_DEFAULT: Use the default hint style for
|
||||
* for font backend and target device
|
||||
* @CAIRO_HINT_STYLE_NONE: Do not hint outlines
|
||||
* @CAIRO_HINT_STYLE_SLIGHT: Hint outlines slightly to improve
|
||||
* contrast while retaining good fidelity to the original
|
||||
* shapes.
|
||||
* @CAIRO_HINT_STYLE_MEDIUM: Hint outlines with medium strength
|
||||
* giving a compromise between fidelity to the original shapes
|
||||
* and contrast
|
||||
* @CAIRO_HINT_STYLE_FULL: Hint outlines to maximize contrast
|
||||
*
|
||||
* Specifies the type of hinting to do on font outlines. Hinting
|
||||
* is the process of fitting outlines to the pixel grid in order
|
||||
* to improve the appearance of the result. Since hinting outlines
|
||||
* involves distorting them, it also reduces the faithfulness
|
||||
* to the original outline shapes. Not all of the outline hinting
|
||||
* styles are supported by all font backends.
|
||||
*/
|
||||
typedef enum _cairo_hint_style {
|
||||
CAIRO_HINT_STYLE_DEFAULT,
|
||||
CAIRO_HINT_STYLE_NONE,
|
||||
CAIRO_HINT_STYLE_SLIGHT,
|
||||
CAIRO_HINT_STYLE_MEDIUM,
|
||||
CAIRO_HINT_STYLE_FULL
|
||||
} cairo_hint_style_t;
|
||||
|
||||
/**
|
||||
* cairo_hint_metrics_t:
|
||||
* @CAIRO_HINT_METRICS_DEFAULT: Hint metrics in the default
|
||||
* manner for the font backend and target device
|
||||
* @CAIRO_HINT_METRICS_OFF: Do not hint font metrics
|
||||
* @CAIRO_HINT_METRICS_ON: Hint font metrics
|
||||
*
|
||||
* Specifies whether to hint font metrics; hinting font metrics
|
||||
* means quantizing them so that they are integer values in
|
||||
* device space. Doing this improves the consistency of
|
||||
* letter and line spacing, however it also means that text
|
||||
* will be laid out differently at different zoom factors.
|
||||
*/
|
||||
typedef enum _cairo_hint_metrics {
|
||||
CAIRO_HINT_METRICS_DEFAULT,
|
||||
CAIRO_HINT_METRICS_OFF,
|
||||
CAIRO_HINT_METRICS_ON
|
||||
} cairo_hint_metrics_t;
|
||||
|
||||
typedef struct _cairo_font_options cairo_font_options_t;
|
||||
|
||||
cairo_font_options_t *
|
||||
cairo_font_options_create (void);
|
||||
|
||||
cairo_font_options_t *
|
||||
cairo_font_options_copy (const cairo_font_options_t *original);
|
||||
|
||||
void
|
||||
cairo_font_options_destroy (cairo_font_options_t *options);
|
||||
|
||||
cairo_status_t
|
||||
cairo_font_options_status (cairo_font_options_t *options);
|
||||
|
||||
void
|
||||
cairo_font_options_merge (cairo_font_options_t *options,
|
||||
const cairo_font_options_t *other);
|
||||
cairo_bool_t
|
||||
cairo_font_options_equal (const cairo_font_options_t *options,
|
||||
const cairo_font_options_t *other);
|
||||
|
||||
unsigned long
|
||||
cairo_font_options_hash (const cairo_font_options_t *options);
|
||||
|
||||
void
|
||||
cairo_font_options_set_antialias (cairo_font_options_t *options,
|
||||
cairo_antialias_t antialias);
|
||||
cairo_antialias_t
|
||||
cairo_font_options_get_antialias (const cairo_font_options_t *options);
|
||||
|
||||
void
|
||||
cairo_font_options_set_subpixel_order (cairo_font_options_t *options,
|
||||
cairo_subpixel_order_t subpixel_order);
|
||||
cairo_subpixel_order_t
|
||||
cairo_font_options_get_subpixel_order (const cairo_font_options_t *options);
|
||||
|
||||
void
|
||||
cairo_font_options_set_hint_style (cairo_font_options_t *options,
|
||||
cairo_hint_style_t hint_style);
|
||||
cairo_hint_style_t
|
||||
cairo_font_options_get_hint_style (const cairo_font_options_t *options);
|
||||
|
||||
void
|
||||
cairo_font_options_set_hint_metrics (cairo_font_options_t *options,
|
||||
cairo_hint_metrics_t hint_metrics);
|
||||
cairo_hint_metrics_t
|
||||
cairo_font_options_get_hint_metrics (const cairo_font_options_t *options);
|
||||
|
||||
|
||||
/* This interface is for dealing with text as text, not caring about the
|
||||
font object inside the the cairo_t. */
|
||||
|
||||
|
|
@ -710,9 +851,10 @@ cairo_font_face_set_user_data (cairo_font_face_t *font_face,
|
|||
/* Portable interface to general font features. */
|
||||
|
||||
cairo_scaled_font_t *
|
||||
cairo_scaled_font_create (cairo_font_face_t *font_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm);
|
||||
cairo_scaled_font_create (cairo_font_face_t *font_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options);
|
||||
|
||||
void
|
||||
cairo_scaled_font_reference (cairo_scaled_font_t *scaled_font);
|
||||
|
|
@ -951,6 +1093,10 @@ cairo_surface_set_user_data (cairo_surface_t *surface,
|
|||
void *user_data,
|
||||
cairo_destroy_func_t destroy);
|
||||
|
||||
void
|
||||
cairo_surface_get_font_options (cairo_surface_t *surface,
|
||||
cairo_font_options_t *options);
|
||||
|
||||
void
|
||||
cairo_surface_set_device_offset (cairo_surface_t *surface,
|
||||
double x_offset,
|
||||
|
|
|
|||
|
|
@ -476,6 +476,13 @@ struct _cairo_font_face {
|
|||
const cairo_font_face_backend_t *backend;
|
||||
};
|
||||
|
||||
struct _cairo_font_options {
|
||||
cairo_antialias_t antialias;
|
||||
cairo_subpixel_order_t subpixel_order;
|
||||
cairo_hint_style_t hint_style;
|
||||
cairo_hint_metrics_t hint_metrics;
|
||||
};
|
||||
|
||||
/* cairo_font.c is responsible for a global glyph cache:
|
||||
*
|
||||
* - glyph entries: [[[base], cairo_unscaled_font_t, scale, flags, index],
|
||||
|
|
@ -534,6 +541,7 @@ struct _cairo_scaled_font_backend {
|
|||
cairo_font_weight_t weight,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options,
|
||||
cairo_scaled_font_t **font);
|
||||
|
||||
void (*destroy) (void *font);
|
||||
|
|
@ -585,6 +593,7 @@ struct _cairo_font_face_backend {
|
|||
cairo_status_t (*create_font) (void *font_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options,
|
||||
cairo_scaled_font_t **scaled_font);
|
||||
};
|
||||
|
||||
|
|
@ -766,6 +775,9 @@ typedef struct _cairo_surface_backend {
|
|||
cairo_fill_rule_t fill_rule,
|
||||
double tolerance);
|
||||
|
||||
void
|
||||
(*get_font_options) (void *surface,
|
||||
cairo_font_options_t *options);
|
||||
} cairo_surface_backend_t;
|
||||
|
||||
typedef struct _cairo_format_masks {
|
||||
|
|
@ -1348,6 +1360,11 @@ cairo_private void
|
|||
_cairo_scaled_font_get_glyph_cache_key (cairo_scaled_font_t *scaled_font,
|
||||
cairo_glyph_cache_key_t *key);
|
||||
|
||||
/* cairo-font-options.c */
|
||||
|
||||
cairo_private void
|
||||
_cairo_font_options_init_default (cairo_font_options_t *options);
|
||||
|
||||
/* cairo_hull.c */
|
||||
cairo_private cairo_status_t
|
||||
_cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue