Support per-item gravity.
authorBehdad Esfahbod <behdad@gnome.org>
Mon, 21 Aug 2006 03:05:46 +0000 (03:05 +0000)
committerBehdad Esfahbod <behdad@src.gnome.org>
Mon, 21 Aug 2006 03:05:46 +0000 (03:05 +0000)
2006-08-20  Behdad Esfahbod  <behdad@gnome.org>

        Support per-item gravity.

        * pango/pango-context.c (update_attr_iterator),
        (itemize_state_init), (itemize_state_update_for_new_run),
        (itemize_state_process_run): Make per-item gravity work, by setting
        gravity into font description before loading fonts.  Also, allow
        the context font description to override the gravity (but not
        centered_baseline.)

        * pango/pangocairo-fcfont.c (_pango_cairo_fc_font_new): Get gravity
        from font description, not context.

        * pango/pangofc-fontmap.c (fontset_hash_key_equal),
        (fontset_hash_key_hash), (fontset_hash_key_copy),
        (pango_fc_make_pattern), (pango_fc_font_map_get_patterns),
        (pango_fc_font_map_load_fontset),
        (pango_fc_font_description_from_pattern): Get gravity from font
        description, not context.  Moreover, put it into pattern, and
        reconstruct it out of font patterns.

        * pango/pangofc-private.h: Define PANGO_FC_GRAVITY, which is the key
        we put PangoGravity into an FcPattern under.

ChangeLog
pango/pango-context.c
pango/pangocairo-fcfont.c
pango/pangofc-fontmap.c
pango/pangofc-private.h

index 5087eae..534e70c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,30 @@
 2006-08-20  Behdad Esfahbod  <behdad@gnome.org>
 
+       Support per-item gravity.
+
+       * pango/pango-context.c (update_attr_iterator),
+       (itemize_state_init), (itemize_state_update_for_new_run),
+       (itemize_state_process_run): Make per-item gravity work, by setting
+       gravity into font description before loading fonts.  Also, allow
+       the context font description to override the gravity (but not
+       centered_baseline.)
+
+       * pango/pangocairo-fcfont.c (_pango_cairo_fc_font_new): Get gravity
+       from font description, not context.
+
+       * pango/pangofc-fontmap.c (fontset_hash_key_equal),
+       (fontset_hash_key_hash), (fontset_hash_key_copy),
+       (pango_fc_make_pattern), (pango_fc_font_map_get_patterns),
+       (pango_fc_font_map_load_fontset),
+       (pango_fc_font_description_from_pattern): Get gravity from font
+       description, not context.  Moreover, put it into pattern, and
+       reconstruct it out of font patterns.
+
+       * pango/pangofc-private.h: Define PANGO_FC_GRAVITY, which is the key
+       we put PangoGravity into an FcPattern under.
+
+2006-08-20  Behdad Esfahbod  <behdad@gnome.org>
+
        * docs/pango-sections.txt:
        * docs/tmpl/fonts.sgml:
        * pango/fonts.c (pango_font_description_set_gravity),
index b3dec72..6044daf 100644 (file)
@@ -615,7 +615,9 @@ struct _ItemizeState
   int embedding_end_offset;
   const char *embedding_end;
   guint8 embedding;
+
   PangoGravity gravity;
+  PangoGravity font_desc_gravity;
   gboolean centered_baseline;
 
   PangoAttrIterator *attr_iter;
@@ -690,6 +692,11 @@ update_attr_iterator (ItemizeState *state)
   state->font_desc = pango_font_description_copy_static (state->context->font_desc);
   pango_attr_iterator_get_font (state->attr_iter, state->font_desc,
                                &state->lang, &state->extra_attrs);
+  if (pango_font_description_get_set_fields (state->font_desc) & PANGO_FONT_MASK_GRAVITY)
+    state->font_desc_gravity = pango_font_description_get_gravity (state->font_desc);
+  else
+    state->font_desc_gravity = PANGO_GRAVITY_AUTO;
+
   state->copy_extra_attrs = FALSE;
 
   if (!state->lang)
@@ -743,14 +750,6 @@ itemize_state_init (ItemizeState      *state,
   state->embedding_end = text + start_index;
   update_embedding_end (state);
 
-  /* FIXME: Set gravity to base gravity for now, until we do
-   * proper gravity assignment.
-   */
-  state->gravity = context->resolved_gravity;
-
-  state->centered_baseline = context->resolved_gravity == PANGO_GRAVITY_EAST
-                         || context->resolved_gravity == PANGO_GRAVITY_WEST;
-
   /* Initialize the attribute iterator
    */
   if (cached_iter)
@@ -796,6 +795,15 @@ itemize_state_init (ItemizeState      *state,
 
   update_end (state);
 
+  state->centered_baseline = state->context->resolved_gravity == PANGO_GRAVITY_EAST
+                         || state->context->resolved_gravity == PANGO_GRAVITY_WEST;
+
+  if (pango_font_description_get_set_fields (state->font_desc) & PANGO_FONT_MASK_GRAVITY)
+    state->font_desc_gravity = pango_font_description_get_gravity (state->font_desc);
+  else
+    state->font_desc_gravity = PANGO_GRAVITY_AUTO;
+
+  state->gravity = PANGO_GRAVITY_AUTO;
   state->derived_lang = NULL;
   state->lang_engine = NULL;
   state->current_fonts = NULL;
@@ -1158,6 +1166,30 @@ get_lang_map (PangoLanguage *lang)
 static void
 itemize_state_update_for_new_run (ItemizeState *state)
 {
+  if (state->changed & (FONT_CHANGED | SCRIPT_CHANGED))
+    {
+      PangoGravity old_gravity = state->gravity;
+
+      if (state->font_desc_gravity != PANGO_GRAVITY_AUTO)
+       state->gravity = state->font_desc_gravity;
+      else
+        {
+         PangoGravity gravity = state->context->resolved_gravity;
+
+         /* FIXME
+          * gravity = pango_script_get_resolved_gravity (script, gravity, hint);
+          */
+
+         state->gravity = gravity;
+       }
+
+      if (old_gravity != state->gravity)
+        {
+         pango_font_description_set_gravity (state->font_desc, state->gravity);
+          state->changed |= FONT_CHANGED;
+       }
+    }
+
   if (state->changed & (SCRIPT_CHANGED | LANG_CHANGED))
     {
       PangoLanguage *old_derived_lang = state->derived_lang;
@@ -1242,9 +1274,6 @@ itemize_state_process_run (ItemizeState *state)
        }
       else
         {
-         /* FIXME: We need a way to respect item gravity when loading
-          * fonts, but we currently don't have a way to do that.
-          */
          get_shaper_and_font (state, wc, &shape_engine, &font);
        }
        
index f6ce108..cb5d959 100644 (file)
@@ -507,8 +507,7 @@ _pango_cairo_fc_font_new (PangoCairoFcFontMap        *cffontmap,
                         "pattern", pattern,
                         NULL);
 
-  /* FIXME: support per-item gravity */
-  cffont->gravity = pango_context_get_gravity (context);
+  cffont->gravity = pango_font_description_get_gravity (desc);
 
   if  (FcPatternGetMatrix (pattern,
                           FC_MATRIX, 0, &fc_matrix) == FcResultMatch)
index 756774a..2c11b10 100644 (file)
@@ -30,6 +30,7 @@
 #include "pangofc-private.h"
 #include "pango-impl-utils.h"
 #include "modules.h"
+#include "pango-enum-types.h"
 
 typedef struct _PangoFcCoverageKey  PangoFcCoverageKey;
 typedef struct _PangoFcFace         PangoFcFace;
@@ -211,6 +212,17 @@ pango_fc_font_map_class_init (PangoFcFontMapClass *class)
   g_type_class_add_private (object_class, sizeof (PangoFcFontMapPrivate));
 }
 
+static gpointer
+get_gravity_class (void)
+{
+  static GEnumClass *class = NULL;
+
+  if (G_UNLIKELY (!class))
+    class = g_type_class_ref (PANGO_TYPE_GRAVITY);
+
+  return class;
+}
+
 static guint
 pango_fc_pattern_hash (FcPattern *pattern)
 {
@@ -265,7 +277,6 @@ struct _FontsetHashKey {
   PangoFcFontMap *fontmap;
   PangoMatrix matrix;
   PangoLanguage *language;
-  PangoGravity gravity;
   PangoFontDescription *desc;
   int size;                    /* scaled via the current DPI */
   gpointer context_key;
@@ -308,7 +319,6 @@ fontset_hash_key_equal (const FontsetHashKey *key_a,
   if (key_a->size == key_b->size &&
       pango_font_description_equal (key_a->desc, key_b->desc) &&
       key_a->language == key_b->language &&
-      key_a->gravity == key_b->gravity &&
       key_a->matrix.xx == key_b->matrix.xx &&
       key_a->matrix.xy == key_b->matrix.xy &&
       key_a->matrix.yx == key_b->matrix.yx &&
@@ -341,7 +351,6 @@ fontset_hash_key_hash (const FontsetHashKey *key)
 
     /* 1237 is just an abitrary prime */
     return (hash ^
-           key->gravity ^
            GPOINTER_TO_UINT (key->language) ^
            (key->size * 1237) ^
            pango_font_description_hash (key->desc));
@@ -367,7 +376,6 @@ fontset_hash_key_copy (FontsetHashKey *old)
   key->fontmap = old->fontmap;
   key->matrix = old->matrix;
   key->language = old->language;
-  key->gravity = old->gravity;
   key->desc = pango_font_description_copy (old->desc);
   key->size = old->size;
   if (old->context_key)
@@ -792,13 +800,13 @@ pango_fc_convert_width_to_fc (PangoStretch pango_stretch)
 static FcPattern *
 pango_fc_make_pattern (const  PangoFontDescription *description,
                       PangoLanguage               *language,
-                      PangoGravity                 gravity,
                       double                       pixel_size,
                       double                       dpi)
 {
   FcPattern *pattern;
   int slant;
   int weight;
+  PangoGravity gravity;
   FcBool vertical;
   char **families;
   int i;
@@ -812,7 +820,7 @@ pango_fc_make_pattern (const  PangoFontDescription *description,
   width = pango_fc_convert_width_to_fc (pango_font_description_get_stretch (description));
 #endif
 
-  /* FIXME: get gravity from description */
+  gravity = pango_font_description_get_gravity (description);
   switch (gravity)
     {
       case PANGO_GRAVITY_SOUTH:
@@ -856,6 +864,12 @@ pango_fc_make_pattern (const  PangoFontDescription *description,
 
   if (language)
     FcPatternAddString (pattern, FC_LANG, (FcChar8 *) pango_language_to_string (language));
+
+  if (gravity != PANGO_GRAVITY_SOUTH)
+    {
+      GEnumValue *value = g_enum_get_value (get_gravity_class (), gravity);
+      FcPatternAddString (pattern, PANGO_FC_GRAVITY, value->value_nick);
+    }
   
   return pattern;
 }
@@ -1037,8 +1051,7 @@ static PangoFcPatternSet *
 pango_fc_font_map_get_patterns (PangoFontMap               *fontmap,
                                PangoContext               *context,
                                const PangoFontDescription *desc,
-                               PangoLanguage              *language,
-                               PangoGravity                gravity)
+                               PangoLanguage              *language)
 {
   PangoFcFontMap *fcfontmap = (PangoFcFontMap *)fontmap;
   PangoFcFontMapPrivate *priv = fcfontmap->priv;
@@ -1055,7 +1068,6 @@ pango_fc_font_map_get_patterns (PangoFontMap               *fontmap,
   key.fontmap = fcfontmap;
   get_context_matrix (context, &key.matrix);
   key.language = language;
-  key.gravity = gravity;
   key.desc = pango_font_description_copy_static (desc);
   pango_font_description_unset_fields (key.desc, PANGO_FONT_MASK_SIZE);
   key.size = get_unscaled_size (fcfontmap, context, desc);
@@ -1071,7 +1083,7 @@ pango_fc_font_map_get_patterns (PangoFontMap               *fontmap,
     {
       double scale_factor = pango_matrix_get_font_scale_factor (&key.matrix);
       double scaled_size = key.size * scale_factor / PANGO_SCALE;
-      pattern = pango_fc_make_pattern (desc, language, gravity,
+      pattern = pango_fc_make_pattern (desc, language,
                                       scaled_size,
                                       pango_fc_font_map_get_resolution (fcfontmap, context));
       
@@ -1232,9 +1244,7 @@ pango_fc_font_map_load_fontset (PangoFontMap                 *fontmap,
                                const PangoFontDescription   *desc,
                                PangoLanguage                *language)
 {
-  /* FIXME: support per-item gravity */
- PangoFcPatternSet *patterns = pango_fc_font_map_get_patterns (fontmap, context, desc, language,
-                                                              pango_context_get_gravity (context));
+  PangoFcPatternSet *patterns = pango_fc_font_map_get_patterns (fontmap, context, desc, language);
   PangoFontset *result;
   int i;
   
@@ -1592,6 +1602,7 @@ pango_fc_font_description_from_pattern (FcPattern *pattern, gboolean include_siz
   PangoWeight weight;
   PangoStretch stretch;
   double size;
+  PangoGravity gravity;
   
   FcChar8 *s;
   int i;
@@ -1632,6 +1643,16 @@ pango_fc_font_description_from_pattern (FcPattern *pattern, gboolean include_siz
   if (include_size && FcPatternGetDouble (pattern, FC_SIZE, 0, &size) == FcResultMatch)
     pango_font_description_set_size (desc, size * PANGO_SCALE);
 
+  if (FcPatternGetString (pattern, PANGO_FC_GRAVITY, 0, (FcChar8 **)&s) == FcResultMatch)
+    {
+      GEnumValue *value = g_enum_get_value_by_nick (get_gravity_class (), s);
+      gravity = value->value;
+    }
+  else
+    gravity = PANGO_GRAVITY_SOUTH;
+
+  pango_font_description_set_gravity (desc, gravity);
+
   return desc;
 }
 
index a8f3c23..27ad576 100644 (file)
@@ -42,6 +42,8 @@ struct _PangoFcMetricsInfo
    ((d) - PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6)
 #define PANGO_UNITS_26_6(d) (PANGO_SCALE_26_6 * (d))
 
+#define PANGO_FC_GRAVITY "pangogravity"
+
 void _pango_fc_font_shutdown (PangoFcFont *fcfont);
 
 void           _pango_fc_font_map_remove          (PangoFcFontMap *fcfontmap,