~ubuntu-branches/ubuntu/trusty/pango1.0/trusty-proposed

« back to all changes in this revision

Viewing changes to pango/pango-context.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2009-09-09 07:49:30 UTC
  • mfrom: (1.6.1 upstream) (63.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090909074930-zlgadwz6svi311vh
Tags: 1.25.6-1
New upstream development release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#include "pango-engine.h"
30
30
#include "pango-engine-private.h"
31
31
#include "pango-modules.h"
 
32
#include "pango-script-private.h"
32
33
 
33
34
struct _PangoContext
34
35
{
286
287
                         const PangoFontDescription *desc)
287
288
{
288
289
  g_return_val_if_fail (context != NULL, NULL);
289
 
  g_return_val_if_fail (pango_font_description_get_family (desc) != NULL, NULL);
290
290
 
291
291
  return pango_font_map_load_font (context->font_map, context, desc);
292
292
}
305
305
PangoFontset *
306
306
pango_context_load_fontset (PangoContext               *context,
307
307
                            const PangoFontDescription *desc,
308
 
                             PangoLanguage             *language)
 
308
                            PangoLanguage             *language)
309
309
{
310
310
  g_return_val_if_fail (context != NULL, NULL);
311
 
  g_return_val_if_fail (pango_font_description_get_family (desc) != NULL, NULL);
312
 
  g_return_val_if_fail (pango_font_description_get_size (desc) != 0, NULL);
313
311
 
314
312
  return pango_font_map_load_fontset (context->font_map, context, desc, language);
315
313
}
647
645
  SCRIPT_CHANGED       = 1 << 1,
648
646
  LANG_CHANGED         = 1 << 2,
649
647
  FONT_CHANGED         = 1 << 3,
650
 
  DERIVED_LANG_CHANGED = 1 << 4
 
648
  DERIVED_LANG_CHANGED = 1 << 4,
 
649
  WIDTH_CHANGED        = 1 << 5
651
650
} ChangedFlags;
652
651
 
 
652
 
 
653
 
 
654
typedef struct _PangoWidthIter PangoWidthIter;
 
655
 
 
656
struct _PangoWidthIter
 
657
{
 
658
        const gchar *text_start;
 
659
        const gchar *text_end;
 
660
        const gchar *start;
 
661
        const gchar *end;
 
662
        gboolean wide;
 
663
};
 
664
 
653
665
typedef struct _ItemizeState ItemizeState;
654
666
 
 
667
 
 
668
 
655
669
struct _ItemizeState
656
670
{
657
671
  PangoContext *context;
685
699
 
686
700
  ChangedFlags changed;
687
701
 
688
 
  PangoScriptIter *script_iter;
 
702
  PangoScriptIter script_iter;
689
703
  const char *script_end;
690
704
  PangoScript script;
691
705
 
 
706
  PangoWidthIter width_iter;
 
707
 
692
708
  PangoLanguage *derived_lang;
693
709
  PangoEngineLang *lang_engine;
694
710
 
779
795
    state->run_end = state->attr_end;
780
796
  if (state->script_end < state->run_end)
781
797
    state->run_end = state->script_end;
 
798
  if (state->width_iter.end < state->run_end)
 
799
    state->run_end = state->width_iter.end;
 
800
}
 
801
 
 
802
static void
 
803
width_iter_next(PangoWidthIter* iter)
 
804
{
 
805
  iter->start = iter->end;
 
806
 
 
807
  if (iter->end < iter->text_end)
 
808
    {
 
809
      gunichar ch = g_utf8_get_char (iter->end);
 
810
      iter->wide = g_unichar_iswide (ch);
 
811
    }
 
812
 
 
813
  while (iter->end < iter->text_end)
 
814
    {
 
815
      gunichar ch = g_utf8_get_char (iter->end);
 
816
      if (g_unichar_iswide (ch) != iter->wide)
 
817
        break;
 
818
      iter->end = g_utf8_next_char (iter->end);
 
819
    }
 
820
}
 
821
 
 
822
static void
 
823
width_iter_init (PangoWidthIter* iter, const char* text, int length)
 
824
{
 
825
  iter->text_start = text;
 
826
  iter->text_end = text + length;
 
827
  iter->start = iter->end = text;
 
828
 
 
829
  width_iter_next (iter);
782
830
}
783
831
 
784
832
static void
850
898
 
851
899
  /* Initialize the script iterator
852
900
   */
853
 
  state->script_iter = pango_script_iter_new (text + start_index, length);
854
 
  pango_script_iter_get_range (state->script_iter, NULL,
 
901
  _pango_script_iter_init (&state->script_iter, text + start_index, length);
 
902
  pango_script_iter_get_range (&state->script_iter, NULL,
855
903
                               &state->script_end, &state->script);
856
904
 
 
905
  /* Initialize the width iterator */
 
906
  width_iter_init (&state->width_iter, text + start_index, length);
 
907
 
857
908
  update_end (state);
858
909
 
859
910
  if (pango_font_description_get_set_fields (state->font_desc) & PANGO_FONT_MASK_GRAVITY)
873
924
  state->fallback_engines = NULL;
874
925
  state->base_font = NULL;
875
926
 
876
 
  state->changed = EMBEDDING_CHANGED | SCRIPT_CHANGED | LANG_CHANGED | FONT_CHANGED;
 
927
  state->changed = EMBEDDING_CHANGED | SCRIPT_CHANGED | LANG_CHANGED | FONT_CHANGED | WIDTH_CHANGED;
877
928
}
878
929
 
879
930
static gboolean
899
950
 
900
951
  if (state->run_end == state->script_end)
901
952
    {
902
 
      pango_script_iter_next (state->script_iter);
903
 
      pango_script_iter_get_range (state->script_iter, NULL,
 
953
      pango_script_iter_next (&state->script_iter);
 
954
      pango_script_iter_get_range (&state->script_iter, NULL,
904
955
                                   &state->script_end, &state->script);
905
956
      state->changed |= SCRIPT_CHANGED;
906
957
    }
 
958
  if (state->run_end == state->width_iter.end)
 
959
    {
 
960
      width_iter_next (&state->width_iter);
 
961
      state->changed |= WIDTH_CHANGED;
 
962
    }
907
963
 
908
964
  update_end (state);
909
965
 
1067
1123
  GetShaperFontInfo *info = data;
1068
1124
  GSList *l;
1069
1125
 
 
1126
  if (G_UNLIKELY (!font))
 
1127
    return FALSE;
 
1128
 
1070
1129
  for (l = info->engines; l; l = l->next)
1071
1130
    {
1072
1131
      PangoEngineShape *engine = l->data;
1230
1289
{
1231
1290
  /* This block should be moved to update_attr_iterator, but I'm too lazy to
1232
1291
   * do it right now */
1233
 
  if (state->changed & (FONT_CHANGED | SCRIPT_CHANGED))
 
1292
  if (state->changed & (FONT_CHANGED | SCRIPT_CHANGED | WIDTH_CHANGED))
1234
1293
    {
1235
1294
      PangoGravity old_gravity = state->resolved_gravity;
1236
1295
 
 
1296
      /* Font-desc gravity overrides everything */
1237
1297
      if (state->font_desc_gravity != PANGO_GRAVITY_AUTO)
1238
1298
        {
1239
1299
          state->resolved_gravity = state->font_desc_gravity;
1246
1306
          if (G_LIKELY (gravity == PANGO_GRAVITY_AUTO))
1247
1307
            gravity = state->context->resolved_gravity;
1248
1308
 
1249
 
          state->resolved_gravity = pango_gravity_get_for_script (state->script,
1250
 
                                                                  gravity,
1251
 
                                                                  gravity_hint);
 
1309
          state->resolved_gravity = pango_gravity_get_for_script_and_width (state->script,
 
1310
                                                                            state->width_iter.wide,
 
1311
                                                                            gravity,
 
1312
                                                                            gravity_hint);
1252
1313
        }
1253
1314
 
1254
1315
      if (old_gravity != state->resolved_gravity)
1407
1468
  g_free (state->embedding_levels);
1408
1469
  if (state->free_attr_iter)
1409
1470
    pango_attr_iterator_destroy (state->attr_iter);
1410
 
  pango_script_iter_free (state->script_iter);
 
1471
  _pango_script_iter_fini (&state->script_iter);
1411
1472
  pango_font_description_free (state->font_desc);
1412
1473
 
1413
1474
  itemize_state_reset_shape_engines (state);
1574
1635
static void
1575
1636
update_metrics_from_items (PangoFontMetrics *metrics,
1576
1637
                           PangoLanguage    *language,
 
1638
                           const char       *text,
1577
1639
                           GList            *items)
1578
1640
 
1579
1641
{
1580
1642
  GHashTable *fonts_seen = g_hash_table_new (NULL, NULL);
1581
 
  int count = 0;
 
1643
  PangoGlyphString *glyphs = pango_glyph_string_new ();
1582
1644
  GList *l;
1583
1645
 
 
1646
  metrics->approximate_char_width = 0;
 
1647
 
1584
1648
  for (l = items; l; l = l->next)
1585
1649
    {
1586
1650
      PangoItem *item = l->data;
1594
1658
          /* metrics will already be initialized from the first font in the fontset */
1595
1659
          metrics->ascent = MAX (metrics->ascent, raw_metrics->ascent);
1596
1660
          metrics->descent = MAX (metrics->descent, raw_metrics->descent);
1597
 
 
1598
 
          if (count == 0)
1599
 
            {
1600
 
              metrics->approximate_char_width = raw_metrics->approximate_char_width;
1601
 
              metrics->approximate_digit_width = raw_metrics->approximate_digit_width;
1602
 
            }
1603
 
          else
1604
 
            {
1605
 
              metrics->approximate_char_width += raw_metrics->approximate_char_width;
1606
 
              metrics->approximate_digit_width += raw_metrics->approximate_digit_width;
1607
 
            }
1608
 
          count++;
1609
1661
          pango_font_metrics_unref (raw_metrics);
1610
1662
        }
 
1663
 
 
1664
      pango_shape (text + item->offset, item->length, &item->analysis, glyphs);
 
1665
      metrics->approximate_char_width += pango_glyph_string_get_width (glyphs);
1611
1666
    }
1612
1667
 
 
1668
  pango_glyph_string_free (glyphs);
1613
1669
  g_hash_table_destroy (fonts_seen);
1614
1670
 
1615
 
  if (count)
1616
 
    {
1617
 
      metrics->approximate_char_width /= count;
1618
 
      metrics->approximate_digit_width /= count;
1619
 
    }
 
1671
  metrics->approximate_char_width /= pango_utf8_strwidth (text);
1620
1672
}
1621
1673
 
1622
1674
/**
1670
1722
  sample_str = pango_language_get_sample_string (language);
1671
1723
  items = itemize_with_font (context, sample_str, 0, strlen (sample_str), desc);
1672
1724
 
1673
 
  update_metrics_from_items (metrics, language, items);
 
1725
  update_metrics_from_items (metrics, language, sample_str, items);
1674
1726
 
1675
1727
  g_list_foreach (items, (GFunc)pango_item_free, NULL);
1676
1728
  g_list_free (items);