Как создать многострочную строку или многострочную метку как CGPath в iOS? - PullRequest
2 голосов
/ 27 сентября 2011

API поддерживает это?Если нет, то как я могу это сделать?

В Базовом тексте есть CTFontCreatePathForGlyph, который может переводить один символ в путь.Я мог бы использовать это в цикле, чтобы создать мою строку как путь, но мне пришлось бы иметь дело с пробелами, кернингом и всеми другими неприятными вещами.Я ищу путь строки, который выглядел бы одинаково, если бы он был нарисован в UILabel с тем же шрифтом и размером.

Ответы [ 2 ]

2 голосов
/ 05 декабря 2012

Посмотрите на категорию UIBezierPath + TextPaths в этом проекте: https://github.com/aderussell/string-to-CGPathRef.

В нем показано, как создавать пути для одиночных и многострочных строк и как использовать их с CAShapeLayers.

Категория - это просто оболочка, и внутренние функции можно использовать в iOS или Mac OS X, вам просто нужно связать свой проект с платформой CoreText.

2 голосов
/ 28 сентября 2011

Существует статья под названием Низкоуровневая отрисовка текста от Ohmu , которая довольно широко освещает эту проблему. Я пробовал этот код и могу подтвердить, что он работает.

Тем не менее, он использует Core Text, поэтому рендеринг, вероятно, не совсем такой, как у UILabel. Кроме того, образец статьи имеет дело только с одной строкой. Чтобы расширить его до нескольких строк, вы должны настроить полную систему Core Text. Вместо:

CTLineRef line = CTLineCreateWithAttributedString( attStr ) ;

Вам необходимо настроить CTFramesetterRef (CTFramesetterCreateWithAttributedString) и CTFrameRef (CTFramesetterCreateFrame), как описано в Руководстве по программированию основного текста. Затем вы можете получить все строки в кадре с помощью CTFrameGetLines().

Затем вы обернули бы цикл for в примере статьи:

CFArrayRef runArray = CTLineGetGlyphRuns(line);

// for each RUN
for (CFIndex runIndex = 0; runIndex < CFArrayGetCount(runArray); runIndex++)

с другим циклом, который повторяется по всем строкам. Внутреннее ядро ​​петли должно быть идентичным.

Образец статьи создает графический контекст и добавляет пути для отдельных глифов к пути этого контекста, но вы также можете легко создать CGMutablePathRef или UIBezierPath и добавить пути к одному глифу к этому объекту.

Одна вещь, которая не на 100% понятна мне без тестирования, это как отрегулировать вертикальное положение глифов на последнем пути. Возможно, вам придется вызвать CTFrameGetLineOrigins(), чтобы получить позицию каждой строки и добавить эту позицию к каждому отображаемому глифу (возможно, после преобразования его в текстовую матрицу).

...