[pango] Bug 589113 – Some characters rotated incorrectly in vertical text



commit a9a416de60ce42fea78e8283253d07a018bf2778
Author: Behdad Esfahbod <behdad behdad org>
Date:   Wed Jul 22 13:39:41 2009 -0400

    Bug 589113 â?? Some characters rotated incorrectly in vertical text
    
    Always show full-width Unicode characters upright.

 pango-view/test-mixed.markup |    2 +-
 pango-view/test-mixed.txt    |    2 +-
 pango/pango-context.c        |   69 ++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 68 insertions(+), 5 deletions(-)
---
diff --git a/pango-view/test-mixed.markup b/pango-view/test-mixed.markup
index daac071..894a1b8 100644
--- a/pango-view/test-mixed.markup
+++ b/pango-view/test-mixed.markup
@@ -5,5 +5,5 @@
 Grass is Green. 2006</span>
 <span lang="fa">Arabic is Ú¯Ù?â??Ù?ا Ù?رÙ?زÙ?دØ?â??
 Ú?Ù?Ù? سبز. Û²Û°Û°Û¶</span>
-<span lang="zh-cn">���山尽� 2006</span>
+<span lang="zh-cn">ABC ���山尽� 2006</span>
 <span lang="ja">ã??ã??ã?¼ã??ã??è²·ã?£ã??ã??ã??</span>
diff --git a/pango-view/test-mixed.txt b/pango-view/test-mixed.txt
index c04a91b..e23f031 100644
--- a/pango-view/test-mixed.txt
+++ b/pango-view/test-mixed.txt
@@ -5,5 +5,5 @@ Roses are Red,
 Grass is Green. 2006
 Arabic is Ú¯Ù?â??Ù?ا Ù?رÙ?زÙ?دØ?â??
 Ú?Ù?Ù? سبز. Û²Û°Û°Û¶
-���山尽� 2006
+ABC ���山尽� 2006
 ã??ã??ã?¼ã??ã??è²·ã?£ã??ã??ã??
diff --git a/pango/pango-context.c b/pango/pango-context.c
index c00338e..4057968 100644
--- a/pango/pango-context.c
+++ b/pango/pango-context.c
@@ -645,11 +645,27 @@ typedef enum {
   SCRIPT_CHANGED       = 1 << 1,
   LANG_CHANGED         = 1 << 2,
   FONT_CHANGED         = 1 << 3,
-  DERIVED_LANG_CHANGED = 1 << 4
+  DERIVED_LANG_CHANGED = 1 << 4,
+  WIDTH_CHANGED        = 1 << 5
 } ChangedFlags;
 
+
+
+typedef struct _PangoWidthIter PangoWidthIter;
+
+struct _PangoWidthIter
+{
+	const gchar *text_start;
+	const gchar *text_end;
+	const gchar *start;
+	const gchar *end;
+	gboolean wide;
+};
+
 typedef struct _ItemizeState ItemizeState;
 
+
+
 struct _ItemizeState
 {
   PangoContext *context;
@@ -687,6 +703,8 @@ struct _ItemizeState
   const char *script_end;
   PangoScript script;
 
+  PangoWidthIter width_iter;
+
   PangoLanguage *derived_lang;
   PangoEngineLang *lang_engine;
 
@@ -777,6 +795,38 @@ update_end (ItemizeState *state)
     state->run_end = state->attr_end;
   if (state->script_end < state->run_end)
     state->run_end = state->script_end;
+  if (state->width_iter.end < state->run_end)
+    state->run_end = state->width_iter.end;
+}
+
+static void
+width_iter_next(PangoWidthIter* iter)
+{
+  iter->start = iter->end;
+
+  if (iter->end < iter->text_end)
+    {
+      gunichar ch = g_utf8_get_char (iter->end);
+      iter->wide = g_unichar_iswide (ch);
+    }
+
+  while (iter->end < iter->text_end)
+    {
+      gunichar ch = g_utf8_get_char (iter->end);
+      if (g_unichar_iswide (ch) != iter->wide)
+        break;
+      iter->end = g_utf8_next_char (iter->end);
+    }
+}
+
+static void
+width_iter_init (PangoWidthIter* iter, const char* text, int length)
+{
+  iter->text_start = text;
+  iter->text_end = text + length;
+  iter->start = iter->end = text;
+
+  width_iter_next (iter);
 }
 
 static void
@@ -852,6 +902,9 @@ itemize_state_init (ItemizeState      *state,
   pango_script_iter_get_range (&state->script_iter, NULL,
 			       &state->script_end, &state->script);
 
+  /* Initialize the width iterator */
+  width_iter_init (&state->width_iter, text + start_index, length);
+
   update_end (state);
 
   if (pango_font_description_get_set_fields (state->font_desc) & PANGO_FONT_MASK_GRAVITY)
@@ -871,7 +924,7 @@ itemize_state_init (ItemizeState      *state,
   state->fallback_engines = NULL;
   state->base_font = NULL;
 
-  state->changed = EMBEDDING_CHANGED | SCRIPT_CHANGED | LANG_CHANGED | FONT_CHANGED;
+  state->changed = EMBEDDING_CHANGED | SCRIPT_CHANGED | LANG_CHANGED | FONT_CHANGED | WIDTH_CHANGED;
 }
 
 static gboolean
@@ -902,6 +955,11 @@ itemize_state_next (ItemizeState *state)
 				   &state->script_end, &state->script);
       state->changed |= SCRIPT_CHANGED;
     }
+  if (state->run_end == state->width_iter.end)
+    {
+      width_iter_next (&state->width_iter);
+      state->changed |= WIDTH_CHANGED;
+    }
 
   update_end (state);
 
@@ -1231,7 +1289,7 @@ itemize_state_update_for_new_run (ItemizeState *state)
 {
   /* This block should be moved to update_attr_iterator, but I'm too lazy to
    * do it right now */
-  if (state->changed & (FONT_CHANGED | SCRIPT_CHANGED))
+  if (state->changed & (FONT_CHANGED | SCRIPT_CHANGED | WIDTH_CHANGED))
     {
       PangoGravity old_gravity = state->resolved_gravity;
 
@@ -1239,6 +1297,11 @@ itemize_state_update_for_new_run (ItemizeState *state)
 	{
 	  state->resolved_gravity = state->font_desc_gravity;
 	}
+      else if (state->width_iter.wide)
+        {
+	  /* Wide characters are always upright */
+          state->resolved_gravity = state->context->resolved_gravity;
+        }
       else
 	{
 	  PangoGravity gravity = state->gravity;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]