Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.postscript > #3250 > unrolled thread
| Started by | luser droog <luser.droog@gmail.com> |
|---|---|
| First post | 2018-03-27 15:57 -0700 |
| Last post | 2018-06-18 23:13 -0700 |
| Articles | 4 — 3 participants |
Back to article view | Back to comp.lang.postscript
Interrogating a font luser droog <luser.droog@gmail.com> - 2018-03-27 15:57 -0700
Re: Interrogating a font Mark Carroll <mtbc@bcs.org> - 2018-03-28 07:32 +0100
Re: Interrogating a font deedubman@gmail.com - 2018-06-18 14:22 -0700
Re: Interrogating a font luser droog <luser.droog@gmail.com> - 2018-06-18 23:13 -0700
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2018-03-27 15:57 -0700 |
| Subject | Interrogating a font |
| Message-ID | <c66ccb1f-ee64-48c2-9d80-0c018c89b137@googlegroups.com> |
Since I cannot predict what pieces may be inaccessible
in any given font dictionary I have tried to achieve
my needs with ... programming. tada! So, the following
incomplete program analyzes the paths produced in
a few key glyphs (CHj) for ascender, descender, cap-height,
italic-angle, and stem-v.
The implementation for stem-v seems to function correctly,
but I have not implemented the distance-between-segments
function, so the result is always 42. I'll fix that later.
I wonder if anyone has any advice on where to find the
information I need for the PDF font descriptor's /Flags
member? How do I determine if a font "is italic", reliably?
Scan the characters of 'FontName tempstring cvs'?
Anyway, here's my workaround for access restrictions
in the font dictionaries preventing a more direct approach.
$ cat fontdata.ps
% main is called at eof
/main {
test-palatino
} def
/test-palatino {
/Palatino-Roman findfont
%dup length dict copy dup /FontMatrix matrix put readonly
1000 scalefont
setfont
% generate-font-extras pstack()=
generate-font-descriptor ===
} def
/generate-font-extras {
/FirstChar 32
/LastChar 127
/Widths [
32 1 127 {
1 string dup 0 4 -1 roll put stringwidth pop
} for
]
} def
/generate-font-descriptor {
<<
/Type /FontDescriptor
/FontName currentfont /FontName get
/FontBBox currentfont /FontBBox get dup length array copy
predicates begin
/Flags is-fixed-pitch 0 bitshift
is-serif 1 bitshift and
is-symbolic 2 bitshift and
is-script 3 bitshift and
is-nonsymbolic 5 bitshift and
is-italic 6 bitshift and
is-allcap 16 bitshift and
is-smallcap 17 bitshift and
is-forcebold 18 bitshift and
end
font-analysis begin
% Private:BlueValues?
/Ascent ascender
/CapHeight cap-height
/Descent descender
%/XHeight (optional)
% /StemV currentfont /Private get /StdVW get dup type == cvx exec
/StemV stem-v
/ItalicAngle italic-angle
%/MissingWidth (optional)
%/CharSet (/string/of/glyph/names) (optional)
end
>>
} def
/font-analysis <<
/ascender {
gsave
0 0 moveto
(C) false charpath flattenpath pathbbox 4 array astore
3 get
grestore
}
/cap-height {
gsave
0 0 moveto
(H) false charpath flattenpath pathbbox 4 array astore
3 get
grestore
}
/descender {
gsave
0 0 moveto
(j) false charpath flattenpath pathbbox 4 array astore
1 get
grestore
}
/italic-angle {
gsave
0 0 moveto
(H) false charpath flattenpath
get-line-segments
discard-horizontal-segments
longest-segment
angle-of-segment
grestore
}
/stem-v {
gsave
0 0 moveto
(H) false charpath flattenpath
get-line-segments
discard-horizontal-segments
dup longest-segment dup 3 1 roll
closest-parallel-segment
distance-between-segments
grestore
}
/get-line-segments{
/ca 2 array def
/cp ca cvx def
/sa 2 array def
/sp sa cvx def
[
{2 copy sa astore pop ca astore pop
[ cp}
{2 copy ca astore pop
] [ cp}
{}
{sp ]}
pathforall
] pop
] % yield array of [x0 y0 x1 y1] arrays
}
/discard-horizontal-segments {
{
dup angle-of-segment dup 45 gt exch 135 lt and not {
pop
} if
} map
}
/longest-segment {
dup { length-of-segment } map
dup { max } reduce
find-index pop get
}
/closest-parallel-segment {
exch discard-single-from-list
discard-non-parallel-segments
dup { counttomark 2 add index distance-between-segments } map
dup { min } reduce
find-index pop get exch pop
}
/discard-single-from-list {
{ dup counttomark 1 add index eq { pop } if } map
}
/distance-between-segments {
pop pop 42
}
/discard-non-parallel-segments {
1 index angle-of-segment exch
{ dup angle-of-segment counttomark 1 add index angles-are-close not {
pop
} if } map
exch pop
}
/angles-are-close {
sq exch sq sub 5 lt
}
/angle-of-segment {
dup dy exch dx
atan
}
/length-of-segment {
dup dx sq exch dy sq add sqrt
}
/dx {
dup 2 get exch 0 get sub
}
/dy {
dup 3 get exch 1 get sub
}
/sq {
dup mul
}
>> def
/find-index {
exch
{
0 1 2 index length 1 sub {
2 copy get
3 index eq {
stop
}{
pop
} ifelse
} for
} stopped {
exch pop exch pop true
}{
pop pop false
} ifelse
} def
/map {
[ 3 1 roll forall ]
} def
/reduce {
1 index 0 get 3 1 roll
exch 1 1 index length 1 sub getinterval exch
forall
} def
/max {
2 copy lt { exch } if pop
} def
/min {
2 copy gt { exch } if pop
} def
/predicates <<
/is-fixed-pitch { 0
}
/is-serif { 0
}
/is-symbolic { 0
}
/is-script { 0
}
/is-nonsymbolic { 0
}
/is-italic { 0
}
/is-allcap { 0
}
/is-smallcap { 0
}
/is-forcebold { 0
}
>> def
main
[toc] | [next] | [standalone]
| From | Mark Carroll <mtbc@bcs.org> |
|---|---|
| Date | 2018-03-28 07:32 +0100 |
| Message-ID | <87a7us6783.fsf@ixod.org> |
| In reply to | #3250 |
On 27 Mar 2018, luser droog wrote: > Since I cannot predict what pieces may be inaccessible > in any given font dictionary I have tried to achieve > my needs with ... programming. tada! So, the following > incomplete program analyzes the paths produced in > a few key glyphs (CHj) for ascender, descender, cap-height, > italic-angle, and stem-v. I had to do a similar kind of thing when I wanted to nestle letters right up against each other. Glad to see it's working for you too. -- Mark
[toc] | [prev] | [next] | [standalone]
| From | deedubman@gmail.com |
|---|---|
| Date | 2018-06-18 14:22 -0700 |
| Message-ID | <80d271e1-9d5c-489d-853b-11225edbbf74@googlegroups.com> |
| In reply to | #3250 |
Doesn't ascender refer to lower-case letters that project above the x-height like b, d, f, h, k, l, and t? I would take the max of this set. Also take the min of g, j, p, q, and y for descender. For stem-v I remember doing a small survey of fonts for which I had AFM files (which have stem-v) and then trying to tune an algorithm such as you described to match the known data, maybe make a wide but thin clip rectangle that crosses the stem of "I" in the middle, which is also 'true charpath clip', then 'clippath pathbbox' that result, get the width. If it could reasonably guess at known stem-v values then I could trust it in the unknown case. But then I noticed (if we are talking about PDF) that a lot of PDF software seems to not care about the stem-v value in font desccriptors, it was often zero. David
[toc] | [prev] | [next] | [standalone]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2018-06-18 23:13 -0700 |
| Message-ID | <68dd4c54-1ae2-4b76-8568-1ceebe713126@googlegroups.com> |
| In reply to | #3271 |
On Monday, June 18, 2018 at 4:22:14 PM UTC-5, deed...@gmail.com wrote: > Doesn't ascender refer to lower-case letters that project above the x-height like b, d, f, h, k, l, and t? I would take the max of this set. Also take the min of g, j, p, q, and y for descender. > That's a good thought. It wouldn't be a lot of work to make that change, too. Just adding those other characters to the string. It already takes the bounding box to get lowest of (currently) one glyph. > For stem-v I remember doing a small survey of fonts for which I had AFM files (which have stem-v) and then trying to tune an algorithm such as you described to match the known data, maybe make a wide but thin clip rectangle that crosses the stem of "I" in the middle, which is also 'true charpath clip', then 'clippath pathbbox' that result, get the width. If it could reasonably guess at known stem-v values then I could trust it in the unknown case. But then I noticed (if we are talking about PDF) that a lot of PDF software seems to not care about the stem-v value in font desccriptors, it was often zero. > > David That does seem like a good strategy. A further complication has arisen in the actual project which changes things somewhat. The fonts I need to deal with are not in the Standard set of 14 fonts. So I need to embed the fonts so Acrobat Reader won't cough at my PDFs. So, I think the simplest thing to do is to write a font sampler program in ps, hoof it over to Kinko's and do the conversion with Acrobat Distiller on a machine that has the required fonts. Then I can reverse engineer what I need from the resulting PDF. Come to think of it, my mom probably has the fonts and distiller, too. And better rates than Kinko's. :)
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.postscript
csiph-web