Лазарь. Эквивалент Chr() для символов Unicode

Есть ли в freepascal функция для отображения символа Unicode по его коду (например, U+1D15E)? К сожалению, Chr() работает только с символами ANSI (с кодами меньше 127).
Я хочу использовать символы из собственного символьного шрифта, а вставлять их напрямую в исходный код очень неудобно (в Lazarus они отображаются как ? или как-то иначе, потому что их нет в системных шрифтах).


person VIK    schedule 05.08.2011    source источник
comment
U+1D15E — слегка патологический пример, поскольку 1D15E — это не слово (на одну шестнадцатеричную цифру слишком много).   -  person Andreas Rejbrand    schedule 06.08.2011
comment
@Andreas: Unicode имеет символ с кодом U + 1D15E. Он находится в группе музыкальных символов: unicode.org/charts/PDF/U1D100.pdf   -  person VIK    schedule 06.08.2011
comment
Я знаю. Я только что сказал, что это немного патологически, что так и есть, в том смысле, что легче работать с кодовыми точками, которые вписываются в слово, и многие приложения работают только с ними.   -  person Andreas Rejbrand    schedule 06.08.2011
comment
@Andreas Если это кодовая точка, которую вы хотите, то это та кодовая точка, которую вы хотите.   -  person David Heffernan    schedule 06.08.2011
comment
@Andreas: U + 1D15E является допустимой кодовой точкой. Такие обозначения кодовых точек не ограничиваются определенной кодировкой вроде UTF-16 (на которую вы вроде бы ссылаетесь) или даже UTF-8. То, как это кодируется в суррогатную пару, является частью UTF-16. И если FP использует UTF-8 (что меня не удивит), он кодируется как количество байтов.   -  person Rudy Velthuis    schedule 06.08.2011


Ответы (4)


Взгляните на эту страницу. Я предполагаю, что Freepascal либо использует UTF-16, в котором он становится суррогатной парой двух WideChars (см. таблицу), либо UTF-8, в котором он становится последовательностью байтовых значений (см. снова таблицу).

УТФ-8:

const
  HalfNoteString = UTF8String(#$F0#$9D#$85#$9E);

УТФ-16:

const
  HalfNoteString = UnicodeString(#$D834#$DD5E);

Названия строковых типов могут отличаться, так как я не очень хорошо знаю FreePascal. Возможно AnsiString и WideString.

person Rudy Velthuis    schedule 05.08.2011
comment
@Rudy Velthuis: Спасибо! Первый вариант отлично работает в Lazarus! - person VIK; 06.08.2011
comment
FPC 2.4.x+ имеет строку unicode. У него нет анзистринга с кодовыми страницами, а unicodestring мало используется в библиотеках, но он есть. (поскольку в основном это старая широкая струна Kylix с небольшими перестановками и улучшениями в записи) - person Marco van de Voort; 08.08.2011

Я никогда не использовал Free Pascal, но на вашем месте я бы попробовал

var
  s: char;
begin
  s := char($222b);                   // Just cast a word

или, если компилятор действительно упрям,

var
  s: char;
begin
  PWord(@s)^ := $222b;                // Forcibly write a word
person Andreas Rejbrand    schedule 05.08.2011
comment
Благодарю вас! Оба варианта работают правильно. Тем не менее, знаете ли вы какой-либо способ использовать кодовые точки, которые не помещаются внутри слова (в моем шрифте есть несколько символов)? - person VIK; 06.08.2011
comment
@VIK: Боюсь, я даже не знаю, как именно Delphi справляется с этим ... Может быть, Дэвид знает? - person Andreas Rejbrand; 06.08.2011
comment
@VIK: в Delphi UnicodeString они кодируются как пара слов, называемая суррогатной парой. Как U+1D15E кодируется в UTF-16 (при условии, что именно это использует Free Pascal — я могу представить, что они могли бы с таким же успехом использовать UTF-8 везде, где он может быть закодирован до 5 байтов, IIRC), Я не знаю. - person Rudy Velthuis; 06.08.2011
comment
UTF-16 действительно является парой WideChars. Вот как вы хотели бы это в Windows. Что касается Free Pascal, я понятия не имею, что такое естественная кодировка Unicode. - person David Heffernan; 06.08.2011
comment
кодовые точки кодируются как максимальная пара широких символов. Обратите внимание, что кодовая точка — это не то же самое, что символ, и что, например. UTF16 в OS X обычно денормализован (больше кодовых точек для акцентированных символов) - person Marco van de Voort; 22.06.2012

Насколько мне известно, текущий статус Unicode для FPC

  1. Кодовую страницу литералов можно установить с помощью $codepage http://www.freepascal.org/docs-html/prog/progsu81.html
  2. FPC 2.4.x+ имеет юникодную строку (поскольку это +/- широкая строка Kylix), но поддерживает только базовые подпрограммы. (pos и copy, а не такие подпрограммы, как формат), но в «записи» отсутствует поле кодовой страницы.
  3. Виджеты Lazarus ожидают UTF8 в обычных анзистрингах (анзисторы D7..D2007 без данных кодовой страницы), и программисты должны вручную вставлять преобразования, если это необходимо. Таким образом, в Windows виджеты в основном используют вызовы unicode (-W), но берут строки с кодировкой UTF8.
  4. FPC не следует за utf8 в схеме ansistring, поэтому для некоторых подпрограмм, принимающих строки в sysutils, в Lazarus есть специальные подпрограммы, которые предполагают UTF8, которые вызывают варианты -W)
  5. Ansistring FPC — это системная 1-байтовая кодировка по умолчанию. ansi в Windows, utf8 на большинстве других платформ.
  6. Trunk, 2.7.1, обеспечивает поддержку новой антистроки D2009+ (с кодовыми страницами).
  7. Пока не обсуждалось, как работать со строковым типом по умолчанию (например, будет ли «string» быть utf8string в *nix и unicodestring в Windows или везде unicodestring или utf8string?)
  8. Другие улучшения, связанные с unicodestring (например, параметры кодирования в tstringlist.savetofile), не реализованы. Аналогично для псевдообъектов (таких как TCharacter, которые на самом деле в основном статичны)

Обновление: 2.7.1 имеет переменную кодировку типа anstring, а lazarus был исправлен, чтобы продолжать работать. Однако на самом деле ничто не использует это, например. большая часть RTL по-прежнему использует вызовы -A, а прототипы sysutils и системных процедур, которые принимают строки, еще не изменились на rawbytestring.

person Marco van de Voort    schedule 08.08.2011

Я предполагаю, что проблема заключается в преобразовании из кодировки UCS4 (которая на самом деле является кодовой точкой Unicode) в UTF16.

В Delphi вы можете использовать функцию UCS4StringToUnicodeString.

Внимание! Будьте осторожны с типом UCS4String. На самом деле это динамический массив с нулевым завершением, а не строка (это означает, что он отсчитывается от нуля).

var
  S1: UCS4String;
  S: string;

begin
  SetLength(S1, 2);
  S1[0]:= UCS4Char($1D15E);
  S1[1]:= UCS4Char(0);
  S:= UCS4StringToUnicodeString(S1);
  ShowMessage(Format('%d, %x, %x', [Length(S), Ord(S[1]), Ord(S[2])]));
end;
person kludg    schedule 06.08.2011
comment
Это должен быть принятый ответ. Другие ответы приведут вас только наполовину. Это действительно работает. - person user4815162342; 06.04.2016