Содержание


CrwDaq - рекомендации по кросс-платформенной разработке

Здесь приводятся рекомендации по кроссплатформенной разработке прикладного ПО в пакете crwdaq, а также рекомендации по переводу прикладных DAQ конфигураций старой версии пакета Crw32 (работающей только под Windows) в новую версию crwdaq (работающей под Unix и Windows). Под кроссплатформенной разработкой понимается такой стиль разработки и программирования, что созданные прикладные программы и конфигурации могут успешно выполняться (в идеале - без каких-либо изменений) под разными операционными системами - например, Linux и Windows.

Перейти к Содержанию


Общие сведения и соглашения

Напомним, что старая версия пакета, именуемая здесь Crw32, разрабатывалась в период 2001-2023 на языке Object Pascal в среде Delphi 5 для платформы Win32 и работает на всех версиях Windows-XP/7/8/10/11, как 32, так и 64 битных. В 2023 начата разработка новой версии пакета, именуемая далее crwdaq, создаваемая на языке Free Pascal в среде Lazarus, и ориентированная на Linux и Windows.

Пакет crwdaq является кроссплатформенным. Это значит, что пакет и разработанные в его среде прикладные программы для систем сбора данных (DAQ = data acquisition) и управления, для краткости именуемые далее DAQ-программами или DAQ-конфигурациями, могут выполняться в разных операционных системах (OS = Operation System).

В настоящее время пакет crwdaq ориентируется на два семейства OS: Unix и Windows.

Семейство OS Unix - это (в первую очередь) различные версии операционных систем GNU/Linux. OS семейства GNU/Linux произошли от операционных систем Unix и наследуют их свойства, поэтому обобщенно называются Unix совместимыми системами или просто Unix системами. В первую очередь пакет ориентируется на Astra Linux, но возможно также его использование на других дистрибутивах с пакетной базой deb, например Debian и Ubuntu. При некоторой доработке возможно использование пакета crwdaq и на дистрибутивах с пакетной базой rpm, однако это потребует определенных усилий по переработке скриптов и инсталляторов. При более существенной доработке пакета crwdaq возможно его использование в других операционных системах Unix, таких как Free BSD или MacOS, однако практической необходимости в этом не просматривается из-за малой распространенности этих систем.

Семейство OS Windows - это различные версии операционных систем с ядром Windows NT - это Windows-XP/7/8/10/11. В первую очередь используются 32-битная версия пакета crwdaq, но она может запускаться как на 32, так и на 64-битных версиях Windows.

В плане аппаратной платформы пакет crwdaq в настоящее время ориентируется на IBM PC совместимые компьютеры с архитектурой x86, разрядности (в основном) 64 бит или (реже) 32 бит. Поддержка других аппаратных платформ возможна, но потребует доработки кода. В настоящее время это не актуально ввиду отсутствия такой аппаратуры.

Пакет crwdaq разработан так, что фактически содержит в общем архиве (в рабочих каталогах) как исходные файлы (программные коды), так и две версии исполняемых файлов - исполняемые файлы Unix в формате ELF (Executable and Linking Format) и исполяемые файлы Windows в формате .exe. Эти файлы генерируются из одного исходного кода и лежат рядом в одном каталоге. При этом исполняемые файлы Unix не имеют расширения (но имеют флаг “исполняемый”), а исполняемые файлы Windows имеют расширение .exe. Например, основной исполняемый файл crwdaq под Unix может иметь имя /opt/daqgroup/suite/crwdaq/crwdaq, а исполняемый файл Windows - имя c:\opt\daqgroup\suite\crwdaq\crwdaq.exe.

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

Перейти к Содержанию


Сводка правил кроссплатформенной разработки

Сначала перечислим краткую сводку основных правил кроссплатформенной разработки в пакете crwdaq.
Более подробная расшифровка этих правил будет дана ниже, по каждой теме отдельно.

Перейти к Содержанию


Обзор функций идентификации системы и поддержки кроссплатформенности

Кроссплатформенное программирование начинается с идентификации (определения) текущей ситемы и её параметров.
После идентификации требуется набор средств для корректной обработки данных под разными платформами.
Здесь перечислены функции DaqPascal, позволяющие это делать.

При решении задачи идентификации следует различать целевую платформу (target platform) и текущую платформу (current platform). Целевая платформа - это платформа, под которую был скомпилирован код. Текущая платформа - это платформа, под которой код работает сейчас. В большинстве случаев целевая платформа совпадает с текущей (для которой она и создавалась). Однако в случае запуска из-под эмуляторов (например, wine) или виртуальных машин целевая платформа может отличаться от текущей. Это довольно тонкое различие, но иногда его (тоже) приходится учитывать.

Функции идентификации

Функции/константы IsUnix, IsLinux, IsWindows позволяют очень быстро определять целевую платформу (под какую операционную систему был скомпилирован код пакета). Это позволяет делать логические “ветки” if IsUnix then … или if IsWindows then … для выполнения действий, зависящих от текущей/целевой OS.

Функция ParamStr и команда @paramstr … в консоли DAQ-устройств содержит много идентифицирующей информации:

# Вызов                                 Пример вывода                          Комментарий
@paramstr system id FpcTargetPlatform   x86_64-Linux                           Целевая платформа (CPU-OS)
@paramstr system id FpcTargetCpu        x86_64                                 Целевая платформа (CPU)
@paramstr system id FpcTargetOs         Linux                                  Целевая платформа (OS)
@paramstr system id FpcVersion          3.2.2                                  Версия FPC, на котором скомпилирован код
@paramstr system id LclVersion          2.2.6.0                                Версия LCL, т.е. библиотеки Lazarus
@paramstr system id WidgetSet           gtk2                                   Версия виджетов графической системы
@paramstr system id SystemVersion       Astra Linux CE 2.12.45 (Orel) x86_64   Версия текущей операционной системы
@paramstr system id WindowManageer      fly-wm                                 Название оконного менеджера
@paramstr system os Platform            Linux                                  Целевая OS
@paramstr system os Version             Linux y510p 5.15.0-33 generic …        Версия текущей системы, аналогично команде uname -a
@paramstr system os SysRoot             /                                      Корневой каталог
@paramstr system os ComSpec             /bin/bash                              Командный процессор
@paramstr system os Shell               /bin/bash                              Командный процессор

Функции кроссплатформенного программирования

Функции EOL, PosEol позволяют определять и правильно обрабатывать разделители строк текста.

Функции PathSep, PathDelim, AddPathDelim позволяют правильно выполнять обработку разделителей имен файлов и списков поиска.

Функции utf8_length, utf8_copy, utf8_ord, utf8_chr, utf8_encode_ansi, utf8_decode_ansi, utf8_uppercase, utf8_lowercase, utf8_bom позволяют корректно обрабатывать строки UTF8. Напомним, что в DaqPascal строки рассматриваются как байтовые строки, т.е. как массив байтов (или char символов), без какой-либо обработки или кодировки. Аналогично этому в библиотеке crwlib используются байтовые строки типа LongString=RawByteString. Использование байтовых строк (без кодировки) дает большие преимущества, т.к. позволяет хранить в них любую (в том числе двоичную) информацию без риска её повреждения. Но в некоторых (довольно редких) случаях необходимо учитывать, что строки заданы в кодировке UTF8. Для этого и нужны функции utf8_xxxx.

Функции AdaptFileName, AdaptExeFileName позволяют адаптировать (подгонять, приспосабливать) имена файлов к текущей операционной системе. Дело в том, что в кроссплатформенной системе имена файлов могут поступать из разных источников (из программного кода, из конфигурационных файлов, из сети) и могут быть заданы по правилам системы Unix, Linux или Windows, отличающейся от текущей системы. Для работы с файлом его имя следует преобразовать (адаптировать) в соответствии с правилами текущей операционной системы. Наконец, функция DaqFileRef (и другие файловые функции) позволяет преобразовать относительные имена файлов в абсолютные, посе чего их уже можно использовать для работы с файлами.

Перечисленные функции образуют программный “базис”, на котром строится кроссплатформенное программирование.

Утилиты для поддержки кроссплатформенного программирования

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

Перейти к Содержанию


Кодировка текста (UTF8)

В старой версии Crw32 использовались кодировки ASCII, CP1251 (ANSI), CP866 (OEM).

В новой версии пакета crwdaq для всех текстов используется универсальная кодировка UTF8, которая имеет код 65001 и задается в Windows командой CHCP 65001. По этой причине при переводе DAQ конфигураций Crw32 в crwdaq требуется перекодировка всех текстов в UTF8.

Поскольку кодировка UTF8 универсальна, она используется для всех текстовых файлов как в Unix, так и в Windows версии пакета. Это удобно, т.к. не требуется отдельных версий DAQ конфигураций для каждой системы.

Для конвертирования кодировок в пакет crwkit входит программа fixutf8, вызвать которую можно кнопкой fixutf8zen в программе Double Commander.


Pазделители строк текста (EOL)

Для разделения строк текста в разных OS используются разные разделители:
- CRLF = chr(13),chr(10) в Windows,
- CR = chr(13) в MacOS,
- LF = chr(10) в Unix.

Для кроссплатформенной разработки в программах (на языке DaqPascal или Free Pascal с использованием библиотеки crwlib) предусмотрен разделитель EOL (end of line), который равен CRLF в Windows и LF в Unix. Поэтому во всех случаях, кроме специально оговоренных (например, когда разделитель определяется протоколом обмена с внешним устройством), настоятельно рекомендуется использовать EOL вместо CRLF или LF.

Как показывает опыт, пакет crwdaq достаточно терпимо относится к разделителям в файлах.
Например, разделители CRLF или LF одинаково допустимы в:
- в конфигурационных файлах .cfg, мнемосхемах .crc, калибровках .cal и т.д.
- в исходных файлах с кодом Pascal - .pas, .inc и т.д.
- в файлах инициализации .ini, журналах .log и т.д.

Однако строго должна соблюдаться корректность разделителей в следующих случаях:
- разделители LF в файлах .c, .h кодов и заголовков программ C/C++ для gcc под Unix,
- разделитель LF в файлах .sml сценариев SMI (конечных автоматов),
- разделитель LF в файлах .sh сценариев bash.

При неверном задании разделителей в этих случаях возникает ошибка.

Для этих файлов предпочтительным разделителем является LF. Например, файлы .c или .sml с разделителями LF корректно компилируются под Windows, хотя с разделителем CRLF под Unix они выдают ошибку при компиляции. Поэтому, видимо, есть смысл всегда использовать LF для этих типов файлов.

Для конвертирования разделителей строк можно использовать программы unix2dos, dos2unix, fixeol, входящие в состав репозитория, либо пакета crwkit под Linux, либо пакета UnixUtils под Windows.

Для конвертирования разделителей в пакет crwkit входит также программа fixeol, вызвать которую можно кнопкой fixeolzen в программе Double Commander.

Для поиска разделителей строк в текстах следует использовать специальную функцию PosEol, а не конструкции типа Pos(EOL,s) или Pos(CRLF,s). Это связано с тем, что в общем случае нельзя предугадать, какой тип разделителя строк поступит на вход процедуры обработки. Устойчиво работающая кроссплатформенная программа должна справляться с любым типом разделителя строк и не делать предположений о том, каким он будет.

Перейти к Содержанию


Разделители путей поиска (PathSep)

Системы Unix и Windows используют разные символы для разделения путей поиска PATH:
- Unix использует разделитель :,
- Windows использует разделитель ;.

Для формирования путей поиска в программах используйте константу PathSep или PathSeparator.
Эта константа содержит правильный разделитель путей для текущей операционной системы.

Перейти к Содержанию


Разделители имен каталогов и файлов (PathDelim)

Системы Unix и Windows используют разные символы для разделения компонентов имени файла (каталогов и файлов):
- Unix использует разделитель /,
- Windows использует разделитель \.

Для формирования путей поиска в программах используйте константу PathDelim или DirectorySeparator.
Эта константа содержит правильный разделитель для каталогов и имен файлов.

Для композиции (составления) имен каталогов и файлов используйте функцию AddPathDelim.
Функция AddBackSlash доступна, но считается устаревшей.

Функция AdaptFileName адаптирует (исправляет) имена файлов по правилам текущей системы, поэтому её также можно использовать для коррекции разделителей каталогов и имен файлов.

Перейти к Содержанию


Соглашения об именах файлов и порядок обработки имен файлов

Имена файлов в Unix и Windows подчиняются похожим, но отличающимся правилам.

Под Windows имена файлов:

Под Unix имена файлов:

Поскольку пакет crwdaq является кроссплатформенным, имена файлов могут быть записаны как по правилам Unix, так и по правилам Windows. Для правильного использования имена файлов должны быть адаптированы (исправлены) в соответствии с правилами текущей операционной системы.

Ключевыми функциями для адаптации имен файлов являются следующие функции:

  1. Функция AdaptFileName применяется для обычных файлов. Она:
  2. Функция AdaptExeFileName применяется для исполняемых файлов. Она:
  3. Функция AdaptDllFileName применяется для файлов динамических библиотек. Она:
  4. Функция AdaptLnkFileName применяется для файлов ярлыков Рабочего Стола. Она:
  5. Функция DaqFileRef применяется для дополнительной (финальной) обработки имен файлов. Она:

Имена файлов обрабатывается поэтапно, в определенном порядке.
Рассмотрим следующий пример.

Допустим, что имя файла считывается из файла demo.cfg с помощью функции ReadIni. Предположим, что в файловой ссылке используется переменная окружения $CRW_DAQ_CONFIG_HOME_DIR, так что в файле содержится, например, параметр FileName:

FileName = $CRW_DAQ_CONFIG_HOME_DIR/../data/params.ini  ; запись по правилам Unix
FileName = %CRW_DAQ_CONFIG_HOME_DIR%\..\Data\Params.ini ; запись по правилам Windows

Как правильно прочитать такой параметр? Это делается так:

  1. Считываем параметр из файла: s:=ReadIni('FileName');.
  2. Делаем подстановку переменных окружения: s:=ExpEnv(s);.
    Эта операция должна быть первой в цепочке обработки.
  3. Применяем операцию адаптации имени: s:=AdaptFileName(s);.
    Эта операция приводит имя файла к правилам текущей операционной системы.
  4. Применяем функцию DaqFileRef: s:=DaqFileRef(s,'.ini');.
    Эта функция выполняет дополнительную коррекцию и проверку имени файла,
    например, преобразует относительные имена в абсолютные, а также приводит
    имя к каноническому виду.

Эту цепочку вычислений можно “свернуть” в один сложный вызов:

s:=DaqFileRef(AdaptFileName(ExpEnv(ReadIni('FileName'))),'.ini');

Порядок в приведенной выше цепочке вычислений важен, т.к. имена в Unix чувствительны к регистру. Если, например, выполнить вызов ExpEnv после AdaptFileName, то будет ошибка, т.к. AdaptFileName изменит регистр строки и ссылка на переменную окружения станет неверной.

Имена исполянемых файлов и сценариев оболочки обрабатываются особенным образом, с помощью AdaptExeFileName.
При этом (дополнительно) предполагается, что:

Если указанные условия выполнены, то вызов типа
s:=DaqFileRef(AdaptExeFileName(ExpEnv(ReadIni('FileName'))),'');
вернет имя исполняемого файла или сценария оболочки, актуального для текущей OS.

Например, если конфигурационный файл содержит параметр

ScriptName = ..\Utility\PreProcessor.cmd ; файл задан по правилам Windows

то вызов s:=DaqFileRef(AdaptExeFileName(ExpEnv(ReadIni('ScriptName'))),''); в системе Unix возвратит имя типа …/utility/preprocessor.sh, преобразованное по правилам Unix.

Таким образом, с помощью AdaptExeFileName в каждой операционной системе с минимальными затратами на кодирование вычисляется имя исполняемого файла, подходящего для этой системы.

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

Перейти к Содержанию


Соглашения об именах переменных окружения

Переменные окружения как правило рекомендуется указывать в верхнем регистре.

В системе Windows имена переменных окружения не зависят от регистра, поэтому вызовы GetEnv(‘Path’) или GetEnv(‘PATH’) эквивалентны.

Однако в системах Unix имена переменных окружения регистро-зависимы, поэтому, например, вызов GetEnv(‘PATH’) будет верен, а вызов GetEnv(‘Path’) ошибочен.

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

Переменная Типичное значение (пример) Комментарий
BASH_ENV /home/alex/.bashrc Файл с настройками командного процессора bash.
DESKTOP_SESSION fly Имя сессии Рабочего Стола.
DISPLAY :0 Имя текущего графического монитора (экрана дисплея).
HOME /home/alex Домашний каталог текущего пользоввателя.
LANG ru_RU.UTF-8 Языковые настройки локали.
LOGNAME alex Имя пользователя, выполнившего вход login.
PATH /usr/local/bin:/usr/bin:/bin Список путей для поиска файлов.
PWD /home/alex Текущий рабочий каталог.
SHELL /bin/bash Путь командного процессора.
TERM xterm Программа эмулятора терминала (консоль).
TMPDIR /tmp Каталог временных файлов (для системы).
USER alex Имя текущего пользователя.
XDG_CURRENT_DESKTOP fly Имя оконного менеджера.
XDG_RUNTIME_DIR /run/user/1000 Каталог временных файлов (для сеанса).
XDG_SESSION_DESKTOP fly Имя оконного менеджера (для сеанса).
XDG_SESSION_ID 3 Идентификатор сеанса.
XDG_SESSION_TYPE x11 Тип сеанса (x11 = графический).

Как легко заметить, переменные окружения указаны в верхнем регистре. Указание переменных окружения в нижнем регистре возможно, но не типично для Unix систем, поэтому там, как правило, используются системные переменные окружения в верхнем регистре. В то же время указание переменных окружения в верхнем регистре не будет ошибкой и в случае системы Windows, т.к. так там регистр вообще не играет роли.

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

Из этого правила есть, однако, исключения.
Например, в пакете crwdaq определяется целый ряд переменных в смешанном регистре:
- WantedWebBrowser - предпочтительный обозреватель для Web сайтов,
- WantedLogViewer - желательная программа просмотра .log журналов,
- и т.д.

В этом случае переменные окружения должны передаваться точно “как есть”:

@run $WantedLogViewer demo.log
@run $WantedWebBrowser help.htm

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

Перейти к Содержанию


Процедура перевода старых конфигураций Crw32 в конфигурации CrwDaq

В пакете Crw32 было разработано множество прикладных DAQ-систем и был накоплен большой объем программных кодов, конфигураций, мнемосхем и т.д.
С появлением новой версии CrwDaq встает задача перевода этих конфигураций в новую версию.

Для этого предлагается следующая процедура:

Перейти к Содержанию


Процедура перевода сценариев .cmd/.bat в .sh

Сценарии оболочки операционной системы используются для решения вспомогательных задач типа обработки файлов, запуска и остановки внешних программ и т.д. средствами командной оболочки операционной системы. Обычно это cmd.exe в Windows или bash в Unix.

Сценарии оболочки операционной системы для кроссплатформенной DAQ конфигурации:

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

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

Обычно первоначальный сценарий пишется и отлаживается в одной из систем (Windows или Unix) - в той, где это удобнее. Затем остается перевести сценарий .cmd в .sh или наоборот.

Перевод сценария .cmd/.bat в .sh

Для перевода сценария .cmd в .sh используется, например, редактор kate.
В ходе перевода большая часть работы выполняется путем нескольких итераций замены текста.
Для замены иногда используется обычный текст plain, либо регулярные выражения regexp.
При замене регистр CS CaseSensitive учитывается (+), либо нет (-).
Некоторая часть требует “ручной” работы, поскольку не поддается автоматизации.

Таблица замен.

Тип CS Шаблон Замена Комментарий
regexp - ^\s*@echo\s+off\s* #!/bin/bash Эхо/интерпретатор.
regexp - ^:(\w+)\s* function \1(){ Объявление функции/подпрограммы.
regexp - ^\s*goto\s+:EOF\s* }; Завершение функции/подпрограммы.
regexp - %(\w+)%_ ${\1}_ Подстановка переменной (первая).
regexp - %(\w+)%(\w) ${\1}\2 Подстановка переменной (вторая).
regexp - %(\w+)% $\1 Подстановка переменной окружения.
regexp - \^$ \ Замена символа ^ (первая).
regexp - \^ Пустая стока Замена символа ^ (вторая).
plain - %* $* Подстановка всех аргументов.
plain - %% % Замена удвоения процента.
regexp - %~?(\d) $\1 Замена позиционных аргументов.
regexp - ^echo (.*) echo "\1"; Замена echo (первая).
regexp - ^echo. echo ""; Замена echo (вторая).
regexp - set /a (.*) let "\1"; Замена арифметического выражения.
-
regexp -
plain -
-

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

Перейти к Содержанию


Шрифты для кроссплатформенной разработки

Старый пакет Crw32 работает под Windows и поэтому в мнемосхемах часто использовались шрифты, штатно имеющиеся в этой системе. Для кроссплатформенной разработки необходимо заменить эти шрифты на свободно распрространяемые кроссплатформенные шрифты, которые доступны в разных системах.

Следует различать основные группы шрифтов:

Также есть эффекты (атрибуты) шрифтов:

Рекомендуемые шрифты для кроссплатформенной разработки

Для кроссплатформенной разработки (для мнемосхем) настоятельно рекомендуется использовать шрифты семейства ParaType:

Шрифты семейства ParaType:

Имя шрифта Назначение шрифта
PT Mono Основной моноширинный шрифт для информационных надписей: полей ввода/вывода, консоли, журналов и т.д.
PT Sans Основной гладкий шрифт для декоративных надписей: меток, комментариев, справочных файлов и т.д.
PT Sans Narrow Специальный узкий шрифт для длинных декоративных надписей при ограниченной длине поля вывода.
PT Sans Caption Специальный широкий шрифт для выделения жирных декоративных надписей (например, заголовков).
PT Serif Основной шрифт с засечками для печатных документов.
PT Astra Sans Гладкий шрифт для документов, совместимый по размерам с Times New Roman.
PT Astra Serif Замена Times New Roman, основной шрифт для печатных документов.

Достоинства шрифтов семейства ParaType:

По этим причинам рекомендуется всегда использовать шрифты семейства ParaType.

Замена шрифтов для кроссплатформенной разработки

При переводе DAQ конфигураций crw32 в crwdaq иногда ввозникает проблема замены шрифтов Windows, которых нет под другими системами.

Для замены шрифтов Windows на кроссплатформенные рекомендуется использовать следующую таблицу.

Таблица замены шрифтов:

Шрифт Windows Рекомендуемая замена Комментарий
Terminal PT Mono Bold Шрифт для ввода-вывода, информационных надписей.
Courier New PT Mono Шрифт для ввода-вывода, информационных надписей.
Courier PT Mono Шрифт для ввода-вывода, информационных надписей.
Lucida Console PT Mono Шрифт для ввода-вывода, информационных надписей.
Arial PT Sans Шрифт для декоративных надписей.
Arial Black PT Sans Caption Шрифт для жирных декоративных надписей.
Arial Narrow PT Sans Narrow Шрифт для узких декоративных надписей.
Tahoma PT Sans Шрифт для декоративных надписей.
Verdana PT Sans Шрифт для декоративных надписей и HTML документов.
Ms Sans Serif PT Sans Шрифт для декоративных надписей, диалогов.
Times New Roman PT Astra Serif Шрифт для печатных документов (основной).
Times New Roman PT Astra Sans Шрифт для документов (для вывода на экран).

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

Перейти к Содержанию