Межстрочный интервал в многоязычном макете с Core Text - PullRequest
9 голосов
/ 16 июня 2011

Атрибутивная строка имеет только один атрибут - 17-точечный шрифт Helvetica NeueUI - охватывающий всю строку Строки 1 ~ 3 - чисто английские, строки 4 ~ 6 - смеси английского и китайского, строки 7 ~ 8 - чисто китайские.

Затем он размещается с помощью CTFramesetter, а результирующий кадр рисуется с помощью CTFrameDraw.

// UIView subclass
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        CTFontRef font = CTFontCreateWithName(CFSTR("Helvetica NeueUI"), 17.f, NULL);
        _text = [[NSAttributedString alloc] initWithString:string attributes:
                 [NSDictionary dictionaryWithObject:(id)font forKey:(id)kCTFontAttributeName]];
        CFRelease(font);
        _framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)_text);
        CGMutablePathRef path = CGPathCreateMutable();
        CGPathAddRect(path, NULL, self.bounds);
        _frame = CTFramesetterCreateFrame(_framesetter, CFRangeMake(0, 0), path, NULL);
        CGPathRelease(path);
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    // Flip the coordinate system.
    CGContextTranslateCTM(context, 0.f, self.bounds.size.height);
    CGContextScaleCTM(context, 1.f, -1.f);

    CGContextSetTextMatrix(context, CGAffineTransformIdentity);

    CTFrameDraw(_frame, context);
    CGContextRestoreGState(context);
}

Проблема в том, что расстояние между строками 7 и 8 (чисто китайские) намного меньше, чем у других.

Для контраста я поставил UILabel под ним, с тем же шрифтом и текстом. Игнорируя разницу в рендеринге отдельных символов, вы можете видеть одинаковые пробелы в UILabel, включая последнюю строку между двумя китайскими строками.

Screenshot

Примечание : приведенные выше результаты получены на реальном устройстве. Если вы запустите тот же код на симуляторе, вы получите совсем другой результат для представления Core Text - пробелы между строками, содержащими китайский, намного больше, чем другие.

  1. Почему расстояние между китайскими строками меньше (больше)?
  2. Как я могу расположить многоязычный текст с одинаковой высотой строки, используя Core Text?

PS: вот пример проекта , который вы можете попробовать сами.

Ответы [ 3 ]

3 голосов
/ 02 марта 2012

Подобно пробелу между буквами в европейских языках, в китайской письменности используется узкий пробел между символами, хотя и не наблюдается эквивалента более широкому пробелу между словами, за исключением редких случаев. (В этом отношении он может несколько напоминать форму scriptio Contina.) Когда используется пространство, это также полная ширина. Одним из примеров его использования является почетный маркер. Современный пример на Тайване встречается в упоминании Чан Кайши как 先 總統 蔣公 (бывший президент лорд Чан), в котором предшествующее место служит почетным маркером для 蔣公. Это использование также все еще актуально в очень формальных письмах или других документах старого стиля. Когда китайский написан в транслитерированной форме (как в Hanyu Pinyin), пробелы используются, чтобы помочь в чтении. источник: http://en.wikipedia.org/wiki/Chinese_punctuation

Так что, потому что в китайском как пространство используется немного иначе, чем в английском.

1 голос
/ 02 марта 2012

Причина пробела зависит от символов, которые могут быть найдены при запросе частей текста для его измерения, но это не говорит о том, почему метка просто игнорирует эту проблему.

ОднакоФактически, FrameSetter вводит пробел, чтобы получить ровное пространство, вы можете использовать FrameSetter для получения разрывов строк и использовать TypeSetter (CTTypesetterCreateWithAttributedString), чтобы создать линии и указать их на желаемом расстоянии между линиями, как показано на Ручной разрыв строки от Apple .Это также работает для вашего данного образца, как я кратко проверил.

В любом случае, я могу только согласиться с тем, что поведение метки как-то странно, но не так уж плохо, поскольку выглядит лучше.

1 голос
/ 01 июля 2011

Я наконец получил официальный ответ от инженера Apple:

Метрики CTLine основаны на максимуме каждого из {подъема, спуска, ведущего};это не изменилось, и не будет.Клиенты могут переопределить метрики линии, используя спецификаторы стиля абзаца или стили текста iOS 7, например [UIFont предпочитаемыйFontForTextStyle: UIFontTextStyleBody].

...