* Re: A patch for enforcing double-width CJK character display
[not found] <4F85A138.6090900@i-soft.com.cn>
@ 2012-04-11 15:48 ` Kan-Ru Chen
2012-04-11 16:16 ` 黄建忠
0 siblings, 1 reply; 53+ messages in thread
From: Kan-Ru Chen @ 2012-04-11 15:48 UTC (permalink / raw)
To: 黄建忠; +Cc: eliz, stepnem, emacs-devel
[ CC:ed emacs-devel ]
Hi!
黄建忠 <jianzhong.huang@i-soft.com.cn> writes:
> Here is a patch to fix double-width issue of CJK fonts when use Xft
> backend , just like some terminal did.
I like you idea to draw glyphs individually when the font is a CJK font.
I didn't realized that when the font changes, XftDrawGlyphs is called
again so we have a chance to examine the font!
Your patch probably needs some adjust to fit the coding style, but the
approach is great! Did you check that it also works with scaled fonts?
Like (text-scale-increase) multiple times.
Kanru
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-11 15:48 ` Kan-Ru Chen
@ 2012-04-11 16:16 ` 黄建忠
2012-04-12 8:56 ` 黄建忠
0 siblings, 1 reply; 53+ messages in thread
From: 黄建忠 @ 2012-04-11 16:16 UTC (permalink / raw)
To: Kan-Ru Chen; +Cc: eliz, stepnem, emacs-devel
Thanks for reply.
I checked with "text-scale-increase" and it did not work.
When scale happened, the space_width and column_width of frame did not
changed, I need find another way to get monospace font width after scale.
But I think we can store the default font face to every xftfont_info and
when scale happened, re-caculate the space width of default face.
Let me try, thanks for the feedback.
于 2012年04月11日 23:48, Kan-Ru Chen 写道:
> [ CC:ed emacs-devel ]
>
> Hi!
>
> 黄建忠<jianzhong.huang@i-soft.com.cn> writes:
>
>> Here is a patch to fix double-width issue of CJK fonts when use Xft
>> backend , just like some terminal did.
> I like you idea to draw glyphs individually when the font is a CJK font.
> I didn't realized that when the font changes, XftDrawGlyphs is called
> again so we have a chance to examine the font!
>
> Your patch probably needs some adjust to fit the coding style, but the
> approach is great! Did you check that it also works with scaled fonts?
> Like (text-scale-increase) multiple times.
>
> Kanru
>
>
--
黄建忠
技术总监
普华基础软件股份有限公司 基础软件事业部
电话:010-82664919-8201
传真:010-82664407
手机:13501162460
网址:http://www.i-soft.com.cn
地址:中国北京市海淀区海淀东三街欧美汇大厦9层
邮编:100080
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-11 16:16 ` 黄建忠
@ 2012-04-12 8:56 ` 黄建忠
2012-04-12 9:53 ` Eli Zaretskii
0 siblings, 1 reply; 53+ messages in thread
From: 黄建忠 @ 2012-04-12 8:56 UTC (permalink / raw)
To: Kan-Ru Chen; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 2040 bytes --]
FRAME_COLUMN_WIDTH and FRAME_SPACE_WIDTH never changed, it only be
initialized when first font loaded.
Here is a try to fix "text-scale-increase/decrease" CJK double width issue.
I did not want to change external codes, So introduce a dirty workaround
and a global static variable "default_font_width", The comments in this
patch explained the idea and necessity.
"get_default_font_width" function is called by "xftfont_text_extents"
and "xftfont_draw" to get default font width correctly after scale.
Can anybody provide a clue how to catch the new width of default font
via FRAME_PTR when scale happened?
于 2012年04月12日 00:16, 黄建忠 写道:
> Thanks for reply.
> I checked with "text-scale-increase" and it did not work.
> When scale happened, the space_width and column_width of frame did not
> changed, I need find another way to get monospace font width after scale.
> But I think we can store the default font face to every xftfont_info
> and when scale happened, re-caculate the space width of default face.
> Let me try, thanks for the feedback.
>
>
> 于 2012年04月11日 23:48, Kan-Ru Chen 写道:
>> [ CC:ed emacs-devel ]
>>
>> Hi!
>>
>> 黄建忠<jianzhong.huang@i-soft.com.cn> writes:
>>
>>> Here is a patch to fix double-width issue of CJK fonts when use Xft
>>> backend , just like some terminal did.
>> I like you idea to draw glyphs individually when the font is a CJK font.
>> I didn't realized that when the font changes, XftDrawGlyphs is called
>> again so we have a chance to examine the font!
>>
>> Your patch probably needs some adjust to fit the coding style, but the
>> approach is great! Did you check that it also works with scaled fonts?
>> Like (text-scale-increase) multiple times.
>>
>> Kanru
>>
>>
>
>
--
黄建忠
技术总监
普华基础软件股份有限公司 基础软件事业部
电话:010-82664919-8201
传真:010-82664407
手机:13501162460
网址:http://www.i-soft.com.cn
地址:中国北京市海淀区海淀东三街欧美汇大厦9层
邮编:100080
[-- Attachment #2: emacs-cjk-monospace-v5.patch --]
[-- Type: text/plain, Size: 6793 bytes --]
--- xftfont.c.orig 2012-04-12 15:18:25.108011233 +0800
+++ xftfont.c 2012-04-12 16:35:50.993433916 +0800
@@ -61,6 +61,7 @@
Display *display;
int screen;
XftFont *xftfont;
+ FRAME_PTR frame; /* hold frame ptr, cjk double width fix need it */
};
/* Structure pointed by (struct face *)->extra */
@@ -137,6 +138,70 @@
}
+static int default_font_width;
+
+static int is_cjk_font(struct xftfont_info *);
+static int calc_cjk_padding(int char_width);
+static void get_default_font_width(struct xftfont_info *);
+
+/* Check whether the font contains CJK Ideograph 'number one', 0x4E00,
+ It should be ok for Chinese/Japanese font.
+ Or font contains Korean script syllable 'Ka',0xAC00,
+ because Korean fonts may not have any Chinese characters at all.
+ codes from xterm.*/
+static int
+is_cjk_font(struct xftfont_info *xftfont_info)
+{
+ if(XftCharExists(xftfont_info->display, xftfont_info->xftfont, 0x4E00) ||
+ XftCharExists(xftfont_info->display, xftfont_info->xftfont, 0xAC00))
+ return 1;
+ return 0;
+}
+
+/* Caculate the width padding according to default font width */
+static int
+calc_cjk_padding(int char_width)
+{
+ int padding = 0;
+ if( default_font_width == 0 || /* the default font is not a monospace font */
+ char_width < default_font_width || /* almost impossible */
+ char_width == default_font_width) /* ascii glyph from real monospace CJK font */
+ return 0;
+ /* get the padding, all cjk symbols is double width */
+ padding = default_font_width * 2 - char_width;
+ /* 1, auto matched CJK pcf/bdf fonts may bigger than 2 * default_font_width.
+ 2, User may set a very big font size for script HAN.
+ Keep it unchanged, should NOT adjust default monospace font width. */
+ return padding > 0 ? padding : 0;
+}
+
+/* Hmm, This function is dirty....
+ Anyway, it fix text-scale-increase/decrease CJK double width issue.
+ Emacs should provide a way to get the default font width of frame when scale happened, but how?
+ After I tried FRAME_* macros, I give up, It is initialized when first font loaded and never changed.
+
+ This is the root cause why we need this function and "default_font_width" global variable.
+ here we get the default font family and compare with every xftfont_info structure,
+ If they are same, we catch the default font, then set "default_font_width" to new value.
+*/
+static void
+get_default_font_width(struct xftfont_info *xftfont_info)
+{
+ struct font *defaultfont = NULL;
+ if(defaultfont = FRAME_FONT(xftfont_info->frame)){ /* default font of frame */
+ Lisp_Object default_font_object;
+ Lisp_Object xftfont_object;
+ XSETFONT (default_font_object, defaultfont);
+ XSETFONT (xftfont_object, &xftfont_info->font);
+ if(!NILP(AREF (default_font_object, FONT_FAMILY_INDEX)) &&
+ !NILP(Fstring_equal (AREF (default_font_object, FONT_FAMILY_INDEX),
+ AREF (xftfont_object, FONT_FAMILY_INDEX) )) &&
+ INTEGERP (AREF (default_font_object, FONT_SPACING_INDEX)) &&
+ XINT(AREF (default_font_object, FONT_SPACING_INDEX)) == FONT_SPACING_MONO) /* ensure monospace */
+ default_font_width = xftfont_info->font.space_width;
+ }
+}
+
static Lisp_Object xftfont_list (Lisp_Object, Lisp_Object);
static Lisp_Object xftfont_match (Lisp_Object, Lisp_Object);
static Lisp_Object xftfont_open (FRAME_PTR, Lisp_Object, int);
@@ -391,6 +456,10 @@
xftfont_info->display = display;
xftfont_info->screen = FRAME_X_SCREEN_NUMBER (f);
xftfont_info->xftfont = xftfont;
+ /* to fix CJK double width alignment issue.
+ pass FRAME_PTR to every xftfont_info structure
+ Later, we can get default font of the frame via the ptr */
+ xftfont_info->frame = f;
/* This means that there's no need of transformation. */
xftfont_info->matrix.xx = 0;
if (FcPatternGetMatrix (xftfont->pattern, FC_MATRIX, 0, &matrix)
@@ -593,20 +662,30 @@
{
struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
XGlyphInfo extents;
-
+ int cjk_padding = 0;
+ int l_padding = 0;
+ int r_padding = 0;
BLOCK_INPUT;
XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code, nglyphs,
&extents);
+ /* get the default font width of the frame
+ and set default_font_width global variable used later by calc_cjk_padding. */
+ get_default_font_width(xftfont_info);
+ if(is_cjk_font(xftfont_info))
+ cjk_padding = calc_cjk_padding(extents.xOff);
+ /* cjk_padding may equals to 0, then all is zero, still ok */
+ l_padding = cjk_padding >> 1; /* get half */
+ r_padding = cjk_padding - l_padding; /* cjk_padding maybe not divided by 2 exactly */
UNBLOCK_INPUT;
if (metrics)
{
- metrics->lbearing = - extents.x;
- metrics->rbearing = - extents.x + extents.width;
- metrics->width = extents.xOff;
+ metrics->lbearing = - extents.x - l_padding;
+ metrics->rbearing = - extents.x + extents.width + r_padding;
+ metrics->width = extents.xOff + cjk_padding;
metrics->ascent = extents.y;
metrics->descent = extents.height - extents.y;
}
- return extents.xOff;
+ return extents.xOff + cjk_padding;
}
static XftDraw *
@@ -660,13 +739,33 @@
code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8)
| XCHAR2B_BYTE2 (s->char2b + from + i));
+ /* get the default font width of the frame
+ and set default_font_width global variable used later by calc_cjk_padding. */
+ get_default_font_width(xftfont_info);
+
if (s->padding_p)
for (i = 0; i < len; i++)
XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
x + i, y, code + i, 1);
- else
- XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
- x, y, code, len);
+ else {
+ if(!is_cjk_font(xftfont_info)) /*not CJK, draw glyphs like before*/
+ XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont, x, y, code, len);
+ else /* draw glyphs one by one and adjust the offset */
+ for (i = 0; i < len; i++) {
+ int cjk_padding = 0;
+ int offset = 0;
+ XGlyphInfo extents;
+ XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code+i, 1,
+ &extents);
+ cjk_padding = calc_cjk_padding(extents.xOff);
+ if(cjk_padding) /* CJK symbol and have padding */
+ offset = default_font_width * i * 2 + (cjk_padding>>1);
+ else /* No padding, just use extents.xOff directly, real monospace CJK font works */
+ offset = extents.xOff * i;
+ XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
+ x+offset, y, code+i, 1);
+ }
+ }
UNBLOCK_INPUT;
return len;
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-12 8:56 ` 黄建忠
@ 2012-04-12 9:53 ` Eli Zaretskii
2012-04-12 11:18 ` 黄建忠
0 siblings, 1 reply; 53+ messages in thread
From: Eli Zaretskii @ 2012-04-12 9:53 UTC (permalink / raw)
To: 黄建忠; +Cc: kanru, emacs-devel
> Date: Thu, 12 Apr 2012 16:56:16 +0800
> From: 黄建忠 <jianzhong.huang@i-soft.com.cn>
> Cc: emacs-devel@gnu.org
>
> FRAME_COLUMN_WIDTH and FRAME_SPACE_WIDTH never changed, it only be
> initialized when first font loaded.
Right, and that's by design.
> Can anybody provide a clue how to catch the new width of default font
> via FRAME_PTR when scale happened?
I don't think there is a way to do that, if all you have is the frame
pointer. text-scale-mode does not modify the frame's default font, it
remaps the 'default' face to another face which specifies a larger or
a smaller font. So the way to find the width of the font after
scaling is to get hold of the font itself, or of the face to which
'default' was remapped. Then you can use FONT_WIDTH, I think (but I
didn't test this).
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-12 9:53 ` Eli Zaretskii
@ 2012-04-12 11:18 ` 黄建忠
2012-04-12 14:27 ` Eli Zaretskii
0 siblings, 1 reply; 53+ messages in thread
From: 黄建忠 @ 2012-04-12 11:18 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: kanru, emacs-devel
于 2012年04月12日 17:53, Eli Zaretskii 写道:
>> Date: Thu, 12 Apr 2012 16:56:16 +0800
>> From: 黄建忠<jianzhong.huang@i-soft.com.cn>
>> Cc: emacs-devel@gnu.org
>>
>> FRAME_COLUMN_WIDTH and FRAME_SPACE_WIDTH never changed, it only be
>> initialized when first font loaded.
> Right, and that's by design.
Can be understood, since the width/height of a lot of UI components was determined via these values.
>
>> Can anybody provide a clue how to catch the new width of default font
>> via FRAME_PTR when scale happened?
> I don't think there is a way to do that, if all you have is the frame
> pointer. text-scale-mode does not modify the frame's default font, it
> remaps the 'default' face to another face which specifies a larger or
> a smaller font. So the way to find the width of the font after
> scaling is to get hold of the font itself, or of the face to which
> 'default' was remapped. Then you can use FONT_WIDTH, I think (but I
> didn't test this).
I can get the default font(the first font loaded when frame be
initialized) via FRAME_FONT, it's great that it can not be changed after
first font loaded.
But I still can not get the current width after scale, since the props
of FRAME_FONT also not be changed.
Since FRAME_FONT always return the initial value, FONT_WIDTH defined in
xterm.h and FONT_WIDTH_NUMERIC defined in font.h DO works but only get
the initial value of font width.
Of couse a new FcPattern can be created, the family of default font and
the pixel_size of current loaded font can be set to the newly created
FcPattern,
After a FcPatternMatch call , width/average_width can be caculated. But
since this function will be involked by "xftfont_text_extents" and
"xftfont_draw" many many times, It should not be too complex and time
consuming, Otherwise it will affect the performance of font drawing.
The problem exist in current patch is the "global variable" and a "dirty
workaround function that a little bit difficult to be understood", I
need to find a better and clean way to accomplish it.
I noticed there were some global Lisp_Object such as
"f_Vface_font_rescale_alist"/"f_Vface_remapping_alist"/"f_Vface_new_frame_defaults",
maybe I can use them, Hope so.
Thanks.
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-12 11:18 ` 黄建忠
@ 2012-04-12 14:27 ` Eli Zaretskii
2012-04-12 17:56 ` 黄建忠
0 siblings, 1 reply; 53+ messages in thread
From: Eli Zaretskii @ 2012-04-12 14:27 UTC (permalink / raw)
To: 黄建忠; +Cc: kanru, emacs-devel
> Date: Thu, 12 Apr 2012 19:18:39 +0800
> From: 黄建忠 <jianzhong.huang@i-soft.com.cn>
> CC: kanru@kanru.info, emacs-devel@gnu.org
>
> >> Can anybody provide a clue how to catch the new width of default font
> >> via FRAME_PTR when scale happened?
> > I don't think there is a way to do that, if all you have is the frame
> > pointer. text-scale-mode does not modify the frame's default font, it
> > remaps the 'default' face to another face which specifies a larger or
> > a smaller font. So the way to find the width of the font after
> > scaling is to get hold of the font itself, or of the face to which
> > 'default' was remapped. Then you can use FONT_WIDTH, I think (but I
> > didn't test this).
> I can get the default font(the first font loaded when frame be
> initialized) via FRAME_FONT, it's great that it can not be changed after
> first font loaded.
> But I still can not get the current width after scale, since the props
> of FRAME_FONT also not be changed.
> [...]
> I noticed there were some global Lisp_Object such as
> "f_Vface_font_rescale_alist"/"f_Vface_remapping_alist"/"f_Vface_new_frame_defaults",
> maybe I can use them, Hope so.
This will retrieve the numerical ID of the default face on frame F:
int id = lookup_basic_face (F, DEFAULT_FACE_ID);
lookup_basic_face consults f_Vface_remapping_alist. If the value of
id above is different from DEFAULT_FACE_ID, that means the default
face was remapped. Then you can get the remapped face like this:
struct face *face = FACE_FROM_ID (F, id);
Now the font of the face is available as
struct font *font = face->font;
And I think FONT_WIDTH (font) will give you the width you want to use
instead of FRAME_COLUMN_WIDTH.
Again, this is 100% untested. Good luck!
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-12 14:27 ` Eli Zaretskii
@ 2012-04-12 17:56 ` 黄建忠
2012-04-12 20:33 ` Stefan Monnier
0 siblings, 1 reply; 53+ messages in thread
From: 黄建忠 @ 2012-04-12 17:56 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: kanru, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 2481 bytes --]
Hi, Eli,
Many many thinks, your suggestion is really very very great.
Now we can get the frame font width no matter it is default, remapped or
rescaled.
I updated the patch as you suggested, other changes also include in
attachment:
1, remove "default_font_width" global variable, get font width from
FRAME_PTR as you sugguested.
2, pass FRAME_PTR to every xftfont_info structure, we can use it anywhere.
3, add a feild "is_cjk" to "xftfont_info" structure, initialize it when
xftfont_open, avoid call "is_cjk_font" many times when draw and extents
calculation.
Now, it works very well with font remapping, rescaling.
于 2012年04月12日 22:27, Eli Zaretskii 写道:
>> Date: Thu, 12 Apr 2012 19:18:39 +0800
>> From: 黄建忠<jianzhong.huang@i-soft.com.cn>
>> CC: kanru@kanru.info, emacs-devel@gnu.org
>>
>>>> Can anybody provide a clue how to catch the new width of default font
>>>> via FRAME_PTR when scale happened?
>>> I don't think there is a way to do that, if all you have is the frame
>>> pointer. text-scale-mode does not modify the frame's default font, it
>>> remaps the 'default' face to another face which specifies a larger or
>>> a smaller font. So the way to find the width of the font after
>>> scaling is to get hold of the font itself, or of the face to which
>>> 'default' was remapped. Then you can use FONT_WIDTH, I think (but I
>>> didn't test this).
>> I can get the default font(the first font loaded when frame be
>> initialized) via FRAME_FONT, it's great that it can not be changed after
>> first font loaded.
>> But I still can not get the current width after scale, since the props
>> of FRAME_FONT also not be changed.
>> [...]
>> I noticed there were some global Lisp_Object such as
>> "f_Vface_font_rescale_alist"/"f_Vface_remapping_alist"/"f_Vface_new_frame_defaults",
>> maybe I can use them, Hope so.
> This will retrieve the numerical ID of the default face on frame F:
>
> int id = lookup_basic_face (F, DEFAULT_FACE_ID);
>
> lookup_basic_face consults f_Vface_remapping_alist. If the value of
> id above is different from DEFAULT_FACE_ID, that means the default
> face was remapped. Then you can get the remapped face like this:
>
> struct face *face = FACE_FROM_ID (F, id);
>
> Now the font of the face is available as
>
> struct font *font = face->font;
>
> And I think FONT_WIDTH (font) will give you the width you want to use
> instead of FRAME_COLUMN_WIDTH.
>
> Again, this is 100% untested. Good luck!
>
>
[-- Attachment #2: emacs-cjk-monospace-v8.patch --]
[-- Type: text/plain, Size: 5524 bytes --]
--- emacs-24.1.50/src/xftfont.c 2012-04-13 00:47:16.703598929 +0800
+++ emacs-24.1.50.cjk/src/xftfont.c 2012-04-13 00:50:02.909608551 +0800
@@ -61,6 +61,8 @@
Display *display;
int screen;
XftFont *xftfont;
+ FRAME_PTR frame; /* hold frame ptr, cjk double width fix need it */
+ int is_cjk; /* Flag to tell if it is CJK font or not. */
};
/* Structure pointed by (struct face *)->extra */
@@ -137,6 +139,62 @@
}
+static int is_cjk_font(struct xftfont_info *);
+static int calc_cjk_padding(int, int);
+static int frame_default_font_width(FRAME_PTR);
+
+/* Check whether the font contains CJK Ideograph 'number one', 0x4E00,
+ It should be ok for Chinese/Japanese font.
+ Or font contains Korean script syllable 'Ka',0xAC00,
+ because Korean fonts may not have any Chinese characters at all.
+ codes from xterm.*/
+static int
+is_cjk_font(struct xftfont_info *xftfont_info)
+{
+ if(XftCharExists(xftfont_info->display, xftfont_info->xftfont, 0x4E00) ||
+ XftCharExists(xftfont_info->display, xftfont_info->xftfont, 0xAC00))
+ return 1;
+ return 0;
+}
+
+/* Caculate the padding according to default font width */
+static int
+calc_cjk_padding(int default_font_width, int char_width)
+{
+ int padding = 0;
+ if( default_font_width == 0 || /* default font is not monospace */
+ char_width < default_font_width || /* almost impossible */
+ char_width == default_font_width) /* already good */
+ return 0;
+ /* get the padding, all cjk symbols is DOUBLE width */
+ padding = default_font_width * 2 - char_width;
+ /* 1, Some old CJK pcf fonts may bigger than 2*default_font_width.
+ 2, User may set a very big font size for script HAN manually.
+ Keep it unchanged, NOT adjust default font width. */
+ return padding > 0 ? padding : 0;
+}
+
+/*
+ Get the width of default font from FRAME_PTR.
+ If it is monospace font, return the space_width(as same as font width)
+ else return 0.
+ font remap can be supported now.
+ Thanks to Eli. */
+static int
+frame_default_font_width(FRAME_PTR f)
+{
+ int id = lookup_basic_face (f, DEFAULT_FACE_ID);
+ struct face *face = FACE_FROM_ID (f, id);
+ if(face && face->font) {
+ Lisp_Object font_object;
+ XSETFONT (font_object, face->font);
+ if(XINT(AREF (font_object, FONT_SPACING_INDEX)) != FONT_SPACING_MONO)
+ return 0;
+ return face->font->space_width;
+ }
+ return 0;
+}
+
static Lisp_Object xftfont_list (Lisp_Object, Lisp_Object);
static Lisp_Object xftfont_match (Lisp_Object, Lisp_Object);
static Lisp_Object xftfont_open (FRAME_PTR, Lisp_Object, int);
@@ -434,6 +492,14 @@
XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents);
font->average_width = (font->space_width + extents.xOff) / 95;
}
+
+ /* to fix CJK double width alignment issue.
+ pass FRAME_PTR to every xftfont_info structure,
+ we can not get it in "xftfont_text_extents". */
+ xftfont_info->frame = f;
+ /* mark it is CJK font or not when font opened,
+ avoid calling "is_cjk_font" many times. */
+ xftfont_info->is_cjk = is_cjk_font(xftfont_info);
UNBLOCK_INPUT;
font->ascent = xftfont->ascent;
@@ -593,20 +659,27 @@
{
struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
XGlyphInfo extents;
-
+ int cjk_padding = 0;
+ int l_padding = 0;
+ int r_padding = 0;
BLOCK_INPUT;
XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code, nglyphs,
&extents);
+ if(xftfont_info->is_cjk)
+ cjk_padding = calc_cjk_padding(frame_default_font_width(xftfont_info->frame), extents.xOff);
+ /* cjk_padding may equals to 0, then all is zero, still ok */
+ l_padding = cjk_padding >> 1; /* get half */
+ r_padding = cjk_padding - l_padding; /* may not divided by 2 exactly */
UNBLOCK_INPUT;
if (metrics)
{
- metrics->lbearing = - extents.x;
- metrics->rbearing = - extents.x + extents.width;
- metrics->width = extents.xOff;
+ metrics->lbearing = - extents.x - l_padding;
+ metrics->rbearing = - extents.x + extents.width + r_padding;
+ metrics->width = extents.xOff + cjk_padding;
metrics->ascent = extents.y;
metrics->descent = extents.height - extents.y;
}
- return extents.xOff;
+ return extents.xOff + cjk_padding;
}
static XftDraw *
@@ -664,9 +737,28 @@
for (i = 0; i < len; i++)
XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
x + i, y, code + i, 1);
- else
- XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
- x, y, code, len);
+ else {
+ if(!xftfont_info->is_cjk)
+ XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont, x, y, code, len);
+ else {
+ /* draw CJK glyphs one by one and adjust the offset */
+ int default_font_width = frame_default_font_width(xftfont_info->frame);
+ for (i = 0; i < len; i++) {
+ int cjk_padding = 0;
+ int offset = 0;
+ XGlyphInfo extents;
+ XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code+i, 1,
+ &extents);
+ cjk_padding = calc_cjk_padding(default_font_width,extents.xOff);
+ if(cjk_padding)
+ offset = default_font_width * i * 2 + (cjk_padding>>1);
+ else
+ offset = extents.xOff * i;
+ XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
+ x+offset, y, code+i, 1);
+ }
+ }
+ }
UNBLOCK_INPUT;
return len;
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-12 17:56 ` 黄建忠
@ 2012-04-12 20:33 ` Stefan Monnier
[not found] ` <4F8782C8.2030005@i-soft.com.cn>
0 siblings, 1 reply; 53+ messages in thread
From: Stefan Monnier @ 2012-04-12 20:33 UTC (permalink / raw)
To: 黄建忠; +Cc: Eli Zaretskii, kanru, emacs-devel
> Now, it works very well with font remapping, rescaling.
BTW, could someone explain to me what this patch intends to do?
Stefan
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
[not found] ` <4F8782C8.2030005@i-soft.com.cn>
@ 2012-04-13 11:42 ` 黄建忠
2012-04-13 12:03 ` 黄建忠
2012-04-13 13:27 ` Stefan Monnier
1 sibling, 1 reply; 53+ messages in thread
From: 黄建忠 @ 2012-04-13 11:42 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Eli Zaretskii, kanru, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 3122 bytes --]
Hi, Stefan,
It seems my mail is rejected, send again.
This patch fix a issue about CJK font alignment with monospace fonts.
The attachment shows before/after situations of same file opened in
Emacs, NOTE the table in org-mode.
As we all know, programmer's editor should use monospace font as it's
default font,
According to http://www.lowing.org/fonts/
/Monospace fonts (Such as Courier or LetterGothic), or "fixed pitch"
fonts, contain characters that all have the same character width,
producing text that can be used to create forms, tabular material or
documents that require exact text line lengths. An example of a fixed
pitch font is Courier 12 pitch, which is a 10 point font that will print
at exactly 12 characters per inch.
/Primarily because the text will align more readily. Especially is areas
like the comment block header.
For ascii users, the default English monospace fonts should be enough
and OK, such as DejaVu Mono, Consolas, Liberation Mono, Monaco etc.
For CJK users, we will encouter a problem.
Normally, we set a default monospace font for Emacs, and let CJK or
other languages font auto-match via fontconfig/Xft.
For example, I user Monaco as default font of Emacs, And when I need to
input CJK characters, Emacs will automatch a proper font for me, For
Chinese, it is "WenQuanYi Zen Hei"; for Japanese, it's "VL Gothic", for
Korean, it's "Batang".
Here is a problem the patch fixed, generally The pixel width of
auto-matched CJK font is not exactly equals to double monospace font
width. mostly, For same font size, the pixel width of CJK font is
smaller than double pixel width of monospace font.
By the way, all CJK glyphs in one CJK font is fixed pitch and double width.
We have some choices here:
1, Use a "so-called real monospace CJK font" as Emacs default font, "a
real monospace CJK font" means the ascii glyphs in font is monospace and
extactly equals to 1/2 of CJK glyph width. But English character's from
most real monospace CJK font looks not so good, and it's also not so
flexible with such settings.
Or 2, Set defferent font size for script HAN, for example , when I set
Emacs default font to Monaco 10, the automatched CJK font is Hei 10, but
the pixelsize of Monaco is 8, the CJK pixelsize is 14, that mean, I need
increase the CJK font size for script HAN like this:
(custom-set-faces '(default ((t (:family "Monaco")))))
(set-fontset-font "fontset-default" 'han "WenQuanYi Zen Hei 12" )
But the CJK characters will looks very big and odd, especially, when we
use them in comments of codes, the big font attracts all my attention:-D.
And such settings also can not support "text-scale" or something else.
This patch try's to fix this issue, calculate the width difference
between default font and CJK fonts, add padding to CJK font width.
Actually, All double width font encounter this problem, but CJK(Script
Han) is notable, since it had a large number of users.
于 2012年04月13日 04:33, Stefan Monnier 写道:
>> Now, it works very well with font remapping, rescaling.
> BTW, could someone explain to me what this patch intends to do?
>
>
> Stefan
>
>
>
[-- Attachment #2: Type: text/html, Size: 4027 bytes --]
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-13 11:42 ` 黄建忠
@ 2012-04-13 12:03 ` 黄建忠
0 siblings, 0 replies; 53+ messages in thread
From: 黄建忠 @ 2012-04-13 12:03 UTC (permalink / raw)
To: Stefan Monnier; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 53 bytes --]
Sorry, forgot the attachments.
--
Huang JianZhong
[-- Attachment #2: result1.png --]
[-- Type: image/png, Size: 162676 bytes --]
[-- Attachment #3: result2.png --]
[-- Type: image/png, Size: 115794 bytes --]
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
[not found] ` <4F8782C8.2030005@i-soft.com.cn>
2012-04-13 11:42 ` 黄建忠
@ 2012-04-13 13:27 ` Stefan Monnier
2012-04-15 5:10 ` Miles Bader
1 sibling, 1 reply; 53+ messages in thread
From: Stefan Monnier @ 2012-04-13 13:27 UTC (permalink / raw)
To: 黄建忠; +Cc: Eli Zaretskii, kanru, emacs-devel
> Here is a problem the patch fixed, generally The pixel width of
> auto-matched CJK font is not exactly equals to double monospace font
> width. mostly, For same font size, the pixel width of CJK font is
> smaller than double pixel width of monospace font.
Ah, I see, thanks. I probably won't benefit much from it, but it seems
like a good feature to have.
Stefan
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-13 13:27 ` Stefan Monnier
@ 2012-04-15 5:10 ` Miles Bader
2012-04-15 13:27 ` 黄建忠
2012-04-15 16:08 ` William Xu
0 siblings, 2 replies; 53+ messages in thread
From: Miles Bader @ 2012-04-15 5:10 UTC (permalink / raw)
To: Stefan Monnier
Cc: 黄建忠, Eli Zaretskii, kanru, emacs-devel
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>> Here is a problem the patch fixed, generally The pixel width of
>> auto-matched CJK font is not exactly equals to double monospace font
>> width. mostly, For same font size, the pixel width of CJK font is
>> smaller than double pixel width of monospace font.
>
> Ah, I see, thanks. I probably won't benefit much from it, but it seems
> like a good feature to have.
BTW, I hope there's a way to disable or tune this... Some CJK fonts seem
to be very small (when rendered at the same size as other characters),
and I think forcing them to be spaced with 2 * the width of the default
font would make CJK characters look weird, with tons of whitespace in
between each character....
Part of the problem, of course, is that it's somewhat difficult / clunky
for the user to customize which fonts get used for different character
sets. There's `set-fontset-font', but I've found it to be sort of hard
to control, as there doesn't seem to be any way of controlling its
interaction with faces...
[Is there a better way?]
Thanks,
-miles
--
"Don't just question authority,
Don't forget to question me."
-- Jello Biafra
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-15 5:10 ` Miles Bader
@ 2012-04-15 13:27 ` 黄建忠
2012-04-15 16:08 ` William Xu
1 sibling, 0 replies; 53+ messages in thread
From: 黄建忠 @ 2012-04-15 13:27 UTC (permalink / raw)
To: Miles Bader; +Cc: Eli Zaretskii, Stefan Monnier, kanru, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 3053 bytes --]
Hi, Miles.
With fontconfig/Xft, emacs fontset setting is almost unnecessary for CJK
users. Applications should leave font auto-matched by fontconfig.
Also the fontset setting will introduce some problems, for example, If I
set a font for script HAN, I need find One font to support All CJK
characters,
and it is almost impossible, auto-matching is a good solution for using
proper font for proper charset.
The default font of Emacs is set to "Monospace 10", that's should be
good and enough for normal users, no more setup should be required.
Also, It's difficult for users to understand the details of "Encoding",
"Charset", "Script Han", "font spec string", etc.
Today, mainstream distributions of *nix always provide proper TrueType
fonts for CJK, mostly, the "small font situation" you mentioned should
not happened.
In fact, I think for these situations, the patch is not a problem, The
font itself is a big problem.
I tried to set font of "script Han" to a smaller size, It seems it can
be accepted, not so weird:-D.
Please refer to the attachment "smallfont.png", the settings is
Monospace 10 and YaHei 8 for script HAN.
If I continue to reduce the fontsize, the chinese characters are almost
unreadable, such setting means nothing for users.
Please refer to the attachment "smallest.png", the settings is Monospace
10, YaHei 4 for script HAN.
And the fix also handle the satuation of "such very small font size", If
the pixelwidth of CJK characters is even smaller than(or equal to) the
pixelwidth of Monospace font, I marked it as "Almost impossible":-D and
will not add space paddings to it.
By the way, the fix didn't affect "fontset setting" of emacs, since it
didn't care about font family or something else, it only cares about
font rendering and alignment.
I hope we can find a better way, vte/xterm/konsole... also suffer from
this issue.
于 2012年04月15日 13:10, Miles Bader 写道:
> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>>> Here is a problem the patch fixed, generally The pixel width of
>>> auto-matched CJK font is not exactly equals to double monospace font
>>> width. mostly, For same font size, the pixel width of CJK font is
>>> smaller than double pixel width of monospace font.
>> Ah, I see, thanks. I probably won't benefit much from it, but it seems
>> like a good feature to have.
> BTW, I hope there's a way to disable or tune this... Some CJK fonts seem
> to be very small (when rendered at the same size as other characters),
> and I think forcing them to be spaced with 2 * the width of the default
> font would make CJK characters look weird, with tons of whitespace in
> between each character....
>
> Part of the problem, of course, is that it's somewhat difficult / clunky
> for the user to customize which fonts get used for different character
> sets. There's `set-fontset-font', but I've found it to be sort of hard
> to control, as there doesn't seem to be any way of controlling its
> interaction with faces...
>
> [Is there a better way?]
>
> Thanks,
>
> -miles
>
--
Huang JianZhong
[-- Attachment #2: smallfont.png --]
[-- Type: image/png, Size: 90693 bytes --]
[-- Attachment #3: smallest.png --]
[-- Type: image/png, Size: 60666 bytes --]
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-15 5:10 ` Miles Bader
2012-04-15 13:27 ` 黄建忠
@ 2012-04-15 16:08 ` William Xu
2012-04-15 22:19 ` Miles Bader
1 sibling, 1 reply; 53+ messages in thread
From: William Xu @ 2012-04-15 16:08 UTC (permalink / raw)
To: emacs-devel
Miles Bader <miles@gnu.org> writes:
> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>>> Here is a problem the patch fixed, generally The pixel width of
>>> auto-matched CJK font is not exactly equals to double monospace font
>>> width. mostly, For same font size, the pixel width of CJK font is
>>> smaller than double pixel width of monospace font.
>>
>> Ah, I see, thanks. I probably won't benefit much from it, but it seems
>> like a good feature to have.
>
> BTW, I hope there's a way to disable or tune this... Some CJK fonts seem
> to be very small (when rendered at the same size as other characters),
> and I think forcing them to be spaced with 2 * the width of the default
> font would make CJK characters look weird, with tons of whitespace in
> between each character....
Why would it look weird? Like the author said, the terminal has rendered
it that way for long. Even on Mac, i find Terminal.app does the same
way. And it is especially useful when i want to align a mix of ASCII
and CJK characters, which is an issue i know many CJK users had
complained.
I made a similar fix on Mac, it also works. Very good!
--
William
http://xwl.appspot.com
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-15 16:08 ` William Xu
@ 2012-04-15 22:19 ` Miles Bader
2012-04-16 0:51 ` 黄建忠
0 siblings, 1 reply; 53+ messages in thread
From: Miles Bader @ 2012-04-15 22:19 UTC (permalink / raw)
To: William Xu; +Cc: emacs-devel
William Xu <william.xwl@gmail.com> writes:
>> BTW, I hope there's a way to disable or tune this... Some CJK fonts seem
>> to be very small (when rendered at the same size as other characters),
>> and I think forcing them to be spaced with 2 * the width of the default
>> font would make CJK characters look weird, with tons of whitespace in
>> between each character....
>
> Why would it look weird?
As I said, because sometimes the CJK font chosen for a given
point-size is very small compared to the ASCII font, the point where
each CJK character is almost as small as a single ASCII character.
[I didn't just make this up, I looked at the fonts being used for my
Emacs on several machines, and thought "hmm, how would this look if
CJK font-spacing was forced to double-width...?"]
> Like the author said, the terminal has rendered it that way for long.
Then the terminal probably does a better job of choosing a CJK font to
match the ASCII font, or simply uses a different ASCII font...
I guess the point is that there are multiple interrelated issues here:
character-spacing, but also font choice.
Ideally the best solution is to automatically choose good matching
fonts (and give the user powerful methods for overriding such
choices).
-miles
--
「寒いね」と話しかければ「寒いね」と答える人のいるあったかさ [俵万智]
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-15 22:19 ` Miles Bader
@ 2012-04-16 0:51 ` 黄建忠
2012-04-16 5:27 ` Miles Bader
0 siblings, 1 reply; 53+ messages in thread
From: 黄建忠 @ 2012-04-16 0:51 UTC (permalink / raw)
To: Miles Bader; +Cc: William Xu, emacs-devel
于 2012年04月16日 06:19, Miles Bader 写道:
> William Xu<william.xwl@gmail.com> writes:
>>> BTW, I hope there's a way to disable or tune this... Some CJK fonts seem
>>> to be very small (when rendered at the same size as other characters),
>>> and I think forcing them to be spaced with 2 * the width of the default
>>> font would make CJK characters look weird, with tons of whitespace in
>>> between each character....
>> Why would it look weird?
> As I said, because sometimes the CJK font chosen for a given
> point-size is very small compared to the ASCII font, the point where
> each CJK character is almost as small as a single ASCII character.
>
> [I didn't just make this up, I looked at the fonts being used for my
> Emacs on several machines, and thought "hmm, how would this look if
> CJK font-spacing was forced to double-width...?"]
Would you please provide some example characters and such a font to help
us make it better?
or If you had a linux environment, you can also try the fix and give
some hints.
I am a native CJK user and know well about Chinese and a little
Japanese/Korean, I really can not understand why shall we use such a
small font?
As I mentioned, such a small character already unreadable, font design
should follow some standards,
If I mean to use size 10, but the font give me a very small glyph like
size 5, these fonts is really a big problem.
Some katakana characters in Japanese may half width, that's OK. as I
said, it already be filtered out.
In emacs, Ctrl-h h shows a multilingual file, the Japanese string
"Japanese (日本語) こんにちは / コンニチハ" in katakana form is half width.
>
>> Like the author said, the terminal has rendered it that way for long.
> Then the terminal probably does a better job of choosing a CJK font to
> match the ASCII font, or simply uses a different ASCII font...
>
> I guess the point is that there are multiple interrelated issues here:
> character-spacing, but also font choice.
Yes, I prefer leave the font auto matching.
>
> Ideally the best solution is to automatically choose good matching
> fonts (and give the user powerful methods for overriding such
> choices).
No such a good font, except use a real CJK monospace fonts, but its
English glyphs look weird.
>
> -miles
>
--
Huang JianZhong
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-16 0:51 ` 黄建忠
@ 2012-04-16 5:27 ` Miles Bader
2012-04-16 5:40 ` 黄建忠
2012-04-18 6:54 ` Kenichi Handa
0 siblings, 2 replies; 53+ messages in thread
From: Miles Bader @ 2012-04-16 5:27 UTC (permalink / raw)
To: 黄建忠; +Cc: William Xu, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 1843 bytes --]
黄建忠 <jianzhong.huang@i-soft.com.cn> writes:
> Would you please provide some example characters and such a font to
> help us make it better?
Here's an example from my (Debian) system; the font I chose in Emacs
is "Droid Sans Mono"; the "x11 size" is 13 [which isn't exactly the
size chosen in the UI; fontconfig sizes and X font sizes seem to be
only loosely related... :( ]
I set the font to "Droid Sans Mono", and the Japanese font Emacs
automatically chose was "きろ字". I don't know _why_ Emacs chose that
font, as other apps don't seem to -- If I select Droid S M in GTK
apps, for instance, they use something much better looking, probably
"Droid Fallback" (which is a matching font for Droid S M).
I've attached an image file showing what this looks like on my
computer.
The things I notice:
(1) The font chosen by Emacs for Japanese might be a bit odd, and
doesn't seem to match what other apps choose.
(2) The "きろ字" font is already pretty widely spaced, maybe near
the limit of readability IMO.
(3) It looks like forcing CJK alignment to 2*ASCII will increase the
width of characters in this font by about 30%. Given the already
very wide spacing, I think the result might look funny.
[ (4) If I grow or shrink the font-size, the ASCII and Japanese grow
by different, and varying amounts (that is, there are obvious
"jumps" in the size increases, and the jumps occur at different
places for the ASCII font and the Japanese font); my guess is that
this is probably due to rounding by the font renderer. So there
will be. ]
Now that I think about it, I'd say that the problem seems to lie more
with Emacs' choice of fonts for Japanese (both the funny automatic
choice, and the lack of good methods for users to tweak it).
Thanks,
-Miles
[-- Attachment #2: CJK / ASCII character alignment with Droid Sans Mono --]
[-- Type: image/png, Size: 17024 bytes --]
[-- Attachment #3: Type: text/plain, Size: 59 bytes --]
--
古池や 蛙飛び込む 水の音 [松尾芭蕉]
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-16 5:27 ` Miles Bader
@ 2012-04-16 5:40 ` 黄建忠
2012-04-16 6:37 ` 黄建忠
2012-04-18 6:54 ` Kenichi Handa
1 sibling, 1 reply; 53+ messages in thread
From: 黄建忠 @ 2012-04-16 5:40 UTC (permalink / raw)
To: Miles Bader; +Cc: William Xu, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 2251 bytes --]
Got it, I will try this font.
by the way, You can add a line to your .emacs.
(set-fontset-font "fontset-default" 'han "FONTFAMILY FONTSIZE" )
replace "FONTFAMILY" and FONTSIZE according to your environment.
And FONTSIZE can be ignored if you had no need to specify a size for
this font.
于 2012年04月16日 13:27, Miles Bader 写道:
> 黄建忠<jianzhong.huang@i-soft.com.cn> writes:
>> Would you please provide some example characters and such a font to
>> help us make it better?
> Here's an example from my (Debian) system; the font I chose in Emacs
> is "Droid Sans Mono"; the "x11 size" is 13 [which isn't exactly the
> size chosen in the UI; fontconfig sizes and X font sizes seem to be
> only loosely related... :( ]
>
> I set the font to "Droid Sans Mono", and the Japanese font Emacs
> automatically chose was "きろ字". I don't know _why_ Emacs chose that
> font, as other apps don't seem to -- If I select Droid S M in GTK
> apps, for instance, they use something much better looking, probably
> "Droid Fallback" (which is a matching font for Droid S M).
>
> I've attached an image file showing what this looks like on my
> computer.
>
> The things I notice:
>
> (1) The font chosen by Emacs for Japanese might be a bit odd, and
> doesn't seem to match what other apps choose.
>
> (2) The "きろ字" font is already pretty widely spaced, maybe near
> the limit of readability IMO.
>
> (3) It looks like forcing CJK alignment to 2*ASCII will increase the
> width of characters in this font by about 30%. Given the already
> very wide spacing, I think the result might look funny.
>
> [ (4) If I grow or shrink the font-size, the ASCII and Japanese grow
> by different, and varying amounts (that is, there are obvious
> "jumps" in the size increases, and the jumps occur at different
> places for the ASCII font and the Japanese font); my guess is that
> this is probably due to rounding by the font renderer. So there
> will be. ]
>
> Now that I think about it, I'd say that the problem seems to lie more
> with Emacs' choice of fonts for Japanese (both the funny automatic
> choice, and the lack of good methods for users to tweak it).
>
> Thanks,
>
> -Miles
>
>
>
--
Huang JianZhong
[-- Attachment #2: Type: text/html, Size: 2866 bytes --]
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-16 5:40 ` 黄建忠
@ 2012-04-16 6:37 ` 黄建忠
2012-04-16 9:21 ` 黄建忠
2012-04-17 0:13 ` Miles Bader
0 siblings, 2 replies; 53+ messages in thread
From: 黄建忠 @ 2012-04-16 6:37 UTC (permalink / raw)
To: emacs-devel
[-- Attachment #1.1: Type: text/plain, Size: 3502 bytes --]
[mail rejected again and again , resend to list]
Hi, Miles.
I had downloaded the font and try it with such settings:
1, LANG=ja_JP.utf8
2, remove all zh/ja fonts existed on my Linux, and just let it match
"kiloji" font.
3, set emacs font size 10 or 13.
And got the result as attachments, It is readable and just looks like
before, but the alignment issue is fixed. (NOTE the alignment of
VERTICAL BAR)
I think you have some misunderstanding about the fix and character width
and font width.
1, although the "kiloji" character width looks as small as monospace
font width, but the real pixel width of the glyph is already wide enough,
It's the font choose to leave too much space left and right of the
character.
2, for Monospace 10, the pixelsize is 14, then it matches a "koliji 10"
with pixelsize 12. that's to say,
*the fix only added ONE pixel left and ONE pixel right.* Can anybody
feel such a little alignment change?
The patch should be good enough for you and I am sure you will never
fell the change of the alignment after the fix.
Do not guess the result and just have a try :-D
于 2012年04月16日 13:40, 黄建忠 写道:
> Got it, I will try this font.
>
> by the way, You can add a line to your .emacs.
> (set-fontset-font "fontset-default" 'han "FONTFAMILY FONTSIZE" )
> replace "FONTFAMILY" and FONTSIZE according to your environment.
> And FONTSIZE can be ignored if you had no need to specify a size for
> this font.
>
> 于 2012年04月16日 13:27, Miles Bader 写道:
>> 黄建忠<jianzhong.huang@i-soft.com.cn> writes:
>>> Would you please provide some example characters and such a font to
>>> help us make it better?
>> Here's an example from my (Debian) system; the font I chose in Emacs
>> is "Droid Sans Mono"; the "x11 size" is 13 [which isn't exactly the
>> size chosen in the UI; fontconfig sizes and X font sizes seem to be
>> only loosely related... :( ]
>>
>> I set the font to "Droid Sans Mono", and the Japanese font Emacs
>> automatically chose was "きろ字". I don't know _why_ Emacs chose that
>> font, as other apps don't seem to -- If I select Droid S M in GTK
>> apps, for instance, they use something much better looking, probably
>> "Droid Fallback" (which is a matching font for Droid S M).
>>
>> I've attached an image file showing what this looks like on my
>> computer.
>>
>> The things I notice:
>>
>> (1) The font chosen by Emacs for Japanese might be a bit odd, and
>> doesn't seem to match what other apps choose.
>>
>> (2) The "きろ字" font is already pretty widely spaced, maybe near
>> the limit of readability IMO.
>>
>> (3) It looks like forcing CJK alignment to 2*ASCII will increase the
>> width of characters in this font by about 30%. Given the already
>> very wide spacing, I think the result might look funny.
>>
>> [ (4) If I grow or shrink the font-size, the ASCII and Japanese grow
>> by different, and varying amounts (that is, there are obvious
>> "jumps" in the size increases, and the jumps occur at different
>> places for the ASCII font and the Japanese font); my guess is that
>> this is probably due to rounding by the font renderer. So there
>> will be. ]
>>
>> Now that I think about it, I'd say that the problem seems to lie more
>> with Emacs' choice of fonts for Japanese (both the funny automatic
>> choice, and the lack of good methods for users to tweak it).
>>
>> Thanks,
>>
>> -Miles
>>
>>
>>
>
>
> --
> Huang JianZhong
--
Huang JianZhong
[-- Attachment #1.2: Type: text/html, Size: 4560 bytes --]
[-- Attachment #2: fontsize10.jpg --]
[-- Type: image/jpeg, Size: 21278 bytes --]
[-- Attachment #3: fontsize13.jpg --]
[-- Type: image/jpeg, Size: 30091 bytes --]
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-16 6:37 ` 黄建忠
@ 2012-04-16 9:21 ` 黄建忠
2012-04-17 2:16 ` 黄建忠
2012-04-17 0:13 ` Miles Bader
1 sibling, 1 reply; 53+ messages in thread
From: 黄建忠 @ 2012-04-16 9:21 UTC (permalink / raw)
To: emacs-devel
[-- Attachment #1.1: Type: text/plain, Size: 4624 bytes --]
Hi, All,
Patch updated, add support for CJK half-width letters.
1, There are some forms in Japanese:
Full-width Hirakana/katakana
Half-width katakana
The width of Half-Width katakana equals to 1/2 of Full-width Katakana
letters.
2, There are also some forms for Korean basic letters. Full-Width
letters and Half-Width letters.
The half-width letters for J/K is ignored in previous patch, since the
width is even smaller than English letters from monospace font.
The updated patch add support for such half-width letters and align it
according to single English glyph width,
Normal CJK glyphs still use 2 * English glyph width as reference.
NOTE the second line in attachments, It shows the result of half-width
katakana before/after the patch applied.
The link below provides a full list of such half-width letters.
http://svn.jacekowski.org/chromium/trunk/third_party/icu/source/data/translit/Fullwidth_Halfwidth.txt
于 2012年04月16日 14:37, 黄建忠 写道:
> [mail rejected again and again , resend to list]
>
> Hi, Miles.
>
> I had downloaded the font and try it with such settings:
>
> 1, LANG=ja_JP.utf8
> 2, remove all zh/ja fonts existed on my Linux, and just let it match
> "kiloji" font.
> 3, set emacs font size 10 or 13.
>
> And got the result as attachments, It is readable and just looks like
> before, but the alignment issue is fixed. (NOTE the alignment of
> VERTICAL BAR)
>
> I think you have some misunderstanding about the fix and character
> width and font width.
>
> 1, although the "kiloji" character width looks as small as monospace
> font width, but the real pixel width of the glyph is already wide enough,
> It's the font choose to leave too much space left and right of the
> character.
>
> 2, for Monospace 10, the pixelsize is 14, then it matches a "koliji
> 10" with pixelsize 12. that's to say,
> *the fix only added ONE pixel left and ONE pixel right.* Can anybody
> feel such a little alignment change?
>
> The patch should be good enough for you and I am sure you will never
> fell the change of the alignment after the fix.
>
> Do not guess the result and just have a try :-D
>
>
> 于 2012年04月16日 13:40, 黄建忠 写道:
>> Got it, I will try this font.
>>
>> by the way, You can add a line to your .emacs.
>> (set-fontset-font "fontset-default" 'han "FONTFAMILY FONTSIZE" )
>> replace "FONTFAMILY" and FONTSIZE according to your environment.
>> And FONTSIZE can be ignored if you had no need to specify a size for
>> this font.
>>
>> 于 2012年04月16日 13:27, Miles Bader 写道:
>>> 黄建忠<jianzhong.huang@i-soft.com.cn> writes:
>>>> Would you please provide some example characters and such a font to
>>>> help us make it better?
>>> Here's an example from my (Debian) system; the font I chose in Emacs
>>> is "Droid Sans Mono"; the "x11 size" is 13 [which isn't exactly the
>>> size chosen in the UI; fontconfig sizes and X font sizes seem to be
>>> only loosely related... :( ]
>>>
>>> I set the font to "Droid Sans Mono", and the Japanese font Emacs
>>> automatically chose was "きろ字". I don't know _why_ Emacs chose that
>>> font, as other apps don't seem to -- If I select Droid S M in GTK
>>> apps, for instance, they use something much better looking, probably
>>> "Droid Fallback" (which is a matching font for Droid S M).
>>>
>>> I've attached an image file showing what this looks like on my
>>> computer.
>>>
>>> The things I notice:
>>>
>>> (1) The font chosen by Emacs for Japanese might be a bit odd, and
>>> doesn't seem to match what other apps choose.
>>>
>>> (2) The "きろ字" font is already pretty widely spaced, maybe near
>>> the limit of readability IMO.
>>>
>>> (3) It looks like forcing CJK alignment to 2*ASCII will increase the
>>> width of characters in this font by about 30%. Given the already
>>> very wide spacing, I think the result might look funny.
>>>
>>> [ (4) If I grow or shrink the font-size, the ASCII and Japanese grow
>>> by different, and varying amounts (that is, there are obvious
>>> "jumps" in the size increases, and the jumps occur at different
>>> places for the ASCII font and the Japanese font); my guess is that
>>> this is probably due to rounding by the font renderer. So there
>>> will be. ]
>>>
>>> Now that I think about it, I'd say that the problem seems to lie more
>>> with Emacs' choice of fonts for Japanese (both the funny automatic
>>> choice, and the lack of good methods for users to tweak it).
>>>
>>> Thanks,
>>>
>>> -Miles
>>>
>>>
>>>
>>
>>
>> --
>> Huang JianZhong
>
>
> --
> Huang JianZhong
--
Huang JianZhong
[-- Attachment #1.2: Type: text/html, Size: 6248 bytes --]
[-- Attachment #2: 2012-04-16-161636_205x195_scrot.png --]
[-- Type: image/png, Size: 30559 bytes --]
[-- Attachment #3: 2012-04-16-161751_197x212_scrot.png --]
[-- Type: image/png, Size: 29810 bytes --]
[-- Attachment #4: emacs-cjk-monospace-v10.patch --]
[-- Type: text/plain, Size: 5814 bytes --]
--- emacs/src/xftfont.c 2012-04-16 16:02:23.621041065 +0800
+++ emacs.cjk/src/xftfont.c 2012-04-16 16:01:33.707037366 +0800
@@ -61,6 +61,8 @@
Display *display;
int screen;
XftFont *xftfont;
+ FRAME_PTR frame; /* hold frame ptr, cjk double width fix need it */
+ int is_cjk; /* Flag to tell if it is CJK font or not. */
};
/* Structure pointed by (struct face *)->extra */
@@ -137,6 +139,68 @@
}
+static int xftfont_is_cjk_font(struct xftfont_info *);
+static int xftfont_get_cjk_padding(int, int, int*);
+static int xftfont_get_default_width(FRAME_PTR);
+
+/* Check whether the font contains CJK Ideograph 'number one', 0x4E00,
+ It should be ok for Chinese/Japanese font.
+ Or font contains Korean script syllable 'Ka',0xAC00,
+ because Korean fonts may not have any Chinese characters at all.
+ codes from xterm.*/
+static int
+xftfont_is_cjk_font(struct xftfont_info *xftfont_info)
+{
+ if(XftCharExists(xftfont_info->display, xftfont_info->xftfont, 0x4E00) ||
+ XftCharExists(xftfont_info->display, xftfont_info->xftfont, 0xAC00))
+ return 1;
+ return 0;
+}
+
+/* Get the padding according to default monospace font width */
+static int
+xftfont_get_cjk_padding(int default_width, int char_width, int *half_width_cjk)
+{
+ int padding = 0;
+ if(half_width_cjk)
+ *half_width_cjk = 0;
+
+ if( default_width == 0 || /* default font is not monospace */
+ char_width == default_width) /* already good */
+ return 0;
+ if( char_width < default_width) { /* almost impossible, but we can handle it */
+ padding = default_width - char_width;
+ if(half_width_cjk)
+ *half_width_cjk = 1;
+ } else /* get the padding, all cjk symbols is DOUBLE width */
+ padding = default_width * 2 - char_width;
+ /* 1, Some old CJK pcf fonts may bigger than 2*default_width.
+ 2, User may set a very big font size for script HAN manually.
+ Keep it unchanged, NOT adjust default font width. */
+ return padding > 0 ? padding : 0;
+}
+
+/*
+ Get the width of default monospace font.
+ If it is monospace font, return the space_width(as same as font width)
+ else return 0.
+ font remap can be supported now.
+ Thanks to Eli. */
+static int
+xftfont_get_default_width(FRAME_PTR f)
+{
+ int id = lookup_basic_face (f, DEFAULT_FACE_ID);
+ struct face *face = FACE_FROM_ID (f, id);
+ if(face && face->font) {
+ Lisp_Object font_object;
+ XSETFONT (font_object, face->font);
+ if(XINT(AREF (font_object, FONT_SPACING_INDEX)) != FONT_SPACING_MONO)
+ return 0;
+ return face->font->space_width;
+ }
+ return 0;
+}
+
static Lisp_Object xftfont_list (Lisp_Object, Lisp_Object);
static Lisp_Object xftfont_match (Lisp_Object, Lisp_Object);
static Lisp_Object xftfont_open (FRAME_PTR, Lisp_Object, int);
@@ -434,6 +498,14 @@
XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents);
font->average_width = (font->space_width + extents.xOff) / 95;
}
+
+ /* to fix CJK double width alignment issue.
+ pass FRAME_PTR to every xftfont_info structure,
+ we can not get it in "xftfont_text_extents". */
+ xftfont_info->frame = f;
+ /* mark it is CJK font or not when font opened,
+ avoid calling "xftfont_is_cjk_font" many times. */
+ xftfont_info->is_cjk = xftfont_is_cjk_font(xftfont_info);
UNBLOCK_INPUT;
font->ascent = xftfont->ascent;
@@ -593,20 +665,27 @@
{
struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
XGlyphInfo extents;
-
+ int cjk_padding = 0;
+ int l_padding = 0;
+ int r_padding = 0;
BLOCK_INPUT;
XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code, nglyphs,
&extents);
+ if(xftfont_info->is_cjk)
+ cjk_padding = xftfont_get_cjk_padding(xftfont_get_default_width(xftfont_info->frame), extents.xOff, NULL);
+ /* cjk_padding may equals to 0, then all is zero, still ok */
+ l_padding = cjk_padding >> 1; /* get half */
+ r_padding = cjk_padding - l_padding; /* may not divided by 2 exactly */
UNBLOCK_INPUT;
if (metrics)
{
- metrics->lbearing = - extents.x;
- metrics->rbearing = - extents.x + extents.width;
- metrics->width = extents.xOff;
+ metrics->lbearing = - extents.x - l_padding;
+ metrics->rbearing = - extents.x + extents.width + r_padding;
+ metrics->width = extents.xOff + cjk_padding;
metrics->ascent = extents.y;
metrics->descent = extents.height - extents.y;
}
- return extents.xOff;
+ return extents.xOff + cjk_padding;
}
static XftDraw *
@@ -664,9 +743,29 @@
for (i = 0; i < len; i++)
XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
x + i, y, code + i, 1);
- else
- XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
- x, y, code, len);
+ else {
+ if(!xftfont_info->is_cjk)
+ XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont, x, y, code, len);
+ else {
+ /* draw CJK glyphs one by one and adjust the offset */
+ int default_width = xftfont_get_default_width(xftfont_info->frame);
+ for (i = 0; i < len; i++) {
+ int cjk_padding = 0;
+ int offset = 0;
+ int half_width_cjk = 0;
+ XGlyphInfo extents;
+ XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code+i, 1,
+ &extents);
+ cjk_padding = xftfont_get_cjk_padding(default_width,extents.xOff, &half_width_cjk);
+ if(cjk_padding)
+ offset = default_width * i * (half_width_cjk ? 1 : 2) + (cjk_padding>>1);
+ else
+ offset = extents.xOff * i;
+ XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
+ x+offset, y, code+i, 1);
+ }
+ }
+ }
UNBLOCK_INPUT;
return len;
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-16 6:37 ` 黄建忠
2012-04-16 9:21 ` 黄建忠
@ 2012-04-17 0:13 ` Miles Bader
2012-04-17 0:39 ` Miles Bader
2012-04-17 1:47 ` 黄建忠
1 sibling, 2 replies; 53+ messages in thread
From: Miles Bader @ 2012-04-17 0:13 UTC (permalink / raw)
To: 黄建忠; +Cc: emacs-devel
黄建忠 <jianzhong.huang@i-soft.com.cn> writes:
> 2, for Monospace 10, the pixelsize is 14, then it matches a "koliji
> 10" with pixelsize 12. that's to say,
> *the fix only added ONE pixel left and ONE pixel right.* Can anybody
> feel such a little alignment change?
Hi,
I tried it again on my home system, which has different fonts
installed.
case 1: size = 13
ASCII: Lucida Sans Typewriter [9 pix per char]
CJK: さざなみ明朝 [12 pix per char]
case 2: size = 11
ASCII: Lucida Sans Typewriter [7 pix per char]
CJK: さざなみ明朝 [10 pix per char]
I think in this case it will add 6 pixels to each CJK character in
case 1, and 4 pixels in case 2, right? That's an increase of 50%
width...
["さざなみ明朝" is actually a very nice and readable font even at
small sizes, because it has built-in hand-tuned bitmaps ...]
> Do not guess the result and just have a try :-D
Fair enough... :]
-miles
--
The secret to creativity is knowing how to hide your sources.
--Albert Einstein
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 0:13 ` Miles Bader
@ 2012-04-17 0:39 ` Miles Bader
2012-04-17 2:00 ` 黄建忠
2012-04-17 9:07 ` James Cloos
2012-04-17 1:47 ` 黄建忠
1 sibling, 2 replies; 53+ messages in thread
From: Miles Bader @ 2012-04-17 0:39 UTC (permalink / raw)
To: 黄建忠; +Cc: emacs-devel
> case 1: size = 13
> ASCII: Lucida Sans Typewriter [9 pix per char]
> CJK: さざなみ明朝 [12 pix per char]
>
> case 2: size = 11
> ASCII: Lucida Sans Typewriter [7 pix per char]
> CJK: さざなみ明朝 [10 pix per char]
p.s. "size" here is what Emacs "C-u C-x =" reports, which is _not_ the
same as the sizes used in the Emacs font dialog... [kinda annoying,
that...]
-miles
--
.Numeric stability is probably not all that important when you're guessing.
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 0:13 ` Miles Bader
2012-04-17 0:39 ` Miles Bader
@ 2012-04-17 1:47 ` 黄建忠
1 sibling, 0 replies; 53+ messages in thread
From: 黄建忠 @ 2012-04-17 1:47 UTC (permalink / raw)
To: Miles Bader; +Cc: emacs-devel
于 2012年04月17日 08:13, Miles Bader 写道:
> 黄建忠<jianzhong.huang@i-soft.com.cn> writes:
>> 2, for Monospace 10, the pixelsize is 14, then it matches a "koliji
>> 10" with pixelsize 12. that's to say,
>> *the fix only added ONE pixel left and ONE pixel right.* Can anybody
>> feel such a little alignment change?
> Hi,
>
> I tried it again on my home system, which has different fonts
> installed.
>
> case 1: size = 13
> ASCII: Lucida Sans Typewriter [9 pix per char]
> CJK: さざなみ明朝 [12 pix per char]
>
> case 2: size = 11
> ASCII: Lucida Sans Typewriter [7 pix per char]
> CJK: さざなみ明朝 [10 pix per char]
>
Please use monospace font, Sans should not be default font of Emacs.
> I think in this case it will add 6 pixels to each CJK character in
> case 1, and 4 pixels in case 2, right? That's an increase of 50%
> width...
According to the pixel values, Yes.
>
> ["さざなみ明朝" is actually a very nice and readable font even at
> small sizes, because it has built-in hand-tuned bitmaps ...]
>> Do not guess the result and just have a try :-D
> Fair enough... :]
>
> -miles
>
--
Huang JianZhong
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 0:39 ` Miles Bader
@ 2012-04-17 2:00 ` 黄建忠
2012-04-17 2:30 ` Miles Bader
2012-04-17 9:07 ` James Cloos
1 sibling, 1 reply; 53+ messages in thread
From: 黄建忠 @ 2012-04-17 2:00 UTC (permalink / raw)
To: Miles Bader; +Cc: emacs-devel
于 2012年04月17日 08:39, Miles Bader 写道:
>> case 1: size = 13
>> ASCII: Lucida Sans Typewriter [9 pix per char]
>> CJK: さざなみ明朝 [12 pix per char]
>>
>> case 2: size = 11
>> ASCII: Lucida Sans Typewriter [7 pix per char]
>> CJK: さざなみ明朝 [10 pix per char]
1, If you use Sans font as default font, the patch will just ignore it
and never adjust the width padding , since it is wrong setting.
2, For Sans font, it's variable pitch, every glyph in the font is
different width.
The C-u C-x = report a font spec string.
Looks like:
xft:-unknown-Monaco-normal-normal-normal-*-17-*-*-*-m-0-iso10646-1 (#x4B)
Note the "17" here is FONT_PIXEL_SIZE from FcPattern of fontconfig, not
Font Size in common sense, It should be same for CJK font and English font.
So Im wondering how you get the pixelsize of fonts?
> p.s. "size" here is what Emacs "C-u C-x =" reports, which is _not_ the
> same as the sizes used in the Emacs font dialog... [kinda annoying,
> that...]
>
> -miles
>
--
Huang JianZhong
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-16 9:21 ` 黄建忠
@ 2012-04-17 2:16 ` 黄建忠
0 siblings, 0 replies; 53+ messages in thread
From: 黄建忠 @ 2012-04-17 2:16 UTC (permalink / raw)
Cc: emacs-devel
[-- Attachment #1.1: Type: text/plain, Size: 5110 bytes --]
Patch update, fix CJK offset calculation in minibuffer after font
rescaling happened.
Font in some buffers will not rescale when
"text-scale-increase/decrease". we need use original FONT_WIDTH as
reference value.
Eli already gives me a hint, it's my fault.
于 2012年04月16日 17:21, 黄建忠 写道:
> Hi, All,
> Patch updated, add support for CJK half-width letters.
>
> 1, There are some forms in Japanese:
> Full-width Hirakana/katakana
> Half-width katakana
> The width of Half-Width katakana equals to 1/2 of Full-width Katakana
> letters.
>
> 2, There are also some forms for Korean basic letters. Full-Width
> letters and Half-Width letters.
>
> The half-width letters for J/K is ignored in previous patch, since the
> width is even smaller than English letters from monospace font.
>
> The updated patch add support for such half-width letters and align it
> according to single English glyph width,
> Normal CJK glyphs still use 2 * English glyph width as reference.
>
> NOTE the second line in attachments, It shows the result of half-width
> katakana before/after the patch applied.
>
> The link below provides a full list of such half-width letters.
> http://svn.jacekowski.org/chromium/trunk/third_party/icu/source/data/translit/Fullwidth_Halfwidth.txt
>
> 于 2012年04月16日 14:37, 黄建忠 写道:
>> [mail rejected again and again , resend to list]
>>
>> Hi, Miles.
>>
>> I had downloaded the font and try it with such settings:
>>
>> 1, LANG=ja_JP.utf8
>> 2, remove all zh/ja fonts existed on my Linux, and just let it match
>> "kiloji" font.
>> 3, set emacs font size 10 or 13.
>>
>> And got the result as attachments, It is readable and just looks like
>> before, but the alignment issue is fixed. (NOTE the alignment of
>> VERTICAL BAR)
>>
>> I think you have some misunderstanding about the fix and character
>> width and font width.
>>
>> 1, although the "kiloji" character width looks as small as monospace
>> font width, but the real pixel width of the glyph is already wide
>> enough,
>> It's the font choose to leave too much space left and right of the
>> character.
>>
>> 2, for Monospace 10, the pixelsize is 14, then it matches a "koliji
>> 10" with pixelsize 12. that's to say,
>> *the fix only added ONE pixel left and ONE pixel right.* Can anybody
>> feel such a little alignment change?
>>
>> The patch should be good enough for you and I am sure you will never
>> fell the change of the alignment after the fix.
>>
>> Do not guess the result and just have a try :-D
>>
>>
>> 于 2012年04月16日 13:40, 黄建忠 写道:
>>> Got it, I will try this font.
>>>
>>> by the way, You can add a line to your .emacs.
>>> (set-fontset-font "fontset-default" 'han "FONTFAMILY FONTSIZE" )
>>> replace "FONTFAMILY" and FONTSIZE according to your environment.
>>> And FONTSIZE can be ignored if you had no need to specify a size for
>>> this font.
>>>
>>> 于 2012年04月16日 13:27, Miles Bader 写道:
>>>> 黄建忠<jianzhong.huang@i-soft.com.cn> writes:
>>>>> Would you please provide some example characters and such a font to
>>>>> help us make it better?
>>>> Here's an example from my (Debian) system; the font I chose in Emacs
>>>> is "Droid Sans Mono"; the "x11 size" is 13 [which isn't exactly the
>>>> size chosen in the UI; fontconfig sizes and X font sizes seem to be
>>>> only loosely related... :( ]
>>>>
>>>> I set the font to "Droid Sans Mono", and the Japanese font Emacs
>>>> automatically chose was "きろ字". I don't know _why_ Emacs chose that
>>>> font, as other apps don't seem to -- If I select Droid S M in GTK
>>>> apps, for instance, they use something much better looking, probably
>>>> "Droid Fallback" (which is a matching font for Droid S M).
>>>>
>>>> I've attached an image file showing what this looks like on my
>>>> computer.
>>>>
>>>> The things I notice:
>>>>
>>>> (1) The font chosen by Emacs for Japanese might be a bit odd, and
>>>> doesn't seem to match what other apps choose.
>>>>
>>>> (2) The "きろ字" font is already pretty widely spaced, maybe near
>>>> the limit of readability IMO.
>>>>
>>>> (3) It looks like forcing CJK alignment to 2*ASCII will increase the
>>>> width of characters in this font by about 30%. Given the already
>>>> very wide spacing, I think the result might look funny.
>>>>
>>>> [ (4) If I grow or shrink the font-size, the ASCII and Japanese grow
>>>> by different, and varying amounts (that is, there are obvious
>>>> "jumps" in the size increases, and the jumps occur at different
>>>> places for the ASCII font and the Japanese font); my guess is that
>>>> this is probably due to rounding by the font renderer. So there
>>>> will be. ]
>>>>
>>>> Now that I think about it, I'd say that the problem seems to lie more
>>>> with Emacs' choice of fonts for Japanese (both the funny automatic
>>>> choice, and the lack of good methods for users to tweak it).
>>>>
>>>> Thanks,
>>>>
>>>> -Miles
>>>>
>>>>
>>>>
>>>
>>>
>>> --
>>> Huang JianZhong
>>
>>
>> --
>> Huang JianZhong
>
>
> --
> Huang JianZhong
--
Huang JianZhong
[-- Attachment #1.2: Type: text/html, Size: 7138 bytes --]
[-- Attachment #2: emacs-cjk-monospace-v12.patch --]
[-- Type: text/plain, Size: 6006 bytes --]
--- emacs/src/xftfont.c 2012-04-16 18:39:33.596738079 +0800
+++ emacs.cjk/src/xftfont.c 2012-04-16 18:40:05.997740449 +0800
@@ -61,6 +61,8 @@
Display *display;
int screen;
XftFont *xftfont;
+ FRAME_PTR frame; /* hold frame ptr, cjk double width fix need it */
+ int is_cjk; /* Flag to tell if it is CJK font or not. */
};
/* Structure pointed by (struct face *)->extra */
@@ -137,6 +139,72 @@
}
+static int xftfont_is_cjk_font(struct xftfont_info *);
+static int xftfont_get_cjk_padding(int, int, int*);
+static int xftfont_get_default_width(FRAME_PTR);
+
+/* Check whether the font contains CJK Ideograph 'number one', 0x4E00,
+ It should be ok for Chinese/Japanese font.
+ Or font contains Korean script syllable 'Ka',0xAC00,
+ because Korean fonts may not have any Chinese characters at all.
+ codes from xterm.*/
+static int
+xftfont_is_cjk_font(struct xftfont_info *xftfont_info)
+{
+ if(XftCharExists(xftfont_info->display, xftfont_info->xftfont, 0x4E00) ||
+ XftCharExists(xftfont_info->display, xftfont_info->xftfont, 0xAC00))
+ return 1;
+ return 0;
+}
+
+/* Get the padding according to default monospace font width */
+static int
+xftfont_get_cjk_padding(int default_width, int char_width, int *half_width_cjk)
+{
+ int padding = 0;
+ if(half_width_cjk)
+ *half_width_cjk = 0;
+
+ if( default_width == 0 || /* default font is not monospace */
+ char_width == default_width) /* already good */
+ return 0;
+ if( char_width < default_width) { /* almost impossible, but we can handle it */
+ padding = default_width - char_width;
+ if(half_width_cjk)
+ *half_width_cjk = 1;
+ } else /* get the padding, all cjk symbols is DOUBLE width */
+ padding = default_width * 2 - char_width;
+ /* 1, Some old CJK pcf fonts may bigger than 2*default_width.
+ 2, User may set a very big font size for script HAN manually.
+ Keep it unchanged, NOT adjust default font width. */
+ return (padding > 0 && padding < default_width) ? padding : 0;
+}
+
+/*
+ Get the width of default monospace font.
+ If it is monospace font, return the space_width(as same as font width)
+ else return 0.
+ font remap can be supported now.
+ Thanks to Eli. */
+static int
+xftfont_get_default_width(FRAME_PTR f)
+{
+ int id = lookup_basic_face (f, DEFAULT_FACE_ID);
+ struct face *face = FACE_FROM_ID (f, id);
+ if(face && face->font) {
+ Lisp_Object font_object;
+ XSETFONT (font_object, face->font);
+ /* not monospace font */
+ if (XINT(AREF (font_object, FONT_SPACING_INDEX)) != FONT_SPACING_MONO)
+ return 0;
+ if(id == DEFAULT_FACE_ID) /* not remapped */
+ return FRAME_SPACE_WIDTH(f);
+ else /* remapped, return new width */
+ return face->font->space_width;
+ }
+ return 0;
+}
+
static Lisp_Object xftfont_list (Lisp_Object, Lisp_Object);
static Lisp_Object xftfont_match (Lisp_Object, Lisp_Object);
static Lisp_Object xftfont_open (FRAME_PTR, Lisp_Object, int);
@@ -434,6 +502,14 @@
XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents);
font->average_width = (font->space_width + extents.xOff) / 95;
}
+
+ /* to fix CJK double width alignment issue.
+ pass FRAME_PTR to every xftfont_info structure,
+ we can not get it in "xftfont_text_extents". */
+ xftfont_info->frame = f;
+ /* mark it is CJK font or not when font opened,
+ avoid calling "xftfont_is_cjk_font" many times. */
+ xftfont_info->is_cjk = xftfont_is_cjk_font(xftfont_info);
UNBLOCK_INPUT;
font->ascent = xftfont->ascent;
@@ -593,20 +669,27 @@
{
struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
XGlyphInfo extents;
-
+ int cjk_padding = 0;
+ int l_padding = 0;
+ int r_padding = 0;
BLOCK_INPUT;
XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code, nglyphs,
&extents);
+ if(xftfont_info->is_cjk)
+ cjk_padding = xftfont_get_cjk_padding(xftfont_get_default_width(xftfont_info->frame), extents.xOff, NULL);
+ /* cjk_padding may equals to 0, then all is zero, still ok */
+ l_padding = cjk_padding >> 1; /* get half */
+ r_padding = cjk_padding - l_padding; /* may not divided by 2 exactly */
UNBLOCK_INPUT;
if (metrics)
{
- metrics->lbearing = - extents.x;
- metrics->rbearing = - extents.x + extents.width;
- metrics->width = extents.xOff;
+ metrics->lbearing = - extents.x - l_padding;
+ metrics->rbearing = - extents.x + extents.width + r_padding;
+ metrics->width = extents.xOff + cjk_padding;
metrics->ascent = extents.y;
metrics->descent = extents.height - extents.y;
}
- return extents.xOff;
+ return extents.xOff + cjk_padding;
}
static XftDraw *
@@ -664,9 +747,29 @@
for (i = 0; i < len; i++)
XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
x + i, y, code + i, 1);
- else
- XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
- x, y, code, len);
+ else {
+ if(!xftfont_info->is_cjk)
+ XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont, x, y, code, len);
+ else {
+ /* draw CJK glyphs one by one and adjust the offset */
+ int default_width = xftfont_get_default_width(xftfont_info->frame);
+ for (i = 0; i < len; i++) {
+ int cjk_padding = 0;
+ int offset = 0;
+ int half_width_cjk = 0;
+ XGlyphInfo extents;
+ XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code+i, 1,
+ &extents);
+ cjk_padding = xftfont_get_cjk_padding(default_width,extents.xOff, &half_width_cjk);
+ if(cjk_padding)
+ offset = default_width * i * (half_width_cjk ? 1 : 2) + (cjk_padding>>1);
+ else
+ offset = extents.xOff * i;
+ XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
+ x+offset, y, code+i, 1);
+ }
+ }
+ }
UNBLOCK_INPUT;
return len;
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 2:00 ` 黄建忠
@ 2012-04-17 2:30 ` Miles Bader
2012-04-17 3:00 ` 黄建忠
0 siblings, 1 reply; 53+ messages in thread
From: Miles Bader @ 2012-04-17 2:30 UTC (permalink / raw)
To: 黄建忠; +Cc: emacs-devel
黄建忠 <jianzhong.huang@i-soft.com.cn> writes:
>>> case 1: size = 13
>>> ASCII: Lucida Sans Typewriter [9 pix per char]
>>> CJK: さざなみ明朝 [12 pix per char]
>>>
>>> case 2: size = 11
>>> ASCII: Lucida Sans Typewriter [7 pix per char]
>>> CJK: さざなみ明朝 [10 pix per char]
>
> 1, If you use Sans font as default font, the patch will just ignore it
> and never adjust the width padding , since it is wrong setting.
>
> 2, For Sans font, it's variable pitch, every glyph in the font is
> different width.
It's "Lucida Sans Typewriter", which is a fixed-pitch font.
> So I'm wondering how you get the pixelsize of fonts?
I used "xzoom" to magnify the display, and counted the pixels... :]
-miles
--
`Suppose Korea goes to the World Cup final against Japan and wins,' Moon said.
`All the past could be forgiven.' [NYT]
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 2:30 ` Miles Bader
@ 2012-04-17 3:00 ` 黄建忠
2012-04-17 4:08 ` Miles Bader
0 siblings, 1 reply; 53+ messages in thread
From: 黄建忠 @ 2012-04-17 3:00 UTC (permalink / raw)
To: Miles Bader; +Cc: emacs-devel
于 2012年04月17日 10:30, Miles Bader 写道:
> 黄建忠<jianzhong.huang@i-soft.com.cn> writes:
>>>> case 1: size = 13
>>>> ASCII: Lucida Sans Typewriter [9 pix per char]
>>>> CJK: さざなみ明朝 [12 pix per char]
>>>>
>>>> case 2: size = 11
>>>> ASCII: Lucida Sans Typewriter [7 pix per char]
>>>> CJK: さざなみ明朝 [10 pix per char]
>> 1, If you use Sans font as default font, the patch will just ignore it
>> and never adjust the width padding , since it is wrong setting.
>>
>> 2, For Sans font, it's variable pitch, every glyph in the font is
>> different width.
> It's "Lucida Sans Typewriter", which is a fixed-pitch font.
>
>> So I'm wondering how you get the pixelsize of fonts?
> I used "xzoom" to magnify the display, and counted the pixels... :]
Wow :-D
But a wrong way to get pixelsize:-(
You have a very BIG BIG BIG misunderstanding of "glyph pixelsize".
Font glyph may leave space around it, so the pixelsize of a font
reported by font rendering subsystem is not just as what it looks, the
space already there should not be dropped.
I explained it when I tried "kiloji" font. as your assumption, the
"kiloji" font would have a big problem with this fix, but it didn't.
>
> -miles
>
--
Huang JianZhong
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 3:00 ` 黄建忠
@ 2012-04-17 4:08 ` Miles Bader
2012-04-17 4:56 ` Werner LEMBERG
0 siblings, 1 reply; 53+ messages in thread
From: Miles Bader @ 2012-04-17 4:08 UTC (permalink / raw)
To: 黄建忠; +Cc: emacs-devel
黄建忠 <jianzhong.huang@i-soft.com.cn> writes:
>>> So I'm wondering how you get the pixelsize of fonts?
>> I used "xzoom" to magnify the display, and counted the pixels... :]
>
> Wow :-D
> But a wrong way to get pixelsize:-(
>
> You have a very BIG BIG BIG misunderstanding of "glyph pixelsize".
That's silly.
It doesn't _matter_ what some definition says somewhere.
In the end, what _actually matters_ is how the characters are
displayed -- and the best way to judge how they are displayed is to
_look at the display_.
[The pixel counts I gave, BTW are actually "advance counts" -- the
number of pixels between the left edge of one character and the left
edge of the next character.]
So the point is that the numbers I have should be accurate in
terms of how the characters are actually displayed.
To reiterate:
1) In case 1, a 20-character sequence of ASCII characters takes 180
pixels to display, and a 10-character sequence of CJK characters
takes 120 pixels to display.
2) So, if you force the CJK characters to fit 2 * ASCII width, then
you obviously need to add (180 - 120) = 60 pixels of extra space
to those 10 CJK characters.
3) That's 6 extra pixels of whitespace (in addition to existing
whitespace) per CJK character.
4) Since each CJK character is 12-pixels wide, that increases the
character advance spacing by 50%...
Anyway, I'll try your patch, and see how it looks in reality.
Thanks,
-miles
--
Zeal, n. A certain nervous disorder afflicting the young and inexperienced.
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 4:08 ` Miles Bader
@ 2012-04-17 4:56 ` Werner LEMBERG
2012-04-17 5:02 ` 黄建忠
2012-04-17 5:52 ` Miles Bader
0 siblings, 2 replies; 53+ messages in thread
From: Werner LEMBERG @ 2012-04-17 4:56 UTC (permalink / raw)
To: miles; +Cc: jianzhong.huang, emacs-devel
> 1) In case 1, a 20-character sequence of ASCII characters takes 180
> pixels to display, and a 10-character sequence of CJK characters
> takes 120 pixels to display.
Mhmm. The silent assumption of making a CJK and ASCII font fit is
that double-width characters are really double width in relation to
single-width characters. In your example, the width of two ASCII
characters is 18px, while one CJK character is 12px. Such two fonts
simply don't fit, and no clever algorithm will be able to make them
ever fit without scaling.[1] Your arguments are thus moot IMHO.
Werner
[1] Not counting a full analysis of all glyphs of a font to check
whether it is possible to compress the advance width horizontally
because the left and right side bearings are large enough to do
that without overlapping.
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 4:56 ` Werner LEMBERG
@ 2012-04-17 5:02 ` 黄建忠
2012-04-17 6:33 ` Miles Bader
2012-04-17 7:03 ` Werner LEMBERG
2012-04-17 5:52 ` Miles Bader
1 sibling, 2 replies; 53+ messages in thread
From: 黄建忠 @ 2012-04-17 5:02 UTC (permalink / raw)
To: miles; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 1409 bytes --]
Hi, Miles.
I tried "Lucida Sans Typewriter" font, It seems Emacs git head(without
cjk patch) had some problems to rendering this font.
See the attachment as reference.
Comparing to normal GTK applications(cairo rendering backend), it's too
wide in Emacs.
I am not sure the problem is related to Emacs or libXft now, but it is a
BUG.
My envs:
libXft-2.3.0 without patch.
fontconfig-2.8.0 without patch.
Freetype-2.4.9 with infinality rendering patchset.
于 2012年04月17日 12:56, Werner LEMBERG 写道:
>> 1) In case 1, a 20-character sequence of ASCII characters takes 180
>> pixels to display, and a 10-character sequence of CJK characters
>> takes 120 pixels to display.
> Mhmm. The silent assumption of making a CJK and ASCII font fit is
> that double-width characters are really double width in relation to
> single-width characters. In your example, the width of two ASCII
> characters is 18px, while one CJK character is 12px. Such two fonts
> simply don't fit, and no clever algorithm will be able to make them
> ever fit without scaling.[1] Your arguments are thus moot IMHO.
>
>
> Werner
>
>
> [1] Not counting a full analysis of all glyphs of a font to check
> whether it is possible to compress the advance width horizontally
> because the left and right side bearings are large enough to do
> that without overlapping.
>
>
>
--
Huang JianZhong
[-- Attachment #2: lucida.jpg --]
[-- Type: image/jpeg, Size: 78045 bytes --]
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 4:56 ` Werner LEMBERG
2012-04-17 5:02 ` 黄建忠
@ 2012-04-17 5:52 ` Miles Bader
2012-04-17 6:10 ` 黄建忠
2012-04-17 6:45 ` Werner LEMBERG
1 sibling, 2 replies; 53+ messages in thread
From: Miles Bader @ 2012-04-17 5:52 UTC (permalink / raw)
To: Werner LEMBERG; +Cc: jianzhong.huang, emacs-devel
Werner LEMBERG <wl@gnu.org> writes:
>> 1) In case 1, a 20-character sequence of ASCII characters takes 180
>> pixels to display, and a 10-character sequence of CJK characters
>> takes 120 pixels to display.
>
> Mhmm. The silent assumption of making a CJK and ASCII font fit is
> that double-width characters are really double width in relation to
> single-width characters. In your example, the width of two ASCII
> characters is 18px, while one CJK character is 12px. Such two fonts
> simply don't fit, and no clever algorithm will be able to make them
> ever fit without scaling.
Er, wait, what?
It can be done trivially, by adding 3 pixels of whitespace on both
sides of every CJK character...
[Which is the source of my concern: that in some cases it might be so
much whitespace that the result looks funny.]
-miles
--
Consult, v.i. To seek another's disapproval of a course already decided on.
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 5:52 ` Miles Bader
@ 2012-04-17 6:10 ` 黄建忠
2012-04-17 7:02 ` Miles Bader
2012-04-17 6:45 ` Werner LEMBERG
1 sibling, 1 reply; 53+ messages in thread
From: 黄建忠 @ 2012-04-17 6:10 UTC (permalink / raw)
To: Miles Bader; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 1383 bytes --]
Miles,
Another try:
Another "Lucida Sans TypeWriter" from Oracle JDK 1.6.
"Sazanami Mincho" from
"http://ja.cooltext.com/Download-Font-%E3%81%95%E3%81%96%E3%81%AA%E3%81%BF%E6%98%8E%E6%9C%9D+Sazanami+Mincho"
The width of this "lucida" font is correct in Emacs, and the font
display had no problem after cjk fix.
Maybe your system have a buggy "Lucida Sans TypeWriter" font, you can
try the lucida font released with JDK.
Hope the problem can be fixed.
于 2012年04月17日 13:52, Miles Bader 写道:
> Werner LEMBERG <wl@gnu.org> writes:
>>> 1) In case 1, a 20-character sequence of ASCII characters takes 180
>>> pixels to display, and a 10-character sequence of CJK characters
>>> takes 120 pixels to display.
>> Mhmm. The silent assumption of making a CJK and ASCII font fit is
>> that double-width characters are really double width in relation to
>> single-width characters. In your example, the width of two ASCII
>> characters is 18px, while one CJK character is 12px. Such two fonts
>> simply don't fit, and no clever algorithm will be able to make them
>> ever fit without scaling.
> Er, wait, what?
>
> It can be done trivially, by adding 3 pixels of whitespace on both
> sides of every CJK character...
>
> [Which is the source of my concern: that in some cases it might be so
> much whitespace that the result looks funny.]
>
> -miles
>
--
Huang JianZhong
[-- Attachment #2: lucida-sazanami.jpg --]
[-- Type: image/jpeg, Size: 39636 bytes --]
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 5:02 ` 黄建忠
@ 2012-04-17 6:33 ` Miles Bader
2012-04-17 7:03 ` Werner LEMBERG
1 sibling, 0 replies; 53+ messages in thread
From: Miles Bader @ 2012-04-17 6:33 UTC (permalink / raw)
To: 黄建忠; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 517 bytes --]
黄建忠 <jianzhong.huang@i-soft.com.cn> writes:
> I tried "Lucida Sans Typewriter" font, It seems Emacs git head(without
> cjk patch) had some problems to rendering this font.
> See the attachment as reference.
>
> Comparing to normal GTK applications(cairo rendering backend), it's too
> wide in Emacs.
>
> I am not sure the problem is related to Emacs or libXft now, but it is a
> BUG.
Hmm, FWIW, it looks OK here (see attached images)... using Emacs recent
trunk with GTK backend....
-miles
[-- Attachment #2: Lucida Sans Typewriter and さざなみ明朝 alignment --]
[-- Type: image/png, Size: 7080 bytes --]
[-- Attachment #3: Lucida Sans Typewriter source code --]
[-- Type: image/png, Size: 11010 bytes --]
[-- Attachment #4: Type: text/plain, Size: 34 bytes --]
--
Do not taunt Happy Fun Ball.
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 5:52 ` Miles Bader
2012-04-17 6:10 ` 黄建忠
@ 2012-04-17 6:45 ` Werner LEMBERG
1 sibling, 0 replies; 53+ messages in thread
From: Werner LEMBERG @ 2012-04-17 6:45 UTC (permalink / raw)
To: miles; +Cc: jianzhong.huang, emacs-devel
>> Mhmm. The silent assumption of making a CJK and ASCII font fit is
>> that double-width characters are really double width in relation to
>> single-width characters. In your example, the width of two ASCII
>> characters is 18px, while one CJK character is 12px. Such two
>> fonts simply don't fit, and no clever algorithm will be able to
>> make them ever fit without scaling.
>
> Er, wait, what?
>
> It can be done trivially, by adding 3 pixels of whitespace on both
> sides of every CJK character...
>
> [Which is the source of my concern: that in some cases it might be
> so much whitespace that the result looks funny.]
Sorry for being imprecise: I don't mean the possibility of making them
technically fit, which gives funny results, as you correctly state. I
rather mean an aesthetic fit.
Werner
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 6:10 ` 黄建忠
@ 2012-04-17 7:02 ` Miles Bader
2012-04-17 8:06 ` Werner LEMBERG
2012-04-17 8:51 ` 黄建忠
0 siblings, 2 replies; 53+ messages in thread
From: Miles Bader @ 2012-04-17 7:02 UTC (permalink / raw)
To: 黄建忠; +Cc: emacs-devel
黄建忠 <jianzhong.huang@i-soft.com.cn> writes:
> Maybe your system have a buggy "Lucida Sans TypeWriter" font, you can
> try the lucida font released with JDK.
> Hope the problem can be fixed.
No, I think my copy of L-S-T is fine here (you can see from the images
I sent in my previous message).
Now that I've seen both, it looks like the issue is that the version
of "Sazanami minchou" in Debian includes hand-tuned bitmaps. These
look much better in many cases, but because there's a limited number
of them, and the font-rendering system prefers bitmaps, it chooses a
slightly smaller size so it can use a bitmap.
The result is as you can see, that the size of CJK characters is
smaller than you might expect from the size specified.
Maybe this is such a rare case that it can be ignored, I dunno, but it
does appear that everything is functioning properly...
-miles
--
Zeal, n. A certain nervous disorder afflicting the young and inexperienced.
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 5:02 ` 黄建忠
2012-04-17 6:33 ` Miles Bader
@ 2012-04-17 7:03 ` Werner LEMBERG
1 sibling, 0 replies; 53+ messages in thread
From: Werner LEMBERG @ 2012-04-17 7:03 UTC (permalink / raw)
To: jianzhong.huang; +Cc: emacs-devel, miles
> Comparing to normal GTK applications (cairo rendering backend), it's
> too wide in Emacs.
This is probably my `fault'. In FreeType 2.4.6, I've applied a patch
which fixed a very longstanding issue of applying non-TrueType metrics
to TrueType fonts. A consequence of this patch was that (a) some
fonts suddenly rendered larger or smaller, and that (b) the advance
width and line heights changed noticeable.[1]
I still think that the patch is correct, making the fonts use the
advance widths and heights as designed, but it seems that many people
don't like this `corrected' appearance; over the years, they have got
used to the (usually) wider appearance. As a consequence, some
GNU/Linux distribution maintainers decided to not work on fixing the
cause (this is, making editors or terminal applications apply
user-defined vertical and horizontal padding, or make the underlying
frameworks provide means for doing that easily). Instead, they are
fixing the symptoms by undoing the FreeType patch in the
distributions...
Werner
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 7:02 ` Miles Bader
@ 2012-04-17 8:06 ` Werner LEMBERG
2012-04-17 8:25 ` Miles Bader
2012-04-17 8:51 ` 黄建忠
1 sibling, 1 reply; 53+ messages in thread
From: Werner LEMBERG @ 2012-04-17 8:06 UTC (permalink / raw)
To: miles; +Cc: jianzhong.huang, emacs-devel
> [...] it looks like the issue is that the version of "Sazanami
> minchou" in Debian includes hand-tuned bitmaps. These look much
> better in many cases, but because there's a limited number of them,
> and the font-rendering system prefers bitmaps, it chooses a slightly
> smaller size so it can use a bitmap.
This is not correct: Bitmap strikes are selected by PPEM only, no
other size is used.
What you are actually observing is a font bug: The bitmap strikes in
sazanami-mincho are buggy, specifying incorrect advance widths for
many PPEM values.
Try the ftview demo program, go to the kana and kanji ranges, then
toggle bitmap strike display with key `b'. You will see `jumping
glyphs' for most PPEM values. Now repeat the same with msmincho.ttc,
and you won't see this effect.
It's probably worth to send a bug report to the people who are
maintaining sazanami-mincho to fix this. All in all, the font is of
really bad quality (I'm not talking of the glyph shapes itself); the
`name' table contains bizarre entries, the version field hasn't been
increased inspite of changes (as preserved in the `FFTM' table, the
`FontForge timestamp' which is not visible for other tools), the
glyphs are unnecessarily big because the outlines aren't properly
simplified, etc., etc.
Note that I've looked at the version which has been modified last at
10-Dec-2011.
Werner
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 8:06 ` Werner LEMBERG
@ 2012-04-17 8:25 ` Miles Bader
2012-04-17 9:06 ` Werner LEMBERG
0 siblings, 1 reply; 53+ messages in thread
From: Miles Bader @ 2012-04-17 8:25 UTC (permalink / raw)
To: Werner LEMBERG; +Cc: jianzhong.huang, emacs-devel
Werner LEMBERG <wl@gnu.org> writes:
> Try the ftview demo program, go to the kana and kanji ranges, then
> toggle bitmap strike display with key `b'. You will see `jumping
> glyphs' for most PPEM values. Now repeat the same with msmincho.ttc,
> and you won't see this effect.
Where is "msmincho.ttc" ?
Thanks,
-miles
--
Mad, adj. Affected with a high degree of intellectual independence; not
conforming to standards of thought, speech, and action derived by the
conformants [sic] from study of themselves; at odds with the majority; in
short, unusual. It is noteworthy that persons are pronounced mad by officials
destitute of evidence that they themselves are sane.
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 7:02 ` Miles Bader
2012-04-17 8:06 ` Werner LEMBERG
@ 2012-04-17 8:51 ` 黄建忠
1 sibling, 0 replies; 53+ messages in thread
From: 黄建忠 @ 2012-04-17 8:51 UTC (permalink / raw)
To: Miles Bader; +Cc: emacs-devel
于 2012年04月17日 15:02, Miles Bader 写道:
> 黄建忠<jianzhong.huang@i-soft.com.cn> writes:
>> Maybe your system have a buggy "Lucida Sans TypeWriter" font, you can
>> try the lucida font released with JDK.
>> Hope the problem can be fixed.
> No, I think my copy of L-S-T is fine here (you can see from the images
> I sent in my previous message).
>
> Now that I've seen both, it looks like the issue is that the version
> of "Sazanami minchou" in Debian includes hand-tuned bitmaps. These
> look much better in many cases, but because there's a limited number
> of them, and the font-rendering system prefers bitmaps, it chooses a
> slightly smaller size so it can use a bitmap.
Yes, I disabled embed-bitmap support in fontconfig, and only tested the
OUTLINE glyphs of "Sazanami mincho".
I also found problems with some old PCF/BDF Chinese fonts, for example,
"Song" and "FangSong" shiped with Xorg.
If I use such a font, the auto-matched Chinese pixelsize is even bigger
than 2 * monospace width.:-(
By the way, some korean PCF fonts also had this problem.
At first, I disable pcf/bdf support in this patch, If it is a pcf/bdf
font, just keep it unchanged.
but this is really not a good idea. for example, "SimSun.ttc"(the
default font of Windowz XP CN version) is a very famous font for
Chinese, almost everyone use it, it provides 9/10/11pt embedded bitmap
"song". A lot of users even can not accept "ClearType" and "YaHei" in
Vizta and Win 7. :-D
>
> The result is as you can see, that the size of CJK characters is
> smaller than you might expect from the size specified.
>
> Maybe this is such a rare case that it can be ignored, I dunno, but it
> does appear that everything is functioning properly...
Yes, I agree, We should try best to keep everything work well.
I consider to ignore PCF/BDF font again in this patch.
>
> -miles
>
--
Huang JianZhong
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 8:25 ` Miles Bader
@ 2012-04-17 9:06 ` Werner LEMBERG
0 siblings, 0 replies; 53+ messages in thread
From: Werner LEMBERG @ 2012-04-17 9:06 UTC (permalink / raw)
To: miles; +Cc: jianzhong.huang, emacs-devel
> Where is "msmincho.ttc"?
Pssst! It's part of [whispering] Windows. Psst!
Werner
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 0:39 ` Miles Bader
2012-04-17 2:00 ` 黄建忠
@ 2012-04-17 9:07 ` James Cloos
2012-04-17 9:27 ` 黄建忠
1 sibling, 1 reply; 53+ messages in thread
From: James Cloos @ 2012-04-17 9:07 UTC (permalink / raw)
To: emacs-devel; +Cc: 黄建忠, Miles Bader
>>>>> "MB" == Miles Bader <miles@gnu.org> writes:
MB> p.s. "size" here is what Emacs "C-u C-x =" reports, which is _not_ the
MB> same as the sizes used in the Emacs font dialog... [kinda annoying, that...]
If that means the size in the XLFD-ish string after "display: by this
font" in the C-u C-x = buffer, that looks to be the pixelheight.
(In my case I get:
xft:-unknown-WenQuanYi Zen Hei-normal-normal-normal-*-21-*-*-*-*-0-iso10646-1 (#x7390)
for the first character in the CC header above.)
The font dialog probably wants the point size.
Things would be easier were Emacs to drop the XLFD-style strings
for xft: and/or fc: prefixed fonts and use fontconfig patterns.
The XLFD-style strings only should be used for actual XLFDs for
X11 server-side fonts.
-JimC
--
James Cloos <cloos@jhcloos.com> OpenPGP: 1024D/ED7DAEA6
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-17 9:07 ` James Cloos
@ 2012-04-17 9:27 ` 黄建忠
0 siblings, 0 replies; 53+ messages in thread
From: 黄建忠 @ 2012-04-17 9:27 UTC (permalink / raw)
To: James Cloos; +Cc: Miles Bader, emacs-devel
于 2012年04月17日 17:07, James Cloos 写道:
>>>>>> "MB" == Miles Bader <miles@gnu.org> writes:
> MB> p.s. "size" here is what Emacs "C-u C-x =" reports, which is _not_ the
> MB> same as the sizes used in the Emacs font dialog... [kinda annoying, that...]
>
> If that means the size in the XLFD-ish string after "display: by this
> font" in the C-u C-x = buffer, that looks to be the pixelheight.
Yes, for xftfont backend, these properties is set according to FcPattern
when "xftfont_open" invoked.
The number here is "FC_PIXEL_SIZE" from a FcPattern.
>
> (In my case I get:
>
> xft:-unknown-WenQuanYi Zen Hei-normal-normal-normal-*-21-*-*-*-*-0-iso10646-1 (#x7390)
>
> for the first character in the CC header above.)
>
> The font dialog probably wants the point size.
>
> Things would be easier were Emacs to drop the XLFD-style strings
> for xft: and/or fc: prefixed fonts and use fontconfig patterns.
>
> The XLFD-style strings only should be used for actual XLFDs for
> X11 server-side fonts.
>
> -JimC
--
Huang JianZhong
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-16 5:27 ` Miles Bader
2012-04-16 5:40 ` 黄建忠
@ 2012-04-18 6:54 ` Kenichi Handa
2012-04-18 8:13 ` 黄建忠
2012-04-18 13:58 ` Miles Bader
1 sibling, 2 replies; 53+ messages in thread
From: Kenichi Handa @ 2012-04-18 6:54 UTC (permalink / raw)
To: Miles Bader; +Cc: jianzhong.huang, william.xwl, emacs-devel
In article <buohawk9rg3.fsf@dhlpc061.dev.necel.com>, Miles Bader <miles@gnu.org> writes:
> I set the font to "Droid Sans Mono", and the Japanese font Emacs
> automatically chose was "きろ字". I don't know _why_ Emacs chose that
> font,
That's because I couldn't use FcFontSetSort because it had a
serious bug when I wrote the relevant code long ago. Could
you please try this patch?
---
Kenichi Handa
handa@m17n.org
=== modified file 'src/ftfont.c'
--- src/ftfont.c 2012-03-19 04:08:07 +0000
+++ src/ftfont.c 2012-04-18 06:44:59 +0000
@@ -123,6 +123,7 @@
{ "big5-0", { 0xF6B1 }, "zh-tw" },
{ "jisx0208.1983-0", { 0x4E55 }, "ja"},
{ "ksc5601.1985-0", { 0xAC00 }, "ko"},
+ { "ksc5601.1987-0", { 0xAC00 }, "ko"},
{ "cns11643.1992-1", { 0xFE32 }, "zh-tw"},
{ "cns11643.1992-2", { 0x4E33, 0x7934 }},
{ "cns11643.1992-3", { 0x201A9 }},
@@ -890,9 +891,10 @@
Lisp_Object val = Qnil, family, adstyle;
int i;
FcPattern *pattern;
- FcFontSet *fontset = NULL;
+ FcFontSet *fontset = NULL, *sorted = NULL;
FcObjectSet *objset = NULL;
FcCharSet *charset;
+ FcResult result;
Lisp_Object chars = Qnil;
char otlayout[15]; /* For "otlayout:XXXX" */
struct OpenTypeSpec *otspec = NULL;
@@ -983,7 +985,12 @@
}
}
#endif
- for (i = 0; i < fontset->nfont; i++)
+ if (FcConfigSubstitute (NULL, pattern, FcMatchPattern) != FcTrue)
+ goto err;
+ FcDefaultSubstitute (pattern);
+ sorted = FcFontSetSort (NULL, &fontset, 1, pattern, FcFalse, NULL, &result);
+
+ for (i = 0; i < sorted->nfont; i++)
{
Lisp_Object entity;
@@ -991,7 +998,7 @@
{
int this;
- if ((FcPatternGetInteger (fontset->fonts[i], FC_SPACING, 0, &this)
+ if ((FcPatternGetInteger (sorted->fonts[i], FC_SPACING, 0, &this)
== FcResultMatch)
&& spacing != this)
continue;
@@ -1002,7 +1009,7 @@
{
FcChar8 *this;
- if (FcPatternGetString (fontset->fonts[i], FC_CAPABILITY, 0, &this)
+ if (FcPatternGetString (sorted->fonts[i], FC_CAPABILITY, 0, &this)
!= FcResultMatch
|| ! strstr ((char *) this, otlayout))
continue;
@@ -1014,7 +1021,7 @@
FcChar8 *file;
OTF *otf;
- if (FcPatternGetString (fontset->fonts[i], FC_FILE, 0, &file)
+ if (FcPatternGetString (sorted->fonts[i], FC_FILE, 0, &file)
!= FcResultMatch)
continue;
otf = OTF_open ((char *) file);
@@ -1035,7 +1042,7 @@
{
int j;
- if (FcPatternGetCharSet (fontset->fonts[i], FC_CHARSET, 0, &charset)
+ if (FcPatternGetCharSet (sorted->fonts[i], FC_CHARSET, 0, &charset)
!= FcResultMatch)
continue;
for (j = 0; j < ASIZE (chars); j++)
@@ -1047,7 +1054,7 @@
}
if (! NILP (adstyle) || langname)
{
- Lisp_Object this_adstyle = get_adstyle_property (fontset->fonts[i]);
+ Lisp_Object this_adstyle = get_adstyle_property (sorted->fonts[i]);
if (! NILP (adstyle)
&& (NILP (this_adstyle)
@@ -1059,7 +1066,7 @@
&& xstrcasecmp (langname, SSDATA (SYMBOL_NAME (this_adstyle))))
continue;
}
- entity = ftfont_pattern_entity (fontset->fonts[i],
+ entity = ftfont_pattern_entity (sorted->fonts[i],
AREF (spec, FONT_EXTRA_INDEX));
if (! NILP (entity))
val = Fcons (entity, val);
@@ -1076,6 +1083,7 @@
FONT_ADD_LOG ("ftfont-list", spec, val);
if (objset) FcObjectSetDestroy (objset);
if (fontset) FcFontSetDestroy (fontset);
+ if (sorted) FcFontSetDestroy (sorted);
if (pattern) FcPatternDestroy (pattern);
return val;
}
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-18 6:54 ` Kenichi Handa
@ 2012-04-18 8:13 ` 黄建忠
2012-04-18 13:58 ` Miles Bader
1 sibling, 0 replies; 53+ messages in thread
From: 黄建忠 @ 2012-04-18 8:13 UTC (permalink / raw)
To: Kenichi Handa; +Cc: william.xwl, emacs-devel, Miles Bader
Not fixed in my OS:
I have the ja "Kiloji" and "VL Gothic" Fonts and zh "YaHei" font
installed in Linux.
And "kiloji" and "VL Gothic" was not added to fontconfig conf files.
1,If the zh fonts exists. no matter whether the ja fonts controlled via
fontconfig conf files or not.
Emacs always try to match zh font first, even under ja_JP.utf8 locale.
But GTK apps will match Japanese font "kiloji" first under ja_JP.utf8.
2,Remove all zh fonts. ja fonts is not controlled via fontconfig conf files.
Emacs will match "kiloji" font first.
All GTK apps also match the "kiloji" font first.
3,Add "VL Gothic" and "kiloji" to fontconfig conf files.
The GTK apps will use "VL Gothic" to display Japanese characters under
ja_JP.utf8.
But Emacs still use "kiloji"
By the way.
CJK font sorting is difficult, since:
1, zh fonts provides almost all ja characters and some basic Korean
letters, we all use "kanji/hanzi" of Chinese.
And lot of "kanji/hanzi" had the same Unicode code.
2, ja fonts provides all ja characters, also some "kanji". some fonts
may provides basic Korean letters.
3, ko fonts may/may not provide "kanji".
That's to say:
1, zh fonts can display ALMOST all ja characters, but not all.
2, ja fonts can display some zh characters, but not all.
Forgive my English writing, hope you can understand:-)
于 2012年04月18日 14:54, Kenichi Handa 写道:
> In article <buohawk9rg3.fsf@dhlpc061.dev.necel.com>, Miles Bader <miles@gnu.org> writes:
>
>> I set the font to "Droid Sans Mono", and the Japanese font Emacs
>> automatically chose was "きろ字". I don't know _why_ Emacs chose that
>> font,
> That's because I couldn't use FcFontSetSort because it had a
> serious bug when I wrote the relevant code long ago. Could
> you please try this patch?
>
> ---
> Kenichi Handa
> handa@m17n.org
>
> === modified file 'src/ftfont.c'
> --- src/ftfont.c 2012-03-19 04:08:07 +0000
> +++ src/ftfont.c 2012-04-18 06:44:59 +0000
> @@ -123,6 +123,7 @@
> { "big5-0", { 0xF6B1 }, "zh-tw" },
> { "jisx0208.1983-0", { 0x4E55 }, "ja"},
> { "ksc5601.1985-0", { 0xAC00 }, "ko"},
> + { "ksc5601.1987-0", { 0xAC00 }, "ko"},
> { "cns11643.1992-1", { 0xFE32 }, "zh-tw"},
> { "cns11643.1992-2", { 0x4E33, 0x7934 }},
> { "cns11643.1992-3", { 0x201A9 }},
> @@ -890,9 +891,10 @@
> Lisp_Object val = Qnil, family, adstyle;
> int i;
> FcPattern *pattern;
> - FcFontSet *fontset = NULL;
> + FcFontSet *fontset = NULL, *sorted = NULL;
> FcObjectSet *objset = NULL;
> FcCharSet *charset;
> + FcResult result;
> Lisp_Object chars = Qnil;
> char otlayout[15]; /* For "otlayout:XXXX" */
> struct OpenTypeSpec *otspec = NULL;
> @@ -983,7 +985,12 @@
> }
> }
> #endif
> - for (i = 0; i < fontset->nfont; i++)
> + if (FcConfigSubstitute (NULL, pattern, FcMatchPattern) != FcTrue)
> + goto err;
> + FcDefaultSubstitute (pattern);
> + sorted = FcFontSetSort (NULL, &fontset, 1, pattern, FcFalse, NULL, &result);
> +
> + for (i = 0; i < sorted->nfont; i++)
> {
> Lisp_Object entity;
>
> @@ -991,7 +998,7 @@
> {
> int this;
>
> - if ((FcPatternGetInteger (fontset->fonts[i], FC_SPACING, 0, &this)
> + if ((FcPatternGetInteger (sorted->fonts[i], FC_SPACING, 0, &this)
> == FcResultMatch)
> && spacing != this)
> continue;
> @@ -1002,7 +1009,7 @@
> {
> FcChar8 *this;
>
> - if (FcPatternGetString (fontset->fonts[i], FC_CAPABILITY, 0, &this)
> + if (FcPatternGetString (sorted->fonts[i], FC_CAPABILITY, 0, &this)
> != FcResultMatch
> || ! strstr ((char *) this, otlayout))
> continue;
> @@ -1014,7 +1021,7 @@
> FcChar8 *file;
> OTF *otf;
>
> - if (FcPatternGetString (fontset->fonts[i], FC_FILE, 0, &file)
> + if (FcPatternGetString (sorted->fonts[i], FC_FILE, 0, &file)
> != FcResultMatch)
> continue;
> otf = OTF_open ((char *) file);
> @@ -1035,7 +1042,7 @@
> {
> int j;
>
> - if (FcPatternGetCharSet (fontset->fonts[i], FC_CHARSET, 0, &charset)
> + if (FcPatternGetCharSet (sorted->fonts[i], FC_CHARSET, 0, &charset)
> != FcResultMatch)
> continue;
> for (j = 0; j < ASIZE (chars); j++)
> @@ -1047,7 +1054,7 @@
> }
> if (! NILP (adstyle) || langname)
> {
> - Lisp_Object this_adstyle = get_adstyle_property (fontset->fonts[i]);
> + Lisp_Object this_adstyle = get_adstyle_property (sorted->fonts[i]);
>
> if (! NILP (adstyle)
> && (NILP (this_adstyle)
> @@ -1059,7 +1066,7 @@
> && xstrcasecmp (langname, SSDATA (SYMBOL_NAME (this_adstyle))))
> continue;
> }
> - entity = ftfont_pattern_entity (fontset->fonts[i],
> + entity = ftfont_pattern_entity (sorted->fonts[i],
> AREF (spec, FONT_EXTRA_INDEX));
> if (! NILP (entity))
> val = Fcons (entity, val);
> @@ -1076,6 +1083,7 @@
> FONT_ADD_LOG ("ftfont-list", spec, val);
> if (objset) FcObjectSetDestroy (objset);
> if (fontset) FcFontSetDestroy (fontset);
> + if (sorted) FcFontSetDestroy (sorted);
> if (pattern) FcPatternDestroy (pattern);
> return val;
> }
>
>
>
--
Huang JianZhong
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2012-04-18 6:54 ` Kenichi Handa
2012-04-18 8:13 ` 黄建忠
@ 2012-04-18 13:58 ` Miles Bader
1 sibling, 0 replies; 53+ messages in thread
From: Miles Bader @ 2012-04-18 13:58 UTC (permalink / raw)
To: Kenichi Handa; +Cc: jianzhong.huang, william.xwl, emacs-devel
2012年4月18日15:54 Kenichi Handa <handa.kenichi@aist.go.jp>:
> In article <buohawk9rg3.fsf@dhlpc061.dev.necel.com>, Miles Bader <miles@gnu.org> writes:
>
>> I set the font to "Droid Sans Mono", and the Japanese font Emacs
>> automatically chose was "きろ字". I don't know _why_ Emacs chose that
>> font,
>
> That's because I couldn't use FcFontSetSort because it had a
> serious bug when I wrote the relevant code long ago. Could
> you please try this patch?
I tried the patch, and the result seem much better: On my home
machine, Emacs now defaults to a Japanese font which is the same as
gedit, and looks quite good (whereas without the patch, Emacs picks a
font which is still decent looking, but doesn't match the ASCII font
very well).
[On my work machine, it's a little less clear what's going on: with
the patch, Emacs picks a nicer looking Japanese font, but it doesn't
seem to be the same font gedit picks...]
One thing I noticed, BTW: gedit, when using a fixed-pitch default
font, _doesn't_ force CJK characters to be 2*the width of ASCII
characters (in fact, with your ftfont patch, the display of the
current Emacs seems to match the display of gedit pretty much
exactly...).
So I'd say this patch seems an improvement over the current behavior...
-miles
--
Cat is power. Cat is peace.
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
@ 2014-04-28 5:35 JunJie Nan
2014-04-29 5:39 ` Stefan Monnier
2014-04-29 20:41 ` Liang Wang
0 siblings, 2 replies; 53+ messages in thread
From: JunJie Nan @ 2014-04-28 5:35 UTC (permalink / raw)
To: emacs-devel
[-- Attachment #1.1: Type: text/plain, Size: 254 bytes --]
Do not know why the patch is still not installed, although from the
discussion thread nobody oppose it indeed.
Below is an updated version based on current stream. It still works well.
--
Cheers
Jun Jie Nan
∧ ∧︵
ミ^ō^ミ灬)~
[-- Attachment #1.2: Type: text/html, Size: 345 bytes --]
[-- Attachment #2: emacs_src_xftfont.patch --]
[-- Type: text/x-patch, Size: 7057 bytes --]
diff --git a/src/xftfont.c b/src/xftfont.c
index 18c180f..2020b4f 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -60,6 +60,8 @@ struct xftfont_info
Display *display;
XftFont *xftfont;
unsigned x_display_id;
+ struct frame *frame; /* hold frame ptr, cjk double width fix need it */
+ int is_cjk; /* Flag to tell if it is CJK font or not. */
};
/* Structure pointed by (struct face *)->extra */
@@ -133,6 +135,83 @@ xftfont_get_colors (struct frame *f, struct face *face, GC gc,
}
+/* Check whether the font contains CJK Ideograph 'number one', 0x4E00,
+ It should be ok for Chinese/Japanese font.
+ Or font contains Korean script syllable 'Ka',0xAC00,
+ because Korean fonts may not have any Chinese characters at all.
+ codes from xterm.*/
+static int
+xftfont_is_cjk_font(struct xftfont_info *xftfont_info)
+{
+ if(XftCharExists(xftfont_info->display, xftfont_info->xftfont, 0x4E00) ||
+ XftCharExists(xftfont_info->display, xftfont_info->xftfont, 0xAC00))
+ return 1;
+ return 0;
+}
+
+/* Get the padding according to default monospace font width */
+static int
+xftfont_get_cjk_padding(int default_width, int char_width, int *half_width_cjk)
+{
+ int padding = 0;
+ if(half_width_cjk)
+ *half_width_cjk = 0;
+
+ if( default_width == 0 || /* something wrong */
+ default_width == -1 || /* default font is not monospace */
+ char_width == default_width) /* already good */
+ return 0;
+ if( char_width < default_width) {
+ /* almost impossible, but we can handle it */
+ padding = default_width - char_width;
+ if(half_width_cjk)
+ *half_width_cjk = 1;
+ } else /* get the padding, all cjk symbols is DOUBLE width */
+ padding = default_width * 2 - char_width;
+ /* 1, Some old CJK pcf fonts may bigger than 2*default_width.
+ 2, User may set a very big font size for script HAN manually.
+ Keep it unchanged, NOT adjust default font width. */
+ return (padding > 0 && padding < default_width) ? padding : 0;
+}
+
+/* Get the font width of monospace font.
+ Something wrong: return 0;
+ Default is not monospace: return -1;
+ Otherwise: return monospace font width; */
+static int
+xftfont_get_default_width(struct xftfont_info *xftfont_info)
+{
+ Lisp_Object font_object;
+ double request_pixel_size;
+ struct frame *frame = xftfont_info->frame;
+ FcPattern * pattern = xftfont_info->xftfont->pattern;
+ int id = lookup_basic_face (frame, DEFAULT_FACE_ID);
+ struct face *face = FACE_FROM_ID (frame, id);
+ if(!face && !face->font)
+ return 0;
+ XSETFONT (font_object, face->font);
+ /* default font is not monospace */
+ if (XINT(AREF (font_object, FONT_SPACING_INDEX)) != FONT_SPACING_MONO)
+ return -1;
+ if(FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &request_pixel_size) != FcResultMatch)
+ return 0;
+ /* the font of minibuf/modeline never changed when rescaling.
+ it's a little bit difficult to determine where the xftfont draw to.
+ for example, when use mule/leim to input some CJK text.
+ it will draw on the selected frame and minibuf(candidate string).
+ by the way, the 'int' conversion should be ok. */
+ if(FRAME_FONT(frame)->pixel_size == (int)request_pixel_size)
+ return FRAME_FONT(frame)->space_width;
+ /* User may set a fixed font size for script han manually,
+ the font will not rescale when issue rescaling,
+ should not ajust the width offset and avoid to make it too wide.
+ its alignment will be wrong, but let's respect user settings.*/
+ if(face->font->pixel_size != (int)request_pixel_size)
+ return FRAME_FONT(frame)->space_width;
+ /* otherwise return the current font width */
+ return face->font->space_width;
+}
+
struct font_driver xftfont_driver;
static Lisp_Object
@@ -420,6 +499,15 @@ xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
XftTextExtents8 (display, xftfont, ascii_printable + 1, 94, &extents);
font->average_width = (font->space_width + extents.xOff) / 95;
}
+
+ /* to fix CJK double width alignment issue.
+ pass FRAME_PTR to every xftfont_info structure,
+ we can not get it in "xftfont_text_extents". */
+ xftfont_info->frame = f;
+ /* mark it is CJK font or not when font opened,
+ avoid calling "xftfont_is_cjk_font" many times. */
+ xftfont_info->is_cjk = xftfont_is_cjk_font(xftfont_info);
+
unblock_input ();
font->ascent = xftfont->ascent;
@@ -588,19 +676,29 @@ xftfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct
struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
XGlyphInfo extents;
+ int cjk_padding = 0;
+ int l_padding = 0;
+ int r_padding = 0;
+
block_input ();
XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code, nglyphs,
&extents);
+ if(xftfont_info->is_cjk)
+ cjk_padding = xftfont_get_cjk_padding(xftfont_get_default_width(xftfont_info), extents.xOff, NULL);
+ /* cjk_padding may equals to 0, then all is zero, still ok */
+ l_padding = cjk_padding >> 1; /* get half */
+ r_padding = cjk_padding - l_padding; /* may not divided by 2 exactly */
+
unblock_input ();
if (metrics)
{
- metrics->lbearing = - extents.x;
- metrics->rbearing = - extents.x + extents.width;
- metrics->width = extents.xOff;
+ metrics->lbearing = - extents.x - l_padding;
+ metrics->rbearing = - extents.x + extents.width + r_padding;
+ metrics->width = extents.xOff + cjk_padding;
metrics->ascent = extents.y;
metrics->descent = extents.height - extents.y;
}
- return extents.xOff;
+ return extents.xOff + cjk_padding;
}
static XftDraw *
@@ -658,9 +756,28 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y,
for (i = 0; i < len; i++)
XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
x + i, y, code + i, 1);
- else
- XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
- x, y, code, len);
+ else {
+ int default_width = xftfont_get_default_width(xftfont_info);
+ if(!xftfont_info->is_cjk || default_width == -1) /* not cjk or default not monospace */
+ XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont, x, y, code, len);
+ else /* draw CJK glyphs one by one and adjust the offset */
+ for (i = 0; i < len; i++) {
+ int cjk_padding = 0;
+ int offset = 0;
+ int half_width_cjk = 0;
+ XGlyphInfo extents;
+ XftGlyphExtents (xftfont_info->display, xftfont_info->xftfont, code+i, 1,
+ &extents);
+ cjk_padding = xftfont_get_cjk_padding(default_width,extents.xOff, &half_width_cjk);
+ if(cjk_padding)
+ offset = default_width * i * (half_width_cjk ? 1 : 2) + (cjk_padding>>1);
+ else
+ offset = extents.xOff * i;
+ XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
+ x+offset, y, code+i, 1);
+ }
+ }
+
unblock_input ();
return len;
^ permalink raw reply related [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2014-04-28 5:35 JunJie Nan
@ 2014-04-29 5:39 ` Stefan Monnier
2014-04-29 6:36 ` Jan D.
2014-04-29 8:16 ` Thien-Thi Nguyen
2014-04-29 20:41 ` Liang Wang
1 sibling, 2 replies; 53+ messages in thread
From: Stefan Monnier @ 2014-04-29 5:39 UTC (permalink / raw)
To: JunJie Nan; +Cc: emacs-devel
> Do not know why the patch is still not installed, although from the
> discussion thread nobody oppose it indeed.
Sorry, I can't remember seeing your patch before, I must have overlooked
it. Is it related to http://debbugs.gnu.org/10179?
This said, I don't know much of anything about the font drivers, so
I can't really comment on the substance of the code, but while waiting
for someone like Jan or Handa to look at it, I can give you some trivial
cosmetic recommendations (most of them documented in the "GNU Coding
Standards").
If you resubmit a new patch, I recommend you send it to
bug-gnu-emacs@gnu.org (so that it gets a tracking number) or directly to
10179@debbugs.gnu.org if it's related to that bug.
> + struct frame *frame; /* hold frame ptr, cjk double width fix need it */
Please capitalize and punctuate your comments.
> + int is_cjk; /* Flag to tell if it is CJK font or not. */
Thanks for capitalizing and punctuating this comment, this one is good.
We usually prefer to two spaces after the final ".", in case you feel
like polishing it yet a bit more.
> + because Korean fonts may not have any Chinese characters at all.
> + codes from xterm.*/
Here we do need spacing (ideally two spaces) between "." and "*/"
I don't understand exactly what is meant by "codes from xterm".
Maybe that should be "Code inspired by similar logic in XTerm"?
> +static int
> +xftfont_is_cjk_font(struct xftfont_info *xftfont_info)
Always put a space before the open parenthesis.
> +{
> + if(XftCharExists(xftfont_info->display, xftfont_info->xftfont, 0x4E00) ||
> + XftCharExists(xftfont_info->display, xftfont_info->xftfont, 0xAC00))
Same here. Additionally, please but the line before "||" rather than after.
> + return 1;
> + return 0;
Please make the return type "bool", then. And use "true" and "false"
rather than 1 and 0. Also, you can apply eta-reduction to the above
code and just write
return (XftCharExists (xftfont_info->display, xftfont_info->xftfont, 0x4E00)
|| XftCharExists (xftfont_info->display, xftfont_info->xftfont, 0xAC00));
[ Tho that would step over the 80 columns limit, so you may then want to
introduce a local var to hold xftfont_info->display, maybe. ]
> + if(half_width_cjk)
> + *half_width_cjk = 0;
I think half_width_cjk should be a pointer to "bool" and we should use
"false" here.
> + if( default_width == 0 || /* something wrong */
Please don't put a space after an open paren (but do put one before).
> + if( char_width < default_width) {
The "{" should be on a line of its own.
> + } else /* get the padding, all cjk symbols is DOUBLE width */
And the "}" should also be on its own line.
> + xftfont_info->is_cjk = xftfont_is_cjk_font(xftfont_info);
`is_cjk' should be a `bool' field.
Stefan
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2014-04-29 5:39 ` Stefan Monnier
@ 2014-04-29 6:36 ` Jan D.
2014-04-29 8:16 ` Thien-Thi Nguyen
1 sibling, 0 replies; 53+ messages in thread
From: Jan D. @ 2014-04-29 6:36 UTC (permalink / raw)
To: Stefan Monnier; +Cc: JunJie Nan, emacs-devel
Hello.
Stefan Monnier skrev 2014-04-29 07:39:
>> Do not know why the patch is still not installed, although from the
>> discussion thread nobody oppose it indeed.
>
> Sorry, I can't remember seeing your patch before, I must have overlooked
> it. Is it related to http://debbugs.gnu.org/10179?
The discussion was in 2012, here is the previous explanation:
http://lists.gnu.org/archive/html/emacs-devel/2012-04/msg00370.html
>
> This said, I don't know much of anything about the font drivers, so
> I can't really comment on the substance of the code, but while waiting
> for someone like Jan or Handa to look at it, I can give you some trivial
> cosmetic recommendations (most of them documented in the "GNU Coding
> Standards").
As I don't use CJK, I'm not qualified to comment more than on code
style, and you already did that.
I would however rather see that frame was not part of the struct
xftfont_info. It is only used in xftfont_get_cjk_padding. You can call
that function at font open time, and store the value in a cjk_padding
member in xftfont_info.
Jan D.
>
> If you resubmit a new patch, I recommend you send it to
> bug-gnu-emacs@gnu.org (so that it gets a tracking number) or directly to
> 10179@debbugs.gnu.org if it's related to that bug.
>
>> + struct frame *frame; /* hold frame ptr, cjk double width fix need it */
>
> Please capitalize and punctuate your comments.
>
>> + int is_cjk; /* Flag to tell if it is CJK font or not. */
>
> Thanks for capitalizing and punctuating this comment, this one is good.
> We usually prefer to two spaces after the final ".", in case you feel
> like polishing it yet a bit more.
>
>> + because Korean fonts may not have any Chinese characters at all.
>> + codes from xterm.*/
>
> Here we do need spacing (ideally two spaces) between "." and "*/"
> I don't understand exactly what is meant by "codes from xterm".
> Maybe that should be "Code inspired by similar logic in XTerm"?
>
>> +static int
>> +xftfont_is_cjk_font(struct xftfont_info *xftfont_info)
>
> Always put a space before the open parenthesis.
>
>> +{
>> + if(XftCharExists(xftfont_info->display, xftfont_info->xftfont, 0x4E00) ||
>> + XftCharExists(xftfont_info->display, xftfont_info->xftfont, 0xAC00))
>
> Same here. Additionally, please but the line before "||" rather than after.
>
>> + return 1;
>> + return 0;
>
> Please make the return type "bool", then. And use "true" and "false"
> rather than 1 and 0. Also, you can apply eta-reduction to the above
> code and just write
>
> return (XftCharExists (xftfont_info->display, xftfont_info->xftfont, 0x4E00)
> || XftCharExists (xftfont_info->display, xftfont_info->xftfont, 0xAC00));
>
> [ Tho that would step over the 80 columns limit, so you may then want to
> introduce a local var to hold xftfont_info->display, maybe. ]
>
>> + if(half_width_cjk)
>> + *half_width_cjk = 0;
>
> I think half_width_cjk should be a pointer to "bool" and we should use
> "false" here.
>
>> + if( default_width == 0 || /* something wrong */
>
> Please don't put a space after an open paren (but do put one before).
>
>> + if( char_width < default_width) {
>
> The "{" should be on a line of its own.
>
>> + } else /* get the padding, all cjk symbols is DOUBLE width */
>
> And the "}" should also be on its own line.
>
>> + xftfont_info->is_cjk = xftfont_is_cjk_font(xftfont_info);
>
> `is_cjk' should be a `bool' field.
>
>
> Stefan
>
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2014-04-29 5:39 ` Stefan Monnier
2014-04-29 6:36 ` Jan D.
@ 2014-04-29 8:16 ` Thien-Thi Nguyen
1 sibling, 0 replies; 53+ messages in thread
From: Thien-Thi Nguyen @ 2014-04-29 8:16 UTC (permalink / raw)
To: emacs-devel
[-- Attachment #1.1: Type: text/plain, Size: 797 bytes --]
() Stefan Monnier <monnier@iro.umontreal.ca>
() Tue, 29 Apr 2014 01:39:39 -0400
> + return 1;
> + return 0;
Please make the return type "bool", then. And use "true" and "false"
rather than 1 and 0. Also, you can apply eta-reduction to the above
code and just write
return (XftCharExists (xftfont_info->display, xftfont_info->xftfont, 0x4E00)
|| XftCharExists (xftfont_info->display, xftfont_info->xftfont, 0xAC00));
[ Tho that would step over the 80 columns limit, so you may then want to
introduce a local var to hold xftfont_info->display, maybe. ]
Another wrinkle is func ‘XftCharExists’ returns ‘FcBool’, so to be
excruciatingly correct, we would want to compare each call's rv against
‘FcTrue’, something like:
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: Type: text/x-c++src, Size: 137 bytes --]
#define EXISTS(c) \
(FcTrue == XftCharExists (i->display, i->xftfont, c))
return EXISTS (0x4E00) || EXISTS (0xAC00);
#undef EXISTS
[-- Attachment #1.3: Type: text/plain, Size: 583 bytes --]
(I'm a fan of local macros (#define/#undef inside a function), but
that's inappropriate for Emacs, it seems. Hmm, i see one other call to
‘XftCharExists’ in that file, so maybe a top-level macro is warranted.)
Also, although we could use ‘(FcChar32) c’ as third arg, that's probably
not a good idea; better to let callers cast if need be.
--
Thien-Thi Nguyen
GPG key: 4C807502
(if you're human and you know it)
read my lisp: (responsep (questions 'technical)
(not (via 'mailing-list)))
=> nil
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2014-04-28 5:35 JunJie Nan
2014-04-29 5:39 ` Stefan Monnier
@ 2014-04-29 20:41 ` Liang Wang
1 sibling, 0 replies; 53+ messages in thread
From: Liang Wang @ 2014-04-29 20:41 UTC (permalink / raw)
To: JunJie Nan; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 690 bytes --]
On Sun, Apr 27, 2014 at 10:35 PM, JunJie Nan <nanjunjie@gmail.com> wrote:
> Do not know why the patch is still not installed, although from the
> discussion thread nobody oppose it indeed.
>
Thanks for your patch. I actually had used the original patch as long
as I can apply it to make org-table aligned.
But there is a bug on displaying Chinese double dash. When I switch
to other buffer and switch back, it looks wrong. I attached both
screenshots and I draw a red line under Chinese double dash in the
correct one.
> Below is an updated version based on current stream. It still works well.
>
>
> --
> Cheers
> Jun Jie Nan
> ∧ ∧︵
> ミ^ō^ミ灬)~
[-- Attachment #2: correct-cjk-display.png --]
[-- Type: image/png, Size: 22650 bytes --]
[-- Attachment #3: wrong-cjk-display.png --]
[-- Type: image/png, Size: 21969 bytes --]
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
@ 2014-04-30 2:00 Hui Liu
2014-04-30 17:08 ` Liang Wang
0 siblings, 1 reply; 53+ messages in thread
From: Hui Liu @ 2014-04-30 2:00 UTC (permalink / raw)
To: netcasper; +Cc: emacs-devel
> But there is a bug on displaying Chinese double dash. When I switch
> to other buffer and switch back, it looks wrong. I attached both
> screenshots and I draw a red line under Chinese double dash in the
> correct one.
I don't think it is a bug of the patch. The font you used looks like
WenQuanYi Micro Hei, so I test a dozen other Chinese fonts. ONLY
WenQuanYi fonts have this problem.
The reason is the some characters (e.g. Chinese punctuations and Greek
letters) in WenQuanYi fonts are halfwidth. I know little about fonts,
so I doubt if it is a bug of WenQuanYi because these characters in
other Chinese fonts are all fullwidth.
Since these characters are included in the symbol charset, You can
simply leave this charset to the default English font. Or use any
other Chinese fonts except WenQuanYi.
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
2014-04-30 2:00 A patch for enforcing double-width CJK character display Hui Liu
@ 2014-04-30 17:08 ` Liang Wang
0 siblings, 0 replies; 53+ messages in thread
From: Liang Wang @ 2014-04-30 17:08 UTC (permalink / raw)
To: Hui Liu; +Cc: emacs-devel
On Tue, Apr 29, 2014 at 7:00 PM, Hui Liu <liuhui.zy@gmail.com> wrote:
>> But there is a bug on displaying Chinese double dash. When I switch
>> to other buffer and switch back, it looks wrong. I attached both
>> screenshots and I draw a red line under Chinese double dash in the
>> correct one.
>
> I don't think it is a bug of the patch. The font you used looks like
> WenQuanYi Micro Hei, so I test a dozen other Chinese fonts. ONLY
> WenQuanYi fonts have this problem.
>
Yes, I use WenQuanYi Micro Hei Mono.
> The reason is the some characters (e.g. Chinese punctuations and Greek
> letters) in WenQuanYi fonts are halfwidth. I know little about fonts,
> so I doubt if it is a bug of WenQuanYi because these characters in
> other Chinese fonts are all fullwidth.
>
> Since these characters are included in the symbol charset, You can
> simply leave this charset to the default English font. Or use any
> other Chinese fonts except WenQuanYi.
Thanks, I choose another font for symbol. It works now!
^ permalink raw reply [flat|nested] 53+ messages in thread
* Re: A patch for enforcing double-width CJK character display
@ 2014-10-04 3:26 Feng Shu
0 siblings, 0 replies; 53+ messages in thread
From: Feng Shu @ 2014-10-04 3:26 UTC (permalink / raw)
To: emacs-devel
This patch can't apply on current emacs development tree, could some
one update it?
--
^ permalink raw reply [flat|nested] 53+ messages in thread
end of thread, other threads:[~2014-10-04 3:26 UTC | newest]
Thread overview: 53+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-30 2:00 A patch for enforcing double-width CJK character display Hui Liu
2014-04-30 17:08 ` Liang Wang
-- strict thread matches above, loose matches on Subject: below --
2014-10-04 3:26 Feng Shu
2014-04-28 5:35 JunJie Nan
2014-04-29 5:39 ` Stefan Monnier
2014-04-29 6:36 ` Jan D.
2014-04-29 8:16 ` Thien-Thi Nguyen
2014-04-29 20:41 ` Liang Wang
[not found] <4F85A138.6090900@i-soft.com.cn>
2012-04-11 15:48 ` Kan-Ru Chen
2012-04-11 16:16 ` 黄建忠
2012-04-12 8:56 ` 黄建忠
2012-04-12 9:53 ` Eli Zaretskii
2012-04-12 11:18 ` 黄建忠
2012-04-12 14:27 ` Eli Zaretskii
2012-04-12 17:56 ` 黄建忠
2012-04-12 20:33 ` Stefan Monnier
[not found] ` <4F8782C8.2030005@i-soft.com.cn>
2012-04-13 11:42 ` 黄建忠
2012-04-13 12:03 ` 黄建忠
2012-04-13 13:27 ` Stefan Monnier
2012-04-15 5:10 ` Miles Bader
2012-04-15 13:27 ` 黄建忠
2012-04-15 16:08 ` William Xu
2012-04-15 22:19 ` Miles Bader
2012-04-16 0:51 ` 黄建忠
2012-04-16 5:27 ` Miles Bader
2012-04-16 5:40 ` 黄建忠
2012-04-16 6:37 ` 黄建忠
2012-04-16 9:21 ` 黄建忠
2012-04-17 2:16 ` 黄建忠
2012-04-17 0:13 ` Miles Bader
2012-04-17 0:39 ` Miles Bader
2012-04-17 2:00 ` 黄建忠
2012-04-17 2:30 ` Miles Bader
2012-04-17 3:00 ` 黄建忠
2012-04-17 4:08 ` Miles Bader
2012-04-17 4:56 ` Werner LEMBERG
2012-04-17 5:02 ` 黄建忠
2012-04-17 6:33 ` Miles Bader
2012-04-17 7:03 ` Werner LEMBERG
2012-04-17 5:52 ` Miles Bader
2012-04-17 6:10 ` 黄建忠
2012-04-17 7:02 ` Miles Bader
2012-04-17 8:06 ` Werner LEMBERG
2012-04-17 8:25 ` Miles Bader
2012-04-17 9:06 ` Werner LEMBERG
2012-04-17 8:51 ` 黄建忠
2012-04-17 6:45 ` Werner LEMBERG
2012-04-17 9:07 ` James Cloos
2012-04-17 9:27 ` 黄建忠
2012-04-17 1:47 ` 黄建忠
2012-04-18 6:54 ` Kenichi Handa
2012-04-18 8:13 ` 黄建忠
2012-04-18 13:58 ` Miles Bader
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.