diff options
39 files changed, 2558 insertions, 129 deletions
@@ -1,3 +1,40 @@ +Sat Jan 8 16:46:37 2005 Owen Taylor <otaylor@redhat.com> + + * configure.in: Add checks for Cairo + + * pango/Makefile.am: Add libpangocairo. + + * pango/pangocairo-font.c pango/pangocairo-fontmap.c + pango/pangocairo.h pango/pangocairo-private.h + pango/pangocairo-fcfont.c pango/pangocairo-fcfontmap.c + pango/pangocairo-fc.h: Start of a Cairo/FreeType backend. + + * pango/pangofc-fontmap.[ch]: Add a "get_render_key" + virtual function to allow subclasses to specialize the + details of how caching works. Add a default implementation + that's a little more sophisticated than what was there + before. + + * pango/pangoft2-private.h pangofc-font.c pangoft2.c: + Move default implementations of has_char(), get_glyph() + to the base class. + + * pango/pangofc-private.h pango/pangoft2-private.h: + Move PANGO_UNITS_26_6 and friends to pango/pangofc-private.h. + + * examples/renderdemo.[ch] examples/pangoft2topgm.c + examples/xftview.c: Allow passing in a custom function + to transform drawing. + + * examples/Makefile.am examples/cairoview.c: Add a + Cairo/Xlib example program. + + * examples/cairosimple.c: Simple Cairo example with + output to a PNG. + + * pango/pango-layout.c (pango_layout_line_get_extents): Fix + bug where line ink rect was always including 0, 0. + Thu Jan 6 12:29:31 2005 Owen Taylor <otaylor@redhat.com> * pango/pango-attributes.c (pango_attr_iterator_get_font): diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10 index a2ed4404..581ec75d 100644 --- a/ChangeLog.pre-1-10 +++ b/ChangeLog.pre-1-10 @@ -1,3 +1,40 @@ +Sat Jan 8 16:46:37 2005 Owen Taylor <otaylor@redhat.com> + + * configure.in: Add checks for Cairo + + * pango/Makefile.am: Add libpangocairo. + + * pango/pangocairo-font.c pango/pangocairo-fontmap.c + pango/pangocairo.h pango/pangocairo-private.h + pango/pangocairo-fcfont.c pango/pangocairo-fcfontmap.c + pango/pangocairo-fc.h: Start of a Cairo/FreeType backend. + + * pango/pangofc-fontmap.[ch]: Add a "get_render_key" + virtual function to allow subclasses to specialize the + details of how caching works. Add a default implementation + that's a little more sophisticated than what was there + before. + + * pango/pangoft2-private.h pangofc-font.c pangoft2.c: + Move default implementations of has_char(), get_glyph() + to the base class. + + * pango/pangofc-private.h pango/pangoft2-private.h: + Move PANGO_UNITS_26_6 and friends to pango/pangofc-private.h. + + * examples/renderdemo.[ch] examples/pangoft2topgm.c + examples/xftview.c: Allow passing in a custom function + to transform drawing. + + * examples/Makefile.am examples/cairoview.c: Add a + Cairo/Xlib example program. + + * examples/cairosimple.c: Simple Cairo example with + output to a PNG. + + * pango/pango-layout.c (pango_layout_line_get_extents): Fix + bug where line ink rect was always including 0, 0. + Thu Jan 6 12:29:31 2005 Owen Taylor <otaylor@redhat.com> * pango/pango-attributes.c (pango_attr_iterator_get_font): diff --git a/configure.in b/configure.in index 5f283583..1c194d57 100644 --- a/configure.in +++ b/configure.in @@ -248,6 +248,30 @@ AM_CONDITIONAL(HAVE_FREETYPE, $have_freetype) AM_CONDITIONAL(HAVE_XFT, $have_xft) # +# Checks for Cairo +# +have_cairo=false +have_cairo_freetype=false + +PKG_CHECK_MODULES(CAIRO, cairo >= 0.2.0, have_cairo=true, :) + +if $have_cairo ; then + pango_save_ldflags=$LDFLAGS + LDFLAGS="$LDFLAGS $CAIRO_LIBS" + AC_CHECK_LIB(cairo, cairo_ft_font_face, have_cairo_freetype=true, :) + LDFLAGS=$pango_save_ldflags + if $have_cairo_freetype ; then + AC_DEFINE(HAVE_CAIRO_FREETYPE, 1, [Whether Cairo uses FreeType for fonts]) + else + AC_MSG_WARN([Disabling Cairo support, no known font system]) + have_cairo=false + fi +fi + +AM_CONDITIONAL(HAVE_CAIRO, $have_cairo) +AM_CONDITIONAL(HAVE_CAIRO_FREETYPE, $have_cairo_freetype) + +# # Checks for Win32 GDI # have_win32=false @@ -680,6 +704,7 @@ backends="" if $have_freetype && $have_fontconfig ; then backends="$backends FreeType"; fi if $have_x ; then backends="$backends X"; fi if $have_xft ; then backends="$backends Xft"; fi +if $have_cairo ; then backends="$backends Cairo"; fi if $have_win32 ; then backends="$backends Win32"; fi echo "configuration: diff --git a/docs/Makefile.am b/docs/Makefile.am index e04dfaed..6d55e7f3 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -25,6 +25,8 @@ IGNORE_HFILES= \ module-defs.h \ opentype \ modules.h \ + pangocairo-private.h \ + pangocairo-fc.h \ pango-engine-private.h \ pango-impl-utils.h \ pango-glyph-item-private.h \ @@ -55,6 +57,9 @@ INCLUDES = \ GTKDOC_LIBS = \ $(top_builddir)/pango/libpangoxft-1.0.la +if HAVE_CAIRO +GTKDOC_LIBS += $(top_builddir)/pango/libpangocairo-1.0.la +endif # Extra options to supply to gtkdoc-mkdb MKDB_OPTIONS=--sgml-mode --output-format=xml @@ -68,7 +73,8 @@ content_files = \ # Images to copy into HTML directory HTML_IMAGES = \ - layout.gif + layout.gif \ + rotated-text.png # Extra options to supply to gtkdoc-fixref FIXXREF_OPTIONS= diff --git a/docs/pango-docs.sgml b/docs/pango-docs.sgml index 21498e6e..aa026ff3 100644 --- a/docs/pango-docs.sgml +++ b/docs/pango-docs.sgml @@ -17,6 +17,7 @@ <!ENTITY pango-Win32-Fonts-and-Rendering SYSTEM "xml/win32-fonts.xml"> <!ENTITY pango-FreeType-Fonts-and-Rendering SYSTEM "xml/freetype-fonts.xml"> <!ENTITY pango-Xft-Fonts-and-Rendering SYSTEM "xml/xft-fonts.xml"> +<!ENTITY pangocairo SYSTEM "xml/pangocairo.xml"> <!ENTITY PangoFcFontMap SYSTEM "xml/pangofc-fontmap.xml"> <!ENTITY PangoFcFont SYSTEM "xml/pangofc-font.xml"> <!ENTITY PangoFcDecoder SYSTEM "xml/pangofc-decoder.xml"> @@ -48,6 +49,7 @@ &pango-Win32-Fonts-and-Rendering; &pango-FreeType-Fonts-and-Rendering; &pango-Xft-Fonts-and-Rendering; + &pangocairo; &pango-X-Fonts-and-Rendering; </chapter> diff --git a/docs/pango-sections.txt b/docs/pango-sections.txt index 11cfe179..1972e9b7 100644 --- a/docs/pango-sections.txt +++ b/docs/pango-sections.txt @@ -769,6 +769,28 @@ pango_xft_renderer_get_type </SECTION> <SECTION> +<TITLE>Cairo Rendering</TITLE> +<FILE>pangocairo</FILE> +PangoCairoFontMap +pango_cairo_font_map_new +pango_cairo_font_map_get_default +pango_cairo_font_map_set_resolution +pango_cairo_font_map_get_resolution +pango_cairo_font_map_create_context +pango_cairo_update_context +pango_cairo_create_layout +pango_cairo_update_layout +pango_cairo_show_glyphs +pango_cairo_show_layout_line +pango_cairo_show_layout +<SUBSECTION Standard> +PANGO_CAIRO_FONT_MAP +PANGO_IS_CAIRO_FONT_MAP +PANGO_TYPE_CAIRO_FONT_MAP +pango_cairo_font_map_get_type +</SECTION> + +<SECTION> <FILE>pangofc-fontmap</FILE> <TITLE>PangoFcFontMap</TITLE> PangoFcFontMap diff --git a/docs/pango.types b/docs/pango.types index 5cda42a7..818e81b8 100644 --- a/docs/pango.types +++ b/docs/pango.types @@ -1,4 +1,5 @@ #include <pango/pango.h> +#include <pango/pangocairo.h> #include <pango/pangofc-font.h> #include <pango/pangofc-fontmap.h> #include <pango/pangoft2.h> @@ -19,5 +20,5 @@ pango_fc_font_map_get_type pango_fc_decoder_get_type pango_ft2_font_map_get_type pango_xft_font_get_type - +pango_cairo_font_map_get_type diff --git a/docs/rotated-text.png b/docs/rotated-text.png Binary files differnew file mode 100644 index 00000000..b29682e8 --- /dev/null +++ b/docs/rotated-text.png diff --git a/docs/tmpl/pango-renderer.sgml b/docs/tmpl/pango-renderer.sgml index adb8f555..f88a679b 100644 --- a/docs/tmpl/pango-renderer.sgml +++ b/docs/tmpl/pango-renderer.sgml @@ -124,12 +124,14 @@ destinations can be created. @renderer: @part: -@y1: +@y1_: @x11: @x21: @y2: @x12: @x22: +<!-- # Unused Parameters # --> +@y1: <!-- ##### FUNCTION pango_renderer_draw_glyph ##### --> diff --git a/docs/tmpl/pangocairo.sgml b/docs/tmpl/pangocairo.sgml new file mode 100644 index 00000000..723a4a09 --- /dev/null +++ b/docs/tmpl/pangocairo.sgml @@ -0,0 +1,248 @@ +<!-- ##### SECTION Title ##### --> +Cairo Rendering + +<!-- ##### SECTION Short_Description ##### --> +Rendering with the Cairo backend + +<!-- ##### SECTION Long_Description ##### --> +<para> +The <ulink url="http://cairographics.org">Cairo library</ulink> is a +vector graphics library with a powerful rendering model. It has such +features as anti-aliased primitives, alpha-compositing, and +gradients. Multiple backends for Cairo are available, to allow +rendering to images, to PDF files, and to the screen on X and on other +windowing systems. The functions in this section allow using Pango +to render to Cairo surfaces. +</para> +<para> +Using Pango with Cairo is straightforward. A #PangoContext created +with pango_cairo_font_map_create_context() can be used on any +Cairo context (cairo_t), but needs to be updated to match the +current transformation matrix and target surface of the Cairo context +using pango_cairo_update_context(). The convenience functions +pango_cairo_create_layout() and pango_cairo_update_layout() handle +the common case where the program doesn't need to manipulate the +properties of the #PangoContext. +</para> +<para> +When you get the metrics of a layout or of a piece of a layout using +functions such as pango_layout_get_extents(), the reported metrics +are in user-space coordinates. If a piece of text is 10 units long, +and you call cairo_scale (cr, 2.0), it still is more-or-less 10 +units long. However, the results will be affected by hinting +(that is, the process of adjusting the text to look good on the +pixel grid), so you shouldn't assume they are completely independent +of the current transformation matrix. Note that the basic metrics +functions in Pango report results in integer Pango units. To get +to the floating point units used in Cairo divide by %PANGO_SCALE. +</para> +<example id="rotated-example"> +<title>Using Pango with Cairo</title> +<programlisting> +#include <math.h> +#include <pango/pangocairo.h> + +static void +draw_text (cairo_t *cr) +{ +#define RADIUS 150 +#define N_WORDS 10 +#define FONT "Sans Bold 27" + + PangoLayout *layout; + PangoFontDescription *desc; + int i; + + /* Center coordinates on the middle of the region we are drawing + */ + cairo_translate (cr, RADIUS, RADIUS); + + /* Create a PangoLayout, set the font and text */ + layout = pango_cairo_create_layout (cr); + + pango_layout_set_text (layout, "Text", -1); + desc = pango_font_description_from_string (FONT); + pango_layout_set_font_description (layout, desc); + pango_font_description_free (desc); + + /* Draw the layout N_WORDS times in a circle */ + for (i = 0; i < N_WORDS; i++) + { + int width, height; + double angle = (360. * i) / N_WORDS; + double red; + + cairo_save (cr); + + /* Gradient from red at angle == 60 to blue at angle == 300 */ + red = (1 + cos ((angle - 60) * G_PI / 180.)) / 2; + cairo_set_rgb_color (cr, red, 0, 1.0 - red); + + cairo_rotate (cr, angle * G_PI / 180.); + + /* Inform Pango to re-layout the text with the new transformation */ + pango_cairo_update_layout (cr, layout); + + pango_layout_get_size (layout, &width, &height); + cairo_move_to (cr, - ((double)width / PANGO_SCALE) / 2, - RADIUS); + pango_cairo_show_layout (cr, layout); + + cairo_restore (cr); + } + + /* free the layout object */ + g_object_unref (layout); +} + +int main (int argc, char **argv) +{ + cairo_t *cr; + FILE *f; + + if (argc != 2) + { + g_printerr ("Usage: cairo-example OUTPUT_FILENAME\n"); + return 1; + } + + f = fopen (argv[1], "w"); + if (!f) + { + g_printerr ("Usage: cannot open '%s'\n", argv[1]); + return 1; + } + + cr = cairo_create(); + cairo_set_target_png (cr, f, + CAIRO_FORMAT_ARGB32, + 2 * RADIUS, 2 * RADIUS); + + cairo_set_rgb_color (cr, 1.0, 1.0, 1.0); + cairo_rectangle (cr, 0, 0, 2 * RADIUS, 2 * RADIUS); + cairo_fill (cr); + draw_text (cr); + + cairo_destroy (cr); + fclose (f); + + return 0; +} +</programlisting> +</example> +<figure> + <title>Output of <xref linkend="rotated-example"/></title> + <graphic fileref="rotated-text.png" format="PNG"/> +</figure> + +<!-- ##### SECTION See_Also ##### --> +<para> + +</para> + +<!-- ##### STRUCT PangoCairoFontMap ##### --> +<para> + +</para> + + +<!-- ##### FUNCTION pango_cairo_font_map_new ##### --> +<para> + +</para> + +@Returns: + + +<!-- ##### FUNCTION pango_cairo_font_map_get_default ##### --> +<para> + +</para> + +@Returns: + + +<!-- ##### FUNCTION pango_cairo_font_map_set_resolution ##### --> +<para> + +</para> + +@fontmap: +@dpi: +<!-- # Unused Parameters # --> +@dpi_x: +@dpi_y: + + +<!-- ##### FUNCTION pango_cairo_font_map_get_resolution ##### --> +<para> + +</para> + +@fontmap: +@Returns: + + +<!-- ##### FUNCTION pango_cairo_font_map_create_context ##### --> +<para> + +</para> + +@fontmap: +@Returns: + + +<!-- ##### FUNCTION pango_cairo_update_context ##### --> +<para> + +</para> + +@cr: +@context: + + +<!-- ##### FUNCTION pango_cairo_create_layout ##### --> +<para> + +</para> + +@cr: +@Returns: + + +<!-- ##### FUNCTION pango_cairo_update_layout ##### --> +<para> + +</para> + +@cr: +@layout: + + +<!-- ##### FUNCTION pango_cairo_show_glyphs ##### --> +<para> + +</para> + +@cr: +@font: +@glyphs: + + +<!-- ##### FUNCTION pango_cairo_show_layout_line ##### --> +<para> + +</para> + +@cr: +@line: + + +<!-- ##### FUNCTION pango_cairo_show_layout ##### --> +<para> + +</para> + +@cr: +@layout: + + diff --git a/docs/tmpl/pangofc-fontmap.sgml b/docs/tmpl/pangofc-fontmap.sgml index db72b732..4f919ca3 100644 --- a/docs/tmpl/pangofc-fontmap.sgml +++ b/docs/tmpl/pangofc-fontmap.sgml @@ -44,6 +44,7 @@ Fontconfig-based backend involves deriving from both @default_substitute: @new_font: +@get_render_key: <!-- ##### FUNCTION pango_fc_font_description_from_pattern ##### --> <para> diff --git a/docs/tmpl/text-attributes.sgml b/docs/tmpl/text-attributes.sgml index ecbf7d9e..7c5fa9da 100644 --- a/docs/tmpl/text-attributes.sgml +++ b/docs/tmpl/text-attributes.sgml @@ -47,6 +47,7 @@ attribute is listed in parentheses after the description. @PANGO_ATTR_LETTER_SPACING: @PANGO_ATTR_UNDERLINE_COLOR: @PANGO_ATTR_STRIKETHROUGH_COLOR: +@PANGO_ATTR_ABSOLUTE_SIZE: <!-- ##### MACRO PANGO_TYPE_ATTR_TYPE ##### --> <para> @@ -151,12 +152,17 @@ impose shape restrictions. <!-- ##### STRUCT PangoAttrSize ##### --> <para> - +The #PangoAttrShape structure is used to represent attributes which +set font size. </para> -@attr: -@size: -@absolute: +@attr: the common portion of the attribute +@size: size of font, in units of 1/PANGO_SCALE of a point (for + PANGO_ATTR_SIZE) or of a device uni (for PANGO_ATTR_ABSOLUTE_SIZE) +@absolute: whether the font size is in device units or points. + This field is only present for compatibility with Pango-1.8.0 + (PANGO_ATTR_ABSOLUTE_SIZE was added in 1.8.1); and always will + be %FALSE for PANGO_ATTR_SIZE and %TRUE for PANGO_ATTR_ABSOLUTE_SIZE. <!-- ##### FUNCTION pango_parse_markup ##### --> <para> diff --git a/docs/tmpl/xft-fonts.sgml b/docs/tmpl/xft-fonts.sgml index 50a6e02a..fc4d6cae 100644 --- a/docs/tmpl/xft-fonts.sgml +++ b/docs/tmpl/xft-fonts.sgml @@ -10,7 +10,7 @@ The Xft library is a library for displaying fonts on the X window system; internally it uses the fontconfig library to locate font files, and the FreeType library to load and render fonts. The Xft backend is the recommended Pango font backend for screen -display with X. +display with X. (The <link linkend="pango-Cairo-Rendering">Cairo back end</link> is another possibility.) </para> <para> Using the Xft backend is generally straightforward; diff --git a/examples/.cvsignore b/examples/.cvsignore index 9b779602..d08e01f3 100644 --- a/examples/.cvsignore +++ b/examples/.cvsignore @@ -2,10 +2,11 @@ Makefile.in Makefile makefile.mingw pango.modules -pango-viewer +cairosimple +pango-cairoview +pango-xftview pangoft2topgm moc_viewer-qt.cc -pango-xftview .deps .libs *.lo diff --git a/examples/Makefile.am b/examples/Makefile.am index a5a87214..88979360 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -53,6 +53,39 @@ pango_xftview_LDADD = \ $(XFT_LIBS) ################################################### +################################################### +if HAVE_CAIRO +if HAVE_X +noinst_PROGRAMS += pango-cairoview +endif +endif + +pango_cairoview_SOURCES = \ + cairoview.c \ + renderdemo.c \ + argcontext.c \ + argcontext.h +pango_cairoview_LDADD = \ + ../pango/libpango-$(PANGO_API_VERSION).la \ + ../pango/libpangoft2-$(PANGO_API_VERSION).la \ + ../pango/libpangocairo-$(PANGO_API_VERSION).la \ + $(CAIRO_LIBS) \ + $(X_LIBS) +################################################### + +################################################### +if HAVE_CAIRO +noinst_PROGRAMS += cairosimple +endif + +cairosimple_SOURCES = \ + cairosimple.c +cairosimple_LDADD = \ + ../pango/libpango-$(PANGO_API_VERSION).la \ + ../pango/libpangocairo-$(PANGO_API_VERSION).la \ + $(CAIRO_LIBS) +################################################### + if CROSS_COMPILING else all-local: pango.modules diff --git a/examples/cairosimple.c b/examples/cairosimple.c new file mode 100644 index 00000000..1ec7edf2 --- /dev/null +++ b/examples/cairosimple.c @@ -0,0 +1,88 @@ +#include <math.h> +#include <pango/pangocairo.h> + +static void +draw_text (cairo_t *cr) +{ +#define RADIUS 150 +#define N_WORDS 10 +#define FONT "Sans Bold 27" + + PangoLayout *layout; + PangoFontDescription *desc; + int i; + + /* Center coordinates on the middle of the region we are drawing + */ + cairo_translate (cr, RADIUS, RADIUS); + + /* Create a PangoLayout, set the font and text */ + layout = pango_cairo_create_layout (cr); + + pango_layout_set_text (layout, "Text", -1); + desc = pango_font_description_from_string (FONT); + pango_layout_set_font_description (layout, desc); + pango_font_description_free (desc); + + /* Draw the layout N_WORDS times in a circle */ + for (i = 0; i < N_WORDS; i++) + { + int width, height; + double angle = (360. * i) / N_WORDS; + double red; + + cairo_save (cr); + + /* Gradient from red at angle == 60 to blue at angle == 300 */ + red = (1 + cos ((angle - 60) * G_PI / 180.)) / 2; + cairo_set_rgb_color (cr, red, 0, 1.0 - red); + + cairo_rotate (cr, angle * G_PI / 180.); + + /* Inform Pango to re-layout the text with the new transformation */ + pango_cairo_update_layout (cr, layout); + + pango_layout_get_size (layout, &width, &height); + cairo_move_to (cr, - ((double)width / PANGO_SCALE) / 2, - RADIUS); + pango_cairo_show_layout (cr, layout); + + cairo_restore (cr); + } + + /* free the layout object */ + g_object_unref (layout); +} + +int main (int argc, char **argv) +{ + cairo_t *cr; + FILE *f; + + if (argc != 2) + { + g_printerr ("Usage: cairosimple OUTPUT_FILENAME\n"); + return 1; + } + + f = fopen (argv[1], "w"); + if (!f) + { + g_printerr ("Usage: cannot open '%s'\n", argv[1]); + return 1; + } + + cr = cairo_create(); + cairo_set_target_png (cr, f, + CAIRO_FORMAT_ARGB32, + 2 * RADIUS, 2 * RADIUS); + + cairo_set_rgb_color (cr, 1.0, 1.0, 1.0); + cairo_rectangle (cr, 0, 0, 2 * RADIUS, 2 * RADIUS); + cairo_fill (cr); + draw_text (cr); + + cairo_destroy (cr); + fclose (f); + + return 0; +} diff --git a/examples/cairoview.c b/examples/cairoview.c new file mode 100644 index 00000000..ec285432 --- /dev/null +++ b/examples/cairoview.c @@ -0,0 +1,272 @@ +/* Pango + * cairoview.c: Example program to view a UTF-8 encoding file + * using Cairo to render result + * + * Copyright (C) 2005 Red Hat, Inc. + * Copyright (C) 2001 Sun Microsystems + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "renderdemo.h" + +#include <pango/pangocairo.h> + +static pixman_region16_t *update_region = NULL; +static PangoContext *context; +static Display *display; +int screen; +static Window window; +gboolean show_borders; + +typedef struct +{ + cairo_t *cr; + int x_offset; + int y_offset; +} RenderData; + +static void +do_cairo_render (PangoLayout *layout, + int x, + int y, + gpointer data) +{ + RenderData *render_data = data; + cairo_t *cr = render_data->cr; + + cairo_move_to (cr, x, y); + pango_cairo_show_layout (cr, layout); + + if (show_borders) + { + PangoRectangle ink, logical; + double lw = cairo_current_line_width (cr); + + pango_layout_get_extents (layout, &ink, &logical); + + cairo_save (cr); + cairo_set_rgb_color (cr, 1.0, 0.0, 0.0); + cairo_set_alpha (cr, 0.75); + + cairo_rectangle (cr, + (double)logical.x / PANGO_SCALE - lw / 2, + (double)logical.y / PANGO_SCALE - lw / 2, + (double)logical.width / PANGO_SCALE + lw, + (double)logical.height / PANGO_SCALE + lw); + cairo_stroke (cr); + + cairo_set_rgb_color (cr, 0.0, 1.0, 0.0); + + cairo_rectangle (cr, + (double)ink.x / PANGO_SCALE - lw / 2, + (double)ink.y / PANGO_SCALE - lw / 2, + (double)ink.width / PANGO_SCALE + lw, + (double)ink.height / PANGO_SCALE + lw); + cairo_stroke (cr); + + cairo_restore (cr); + } +} + +static void +do_cairo_transform (PangoContext *context, + PangoMatrix *matrix, + gpointer data) +{ + RenderData *render_data = data; + cairo_matrix_t *cairo_matrix = cairo_matrix_create (); + + if (matrix) + { + cairo_matrix_set_affine (cairo_matrix, + matrix->xx, matrix->yx, + matrix->xy, matrix->yy, + matrix->x0 + render_data->x_offset, + matrix->y0 + render_data->y_offset); + } + else + { + cairo_matrix_set_affine (cairo_matrix, + 1.0, 0, + 0, 1.0, + render_data->x_offset, + render_data->y_offset); + } + + cairo_set_matrix (render_data->cr, cairo_matrix); + cairo_matrix_destroy (cairo_matrix); + + pango_context_set_matrix (context, matrix); + pango_cairo_update_context (render_data->cr, context); +} + +void +update () +{ + RenderData render_data; + cairo_t *cr; + Pixmap pixmap; + GC gc; + pixman_box16_t *extents; + int n_rects; + pixman_box16_t *rects; + XRectangle *xrects; + int i; + + /* Create a temporary pixmap and a Cairo context pointing to it */ + extents = pixman_region_extents (update_region); + pixmap = XCreatePixmap (display, window, + extents->x2 - extents->x1, + extents->y2 - extents->y1, + DefaultDepth (display, screen)); + + cr = render_data.cr = cairo_create(); + cairo_set_target_drawable (cr, display, pixmap); + render_data.x_offset = - extents->x1; + render_data.y_offset = - extents->y1; + + do_cairo_transform (context, NULL, &render_data); + + /* Clip to the current update region and fill with white */ + n_rects = pixman_region_num_rects (update_region); + rects = pixman_region_rects (update_region); + xrects = g_new (XRectangle, n_rects); + + for (i = 0; i < n_rects; i++) + { + xrects[i].x = rects[i].x1; + xrects[i].y = rects[i].y1; + xrects[i].width = rects[i].x2 - rects[i].x1; + xrects[i].height = rects[i].y2 - rects[i].y1; + + cairo_rectangle (cr, xrects[i].x, xrects[i].y, + xrects[i].width, xrects[i].height); + } + + cairo_clip (cr); + cairo_set_rgb_color (cr, 1.0, 1.0, 1.0); + cairo_fill (cr); + + /* Draw the text in black */ + cairo_set_rgb_color (cr, 0.0, 0.0, 0.0); + do_output (context, do_cairo_render, do_cairo_transform, &render_data, NULL, NULL); + cairo_destroy (cr); + + /* Copy the updated area onto the window */ + gc = XCreateGC (display, pixmap, 0, NULL); + XSetClipRectangles (display, gc, 0, 0, xrects, n_rects, YXBanded); + + XCopyArea (display, pixmap, window, gc, + 0, 0, + extents->x2 - extents->x1, extents->y2 - extents->y1, + extents->x1, extents->y1); + + g_free (xrects); + XFreeGC (display, gc); + XFreePixmap (display, pixmap); + + pixman_region_destroy (update_region); + update_region = NULL; +} + +void +expose (XExposeEvent *xev) +{ + if (!update_region) + update_region = pixman_region_create (); + + pixman_region_union_rect (update_region, update_region, + xev->x, xev->y, xev->width, xev->height); +} + +int main (int argc, char **argv) +{ + PangoFontMap *fontmap; + XEvent xev; + unsigned long bg; + int width, height; + RenderData render_data; + unsigned int quit_keycode; + unsigned int borders_keycode; + + g_type_init(); + + parse_options (argc, argv); + + display = XOpenDisplay (NULL); + if (!display) + fail ("Cannot open display %s\n", XDisplayName (NULL)); + screen = DefaultScreen (display); + + fontmap = pango_cairo_font_map_get_default (); + context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap)); + + render_data.cr = cairo_create (); + render_data.x_offset = 0; + render_data.y_offset = 0; + do_output (context, NULL, do_cairo_transform, &render_data, &width, &height); + cairo_destroy (render_data.cr); + + bg = WhitePixel (display, screen); + + window = XCreateSimpleWindow (display, DefaultRootWindow (display), + 0, 0, width, height, 0, + bg, bg); + XSelectInput (display, window, ExposureMask | KeyPressMask); + + XMapWindow (display, window); + XmbSetWMProperties (display, window, + get_options_string (), + NULL, NULL, 0, NULL, NULL, NULL); + + borders_keycode = XKeysymToKeycode(display, 'B'); + quit_keycode = XKeysymToKeycode(display, 'Q'); + + while (1) + { + if (!XPending (display) && update_region) + update (); + + XNextEvent (display, &xev); + switch (xev.xany.type) { + case KeyPress: + if (xev.xkey.keycode == quit_keycode) + goto done; + else if (xev.xkey.keycode == borders_keycode) + { + show_borders = !show_borders; + if (!update_region) + update_region = pixman_region_create (); + + pixman_region_union_rect (update_region, update_region, + 0, 0, width, height); + } + break; + case Expose: + expose (&xev.xexpose); + break; + } + } + + done: + return 0; +} diff --git a/examples/pangoft2topgm.c b/examples/pangoft2topgm.c index f3a1a15c..c3f90090 100644 --- a/examples/pangoft2topgm.c +++ b/examples/pangoft2topgm.c @@ -93,7 +93,7 @@ main(int argc, char *argv[]) int row; int width, height; - do_output (context, NULL, NULL, &width, &height); + do_output (context, NULL, NULL, NULL, &width, &height); bitmap.width = width; bitmap.pitch = (bitmap.width + 3) & ~3; @@ -103,7 +103,7 @@ main(int argc, char *argv[]) bitmap.pixel_mode = ft_pixel_mode_grays; memset (buf, 0x00, bitmap.pitch * bitmap.rows); - do_output (context, ft2_render, &bitmap, &width, &height); + do_output (context, ft2_render, NULL, &bitmap, &width, &height); /* Invert bitmap to get black text on white background */ { diff --git a/examples/renderdemo.c b/examples/renderdemo.c index 669ad81b..34d9a057 100644 --- a/examples/renderdemo.c +++ b/examples/renderdemo.c @@ -156,13 +156,12 @@ transform_point (PangoMatrix *matrix, } static void -output_body (PangoContext *context, - const char *text, - RenderCallback render_cb, - gpointer render_data, - PangoMatrix *matrix, - int *width, - int *height) +output_body (PangoContext *context, + const char *text, + RenderCallback render_cb, + gpointer cb_data, + int *width, + int *height) { PangoLayout *layout; PangoRectangle logical_rect; @@ -187,8 +186,6 @@ output_body (PangoContext *context, for (size = start_size; size <= end_size; size += increment) { - pango_context_set_matrix (context, matrix); - layout = make_layout (context, text, size); pango_layout_get_extents (layout, NULL, &logical_rect); @@ -196,7 +193,7 @@ output_body (PangoContext *context, *height += PANGO_PIXELS (logical_rect.height); if (render_cb) - (*render_cb) (layout, 0, dy, render_data); + (*render_cb) (layout, 0, dy, cb_data); dy += PANGO_PIXELS (logical_rect.height); @@ -204,12 +201,25 @@ output_body (PangoContext *context, } } +static void +set_transform (PangoContext *context, + TransformCallback transform_cb, + gpointer cb_data, + PangoMatrix *matrix) +{ + if (transform_cb) + (*transform_cb) (context, matrix, cb_data); + else + pango_context_set_matrix (context, matrix); +} + void -do_output (PangoContext *context, - RenderCallback render_cb, - gpointer render_data, - int *width_out, - int *height_out) +do_output (PangoContext *context, + RenderCallback render_cb, + TransformCallback transform_cb, + gpointer cb_data, + int *width_out, + int *height_out) { PangoLayout *layout; PangoRectangle logical_rect; @@ -228,6 +238,8 @@ do_output (PangoContext *context, width = 0; height = 0; + set_transform (context, transform_cb, cb_data, NULL); + pango_context_set_language (context, pango_language_from_string ("en_US")); pango_context_set_base_dir (context, opt_rtl ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR); @@ -242,7 +254,7 @@ do_output (PangoContext *context, height += PANGO_PIXELS (logical_rect.height); if (render_cb) - (*render_cb) (layout, x, y, render_data); + (*render_cb) (layout, x, y, cb_data); y += PANGO_PIXELS (logical_rect.height); @@ -250,9 +262,11 @@ do_output (PangoContext *context, g_free (options_string); } - output_body (context, text, NULL, NULL, NULL, &rotated_width, &rotated_height); - pango_matrix_rotate (&matrix, opt_rotate); + + set_transform (context, transform_cb, cb_data, &matrix); + + output_body (context, text, NULL, NULL, &rotated_width, &rotated_height); transform_point (&matrix, 0, 0, &p1x, &p1y); transform_point (&matrix, rotated_width, 0, &p2x, &p2y); @@ -268,8 +282,10 @@ do_output (PangoContext *context, matrix.x0 = x - minx; matrix.y0 = y - miny; + set_transform (context, transform_cb, cb_data, &matrix); + if (render_cb) - output_body (context, text, render_cb, render_data, &matrix, &rotated_width, &rotated_height); + output_body (context, text, render_cb, cb_data, &rotated_width, &rotated_height); width = MAX (width, maxx - minx); height += maxy - miny; @@ -421,11 +437,8 @@ parse_options (int argc, char *argv[]) exit (1); } - if (!opt_display && !opt_output) - { - g_printerr ("%s: --output not specified, assuming --display\n", prog_name); - opt_display = TRUE; - } + if (!opt_output) + opt_display = TRUE; /* Get the text */ diff --git a/examples/renderdemo.h b/examples/renderdemo.h index cffea109..84fc56b0 100644 --- a/examples/renderdemo.h +++ b/examples/renderdemo.h @@ -33,18 +33,22 @@ typedef void (*RenderCallback) (PangoLayout *layout, int x, int y, gpointer data); +typedef void (*TransformCallback) (PangoContext *context, + PangoMatrix *transform, + gpointer data); void fail (const char *format, ...) G_GNUC_PRINTF (1, 2); -void parse_options (int argc, - char *argv[]); -void do_output (PangoContext *context, - RenderCallback render_cb, - gpointer render_data, - int *width, - int *height); -void fc_substitute_func (FcPattern *pattern, - gpointer data); +void parse_options (int argc, + char *argv[]); +void do_output (PangoContext *context, + RenderCallback render_cb, + TransformCallback transform_cb, + gpointer cb_data, + int *width, + int *height); +void fc_substitute_func (FcPattern *pattern, + gpointer data); gchar *get_options_string (void); extern char *prog_name; diff --git a/examples/xftview.c b/examples/xftview.c index 0b95e2f9..c559c8ee 100644 --- a/examples/xftview.c +++ b/examples/xftview.c @@ -69,7 +69,7 @@ update () XftDrawRect (draw, &color, area.x, area.y, area.width, area.height); - do_output (context, xft_render, draw, NULL, NULL); + do_output (context, xft_render, NULL, draw, NULL, NULL); } void @@ -111,7 +111,7 @@ int main (int argc, char **argv) bg = WhitePixel (display, screen); context = pango_xft_get_context (display, screen); - do_output (context, NULL, NULL, &width, &height); + do_output (context, NULL, NULL, NULL, &width, &height); window = XCreateSimpleWindow (display, DefaultRootWindow (display), 0, 0, width, height, 0, diff --git a/pango/Makefile.am b/pango/Makefile.am index 56af60f0..7142b8d3 100644 --- a/pango/Makefile.am +++ b/pango/Makefile.am @@ -213,6 +213,33 @@ libpangoxft_1_0_la_SOURCES = \ pangoxft-render.c +# ------------------- libpangocairo ------------------- + +if HAVE_CAIRO +pangoinclude_HEADERS += pangocairo.h +lib_LTLIBRARIES += libpangocairo-1.0.la +endif + +libpangocairo_1_0_la_LDFLAGS = -version-info $(LT_VERSION_INFO) $(no_undefined) +libpangocairo_1_0_la_LIBADD = libpangoft2-$(PANGO_API_VERSION).la libpango-$(PANGO_API_VERSION).la $(CAIRO_LIBS) $(GLIB_LIBS) +libpangocairo_1_0_la_DEPENDENCIES = libpango-$(PANGO_API_VERSION).la + +libpangocairo_1_0_la_SOURCES = \ + pangocairo-font.c \ + pangocairo-fontmap.c \ + pangocairo-render.c \ + pangocairo-private.h + +if HAVE_CAIRO_FREETYPE +libpangocairo_1_0_la_LIBADD += $(FREETYPE_LIBS) +libpangocairo_1_0_la_DEPENDENCIES += libpangoft2-$(PANGO_API_VERSION).la + +libpangocairo_1_0_la_SOURCES += \ + pangocairo-fcfont.c \ + pangocairo-fcfontmap.c \ + pangocairo-fc.h +endif + # ------------------- libpangowin32 ------------------- if HAVE_WIN32 diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c index 3191c029..edf0d966 100644 --- a/pango/pango-attributes.c +++ b/pango/pango-attributes.c @@ -402,8 +402,11 @@ static PangoAttribute * pango_attr_size_copy (const PangoAttribute *attr) { const PangoAttrSize *size_attr = (PangoAttrSize *)attr; - - return pango_attr_size_new_internal (size_attr->size, size_attr->absolute); + + if (attr->klass->type == PANGO_ATTR_ABSOLUTE_SIZE) + return pango_attr_size_new_absolute (size_attr->size); + else + return pango_attr_size_new (size_attr->size); } static void @@ -419,8 +422,7 @@ pango_attr_size_equal (const PangoAttribute *attr1, const PangoAttrSize *size_attr1 = (const PangoAttrSize *)attr1; const PangoAttrSize *size_attr2 = (const PangoAttrSize *)attr2; - return (size_attr1->size == size_attr2->size && - size_attr1->absolute == size_attr2->absolute); + return size_attr1->size == size_attr2->size; } static PangoAttribute * @@ -428,15 +430,22 @@ pango_attr_size_new_internal (int size, gboolean absolute) { PangoAttrSize *result; + static const PangoAttrClass klass = { PANGO_ATTR_SIZE, pango_attr_size_copy, pango_attr_size_destroy, pango_attr_size_equal }; + static const PangoAttrClass absolute_klass = { + PANGO_ATTR_ABSOLUTE_SIZE, + pango_attr_size_copy, + pango_attr_size_destroy, + pango_attr_size_equal + }; result = g_new (PangoAttrSize, 1); - result->attr.klass = &klass; + result->attr.klass = absolute ? &absolute_klass : &klass; result->size = size; result->absolute = absolute; @@ -458,8 +467,8 @@ pango_attr_size_new (int size) } /** - * pango_attr_size_absolute_new: - * @size: the font size, in #PANGO_SCALE<!-- -->ths of a device units. + * pango_attr_size_new_absolute: + * @size: the font size, in #PANGO_SCALE<!-- -->ths of a device unit. * * Create a new font-size attribute in device units. * @@ -1676,10 +1685,14 @@ pango_attr_iterator_get_font (PangoAttrIterator *iterator, if (!(mask & PANGO_FONT_MASK_SIZE)) { mask |= PANGO_FONT_MASK_SIZE; - if (((PangoAttrSize *)attr)->absolute) - pango_font_description_set_absolute_size (desc, ((PangoAttrSize *)attr)->size); - else - pango_font_description_set_size (desc, ((PangoAttrSize *)attr)->size); + pango_font_description_set_size (desc, ((PangoAttrSize *)attr)->size); + } + break; + case PANGO_ATTR_ABSOLUTE_SIZE: + if (!(mask & PANGO_FONT_MASK_SIZE)) + { + mask |= PANGO_FONT_MASK_SIZE; + pango_font_description_set_absolute_size (desc, ((PangoAttrSize *)attr)->size); } break; case PANGO_ATTR_SCALE: diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h index a1877058..f26e178f 100644 --- a/pango/pango-attributes.h +++ b/pango/pango-attributes.h @@ -85,7 +85,8 @@ typedef enum PANGO_ATTR_FALLBACK, /* PangoAttrInt */ PANGO_ATTR_LETTER_SPACING, /* PangoAttrInt */ PANGO_ATTR_UNDERLINE_COLOR, /* PangoAttrColor */ - PANGO_ATTR_STRIKETHROUGH_COLOR /* PangoAttrColor */ + PANGO_ATTR_STRIKETHROUGH_COLOR, /* PangoAttrColor */ + PANGO_ATTR_ABSOLUTE_SIZE /* PangoAttrSize */ } PangoAttrType; typedef enum { diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 53106f20..d475a945 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -3917,15 +3917,22 @@ pango_layout_line_get_extents (PangoLayoutLine *line, if (ink_rect) { - new_pos = MIN (ink_rect->x, x_pos + run_ink.x); - ink_rect->width = MAX (ink_rect->x + ink_rect->width, - x_pos + run_ink.x + run_ink.width) - new_pos; - ink_rect->x = new_pos; + if (tmp_list == line->runs) + { + *ink_rect = run_ink; + } + else + { + new_pos = MIN (ink_rect->x, x_pos + run_ink.x); + ink_rect->width = MAX (ink_rect->x + ink_rect->width, + x_pos + run_ink.x + run_ink.width) - new_pos; + ink_rect->x = new_pos; - new_pos = MIN (ink_rect->y, run_ink.y); - ink_rect->height = MAX (ink_rect->y + ink_rect->height, - run_ink.y + run_ink.height) - new_pos; - ink_rect->y = new_pos; + new_pos = MIN (ink_rect->y, run_ink.y); + ink_rect->height = MAX (ink_rect->y + ink_rect->height, + run_ink.y + run_ink.height) - new_pos; + ink_rect->y = new_pos; + } } if (logical_rect) diff --git a/pango/pangocairo-fc.h b/pango/pangocairo-fc.h new file mode 100644 index 00000000..22fd1b60 --- /dev/null +++ b/pango/pangocairo-fc.h @@ -0,0 +1,54 @@ +/* Pango + * pangocairo-fc.h: Private header file for Cairo/fontconfig combination + * + * Copyright (C) 2005 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __PANGOCAIRO_FC_H__ +#define __PANGOCAIRO_FC_H__ + +#include "pangofc-fontmap.h" +#include "pangocairo.h" + +G_BEGIN_DECLS + +#define PANGO_TYPE_CAIRO_FC_FONT_MAP (pango_cairo_fc_font_map_get_type ()) +#define PANGO_CAIRO_FC_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_FC_FONT_MAP, PangoCairoFcFontMap)) +#define PANGO_IS_CAIRO_FC_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_CAIRO_FC_FONT_MAP)) + +typedef struct _PangoCairoFcFontMap PangoCairoFcFontMap; + +struct _PangoCairoFcFontMap +{ + PangoFcFontMap parent_instance; + + double dpi; + + FT_Library library; + PangoRenderer *renderer; +}; + +GType pango_cairo_fc_font_map_get_type (void); + +PangoFcFont *_pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap, + FcPattern *pattern); + +G_END_DECLS + +#endif /* __PANGOCAIRO_FC_H__ */ + diff --git a/pango/pangocairo-fcfont.c b/pango/pangocairo-fcfont.c new file mode 100644 index 00000000..b8f4a32b --- /dev/null +++ b/pango/pangocairo-fcfont.c @@ -0,0 +1,508 @@ +/* Pango + * pangocairofc-font.c: Cairo font handling, fontconfig backend + * + * Copyright (C) 2000-2005 Red Hat Software + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include <stdlib.h> + +#include "pango-fontmap.h" +#include "pangocairo-private.h" +#include "pangocairo-fc.h" +#include "pangofc-private.h" + +#define PANGO_TYPE_CAIRO_FC_FONT (pango_cairo_fc_font_get_type ()) +#define PANGO_CAIRO_FC_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_FC_FONT, PangoCairoFcFont)) +#define PANGO_CAIRO_FC_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_CAIRO_FC_FONT, PangoCairoFcFontClass)) +#define PANGO_CAIRO_IS_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_CAIRO_FC_FONT)) +#define PANGO_CAIRO_FC_FONT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_CAIRO_FC_FONT, PangoCairoFcFontClass)) + +#define PANGO_CAIRO_UNKNOWN_FLAG 0x10000000 + +typedef struct _PangoCairoFcFont PangoCairoFcFont; +typedef struct _PangoCairoFcFontClass PangoCairoFcFontClass; + +struct _PangoCairoFcFont +{ + PangoFcFont font; + + FT_Face face; + cairo_font_t *cairo_font; + + int load_flags; + gboolean have_size; + + GHashTable *glyph_info; +}; + +struct _PangoCairoFcFontClass +{ + PangoFcFontClass parent_class; +}; + +GType pango_cairo_fc_font_get_type (void); + +/******************************* + * Utility functions * + *******************************/ + +static FT_Face +load_face (PangoCairoFcFont *cffont) +{ + PangoFcFont *fcfont = PANGO_FC_FONT (cffont); + FT_Library library = PANGO_CAIRO_FC_FONT_MAP (fcfont->fontmap)->library; + FT_Error error; + FcPattern *pattern; + FcChar8 *filename; + FcBool antialias, hinting, autohint; + FT_Face face = NULL; + int id; + + pattern = fcfont->font_pattern; + + cffont->load_flags = 0; + + /* disable antialiasing if requested */ + if (FcPatternGetBool (pattern, + FC_ANTIALIAS, 0, &antialias) != FcResultMatch) + antialias = FcTrue; + + if (antialias) + cffont->load_flags |= FT_LOAD_NO_BITMAP; + else + cffont->load_flags |= FT_LOAD_TARGET_MONO; + + /* disable hinting if requested */ + if (FcPatternGetBool (pattern, + FC_HINTING, 0, &hinting) != FcResultMatch) + hinting = FcTrue; + + if (!hinting) + cffont->load_flags |= FT_LOAD_NO_HINTING; + + /* force autohinting if requested */ + if (FcPatternGetBool (pattern, + FC_AUTOHINT, 0, &autohint) != FcResultMatch) + autohint = FcFalse; + + if (autohint) + cffont->load_flags |= FT_LOAD_FORCE_AUTOHINT; + + if (FcPatternGetString (pattern, FC_FILE, 0, &filename) != FcResultMatch) + goto bail; + + if (FcPatternGetInteger (pattern, FC_INDEX, 0, &id) != FcResultMatch) + goto bail; + + error = FT_New_Face (library, (char *) filename, id, &face); + + bail: + return face; +} + +static FT_Face +load_fallback_face (PangoCairoFcFont *cffont) +{ + PangoFcFont *fcfont = PANGO_FC_FONT (cffont); + FT_Library library = PANGO_CAIRO_FC_FONT_MAP (fcfont->fontmap)->library; + FcPattern *sans; + FcPattern *matched; + FcResult result; + FT_Error error; + FcChar8 *filename = NULL; + FT_Face face = NULL; + int id; + + /* FIXME: pass in a size in case Sans is bitmap */ + sans = FcPatternBuild (NULL, + FC_FAMILY, FcTypeString, "sans", + NULL); + + matched = FcFontMatch (NULL, sans, &result); + + if (FcPatternGetString (matched, FC_FILE, 0, &filename) != FcResultMatch) + goto bail; + + if (FcPatternGetInteger (matched, FC_INDEX, 0, &id) != FcResultMatch) + goto bail; + + face = NULL; + error = FT_New_Face (library, (char *) filename, id, &face); + + if (error) + { + bail: + g_warning ("Unable to open font file %s for Sans, exiting", filename); + exit (1); + } + + FcPatternDestroy (sans); + FcPatternDestroy (matched); + + return face; +} + +static cairo_font_t * +get_cairo_font (PangoCairoFcFont *cffont) +{ + PangoFcFont *fcfont = PANGO_FC_FONT (cffont); + + if (cffont->cairo_font == NULL) + { + FT_Face face = load_face (cffont); + + if (face) + cffont->cairo_font = cairo_ft_font_create_for_ft_face (face); + + if (!cffont->cairo_font) + { + gchar *name = pango_font_description_to_string (fcfont->description); + g_warning ("Cannot open font file for font %s, trying Sans", name); + g_free (name); + + if (face) + FT_Done_Face (face); + + face = load_fallback_face (cffont); + + if (face) + cffont->cairo_font = cairo_ft_font_create_for_ft_face (face); + + if (!cffont->cairo_font) + { + g_warning ("Unable create Cairo font for Sans, exiting"); + exit (1); + } + } + + cffont->face = face; + } + + return cffont->cairo_font; +} + +static void +make_current (PangoCairoFcFont *cffont, + cairo_t *cr) +{ + PangoFcFont *fcfont = PANGO_FC_FONT (cffont); + double scale; + + if (pango_font_description_get_size_is_absolute (fcfont->description)) + scale = pango_font_description_get_size (fcfont->description); + else + scale = (PANGO_CAIRO_FC_FONT_MAP (fcfont->fontmap)->dpi * + pango_font_description_get_size (fcfont->description)) / (PANGO_SCALE * 72.); + + cairo_set_font (cr, get_cairo_font (cffont)); + cairo_scale_font (cr, scale); +} + +static void +pango_cairo_fc_font_make_current (PangoCairoFont *font, + cairo_t *cr) +{ + make_current (PANGO_CAIRO_FC_FONT (font), cr); +} + +static void +cairo_font_iface_init (PangoCairoFontIface *iface) +{ + iface->make_current = pango_cairo_fc_font_make_current; +} + +G_DEFINE_TYPE_WITH_CODE (PangoCairoFcFont, pango_cairo_fc_font, PANGO_TYPE_FC_FONT, + { G_IMPLEMENT_INTERFACE (PANGO_TYPE_CAIRO_FONT, cairo_font_iface_init) }); + +/******************************** + * Method implementations * + ********************************/ + +static void +pango_cairo_fc_font_finalize (GObject *object) +{ + PangoCairoFcFont *cffont = PANGO_CAIRO_FC_FONT (object); + + if (cffont->cairo_font) + { + cairo_font_destroy (cffont->cairo_font); + cffont->cairo_font = NULL; + + FT_Done_Face (cffont->face); + cffont->face = NULL; + } + + if (cffont->glyph_info) + g_hash_table_destroy (cffont->glyph_info); + + G_OBJECT_CLASS (pango_cairo_fc_font_parent_class)->finalize (object); +} + +static cairo_t * +get_temporary_context (PangoCairoFcFont *cffont) +{ + PangoFcFont *fcfont = PANGO_FC_FONT (cffont); + FcMatrix *fc_matrix; + cairo_t *cr; + + cr = cairo_create (); + + if (FcPatternGetMatrix (fcfont->font_pattern, + FC_MATRIX, 0, &fc_matrix) == FcResultMatch) + { + cairo_matrix_t *cairo_matrix = cairo_matrix_create (); + cairo_matrix_set_affine (cairo_matrix, + fc_matrix->xx, fc_matrix->yx, + fc_matrix->xy, fc_matrix->yy, + 0, 0); + cairo_set_matrix (cr, cairo_matrix); + cairo_matrix_destroy (cairo_matrix); + } + + make_current (cffont, cr); + + return cr; +} + +static void +get_ascent_descent (PangoCairoFcFont *cffont, + int *ascent, + int *descent) +{ + /* This is complicated in general (see pangofc-font.c:get_face_metrics(), + * but simple for hinted, untransformed fonts. cairo_glyph_extents() will + * have set up the right size on the font as a side-effect. + */ + *descent = - PANGO_UNITS_26_6 (cffont->face->size->metrics.descender); + *ascent = PANGO_UNITS_26_6 (cffont->face->size->metrics.ascender); +} + +static void +get_glyph_extents_cairo (PangoFcFont *fcfont, + PangoGlyph glyph, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect) +{ + PangoCairoFcFont *cffont = PANGO_CAIRO_FC_FONT (fcfont); + cairo_text_extents_t extents; + cairo_glyph_t cairo_glyph; + cairo_t *cr; + + cairo_glyph.index = glyph; + cairo_glyph.x = 0; + cairo_glyph.y = 0; + + cr = get_temporary_context (cffont); + cairo_glyph_extents (cr, &cairo_glyph, 1, &extents); + cairo_destroy (cr); + + if (ink_rect) + { + ink_rect->x = extents.x_bearing * PANGO_SCALE; + ink_rect->y = extents.y_bearing * PANGO_SCALE; + ink_rect->width = extents.width * PANGO_SCALE; + ink_rect->height = extents.height * PANGO_SCALE; + } + + if (logical_rect) + { + int ascent, descent; + + get_ascent_descent (cffont, &ascent, &descent); + + logical_rect->x = 0; + logical_rect->y = - ascent; + logical_rect->width = extents.x_advance * PANGO_SCALE; + logical_rect->height = ascent + descent; + } +} + +typedef struct +{ + PangoRectangle ink_rect; + PangoRectangle logical_rect; +} Extents; + +static void +get_glyph_extents_raw (PangoCairoFcFont *cffont, + PangoGlyph glyph, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect) +{ + Extents *extents; + + if (!cffont->glyph_info) + cffont->glyph_info = g_hash_table_new_full (NULL, NULL, + NULL, (GDestroyNotify)g_free); + + extents = g_hash_table_lookup (cffont->glyph_info, + GUINT_TO_POINTER (glyph)); + + if (!extents) + { + extents = g_new (Extents, 1); + + pango_fc_font_get_raw_extents (PANGO_FC_FONT (cffont), + FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING, + glyph, + &extents->ink_rect, + &extents->logical_rect); + + g_hash_table_insert (cffont->glyph_info, + GUINT_TO_POINTER (glyph), + extents); + } + + if (ink_rect) + *ink_rect = extents->ink_rect; + + if (logical_rect) + *logical_rect = extents->logical_rect; +} + +static void +pango_cairo_fc_font_get_glyph_extents (PangoFont *font, + PangoGlyph glyph, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect) +{ + PangoCairoFcFont *cffont = PANGO_CAIRO_FC_FONT (font); + PangoFcFont *fcfont = PANGO_FC_FONT (font); + + if (!fcfont->fontmap) /* Display closed */ + goto fallback; + + if (glyph == (PangoGlyph)-1) + glyph = 0; + + if (glyph) + { + if (!fcfont->is_transformed && fcfont->is_hinted) + get_glyph_extents_cairo (fcfont, glyph, ink_rect, logical_rect); + else + get_glyph_extents_raw (cffont, glyph, ink_rect, logical_rect); + } + else + { + fallback: + + if (ink_rect) + { + ink_rect->x = 0; + ink_rect->width = 0; + ink_rect->y = 0; + ink_rect->height = 0; + } + if (logical_rect) + { + logical_rect->x = 0; + logical_rect->width = 0; + logical_rect->y = 0; + logical_rect->height = 0; + } + } +} + +static FT_Face +pango_cairo_fc_font_lock_face (PangoFcFont *font) +{ + PangoCairoFcFont *cffont = PANGO_CAIRO_FC_FONT (font); + + /* Horrible hack, we need the font's face to be sized when + * locked, but sizing is only done as a side-effect + */ + if (!cffont->have_size) + { + cairo_t *cr = get_temporary_context (cffont); + cairo_font_extents_t extents; + + cairo_current_font_extents (cr, &extents); + cairo_destroy (cr); + + cffont->have_size = TRUE; + } + + return cairo_ft_font_face (cffont->cairo_font); +} + +static void +pango_cairo_fc_font_unlock_face (PangoFcFont *font) +{ +} + +static PangoGlyph +pango_cairo_fc_font_real_get_unknown_glyph (PangoFcFont *font, + gunichar wc) +{ + return 0; +} + +static void +pango_cairo_fc_font_shutdown (PangoFcFont *fcfont) +{ + PangoCairoFcFont *cffont = PANGO_CAIRO_FC_FONT (fcfont); + if (cffont->cairo_font) + { + cairo_font_destroy (cffont->cairo_font); + cffont->cairo_font = NULL; + + FT_Done_Face (cffont->face); + cffont->face = NULL; + } +} + +static void +pango_cairo_fc_font_class_init (PangoCairoFcFontClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + PangoFontClass *font_class = PANGO_FONT_CLASS (class); + PangoFcFontClass *fc_font_class = PANGO_FC_FONT_CLASS (class); + + object_class->finalize = pango_cairo_fc_font_finalize; + + font_class->get_glyph_extents = pango_cairo_fc_font_get_glyph_extents; + + fc_font_class->lock_face = pango_cairo_fc_font_lock_face; + fc_font_class->unlock_face = pango_cairo_fc_font_unlock_face; + fc_font_class->get_unknown_glyph = pango_cairo_fc_font_real_get_unknown_glyph; + fc_font_class->shutdown = pango_cairo_fc_font_shutdown; +} + +static void +pango_cairo_fc_font_init (PangoCairoFcFont *cffont) +{ +} + +/******************** + * Private API * + ********************/ + +PangoFcFont * +_pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap, + FcPattern *pattern) +{ + g_return_val_if_fail (PANGO_IS_CAIRO_FC_FONT_MAP (cffontmap), NULL); + g_return_val_if_fail (pattern != NULL, NULL); + + return g_object_new (PANGO_TYPE_CAIRO_FC_FONT, + "pattern", pattern, + NULL); +} + diff --git a/pango/pangocairo-fcfontmap.c b/pango/pangocairo-fcfontmap.c new file mode 100644 index 00000000..0d05c422 --- /dev/null +++ b/pango/pangocairo-fcfontmap.c @@ -0,0 +1,140 @@ +/* Pango + * pangocairo-fontmap.c: Cairo font handling, fontconfig backend + * + * Copyright (C) 2000-2005 Red Hat Software + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "pangofc-fontmap.h" +#include "pangocairo.h" +#include "pangocairo-private.h" +#include "pangocairo-fc.h" + +typedef struct _PangoCairoFcFontMapClass PangoCairoFcFontMapClass; + +struct _PangoCairoFcFontMapClass +{ + PangoFcFontMapClass parent_class; +}; + +static void +pango_cairo_fc_font_map_set_resolution (PangoCairoFontMap *cfontmap, + double dpi) +{ + PangoCairoFcFontMap *cffontmap = PANGO_CAIRO_FC_FONT_MAP (cfontmap); + + cffontmap->dpi = dpi; + + pango_fc_font_map_cache_clear (PANGO_FC_FONT_MAP (cfontmap)); +} + +static double +pango_cairo_fc_font_map_get_resolution (PangoCairoFontMap *cfontmap) +{ + PangoCairoFcFontMap *cffontmap = PANGO_CAIRO_FC_FONT_MAP (cfontmap); + + return cffontmap->dpi; +} + +static PangoRenderer * +pango_cairo_fc_font_map_get_renderer (PangoCairoFontMap *cfontmap) +{ + PangoCairoFcFontMap *cffontmap = PANGO_CAIRO_FC_FONT_MAP (cfontmap); + + if (!cffontmap->renderer) + cffontmap->renderer = g_object_new (PANGO_TYPE_CAIRO_RENDERER, NULL); + + return cffontmap->renderer; +} + +static void +cairo_font_map_iface_init (PangoCairoFontMapIface *iface) +{ + iface->set_resolution = pango_cairo_fc_font_map_set_resolution; + iface->get_resolution = pango_cairo_fc_font_map_get_resolution; + iface->get_renderer = pango_cairo_fc_font_map_get_renderer; +} + +G_DEFINE_TYPE_WITH_CODE (PangoCairoFcFontMap, pango_cairo_fc_font_map, PANGO_TYPE_FC_FONT_MAP, + { G_IMPLEMENT_INTERFACE (PANGO_TYPE_CAIRO_FONT_MAP, cairo_font_map_iface_init) }); + +static void +pango_cairo_fc_font_map_finalize (GObject *object) +{ + PangoCairoFcFontMap *cffontmap = PANGO_CAIRO_FC_FONT_MAP (object); + + if (cffontmap->renderer) + g_object_unref (cffontmap->renderer); + + FT_Done_FreeType (cffontmap->library); + + G_OBJECT_CLASS (pango_cairo_fc_font_map_parent_class)->finalize (object); +} + +static void +pango_cairo_fc_font_map_default_substitute (PangoFcFontMap *fcfontmap, + FcPattern *pattern) +{ + PangoCairoFcFontMap *cffontmap = PANGO_CAIRO_FC_FONT_MAP (fcfontmap); + FcValue v; + + FcConfigSubstitute (NULL, pattern, FcMatchPattern); + + if (FcPatternGet (pattern, FC_DPI, 0, &v) == FcResultNoMatch) + FcPatternAddDouble (pattern, FC_DPI, cffontmap->dpi); + FcDefaultSubstitute (pattern); +} + +static PangoFcFont * +pango_cairo_fc_font_map_new_font (PangoFcFontMap *fcfontmap, + FcPattern *pattern) +{ + return _pango_cairo_fc_font_new (PANGO_CAIRO_FC_FONT_MAP (fcfontmap), pattern); +} + +static void +pango_cairo_fc_font_map_class_init (PangoCairoFcFontMapClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + PangoFcFontMapClass *fcfontmap_class = PANGO_FC_FONT_MAP_CLASS (class); + + gobject_class->finalize = pango_cairo_fc_font_map_finalize; + fcfontmap_class->default_substitute = pango_cairo_fc_font_map_default_substitute; + fcfontmap_class->new_font = pango_cairo_fc_font_map_new_font; +} + +static void +pango_cairo_fc_font_map_init (PangoCairoFcFontMap *cffontmap) +{ + FT_Error error; + + cffontmap->library = NULL; + error = FT_Init_FreeType (&cffontmap->library); + if (error != FT_Err_Ok) + g_error ("pango_cairo_font_map_init: Could not initialize freetype"); + + cffontmap->dpi = 96.0; +} + +FT_Library +_pango_cairo_fc_font_map_get_library (PangoCairoFcFontMap *fontmap) +{ + g_return_val_if_fail (PANGO_IS_CAIRO_FC_FONT_MAP (fontmap), NULL); + + return fontmap->library; +} + diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c new file mode 100644 index 00000000..7aae83ec --- /dev/null +++ b/pango/pangocairo-font.c @@ -0,0 +1,69 @@ +/* Pango + * pangocairo-font.c: Cairo font handling + * + * Copyright (C) 2000-2005 Red Hat Software + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "pangocairo.h" +#include "pangocairo-private.h" + +GType +pango_cairo_font_get_type (void) +{ + static GType cairo_font_type = 0; + + if (! cairo_font_type) + { + static const GTypeInfo cairo_font_info = + { + sizeof (PangoCairoFontIface), /* class_size */ + NULL, /* base_init */ + NULL, /* base_finalize */ + NULL, + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, + NULL + }; + + cairo_font_type = + g_type_register_static (G_TYPE_INTERFACE, "PangoCairoFont", + &cairo_font_info, 0); + + g_type_interface_add_prerequisite (cairo_font_type, PANGO_TYPE_FONT); + } + + return cairo_font_type; +} + +/** + * _pango_cairo_font_get_cairo_font: + * @font: a #PangoCairoFont + * @cr: a #CairoConext + * + * Install the font and size of @font onto @cr + **/ +void +_pango_cairo_font_make_current (PangoCairoFont *font, + cairo_t *cr) +{ + g_return_if_fail (PANGO_IS_CAIRO_FONT (font)); + + return (* PANGO_CAIRO_FONT_GET_IFACE (font)->make_current) (font, cr); +} diff --git a/pango/pangocairo-fontmap.c b/pango/pangocairo-fontmap.c new file mode 100644 index 00000000..692b7786 --- /dev/null +++ b/pango/pangocairo-fontmap.c @@ -0,0 +1,285 @@ +/* Pango + * pangocairo-fontmap.c: Cairo font handling + * + * Copyright (C) 2000-2005 Red Hat Software + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include "pangocairo.h" +#include "pangocairo-private.h" + +#ifdef HAVE_CAIRO_FREETYPE +#include "pangocairo-fc.h" +#endif + +GType +pango_cairo_font_map_get_type (void) +{ + static GType cairo_font_map_type = 0; + + if (! cairo_font_map_type) + { + static const GTypeInfo cairo_font_map_info = + { + sizeof (PangoCairoFontMapIface), /* class_size */ + NULL, /* base_init */ + NULL, /* base_finalize */ + NULL, + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, + NULL + }; + + cairo_font_map_type = + g_type_register_static (G_TYPE_INTERFACE, "PangoCairoFontMap", + &cairo_font_map_info, 0); + + g_type_interface_add_prerequisite (cairo_font_map_type, PANGO_TYPE_FONT_MAP); + } + + return cairo_font_map_type; +} + +/** + * pango_cairo_font_map_new: + * + * Creates a new #PangoCairoFontMap object; a fontmap is used + * to cache information about available fonts, and holds + * certain global parameters such as the resolution. + * In most cases, you can use pango_cairo_font_map_get_default() + * instead. + * + * Note that the type of the returned object will depend + * on the particular font backend Cairo was compiled to use; + * You generally should only use the #PangoFontMap and + * #PangoCairoFontMap interfaces on the returned object. + * + * Return value: the newly created fontmap object. Free + * with g_object_unref(). + * + * Since: 1.10 + **/ +PangoFontMap * +pango_cairo_font_map_new (void) +{ + /* Make sure that the type system is initialized */ + g_type_init (); + + return g_object_new (PANGO_TYPE_CAIRO_FC_FONT_MAP, NULL); +} + +/** + * pango_cairo_font_map_get_default: + * + * Gets a default font map to use with Cairo. + * + * Return value: the default Cairo fontmap for Pango. This + * object is owned by Pango and must not be freed. + * + * Since: 1.10 + **/ +PangoFontMap * +pango_cairo_font_map_get_default (void) +{ + static PangoFontMap *default_font_map = NULL; + + if (!default_font_map) + default_font_map = pango_cairo_font_map_new (); + + return default_font_map; +} + +/** + * pango_cairo_font_map_set_resolution: + * @fontmap: a #PangoCairoFontMap + * @dpi: the resolution in "dots per inch". (Physical inches aren't actually + * involved; the terminology is conventional.) + * + * Sets the resolution for the fontmap. This is a scale factor between + * points specified in a #PangoFontDescription and Cairo units. The + * default value is 96, meaning that a 10 point font will be 13 + * units high. (10 * 96. / 72. = 13.3). + * + * Since: 1.10 + **/ +void +pango_cairo_font_map_set_resolution (PangoCairoFontMap *fontmap, + double dpi) +{ + g_return_if_fail (PANGO_IS_CAIRO_FONT_MAP (fontmap)); + + (* PANGO_CAIRO_FONT_MAP_GET_IFACE (fontmap)->set_resolution) (fontmap, dpi); +} + +/** + * pango_cairo_font_map_get_resolution: + * @fontmap: a #PangoCairoFontMap + * + * Gets the resolutions for the fontmap. See pango_cairo_font_map_set_resolution. + * + * Return value: the resolution in "dots per inch" + * + * Since: 1.10 + **/ +double +pango_cairo_font_map_get_resolution (PangoCairoFontMap *fontmap) +{ + g_return_val_if_fail (PANGO_IS_CAIRO_FONT_MAP (fontmap), 96.); + + return (* PANGO_CAIRO_FONT_MAP_GET_IFACE (fontmap)->get_resolution) (fontmap); +} + +/** + * pango_cairo_font_map_create_context: + * @fontmap: a #PangoCairoFontMap + * + * Create a #PangoContext for the given fontmap. + * + * Return value: the newly created context; free with g_object_unref(). + * + * Since: 1.10 + **/ +PangoContext * +pango_cairo_font_map_create_context (PangoCairoFontMap *fontmap) +{ + PangoContext *context; + + g_return_val_if_fail (PANGO_IS_CAIRO_FONT_MAP (fontmap), NULL); + + context = pango_context_new (); + pango_context_set_font_map (context, PANGO_FONT_MAP (fontmap)); + + return context; +} + +/** + * _pango_cairo_font_map_get_renderer: + * @fontmap: a #PangoCairoFontmap + * + * Gets the singleton PangoCairoRenderer for this fontmap. + * + * Return value: the singleton renderer + **/ +PangoRenderer * +_pango_cairo_font_map_get_renderer (PangoCairoFontMap *fontmap) +{ + g_return_val_if_fail (PANGO_IS_CAIRO_FONT_MAP (fontmap), NULL); + + return (* PANGO_CAIRO_FONT_MAP_GET_IFACE (fontmap)->get_renderer) (fontmap); +} + +/** + * pango_cairo_update_context: + * @cr: a Cairo context + * @context: a #PangoContext, from pango_cairo_font_map_create_context() + * + * Updates a #PangoContext previously created for use with Cairo to + * match the current transformation and target surface of a Cairo + * context. If any layouts have been created for the context, + * it's necessary to call pango_layout_context_changed() on those + * layouts. + * + * Since: 1.10 + **/ +void +pango_cairo_update_context (cairo_t *cr, + PangoContext *context) +{ + cairo_matrix_t *cairo_matrix; + PangoMatrix pango_matrix; + + g_return_if_fail (cr != NULL); + g_return_if_fail (PANGO_IS_CONTEXT (context)); + + cairo_matrix = cairo_matrix_create (); + cairo_current_matrix (cr, cairo_matrix); + cairo_matrix_get_affine (cairo_matrix, + &pango_matrix.xx, &pango_matrix.yx, + &pango_matrix.xy, &pango_matrix.yy, + &pango_matrix.x0, &pango_matrix.y0); + + pango_context_set_matrix (context, &pango_matrix); + + cairo_matrix_destroy (cairo_matrix); +} + +/** + * pango_cairo_create_layout: + * @cr: a Cairo context + * + * Creates a layout object set up to match the current transformation + * and target surface of the Cairo context. This layout can then be + * used for text measurement with functions like + * pango_layout_get_size() or drawing with functions like + * pango_cairo_show_layout(). If you change the transformation + * or target surface for @cr, you need to call pango_cairo_update_layout() + * + * This function is the most convenient way to use Cairo with Pango, + * however it is slightly inefficient since it creates a separate + * #PangoContext object for each layout. This might matter in an + * application that was laying out large amounts of text. + * + * Return value: the newly created #PangoLayout. Free with + * g_object_unref(). + * + * Since: 1.10 + **/ +PangoLayout * +pango_cairo_create_layout (cairo_t *cr) +{ + PangoFontMap *fontmap; + PangoContext *context; + PangoLayout *layout; + + g_return_val_if_fail (cr != NULL, NULL); + + fontmap = pango_cairo_font_map_get_default (); + context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap)); + layout = pango_layout_new (context); + + pango_cairo_update_context (cr, context); + g_object_unref (context); + + return layout; +} + +/** + * pango_cairo_update_layout: + * @cr: a Cairo context + * @layout: a #PangoLayout, from pango_cairo_create_layout() + * + * Updates the private #PangoContext of a #PangoLayout created with + * pango_cairo_create_layout() to match the current transformation + * and target surface of a Cairo context. + * + * Since: 1.10 + **/ +void +pango_cairo_update_layout (cairo_t *cr, + PangoLayout *layout) +{ + g_return_if_fail (cr != NULL); + g_return_if_fail (PANGO_IS_LAYOUT (layout)); + + pango_cairo_update_context (cr, pango_layout_get_context (layout)); + pango_layout_context_changed (layout); +} + diff --git a/pango/pangocairo-private.h b/pango/pangocairo-private.h new file mode 100644 index 00000000..64e9a4d9 --- /dev/null +++ b/pango/pangocairo-private.h @@ -0,0 +1,78 @@ +/* Pango + * pangocairo-private.h: private symbols for the Cairo backend + * + * Copyright (C) 2000,2004 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __PANGOCAIRO_PRIVATE_H__ +#define __PANGOCAIRO_PRIVATE_H__ + +#include <pango/pangocairo.h> +#include <pango/pango-renderer.h> + +G_BEGIN_DECLS + +#define PANGO_CAIRO_FONT_MAP_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), PANGO_TYPE_CAIRO_FONT_MAP, PangoCairoFontMapIface)) + +typedef struct _PangoCairoFontMapIface PangoCairoFontMapIface; + +struct _PangoCairoFontMapIface +{ + GTypeInterface g_iface; + + void (*set_resolution) (PangoCairoFontMap *fontmap, + double dpi); + double (*get_resolution) (PangoCairoFontMap *fontmap); + PangoRenderer *(*get_renderer) (PangoCairoFontMap *fontmap); +}; + +PangoRenderer *_pango_cairo_font_map_get_renderer (PangoCairoFontMap *cfontmap); + +#define PANGO_CAIRO_FONT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), PANGO_TYPE_CAIRO_FONT, PangoCairoFontIface)) + +#define PANGO_TYPE_CAIRO_FONT (pango_cairo_font_get_type ()) +#define PANGO_CAIRO_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_FONT, PangoCairoFont)) +#define PANGO_IS_CAIRO_FONT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_CAIRO_FONT)) + +typedef struct _PangoCairoFont PangoCairoFont; +typedef struct _PangoCairoFontIface PangoCairoFontIface; + +struct _PangoCairoFontIface +{ + GTypeInterface g_iface; + + void (*make_current) (PangoCairoFont *font, + cairo_t *cr); +}; + +GType pango_cairo_font_get_type (void); + +void _pango_cairo_font_make_current (PangoCairoFont *font, + cairo_t *cr); + +#define PANGO_TYPE_CAIRO_RENDERER (pango_cairo_renderer_get_type()) +#define PANGO_CAIRO_RENDERER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_RENDERER, PangoCairoRenderer)) +#define PANGO_IS_CAIRO_RENDERER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_CAIRO_RENDERER)) + +typedef struct _PangoCairoRenderer PangoCairoRenderer; + +GType pango_cairo_renderer_get_type (void); + +G_END_DECLS + +#endif /* __PANGOCAIRO_PRIVATE_H__ */ diff --git a/pango/pangocairo-render.c b/pango/pangocairo-render.c new file mode 100644 index 00000000..305a5e08 --- /dev/null +++ b/pango/pangocairo-render.c @@ -0,0 +1,354 @@ +/* Pango + * pangocairo-render.c: Rendering routines to Cairo surfaces + * + * Copyright (C) 2004 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "pangocairo-private.h" + +typedef struct _PangoCairoRendererClass PangoCairoRendererClass; + +#define PANGO_CAIRO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_CAIRO_RENDERER, PangoCairoRendererClass)) +#define PANGO_IS_CAIRO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_CAIRO_RENDERER)) +#define PANGO_CAIRO_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_CAIRO_RENDERER, PangoCairoRendererClass)) + +struct _PangoCairoRenderer +{ + PangoRenderer parent_instance; + + cairo_t *cr; +}; + +struct _PangoCairoRendererClass +{ + PangoRendererClass parent_class; +}; + +G_DEFINE_TYPE (PangoCairoRenderer, pango_cairo_renderer, PANGO_TYPE_RENDERER) + +static void +set_color (PangoCairoRenderer *crenderer, + PangoRenderPart part) +{ + PangoColor *color = pango_renderer_get_color (PANGO_RENDERER (crenderer), part); + + if (color) + cairo_set_rgb_color (crenderer->cr, + color->red / 65535., + color->green / 65535., + color->blue / 65535.); +} + +static void +pango_cairo_renderer_draw_glyphs (PangoRenderer *renderer, + PangoFont *font, + PangoGlyphString *glyphs, + int x, + int y) +{ + PangoCairoRenderer *crenderer = PANGO_CAIRO_RENDERER (renderer); + + /* cairo_glyph_t is 24 bytes */ +#define MAX_STACK 40 + + int i; + int x_position = 0; + cairo_glyph_t *cairo_glyphs; + cairo_glyph_t stack_glyphs[MAX_STACK]; + + cairo_save (crenderer->cr); + + set_color (crenderer, PANGO_RENDER_PART_FOREGROUND); + + if (glyphs->num_glyphs > MAX_STACK) + cairo_glyphs = g_new (cairo_glyph_t, glyphs->num_glyphs); + else + cairo_glyphs = stack_glyphs; + + for (i = 0; i < glyphs->num_glyphs; i++) + { + PangoGlyphInfo *gi = &glyphs->glyphs[i]; + + cairo_glyphs[i].index = gi->glyph; + cairo_glyphs[i].x = (double)(x + x_position + gi->geometry.x_offset) / PANGO_SCALE; + cairo_glyphs[i].y = (double)(y + gi->geometry.y_offset) / PANGO_SCALE; + + x_position += gi->geometry.width; + } + + _pango_cairo_font_make_current (PANGO_CAIRO_FONT (font), crenderer->cr); + cairo_show_glyphs (crenderer->cr, cairo_glyphs, glyphs->num_glyphs); + + if (glyphs->num_glyphs > MAX_STACK) + g_free (cairo_glyphs); + + cairo_restore (crenderer->cr); + +#undef MAX_STACK +} + +static void +pango_cairo_renderer_draw_rectangle (PangoRenderer *renderer, + PangoRenderPart part, + int x, + int y, + int width, + int height) +{ + PangoCairoRenderer *crenderer = PANGO_CAIRO_RENDERER (renderer); + + cairo_save (crenderer->cr); + + set_color (crenderer, part); + + cairo_rectangle (crenderer->cr, + (double)x / PANGO_SCALE, (double)y / PANGO_SCALE, + (double)width / PANGO_SCALE, (double)height / PANGO_SCALE); + cairo_fill (crenderer->cr); + + cairo_restore (crenderer->cr); +} + +/* Draws an error underline that looks like one of: + * H E H + * /\ /\ /\ /\ /\ - + * A/ \ / \ / \ A/ \ / \ | + * \ \ / \ / /D \ \ / \ | + * \ \/ C \/ / \ \/ C \ | height = HEIGHT_SQUARES * square + * \ /\ F / \ F /\ \ | + * \ / \ / \ / \ \G | + * \ / \ / \ / \ / | + * \/ \/ \/ \/ - + * B B + * |----| + * unit_width = (HEIGHT_SQUARES - 1) * square + * + * The x, y, width, height passed in give the desired bounding box; + * x/width are adjusted to make the underline a integer number of units + * wide. + */ +#define HEIGHT_SQUARES 2.5 + +static void +pango_cairo_renderer_draw_error_underline (PangoRenderer *renderer, + int x, + int y, + int width, + int height) +{ + PangoCairoRenderer *crenderer = PANGO_CAIRO_RENDERER (renderer); + cairo_t *cr = crenderer->cr; + + double square = height / HEIGHT_SQUARES; + double unit_width = (HEIGHT_SQUARES - 1) * square; + int width_units = (width + unit_width / 2) / unit_width; + double y_top, y_bottom; + int i; + + cairo_save (cr); + + set_color (crenderer, PANGO_RENDER_PART_UNDERLINE); + + x += (width - width_units * unit_width); + width = width_units * unit_width; + + cairo_new_path (cr); + + y_top = y + height; + y_bottom = y; + + /* Bottom of squiggle */ + cairo_move_to (cr, x - square / 2, y_top - square / 2); /* A */ + for (i = 0; i < width_units; i += 2) + { + double x_middle = x + (i + 1) * unit_width; + double x_right = x + (i + 2) * unit_width; + + cairo_line_to (cr, x_middle, y_bottom); /* B */ + + if (i + 1 == width_units) + /* Nothing */; + else if (i + 2 == width_units) + cairo_line_to (cr, x_right + square / 2, y_top - square / 2); /* D */ + else + cairo_line_to (cr, x_right, y_top - square); /* C */ + } + + /* Top of squiggle */ + for (i -= 2; i >= 0; i -= 2) + { + double x_left = x + i * unit_width; + double x_middle = x + (i + 1) * unit_width; + double x_right = x + (i + 2) * unit_width; + + if (i + 1 == width_units) + cairo_line_to (cr, x_middle + square / 2, y_bottom + square / 2); /* G */ + else + { + if (i + 2 == width_units) + cairo_line_to (cr, x_right, y_top); /* E */ + cairo_line_to (cr, x_middle, y_bottom + square); /* F */ + } + + cairo_line_to (cr, x_left, y_top); /* H */ + } + + cairo_close_path (cr); + cairo_fill (cr); + + cairo_restore (cr); +} + +static void +pango_cairo_renderer_init (PangoCairoRenderer *renderer) +{ +} + +static void +pango_cairo_renderer_class_init (PangoCairoRendererClass *klass) +{ + PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass); + + renderer_class->draw_glyphs = pango_cairo_renderer_draw_glyphs; + renderer_class->draw_rectangle = pango_cairo_renderer_draw_rectangle; + renderer_class->draw_error_underline = pango_cairo_renderer_draw_error_underline; +} + +static void +current_point_to_origin (cairo_t *cr) +{ + double x, y; + + cairo_current_point (cr, &x, &y); + cairo_translate (cr, x, y); +} + +/** + * pango_cairo_show_glyphs: + * @cr: a Cairo context + * @font: a #PangoFont + * @glyphs: a #PangoGlyphString + * + * Draws the glyphs in @glyphs in the specified cairo context. + * The origin of the glyphs (the left edge of the baseline) will + * be drawn at the current point of the cairo context. + * + * Since: 1.10 + **/ +void +pango_cairo_show_glyphs (cairo_t *cr, + PangoFont *font, + PangoGlyphString *glyphs) +{ + PangoFontMap *fontmap; + PangoCairoRenderer *crenderer; + PangoRenderer *renderer; + + g_return_if_fail (cr != NULL); + g_return_if_fail (PANGO_IS_CAIRO_FONT (font)); + g_return_if_fail (glyphs != NULL); + + fontmap = PANGO_FC_FONT (font)->fontmap; + renderer = _pango_cairo_font_map_get_renderer (PANGO_CAIRO_FONT_MAP (fontmap)); + crenderer = PANGO_CAIRO_RENDERER (renderer); + + cairo_save (cr); + current_point_to_origin (cr); + + crenderer->cr = cr; + pango_renderer_draw_glyphs (renderer, font, glyphs, 0, 0); + crenderer->cr = NULL; + + cairo_restore (cr); +} + +/** + * pango_cairo_show_layout_line: + * @cr: a Cairo context + * @line: a #PangoLayoutLine + * + * Draws a #PangoLayoutLine in the specified cairo context. + * The origin of the glyphs (the left edge of the line) will + * be drawn at the current point of the cairo context. + * + * Since: 1.10 + **/ +void +pango_cairo_show_layout_line (cairo_t *cr, + PangoLayoutLine *line) +{ + PangoContext *context; + PangoFontMap *fontmap; + PangoRenderer *renderer; + PangoCairoRenderer *crenderer; + + g_return_if_fail (cr != NULL); + g_return_if_fail (line != NULL); + + context = pango_layout_get_context (line->layout); + fontmap = pango_context_get_font_map (context); + renderer = _pango_cairo_font_map_get_renderer (PANGO_CAIRO_FONT_MAP (fontmap)); + crenderer = PANGO_CAIRO_RENDERER (renderer); + + cairo_save (cr); + current_point_to_origin (cr); + + crenderer->cr = cr; + pango_renderer_draw_layout_line (renderer, line, 0, 0); + crenderer->cr = NULL; + + cairo_restore (cr); +} + +/** + * pango_cairo_show_layout: + * @cr: a Cairo context + * @layout: a Pango layout + * + * Draws a #PangoLayoutLine in the specified cairo context. + * The top-left corner of the #PangoLayout will be drawn + * at the current point of the cairo context. + * + * Since: 1.10 + **/ +void +pango_cairo_show_layout (cairo_t *cr, + PangoLayout *layout) +{ + PangoContext *context; + PangoFontMap *fontmap; + PangoRenderer *renderer; + PangoCairoRenderer *crenderer; + + g_return_if_fail (cr != NULL); + g_return_if_fail (PANGO_IS_LAYOUT (layout)); + + context = pango_layout_get_context (layout); + fontmap = pango_context_get_font_map (context); + renderer = _pango_cairo_font_map_get_renderer (PANGO_CAIRO_FONT_MAP (fontmap)); + crenderer = PANGO_CAIRO_RENDERER (renderer); + + cairo_save (cr); + current_point_to_origin (cr); + + crenderer->cr = cr; + pango_renderer_draw_layout (renderer, layout, 0, 0); + crenderer->cr = NULL; + + cairo_restore (cr); +} diff --git a/pango/pangocairo.h b/pango/pangocairo.h new file mode 100644 index 00000000..f46987a0 --- /dev/null +++ b/pango/pangocairo.h @@ -0,0 +1,84 @@ +/* Pango + * pangocairo.h: + * + * Copyright (C) 1999, 2004 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __PANGOCAIRO_H__ +#define __PANGOCAIRO_H__ + +#include <pango/pango-context.h> +#include <pango/pangofc-fontmap.h> +#include <pango/pango-layout.h> +#include <cairo.h> + +G_BEGIN_DECLS + +/** + * PangoCairoFontMap: + * + * #PangoCairoFontMap is an interface exported by font maps for + * use with Cairo. The actual type of the font map will depend + * on the particular font technology Cairo was compiled to use. + * + * Since: 1.10 + **/ +#define PANGO_TYPE_CAIRO_FONT_MAP (pango_cairo_font_map_get_type ()) +#define PANGO_CAIRO_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_FONT_MAP, PangoCairoFontMap)) +#define PANGO_IS_CAIRO_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_CAIRO_FONT_MAP)) + +typedef struct _PangoCairoFontMap PangoCairoFontMap; + +/* + * PangoCairoFontMap + */ +GType pango_cairo_font_map_get_type (void); + +PangoFontMap *pango_cairo_font_map_new (void); +PangoFontMap *pango_cairo_font_map_get_default (void); + +void pango_cairo_font_map_set_resolution (PangoCairoFontMap *fontmap, + double dpi); +double pango_cairo_font_map_get_resolution (PangoCairoFontMap *fontmap); +PangoContext *pango_cairo_font_map_create_context (PangoCairoFontMap *fontmap); + +/* Update a Pango context for the current state of a cairo context + */ +void pango_cairo_update_context (cairo_t *cr, + PangoContext *context); + +/* Convenience + */ +PangoLayout *pango_cairo_create_layout (cairo_t *cr); +void pango_cairo_update_layout (cairo_t *cr, + PangoLayout *layout); + +/* + * Rendering + */ +void pango_cairo_show_glyphs (cairo_t *cr, + PangoFont *font, + PangoGlyphString *glyphs); +void pango_cairo_show_layout_line (cairo_t *cr, + PangoLayoutLine *line); +void pango_cairo_show_layout (cairo_t *cr, + PangoLayout *layout); + +G_END_DECLS + +#endif /* __PANGOCAIRO_H__ */ diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c index 71c81bc2..65620384 100644 --- a/pango/pangofc-font.c +++ b/pango/pangofc-font.c @@ -26,14 +26,9 @@ #include "pango-modules.h" #include "pango-utils.h" -#include FT_TRUETYPE_TABLES_H +#include <fontconfig/fcfreetype.h> -#define PANGO_SCALE_26_6 (PANGO_SCALE / (1<<6)) -#define PANGO_PIXELS_26_6(d) \ - (((d) >= 0) ? \ - ((d) + PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6 : \ - ((d) - PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6) -#define PANGO_UNITS_26_6(d) (PANGO_SCALE_26_6 * (d)) +#include FT_TRUETYPE_TABLES_H typedef struct _PangoFcMetricsInfo PangoFcMetricsInfo; @@ -57,6 +52,11 @@ struct _PangoFcFontPrivate PangoFcDecoder *decoder; }; +static gboolean pango_fc_font_real_has_char (PangoFcFont *font, + gunichar wc); +static guint pango_fc_font_real_get_glyph (PangoFcFont *font, + gunichar wc); + static void pango_fc_font_finalize (GObject *object); static void pango_fc_font_set_property (GObject *object, guint prop_id, @@ -78,6 +78,9 @@ pango_fc_font_class_init (PangoFcFontClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); PangoFontClass *font_class = PANGO_FONT_CLASS (class); + + class->has_char = pango_fc_font_real_has_char; + class->get_glyph = pango_fc_font_real_get_glyph; object_class->finalize = pango_fc_font_finalize; object_class->set_property = pango_fc_font_set_property; @@ -458,6 +461,37 @@ pango_fc_font_get_metrics (PangoFont *font, return pango_font_metrics_ref (info->metrics); } +static gboolean +pango_fc_font_real_has_char (PangoFcFont *font, + gunichar wc) +{ + FcCharSet *charset; + + if (FcPatternGetCharSet (font->font_pattern, + FC_CHARSET, 0, &charset) != FcResultMatch) + return FALSE; + + return FcCharSetHasChar (charset, wc); +} + +static guint +pango_fc_font_real_get_glyph (PangoFcFont *font, + gunichar wc) +{ + FT_Face face; + FT_UInt index; + + face = pango_fc_font_lock_face (font); + + index = FcFreeTypeCharIndex (face, wc); + if (index && index <= face->num_glyphs) + return index; + + pango_fc_font_unlock_face (font); + + return 0; +} + /** * pango_fc_font_lock_face: * @font: a #PangoFcFont. diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c index 5ac4f285..9dad20b9 100644 --- a/pango/pangofc-fontmap.c +++ b/pango/pangofc-fontmap.c @@ -246,6 +246,7 @@ struct _FontsetHashKey { PangoFontDescription *desc; int x_size; int y_size; + guint flags; }; static gboolean @@ -254,6 +255,7 @@ fontset_hash_key_equal (const FontsetHashKey *key_a, { if (key_a->x_size == key_b->x_size && key_a->y_size == key_b->y_size && + key_a->flags == key_b->flags && pango_font_description_equal (key_a->desc, key_b->desc)) return TRUE; else @@ -263,7 +265,7 @@ fontset_hash_key_equal (const FontsetHashKey *key_a, static guint fontset_hash_key_hash (const FontsetHashKey *key) { - return (key->x_size << 16) ^ (key->y_size) ^ pango_font_description_hash (key->desc); + return (key->x_size << 16) ^ (key->y_size) ^ (key->flags) ^ pango_font_description_hash (key->desc); } static void @@ -280,6 +282,7 @@ fontset_hash_key_copy (FontsetHashKey *old) key->x_size = old->x_size; key->y_size = old->y_size; + key->flags = old->flags; key->desc = pango_font_description_copy (old->desc); return key; @@ -803,14 +806,15 @@ transformed_length (const PangoMatrix *matrix, } static gboolean -pango_fc_font_map_get_rendered_size (PangoFcFontMap *fcfontmap, - PangoContext *context, - const PangoFontDescription *desc, - int *x_size, - int *y_size) -{ - if (PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->get_rendered_size) - return PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->get_rendered_size (fcfontmap, context, desc, x_size, y_size); +pango_fc_font_map_get_render_key (PangoFcFontMap *fcfontmap, + PangoContext *context, + const PangoFontDescription *desc, + int *x_size, + int *y_size, + guint *flags) +{ + if (PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->get_render_key) + return PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->get_render_key (fcfontmap, context, desc, x_size, y_size, flags); else { int size = pango_font_description_get_size (desc); @@ -841,6 +845,8 @@ pango_fc_font_map_get_rendered_size (PangoFcFontMap *fcfontmap, retval = FALSE; } + *flags = 0; + return retval; } } @@ -865,11 +871,11 @@ pango_fc_font_map_get_patterns (PangoFontMap *fontmap, if (!language && context) language = pango_context_get_language (context); - fontset_hash = pango_fc_get_fontset_hash (fcfontmap, language); + fontset_hash = pango_fc_get_fontset_hash (fcfontmap, language); key.desc = pango_font_description_copy_static (desc); pango_font_description_unset_fields (key.desc, PANGO_FONT_MASK_SIZE); - cache = pango_fc_font_map_get_rendered_size (fcfontmap, context, desc, &key.x_size, &key.y_size); + cache = pango_fc_font_map_get_render_key (fcfontmap, context, desc, &key.x_size, &key.y_size, &key.flags); if (cache_out) *cache_out = cache; diff --git a/pango/pangofc-fontmap.h b/pango/pangofc-fontmap.h index 318ad03c..9302a701 100644 --- a/pango/pangofc-fontmap.h +++ b/pango/pangofc-fontmap.h @@ -68,6 +68,11 @@ struct _PangoFcFontMap * pattern of the appropriate type for this font map. The * @pattern argument must be passed to the "pattern" property * of #PangoFcFont when you call g_object_new() + * @get_render_key: Given a context and font description, + * calculate a "key" of X and Y sizes and a flags word + * that can be used to hash the results of loading a font + * with that information. If %NULL, a default implementation + is used. * * Class structure for #PangoFcFontMap. **/ @@ -82,11 +87,12 @@ struct _PangoFcFontMapClass PangoFcFont *(*new_font) (PangoFcFontMap *fontmap, FcPattern *pattern); - gboolean (*get_rendered_size) (PangoFcFontMap *fcfontmap, + gboolean (*get_render_key) (PangoFcFontMap *fcfontmap, PangoContext *context, const PangoFontDescription *desc, int *xsize, - int *ysize); + int *ysize, + guint *flags); /*< private >*/ /* Padding for future expansion */ diff --git a/pango/pangofc-private.h b/pango/pangofc-private.h index 1b42ba16..751a87f6 100644 --- a/pango/pangofc-private.h +++ b/pango/pangofc-private.h @@ -27,6 +27,13 @@ G_BEGIN_DECLS +#define PANGO_SCALE_26_6 (PANGO_SCALE / (1<<6)) +#define PANGO_PIXELS_26_6(d) \ + (((d) >= 0) ? \ + ((d) + PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6 : \ + ((d) - PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6) +#define PANGO_UNITS_26_6(d) (PANGO_SCALE_26_6 * (d)) + void _pango_fc_font_shutdown (PangoFcFont *fcfont); void _pango_fc_font_map_remove (PangoFcFontMap *fcfontmap, diff --git a/pango/pangoft2-private.h b/pango/pangoft2-private.h index c0b8a7e5..ac5c85a8 100644 --- a/pango/pangoft2-private.h +++ b/pango/pangoft2-private.h @@ -26,7 +26,6 @@ #include "pangoft2.h" #include "pango-renderer.h" #include <fontconfig/fontconfig.h> -#include <fontconfig/fcfreetype.h> /* Debugging... */ /*#define DEBUGGING 1*/ @@ -47,13 +46,6 @@ #define PING(printlist) #endif -#define PANGO_SCALE_26_6 (PANGO_SCALE / (1<<6)) -#define PANGO_PIXELS_26_6(d) \ - (((d) >= 0) ? \ - ((d) + PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6 : \ - ((d) - PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6) -#define PANGO_UNITS_26_6(d) (PANGO_SCALE_26_6 * (d)) - typedef struct _PangoFT2Font PangoFT2Font; typedef struct _PangoFT2GlyphInfo PangoFT2GlyphInfo; typedef struct _PangoFT2Renderer PangoFT2Renderer; diff --git a/pango/pangoft2.c b/pango/pangoft2.c index d0c35358..75168307 100644 --- a/pango/pangoft2.c +++ b/pango/pangoft2.c @@ -58,10 +58,6 @@ static void pango_ft2_font_get_glyph_extents (PangoFont * static FT_Face pango_ft2_font_real_lock_face (PangoFcFont *font); static void pango_ft2_font_real_unlock_face (PangoFcFont *font); -static gboolean pango_ft2_font_real_has_char (PangoFcFont *font, - gunichar wc); -static guint pango_ft2_font_real_get_glyph (PangoFcFont *font, - gunichar wc); static PangoGlyph pango_ft2_font_real_get_unknown_glyph (PangoFcFont *font, gunichar wc); @@ -263,8 +259,6 @@ pango_ft2_font_class_init (PangoFT2FontClass *class) fc_font_class->lock_face = pango_ft2_font_real_lock_face; fc_font_class->unlock_face = pango_ft2_font_real_unlock_face; - fc_font_class->has_char = pango_ft2_font_real_has_char; - fc_font_class->get_glyph = pango_ft2_font_real_get_glyph; fc_font_class->get_unknown_glyph = pango_ft2_font_real_get_unknown_glyph; } @@ -366,34 +360,6 @@ pango_ft2_font_real_unlock_face (PangoFcFont *font) { } -static gboolean -pango_ft2_font_real_has_char (PangoFcFont *font, - gunichar wc) -{ - FcCharSet *charset; - - if (FcPatternGetCharSet (font->font_pattern, - FC_CHARSET, 0, &charset) != FcResultMatch) - return FALSE; - - return FcCharSetHasChar (charset, wc); -} - -static guint -pango_ft2_font_real_get_glyph (PangoFcFont *font, - gunichar wc) -{ - FT_Face face; - FT_UInt index; - - face = pango_ft2_font_get_face ((PangoFont *)font); - index = FcFreeTypeCharIndex (face, wc); - if (index && index <= face->num_glyphs) - return index; - - return 0; -} - static PangoGlyph pango_ft2_font_real_get_unknown_glyph (PangoFcFont *font, gunichar wc) |