Проблема .net DrawString / StringFormat - PullRequest
5 голосов
/ 25 августа 2010

Я занимаюсь разработкой программы Winnet Forms .net 3.5, и у меня возникла "интересная" проблема с рисованием текста.

Я реализую элемент управления для редактирования текста, и он рисует текст с помощью DrawString () и StringFormat.GenericTypographic (далее GT).По мере того, как пользователь вводит, целые слова (или группы слов), находящиеся в начале строки, слегка движутся влево и вправо наугад.

Вероятно, это ошибки округления - затронутый блок выглядит смещенным на один пиксель вгоризонтальная плоскость, так как буквы добавляются в конец строки.Если я использую StringFormat.GenericDefault (GD), этого не произойдет, но символы будут отображаться менее точно, и это неприемлемо.

Я решил, что могу медленно сменить GD на GT (настройки для каждогообсуждается в MSDN и, очевидно, может быть исследован в отладчике), посмотреть, какие FormatFlags или другие настройки вызывали это, и идти дальше.Однако, если я возьму копию GD, изменю все свойства так, чтобы они были идентичны GT, размещение символов будет совершенно другим - поведение этих двух предположительно идентичных объектов, очевидно, не одинаково.

Как иIMHO, .net Reflector показывает, что StringFormat - это просто оболочка для неуправляемого объекта, и я могу только предположить, что не все свойства этого объекта доступны для программного обеспечения .net.

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

Редактировать

Код, который я использую для рендеринга, выглядит следующим образом:

sForm = new StringFormat(StringFormat.GenericTypographic);
sForm.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;

using (SolidBrush brush = new SolidBrush(frmt.ForegroundColour))
  context.DrawString(line.Text, frmt.DisplayFont, brush, new PointF(horizontal, height), sForm);

1 Ответ

0 голосов
/ 26 августа 2010

Ну, я решил проблему. Это не так, как я хотел, но для справки я сделал это так:

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

Кажется бесполезным непрерывно вызывать DrawString() для каждого слова (когда оно может справиться с целыми многострочными блоками за один раз), но программа остается довольно быстрой.

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

...