summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2000-05-07 04:06:29 +0000
committerOwen Taylor <otaylor@src.gnome.org>2000-05-07 04:06:29 +0000
commit1a9eb53c12b49c53aaaf56ef40220c28bd13df84 (patch)
treefd8a5035b8606576ef7c9b9fa2366d4f7880b94e
parentadf1db25a516e1a8b02b89de216e2b42ef1d7639 (diff)
downloadpango-1a9eb53c12b49c53aaaf56ef40220c28bd13df84.tar.gz
When handling overstrikes, try to guess a bit better how overstrike glyphs
Sun May 7 00:00:00 2000 Owen Taylor <otaylor@redhat.com> * modules/basic/basic.c (basic_engine_shape): When handling overstrikes, try to guess a bit better how overstrike glyphs are positioned in the font. (Now works with more of glyphs from clearlyu, though not the Hebrew accents in that font) * examples/HELLO.utf8: Insert tab characters to keep the columns in the right order for either global direction. Insert left-to-right marks in a few places to keep leading and trailing punctuation in the right place. * modules/basic/basic.c (basic_engine_shape): Don't show RLM and LRM * pango/glyphstring.c (pango_glyph_string_extents): Use the logical width set in the glyph string rather than that from the font's metrics. * pango/pangox.c (pango_x_render): Treat glyph index 0 as special - representing invisible, 0 size character. We need this sometimes, and it is easier and faster to have this special case than to shape a space. * pango/pango-context.c (pango_itemize): Put tabs into separate items. (Sort of lame hack, we do this to make line breaking with tab handling simpler) * examples/viewer.c (checkbutton_toggled): Notify all the layouts that the context has changed so the RTL base dir change actually takes effect.
-rw-r--r--ChangeLog36
-rw-r--r--ChangeLog.pre-1-036
-rw-r--r--ChangeLog.pre-1-1036
-rw-r--r--ChangeLog.pre-1-236
-rw-r--r--ChangeLog.pre-1-436
-rw-r--r--ChangeLog.pre-1-636
-rw-r--r--ChangeLog.pre-1-836
-rw-r--r--examples/HELLO.utf873
-rw-r--r--examples/viewer.c12
-rw-r--r--modules/basic/basic-x.c20
-rw-r--r--modules/basic/basic.c20
-rw-r--r--pango/glyphstring.c13
-rw-r--r--pango/mapping.c3
-rw-r--r--pango/pango-context.c1
-rw-r--r--pango/pango-layout.c87
-rw-r--r--pango/pangox.c51
16 files changed, 443 insertions, 89 deletions
diff --git a/ChangeLog b/ChangeLog
index 0dfd6c7f..8a23fa5c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,39 @@
+Sun May 7 00:00:00 2000 Owen Taylor <otaylor@redhat.com>
+
+ * modules/basic/basic.c (basic_engine_shape): When
+ handling overstrikes, try to guess a bit better
+ how overstrike glyphs are positioned in the font.
+ (Now works with more of glyphs from clearlyu, though
+ not the Hebrew accents in that font)
+
+ * examples/HELLO.utf8: Insert tab characters to
+ keep the columns in the right order for either
+ global direction. Insert left-to-right marks in
+ a few places to keep leading and trailing punctuation
+ in the right place.
+
+ * modules/basic/basic.c (basic_engine_shape): Don't
+ show RLM and LRM
+
+ * pango/glyphstring.c (pango_glyph_string_extents): Use
+ the logical width set in the glyph string rather than
+ that from the font's metrics.
+
+ * pango/pangox.c (pango_x_render): Treat glyph index
+ 0 as special - representing invisible, 0 size
+ character. We need this sometimes, and it is
+ easier and faster to have this special case
+ than to shape a space.
+
+ * pango/pango-context.c (pango_itemize): Put
+ tabs into separate items. (Sort of lame hack,
+ we do this to make line breaking with tab
+ handling simpler)
+
+ * examples/viewer.c (checkbutton_toggled): Notify
+ all the layouts that the context has changed so
+ the RTL base dir change actually takes effect.
+
Fri May 5 18:56:45 2000 Owen Taylor <otaylor@redhat.com>
* pango/break.c (pango_break): Add ZWS to hacky
diff --git a/ChangeLog.pre-1-0 b/ChangeLog.pre-1-0
index 0dfd6c7f..8a23fa5c 100644
--- a/ChangeLog.pre-1-0
+++ b/ChangeLog.pre-1-0
@@ -1,3 +1,39 @@
+Sun May 7 00:00:00 2000 Owen Taylor <otaylor@redhat.com>
+
+ * modules/basic/basic.c (basic_engine_shape): When
+ handling overstrikes, try to guess a bit better
+ how overstrike glyphs are positioned in the font.
+ (Now works with more of glyphs from clearlyu, though
+ not the Hebrew accents in that font)
+
+ * examples/HELLO.utf8: Insert tab characters to
+ keep the columns in the right order for either
+ global direction. Insert left-to-right marks in
+ a few places to keep leading and trailing punctuation
+ in the right place.
+
+ * modules/basic/basic.c (basic_engine_shape): Don't
+ show RLM and LRM
+
+ * pango/glyphstring.c (pango_glyph_string_extents): Use
+ the logical width set in the glyph string rather than
+ that from the font's metrics.
+
+ * pango/pangox.c (pango_x_render): Treat glyph index
+ 0 as special - representing invisible, 0 size
+ character. We need this sometimes, and it is
+ easier and faster to have this special case
+ than to shape a space.
+
+ * pango/pango-context.c (pango_itemize): Put
+ tabs into separate items. (Sort of lame hack,
+ we do this to make line breaking with tab
+ handling simpler)
+
+ * examples/viewer.c (checkbutton_toggled): Notify
+ all the layouts that the context has changed so
+ the RTL base dir change actually takes effect.
+
Fri May 5 18:56:45 2000 Owen Taylor <otaylor@redhat.com>
* pango/break.c (pango_break): Add ZWS to hacky
diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10
index 0dfd6c7f..8a23fa5c 100644
--- a/ChangeLog.pre-1-10
+++ b/ChangeLog.pre-1-10
@@ -1,3 +1,39 @@
+Sun May 7 00:00:00 2000 Owen Taylor <otaylor@redhat.com>
+
+ * modules/basic/basic.c (basic_engine_shape): When
+ handling overstrikes, try to guess a bit better
+ how overstrike glyphs are positioned in the font.
+ (Now works with more of glyphs from clearlyu, though
+ not the Hebrew accents in that font)
+
+ * examples/HELLO.utf8: Insert tab characters to
+ keep the columns in the right order for either
+ global direction. Insert left-to-right marks in
+ a few places to keep leading and trailing punctuation
+ in the right place.
+
+ * modules/basic/basic.c (basic_engine_shape): Don't
+ show RLM and LRM
+
+ * pango/glyphstring.c (pango_glyph_string_extents): Use
+ the logical width set in the glyph string rather than
+ that from the font's metrics.
+
+ * pango/pangox.c (pango_x_render): Treat glyph index
+ 0 as special - representing invisible, 0 size
+ character. We need this sometimes, and it is
+ easier and faster to have this special case
+ than to shape a space.
+
+ * pango/pango-context.c (pango_itemize): Put
+ tabs into separate items. (Sort of lame hack,
+ we do this to make line breaking with tab
+ handling simpler)
+
+ * examples/viewer.c (checkbutton_toggled): Notify
+ all the layouts that the context has changed so
+ the RTL base dir change actually takes effect.
+
Fri May 5 18:56:45 2000 Owen Taylor <otaylor@redhat.com>
* pango/break.c (pango_break): Add ZWS to hacky
diff --git a/ChangeLog.pre-1-2 b/ChangeLog.pre-1-2
index 0dfd6c7f..8a23fa5c 100644
--- a/ChangeLog.pre-1-2
+++ b/ChangeLog.pre-1-2
@@ -1,3 +1,39 @@
+Sun May 7 00:00:00 2000 Owen Taylor <otaylor@redhat.com>
+
+ * modules/basic/basic.c (basic_engine_shape): When
+ handling overstrikes, try to guess a bit better
+ how overstrike glyphs are positioned in the font.
+ (Now works with more of glyphs from clearlyu, though
+ not the Hebrew accents in that font)
+
+ * examples/HELLO.utf8: Insert tab characters to
+ keep the columns in the right order for either
+ global direction. Insert left-to-right marks in
+ a few places to keep leading and trailing punctuation
+ in the right place.
+
+ * modules/basic/basic.c (basic_engine_shape): Don't
+ show RLM and LRM
+
+ * pango/glyphstring.c (pango_glyph_string_extents): Use
+ the logical width set in the glyph string rather than
+ that from the font's metrics.
+
+ * pango/pangox.c (pango_x_render): Treat glyph index
+ 0 as special - representing invisible, 0 size
+ character. We need this sometimes, and it is
+ easier and faster to have this special case
+ than to shape a space.
+
+ * pango/pango-context.c (pango_itemize): Put
+ tabs into separate items. (Sort of lame hack,
+ we do this to make line breaking with tab
+ handling simpler)
+
+ * examples/viewer.c (checkbutton_toggled): Notify
+ all the layouts that the context has changed so
+ the RTL base dir change actually takes effect.
+
Fri May 5 18:56:45 2000 Owen Taylor <otaylor@redhat.com>
* pango/break.c (pango_break): Add ZWS to hacky
diff --git a/ChangeLog.pre-1-4 b/ChangeLog.pre-1-4
index 0dfd6c7f..8a23fa5c 100644
--- a/ChangeLog.pre-1-4
+++ b/ChangeLog.pre-1-4
@@ -1,3 +1,39 @@
+Sun May 7 00:00:00 2000 Owen Taylor <otaylor@redhat.com>
+
+ * modules/basic/basic.c (basic_engine_shape): When
+ handling overstrikes, try to guess a bit better
+ how overstrike glyphs are positioned in the font.
+ (Now works with more of glyphs from clearlyu, though
+ not the Hebrew accents in that font)
+
+ * examples/HELLO.utf8: Insert tab characters to
+ keep the columns in the right order for either
+ global direction. Insert left-to-right marks in
+ a few places to keep leading and trailing punctuation
+ in the right place.
+
+ * modules/basic/basic.c (basic_engine_shape): Don't
+ show RLM and LRM
+
+ * pango/glyphstring.c (pango_glyph_string_extents): Use
+ the logical width set in the glyph string rather than
+ that from the font's metrics.
+
+ * pango/pangox.c (pango_x_render): Treat glyph index
+ 0 as special - representing invisible, 0 size
+ character. We need this sometimes, and it is
+ easier and faster to have this special case
+ than to shape a space.
+
+ * pango/pango-context.c (pango_itemize): Put
+ tabs into separate items. (Sort of lame hack,
+ we do this to make line breaking with tab
+ handling simpler)
+
+ * examples/viewer.c (checkbutton_toggled): Notify
+ all the layouts that the context has changed so
+ the RTL base dir change actually takes effect.
+
Fri May 5 18:56:45 2000 Owen Taylor <otaylor@redhat.com>
* pango/break.c (pango_break): Add ZWS to hacky
diff --git a/ChangeLog.pre-1-6 b/ChangeLog.pre-1-6
index 0dfd6c7f..8a23fa5c 100644
--- a/ChangeLog.pre-1-6
+++ b/ChangeLog.pre-1-6
@@ -1,3 +1,39 @@
+Sun May 7 00:00:00 2000 Owen Taylor <otaylor@redhat.com>
+
+ * modules/basic/basic.c (basic_engine_shape): When
+ handling overstrikes, try to guess a bit better
+ how overstrike glyphs are positioned in the font.
+ (Now works with more of glyphs from clearlyu, though
+ not the Hebrew accents in that font)
+
+ * examples/HELLO.utf8: Insert tab characters to
+ keep the columns in the right order for either
+ global direction. Insert left-to-right marks in
+ a few places to keep leading and trailing punctuation
+ in the right place.
+
+ * modules/basic/basic.c (basic_engine_shape): Don't
+ show RLM and LRM
+
+ * pango/glyphstring.c (pango_glyph_string_extents): Use
+ the logical width set in the glyph string rather than
+ that from the font's metrics.
+
+ * pango/pangox.c (pango_x_render): Treat glyph index
+ 0 as special - representing invisible, 0 size
+ character. We need this sometimes, and it is
+ easier and faster to have this special case
+ than to shape a space.
+
+ * pango/pango-context.c (pango_itemize): Put
+ tabs into separate items. (Sort of lame hack,
+ we do this to make line breaking with tab
+ handling simpler)
+
+ * examples/viewer.c (checkbutton_toggled): Notify
+ all the layouts that the context has changed so
+ the RTL base dir change actually takes effect.
+
Fri May 5 18:56:45 2000 Owen Taylor <otaylor@redhat.com>
* pango/break.c (pango_break): Add ZWS to hacky
diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8
index 0dfd6c7f..8a23fa5c 100644
--- a/ChangeLog.pre-1-8
+++ b/ChangeLog.pre-1-8
@@ -1,3 +1,39 @@
+Sun May 7 00:00:00 2000 Owen Taylor <otaylor@redhat.com>
+
+ * modules/basic/basic.c (basic_engine_shape): When
+ handling overstrikes, try to guess a bit better
+ how overstrike glyphs are positioned in the font.
+ (Now works with more of glyphs from clearlyu, though
+ not the Hebrew accents in that font)
+
+ * examples/HELLO.utf8: Insert tab characters to
+ keep the columns in the right order for either
+ global direction. Insert left-to-right marks in
+ a few places to keep leading and trailing punctuation
+ in the right place.
+
+ * modules/basic/basic.c (basic_engine_shape): Don't
+ show RLM and LRM
+
+ * pango/glyphstring.c (pango_glyph_string_extents): Use
+ the logical width set in the glyph string rather than
+ that from the font's metrics.
+
+ * pango/pangox.c (pango_x_render): Treat glyph index
+ 0 as special - representing invisible, 0 size
+ character. We need this sometimes, and it is
+ easier and faster to have this special case
+ than to shape a space.
+
+ * pango/pango-context.c (pango_itemize): Put
+ tabs into separate items. (Sort of lame hack,
+ we do this to make line breaking with tab
+ handling simpler)
+
+ * examples/viewer.c (checkbutton_toggled): Notify
+ all the layouts that the context has changed so
+ the RTL base dir change actually takes effect.
+
Fri May 5 18:56:45 2000 Owen Taylor <otaylor@redhat.com>
* pango/break.c (pango_break): Add ZWS to hacky
diff --git a/examples/HELLO.utf8 b/examples/HELLO.utf8
index 7c624392..281c1be1 100644
--- a/examples/HELLO.utf8
+++ b/examples/HELLO.utf8
@@ -5,43 +5,42 @@ This is a list of ways to say hello in various languages. Its purpose is to illu
(Converted into UTF-8)
---------------------------------------------------------
-Arabic السلام عليكم
-Czech (česky) Dobrý den
-Danish (Dansk) Hej, Goddag
-English Hello
-Esperanto Saluton
-Estonian Tere, Tervist
-FORTRAN PROGRAM
-Finnish (Suomi) Hei
-French (Français) Bonjour, Salut
-German (Deutsch Nord) Guten Tag
-German (Deutsch Süd) Grüß Gott
-Greek (Ελληνικά) Γειά σας
-Hebrew שלום
-Hindi नमस्ते, नमस्कार।
-Italiano Ciao, Buon giorno
-Maltese Ċaw, Saħħa
-Nederlands, Vlaams Hallo, Dag
-Norwegian (Norsk) Hei, God dag
-Polish Dzień dobry, Hej
-Russian (Русский) Здравствуйте!
-Slovak Dobrý deň
-Spanish (Español) ¡Hola!
-Swedish (Svenska) Hej, Goddag
-Thai (ภาษาไทย) สวัสดีครับ, สวัสดีค่ะ
-Turkish (Türkçe) Merhaba
-Vietnamese (Tiếng Việt) Xin Chào
-Yiddish (ײַדישע) דאָס הײַזעלע
+Arabic السلام عليكم
+Czech (česky) Dobrý den
+Danish (Dansk) Hej, Goddag
+English Hello
+Esperanto Saluton
+Estonian Tere, Tervist
+FORTRAN PROGRAM
+Finnish (Suomi) Hei
+French (Français) Bonjour, Salut
+German (Deutsch Nord) Guten Tag
+German (Deutsch Süd) Grüß Gott
+Greek (Ελληνικά) Γειά σας
+Hebrew שלום
+Hindi नमस्ते, नमस्कार।
+Italiano Ciao, Buon giorno
+Maltese Ċaw, Saħħa
+Nederlands, Vlaams Hallo, Dag
+Norwegian (Norsk) Hei, God dag
+Polish Dzień dobry, Hej
+Russian (Русский) Здравствуйте!‎
+Slovak Dobrý deň
+Spanish (Español) ‎¡Hola!‎
+Swedish (Svenska) Hej, Goddag
+Thai (ภาษาไทย) สวัสดีครับ, สวัสดีค่ะ
+Turkish (Türkçe) Merhaba
+Vietnamese (Tiếng Việt) Xin Chào
+Yiddish (ײַדישע) דאָס הײַזעלע
-Japanese (日本語) こんにちは, コンニチハ
-Chinese (中文,普通话,汉语) 你好
-Cantonese (粵語,廣東話) 早晨, 你好
-Korean (한글) 안녕하세요, 안녕하십니까
-
-Difference among chinese characters in GB, JIS, KSC, BIG5:
- GB -- 元气 开发
- JIS -- 元気 開発
- KSC -- 元氣 開發
- BIG5 -- 元氣 開發
+Japanese (日本語) こんにちは, コンニチハ
+Chinese (中文,普通话,汉语) 你好
+Cantonese (粵語,廣東話) 早晨, 你好
+Korean (한글) 안녕하세요, 안녕하십니까
+Difference among chinese characters in GB, JIS, KSC, BIG5:‎
+ GB -- 元气 开发
+ JIS -- 元気 開発
+ KSC -- 元氣 開發
+ BIG5 -- 元氣 開發
diff --git a/examples/viewer.c b/examples/viewer.c
index ccff0b77..61beceab 100644
--- a/examples/viewer.c
+++ b/examples/viewer.c
@@ -372,7 +372,19 @@ button_press (GtkWidget *layout, GdkEventButton *event)
static void
checkbutton_toggled (GtkWidget *widget, gpointer data)
{
+ GSList *para_list;
+
pango_context_set_base_dir (context, GTK_TOGGLE_BUTTON (widget)->active ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR);
+
+ para_list = paragraphs;
+ while (para_list)
+ {
+ Paragraph *para = para_list->data;
+
+ pango_layout_context_changed (para->layout);
+ para_list = para_list->next;
+ }
+
gtk_widget_queue_resize (layout);
}
diff --git a/modules/basic/basic-x.c b/modules/basic/basic-x.c
index 6c851228..e78aa384 100644
--- a/modules/basic/basic-x.c
+++ b/modules/basic/basic-x.c
@@ -401,16 +401,9 @@ basic_engine_shape (PangoFont *font,
input = buf;
}
- if (wc == 0x200B) /* Zero-width space */
+ if (wc == 0x200B || wc == 0x200E || wc == 0x200F) /* Zero-width characters */
{
- index = find_char (cache, font, ' ', input);
- if (index)
- {
- set_glyph (font, glyphs, i, p - text, index);
- glyphs->glyphs[i].geometry.width = 0;
- }
- else
- set_glyph (font, glyphs, i, p - text, pango_x_get_unknown_glyph (font));
+ set_glyph (font, glyphs, i, p - text, 0);
}
else
{
@@ -423,10 +416,19 @@ basic_engine_shape (PangoFont *font,
{
if (i > 0)
{
+ PangoRectangle logical_rect, ink_rect;
+
glyphs->glyphs[i].geometry.width = MAX (glyphs->glyphs[i-1].geometry.width,
glyphs->glyphs[i].geometry.width);
glyphs->glyphs[i-1].geometry.width = 0;
glyphs->log_clusters[i] = glyphs->log_clusters[i-1];
+
+ /* Some heuristics to try to guess how overstrike glyphs are
+ * done and compensate
+ */
+ pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, &ink_rect, &logical_rect);
+ if (logical_rect.width == 0 && ink_rect.x == 0)
+ glyphs->glyphs[i].geometry.x_offset = (glyphs->glyphs[i].geometry.width - ink_rect.width) / 2;
}
}
}
diff --git a/modules/basic/basic.c b/modules/basic/basic.c
index 6c851228..e78aa384 100644
--- a/modules/basic/basic.c
+++ b/modules/basic/basic.c
@@ -401,16 +401,9 @@ basic_engine_shape (PangoFont *font,
input = buf;
}
- if (wc == 0x200B) /* Zero-width space */
+ if (wc == 0x200B || wc == 0x200E || wc == 0x200F) /* Zero-width characters */
{
- index = find_char (cache, font, ' ', input);
- if (index)
- {
- set_glyph (font, glyphs, i, p - text, index);
- glyphs->glyphs[i].geometry.width = 0;
- }
- else
- set_glyph (font, glyphs, i, p - text, pango_x_get_unknown_glyph (font));
+ set_glyph (font, glyphs, i, p - text, 0);
}
else
{
@@ -423,10 +416,19 @@ basic_engine_shape (PangoFont *font,
{
if (i > 0)
{
+ PangoRectangle logical_rect, ink_rect;
+
glyphs->glyphs[i].geometry.width = MAX (glyphs->glyphs[i-1].geometry.width,
glyphs->glyphs[i].geometry.width);
glyphs->glyphs[i-1].geometry.width = 0;
glyphs->log_clusters[i] = glyphs->log_clusters[i-1];
+
+ /* Some heuristics to try to guess how overstrike glyphs are
+ * done and compensate
+ */
+ pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, &ink_rect, &logical_rect);
+ if (logical_rect.width == 0 && ink_rect.x == 0)
+ glyphs->glyphs[i].geometry.x_offset = (glyphs->glyphs[i].geometry.width - ink_rect.width) / 2;
}
}
}
diff --git a/pango/glyphstring.c b/pango/glyphstring.c
index c2964704..d9d7c87b 100644
--- a/pango/glyphstring.c
+++ b/pango/glyphstring.c
@@ -139,6 +139,12 @@ pango_glyph_string_extents (PangoGlyphString *glyphs,
if (i == 0)
{
pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, ink_rect, logical_rect);
+
+ if (logical_rect)
+ {
+ logical_rect->x = 0;
+ logical_rect->width = geometry->width;
+ }
}
else
{
@@ -163,14 +169,11 @@ pango_glyph_string_extents (PangoGlyphString *glyphs,
if (logical_rect)
{
- new_pos = MIN (logical_rect->x, x_pos + glyph_logical.x + geometry->x_offset);
- logical_rect->width = MAX (logical_rect->x + logical_rect->width,
- x_pos + glyph_logical.x + glyph_logical.width + geometry->x_offset) - new_pos;
- logical_rect->x = new_pos;
+ logical_rect->width += geometry->width;
new_pos = MIN (logical_rect->y, glyph_logical.y + geometry->y_offset);
logical_rect->height = MAX (logical_rect->y + logical_rect->height,
- glyph_logical.y + glyph_logical.height + geometry->y_offset) - new_pos;
+ glyph_logical.y + glyph_logical.height + geometry->y_offset) - new_pos;
logical_rect->y = new_pos;
}
}
diff --git a/pango/mapping.c b/pango/mapping.c
index 3ed47c66..57a438d9 100644
--- a/pango/mapping.c
+++ b/pango/mapping.c
@@ -300,6 +300,3 @@ pango_glyph_string_x_to_index (PangoGlyphString *glyphs,
*trailing = (cp - (int)cp > 0.5) ? 1 : 0;
}
}
-
-
-
diff --git a/pango/pango-context.c b/pango/pango-context.c
index 0c2e3dcf..a0134eb4 100644
--- a/pango/pango-context.c
+++ b/pango/pango-context.c
@@ -582,6 +582,7 @@ pango_itemize (PangoContext *context,
next = unicode_next_utf8 (p);
if (i == 0 ||
+ text_ucs4[i] == '\t' || text_ucs4[i-1] == '\t' ||
embedding_levels[i] != embedding_levels[i-1] ||
shape_engines[i] != shape_engines[i-1] ||
lang_engines[i] != lang_engines[i-1] ||
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 30a872da..b3ce1c89 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -46,6 +46,8 @@ struct _PangoLayout
gint n_chars; /* Total number of characters in layout */
PangoLogAttr *log_attrs; /* Logical attributes for layout's text */
+ int tab_width; /* Cached width of a tab. -1 == not yet calculated */
+
GSList *lines;
};
@@ -104,6 +106,8 @@ pango_layout_new (PangoContext *context)
layout->log_attrs = NULL;
layout->lines = NULL;
+ layout->tab_width = -1;
+
return layout;
}
@@ -437,6 +441,7 @@ void
pango_layout_context_changed (PangoLayout *layout)
{
pango_layout_clear_lines (layout);
+ layout->tab_width = -1;
}
/**
@@ -1381,6 +1386,81 @@ free_run (PangoLayoutRun *run, gboolean free_item)
g_free (run);
}
+static int
+get_tab_pos (PangoLayout *layout, int index)
+{
+ if (layout->tab_width == -1)
+ {
+ /* Find out how wide 8 spaces are in the context's default font. Utter
+ * performance killer. :-(
+ */
+ PangoGlyphString *glyphs = pango_glyph_string_new ();
+ PangoItem *item;
+ GList *items;
+ int i;
+
+ PangoAttrList *attrs = pango_attr_list_new ();
+ items = pango_itemize (layout->context, " ", 1, attrs);
+ pango_attr_list_unref (attrs);
+
+ item = items->data;
+ pango_shape (" ", 8, &item->analysis, glyphs);
+
+ pango_item_free (item);
+ g_list_free (items);
+
+ layout->tab_width = 0;
+ for (i=0; i < glyphs->num_glyphs; i++)
+ layout->tab_width += glyphs->glyphs[i].geometry.width;
+
+ pango_glyph_string_free (glyphs);
+ }
+
+ return layout->tab_width * index;
+}
+
+static void
+shape_tab (PangoLayoutLine *line,
+ PangoGlyphString *glyphs)
+{
+ int i;
+ GSList *tmp_list;
+
+ int current_width = 0;
+
+ /* Compute the width of the line currently - inefficient, but easier
+ * than keeping the current width of the line up to date everywhere
+ */
+ tmp_list = line->runs;
+ while (tmp_list)
+ {
+ PangoLayoutRun *run = tmp_list->data;
+ for (i=0; i < run->glyphs->num_glyphs; i++)
+ current_width += run->glyphs->glyphs[i].geometry.width;
+
+ tmp_list = tmp_list->next;
+ }
+
+ pango_glyph_string_set_size (glyphs, 1);
+
+ glyphs->glyphs[0].glyph = 0;
+ glyphs->glyphs[0].geometry.x_offset = 0;
+ glyphs->glyphs[0].geometry.y_offset = 0;
+ glyphs->glyphs[0].attr.is_cluster_start = 1;
+
+ glyphs->log_clusters[0] = 0;
+
+ for (i=0;;i++)
+ {
+ int tab_pos = get_tab_pos (line->layout, i);
+ if (tab_pos > current_width)
+ {
+ glyphs->glyphs[0].geometry.width = tab_pos - current_width;
+ break;
+ }
+ }
+}
+
static gboolean
process_item (PangoLayoutLine *line,
PangoItem *item,
@@ -1397,7 +1477,10 @@ process_item (PangoLayoutLine *line,
if (*remaining_width == 0)
return FALSE;
- pango_shape (text + item->offset, item->length, &item->analysis, glyphs);
+ if (text[item->offset] == '\t')
+ shape_tab (line, glyphs);
+ else
+ pango_shape (text + item->offset, item->length, &item->analysis, glyphs);
if (*remaining_width < 0)
{
@@ -1579,7 +1662,7 @@ pango_layout_check_lines (PangoLayout *layout)
{
PangoItem *item = tmp_list->data;
gboolean fits;
- int old_num_chars = item->num_chars;
+ int old_num_chars = item->num_chars;
fits = process_item (line, item, start,
layout->log_attrs + start_offset, current_cant_end,
diff --git a/pango/pangox.c b/pango/pangox.c
index c35e614e..34cd0d46 100644
--- a/pango/pangox.c
+++ b/pango/pangox.c
@@ -1413,32 +1413,35 @@ pango_x_render (Display *display,
for (i=0; i<glyphs->num_glyphs; i++)
{
- guint16 index = PANGO_X_GLYPH_INDEX (glyphs->glyphs[i].glyph);
- guint16 subfont_index = PANGO_X_GLYPH_SUBFONT (glyphs->glyphs[i].glyph);
- PangoXSubfontInfo *subfont;
-
- XChar2b c;
-
- subfont = pango_x_find_subfont (font, subfont_index);
- if (subfont)
+ if (glyphs->glyphs[i].glyph)
{
- c.byte1 = index / 256;
- c.byte2 = index % 256;
-
- fs = pango_x_get_font_struct (font, subfont);
- if (!fs)
- continue;
+ guint16 index = PANGO_X_GLYPH_INDEX (glyphs->glyphs[i].glyph);
+ guint16 subfont_index = PANGO_X_GLYPH_SUBFONT (glyphs->glyphs[i].glyph);
+ PangoXSubfontInfo *subfont;
+
+ XChar2b c;
- if (fs->fid != old_fid)
+ subfont = pango_x_find_subfont (font, subfont_index);
+ if (subfont)
{
- XSetFont (display, gc, fs->fid);
- old_fid = fs->fid;
+ c.byte1 = index / 256;
+ c.byte2 = index % 256;
+
+ fs = pango_x_get_font_struct (font, subfont);
+ if (!fs)
+ continue;
+
+ if (fs->fid != old_fid)
+ {
+ XSetFont (display, gc, fs->fid);
+ old_fid = fs->fid;
+ }
+
+ XDrawString16 (display, d, gc,
+ x + (x_off + glyphs->glyphs[i].geometry.x_offset) / PANGO_SCALE,
+ y + glyphs->glyphs[i].geometry.y_offset / PANGO_SCALE,
+ &c, 1);
}
-
- XDrawString16 (display, d, gc,
- x + (x_off + glyphs->glyphs[i].geometry.x_offset) / PANGO_SCALE,
- y + glyphs->glyphs[i].geometry.y_offset / PANGO_SCALE,
- &c, 1);
}
x_off += glyphs->glyphs[i].geometry.width;
@@ -1454,7 +1457,7 @@ pango_x_font_get_glyph_extents (PangoFont *font,
XCharStruct *cs;
PangoXSubfontInfo *subfont;
- if (pango_x_find_glyph (font, glyph, &subfont, &cs))
+ if (glyph && pango_x_find_glyph (font, glyph, &subfont, &cs))
{
if (ink_rect)
{
@@ -2019,7 +2022,7 @@ pango_x_list_subfonts (PangoFont *font,
}
gboolean
-pango_x_has_glyph (PangoFont *font,
+pango_x_has_glyph (PangoFont *font,
PangoGlyph glyph)
{
g_return_val_if_fail (font != NULL, FALSE);