summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--src/vtedraw.h7
-rw-r--r--src/vteglyph.c24
-rw-r--r--src/vtepango.c5
-rw-r--r--src/vtepangox.c5
-rw-r--r--src/vtexft.c23
6 files changed, 63 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 2275aea..c0c484d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2007-02-04 Chris Wilson <chris@chris-wilson.co.uk>
+ Bug 106618 – CJK 'fixed width' font and 's p a c e d o u t' issue
+
+ * src/vtedraw.h:
+ * src/vteglyph.c: (_vte_glyph_cache_set_font_description):
+ * src/vtepango.c: (_vte_pango_set_text_font):
+ * src/vtepangox.c: (_vte_pango_x_set_text_font):
+ * src/vtexft.c: (_vte_xft_set_text_font):
+ Detect a change in font between wide-chars and recheck for a
+ fixed-width estimate.
+
+2007-02-04 Chris Wilson <chris@chris-wilson.co.uk>
+
Micro-opts.
* src/table.c: (_vte_table_match):
diff --git a/src/vtedraw.h b/src/vtedraw.h
index 84403f5..bbff2f9 100644
--- a/src/vtedraw.h
+++ b/src/vtedraw.h
@@ -32,7 +32,12 @@ G_BEGIN_DECLS
#define VTE_DRAW_SINGLE_WIDE_CHARACTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"abcdefgjijklmnopqrstuvwxyz" \
"0123456789./+@&"
-#define VTE_DRAW_DOUBLE_WIDE_CHARACTERS 0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x4e94
+#define VTE_DRAW_DOUBLE_WIDE_CHARACTERS 0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x4e94,\
+ 0xac00, 0xac01, 0xac04, 0xac08, 0xac10
+/* For Pango, we have to use CJK Ideographs alone. Otherwise, 'width'
+ returned by pango_layout would be screwed up for Chinese and Japanese
+ fonts without Hangul */
+#define VTE_DRAW_DOUBLE_WIDE_IDEOGRAPHS 0x4e00, 0x4e8c, 0x4e09, 0x56db, 0x4e94
#define VTE_DRAW_OPAQUE 0xff
#define VTE_DRAW_MAX_LENGTH 540
diff --git a/src/vteglyph.c b/src/vteglyph.c
index 66d420a..2172c06 100644
--- a/src/vteglyph.c
+++ b/src/vteglyph.c
@@ -127,7 +127,7 @@ _vte_glyph_cache_set_font_description(GtkWidget *widget,
GList *iter;
FcPattern *pattern;
GPtrArray *patterns;
- FT_Face face;
+ FT_Face face, prev_face;
gunichar double_wide_characters[] = {VTE_DRAW_DOUBLE_WIDE_CHARACTERS};
g_return_if_fail(cache != NULL);
@@ -327,7 +327,9 @@ _vte_glyph_cache_set_font_description(GtkWidget *widget,
cache->height = 1;
cache->ascent = 1;
}
- width = 0;
+ /* detect if font measured above has the fixed-width property */
+ width = count = 0;
+ prev_face = NULL;
for (i = 0; i < G_N_ELEMENTS(double_wide_characters); i++) {
face = _vte_glyph_cache_face_for_char(cache,
double_wide_characters[i]);
@@ -342,13 +344,27 @@ _vte_glyph_cache_set_font_description(GtkWidget *widget,
cache->ft_render_flags);
}
if (error == 0) {
+ if (count && prev_face != face) {
+ width /= 64 * count;
+ if (cache->width >= width - 1 &&
+ cache->width <= width + 1) {
+ /* add 1 to round up when dividing by 2 */
+ cache->width = (cache->width + 1) / 2;
+ break;
+ }
+ count = width =0;
+ }
width += face->glyph->metrics.horiAdvance;
count++;
+ prev_face = face;
}
}
if (count > 0) {
- if (cache->width == width / 64 / count) {
- cache->width /= 2;
+ width /= 64 * count;
+ if (cache->width >= width - 1 &&
+ cache->width <= width + 1) {
+ /* add 1 to round up when dividing by 2 */
+ cache->width = (cache->width + 1) / 2;
}
}
}
diff --git a/src/vtepango.c b/src/vtepango.c
index 1535155..7defba0 100644
--- a/src/vtepango.c
+++ b/src/vtepango.c
@@ -245,7 +245,7 @@ _vte_pango_set_text_font(struct _vte_draw *draw,
PangoLayout *layout;
PangoLayoutIter *iter;
PangoRectangle ink, logical;
- gunichar full_codepoints[] = {VTE_DRAW_DOUBLE_WIDE_CHARACTERS};
+ gunichar full_codepoints[] = {VTE_DRAW_DOUBLE_WIDE_IDEOGRAPHS};
GString *full_string;
gint full_width;
guint i;
@@ -287,7 +287,8 @@ _vte_pango_set_text_font(struct _vte_draw *draw,
/* If they're the same, then we have a screwy font. */
if (full_width == draw->width) {
- draw->width /= 2;
+ /* add 1 to round up when dividing by 2 */
+ draw->width = (draw->width + 1) / 2;
}
draw->width = PANGO_PIXELS(draw->width);
diff --git a/src/vtepangox.c b/src/vtepangox.c
index f61d101..58ffedf 100644
--- a/src/vtepangox.c
+++ b/src/vtepangox.c
@@ -279,7 +279,7 @@ _vte_pango_x_set_text_font(struct _vte_draw *draw,
PangoLayout *layout;
PangoLayoutIter *iter;
PangoRectangle ink, logical;
- gunichar full_codepoints[] = {VTE_DRAW_DOUBLE_WIDE_CHARACTERS};
+ gunichar full_codepoints[] = {VTE_DRAW_DOUBLE_WIDE_IDEOGRAPHS};
GString *full_string;
gint full_width;
guint i;
@@ -325,7 +325,8 @@ _vte_pango_x_set_text_font(struct _vte_draw *draw,
/* If they're the same, then we have a screwy font. */
if (full_width == draw->width) {
- draw->width /= 2;
+ /* add 1 to round up when dividing by 2 */
+ draw->width = (draw->width + 1) / 2;
}
draw->width = PANGO_PIXELS(draw->width);
diff --git a/src/vtexft.c b/src/vtexft.c
index 5f9b1d8..5bb2dcf 100644
--- a/src/vtexft.c
+++ b/src/vtexft.c
@@ -493,7 +493,7 @@ _vte_xft_set_text_font(struct _vte_draw *draw,
VteTerminalAntiAlias antialias)
{
struct _vte_xft_font *ft;
- XftFont *font;
+ XftFont *font, *prev_font;
XGlyphInfo extents;
struct _vte_xft_data *data;
gunichar wide_chars[] = {VTE_DRAW_DOUBLE_WIDE_CHARACTERS};
@@ -550,21 +550,36 @@ _vte_xft_set_text_font(struct _vte_draw *draw,
/* Estimate a typical cell width by looking at double-width
* characters, and if it's the same as the single width, assume the
* single-width stuff is broken. */
- n = 0;
+ n = width = 0;
+ prev_font = NULL;
for (i = 0; i < G_N_ELEMENTS(wide_chars); i++) {
c = wide_chars[i];
font = _vte_xft_font_for_char(data->font, c);
if ((font != NULL) &&
(_vte_xft_char_exists(data->font, font, c))) {
+ if (n && prev_font != font) {/* font change */
+ width = howmany(width, n);
+ if (width >= draw->width -1 &&
+ width <= draw->width + 1){
+ /* add 1 to round up when dividing by 2 */
+ draw->width = (draw->width + 1) / 2;
+ break;
+ }
+ n = width =0;
+ }
memset(&extents, 0, sizeof(extents));
_vte_xft_text_extents(data->font, font, c, &extents);
n++;
width += extents.xOff;
+ prev_font = font;
}
}
if (n > 0) {
- if (howmany(width, n) == draw->width) {
- draw->width /= 2;
+ width = howmany(width, n);
+ if (width >= draw->width -1 &&
+ width <= draw->width + 1){
+ /* add 1 to round up when dividing by 2 */
+ draw->width = (draw->width + 1) / 2;
}
}