«Увеличить» текст, чтобы быть как можно большим в пределах ограничений / блока - PullRequest
4 голосов
/ 15 мая 2010

Первая проблема: у вас есть ширина в 400 пикселей, и вам нужно как можно больше разместить текст в пределах этого ограничения (таким образом, текст должен использовать этот объем пространства).

Добавьте новое ограничение: если текст просто "A", он не должен увеличивать это значение выше высоты 100 пикселей (или некоторого определенного размера шрифта).

Затем финальная ситуация: разрывы строк. Поместите некоторый текст максимально возможным способом, например 400 х 150 пикселей.

Очевидный способ - просто начать с точки 1, а затем увеличивать до тех пор, пока вы не сможете больше соответствовать ей. Это будет работать для всех трех проблем, но будет очень грубым. Подгонка отдельной строки в пределах границ может быть выполнена путем записи ее с фиксированным размером точки, проверки результирующих пиксельных границ текста, а затем просто масштабирования с преобразованием (тогда текст тоже правильно масштабируется, проверьте TransformUI ).

Буду очень признателен за любые идеи о других способах нападения!

Ответы [ 3 ]

3 голосов
/ 15 мая 2010

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

Однако вместо того, чтобы проверять каждое значение, вы можете использовать бинарный поиск, чтобы найти подходящий размер шрифта. Вы знаете, что размер где-то между 1 и 100 (ваш верхний диапазон). используя бинарный поиск, каждый тест устанавливает размер шрифта и проверяет получившийся макет. Если текст слишком большой, мы ищем нижнюю половину текущего диапазона возможных значений. Если размер шрифта подходит, то мы ищем верхнюю половину. Ваш поиск будет использовать не более 7 попыток (100 журналов, основание 2, округлено в большую сторону), он будет точным, найдя самый большой размер без перехода, и будет гибким, если вам потребуется добавить больше требований позже, например, набор шрифтов. или более строгие ограничения на макет.

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

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

См. Википедию - Алгоритм двоичного поиска

3 голосов
/ 15 мая 2010

Я бы создал экземпляр Font с самым большим желаемым размером: скажем, 72 для однодюймовых глифов при 72 dpi. Используйте TextLayout, чтобы получить границы и масштаб, используя AffineTransform (прямой) или AffineTransformOp (за кадром), сохраняя соотношение сторон. Подходит RenderingHints помощь тоже.

3 голосов
/ 15 мая 2010

Я бы сделал следующее:

Предположим, вам нужен текст шириной W.

Выберите произвольный размер, скажем, 10pt, и посмотрите, какую ограничительную рамку получает текстовая строка для этого размера. Допустим, он получает N пикселей в ширину.

Установите новый размер на 10pt * W/N и повторяйте с первого шага, пока не достигнете разумного порога. (Надеюсь, это сработает за одну итерацию.)

Это зависит от того факта, что ширина строки примерно пропорциональна размеру шрифта.

...