summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@behdad.org>2009-07-22 13:39:41 -0400
committerBehdad Esfahbod <behdad@behdad.org>2009-07-22 13:43:49 -0400
commitb326e778c4fec8a4a11c53e21d59095bcb0d0eb2 (patch)
tree728c85cb7de59cb0acb40a97b71d84881c6d0c94
parent4fb1de63b836c08e7f92e0d696d25c45985fa0d3 (diff)
downloadpango-b326e778c4fec8a4a11c53e21d59095bcb0d0eb2.tar.gz
Bug 589113 – Some characters rotated incorrectly in vertical text
Always show full-width Unicode characters upright.
-rw-r--r--pango-view/test-mixed.markup2
-rw-r--r--pango-view/test-mixed.txt2
-rw-r--r--pango/pango-context.c69
3 files changed, 68 insertions, 5 deletions
diff --git a/pango-view/test-mixed.markup b/pango-view/test-mixed.markup
index daac071d..894a1b81 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 c04a91b5..e23f0314 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 c00338e0..40579686 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;