Changed to use JavaScript glyph engine.
Added index.html for web user interface.
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<html>
+<head>
+<title>TTF(TrueType)フォント生成 (試作)</title>
+</head>
+<body>
+<h1>TTF(TrueType)フォント生成</h1>
+<form action="makettf.cgi" method="POST">
+フォント名(英語):<input type="text" name="fontname-en" value="Test" size="20"><br>
+フォント名(漢字):<input type="text" name="fontname-ja" value="テスト" size="20"><br>
+部品データ<br>
+<textarea wrap="off" name="partsdata" cols="80" rows="10">30A8 2:7:8:66:2:95:16:110:33$1:0:2:28:56:102:56$1:22:4:103:56:103:196$1:0:2:3:92:66:92$2:22:7:66:92:48:146:1:178$2:0:7:186:66:163:89:125:112$2:7:0:107:60:130:144:196:182
+一 2:7:8:66:2:95:16:110:33$1:0:2:28:56:102:56$1:22:4:103:56:103:196$1:0:2:3:92:66:92$2:22:7:66:92:48:146:1:178$2:0:7:186:66:163:89:125:112$2:7:0:107:60:130:144:196:182
+</textarea>
+<br>
+<input type="submit" value="生成">
+</form>
+<hr>
+部品データは1部品=1行で、「部品名、スペース、部品データ」の順に記述します。<br>実際に生成されるコードポイントは、部品名が「単独の文字」「[単独の文字]」「コードポイント16進数(頭にUu,+-を付けても可)」のいずれかとなります。<br>
+<ul>
+<li>(例)</li>
+<li>30A8</li>
+<li>U+30A8</li>
+<li>u30a8</li>
+<li>u-00020000</li>
+<li>一</li>
+<li>[壱]</li>
+</ul>
+<hr>
+注意<br>
+TrueTypeフォントを生成するソフトウェアfontforge の制約により、以下の条件を満たさない場合には生成したフォントをWord2002で利用できません。
+<dl>
+<dt>日本語フォント</dt><dd>U+30A8「(カタカナ)エ」を含めてください</dd>
+<dt>簡体字中国語フォント</dt><dd>U+3105「ボポモフォB」を含めてください</dd>
+<dt>繁体字中国語フォント</dt><dd>U+592E「央」を含めてください</dd>
+<dt>韓国語フォント</dt><dd>U+3131「ハングル字母1番目」を含めてください</dd>
+</dl>
+<hr>
+<div align="right">fonts.jp</div>
+</body>
+</html>
+
+
--- /dev/null
+// arguments ... 0:target_char_name 1:related_parts 2:shotai 3:weight
+// shotai ... mincho or gothic
+// weight ... 1 3 5 7
+
+load("engine/polygon.js");
+load("engine/polygons.js");
+load("engine/buhin.js");
+load("engine/kage.js");
+load("engine/kagecd.js");
+load("engine/kagedf.js");
+
+kage = new Kage();
+
+if(arguments[2] == "gothic"){
+ kage.kShotai = kage.kGothic;
+} else {
+ kage.kShotai = kage.kMincho;
+}
+
+if(arguments[3] == 1){
+ kage.kMinWidthY = 1;
+ kage.kMinWidthT = 4;
+ kage.kWidth = 3;
+ kage.kKakato = 4;
+} else if(arguments[3] == 5){
+ kage.kMinWidthY = 3;
+ kage.kMinWidthT = 8;
+ kage.kWidth = 7;
+ kage.kKakato = 2;
+} else if(arguments[3] == 7){
+ kage.kMinWidthY = 4;
+ kage.kMinWidthT = 10;
+ kage.kWidth = 9;
+ kage.kKakato = 1;
+} else {
+ kage.kMinWidthY = 2;
+ kage.kMinWidthT = 6;
+ kage.kWidth = 5;
+ kage.kKakato = 3;
+}
+
+polygons = new Polygons();
+
+target = (unescape(arguments[0]));
+buhin = (unescape(arguments[1])).replace(/\r\n|\n/g, "\r").replace(/\+|\t/g, " ");
+
+temp = buhin.split("\r");
+for(i = 0; i < temp.length; i++){
+ temp2 = temp[i].split(" ");
+ kage.kBuhin.push(temp2[0], temp2[1]);
+}
+
+kage.makeGlyph(polygons, target);
+print(polygons.generateSVG());
#!/usr/bin/perl
use utf8;
+binmode STDOUT, ":utf8";
+
use CGI;
+$form = new CGI;
$FONTFORGE = "/usr/local/bin/fontforge";
$PERL = "/usr/bin/perl";
-$ECHO = "/bin/echo";
$RM = "/bin/rm";
-$TEMP = "/tmp/tempKAGE";
-$KAGESCRIPT = "/home/kamichi/perl";
-$FMT = "svg";
$LICENSE = 'Created by KAGE system. (http://fonts.jp/)';
+$TEMP="temp";
-$form = new CGI;
+$RANDOM = sprintf("%05X", rand() * 0x100000);
+$TEMPDIR = "/tmp/makettf_$RANDOM";
+mkdir($TEMPDIR);
-$fontname_en = $form->param('fontname-en');
-$fontname_en =~ s/[\;\&\#\"\'\%\\\$\:\!\=\~\^\`]//g;
-$fontname_ja = $form->param('fontname-ja');
-$fontname_ja =~ s/[\;\&\#\"\'\%\\\$\:\!\=\~\^\`]//g;
-utf8::decode($fontname_ja);
-if($fontname_en eq ""){
- $fontname_en = "Untitled";
-}
-if($fontname_ja eq ""){
- $fontname_ja = $fontname_en;
-}
-
-#open FH, "<", "parts.txt";
-#$temp = "";
-#%parts = ();
-#foreach(<FH>){
-# $temp .= $_;
-# @temp = split(/ \t|\r\n|\r|\n/, $_);
-# $parts{$temp[0]} = $temp[1];
-#}
-#close FH;
-@temp2 = split(/\r\n|\r|\n/, $partsdata);
-$temp = "";
-%parts = ();
-foreach(@temp2){
- $temp .= $_;
- @temp = split(/ |\t|\r\n|\r|\n/, $_);
- $parts{$temp[0]} = $temp[1];
-}
-open FH, ">", "$TEMP.parts.txt";
-$temp =~ s/ /\t/g;
-print FH $temp;
-close FH;
-
-#open FH, "<", "map.txt";
-#%map = ();
-#foreach(<FH>){
-# @temp = split(/\t|\r\n|\r|\n/, $_);
-# $map{$temp[0]} = $temp[1];
-#}
-#close FH;
-@temp2 = split(/\r\n|\r|\n/, $mappingtable);
-%map = ();
-foreach(@temp2){
- @temp = split(/ |\t|\r\n|\r|\n/, $_);
- $map{$temp[0]} = $temp[1];
-}
+&makehead();
+&makefoot();
+&makeparts();
+$dummy = `$PERL makettf.pl $TEMPDIR $TEMP mincho 3`;
+&sendfont();
-$script =<<"EOT";
+sub makehead{
+ $fontname_en = $form->param('fontname-en');
+ $fontname_en =~ s/[\;\&\#\"\'\%\\\$\:\!\=\~\^\`]//g;
+ $fontname_ja = $form->param('fontname-ja');
+ $fontname_ja =~ s/[\;\&\#\"\'\%\\\$\:\!\=\~\^\`]//g;
+ utf8::decode($fontname_ja);
+ if($fontname_en eq ""){
+ $fontname_en = "Untitled";
+ }
+ if($fontname_ja eq ""){
+ $fontname_ja = $fontname_en;
+ }
+ open FH, ">:utf8", "$TEMPDIR/head.txt";
+ print FH <<"EOT";
New()
Reencode("UnicodeFull")
SetTTFName(0x409,0,"$LICENSE")
SetTTFName(0x411,1,"$fontname_ja")
SetTTFName(0x411,4,"$fontname_ja")
EOT
-
-foreach(sort(keys %map)){
- $temp = $parts{$map{$_}};
- $dummy = `cd $KAGESCRIPT; $ECHO '$temp' | $PERL $KAGESCRIPT/kagepre.pl $TEMP.parts.txt | $PERL $KAGESCRIPT/kage$FMT.pl > $TEMP.$_.$FMT`;
- &addglyph($_);
+ close FH;
}
-&makefont;
-sub addglyph{
- $script .=<<"EOT";
-Select(0u$_[0])
-Clear()
-Import("$TEMP.$_[0].$FMT")
-#Import("$TEMP.$_[0].$FMT",0,2)
-RemoveOverlap()
-Simplify()
-SetWidth(1000)
-SetVWidth(1000)
-Move(0, 50)
-RoundToInt()
-AutoHint()
-EOT
+sub makefoot{
+ open FH, ">:utf8", "$TEMPDIR/foot.txt";
+ close FH;
}
-sub makefont{
- $script .= "Generate(\"$TEMP.ttf\", \"\", 0)\n";
- $script .= "Quit()\n";
- open FH, ">:utf8", "$TEMP.scr";
- print FH $script;
+sub makeparts{
+ my $temp = $form->param('partsdata');
+ utf8::decode($temp);
+ open FH, ">:utf8", "$TEMPDIR/parts.txt";
+ print FH $temp;
close FH;
-
- $dummy = `export LANG=utf-8; $FONTFORGE -script $TEMP.scr 2>/dev/null`;
-
+}
+
+sub sendfont{
my $fdata = "";
my $fsize = 0;
my @bdata;
- open FH, "<$TEMP.ttf";
- $fsize = -s FH;
- read FH, $fdata, $fsize;
- close FH;
print <<"EOT";
Content-type: application/octet-stream
Content-Disposition: attachment; filename = $fontname_en.ttf
-$fdata
EOT
-
- $dummy = `$RM $TEMP*`;
+ open FH, "<:utf8", "$TEMPDIR/$TEMP.ttf";
+ while(1){
+ $readed = read FH, $fdata, 1024;
+ utf8::decode($fdata);
+ print $fdata;
+ if($readed <= 0){
+ last;
+ }
+ }
+ close FH;
+ $dummy = `$RM -r $TEMPDIR`;
}
-
--- /dev/null
+#!/usr/bin/perl
+use utf8;
+use CGI;
+binmode STDOUT, ":utf8";
+
+if(scalar(@ARGV) != 4){
+ print "Usage: makettf.pl WorkingDirectory WorkingName Shotai Weight\n";
+ print "Shotai: mincho or gothic\n";
+ print "Weight: 1 3 5 7\n";
+ exit;
+}
+
+$FONTFORGE = "/usr/local/bin/fontforge";
+$PERL = "/usr/bin/perl";
+$WORKDIR=$ARGV[0];
+$WORKNAME=$ARGV[1];
+$SHOTAI=$ARGV[2];
+$WEIGHT=$ARGV[3];
+
+unlink "$WORKDIR/$WORKNAME.log";
+unlink "$WORKDIR/$WORKNAME.scr";
+unlink "$WORKDIR/$WORKNAME.ttf";
+mkdir "$WORKDIR/build";
+
+sub addglyph{
+ my $buffer =<<"EOT";
+Print(0u$_[0])
+Select(0u$_[0])
+Clear()
+Import("$WORKDIR/build/$_[0].svg")
+Scale(500)
+Move(400, -400)
+RemoveOverlap()
+Simplify()
+SetWidth(1000)
+Move(0, 50)
+RoundToInt()
+AutoHint()
+EOT
+ open FH, ">>:utf8", "$WORKDIR/$WORKNAME.scr";
+ print FH $buffer;
+ close FH;
+}
+
+sub makefont{
+ my $buffer = "Generate(\"$WORKDIR/$WORKNAME.ttf\", \"\", 0)\n";
+ $buffer .= "Quit()\n";
+ open FH, ">>:utf8", "$WORKDIR/$WORKNAME.scr";
+ print FH $buffer;
+ close FH;
+
+ $buffer = `export LANG=utf-8; $FONTFORGE -script $WORKDIR/$WORKNAME.scr > $WORKDIR/$WORKNAME.log 2>&1`;
+ #open FH, ">>:utf8", "$WORKDIR/$WORKNAME.log";
+ #print FH $buffer;
+ #close FH;
+}
+
+sub addsubset{
+ $subset{$_[0]} = $buhin{$_[0]};
+ if($buhin{$_[0]} =~ m/(^|\$)99:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:(.+?)(\$|$)/){
+ if(!exists($subset{$2})){
+ &addsubset($2);
+ }
+ }
+}
+
+# initialize
+if(-e "$WORKDIR/head.txt"){
+ open FH, "<:utf8", "$WORKDIR/head.txt";
+ open FH2, ">>:utf8", "$WORKDIR/$WORKNAME.scr";
+ while(!eof FH){
+ my $buffer = <FH>;
+ print FH2 $buffer;
+ }
+ close FH;
+ close FH2;
+}
+else{
+ open FH, ">>:utf8", "$WORKDIR/$WORKNAME.log";
+ print FH "No header file.\n";
+ close FH;
+ exit;
+}
+
+# parse buhin
+%buhin = ();
+if(-e "$WORKDIR/parts.txt"){
+ open FH, "<:utf8", "$WORKDIR/parts.txt";
+ my $buffer = "";
+ while(<FH>){
+ $buffer .= $_;
+ }
+ close FH;
+ $temp = $buffer;
+}
+else{
+ open FH, ">>:utf8", "$WORKDIR/$WORKNAME.log";
+ print FH "No parts file.\n";
+ close FH;
+ exit;
+}
+@temp = split(/\r\n|\r|\n/, $temp);
+foreach(@temp){
+ @temp2 = split(/ |\t/, $_);
+ $buhin{$temp2[0]} = $temp2[1];
+}
+
+# parse target codepoint
+%target = ();
+foreach(sort(keys %buhin)){
+ if($_ =~ m/^\[([^\]])\]$/){
+ $target = sprintf("%X", unpack('U', $1));
+ } elsif(length($_) == 1){
+ $target = sprintf("%X", unpack('U', $_));
+ } elsif($_ =~ m/^[Uu]{0,1}[\+\-]{0,1}([0-9A-Fa-f]{1,8})$/){
+ $target = $1;
+ } else {
+ next;
+ }
+ $target =~ s/^0+//g; # delete zero for the beginning
+ $name = $_;
+ $target{$target} = $name;
+}
+
+# make glyph for each target
+foreach(sort(keys(%target))){
+ $code = $_;
+ $target = $target{$_};
+ %subset = ();
+ &addsubset($target);
+ $partsdata = "";
+ foreach(keys(%subset)){
+ $partsdata .= $_." ".$subset{$_}."\n";
+ }
+ utf8::encode($target);
+ $target =~ s/([^0-9A-Za-z_ ])/'%'.unpack('H2',$1)/ge;
+ $target =~ s/\s/+/g;
+ utf8::encode($partsdata);
+ $partsdata =~ s/([^0-9A-Za-z_ ])/'%'.unpack('H2',$1)/ge;
+ $partsdata =~ s/\s/+/g;
+ $svg = `/usr/bin/js makeglyph.js $target $partsdata $SHOTAI $WEIGHT`;
+ open FH, ">$WORKDIR/build/$code.svg";
+ print FH $svg;
+ close FH;
+ &addglyph($code);
+}
+
+# scripts footer
+if(-e "$WORKDIR/foot.txt"){
+ open FH, "<:utf8", "$WORKDIR/foot.txt";
+ open FH2, ">>:utf8", "$WORKDIR/$WORKNAME.scr";
+ while(!eof FH){
+ my $buffer = <FH>;
+ print FH2 $buffer;
+ }
+ close FH;
+ close FH2;
+}
+else{
+ open FH, ">>:utf8", "$WORKDIR/$WORKNAME.log";
+ print FH "No footer file.\n";
+ close FH;
+ exit;
+}
+
+&makefont;