|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T g
Length: 20631 (0x5097) Types: TextFile Names: »gftopxl.BSD4_n.ch«
└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89 └─⟦this⟧ »./tex82/Unsupported/MFpxl/mfware/gftopxl.BSD4_n.ch« └─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦beba6c409⟧ »unix3.0/Unsupported.tar.Z« └─⟦25c524ae4⟧ └─⟦this⟧ »Unsupported/MFpxl/mfware/gftopxl.BSD4_n.ch«
% $Header: gftopxl.ch,v 2.2 86/12/06 11:03:12 mackay Released $ % Change file for the GFtoPXL processor, for use on Berkeley UNIX systems. % History: % % $Log: gftopxl.ch,v $ % Revision 2.2 86/12/06 11:03:12 mackay % Changed: % Version change to 2.2 to incorporate William Lefebvre's corrections % for all blank rasters. Change to way out .?pxl file is named so % that it goes to the current working directory by default. % % Revision 2.1.1.2 86/01/29 00:54:19 richards % Changed: % file name construction to skip pathname prefixes before looking % for '.' in name % % Revision 2.1.1.1 86/01/21 22:33:47 richards % Updated to incorporate new binary I/O routines % % Revision 2.1 85/03/03 21:43:35 richards % Updated to GF utilities distributed with MF Version 0.77 % (New GF file format) % % Revision 2.0 84/12/16 22:40:15 richards % Updated for GFtoPXL Version 2.0 (New GF file format) % % Revision 1.1 84/12/06 03:14:54 richards % Updated for GFtoPXL Version 1.1; merged in changes from sdcarl!rusty % % Revision 1.0 84/11/17 23:53:20 richards % Base version for GFtoPXL Version 1.0 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{GF\lowercase{to}PXL changes for Berkeley {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner string %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is GFtoPXL, Version 2.2' {printed when the program starts} @y @d banner=='This is GFtoPXL, Version 2.2 for Berkeley UNIX' {printed when the program starts} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [4] Delete files from program header, % Add gftopxl_ext.h, % have initialize() setup file names from command line %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p program GF_to_PXL(@!gf_file,@!pxl_file,@!output); label @<Labels in the outer block@>@/ const @<Constants in the outer block@>@/ type @<Types in the outer block@>@/ var @<Globals in the outer block@>@/ procedure initialize; {this procedure gets things started properly} var i:integer; {loop index for initializations} begin print_ln(banner);@/ @<Set initial values@>@/ end; @y @p program GF_to_PXL(@!input,@!output); label @<Labels in the outer block@>@/ const @<Constants in the outer block@>@/ type @<Types in the outer block@>@/ var @<Globals in the outer block@>@/ @\@=#include "gftopxl_ext.h"@>@\ {declarations for external C procedures} @^system dependencies@> procedure initialize; {this procedure gets things started properly} var i:integer; {loop index for initializations} begin print_ln(banner);@/ @<Set initial values@>@/ @<Parse command line arguments@>@/ end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [6] Add file_name_size to constants %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @<Constants...@>= @!line_length=79; {bracketed lines of output will be at most this long} @!terminal_line_length=150; {maximum number of characters input in a single line of input from the terminal} @!max_glyph_no=127; {maximum glyph number in font, later change to 255} @!top_pixel=700; {boundary of pixel image of glyph} @!bot_pixel=-250; @!left_pixel=-250; @!right_pixel=750; @y @<Constants...@>= @!line_length=79; {bracketed lines of output will be at most this long} @!terminal_line_length=150; {maximum number of characters input in a single line of input from the terminal} @!max_glyph_no=127; {maximum glyph number in font, later change to 255} @!top_pixel=700; {boundary of pixel image of glyph} @!bot_pixel=-250; @!left_pixel=-250; @!right_pixel=750;@/ @!file_name_size=256; {max length of file name on command line} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [8] modify abort to append <nl> to end of message %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d abort(#)==begin print(' ',#); jump_out; @y @d abort(#)==begin print_ln(' ',#); jump_out; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [10] Add definition of "update_terminal" to flush output %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x The |input_ln| routine waits for the user to type a line at his or her terminal; then it puts ASCII-code equivalents for the characters on that line into the |buffer| array. The |term_in| file is used for terminal input, and |term_out| for terminal output. @^system dependencies@> @<Glob...@>= @!buffer:array[0..terminal_line_length] of ASCII_code; @!term_in:text_file; {the terminal, considered as an input file} @!term_out:text_file; {the terminal, considered as an output file} @y The |input_ln| routine waits for the user to type a line at his or her terminal; then it puts ASCII-code equivalents for the characters on that line into the |buffer| array. The |term_in| file is used for terminal input, and |term_out| for terminal output. Output written to the terminal should be forced to appear by |update_terminal|, in case the Pascal system buffers the output. @^system dependencies@> @d update_terminal==flush(output); @<Glob...@>= @!buffer:array[0..terminal_line_length] of ASCII_code; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [24] Change type of binary file for gf_file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x We shall stick to simple \PASCAL\ in this program, for reasons of clarity, even if such simplicity is sometimes unrealistic. @<Types...@>= @!eight_bits=0..255; {unsigned one-byte quantity} @!byte_file=packed file of eight_bits; {files that contain binary data} @y For Berkeley Pascal, we use a set of library routines to do binary input and output. These routines don't use the standard Pascal file structures, but rather a ``magic cookie'' stored in a record, to identify the file. Therefore, we redefine |byte_file| to be a record type. We also add a new type, |UNIX_file_name|, to be used when passing the name of the file to the file opening routines. @<Types...@>= @!eight_bits=0..255; {unsigned one-byte quantity} @!UNIX_file_name=packed array [1..file_name_size] of char; @!byte_file=record@/ stdio_ptr: ^integer; {pointer for stdio FILE struct} loc_ptr: ^integer; {pointer to byte position ptr to keep in sync with file} file_name: UNIX_file_name; {copy of file name saved when file opened} end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [25] Add gf_name and pxl_name declarations %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The program deals with two binary file variables: |gf_file| is the input file that we are translating into \.{PXL} format, to be written on |pxl_file|. @<Glob...@>= @!gf_file:byte_file; {the stuff we are \.{GFtoPXL}ing} @!pxl_file:byte_file; {the stuff we have \.{GFtoPXL}ed} @y @ The program deals with two binary file variables: |gf_file| is the input file that we are translating into \.{PXL} format, to be written on |pxl_file|. We also declare here the array used to hold the name of |gf_file| and |pxl_file|. @<Glob...@>= @!gf_file:byte_file; {the stuff we are \.{GFtoPXL}ing} @!gf_name: UNIX_file_name; @!pxl_file:byte_file; {the stuff we have \.{GFtoPXL}ed} @!pxl_name: UNIX_file_name; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [26] We use a new routine to open binary files, redefine the existing % opens in terms of the new routines. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ To prepare the |gf_file| for input, we |reset| it. @p procedure open_gf_file; {prepares to read packed bytes in |gf_file|} begin reset(gf_file); cur_loc:=0; end; @y @ To prepare the |gf_file| for input, we use an external library routine that is coupled to the byte input and output library routines. Procedure |b_set_ptr| makes the library know about |cur_loc| so it will be kept in sync with the byte offset for that file. @d NO_path_searching == 0 @p procedure open_gf_file; {prepares to read packed bytes in |gf_file|} begin if not b_open_in(gf_file, gf_name, NO_path_searching) then@/ abort('Unable to open GF file for input'); b_set_ptr(gf_file, cur_loc);@/ cur_loc:=0; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [27] Redefine open_pxl_file to use b_open_out %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ To prepare the |pxl_file| for output, we |rewrite| it. @p procedure open_pxl_file; {prepares to write packed bytes in |pxl_file|} begin rewrite(pxl_file); end; @y @ To prepare the |pxl_file| for output, we call our friendly library again. @p procedure open_pxl_file; {prepares to write packed bytes in |pxl_file|} var @!name_len: integer; @!i,j,k: integer; @!started_number: boolean; begin@/ if not pxl_name_ready then @<Construct |pxl_name| from |gf_name| and |magnification|@>@/ if not b_open_out(pxl_file, pxl_name) then begin name_len := 1; while (name_len < file_name_size) and (not (pxl_name[name_len] = ' ')) do@/ name_len := name_len + 1; abort('Unable to open ', pxl_name:name_len, ' for output'); end;@/ b_set_ptr(pxl_file, pxl_byte_no); end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [29] Use modified routines to access gf_file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ We shall use a set of simple functions to read the next byte or bytes from |gf_file|. There are seven possibilities, each of which is treated as a separate function in order to minimize the overhead for subroutine calls. @^system dependencies@> @p function get_byte:integer; {returns the next byte, unsigned} var b:eight_bits; begin if eof(gf_file) then get_byte:=0 else begin read(gf_file,b); incr(cur_loc); get_byte:=b; end; end; @# function signed_byte:integer; {returns the next byte, signed} var b:eight_bits; begin read(gf_file,b); incr(cur_loc); if b<128 then signed_byte:=b @+ else signed_byte:=b-256; end; @# function get_two_bytes:integer; {returns the next two bytes, unsigned} var a,@!b:eight_bits; begin read(gf_file,a); read(gf_file,b); cur_loc:=cur_loc+2; get_two_bytes:=a*256+b; end; @# function signed_pair:integer; {returns the next two bytes, signed} var a,@!b:eight_bits; begin read(gf_file,a); read(gf_file,b); cur_loc:=cur_loc+2; if a<128 then signed_pair:=a*256+b else signed_pair:=(a-256)*256+b; end; @# function get_three_bytes:integer; {returns the next three bytes, unsigned} var a,@!b,@!c:eight_bits; begin read(gf_file,a); read(gf_file,b); read(gf_file,c); cur_loc:=cur_loc+3; get_three_bytes:=(a*256+b)*256+c; end; @# function signed_trio:integer; {returns the next three bytes, signed} var a,@!b,@!c:eight_bits; begin read(gf_file,a); read(gf_file,b); read(gf_file,c); cur_loc:=cur_loc+3; if a<128 then signed_trio:=(a*256+b)*256+c else signed_trio:=((a-256)*256+b)*256+c; end; @# function signed_quad:integer; {returns the next four bytes, signed} var a,@!b,@!c,@!d:eight_bits; begin read(gf_file,a); read(gf_file,b); read(gf_file,c); read(gf_file,d); cur_loc:=cur_loc+4; if a<128 then signed_quad:=((a*256+b)*256+c)*256+d else signed_quad:=(((a-256)*256+b)*256+c)*256+d; end; @y @ We shall use a set of simple functions to read the next byte or bytes from |gf_file|. There are seven possibilities, each of which is treated as a separate function in order to minimize the overhead for subroutine calls. We use an external C routines in the {\mc UNIX} version to read from |gf_file| because we need random access to that file, and for efficiency, neither of which is available from the standard Berkeley Pascal run-time library. @^system dependencies@> @d get_byte == b_read_unsigned(gf_file) @d signed_byte == b_read_signed(gf_file) @d get_two_bytes == b_read_2_unsigned(gf_file) @d signed_pair == b_read_2_signed(gf_file) @d get_three_bytes == b_read_3_unsigned(gf_file) @d signed_trio == b_read_3_signed(gf_file) @d signed_quad == b_read_4_signed(gf_file) @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [30] change pxl_byte from macro to procedure that calls b_write_byte %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ Most info in the |pxl_file| comes in words, but we have to write it as bytes and halfwords occasionally. @d pxl_byte(#)==begin write(pxl_file,#); incr(pxl_byte_no); end @p procedure pxl_halfword(@!w:integer); begin if w<0 then w:=w+@"10000; pxl_byte(w div @"100); pxl_byte(w mod @"100); end; @# procedure pxl_word(@!w:integer); begin if w>0 then pxl_byte(w div @"1000000) else begin w:=w+@"40000000; w:=w+@"40000000; pxl_byte((w div @"1000000) + 128); end; pxl_byte((w div @"10000) mod @"100); pxl_byte((w div @"100) mod @"100); pxl_byte(w mod @"100); end; @y @ Most info in the |pxl_file| comes in words, but we have to write it as bytes and halfwords occasionally. For Berkeley {\mc UNIX}, we changed these routines into external C routines. @d pxl_byte(#) == b_write_byte(pxl_file, #) @d pxl_halfword(#) == b_write_2_bytes(pxl_file, #) @d pxl_word(#) == b_write_4_bytes(pxl_file, #) @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [31] change gf_length and move_to_byte to match C routines %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x Such routines are, of course, highly system dependent. They are implemented here in terms of two assumed system routines called |set_pos| and |cur_pos|. The call |set_pos(f,n)| moves to item |n| in file |f|, unless |n| is negative or larger than the total number of items in |f|; in the latter case, |set_pos(f,n)| moves to the end of file |f|. The call |cur_pos(f)| gives the total number of items in |f|, if |eof(f)| is true; we use |cur_pos| only in such a situation. @p function gf_length:integer; begin set_pos(gf_file,-1); gf_length:=cur_pos(gf_file); end; @# procedure move_to_byte(n:integer); begin set_pos(gf_file,n); cur_loc:=n; end; @y Such routines are, of course, highly system dependent. They are implemented here in terms of two external C routines called |b_seek| and |b_file_len|, which work together with external routines |b_read_byte| and company. The call |b_seek(f,n)| moves to byte |n| in file |f|, unless |n| is larger than the total number of items in |f|; in the latter case, |b_seek(f,n)| moves to the end of file |f|. The call |b_file_len(f)| gives the total number of bytes in |f|, assuming that |f| has been opened via |b_open|. @d gf_length == b_file_len(gf_file) @d move_to_byte(#) == b_seek(gf_file, #) @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [43] change eof(gf_file) tests to b_eof(gf_file) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x if eof(gf_file) then bad_gf('the file ended prematurely'); @y if b_eof(gf_file) then bad_gf('the file ended prematurely'); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [55] change eof(gf_file) tests to b_eof(gf_file) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x while (m=223)and not eof(gf_file) do m:=get_byte; if not eof(gf_file) then bad_gf('signature in byte ',cur_loc-1:1, @y while (m=223)and not b_eof(gf_file) do m:=get_byte; if not b_eof(gf_file) then bad_gf('signature in byte ',cur_loc-1:1, @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [67] print <nl> after final summary %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x if total_chars<>1 then print('s'); print(' altogether'); @y if total_chars<>1 then print('s'); print_ln(' altogether'); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [70] flush output when announcing completion of a character %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @.char ended unexpectedly@> print(']'); incr(total_chars); @y @.char ended unexpectedly@> print(']'); update_terminal; incr(total_chars); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [71] change eof(gf_file) to b_eof(gf_file) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x if eof(gf_file) then bad_gf('the file ended prematurely'); @y if b_eof(gf_file) then bad_gf('the file ended prematurely'); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [72] flush output after announcing new character %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x min_m:=signed_quad; max_m:=signed_quad; min_n:=signed_quad; max_n:=signed_quad; end; print('[',char_code:1); if char_code>max_glyph_no then abort('Character number too large'); @y min_m:=signed_quad; max_m:=signed_quad; min_n:=signed_quad; max_n:=signed_quad; end; print('[',char_code:1); update_terminal; if char_code>max_glyph_no then abort('Character number too large'); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [73-77] add system dependent sections: parsing command line arguments % and generating output file name %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @* System-dependent changes. This section should be replaced, if necessary, by changes to the program that are necessary to make \.{GFtoPXL} work at a particular installation. It is usually best to design your change file so that all changes to previous sections preserve the section numbering; then everybody's version will be consistent with the printed program. More extensive changes, which introduce new sections, can be inserted here; then only the index itself will get a new section number. @^system dependencies@> @y @* System-dependent changes. This section contains changes to the program that are necessary to make \.{GFtoPXL} work under Berkeley {\mc UNIX} and aren't modifications of existing sections. @^system dependencies@> @ We defined back in |initialize| a section for parsing the command line. Under {\mc UNIX} we provide the names of the input and output files on the command we issue to start \.{GFtoPXL}. The output file name is optional, and if omitted, is constructed by taking the first part of the GF file name (up to the first ``.'') and appending the appropriate magnification and the letters ``pxl''. (See routine |open_pxl_file|). @^system dependencies@> @<Parse command ...@>= if (argc < 2) or (argc > 3) then begin write_ln('Usage: gftopxl GFfile [PXLfile]');@/ goto final_end; {we will allow this unstructure once} end; argv(1, gf_name); if argc > 2 then begin argv(2, pxl_name);@/ pxl_name_ready := true; end; @ We need another declaration for |pxl_name_ready|, which is true if the name of the PXL file was specified on the command line. @<Glob...@>= @!pxl_name_ready: boolean; {true if |pxl_name[]| has valid name in it} @ Also, it should be initialized at startup. @<Set init...@>= pxl_name_ready := false; @ In |open_pxl_file|, we added a section to construct the name of the output file from the name of the input file and the magnification gleaned from the input file postamble. Here it is. @<Construct |pxl_name| ...@>= begin j := file_name_size;@/ while (j > 1) and (gf_name[j] <> '/') do@/ decr(j); if (gf_name[j] = '/') then incr(j); { to avoid picking up the / } name_len := 1;@/ while (j < file_name_size) and (not (gf_name[j] = '.') or (gf_name[j] = ' ')) do begin @/ pxl_name[name_len] := gf_name[j]; incr(name_len); incr(j); end; pxl_name[name_len] := '.'; incr(name_len);@/ i := 10000;@/ j := ((round(1000*magnification)) mod i); started_number := false; while i > 0 do begin@/ k := j div i;@/ j := j mod i;@/ i := i div 10;@/ if started_number or (k > 0) or (i = 0) then begin pxl_name[name_len] := chr( ord('0') + k); incr(name_len);@/ started_number := true; end; end; pxl_name[name_len] := 'p'; incr(name_len); @/ pxl_name[name_len] := 'x'; incr(name_len); @/ pxl_name[name_len] := 'l'; incr(name_len); @/ pxl_name[name_len] := ' '; @/ write_ln('[Output file named ''', pxl_name:name_len-1, ''']'); end; @z