*.o
Makefile
Makefile.old
+MANIFEST.bak
pm_to_blib
blib
# build generated files
*.bs
*/Makefile
+Imager-[0-9]*
# test generated files
_Inline/
i_img_diff
- i_init_fonts
- i_t1_new
- i_t1_destroy
- i_t1_set_aa
- i_t1_cp
- i_t1_text
- i_t1_bbox
-
i_tt_set_aa
i_tt_cp
i_tt_text
BEGIN {
require Exporter;
@ISA = qw(Exporter);
- $VERSION = '0.80';
+ $VERSION = '0.80_01';
eval {
require XSLoader;
XSLoader::load(Imager => $VERSION);
jpeg => "Imager::File::JPEG",
w32 => "Imager::Font::W32",
ft2 => "Imager::Font::FT2",
+ t1 => "Imager::Font::T1",
);
tie %formats, "Imager::FORMATS", \%formats_low, \%format_classes;
$warn_obsolete = $parms{'warn_obsolete'};
}
-# if ($parms{T1LIB_CONFIG}) { $ENV{T1LIB_CONFIG}=$parms{T1LIB_CONFIG}; }
-# if ( $ENV{T1LIB_CONFIG} and ( $fontstate eq 'missing conf' )) {
-# i_init_fonts();
-# $fontstate='ok';
-# }
if (exists $parms{'t1log'}) {
- i_init_fonts($parms{'t1log'});
+ if ($formats{t1}) {
+ Imager::Font::T1::i_init_t1($parms{'t1log'});
+ }
}
}
Imager::ImgRaw im1
Imager::ImgRaw im2
-undef_int
-i_init_fonts(t1log=0)
- int t1log
-
bool
_is_color_object(sv)
SV* sv
RETVAL
#ifdef HAVE_LIBT1
-
-void
-i_t1_set_aa(st)
- int st
-
-int
-i_t1_new(pfb,afm)
- char* pfb
- char* afm
-
-int
-i_t1_destroy(font_id)
- int font_id
-
-
-undef_int
-i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
- Imager::ImgRaw im
- int xb
- int yb
- int channel
- int fontnum
- float points
- SV* str_sv
- int align
- int utf8
- char* flags
- PREINIT:
- char *str;
- STRLEN len;
- CODE:
-#ifdef SvUTF8
- if (SvUTF8(str_sv))
- utf8 = 1;
-#endif
- str = SvPV(str_sv, len);
- RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
- utf8,flags);
- OUTPUT:
- RETVAL
-
-
-void
-i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
- int fontnum
- float point
- SV* str_sv
- int utf8
- char* flags
- PREINIT:
- char *str;
- STRLEN len;
- int cords[BOUNDING_BOX_COUNT];
- int i;
- int rc;
- PPCODE:
-#ifdef SvUTF8
- if (SvUTF8(str_sv))
- utf8 = 1;
-#endif
- str = SvPV(str_sv, len);
- rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
- if (rc > 0) {
- EXTEND(SP, rc);
- for (i = 0; i < rc; ++i)
- PUSHs(sv_2mortal(newSViv(cords[i])));
- }
-
-
-
-undef_int
-i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
- Imager::ImgRaw im
- int xb
- int yb
- Imager::Color cl
- int fontnum
- float points
- SV* str_sv
- int align
- int utf8
- char* flags
- PREINIT:
- char *str;
- STRLEN len;
- CODE:
-#ifdef SvUTF8
- if (SvUTF8(str_sv))
- utf8 = 1;
-#endif
- str = SvPV(str_sv, len);
- RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
- utf8,flags);
- OUTPUT:
- RETVAL
-
-void
-i_t1_has_chars(handle, text_sv, utf8 = 0)
- int handle
- SV *text_sv
- int utf8
- PREINIT:
- char const *text;
- STRLEN len;
- char *work;
- int count;
- int i;
- PPCODE:
-#ifdef SvUTF8
- if (SvUTF8(text_sv))
- utf8 = 1;
-#endif
- text = SvPV(text_sv, len);
- work = mymalloc(len);
- count = i_t1_has_chars(handle, text, len, utf8, work);
- if (GIMME_V == G_ARRAY) {
- EXTEND(SP, count);
- for (i = 0; i < count; ++i) {
- PUSHs(sv_2mortal(newSViv(work[i])));
- }
- }
- else {
- EXTEND(SP, 1);
- PUSHs(sv_2mortal(newSVpv(work, count)));
- }
- myfree(work);
-
-void
-i_t1_face_name(handle)
- int handle
- PREINIT:
- char name[255];
- int len;
- PPCODE:
- len = i_t1_face_name(handle, name, sizeof(name));
- if (len) {
- EXTEND(SP, 1);
- PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
- }
-
-void
-i_t1_glyph_name(handle, text_sv, utf8 = 0)
- int handle
- SV *text_sv
- int utf8
- PREINIT:
- char const *text;
- STRLEN work_len;
- size_t len;
- char name[255];
- PPCODE:
-#ifdef SvUTF8
- if (SvUTF8(text_sv))
- utf8 = 1;
-#endif
- text = SvPV(text_sv, work_len);
- len = work_len;
- while (len) {
- unsigned long ch;
- if (utf8) {
- ch = i_utf8_advance(&text, &len);
- if (ch == ~0UL) {
- i_push_error(0, "invalid UTF8 character");
- break;
- }
- }
- else {
- ch = *text++;
- --len;
- }
- EXTEND(SP, 1);
- if (i_t1_glyph_name(handle, ch, name, sizeof(name))) {
- PUSHs(sv_2mortal(newSVpv(name, 0)));
- }
- else {
- PUSHs(&PL_sv_undef);
- }
- }
-
#endif
#ifdef HAVE_LIBTT
Flines/t/t00flines.t
flip.im
font.c
-fontfiles/dcr10.afm
-fontfiles/dcr10.pfb
fontfiles/dodge.ttf
-fontfiles/ExistenceTest.afm please edit ExistenceTest.sfd in CVS
-fontfiles/ExistenceTest.pfb to change these files, edited and
fontfiles/ExistenceTest.ttf generated using pfaedit
fontfiles/ImUgly.ttf
fontfiles/NameTest.ttf test glyph_names() - see FT2/t/t10ft2.t
-fontfiles/SpaceTest.afm
-fontfiles/SpaceTest.pfb test bounding box with spaces in t30t1font.t
FT2/fontfiles/dodge.ttf
FT2/fontfiles/ExistenceTest.afm
FT2/fontfiles/ExistenceTest.pfb
lib/Imager/Font/FreeType2.pm
lib/Imager/Font/Image.pm
lib/Imager/Font/Truetype.pm
-lib/Imager/Font/Type1.pm
+lib/Imager/Font/Type1.pm Compatibilty wrapper for Imager::Font::T1
lib/Imager/Font/Wrap.pm
lib/Imager/Fountain.pm
lib/Imager/Handy.pod
t/t99thread.t Test wrt to perl threads
t/tr18561.t Regression tests
t/tr18561b.t
+T1/fontfiles/dcr10.afm
+T1/fontfiles/dcr10.pfb
+T1/fontfiles/ExistenceTest.afm please edit ExistenceTest.sfd in CVS
+T1/fontfiles/ExistenceTest.pfb to change these files, edited and
+T1/fontfiles/SpaceTest.afm test bounding box with spaces in t10type1.t
+T1/fontfiles/SpaceTest.pfb
+T1/imt1.c
+T1/imt1.h
+T1/Makefile.PL
+T1/t/t10type1.t
+T1/t/t20oo.t
+T1/T1.pm
+T1/T1.xs
tags.c
testimg/alpha16.tga 16-bit/pixel TGA with alpha "channel" RT 32926
testimg/bad1oflow.bmp 1-bit/pixel, overflow integer on 32-bit machines
^\.svn\b
/\.svn\b
+# git work files
+^\.git/
+^(?:.*/)?\.gitignore$
+
# editor trash
~$
(^|/)\#.*\#$
^PNG/testout/
^SGI/testout/
^TIFF/testout/
+^T1/testout/
# generated from .xs
^CountColor/CountColor\.c$
^PNG/PNG\.c$
^SGI/SGI\.c$
^TIFF/TIFF\.c$
+^T1/T1\.c$
^.*/Changes$
^blib/
# should use this option instead of the 'gif' option}
# };
- $formats{'T1-fonts'}={
- order=>'30',
- def=>'HAVE_LIBT1',
- inccheck=>sub { -e catfile($_[0], 't1lib.h') },
- libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
- libfiles=>'-lt1',
- objfiles=>'',
- docs=>q{
- postscript t1 fonts are scalable fonts. They can include
- ligatures and kerning information and generally yield good
- visual quality. We depend on libt1 to rasterize the fonts
- for use in images.}
- };
+# $formats{'T1-fonts'}={
+# order=>'30',
+# def=>'HAVE_LIBT1',
+# inccheck=>sub { -e catfile($_[0], 't1lib.h') },
+# libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
+# libfiles=>'-lt1',
+# objfiles=>'',
+# docs=>q{
+# postscript t1 fonts are scalable fonts. They can include
+# ligatures and kerning information and generally yield good
+# visual quality. We depend on libt1 to rasterize the fonts
+# for use in images.}
+# };
$formats{'TT-fonts'}=
{
--- /dev/null
+#!perl -w
+use strict;
+use ExtUtils::MakeMaker;
+use Getopt::Long;
+use Config;
+
+my $verbose = $ENV{IM_VERBOSE};
+my @libpaths;
+my @incpaths;
+
+GetOptions("incpath=s", \@incpaths,
+ "libpath=s" => \@libpaths,
+ "verbose|v" => \$verbose);
+
+our $BUILDING_IMAGER;
+
+my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
+
+my %opts =
+ (
+ NAME => 'Imager::Font::T1',
+ VERSION_FROM => 'T1.pm',
+ OBJECT => 'T1.o imt1.o',
+ clean => { FILES => 'testout' },
+ );
+
+my @inc;
+if ($BUILDING_IMAGER) {
+ push @inc, "-I..";
+ unshift @INC, "../lib";
+}
+else {
+ unshift @INC, "inc";
+ print "T1Lib: building independently\n";
+ require Imager::ExtUtils;
+ push @inc, Imager::ExtUtils->includes;
+ $opts{TYPEMAPS} = [ Imager::ExtUtils->typemap ];
+
+ # Imager required configure through use
+ my @Imager_req = ( Imager => "0.80_01" );
+ if ($MM_ver >= 6.46) {
+ $opts{META_MERGE} =
+ {
+ configure_requires =>
+ {
+ @Imager_req,
+ },
+ build_requires =>
+ {
+ @Imager_req,
+ "Test::More" => "0.47",
+ },
+ resources =>
+ {
+ homepage => "http://imager.perl.org/",
+ repository =>
+ {
+ url => "git://git.imager.perl.org/imager-type1.git",
+ web => "http://git.imager.perl.org/imager-type1.git/",
+ type => "git",
+ },
+ },
+ };
+ $opts{PREREQ_PM} =
+ {
+ @Imager_req,
+ };
+ }
+}
+
+require Imager::Probe;
+
+my %probe =
+ (
+ name => "T1Lib",
+ inccheck =>
+ sub { -e File::Spec->catfile($_[0], "t1lib.h") },
+ libbase => "t1",
+ testcode => _t1_test_code(),
+ testcodeheaders => [ "stdio.h", "string.h", "t1lib.h" ],
+ incpath => \@incpaths,
+ libpath => \@libpaths,
+ );
+
+my $probe_res = Imager::Probe->probe(\%probe);
+if ($probe_res) {
+ push @inc, $probe_res->{INC};
+ $opts{LIBS} = $probe_res->{LIBS};
+ $opts{DEFINE} = $probe_res->{DEFINE};
+ $opts{INC} = "@inc";
+
+ if ($MM_ver > 6.06) {
+ $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>';
+ $opts{ABSTRACT} = 'T1Lib font driver for Imager';
+ }
+
+ WriteMakefile(%opts);
+}
+else {
+ if ($BUILDING_IMAGER) {
+ ExtUtils::MakeMaker::WriteEmptyMakefile(%opts);
+ }
+ else {
+ # fail in good way
+ die "OS unsupported: T1Lib headers/libraries not found\n";
+ }
+}
+
+sub _t1_test_code {
+ return <<'CODE';
+int font_id;
+if (T1_InitLib(IGNORE_CONFIGFILE|IGNORE_FONTDATABASE) == NULL) {
+ fprintf(stderr, "T1Lib: Cannot initialize\n");
+ return 1;
+}
+T1_CloseLib();
+return 0;
+CODE
+}
+
--- /dev/null
+package Imager::Font::T1;
+use strict;
+use Imager::Color;
+use vars qw(@ISA $VERSION);
+@ISA = qw(Imager::Font);
+
+BEGIN {
+ $VERSION = "1.011";
+
+ eval {
+ require XSLoader;
+ XSLoader::load('Imager::Font::T1', $VERSION);
+ 1;
+ } or do {
+ require DynaLoader;
+ push @ISA, 'DynaLoader';
+ bootstrap Imager::Font::T1 $VERSION;
+ };
+}
+
+
+*_first = \&Imager::Font::_first;
+
+my $t1aa;
+
+# $T1AA is in there because for some reason (probably cache related) antialiasing
+# is a system wide setting in t1 lib.
+
+sub t1_set_aa_level {
+ if (!defined $t1aa or $_[0] != $t1aa) {
+ i_t1_set_aa($_[0]);
+ $t1aa=$_[0];
+ }
+}
+
+sub new {
+ my $class = shift;
+ my %hsh=(color=>Imager::Color->new(255,0,0,0),
+ size=>15,
+ @_);
+
+ unless ($hsh{file}) {
+ $Imager::ERRSTR = "No font file specified";
+ return;
+ }
+ unless (-e $hsh{file}) {
+ $Imager::ERRSTR = "Font file $hsh{file} not found";
+ return;
+ }
+ unless ($Imager::formats{t1}) {
+ $Imager::ERRSTR = "Type 1 fonts not supported in this build";
+ return;
+ }
+ # we want to avoid T1Lib's file search mechanism
+ unless ($hsh{file} =~ m!^/!
+ || $hsh{file} =~ m!^\.\/?/!
+ || $^O =~ /^(MSWin32|cygwin)$/ && $hsh{file} =~ /^[a-z]:/) {
+ $hsh{file} = './' . $hsh{file};
+ }
+
+ if($hsh{afm}) {
+ unless (-e $hsh{afm}) {
+ $Imager::ERRSTR = "Afm file $hsh{afm} not found";
+ return;
+ }
+ unless ($hsh{afm} =~ m!^/!
+ || $hsh{afm} =~ m!^\./!
+ || $^O =~ /^(MSWin32|cygwin)$/ && $hsh{file} =~ /^[a-z]:/) {
+ $hsh{file} = './' . $hsh{file};
+ }
+ } else {
+ $hsh{afm} = 0;
+ }
+
+ my $id = i_t1_new($hsh{file},$hsh{afm});
+ unless ($id >= 0) { # the low-level code may miss some error handling
+ $Imager::ERRSTR = "Could not load font ($id)";
+ return;
+ }
+ return bless {
+ id => $id,
+ aa => $hsh{aa} || 0,
+ file => $hsh{file},
+ type => 't1',
+ size => $hsh{size},
+ color => $hsh{color},
+ }, $class;
+}
+
+sub _draw {
+ my $self = shift;
+ my %input = @_;
+ t1_set_aa_level($input{aa});
+ my $flags = '';
+ $flags .= 'u' if $input{underline};
+ $flags .= 's' if $input{strikethrough};
+ $flags .= 'o' if $input{overline};
+ if (exists $input{channel}) {
+ i_t1_cp($input{image}{IMG}, $input{'x'}, $input{'y'},
+ $input{channel}, $self->{id}, $input{size},
+ $input{string}, length($input{string}), $input{align},
+ $input{utf8}, $flags);
+ } else {
+ i_t1_text($input{image}{IMG}, $input{'x'}, $input{'y'},
+ $input{color}, $self->{id}, $input{size},
+ $input{string}, length($input{string}),
+ $input{align}, $input{utf8}, $flags);
+ }
+
+ return $self;
+}
+
+sub _bounding_box {
+ my $self = shift;
+ my %input = @_;
+ my $flags = '';
+ $flags .= 'u' if $input{underline};
+ $flags .= 's' if $input{strikethrough};
+ $flags .= 'o' if $input{overline};
+ return i_t1_bbox($self->{id}, $input{size}, $input{string},
+ length($input{string}), $input{utf8}, $flags);
+}
+
+# check if the font has the characters in the given string
+sub has_chars {
+ my ($self, %hsh) = @_;
+
+ unless (defined $hsh{string} && length $hsh{string}) {
+ $Imager::ERRSTR = "No string supplied to \$font->has_chars()";
+ return;
+ }
+ return i_t1_has_chars($self->{id}, $hsh{string},
+ _first($hsh{'utf8'}, $self->{utf8}, 0));
+}
+
+sub utf8 {
+ 1;
+}
+
+sub face_name {
+ my ($self) = @_;
+
+ i_t1_face_name($self->{id});
+}
+
+sub glyph_names {
+ my ($self, %input) = @_;
+
+ my $string = $input{string};
+ defined $string
+ or return Imager->_set_error("no string parameter passed to glyph_names");
+ my $utf8 = _first($input{utf8} || 0);
+
+ i_t1_glyph_name($self->{id}, $string, $utf8);
+}
+
+
+1;
+
+__END__
+
+=head1 NAME
+
+ Imager::Font::Type1 - low-level functions for Type1 fonts
+
+=head1 DESCRIPTION
+
+Imager::Font creates a Imager::Font::Type1 object when asked to create
+a font object based on a C<.pfb> file.
+
+See Imager::Font to see how to use this type.
+
+This class provides low-level functions that require the caller to
+perform data validation
+
+By default Imager no longer creates the F<t1lib.log> log file. You
+can re-enable that by calling Imager::init() with the C<t1log> option:
+
+ Imager::init(t1log=>1);
+
+This must be called before creating any fonts.
+
+Currently specific to Imager::Font::Type1, you can use the following
+flags when drawing text or calculating a bounding box:
+
+=for stopwords overline strikethrough
+
+=over
+
+=item *
+
+C<underline> - Draw the text with an underline.
+
+=item *
+
+C<overline> - Draw the text with an overline.
+
+=item *
+
+C<strikethrough> - Draw the text with a strikethrough.
+
+=back
+
+Obviously, if you're calculating the bounding box the size of the line
+is included in the box, and the line isn't drawn :)
+
+=head1 AUTHOR
+
+Addi, Tony
+
+=cut
--- /dev/null
+#define PERL_NO_GET_CONTEXT
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include "imext.h"
+#include "imperl.h"
+#include "imt1.h"
+
+DEFINE_IMAGER_CALLBACKS;
+
+MODULE = Imager::Font::T1 PACKAGE = Imager::Font::T1
+
+undef_int
+i_init_t1(t1log)
+ int t1log
+
+void
+i_t1_set_aa(st)
+ int st
+
+int
+i_t1_new(pfb,afm)
+ char* pfb
+ char* afm
+
+int
+i_t1_destroy(font_id)
+ int font_id
+
+
+undef_int
+i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
+ Imager::ImgRaw im
+ int xb
+ int yb
+ int channel
+ int fontnum
+ float points
+ SV* str_sv
+ int align
+ int utf8
+ char* flags
+ PREINIT:
+ char *str;
+ STRLEN len;
+ CODE:
+#ifdef SvUTF8
+ if (SvUTF8(str_sv))
+ utf8 = 1;
+#endif
+ str = SvPV(str_sv, len);
+ RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
+ utf8,flags);
+ OUTPUT:
+ RETVAL
+
+
+void
+i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
+ int fontnum
+ float point
+ SV* str_sv
+ int utf8
+ char* flags
+ PREINIT:
+ char *str;
+ STRLEN len;
+ int cords[BOUNDING_BOX_COUNT];
+ int i;
+ int rc;
+ PPCODE:
+#ifdef SvUTF8
+ if (SvUTF8(str_sv))
+ utf8 = 1;
+#endif
+ str = SvPV(str_sv, len);
+ rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
+ if (rc > 0) {
+ EXTEND(SP, rc);
+ for (i = 0; i < rc; ++i)
+ PUSHs(sv_2mortal(newSViv(cords[i])));
+ }
+
+
+
+undef_int
+i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
+ Imager::ImgRaw im
+ int xb
+ int yb
+ Imager::Color cl
+ int fontnum
+ float points
+ SV* str_sv
+ int align
+ int utf8
+ char* flags
+ PREINIT:
+ char *str;
+ STRLEN len;
+ CODE:
+#ifdef SvUTF8
+ if (SvUTF8(str_sv))
+ utf8 = 1;
+#endif
+ str = SvPV(str_sv, len);
+ RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
+ utf8,flags);
+ OUTPUT:
+ RETVAL
+
+void
+i_t1_has_chars(handle, text_sv, utf8 = 0)
+ int handle
+ SV *text_sv
+ int utf8
+ PREINIT:
+ char const *text;
+ STRLEN len;
+ char *work;
+ int count;
+ int i;
+ PPCODE:
+#ifdef SvUTF8
+ if (SvUTF8(text_sv))
+ utf8 = 1;
+#endif
+ text = SvPV(text_sv, len);
+ work = mymalloc(len);
+ count = i_t1_has_chars(handle, text, len, utf8, work);
+ if (GIMME_V == G_ARRAY) {
+ EXTEND(SP, count);
+ for (i = 0; i < count; ++i) {
+ PUSHs(sv_2mortal(newSViv(work[i])));
+ }
+ }
+ else {
+ EXTEND(SP, 1);
+ PUSHs(sv_2mortal(newSVpv(work, count)));
+ }
+ myfree(work);
+
+void
+i_t1_face_name(handle)
+ int handle
+ PREINIT:
+ char name[255];
+ int len;
+ PPCODE:
+ len = i_t1_face_name(handle, name, sizeof(name));
+ if (len) {
+ EXTEND(SP, 1);
+ PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
+ }
+
+void
+i_t1_glyph_name(handle, text_sv, utf8 = 0)
+ int handle
+ SV *text_sv
+ int utf8
+ PREINIT:
+ char const *text;
+ STRLEN work_len;
+ size_t len;
+ char name[255];
+ PPCODE:
+#ifdef SvUTF8
+ if (SvUTF8(text_sv))
+ utf8 = 1;
+#endif
+ text = SvPV(text_sv, work_len);
+ len = work_len;
+ while (len) {
+ unsigned long ch;
+ if (utf8) {
+ ch = i_utf8_advance(&text, &len);
+ if (ch == ~0UL) {
+ i_push_error(0, "invalid UTF8 character");
+ break;
+ }
+ }
+ else {
+ ch = *text++;
+ --len;
+ }
+ EXTEND(SP, 1);
+ if (i_t1_glyph_name(handle, ch, name, sizeof(name))) {
+ PUSHs(sv_2mortal(newSVpv(name, 0)));
+ }
+ else {
+ PUSHs(&PL_sv_undef);
+ }
+ }
+
+BOOT:
+ PERL_INITIALIZE_IMAGER_CALLBACKS;
--- /dev/null
+StartFontMetrics 2.0
+Comment Generated by pfaedit
+Comment Creation Date: Thu Jul 20 21:57:23 2006
+FontName ExistenceTest
+FullName ExistenceTest
+FamilyName ExistenceTest
+Weight Medium
+Notice (Created by Tony Cook,,, with PfaEdit 1.0 (http://pfaedit.sf.net))
+ItalicAngle 0
+IsFixedPitch false
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.000
+EncodingScheme AdobeStandardEncoding
+FontBBox -60 -55 819 775
+StartCharMetrics 3
+C 0 ; WX 487 ; N uniFFFD ; B 72 87 414 396 ;
+C 33 ; WX 310 ; N exclam ; B 51 0 207 738 ;
+C 47 ; WX 761 ; N slash ; B -60 -55 819 775 ;
+EndCharMetrics
+EndFontMetrics
--- /dev/null
+StartFontMetrics 2.0
+Comment Generated by pfaedit
+Comment Creation Date: Thu Jul 20 21:51:08 2006
+FontName SpaceTest
+FullName SpaceTest
+FamilyName SpaceTest
+Weight Medium
+Notice (Created by Tony Cook,,, with FontForge 1.0 (http://fontforge.sf.net))
+ItalicAngle 0
+IsFixedPitch false
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.000
+EncodingScheme AdobeStandardEncoding
+FontBBox 72 -24 414 684
+StartCharMetrics 3
+C 0 ; WX 487 ; N uniFFFD ; B 72 87 414 396 ;
+C 32 ; WX 500 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 451 ; N exclam ; B 156 -24 312 684 ;
+EndCharMetrics
+EndFontMetrics
--- /dev/null
+StartFontMetrics 2.0
+FontName dcr10
+FullName dcr10
+FamilyName dcr10
+Weight Medium
+ItalicAngle 0.000000
+IsFixedPitch false
+UnderlinePosition -133
+UnderlineThickness 20
+Version 1.0\(Level-B\)
+FontBBox -55, -250, 1054, 913
+Notice Copyright \(C\) 1994, Basil K. Malyshev. All Rights Reserved.\nBaKoMa Fonts Collection, Level-B.
+EncodingScheme FontSpecific
+CapHeight 683
+XHeight 430
+Descender -194
+Ascender 694
+StartCharMetrics 256
+C 0 ; WX 499.89 ; N grave ; B 107 508 294 698 ;
+C 1 ; WX 499.89 ; N acute ; B 205 508 392 698 ;
+C 2 ; WX 499.89 ; N circumflex ; B 115 537 384 694 ;
+C 3 ; WX 499.89 ; N tilde ; B 83 572 416 668 ;
+C 4 ; WX 499.89 ; N dieresis ; B 101 565 398 669 ;
+C 5 ; WX 499.89 ; N hungarumlaut ; B 126 511 420 699 ;
+C 6 ; WX 749.83 ; N ring ; B 263 540 458 716 ;
+C 7 ; WX 499.89 ; N caron ; B 117 515 382 640 ;
+C 8 ; WX 499.89 ; N breve ; B 98 519 401 694 ;
+C 9 ; WX 499.89 ; N macron ; B 69 555 430 590 ;
+C 10 ; WX 277.72 ; N dotaccent ; B 84 559 194 669 ;
+C 11 ; WX 444.33 ; N cedilla ; B 129 -205 369 -22 ;
+C 12 ; WX 277.72 ; N ogonek ; B 9 -194 226 20 ;
+C 13 ; WX 277.72 ; N quotesinglbase ; B 112 -194 233 110 ;
+C 14 ; WX 444.33 ; N guilsinglleft ; B 94 26 330 457 ;
+C 15 ; WX 444.33 ; N guilsinglright ; B 94 26 360 457 ;
+C 16 ; WX 499.89 ; N quotedblleft ; B 148 390 466 694 ;
+C 17 ; WX 499.89 ; N quotedblright ; B 33 390 351 694 ;
+C 18 ; WX 499.89 ; N quotedblbase ; B 138 -194 456 110 ;
+C 19 ; WX 666.5 ; N guillemotleft ; B 94 26 553 457 ;
+C 20 ; WX 666.5 ; N guillemotright ; B 94 26 583 457 ;
+C 21 ; WX 499.89 ; N endash ; B 0 253 499 279 ; L hyphen emdash ;
+C 22 ; WX 999.78 ; N emdash ; B 0 253 999 279 ;
+C 23 ; WX 0 ; N compoundwordmark ; B 0 0 0 0 ;
+C 24 ; WX 388.78 ; N perthousand ; B 55 -56 333 347 ;
+C 25 ; WX 277.72 ; N dotlessi ; B 25 0 243 441 ;
+C 26 ; WX 305.5 ; N dotlessj ; B -55 -205 201 441 ;
+C 27 ; WX 583.17 ; N ff ; B 26 0 632 705 ; L i ffi ; L l ffl ;
+C 28 ; WX 555.44 ; N fi ; B 26 0 528 705 ;
+C 29 ; WX 555.44 ; N fl ; B 26 0 528 705 ;
+C 30 ; WX 833.11 ; N ffi ; B 26 0 807 705 ;
+C 31 ; WX 833.11 ; N ffl ; B 26 0 807 705 ;
+C 32 ; WX 499.89 ; N visiblespace ; B 42 -107 457 252 ;
+C 33 ; WX 277.72 ; N exclam ; B 84 0 194 716 ;
+C 34 ; WX 499.89 ; N quotedbl ; B 117 349 383 711 ;
+C 35 ; WX 833.11 ; N numbersign ; B 56 -194 776 694 ;
+C 36 ; WX 499.89 ; N dollar ; B 57 -56 444 750 ;
+C 37 ; WX 833.11 ; N percent ; B 56 -56 776 750 ;
+C 38 ; WX 777.61 ; N ampersand ; B 42 -22 727 716 ;
+C 39 ; WX 277.72 ; N quoteright ; B 84 390 208 694 ; L quoteright quotedblright ;
+C 40 ; WX 388.78 ; N parenleft ; B 97 -250 332 750 ;
+C 41 ; WX 388.78 ; N parenright ; B 56 -250 291 750 ;
+C 42 ; WX 499.89 ; N asterisk ; B 65 320 434 750 ;
+C 43 ; WX 777.61 ; N plus ; B 56 -83 721 583 ;
+C 44 ; WX 277.72 ; N comma ; B 84 -194 205 110 ; L comma quotedblbase ;
+C 45 ; WX 333.28 ; N hyphen ; B 11 184 276 246 ; L hyphen endash ;
+C 46 ; WX 277.72 ; N period ; B 84 0 194 110 ;
+C 47 ; WX 499.89 ; N slash ; B 56 -250 443 750 ;
+C 48 ; WX 499.89 ; N zero ; B 39 -22 460 666 ;
+C 49 ; WX 499.89 ; N one ; B 87 0 421 666 ;
+C 50 ; WX 499.89 ; N two ; B 50 0 449 666 ;
+C 51 ; WX 499.89 ; N three ; B 42 -22 457 666 ;
+C 52 ; WX 499.89 ; N four ; B 28 0 471 677 ;
+C 53 ; WX 499.89 ; N five ; B 50 -22 449 666 ;
+C 54 ; WX 499.89 ; N six ; B 42 -22 457 666 ;
+C 55 ; WX 499.89 ; N seven ; B 56 -22 485 676 ;
+C 56 ; WX 499.89 ; N eight ; B 42 -22 457 666 ;
+C 57 ; WX 499.89 ; N nine ; B 42 -22 457 666 ;
+C 58 ; WX 277.72 ; N colon ; B 84 0 194 430 ;
+C 59 ; WX 277.72 ; N semicolon ; B 84 -194 197 430 ;
+C 60 ; WX 777.61 ; N less ; B 83 -33 694 533 ; L less guillemotleft ;
+C 61 ; WX 777.61 ; N equal ; B 56 140 721 360 ;
+C 62 ; WX 777.61 ; N greater ; B 83 -33 694 533 ; L greater guillemotright ;
+C 63 ; WX 472.11 ; N question ; B 56 0 415 705 ;
+C 64 ; WX 777.61 ; N at ; B 56 -11 721 705 ;
+C 65 ; WX 749.83 ; N A ; B 18 0 703 716 ;
+C 66 ; WX 708.17 ; N B ; B 20 0 637 683 ;
+C 67 ; WX 722 ; N C ; B 56 -22 665 705 ;
+C 68 ; WX 763.72 ; N D ; B 19 0 693 683 ;
+C 69 ; WX 680.39 ; N E ; B 17 0 637 680 ;
+C 70 ; WX 652.61 ; N F ; B 17 0 596 680 ;
+C 71 ; WX 784.56 ; N G ; B 56 -22 735 705 ;
+C 72 ; WX 749.83 ; N H ; B 17 0 704 683 ;
+C 73 ; WX 361 ; N I ; B 12 0 321 683 ;
+C 74 ; WX 513.78 ; N J ; B 37 -22 465 683 ;
+C 75 ; WX 777.61 ; N K ; B 17 0 722 683 ;
+C 76 ; WX 624.83 ; N L ; B 17 0 568 683 ;
+C 77 ; WX 916.44 ; N M ; B 21 0 866 683 ;
+C 78 ; WX 749.83 ; N N ; B 17 0 704 683 ;
+C 79 ; WX 777.61 ; N O ; B 56 -22 721 705 ;
+C 80 ; WX 680.39 ; N P ; B 19 0 609 683 ;
+C 81 ; WX 777.61 ; N Q ; B 56 -194 727 705 ;
+C 82 ; WX 735.94 ; N R ; B 19 -22 718 683 ;
+C 83 ; WX 555.44 ; N S ; B 56 -22 498 705 ;
+C 84 ; WX 722 ; N T ; B 37 0 686 677 ;
+C 85 ; WX 749.83 ; N U ; B 17 -22 704 683 ;
+C 86 ; WX 749.83 ; N V ; B 5 -22 716 683 ;
+C 87 ; WX 1027.56 ; N W ; B 4 -22 995 683 ;
+C 88 ; WX 749.83 ; N X ; B 9 0 712 683 ;
+C 89 ; WX 749.83 ; N Y ; B -3 0 724 683 ;
+C 90 ; WX 611 ; N Z ; B 56 0 560 683 ;
+C 91 ; WX 277.72 ; N bracketleft ; B 103 -250 255 750 ;
+C 92 ; WX 499.89 ; N backslash ; B 56 -250 443 750 ;
+C 93 ; WX 277.72 ; N bracketright ; B 22 -250 174 750 ;
+C 94 ; WX 611 ; N asciicircum ; B 117 461 493 628 ;
+C 95 ; WX 777.61 ; N underscore ; B 83 -233 694 -193 ;
+C 96 ; WX 277.72 ; N quoteleft ; B 70 390 194 694 ; L quoteleft quotedblleft ;
+C 97 ; WX 499.89 ; N a ; B 40 -11 493 447 ;
+C 98 ; WX 555.44 ; N b ; B 26 -11 521 694 ;
+C 99 ; WX 444.33 ; N c ; B 33 -11 415 447 ;
+C 100 ; WX 555.44 ; N d ; B 33 -11 528 694 ;
+C 101 ; WX 444.33 ; N e ; B 28 -11 415 447 ;
+C 102 ; WX 305.5 ; N f ; B 26 0 354 705 ; L i fi ; L f ff ; L l fl ;
+C 103 ; WX 499.89 ; N g ; B 28 -206 485 452 ;
+C 104 ; WX 555.44 ; N h ; B 24 0 530 694 ;
+C 105 ; WX 277.72 ; N i ; B 25 0 243 669 ;
+C 106 ; WX 305.5 ; N j ; B -55 -205 201 669 ;
+C 107 ; WX 527.67 ; N k ; B 26 0 511 694 ;
+C 108 ; WX 277.72 ; N l ; B 25 0 251 694 ;
+C 109 ; WX 833.11 ; N m ; B 24 0 810 441 ;
+C 110 ; WX 555.44 ; N n ; B 24 0 530 441 ;
+C 111 ; WX 499.89 ; N o ; B 28 -11 471 447 ;
+C 112 ; WX 555.44 ; N p ; B 26 -194 521 441 ;
+C 113 ; WX 527.67 ; N q ; B 33 -194 529 441 ;
+C 114 ; WX 391.56 ; N r ; B 26 0 364 441 ;
+C 115 ; WX 394.33 ; N s ; B 33 -11 360 447 ;
+C 116 ; WX 388.78 ; N t ; B 19 -11 332 615 ;
+C 117 ; WX 555.44 ; N u ; B 24 -11 530 441 ;
+C 118 ; WX 527.67 ; N v ; B 19 -11 508 430 ;
+C 119 ; WX 722 ; N w ; B 18 -11 703 430 ;
+C 120 ; WX 527.67 ; N x ; B 12 0 516 430 ;
+C 121 ; WX 527.67 ; N y ; B 19 -205 508 430 ;
+C 122 ; WX 444.33 ; N z ; B 28 0 401 430 ;
+C 123 ; WX 499.89 ; N braceleft ; B 70 -250 429 750 ;
+C 124 ; WX 277.72 ; N bar ; B 119 -250 159 750 ;
+C 125 ; WX 499.89 ; N braceright ; B 70 -250 429 750 ;
+C 126 ; WX 611 ; N asciitilde ; B 83 572 527 668 ;
+C 127 ; WX 333.28 ; N hyphen ; B 11 184 276 246 ;
+C 128 ; WX 749.83 ; N Abreve ; B 18 0 703 891 ;
+C 129 ; WX 749.83 ; N Aogonek ; B 18 -188 740 716 ;
+C 130 ; WX 722 ; N Cacute ; B 56 -22 665 895 ;
+C 131 ; WX 722 ; N Ccaron ; B 56 -22 665 856 ;
+C 132 ; WX 763.72 ; N Dcaron ; B 19 0 693 856 ;
+C 133 ; WX 680.39 ; N Ecaron ; B 17 0 637 856 ;
+C 134 ; WX 680.39 ; N Eogonek ; B 17 -188 637 680 ;
+C 135 ; WX 784.56 ; N Gbreve ; B 56 -22 735 891 ;
+C 136 ; WX 624.83 ; N Lacute ; B 17 0 568 895 ;
+C 137 ; WX 624.83 ; N Lquoteright ; B 17 0 568 683 ;
+C 138 ; WX 624.83 ; N Lslash ; B 17 0 568 683 ;
+C 139 ; WX 749.83 ; N Nacute ; B 17 0 704 895 ;
+C 140 ; WX 749.83 ; N Ncaron ; B 17 0 704 856 ;
+C 141 ; WX 727.61 ; N Eng ; B 24 -22 676 694 ;
+C 142 ; WX 777.61 ; N Ohungarumlaut ; B 56 -22 721 895 ;
+C 143 ; WX 735.94 ; N Racute ; B 19 -22 718 895 ;
+C 144 ; WX 735.94 ; N Rcaron ; B 19 -22 718 856 ;
+C 145 ; WX 555.44 ; N Sacute ; B 56 -22 498 895 ;
+C 146 ; WX 555.44 ; N Scaron ; B 56 -22 498 856 ;
+C 147 ; WX 555.44 ; N Scedilla ; B 56 -205 498 705 ;
+C 148 ; WX 722 ; N Tcaron ; B 37 0 686 856 ;
+C 149 ; WX 722 ; N Tcedilla ; B 37 -205 686 677 ;
+C 150 ; WX 749.83 ; N Uhungarumlaut ; B 17 -22 704 895 ;
+C 151 ; WX 749.83 ; N Uring ; B 17 -22 704 913 ;
+C 152 ; WX 749.83 ; N Ydieresis ; B -3 0 724 839 ;
+C 153 ; WX 611 ; N Zacute ; B 56 0 560 895 ;
+C 154 ; WX 611 ; N Zcaron ; B 56 0 560 856 ;
+C 155 ; WX 611 ; N Zdotaccent ; B 56 0 560 891 ;
+C 156 ; WX 860.89 ; N IJ ; B 12 -22 798 683 ;
+C 157 ; WX 361 ; N Idotaccent ; B 12 0 321 877 ;
+C 158 ; WX 555.44 ; N dbar ; B 33 -11 528 694 ;
+C 159 ; WX 444.33 ; N section ; B 69 -205 374 705 ;
+C 160 ; WX 499.89 ; N abreve ; B 40 -11 493 694 ;
+C 161 ; WX 499.89 ; N aogonek ; B 40 -194 493 447 ;
+C 162 ; WX 444.33 ; N cacute ; B 33 -11 415 643 ;
+C 163 ; WX 444.33 ; N ccaron ; B 33 -11 415 604 ;
+C 164 ; WX 674.83 ; N dquoteright ; B 33 -11 665 694 ;
+C 165 ; WX 444.33 ; N ecaron ; B 28 -11 415 604 ;
+C 166 ; WX 444.33 ; N eogonek ; B 28 -194 415 447 ;
+C 167 ; WX 499.89 ; N gbreve ; B 28 -206 485 694 ;
+C 168 ; WX 277.72 ; N lacute ; B 25 0 282 907 ;
+C 169 ; WX 402.67 ; N lquoteright ; B 25 0 386 694 ;
+C 170 ; WX 277.72 ; N lslash ; B 18 0 258 694 ;
+C 171 ; WX 555.44 ; N nacute ; B 24 0 530 643 ;
+C 172 ; WX 555.44 ; N ncaron ; B 24 0 530 604 ;
+C 173 ; WX 555.44 ; N eng ; B 24 -205 452 441 ;
+C 174 ; WX 499.89 ; N ohungarumlaut ; B 28 -11 521 643 ;
+C 175 ; WX 391.56 ; N racute ; B 26 0 364 643 ;
+C 176 ; WX 391.56 ; N rcaron ; B 26 0 364 604 ;
+C 177 ; WX 394.33 ; N sacute ; B 33 -11 360 643 ;
+C 178 ; WX 394.33 ; N scaron ; B 33 -11 360 604 ;
+C 179 ; WX 394.33 ; N scedilla ; B 33 -205 360 447 ;
+C 180 ; WX 411 ; N tquoteright ; B 19 -11 401 704 ;
+C 181 ; WX 388.78 ; N tcedilla ; B 19 -205 359 615 ;
+C 182 ; WX 555.44 ; N uhungarumlaut ; B 24 -11 549 643 ;
+C 183 ; WX 555.44 ; N uring ; B 24 -11 530 661 ;
+C 184 ; WX 527.67 ; N ydieresis ; B 19 -205 508 586 ;
+C 185 ; WX 444.33 ; N zacute ; B 28 0 401 643 ;
+C 186 ; WX 444.33 ; N zcaron ; B 28 0 401 604 ;
+C 187 ; WX 444.33 ; N zdotaccent ; B 28 0 402 669 ;
+C 188 ; WX 583.17 ; N ij ; B 33 -205 485 669 ;
+C 189 ; WX 277.72 ; N exclamdown ; B 84 -216 194 500 ;
+C 190 ; WX 472.11 ; N questiondown ; B 56 -205 415 500 ;
+C 191 ; WX 638.72 ; N sterling ; B 56 -11 620 709 ;
+C 192 ; WX 749.83 ; N Agrave ; B 18 0 703 895 ;
+C 193 ; WX 749.83 ; N Aacute ; B 18 0 703 895 ;
+C 194 ; WX 749.83 ; N Acircumflex ; B 18 0 703 891 ;
+C 195 ; WX 749.83 ; N Atilde ; B 18 0 703 891 ;
+C 196 ; WX 749.83 ; N Adieresis ; B 18 0 703 839 ;
+C 197 ; WX 749.83 ; N Aring ; B 18 0 703 872 ;
+C 198 ; WX 902.56 ; N AE ; B 18 0 860 683 ;
+C 199 ; WX 722 ; N Ccedilla ; B 56 -205 665 705 ;
+C 200 ; WX 680.39 ; N Egrave ; B 17 0 637 895 ;
+C 201 ; WX 680.39 ; N Eacute ; B 17 0 637 895 ;
+C 202 ; WX 680.39 ; N Ecircumflex ; B 17 0 637 891 ;
+C 203 ; WX 680.39 ; N Edieresis ; B 17 0 637 839 ;
+C 204 ; WX 361 ; N Igrave ; B 12 0 321 895 ;
+C 205 ; WX 361 ; N Iacute ; B 12 0 321 895 ;
+C 206 ; WX 361 ; N Icircumflex ; B 12 0 321 891 ;
+C 207 ; WX 361 ; N Idieresis ; B 12 0 321 839 ;
+C 208 ; WX 763.72 ; N Eth ; B 19 0 693 683 ;
+C 209 ; WX 749.83 ; N Ntilde ; B 17 0 704 891 ;
+C 210 ; WX 777.61 ; N Ograve ; B 56 -22 721 895 ;
+C 211 ; WX 777.61 ; N Oacute ; B 56 -22 721 895 ;
+C 212 ; WX 777.61 ; N Ocircumflex ; B 56 -22 721 891 ;
+C 213 ; WX 777.61 ; N Otilde ; B 56 -22 721 891 ;
+C 214 ; WX 777.61 ; N Odieresis ; B 56 -22 721 839 ;
+C 215 ; WX 1013.67 ; N OE ; B 56 -22 971 705 ;
+C 216 ; WX 777.61 ; N Oslash ; B 56 -57 721 740 ;
+C 217 ; WX 749.83 ; N Ugrave ; B 17 -22 704 895 ;
+C 218 ; WX 749.83 ; N Uacute ; B 17 -22 704 895 ;
+C 219 ; WX 749.83 ; N Ucircumflex ; B 17 -22 704 891 ;
+C 220 ; WX 749.83 ; N Udieresis ; B 17 -22 704 839 ;
+C 221 ; WX 749.83 ; N Yacute ; B -3 0 724 895 ;
+C 222 ; WX 624.83 ; N Thorn ; B 20 0 554 683 ;
+C 223 ; WX 1110.83 ; N Germandbls ; B 56 -22 1054 705 ;
+C 224 ; WX 499.89 ; N agrave ; B 40 -11 493 643 ;
+C 225 ; WX 499.89 ; N aacute ; B 40 -11 493 643 ;
+C 226 ; WX 499.89 ; N acircumflex ; B 40 -11 493 639 ;
+C 227 ; WX 499.89 ; N atilde ; B 40 -11 493 669 ;
+C 228 ; WX 499.89 ; N adieresis ; B 40 -11 493 586 ;
+C 229 ; WX 499.89 ; N aring ; B 40 -11 493 661 ;
+C 230 ; WX 722 ; N ae ; B 43 -11 693 447 ;
+C 231 ; WX 444.33 ; N ccedilla ; B 33 -205 415 447 ;
+C 232 ; WX 444.33 ; N egrave ; B 28 -11 415 643 ;
+C 233 ; WX 444.33 ; N eacute ; B 28 -11 415 643 ;
+C 234 ; WX 444.33 ; N ecircumflex ; B 28 -11 415 639 ;
+C 235 ; WX 444.33 ; N edieresis ; B 28 -11 415 586 ;
+C 236 ; WX 277.72 ; N igrave ; B -6 0 243 643 ;
+C 237 ; WX 277.72 ; N iacute ; B 25 0 282 643 ;
+C 238 ; WX 277.72 ; N icircumflex ; B 3 0 274 639 ;
+C 239 ; WX 333.28 ; N idieresis ; B -9 0 289 586 ;
+C 240 ; WX 499.89 ; N eth ; B 28 -11 471 694 ;
+C 241 ; WX 555.44 ; N ntilde ; B 24 0 530 669 ;
+C 242 ; WX 499.89 ; N ograve ; B 28 -11 471 643 ;
+C 243 ; WX 499.89 ; N oacute ; B 28 -11 471 643 ;
+C 244 ; WX 499.89 ; N ocircumflex ; B 28 -11 471 639 ;
+C 245 ; WX 499.89 ; N otilde ; B 28 -11 471 669 ;
+C 246 ; WX 499.89 ; N odieresis ; B 28 -11 471 586 ;
+C 247 ; WX 777.61 ; N oe ; B 28 -11 749 447 ;
+C 248 ; WX 499.89 ; N oslash ; B 33 -103 466 534 ;
+C 249 ; WX 555.44 ; N ugrave ; B 24 -11 530 643 ;
+C 250 ; WX 555.44 ; N uacute ; B 24 -11 530 643 ;
+C 251 ; WX 555.44 ; N ucircumflex ; B 24 -11 530 639 ;
+C 252 ; WX 555.44 ; N udieresis ; B 24 -11 530 586 ;
+C 253 ; WX 527.67 ; N yacute ; B 19 -205 508 643 ;
+C 254 ; WX 555.44 ; N thorn ; B 25 -205 521 694 ;
+C 255 ; WX 499.89 ; N germandbls ; B 26 -11 471 705 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 471
+KPX A C -27.77
+KPX A G -27.77
+KPX A O -27.77
+KPX A Q -27.77
+KPX A T -83.31
+KPX A U -27.77
+KPX A V -111.08
+KPX A W -111.08
+KPX A Y -83.31
+KPX A t -27.77
+KPX Aacute C -27.77
+KPX Aacute G -27.77
+KPX Aacute O -27.77
+KPX Aacute Q -27.77
+KPX Aacute T -83.31
+KPX Aacute U -27.77
+KPX Aacute V -111.08
+KPX Aacute W -111.08
+KPX Aacute Y -83.31
+KPX Aacute t -27.77
+KPX Abreve C -27.77
+KPX Abreve G -27.77
+KPX Abreve O -27.77
+KPX Abreve Q -27.77
+KPX Abreve T -83.31
+KPX Abreve U -27.77
+KPX Abreve V -111.08
+KPX Abreve W -111.08
+KPX Abreve Y -83.31
+KPX Abreve t -27.77
+KPX Acircumflex C -27.77
+KPX Acircumflex G -27.77
+KPX Acircumflex O -27.77
+KPX Acircumflex Q -27.77
+KPX Acircumflex T -83.31
+KPX Acircumflex U -27.77
+KPX Acircumflex V -111.08
+KPX Acircumflex W -111.08
+KPX Acircumflex Y -83.31
+KPX Acircumflex t -27.77
+KPX Adieresis C -27.77
+KPX Adieresis G -27.77
+KPX Adieresis O -27.77
+KPX Adieresis Q -27.77
+KPX Adieresis T -83.31
+KPX Adieresis U -27.77
+KPX Adieresis V -111.08
+KPX Adieresis W -111.08
+KPX Adieresis Y -83.31
+KPX Adieresis t -27.77
+KPX Agrave C -27.77
+KPX Agrave G -27.77
+KPX Agrave O -27.77
+KPX Agrave Q -27.77
+KPX Agrave T -83.31
+KPX Agrave U -27.77
+KPX Agrave V -111.08
+KPX Agrave W -111.08
+KPX Agrave Y -83.31
+KPX Agrave t -27.77
+KPX Aogonek C -27.77
+KPX Aogonek G -27.77
+KPX Aogonek O -27.77
+KPX Aogonek Q -27.77
+KPX Aogonek T -83.31
+KPX Aogonek U -27.77
+KPX Aogonek V -111.08
+KPX Aogonek W -111.08
+KPX Aogonek Y -83.31
+KPX Aogonek t -27.77
+KPX Aring C -27.77
+KPX Aring G -27.77
+KPX Aring O -27.77
+KPX Aring Q -27.77
+KPX Aring T -83.31
+KPX Aring U -27.77
+KPX Aring V -111.08
+KPX Aring W -111.08
+KPX Aring Y -83.31
+KPX Aring t -27.77
+KPX Atilde C -27.77
+KPX Atilde G -27.77
+KPX Atilde O -27.77
+KPX Atilde Q -27.77
+KPX Atilde T -83.31
+KPX Atilde U -27.77
+KPX Atilde V -111.08
+KPX Atilde W -111.08
+KPX Atilde Y -83.31
+KPX Atilde t -27.77
+KPX D A -27.77
+KPX D V -27.77
+KPX D W -27.77
+KPX D X -27.77
+KPX D Y -27.77
+KPX F A -111.08
+KPX F C -27.77
+KPX F G -27.77
+KPX F O -27.77
+KPX F Q -27.77
+KPX F a -83.31
+KPX F e -83.31
+KPX F o -83.31
+KPX F r -83.31
+KPX F u -83.31
+KPX I I 27.77
+KPX K C -27.77
+KPX K G -27.77
+KPX K O -27.77
+KPX K Q -27.77
+KPX L T -83.31
+KPX L V -111.08
+KPX L W -111.08
+KPX L Y -83.31
+KPX O A -27.77
+KPX O V -27.77
+KPX O W -27.77
+KPX O X -27.77
+KPX O Y -27.77
+KPX P A -83.31
+KPX P a -27.77
+KPX P aacute -27.77
+KPX P acircumflex -27.77
+KPX P acircumflex -27.77
+KPX P adieresis -27.77
+KPX P ae -27.77
+KPX P agrave -27.77
+KPX P aogonek -27.77
+KPX P aring -27.77
+KPX P atilde -27.77
+KPX P cacute -27.77
+KPX P comma -83.31
+KPX P e -27.77
+KPX P eacute -27.77
+KPX P ecaron -27.77
+KPX P ecircumflex -27.77
+KPX P edieresis -27.77
+KPX P egrave -27.77
+KPX P eogonek -27.77
+KPX P o -27.77
+KPX P oacute -27.77
+KPX P ocircumflex -27.77
+KPX P odieresis -27.77
+KPX P oe -27.77
+KPX P ograve -27.77
+KPX P ohungarumlaut -27.77
+KPX P otilde -27.77
+KPX P period -83.31
+KPX R C -27.77
+KPX R G -27.77
+KPX R O -27.77
+KPX R Q -27.77
+KPX R T -83.31
+KPX R U -27.77
+KPX R V -111.08
+KPX R W -111.08
+KPX R Y -83.31
+KPX R t -27.77
+KPX T A -83.31
+KPX T a -83.31
+KPX T e -83.31
+KPX T o -83.31
+KPX T r -83.31
+KPX T u -83.31
+KPX T y -27.77
+KPX V A -111.08
+KPX V C -27.77
+KPX V G -27.77
+KPX V O -27.77
+KPX V Q -27.77
+KPX V a -83.31
+KPX V e -83.31
+KPX V o -83.31
+KPX V r -83.31
+KPX V u -83.31
+KPX W A -111.08
+KPX W C -27.77
+KPX W G -27.77
+KPX W O -27.77
+KPX W Q -27.77
+KPX W a -83.31
+KPX W e -83.31
+KPX W o -83.31
+KPX W r -83.31
+KPX W u -83.31
+KPX X C -27.77
+KPX X G -27.77
+KPX X O -27.77
+KPX X Q -27.77
+KPX Y A -83.31
+KPX Y a -83.31
+KPX Y e -83.31
+KPX Y o -83.31
+KPX Y r -83.31
+KPX Y u -83.31
+KPX a j 55.54
+KPX a v -27.77
+KPX a w -27.77
+KPX a y -27.77
+KPX b c 27.77
+KPX b cacute 27.77
+KPX b ccaron 27.77
+KPX b ccedilla 27.77
+KPX b d 27.77
+KPX b e 27.77
+KPX b eacute 27.77
+KPX b ecaron 27.77
+KPX b ecircumflex 27.77
+KPX b edieresis 27.77
+KPX b egrave 27.77
+KPX b eogonek 27.77
+KPX b j 55.54
+KPX b o 27.77
+KPX b oacute 27.77
+KPX b ocircumflex 27.77
+KPX b odieresis 27.77
+KPX b oe 27.77
+KPX b ograve 27.77
+KPX b ohungarumlaut 27.77
+KPX b otilde 27.77
+KPX b q 27.77
+KPX b v -27.77
+KPX b w -27.77
+KPX b x -27.77
+KPX b y -27.77
+KPX c h -27.77
+KPX c k -27.77
+KPX f bracketright 77.76
+KPX f exclam 77.76
+KPX f parenright 77.76
+KPX f question 77.76
+KPX f quoteright 77.76
+KPX ff bracketright 77.76
+KPX ff exclam 77.76
+KPX ff parenright 77.76
+KPX ff question 77.76
+KPX ff quoteright 77.76
+KPX g j 27.77
+KPX h b -27.77
+KPX h t -27.77
+KPX h u -27.77
+KPX h uacute -27.77
+KPX h ucircumflex -27.77
+KPX h udieresis -27.77
+KPX h ugrave -27.77
+KPX h uhungarumlaut -27.77
+KPX h uring -27.77
+KPX h v -27.77
+KPX h w -27.77
+KPX h y -27.77
+KPX k a -27.77
+KPX k a -55.54
+KPX k aacute -27.77
+KPX k aacute -55.54
+KPX k acircumflex -55.54
+KPX k acircumflex -55.54
+KPX k acircumflex -27.77
+KPX k acircumflex -27.77
+KPX k adieresis -27.77
+KPX k adieresis -55.54
+KPX k ae -55.54
+KPX k ae -27.77
+KPX k agrave -55.54
+KPX k agrave -27.77
+KPX k aogonek -55.54
+KPX k aogonek -27.77
+KPX k aring -55.54
+KPX k aring -27.77
+KPX k atilde -27.77
+KPX k atilde -55.54
+KPX k c -27.77
+KPX k cacute -27.77
+KPX k cacute -27.77
+KPX k cacute -55.54
+KPX k ccaron -27.77
+KPX k ccedilla -27.77
+KPX k e -27.77
+KPX k eacute -27.77
+KPX k ecaron -27.77
+KPX k ecircumflex -27.77
+KPX k edieresis -27.77
+KPX k egrave -27.77
+KPX k eogonek -27.77
+KPX k o -27.77
+KPX k oacute -27.77
+KPX k ocircumflex -27.77
+KPX k odieresis -27.77
+KPX k oe -27.77
+KPX k ograve -27.77
+KPX k ohungarumlaut -27.77
+KPX k otilde -27.77
+KPX m b -27.77
+KPX m t -27.77
+KPX m u -27.77
+KPX m uacute -27.77
+KPX m ucircumflex -27.77
+KPX m udieresis -27.77
+KPX m ugrave -27.77
+KPX m uhungarumlaut -27.77
+KPX m uring -27.77
+KPX m v -27.77
+KPX m w -27.77
+KPX m y -27.77
+KPX n b -27.77
+KPX n t -27.77
+KPX n u -27.77
+KPX n uacute -27.77
+KPX n ucircumflex -27.77
+KPX n udieresis -27.77
+KPX n ugrave -27.77
+KPX n uhungarumlaut -27.77
+KPX n uring -27.77
+KPX n v -27.77
+KPX n w -27.77
+KPX n y -27.77
+KPX o c 27.77
+KPX o cacute 27.77
+KPX o ccaron 27.77
+KPX o ccedilla 27.77
+KPX o d 27.77
+KPX o e 27.77
+KPX o eacute 27.77
+KPX o ecaron 27.77
+KPX o ecircumflex 27.77
+KPX o edieresis 27.77
+KPX o egrave 27.77
+KPX o eogonek 27.77
+KPX o j 55.54
+KPX o o 27.77
+KPX o oacute 27.77
+KPX o ocircumflex 27.77
+KPX o odieresis 27.77
+KPX o oe 27.77
+KPX o ograve 27.77
+KPX o ohungarumlaut 27.77
+KPX o otilde 27.77
+KPX o q 27.77
+KPX o v -27.77
+KPX o w -27.77
+KPX o x -27.77
+KPX o y -27.77
+KPX p c 27.77
+KPX p cacute 27.77
+KPX p ccaron 27.77
+KPX p ccedilla 27.77
+KPX p d 27.77
+KPX p e 27.77
+KPX p eacute 27.77
+KPX p ecaron 27.77
+KPX p ecircumflex 27.77
+KPX p edieresis 27.77
+KPX p egrave 27.77
+KPX p eogonek 27.77
+KPX p j 55.54
+KPX p o 27.77
+KPX p oacute 27.77
+KPX p ocircumflex 27.77
+KPX p odieresis 27.77
+KPX p oe 27.77
+KPX p ograve 27.77
+KPX p ohungarumlaut 27.77
+KPX p otilde 27.77
+KPX p q 27.77
+KPX p v -27.77
+KPX p w -27.77
+KPX p x -27.77
+KPX p y -27.77
+KPX quoteright exclam 111.08
+KPX quoteright question 111.08
+KPX t w -27.77
+KPX t y -27.77
+KPX u w -27.77
+KPX v a -27.77
+KPX v a -55.54
+KPX v aacute -27.77
+KPX v aacute -55.54
+KPX v acircumflex -55.54
+KPX v acircumflex -27.77
+KPX v acircumflex -27.77
+KPX v acircumflex -55.54
+KPX v adieresis -27.77
+KPX v adieresis -55.54
+KPX v ae -27.77
+KPX v ae -55.54
+KPX v agrave -27.77
+KPX v agrave -55.54
+KPX v aogonek -55.54
+KPX v aogonek -27.77
+KPX v aring -55.54
+KPX v aring -27.77
+KPX v atilde -55.54
+KPX v atilde -27.77
+KPX v c -27.77
+KPX v cacute -55.54
+KPX v cacute -27.77
+KPX v cacute -27.77
+KPX v ccaron -27.77
+KPX v ccedilla -27.77
+KPX v e -27.77
+KPX v eacute -27.77
+KPX v ecaron -27.77
+KPX v ecircumflex -27.77
+KPX v edieresis -27.77
+KPX v egrave -27.77
+KPX v eogonek -27.77
+KPX v o -27.77
+KPX v oacute -27.77
+KPX v ocircumflex -27.77
+KPX v odieresis -27.77
+KPX v oe -27.77
+KPX v ograve -27.77
+KPX v ohungarumlaut -27.77
+KPX v otilde -27.77
+KPX w a -27.77
+KPX w aacute -27.77
+KPX w acircumflex -27.77
+KPX w acircumflex -27.77
+KPX w adieresis -27.77
+KPX w ae -27.77
+KPX w agrave -27.77
+KPX w aogonek -27.77
+KPX w aring -27.77
+KPX w atilde -27.77
+KPX w c -27.77
+KPX w cacute -27.77
+KPX w cacute -27.77
+KPX w ccaron -27.77
+KPX w ccedilla -27.77
+KPX w e -27.77
+KPX w eacute -27.77
+KPX w ecaron -27.77
+KPX w ecircumflex -27.77
+KPX w edieresis -27.77
+KPX w egrave -27.77
+KPX w eogonek -27.77
+KPX w o -27.77
+KPX w oacute -27.77
+KPX w ocircumflex -27.77
+KPX w odieresis -27.77
+KPX w oe -27.77
+KPX w ograve -27.77
+KPX w ohungarumlaut -27.77
+KPX w otilde -27.77
+KPX y a -27.77
+KPX y aacute -27.77
+KPX y acircumflex -27.77
+KPX y acircumflex -27.77
+KPX y adieresis -27.77
+KPX y ae -27.77
+KPX y agrave -27.77
+KPX y aogonek -27.77
+KPX y aring -27.77
+KPX y atilde -27.77
+KPX y cacute -27.77
+KPX y comma -83.31
+KPX y e -27.77
+KPX y eacute -27.77
+KPX y ecaron -27.77
+KPX y ecircumflex -27.77
+KPX y edieresis -27.77
+KPX y egrave -27.77
+KPX y eogonek -27.77
+KPX y o -27.77
+KPX y oacute -27.77
+KPX y ocircumflex -27.77
+KPX y odieresis -27.77
+KPX y oe -27.77
+KPX y ograve -27.77
+KPX y ohungarumlaut -27.77
+KPX y otilde -27.77
+KPX y period -83.31
+EndKernPairs
+EndKernData
+EndFontMetrics
--- /dev/null
+#include "imext.h"
+#include "imt1.h"
+#include <t1lib.h>
+#include <string.h>
+
+static int t1_get_flags(char const *flags);
+static char *t1_from_utf8(char const *in, size_t len, int *outlen);
+
+static void t1_push_error(void);
+
+static int t1_active_fonts = 0;
+static int t1_initialized = 0;
+
+/*
+=item i_init_t1(t1log)
+
+Initializes the t1lib font rendering engine.
+
+=cut
+*/
+
+undef_int
+i_init_t1(int t1log) {
+ int init_flags = IGNORE_CONFIGFILE|IGNORE_FONTDATABASE;
+ mm_log((1,"init_t1()\n"));
+
+ i_clear_error();
+
+ if (t1_active_fonts) {
+ mm_log((1, "Cannot re-initialize T1 - active fonts\n"));
+ i_push_error(0, "Cannot re-initialize T1 - active fonts");
+ return 1;
+ }
+
+ if (t1_initialized) {
+ T1_CloseLib();
+ }
+
+ if (t1log)
+ init_flags |= LOGFILE;
+ if ((T1_InitLib(init_flags) == NULL)){
+ mm_log((1,"Initialization of t1lib failed\n"));
+ i_push_error(0, "T1_InitLib failed");
+ return(1);
+ }
+ T1_SetLogLevel(T1LOG_DEBUG);
+ i_t1_set_aa(1); /* Default Antialias value */
+
+ ++t1_initialized;
+
+ return(0);
+}
+
+/*
+=item i_close_t1()
+
+Shuts the t1lib font rendering engine down.
+
+ This it seems that this function is never used.
+
+=cut
+*/
+
+void
+i_close_t1(void) {
+ T1_CloseLib();
+ t1_initialized = 0;
+}
+
+
+/*
+=item i_t1_new(pfb, afm)
+
+Loads the fonts with the given filenames, returns its font id
+
+ pfb - path to pfb file for font
+ afm - path to afm file for font
+
+=cut
+*/
+
+int
+i_t1_new(char *pfb,char *afm) {
+ int font_id;
+
+ i_clear_error();
+
+ if (!t1_initialized && i_init_t1(0))
+ return -1;
+
+ mm_log((1,"i_t1_new(pfb %s,afm %s)\n",pfb,(afm?afm:"NULL")));
+ font_id = T1_AddFont(pfb);
+ if (font_id<0) {
+ mm_log((1,"i_t1_new: Failed to load pfb file '%s' - return code %d.\n",pfb,font_id));
+ return font_id;
+ }
+
+ if (afm != NULL) {
+ mm_log((1,"i_t1_new: requesting afm file '%s'.\n",afm));
+ if (T1_SetAfmFileName(font_id,afm)<0) mm_log((1,"i_t1_new: afm loading of '%s' failed.\n",afm));
+ }
+
+ ++t1_active_fonts;
+
+ return font_id;
+}
+
+/*
+=item i_t1_destroy(font_id)
+
+Frees resources for a t1 font with given font id.
+
+ font_id - number of the font to free
+
+=cut
+*/
+
+int
+i_t1_destroy(int font_id) {
+ mm_log((1,"i_t1_destroy(font_id %d)\n",font_id));
+
+ --t1_active_fonts;
+
+ return T1_DeleteFont(font_id);
+}
+
+
+/*
+=item i_t1_set_aa(st)
+
+Sets the antialiasing level of the t1 library.
+
+ st - 0 = NONE, 1 = LOW, 2 = HIGH.
+
+=cut
+*/
+
+void
+i_t1_set_aa(int st) {
+ int i;
+ unsigned long cst[17];
+ switch(st) {
+ case 0:
+ T1_AASetBitsPerPixel( 8 );
+ T1_AASetLevel( T1_AA_NONE );
+ T1_AANSetGrayValues( 0, 255 );
+ mm_log((1,"setting T1 antialias to none\n"));
+ break;
+ case 1:
+ T1_AASetBitsPerPixel( 8 );
+ T1_AASetLevel( T1_AA_LOW );
+ T1_AASetGrayValues( 0,65,127,191,255 );
+ mm_log((1,"setting T1 antialias to low\n"));
+ break;
+ case 2:
+ T1_AASetBitsPerPixel(8);
+ T1_AASetLevel(T1_AA_HIGH);
+ for(i=0;i<17;i++) cst[i]=(i*255)/16;
+ T1_AAHSetGrayValues( cst );
+ mm_log((1,"setting T1 antialias to high\n"));
+ }
+}
+
+
+/*
+=item i_t1_cp(im, xb, yb, channel, fontnum, points, str, len, align)
+
+Interface to text rendering into a single channel in an image
+
+ im pointer to image structure
+ xb x coordinate of start of string
+ yb y coordinate of start of string ( see align )
+ channel - destination channel
+ fontnum - t1 library font id
+ points - number of points in fontheight
+ str - string to render
+ len - string length
+ align - (0 - top of font glyph | 1 - baseline )
+
+=cut
+*/
+
+undef_int
+i_t1_cp(i_img *im,int xb,int yb,int channel,int fontnum,float points,char* str,size_t len,int align, int utf8, char const *flags) {
+ GLYPH *glyph;
+ int xsize,ysize,x,y;
+ i_color val;
+ int mod_flags = t1_get_flags(flags);
+
+ unsigned int ch_mask_store;
+
+ if (im == NULL) { mm_log((1,"i_t1_cp: Null image in input\n")); return(0); }
+
+ if (utf8) {
+ int worklen;
+ char *work = t1_from_utf8(str, len, &worklen);
+ glyph=T1_AASetString( fontnum, work, worklen, 0, mod_flags, points, NULL);
+ myfree(work);
+ }
+ else {
+ glyph=T1_AASetString( fontnum, str, len, 0, mod_flags, points, NULL);
+ }
+ if (glyph == NULL)
+ return 0;
+
+ mm_log((1,"metrics: ascent: %d descent: %d\n",glyph->metrics.ascent,glyph->metrics.descent));
+ mm_log((1," leftSideBearing: %d rightSideBearing: %d\n",glyph->metrics.leftSideBearing,glyph->metrics.rightSideBearing));
+ mm_log((1," advanceX: %d advanceY: %d\n",glyph->metrics.advanceX,glyph->metrics.advanceY));
+ mm_log((1,"bpp: %d\n",glyph->bpp));
+
+ xsize=glyph->metrics.rightSideBearing-glyph->metrics.leftSideBearing;
+ ysize=glyph->metrics.ascent-glyph->metrics.descent;
+
+ mm_log((1,"width: %d height: %d\n",xsize,ysize));
+
+ ch_mask_store=im->ch_mask;
+ im->ch_mask=1<<channel;
+
+ if (align==1) { xb+=glyph->metrics.leftSideBearing; yb-=glyph->metrics.ascent; }
+
+ for(y=0;y<ysize;y++) for(x=0;x<xsize;x++) {
+ val.channel[channel]=glyph->bits[y*xsize+x];
+ i_ppix(im,x+xb,y+yb,&val);
+ }
+
+ im->ch_mask=ch_mask_store;
+ return 1;
+}
+
+static void
+t1_fix_bbox(BBox *bbox, const char *str, size_t len, int advance,
+ int space_position) {
+ /* never called with len == 0 */
+ if (str[0] == space_position && bbox->llx > 0)
+ bbox->llx = 0;
+ if (str[len-1] == space_position && bbox->urx < advance)
+ bbox->urx = advance;
+ if (bbox->lly > bbox->ury)
+ bbox->lly = bbox->ury = 0;
+}
+
+/*
+=item i_t1_bbox(handle, fontnum, points, str, len, cords)
+
+function to get a strings bounding box given the font id and sizes
+
+ handle - pointer to font handle
+ fontnum - t1 library font id
+ points - number of points in fontheight
+ str - string to measure
+ len - string length
+ cords - the bounding box (modified in place)
+
+=cut
+*/
+
+int
+i_t1_bbox(int fontnum,float points,const char *str,size_t len,int cords[6], int utf8,char const *flags) {
+ BBox bbox;
+ BBox gbbox;
+ int mod_flags = t1_get_flags(flags);
+ int advance;
+ int space_position = T1_GetEncodingIndex(fontnum, "space");
+
+ mm_log((1,"i_t1_bbox(fontnum %d,points %.2f,str '%.*s', len %d)\n",fontnum,points,len,str,len));
+ T1_LoadFont(fontnum); /* FIXME: Here a return code is ignored - haw haw haw */
+
+ if (len == 0) {
+ /* len == 0 has special meaning to T1lib, but it means there's
+ nothing to draw, so return that */
+ bbox.llx = bbox.lly = bbox.urx = bbox.ury = 0;
+ advance = 0;
+ }
+ else {
+ if (utf8) {
+ int worklen;
+ char *work = t1_from_utf8(str, len, &worklen);
+ advance = T1_GetStringWidth(fontnum, work, worklen, 0, mod_flags);
+ bbox = T1_GetStringBBox(fontnum,work,worklen,0,mod_flags);
+ t1_fix_bbox(&bbox, work, worklen, advance, space_position);
+ myfree(work);
+ }
+ else {
+ advance = T1_GetStringWidth(fontnum, (char *)str, len, 0, mod_flags);
+ bbox = T1_GetStringBBox(fontnum,(char *)str,len,0,mod_flags);
+ t1_fix_bbox(&bbox, str, len, advance, space_position);
+ }
+ }
+ gbbox = T1_GetFontBBox(fontnum);
+
+ mm_log((1,"bbox: (%d,%d,%d,%d)\n",
+ (int)(bbox.llx*points/1000),
+ (int)(gbbox.lly*points/1000),
+ (int)(bbox.urx*points/1000),
+ (int)(gbbox.ury*points/1000),
+ (int)(bbox.lly*points/1000),
+ (int)(bbox.ury*points/1000) ));
+
+
+ cords[BBOX_NEG_WIDTH]=((float)bbox.llx*points)/1000;
+ cords[BBOX_POS_WIDTH]=((float)bbox.urx*points)/1000;
+
+ cords[BBOX_GLOBAL_DESCENT]=((float)gbbox.lly*points)/1000;
+ cords[BBOX_GLOBAL_ASCENT]=((float)gbbox.ury*points)/1000;
+
+ cords[BBOX_DESCENT]=((float)bbox.lly*points)/1000;
+ cords[BBOX_ASCENT]=((float)bbox.ury*points)/1000;
+
+ cords[BBOX_ADVANCE_WIDTH] = ((float)advance * points)/1000;
+ cords[BBOX_RIGHT_BEARING] =
+ cords[BBOX_ADVANCE_WIDTH] - cords[BBOX_POS_WIDTH];
+
+ return BBOX_RIGHT_BEARING+1;
+}
+
+
+/*
+=item i_t1_text(im, xb, yb, cl, fontnum, points, str, len, align)
+
+Interface to text rendering in a single color onto an image
+
+ im - pointer to image structure
+ xb - x coordinate of start of string
+ yb - y coordinate of start of string ( see align )
+ cl - color to draw the text in
+ fontnum - t1 library font id
+ points - number of points in fontheight
+ str - char pointer to string to render
+ len - string length
+ align - (0 - top of font glyph | 1 - baseline )
+
+=cut
+*/
+
+undef_int
+i_t1_text(i_img *im,int xb,int yb,const i_color *cl,int fontnum,float points,const char* str,size_t len,int align, int utf8, char const *flags) {
+ GLYPH *glyph;
+ int xsize,ysize,y;
+ int mod_flags = t1_get_flags(flags);
+ i_render *r;
+
+ if (im == NULL) { mm_log((1,"i_t1_cp: Null image in input\n")); return(0); }
+
+ if (utf8) {
+ int worklen;
+ char *work = t1_from_utf8(str, len, &worklen);
+ glyph=T1_AASetString( fontnum, work, worklen, 0, mod_flags, points, NULL);
+ myfree(work);
+ }
+ else {
+ /* T1_AASetString() accepts a char * not a const char */
+ glyph=T1_AASetString( fontnum, (char *)str, len, 0, mod_flags, points, NULL);
+ }
+ if (glyph == NULL)
+ return 0;
+
+ mm_log((1,"metrics: ascent: %d descent: %d\n",glyph->metrics.ascent,glyph->metrics.descent));
+ mm_log((1," leftSideBearing: %d rightSideBearing: %d\n",glyph->metrics.leftSideBearing,glyph->metrics.rightSideBearing));
+ mm_log((1," advanceX: %d advanceY: %d\n",glyph->metrics.advanceX,glyph->metrics.advanceY));
+ mm_log((1,"bpp: %d\n",glyph->bpp));
+
+ xsize=glyph->metrics.rightSideBearing-glyph->metrics.leftSideBearing;
+ ysize=glyph->metrics.ascent-glyph->metrics.descent;
+
+ mm_log((1,"width: %d height: %d\n",xsize,ysize));
+
+ if (align==1) { xb+=glyph->metrics.leftSideBearing; yb-=glyph->metrics.ascent; }
+
+ r = i_render_new(im, xsize);
+ for(y=0;y<ysize;y++) {
+ i_render_color(r, xb, yb+y, xsize, (unsigned char *)glyph->bits+y*xsize, cl);
+ }
+ i_render_delete(r);
+
+ return 1;
+}
+
+/*
+=item t1_get_flags(flags)
+
+Processes the characters in I<flags> to create a mod_flags value used
+by some T1Lib functions.
+
+=cut
+ */
+static int
+t1_get_flags(char const *flags) {
+ int mod_flags = T1_KERNING;
+
+ while (*flags) {
+ switch (*flags++) {
+ case 'u': case 'U': mod_flags |= T1_UNDERLINE; break;
+ case 'o': case 'O': mod_flags |= T1_OVERLINE; break;
+ case 's': case 'S': mod_flags |= T1_OVERSTRIKE; break;
+ /* ignore anything we don't recognize */
+ }
+ }
+
+ return mod_flags;
+}
+
+/*
+=item t1_from_utf8(char const *in, size_t len, int *outlen)
+
+Produces an unencoded version of I<in> by dropping any Unicode
+character over 255.
+
+Returns a newly allocated buffer which should be freed with myfree().
+Sets *outlen to the number of bytes used in the output string.
+
+=cut
+*/
+
+static char *
+t1_from_utf8(char const *in, size_t len, int *outlen) {
+ /* at this point len is from a perl SV, so can't approach MAXINT */
+ char *out = mymalloc(len+1); /* checked 5Nov05 tonyc */
+ char *p = out;
+ unsigned long c;
+
+ while (len) {
+ c = i_utf8_advance(&in, &len);
+ if (c == ~0UL) {
+ myfree(out);
+ i_push_error(0, "invalid UTF8 character");
+ return 0;
+ }
+ /* yeah, just drop them */
+ if (c < 0x100) {
+ *p++ = (char)c;
+ }
+ }
+ *p = '\0';
+ *outlen = p - out;
+
+ return out;
+}
+
+/*
+=item i_t1_has_chars(font_num, text, len, utf8, out)
+
+Check if the given characters are defined by the font. Note that len
+is the number of bytes, not the number of characters (when utf8 is
+non-zero).
+
+out[char index] will be true if the character exists.
+
+Accepts UTF-8, but since T1 can only have 256 characters, any chars
+with values over 255 will simply be returned as false.
+
+Returns the number of characters that were checked.
+
+=cut
+*/
+
+int
+i_t1_has_chars(int font_num, const char *text, size_t len, int utf8,
+ char *out) {
+ int count = 0;
+
+ mm_log((1, "i_t1_has_chars(font_num %d, text %p, len %d, utf8 %d)\n",
+ font_num, text, len, utf8));
+
+ i_clear_error();
+ if (T1_LoadFont(font_num)) {
+ t1_push_error();
+ return 0;
+ }
+
+ while (len) {
+ unsigned long c;
+ if (utf8) {
+ c = i_utf8_advance(&text, &len);
+ if (c == ~0UL) {
+ i_push_error(0, "invalid UTF8 character");
+ return 0;
+ }
+ }
+ else {
+ c = (unsigned char)*text++;
+ --len;
+ }
+
+ if (c >= 0x100) {
+ /* limit of 256 characters for T1 */
+ *out++ = 0;
+ }
+ else {
+ char const * name = T1_GetCharName(font_num, (unsigned char)c);
+
+ if (name) {
+ *out++ = strcmp(name, ".notdef") != 0;
+ }
+ else {
+ mm_log((2, " No name found for character %lx\n", c));
+ *out++ = 0;
+ }
+ }
+ ++count;
+ }
+
+ return count;
+}
+
+/*
+=item i_t1_face_name(font_num, name_buf, name_buf_size)
+
+Copies the face name of the given C<font_num> to C<name_buf>. Returns
+the number of characters required to store the name (which can be
+larger than C<name_buf_size>, including the space required to store
+the terminating NUL).
+
+If name_buf is too small (as specified by name_buf_size) then the name
+will be truncated. name_buf will always be NUL termintaed.
+
+=cut
+*/
+
+int
+i_t1_face_name(int font_num, char *name_buf, size_t name_buf_size) {
+ char *name;
+
+ T1_errno = 0;
+ if (T1_LoadFont(font_num)) {
+ t1_push_error();
+ return 0;
+ }
+ name = T1_GetFontName(font_num);
+
+ if (name) {
+ strncpy(name_buf, name, name_buf_size);
+ name_buf[name_buf_size-1] = '\0';
+ return strlen(name) + 1;
+ }
+ else {
+ t1_push_error();
+ return 0;
+ }
+}
+
+int
+i_t1_glyph_name(int font_num, unsigned long ch, char *name_buf,
+ size_t name_buf_size) {
+ char *name;
+
+ i_clear_error();
+ if (ch > 0xFF) {
+ return 0;
+ }
+ if (T1_LoadFont(font_num)) {
+ t1_push_error();
+ return 0;
+ }
+ name = T1_GetCharName(font_num, (unsigned char)ch);
+ if (name) {
+ if (strcmp(name, ".notdef")) {
+ strncpy(name_buf, name, name_buf_size);
+ name_buf[name_buf_size-1] = '\0';
+ return strlen(name) + 1;
+ }
+ else {
+ return 0;
+ }
+ }
+ else {
+ t1_push_error();
+ return 0;
+ }
+}
+
+static void
+t1_push_error(void) {
+ switch (T1_errno) {
+ case 0:
+ i_push_error(0, "No error");
+ break;
+
+#ifdef T1ERR_SCAN_FONT_FORMAT
+ case T1ERR_SCAN_FONT_FORMAT:
+ i_push_error(T1ERR_SCAN_FONT_FORMAT, "SCAN_FONT_FORMAT");
+ break;
+#endif
+
+#ifdef T1ERR_SCAN_FILE_OPEN_ERR
+ case T1ERR_SCAN_FILE_OPEN_ERR:
+ i_push_error(T1ERR_SCAN_FILE_OPEN_ERR, "SCAN_FILE_OPEN_ERR");
+ break;
+#endif
+
+#ifdef T1ERR_SCAN_OUT_OF_MEMORY
+ case T1ERR_SCAN_OUT_OF_MEMORY:
+ i_push_error(T1ERR_SCAN_OUT_OF_MEMORY, "SCAN_OUT_OF_MEMORY");
+ break;
+#endif
+
+#ifdef T1ERR_SCAN_ERROR
+ case T1ERR_SCAN_ERROR:
+ i_push_error(T1ERR_SCAN_ERROR, "SCAN_ERROR");
+ break;
+#endif
+
+#ifdef T1ERR_SCAN_FILE_EOF
+ case T1ERR_SCAN_FILE_EOF:
+ i_push_error(T1ERR_SCAN_FILE_EOF, "SCAN_FILE_EOF");
+ break;
+#endif
+
+#ifdef T1ERR_PATH_ERROR
+ case T1ERR_PATH_ERROR:
+ i_push_error(T1ERR_PATH_ERROR, "PATH_ERROR");
+ break;
+#endif
+
+#ifdef T1ERR_PARSE_ERROR
+ case T1ERR_PARSE_ERROR:
+ i_push_error(T1ERR_PARSE_ERROR, "PARSE_ERROR");
+ break;
+#endif
+
+#ifdef T1ERR_TYPE1_ABORT
+ case T1ERR_TYPE1_ABORT:
+ i_push_error(T1ERR_TYPE1_ABORT, "TYPE1_ABORT");
+ break;
+#endif
+
+#ifdef T1ERR_INVALID_FONTID
+ case T1ERR_INVALID_FONTID:
+ i_push_error(T1ERR_INVALID_FONTID, "INVALID_FONTID");
+ break;
+#endif
+
+#ifdef T1ERR_INVALID_PARAMETER
+ case T1ERR_INVALID_PARAMETER:
+ i_push_error(T1ERR_INVALID_PARAMETER, "INVALID_PARAMETER");
+ break;
+#endif
+
+#ifdef T1ERR_OP_NOT_PERMITTED
+ case T1ERR_OP_NOT_PERMITTED:
+ i_push_error(T1ERR_OP_NOT_PERMITTED, "OP_NOT_PERMITTED");
+ break;
+#endif
+
+#ifdef T1ERR_ALLOC_MEM
+ case T1ERR_ALLOC_MEM:
+ i_push_error(T1ERR_ALLOC_MEM, "ALLOC_MEM");
+ break;
+#endif
+
+#ifdef T1ERR_FILE_OPEN_ERR
+ case T1ERR_FILE_OPEN_ERR:
+ i_push_error(T1ERR_FILE_OPEN_ERR, "FILE_OPEN_ERR");
+ break;
+#endif
+
+#ifdef T1ERR_UNSPECIFIED
+ case T1ERR_UNSPECIFIED:
+ i_push_error(T1ERR_UNSPECIFIED, "UNSPECIFIED");
+ break;
+#endif
+
+#ifdef T1ERR_NO_AFM_DATA
+ case T1ERR_NO_AFM_DATA:
+ i_push_error(T1ERR_NO_AFM_DATA, "NO_AFM_DATA");
+ break;
+#endif
+
+#ifdef T1ERR_X11
+ case T1ERR_X11:
+ i_push_error(T1ERR_X11, "X11");
+ break;
+#endif
+
+#ifdef T1ERR_COMPOSITE_CHAR
+ case T1ERR_COMPOSITE_CHAR:
+ i_push_error(T1ERR_COMPOSITE_CHAR, "COMPOSITE_CHAR");
+ break;
+#endif
+
+ default:
+ i_push_errorf(T1_errno, "unknown error %d", (int)T1_errno);
+ }
+}
+
--- /dev/null
+#ifndef IMAGER_IMT1_H
+#define IMAGER_IMT1_H
+
+#include "imdatatypes.h"
+
+extern undef_int
+i_init_t1(int t1log);
+
+extern void
+i_close_t1(void);
+
+extern int
+i_t1_new(char *pfb,char *afm);
+
+extern int
+i_t1_destroy(int font_id);
+
+extern void
+i_t1_set_aa(int st);
+
+extern undef_int
+i_t1_cp(i_img *im,int xb,int yb,int channel,int fontnum,float points,char* str,size_t len,int align, int utf8, char const *flags);
+
+extern int
+i_t1_bbox(int fontnum,float points,const char *str,size_t len,int cords[6], int utf8,char const *flags);
+
+extern undef_int
+i_t1_text(i_img *im,int xb,int yb,const i_color *cl,int fontnum,float points,const char* str,size_t len,int align, int utf8, char const *flags);
+
+extern int
+i_t1_has_chars(int font_num, const char *text, size_t len, int utf8,
+ char *out);
+
+extern int
+i_t1_face_name(int font_num, char *name_buf, size_t name_buf_size);
+
+extern int
+i_t1_glyph_name(int font_num, unsigned long ch, char *name_buf,
+ size_t name_buf_size);
+#endif
--- /dev/null
+#!perl -w
+use strict;
+use Test::More;
+use Imager ':all';
+use Imager::Test qw(diff_text_with_nul is_color3);
+use Imager::Font::T1;
+use Cwd qw(getcwd abs_path);
+
+#$Imager::DEBUG=1;
+
+plan tests => 97;
+
+ok($Imager::formats{t1}, "must have t1");
+
+ok((-d "testout" or mkdir "testout"), "make output directory");
+
+-d "testout" or mkdir "testout";
+
+init_log("testout/t10type1.log",1);
+
+my $deffont = 'fontfiles/dcr10.pfb';
+
+my $fontname_pfb=$ENV{'T1FONTTESTPFB'}||$deffont;
+my $fontname_afm=$ENV{'T1FONTTESTAFM'}||'./fontfiles/dcr10.afm';
+
+-f $fontname_pfb
+ or skip_all("cannot find fontfile for type 1 test $fontname_pfb");
+-f $fontname_afm
+ or skip_all("cannot find fontfile for type 1 test $fontname_afm");
+
+SKIP:
+{
+ print "# has t1\n";
+
+ #i_t1_set_aa(1);
+
+ unlink "t1lib.log"; # lose it if it exists
+ init(t1log=>0);
+ ok(!-e("t1lib.log"), "disable t1log");
+ init(t1log=>1);
+ ok(-e("t1lib.log"), "enable t1log");
+ init(t1log=>0);
+ unlink "t1lib.log";
+
+ my $fnum=Imager::Font::T1::i_t1_new($fontname_pfb,$fontname_afm); # this will load the pfb font
+ unless (ok($fnum >= 0, "load font $fontname_pfb")) {
+ skip("without the font I can't do a thing", 90);
+ }
+
+ my $bgcolor=Imager::Color->new(255,0,0,0);
+ my $overlay=Imager::ImgRaw::new(200,70,3);
+
+ ok(Imager::Font::T1::i_t1_cp($overlay,5,50,1,$fnum,50.0,'XMCLH',5,1), "i_t1_cp");
+
+ i_line($overlay,0,50,100,50,$bgcolor,1);
+
+ my @bbox=Imager::Font::T1::i_t1_bbox(0,50.0,'XMCLH',5);
+ is(@bbox, 8, "i_t1_bbox");
+ print "# bbox: ($bbox[0], $bbox[1]) - ($bbox[2], $bbox[3])\n";
+
+ open(FH,">testout/t30t1font.ppm") || die "cannot open testout/t35t1font.ppm\n";
+ binmode(FH); # for os2
+ my $IO = Imager::io_new_fd( fileno(FH) );
+ i_writeppm_wiol($overlay,$IO);
+ close(FH);
+
+ $bgcolor=Imager::Color::set($bgcolor,200,200,200,0);
+ my $backgr=Imager::ImgRaw::new(280,300,3);
+
+ Imager::Font::T1::i_t1_set_aa(2);
+ ok(Imager::Font::T1::i_t1_text($backgr,10,100,$bgcolor,$fnum,150.0,'test',4,1), "i_t1_text");
+
+ # "UTF8" tests
+ # for perl < 5.6 we can hand-encode text
+ # since T1 doesn't support over 256 chars in an encoding we just drop
+ # chars over \xFF
+ # the following is "A\xA1\x{2010}A"
+ #
+ my $text = pack("C*", 0x41, 0xC2, 0xA1, 0xE2, 0x80, 0x90, 0x41);
+ my $alttext = "A\xA1A";
+
+ my @utf8box = Imager::Font::T1::i_t1_bbox($fnum, 50.0, $text, length($text), 1);
+ is(@utf8box, 8, "utf8 bbox element count");
+ my @base = Imager::Font::T1::i_t1_bbox($fnum, 50.0, $alttext, length($alttext), 0);
+ is(@base, 8, "alt bbox element count");
+ my $maxdiff = $fontname_pfb eq $deffont ? 0 : $base[2] / 3;
+ print "# (@utf8box vs @base)\n";
+ ok(abs($utf8box[2] - $base[2]) <= $maxdiff,
+ "compare box sizes $utf8box[2] vs $base[2] (maxerror $maxdiff)");
+
+ # hand-encoded UTF8 drawing
+ ok(Imager::Font::T1::i_t1_text($backgr, 10, 140, $bgcolor, $fnum, 32, $text, length($text), 1,1), "draw hand-encoded UTF8");
+
+ ok(Imager::Font::T1::i_t1_cp($backgr, 80, 140, 1, $fnum, 32, $text, length($text), 1, 1),
+ "cp hand-encoded UTF8");
+
+ # ok, try native perl UTF8 if available
+ SKIP:
+ {
+ $] >= 5.006 or skip("perl too old to test native UTF8 support", 5);
+ my $text;
+ # we need to do this in eval to prevent compile time errors in older
+ # versions
+ eval q{$text = "A\xA1\x{2010}A"}; # A, a with ogonek, HYPHEN, A in our test font
+ #$text = "A".chr(0xA1).chr(0x2010)."A"; # this one works too
+ ok(Imager::Font::T1::i_t1_text($backgr, 10, 180, $bgcolor, $fnum, 32, $text, length($text), 1),
+ "draw UTF8");
+ ok(Imager::Font::T1::i_t1_cp($backgr, 80, 180, 1, $fnum, 32, $text, length($text), 1),
+ "cp UTF8");
+ @utf8box = Imager::Font::T1::i_t1_bbox($fnum, 50.0, $text, length($text), 0);
+ is(@utf8box, 8, "native utf8 bbox element count");
+ ok(abs($utf8box[2] - $base[2]) <= $maxdiff,
+ "compare box sizes native $utf8box[2] vs $base[2] (maxerror $maxdiff)");
+ eval q{$text = "A\xA1\xA2\x01\x1F\x{0100}A"};
+ ok(Imager::Font::T1::i_t1_text($backgr, 10, 220, $bgcolor, $fnum, 32, $text, 0, 1, 0, "uso"),
+ "more complex output");
+ }
+
+ open(FH,">testout/t30t1font2.ppm") || die "cannot open testout/t35t1font.ppm\n";
+ binmode(FH);
+ $IO = Imager::io_new_fd( fileno(FH) );
+ i_writeppm_wiol($backgr, $IO);
+ close(FH);
+
+ my $rc=Imager::Font::T1::i_t1_destroy($fnum);
+ unless (ok($rc >= 0, "i_t1_destroy")) {
+ print "# i_t1_destroy failed: rc=$rc\n";
+ }
+
+ print "# debug: ",join(" x ",Imager::Font::T1::i_t1_bbox(0,50,"eses",4) ),"\n";
+ print "# debug: ",join(" x ",Imager::Font::T1::i_t1_bbox(0,50,"llll",4) ),"\n";
+
+ # character existance tests - uses the special ExistenceTest font
+ my $exists_font = 'fontfiles/ExistenceTest.pfb';
+ my $exists_afm = 'fontfiles/ExistenceText.afm';
+
+ -e $exists_font or die "$exists_font not found";
+
+ my $font_num = Imager::Font::T1::i_t1_new($exists_font, $exists_afm);
+ SKIP: {
+ ok($font_num >= 0, 'loading test font')
+ or skip('Could not load test font', 6);
+ # first the list interface
+ my @exists = Imager::Font::T1::i_t1_has_chars($font_num, "!A");
+ is(@exists, 2, "return count from has_chars");
+ ok($exists[0], "we have an exclamation mark");
+ ok(!$exists[1], "we have no uppercase A");
+
+ # then the scalar interface
+ my $exists = Imager::Font::T1::i_t1_has_chars($font_num, "!A");
+ is(length($exists), 2, "return scalar length");
+ ok(ord(substr($exists, 0, 1)), "we have an exclamation mark");
+ ok(!ord(substr($exists, 1, 1)), "we have no upper-case A");
+ Imager::Font::T1::i_t1_destroy($font_num);
+ }
+
+ my $font = Imager::Font->new(file=>$exists_font, type=>'t1');
+ SKIP:
+ {
+ ok($font, "loaded OO font")
+ or skip("Could not load test font", 24);
+ my @exists = $font->has_chars(string=>"!A");
+ is(@exists, 2, "return count from has_chars");
+ ok($exists[0], "we have an exclamation mark");
+ ok(!$exists[1], "we have no uppercase A");
+
+ # then the scalar interface
+ my $exists = $font->has_chars(string=>"!A");
+ is(length($exists), 2, "return scalar length");
+ ok(ord(substr($exists, 0, 1)), "we have an exclamation mark");
+ ok(!ord(substr($exists, 1, 1)), "we have no upper-case A");
+
+ # check the advance width
+ my @bbox = $font->bounding_box(string=>'/', size=>100);
+ print "# @bbox\n";
+ isnt($bbox[2], $bbox[5], "different advance to pos_width");
+
+ # names
+ my $face_name = Imager::Font::T1::i_t1_face_name($font->{id});
+ print "# face $face_name\n";
+ is($face_name, 'ExistenceTest', "face name");
+ $face_name = $font->face_name;
+ is($face_name, 'ExistenceTest', "face name");
+
+ my @glyph_names = $font->glyph_names(string=>"!J/");
+ is($glyph_names[0], 'exclam', "check exclam name OO");
+ ok(!defined($glyph_names[1]), "check for no J name OO");
+ is($glyph_names[2], 'slash', "check slash name OO");
+
+ # this character chosen since when it's truncated to one byte it
+ # becomes 0x21 or '!' which the font does define
+ my $text = pack("C*", 0xE2, 0x80, 0xA1); # "\x{2021}" as utf-8
+ @glyph_names = $font->glyph_names(string=>$text, utf8=>1);
+ is($glyph_names[0], undef, "expect no glyph_name for \\x{20A1}");
+
+ # make sure a missing string parameter is handled correctly
+ eval {
+ $font->glyph_names();
+ };
+ is($@, "", "correct error handling");
+ cmp_ok(Imager->errstr, '=~', qr/no string parameter/, "error message");
+
+ # test extended bounding box results
+ # the test font is known to have a shorter advance width for that char
+ @bbox = $font->bounding_box(string=>"/", size=>100);
+ is(@bbox, 8, "should be 8 entries");
+ isnt($bbox[6], $bbox[2], "different advance width");
+ my $bbox = $font->bounding_box(string=>"/", size=>100);
+ cmp_ok($bbox->pos_width, '>', $bbox->advance_width, "OO check");
+
+ cmp_ok($bbox->right_bearing, '<', 0, "check right bearing");
+
+ cmp_ok($bbox->display_width, '>', $bbox->advance_width,
+ "check display width (roughly)");
+
+ # check with a char that fits inside the box
+ $bbox = $font->bounding_box(string=>"!", size=>100);
+ print "# pos width ", $bbox->pos_width, "\n";
+
+ # they aren't the same historically for the type 1 driver
+ isnt($bbox->pos_width, $bbox->advance_width,
+ "check backwards compatibility");
+ cmp_ok($bbox->left_bearing, '>', 0, "left bearing positive");
+ cmp_ok($bbox->right_bearing, '>', 0, "right bearing positive");
+ cmp_ok($bbox->display_width, '<', $bbox->advance_width,
+ "display smaller than advance");
+ }
+
+ SKIP:
+ { print "# alignment tests\n";
+ my $font = Imager::Font->new(file=>$deffont, type=>'t1');
+ ok($font, "loaded deffont OO")
+ or skip("could not load font:".Imager->errstr, 4);
+ my $im = Imager->new(xsize=>140, ysize=>150);
+ my %common =
+ (
+ font=>$font,
+ size=>40,
+ aa=>1,
+ );
+ $im->line(x1=>0, y1=>40, x2=>139, y2=>40, color=>'blue');
+ $im->line(x1=>0, y1=>90, x2=>139, y2=>90, color=>'blue');
+ $im->line(x1=>0, y1=>110, x2=>139, y2=>110, color=>'blue');
+ for my $args ([ x=>5, text=>"A", color=>"white" ],
+ [ x=>40, text=>"y", color=>"white" ],
+ [ x=>75, text=>"A", channel=>1 ],
+ [ x=>110, text=>"y", channel=>1 ]) {
+ ok($im->string(%common, @$args, 'y'=>40), "A no alignment");
+ ok($im->string(%common, @$args, 'y'=>90, align=>1), "A align=1");
+ ok($im->string(%common, @$args, 'y'=>110, align=>0), "A align=0");
+ }
+ ok($im->write(file=>'testout/t30align.ppm'), "save align image");
+ }
+
+ SKIP:
+ {
+ # see http://rt.cpan.org/Ticket/Display.html?id=20555
+ print "# bounding box around spaces\n";
+ # SpaceTest contains 3 characters, space, ! and .undef
+ # only characters that define character zero seem to illustrate
+ # the problem we had with spaces
+ my $space_fontfile = "fontfiles/SpaceTest.pfb";
+ my $font = Imager::Font->new(file => $space_fontfile, type => 't1');
+ ok($font, "loaded $space_fontfile")
+ or skip("failed to load $space_fontfile" . Imager->errstr, 13);
+ my $bbox = $font->bounding_box(string => "", size => 36);
+ print "# empty string bbox: @$bbox\n";
+ is($bbox->start_offset, 0, "empty string start_offset");
+ is($bbox->end_offset, 0, "empty string end_offset");
+ is($bbox->advance_width, 0, "empty string advance_width");
+ is($bbox->ascent, 0, "empty string ascent");
+ is($bbox->descent, 0, "empty string descent");
+
+ # a single space
+ my $bbox_space = $font->bounding_box(string => " ", size => 36);
+ print "# space bbox: @$bbox_space\n";
+ is($bbox_space->start_offset, 0, "single space start_offset");
+ is($bbox_space->end_offset, $bbox_space->advance_width,
+ "single space end_offset");
+ cmp_ok($bbox_space->ascent, '>=', $bbox_space->descent,
+ "single space ascent/descent");
+
+ my $bbox_bang = $font->bounding_box(string => "!", size => 36);
+ print "# '!' bbox: @$bbox_bang\n";
+
+ # space ! space
+ my $bbox_spbangsp = $font->bounding_box(string => " ! ", size => 36);
+ print "# ' ! ' bbox: @$bbox_spbangsp\n";
+ my $exp_advance = $bbox_bang->advance_width + 2 * $bbox_space->advance_width;
+ is($bbox_spbangsp->advance_width, $exp_advance, "sp ! sp advance_width");
+ is($bbox_spbangsp->start_offset, 0, "sp ! sp start_offset");
+ is($bbox_spbangsp->end_offset, $exp_advance, "sp ! sp end_offset");
+ }
+
+ SKIP:
+ { # http://rt.cpan.org/Ticket/Display.html?id=20554
+ # this is "A\xA1\x{2010}A"
+ # the t1 driver is meant to ignore any UTF8 characters over 0xff
+ print "# issue 20554\n";
+ my $text = pack("C*", 0x41, 0xC2, 0xA1, 0xE2, 0x80, 0x90, 0x41);
+ my $tran_text = "A\xA1A";
+ my $font = Imager::Font->new(file => 'fontfiles/dcr10.pfb', type => 't1');
+ $font
+ or skip("cannot load font fontfiles/fcr10.pfb:".Imager->errstr, 1);
+ my $bbox_utf8 = $font->bounding_box(string => $text, utf8 => 1, size => 36);
+ my $bbox_tran = $font->bounding_box(string => $tran_text, size => 36);
+ is($bbox_utf8->advance_width, $bbox_tran->advance_width,
+ "advance widths should match");
+ }
+ { # string output cut off at NUL ('\0')
+ # https://rt.cpan.org/Ticket/Display.html?id=21770 cont'd
+ my $font = Imager::Font->new(file => 'fontfiles/dcr10.pfb', type => 't1');
+ ok($font, "loaded dcr10.pfb");
+
+ diff_text_with_nul("a\\0b vs a", "a\0b", "a",
+ font => $font, color => '#FFFFFF');
+ diff_text_with_nul("a\\0b vs a", "a\0b", "a",
+ font => $font, channel => 1);
+
+ # UTF8 encoded \xBF
+ my $pound = pack("C*", 0xC2, 0xBF);
+ diff_text_with_nul("utf8 pound\0pound vs pound", "$pound\0$pound", $pound,
+ font => $font, color => '#FFFFFF', utf8 => 1);
+ diff_text_with_nul("utf8 dash\0dash vs dash", "$pound\0$pound", $pound,
+ font => $font, channel => 1, utf8 => 1);
+
+ }
+
+ { # RT 11972
+ # when rendering to a transparent image the coverage should be
+ # expressed in terms of the alpha channel rather than the color
+ my $font = Imager::Font->new(file=>'fontfiles/dcr10.pfb', type=>'t1');
+ my $im = Imager->new(xsize => 40, ysize => 20, channels => 4);
+ ok($im->string(string => "AB", size => 20, aa => 2, color => '#F00',
+ x => 0, y => 15, font => $font),
+ "draw to transparent image");
+ my $im_noalpha = $im->convert(preset => 'noalpha');
+ my $im_pal = $im->to_paletted(make_colors => 'mediancut');
+ my @colors = $im_pal->getcolors;
+ is(@colors, 2, "should be only 2 colors");
+ @colors = sort { ($a->rgba)[0] <=> ($b->rgba)[0] } @colors;
+ is_color3($colors[0], 0, 0, 0, "check we got black");
+ is_color3($colors[1], 255, 0, 0, "and red");
+ }
+
+ SKIP:
+ { # RT 60509
+ # checks that a c:foo or c:\foo path is handled correctly on win32
+ my $type = "t1";
+ $^O eq "MSWin32" || $^O eq "cygwin"
+ or skip("only for win32", 2);
+ my $dir = getcwd
+ or skip("Cannot get cwd", 2);
+ if ($^O eq "cygwin") {
+ $dir = Cygwin::posix_to_win_path($dir);
+ }
+ my $abs_path = abs_path($deffont);
+ my $font = Imager::Font->new(file => $abs_path, type => $type);
+ ok($font, "found font by absolute path")
+ or print "# path $abs_path\n";
+ undef $font;
+
+ $^O eq "cygwin"
+ and skip("cygwin doesn't support drive relative DOSsish paths", 1);
+ my ($drive) = $dir =~ /^([a-z]:)/i
+ or skip("cwd has no drive letter", 2);
+ my $drive_path = $drive . $deffont;
+ $font = Imager::Font->new(file => $drive_path, type => $type);
+ ok($font, "found font by drive relative path")
+ or print "# path $drive_path\n";
+ }
+}
+
+#malloc_state();
--- /dev/null
+#!/usr/bin/perl -w
+use strict;
+use Imager;
+use Test::More tests => 9;
+
+# extracted from t/t36oofont.t
+
+my $fontname_pfb = "fontfiles/dcr10.pfb";
+
+my $green=Imager::Color->new(92,205,92,128);
+die $Imager::ERRSTR unless $green;
+my $red=Imager::Color->new(205, 92, 92, 255);
+die $Imager::ERRSTR unless $red;
+
+ok((-d "testout" or mkdir "testout"), "make output directory");
+
+init_log("testout/t20oo.log", 1);
+
+my $img=Imager->new(xsize=>300, ysize=>100) or die "$Imager::ERRSTR\n";
+
+my $font=Imager::Font->new(file=>$fontname_pfb,size=>25, type => "t1")
+ or die $img->{ERRSTR};
+
+ok(1, "created font");
+
+ok($img->string(font=>$font, text=>"XMCLH", 'x'=>100, 'y'=>100),
+ "draw text");
+$img->line(x1=>0, x2=>300, y1=>50, y2=>50, color=>$green);
+
+my $text="LLySja";
+my @bbox=$font->bounding_box(string=>$text, 'x'=>0, 'y'=>50);
+
+is(@bbox, 8, "bounding box list length");
+
+$img->box(box=>\@bbox, color=>$green);
+
+# "utf8" support
+$text = pack("C*", 0x41, 0xE2, 0x80, 0x90, 0x41);
+ok($img->string(font=>$font, text=>$text, 'x'=>100, 'y'=>50, utf8=>1,
+ overline=>1),
+ "draw 'utf8' hand-encoded text");
+
+ok($img->string(font=>$font, text=>$text, 'x'=>140, 'y'=>50, utf8=>1,
+ underline=>1, channel=>2),
+ "channel 'utf8' hand-encoded text");
+
+SKIP:
+{
+ $] >= 5.006
+ or skip("perl too old for native utf8", 2);
+ eval q{$text = "A\x{2010}A"};
+ ok($img->string(font=>$font, text=>$text, 'x'=>180, 'y'=>50,
+ strikethrough=>1),
+ "draw native UTF8 text");
+ ok($img->string(font=>$font, text=>$text, 'x'=>220, 'y'=>50, channel=>1),
+ "channel native UTF8 text");
+}
+
+ok($img->write(file=>"testout/t36oofont1.ppm", type=>'pnm'),
+ "write t36oofont1.ppm")
+ or print "# ",$img->errstr,"\n";
+
+unless ($ENV{IMAGER_KEEP_FILES}) {
+ unlink "testout/t36oofont1.ppm";
+}
#include <stdlib.h>
#ifdef HAVE_LIBT1
-#include <t1lib.h>
#endif
*/
-/*
-=item i_init_fonts()
-
-Initialize font rendering libraries if they are avaliable.
-
-=cut
-*/
-
-undef_int
-i_init_fonts(int t1log) {
- mm_log((1,"Initializing fonts\n"));
-
-#ifdef HAVE_LIBT1
- if (i_init_t1(t1log))
- return 0;
-#endif
-
- return(1); /* FIXME: Always true - check the return values of the init_t1 and init_tt functions */
-}
-
-
-
-
-#ifdef HAVE_LIBT1
-
-static int t1_get_flags(char const *flags);
-static char *t1_from_utf8(char const *in, size_t len, int *outlen);
-
-static void t1_push_error(void);
-
-static int t1_active_fonts = 0;
-static int t1_initialized = 0;
-
-/*
-=item i_init_t1(t1log)
-
-Initializes the t1lib font rendering engine.
-
-=cut
-*/
-
-undef_int
-i_init_t1(int t1log) {
- int init_flags = IGNORE_CONFIGFILE|IGNORE_FONTDATABASE;
- mm_log((1,"init_t1()\n"));
-
- i_clear_error();
-
- if (t1_active_fonts) {
- mm_log((1, "Cannot re-initialize T1 - active fonts\n"));
- i_push_error(0, "Cannot re-initialize T1 - active fonts");
- return 1;
- }
-
- if (t1_initialized) {
- T1_CloseLib();
- }
-
- if (t1log)
- init_flags |= LOGFILE;
- if ((T1_InitLib(init_flags) == NULL)){
- mm_log((1,"Initialization of t1lib failed\n"));
- i_push_error(0, "T1_InitLib failed");
- return(1);
- }
- T1_SetLogLevel(T1LOG_DEBUG);
- i_t1_set_aa(1); /* Default Antialias value */
-
- ++t1_initialized;
-
- return(0);
-}
-
-
-/*
-=item i_close_t1()
-
-Shuts the t1lib font rendering engine down.
-
- This it seems that this function is never used.
-
-=cut
-*/
-
-void
-i_close_t1(void) {
- T1_CloseLib();
- t1_initialized = 0;
-}
-
-
-/*
-=item i_t1_new(pfb, afm)
-
-Loads the fonts with the given filenames, returns its font id
-
- pfb - path to pfb file for font
- afm - path to afm file for font
-
-=cut
-*/
-
-int
-i_t1_new(char *pfb,char *afm) {
- int font_id;
-
- i_clear_error();
-
- if (!t1_initialized && i_init_t1(0))
- return -1;
-
- mm_log((1,"i_t1_new(pfb %s,afm %s)\n",pfb,(afm?afm:"NULL")));
- font_id = T1_AddFont(pfb);
- if (font_id<0) {
- mm_log((1,"i_t1_new: Failed to load pfb file '%s' - return code %d.\n",pfb,font_id));
- return font_id;
- }
-
- if (afm != NULL) {
- mm_log((1,"i_t1_new: requesting afm file '%s'.\n",afm));
- if (T1_SetAfmFileName(font_id,afm)<0) mm_log((1,"i_t1_new: afm loading of '%s' failed.\n",afm));
- }
-
- ++t1_active_fonts;
-
- return font_id;
-}
-
-/*
-=item i_t1_destroy(font_id)
-
-Frees resources for a t1 font with given font id.
-
- font_id - number of the font to free
-
-=cut
-*/
-
-int
-i_t1_destroy(int font_id) {
- mm_log((1,"i_t1_destroy(font_id %d)\n",font_id));
-
- --t1_active_fonts;
-
- return T1_DeleteFont(font_id);
-}
-
-
-/*
-=item i_t1_set_aa(st)
-
-Sets the antialiasing level of the t1 library.
-
- st - 0 = NONE, 1 = LOW, 2 = HIGH.
-
-=cut
-*/
-
-void
-i_t1_set_aa(int st) {
- int i;
- unsigned long cst[17];
- switch(st) {
- case 0:
- T1_AASetBitsPerPixel( 8 );
- T1_AASetLevel( T1_AA_NONE );
- T1_AANSetGrayValues( 0, 255 );
- mm_log((1,"setting T1 antialias to none\n"));
- break;
- case 1:
- T1_AASetBitsPerPixel( 8 );
- T1_AASetLevel( T1_AA_LOW );
- T1_AASetGrayValues( 0,65,127,191,255 );
- mm_log((1,"setting T1 antialias to low\n"));
- break;
- case 2:
- T1_AASetBitsPerPixel(8);
- T1_AASetLevel(T1_AA_HIGH);
- for(i=0;i<17;i++) cst[i]=(i*255)/16;
- T1_AAHSetGrayValues( cst );
- mm_log((1,"setting T1 antialias to high\n"));
- }
-}
-
-
-/*
-=item i_t1_cp(im, xb, yb, channel, fontnum, points, str, len, align)
-
-Interface to text rendering into a single channel in an image
-
- im pointer to image structure
- xb x coordinate of start of string
- yb y coordinate of start of string ( see align )
- channel - destination channel
- fontnum - t1 library font id
- points - number of points in fontheight
- str - string to render
- len - string length
- align - (0 - top of font glyph | 1 - baseline )
-
-=cut
-*/
-
-undef_int
-i_t1_cp(i_img *im,int xb,int yb,int channel,int fontnum,float points,char* str,size_t len,int align, int utf8, char const *flags) {
- GLYPH *glyph;
- int xsize,ysize,x,y;
- i_color val;
- int mod_flags = t1_get_flags(flags);
-
- unsigned int ch_mask_store;
-
- if (im == NULL) { mm_log((1,"i_t1_cp: Null image in input\n")); return(0); }
-
- if (utf8) {
- int worklen;
- char *work = t1_from_utf8(str, len, &worklen);
- glyph=T1_AASetString( fontnum, work, worklen, 0, mod_flags, points, NULL);
- myfree(work);
- }
- else {
- glyph=T1_AASetString( fontnum, str, len, 0, mod_flags, points, NULL);
- }
- if (glyph == NULL)
- return 0;
-
- mm_log((1,"metrics: ascent: %d descent: %d\n",glyph->metrics.ascent,glyph->metrics.descent));
- mm_log((1," leftSideBearing: %d rightSideBearing: %d\n",glyph->metrics.leftSideBearing,glyph->metrics.rightSideBearing));
- mm_log((1," advanceX: %d advanceY: %d\n",glyph->metrics.advanceX,glyph->metrics.advanceY));
- mm_log((1,"bpp: %d\n",glyph->bpp));
-
- xsize=glyph->metrics.rightSideBearing-glyph->metrics.leftSideBearing;
- ysize=glyph->metrics.ascent-glyph->metrics.descent;
-
- mm_log((1,"width: %d height: %d\n",xsize,ysize));
-
- ch_mask_store=im->ch_mask;
- im->ch_mask=1<<channel;
-
- if (align==1) { xb+=glyph->metrics.leftSideBearing; yb-=glyph->metrics.ascent; }
-
- for(y=0;y<ysize;y++) for(x=0;x<xsize;x++) {
- val.channel[channel]=glyph->bits[y*xsize+x];
- i_ppix(im,x+xb,y+yb,&val);
- }
-
- im->ch_mask=ch_mask_store;
- return 1;
-}
-
-static void
-t1_fix_bbox(BBox *bbox, const char *str, size_t len, int advance,
- int space_position) {
- /* never called with len == 0 */
- if (str[0] == space_position && bbox->llx > 0)
- bbox->llx = 0;
- if (str[len-1] == space_position && bbox->urx < advance)
- bbox->urx = advance;
- if (bbox->lly > bbox->ury)
- bbox->lly = bbox->ury = 0;
-}
-
-/*
-=item i_t1_bbox(handle, fontnum, points, str, len, cords)
-
-function to get a strings bounding box given the font id and sizes
-
- handle - pointer to font handle
- fontnum - t1 library font id
- points - number of points in fontheight
- str - string to measure
- len - string length
- cords - the bounding box (modified in place)
-
-=cut
-*/
-
-int
-i_t1_bbox(int fontnum,float points,const char *str,size_t len,int cords[6], int utf8,char const *flags) {
- BBox bbox;
- BBox gbbox;
- int mod_flags = t1_get_flags(flags);
- int advance;
- int space_position = T1_GetEncodingIndex(fontnum, "space");
-
- mm_log((1,"i_t1_bbox(fontnum %d,points %.2f,str '%.*s', len %d)\n",fontnum,points,len,str,len));
- T1_LoadFont(fontnum); /* FIXME: Here a return code is ignored - haw haw haw */
-
- if (len == 0) {
- /* len == 0 has special meaning to T1lib, but it means there's
- nothing to draw, so return that */
- bbox.llx = bbox.lly = bbox.urx = bbox.ury = 0;
- advance = 0;
- }
- else {
- if (utf8) {
- int worklen;
- char *work = t1_from_utf8(str, len, &worklen);
- advance = T1_GetStringWidth(fontnum, work, worklen, 0, mod_flags);
- bbox = T1_GetStringBBox(fontnum,work,worklen,0,mod_flags);
- t1_fix_bbox(&bbox, work, worklen, advance, space_position);
- myfree(work);
- }
- else {
- advance = T1_GetStringWidth(fontnum, (char *)str, len, 0, mod_flags);
- bbox = T1_GetStringBBox(fontnum,(char *)str,len,0,mod_flags);
- t1_fix_bbox(&bbox, str, len, advance, space_position);
- }
- }
- gbbox = T1_GetFontBBox(fontnum);
-
- mm_log((1,"bbox: (%d,%d,%d,%d)\n",
- (int)(bbox.llx*points/1000),
- (int)(gbbox.lly*points/1000),
- (int)(bbox.urx*points/1000),
- (int)(gbbox.ury*points/1000),
- (int)(bbox.lly*points/1000),
- (int)(bbox.ury*points/1000) ));
-
-
- cords[BBOX_NEG_WIDTH]=((float)bbox.llx*points)/1000;
- cords[BBOX_POS_WIDTH]=((float)bbox.urx*points)/1000;
-
- cords[BBOX_GLOBAL_DESCENT]=((float)gbbox.lly*points)/1000;
- cords[BBOX_GLOBAL_ASCENT]=((float)gbbox.ury*points)/1000;
-
- cords[BBOX_DESCENT]=((float)bbox.lly*points)/1000;
- cords[BBOX_ASCENT]=((float)bbox.ury*points)/1000;
-
- cords[BBOX_ADVANCE_WIDTH] = ((float)advance * points)/1000;
- cords[BBOX_RIGHT_BEARING] =
- cords[BBOX_ADVANCE_WIDTH] - cords[BBOX_POS_WIDTH];
-
- return BBOX_RIGHT_BEARING+1;
-}
-
-
-/*
-=item i_t1_text(im, xb, yb, cl, fontnum, points, str, len, align)
-
-Interface to text rendering in a single color onto an image
-
- im - pointer to image structure
- xb - x coordinate of start of string
- yb - y coordinate of start of string ( see align )
- cl - color to draw the text in
- fontnum - t1 library font id
- points - number of points in fontheight
- str - char pointer to string to render
- len - string length
- align - (0 - top of font glyph | 1 - baseline )
-
-=cut
-*/
-
-undef_int
-i_t1_text(i_img *im,int xb,int yb,const i_color *cl,int fontnum,float points,const char* str,size_t len,int align, int utf8, char const *flags) {
- GLYPH *glyph;
- int xsize,ysize,y;
- int mod_flags = t1_get_flags(flags);
- i_render r;
-
- if (im == NULL) { mm_log((1,"i_t1_cp: Null image in input\n")); return(0); }
-
- if (utf8) {
- int worklen;
- char *work = t1_from_utf8(str, len, &worklen);
- glyph=T1_AASetString( fontnum, work, worklen, 0, mod_flags, points, NULL);
- myfree(work);
- }
- else {
- /* T1_AASetString() accepts a char * not a const char */
- glyph=T1_AASetString( fontnum, (char *)str, len, 0, mod_flags, points, NULL);
- }
- if (glyph == NULL)
- return 0;
-
- mm_log((1,"metrics: ascent: %d descent: %d\n",glyph->metrics.ascent,glyph->metrics.descent));
- mm_log((1," leftSideBearing: %d rightSideBearing: %d\n",glyph->metrics.leftSideBearing,glyph->metrics.rightSideBearing));
- mm_log((1," advanceX: %d advanceY: %d\n",glyph->metrics.advanceX,glyph->metrics.advanceY));
- mm_log((1,"bpp: %d\n",glyph->bpp));
-
- xsize=glyph->metrics.rightSideBearing-glyph->metrics.leftSideBearing;
- ysize=glyph->metrics.ascent-glyph->metrics.descent;
-
- mm_log((1,"width: %d height: %d\n",xsize,ysize));
-
- if (align==1) { xb+=glyph->metrics.leftSideBearing; yb-=glyph->metrics.ascent; }
-
- i_render_init(&r, im, xsize);
- for(y=0;y<ysize;y++) {
- i_render_color(&r, xb, yb+y, xsize, (unsigned char *)glyph->bits+y*xsize, cl);
- }
- i_render_done(&r);
-
- return 1;
-}
-
-/*
-=item t1_get_flags(flags)
-
-Processes the characters in I<flags> to create a mod_flags value used
-by some T1Lib functions.
-
-=cut
- */
-static int
-t1_get_flags(char const *flags) {
- int mod_flags = T1_KERNING;
-
- while (*flags) {
- switch (*flags++) {
- case 'u': case 'U': mod_flags |= T1_UNDERLINE; break;
- case 'o': case 'O': mod_flags |= T1_OVERLINE; break;
- case 's': case 'S': mod_flags |= T1_OVERSTRIKE; break;
- /* ignore anything we don't recognize */
- }
- }
-
- return mod_flags;
-}
-
-/*
-=item t1_from_utf8(char const *in, size_t len, int *outlen)
-
-Produces an unencoded version of I<in> by dropping any Unicode
-character over 255.
-
-Returns a newly allocated buffer which should be freed with myfree().
-Sets *outlen to the number of bytes used in the output string.
-
-=cut
-*/
-
-static char *
-t1_from_utf8(char const *in, size_t len, int *outlen) {
- /* at this point len is from a perl SV, so can't approach MAXINT */
- char *out = mymalloc(len+1); /* checked 5Nov05 tonyc */
- char *p = out;
- unsigned long c;
-
- while (len) {
- c = i_utf8_advance(&in, &len);
- if (c == ~0UL) {
- myfree(out);
- i_push_error(0, "invalid UTF8 character");
- return 0;
- }
- /* yeah, just drop them */
- if (c < 0x100) {
- *p++ = (char)c;
- }
- }
- *p = '\0';
- *outlen = p - out;
-
- return out;
-}
-
-/*
-=item i_t1_has_chars(font_num, text, len, utf8, out)
-
-Check if the given characters are defined by the font. Note that len
-is the number of bytes, not the number of characters (when utf8 is
-non-zero).
-
-out[char index] will be true if the character exists.
-
-Accepts UTF-8, but since T1 can only have 256 characters, any chars
-with values over 255 will simply be returned as false.
-
-Returns the number of characters that were checked.
-
-=cut
-*/
-
-int
-i_t1_has_chars(int font_num, const char *text, size_t len, int utf8,
- char *out) {
- int count = 0;
-
- mm_log((1, "i_t1_has_chars(font_num %d, text %p, len %d, utf8 %d)\n",
- font_num, text, len, utf8));
-
- i_clear_error();
- if (T1_LoadFont(font_num)) {
- t1_push_error();
- return 0;
- }
-
- while (len) {
- unsigned long c;
- if (utf8) {
- c = i_utf8_advance(&text, &len);
- if (c == ~0UL) {
- i_push_error(0, "invalid UTF8 character");
- return 0;
- }
- }
- else {
- c = (unsigned char)*text++;
- --len;
- }
-
- if (c >= 0x100) {
- /* limit of 256 characters for T1 */
- *out++ = 0;
- }
- else {
- char const * name = T1_GetCharName(font_num, (unsigned char)c);
-
- if (name) {
- *out++ = strcmp(name, ".notdef") != 0;
- }
- else {
- mm_log((2, " No name found for character %lx\n", c));
- *out++ = 0;
- }
- }
- ++count;
- }
-
- return count;
-}
-
-/*
-=item i_t1_face_name(font_num, name_buf, name_buf_size)
-
-Copies the face name of the given C<font_num> to C<name_buf>. Returns
-the number of characters required to store the name (which can be
-larger than C<name_buf_size>, including the space required to store
-the terminating NUL).
-
-If name_buf is too small (as specified by name_buf_size) then the name
-will be truncated. name_buf will always be NUL termintaed.
-
-=cut
-*/
-
-int
-i_t1_face_name(int font_num, char *name_buf, size_t name_buf_size) {
- char *name;
-
- T1_errno = 0;
- if (T1_LoadFont(font_num)) {
- t1_push_error();
- return 0;
- }
- name = T1_GetFontName(font_num);
-
- if (name) {
- strncpy(name_buf, name, name_buf_size);
- name_buf[name_buf_size-1] = '\0';
- return strlen(name) + 1;
- }
- else {
- t1_push_error();
- return 0;
- }
-}
-
-int
-i_t1_glyph_name(int font_num, unsigned long ch, char *name_buf,
- size_t name_buf_size) {
- char *name;
-
- i_clear_error();
- if (ch > 0xFF) {
- return 0;
- }
- if (T1_LoadFont(font_num)) {
- t1_push_error();
- return 0;
- }
- name = T1_GetCharName(font_num, (unsigned char)ch);
- if (name) {
- if (strcmp(name, ".notdef")) {
- strncpy(name_buf, name, name_buf_size);
- name_buf[name_buf_size-1] = '\0';
- return strlen(name) + 1;
- }
- else {
- return 0;
- }
- }
- else {
- t1_push_error();
- return 0;
- }
-}
-
-static void
-t1_push_error(void) {
- switch (T1_errno) {
- case 0:
- i_push_error(0, "No error");
- break;
-
-#ifdef T1ERR_SCAN_FONT_FORMAT
- case T1ERR_SCAN_FONT_FORMAT:
- i_push_error(T1ERR_SCAN_FONT_FORMAT, "SCAN_FONT_FORMAT");
- break;
-#endif
-
-#ifdef T1ERR_SCAN_FILE_OPEN_ERR
- case T1ERR_SCAN_FILE_OPEN_ERR:
- i_push_error(T1ERR_SCAN_FILE_OPEN_ERR, "SCAN_FILE_OPEN_ERR");
- break;
-#endif
-
-#ifdef T1ERR_SCAN_OUT_OF_MEMORY
- case T1ERR_SCAN_OUT_OF_MEMORY:
- i_push_error(T1ERR_SCAN_OUT_OF_MEMORY, "SCAN_OUT_OF_MEMORY");
- break;
-#endif
-
-#ifdef T1ERR_SCAN_ERROR
- case T1ERR_SCAN_ERROR:
- i_push_error(T1ERR_SCAN_ERROR, "SCAN_ERROR");
- break;
-#endif
-
-#ifdef T1ERR_SCAN_FILE_EOF
- case T1ERR_SCAN_FILE_EOF:
- i_push_error(T1ERR_SCAN_FILE_EOF, "SCAN_FILE_EOF");
- break;
-#endif
-
-#ifdef T1ERR_PATH_ERROR
- case T1ERR_PATH_ERROR:
- i_push_error(T1ERR_PATH_ERROR, "PATH_ERROR");
- break;
-#endif
-
-#ifdef T1ERR_PARSE_ERROR
- case T1ERR_PARSE_ERROR:
- i_push_error(T1ERR_PARSE_ERROR, "PARSE_ERROR");
- break;
-#endif
-
-#ifdef T1ERR_TYPE1_ABORT
- case T1ERR_TYPE1_ABORT:
- i_push_error(T1ERR_TYPE1_ABORT, "TYPE1_ABORT");
- break;
-#endif
-
-#ifdef T1ERR_INVALID_FONTID
- case T1ERR_INVALID_FONTID:
- i_push_error(T1ERR_INVALID_FONTID, "INVALID_FONTID");
- break;
-#endif
-
-#ifdef T1ERR_INVALID_PARAMETER
- case T1ERR_INVALID_PARAMETER:
- i_push_error(T1ERR_INVALID_PARAMETER, "INVALID_PARAMETER");
- break;
-#endif
-
-#ifdef T1ERR_OP_NOT_PERMITTED
- case T1ERR_OP_NOT_PERMITTED:
- i_push_error(T1ERR_OP_NOT_PERMITTED, "OP_NOT_PERMITTED");
- break;
-#endif
-
-#ifdef T1ERR_ALLOC_MEM
- case T1ERR_ALLOC_MEM:
- i_push_error(T1ERR_ALLOC_MEM, "ALLOC_MEM");
- break;
-#endif
-
-#ifdef T1ERR_FILE_OPEN_ERR
- case T1ERR_FILE_OPEN_ERR:
- i_push_error(T1ERR_FILE_OPEN_ERR, "FILE_OPEN_ERR");
- break;
-#endif
-
-#ifdef T1ERR_UNSPECIFIED
- case T1ERR_UNSPECIFIED:
- i_push_error(T1ERR_UNSPECIFIED, "UNSPECIFIED");
- break;
-#endif
-
-#ifdef T1ERR_NO_AFM_DATA
- case T1ERR_NO_AFM_DATA:
- i_push_error(T1ERR_NO_AFM_DATA, "NO_AFM_DATA");
- break;
-#endif
-
-#ifdef T1ERR_X11
- case T1ERR_X11:
- i_push_error(T1ERR_X11, "X11");
- break;
-#endif
-
-#ifdef T1ERR_COMPOSITE_CHAR
- case T1ERR_COMPOSITE_CHAR:
- i_push_error(T1ERR_COMPOSITE_CHAR, "COMPOSITE_CHAR");
- break;
-#endif
-
- default:
- i_push_errorf(T1_errno, "unknown error %d", (int)T1_errno);
- }
-}
-
-#endif /* HAVE_LIBT1 */
-
/* Truetype font support */
#ifdef HAVE_LIBTT
+++ /dev/null
-StartFontMetrics 2.0
-Comment Generated by pfaedit
-Comment Creation Date: Thu Jul 20 21:57:23 2006
-FontName ExistenceTest
-FullName ExistenceTest
-FamilyName ExistenceTest
-Weight Medium
-Notice (Created by Tony Cook,,, with PfaEdit 1.0 (http://pfaedit.sf.net))
-ItalicAngle 0
-IsFixedPitch false
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.000
-EncodingScheme AdobeStandardEncoding
-FontBBox -60 -55 819 775
-StartCharMetrics 3
-C 0 ; WX 487 ; N uniFFFD ; B 72 87 414 396 ;
-C 33 ; WX 310 ; N exclam ; B 51 0 207 738 ;
-C 47 ; WX 761 ; N slash ; B -60 -55 819 775 ;
-EndCharMetrics
-EndFontMetrics
+++ /dev/null
-StartFontMetrics 2.0
-Comment Generated by pfaedit
-Comment Creation Date: Thu Jul 20 21:51:08 2006
-FontName SpaceTest
-FullName SpaceTest
-FamilyName SpaceTest
-Weight Medium
-Notice (Created by Tony Cook,,, with FontForge 1.0 (http://fontforge.sf.net))
-ItalicAngle 0
-IsFixedPitch false
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.000
-EncodingScheme AdobeStandardEncoding
-FontBBox 72 -24 414 684
-StartCharMetrics 3
-C 0 ; WX 487 ; N uniFFFD ; B 72 87 414 396 ;
-C 32 ; WX 500 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 451 ; N exclam ; B 156 -24 312 684 ;
-EndCharMetrics
-EndFontMetrics
+++ /dev/null
-StartFontMetrics 2.0
-FontName dcr10
-FullName dcr10
-FamilyName dcr10
-Weight Medium
-ItalicAngle 0.000000
-IsFixedPitch false
-UnderlinePosition -133
-UnderlineThickness 20
-Version 1.0\(Level-B\)
-FontBBox -55, -250, 1054, 913
-Notice Copyright \(C\) 1994, Basil K. Malyshev. All Rights Reserved.\nBaKoMa Fonts Collection, Level-B.
-EncodingScheme FontSpecific
-CapHeight 683
-XHeight 430
-Descender -194
-Ascender 694
-StartCharMetrics 256
-C 0 ; WX 499.89 ; N grave ; B 107 508 294 698 ;
-C 1 ; WX 499.89 ; N acute ; B 205 508 392 698 ;
-C 2 ; WX 499.89 ; N circumflex ; B 115 537 384 694 ;
-C 3 ; WX 499.89 ; N tilde ; B 83 572 416 668 ;
-C 4 ; WX 499.89 ; N dieresis ; B 101 565 398 669 ;
-C 5 ; WX 499.89 ; N hungarumlaut ; B 126 511 420 699 ;
-C 6 ; WX 749.83 ; N ring ; B 263 540 458 716 ;
-C 7 ; WX 499.89 ; N caron ; B 117 515 382 640 ;
-C 8 ; WX 499.89 ; N breve ; B 98 519 401 694 ;
-C 9 ; WX 499.89 ; N macron ; B 69 555 430 590 ;
-C 10 ; WX 277.72 ; N dotaccent ; B 84 559 194 669 ;
-C 11 ; WX 444.33 ; N cedilla ; B 129 -205 369 -22 ;
-C 12 ; WX 277.72 ; N ogonek ; B 9 -194 226 20 ;
-C 13 ; WX 277.72 ; N quotesinglbase ; B 112 -194 233 110 ;
-C 14 ; WX 444.33 ; N guilsinglleft ; B 94 26 330 457 ;
-C 15 ; WX 444.33 ; N guilsinglright ; B 94 26 360 457 ;
-C 16 ; WX 499.89 ; N quotedblleft ; B 148 390 466 694 ;
-C 17 ; WX 499.89 ; N quotedblright ; B 33 390 351 694 ;
-C 18 ; WX 499.89 ; N quotedblbase ; B 138 -194 456 110 ;
-C 19 ; WX 666.5 ; N guillemotleft ; B 94 26 553 457 ;
-C 20 ; WX 666.5 ; N guillemotright ; B 94 26 583 457 ;
-C 21 ; WX 499.89 ; N endash ; B 0 253 499 279 ; L hyphen emdash ;
-C 22 ; WX 999.78 ; N emdash ; B 0 253 999 279 ;
-C 23 ; WX 0 ; N compoundwordmark ; B 0 0 0 0 ;
-C 24 ; WX 388.78 ; N perthousand ; B 55 -56 333 347 ;
-C 25 ; WX 277.72 ; N dotlessi ; B 25 0 243 441 ;
-C 26 ; WX 305.5 ; N dotlessj ; B -55 -205 201 441 ;
-C 27 ; WX 583.17 ; N ff ; B 26 0 632 705 ; L i ffi ; L l ffl ;
-C 28 ; WX 555.44 ; N fi ; B 26 0 528 705 ;
-C 29 ; WX 555.44 ; N fl ; B 26 0 528 705 ;
-C 30 ; WX 833.11 ; N ffi ; B 26 0 807 705 ;
-C 31 ; WX 833.11 ; N ffl ; B 26 0 807 705 ;
-C 32 ; WX 499.89 ; N visiblespace ; B 42 -107 457 252 ;
-C 33 ; WX 277.72 ; N exclam ; B 84 0 194 716 ;
-C 34 ; WX 499.89 ; N quotedbl ; B 117 349 383 711 ;
-C 35 ; WX 833.11 ; N numbersign ; B 56 -194 776 694 ;
-C 36 ; WX 499.89 ; N dollar ; B 57 -56 444 750 ;
-C 37 ; WX 833.11 ; N percent ; B 56 -56 776 750 ;
-C 38 ; WX 777.61 ; N ampersand ; B 42 -22 727 716 ;
-C 39 ; WX 277.72 ; N quoteright ; B 84 390 208 694 ; L quoteright quotedblright ;
-C 40 ; WX 388.78 ; N parenleft ; B 97 -250 332 750 ;
-C 41 ; WX 388.78 ; N parenright ; B 56 -250 291 750 ;
-C 42 ; WX 499.89 ; N asterisk ; B 65 320 434 750 ;
-C 43 ; WX 777.61 ; N plus ; B 56 -83 721 583 ;
-C 44 ; WX 277.72 ; N comma ; B 84 -194 205 110 ; L comma quotedblbase ;
-C 45 ; WX 333.28 ; N hyphen ; B 11 184 276 246 ; L hyphen endash ;
-C 46 ; WX 277.72 ; N period ; B 84 0 194 110 ;
-C 47 ; WX 499.89 ; N slash ; B 56 -250 443 750 ;
-C 48 ; WX 499.89 ; N zero ; B 39 -22 460 666 ;
-C 49 ; WX 499.89 ; N one ; B 87 0 421 666 ;
-C 50 ; WX 499.89 ; N two ; B 50 0 449 666 ;
-C 51 ; WX 499.89 ; N three ; B 42 -22 457 666 ;
-C 52 ; WX 499.89 ; N four ; B 28 0 471 677 ;
-C 53 ; WX 499.89 ; N five ; B 50 -22 449 666 ;
-C 54 ; WX 499.89 ; N six ; B 42 -22 457 666 ;
-C 55 ; WX 499.89 ; N seven ; B 56 -22 485 676 ;
-C 56 ; WX 499.89 ; N eight ; B 42 -22 457 666 ;
-C 57 ; WX 499.89 ; N nine ; B 42 -22 457 666 ;
-C 58 ; WX 277.72 ; N colon ; B 84 0 194 430 ;
-C 59 ; WX 277.72 ; N semicolon ; B 84 -194 197 430 ;
-C 60 ; WX 777.61 ; N less ; B 83 -33 694 533 ; L less guillemotleft ;
-C 61 ; WX 777.61 ; N equal ; B 56 140 721 360 ;
-C 62 ; WX 777.61 ; N greater ; B 83 -33 694 533 ; L greater guillemotright ;
-C 63 ; WX 472.11 ; N question ; B 56 0 415 705 ;
-C 64 ; WX 777.61 ; N at ; B 56 -11 721 705 ;
-C 65 ; WX 749.83 ; N A ; B 18 0 703 716 ;
-C 66 ; WX 708.17 ; N B ; B 20 0 637 683 ;
-C 67 ; WX 722 ; N C ; B 56 -22 665 705 ;
-C 68 ; WX 763.72 ; N D ; B 19 0 693 683 ;
-C 69 ; WX 680.39 ; N E ; B 17 0 637 680 ;
-C 70 ; WX 652.61 ; N F ; B 17 0 596 680 ;
-C 71 ; WX 784.56 ; N G ; B 56 -22 735 705 ;
-C 72 ; WX 749.83 ; N H ; B 17 0 704 683 ;
-C 73 ; WX 361 ; N I ; B 12 0 321 683 ;
-C 74 ; WX 513.78 ; N J ; B 37 -22 465 683 ;
-C 75 ; WX 777.61 ; N K ; B 17 0 722 683 ;
-C 76 ; WX 624.83 ; N L ; B 17 0 568 683 ;
-C 77 ; WX 916.44 ; N M ; B 21 0 866 683 ;
-C 78 ; WX 749.83 ; N N ; B 17 0 704 683 ;
-C 79 ; WX 777.61 ; N O ; B 56 -22 721 705 ;
-C 80 ; WX 680.39 ; N P ; B 19 0 609 683 ;
-C 81 ; WX 777.61 ; N Q ; B 56 -194 727 705 ;
-C 82 ; WX 735.94 ; N R ; B 19 -22 718 683 ;
-C 83 ; WX 555.44 ; N S ; B 56 -22 498 705 ;
-C 84 ; WX 722 ; N T ; B 37 0 686 677 ;
-C 85 ; WX 749.83 ; N U ; B 17 -22 704 683 ;
-C 86 ; WX 749.83 ; N V ; B 5 -22 716 683 ;
-C 87 ; WX 1027.56 ; N W ; B 4 -22 995 683 ;
-C 88 ; WX 749.83 ; N X ; B 9 0 712 683 ;
-C 89 ; WX 749.83 ; N Y ; B -3 0 724 683 ;
-C 90 ; WX 611 ; N Z ; B 56 0 560 683 ;
-C 91 ; WX 277.72 ; N bracketleft ; B 103 -250 255 750 ;
-C 92 ; WX 499.89 ; N backslash ; B 56 -250 443 750 ;
-C 93 ; WX 277.72 ; N bracketright ; B 22 -250 174 750 ;
-C 94 ; WX 611 ; N asciicircum ; B 117 461 493 628 ;
-C 95 ; WX 777.61 ; N underscore ; B 83 -233 694 -193 ;
-C 96 ; WX 277.72 ; N quoteleft ; B 70 390 194 694 ; L quoteleft quotedblleft ;
-C 97 ; WX 499.89 ; N a ; B 40 -11 493 447 ;
-C 98 ; WX 555.44 ; N b ; B 26 -11 521 694 ;
-C 99 ; WX 444.33 ; N c ; B 33 -11 415 447 ;
-C 100 ; WX 555.44 ; N d ; B 33 -11 528 694 ;
-C 101 ; WX 444.33 ; N e ; B 28 -11 415 447 ;
-C 102 ; WX 305.5 ; N f ; B 26 0 354 705 ; L i fi ; L f ff ; L l fl ;
-C 103 ; WX 499.89 ; N g ; B 28 -206 485 452 ;
-C 104 ; WX 555.44 ; N h ; B 24 0 530 694 ;
-C 105 ; WX 277.72 ; N i ; B 25 0 243 669 ;
-C 106 ; WX 305.5 ; N j ; B -55 -205 201 669 ;
-C 107 ; WX 527.67 ; N k ; B 26 0 511 694 ;
-C 108 ; WX 277.72 ; N l ; B 25 0 251 694 ;
-C 109 ; WX 833.11 ; N m ; B 24 0 810 441 ;
-C 110 ; WX 555.44 ; N n ; B 24 0 530 441 ;
-C 111 ; WX 499.89 ; N o ; B 28 -11 471 447 ;
-C 112 ; WX 555.44 ; N p ; B 26 -194 521 441 ;
-C 113 ; WX 527.67 ; N q ; B 33 -194 529 441 ;
-C 114 ; WX 391.56 ; N r ; B 26 0 364 441 ;
-C 115 ; WX 394.33 ; N s ; B 33 -11 360 447 ;
-C 116 ; WX 388.78 ; N t ; B 19 -11 332 615 ;
-C 117 ; WX 555.44 ; N u ; B 24 -11 530 441 ;
-C 118 ; WX 527.67 ; N v ; B 19 -11 508 430 ;
-C 119 ; WX 722 ; N w ; B 18 -11 703 430 ;
-C 120 ; WX 527.67 ; N x ; B 12 0 516 430 ;
-C 121 ; WX 527.67 ; N y ; B 19 -205 508 430 ;
-C 122 ; WX 444.33 ; N z ; B 28 0 401 430 ;
-C 123 ; WX 499.89 ; N braceleft ; B 70 -250 429 750 ;
-C 124 ; WX 277.72 ; N bar ; B 119 -250 159 750 ;
-C 125 ; WX 499.89 ; N braceright ; B 70 -250 429 750 ;
-C 126 ; WX 611 ; N asciitilde ; B 83 572 527 668 ;
-C 127 ; WX 333.28 ; N hyphen ; B 11 184 276 246 ;
-C 128 ; WX 749.83 ; N Abreve ; B 18 0 703 891 ;
-C 129 ; WX 749.83 ; N Aogonek ; B 18 -188 740 716 ;
-C 130 ; WX 722 ; N Cacute ; B 56 -22 665 895 ;
-C 131 ; WX 722 ; N Ccaron ; B 56 -22 665 856 ;
-C 132 ; WX 763.72 ; N Dcaron ; B 19 0 693 856 ;
-C 133 ; WX 680.39 ; N Ecaron ; B 17 0 637 856 ;
-C 134 ; WX 680.39 ; N Eogonek ; B 17 -188 637 680 ;
-C 135 ; WX 784.56 ; N Gbreve ; B 56 -22 735 891 ;
-C 136 ; WX 624.83 ; N Lacute ; B 17 0 568 895 ;
-C 137 ; WX 624.83 ; N Lquoteright ; B 17 0 568 683 ;
-C 138 ; WX 624.83 ; N Lslash ; B 17 0 568 683 ;
-C 139 ; WX 749.83 ; N Nacute ; B 17 0 704 895 ;
-C 140 ; WX 749.83 ; N Ncaron ; B 17 0 704 856 ;
-C 141 ; WX 727.61 ; N Eng ; B 24 -22 676 694 ;
-C 142 ; WX 777.61 ; N Ohungarumlaut ; B 56 -22 721 895 ;
-C 143 ; WX 735.94 ; N Racute ; B 19 -22 718 895 ;
-C 144 ; WX 735.94 ; N Rcaron ; B 19 -22 718 856 ;
-C 145 ; WX 555.44 ; N Sacute ; B 56 -22 498 895 ;
-C 146 ; WX 555.44 ; N Scaron ; B 56 -22 498 856 ;
-C 147 ; WX 555.44 ; N Scedilla ; B 56 -205 498 705 ;
-C 148 ; WX 722 ; N Tcaron ; B 37 0 686 856 ;
-C 149 ; WX 722 ; N Tcedilla ; B 37 -205 686 677 ;
-C 150 ; WX 749.83 ; N Uhungarumlaut ; B 17 -22 704 895 ;
-C 151 ; WX 749.83 ; N Uring ; B 17 -22 704 913 ;
-C 152 ; WX 749.83 ; N Ydieresis ; B -3 0 724 839 ;
-C 153 ; WX 611 ; N Zacute ; B 56 0 560 895 ;
-C 154 ; WX 611 ; N Zcaron ; B 56 0 560 856 ;
-C 155 ; WX 611 ; N Zdotaccent ; B 56 0 560 891 ;
-C 156 ; WX 860.89 ; N IJ ; B 12 -22 798 683 ;
-C 157 ; WX 361 ; N Idotaccent ; B 12 0 321 877 ;
-C 158 ; WX 555.44 ; N dbar ; B 33 -11 528 694 ;
-C 159 ; WX 444.33 ; N section ; B 69 -205 374 705 ;
-C 160 ; WX 499.89 ; N abreve ; B 40 -11 493 694 ;
-C 161 ; WX 499.89 ; N aogonek ; B 40 -194 493 447 ;
-C 162 ; WX 444.33 ; N cacute ; B 33 -11 415 643 ;
-C 163 ; WX 444.33 ; N ccaron ; B 33 -11 415 604 ;
-C 164 ; WX 674.83 ; N dquoteright ; B 33 -11 665 694 ;
-C 165 ; WX 444.33 ; N ecaron ; B 28 -11 415 604 ;
-C 166 ; WX 444.33 ; N eogonek ; B 28 -194 415 447 ;
-C 167 ; WX 499.89 ; N gbreve ; B 28 -206 485 694 ;
-C 168 ; WX 277.72 ; N lacute ; B 25 0 282 907 ;
-C 169 ; WX 402.67 ; N lquoteright ; B 25 0 386 694 ;
-C 170 ; WX 277.72 ; N lslash ; B 18 0 258 694 ;
-C 171 ; WX 555.44 ; N nacute ; B 24 0 530 643 ;
-C 172 ; WX 555.44 ; N ncaron ; B 24 0 530 604 ;
-C 173 ; WX 555.44 ; N eng ; B 24 -205 452 441 ;
-C 174 ; WX 499.89 ; N ohungarumlaut ; B 28 -11 521 643 ;
-C 175 ; WX 391.56 ; N racute ; B 26 0 364 643 ;
-C 176 ; WX 391.56 ; N rcaron ; B 26 0 364 604 ;
-C 177 ; WX 394.33 ; N sacute ; B 33 -11 360 643 ;
-C 178 ; WX 394.33 ; N scaron ; B 33 -11 360 604 ;
-C 179 ; WX 394.33 ; N scedilla ; B 33 -205 360 447 ;
-C 180 ; WX 411 ; N tquoteright ; B 19 -11 401 704 ;
-C 181 ; WX 388.78 ; N tcedilla ; B 19 -205 359 615 ;
-C 182 ; WX 555.44 ; N uhungarumlaut ; B 24 -11 549 643 ;
-C 183 ; WX 555.44 ; N uring ; B 24 -11 530 661 ;
-C 184 ; WX 527.67 ; N ydieresis ; B 19 -205 508 586 ;
-C 185 ; WX 444.33 ; N zacute ; B 28 0 401 643 ;
-C 186 ; WX 444.33 ; N zcaron ; B 28 0 401 604 ;
-C 187 ; WX 444.33 ; N zdotaccent ; B 28 0 402 669 ;
-C 188 ; WX 583.17 ; N ij ; B 33 -205 485 669 ;
-C 189 ; WX 277.72 ; N exclamdown ; B 84 -216 194 500 ;
-C 190 ; WX 472.11 ; N questiondown ; B 56 -205 415 500 ;
-C 191 ; WX 638.72 ; N sterling ; B 56 -11 620 709 ;
-C 192 ; WX 749.83 ; N Agrave ; B 18 0 703 895 ;
-C 193 ; WX 749.83 ; N Aacute ; B 18 0 703 895 ;
-C 194 ; WX 749.83 ; N Acircumflex ; B 18 0 703 891 ;
-C 195 ; WX 749.83 ; N Atilde ; B 18 0 703 891 ;
-C 196 ; WX 749.83 ; N Adieresis ; B 18 0 703 839 ;
-C 197 ; WX 749.83 ; N Aring ; B 18 0 703 872 ;
-C 198 ; WX 902.56 ; N AE ; B 18 0 860 683 ;
-C 199 ; WX 722 ; N Ccedilla ; B 56 -205 665 705 ;
-C 200 ; WX 680.39 ; N Egrave ; B 17 0 637 895 ;
-C 201 ; WX 680.39 ; N Eacute ; B 17 0 637 895 ;
-C 202 ; WX 680.39 ; N Ecircumflex ; B 17 0 637 891 ;
-C 203 ; WX 680.39 ; N Edieresis ; B 17 0 637 839 ;
-C 204 ; WX 361 ; N Igrave ; B 12 0 321 895 ;
-C 205 ; WX 361 ; N Iacute ; B 12 0 321 895 ;
-C 206 ; WX 361 ; N Icircumflex ; B 12 0 321 891 ;
-C 207 ; WX 361 ; N Idieresis ; B 12 0 321 839 ;
-C 208 ; WX 763.72 ; N Eth ; B 19 0 693 683 ;
-C 209 ; WX 749.83 ; N Ntilde ; B 17 0 704 891 ;
-C 210 ; WX 777.61 ; N Ograve ; B 56 -22 721 895 ;
-C 211 ; WX 777.61 ; N Oacute ; B 56 -22 721 895 ;
-C 212 ; WX 777.61 ; N Ocircumflex ; B 56 -22 721 891 ;
-C 213 ; WX 777.61 ; N Otilde ; B 56 -22 721 891 ;
-C 214 ; WX 777.61 ; N Odieresis ; B 56 -22 721 839 ;
-C 215 ; WX 1013.67 ; N OE ; B 56 -22 971 705 ;
-C 216 ; WX 777.61 ; N Oslash ; B 56 -57 721 740 ;
-C 217 ; WX 749.83 ; N Ugrave ; B 17 -22 704 895 ;
-C 218 ; WX 749.83 ; N Uacute ; B 17 -22 704 895 ;
-C 219 ; WX 749.83 ; N Ucircumflex ; B 17 -22 704 891 ;
-C 220 ; WX 749.83 ; N Udieresis ; B 17 -22 704 839 ;
-C 221 ; WX 749.83 ; N Yacute ; B -3 0 724 895 ;
-C 222 ; WX 624.83 ; N Thorn ; B 20 0 554 683 ;
-C 223 ; WX 1110.83 ; N Germandbls ; B 56 -22 1054 705 ;
-C 224 ; WX 499.89 ; N agrave ; B 40 -11 493 643 ;
-C 225 ; WX 499.89 ; N aacute ; B 40 -11 493 643 ;
-C 226 ; WX 499.89 ; N acircumflex ; B 40 -11 493 639 ;
-C 227 ; WX 499.89 ; N atilde ; B 40 -11 493 669 ;
-C 228 ; WX 499.89 ; N adieresis ; B 40 -11 493 586 ;
-C 229 ; WX 499.89 ; N aring ; B 40 -11 493 661 ;
-C 230 ; WX 722 ; N ae ; B 43 -11 693 447 ;
-C 231 ; WX 444.33 ; N ccedilla ; B 33 -205 415 447 ;
-C 232 ; WX 444.33 ; N egrave ; B 28 -11 415 643 ;
-C 233 ; WX 444.33 ; N eacute ; B 28 -11 415 643 ;
-C 234 ; WX 444.33 ; N ecircumflex ; B 28 -11 415 639 ;
-C 235 ; WX 444.33 ; N edieresis ; B 28 -11 415 586 ;
-C 236 ; WX 277.72 ; N igrave ; B -6 0 243 643 ;
-C 237 ; WX 277.72 ; N iacute ; B 25 0 282 643 ;
-C 238 ; WX 277.72 ; N icircumflex ; B 3 0 274 639 ;
-C 239 ; WX 333.28 ; N idieresis ; B -9 0 289 586 ;
-C 240 ; WX 499.89 ; N eth ; B 28 -11 471 694 ;
-C 241 ; WX 555.44 ; N ntilde ; B 24 0 530 669 ;
-C 242 ; WX 499.89 ; N ograve ; B 28 -11 471 643 ;
-C 243 ; WX 499.89 ; N oacute ; B 28 -11 471 643 ;
-C 244 ; WX 499.89 ; N ocircumflex ; B 28 -11 471 639 ;
-C 245 ; WX 499.89 ; N otilde ; B 28 -11 471 669 ;
-C 246 ; WX 499.89 ; N odieresis ; B 28 -11 471 586 ;
-C 247 ; WX 777.61 ; N oe ; B 28 -11 749 447 ;
-C 248 ; WX 499.89 ; N oslash ; B 33 -103 466 534 ;
-C 249 ; WX 555.44 ; N ugrave ; B 24 -11 530 643 ;
-C 250 ; WX 555.44 ; N uacute ; B 24 -11 530 643 ;
-C 251 ; WX 555.44 ; N ucircumflex ; B 24 -11 530 639 ;
-C 252 ; WX 555.44 ; N udieresis ; B 24 -11 530 586 ;
-C 253 ; WX 527.67 ; N yacute ; B 19 -205 508 643 ;
-C 254 ; WX 555.44 ; N thorn ; B 25 -205 521 694 ;
-C 255 ; WX 499.89 ; N germandbls ; B 26 -11 471 705 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 471
-KPX A C -27.77
-KPX A G -27.77
-KPX A O -27.77
-KPX A Q -27.77
-KPX A T -83.31
-KPX A U -27.77
-KPX A V -111.08
-KPX A W -111.08
-KPX A Y -83.31
-KPX A t -27.77
-KPX Aacute C -27.77
-KPX Aacute G -27.77
-KPX Aacute O -27.77
-KPX Aacute Q -27.77
-KPX Aacute T -83.31
-KPX Aacute U -27.77
-KPX Aacute V -111.08
-KPX Aacute W -111.08
-KPX Aacute Y -83.31
-KPX Aacute t -27.77
-KPX Abreve C -27.77
-KPX Abreve G -27.77
-KPX Abreve O -27.77
-KPX Abreve Q -27.77
-KPX Abreve T -83.31
-KPX Abreve U -27.77
-KPX Abreve V -111.08
-KPX Abreve W -111.08
-KPX Abreve Y -83.31
-KPX Abreve t -27.77
-KPX Acircumflex C -27.77
-KPX Acircumflex G -27.77
-KPX Acircumflex O -27.77
-KPX Acircumflex Q -27.77
-KPX Acircumflex T -83.31
-KPX Acircumflex U -27.77
-KPX Acircumflex V -111.08
-KPX Acircumflex W -111.08
-KPX Acircumflex Y -83.31
-KPX Acircumflex t -27.77
-KPX Adieresis C -27.77
-KPX Adieresis G -27.77
-KPX Adieresis O -27.77
-KPX Adieresis Q -27.77
-KPX Adieresis T -83.31
-KPX Adieresis U -27.77
-KPX Adieresis V -111.08
-KPX Adieresis W -111.08
-KPX Adieresis Y -83.31
-KPX Adieresis t -27.77
-KPX Agrave C -27.77
-KPX Agrave G -27.77
-KPX Agrave O -27.77
-KPX Agrave Q -27.77
-KPX Agrave T -83.31
-KPX Agrave U -27.77
-KPX Agrave V -111.08
-KPX Agrave W -111.08
-KPX Agrave Y -83.31
-KPX Agrave t -27.77
-KPX Aogonek C -27.77
-KPX Aogonek G -27.77
-KPX Aogonek O -27.77
-KPX Aogonek Q -27.77
-KPX Aogonek T -83.31
-KPX Aogonek U -27.77
-KPX Aogonek V -111.08
-KPX Aogonek W -111.08
-KPX Aogonek Y -83.31
-KPX Aogonek t -27.77
-KPX Aring C -27.77
-KPX Aring G -27.77
-KPX Aring O -27.77
-KPX Aring Q -27.77
-KPX Aring T -83.31
-KPX Aring U -27.77
-KPX Aring V -111.08
-KPX Aring W -111.08
-KPX Aring Y -83.31
-KPX Aring t -27.77
-KPX Atilde C -27.77
-KPX Atilde G -27.77
-KPX Atilde O -27.77
-KPX Atilde Q -27.77
-KPX Atilde T -83.31
-KPX Atilde U -27.77
-KPX Atilde V -111.08
-KPX Atilde W -111.08
-KPX Atilde Y -83.31
-KPX Atilde t -27.77
-KPX D A -27.77
-KPX D V -27.77
-KPX D W -27.77
-KPX D X -27.77
-KPX D Y -27.77
-KPX F A -111.08
-KPX F C -27.77
-KPX F G -27.77
-KPX F O -27.77
-KPX F Q -27.77
-KPX F a -83.31
-KPX F e -83.31
-KPX F o -83.31
-KPX F r -83.31
-KPX F u -83.31
-KPX I I 27.77
-KPX K C -27.77
-KPX K G -27.77
-KPX K O -27.77
-KPX K Q -27.77
-KPX L T -83.31
-KPX L V -111.08
-KPX L W -111.08
-KPX L Y -83.31
-KPX O A -27.77
-KPX O V -27.77
-KPX O W -27.77
-KPX O X -27.77
-KPX O Y -27.77
-KPX P A -83.31
-KPX P a -27.77
-KPX P aacute -27.77
-KPX P acircumflex -27.77
-KPX P acircumflex -27.77
-KPX P adieresis -27.77
-KPX P ae -27.77
-KPX P agrave -27.77
-KPX P aogonek -27.77
-KPX P aring -27.77
-KPX P atilde -27.77
-KPX P cacute -27.77
-KPX P comma -83.31
-KPX P e -27.77
-KPX P eacute -27.77
-KPX P ecaron -27.77
-KPX P ecircumflex -27.77
-KPX P edieresis -27.77
-KPX P egrave -27.77
-KPX P eogonek -27.77
-KPX P o -27.77
-KPX P oacute -27.77
-KPX P ocircumflex -27.77
-KPX P odieresis -27.77
-KPX P oe -27.77
-KPX P ograve -27.77
-KPX P ohungarumlaut -27.77
-KPX P otilde -27.77
-KPX P period -83.31
-KPX R C -27.77
-KPX R G -27.77
-KPX R O -27.77
-KPX R Q -27.77
-KPX R T -83.31
-KPX R U -27.77
-KPX R V -111.08
-KPX R W -111.08
-KPX R Y -83.31
-KPX R t -27.77
-KPX T A -83.31
-KPX T a -83.31
-KPX T e -83.31
-KPX T o -83.31
-KPX T r -83.31
-KPX T u -83.31
-KPX T y -27.77
-KPX V A -111.08
-KPX V C -27.77
-KPX V G -27.77
-KPX V O -27.77
-KPX V Q -27.77
-KPX V a -83.31
-KPX V e -83.31
-KPX V o -83.31
-KPX V r -83.31
-KPX V u -83.31
-KPX W A -111.08
-KPX W C -27.77
-KPX W G -27.77
-KPX W O -27.77
-KPX W Q -27.77
-KPX W a -83.31
-KPX W e -83.31
-KPX W o -83.31
-KPX W r -83.31
-KPX W u -83.31
-KPX X C -27.77
-KPX X G -27.77
-KPX X O -27.77
-KPX X Q -27.77
-KPX Y A -83.31
-KPX Y a -83.31
-KPX Y e -83.31
-KPX Y o -83.31
-KPX Y r -83.31
-KPX Y u -83.31
-KPX a j 55.54
-KPX a v -27.77
-KPX a w -27.77
-KPX a y -27.77
-KPX b c 27.77
-KPX b cacute 27.77
-KPX b ccaron 27.77
-KPX b ccedilla 27.77
-KPX b d 27.77
-KPX b e 27.77
-KPX b eacute 27.77
-KPX b ecaron 27.77
-KPX b ecircumflex 27.77
-KPX b edieresis 27.77
-KPX b egrave 27.77
-KPX b eogonek 27.77
-KPX b j 55.54
-KPX b o 27.77
-KPX b oacute 27.77
-KPX b ocircumflex 27.77
-KPX b odieresis 27.77
-KPX b oe 27.77
-KPX b ograve 27.77
-KPX b ohungarumlaut 27.77
-KPX b otilde 27.77
-KPX b q 27.77
-KPX b v -27.77
-KPX b w -27.77
-KPX b x -27.77
-KPX b y -27.77
-KPX c h -27.77
-KPX c k -27.77
-KPX f bracketright 77.76
-KPX f exclam 77.76
-KPX f parenright 77.76
-KPX f question 77.76
-KPX f quoteright 77.76
-KPX ff bracketright 77.76
-KPX ff exclam 77.76
-KPX ff parenright 77.76
-KPX ff question 77.76
-KPX ff quoteright 77.76
-KPX g j 27.77
-KPX h b -27.77
-KPX h t -27.77
-KPX h u -27.77
-KPX h uacute -27.77
-KPX h ucircumflex -27.77
-KPX h udieresis -27.77
-KPX h ugrave -27.77
-KPX h uhungarumlaut -27.77
-KPX h uring -27.77
-KPX h v -27.77
-KPX h w -27.77
-KPX h y -27.77
-KPX k a -27.77
-KPX k a -55.54
-KPX k aacute -27.77
-KPX k aacute -55.54
-KPX k acircumflex -55.54
-KPX k acircumflex -55.54
-KPX k acircumflex -27.77
-KPX k acircumflex -27.77
-KPX k adieresis -27.77
-KPX k adieresis -55.54
-KPX k ae -55.54
-KPX k ae -27.77
-KPX k agrave -55.54
-KPX k agrave -27.77
-KPX k aogonek -55.54
-KPX k aogonek -27.77
-KPX k aring -55.54
-KPX k aring -27.77
-KPX k atilde -27.77
-KPX k atilde -55.54
-KPX k c -27.77
-KPX k cacute -27.77
-KPX k cacute -27.77
-KPX k cacute -55.54
-KPX k ccaron -27.77
-KPX k ccedilla -27.77
-KPX k e -27.77
-KPX k eacute -27.77
-KPX k ecaron -27.77
-KPX k ecircumflex -27.77
-KPX k edieresis -27.77
-KPX k egrave -27.77
-KPX k eogonek -27.77
-KPX k o -27.77
-KPX k oacute -27.77
-KPX k ocircumflex -27.77
-KPX k odieresis -27.77
-KPX k oe -27.77
-KPX k ograve -27.77
-KPX k ohungarumlaut -27.77
-KPX k otilde -27.77
-KPX m b -27.77
-KPX m t -27.77
-KPX m u -27.77
-KPX m uacute -27.77
-KPX m ucircumflex -27.77
-KPX m udieresis -27.77
-KPX m ugrave -27.77
-KPX m uhungarumlaut -27.77
-KPX m uring -27.77
-KPX m v -27.77
-KPX m w -27.77
-KPX m y -27.77
-KPX n b -27.77
-KPX n t -27.77
-KPX n u -27.77
-KPX n uacute -27.77
-KPX n ucircumflex -27.77
-KPX n udieresis -27.77
-KPX n ugrave -27.77
-KPX n uhungarumlaut -27.77
-KPX n uring -27.77
-KPX n v -27.77
-KPX n w -27.77
-KPX n y -27.77
-KPX o c 27.77
-KPX o cacute 27.77
-KPX o ccaron 27.77
-KPX o ccedilla 27.77
-KPX o d 27.77
-KPX o e 27.77
-KPX o eacute 27.77
-KPX o ecaron 27.77
-KPX o ecircumflex 27.77
-KPX o edieresis 27.77
-KPX o egrave 27.77
-KPX o eogonek 27.77
-KPX o j 55.54
-KPX o o 27.77
-KPX o oacute 27.77
-KPX o ocircumflex 27.77
-KPX o odieresis 27.77
-KPX o oe 27.77
-KPX o ograve 27.77
-KPX o ohungarumlaut 27.77
-KPX o otilde 27.77
-KPX o q 27.77
-KPX o v -27.77
-KPX o w -27.77
-KPX o x -27.77
-KPX o y -27.77
-KPX p c 27.77
-KPX p cacute 27.77
-KPX p ccaron 27.77
-KPX p ccedilla 27.77
-KPX p d 27.77
-KPX p e 27.77
-KPX p eacute 27.77
-KPX p ecaron 27.77
-KPX p ecircumflex 27.77
-KPX p edieresis 27.77
-KPX p egrave 27.77
-KPX p eogonek 27.77
-KPX p j 55.54
-KPX p o 27.77
-KPX p oacute 27.77
-KPX p ocircumflex 27.77
-KPX p odieresis 27.77
-KPX p oe 27.77
-KPX p ograve 27.77
-KPX p ohungarumlaut 27.77
-KPX p otilde 27.77
-KPX p q 27.77
-KPX p v -27.77
-KPX p w -27.77
-KPX p x -27.77
-KPX p y -27.77
-KPX quoteright exclam 111.08
-KPX quoteright question 111.08
-KPX t w -27.77
-KPX t y -27.77
-KPX u w -27.77
-KPX v a -27.77
-KPX v a -55.54
-KPX v aacute -27.77
-KPX v aacute -55.54
-KPX v acircumflex -55.54
-KPX v acircumflex -27.77
-KPX v acircumflex -27.77
-KPX v acircumflex -55.54
-KPX v adieresis -27.77
-KPX v adieresis -55.54
-KPX v ae -27.77
-KPX v ae -55.54
-KPX v agrave -27.77
-KPX v agrave -55.54
-KPX v aogonek -55.54
-KPX v aogonek -27.77
-KPX v aring -55.54
-KPX v aring -27.77
-KPX v atilde -55.54
-KPX v atilde -27.77
-KPX v c -27.77
-KPX v cacute -55.54
-KPX v cacute -27.77
-KPX v cacute -27.77
-KPX v ccaron -27.77
-KPX v ccedilla -27.77
-KPX v e -27.77
-KPX v eacute -27.77
-KPX v ecaron -27.77
-KPX v ecircumflex -27.77
-KPX v edieresis -27.77
-KPX v egrave -27.77
-KPX v eogonek -27.77
-KPX v o -27.77
-KPX v oacute -27.77
-KPX v ocircumflex -27.77
-KPX v odieresis -27.77
-KPX v oe -27.77
-KPX v ograve -27.77
-KPX v ohungarumlaut -27.77
-KPX v otilde -27.77
-KPX w a -27.77
-KPX w aacute -27.77
-KPX w acircumflex -27.77
-KPX w acircumflex -27.77
-KPX w adieresis -27.77
-KPX w ae -27.77
-KPX w agrave -27.77
-KPX w aogonek -27.77
-KPX w aring -27.77
-KPX w atilde -27.77
-KPX w c -27.77
-KPX w cacute -27.77
-KPX w cacute -27.77
-KPX w ccaron -27.77
-KPX w ccedilla -27.77
-KPX w e -27.77
-KPX w eacute -27.77
-KPX w ecaron -27.77
-KPX w ecircumflex -27.77
-KPX w edieresis -27.77
-KPX w egrave -27.77
-KPX w eogonek -27.77
-KPX w o -27.77
-KPX w oacute -27.77
-KPX w ocircumflex -27.77
-KPX w odieresis -27.77
-KPX w oe -27.77
-KPX w ograve -27.77
-KPX w ohungarumlaut -27.77
-KPX w otilde -27.77
-KPX y a -27.77
-KPX y aacute -27.77
-KPX y acircumflex -27.77
-KPX y acircumflex -27.77
-KPX y adieresis -27.77
-KPX y ae -27.77
-KPX y agrave -27.77
-KPX y aogonek -27.77
-KPX y aring -27.77
-KPX y atilde -27.77
-KPX y cacute -27.77
-KPX y comma -83.31
-KPX y e -27.77
-KPX y eacute -27.77
-KPX y ecaron -27.77
-KPX y ecircumflex -27.77
-KPX y edieresis -27.77
-KPX y egrave -27.77
-KPX y eogonek -27.77
-KPX y o -27.77
-KPX y oacute -27.77
-KPX y ocircumflex -27.77
-KPX y odieresis -27.77
-KPX y oe -27.77
-KPX y ograve -27.77
-KPX y ohungarumlaut -27.77
-KPX y otilde -27.77
-KPX y period -83.31
-EndKernPairs
-EndKernData
-EndFontMetrics
checktype => 1,
},
t1=>{
- class=>'Imager::Font::Type1',
- module=>'Imager/Font/Type1.pm',
+ class=>'Imager::Font::T1',
+ module=>'Imager/Font/T1.pm',
files=>'.*\.pfb$',
description => 'T1Lib',
checktype => 1,
package Imager::Font::Type1;
use strict;
-use Imager::Color;
+use Imager::Font::T1;
use vars qw(@ISA $VERSION);
-@ISA = qw(Imager::Font);
-
-$VERSION = "1.011";
-
-*_first = \&Imager::Font::_first;
-
-my $t1aa;
-
-# $T1AA is in there because for some reason (probably cache related) antialiasing
-# is a system wide setting in t1 lib.
-
-sub t1_set_aa_level {
- if (!defined $t1aa or $_[0] != $t1aa) {
- Imager::i_t1_set_aa($_[0]);
- $t1aa=$_[0];
- }
-}
-
-sub new {
- my $class = shift;
- my %hsh=(color=>Imager::Color->new(255,0,0,0),
- size=>15,
- @_);
-
- unless ($hsh{file}) {
- $Imager::ERRSTR = "No font file specified";
- return;
- }
- unless (-e $hsh{file}) {
- $Imager::ERRSTR = "Font file $hsh{file} not found";
- return;
- }
- unless ($Imager::formats{t1}) {
- $Imager::ERRSTR = "Type 1 fonts not supported in this build";
- return;
- }
- # we want to avoid T1Lib's file search mechanism
- unless ($hsh{file} =~ m!^/!
- || $hsh{file} =~ m!^\.\/?/!
- || $^O =~ /^(MSWin32|cygwin)$/ && $hsh{file} =~ /^[a-z]:/) {
- $hsh{file} = './' . $hsh{file};
- }
-
- if($hsh{afm}) {
- unless (-e $hsh{afm}) {
- $Imager::ERRSTR = "Afm file $hsh{afm} not found";
- return;
- }
- unless ($hsh{afm} =~ m!^/!
- || $hsh{afm} =~ m!^\./!
- || $^O =~ /^(MSWin32|cygwin)$/ && $hsh{file} =~ /^[a-z]:/) {
- $hsh{file} = './' . $hsh{file};
- }
- } else {
- $hsh{afm} = 0;
- }
-
- my $id = Imager::i_t1_new($hsh{file},$hsh{afm});
- unless ($id >= 0) { # the low-level code may miss some error handling
- $Imager::ERRSTR = "Could not load font ($id)";
- return;
- }
- return bless {
- id => $id,
- aa => $hsh{aa} || 0,
- file => $hsh{file},
- type => 't1',
- size => $hsh{size},
- color => $hsh{color},
- }, $class;
-}
-
-sub _draw {
- my $self = shift;
- my %input = @_;
- t1_set_aa_level($input{aa});
- my $flags = '';
- $flags .= 'u' if $input{underline};
- $flags .= 's' if $input{strikethrough};
- $flags .= 'o' if $input{overline};
- if (exists $input{channel}) {
- Imager::i_t1_cp($input{image}{IMG}, $input{'x'}, $input{'y'},
- $input{channel}, $self->{id}, $input{size},
- $input{string}, length($input{string}), $input{align},
- $input{utf8}, $flags);
- } else {
- Imager::i_t1_text($input{image}{IMG}, $input{'x'}, $input{'y'},
- $input{color}, $self->{id}, $input{size},
- $input{string}, length($input{string}),
- $input{align}, $input{utf8}, $flags);
- }
-
- return $self;
-}
-
-sub _bounding_box {
- my $self = shift;
- my %input = @_;
- my $flags = '';
- $flags .= 'u' if $input{underline};
- $flags .= 's' if $input{strikethrough};
- $flags .= 'o' if $input{overline};
- return Imager::i_t1_bbox($self->{id}, $input{size}, $input{string},
- length($input{string}), $input{utf8}, $flags);
-}
-
-# check if the font has the characters in the given string
-sub has_chars {
- my ($self, %hsh) = @_;
-
- unless (defined $hsh{string} && length $hsh{string}) {
- $Imager::ERRSTR = "No string supplied to \$font->has_chars()";
- return;
- }
- return Imager::i_t1_has_chars($self->{id}, $hsh{string},
- _first($hsh{'utf8'}, $self->{utf8}, 0));
-}
-
-sub utf8 {
- 1;
-}
-
-sub face_name {
- my ($self) = @_;
-
- Imager::i_t1_face_name($self->{id});
-}
-
-sub glyph_names {
- my ($self, %input) = @_;
-
- my $string = $input{string};
- defined $string
- or return Imager->_set_error("no string parameter passed to glyph_names");
- my $utf8 = _first($input{utf8} || 0);
-
- Imager::i_t1_glyph_name($self->{id}, $string, $utf8);
-}
+@ISA = qw(Imager::Font::FT2);
+$VERSION = "1.000";
1;
=head1 NAME
- Imager::Font::Type1 - low-level functions for Type1 fonts
+ Imager::Font::Type1 - low-level functions for T1Lib text output
=head1 DESCRIPTION
-Imager::Font creates a Imager::Font::Type1 object when asked to create
-a font object based on a C<.pfb> file.
-
-See Imager::Font to see how to use this type.
-
-This class provides low-level functions that require the caller to
-perform data validation
-
-By default Imager no longer creates the F<t1lib.log> log file. You
-can re-enable that by calling Imager::init() with the C<t1log> option:
-
- Imager::init(t1log=>1);
-
-This must be called before creating any fonts.
-
-Currently specific to Imager::Font::Type1, you can use the following
-flags when drawing text or calculating a bounding box:
-
-=for stopwords overline strikethrough
-
-=over
-
-=item *
-
-C<underline> - Draw the text with an underline.
-
-=item *
-
-C<overline> - Draw the text with an overline.
-
-=item *
-
-C<strikethrough> - Draw the text with a strikethrough.
-
-=back
-
-Obviously, if you're calculating the bounding box the size of the line
-is included in the box, and the line isn't drawn :)
+This is a simple wrapper around Imager::Font::T1 for backwards
+compatibility.
=head1 AUTHOR
-Addi, Tony
+Tony Cook <tonyc@cpan.org>
=cut
+++ /dev/null
-#!perl -w
-# Before `make install' is performed this script should be runnable with
-# `make test'. After `make install' it should work as `perl test.pl'
-
-######################### We start with some black magic to print on failure.
-
-# Change 1..1 below to 1..last_test_to_print .
-# (It may become useful if the test is moved to ./t subdirectory.)
-use strict;
-use Test::More;
-use Imager ':all';
-use Imager::Test qw(diff_text_with_nul is_color3);
-use Cwd qw(getcwd abs_path);
-
-#$Imager::DEBUG=1;
-
-i_has_format("t1")
- or plan skip_all => "t1lib unavailble or disabled";
-
-plan tests => 95;
-
--d "testout" or mkdir "testout";
-
-init_log("testout/t30t1font.log",1);
-
-my $deffont = 'fontfiles/dcr10.pfb';
-
-my $fontname_pfb=$ENV{'T1FONTTESTPFB'}||$deffont;
-my $fontname_afm=$ENV{'T1FONTTESTAFM'}||'./fontfiles/dcr10.afm';
-
--f $fontname_pfb
- or skip_all("cannot find fontfile for type 1 test $fontname_pfb");
--f $fontname_afm
- or skip_all("cannot find fontfile for type 1 test $fontname_afm");
-
-SKIP:
-{
- print "# has t1\n";
-
- #i_t1_set_aa(1);
-
- unlink "t1lib.log"; # lose it if it exists
- init(t1log=>0);
- ok(!-e("t1lib.log"), "disable t1log");
- init(t1log=>1);
- ok(-e("t1lib.log"), "enable t1log");
- init(t1log=>0);
- unlink "t1lib.log";
-
- my $fnum=Imager::i_t1_new($fontname_pfb,$fontname_afm); # this will load the pfb font
- unless (ok($fnum >= 0, "load font $fontname_pfb")) {
- skip("without the font I can't do a thing", 90);
- }
-
- my $bgcolor=Imager::Color->new(255,0,0,0);
- my $overlay=Imager::ImgRaw::new(200,70,3);
-
- ok(i_t1_cp($overlay,5,50,1,$fnum,50.0,'XMCLH',5,1), "i_t1_cp");
-
- i_line($overlay,0,50,100,50,$bgcolor,1);
-
- my @bbox=i_t1_bbox(0,50.0,'XMCLH',5);
- is(@bbox, 8, "i_t1_bbox");
- print "# bbox: ($bbox[0], $bbox[1]) - ($bbox[2], $bbox[3])\n";
-
- open(FH,">testout/t30t1font.ppm") || die "cannot open testout/t35t1font.ppm\n";
- binmode(FH); # for os2
- my $IO = Imager::io_new_fd( fileno(FH) );
- i_writeppm_wiol($overlay,$IO);
- close(FH);
-
- $bgcolor=Imager::Color::set($bgcolor,200,200,200,0);
- my $backgr=Imager::ImgRaw::new(280,300,3);
-
- i_t1_set_aa(2);
- ok(i_t1_text($backgr,10,100,$bgcolor,$fnum,150.0,'test',4,1), "i_t1_text");
-
- # "UTF8" tests
- # for perl < 5.6 we can hand-encode text
- # since T1 doesn't support over 256 chars in an encoding we just drop
- # chars over \xFF
- # the following is "A\xA1\x{2010}A"
- #
- my $text = pack("C*", 0x41, 0xC2, 0xA1, 0xE2, 0x80, 0x90, 0x41);
- my $alttext = "A\xA1A";
-
- my @utf8box = i_t1_bbox($fnum, 50.0, $text, length($text), 1);
- is(@utf8box, 8, "utf8 bbox element count");
- my @base = i_t1_bbox($fnum, 50.0, $alttext, length($alttext), 0);
- is(@base, 8, "alt bbox element count");
- my $maxdiff = $fontname_pfb eq $deffont ? 0 : $base[2] / 3;
- print "# (@utf8box vs @base)\n";
- ok(abs($utf8box[2] - $base[2]) <= $maxdiff,
- "compare box sizes $utf8box[2] vs $base[2] (maxerror $maxdiff)");
-
- # hand-encoded UTF8 drawing
- ok(i_t1_text($backgr, 10, 140, $bgcolor, $fnum, 32, $text, length($text), 1,1), "draw hand-encoded UTF8");
-
- ok(i_t1_cp($backgr, 80, 140, 1, $fnum, 32, $text, length($text), 1, 1),
- "cp hand-encoded UTF8");
-
- # ok, try native perl UTF8 if available
- SKIP:
- {
- $] >= 5.006 or skip("perl too old to test native UTF8 support", 5);
- my $text;
- # we need to do this in eval to prevent compile time errors in older
- # versions
- eval q{$text = "A\xA1\x{2010}A"}; # A, a with ogonek, HYPHEN, A in our test font
- #$text = "A".chr(0xA1).chr(0x2010)."A"; # this one works too
- ok(i_t1_text($backgr, 10, 180, $bgcolor, $fnum, 32, $text, length($text), 1),
- "draw UTF8");
- ok(i_t1_cp($backgr, 80, 180, 1, $fnum, 32, $text, length($text), 1),
- "cp UTF8");
- @utf8box = i_t1_bbox($fnum, 50.0, $text, length($text), 0);
- is(@utf8box, 8, "native utf8 bbox element count");
- ok(abs($utf8box[2] - $base[2]) <= $maxdiff,
- "compare box sizes native $utf8box[2] vs $base[2] (maxerror $maxdiff)");
- eval q{$text = "A\xA1\xA2\x01\x1F\x{0100}A"};
- ok(i_t1_text($backgr, 10, 220, $bgcolor, $fnum, 32, $text, 0, 1, 0, "uso"),
- "more complex output");
- }
-
- open(FH,">testout/t30t1font2.ppm") || die "cannot open testout/t35t1font.ppm\n";
- binmode(FH);
- $IO = Imager::io_new_fd( fileno(FH) );
- i_writeppm_wiol($backgr, $IO);
- close(FH);
-
- my $rc=i_t1_destroy($fnum);
- unless (ok($rc >= 0, "i_t1_destroy")) {
- print "# i_t1_destroy failed: rc=$rc\n";
- }
-
- print "# debug: ",join(" x ",i_t1_bbox(0,50,"eses",4) ),"\n";
- print "# debug: ",join(" x ",i_t1_bbox(0,50,"llll",4) ),"\n";
-
- # character existance tests - uses the special ExistenceTest font
- my $exists_font = 'fontfiles/ExistenceTest.pfb';
- my $exists_afm = 'fontfiles/ExistenceText.afm';
-
- -e $exists_font or die;
-
- my $font_num = Imager::i_t1_new($exists_font, $exists_afm);
- SKIP: {
- ok($font_num >= 0, 'loading test font')
- or skip('Could not load test font', 6);
- # first the list interface
- my @exists = Imager::i_t1_has_chars($font_num, "!A");
- is(@exists, 2, "return count from has_chars");
- ok($exists[0], "we have an exclamation mark");
- ok(!$exists[1], "we have no uppercase A");
-
- # then the scalar interface
- my $exists = Imager::i_t1_has_chars($font_num, "!A");
- is(length($exists), 2, "return scalar length");
- ok(ord(substr($exists, 0, 1)), "we have an exclamation mark");
- ok(!ord(substr($exists, 1, 1)), "we have no upper-case A");
- i_t1_destroy($font_num);
- }
-
- my $font = Imager::Font->new(file=>$exists_font, type=>'t1');
- SKIP:
- {
- ok($font, "loaded OO font")
- or skip("Could not load test font", 24);
- my @exists = $font->has_chars(string=>"!A");
- is(@exists, 2, "return count from has_chars");
- ok($exists[0], "we have an exclamation mark");
- ok(!$exists[1], "we have no uppercase A");
-
- # then the scalar interface
- my $exists = $font->has_chars(string=>"!A");
- is(length($exists), 2, "return scalar length");
- ok(ord(substr($exists, 0, 1)), "we have an exclamation mark");
- ok(!ord(substr($exists, 1, 1)), "we have no upper-case A");
-
- # check the advance width
- my @bbox = $font->bounding_box(string=>'/', size=>100);
- print "# @bbox\n";
- isnt($bbox[2], $bbox[5], "different advance to pos_width");
-
- # names
- my $face_name = Imager::i_t1_face_name($font->{id});
- print "# face $face_name\n";
- is($face_name, 'ExistenceTest', "face name");
- $face_name = $font->face_name;
- is($face_name, 'ExistenceTest', "face name");
-
- my @glyph_names = $font->glyph_names(string=>"!J/");
- is($glyph_names[0], 'exclam', "check exclam name OO");
- ok(!defined($glyph_names[1]), "check for no J name OO");
- is($glyph_names[2], 'slash', "check slash name OO");
-
- # this character chosen since when it's truncated to one byte it
- # becomes 0x21 or '!' which the font does define
- my $text = pack("C*", 0xE2, 0x80, 0xA1); # "\x{2021}" as utf-8
- @glyph_names = $font->glyph_names(string=>$text, utf8=>1);
- is($glyph_names[0], undef, "expect no glyph_name for \\x{20A1}");
-
- # make sure a missing string parameter is handled correctly
- eval {
- $font->glyph_names();
- };
- is($@, "", "correct error handling");
- cmp_ok(Imager->errstr, '=~', qr/no string parameter/, "error message");
-
- # test extended bounding box results
- # the test font is known to have a shorter advance width for that char
- @bbox = $font->bounding_box(string=>"/", size=>100);
- is(@bbox, 8, "should be 8 entries");
- isnt($bbox[6], $bbox[2], "different advance width");
- my $bbox = $font->bounding_box(string=>"/", size=>100);
- cmp_ok($bbox->pos_width, '>', $bbox->advance_width, "OO check");
-
- cmp_ok($bbox->right_bearing, '<', 0, "check right bearing");
-
- cmp_ok($bbox->display_width, '>', $bbox->advance_width,
- "check display width (roughly)");
-
- # check with a char that fits inside the box
- $bbox = $font->bounding_box(string=>"!", size=>100);
- print "# pos width ", $bbox->pos_width, "\n";
-
- # they aren't the same historically for the type 1 driver
- isnt($bbox->pos_width, $bbox->advance_width,
- "check backwards compatibility");
- cmp_ok($bbox->left_bearing, '>', 0, "left bearing positive");
- cmp_ok($bbox->right_bearing, '>', 0, "right bearing positive");
- cmp_ok($bbox->display_width, '<', $bbox->advance_width,
- "display smaller than advance");
- }
-
- SKIP:
- { print "# alignment tests\n";
- my $font = Imager::Font->new(file=>$deffont, type=>'t1');
- ok($font, "loaded deffont OO")
- or skip("could not load font:".Imager->errstr, 4);
- my $im = Imager->new(xsize=>140, ysize=>150);
- my %common =
- (
- font=>$font,
- size=>40,
- aa=>1,
- );
- $im->line(x1=>0, y1=>40, x2=>139, y2=>40, color=>'blue');
- $im->line(x1=>0, y1=>90, x2=>139, y2=>90, color=>'blue');
- $im->line(x1=>0, y1=>110, x2=>139, y2=>110, color=>'blue');
- for my $args ([ x=>5, text=>"A", color=>"white" ],
- [ x=>40, text=>"y", color=>"white" ],
- [ x=>75, text=>"A", channel=>1 ],
- [ x=>110, text=>"y", channel=>1 ]) {
- ok($im->string(%common, @$args, 'y'=>40), "A no alignment");
- ok($im->string(%common, @$args, 'y'=>90, align=>1), "A align=1");
- ok($im->string(%common, @$args, 'y'=>110, align=>0), "A align=0");
- }
- ok($im->write(file=>'testout/t30align.ppm'), "save align image");
- }
-
- SKIP:
- {
- # see http://rt.cpan.org/Ticket/Display.html?id=20555
- print "# bounding box around spaces\n";
- # SpaceTest contains 3 characters, space, ! and .undef
- # only characters that define character zero seem to illustrate
- # the problem we had with spaces
- my $space_fontfile = "fontfiles/SpaceTest.pfb";
- my $font = Imager::Font->new(file => $space_fontfile, type => 't1');
- ok($font, "loaded $deffont")
- or skip("failed to load $deffont" . Imager->errstr, 13);
- my $bbox = $font->bounding_box(string => "", size => 36);
- print "# empty string bbox: @$bbox\n";
- is($bbox->start_offset, 0, "empty string start_offset");
- is($bbox->end_offset, 0, "empty string end_offset");
- is($bbox->advance_width, 0, "empty string advance_width");
- is($bbox->ascent, 0, "empty string ascent");
- is($bbox->descent, 0, "empty string descent");
-
- # a single space
- my $bbox_space = $font->bounding_box(string => " ", size => 36);
- print "# space bbox: @$bbox_space\n";
- is($bbox_space->start_offset, 0, "single space start_offset");
- is($bbox_space->end_offset, $bbox_space->advance_width,
- "single space end_offset");
- cmp_ok($bbox_space->ascent, '>=', $bbox_space->descent,
- "single space ascent/descent");
-
- my $bbox_bang = $font->bounding_box(string => "!", size => 36);
- print "# '!' bbox: @$bbox_bang\n";
-
- # space ! space
- my $bbox_spbangsp = $font->bounding_box(string => " ! ", size => 36);
- print "# ' ! ' bbox: @$bbox_spbangsp\n";
- my $exp_advance = $bbox_bang->advance_width + 2 * $bbox_space->advance_width;
- is($bbox_spbangsp->advance_width, $exp_advance, "sp ! sp advance_width");
- is($bbox_spbangsp->start_offset, 0, "sp ! sp start_offset");
- is($bbox_spbangsp->end_offset, $exp_advance, "sp ! sp end_offset");
- }
-
- SKIP:
- { # http://rt.cpan.org/Ticket/Display.html?id=20554
- # this is "A\xA1\x{2010}A"
- # the t1 driver is meant to ignore any UTF8 characters over 0xff
- print "# issue 20554\n";
- my $text = pack("C*", 0x41, 0xC2, 0xA1, 0xE2, 0x80, 0x90, 0x41);
- my $tran_text = "A\xA1A";
- my $font = Imager::Font->new(file => 'fontfiles/dcr10.pfb', type => 't1');
- $font
- or skip("cannot load font fontfiles/fcr10.pfb:".Imager->errstr, 1);
- my $bbox_utf8 = $font->bounding_box(string => $text, utf8 => 1, size => 36);
- my $bbox_tran = $font->bounding_box(string => $tran_text, size => 36);
- is($bbox_utf8->advance_width, $bbox_tran->advance_width,
- "advance widths should match");
- }
- { # string output cut off at NUL ('\0')
- # https://rt.cpan.org/Ticket/Display.html?id=21770 cont'd
- my $font = Imager::Font->new(file => 'fontfiles/dcr10.pfb', type => 't1');
- ok($font, "loaded dcr10.pfb");
-
- diff_text_with_nul("a\\0b vs a", "a\0b", "a",
- font => $font, color => '#FFFFFF');
- diff_text_with_nul("a\\0b vs a", "a\0b", "a",
- font => $font, channel => 1);
-
- # UTF8 encoded \xBF
- my $pound = pack("C*", 0xC2, 0xBF);
- diff_text_with_nul("utf8 pound\0pound vs pound", "$pound\0$pound", $pound,
- font => $font, color => '#FFFFFF', utf8 => 1);
- diff_text_with_nul("utf8 dash\0dash vs dash", "$pound\0$pound", $pound,
- font => $font, channel => 1, utf8 => 1);
-
- }
-
- { # RT 11972
- # when rendering to a transparent image the coverage should be
- # expressed in terms of the alpha channel rather than the color
- my $font = Imager::Font->new(file=>'fontfiles/dcr10.pfb', type=>'t1');
- my $im = Imager->new(xsize => 40, ysize => 20, channels => 4);
- ok($im->string(string => "AB", size => 20, aa => 2, color => '#F00',
- x => 0, y => 15, font => $font),
- "draw to transparent image");
- my $im_noalpha = $im->convert(preset => 'noalpha');
- my $im_pal = $im->to_paletted(make_colors => 'mediancut');
- my @colors = $im_pal->getcolors;
- is(@colors, 2, "should be only 2 colors");
- @colors = sort { ($a->rgba)[0] <=> ($b->rgba)[0] } @colors;
- is_color3($colors[0], 0, 0, 0, "check we got black");
- is_color3($colors[1], 255, 0, 0, "and red");
- }
-
- SKIP:
- { # RT 60509
- # checks that a c:foo or c:\foo path is handled correctly on win32
- my $type = "t1";
- $^O eq "MSWin32" || $^O eq "cygwin"
- or skip("only for win32", 2);
- my $dir = getcwd
- or skip("Cannot get cwd", 2);
- if ($^O eq "cygwin") {
- $dir = Cygwin::posix_to_win_path($dir);
- }
- my $abs_path = abs_path($deffont);
- my $font = Imager::Font->new(file => $abs_path, type => $type);
- ok($font, "found font by absolute path")
- or print "# path $abs_path\n";
- undef $font;
-
- $^O eq "cygwin"
- and skip("cygwin doesn't support drive relative DOSsish paths", 1);
- my ($drive) = $dir =~ /^([a-z]:)/i
- or skip("cwd has no drive letter", 2);
- my $drive_path = $drive . $deffont;
- $font = Imager::Font->new(file => $drive_path, type => $type);
- ok($font, "found font by drive relative path")
- or print "# path $drive_path\n";
- }
-}
-
-#malloc_state();
# Change 1..1 below to 1..last_test_to_print .
# (It may become useful if the test is moved to ./t subdirectory.)
-use Test::More tests => 20;
+use Test::More tests => 12;
BEGIN { use_ok('Imager') };
init_log("testout/t36oofont.log", 1);
my $fontname_tt=$ENV{'TTFONTTEST'}||'./fontfiles/dodge.ttf';
-my $fontname_pfb=$ENV{'T1FONTTESTPFB'}||'./fontfiles/dcr10.pfb';
-
my $green=Imager::Color->new(92,205,92,128);
die $Imager::ERRSTR unless $green;
my $red=Imager::Color->new(205, 92, 92, 255);
die $Imager::ERRSTR unless $red;
-SKIP:
-{
- i_has_format("t1") && -f $fontname_pfb
- or skip("T1lib missing or disabled", 8);
-
- my $img=Imager->new(xsize=>300, ysize=>100) or die "$Imager::ERRSTR\n";
-
- my $font=Imager::Font->new(file=>$fontname_pfb,size=>25)
- or die $img->{ERRSTR};
-
- ok(1, "created font");
-
- ok($img->string(font=>$font, text=>"XMCLH", 'x'=>100, 'y'=>100),
- "draw text");
- $img->line(x1=>0, x2=>300, y1=>50, y2=>50, color=>$green);
-
- my $text="LLySja";
- my @bbox=$font->bounding_box(string=>$text, 'x'=>0, 'y'=>50);
-
- is(@bbox, 8, "bounding box list length");
-
- $img->box(box=>\@bbox, color=>$green);
-
- # "utf8" support
- $text = pack("C*", 0x41, 0xE2, 0x80, 0x90, 0x41);
- ok($img->string(font=>$font, text=>$text, 'x'=>100, 'y'=>50, utf8=>1,
- overline=>1),
- "draw 'utf8' hand-encoded text");
-
- ok($img->string(font=>$font, text=>$text, 'x'=>140, 'y'=>50, utf8=>1,
- underline=>1, channel=>2),
- "channel 'utf8' hand-encoded text");
-
- SKIP:
- {
- $] >= 5.006
- or skip("perl too old for native utf8", 2);
- eval q{$text = "A\x{2010}A"};
- ok($img->string(font=>$font, text=>$text, 'x'=>180, 'y'=>50,
- strikethrough=>1),
- "draw native UTF8 text");
- ok($img->string(font=>$font, text=>$text, 'x'=>220, 'y'=>50, channel=>1),
- "channel native UTF8 text");
- }
-
- ok($img->write(file=>"testout/t36oofont1.ppm", type=>'pnm'),
- "write t36oofont1.ppm")
- or print "# ",$img->errstr,"\n";
-
-}
-
SKIP:
{
i_has_format("tt") && -f $fontname_tt