usage from ttf to cfdg with the batik ttf2svg, goes something like this:
Code: Select all
java -jar batik-ttf2svg.jar font.ttf > font.svg
svgglyphs2cfdg.pl font.svg > font.cfdg #(svgglyphs2cfdg.pl beeing the attached script)
Code: Select all
startshape txt
rule txt {
A_A{}
B_A{x 1000}
C_A{x 1900}
}
rule LINE{SQUARE{s 1.1 6}}
rule ADD{SQUARE{s 6 50 r 45 y 25}}
include font.cfdg
Code: Select all
#!/usr/bin/perl
use XML::Simple; #you need this library
$lineobject = "LINE"; #shape that is used as line (streched)
$addobject = "ADD"; #shape that is placed unscaled for each line
$res = 25; #approx. line length; smaller number = bigger resolution
$rulesuffix = "_A";
$svg = XMLin($ARGV[0],keyattr => 'glyph-name');
if($#ARGV==0){
foreach $k (sort(keys %{$svg->{"defs"}->{"font"}->{"glyph"}})) {
printf "rule $k$rulesuffix\{\n";
d2cfdg($svg->{"defs"}->{"font"}->{"glyph"}->{$k}->{"d"});
printf "}\n";
}
}else{
for($ik=1;$ik<=$#ARGV;$ik++){
$k=$ARGV[$ik];
if(exists $svg->{"defs"}->{"font"}->{"glyph"}->{$k}){
printf "rule $k$rulesuffix\{\n";
d2cfdg($svg->{"defs"}->{"font"}->{"glyph"}->{$k}->{"d"});
printf "}\n";
}else{
printf "#$k not found\n";
}
}
}
sub absrel {
if($_[0]=~/[A-Z]/){
return $_[1];
}else{
return $_[1] + $_[2];
}
}
sub line{
$x1 = shift;
$y1 = shift;
$x2 = shift;
$y2 = shift;
$norep = shift;
$dx = $x2 - $x1;
$dy = $y2 - $y1;
if($dx==0){
$ly=abs($dy);
if($ly==0){
$n=1;
}else{
$n = int($ly/$res);
$n = 1 if $n<1;
}
if($norep || $n <= 1){
$ym = $y1 + $dy/2;
printf "\t%s{s %.2f 1 x %.2f y %.2f r 90}\n",$lineobject,$ly,$x1,$ym;
printf "\t%s{x %.2f y %.2f r 90}\n",$addobject,$x1,$ym if ($addobject);
}else{
$step = $dy/$n;
$ym = $y1 + $step/2;
printf "\t%d*{y %.2f}%s{s %.2f 1 x %.2f y %.2f r 90}\n",$n,$step,$lineobject,abs($step),$x1,$ym;
printf "\t%d*{y %.2f}%s{x %.2f y %.2f r 90}\n",$n,$step,$addobject,$x1,$ym if ($addobject);
}
}elsif($dy==0){
$lx=abs($dx);
if($lx==0){
$n = 1;
}else{
$n = int($lx/$res);
$n = 1 if $n<1;
}
if($norep || $n <= 1){
$xm = $x1 + $dx/2;
printf "\t%s{s %.2f 1 x %.2f y %.2f}\n",$lineobject,$lx,$xm,$y1;
printf "\t%s{x %.2f y %.2f}\n",$addobject,$xm,$y1 if ($addobject);
}else{
$step = $dx/$n;
$xm = $x1 + $step/2;
printf "\t%d*{x %.2f}%s{s %.2f 1 x %.2f y %.2f}\n",$n,$step,$lineobject,abs($step),$xm,$y1;
printf "\t%d*{x %.2f}%s{x %.2f y %.2f}\n",$n,$step,$addobject,$xm,$y1 if ($addobject);
}
}else{
$r = atan2($dy,$dx)/3.1415*180;
$l = sqrt(($dx*$dx)+($dy*$dy));
if($l==0){
$n = 1;
}else{
$n = int($l/$res);
$n = 1 if $n<1;
}
if($norep || $n <= 1){
$xm = $x1 + $dx/2;
$ym = $y1 + $dy/2;
printf "\t%s{s %.2f 1 x %.2f y %.2f r %.2f}\n",$lineobject,$l,$xm,$ym,$r;
printf "\t%s{x %.2f y %.2f r %.2f}\n",$addobject,$xm,$ym,$r if ($addobject);
}else{
$step = $l/$n;
$stepx = $dx/$n;
$stepy = $dy/$n;
$xm = $x1 + $stepx/2;
$ym = $y1 + $stepy/2;
printf "\t%d*{x %.2f y %.2f}%s{s %.2f 1 x %.2f y %.2f r %.2f}\n",$n,$stepx,$stepy,$lineobject,$step,$xm,$ym,$r;
printf "\t%d*{x %.2f y %.2f}%s{x %.2f y %.2f r %.2f}\n",$n,$stepx,$stepy,$addobject,$xm,$ym,$r if ($addobject);
}
}
}
sub qbezier{
$xx1=shift;$yy1=shift;
$xx2=shift;$yy2=shift;
$xx3=shift;$yy3=shift;
$dx1 = $xx1 - $xx2;
$dy1 = $yy1 - $yy2;
$dx2 = $xx1 - $xx3;
$dy2 = $yy1 - $yy3;
$l = sqrt($dx2*$dx2+$dy2*$dy2);
if($l==0){
$step = 1;
}else{
$step = $res/$l;
$step = 1 if($step>0.5);
$step = 1 if($step<=0);
}
if( $step<1 && (!($dx1==0&&$dx2==0)&&!($dy1==0&&$dy2==0))&&
(($dy1!=0&&$dy2==0)||($dy1==0&&$dy2!=0)||($dx1==0&&$dx2!=0)||($dx1!=0&&$dx2==0)
|| abs($dx1/$dy1/$dx2*$dy2-1)>0.2)){
$xo = $xx1;
$yo = $yy1;
for($t=$step;$t<1;$t+=$step){
$xc=(1-$t)*(1-$t)*$xx1+2*$t*(1-$t)*$xx2+$t*$t*$xx3;
$yc=(1-$t)*(1-$t)*$yy1+2*$t*(1-$t)*$yy2+$t*$t*$yy3;
line($xo,$yo,$xc,$yc,1);
$xo = $xc;
$yo = $yc;
}
line($xo,$yo,$xx3,$yy3,1);
}else{
line($xx1,$yy1,$xx3,$yy3);
}
}
sub d2cfdg {
@l = $_[0] =~ /([-0-9]+|[MmZzLlHhVvCcSsQqTtAa])/g;
for($i=0;$i<=$#l;$i++){
$o=$l[$i];
$_=$o;
if(/[Mm]/){
$px=absrel($o,$l[++$i],$px);
$py=absrel($o,$l[++$i],$py);
}elsif(/[Zz]/){
}elsif(/[Ll]/){
$x=absrel($o,$l[++$i],$px);
$y=absrel($o,$l[++$i],$py);
line($px,$py,$x,$y);
$px = $x;
$py = $y;
}elsif(/[Hh]/){
$x=absrel($o,$l[++$i],$px);
line($px,$py,$x,$py);
$px = $x;
}elsif(/[Vv]/){
$y=absrel($o,$l[++$i],$py);
line($px,$py,$px,$y);
$py = $y;
}elsif(/[Cc]/){
$x1=absrel($o,$l[++$i],$px);
$y1=absrel($o,$l[++$i],$py);
$x2=absrel($o,$l[++$i],$px);
$y2=absrel($o,$l[++$i],$py);
$x=absrel($o,$l[++$i],$px);
$y=absrel($o,$l[++$i],$py);
line($px,$py,$x,$y); #cubic bezier not implemented yet
$px=$x;
$py=$y;
}elsif(/[Ss]/){
$x1 = 2*$px-$x2;
$y1 = 2*$py-$y2;
$x2=absrel($o,$l[++$i],$px);
$y2=absrel($o,$l[++$i],$py);
$x=absrel($o,$l[++$i],$px);
$y=absrel($o,$l[++$i],$py);
line($px,$py,$x,$y); #cubic bezier not implemented yet
$px=$x;
$py=$y;
}elsif(/[Qq]/){
$x1=absrel($o,$l[++$i],$px);
$y1=absrel($o,$l[++$i],$py);
$x=absrel($o,$l[++$i],$px);
$y=absrel($o,$l[++$i],$py);
qbezier($px,$py,$x1,$y1,$x,$y);
$px=$x;
$py=$y;
}elsif(/[Tt]/){
$x1 = 2*$px-$x1;
$y1 = 2*$py-$y1;
$x=absrel($o,$l[++$i],$px);
$y=absrel($o,$l[++$i],$py);
qbezier($px,$py,$x1,$y1,$x,$y);
$px=$x;
$py=$y;
}elsif(/[Aa]/){
$rx=$l[++$i];
$ry=$l[++$i];
$xr=$l[++$i];
$la=$l[++$i];
$sf=$l[++$i];
$x=absrel($o,$l[++$i],$px);
$y=absrel($o,$l[++$i],$py);
printf "#ecllipse ($px,$py)->($x,$y) ($rx,$ry,$xr,$la,$sf)\n";
$px=$x;
$py=$y;
}else{
printf "#problem parsing at $_\n";
}
}
}