auto9817 Ответов: 2

Рисование строки unicode не работает с методом drawstring


Есть отличная статья о манупляции unicode в csharp.

http://csharphelper.com/blog/2014/09/explore-unicode-characters-c/[^]

Также приведенная выше ссылка предоставляет двоичный исполняемый файл, который вы можете распечатать доступными символами Юникода шрифтом "Times New Roman".

Однако, когда я пытаюсь нарисовать эти символы юникода с помощью метода DrawString, многие символы юникода, отображаемые в текстовом поле, просто рисуются как hallow sqare (т. е. неподдерживаемый символ), тогда как те же самые символы отображаются в правильной форме в текстовом поле.

Я использовал тот же шрифт "Times New Roman" с помощью метода DrawString.

Мне просто любопытно, почему существует некоторое несоответствие между textbox и DrawString методом, даже если я использую один и тот же шрифт.

Ocassioanlly, я могу нарисовать некоторые символы, используя метод Draw String, но многие из них рисуются как пустой квадрат.

Кажется, что между этими двумя методами нет согласованности даже при использовании одного и того же шрифта.


Там не должно быть никаких расхождений, потому что я поставляю шрифт "Times New Roman" в методе DrawString, не так ли?


Есть ли какое-то чистое решение или обходной путь по этой проблеме ? Я действительно хочу, чтобы и текстовое поле, и метод DrawString давали одинаковые результаты.


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

https://www.photobox.co.uk/my/photo/full-что?photo_id=502475949276[^]

Что я уже пробовал:

Вот мой код попытки нарисовать символы юникода с помощью метода DrawString.

int unicodeIndex = 10728;

this._provider = new CultureInfo("en-us");

string unicodeString = ((char)unicodeIndex).ToString(_provider);

this.Font = new Font("Times New Roman", arrowSize);


int x = 200;
int y = 200;

SizeF sizef = g.MeasureString(unicodeString+"W", this.Font, new PointF(x, y), _sformat);
int w = Convert.ToInt32(sizef.Width) + 2;
int h = Convert.ToInt32(sizef.Height) + 2;


RectangleF rectf = new RectangleF(x, y-h/2, w, h);


g.DrawString(unicodeString, this.Font, myBrush, rectf, myFormat);




Это исходный код, отображающий Юникод в текстовом поле с использованием шрифта Times New Roman из приведенной выше ссылки shared.

// Display the desired Unicode characters
  private void btnList_Click(object sender, EventArgs e)
  {
      txtChars.Clear();
      txtCharCode.Clear();
      lblSample.Text = "";
      Cursor = Cursors.WaitCursor;
      Refresh();

      // Set the font size.
      float font_size = float.Parse(txtFontSize.Text);
      Font font = new Font("Times New Roman", font_size);
      txtChars.Font = font;
      lblSample.Font = font;

      // Display the characters.
      int min = int.Parse(txtMin.Text);
      int max = int.Parse(txtMax.Text);
      StringBuilder sb = new StringBuilder();
      for (int i = min; i <= max; i++)
          sb.Append(((char)i).ToString());
      txtChars.Text = sb.ToString();
      txtChars.Select(0, 0);

      Cursor = Cursors.Default;
  }

0x01AA

В чем же заключается ценность myFormat? Вы mabye отключили резервный шрифт здесь?

auto9817

Вот значение myFormat.

myFormat = новый StringFormat();
мой формат.Выравнивание = StringAlignment.Центр;
мой формат.LineAlignment = Выравнивание Строк.Центр;
мой формат.FormatFlags = StringFormatFlags.Без переноса;

Richard MacCutchan

Это не имеет значения, смотрите мой ответ ниже.

0x01AA

Это ни в коем случае не имеет значения, похоже, вы не знаете о резервном шрифте ;)

Richard MacCutchan

Да, и запасной вариант в этом случае-маленькие квадраты. Все, что показал ОП, - это значения выравнивания для его текста.

0x01AA

Итак, "да" означает, что вы не знакомы с резервным шрифтом? :-)

Richard MacCutchan

Нет.

0x01AA

*лол* в любом случае спасибо за ответ. Странно, я не буду проинформирован о сообщениях, мне нужно сканировать что-то подобное самостоятельно.

И да/нет запасной вариант шрифта очень громоздок :-)

Richard MacCutchan

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

auto9817

Я снабдил тот же шрифт "Times New Roman" методом DrawString, как вы можете видеть.

Почему я получаю неподдерживаемые символы (например, пустой квадрат) в методе DrawString, в то время как текстовое поле может отображать одни и те же символы без каких-либо проблем под одним и тем же шрифтом ?

auto9817

Например, я могу нарисовать 42 (*) и 43 (+) без каких-либо проблем, используя метод DrawString. Но я не могу нарисовать 9978 и 9900.

Проверьте карту шрифтов здесь. И 9978, и 9900 являются поддерживаемыми символами Times New Roman.

https://www.martinstoeckli.ch/fontmap/fontmap.html

0x01AA

Если я загляну в справочный источник textbox, то обнаружу, что textbox (TextBoxBase) использует "TextRenderer.DrawText", чтобы нарисовать строку.

auto9817

Итак, вы говорите, что невозможно нарисовать эти поддерживаемые символы с помощью метода DrawString ?

0x01AA

Ещё нет. Мне нужно погрузиться в исходный код. У меня была похожая вещь с китайскими иероглифами для отчета принтера, и я думаю, что помню, что указание шрифта для резервного копирования было решением проблемы. Но со всем этим я столкнулся еще до десятилетия :-)

auto9817

Вы предполагаете, что это может помочь ?

мой формат.FormatFlags = StringFormatFlags.NoFontFallback;

0x01AA

Нет, потому что именно это помешало бы получить замену отсутствующим символам.

Richard MacCutchan

Я только что попробовал его, и он производит два действительных китайских иероглифа.

0x01AA

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

0x01AA

Не нашел решения с помощью DrawString, но в качестве обходного пути это, возможно, поможет:

...
this.Font = new Font("Times New Roman", 16);
...
private void FormFontTest_Paint(object sender, PaintEventArgs e)
{
string ucs = ((char)10728).ToString();
TextRenderer.DrawText(e.Graphics, ucs, this.Font,
new Point(200, 200), SystemColors.ControlText);
}

2 Ответов

Рейтинг:
1

Richard MacCutchan

Квадратные символы-это просто заменители символов Юникода, которые не имеют эквивалента в выбранном шрифте и наборе символов. Это довольно часто встречается при печати нелатинских алфавитов.


Рейтинг:
1

0x01AA

Проблема в том, что Graphics.DrawString не найдете глиф в "Таймс Нью Роман" интервью "Таймс Нью Роман" нет "отката" определяется.

Одна вещь, которую вы можете сделать, это добавить "запасной шрифт" для "Times New Roman" в реестр, кстати, с моей точки зрения, не очень хорошее решение. Для этого добавьте еще один элемент типа REG_MULTI_SZ к

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink
где это имя "Times New Roman" и значение должно быть "Камбрии.ТТК,Камбрия".
Теперь также шнурок найдет недостающий глиф в Камбрия.

Примечание:
Как уже упоминалось в моем комментарии к этому вопросу TextRenderer.DrawText действительно работает без этой модификации regsitry и выглядит для меня предпочтительным способом решить вашу просьбу.


Richard MacCutchan

Это не очень хорошая идея, чтобы возиться с реестром.

0x01AA

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

Richard MacCutchan

Так зачем же упоминать об этом в первую очередь?