Почему -[NSTextStorage replaceCharactersInRange: withAttributedString:] иногда иногда не учитывает шрифты в других наборах символов?

Я пытаюсь диагностировать проблему в UKSyntaxColoredTextDocument 0.4 http://www.zathras.de/angelweb/blog-uksctd-oh-four.htm где текст, который на самом деле живет не тем шрифтом, который вы указали, исчезает, когда вы тип. (Вы можете скачать и попробовать эту классную утилиту, чтобы увидеть эту проблему для себя...)

Вот фон: это некоторый синтаксический код окраски, который перекрашивается при вводе. Это прекрасно работает, но если вы вводите некоторые символы, которые не являются частью набора шрифтов для этого текстового представления (например, Monaco, Helvetica) ... например, символьный символ или что-то на японском языке, который на самом деле использует шрифты, такие как ZapfDingbatsITC или HiraKakuProN-W3, чтобы отобразить его, то эти символы не отображаются при вводе.

Допустим, у вас есть такой текст: fdsafd[☀]sfds‡[☀☀☀][日本語]...

Если вы вставите это в текстовое поле и переключитесь между цветовыми синтаксисами во всплывающем окне, это вызовет oldRecolorRange:с этой строкой:

[[textView textStorage] replaceCharactersInRange: range withAttributedString: vString];

Здесь все ведет себя так, как я ожидал. Текст ASCII, символы и японский текст видны. Значение [textView textStorage] начинается и заканчивается примерно так: (Это вывод gdb; он не показывает символы Юникода, не беспокойтесь об этом.)

ДФ {
    NSFont = "LucidaGrande 20,00 pt. P [] (0x001a3380) fobj=0x001a4970, spc=6,33";
}?{
    NSFont = "ZapfDingbatsITC 20,00 pt. P [] (0x001ae720) fobj=0x001bb370, spc=5,56";
} Fdsafd[{
    NSFont = "LucidaGrande 20,00 pt. P [] (0x001a3380) fobj=0x001a4970, spc=6,33";
}?{
    NSFont = "HiraKakuProN-W3 20,00 pt. P [] (0x001b59e0) fobj=0x001bb600, spc=6,66";
}] sfds [{...

... даже после установки нового значения

dffdsafd[?]sfds[???][???] Nihddfdfffdfdd{
    NSFont = "LucidaGrande 20,00 pt. P [] (0x001a3380) fobj=0x001a4970, spc=6,33";
}

Другими словами, "чужие" шрифты, необходимые для отображения этой строки, каким-то образом автоматически сохраняются, даже если эти шрифты не указаны в строке замены.

Однако, когда вы вводите по одному символу за раз, другой вызов replaceCharactersInRange:withAttributedString: в методе recolorRange: в результате получается атрибутивная строка, которая есть только в базовом шрифте - для нас не было добавлено никаких иностранных символов, поэтому символы вне диапазона основного шрифта вообще не видны!

dffdsafd [?] sfds [???] [???] Nihddfdfffdfddx {
    NSFont = "LucidaGrande 20,00 pt. P [] (0x001a3380) fobj=0x001a4970, spc=6,33";
}

Любая идея, почему этот метод будет работать так или иначе в одном случае? Есть ли какой-то переключатель, который я могу передать NSTextStorage/NSAttributedString намек на то, что мы хотим, чтобы текст отображал иностранные символы?

1 ответ

Решение

Попробуйте [[textView textStorage] fixFontAttributeInRange:range]; после [[textView textStorage] replaceCharactersInRange: диапазон с AttributedString: vString] в recolorRange:

Я думаю, что проблема заключается в том, чтобы снова отредактировать хранилище текста в ответ на processEditing, которое уже является концом редактирования. -[NSTextStorage processEditing] использует fixFontAttributeInRange:, но, поскольку вы пытаетесь редактировать снова, что-то идет не так, и поведение исправления отбрасывается.

Когда вы делаете это для всего документа, существует нормальная последовательность beginEditing / endEditing / processEditing, которая заставляет fixFontAttributeInRange: счастливо вызываться.

Другие вопросы по тегам