Ключевые слова:text, latex, rus, font, type1, truetype, (найти похожие документы)
From: geekkoo
Newsgroups: http://linuxportal.ru/
Date: Mon, 20 Sep 2004 18:21:07 +0000 (UTC)
Subject: Type1 и truetype шрифты в LaTeX
Оригинал: http://linuxportal.ru/entry.php/P1003_0_3_0/
Автор статьи: geekkoo
Дата: 03.05.2004
Type1 и truetype шрифты в LaTeX.
Довольно большой набор русских type1 шрифтов распространяется в пакете
pscyr (ftp://mch5.chem.msu.su/pub/russian/psfonts/). Установка
этого пакета подробно (и по русски!) описана в файле README. Однако,
ничто не мешает вам использовать любые понравившиеся вам шрифты в
latex. Единственные проблемы - это 1) сделать эти шрифты доступными
для latexa, и 2) отучить latex растеризовать их. Как это сделать и
будет описано в данном тексте.
Что нужно?
tetex версии >= 1.0.7, ghostscript версии >=6.5 и несколько фонтов. В
качестве примера предлагаю использовать свободные фонты с сайта Vedi
(http://www.prodtp.ru/) - Quake (type1 версия) и Stonehenge,
Nadejda, Coptic (ttf версии). Также нужен будет один файл из пакета
pscyr t2a.enc (файл с вектором кодировки T2AAdobeEncoding), но вы
можете просто установить у себя этот пакет
целиком, тем более, что в нем содержатся очень симпатичные русские
шрифты (мне лично очень понравились Лазурский и Академия - шрифт
используемый в старых изданиях 50х годов прошлого века). Тем кто хочет
поглубже разобраться в структурах ps, pdf файлов, а также в том, как
использовать фонты в этих файлах могу порекомендовать толстые
английские мануалы с сайта Adobe (
http://partners.adobe.com/asn/tech/ps/technotes.jsp ) - PostScript
Language Reference, 3'd edition; PDF Reference, 3'd edition; Adobe
Type 1 Font Format; Supporting Fonts in the PostScript Language
Environment.
В чем проблема?
"Корявые" фонты - это type3 фонты, т.е. фонты реализованные с помощью
графических команд postscript. С одной стороны это делает фонт более
гибким (можно нарисовать любой символ), но с другой - это все же
графика, и хотя pdf умеет сглаживать графику, но результат оказывается
хуже чем у outlined type1 и truetype шрифтов. Однако просто взять и
вставить outlined шрифт не получится (например отредактировав ps-файл
) - дело в том что эти шрифты должны быть правильно "реализованы" в
postscript файле, иначе ps2pdf конвертор все равно будет растеризовать
их, и в результате для некоторых символов (как правило русских букв)
будет использован type3 шрифт.
Что значит правильно реализовать шрифт? Дело в том, что хотя в самом
файле шрифта может содержаться любое количество глифов, но
одновременно адресовать и отобразить с помощью постскрипт команды show
в постскрипт файле можно только 256 символов. Если вы заглянете внутрь
файла с type1 шрифтом (лучше брать файлы с расширением pfa), то вы
найдете в начале список глифов реализованных по-умолчанию в этом фонте
(строчка Encoding). Список может быть как стандартным, например,
AdobeStandardEncoding, либо явно определяться как encoding-array.
Например, в шрифте Quake он определен так:
/FontName /QuakeСyr def
/Encoding 256 array 0 1 255 {1 index exch /.notdef put } for
dup 32 /space put
dup 33 /exclam put
dup 34 /quotedbl put
и т.д. - ровно 256 символов. Если же просмотреть его с помощью
ghostscript-команд (как это сделать, описано в "Почему Мозилла
печатает пустые квадраты вместо русских букв") можно убедится, что он
дополнительно содержит еще 3 незакодированных символа. В
postscript-language любой символ имеет уникальное имя - /space -
пробел и т.д., в частности для русских букв зарезервированы имена
/afii10017-afii10049; /afii10065-/afii10097 (можно убедится, что в
шрифте Quake они уже закодированы). Вывод текста в постскрипт файле
осуществляется с помощью команды show, которая принимает в качестве
аргумента последовательность байт - индексов букв в текущем фонте
(т.е. в фонте предварительно реализованном в постскрипт-файле с
помощью команды selectfont). Чтобы отобразить символы, которые не
содержатся в предопределенном encoding-array фонта, нужно в постскрипт
файле "динамически" создать фонт (команда definefont), в котором бы
содержались нужные символы. Причем сделать это можно двумя путями:
1. Заменив кодировку type1 фонта. Это я бы назвал "правильно"
реализованным фонтом. Замена кодировки заключается в том, что задается
последовательность имен символов (которые уникальны и стандартны),
которые будут включены в логический динамический фонт.
Последовательность, в которой эти имена указываются, задает
индексирование шрифта. В принципе, из одного физического шрифта внутри
одного постскрипт файл можно создать множество логических шрифтов, но
в каждый момент активным (selected) будет только один. Когда шрифт
подгружается в постскрипт файл, то автоматически создается логический
фонт с кодировкой, указанной в самом фонте.
2. Создать фонт с "нуля". Нужные символы определяются в шрифте либо
как битмапы, полученные растеризацией глифов исходного фонта, либо
символы исходного фонта вставляются с помощью команд showglyph. В
обеих этих случаях вы имеете type3 фонт.
Собственно, чтобы из latex файла получать красивые pdf - нужно научить
dvips обрабатывать "нестандартные" символы согласно варианту 1, а не
2, что он склонен делать, так сказать, по умолчанию.
Фонты в LaTeX
Вообще говоря, LaTeX безразлично какие именно шрифты вы собираетесь
использовать в своем документе (LaTeX не занимается отображением
документа). Единственное, что ему нужно знать о шрифте - это где-какие
символы расположены и их метрику, чтобы правильно распределять текст
на странице. Эту информацию latex извлекает из tfm (tex font metric)
файла и его наличие - непременное условие, чтобы любой фонт можно было
бы использовать в latex документах. Т.е. первый шаг к подключению
какого-либо шрифта к latex - это преобразовании метрики шрифта. У
type1 шрифтов информация о начертании букв и их размерах содержится в
двух различных файлах - afm (может также иметь расширение pfm) и pfa
(или pfb) соответственно, для ttf данные о глифах и метрика содержатся
в одном и том-же файле. Если же вы хотите классифицировать шрифты по
стилям, чтобы LaTeX автоматически подбирал шрифты для bold, italic,
serifed, sans-serifed и т.д. текста, то для этой цели вам понадобится
еще fd-файл (font descriptor). Однако, этот файл не является
обязательным, если вы собираетесь использовать фонта в своем документе
"разово" - например для каких-нибудь декоративных надписей.
Прежде чем вставлять шрифты подготовьте временную директорию
(~/latex-fonts к примеру), где будут собраны шрифты, копируйте в нее
quake.pfa, quake.afm, coptic.ttf, stonhen.ttf и nadeb.ttf
(предварительно скачав их с сайта Vedi), а также t2a.enc из пакета
pscyr. Для генерации pdf файла будет использована команда pdflatex,
напрямую создающая pdf-файл из исходников latex. Поэтому создайте в
этой временной директории еще файл pdftex.cfg, скопировав системный
pdftex.cfg файл (найти его можно командой
cd / ; kpsewhich -progname=pdftex pdftex.cfg
у меня это /usr/share/texmf/pdftex/config/pdftex.cfg). Где-нибудь в
конце этого файла добавьте строчку
map +myfonts.map
и создайте в директории ~/latex-fonts файл myfonts.map (в него будем
записывать описания сгенерированных фонтов). Теперь, сделав cd
~/latex-fonts, убедитесь, что tetex видит локальный конфигурационный
файл
cd ~/latex-fonts; kpsewhich --progname=pdftex pdftex.cfg
(ответ должен быть ./pdftex.cfg). Таким образом вы можете как угодно
экспериментировать со шрифтами, не затрагивая системную конфигурацию
tetex.
Еще раз замечу, что метод, который будет приведен ниже, работает
только в случае использования команды pdflatex, генерирующей pdf файл
непосредственно из latex исходника. Если же вам для каких-то целей
нужно сгенерировать постскрипт-файл (последовательностью команд
latex...; dvips ...), то тут имеются проблемы связанные с тем, что
ghostscript не умеет обрабатывать embedded true-type фонты (в конце я
остановлюсь на этом).
type1 шрифты.
Поскольку технология type1 шрифтов, также как и формат pdf, разработы
Adobe, то с type1 шрифтами проблем не возникает. Вначале изготавливаем
tfm из afm файла (например из шрифта QuakeCyr)
>afm2tfm quake.afm -T t2a.enc
quake QuakeCyr " T2AEncoding ReEncodeFont " < t2a.enc
Команда afm2tfm (входит в состав tetex) конвертирует afm (adobe font
metric) файл в quake.tfm файл, попутно перекодируя его в
T2AAdobeEncoding (-T t2a.enc). Вывод этой команды - это примерно та
строчка, которую теперь нужно добавить в файл myfonts.map. Вам только
нужно еще указать файл, из которого pdflatex будет брать начертание
шрифтов. Так что, в окончательном виде, вам нужно дописать в файл
myfonts.map строку:
quake QuakeCyr " T2AEncoding ReEncodeFont " < quake.pfa < t2a.enc
(означает она следующее - latex имя шрифта, постскрипт имя шрифта,
команда указывающая перекодировку фонта, файл где находятся глифы
шрифта и файл с кодировкой).
ttf шрифты.
С ними ситуация хуже. Поскольку стандарт Adobe на true-type шрифты не
распространяется, то кодировка символов в ttf шрифте может отличаться
от стандартной адобовской, и в основном проблемы возникают именно с
тем, что в шрифте не удается найти глиф с именем (к примеру)
/afii10017, а большая русская буква А именуется как Agrave. Поэтому,
прежде чем начать встраивать ttf шрифт в latex, рекомендуется вначале
просмотреть его с помощью ghostscript, чтобы понять, какой способ
наименования глифов выбрал автор при создании шрифта. Проще всего это
сделать, добавив в ghostscript'овский Fontmap.GS файл строчку вида:
/Test-Font (/path/to/some/font.ttf);
и открыть в gv ps файл:
(prfont.ps) runlibfile
/Test-Font DoFont
В результате в ghostviewer'e вы увидите таблицу со всеми глифами,
содержащимися в шрифте, вместе с их адобовскими названиями.
Способов кодирования символов может быть три (the good, the bad and
the ugly):
1 Автор шрифта следует адобовскому стандарту именования символов.
Самый лучший вариант и (к счастью) самый распространенный - если вы
имеете дело с профессионально сделанным шрифтом (например с
Monotype'овским), то можно быть уверенным, что шрифт закодирован
именно так.
2 В шрифте сбита кодировка (случайно или умышленно). Некоторый глифы
имеют странные названия (если вы смотрите шрифт с помощью DoFоnt
команды) или не отображаются, когда вы пытаетесь использовать шрифт в
latex-документе.
3 Шрифт закодирован с помощью грубого хака - национальные символы
отображаются на верхнюю половину ISOLatin1Charset.
Последние два случая лечению, тем не менее, поддаются.
Начнем с самого простого случая. В первую очередь вам нужно извлечь
метрику шрифта из ttf файла (напомню, что в отличии от type1 шрифтов,
где метрика и глифы хранятся в разных файлах, true-type шрифты cостоят
из одного файла). Для этого воспользуемся командой ttf2afm из пакета
ghostscript:
ttf2afm -e t2a.enc -o dscopt.afm dscoptic.ttf
Единственная неочевидная опция - это -e t2a которая указывает, что в
dscoptic.afm файл будут помещена информация только о символах
содержащихся в файле t2a.enc. Далее следуем уже известным путем:
>afm2tfm dscopt.afm -T t2a.enc
dscopt DSCoptic " T2AEncoding ReEncodeFont " < t2a.enc
и добавляем эту строчку в файл myfonts.map так же как и раньше, опять
же дописывая имя шрифта:
dscopt DSCoptic " T2AEncoding ReEncodeFont " < dscoptic.ttf < t2a.enc
DSCoptic - это вариант 1, шрифт закодированный согласно адобовскому
стандарту. Вариант 2 - шрифт Надежда, в котором латинская буква /H
именуется как /FL0048h. Так что, если вы попытаетесь конвертировать
его аналогично случаю приведеному выше, то большой латинской буквы H в
текстах вы не увидите. Лечится это подкручиванием кодировки. Копируете
файл t2a.enc в файл t2a_nade.enc и в последнем вместо строчки /H
вставляете /FL0048h. После чего конвертируете файл nadeb2.ttf
ttf2afm -e t2a_nade.enc -o nade.afm nadeb2.ttf
afm2tfm nade.afm -T t2a_nade.enc
echo 'nade Nadejda-Bold " T2AAdobeEncoding ReEncodeFont" < nadeb2.ttf \
< t2a_nade.enc ' >> myfonts.map
Шрифт Stonhenge - это третий случай. В принципе, можно исправить
кодировку в нем точно также как и в шрифте Надежда (исправлений вам,
правда, придется вносить гораздо больше), но есть и более простой
вариант. А именно - позиции русских символов в T2A кодировке совпадают
с позициями символов в шрифте Stonehenge. Поэтому можно вытащить
кодировку из этого шрифта и затем с ее помощью создать tfm файл.
ttf2afm -с stone -o stone.afm stone.ttf
ttf2afm -e stone.e00 -o stone.afm stone.ttf
afm2tfm stone.afm -T stone.e00
echo 'stone Stonehenge " Encoding1 ReEncodeFont" < stone.ttf < stone.e00 ' >> myfonts.map
Комментарии: ttf2afm -с stone ... извлекает кодировки из шрифта и
сохраняет их в нескольких файлах с названиями stone.e. Мы используем
кодировку из файла stone.e00 для перекодировки фонта.
Тестируем шрифты.
Простой пример. В данном примере переопределяются стили для roman,
sans-serif и typewriter текста. Четвертый шрифт определяется in-place
и используется разово.
\documentclass[a4]{article}
\usepackage[koi8-r]{inputenc}
\usepackage[russian]{babel}
\renewcommand{\rmdefault}{stone}
\renewcommand{\sfdefault}{nade}
\renewcommand{\ttdefault}{dscoptic}
\title{Использование type1 и tt шрифтов в LaTeX.}
\author{Проект Vedi}
\sloppy
\begin{document}
\maketitle
Дурацкий тест включения true-type и type1 шрифтов в LaTeX.
\sf Внимание! \tt Специалистам в полиграфии и издательском деле просьба этот
текст не компилировать и не смотреть!
Это может повлечь за собой
\font\Scary quake at20pt \Scary обострение профессиональных заболеваний -
аллергию, тошноту и рвоту !
\end{document}
Компилировать его следует в директории latex-fonts командой pdflatex
test.tex. В итоге, в сгенерированном pdf файле все шрифты окажутся или
Type1 или TrueType, Embedded в том и другом случае - в чем можно
убедиться командой:
$pdffonts test.pdf
name type emb sub uni object ID
--------------------------------
Stonehenge TrueType yes no no 6 0
Nadejda-Bold TrueType yes no no 9 0
DSCoptic TrueType yes no no 12 0
OXCCSV+QuakeCyr Type 1 yes yes no 15 0
Наводим порядок.
Если результат тестирования вас удовлетворил, то можно заняться
раскладыванием шрифтов и конфигурационных файлов по их привычным
местам.
cp *.afm /usr/share/texmf/fonts/afm/public/local
cp *.pfa *.pfb *.ttf /usr/share/texmf/fonts/type1/public/local
cat ./myfonts.map >> /usr/share/texmf/dvips/config/pdftex.map
Проверьте также, что файл pdftex.map указан в конфигурационном файле
pdflatex'а /usr/share/texmf/pdftex/config/pdftex.cfg. Если нет
допишите в него строчку map +pdftex.map (или map pdftex.map). Теперь
остается только синхронизировать базу данных tetex (команда mktexlsr)
и шрифты готовы к использованию.
Почему же нельзя использовать ttf шрифты с dvips ?
На самом деле можно, но ;) ...
Для чего вообще может понадобится использование dvips: pdflatex имеет
ограничение - он не умеет обрабатывать встроенную в latex-документ
postscript графику (обойти это ограничение можно, если преобразовать
рисунки в pdf-формат, а в latex вставлять уже сгенерированные pdf
файлы). Но, в то же время, вместо использования pdflatex напрямую
можно пойти длинным путем - конвертировать latex в dvi-файл (latex
test.tex), затем полученный dvi преобразовать в постскрипт (командой
из пакета tetex - dvips test.dvi), и потом уже конвертировать его в
pdf программой из пакета ghostscript ps2pdf test.ps. Программа dvips
конвертирует latex шрифты в постскриптовские по правилам, записанным в
ее конфигурационном файле /usr/share/texmf/dvips/config/psfonts.map.
Его формат такой-же как и pdftex.map, поэтому строки, соответствующие
type1 шрифтам, вы можете не задумываясь переносить в этот файл. С ttf
шрифтами (в отличии от type 1) возникает следующая проблема: если в
строке описания шрифта упоминается файл *.ttf, то dvips встраивает
этот шрифт в постскрипт файл. А ghostscript (по крайней мере вплоть до
версии 7.05) не умеет работать со встроенными в постскрипт файл
true-type шрифтами. Соответственно любые программы, использующие при
работе ghostscript (gv, gs и ps2pdf в том числе), вылетатют с
cообщением об ошибке в постскрипт файле (если у кого имеется
интерпретатор постскрипта, отличный от gs, или постскрипт-принтер, то
можете проверить, как они реагируют на встроенные ttf).
Очевидное решение - не встраивать в постскрипт true-type шрифты - тоже
не проходит (замечу, что постскрипт без встроенных "экзотических"
шрифтов - вещь крайне непортабельная, и отсылать его своим сотрудникам
или знакомым не стоит - все равно они там ничего не увидят). А именно:
предположим вы добавляете в psfonts.map строчку
dscopt DSCoptic " T2AEncoding ReEncodeFont " < t2a.enc
и генерируете постскрипт файл. Чтобы ghostscript смог его отобразить,
нужно указать ghostscript'у, где именно нужно брать глифы для шрифта
DSCoptic, для чего в файл /usr/share/ghostscript//lib/Fontmap.GS
вставляете путь к файлу шрифта
/DSCoptic (/usr/share/texmf/fonts/type1/public/local/dscoptic.ttf);
Ghostviewer после этого должен правильно и без ошибок отобразить
документ. Однако, если вы запустите ps2pdf, то в сгенерированном pdf
файле вы увидите все те же кривые type3 шрифты, отдаленно напоминающие
DSCoptic. Это также ограничение ghostscript'a, о чем его авторы пишут
в документации :
ps2pdf will sometimes convert text to high-resolution bitmapped fonts rather than to
embedded outline fonts. This will occur when the PostScript file uses Type 3, CIDFontType 1, or
CIDFontType 4 fonts, or Type 0 fonts that reference any of these; it may also occur in some
cases if the input file uses fonts with non-standard encodings, or in some other rare cases
Ну, это для них они "rare cases" - а для нас суровые будни. Так что,
если вы хотите использовать графику в latex-докуменетах, то либо
используйте исключительно type1 шрифты, postscript графику и команду
dvips, либо все же предварительно конвертируйте постскрипт рисунки в
pdf и пользуйтесь командой pdflatex (заметьте, что для надписей на
рисунках вам, тем не менее, придется использовать type1 шрифты,
поскольку конвертировать ps->pdf вам придется все той-же командой
ps2pdf).