一段文字中包含多种语言时行间距问题

# 一段文字中包含多种语言时行间距问题

问题描述

如上图1,中英文混合在一起,造成第三行前后的行间距不同。

我的猜测

不同字体的descender和ascender不同造成的,我猜测如果使用baseline相同的字体,是不是就可以避免这个问题了。

如下图,是我使用黑体的结果:由于黑体既支持英文字母,又支持汉字,而且这些字体的baseline都是一样的,所以没有了这个问题。

猜测验证

1. 如果这一行同时有英文和中文,而绘制的字体又懒懒地使用了UIFont的 systemFontOfSize:创建出来的.Helvetica字体。

.Helvetica字体是不支持中文的,遇到中文,它就使用黑体了。

    CFArrayRef runs = CTLineGetGlyphRuns(line);
    CFIndex runsCount = CFArrayGetCount(runs);
    
    if (runsCount >= 2) {
        for (CFIndex i = 0; i < runsCount; i++) {
            CTRunRef run = CFArrayGetValueAtIndex(runs, i);
            CFDictionaryRef attDic = CTRunGetAttributes(run);
            const UIFont *value = CFDictionaryGetValue(attDic, kCTFontAttributeName);
            NSLog(@"%@", value.fontName);
        }
    }

结果如下:

2016-11-07 15:37:16.394 * .HelveticaNeueUI
2016-11-07 15:37:25.472 * STHeitiSC-Light
2016-11-07 15:37:25.472 * .HelveticaNeueUI
2016-11-07 15:37:25.472 * .HelveticaNeueUI
2016-11-07 15:37:25.472 * STHeitiSC-Light
2016-11-07 15:37:25.473 * .HelveticaNeueUI
2016-11-07 15:37:25.473 * .HelveticaNeueUI
2016-11-07 15:37:25.473 * STHeitiSC-Light
2016-11-07 15:37:25.473 * .HelveticaNeueUI
2016-11-07 15:37:25.473 * .HelveticaNeueUI
2016-11-07 15:37:25.473 * STHeitiSC-Light
2016-11-07 15:37:25.473 * .HelveticaNeueUI
2016-11-07 15:37:25.474 * .HelveticaNeueUI
2016-11-07 15:37:25.474 * STHeitiSC-Light
2016-11-07 15:37:25.474 * .HelveticaNeueUI

2. 黑体与.Helvetica的baseline不同,也就导致ascender和descender不同。

    UIFont *heiti = [UIFont fontWithName:@"STHeitiSC-Light" size:18.0f];
    UIFont *system = [UIFont fontWithName:nil size:18.0f];
    NSLog(@"黑体ascender:%f;descender:%f", heiti.ascender, heiti.descender);
    NSLog(@"系统ascender:%f;descender:%f", system.ascender, system.descender);

结果如下:

2016-11-07 15:47:08.456 * 黑体ascender:15.480000;descender:-2.520000
2016-11-07 15:47:08.456 * 系统ascender:16.560000;descender:-4.140000

3. 但是,.HelveticaNeueUI字体得到的descender和ascender与真实的并不一致,.HelveticaNeueUI字体集中,不同字形的descender和ascender不同。

如下图:每行都只有一种语言,使用的是.HelveticaNeueUI字体。

结果如下:

ascent:13.860000 descent:4.140000 leading:0.000000 lineheight:21.600000
ascent:15.480000 descent:4.140000 leading:0.540000 lineheight:22.140000

我的猜测:
第一行中,只有英文,且该字形的ascent和descent分别为13.86和4.14;
第二行中,只有中文,结果综合了两种字体。ascent:13.86 vs 15.48,最后15.48;descent:4.14 vs 2.52,最后4.14。(可能因为换行符)

4. core text引擎取最大的值作为ascender和descender,那么这一行就会变高,间距变大。

如下是上图1中每行的打印结果,有英文/没有英文反映的是本行当中是否有中文以外的文字,也就是.HelveticaNeueUI支持的字体,包括英文、数字、换行符,紧随的下面一行展示的是该行的信息:

有英文
ascent:15.480000 descent:4.140000 leading:0.540000 lineheight:22.140000
有英文
ascent:15.480000 descent:4.140000 leading:0.540000 lineheight:22.140000
有英文
ascent:15.480000 descent:4.140000 leading:0.540000 lineheight:22.140000
有英文
ascent:15.480000 descent:4.140000 leading:0.540000 lineheight:22.140000
没有英文
ascent:15.480000 descent:2.520000 leading:0.540000 lineheight:18.540000
有英文
ascent:15.480000 descent:4.140000 leading:0.540000 lineheight:22.140000
有英文
ascent:15.480000 descent:4.140000 leading:0.540000 lineheight:22.140000
没有英文
ascent:15.480000 descent:2.520000 leading:0.540000 lineheight:18.540000
没有英文
ascent:15.480000 descent:2.520000 leading:0.540000 lineheight:18.540000
有英文
ascent:15.480000 descent:4.140000 leading:0.540000 lineheight:22.140000
没有英文
ascent:15.480000 descent:2.520000 leading:0.540000 lineheight:18.540000
没有英文
ascent:15.480000 descent:2.520000 leading:0.540000 lineheight:18.540000
没有英文
ascent:15.480000 descent:2.520000 leading:0.540000 lineheight:18.540000
没有英文
ascent:15.480000 descent:2.520000 leading:0.540000 lineheight:18.540000
没有英文
ascent:15.480000 descent:2.520000 leading:0.540000 lineheight:18.540000
没有英文
ascent:15.480000 descent:2.520000 leading:0.540000 lineheight:18.540000
没有英文
ascent:15.480000 descent:2.520000 leading:0.540000 lineheight:18.540000
有英文
ascent:15.480000 descent:4.140000 leading:0.540000 lineheight:22.140000
posted @ 2016-11-14 12:10  小Garfield  阅读(913)  评论(0编辑  收藏  举报