2017-01-11 9 views
0

Так что я пытаюсь написать пользовательский NSView с текстом в нем, но не используя NSTextView (так как это будет больше, чем просто текст). Я могу использовать Core Text для рисования текста, но теперь мне также нужно иметь возможность проводить тестирование и рисование каттеров и выборок.Я что-то пропустил в Core Text, который позволит мне увидеть, в какой строке находится определенная точка, и насколько высока линия, в которой есть стили абзаца?

Наивный способ нанесения CARETS и выбора, как показано с помощью различных образцов Apple, чтобы получить типографские границы различных CTLines, охватывающих требуемый диапазон строк (с использованием CTLineGetBoundsWithOptions(0) вместо CTLineGetTypographicBounds() из-за различные ошибки в последнем) и заполняя результирующие прямые. К сожалению, как только существует стиль абзаца любого типа (будь то интервал между абзацами, межстрочный интервал или высота строки), это перестает работать, поскольку стили абзаца - , а не, включенные в типографские границы. Если вы выберете текст, охватывающий несколько строк, вы увидите этот знаковый белый промежуток между линиями! И это все еще не отвечает на вопрос о том, как узнать, какую строку использовать, если я нажимаю на пробел между строками.

После дерешься за типографские границы прямоугольников перекрытия или имеющие разрывы между ними из-за того, как основной текст имеет привязок метрика указует на целые по умолчанию, я заметил, что если я называю CTFrameGetLineOrigins() я могу определить высоту линии i + 1 путем вычисления origins[i].y - origins[i + 1].y; высота линии 0 - это высота кадра за вычетом высоты комбинированных других линий. Здесь важно использование i + 1; он имеет дело с нечетными сценариями, вызванными шрифтами, которые имеют высоту пространства, отличную от других высот персонажа.

Однако, используя эту технику, я не могу отличить интервал между строкой и интервалом ниже строки, независимо от того, является ли это пространство абзацем или пространственным пространством. Все интервалы рассматриваются как находящиеся над линией, и если используются несколько режимов интервала, они просто объединяются. У меня есть a small program, который вы можете использовать, чтобы поэкспериментировать с этим для себя; установите флажок «Базовые уровни», чтобы закрасить высоту линии.

Итак, вопрос: что мне не хватает, что я не могу понять, насколько высока линия на самом деле и где ее базовая линия относительно ее высоты, независимо от стиля абзаца? Или мне нужно переделать внутреннюю логику Core Text самостоятельно, если я хочу это сделать? У меня много кусочков, но многие из них очень условны ...

А что происходит в последнем абзаце? Должен ли я имитировать конечное пространство?

Решение должно запускаться на OS X 10.8 или новее.

Спасибо.

ответ

1

Большой вопрос, который вам нужно задать себе, это то, что вы хотите результаты этих вещей. Высота линии - это всего лишь высота линии. Он не включает расстояние между строками. Наборщику не нужно делать все стеки строк. Рассмотрим ситуации с двумя столбцами, где строка может быть выше, чем предыдущая строка. Или если есть разрывы страниц; считаете ли вы, что поля страницы являются частью линии? Core Text не просто обрабатывает «вещи, похожие на TextView». Он обрабатывает совершенно произвольные макеты.

Вы столкнулись с трудным вопросом о том, к какой строке должно принадлежать пространство между линиями. Это вопрос, на который вы должны ответить. Core Text не знает, чего вы хотите. Он не знает , что означает любого из этих прямоугольников или как вы хотите, чтобы они работали вместе.

Итак, для вопроса выбора да, вам нужно будет вычислить полный блок, создав объединение всех прямоугольников линии, которые полностью выбраны (плюс дополнительные биты на первой и последней строке). Вот как это делается обычно для простого текстового текста с одним столбцом; очевидно, что это немного усложняется, если текст может охватывать несколько столбцов. Вам также может потребоваться рассмотреть ситуации, когда текст течет «назад» (т. Е. Справа налево внутри обычно слева направо).

Работает с использованием примитивов основного текста низкого уровня. Сначала я попытался бы использовать NSLayoutManager и посмотреть, достаточно ли он для ваших целей. Если ваша проблема в том, что вам нужно обернуть (или пропустить) графику или другие нетекстовые элементы, то NSLayoutManager может сделать лот работы для вас и позволить вам по-прежнему использовать NSTextView. NSLayoutManager очень подклассы, чтобы настроить его поведение, и используя его, вы часто можете использовать встроенные возможности выбора Cocoa, не переопределяя их.

+0

Вторичный. Вы должны быть более конкретным о том, что вы делаете, и каким образом это «больше, чем просто текст». NSTextView может вместить всевозможные вещи, которые «больше, чем просто текст», путем изменения потока текста или с помощью вложений различными способами. Вы, вероятно, много делаете для себя без необходимости. – bhaller

+0

Хорошо, я вижу, как я был введен в заблуждение; Благодарю. Хотя я действительно задаюсь вопросом, почему Core Text обрабатывает стили абзаца вообще, если это так ... Я действительно рассматривал использование API Cocoa, но я не совсем уверен, как переводить из Core Text в NSLayoutManager. А что касается NSTextView, представление представляет собой существующее представление чистой графики, которое я хочу добавить для редактирования текста, а не наоборот. Я также знаю, что в моей тестовой программе, которая оценивает требуемые усилия, более похож на Slack Pages, чем на Word, а не на строго свободный текст. Я действительно удивляюсь, как податливый NSTextView, хотя, поскольку все использует его ... – andlabs

+0

И, признается, все, что приходит из этого, со временем также станет частью libui (хотя у меня есть несколько личных вещей, которые я хочу сделать с ним, так как намекнул). – andlabs