Показаны сообщения с ярлыком шрифты. Показать все сообщения
Показаны сообщения с ярлыком шрифты. Показать все сообщения

воскресенье, 25 ноября 2012 г.

Шрифты Powerline в linux консоли

Отвечая на вопрос о шрифтах Powerline в linux консоли (см. комментарии к этому посту), я привел варианты, как этого можно добиться. Ни один вариант для меня не подошел в силу разных обстоятельств. Добавлять новые символы в консоли оказалось вообще не просто и какого-то единого алгоритма попросту не существует. Но мне все-таки удалось с этим справиться, и здесь я хочу поведать об этой истории успеха. Все, что здесь будет сказано, относится к Fedora 17, для других дистрибутивов действия могут слегка отличаться.


Картинка большая и кликабельная. Символы из Powerline видны в статусной строке vim (там где им и положено находиться), а также внутри присваиваемого значения переменной PROMPTLINE в функции proml редактируемого файла .bashrc (курсор находится между словами function и proml, создавая впечатление, что это одно слово, соединенное символом подчеркивания). Цветов в статусной строке нет по той простой причине, что в дефолтной схеме Powerline используется 256-цветная палитра, которая не работает в linux консоли. Так что если вы хотите нормальную цветную статусную строку Powerline в linux консоли, вам придется изменить дефолтную цветовую схему Powerline, или создать новую (схемы находятся в директории $HOME/.vim/autoload/Powerline/Colorschemes/). Также хочу отметить, что эта картинка была получена с помощью замечательной программы fbgrab из пакета fbcat, который я взял отсюда (кликнув на строке Fedora 17).

Итак, что нам понадобится для создания нового шрифта с символами из Powerline для linux консоли? Прежде всего, понимание того, что нам нужен шрифт с весьма специфичным форматом PSF, который, хотя и поддерживает Unicode mapping, все же не может содержать более 512 символов. В Fedora 17 psf шрифты находятся в директории /lib/kbd/consolefonts/. При включении режима Unicode в консоли c помощью команды unicode_start, попросту загружается новый шрифт с необходимыми символами, в частности у меня в Fedora это /lib/kbd/consolefonts/UniCyr_8x16.psf.gz, который содержит всего 256 символов. Если в вашей консоли используется шрифт terminus, то название файла будет, естественно, другим. Таблица соответствия с символами Unicode прописана внутри файла шрифта, и просмотреть ее можно с помощью команды psfgettable. Таким образом, задача сводится к созданию нового psf файла, в который добавлены символы из Powerline, при этом общее количество символов в файле не должно превышать 512. В дальнейшем, в качестве базового шрифта я буду использовать UniCyr_8x16.psf.

Что нам понадобится из программного обеспечения? Первое - программа otf2bdf для создания шрифта в промежуточном формате bdf: ее в Fedora 17 можно установить с помощью yum. Второе - программа gbdfed для конвертации шрифта bdf в формат psf: она также устанавливается с помощью yum. Третье - пакет PSF tools для манипуляции с psf шрифтами: его я скачал отсюда. Четвертое - удобный текстовый редактор (например, vim) для удаления артефактов конвертации в текстовом представлении шрифта. Пятое - исходный файл с базовыми кириллическими символами, в который мы внедрим новые символы Powerline, как я уже говорил это будет файл UniCyr_8x16.psf из директории /lib/lbd/consolefonts/.

Итак, приступим. Первое, что мы сделаем - это выделим все символы из Powerline (всего их девять) в отдельный шрифт в формате bdf. Эта задача вполне по плечу программе otf2bdf. Исходный файл должен быть получен с помощью программы  fontpatcher из плагина Powerline и иметь формат otf или ttf (см. подробности здесь). У меня данный файл называется DejaVuSansMonoForPowerline.ttf. Программа otf2bdf должна знать, какие символы нам нужны, а также соответствующие им значения Unicode. Для этого мы создадим вспомогательный файл dvusmpl.bdfmap (название не имеет значения), в котором зададим этот маппинг:
REGISTRY ISO10646
ENCODING 1
0x60 0x2B60
0x61 0x2B61
0x62 0x2B62
0x63 0x2B63
0x64 0x2B64
0x80 0x2B80
0x81 0x2B81
0x82 0x2B82
0x83 0x2B83
Строки REGISTRY и ENCODING могут содержать достаточно произвольные значения: в нашем случае они не будут важны. Далее прописан маппинг номер символа : значение Unicode. Номера символов в принципе тоже не имеют значения, однако здесь я сопоставил их со значениями Unicode, которые соответствуют символам Powerline. Первая попытка:
otf2bdf -v -c M -l '96_131' -o dvusmpl.bdf -m dvusmpl.bdfmap DejaVuSansMonoForPowerline.ttf
не увенчается успехом из-за размера сгенерированного шрифта, который окажется 12x20 вместо 8x16 (bdf формат имеет текстовое представление и размер шрифта можно найти в строке FONTBOUNDINGBOX в заголовке файла). otf2bdf позволяет настроить размер шрифта с помощью опций -rh и -rv, значения которых, однако, соответствуют не количеству пикселов по горизонтали и вертикали, а количеству точек на дюйм, поэтому поиск подходящих значений - задача творческая. После нескольких попыток я наконец подобрал подходящие значения для этих опций:
otf2bdf -v -c M -rh 66 -rv 86 -l '96_131' -o dvusmpl.bdf -m dvusmpl.bdfmap DejaVuSansMonoForPowerline.ttf
Опция -c M указывает на то, что мы хотим создать моноширинный шрифт, а опция -l '96_131' задает диапазон символов для генерации (десятиричное число 91 соответствует шестнадцатиричному 0x60, a 131 - 0x83).

Теперь у нас есть файл c символами Powerline в формате bdf. Открываем его в программе gbdfed, убеждаемся, что все 9 символов на месте (скорее всего gbdfed разобьет шрифт на 2 страницы, при этом первые 5 символов окажутся на первой, а оставшиеся 4 - на второй), и экспортируем его в формат PSF (в меню File программы). После экспорта файла у нас появится файл dvusmpl.psfu.

Следующий шаг - переводим файл dvusmpl.psfu в текстовый формат с помощью программы psf2txt из PSF Tools.
psf2txt dvusmpl.psfu dvusmpl.txt
Открываем dvusmpl.txt в текстовом редакторе и правим псевдографические изображения символов по своему вкусу: это необходимо, так как odf2bdf в процессе масштабирования шрифта исказила исходные символы (главным образом стрелки). Поскольку я все это уже проделал, то результат (с дополнительными правками - см. ниже) проще скачать отсюда.

Теперь берем исходный PSF файл UniCyr_8x16.psf.gz, раззиповываем его и переводим в текстовый формат:
psf2txt UniCyr_8x16.psf UniCyr_8x16ForPowerline.txt
В конец нового файла UniCyr_8x16ForPowerline.txt вставляем содержимое файла dvusmpl.txt, меняем  строки // Character 0 .. 8 во вставленном участке на // Character 256 .. 264. Также добавляем во вставленном участке строки с Unicode информацией для каждого отдельного символа таким же образом, как это сделано для символов исходного psf шрифта. Если вы скачали выложенный мною файл dvusmpl.txt, то достаточно просто добавить его в конец файла UniCyr_8x16ForPowerline.txt, так как все необходимые изменения в нем уже есть. Теперь идем в начало файла, ищем строку Length: 256 и заменяем ее на Length: 265 (мы ведь добавили 9 новых символов).

Переводим UniCyr_8x16ForPowerline.txt в формат psf c помощью программы txt2psf из PSF Tools:
txt2psf UniCyr_8x16ForPowerline.txt UniCyr_8x16ForPowerline.psf
Можно убедиться, что новые символы присутствуют в UniCyr_8x16ForPowerline.psf:
psfgettable PowerLineSymbols1.psf | grep -i 2b80
Зипуем файл и кладем его в директорию /lib/kbd/consolefonts/. Логинимся в виртуальной консоли и загружаем новый шрифт:
unicode_start UniCyr_8x16ForPowerline
Теперь открываем vim и смотрим, присутствуют ли в статусной строке символы из Powerline.

Если есть желание загружать новый шрифт каждый раз при входе в систему из виртуальной консоли, то можно добавить строку unicode_start UniCyr_8x16ForPowerline для linux консоли в какой-нибудь файл из директории /etc/profile.d/ (см. подробно здесь). Кроме того, теперь и в linux консоли вы сможете сделать приглашение командной строки более привлекательным (см. здесь).

Update. Выяснилось, что дефолтный консольный Unicode шрифт в Fedora 17 - это latarcyrheb-sun16 (загляните внутрь скрипта /usr/bin/unicode_start и поймете почему). В шрифте определены 512 символов, поэтому, если брать его за основу, следует не добавлять дополнительные символы, а заменить те из существующих, которые вы вряд ли будете использовать, например в позициях 460 - 488 находятся символы арабского алфавита, и если вы не читаете тексты на арабском, то можете смело вставлять новые символы куда-нибудь внутрь этого диапазона.

Последние изменения. Картинка:


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

За базовый шрифт я взял /lib/kbd/consolefonts/latarcyrheb-sun16.psfu.gz. Распаковываем, переводим в текст с помощью psf2txt, заменяем символы с 460 по 472 этим. Переводим обратно в psf:
txt2psf latarcyrheb-sun16.txt latarcyrheb-sun16_vim-unicode.psfu
Зипуем latarcyrheb-sun16_vim-unicode.psfu и кладем в /lib/kbd/consolefonts/. Файл /etc/profile.d/console_unicode.sh теперь выглядит так:
if [ "$TERM" = "linux" ]; then
    unicode_start latarcyrheb-sun16_vim-unicode
    export CONSOLEFONT_HAS_VIM_UNICODE_SYMB=1
fi
Изменения в файле $HOME/.bashrc:
case $COLORTERM in
    gnome*|mate*|konsole*)
        TERM=xterm-256color
        ;;
esac

[ -n "$XTERM_SHELL" ] && COLORTERM=xterm-256color

function proml
{
    case $COLORTERM in
        gnome*|mate*|konsole*)
            local PROMPTLINE="\[\033[38;5;167m\]\$(date +%d/%m/%y\ %H:%M)⮁⮁ \
\[\033[38;5;173m\]\u@\[\033[38;5;140m\]\h⮁⮁\[\033[38;5;173m\] \W \[\033[0m\] "
            local PROMPTLINE2='\[\033[38;5;196m\]⮀\[\033[0m\] '
            ;;
        xterm*)
            local PROMPTLINE="\[\033[38;5;167m\](\$(date +%d/%m/%y\ %H:%M))\
\[\033[38;5;173m\][\u@\[\033[38;5;140m\]\h\[\033[38;5;173m\] \W]$\[\033[0m\] "
            local PROMPTLINE2='\[\033[38;5;196m\]>\[\033[0m\] '
            ;;
        *)
            if [ "$TERM" = "linux" ] && \
               [ -n "$CONSOLEFONT_HAS_VIM_UNICODE_SYMB" ] ; then
                local PROMPTLINE="\[\033[32m\]\$(date +%d/%m/%y\ %H:%M)⮁⮁ \
\[\033[0m\]\u@\[\[\033[1;34m\]\h\[\033[0m\]⮁⮁\[ \W \033[32m\]\[\033[0m\] "
                local PROMPTLINE2='\[\033[31m\]⮀\[\033[0m\] '
            else
                local PROMPTLINE="(\$(date +%d/%m/%y\ %H:%M))[\u@\h \W]$ "
                local PROMPTLINE2=''
            fi
            ;;
    esac
    PS1=$PROMPTLINE
    PS2=$PROMPTLINE2
}

proml
unset proml
Изменения в $HOME/.vimrc:
" ---- Powerline settings
" ----
" disable Unicode symbols in linux console if font does not support them
let g:DisableUnicodeSymbols = &term =~? '^linux' &&
            \ empty($CONSOLEFONT_HAS_VIM_UNICODE_SYMB)

let g:Powerline_theme = 'default'

" solarized theme is suitable for linux console
if &t_Co < 256
    let g:Powerline_colorscheme = 'solarized'
else
    let g:Powerline_colorscheme = 'default'
endif

" fancy symbols need patched font!
if g:DisableUnicodeSymbols
    let g:Powerline_symbols = 'compatible'
else
    let g:Powerline_symbols = 'fancy'
endif

" do not use Powerline in simple console terminals
let g:DisablePowerline = &term =~? '^linux' && 0

if g:DisablePowerline
    let g:Powerline_loaded = 0
endif

if !empty($TMPDIR)
    let g:Powerline_cache_file = $TMPDIR."/Powerline_".$USER."_".
                \ g:Powerline_theme."_".g:Powerline_colorscheme."_".
                \ g:Powerline_symbols.".cache"
else
    let g:Powerline_cache_file = '/tmp/Powerline_'.$USER.'_'.
                \ g:Powerline_theme.'_'.g:Powerline_colorscheme.'_'.
                \ g:Powerline_symbols.'.cache'
endif
(я сюда еще правильную обработку кэша цветовой схемы Powerline добавил).

Да, и самое главное - патч для  цветовой схемы solarized.vim. Без него статусная строка Powerline в консоли правильно работать не будет!
--- autoload/Powerline/Colorschemes/solarized.vim   2012-11-27 13:46:28.923529118 +0400
+++ autoload/Powerline/Colorschemes/solarized.vim.new   2012-11-27 13:35:09.794349678 +0400
@@ -3,19 +3,19 @@
 " N = no focus
 " 16 hex colors as defined on http://ethanschoonover.com/solarized
 call Pl#Hi#Allocate({
-  \ 'base03'  : [8,   0x002b36],
+  \ 'base03'  : [&t_Co > 8 ? 8 : '0*',   0x002b36],
   \ 'base02'  : [0,   0x073642],
-  \ 'base01'  : [10,  0x586e75],
-  \ 'base00'  : [11,  0x657b83],
-  \ 'base0'   : [12,  0x839496],
-  \ 'base1'   : [14,  0x93a1a1],
+  \ 'base01'  : [&t_Co > 8 ? 10 : '2*',  0x586e75],
+  \ 'base00'  : [&t_Co > 8 ? 11 : '6*',  0x657b83],
+  \ 'base0'   : [&t_Co > 8 ? 12 : '1*',  0x839496],
+  \ 'base1'   : [&t_Co > 8 ? 14 : '3*',  0x93a1a1],
   \ 'base2'   : [7,   0xeee8d5],
-  \ 'base3'   : [15,  0xfdf6e3],
+  \ 'base3'   : [&t_Co > 8 ? 15 : '7*',  0xfdf6e3],
   \ 'yellow'  : [3,   0xb58900],
-  \ 'orange'  : [9,   0xcb4b16],
+  \ 'orange'  : [&t_Co > 8 ? 9 : '4*',   0xcb4b16],
   \ 'red'     : [1,   0xdc322f],
   \ 'magenta' : [5,   0xd33682],
-  \ 'violet'  : [13,  0x6c71c4],
+  \ 'violet'  : [&t_Co > 8 ? 13 : '5*',  0x6c71c4],
   \ 'blue'    : [4,   0x268bd2],
   \ 'cyan'    : [6,   0x2aa198],
   \ 'green'   : [2,   0x859900],
(зафайлил баг в Powerline, надеюсь починят).

пятница, 19 августа 2011 г.

Установка Firefox 6 и Thunderbird 6 в Fedora 14

Да, я так и не перешел на Fedora 15, так как не определился, чем заменить старый добрый Gnome 2. А пользоваться обновленными продуктами от Mozilla очень хочется. Так, недавно вышли очередные мажорные версии Firefox и Thunderbird, обе за номером 6. Естественно, в репозиториях Федоры их нет, зато они нашлись в репозитории Remi. Я не подключал данный репозиторий, поэтому просто скачал соответствующие пакеты (thunderbird, firefox и xulrunner6) и установил их. К сожалению, сразу же всплыла старая проблема с ужасными шрифтами без поддержки Byte Code Interpreter. Насколько я помню, исходный код библиотеки cairo был с изменениями включен в состав Firefox для сборки из-за какого-то странного бага с никому ненужными анимированными файлами gif. Благодаря этому, результирующий вид шрифтов стал зависеть не от того, какие системные библиотеки, отвечающие за рендеринг шрифтов, используются в вашей системе, а от того, какие библиотеки были у сборщика во время компиляции. Таким образом, товарищ Remi Collet при компиляции Firefox и Thunderbird использовал опцию, которая включает измененный вариант cairo, и кроме того, он располагал библиотеками для рендеринга шрифтов (fontconfig и libXft), которые поставлялись с Fedora 14 по умолчанию, что, в общем-то, логично и неудивительно.

Итак, проблема ясна. Будем лечить. Я не захотел собирать firefox и thunderbird с нуля, а решил воспользоваться SRPM пакетами из репозитория Remi. Найти их можно здесь. Очевидно, для того чтобы правильно пересобрать эти пакеты, нужно чтобы соответствующие правильные библиотеки были представлены в вашей  системе. Проще всего это сделать (если вы до сих пор этого не сделали и не используете репозиторий infinality), подключив репозиторий russianfedora-fixes и обновившись через yum update. После обновления будут установлены правильные fontconfig и libXft. Кроме того, для сборки нам понадобятся fontconfig-devel, libXft-devel и, разумеется, cairo-devel:
yum install fontconfig-devel libXft-devel cairo-devel
Перейдем к сборке rpm. Если вы еще не завели специального псевдопользователя для этой цели (а так рекомендует Федора), то сейчас самое время. От имени суперпользователя вводим
useradd mockbuild
Я назвал его mockbuild, хотя конкретное имя ничего не значит, можно выбрать на свой вкус. Задаем ему какой-нибудь пароль:
passwd mockbuild
Для того, чтобы пользователь-сборщик не появился в списке приглашения GDM, откроем файл /usr/share/gdm/gdm.schemas, найдем там строку <key>greeter/Exclude</key> и добавим в список пользователей ниже внутри тегов <default>...</default> нашего mockbuild.

Теперь нужно установить пакет для поддержки сборки rpm пакетов:
yum install rpmdevtools
Затем логинимся как mockbuild:
su - mockbuild
и создаем дерево директорий для сборки пакетов:
rpmdev-setuptree
Устанавливаем скачанные пакеты SRPM (от имени mockbuild, конечно) с помощью простой команды
rpm -ivh firefox-6.0-1.remi.src.rpm xulrunner6-6.0-1.remi.src.rpm thunderbird-6.0-1.remi.src.rpm
После этой команды исходники попадают в rpmbuild/SOURCES, а spec файлы - в директорию rpmbuild/SPECS. Переходим в директорию со spec файлами и правим. В файлах firefox6.spec и xulrunner6.spec после строки
echo "ac_add_options --enable-system-lcms" >> .mozconfig
добавляем строку
echo "ac_add_options --enable-system-cairo" >> .mozconfig
а в файле thunderbird.spec добавляем строку
ac_add_options --enable-system-cairo
где-нибудь между строками
cat <<EOF | tee -a .mozconfig
и
EOF
(например в самом конце, прямо перед строкой EOF).

Возможно, для сборки вам придется установить дополнительные пакеты. Так, мне пришлось установить autoconf213, lcms-devel, wireless-tools-devel и libvpx-devel. С помощью yum это сделать несложно.

Переходим к построению rpm, последовательно запуская команды
rpmbuild -ba xulrunner6.spec
rpmbuild -ba thunderbird.spec
В списке нет firefox, поскольку он зависит от построенного xulrunner6, поэтому, когда эти две команды отработают (а ждать нужно достаточно долго), переходим в директорию /home/mockbuild/rpmbuild/RPMS/your_arch, где your_arch - архитектура вашей системы (например, x86_64) и от имени суперпользователя обновляем свежесобранные пакеты:
rpm -Uvh thunderbird-6.0-1.fc14.x86_64.rpm  xulrunner6-6.0-1.fc14.x86_64.rpm xulrunner6-devel-6.0-1.fc14.x86_64.rpm
Если в вашей системе уже стоит xulrunner-devel, то его нужно будет предварительно удалить, так как он конфликтует с xulrunner6-devel. После установки новых пакетов возвращаемся в директорию SPECS и от имени mockbuild строим firefox:
rpmbuild -ba firefox6.spec
После завершения сборки снова возвращаемся в директорию RPMS и от имени суперпользователя обновляем firefox:
rpm -Uvh firefox-6.0-1.fc14.x86_64.rpm
После установки запускаем новые firefox и thunderbird и наслаждаемся правильным рендерингом шрифтов и проделанной работой :)