summaryrefslogtreecommitdiff
path: root/fonts/utilities/t1infos
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /fonts/utilities/t1infos
Initial commit
Diffstat (limited to 'fonts/utilities/t1infos')
-rw-r--r--fonts/utilities/t1infos/README9
-rw-r--r--fonts/utilities/t1infos/kerndict.ps618
-rw-r--r--fonts/utilities/t1infos/t1area.c167
-rw-r--r--fonts/utilities/t1infos/t1extremes.c159
4 files changed, 953 insertions, 0 deletions
diff --git a/fonts/utilities/t1infos/README b/fonts/utilities/t1infos/README
new file mode 100644
index 0000000000..873fc565e1
--- /dev/null
+++ b/fonts/utilities/t1infos/README
@@ -0,0 +1,9 @@
+Two tiny tools for studying Type 1 fonts.
+ - t1area: give informations about the black area of a glyph;
+ - t1extremes: tell if "extremes" of Bzeier curves are at the right place.
+Compile the tools with:
+
+gcc -lm -lt1 -I /usr/local/include -L /usr/local/lib -o t1area t1area.c
+gcc -lm -lt1 -I /usr/local/include -L /usr/local/lib -o t1extremes t1aextremes.c
+
+Thomas Baruchel (baruchel@users.sourceforge.net)
diff --git a/fonts/utilities/t1infos/kerndict.ps b/fonts/utilities/t1infos/kerndict.ps
new file mode 100644
index 0000000000..d5c895d25f
--- /dev/null
+++ b/fonts/utilities/t1infos/kerndict.ps
@@ -0,0 +1,618 @@
+%!
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% KERNDICT a PostScript dictionary for automatical kerning %
+% written by Thomas Baruchel (may 2003) %
+% %
+% Several methods are provided %
+% * Tangent-based kerning (an idea of the author) %
+% 45° tangents encapsulate the letter at the right or at the left. %
+% How far they are from the left or right side of the BoundingBox %
+% tells what can be done. The method is intended to be very quick. %
+% Usage : { kernproc } (Hello) kshow %
+% %
+% * Sector-based kerning (a classical method) %
+% The user chooses the length of the smallest horizontal gap %
+% between the two letters. The number of sectors gives the %
+% precision of the computation. %
+% Usage : { 175 12 kernsector } (Hello) kshow %
+% Warning : not intended to take account of spaces %
+% %
+% * Outline-based kerning %
+% The user chooses the real distance between the characters even %
+% if the two closest points of the outline are not at the same %
+% height. The user must build an outline version of the font he %
+% uses before calling the procedure. The /StrokeWidth key of this %
+% outline font must be set to the expected distance. A number of %
+% sectors give the precision of the computation. %
+% Usage : { /Outline-Font findfont 12 kernoutline } (Hello) kshow %
+% Warning : not intended to take account of spaces %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+/kerndict 5 dict dup begin
+
+/min { dup 2 index ge { pop } { exch pop } ifelse } bind def
+/kerncompute { 1 index 1 index mul 0 ge { abs exch abs min
+neg 3 div } { pop pop 0 } ifelse } bind def
+/kernproc { gsave (..) dup 0 4 -1 roll put dup 1 4 -1 roll put
+currentfont dup /FontMatrix get matrix invertmatrix makefont setfont
+newpath 0 0 moveto dup true charpath flattenpath pathbbox pop exch pop
+add exch [1 -1 -1 -1 0 0] setmatrix newpath 0 0 moveto true charpath
+[1 0 0 1 0 0] setmatrix pathbbox sub 3 index sub 4 1 roll sub sub
+grestore kerncompute currentfont /FontMatrix get matrix currentmatrix
+exch concat exch 0 rmoveto setmatrix } bind def
+/kernsector { matrix currentmatrix currentfont dup dup /FontMatrix get
+dup concat gsave newpath matrix invertmatrix makefont setfont /FontBBox
+get aload pop 2 {3 index neg} repeat moveto exch 3 index sub 2 mul (.)
+dup 0 11 -1 roll put true charpath currentpoint pop (.) dup 0 12 -1 roll
+put true charpath currentpoint pop exch flattenpath 0 moveto 3 -1 roll 4
+-1 roll sub dup 0 exch rlineto clip dup 7 -1 roll div 0 0 2 index 5 -1
+roll { gsave 0 exch 5 index 4 index rectclip clippath pathbbox pop exch
+pop sub min grestore } for exch pop add exch pop add 3 -1 roll sub neg
+grestore 0 rmoveto setmatrix } bind def
+/kernoutline { matrix currentmatrix currentfont /FontMatrix get concat
+gsave 3 -1 roll dup /FontMatrix get matrix invertmatrix makefont dup
+setfont /FontBBox get aload pop 2 {3 index neg} repeat moveto exch 3
+index sub 2 mul (.) dup 0 10 -1 roll put true charpath currentpoint pop
+(.) dup 0 11 -1 roll put true charpath currentpoint pop exch flattenpath
+0 moveto 3 -1 roll 4 -1 roll sub dup 0 exch rlineto clip dup 7 -1 roll
+div 0 0 2 index 5 -1 roll { gsave 0 exch 5 index 4 index rectclip
+clippath pathbbox pop exch pop sub min grestore } for exch pop add exch
+pop add neg grestore 0 rmoveto setmatrix } bind def
+
+
+end def
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% Test %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+gsave 0 -36 translate
+/Courier-Bold findfont 48 scalefont setfont
+%595 (kerndict.ps) stringwidth pop sub 2 div
+72 772 moveto (kerndict.ps) show
+/myfont /Helvetica def
+myfont findfont dup length 1 add dict begin
+currentdict copy /PaintType 2 def /StrokeWidth 128 def
+/myfont-Outline exch definefont pop end
+
+gsave 84 -10 translate
+kerndict begin
+myfont findfont 64 scalefont setfont
+72 700 moveto (AVATeV/4) show
+72 600 moveto {175 16 kernsector} (AVATeV/4) kshow
+72 500 moveto {kernproc} (AVATeV/4) kshow
+72 400 moveto {/myfont-Outline findfont 12 kernoutline} (AVATeV/4) kshow
+/Helvetica findfont 10 scalefont setfont
+84 688 moveto (No correction) show
+84 588 moveto (Sector-based kerning) show
+84 488 moveto (Tangent-based kerning) show
+84 388 moveto (Outline-based kerning) show
+end grestore
+
+newpath 140 750 moveto 330 0 rlineto 0 -385 rlineto
+-330 0 rlineto closepath stroke
+
+gsave 0 -6 translate
+/Courier findfont 10 scalefont setfont
+84 344 moveto (Copyright \(c\) 2003 Thomas Baruchel) show
+84 332 moveto () show
+84 320 moveto (Permission is hereby granted, free of charge, to any person obtaining) show
+84 308 moveto (a copy of this software and associated documentation files \(the) show
+84 296 moveto ("Software"\), to deal in the Software without restriction, including) show
+84 284 moveto (without limitation the rights to use, copy, modify, merge, publish,) show
+84 272 moveto (distribute, sublicense, and/or sell copies of the Software, and to) show
+84 260 moveto (permit persons to whom the Software is furnished to do so, subject to) show
+84 248 moveto (the following conditions:) show
+84 236 moveto () show
+84 224 moveto (The above copyright notice and this permission notice shall be) show
+84 212 moveto (included in all copies or substantial portions of the Software.) show
+84 200 moveto () show
+84 188 moveto (THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,) show
+84 176 moveto (EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF) show
+84 164 moveto (MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.) show
+84 152 moveto (IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY) show
+84 140 moveto (CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,) show
+84 128 moveto (TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE) show
+84 116 moveto ( SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.) show
+grestore grestore showpage
+
+
+/_S { % save current state
+ /_s save def
+} def
+/_R { % restore from saved state
+ _s restore
+} def
+
+/S { % showpage protecting gstate
+ gsave
+ showpage
+ grestore
+} bind def
+
+/MF { % fontname newfontname -> - make a new encoded font
+ /newfontname exch def
+ /fontname exch def
+
+ /fontdict fontname findfont def
+ /newfont fontdict maxlength dict def
+
+ fontdict {
+ exch
+ dup /FID eq {
+ % skip FID pair
+ pop pop
+ } {
+ % copy to the new font dictionary
+ exch newfont 3 1 roll put
+ } ifelse
+ } forall
+
+ newfont /FontName newfontname put
+
+ % insert only valid encoding vectors
+ encoding_vector length 256 eq {
+ newfont /Encoding encoding_vector put
+ } if
+
+ newfontname newfont definefont pop
+} def
+
+/SF { % fontname width height -> - set a new font
+ /height exch def
+ /width exch def
+
+ findfont
+ [width 0 0 height 0 0] makefont setfont
+} def
+
+/SUF { % fontname width height -> - set a new user font
+ /height exch def
+ /width exch def
+
+ /F-gs-user-font MF
+ /F-gs-user-font width height SF
+} def
+
+/M {moveto} bind def
+/s {show} bind def
+
+/Box { % x y w h -> - define box path
+ /d_h exch def /d_w exch def /d_y exch def /d_x exch def
+ d_x d_y moveto
+ d_w 0 rlineto
+ 0 d_h rlineto
+ d_w neg 0 rlineto
+ closepath
+} def
+
+/bgs { % x y height blskip gray str -> - show string with bg color
+ /str exch def
+ /gray exch def
+ /blskip exch def
+ /height exch def
+ /y exch def
+ /x exch def
+
+ gsave
+ x y blskip sub str stringwidth pop height Box
+ gray setgray
+ fill
+ grestore
+ x y M str s
+} def
+
+% Highlight bars.
+/highlight_bars { % nlines lineheight output_y_margin gray -> -
+ gsave
+ setgray
+ /ymarg exch def
+ /lineheight exch def
+ /nlines exch def
+
+ % This 2 is just a magic number to sync highlight lines to text.
+ 0 d_header_y ymarg sub 2 sub translate
+
+ /cw d_output_w cols div def
+ /nrows d_output_h ymarg 2 mul sub lineheight div cvi def
+
+ % for each column
+ 0 1 cols 1 sub {
+ cw mul /xp exch def
+
+ % for each rows
+ 0 1 nrows 1 sub {
+ /rn exch def
+ rn lineheight mul neg /yp exch def
+ rn nlines idiv 2 mod 0 eq {
+ % Draw highlight bar. 4 is just a magic indentation.
+ xp 4 add yp cw 8 sub lineheight neg Box fill
+ } if
+ } for
+ } for
+
+ grestore
+} def
+
+% Line highlight bar.
+/line_highlight { % x y width height gray -> -
+ gsave
+ /gray exch def
+ Box gray setgray fill
+ grestore
+} def
+
+% Column separator lines.
+/column_lines {
+ gsave
+ .1 setlinewidth
+ 0 d_footer_h translate
+ /cw d_output_w cols div def
+ 1 1 cols 1 sub {
+ cw mul 0 moveto
+ 0 d_output_h rlineto stroke
+ } for
+ grestore
+} def
+
+% Column borders.
+/column_borders {
+ gsave
+ .1 setlinewidth
+ 0 d_footer_h moveto
+ 0 d_output_h rlineto
+ d_output_w 0 rlineto
+ 0 d_output_h neg rlineto
+ closepath stroke
+ grestore
+} def
+
+% Do the actual underlay drawing
+/draw_underlay {
+ ul_style 0 eq {
+ ul_str true charpath stroke
+ } {
+ ul_str show
+ } ifelse
+} def
+
+% Underlay
+/underlay { % - -> -
+ gsave
+ 0 d_page_h translate
+ d_page_h neg d_page_w atan rotate
+
+ ul_gray setgray
+ ul_font setfont
+ /dw d_page_h dup mul d_page_w dup mul add sqrt def
+ ul_str stringwidth pop dw exch sub 2 div ul_h_ptsize -2 div moveto
+ draw_underlay
+ grestore
+} def
+
+/user_underlay { % - -> -
+ gsave
+ ul_x ul_y translate
+ ul_angle rotate
+ ul_gray setgray
+ ul_font setfont
+ 0 0 ul_h_ptsize 2 div sub moveto
+ draw_underlay
+ grestore
+} def
+
+% Page prefeed
+/page_prefeed { % bool -> -
+ statusdict /prefeed known {
+ statusdict exch /prefeed exch put
+ } {
+ pop
+ } ifelse
+} def
+
+% Wrapped line markers
+/wrapped_line_mark { % x y charwith charheight type -> -
+ /type exch def
+ /h exch def
+ /w exch def
+ /y exch def
+ /x exch def
+
+ type 2 eq {
+ % Black boxes (like TeX does)
+ gsave
+ 0 setlinewidth
+ x w 4 div add y M
+ 0 h rlineto w 2 div 0 rlineto 0 h neg rlineto
+ closepath fill
+ grestore
+ } {
+ type 3 eq {
+ % Small arrows
+ gsave
+ .2 setlinewidth
+ x w 2 div add y h 2 div add M
+ w 4 div 0 rlineto
+ x w 4 div add y lineto stroke
+
+ x w 4 div add w 8 div add y h 4 div add M
+ x w 4 div add y lineto
+ w 4 div h 8 div rlineto stroke
+ grestore
+ } {
+ % do nothing
+ } ifelse
+ } ifelse
+} def
+
+% EPSF import.
+
+/BeginEPSF {
+ /b4_Inc_state save def % Save state for cleanup
+ /dict_count countdictstack def % Count objects on dict stack
+ /op_count count 1 sub def % Count objects on operand stack
+ userdict begin
+ /showpage { } def
+ 0 setgray 0 setlinecap
+ 1 setlinewidth 0 setlinejoin
+ 10 setmiterlimit [ ] 0 setdash newpath
+ /languagelevel where {
+ pop languagelevel
+ 1 ne {
+ false setstrokeadjust false setoverprint
+ } if
+ } if
+} bind def
+
+/EndEPSF {
+ count op_count sub { pos } repeat % Clean up stacks
+ countdictstack dict_count sub { end } repeat
+ b4_Inc_state restore
+} bind def
+
+% Check PostScript language level.
+/languagelevel where {
+ pop /gs_languagelevel languagelevel def
+} {
+ /gs_languagelevel 1 def
+} ifelse
+%%EndResource
+%%BeginResource: procset Enscript-Encoding-88591 1.6 1
+/encoding_vector [
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign
+/dollar /percent /ampersand /quoteright
+/parenleft /parenright /asterisk /plus
+/comma /hyphen /period /slash
+/zero /one /two /three
+/four /five /six /seven
+/eight /nine /colon /semicolon
+/less /equal /greater /question
+/at /A /B /C
+/D /E /F /G
+/H /I /J /K
+/L /M /N /O
+/P /Q /R /S
+/T /U /V /W
+/X /Y /Z /bracketleft
+/backslash /bracketright /asciicircum /underscore
+/quoteleft /a /b /c
+/d /e /f /g
+/h /i /j /k
+/l /m /n /o
+/p /q /r /s
+/t /u /v /w
+/x /y /z /braceleft
+/bar /braceright /tilde /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef
+/space /exclamdown /cent /sterling
+/currency /yen /brokenbar /section
+/dieresis /copyright /ordfeminine /guillemotleft
+/logicalnot /hyphen /registered /macron
+/degree /plusminus /twosuperior /threesuperior
+/acute /mu /paragraph /bullet
+/cedilla /onesuperior /ordmasculine /guillemotright
+/onequarter /onehalf /threequarters /questiondown
+/Agrave /Aacute /Acircumflex /Atilde
+/Adieresis /Aring /AE /Ccedilla
+/Egrave /Eacute /Ecircumflex /Edieresis
+/Igrave /Iacute /Icircumflex /Idieresis
+/Eth /Ntilde /Ograve /Oacute
+/Ocircumflex /Otilde /Odieresis /multiply
+/Oslash /Ugrave /Uacute /Ucircumflex
+/Udieresis /Yacute /Thorn /germandbls
+/agrave /aacute /acircumflex /atilde
+/adieresis /aring /ae /ccedilla
+/egrave /eacute /ecircumflex /edieresis
+/igrave /iacute /icircumflex /idieresis
+/eth /ntilde /ograve /oacute
+/ocircumflex /otilde /odieresis /divide
+/oslash /ugrave /uacute /ucircumflex
+/udieresis /yacute /thorn /ydieresis
+] def
+%%EndResource
+%%EndProlog
+%%BeginSetup
+%%IncludeResource: font Courier
+/HFpt_w 10 def
+/HFpt_h 10 def
+/Courier-Bold /HF-gs-font MF
+/HF /HF-gs-font findfont [HFpt_w 0 0 HFpt_h 0 0] makefont def
+/Courier-Bold /F-gs-font MF
+/F-gs-font 10 10 SF
+/#copies 1 def
+% Pagedevice definitions:
+gs_languagelevel 1 gt {
+ <<
+ /PageSize [595 842]
+ >> setpagedevice
+} if
+/d_page_w 451 def
+/d_page_h 698 def
+/d_header_x 0 def
+/d_header_y 698 def
+/d_header_w 451 def
+/d_header_h 0 def
+/d_footer_x 0 def
+/d_footer_y 0 def
+/d_footer_w 451 def
+/d_footer_h 0 def
+/d_output_w 451 def
+/d_output_h 698 def
+/cols 1 def
+%%EndSetup
+%%Page: (1) 1
+%%BeginPageSetup
+_S
+72 72 translate
+/pagenum 1 def
+/fname (code) def
+/fdir () def
+/ftail (code) def
+/user_header_p false def
+%%EndPageSetup
+5 685 M
+(%!) s
+5 674 M
+(%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%) s
+5 663 M
+(% %) s
+5 652 M
+(% KERNDICT a PostScript dictionary for automatical kerning %) s
+5 641 M
+(% written by Thomas Baruchel \(may 2003\) %) s
+5 630 M
+(% %) s
+5 619 M
+(% Several methods are provided %) s
+5 608 M
+(% * Tangent-based kerning \(an idea of the author\) %) s
+5 597 M
+(% 45\260 tangents encapsulate the letter at the right or at the left. %) s
+5 586 M
+(% How far they are from the left or right side of the BoundingBox %) s
+5 575 M
+(% tells what can be done. The method is intended to be very quick. %) s
+5 564 M
+(% Usage : { kernproc } \(Hello\) kshow %) s
+5 553 M
+(% %) s
+5 542 M
+(% * Sector-based kerning \(a classical method\) %) s
+5 531 M
+(% The user chooses the length of the smallest horizontal gap %) s
+5 520 M
+(% between the two letters. The number of sectors gives the %) s
+5 509 M
+(% precision of the computation. %) s
+5 498 M
+(% Usage : { 175 12 kernsector } \(Hello\) kshow %) s
+5 487 M
+(% Warning : not intended to take account of spaces %) s
+5 476 M
+(% %) s
+5 465 M
+(% * Outline-based kerning %) s
+5 454 M
+(% The user chooses the real distance between the characters even %) s
+5 443 M
+(% if the two closest points of the outline are not at the same %) s
+5 432 M
+(% height. The user must build an outline version of the font he %) s
+5 421 M
+(% uses before calling the procedure. The /StrokeWidth key of this %) s
+5 410 M
+(% outline font must be set to the expected distance. A number of %) s
+5 399 M
+(% sectors give the precision of the computation. %) s
+5 388 M
+(% Usage : { /Outline-Font findfont 12 kernoutline } \(Hello\) kshow %) s
+5 377 M
+(% Warning : not intended to take account of spaces %) s
+5 366 M
+(% %) s
+5 355 M
+(%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%) s
+5 333 M
+(/kerndict 5 dict dup begin) s
+5 322 M
+(/min { dup 2 index ge { pop } { exch pop } ifelse } bind def) s
+5 311 M
+(/kerncompute { 1 index 1 index mul 0 ge { abs exch abs min) s
+5 300 M
+(neg 3 div } { pop pop 0 } ifelse } bind def) s
+5 289 M
+(/kernproc { gsave \(..\) dup 0 4 -1 roll put dup 1 4 -1 roll put) s
+5 278 M
+(currentfont dup /FontMatrix get matrix invertmatrix makefont setfont) s
+5 267 M
+(newpath 0 0 moveto dup true charpath flattenpath pathbbox pop exch pop) s
+5 256 M
+(add exch [1 -1 -1 -1 0 0] setmatrix newpath 0 0 moveto true charpath) s
+5 245 M
+([1 0 0 1 0 0] setmatrix pathbbox sub 3 index sub 4 1 roll sub sub) s
+5 234 M
+(grestore kerncompute currentfont /FontMatrix get matrix currentmatrix) s
+5 223 M
+(exch concat exch 0 rmoveto setmatrix } bind def) s
+5 212 M
+(/kernsector { matrix currentmatrix currentfont dup dup /FontMatrix get) s
+5 201 M
+(dup concat gsave newpath matrix invertmatrix makefont setfont /FontBBox) s
+5 190 M
+(get aload pop 2 {3 index neg} repeat moveto exch 3 index sub 2 mul \(.\)) s
+5 179 M
+(dup 0 11 -1 roll put true charpath currentpoint pop \(.\) dup 0 12 -1 roll) s
+5 168 M
+(put true charpath currentpoint pop exch flattenpath 0 moveto 3 -1 roll 4) s
+5 157 M
+(-1 roll sub dup 0 exch rlineto clip dup 7 -1 roll div 0 0 2 index 5 -1) s
+5 146 M
+(roll { gsave 0 exch 5 index 4 index rectclip clippath pathbbox pop exch) s
+5 135 M
+(pop sub min grestore } for exch pop add exch pop add 3 -1 roll sub neg) s
+5 124 M
+(grestore 0 rmoveto setmatrix } bind def) s
+5 113 M
+(/kernoutline { matrix currentmatrix currentfont /FontMatrix get concat) s
+5 102 M
+(gsave 3 -1 roll dup /FontMatrix get matrix invertmatrix makefont dup) s
+5 91 M
+(setfont /FontBBox get aload pop 2 {3 index neg} repeat moveto exch 3) s
+5 80 M
+(index sub 2 mul \(.\) dup 0 10 -1 roll put true charpath currentpoint pop) s
+5 69 M
+(\(.\) dup 0 11 -1 roll put true charpath currentpoint pop exch flattenpath) s
+5 58 M
+(0 moveto 3 -1 roll 4 -1 roll sub dup 0 exch rlineto clip dup 7 -1 roll) s
+5 47 M
+(div 0 0 2 index 5 -1 roll { gsave 0 exch 5 index 4 index rectclip) s
+5 36 M
+(clippath pathbbox pop exch pop sub min grestore } for exch pop add exch) s
+5 25 M
+(pop add neg grestore 0 rmoveto setmatrix } bind def) s
+5 14 M
+(end def) s
+_R
+S
+%%Trailer
+%%Pages: 1
+%%DocumentNeededResources: font Courier-Bold Courier
+%%EOF
diff --git a/fonts/utilities/t1infos/t1area.c b/fonts/utilities/t1infos/t1area.c
new file mode 100644
index 0000000000..6630c390e9
--- /dev/null
+++ b/fonts/utilities/t1infos/t1area.c
@@ -0,0 +1,167 @@
+/*
+
+ t1area
+ ======
+
+ Scan a Type 1 font and tell the area of each character.
+ Also tell how much percent of the bounding box of the character
+ is filled by this area.
+
+ Copyright (c) 2003 Thomas Baruchel
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <t1lib.h>
+#include <math.h>
+
+int usage(void) {
+ fprintf(stderr,"Usage: t1area [-v] file\n -v verbose output\n");
+ return(EXIT_FAILURE);
+}
+
+double integrale(double t1, double t2, int ay, int by, int cy, int dy,
+ int a, int b, int c) {
+ return(
+ ( ay*a*t2*t2*t2*t2*t2*t2/6
+ + (ay*b+by*a)*t2*t2*t2*t2*t2/5
+ + (ay*c+by*b+cy*a)*t2*t2*t2*t2/4
+ + (by*c+cy*b+dy*a)*t2*t2*t2/3
+ + (cy*c+dy*b)*t2*t2/2
+ + dy*c*t2 )
+-
+ ( ay*a*t1*t1*t1*t1*t1*t1/6
+ + (ay*b+by*a)*t1*t1*t1*t1*t1/5
+ + (ay*c+by*b+cy*a)*t1*t1*t1*t1/4
+ + (by*c+cy*b+dy*a)*t1*t1*t1/3
+ + (cy*c+dy*b)*t1*t1/2
+ + dy*c*t1 )
+ );
+}
+
+void area(T1_OUTLINE *outline, BBox bb, char *name, unsigned char v) {
+ auto int xpos = 0;
+ auto int ypos = -bb.lly;
+ auto double area = 0;
+ do {
+ switch(((T1_PATHSEGMENT *) outline)->type) {
+ case T1_PATHTYPE_MOVE: {
+ xpos += (int) T1_NEARESTPOINT(((T1_PATHSEGMENT *) outline)->dest.x);
+ ypos -= (int) T1_NEARESTPOINT(((T1_PATHSEGMENT *) outline)->dest.y);
+ break;
+ }
+ case T1_PATHTYPE_LINE: {
+ auto int dx =
+ (int) T1_NEARESTPOINT(((T1_PATHSEGMENT *) outline)->dest.x);
+ auto int dy =
+ - (int) T1_NEARESTPOINT(((T1_PATHSEGMENT *) outline)->dest.y);
+ auto double surface = (double) (abs(dx)*((dy<0) ? (ypos+dy) : ypos))
+ + ((double) (abs(dy*dx)))/((double) 2);
+ area += (dx<0) ? surface : -surface;
+ xpos += dx;
+ ypos += dy;
+ break;
+ }
+ case T1_PATHTYPE_BEZIER: {
+ auto int x0 = xpos;
+ auto int y0 = ypos;
+ auto int x1 =
+ xpos+T1_NEARESTPOINT(((T1_BEZIERSEGMENT *) outline)->B.x);
+ auto int y1 =
+ ypos-T1_NEARESTPOINT(((T1_BEZIERSEGMENT *) outline)->B.y);
+ auto int x2 =
+ xpos+T1_NEARESTPOINT(((T1_BEZIERSEGMENT *) outline)->C.x);
+ auto int y2 =
+ ypos-T1_NEARESTPOINT(((T1_BEZIERSEGMENT *) outline)->C.y);
+ /* x'(t) = a.t^2 + b.t + c */
+ auto int a,b,c;
+ /* y(t) = ay.t^3 + by.t^2 + cy.t + dy */
+ auto int ay,by,cy;
+ /* auto int dy; useless */
+ xpos += (int) T1_NEARESTPOINT(outline->dest.x);
+ ypos -= (int) T1_NEARESTPOINT(outline->dest.y);
+ ay = -y0 + 3*y1 -3*y2 + ypos;
+ by = 3*y0-6*y1+3*y2;
+ cy = -3*y0+3*y1;
+ /* dy = y0; useless */
+ a = 3*(-x0+3*x1-3*x2+xpos);
+ b = 6*(x0-2*x1+x2);
+ c = 3*(-x0+x1);
+ area -= integrale(0,1,ay,by,cy,y0,a,b,c);
+ break;
+ }
+ }
+ } while ((outline = outline->link) != NULL);
+ if(area != (double) 0) {
+ fprintf(stdout,"/%s area = %.2f",name,area);
+ if(v!=0) {
+ fprintf(stdout," (%.2f %% of BBox)",
+ area/((bb.urx-bb.llx)*(bb.ury-bb.lly))*100);
+ }
+ fprintf(stdout,"\n");
+ }
+}
+
+int main(int argc, char **argv)
+{
+ static signed int i;
+ static unsigned char j=0;
+ static char *fontname = NULL;
+ static unsigned char v = 0;
+
+ for(i=1;i<argc;i++) {
+ if((argv[i][0]=='-')
+ && (argv[i][1]=='v')
+ && (argv[i][2]=='\0')) v = 1;
+ else if(fontname==NULL) fontname = argv[i];
+ else exit(usage());
+ }
+ if(fontname==NULL) exit(usage());
+ if (T1_InitLib(NO_LOGFILE)==NULL) {
+ fprintf(stderr, "Initialization of t1lib failed\n");
+ exit(EXIT_FAILURE);
+ }
+ i = T1_AddFont(fontname);
+ if(i<0) {
+ T1_CloseLib();
+ if(i==-1) {
+ fprintf(stderr, "Font file could not be located\n");
+ exit(EXIT_FAILURE);
+ }
+ fprintf(stderr, "Memory allocation failure\n");
+ exit(EXIT_FAILURE);
+ }
+ if(T1_LoadFont(i)==-1) {
+ T1_CloseLib();
+ fprintf(stderr, "t1lib could not load the font\n");
+ exit(EXIT_FAILURE);
+ }
+ do {
+ auto T1_OUTLINE *myoutline;
+ area(myoutline = T1_GetCharOutline(i,j,1000,NULL),
+ T1_GetCharBBox(i,j),
+ T1_GetCharName(i,j),v);
+ T1_FreeOutline(myoutline);
+ } while(j++<255);
+ T1_CloseLib();
+ return(EXIT_SUCCESS);
+}
diff --git a/fonts/utilities/t1infos/t1extremes.c b/fonts/utilities/t1infos/t1extremes.c
new file mode 100644
index 0000000000..6ab8363c33
--- /dev/null
+++ b/fonts/utilities/t1infos/t1extremes.c
@@ -0,0 +1,159 @@
+/*
+
+ t1extremes
+ ==========
+
+ Scan the outlines of a Type 1 font in order to see if some extremes
+ are missing. Type 1 specifications strongly suggest to add a point in
+ the outline path at such extreme places.
+
+ Copyright (c) 2003 Thomas Baruchel
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <t1lib.h>
+#include <math.h>
+
+int usage(void) {
+ fprintf(stderr,
+ "Usage: t1extremes [-v] file\n -v verbose output\n");
+ return(EXIT_FAILURE);
+}
+
+void position(double t, int x0, int y0, int x1, int y1,
+ int x2, int y2, int x3, int y3, char *name,
+ unsigned char d, unsigned char v) {
+ auto double x =
+ (double) x0 + ((double) (3*(-x0+x1)))*t
+ + ((double) (3*(x0-2*x1+x2)))*t*t
+ + ((double) (-x0+3*x1-3*x2+x3))*t*t*t;
+ auto double y =
+ (double) y0 + ((double) (3*(-y0+y1)))*t
+ + ((double) (3*(y0-2*y1+y2)))*t*t
+ + ((double) (-y0+3*y1-3*y2+y3))*t*t*t;
+ fprintf(stdout,"/%s : missing an extreme at (%.3f , %.3f) with a",name,x,y);
+ if(d==0) fprintf(stdout," vertical tangent\n");
+ else fprintf(stdout,"n horizontal tangent\n");
+ if(v!=0) {
+ auto double d1 = (x0-x)*(x0-x) + (y0-y)*(y0-y);
+ auto double d2 = (x3-x)*(x3-x) + (y3-y)*(y3-y);
+ fprintf(stdout," closest point of the outline is (");
+ if(d1<d2) fprintf(stdout,"%d , %d), distance = %.3f\n",x0,y0,sqrt(d1));
+ else fprintf(stdout,"%d , %d), distance = %.3f\n",x3,y3,sqrt(d2));
+ }
+}
+
+void missing_extremes(T1_OUTLINE *outline, char *name, unsigned char v) {
+ auto int xpos = 0;
+ auto int ypos = 0;
+ do {
+ switch(((T1_PATHSEGMENT *) outline)->type) {
+ case T1_PATHTYPE_MOVE:
+ case T1_PATHTYPE_LINE: {
+ xpos += (int) T1_NEARESTPOINT(((T1_PATHSEGMENT *) outline)->dest.x);
+ ypos -= (int) T1_NEARESTPOINT(((T1_PATHSEGMENT *) outline)->dest.y);
+ break;
+ }
+ case T1_PATHTYPE_BEZIER: {
+ auto int x0 = xpos;
+ auto int y0 = ypos;
+ auto int x1 =
+ xpos+T1_NEARESTPOINT(((T1_BEZIERSEGMENT *) outline)->B.x);
+ auto int y1 =
+ ypos-T1_NEARESTPOINT(((T1_BEZIERSEGMENT *) outline)->B.y);
+ auto int x2 =
+ xpos+T1_NEARESTPOINT(((T1_BEZIERSEGMENT *) outline)->C.x);
+ auto int y2 =
+ ypos-T1_NEARESTPOINT(((T1_BEZIERSEGMENT *) outline)->C.y);
+ auto int a,b,c,delta;
+ xpos += (int) T1_NEARESTPOINT(outline->dest.x);
+ ypos -= (int) T1_NEARESTPOINT(outline->dest.y);
+ a = 3*(-x0+3*x1-3*x2+xpos);
+ b = 6*(x0-2*x1+x2);
+ c = 3*(-x0+x1);
+ delta = b*b-4*a*c;
+ if(delta>=0) {
+ auto double t1 = (-b-sqrt(delta))/(2*a);
+ auto double t2 = (-b+sqrt(delta))/(2*a);
+ if((t1>0)&&(t1<1)) position(t1,x0,y0,x1,y1,x2,y2,xpos,ypos,name,0,v);
+ if((t2>0)&&(t2<1)) position(t2,x0,y0,x1,y1,x2,y2,xpos,ypos,name,0,v);
+ }
+ a = 3*(-y0+3*y1-3*y2+ypos);
+ b = 6*(y0-2*y1+y2);
+ c = 3*(-y0+y1);
+ delta = b*b-4*a*c;
+ if(delta>=0) {
+ auto double t1 = (-b-sqrt(delta))/(2*a);
+ auto double t2 = (-b+sqrt(delta))/(2*a);
+ if((t1>0)&&(t1<1)) position(t1,x0,y0,x1,y1,x2,y2,xpos,ypos,name,1,v);
+ if((t2>0)&&(t2<1)) position(t2,x0,y0,x1,y1,x2,y2,xpos,ypos,name,1,v);
+ }
+ break;
+ }
+ }
+ } while ((outline = outline->link) != NULL);
+}
+
+int main(int argc, char **argv)
+{
+ static signed int i;
+ static unsigned char j=0;
+ static char *fontname = NULL;
+ static unsigned char v = 0;
+
+ for(i=1;i<argc;i++) {
+ if((argv[i][0]=='-')
+ && (argv[i][1]=='v')
+ && (argv[i][2]=='\0')) v = 1;
+ else if(fontname==NULL) fontname = argv[i];
+ else exit(usage());
+ }
+ if(fontname==NULL) exit(usage());
+ if (T1_InitLib(NO_LOGFILE)==NULL) {
+ fprintf(stderr, "Initialization of t1lib failed\n");
+ exit(EXIT_FAILURE);
+ }
+ i = T1_AddFont(fontname);
+ if(i<0) {
+ T1_CloseLib();
+ if(i==-1) {
+ fprintf(stderr, "Font file could not be located\n");
+ exit(EXIT_FAILURE);
+ }
+ fprintf(stderr, "Memory allocation failure\n");
+ exit(EXIT_FAILURE);
+ }
+ if(T1_LoadFont(i)==-1) {
+ T1_CloseLib();
+ fprintf(stderr, "t1lib could not load the font\n");
+ exit(EXIT_FAILURE);
+ }
+ do {
+ auto T1_OUTLINE *myoutline;
+ missing_extremes(myoutline = T1_GetCharOutline(i,j,1000,NULL),
+ T1_GetCharName(i,j),v);
+ T1_FreeOutline(myoutline);
+ } while(j++<255);
+ T1_CloseLib();
+ return(EXIT_SUCCESS);
+}