From a03ec45dffe96fcaa84521d9d3f3649b2b288e4e Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 28 May 2008 14:14:56 +0000 Subject: [PATCH] 2008-05-28 Emmanuele Bassi * clutter/pango/pangoclutter-font.c: Remove unneeded file. * tests/Makefile.am: * tests/test-random-text.c: Add a test for checking the glyph cache. --- ChangeLog | 8 + clutter/pango/pangoclutter-font.c | 474 ------------------------------ tests/Makefile.am | 74 ++--- tests/test-random-text.c | 85 ++++++ 4 files changed, 131 insertions(+), 510 deletions(-) delete mode 100644 clutter/pango/pangoclutter-font.c create mode 100644 tests/test-random-text.c diff --git a/ChangeLog b/ChangeLog index 930d35032..a50af24a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-05-28 Emmanuele Bassi + + * clutter/pango/pangoclutter-font.c: Remove unneeded file. + + * tests/Makefile.am: + * tests/test-random-text.c: Add a test for checking the + glyph cache. + 2008-05-28 Emmanuele Bassi Bug #919 - Replacement pango renderer (Neil Roberts) diff --git a/clutter/pango/pangoclutter-font.c b/clutter/pango/pangoclutter-font.c deleted file mode 100644 index c57cc100a..000000000 --- a/clutter/pango/pangoclutter-font.c +++ /dev/null @@ -1,474 +0,0 @@ -/* Pango - * Clutter Freetype2 handling - * - * Copyright (C) 1999 Red Hat Software - * Copyright (C) 2000 Tor Lillqvist - * Copyright (C) 2006 Marc Lehmann - * - * This file 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 file 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. - */ - -#define PANGO_ENABLE_BACKEND - -#include -#include -#include -#include -#include - -#include "pangoclutter.h" -#include "pangoclutter-private.h" -#include -#include - -#define PANGO_CLUTTER_FONT_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - PANGO_TYPE_CLUTTER_FONT, \ - PangoClutterFontClass)) - -#define PANGO_CLUTTER_IS_FONT_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_CLUTTER_FONT)) - -#define PANGO_CLUTTER_FONT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - PANGO_TYPE_CLUTTER_FONT, \ - PangoClutterFontClass)) - -typedef struct _PangoClutterFontClass PangoClutterFontClass; - -struct _PangoClutterFontClass -{ - PangoFcFontClass parent_class; -}; - -static void pango_clutter_font_finalize (GObject *object); - -static void pango_clutter_font_get_glyph_extents (PangoFont *font, - PangoGlyph glyph, - PangoRectangle *ink_rect, - PangoRectangle *logical_rect); - -static FT_Face pango_clutter_font_real_lock_face (PangoFcFont *font); -static void pango_clutter_font_real_unlock_face (PangoFcFont *font); - -PangoClutterFont * -_pango_clutter_font_new (PangoClutterFontMap *fontmap_, FcPattern *pattern) -{ - PangoFontMap *fontmap = PANGO_FONT_MAP (fontmap_); - PangoClutterFont *font; - double d; - - g_return_val_if_fail (fontmap != NULL, NULL); - g_return_val_if_fail (pattern != NULL, NULL); - - font = (PangoClutterFont *)g_object_new (PANGO_TYPE_CLUTTER_FONT, - "pattern", pattern, - NULL); - - if (FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &d) == FcResultMatch) - { - /* Cannot use 16.16 fixed here, because multiplying by PANGO_SCALE - * could easily take us out of range, but we do not need the 16 bit - * precission for the fraction, so we use 20.12 fixed point here - */ - int f = CLUTTER_FLOAT_TO_FIXED (d) >> 4; - font->size = (f * PANGO_SCALE) >> 12; - } - - return font; -} - -static void -load_fallback_face (PangoClutterFont *font, const char *original_file) -{ - PangoFcFont *fcfont = PANGO_FC_FONT (font); - FcPattern *sans; - FcPattern *matched; - FcResult result; - FT_Error error; - FcChar8 *filename2 = NULL; - gchar *name; - int id; - - sans = FcPatternBuild - (NULL, - FC_FAMILY, FcTypeString, "sans", - FC_PIXEL_SIZE, FcTypeDouble, (double)font->size / PANGO_SCALE, - NULL); - - matched = FcFontMatch (NULL, sans, &result); - - if (FcPatternGetString (matched, FC_FILE, 0, &filename2) != FcResultMatch) - goto bail1; - - if (FcPatternGetInteger (matched, FC_INDEX, 0, &id) != FcResultMatch) - goto bail1; - - error = FT_New_Face (_pango_clutter_font_map_get_library (fcfont->fontmap), - (char *) filename2, id, &font->face); - - if (error) - { - bail1: - name = pango_font_description_to_string (fcfont->description); - g_warning ("Unable to open font file %s for font %s, exiting\n", - filename2, name); - exit (1); - } - else - { - name = pango_font_description_to_string (fcfont->description); - g_warning ("Unable to open font file %s for font %s, falling back to %s\n", original_file, name, filename2); - g_free (name); - } - - FcPatternDestroy (sans); - FcPatternDestroy (matched); -} - -static void -set_transform (PangoClutterFont *font) -{ - PangoFcFont *fcfont = (PangoFcFont *)font; - FcMatrix *fc_matrix; - - if (FcPatternGetMatrix (fcfont->font_pattern, - FC_MATRIX, - 0, - &fc_matrix) == FcResultMatch) - { - FT_Matrix ft_matrix; - - ft_matrix.xx = 0x10000L * fc_matrix->xx; - ft_matrix.yy = 0x10000L * fc_matrix->yy; - ft_matrix.xy = 0x10000L * fc_matrix->xy; - ft_matrix.yx = 0x10000L * fc_matrix->yx; - - FT_Set_Transform (font->face, &ft_matrix, NULL); - } -} - -FT_Face -pango_clutter_font_get_face (PangoFont *font) -{ - PangoClutterFont *glfont = (PangoClutterFont *)font; - PangoFcFont *fcfont = (PangoFcFont *)font; - FcPattern *pattern; - FcChar8 *filename; - FcBool antialias, hinting, autohint; - FT_Error error; - int id; - - pattern = fcfont->font_pattern; - - if (!glfont->face) - { - glfont->load_flags = 0; - - /* disable antialiasing if requested */ - if (FcPatternGetBool (pattern, FC_ANTIALIAS, - 0, &antialias) != FcResultMatch) - antialias = FcTrue; - - glfont->load_flags |= FT_LOAD_NO_BITMAP; - - /* disable hinting if requested */ - if (FcPatternGetBool (pattern, FC_HINTING, - 0, &hinting) != FcResultMatch) - hinting = FcTrue; - - if (!hinting) - glfont->load_flags |= FT_LOAD_NO_HINTING; - - /* force autohinting if requested */ - if (FcPatternGetBool (pattern, FC_AUTOHINT, - 0, &autohint) != FcResultMatch) - autohint = FcFalse; - - if (autohint) - glfont->load_flags |= FT_LOAD_FORCE_AUTOHINT; - - if (FcPatternGetString (pattern, FC_FILE, 0, &filename) != FcResultMatch) - goto bail0; - - if (FcPatternGetInteger (pattern, FC_INDEX, 0, &id) != FcResultMatch) - goto bail0; - - error - = FT_New_Face (_pango_clutter_font_map_get_library (fcfont->fontmap), - (char *)filename, id, &glfont->face); - - if (error != FT_Err_Ok) - { - bail0: - load_fallback_face (glfont, (char *)filename); - } - - g_assert (glfont->face); - - set_transform (glfont); - - error = FT_Set_Char_Size (glfont->face, - PANGO_PIXELS_26_6 (glfont->size), - PANGO_PIXELS_26_6 (glfont->size), - 0, 0); - if (error) - g_warning ("Error in FT_Set_Char_Size: %d", error); - } - - return glfont->face; -} - -G_DEFINE_TYPE (PangoClutterFont, pango_clutter_font, PANGO_TYPE_FC_FONT) - -static void -pango_clutter_font_init (PangoClutterFont *font) -{ - font->face = NULL; - font->size = 0; - font->glyph_info = g_hash_table_new (NULL, NULL); -} - -static void -pango_clutter_font_class_init (PangoClutterFontClass *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_clutter_font_finalize; - - font_class->get_glyph_extents = pango_clutter_font_get_glyph_extents; - - fc_font_class->lock_face = pango_clutter_font_real_lock_face; - fc_font_class->unlock_face = pango_clutter_font_real_unlock_face; -} - -static PangoClutterGlyphInfo * -pango_clutter_font_get_glyph_info (PangoFont *font_, - PangoGlyph glyph, - gboolean create) -{ - PangoClutterFont *font = (PangoClutterFont *)font_; - PangoFcFont *fcfont = (PangoFcFont *)font; - PangoClutterGlyphInfo *info; - - info = g_hash_table_lookup (font->glyph_info, GUINT_TO_POINTER (glyph)); - - if ((info == NULL) && create) - { - info = g_slice_new0 (PangoClutterGlyphInfo); - - pango_fc_font_get_raw_extents (fcfont, font->load_flags, - glyph, - &info->ink_rect, - &info->logical_rect); - - g_hash_table_insert (font->glyph_info, GUINT_TO_POINTER(glyph), info); - } - - return info; -} - -PangoGlyph -pango_clutter_get_unknown_glyph (PangoFont *font) -{ - FT_Face face = pango_clutter_font_get_face (font); - - if (face && FT_IS_SFNT (face)) - /* TrueType fonts have an 'unknown glyph' box on glyph index 0 */ - return 0; - else - return PANGO_GLYPH_EMPTY; -} - -static void -pango_clutter_font_get_glyph_extents (PangoFont *font, - PangoGlyph glyph, - PangoRectangle *ink_rect, - PangoRectangle *logical_rect) -{ - PangoClutterGlyphInfo *info; - - if (glyph == PANGO_GLYPH_EMPTY) - { - if (ink_rect) - ink_rect->x = ink_rect->y = - ink_rect->height = ink_rect->width = 0; - if (logical_rect) - logical_rect->x = logical_rect->y = - logical_rect->height = logical_rect->width = 0; - return; - } - - if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) - { - glyph = pango_clutter_get_unknown_glyph (font); - if (glyph == PANGO_GLYPH_EMPTY) - { - /* No unknown glyph found for the font, draw a box */ - PangoFontMetrics *metrics = pango_font_get_metrics (font, NULL); - - if (metrics) - { - if (ink_rect) - { - ink_rect->x = PANGO_SCALE; - ink_rect->width = metrics->approximate_char_width - 2 * PANGO_SCALE; - ink_rect->y = - (metrics->ascent - PANGO_SCALE); - ink_rect->height = metrics->ascent + metrics->descent - 2 * PANGO_SCALE; - } - if (logical_rect) - { - logical_rect->x = 0; - logical_rect->width = metrics->approximate_char_width; - logical_rect->y = -metrics->ascent; - logical_rect->height = metrics->ascent + metrics->descent; - } - - pango_font_metrics_unref (metrics); - } - else - { - if (ink_rect) - ink_rect->x = ink_rect->y = - ink_rect->height = ink_rect->width = 0; - if (logical_rect) - logical_rect->x = logical_rect->y = - logical_rect->height = logical_rect->width = 0; - } - return; - } - } - - info = pango_clutter_font_get_glyph_info (font, glyph, TRUE); - - if (ink_rect) - *ink_rect = info->ink_rect; - if (logical_rect) - *logical_rect = info->logical_rect; -} - -int -pango_clutter_font_get_kerning (PangoFont *font, - PangoGlyph left, - PangoGlyph right) -{ - PangoFcFont *fc_font = PANGO_FC_FONT (font); - - FT_Face face; - FT_Error error; - FT_Vector kerning; - - face = pango_fc_font_lock_face (fc_font); - if (!face) - return 0; - - if (!FT_HAS_KERNING (face)) - { - pango_fc_font_unlock_face (fc_font); - return 0; - } - - error = FT_Get_Kerning (face, left, right, ft_kerning_default, &kerning); - if (error != FT_Err_Ok) - { - pango_fc_font_unlock_face (fc_font); - return 0; - } - - pango_fc_font_unlock_face (fc_font); - return PANGO_UNITS_26_6 (kerning.x); -} - -static FT_Face -pango_clutter_font_real_lock_face (PangoFcFont *font) -{ - return pango_clutter_font_get_face ((PangoFont *)font); -} - -static void -pango_clutter_font_real_unlock_face (PangoFcFont *font) -{ -} - -static gboolean -pango_clutter_free_glyph_info_callback (gpointer key, - gpointer value, - gpointer data) -{ - PangoClutterFont *font = PANGO_CLUTTER_FONT (data); - PangoClutterGlyphInfo *info = value; - - if (font->glyph_cache_destroy && info->cached_glyph) - (*font->glyph_cache_destroy) (info->cached_glyph); - - g_slice_free (PangoClutterGlyphInfo, info); - return TRUE; -} - -static void -pango_clutter_font_finalize (GObject *object) -{ - PangoClutterFont *font = (PangoClutterFont *)object; - - if (font->face) - { - FT_Done_Face (font->face); - font->face = NULL; - } - - g_hash_table_foreach_remove (font->glyph_info, - pango_clutter_free_glyph_info_callback, object); - g_hash_table_destroy (font->glyph_info); - - G_OBJECT_CLASS (pango_clutter_font_parent_class)->finalize (object); -} - -PangoCoverage* -pango_clutter_font_get_coverage (PangoFont *font, PangoLanguage *language) -{ - return pango_font_get_coverage (font, language); -} - -void* -_pango_clutter_font_get_cache_glyph_data (PangoFont *font, int glyph_index) -{ - PangoClutterGlyphInfo *info; - - info = pango_clutter_font_get_glyph_info (font, glyph_index, FALSE); - - return info ? info->cached_glyph : 0; -} - -void -_pango_clutter_font_set_cache_glyph_data (PangoFont *font, - int glyph_index, - void *cached_glyph) -{ - PangoClutterGlyphInfo *info; - - info = pango_clutter_font_get_glyph_info (font, glyph_index, TRUE); - - info->cached_glyph = cached_glyph; -} - -void -_pango_clutter_font_set_glyph_cache_destroy (PangoFont *font, - GDestroyNotify destroy_notify) -{ - PANGO_CLUTTER_FONT (font)->glyph_cache_destroy = destroy_notify; -} diff --git a/tests/Makefile.am b/tests/Makefile.am index 74986bb94..8d2c8b672 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -11,7 +11,8 @@ noinst_PROGRAMS = test-textures test-events test-offscreen test-scale \ test-cogl-primitives test-cogl-tex-tile \ test-cogl-tex-convert test-cogl-tex-foreign \ test-cogl-tex-getset test-cogl-offscreen \ - test-cogl-tex-polygon test-stage-read-pixels + test-cogl-tex-polygon test-stage-read-pixels \ + test-random-text if X11_TESTS noinst_PROGRAMS += test-pixmap @@ -22,44 +23,45 @@ LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_FLAVOUR@-@CLUTTER_MAJORMINOR AM_CFLAGS = $(CLUTTER_CFLAGS) AM_LDFLAGS = $(CLUTTER_LIBS) -test_textures_SOURCES = test-textures.c -test_events_SOURCES = test-events.c -test_offscreen_SOURCES = test-offscreen.c -test_scale_SOURCES = test-scale.c -test_actors_SOURCES = test-actors.c -test_grab_SOURCES = test-grab.c -test_behave_SOURCES = test-behave.c -test_text_SOURCES = test-text.c -test_entry_SOURCES = test-entry.c -test_project_SOURCES = test-project.c -test_unproject_SOURCES = test-unproject.c -test_perspective_SOURCES = test-perspective.c -test_rotate_SOURCES = test-rotate.c -test_depth_SOURCES = test-depth.c -test_threads_SOURCES = test-threads.c -test_timeline_SOURCES = test-timeline.c +test_textures_SOURCES = test-textures.c +test_events_SOURCES = test-events.c +test_offscreen_SOURCES = test-offscreen.c +test_scale_SOURCES = test-scale.c +test_actors_SOURCES = test-actors.c +test_grab_SOURCES = test-grab.c +test_behave_SOURCES = test-behave.c +test_text_SOURCES = test-text.c +test_entry_SOURCES = test-entry.c +test_project_SOURCES = test-project.c +test_unproject_SOURCES = test-unproject.c +test_perspective_SOURCES = test-perspective.c +test_rotate_SOURCES = test-rotate.c +test_depth_SOURCES = test-depth.c +test_threads_SOURCES = test-threads.c +test_timeline_SOURCES = test-timeline.c test_timeline_dup_frames_SOURCES = test-timeline-dup-frames.c test_timeline_interpolate_SOURCES = test-timeline-interpolate.c test_timeline_rewind_SOURCES = test-timeline-rewind.c test_timeline_smoothness_SOURCES = test-timeline-smoothness.c -test_shader_SOURCES = test-shader.c -test_score_SOURCES = test-score.c -test_script_SOURCES = test-script.c -test_model_SOURCES = test-model.c -test_effects_SOURCES = test-effects.c -test_fullscreen_SOURCES = test-fullscreen.c -test_viewport_SOURCES = test-viewport.c -test_fbo_SOURCES = test-fbo.c -test_opacity_SOURCES = test-opacity.c -test_multistage_SOURCES = test-multistage.c -test_pixmap_SOURCES = test-pixmap.c -test_pixmap_LDFLAGS = -lXcomposite -test_cogl_primitives_SOURCES = test-cogl-primitives.c -test_cogl_tex_tile_SOURCES = test-cogl-tex-tile.c -test_cogl_tex_convert_SOURCES = test-cogl-tex-convert.c -test_cogl_tex_foreign_SOURCES = test-cogl-tex-foreign.c -test_cogl_tex_getset_SOURCES = test-cogl-tex-getset.c -test_cogl_offscreen_SOURCES = test-cogl-offscreen.c -test_stage_read_pixels_SOURCES = test-stage-read-pixels.c +test_shader_SOURCES = test-shader.c +test_score_SOURCES = test-score.c +test_script_SOURCES = test-script.c +test_model_SOURCES = test-model.c +test_effects_SOURCES = test-effects.c +test_fullscreen_SOURCES = test-fullscreen.c +test_viewport_SOURCES = test-viewport.c +test_fbo_SOURCES = test-fbo.c +test_opacity_SOURCES = test-opacity.c +test_multistage_SOURCES = test-multistage.c +test_pixmap_SOURCES = test-pixmap.c +test_pixmap_LDFLAGS = -lXcomposite +test_cogl_primitives_SOURCES = test-cogl-primitives.c +test_cogl_tex_tile_SOURCES = test-cogl-tex-tile.c +test_cogl_tex_convert_SOURCES = test-cogl-tex-convert.c +test_cogl_tex_foreign_SOURCES = test-cogl-tex-foreign.c +test_cogl_tex_getset_SOURCES = test-cogl-tex-getset.c +test_cogl_offscreen_SOURCES = test-cogl-offscreen.c +test_stage_read_pixels_SOURCES = test-stage-read-pixels.c +test_random_text_SOURCES = test-random-text.c EXTRA_DIST = redhand.png test-script.json diff --git a/tests/test-random-text.c b/tests/test-random-text.c new file mode 100644 index 000000000..27c8d8454 --- /dev/null +++ b/tests/test-random-text.c @@ -0,0 +1,85 @@ +#include +#include + +#define MAX_TEXT_LEN 10 +#define MIN_FONT_SIZE 10 +#define MAX_FONT_SIZE 30 + +static const char * const font_names[] = + { + "Sans", "Sans Italic", "Serif", "Serif Bold", "Times", "Monospace" + }; +#define FONT_NAME_COUNT 6 + +static gboolean +on_idle (gpointer data) +{ + ClutterActor *stage = CLUTTER_ACTOR (data); + int line_height = 0, xpos = 0, ypos = 0; + int stage_width = clutter_actor_get_width (stage); + int stage_height = clutter_actor_get_height (stage); + char text[MAX_TEXT_LEN + 1]; + char font_name[64]; + int i; + GList *children, *node; + + /* Remove all of the children of the stage */ + children = clutter_container_get_children (CLUTTER_CONTAINER (stage)); + for (node = children; node; node = node->next) + clutter_container_remove_actor (CLUTTER_CONTAINER (stage), + CLUTTER_ACTOR (node->data)); + g_list_free (children); + + /* Fill the stage with new random labels */ + while (ypos < stage_height) + { + int text_len = rand () % MAX_TEXT_LEN + 1; + ClutterActor *label; + + for (i = 0; i < text_len; i++) + text[i] = rand () % (128 - 32) + 32; + text[text_len] = '\0'; + + sprintf (font_name, "%s %i", + font_names[rand () % FONT_NAME_COUNT], + rand () % (MAX_FONT_SIZE - MIN_FONT_SIZE) + MIN_FONT_SIZE); + + label = clutter_label_new_with_text (font_name, text); + + if (clutter_actor_get_height (label) > line_height) + line_height = clutter_actor_get_height (label); + + if (xpos + clutter_actor_get_width (label) > stage_width) + { + xpos = 0; + ypos += line_height; + line_height = 0; + } + + clutter_actor_set_position (label, xpos, ypos); + + clutter_container_add (CLUTTER_CONTAINER (stage), label, NULL); + + xpos += clutter_actor_get_width (label); + } + + return TRUE; +} + +int +main (int argc, char **argv) +{ + ClutterActor *stage; + + clutter_init (&argc, &argv); + + stage = clutter_stage_get_default (); + + clutter_actor_show (stage); + + clutter_threads_add_idle (on_idle, stage); + + clutter_main (); + + return 0; +}