понедельник, 17 июня 2019 г.

Изменение шрифтов в диалоге инсталлятора LibreOffice в Windows

Сегодня диалог инсталлятора LibreOffice в Windows использует шрифт Tahoma с кеглем 8. В багзилле есть запрос на приведение шрифтов к стандартному шрифту в Windows для GUI, коим является Segoe UI с кеглем не менее, чем 9. Попробуем это сделать (спасибо Майку за теорию!)
Инсталлятор LibreOffice использует стандартный для Windows механизм msi. Любой файл msi можно редактировать ручками, используя специальную утилиту от MicroSoft - Orca. Скачать ее можно по этой ссылке.
После установки Orca нужно щёлкнуть правой кнопкой по файлу инсталлятора LibreOffice с расширением .msi и выбрать пункт "Edit with Orca". Откроется вот такое окно:
С первого взгляда ничего не понятно и вообще страшно глядеть, одни цифры и символы.
Примечание: вот кстати ссылка на документацию по msi: https://docs.microsoft.com/en-us/windows/desktop/Msi/windows-installer-portal.
Будем разбираться. Итак, в левой части окна мы видим список таблиц, используя данные из которых, msi и формирует внешний вид диалоговых окон инсталлятора. А в правой части окна мы как раз видим данные той таблицы, которая выделена в настоящий момент в левой части окна.
Для изменения только лишь шрифтов нам необходима таблица TextStyle. Найдем её в левой части окна и выберем её:
Это относительно простая таблица. По столбцам содержится следующая информация:
TextStyle - это внутреннее название шрифта, которое используется в других таблицах внутри нашего msi.
FaceName - это название шрифта, которое отображается в операционной системе. Обязательно корректное написание.
Size - это кегль шрифта, который будет отображаться в диалоге.
Color - здесь можно задать цвет шрифта, если ничего не указано, то шрифт скорее всего выставлен в "Авто". Я с цветом экспериментов не ставил, мне было ни к чему.
StyleBits - это отдельный признак форматирования символов шрифта. Цифра 1 - жирное написание, 2 - курсив.
Обратите внимание, как много самых разных шрифтов прописано в таблице. При этом, как оказалось, большинство указанных шрифтов просто нигде в нашем диалоге не используется. Проверяется это очень просто: жмём Ctrl+F, открывается окно поиска, забиваем туда внутреннее имя шрифта и жмём кнопку "Найти". Поиск осуществляется по всем таблицам файла msi с текущей строки сверху вниз. Когда поиск дойдет до последней строки в последней таблице, просто на соответствующий вопрос (Продолжить поиск с начала?):
нужно ответить "Да".
И вы увидите, что больше ни в одной таблице шрифт, например MSSGreySerif8, не используется. Аналогично нужно было проверить все остальные шрифты, что и было сделано.
Далее мы осознали, что всего для нашего диалога нам требуется три вида шрифта: основной, основной с жирным написанием и заголовок. Соответственно основной шрифт - Segoe UI кегль 9, заголовок - Segoe UI кегль 11. Вот какой вид приняла таблица TextStyle после наших правок:
Описаны всего три шрифта, все три это Segoe UI. Обратите внимание на StyleBits равном 1 (жирное начертание) для двух из них. Также были изменены внутренние названия шрифтов.
Теперь, в связи с тем, что мы изменили внутренние названия шрифтов, необходимо для ВСЕХ управляющих элементов диалогов (Controls) и для текста в диалогах (Text) прописать новые внутренние названия.
Делается это:
- во-первых в таблице Property, где необходимо в строке DefaultUIFont задать в столбце Value внутреннее имя нашего основного шрифта - DialogDefault. Это мы задали шрифт по-умолчанию для всего диалога.
- во-вторых в таблице Control, где необходимо в каждой строке, которая имеет в столбце Text первыми символами, например {&Tahoma8} заменить их на например {&DialogHeading}. Этим мы задаём форматирование конкретно этого текста не шрифтом по-умолчанию, а другим, но также заданным в таблице TextStyle.
- в-третьих в таблице RadioButton, где нужно построчно заменить старые внутренние имена шрифтов на новые по логике, указанной выше.
В принципе, на этом замена собственно шрифтов в диалоге закончена. 
Но тут возникает непредвиденная проблема - все геометрические размеры диалоговых окон, геометрические размеры областей с текстом внутри окон диалога, все расположения контролов внутри окна диалога, жёстко заданы в тех же таблицах. А так как мы изменили и шрифт (который сам по себе чуть больше старого) и кегль шрифта сделали больше, то теперь некоторые слова в диалогах не показываются, они обрезаются по жестко заданным старым границам!
Примечание: кстати, цифры, которыми обозначены размеры диалогов, областей текста, отступы контролов, - это вовсе не пикселы, как я сначала подумал. Это некий стандартный юнит, который равен 1/12 размера шрифта MS Sans Serif с кеглем 10! Я сначала вообще был в шоке от такой забавной привязки. А потом всё же стал разбираться. По сути, это сделано так по очень простой причине: пользователь может масштабировать весь UI в системе на, например, 125%. А так как размер любого шрифта в системе (включая тот самый MS Sans Serif) зависит от DPI, то и диалог наш точно также масштабируется пропорционально.
Возникла дополнительная задача - изменить всю геометрию диалогов так, чтобы все надписи полностью отображались бы.
Всего диалоговых окон в инсталляторе msi LibreOffice 31 штука, включая информационные окна и сообщения об ошибках при установке. ВСЕ из них необходимо предварительно просмотреть, используя возможности Orca. Выберите пункт меню Tools->Dialog Preview, откроется вот такое окно:
Выберите любой диалог из списка (не нужно раскрывать плюсик) и нажмите кнопку Preview. Вам будет показано как выглядит данный диалог при текущих значениях в таблицах.
Соответственно, проверив все диалоги на корректность отображения всей информации на них, приступаем к правке геометрии.
Не забываем, что чтобы корректно отобразить весь текст в диалоге, мы должны увеличить область с текстом и следом размер самого диалога!
Я начал с изменения размеров диалогов. Чтобы не путаться с одновременным изменением и ширины и высоты, я изменю только ширину диалогов. Все основные диалоги инсталлятора имеют одинаковый размер 374 х 266 юнитов. Для простоты подсчета новых размеров я просто добавил 100 юнитов к ширине каждого такого диалога.
Размеры диалогов указаны в таблице Dialog в столбцах Width (ширина) и Height (высота). Соответственно для каждого диалога мы меняем 374 на 474.
Далее нам нужно изменить местоположение и размеры контролов (кнопок, выпадающих списков, радио-кнопок, полей для ввода/отображения данных) и размеры областей с текстом. Все эти цифры находятся в таблице Control. Нам нужны столбцы:
Dialog - внутреннее имя диалогового окна
Control - внутреннее название контрола 
Type - тип контрола (кнопка, выпадающий список, радио-кнопка, поле для ввода/отображения данных, область с текстом)
Х - расстояние от левого края диалога до контрола в юнитах.
Y - расстояние от верхнего края диалога до контрола в юнитах.
Width - ширина контрола в юнитах
Height - высота контрола в юнитах
Text - собственно надпись на контроле. На это поле мы будем глядеть, чтобы понимать, а какой блок мы двигаем на диалоге, иногда это не очень очевидно.
Логика при изменении контролов была такая:
- если мы трогаем кнопки - меняем значение в столбце Х (двигаем кнопку!), просто добавляем 100. Но не для всех кнопок, например Help как была в левой части диалога, так и осталась!
- если мы трогаем область с текстом, выпадающий список или поле для ввода/отображения текста - меняем значение в столбце Width (увеличиваем ширину!), также просто добавляем 100.
После завершения манипуляций для одного диалога - смотрим превью получившегося. Если всё ОК - переходим к следующему.
А теперь самая вишенка. В исходном коде LibreOffice есть абсолютно те же самые таблицы с данными, на основании которых собирается диалог инсталлятора msi. Orca позволяет сделать экспорт получившихся таблиц на диск, в том же самом формате, как и в исходниках LibreOffice. Вспоминаем, какие таблицы мы затронули своими действиями и экспортируем только их.
Это были Control, Dialog, Property, RadioButton, TextStyle. Используйте пункт меню Tables->Export Tables для экспорта таблиц на диск.
Далее можно спокойно формировать патч для LibreOffice, как вам удобно.
ps: кстати, вот, что получилось в итоге (показано одно из диалоговых окон). Слева новый вариант, справа - старый):
pps: после ревью патча выявилось несколько проблем:
- я полностью заменил таблицы Dialog и Control и теперь проблемно отследить в каких строках, что менялось. Попросили исправить. Это чисто оформительская проблема.
- в файлах .idt в исходниках LibreOffice были прописаны идентификаторы текстовых строк, вместо самого текста, как мне показывал Orca. Это сделано для возможности локализации интерфейса. Поэтому тем более нельзя просто весь файл заменить на новый: помимо проблем оформления и читабельности патча это ломает локализацию.
- баннер в верхней части диалога нужно перерисовать, увеличив его длину. На скриншоте выше явно видно, что баннер растянут.
ppps: замечания ревью были исправлены и патч был влит в исходники LibreOffice 27 июня 2019 года. Теперь выявилась другая проблема: диалог доступен на куче языков, а я проверял внешний вид только на английском. Это в принципе нормально, я на это и рассчитывал изначально, что патч будет принят, а затем "возможно" будут какие-то замечания к внешнему виду текста в различных языках. Например, в русском обрезаются палочки и хвостики букв "у", "р", "ф" и тому подобное в некоторых строках. Завтра будет доступен свежий ежедневный билд и каждый сможет поглядеть, как стал выглядеть диалог инсталлера на английском. Исправление проблем с обрезанием текста будем делать после выхода 1 альфа версии 6.4, чтобы люди из разных стран могли протестировать на родных языках инсталлер.

7 комментариев:

  1. Пишу сюда, друг места для этого не знаю.
    Даю идею по развитию меню.
    Разделение ячеек в таблице. Сейчас для этого нужно выходить в отдельное меню по центру экрана. Выбирать как и насколько надо разделить.
    Предлагаю выежающие меню как в спец символах https://yadi.sk/i/EVuxFP67YZvlCw
    Функция разделение ячеек популярная, выежающие меню упростит работу с ней.
    В этом варианте убран выбор, как делить ячейку. Только числа. Можно убрать пропорционально деление.
    Убрана кнопка отмены, за ненадобностью.
    Отдаю идею как сам не программист, и сделать такое не могу.

    ОтветитьУдалить
    Ответы
    1. Прекрасная идея. У меня есть пара вопросов уточняющих:
      1. Выезжающее откуда меню? Из панели инструментов? На фоне таблицы? Конкретизируйте.
      2. "В этом варианте убран выбор, как делить ячейку". Почему? Зачем ограничивать юзера?
      3. "Убрана кнопка отмены". Ок. Как будет исчезать менюха? Просто кликнул мимо нее и она исчезла? А если я кликну случайно, то данные пропадут?
      4. "Пишу сюда, друг места для этого не знаю". bugs.documentfoundation.org, не стесняйтесь писать туда все ваши идеи, какими бы странными они вам не казались
      5. "Отдаю идею как сам не программист, и сделать такое не могу". Я тоже не кодер и тое вряд ли смогу сделать виджет без посторонней помощи. Но см. пункт 4, напишите в багзиллу, там как раз кого-то из кодеров может и заинтересовать ваше предложение.

      Удалить
    2. 1. Да, из панели управления.
      2. Это не ограничение. Сейчас переключение нужно из за одного поля ввода количества столбцов или строк. При двух, выбор не нужен ты сразу вбиваешь нужные числа. По умолчанию всё по единице.
      3. Да отмена мимо поля. Да изчезают.Это даст скорость выхода из функции, при риске случайного закрытия. Функция простая, 2-3 действия. С новым расположением и видом нужна 1-3 секунды, на её использование.Это допустимо. Быстро привыкнут.
      Спасибо.

      Удалить
    3. Возник вопрос. Куда в bugs.documentfoundation.org писать предложения. Там только ошибки.

      Удалить
    4. Там при создании бага есть выпадающий список Severity, выберите вместо Normal Enhancement

      Удалить
  2. Роман, спасибо за улучшение LibreOffice! :)

    ОтветитьУдалить
    Ответы
    1. Пожалуйста. Скажи пожалуйста, идиота модератора, который развязал политический и националистический срач на форуме убунту, уволили или как?

      Удалить

Внимание! Сообщения проходят премодерацию!