Типографика и текст
Текст — одна из самых сложных частей любой графической библиотеки. Skija предоставляет высокоуровневый API для работы со всем: от простых подписей до сложной многострочной вёрстки текста.
Шрифт (The "What")
Typeface представляет конкретный файл шрифта (например, "Inter-Bold.ttf"). Он определяет форму глифов.
Загрузка шрифтов
Их можно загружать из файлов, ресурсов или системного менеджера шрифтов.
// Из файла
Typeface inter = Typeface.makeFromFile("fonts/Inter.ttf");
// Из системы (безопасный способ)
Typeface sans = FontMgr.getDefault().matchFamilyStyle("sans-serif", FontStyle.NORMAL);Частая ошибка: Не предполагайте, что шрифт существует в системе пользователя. Всегда предоставляйте запасной вариант или включайте свои шрифты в ресурсы.
Начертание (The "How")
Font берёт Typeface и задаёт ему размер и другие атрибуты отрисовки.
Font font = new Font(inter, 14f);Позиционирование текста: метрики шрифта
Если вы хотите центрировать текст или точно его выровнять, вам нужно понимать FontMetrics.
FontMetrics metrics = font.getMetrics();
// metrics.getAscent() -> Расстояние от базовой линии до верха (отрицательное)
// metrics.getDescent() -> Расстояние от базовой линии до низа (положительное)
// metrics.getLeading() -> Рекомендуемое расстояние между строкамиПример: Идеальное вертикальное центрирование Чтобы центрировать текст по вертикали в точке y, обычно нужно сместить его на половину высоты "заглавной высоты" (высоты заглавных букв).
float centerY = rect.getMidY() - metrics.getCapHeight() / 2f;
canvas.drawString("HELLO", rect.getLeft(), centerY, font, paint);Продвинутый текст: Paragraph
Для всего, что сложнее одного слова или строки, используйте API Paragraph. Он обрабатывает:
- Перенос строк
- Несколько стилей (жирный, курсив, цвета) в одном блоке
- Текст справа налево (RTL)
- Поддержку эмодзи
Подробности см. в Справочнике по API Paragraph.
Интерактивный текст: TextLine
Если вам нужна одна строка текста, но необходимо точно знать, где находится каждый символ (например, для курсора или выделения в текстовом поле), используйте TextLine.
TextLine line = TextLine.make("Interact with me", font);
// Получение визуальных свойств
float width = line.getWidth();
float height = line.getHeight();
// Hit-тестинг: Получение индекса символа по координате в пикселях
int charIndex = line.getOffsetAtCoord(45.0f);
// Получение координаты в пикселях для индекса символа
float xCoord = line.getCoordAtOffset(5);
// Отрисовка
canvas.drawTextLine(line, 20, 50, paint);Визуальные примеры
Интерактивная строка текста: См. examples/scenes/src/TextLineScene.java для демонстрации позиционирования курсора, hit-тестинга и вёрстки текста с несколькими системами письма.
Эффекты Text Blob: См. examples/scenes/src/TextBlobScene.java для примеров текста по пути, волнистого текста и пользовательского позиционирования.
Рекомендации
- Кэшируйте свои Fonts/Typefaces: Создание
Typefaceвключает в себя разбор файла и может быть медленным. Храните их в статическом кэше или менеджере тем. - Используйте хинтинг/сглаживание: Для мелкого текста на экранах убедитесь, что сглаживание включено в вашем
Paint, чтобы текст оставался читаемым. - Измеряйте перед отрисовкой: Используйте
font.measureTextWidth(string), чтобы рассчитать макет, прежде чем фактически рисовать его на холсте.