diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/font/tfmofm.w')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/tfmofm.w | 1119 |
1 files changed, 0 insertions, 1119 deletions
diff --git a/Build/source/texk/web2c/luatexdir/font/tfmofm.w b/Build/source/texk/web2c/luatexdir/font/tfmofm.w deleted file mode 100644 index 6eeccdda214..00000000000 --- a/Build/source/texk/web2c/luatexdir/font/tfmofm.w +++ /dev/null @@ -1,1119 +0,0 @@ -% tfmofm.w -% -% Copyright 2006-2012 Taco Hoekwater <taco@@luatex.org> -% -% This file is part of LuaTeX. -% -% LuaTeX is free software; you can redistribute it and/or modify it under -% the terms of the GNU General Public License as published by the Free -% Software Foundation; either version 2 of the License, or (at your -% option) any later version. -% -% LuaTeX is distributed in the hope that it will be useful, but WITHOUT -% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -% License for more details. -% -% You should have received a copy of the GNU General Public License along -% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -@ @c - - -#include "ptexlib.h" - -@ Here are some macros that help process ligatures and kerns -@c -#define lig_kern_start(f,c) char_remainder(f,c) -#define stop_flag 128 /* value indicating `\.{STOP}' in a lig/kern program */ -#define kern_flag 128 /* op code for a kern step */ - -#define skip_byte(z) lig_kerns[z].b0 -#define next_char(z) lig_kerns[z].b1 -#define op_byte(z) lig_kerns[z].b2 -#define rem_byte(z) lig_kerns[z].b3 -#define lig_kern_restart(c) (256*op_byte(c)+rem_byte(c)) - - -@ -The information in a \.{TFM} file appears in a sequence of 8-bit bytes. -Since the number of bytes is always a multiple of 4, we could -also regard the file as a sequence of 32-bit words, but \TeX\ uses the -byte interpretation. The format of \.{TFM} files was designed by -Lyle Ramshaw in 1980. The intent is to convey a lot of different kinds -@^Ramshaw, Lyle Harold@> -of information in a compact but useful form. - -$\Omega$ is capable of reading not only \.{TFM} files, but also -\.{OFM} files, which can describe fonts with up to 65536 characters -and with huge lig/kern tables. These fonts will often be virtual -fonts built up from real fonts with 256 characters, but $\Omega$ -is not aware of this. - -The documentation below describes \.{TFM} files, with slight additions -to show where \.{OFM} files differ. - -@ -The first 24 bytes (6 words) of a \.{TFM} file contain twelve 16-bit -integers that give the lengths of the various subsequent portions -of the file. These twelve integers are, in order: -$$\vbox{\halign{\hfil#&$\null=\null$#\hfil\cr -|lf|&length of the entire file, in words;\cr -|lh|&length of the header data, in words;\cr -|bc|&smallest character code in the font;\cr -|ec|&largest character code in the font;\cr -|nw|&number of words in the width table;\cr -|nh|&number of words in the height table;\cr -|nd|&number of words in the depth table;\cr -|ni|&number of words in the italic correction table;\cr -|nl|&number of words in the lig/kern table;\cr -|nk|&number of words in the kern table;\cr -|ne|&number of words in the extensible character table;\cr -|np|&number of font parameter words.\cr}}$$ -They are all nonnegative and less than $2^{15}$. We must have |bc-1<=ec<=255|, -and -$$\hbox{|lf=6+lh+(ec-bc+1)+nw+nh+nd+ni+nl+nk+ne+np|.}$$ -Note that a \.{TFM} font may contain as many as 256 characters -(if |bc=0| and |ec=255|), and as few as 0 characters (if |bc=ec+1|). - -Incidentally, when two or more 8-bit bytes are combined to form an integer of -16 or more bits, the most significant bytes appear first in the file. -This is called BigEndian order. -@!@^BigEndian order@> - -The first 52 bytes (13 words) of an \.{OFM} file contains thirteen -32-bit integers that give the lengths of the various subsequent -portions of the file. The first word is 0 (future versions of -\.{OFM} files could have different values; what is important is that -the first two bytes be 0 to differentiate \.{TFM} and \.{OFM} files). -The next twelve integers are as above, all nonegative and less -than~$2^{31}$. We must have |bc-1<=ec<=65535|, and -$$\hbox{|lf=13+lh+2*(ec-bc+1)+nw+nh+nd+ni+nl+nk+ne+np|.}$$ -Note that an \.{OFM} font may contain as many as 65536 characters -(if |bc=0| and |ec=65535|), and as few as 0 characters (if |bc=ec+1|). - -The rest of the \.{TFM} file may be regarded as a sequence of ten data -arrays having the informal specification -$$\def\arr$[#1]#2${\&{array} $[#1]$ \&{of} #2} -\def\doarr\PB#1{\arr#1} -\vbox{\halign{\hfil\\{#}&$\,:\,$\doarr#\hfil\cr -header&|[0..lh-1]stuff|\cr -char\_info&|[bc..ec]char_info_word|\cr -width&|[0..nw-1]fix_word|\cr -height&|[0..nh-1]fix_word|\cr -depth&|[0..nd-1]fix_word|\cr -italic&|[0..ni-1]fix_word|\cr -lig\_kern&|[0..nl-1]lig_kern_command|\cr -kern&|[0..nk-1]fix_word|\cr -exten&|[0..ne-1]extensible_recipe|\cr -param&\omit |[1..np]fix_word|\cr}}$$ -The most important data type used here is a |@!fix_word|, which is -a 32-bit representation of a binary fraction. A |fix_word| is a signed -quantity, with the two's complement of the entire word used to represent -negation. Of the 32 bits in a |fix_word|, exactly 12 are to the left of the -binary point; thus, the largest |fix_word| value is $2048-2^{-20}$, and -the smallest is $-2048$. We will see below, however, that all but two of -the |fix_word| values must lie between $-16$ and $+16$. - -The first data array is a block of header information, which contains -general facts about the font. The header must contain at least two words, -|header[0]| and |header[1]|, whose meaning is explained below. -Additional header information of use to other software routines might -also be included, but \TeX82 does not need to know about such details. -For example, 16 more words of header information are in use at the Xerox -Palo Alto Research Center; the first ten specify the character coding -scheme used (e.g., `\.{XEROX text}' or `\.{TeX math symbols}'), the next five -give the font identifier (e.g., `\.{HELVETICA}' or `\.{CMSY}'), and the -last gives the ``face byte.'' The program that converts \.{DVI} files -to Xerox printing format gets this information by looking at the \.{TFM} -file, which it needs to read anyway because of other information that -is not explicitly repeated in \.{DVI}~format. - -\yskip\hang|header[0]| is a 32-bit check sum that \TeX\ will copy into -the \.{DVI} output file. Later on when the \.{DVI} file is printed, -possibly on another computer, the actual font that gets used is supposed -to have a check sum that agrees with the one in the \.{TFM} file used by -\TeX. In this way, users will be warned about potential incompatibilities. -(However, if the check sum is zero in either the font file or the \.{TFM} -file, no check is made.) The actual relation between this check sum and -the rest of the \.{TFM} file is not important; the check sum is simply an -identification number with the property that incompatible fonts almost -always have distinct check sums. -@^check sum@> - -\yskip\hang|header[1]| is a |fix_word| containing the design size of -the font, in units of \TeX\ points. This number must be at least 1.0; it is -fairly arbitrary, but usually the design size is 10.0 for a ``10 point'' -font, i.e., a font that was designed to look best at a 10-point size, -whatever that really means. When a \TeX\ user asks for a font -`\.{at} $\delta$ \.{pt}', the effect is to override the design size -and replace it by $\delta$, and to multiply the $x$ and~$y$ coordinates -of the points in the font image by a factor of $\delta$ divided by the -design size. {\sl All other dimensions in the\/ \.{TFM} file are -|fix_word|\kern-1pt\ numbers in design-size units}, with the exception of -|param[1]| (which denotes the slant ratio). Thus, for example, the value -of |param[6]|, which defines the \.{em} unit, is often the |fix_word| value -$2^{20}=1.0$, since many fonts have a design size equal to one em. -The other dimensions must be less than 16 design-size units in absolute -value; thus, |header[1]| and |param[1]| are the only |fix_word| -entries in the whole \.{TFM} file whose first byte might be something -besides 0 or 255. - -Next comes the |char_info| array, which contains one |@!char_info_word| -per character. Each word in this part of a \.{TFM} file contains six fields -packed into four bytes as follows. - -\yskip\hang first byte: |@!width_index| (8 bits)\par -\hang second byte: |@!height_index| (4 bits) times 16, plus |@!depth_index| - (4~bits)\par -\hang third byte: |@!italic_index| (6 bits) times 4, plus |@!tag| - (2~bits)\par -\hang fourth byte: |@!remainder| (8 bits)\par -\yskip\noindent -The actual width of a character is \\{width}|[width_index]|, in design-size -units; this is a device for compressing information, since many characters -have the same width. Since it is quite common for many characters -to have the same height, depth, or italic correction, the \.{TFM} format -imposes a limit of 16 different heights, 16 different depths, and -64 different italic corrections. - -For \.{OFM} files, two words (eight bytes) are used. -The arrangement is as follows. - -\yskip\hang first and second bytes: |@!width_index| (16 bits)\par -\hang third byte: |@!height_index| (8 bits)\par -\hang fourth byte: |@!depth_index| (8~bits)\par -\hang fifth and sixth bytes: -|@!italic_index| (14 bits) times 4, plus |@!tag| (2~bits)\par -\hang seventh and eighth bytes: |@!remainder| (16 bits)\par -\yskip\noindent -Therefore the \.{OFM} format imposes a limit of 256 different heights, -256 different depths, and 16384 different italic corrections. - -@!@^italic correction@> -The italic correction of a character has two different uses. -(a)~In ordinary text, the italic correction is added to the width only if -the \TeX\ user specifies `\.{\\/}' after the character. -(b)~In math formulas, the italic correction is always added to the width, -except with respect to the positioning of subscripts. - -Incidentally, the relation $\\{width}[0]=\\{height}[0]=\\{depth}[0]= -\\{italic}[0]=0$ should always hold, so that an index of zero implies a -value of zero. The |width_index| should never be zero unless the -character does not exist in the font, since a character is valid if and -only if it lies between |bc| and |ec| and has a nonzero |width_index|. - - -@ \TeX\ checks the information of a \.{TFM} file for validity as the -file is being read in, so that no further checks will be needed when -typesetting is going on. The somewhat tedious subroutine that does this -is called |read_font_info|. It has four parameters: the user font -identifier~|u|, the file name and area strings |nom| and |aire|, and the -``at'' size~|s|. If |s|~is negative, it's the negative of a scale factor -to be applied to the design size; |s=-1000| is the normal case. -Otherwise |s| will be substituted for the design size; in this -case, |s| must be positive and less than $2048\rm\,pt$ -(i.e., it must be less than $2^{27}$ when considered as an integer). - -The subroutine opens and closes a global file variable called |tfm_file|. -It returns the value of the internal font number that was just loaded. -If an error is detected, an error message is issued and no font -information is stored; |null_font| is returned in this case. - -@ -The |tag| field in a |char_info_word| has four values that explain how to -interpret the |remainder| field. - -\yskip\hang|tag=0| (|no_tag|) means that |remainder| is unused.\par -\hang|tag=1| (|lig_tag|) means that this character has a ligature/kerning -program starting at position |remainder| in the |lig_kern| array.\par -\hang|tag=2| (|list_tag|) means that this character is part of a chain of -characters of ascending sizes, and not the largest in the chain. The -|remainder| field gives the character code of the next larger character.\par -\hang|tag=3| (|ext_tag|) means that this character code represents an -extensible character, i.e., a character that is built up of smaller pieces -so that it can be made arbitrarily large. The pieces are specified in -|@!exten[remainder]|.\par -\yskip\noindent -Characters with |tag=2| and |tag=3| are treated as characters with |tag=0| -unless they are used in special circumstances in math formulas. For example, -the \.{\\sum} operation looks for a |list_tag|, and the \.{\\left} -operation looks for both |list_tag| and |ext_tag|. - - -@ The |lig_kern| array contains instructions in a simple programming language -that explains what to do for special letter pairs. Each word in this array, -in a \.{TFM} file, is a |@!lig_kern_command| of four bytes. - -\yskip\hang first byte: |skip_byte|, indicates that this is the final program - step if the byte is 128 or more, otherwise the next step is obtained by - skipping this number of intervening steps.\par -\hang second byte: |next_char|, ``if |next_char| follows the current character, - then perform the operation and stop, otherwise continue.''\par -\hang third byte: |op_byte|, indicates a ligature step if less than~128, - a kern step otherwise.\par -\hang fourth byte: |remainder|.\par -\yskip\noindent -In an \.{OFM} file, eight bytes are used, two bytes for each field. - -In a kern step, an -additional space equal to |kern[256*(op_byte-128)+remainder]| is inserted -between the current character and |next_char|. This amount is -often negative, so that the characters are brought closer together -by kerning; but it might be positive. - -There are eight kinds of ligature steps, having |op_byte| codes $4a+2b+c$ where -$0\le a\le b+c$ and $0\le b,c\le1$. The character whose code is -|remainder| is inserted between the current character and |next_char|; -then the current character is deleted if $b=0$, and |next_char| is -deleted if $c=0$; then we pass over $a$~characters to reach the next -current character (which may have a ligature/kerning program of its own). - -If the very first instruction of the |lig_kern| array has |skip_byte=255|, -the |next_char| byte is the so-called right boundary character of this font; -the value of |next_char| need not lie between |bc| and~|ec|. -If the very last instruction of the |lig_kern| array has |skip_byte=255|, -there is a special ligature/kerning program for a left boundary character, -beginning at location |256*op_byte+remainder|. -The interpretation is that \TeX\ puts implicit boundary characters -before and after each consecutive string of characters from the same font. -These implicit characters do not appear in the output, but they can affect -ligatures and kerning. - -If the very first instruction of a character's |lig_kern| program has -|skip_byte>128|, the program actually begins in location -|256*op_byte+remainder|. This feature allows access to large |lig_kern| -arrays, because the first instruction must otherwise -appear in a location |<=255| in a \.{TFM} file, |<=65535| in an \.{OFM} file. - -Any instruction with |skip_byte>128| in the |lig_kern| array must satisfy -the condition -$$\hbox{|256*op_byte+remainder<nl|.}$$ -If such an instruction is encountered during -normal program execution, it denotes an unconditional halt; no ligature -or kerning command is performed. - - -@ Extensible characters are specified by an |@!extensible_recipe|, which -consists of four bytes in a \.{TFM} file, -called |@!top|, |@!mid|, |@!bot|, and |@!rep| (in this order). -In an \.{OFM} file, each field takes two bytes, for eight in total. -These bytes are the character codes of individual pieces used to -build up a large symbol. If |top|, |mid|, or |bot| are zero, they are not -present in the built-up result. For example, an extensible vertical line is -like an extensible bracket, except that the top and bottom pieces are missing. - -Let $T$, $M$, $B$, and $R$ denote the respective pieces, or an empty box -if the piece isn't present. Then the extensible characters have the form -$TR^kMR^kB$ from top to bottom, for some |k>=0|, unless $M$ is absent; -in the latter case we can have $TR^kB$ for both even and odd values of~|k|. -The width of the extensible character is the width of $R$; and the -height-plus-depth is the sum of the individual height-plus-depths of the -components used, since the pieces are butted together in a vertical list. - - -@ -The final portion of a \.{TFM} file is the |param| array, which is another -sequence of |fix_word| values. - -\yskip\hang|param[1]=slant| is the amount of italic slant, which is used -to help position accents. For example, |slant=.25| means that when you go -up one unit, you also go .25 units to the right. The |slant| is a pure -number; it's the only |fix_word| other than the design size itself that is -not scaled by the design size. - -\hang|param[2]=space| is the normal spacing between words in text. -Note that character |" "| in the font need not have anything to do with -blank spaces. - -\hang|param[3]=space_stretch| is the amount of glue stretching between words. - -\hang|param[4]=space_shrink| is the amount of glue shrinking between words. - -\hang|param[5]=x_height| is the size of one ex in the font; it is also -the height of letters for which accents don't have to be raised or lowered. - -\hang|param[6]=quad| is the size of one em in the font. - -\hang|param[7]=extra_space| is the amount added to |param[2]| at the -ends of sentences. - -\yskip\noindent -If fewer than seven parameters are present, \TeX\ sets the missing parameters -to zero. Fonts used for math symbols are required to have -additional parameter information, which is explained later. - - -@ - There are programs called \.{TFtoPL} and \.{PLtoTF} that convert - between the \.{TFM} format and a symbolic property-list format - that can be easily edited. These programs contain extensive - diagnostic information, so \TeX\ does not have to bother giving - precise details about why it rejects a particular \.{TFM} file. - -@c -#define tfm_abort { font_tables[f]->_font_name = NULL; \ - font_tables[f]->_font_area = NULL; \ - xfree(tfm_buffer); xfree(kerns); \ - xfree(widths); xfree(heights); xfree(depths); \ - xfree(italics); xfree(extens); xfree(lig_kerns); \ - xfree(xligs); xfree(xkerns); \ - return 0; } - -#define tfm_success { xfree(tfm_buffer); xfree(kerns); \ - xfree(widths); xfree(heights); xfree(depths); \ - xfree(italics); xfree(extens); xfree(lig_kerns); \ - xfree(xligs); xfree(xkerns); return 1; } - -@ @c -static int open_tfm_file(const char *nom, unsigned char **tfm_buf, int *tfm_siz) -{ - boolean res; /* was the callback successful? */ - boolean opened; /* was |tfm_file| successfully opened? */ - int callback_id; - FILE *tfm_file; - char *fname = luatex_find_file(nom, find_font_file_callback); - if (!fname) - return -1; - callback_id = callback_defined(read_font_file_callback); - if (callback_id > 0) { - res = - run_callback(callback_id, "S->bSd", fname, &opened, tfm_buf, - tfm_siz); - if (res && opened && (*tfm_siz > 0)) { - return 1; - } - if (!opened) - return -1; - } else { - if (luatex_open_input - (&(tfm_file), fname, kpse_ofm_format, FOPEN_RBIN_MODE, true)) { - res = read_tfm_file(tfm_file, tfm_buf, tfm_siz); - close_file(tfm_file); - if (res) { - return 1; - } - } else { - return -1; - } - } - return 0; -} - - -@ - Note: A malformed \.{TFM} file might be shorter than it claims to be; - thus |eof(tfm_file)| might be true when |read_font_info| refers to - |tfm_file^| or when it says |get(tfm_file)|. If such circumstances - cause system error messages, you will have to defeat them somehow, - for example by defining |fget| to be `\ignorespaces|begin get(tfm_file);| - |if eof(tfm_file) then abort; end|\unskip'. - @^system dependencies@> -@c - -#define fget tfm_byte++ -#define fbyte tfm_buffer[tfm_byte] - -#define read_sixteen(a) \ - { a=tfm_buffer[tfm_byte++]; \ - if (a>127) { tfm_abort; } \ - a=(a*256)+tfm_buffer[tfm_byte]; } - -#define read_sixteen_unsigned(a) \ - { a=tfm_buffer[tfm_byte++]; \ - a=(a*256)+tfm_buffer[tfm_byte]; } - -#define read_thirtytwo(a) \ - { a=tfm_buffer[++tfm_byte]; \ - if (a>127) { tfm_abort; } \ - a=(a*256)+tfm_buffer[++tfm_byte]; \ - a=(a*256)+tfm_buffer[++tfm_byte]; \ - a=(a*256)+tfm_buffer[++tfm_byte]; } - -#define store_four_bytes(z) \ - { a=tfm_buffer[++tfm_byte]; \ - a=(a*256)+tfm_buffer[++tfm_byte]; \ - a=(a*256)+tfm_buffer[++tfm_byte]; \ - a=(a*256)+tfm_buffer[++tfm_byte]; \ - z = a; } - -#define store_char_info(z) \ - { if (font_level!=-1) { \ - fget; read_sixteen_unsigned(a); \ - ci._width_index=a; \ - fget; read_sixteen_unsigned(b); \ - ci._height_index=b>>8; \ - ci._depth_index=b%256; \ - fget; read_sixteen_unsigned(c); \ - ci._italic_index=c>>8; \ - ci._tag=(unsigned char)(c%4); \ - fget; read_sixteen_unsigned(d); \ - ci._remainder=d; \ - } else { \ - a=tfm_buffer[++tfm_byte]; \ - ci._width_index=a; \ - b=tfm_buffer[++tfm_byte]; \ - ci._height_index=b>>4; \ - ci._depth_index=b%16; \ - c=tfm_buffer[++tfm_byte]; \ - ci._italic_index=c>>2; \ - ci._tag=(unsigned char)(c%4); \ - d=tfm_buffer[++tfm_byte]; \ - ci._remainder=d; \ - } } - -#define read_four_quarters(q) \ - { if (font_level!=-1) { \ - fget; read_sixteen_unsigned(a); q.b0=(quarterword)a; \ - fget; read_sixteen_unsigned(b); q.b1=(quarterword)b; \ - fget; read_sixteen_unsigned(c); q.b2=(quarterword)c; \ - fget; read_sixteen_unsigned(d); q.b3=(quarterword)d; \ - } else { \ - a=tfm_buffer[++tfm_byte]; q.b0=(quarterword)a; \ - b=tfm_buffer[++tfm_byte]; q.b1=(quarterword)b; \ - c=tfm_buffer[++tfm_byte]; q.b2=(quarterword)c; \ - d=tfm_buffer[++tfm_byte]; q.b3=(quarterword)d; \ - } } - -#define check_byte_range(z) { if ((z<bc)||(z>ec)) tfm_abort ; } - - -@ A |fix_word| whose four bytes are $(a,b,c,d)$ from left to right represents - the number - $$x=\left\{\vcenter{\halign{$#$,\hfil\qquad&if $#$\hfil\cr - b\cdot2^{-4}+c\cdot2^{-12}+d\cdot2^{-20}&a=0;\cr - -16+b\cdot2^{-4}+c\cdot2^{-12}+d\cdot2^{-20}&a=255.\cr}}\right.$$ - (No other choices of |a| are allowed, since the magnitude of a number in - design-size units must be less than 16.) We want to multiply this - quantity by the integer~|z|, which is known to be less than $2^{27}$. - If $|z|<2^{23}$, the individual multiplications $b\cdot z$, - $c\cdot z$, $d\cdot z$ cannot overflow; otherwise we will divide |z| by 2, - 4, 8, or 16, to obtain a multiplier less than $2^{23}$, and we can - compensate for this later. If |z| has thereby been replaced by - $|z|^\prime=|z|/2^e$, let $\beta=2^{4-e}$; we shall compute - $$\lfloor(b+c\cdot2^{-8}+d\cdot2^{-16})\,z^\prime/\beta\rfloor$$ - if $a=0$, or the same quantity minus $\alpha=2^{4+e}z^\prime$ if $a=255$. - This calculation must be done exactly, in order to guarantee portability - of \TeX\ between computers. - -@c -#define store_scaled(zz) \ - { fget; a=fbyte; fget; b=fbyte; \ - fget; c=fbyte; fget; d=fbyte; \ - sw=(((((d*z)>>8)+(c*z))>>8)+(b*z)) / beta; \ - if (a==0) { zz=sw; } else if (a==255) { zz=sw-alpha; } else tfm_abort; \ - } - -scaled store_scaled_f(scaled sq, scaled z_in) -{ - eight_bits a, b, c, d; - scaled sw; - static int alpha, beta; /* beta:1..16 */ - static scaled z, z_prev = 0; - /* Replace |z| by $|z|^\prime$ and compute $\alpha,\beta$ */ - if (z_in != z_prev || z_prev == 0) { - z = z_prev = z_in; - alpha = 16; - while (z >= 0x800000) { - z /= 2; - alpha += alpha; - } - beta = 256 / alpha; - alpha *= z; - }; - if (sq >= 0) { - d = (eight_bits) (sq % 256); - sq = sq / 256; - c = (eight_bits) (sq % 256); - sq = sq / 256; - b = (eight_bits) (sq % 256); - sq = sq / 256; - a = (eight_bits) (sq % 256); - } else { - sq = (sq + 1073741824) + 1073741824; /* braces for optimizing compiler */ - d = (eight_bits) (sq % 256); - sq = sq / 256; - c = (eight_bits) (sq % 256); - sq = sq / 256; - b = (eight_bits) (sq % 256); - sq = sq / 256; - a = (eight_bits) ((sq + 128) % 256); - } - if (beta==0) - normal_error("vf", "vf scaling"); - sw = (((((d * z) >> 8) + (c * z)) >> 8) + (b * z)) / beta; - if (a == 0) - return sw; - else if (a == 255) - return (sw - alpha); - else - normal_error("vf", "vf scaling"); - return sw; /* not reached, just to make the compiler happy */ -} - -@ @c -#define check_existence(z) \ - { check_byte_range(z); \ - if (!char_exists(f,z)) tfm_abort; \ - } - -typedef struct tfmcharacterinfo { - int _kern_index; - int _lig_index; - int _width_index; - int _height_index; - int _depth_index; - int _italic_index; - int _remainder; - unsigned char _tag; -} tfmcharacterinfo; - -@ @c -int read_tfm_info(internal_font_number f, const char *cnom, scaled s) -{ - int k; /* index into |font_info| */ - halfword lf, lh, bc, ec, nw, nh, nd, ni, nl, nk, ne, np, slh; /* sizes of subfiles */ - scaled *widths, *heights, *depths, *italics, *kerns; - halfword font_dir; - int a, b, c=0, d=0; /* byte variables */ - int i; /* counter */ - int font_level, header_length; - int ncw, nlw, neew; - tfmcharacterinfo ci; - charinfo *co; - four_quarters qw; - four_quarters *lig_kerns, *extens; - scaled sw; /* accumulators */ - int bch_label; /* left boundary start location, or infinity */ - int bchar; /* |:0..too_big_char;| *//* right boundary character, or |too_big_char| */ - int first_two; - scaled z; /* the design size or the ``at'' size */ - int alpha; - char beta; /* :1..16 */ - int *xligs, *xkerns; /* aux. for ligkern processing */ - liginfo *cligs; - kerninfo *ckerns; - int fligs, fkerns; - char *tmpnam; - int tfm_byte = 0; /* index into |tfm_buffer| */ - int saved_tfm_byte = 0; /* saved index into |tfm_buffer| */ - unsigned char *tfm_buffer = NULL; /* byte buffer for tfm files */ - int tfm_size = 0; /* total size of the tfm file */ - int tmp; - - widths = NULL; - heights = NULL; - depths = NULL; - italics = NULL; - kerns = NULL; - lig_kerns = NULL; - extens = NULL; - xkerns = NULL; - ckerns = NULL; - xligs = NULL; - cligs = NULL; - - font_dir = 0; - - memset(&ci, 0, sizeof(tfmcharacterinfo)); - - if (open_tfm_file(cnom, &tfm_buffer, &tfm_size) != 1) - tfm_abort; - - /* cnom can be an absolute filename, xbasename() fixes that. */ - - tmpnam = strdup(xbasename(cnom)); - if (strcmp(tmpnam + strlen(tmpnam) - 4, ".tfm") == 0 || strcmp(tmpnam + strlen(tmpnam) - 4, ".ofm") == 0) { - *(tmpnam + strlen(tmpnam) - 4) = 0; - } - set_font_name(f, tmpnam); - set_font_area(f, NULL); - - /* Read the {\.{TFM}} size fields */ - ncw = 0; - read_sixteen(first_two); - if (first_two != 0) { - font_level = -1; - lf = first_two; - fget; - read_sixteen(lh); - fget; - read_sixteen(bc); - fget; - read_sixteen(ec); - if ((bc > ec + 1) || (ec > 255)) - tfm_abort; - if (bc > 255) { /* |bc=256| and |ec=255| */ - bc = 1; - ec = 0; - }; - fget; - read_sixteen(nw); - fget; - read_sixteen(nh); - fget; - read_sixteen(nd); - fget; - read_sixteen(ni); - fget; - read_sixteen(nl); - fget; - read_sixteen(nk); - fget; - read_sixteen(ne); - fget; - read_sixteen(np); - header_length = 6; - ncw = (ec - bc + 1); - nlw = nl; - neew = ne; - } else { - fget; - read_sixteen(font_level); - if (font_level != 0) - tfm_abort; - read_thirtytwo(lf); - read_thirtytwo(lh); - read_thirtytwo(bc); - read_thirtytwo(ec); - if ((bc > ec + 1) || (ec > 65535)) - tfm_abort; - if (bc > 65535) { /* |bc=65536| and |ec=65535| */ - bc = 1; - ec = 0; - }; - read_thirtytwo(nw); - read_thirtytwo(nh); - read_thirtytwo(nd); - read_thirtytwo(ni); - read_thirtytwo(nl); - read_thirtytwo(nk); - read_thirtytwo(ne); - read_thirtytwo(np); - read_thirtytwo(font_dir); /* junk */ - nlw = 2 * nl; - neew = 2 * ne; - header_length = 14; - ncw = 2 * (ec - bc + 1); - }; - if (lf != - (header_length + lh + ncw + nw + nh + nd + ni + nlw + nk + neew + np)) - tfm_abort; - if ((nw == 0) || (nh == 0) || (nd == 0) || (ni == 0)) - tfm_abort; - - /* - We check to see that the \.{TFM} file doesn't end prematurely; but - no error message is given for files having more than |lf| words. - */ - if (lf * 4 > tfm_size) - tfm_abort; - - /* Use size fields to allocate font information */ - - set_font_natural_dir(f, font_dir); - set_font_bc(f, bc); - set_font_ec(f, ec); - - /* read the arrays first */ - widths = xmalloc((unsigned) ((unsigned) nw * sizeof(scaled))); - heights = xmalloc((unsigned) ((unsigned) nh * sizeof(scaled))); - depths = xmalloc((unsigned) ((unsigned) nd * sizeof(scaled))); - italics = xmalloc((unsigned) ((unsigned) ni * sizeof(scaled))); - extens = xmalloc((unsigned) ((unsigned) ne * sizeof(four_quarters))); - lig_kerns = xmalloc((unsigned) ((unsigned) nl * sizeof(four_quarters))); - kerns = xmalloc((unsigned) ((unsigned) nk * sizeof(scaled))); - - /* Read the {\.{TFM}} header */ - - /* Only the first two words of the header are needed by \TeX82. */ - slh = lh; - if (lh < 2) - tfm_abort; - store_four_bytes(tmp); - font_checksum(f) = (unsigned) tmp; - fget; - read_sixteen(z); /* this rejects a negative design size */ - fget; - z = z * 256 + fbyte; - fget; - z = (z * 16) + (fbyte >> 4); - if (z < unity) - tfm_abort; - while (lh > 2) { - fget; - fget; - fget; - fget; - lh--; /* ignore the rest of the header */ - }; - - /* read the arrays before the character info */ - - set_font_dsize(f, z); - if (s != -1000) { - z = (s >= 0 ? s : xn_over_d(z, -s, 1000)); - } - set_font_size(f, z); - - if (np > 7) - set_font_params(f, np); - - saved_tfm_byte = tfm_byte; - tfm_byte = (header_length + slh + ncw) * 4 - 1; - - /* Replace |z| by $|z|^\prime$ and compute $\alpha,\beta$ */ - - alpha = 16; - while (z >= 040000000) { - z = z >> 1; - alpha = alpha + alpha; - }; - beta = (char) (256 / alpha); - - /* beta cannot be zero */ - if (beta==0) - normal_error("vf", "vf reading"); - alpha = alpha * z; - - /* Read box dimensions */ - - for (k = 0; k < nw; k++) { - store_scaled(sw); - widths[k] = sw; - } - if (widths[0] != 0) /* \\{width}[0] must be zero */ - tfm_abort; - for (k = 0; k < nh; k++) { - store_scaled(sw); - heights[k] = sw; - } - if (heights[0] != 0) - tfm_abort; /* \\{height}[0] must be zero */ - for (k = 0; k < nd; k++) { - store_scaled(sw); - depths[k] = sw; - } - if (depths[0] != 0) - tfm_abort; /* \\{depth}[0] must be zero */ - for (k = 0; k < ni; k++) { - store_scaled(sw); - italics[k] = sw; - } - if (italics[0] != 0) - tfm_abort; /* \\{italic}[0] must be zero */ - - - /* Read ligature/kern program */ - - bch_label = nl; /* infinity */ - bchar = 65536; - if (nl > 0) { - for (k = 0; k < nl; k++) { - read_four_quarters(qw); - lig_kerns[k] = qw; - if (a > 128) { - if (256 * c + d >= nl) - tfm_abort; - if (a == 255 && k == 0) - bchar = b; - } else { -#if 0 - if (b!=bchar) check_existence(b); -#endif - if (c < 128) { -#if 0 - check_existence(d); /* check ligature */ -#endif - } else if (256 * (c - 128) + d >= nk) { - tfm_abort; /* check kern */ - } - if ((a < 128) && (k - 0 + a + 1 >= nl)) - tfm_abort; - }; - }; - if (a == 255) - bch_label = 256 * c + d; - }; - - /* the actual kerns */ - for (k = 0; k < nk; k++) { - store_scaled(sw); - kerns[k] = sw; - } - - /* Read extensible character recipes */ - for (k = 0; k < ne; k++) { - read_four_quarters(qw); - extens[k] = qw; - } - - /* Read font parameters */ - - if (np > 7) { - set_font_params(f, np); - } - for (k = 1; k <= np; k++) { - if (k == 1) { /* the |slant| parameter is a pure number */ - fget; - sw = fbyte; - if (sw > 127) - sw = sw - 256; - fget; - sw = sw * 256 + fbyte; - fget; - sw = sw * 256 + fbyte; - fget; - sw = (sw * 16) + (fbyte >> 4); - set_font_param(f, k, sw); - } else { - store_scaled(font_param(f, k)); - } - } - - tfm_byte = saved_tfm_byte; - - /* fix up the left boundary character */ - fligs = 0; - fkerns = 0; - if (bch_label != nl) { - k = bch_label; -#if 0 - if (skip_byte(k) > stop_flag) - k = lig_kern_restart(k); -#endif - while (1) { - if (skip_byte(k) <= stop_flag) { - if (op_byte(k) >= kern_flag) { /* kern */ - fkerns++; - } else { /* lig */ - fligs++; - } - } - if (skip_byte(k) == 0) { - k++; - } else { - if (skip_byte(k) >= stop_flag) - break; - k += skip_byte(k) + 1; - } - } - } - if (fkerns > 0 || fligs > 0) { - if (fligs > 0) - cligs = xcalloc((unsigned) (fligs + 1), sizeof(liginfo)); - if (fkerns > 0) - ckerns = xcalloc((unsigned) (fkerns + 1), sizeof(kerninfo)); - fligs = 0; - fkerns = 0; - k = bch_label; -#if 0 - if (skip_byte(k) > stop_flag) - k = lig_kern_restart(k); -#endif - while (1) { - if (skip_byte(k) <= stop_flag) { - if (op_byte(k) >= kern_flag) { /* kern */ - set_kern_item(ckerns[fkerns], next_char(k), - kerns[256 * (op_byte(k) - 128) + - rem_byte(k)]); - fkerns++; - } else { /* lig */ - set_ligature_item(cligs[fligs], (char) (op_byte(k) * 2 + 1), - next_char(k), rem_byte(k)); - fligs++; - } - } - if (skip_byte(k) == 0) { - k++; - } else { - if (skip_byte(k) >= stop_flag) - break; - k += skip_byte(k) + 1; - } - } - if (fkerns > 0 || fligs > 0) { - co = get_charinfo(f, left_boundarychar); - if (fkerns > 0) { - set_kern_item(ckerns[fkerns], end_kern, 0); - fkerns++; - set_charinfo_kerns(co, ckerns); - } - if (fligs > 0) { - set_ligature_item(cligs[fligs], 0, end_ligature, 0); - fligs++; - set_charinfo_ligatures(co, cligs); - } - set_charinfo_remainder(co, 0); - } - } - - /* Read character data */ - for (k = bc; k <= ec; k++) { - store_char_info(k); - if (ci._width_index == 0) - continue; - if (ci._width_index >= nw || ci._height_index >= nh || - ci._depth_index >= nd || ci._italic_index >= ni) - tfm_abort; - d = ci._remainder; - switch (ci._tag) { - case lig_tag: - if (d >= nl) - tfm_abort; - break; - case ext_tag: - if (d >= ne) - tfm_abort; - break; - case list_tag: - /* We want to make sure that there is no cycle of characters linked together - by |list_tag| entries, since such a cycle would get \TeX\ into an endless - loop. If such a cycle exists, the routine here detects it when processing - the largest character code in the cycle. - */ - check_byte_range(d); - while (d < k) { /* |current_character == k| */ - if (char_tag(f, d) != list_tag) - goto NOT_FOUND; /* not a cycle */ - d = char_remainder(f, d); /* next character on the list */ - }; - if (d == k) - tfm_abort; /* yes, there's a cycle */ - NOT_FOUND: - break; - } - /* put it in the actual font */ - co = get_charinfo(f, k); - set_charinfo_index(co, k); - set_charinfo_tag(co, ci._tag); - if (ci._tag == ext_tag) { - set_charinfo_extensible(co, extens[ci._remainder].b0, /* top */ - extens[ci._remainder].b2, /* bot */ - extens[ci._remainder].b1, /* mid */ - extens[ci._remainder].b3); /* rep */ - set_charinfo_remainder(co, 0); - } else { - set_charinfo_remainder(co, ci._remainder); - } - set_charinfo_width(co, widths[ci._width_index]); - set_charinfo_height(co, heights[ci._height_index]); - set_charinfo_depth(co, depths[ci._depth_index]); - set_charinfo_italic(co, italics[ci._italic_index]); - }; - - /* first pass: count ligs and kerns */ - - xligs = xcalloc((unsigned) (ec + 1), sizeof(int)); - xkerns = xcalloc((unsigned) (ec + 1), sizeof(int)); - - for (i = bc; i <= ec; i++) { - if (char_tag(f, i) == lig_tag) { - k = lig_kern_start(f, i); - if (skip_byte(k) > stop_flag) - k = lig_kern_restart(k); - /* now k is the start index */ - while (1) { - if (skip_byte(k) <= stop_flag) { - if (op_byte(k) >= kern_flag) { /* kern */ - xkerns[i]++; - if (next_char(k) == bchar) - xkerns[i]++; - } else { /* lig */ - xligs[i]++; - if (next_char(k) == bchar) - xligs[i]++; - } - } - if (skip_byte(k) == 0) { - k++; - } else { - if (skip_byte(k) >= stop_flag) - break; - k += skip_byte(k) + 1; - } - } - } - } - - cligs = NULL; - ckerns = NULL; - - for (i = bc; i <= ec; i++) { - fligs = 0; - fkerns = 0; - if (char_tag(f, i) == lig_tag) { - k = lig_kern_start(f, i); - if (skip_byte(k) > stop_flag) - k = lig_kern_restart(k); - /* now k is the start index */ - if (xligs[i] > 0) - cligs = xcalloc((unsigned) (xligs[i] + 1), sizeof(liginfo)); - if (xkerns[i] > 0) - ckerns = xcalloc((unsigned) (xkerns[i] + 1), sizeof(kerninfo)); - while (1) { - if (skip_byte(k) <= stop_flag) { - if (op_byte(k) >= kern_flag) { /* kern */ - if (next_char(k) == bchar) { - set_kern_item(ckerns[fkerns], right_boundarychar, - kerns[256 * (op_byte(k) - 128) + - rem_byte(k)]); - fkerns++; - } - set_kern_item(ckerns[fkerns], next_char(k), - kerns[256 * (op_byte(k) - 128) + - rem_byte(k)]); - fkerns++; - } else { /* lig */ - if (next_char(k) == bchar) { - set_ligature_item(cligs[fligs], - (char) (op_byte(k) * 2 + 1), - right_boundarychar, rem_byte(k)); - fligs++; - } - set_ligature_item(cligs[fligs], - (char) (op_byte(k) * 2 + 1), - next_char(k), rem_byte(k)); - fligs++; - } - } - if (skip_byte(k) == 0) { - k++; - } else { - if (skip_byte(k) >= stop_flag) - break; - k += skip_byte(k) + 1; - } - } - if (fkerns > 0 || fligs > 0) { - co = get_charinfo(f, i); - if (fkerns > 0) { - set_kern_item(ckerns[fkerns], end_kern, 0); - fkerns++; - set_charinfo_kerns(co, ckerns); - } - if (fligs > 0) { - set_ligature_item(cligs[fligs], 0, end_ligature, 0); - fligs++; - set_charinfo_ligatures(co, cligs); - } - set_charinfo_remainder(co, 0); - } - } - } - - - /* Make final adjustments and |goto done| */ - - /* Now to wrap it up, we have checked all the necessary things about the \.{TFM} - file, and all we need to do is put the finishing touches on the data for - the new font. - */ - - if (bchar != 65536) { - co = copy_charinfo(char_info(f, bchar)); - set_right_boundary(f, co); - } - - tfm_success; -} |