Подтвердить что ты не робот

Эффективное вычисление ширины текста

Мне нужно вычислить ширину столбца со многими строками (функция AutoSize столбца). Использование Canvas.TextWidth слишком медленное.

Текущее решение: В моем текущем решении используется класс измерителя текста, который строит таблицу поиска для фиксированного алфавита один раз, а затем очень быстро вычисляет ширину данной строки, добавляя ширину символов, извлекаемую из Справочная таблица. Для символов, не содержащихся в таблице поиска, используется средняя ширина символа (также вычисленная один раз).

Проблема: Это хорошо работает для европейских языков, но не для азиатских языков.

Вопрос: Какой лучший способ решить эту проблему? Как можно реализовать такую ​​функцию AutoSize без относительно медленных функций Canvas и без зависимости от конкретного алфавита?

Спасибо за любую помощь.

4b9b3361

Ответ 1

Вы сказали, что хотите получить максимальную ширину текста для столбца. Не могли бы вы, скажем, взять только 4 или 5 самых длинных строк и получить их ширину? Таким образом вам не придется искать ширину для всех предметов и может сэкономить довольно много времени.

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

Я не думаю, что это имеет большое значение, используете ли вы Canvas.TextWidth или GetTextExtentPoint32. Просто используйте один из них, чтобы получить точную ширину, после того, как вы использовали один из вышеперечисленных методов, чтобы оценить длинные/самые широкие строки.

Тем, кто считает, что это не работает

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

Но это не мой главный аргумент. Он уже писал, что он делает предварительную текстовую ширину, добавляя заданные индивидуальные ширины символов. Это не учитывает кернинг. Ну, кернинг может сделать только строку более узкой, поэтому имеет смысл проверить только верхние 4 или 5 элементов для точной ширины. Самая большая проблема, которая может возникнуть, состоит в том, что столбец может быть несколько пикселей слишком широк, не более. Но это будет намного быстрее, чем использование TextWidth или GetTextExtentPoint32 или подобных функций для каждой записи (при условии, что более 5 записей), и это то, чего хотел исходный плакат. Я предлагаю, чтобы те, кто мне не верил, просто попробовали.

Что касается использования чистой длины строки: даже это, вероятно, достаточно хорошо. Да, "WWW", вероятно, шире, чем "!!!!!", но исходный плакат, вероятно, будет знать лучший материал для струн, который у него есть, и если это возможно. '!!!!!' или "WWW" - это не обычные записи, которые вы ожидаете. Особенно, если вы считаете, что проверяется не только одна строка, но самые длинные 4 или 5 строк (или любой номер оказывается оптимальным). Очень маловероятно, что самая широкая строка не входит в их число. Но оригинальный плакат может сказать, возможно ли это или возможно. Кажется, он так думает.

Итак, остановите downvoting и попробуйте сами.

Ответ 2

Я боюсь, что вам нужно использовать Canvas.TextWidth, или ваша реализация будет неточной. Ширина текста зависит от шрифта кернинга, где разные последовательности символов могут иметь разную ширину (а не только общую ширину отдельных символов).

Ответ 3

Я, я вырезал среднего человека и напрямую использовал Windows API. В частности, я использую GetTextExtentPoint32 с .Handle Canvas. Вы ничего не можете сделать, чтобы быть быстрее, за исключением кеширования, и, откровенно говоря, вы просто добавите накладные расходы.