Как вы можете получить метрику высоты строки в PostScript?

Вы можете получить ширину строки в текущем шрифте с помощью stringwidth, и хотя это фактически толкает смещенные координаты в стеке, значение y всегда кажется бесполезным. Есть ли способ определить точную высоту строки, которая может включать или не включать descenders?

Ответ 1

stringwidth, как он говорит, не возвращает высоту строки. (Во всех случаях, на которые я смотрел, второе целое в стеке после выполнения stringwidth было 0 - для строк, которые выполняются в горизонтальном направлении.) stringwidth дает относительные координаты текущей точки после выполнения (string) show,

PLRM имеет это сказать о stringwidth:

Обратите внимание, что ширина, возвращаемая stringwidth, определяется как перемещение текущего точка. Он не имеет ничего общего с размерами контуров глифов.

Итак, что будет работать, чтобы учесть высоту строки? Волшебные слова для чтения в PRLM: charpath и pathbbox. Попробуйте следующее:

%!
/Helvetica findfont 60 scalefont setfont
200 700 4 0 360 arc fill 
200 700 moveto (test test) dup 
true charpath pathbbox 
3 -1 roll sub 2 div neg 3 1 roll sub 2 div exch 
1 0 0 setrgbcolor
200 700 moveto rmoveto show showpage

Он вычисляет высоту строки (печатается красным цветом) и использует эту информацию, чтобы попытаться центрировать небольшой заполненный круг (напечатанный черным цветом) в центре его ограничивающего прямоугольника:

Пример визуализации PostScript

Ответ 2

Я уже ответил на это в Как определить высоту строки в PostScript?, но это также полезно здесь.

Просто добавив к pipitas ответ:

/textheight { 
    gsave                                  % save graphic context
    {                            
        100 100 moveto                     % move to some point 
        (HÍpg) true charpath pathbbox      % gets text path bounding box (LLx LLy URx URy)
        exch pop 3 -1 roll pop             % keeps LLy and URy
        exch sub                           % URy - LLy
    }
    stopped                                % did the last block fail?
    {
        pop pop                            % get rid of "stopped" junk
        currentfont /FontMatrix get 3 get  % gets alternative text height
    }
    if
    grestore                               % restore graphic context
} bind def

/jumpTextLine { 
    textheight 1.25 mul                    % gets textheight and adds 1/4
    0 exch neg rmoveto                     % move down only in Y axis
} bind def

Метод предполагает, что некоторый шрифт уже установлен. Он работает над выбранным шрифтом (setfont) и его размером (scalefont).

Я использую (HÍpg), чтобы получить самый большой ограничивающий прямоугольник, используя подчеркнутые символы верхнего регистра и символы "ниже строки". Результат достаточно хорош.

Альтернативный подход ворует из ответа dreamlax - некоторые шрифты не поддерживают оператор charpath.

Сохранение и восстановление графического контекста сохраняет текущую точку на месте, поэтому она не влияет на "поток" вашего документа.

Надеюсь, я помог.

Ответ 3

Это, похоже, работает большую часть времени:

/fontheight { currentfont /FontMatrix get 3 get } bind def
/lineheight { fontheight 1.2 mul } bind def

Он не будет работать для всех /FontType s.