{$A-,B-,D-,E-,F-,I+,L-,N-,O-,R-,S-,V-} {Compile with Turbo-Pascal 5.0} Program JIS2MF(Input,Output); { This program generates METAFONT code from a Bitmaps file JIS24 Author: Francois Jalbert ' Date: November 1990 Version: 1.0 Date: April 1991 Version: 2.00 Modifications: - Added four kanjis. - Fixed incorrect VGA resolution. - Command line parameter now supported. - Added automatic mode. - Added batch mode. - Updated and improved run-time messages. - Long triangles added by Mr. Masatoshi Watanabe. Fantastic! - Fixed and proportional parameters added. - Standard and dictionary parameters added. - JIS24 now accessed through low-level I/O channel for speed. Error Levels: 0 - Normal termination. 1 - Error. 2 - All fonts generated (batch). } Const {Number of Bitmaps in JIS24} BitmapMax=7806; {Size of each square Bitmap} SizeMax=24; SizeMax1=25; {DOS Record Size} RecSize=72; {SizeMax*SizeMax/8} {Parameter flag} Flag1='/'; {DOS style} Flag2='-'; {UNIX style} {Parameter keywords} FixedX1:String[10]='FIXEDWIDTH'; FixedX2:String[6]='FIXEDX'; FixedX3:String[19]='NOPROPORTIONALWIDTH'; FixedX4:String[15]='NOPROPORTIONALX'; NoFixedX1:String[12]='NOFIXEDWIDTH'; NoFixedX2:String[8]='NOFIXEDX'; NoFixedX3:String[17]='PROPORTIONALWIDTH'; NoFixedX4:String[13]='PROPORTIONALX'; FixedY1:String[11]='FIXEDHEIGHT'; FixedY2:String[6]='FIXEDY'; FixedY3:String[20]='NOPROPORTIONALHEIGHT'; FixedY4:String[15]='NOPROPORTIONALY'; NoFixedY1:String[13]='NOFIXEDHEIGHT'; NoFixedY2:String[8]='NOFIXEDY'; NoFixedY3:String[18]='PROPORTIONALHEIGHT'; NoFixedY4:String[13]='PROPORTIONALY'; Standard1:String[8]='STANDARD'; NoStandard1:String[10]='DICTIONARY'; Batch1:String[5]='BATCH'; Type InFileType=File; {Low-level I/O channel} OutFileType=Text; BitmapRange=1..BitmapMax; Bitmap0Range=0..BitmapMax; SizeRange=1..SizeMax; Size0Range=0..SizeMax1; {Buffer for the Bitmap Data} ColumnType=Record Data1,Data2,Data3:Byte End; BufferType=Array [SizeRange] Of ColumnType; {The Bitmap array is defined larger to simplify the forthcoming code} BitmapType=Array [Size0Range,Size0Range] Of Boolean; BitmapsType=Record Bitmap:BitmapType; XMin,XMax,YMin,YMax:Size0Range End; {Run time parameters} RunTimeType=Record FileName:String; {Batch mode} Batch:Boolean; {Automatic mode for JemTeX fonts only} Automatic:Boolean; {Fixed or proportional fonts} FixedX,FixedY:Boolean; {Standard or dictionary fonts} Standard:Boolean End; Var {JIS24 and METAFONT file names} InFile:InFileType; OutFile:OutFileType; {Current METAFONT character number} Number:Integer; {Run time parameters} RunTime:RunTimeType; {-------------------------------- GetParameters ------------------------------} Procedure SimpleQuery(Title,ChoiceA,ChoiceB:String; Var Answer:Boolean); Var JChar:Char; Valid:Boolean; Begin Repeat Valid:=True; Writeln(Title+':'); Writeln(' a) '+ChoiceA); Writeln(' b) '+ChoiceB); Write('Your choice? '); Readln(JChar); JChar:=UpCase(JChar); If JChar='A' Then Answer:=True Else If JChar='B' Then Answer:=False Else Begin Valid:=False; Write(Chr(7)) End Until Valid; Writeln End; Procedure GetMode(Var RunTime:RunTimeType); {Determines if the desired font is a JemTeX font} Begin With RunTime Do Begin Automatic:=False; If UpCase(FileName[1])='K' Then If UpCase(FileName[2])='A' Then If UpCase(FileName[3])='N' Then If UpCase(FileName[4])='J' Then If UpCase(FileName[5])='I' Then If ('A'<=UpCase(FileName[6])) And (UpCase(FileName[6])<='H') Then If ('A'<=UpCase(FileName[7])) And (UpCase(FileName[7])<='H') Then If Length(FileName)=7 Then If UpCase(FileName[6])<='G' Then Automatic:=True Else If UpCase(FileName[7])<='E' Then Automatic:=True End End; Procedure EchoParameters(Var RunTime:RunTimeType); {Echoes the current parameters} Begin With RunTime Do Begin Write('Font='+FileName); If FixedX Then Write(' Fixed Width') Else Write(' Prop. Width'); If FixedY Then Write(' Fixed Height') Else Write(' Prop. Height'); If Standard Then Write(' Standard') Else Write(' Dictionary'); If Automatic Then Write(' Automatic') Else Write(' Manual'); If Batch Then Write(' Batch'); Writeln('.') End End; Procedure Manual(Var RunTime:RunTimeType); {Get parameters from user} Begin With RunTime Do Begin Write('METAFONT file name? '); Readln(FileName); Writeln; SimpleQuery('Fixed or proportional font width','Fixed','Proportional',FixedX); SimpleQuery('Fixed or proportional font height','Fixed','Proportional',FixedY); SimpleQuery('Standard or dictionary font','Standard','Dictionary',Standard); {Batch mode intrinsically isn't manual} Batch:=False End End; Procedure FindBefore(Var FileName:String); {No check for before kanjiaa} Begin If FileName[7]='a' Then Begin FileName[7]:='h'; FileName[6]:=Pred(FileName[6]) End Else FileName[7]:=Pred(FileName[7]) End; Procedure FindAfter(Var FileName:String); {No check for above kanjihe} Begin If FileName[7]='h' Then Begin FileName[7]:='a'; FileName[6]:=Succ(FileName[6]) End Else FileName[7]:=Succ(FileName[7]) End; Procedure ScanMF(Var FileName:String); {Scans backwards for the last JemTeX font generated} {Looks first for a .TFM and then for an .MF} {If no more fonts to generate, stops with error level 2} Var TestFile:Text; Found:Boolean; Begin FileName:='kanjihf'; Repeat FindBefore(FileName); Assign(TestFile,FileName+'.tfm'); {$I-}Reset(TestFile);{$I+} {IOResult must be immediately used once only} Found:=(IOResult=0); If Not Found Then Begin Assign(TestFile,FileName+'.mf'); {$I-}Reset(TestFile);{$I+} {IOResult must be immediately used once only} Found:=(IOResult=0) End; Until Found Or (FileName='kanjiaa'); If Found Then Begin Close(TestFile); If FileName='kanjihe' Then Begin Writeln(Chr(7)+'All JemTeX fonts generated!'); Halt(2) End Else FindAfter(FileName) End End; Procedure Automate(Var RunTime:RunTimeType); {Get parameters from command line} {Finds the next font to be generated if in batch mode} Var ParamIndex,Index:Integer; Param:String; Begin With RunTime Do Begin {Defaults} FileName:='kanjiaa'; FixedX:=False; FixedY:=False; Standard:=True; Batch:=False; {Scan command line parameters} For ParamIndex:=1 To ParamCount Do Begin Param:=ParamStr(ParamIndex); If (Param[1]=Flag1) Or (Param[1]=Flag2) Then {Not a font name} Begin {Delete 1 char at the 1st position} Delete(Param,1,1); {Convert to upper case} For Index:=1 To Length(Param) Do Param[Index]:=UpCase(Param[Index]); {Scan known keywords} If (Param=FixedX1) Or (Param=FixedX2) Or (Param=FixedX3) Or (Param=FixedX4) Then FixedX:=True Else If (Param=NoFixedX1) Or (Param=NoFixedX2) Or (Param=NoFixedX3) Or (Param=NoFixedX4) Then FixedX:=False Else If (Param=FixedY1) Or (Param=FixedY2) Or (Param=FixedY3) Or (Param=FixedY4) Then FixedY:=True Else If (Param=NoFixedY1) Or (Param=NoFixedY2) Or (Param=NoFixedY3) Or (Param=NoFixedY4) Then FixedY:=False Else If Param=Standard1 Then Standard:=True Else If Param=NoStandard1 Then Standard:=False Else If Param=Batch1 Then Batch:=True Else {Unknown keyword} Begin Writeln(Chr(7)+'Invalid command line parameter: '+Param+'...'); Halt(1) End End Else {Must be a font name} FileName:=Param End; If Batch Then ScanMF(FileName) End End; Procedure GetParameters(Var RunTime:RunTimeType); {Get parameters from user or command line} Begin If ParamCount=0 Then Manual(RunTime) Else Automate(RunTime); GetMode(RunTime); EchoParameters(RunTime); Writeln End; {----------------------------------- Output ----------------------------------} Procedure BeginOut(Var OutFile:OutFileType; Var RunTime:RunTimeType); {Writes initial METAFONT header} {Co-author is Mr. Masatoshi Watanabe} Begin Writeln(OutFile,'%JIS2MF Version 2.00 of 14 April 1991.'); Writeln(OutFile); Writeln(OutFile,'% Font='+RunTime.FileName); If RunTime.FixedX Then Writeln(OutFile,'% Fixed Width') Else Writeln(OutFile,'% Proportional Width'); If RunTime.FixedY Then Writeln(OutFile,'% Fixed Height') Else Writeln(OutFile,'% Proportional Height'); If RunTime.Standard Then Writeln(OutFile,'% Standard Positioning') Else Writeln(OutFile,'% Dictionary Positioning'); Writeln(OutFile); Writeln(OutFile,'tracingstats:=1;'); Writeln(OutFile,'screen_cols:=640; %VGA'); Writeln(OutFile,'screen_rows:=480; %VGA'); Writeln(OutFile,'font_size 10pt#;'); If RunTime.Standard Then Begin Writeln(OutFile,'u#:=12.7/36pt#;'); Writeln(OutFile,'body_height#:=23.25u#;'); Writeln(OutFile,'desc_depth#:=4.75u#;') End Else Begin Writeln(OutFile,'u#:=13/36pt#;'); Writeln(OutFile,'body_height#:=21u#;'); Writeln(OutFile,'desc_depth#:=7u#;') End; Writeln(OutFile); Writeln(OutFile,'letter_fit#:=0pt#;'); Writeln(OutFile,'asc_height#:=0pt#;'); Writeln(OutFile,'cap_height#:=0pt#;'); Writeln(OutFile,'fig_height#:=0pt#;'); Writeln(OutFile,'x_height#:=0pt#;'); Writeln(OutFile,'math_axis#:=0pt#;'); Writeln(OutFile,'bar_height#:=0pt#;'); Writeln(OutFile,'comma_depth#:=0pt#;'); Writeln(OutFile,'crisp#:=0pt#;'); Writeln(OutFile,'tiny#:=0pt#;'); Writeln(OutFile,'fine#:=0pt#;'); Writeln(OutFile,'thin_join#:=0pt#;'); Writeln(OutFile,'hair#:=1pt#;'); Writeln(OutFile,'stem#:=1pt#;'); Writeln(OutFile,'curve#:=1pt#;'); Writeln(OutFile,'flare#:=1pt#;'); Writeln(OutFile,'dot_size#:=0pt#;'); Writeln(OutFile,'cap_hair#:=1pt#;'); Writeln(OutFile,'cap_stem#:=1pt#;'); Writeln(OutFile,'cap_curve#:=1pt#;'); Writeln(OutFile,'rule_thickness#:=0pt#;'); Writeln(OutFile,'vair#:=0pt#;'); Writeln(OutFile,'notch_cut#:=0pt#;'); Writeln(OutFile,'bar#:=1pt#;'); Writeln(OutFile,'slab#:=1pt#;'); Writeln(OutFile,'cap_bar#:=1pt#;'); Writeln(OutFile,'cap_band#:=1pt#;'); Writeln(OutFile,'cap_notch_cut#:=0pt#;'); Writeln(OutFile,'serif_drop#:=0pt#;'); Writeln(OutFile,'stem_corr#:=0pt#;'); Writeln(OutFile,'vair_corr#:=0pt#;'); Writeln(OutFile,'o#:=0pt#;'); Writeln(OutFile,'apex_o#:=0pt#;'); Writeln(OutFile,'hefty:=true;'); Writeln(OutFile,'serifs:=true;'); Writeln(OutFile,'monospace:=false;'); Writeln(OutFile,'math_fitting:=false;'); Writeln(OutFile); Writeln(OutFile,'mode_setup;'); Writeln(OutFile,'font_setup;'); Writeln(OutFile); Writeln(OutFile,'pair z;'); Writeln(OutFile); Writeln(OutFile,'def s(expr col,row)= %square'); Writeln(OutFile,' z:=((col*u),(row*u));'); Writeln(OutFile,' fill unitsquare scaled u shifted z;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def sul(expr col,row)= %upper left square'); Writeln(OutFile,' z:=((col*u),(row*u)+.5u);'); Writeln(OutFile,' fill unitsquare scaled .5u shifted z;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def sur(expr col,row)= %upper right square'); Writeln(OutFile,' z:=((col*u)+.5u,(row*u)+.5u);'); Writeln(OutFile,' fill unitsquare scaled .5u shifted z;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def sbr(expr col,row)= %bottom right square'); Writeln(OutFile,' z:=((col*u)+.5u,(row*u));'); Writeln(OutFile,' fill unitsquare scaled .5u shifted z;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def sbl(expr col,row)= %bottom left square'); Writeln(OutFile,' z:=((col*u),(row*u));'); Writeln(OutFile,' fill unitsquare scaled .5u shifted z;'); Writeln(OutFile,'enddef;'); Writeln(OutFile); Writeln(OutFile,'def c(expr col,row)= %circle'); Writeln(OutFile,' z:=((col*u)+.5u,(row*u)+.5u);'); Writeln(OutFile,' fill fullcircle scaled u shifted z;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def cul(expr col,row)= %upper left circle'); Writeln(OutFile,' z:=((col*u)+.5u,(row*u)+.5u);'); Writeln(OutFile,' fill z--quartercircle rotated 90 scaled u shifted z--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def cur(expr col,row)= %upper right circle'); Writeln(OutFile,' z:=((col*u)+.5u,(row*u)+.5u);'); Writeln(OutFile,' fill z--quartercircle scaled u shifted z--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def cbr(expr col,row)= %bottom right circle'); Writeln(OutFile,' z:=((col*u)+.5u,(row*u)+.5u);'); Writeln(OutFile,' fill z--quartercircle rotated 270 scaled u shifted z--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def cbl(expr col,row)= %bottom left circle'); Writeln(OutFile,' z:=((col*u)+.5u,(row*u)+.5u);'); Writeln(OutFile,' fill z--quartercircle rotated 180 scaled u shifted z--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile); Writeln(OutFile,'def tul(expr col,row)= %upper left triangle'); Writeln(OutFile,' z:=((col*u)+.5u,(row*u)+.5u);'); Writeln(OutFile,' fill z--z+(0,.5u)--z-(.5u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def tur(expr col,row)= %upper right triangle'); Writeln(OutFile,' z:=((col*u)+.5u,(row*u)+.5u);'); Writeln(OutFile,' fill z--z+(0,.5u)--z+(.5u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def tbr(expr col,row)= %bottom right triangle'); Writeln(OutFile,' z:=((col*u)+.5u,(row*u)+.5u);'); Writeln(OutFile,' fill z--z-(0,.5u)--z+(.5u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def tbl(expr col,row)= %bottom left triangle'); Writeln(OutFile,' z:=((col*u)+.5u,(row*u)+.5u);'); Writeln(OutFile,' fill z--z-(0,.5u)--z-(.5u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile); Writeln(OutFile,'def rul(expr col,row)= %upper left reverse triangle'); Writeln(OutFile,' z:=((col*u),(row*u)+u);'); Writeln(OutFile,' fill z--z-(0,.5u)--z+(.5u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def rur(expr col,row)= %upper right reverse triangle'); Writeln(OutFile,' z:=((col*u)+u,(row*u)+u);'); Writeln(OutFile,' fill z--z-(0,.5u)--z-(.5u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def rbr(expr col,row)= %bottom right reverse triangle'); Writeln(OutFile,' z:=((col*u)+u,(row*u));'); Writeln(OutFile,' fill z--z+(0,.5u)--z-(.5u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def rbl(expr col,row)= %bottom left reverse triangle'); Writeln(OutFile,' z:=((col*u),(row*u));'); Writeln(OutFile,' fill z--z+(0,.5u)--z+(.5u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile); Writeln(OutFile,'def tuul(expr col,row)= %upper left long triangle'); Writeln(OutFile,' z:=((col*u)+u,(row*u)+.5u);'); Writeln(OutFile,' fill z--z+(0,.5u)--z-(u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def tull(expr col,row)= %upper left long triangle'); Writeln(OutFile,' z:=((col*u)+.5u,(row*u));'); Writeln(OutFile,' fill z--z+(0,u)--z-(.5u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def tuur(expr col,row)= %upper right long triangle'); Writeln(OutFile,' z:=((col*u),(row*u)+.5u);'); Writeln(OutFile,' fill z--z+(0,.5u)--z+(u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def turr(expr col,row)= %upper right long triangle'); Writeln(OutFile,' z:=((col*u)+.5u,(row*u));'); Writeln(OutFile,' fill z--z+(0,u)--z+(.5u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def tbbr(expr col,row)= %bottom right long triangle'); Writeln(OutFile,' z:=((col*u),(row*u)+.5u);'); Writeln(OutFile,' fill z--z-(0,.5u)--z+(u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def tbrr(expr col,row)= %bottom right long triangle'); Writeln(OutFile,' z:=((col*u)+.5u,(row*u)+u);'); Writeln(OutFile,' fill z--z-(0,u)--z+(.5u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def tbbl(expr col,row)= %bottom left long triangle'); Writeln(OutFile,' z:=((col*u)+u,(row*u)+.5u);'); Writeln(OutFile,' fill z--z-(0,.5u)--z-(u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def tbll(expr col,row)= %bottom left long triangle'); Writeln(OutFile,' z:=((col*u)+.5u,(row*u)+u);'); Writeln(OutFile,' fill z--z-(0,u)--z-(.5u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile); Writeln(OutFile,'def ruul(expr col,row)= %upper left reverse long triangle'); Writeln(OutFile,' z:=((col*u),(row*u)+u);'); Writeln(OutFile,' fill z--z-(0,u)--z+(.5u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def rull(expr col,row)= %upper left reverse long triangle'); Writeln(OutFile,' z:=((col*u),(row*u)+u);'); Writeln(OutFile,' fill z--z-(0,.5u)--z+(u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def ruur(expr col,row)= %upper right reverse long triangle'); Writeln(OutFile,' z:=((col*u)+u,(row*u)+u);'); Writeln(OutFile,' fill z--z-(0,u)--z-(.5u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def rurr(expr col,row)= %upper right reverse long triangle'); Writeln(OutFile,' z:=((col*u)+u,(row*u)+u);'); Writeln(OutFile,' fill z--z-(0,.5u)--z-(u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def rbbr(expr col,row)= %bottom right reverse long triangle'); Writeln(OutFile,' z:=((col*u)+u,(row*u));'); Writeln(OutFile,' fill z--z+(0,u)--z-(.5u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def rbrr(expr col,row)= %bottom right reverse long triangle'); Writeln(OutFile,' z:=((col*u)+u,(row*u));'); Writeln(OutFile,' fill z--z+(0,.5u)--z-(u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def rbbl(expr col,row)= %bottom left reverse long triangle'); Writeln(OutFile,' z:=((col*u),(row*u));'); Writeln(OutFile,' fill z--z+(0,u)--z+(.5u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile,'def rbll(expr col,row)= %bottom left reverse long triangle'); Writeln(OutFile,' z:=((col*u),(row*u));'); Writeln(OutFile,' fill z--z+(0,.5u)--z+(u,0)--cycle;'); Writeln(OutFile,'enddef;'); Writeln(OutFile) End; Procedure ActiveBitmap(Var OutFile:OutFileType; Var Bitmap:BitmapType; X,Y:SizeRange; XX:Integer; YY:Real); {Writes METAFONT code for an active cell} {Co-author is Mr. Masatoshi Watanabe} Var SquareUR,SquareUL,SquareBR,SquareBL:Boolean; CircleUR,CircleUL,CircleBR,CircleBL:Boolean; LTryUUR,LTryURR,LTryUUL,LTryULL:Boolean; LTryBBR,LTryBRR,LTryBBL,LTryBLL:Boolean; Begin SquareUL:=(Bitmap[X-1,Y] Or Bitmap[X-1,Y+1] Or Bitmap[X,Y+1]); SquareUR:=(Bitmap[X+1,Y] Or Bitmap[X+1,Y+1] Or Bitmap[X,Y+1]); SquareBL:=(Bitmap[X-1,Y] Or Bitmap[X-1,Y-1] Or Bitmap[X,Y-1]); SquareBR:=(Bitmap[X+1,Y] Or Bitmap[X+1,Y-1] Or Bitmap[X,Y-1]); CircleUL:=(Not Bitmap[X-1,Y-1] And Not Bitmap[X-1,Y] And Not Bitmap[X-1,Y+1] And Not Bitmap[X,Y+1] And Not Bitmap[X+1,Y+1]); CircleUR:=(Not Bitmap[X+1,Y-1] And Not Bitmap[X+1,Y] And Not Bitmap[X+1,Y+1] And Not Bitmap[X,Y+1] And Not Bitmap[X-1,Y+1]); CircleBL:=(Not Bitmap[X-1,Y+1] And Not Bitmap[X-1,Y] And Not Bitmap[X-1,Y-1] And Not Bitmap[X,Y-1] And Not Bitmap[X+1,Y-1]); CircleBR:=(Not Bitmap[X+1,Y+1] And Not Bitmap[X+1,Y] And Not Bitmap[X+1,Y-1] And Not Bitmap[X,Y-1] And Not Bitmap[X-1,Y-1]); LTryUUL:=(Bitmap[X-1,Y-1] And Not Bitmap[X-1,Y] And Not Bitmap[X-1,Y+1] And Not Bitmap[X,Y+1] And Not Bitmap[X+1,Y+1] And Bitmap[X+1,Y]); LTryUUR:=(Bitmap[X+1,Y-1] And Not Bitmap[X+1,Y] And Not Bitmap[X+1,Y+1] And Not Bitmap[X,Y+1] And Not Bitmap[X-1,Y+1] And Bitmap[X-1,Y]); LTryBBL:=(Bitmap[X-1,Y+1] And Not Bitmap[X-1,Y] And Not Bitmap[X-1,Y-1] And Not Bitmap[X,Y-1] And Not Bitmap[X+1,Y-1] And Bitmap[X+1,Y]); LTryBBR:=(Bitmap[X+1,Y+1] And Not Bitmap[X+1,Y] And Not Bitmap[X+1,Y-1] And Not Bitmap[X,Y-1] And Not Bitmap[X-1,Y-1] And Bitmap[X-1,Y]); LTryULL:=(Not Bitmap[X-1,Y-1] And Not Bitmap[X-1,Y] And Not Bitmap[X-1,Y+1] And Not Bitmap[X,Y+1] And Bitmap[X+1,Y+1] And Bitmap[X,Y-1]); LTryURR:=(Not Bitmap[X+1,Y-1] And Not Bitmap[X+1,Y] And Not Bitmap[X+1,Y+1] And Not Bitmap[X,Y+1] And Bitmap[X-1,Y+1] And Bitmap[X,Y-1]); LTryBLL:=(Not Bitmap[X-1,Y+1] And Not Bitmap[X-1,Y] And Not Bitmap[X-1,Y-1] And Not Bitmap[X,Y-1] And Bitmap[X+1,Y-1] And Bitmap[X,Y+1]); LTryBRR:=(Not Bitmap[X+1,Y+1] And Not Bitmap[X+1,Y] And Not Bitmap[X+1,Y-1] And Not Bitmap[X,Y-1] And Bitmap[X-1,Y-1] And Bitmap[X,Y+1]); If LTryUUL Then Write(OutFile,'tuul(',XX,',',YY:4:2,');'); If LTryULL Then Write(OutFile,'tull(',XX,',',YY:4:2,');'); If LTryUUR Then Write(OutFile,'tuur(',XX,',',YY:4:2,');'); If LTryURR Then Write(OutFile,'turr(',XX,',',YY:4:2,');'); If LTryBBL Then Write(OutFile,'tbbl(',XX,',',YY:4:2,');'); If LTryBLL Then Write(OutFile,'tbll(',XX,',',YY:4:2,');'); If LTryBBR Then Write(OutFile,'tbbr(',XX,',',YY:4:2,');'); If LTryBRR Then Write(OutFile,'tbrr(',XX,',',YY:4:2,');'); If SquareUL And SquareUR And SquareBL And SquareBR Then Write(OutFile,'s(',XX,',',YY:4:2,');') Else If CircleUL And CircleUR And CircleBL And CircleBR Then Write(OutFile,'c(',XX,',',YY:4:2,');') Else Begin If Not LTryUUL And Not LTryULL And Not LTryUUR And Not LTryBLL Then If SquareUL Then Write(OutFile,'sul(',XX,',',YY:4:2,');') Else If CircleUL Then Write(OutFile,'cul(',XX,',',YY:4:2,');') Else Write(OutFile,'tul(',XX,',',YY:4:2,');'); If Not LTryUUL And Not LTryURR And Not LTryUUR And Not LTryBRR Then If SquareUR Then Write(OutFile,'sur(',XX,',',YY:4:2,');') Else If CircleUR Then Write(OutFile,'cur(',XX,',',YY:4:2,');') Else Write(OutFile,'tur(',XX,',',YY:4:2,');'); If Not LTryBBL And Not LTryULL And Not LTryBBR And Not LTryBLL Then If SquareBL Then Write(OutFile,'sbl(',XX,',',YY:4:2,');') Else If CircleBL Then Write(OutFile,'cbl(',XX,',',YY:4:2,');') Else Write(OutFile,'tbl(',XX,',',YY:4:2,');'); If Not LTryBBL And Not LTryURR And Not LTryBBR And Not LTryBRR Then If SquareBR Then Write(OutFile,'sbr(',XX,',',YY:4:2,');') Else If CircleBR Then Write(OutFile,'cbr(',XX,',',YY:4:2,');') Else Write(OutFile,'tbr(',XX,',',YY:4:2,');') End End; Procedure InactiveBitmap(Var OutFile:OutFileType; Var Bitmap:BitmapType; X,Y:SizeRange; XX:Integer; YY:Real; Var Active:Boolean); {Writes METAFONT code for an inactive cell} {Co-author is Mr. Masatoshi Watanabe} Begin If Bitmap[X-1,Y] And Bitmap[X,Y+1] Then If Bitmap[X-1,Y-1] And Not Bitmap[X+1,Y+1] Then Begin Active:=True; Write(OutFile,'ruul(',XX,',',YY:4:2,');') End Else If Bitmap[X+1,Y+1] And Not Bitmap[X-1,Y-1] Then Begin Active:=True; Write(OutFile,'rull(',XX,',',YY:4:2,');') End Else Begin Active:=True; Write(OutFile,'rul(',XX,',',YY:4:2,');') End; If Bitmap[X+1,Y] And Bitmap[X,Y+1] Then If Bitmap[X+1,Y-1] And Not Bitmap[X-1,Y+1] Then Begin Active:=True; Write(OutFile,'ruur(',XX,',',YY:4:2,');') End Else If Bitmap[X-1,Y+1] And Not Bitmap[X+1,Y-1] Then Begin Active:=True; Write(OutFile,'rurr(',XX,',',YY:4:2,');') End Else Begin Active:=True; Write(OutFile,'rur(',XX,',',YY:4:2,');') End; If Bitmap[X-1,Y] And Bitmap[X,Y-1] Then If Bitmap[X-1,Y+1] And Not Bitmap[X+1,Y-1] Then Begin Active:=True; Write(OutFile,'rbbl(',XX,',',YY:4:2,');') End Else If Bitmap[X+1,Y-1] And Not Bitmap[X-1,Y+1] Then Begin Active:=True; Write(OutFile,'rbll(',XX,',',YY:4:2,');') End Else Begin Active:=True; Write(OutFile,'rbl(',XX,',',YY:4:2,');') End; If Bitmap[X+1,Y] And Bitmap[X,Y-1] Then If Bitmap[X+1,Y+1] And Not Bitmap[X-1,Y-1] Then Begin Active:=True; Write(OutFile,'rbbr(',XX,',',YY:4:2,');') End Else If Bitmap[X-1,Y-1] And Not Bitmap[X+1,Y+1] Then Begin Active:=True; Write(OutFile,'rbrr(',XX,',',YY:4:2,');') End Else Begin Active:=True; Write(OutFile,'rbr(',XX,',',YY:4:2,');') End End; Procedure MiddleOut(Var OutFile:OutFileType; Var Bitmaps:BitmapsType; Number:Integer; Standard:Boolean); {Writes METAFONT code for a given Bitmap} Var X,Y:SizeRange; Active:Boolean; Begin With Bitmaps Do Begin Write(OutFile,'beginchar(',Number,',',XMax-XMin+1,'u#,'); If Standard Then Begin If YMax>0.75 Then Write(OutFile,(YMax-0.75):4:2,'u#,') Else Write(OutFile,'0,'); If 5.75>YMin Then Writeln(OutFile,(5.75-YMin):4:2,'u#);') Else Writeln(OutFile,'0);') End Else Begin If YMax>3 Then Write(OutFile,YMax-3,'u#,') Else Write(OutFile,'0,'); If 8>YMin Then Writeln(OutFile,8-YMin,'u#);') Else Writeln(OutFile,'0);') End; Writeln(OutFile,'normal_adjust_fit(2u#,2u#);'); For X:=XMin To XMax Do For Y:=1 To SizeMax Do Begin Active:=Bitmap[X,Y]; If Active Then {Current pixel is on} If Standard Then ActiveBitmap(OutFile,Bitmap,X,Y,X-XMin,Y-3.75) Else ActiveBitmap(OutFile,Bitmap,X,Y,X-XMin,Y-6) Else {Current pixel is off} If Standard Then InactiveBitmap(OutFile,Bitmap,X,Y,X-XMin,Y-3.75,Active) Else InactiveBitmap(OutFile,Bitmap,X,Y,X-XMin,Y-6,Active); {Avoid METAFONT buffer overflow} If Active Then Writeln(OutFile) End; Writeln(OutFile,'endchar;'); Writeln(OutFile) End End; Procedure EndOut(Var OutFile:OutFileType; Var RunTime:RunTimeType); {Writes final METAFONT header} Begin Writeln(OutFile,'font_identifier "'+RunTime.FileName+'";'); If RunTime.Standard Then Writeln(OutFile,'font_coding_scheme "JemTeX Standard";') Else Writeln(OutFile,'font_coding_scheme "JemTeX Dictionary";'); Writeln(OutFile,'font_slant slant;'); Writeln(OutFile,'font_normal_space 8u#;'); Writeln(OutFile,'font_normal_stretch 4u#;'); Writeln(OutFile,'font_normal_shrink 3u#;'); Writeln(OutFile,'font_x_height 24u#; %ex'); Writeln(OutFile,'font_quad 24u#; %em'); Writeln(OutFile,'font_extra_space 0u#;'); Writeln(OutFile); {Must end with CR/LF because of a bug(?) in emTeX METAFONT} Writeln(OutFile,'bye') End; {---------------------------------- Generate ---------------------------------} Procedure FindWantedBitmap(Automatic:Boolean; Var First:Boolean; Var WantedBitmap:Bitmap0Range; Var Number:Integer); {Finds the number of the next desired Bitmap either automatically or manually} {The characters 0 and 1 in the first font kanjiaa are both set to Bitmap 1} Var Valid:Boolean; Begin If Automatic Then {Find automatically} If First Then {Early in font kanjiaa} If WantedBitmap=-1 Then WantedBitmap:=1 Else Begin WantedBitmap:=1; First:=False End Else If (Number=128) Or (WantedBitmap=BitmapMax) Then WantedBitmap:=0 Else WantedBitmap:=WantedBitmap+1 Else {Find manually} Repeat Write('Bitmap number? '); Readln(WantedBitmap); Writeln; Valid:=( (0<=WantedBitmap) And (WantedBitmap<=BitmapMax) ); If Not Valid Then Writeln(Chr(7)+'Bitmap ',WantedBitmap,' out of range...') Until Valid; Writeln('Bitmap number ',WantedBitmap,'.') End; Procedure ScanBitmap(Var InFile:InFileType; Var Bitmap:BitmapType; Var Empty:Boolean); {Reads the Bitmap in a logical grid} {(0,0) is the lower left corner of the Bitmap} Label 1; Var Y:SizeRange; Buffer:BufferType; Begin {Read the Bitmap} BlockRead(InFile,Buffer,1); {Find if the Bitmap is empty} Empty:=True; For Y:=1 To SizeMax Do With Buffer[Y] Do If (Data1<>$00) Or (Data2<>$00) Or (Data3<>$00) Then Begin Empty:=False; Goto 1 End; {Update logical grid} 1:If Not Empty Then For Y:=1 To SizeMax Do With Buffer[SizeMax1-Y] Do Begin Bitmap[ 1,Y]:=((Data1 And $80)<>0); Bitmap[ 2,Y]:=((Data1 And $40)<>0); Bitmap[ 3,Y]:=((Data1 And $20)<>0); Bitmap[ 4,Y]:=((Data1 And $10)<>0); Bitmap[ 5,Y]:=((Data1 And $08)<>0); Bitmap[ 6,Y]:=((Data1 And $04)<>0); Bitmap[ 7,Y]:=((Data1 And $02)<>0); Bitmap[ 8,Y]:=((Data1 And $01)<>0); Bitmap[ 9,Y]:=((Data2 And $80)<>0); Bitmap[10,Y]:=((Data2 And $40)<>0); Bitmap[11,Y]:=((Data2 And $20)<>0); Bitmap[12,Y]:=((Data2 And $10)<>0); Bitmap[13,Y]:=((Data2 And $08)<>0); Bitmap[14,Y]:=((Data2 And $04)<>0); Bitmap[15,Y]:=((Data2 And $02)<>0); Bitmap[16,Y]:=((Data2 And $01)<>0); Bitmap[17,Y]:=((Data3 And $80)<>0); Bitmap[18,Y]:=((Data3 And $40)<>0); Bitmap[19,Y]:=((Data3 And $20)<>0); Bitmap[20,Y]:=((Data3 And $10)<>0); Bitmap[21,Y]:=((Data3 And $08)<>0); Bitmap[22,Y]:=((Data3 And $04)<>0); Bitmap[23,Y]:=((Data3 And $02)<>0); Bitmap[24,Y]:=((Data3 And $01)<>0) End End; Procedure ScanSides(Var Bitmaps:BitmapsType; FixedX,FixedY:Boolean); {Determines the minimal size of the Bitmap for proportional spacing} Var X,Y:SizeRange; Begin With Bitmaps Do Begin If FixedX Then Begin XMin:=1; XMax:=SizeMax End Else Begin XMin:=SizeMax1; For X:=SizeMax DownTo 1 Do For Y:=1 To SizeMax Do If Bitmap[X,Y] Then XMin:=X; XMax:=0; For X:=1 To SizeMax Do For Y:=1 To SizeMax Do If Bitmap[X,Y] Then XMax:=X End; If FixedY Then Begin YMin:=1; YMax:=SizeMax End Else Begin YMin:=SizeMax1; For Y:=SizeMax DownTo 1 Do For X:=1 To SizeMax Do If Bitmap[X,Y] Then YMin:=Y; YMax:=0; For Y:=1 To SizeMax Do For X:=1 To SizeMax Do If Bitmap[X,Y] Then YMax:=Y End End End; Procedure Generate(Var InFile:InFileType; Var OutFile:OutFileType; Var Number:Integer; Var RunTime:RunTimeType); {Generates the METAFONT code for the selected font} Var {Bitmap pointers} CurrentBitmap,WantedBitmap:Bitmap0Range; {Current Bitmap} Bitmaps:BitmapsType; X,Y:Size0Range; {Indicates early in font kanjiaa} First:Boolean; {Indicates current Bitmap is empty} Empty:Boolean; Begin {Clear the area outside the Bitmap once and for all} With Bitmaps Do Begin For X:=0 To SizeMax1 Do Begin Bitmap[X,0]:=False; Bitmap[X,SizeMax1]:=False End; For Y:=1 To SizeMax Do Begin Bitmap[0,Y]:=False; Bitmap[SizeMax1,Y]:=False End End; {Number of the Bitmap ready to be read} CurrentBitmap:=1; {First METAFONT character number} Number:=0; {First Bitmap wanted} If RunTime.Automatic Then Begin WantedBitmap:=1024 * ( Ord(UpCase(RunTime.FileName[6]))-Ord('A') ) + 128 * ( Ord(UpCase(RunTime.FileName[7]))-Ord('A') ) - 1; First:=(WantedBitmap=-1) End; Repeat FindWantedBitmap(RunTime.Automatic,First,WantedBitmap,Number); If WantedBitmap<>0 Then Begin {Position pointer} If WantedBitmap<>CurrentBitmap Then Begin Seek(InFile,WantedBitmap-1); CurrentBitmap:=WantedBitmap End; Write('Reading Bitmap'); ScanBitmap(InFile,Bitmaps.Bitmap,Empty); CurrentBitmap:=CurrentBitmap+1; Writeln('.'); {Process Bitmap} If Empty Then Writeln('Bitmap is empty, no METAFONT code ',Number,'.') Else Begin Write('Writing METAFONT code ',Number); ScanSides(Bitmaps,RunTime.FixedX,RunTime.FixedY); MiddleOut(OutFile,Bitmaps,Number,RunTime.Standard); Writeln('.') End; Writeln; {Ready to generate next METAFONT character} Number:=Number+1 End; Until WantedBitmap=0 End; {------------------------------------ Main -----------------------------------} Begin Writeln; Writeln('Bitmaps to METAFONT Conversion Program.'); {To make Borland happy} Writeln('Version 2.00 Copyright F. Jalbert 1991.'); Writeln; Write('Opening Bitmap file JIS24'); Assign(InFile,'JIS24'); Reset(InFile,RecSize); Writeln('.'); Writeln; GetParameters(RunTime); Write('Creating METAFONT file '+RunTime.FileName+'.mf'); Assign(OutFile,RunTime.FileName+'.mf'); Rewrite(OutFile); Writeln('.'); Writeln; Write('Writing initial METAFONT header'); BeginOut(OutFile,RunTime); Writeln('.'); Writeln; Generate(InFile,OutFile,Number,RunTime); Writeln; Write('Writing final METAFONT header'); EndOut(OutFile,RunTime); Writeln('.'); Write('Closing METAFONT file '+RunTime.FileName+'.mf'); Close(OutFile); Writeln('.'); Write('Closing Bitmap file JIS24'); Close(InFile); Writeln('.'); Writeln; Writeln('METAFONT code for ',Number,' Bitmap(s) generated.'); Writeln End.