251 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
		
		
			
		
	
	
			251 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| 
								 | 
							
								#!/usr/bin/env perl
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# -------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								# file:		dhw2ps.pl
							 | 
						||
| 
								 | 
							
								# task:		convert the internal dwh file format of DigiMemo A501 to
							 | 
						||
| 
								 | 
							
								#		ps or pdf files
							 | 
						||
| 
								 | 
							
								# authors:	Jan Theofel (theofel@etes.de)
							 | 
						||
| 
								 | 
							
								#		Harald Koenig
							 | 
						||
| 
								 | 
							
								# version:	0.1
							 | 
						||
| 
								 | 
							
								# license:	free to use, an official license will follow
							 | 
						||
| 
								 | 
							
								# -------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								# TODO:
							 | 
						||
| 
								 | 
							
								# - code cleanup
							 | 
						||
| 
								 | 
							
								# - code optimisation (the array of chars is very slow)
							 | 
						||
| 
								 | 
							
								# - adding a real license
							 | 
						||
| 
								 | 
							
								# - add documentation
							 | 
						||
| 
								 | 
							
								# -------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								use strict;
							 | 
						||
| 
								 | 
							
								use Getopt::Long qw(:config gnu_getopt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								my $pdfout = ($0 =~ /dhw2pdf/);;
							 | 
						||
| 
								 | 
							
								my $debug = 0;
							 | 
						||
| 
								 | 
							
								my $verbose = 0;
							 | 
						||
| 
								 | 
							
								my $usage = 0;
							 | 
						||
| 
								 | 
							
								my $quiet = 0;
							 | 
						||
| 
								 | 
							
								my $colorlayers = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								sub usage
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  print "usage: $0 [params] [dwh file(s)]\n\n";
							 | 
						||
| 
								 | 
							
								  print "Where params can be:\n";
							 | 
						||
| 
								 | 
							
								  print "-c|--colorlayers     color layers\n";
							 | 
						||
| 
								 | 
							
								  print "-d|--debug           run in debug mode\n";
							 | 
						||
| 
								 | 
							
								  print "-h|--help            display this usage message\n";
							 | 
						||
| 
								 | 
							
								  print "-q|--quiet           run in quite mode\n";
							 | 
						||
| 
								 | 
							
								  print "-v|--verbose         run in verbose mode\n";
							 | 
						||
| 
								 | 
							
								  print "--pdf                create pdf files (nneds ps2pdf)\n";
							 | 
						||
| 
								 | 
							
								  print "--ps                 create ps files\n"; 
							 | 
						||
| 
								 | 
							
								  exit $_[0];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								GetOptions (
							 | 
						||
| 
								 | 
							
									    'c' => \$colorlayers, 'colorlayers!' => \$colorlayers,
							 | 
						||
| 
								 | 
							
									    'd' => \$debug,       'debug!'       => \$debug,
							 | 
						||
| 
								 | 
							
									    'h' => \$usage,       'help'         => \$usage,
							 | 
						||
| 
								 | 
							
									    'q' => \$quiet,       'quiet!'       => \$quiet,
							 | 
						||
| 
								 | 
							
									    'v' => \$verbose,     'verbose!'     => \$verbose,
							 | 
						||
| 
								 | 
							
									    'pdf!' => \$pdfout,
							 | 
						||
| 
								 | 
							
									    'ps!'  => sub { $pdfout = 0 },
							 | 
						||
| 
								 | 
							
									    ) or usage(1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								my $inname = shift();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								usage(0) if ($usage || !$inname);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if ($pdfout) 
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  my $check_ps2pdf = `which ps2pdf`;
							 | 
						||
| 
								 | 
							
								  if($check_ps2pdf eq "")
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    die "ERROR: ps2pdf is needed in pdf mode.\n";
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								while ($inname) { # loop for all input files
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    my ($buffer, $skip, $data);
							 | 
						||
| 
								 | 
							
								    my ($fileversion, $paperwidth, $paperheight, $paperformat);
							 | 
						||
| 
								 | 
							
								    my $file_content;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    print "INFO: input file: $inname\n" if (!$quiet);
							 | 
						||
| 
								 | 
							
								    open(IN, "$inname");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    my $count = 32;
							 | 
						||
| 
								 | 
							
								    read(IN, $data, $count);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if($data ne "ACECAD_DIGIMEMO_HANDWRITING_____") {
							 | 
						||
| 
								 | 
							
									die "Invalid INK file $inname\n";
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# read rest of input file in 64K junks
							 | 
						||
| 
								 | 
							
								    while(read(IN, $buffer, 64*1024)) {
							 | 
						||
| 
								 | 
							
									$data .= $buffer;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    close(IN);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    my @data = split(//, $data);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# decode header data
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    $fileversion = ord($data[$count++]);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    $paperwidth = ord($data[$count+0]) + (ord($data[$count+1]) << 8);
							 | 
						||
| 
								 | 
							
								    $count += 2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    $paperheight = ord($data[$count+0]) + (ord($data[$count+1]) << 8);
							 | 
						||
| 
								 | 
							
								    $count += 2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    my $pagetype = ord($data[$count++]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ord($data[$count++]);  # skip header byte
							 | 
						||
| 
								 | 
							
								    ord($data[$count++]);  # skip header byte
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    my $paper = ("a5", "a4", "??2", "??3", "??4", "??5", "??6", "??7", "b5", "b4")[$pagetype];
							 | 
						||
| 
								 | 
							
								    my $orientation = ("Portrait", "Landscape")[ $paperheight < $paperwidth ];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    my $llx = 0;  #  87  for A4 centering on A4
							 | 
						||
| 
								 | 
							
								    my $lly = 0;  # 123  for A4 centering on A4
							 | 
						||
| 
								 | 
							
								    my $urx = $llx + int($paperwidth  / 1000. * 72. + 0.999999);
							 | 
						||
| 
								 | 
							
								    my $ury = $lly + int($paperheight / 1000. * 72. + 0.999999);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    my $now = gmtime;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    print "DEBUG: ink file version: $fileversion\n" if ($debug);
							 | 
						||
| 
								 | 
							
								    print "DEBUG: width / height: $paperwidth / $paperheight\n" if ($debug);
							 | 
						||
| 
								 | 
							
								    print "DEBUG: pagetype: $pagetype ($paper)\n" if ($debug);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    my $outfile;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if ($pdfout) {
							 | 
						||
| 
								 | 
							
									$outfile = "|ps2pdf -sPAPERSIZE=$paper - $inname";
							 | 
						||
| 
								 | 
							
									$outfile =~ s/\.dhw$//;
							 | 
						||
| 
								 | 
							
									$outfile .= ".pdf";
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
									$outfile = ">$inname";
							 | 
						||
| 
								 | 
							
									$outfile =~ s/\.dhw$//;
							 | 
						||
| 
								 | 
							
									$outfile .= ".ps";
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    print "DEBUG: output file: $outfile\n" if ($debug);
							 | 
						||
| 
								 | 
							
								    open(OUT, "$outfile");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    print OUT <<PSHEAD;
							 | 
						||
| 
								 | 
							
								    %!PS-Adobe-2.0
							 | 
						||
| 
								 | 
							
									%%Title: $inname
							 | 
						||
| 
								 | 
							
									%%Creator: ink2ps $inname
							 | 
						||
| 
								 | 
							
									%%CreationDate: $now
							 | 
						||
| 
								 | 
							
									%%Orientation: $orientation
							 | 
						||
| 
								 | 
							
									%%BoundingBox: $llx $lly $urx $ury
							 | 
						||
| 
								 | 
							
									%%DocumentPaperSizes: $paper
							 | 
						||
| 
								 | 
							
									%%Pages: 1
							 | 
						||
| 
								 | 
							
									%%EndComments
							 | 
						||
| 
								 | 
							
									/StartPage {
							 | 
						||
| 
								 | 
							
									    gsave
							 | 
						||
| 
								 | 
							
										$llx $lly translate
							 | 
						||
| 
								 | 
							
										72 1000 div dup scale
							 | 
						||
| 
								 | 
							
										1 setlinecap
							 | 
						||
| 
								 | 
							
										1 setlinejoin
							 | 
						||
| 
								 | 
							
										1 LW
							 | 
						||
| 
								 | 
							
									    } bind def
							 | 
						||
| 
								 | 
							
									    /EndPage {
							 | 
						||
| 
								 | 
							
										grestore
							 | 
						||
| 
								 | 
							
										    showpage
							 | 
						||
| 
								 | 
							
										} bind def
							 | 
						||
| 
								 | 
							
										/RGB { setrgbcolor } bind def
							 | 
						||
| 
								 | 
							
										/LW { setlinewidth } bind def
							 | 
						||
| 
								 | 
							
										/S { newpath moveto } bind def
							 | 
						||
| 
								 | 
							
										/L { lineto } bind def
							 | 
						||
| 
								 | 
							
										/E { stroke } bind def
							 | 
						||
| 
								 | 
							
										%%EndProlog
							 | 
						||
| 
								 | 
							
										%%Page: 1 1
							 | 
						||
| 
								 | 
							
										StartPage
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										% set line width
							 | 
						||
| 
								 | 
							
										16 LW
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										% set color
							 | 
						||
| 
								 | 
							
										0 0 0 RGB
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										% strokes
							 | 
						||
| 
								 | 
							
								PSHEAD
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    my $color     = 0;
							 | 
						||
| 
								 | 
							
								    my $lastcolor = 0;
							 | 
						||
| 
								 | 
							
								    my $layer     = 0;
							 | 
						||
| 
								 | 
							
								    my $strokes   = 0;
							 | 
						||
| 
								 | 
							
								    my $points    = 0;
							 | 
						||
| 
								 | 
							
								    my $pointcmd  = "S";
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    while($count < $#data) {
							 | 
						||
| 
								 | 
							
									my $next = ord($data[$count++]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (($next & ~0x07) == 0x80) {  # pen up/down
							 | 
						||
| 
								 | 
							
									    if ($next & 0x01) {
							 | 
						||
| 
								 | 
							
										$pointcmd = "S";
							 | 
						||
| 
								 | 
							
										print "DEBUG pen down POSITION $count\n" if ($debug);
							 | 
						||
| 
								 | 
							
									    }
							 | 
						||
| 
								 | 
							
									    else {
							 | 
						||
| 
								 | 
							
										$pointcmd = "L\nE\n";
							 | 
						||
| 
								 | 
							
										$strokes++;
							 | 
						||
| 
								 | 
							
										print "DEBUG pen up POSITION $count\n" if ($debug);
							 | 
						||
| 
								 | 
							
									    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									    $color = (($next >> 1) + ($layer * $colorlayers))  & 0x03;
							 | 
						||
| 
								 | 
							
									    print "DEBUG pen color $color\n" if ($debug);
							 | 
						||
| 
								 | 
							
									    if ($color != $lastcolor) {
							 | 
						||
| 
								 | 
							
										$lastcolor = $color;
							 | 
						||
| 
								 | 
							
										print OUT "%%Color: $color\n";
							 | 
						||
| 
								 | 
							
										print OUT ("0 0 0", "1 0 0", "0 1 0", "0 0 1")[$color] . " RGB\n";
							 | 
						||
| 
								 | 
							
									    }
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									elsif ($next == 0x88) {  # time stamp
							 | 
						||
| 
								 | 
							
									    my $timestamp = ord($data[$count++]);
							 | 
						||
| 
								 | 
							
									    print "DEBUG TimeStamp $timestamp\n" if ($debug);
							 | 
						||
| 
								 | 
							
									    print OUT "%%TimeStamp: $timestamp\n" if ($timestamp < 0x7f);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									elsif ($next == 0x90) {  ## end of layer
							 | 
						||
| 
								 | 
							
									    $layer = ord($data[$count++]);
							 | 
						||
| 
								 | 
							
									    print "DEBUG End of LAYER $layer\n" if ($debug);
							 | 
						||
| 
								 | 
							
									    die("Layer # $layer > 127") if ($layer & 0x80);
							 | 
						||
| 
								 | 
							
										print OUT "%%EndOfLayer: $layer\n\n";
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									elsif (!($next & ~0x7f)) {  ## coordinates
							 | 
						||
| 
								 | 
							
									    my ($b1, $b2, $b3, $b4) = ($next, ord($data[$count+0]), ord($data[$count+1]), ord($data[$count+2]));
							 | 
						||
| 
								 | 
							
									    $count += 3;
							 | 
						||
| 
								 | 
							
									    printf "DEBUG CHECK position $count A %02x %02x %02x %02x\n", $b1, $b2, $b3, $b4 if ($debug);
							 | 
						||
| 
								 | 
							
									    # die("MSB set in coordinate bytes") if (($b1 | $$b2 | $b3 | $b4) & ~0x7f);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									    my $x = $b1 + ($b2 << 7);
							 | 
						||
| 
								 | 
							
									    my $y = $b3 + ($b4 << 7);
							 | 
						||
| 
								 | 
							
									    print "DEBUG $count: x = $x / y = $y\n" if ($debug);
							 | 
						||
| 
								 | 
							
									    print OUT "$x $y " . $pointcmd . "\n";
							 | 
						||
| 
								 | 
							
									    $points++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									    $pointcmd = "L";
							 | 
						||
| 
								 | 
							
									} else {
							 | 
						||
| 
								 | 
							
									    die("unknown byte " . sprintf("0x%02x", $next) . " at position $count");
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    print OUT <<PSFOOT;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    EndPage
							 | 
						||
| 
								 | 
							
									%%Trailer
							 | 
						||
| 
								 | 
							
									%%EOF
							 | 
						||
| 
								 | 
							
								PSFOOT
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    close(OUT);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    print "INFO: $points points, $strokes strokes, $layer layers\n\n" if (! $quiet);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    $inname = shift();
							 | 
						||
| 
								 | 
							
								}
							 |