use ExtUtils::Manifest qw(maniread);
use ExtUtils::Liblist;
use vars qw(%formats $VERBOSE $INCPATH $LIBPATH $NOLOG $DEBUG_MALLOC $MANUAL $CFLAGS $LFLAGS $DFLAGS);
-use lib 'inc';
-use Devel::CheckLib;
+use lib 'inc', 'lib';
+use Imager::Probe;
# EU::MM runs Makefile.PL all in the same process, so sub-modules will
# see this
my $KEEP_FILES = $ENV{IMAGER_KEEP_FILES};
+# make sure --verbose will dump environment settings
+if (grep $_ =~ /^--?v(?:erbose)?$/, @ARGV) {
+ $VERBOSE = 1;
+}
+
+# modules/features bundled with Imager that can be enabled/disabled
+# withs --enable/--disable
+my @bundled = qw(FT1 FT2 GIF JPEG PNG T1 TIFF W32);
+
+# extra modules bundled with Imager not available on CPAN
+my @extras = qw(CountColor DynTest ICO SGI Mandelbrot Flines);
+
+# alternate names for modules
+my %bundled_names = qw(win32 w32 tt ft1);
+
getenv(); # get environment variables
my $lext=$Config{'so'}; # Get extensions of libraries
init(); # initialize global data
pathcheck(); # Check if directories exist
+my @enabled_bundled;
if (exists $ENV{IM_ENABLE}) {
- my %en = map { $_, 1 } split ' ', $ENV{IM_ENABLE};
- for my $key (keys %formats) {
- delete $formats{$key} unless $en{$key};
- }
+ push @enable, split ' ', $ENV{IM_ENABLE};
}
if (@enable) {
- my %en = map { $_ => 1 } map { split /,/ } @enable;
- for my $key (keys %formats) {
- delete $formats{$key} unless $en{$key};
- }
+ my %en = map { lc $_ => 1 } map_bundled(@enable);
+ @enabled_bundled = grep $en{lc $_}, @bundled;
}
elsif (@disable) {
- delete @formats{map { split /,/ } @disable};
+ my %dis = map { lc $_ => 1 } map_bundled(@disable);
+ @enabled_bundled = grep !$dis{lc $_}, @bundled;
+}
+else {
+ @enabled_bundled = @bundled;
}
# Pick what libraries are used
automatic();
}
-my $lib_cflags = '';
-my $lib_lflags = '';
-my $F_LIBS = '';
-my $F_OBJECT = '';
+my @objs = qw(Imager.o context.o draw.o polygon.o image.o io.o iolayer.o
+ log.o gaussian.o conv.o pnm.o raw.o feat.o combine.o
+ filters.o dynaload.o stackmach.o datatypes.o
+ regmach.o trans2.o quant.o error.o convert.o
+ map.o tags.o palimg.o maskimg.o img8.o img16.o rotate.o
+ bmp.o tga.o color.o fills.o imgdouble.o limits.o hlines.o
+ imext.o scale.o rubthru.o render.o paste.o compose.o flip.o
+ perlio.o);
+
+my $lib_define = '';
+my $lib_inc = '';
+my $lib_libs = '';
for my $frmkey (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
my $frm = $formats{$frmkey};
- push @defines, [ $frm->{def}, 1, "$frmkey available" ];
- $F_OBJECT .= ' ' .$frm->{objfiles};
- if ($frm->{cflags}) {
- $lib_cflags .= ' ' .$frm->{cflags};
- ++$definc{$_} for map { /^-I(.*)$/ ? ($1) : () }
- grep /^-I./, split ' ', $frm->{cflags};
+ if ($frm->{enabled}) {
+ push @defines, [ $frm->{def}, 1, "$frmkey available" ];
+ push @objs, $frm->{objfiles};
+ $lib_define .= " $frm->{DEFINE}" if $frm->{DEFINE};
+ $lib_inc .= " $frm->{INC}" if $frm->{INC};
+ $lib_libs .= " $frm->{LIBS}" if $frm->{LIBS};
}
- if ($frm->{lflags}) {
- $lib_lflags .= ' ' . $frm->{lflags};
- }
- else {
- $F_LIBS .= ' ' .$frm->{libfiles};
- }
-
}
-my $F_INC = join ' ', map "-I$_", map / / ? qq{"$_"} : $_,
- grep !$definc{$_}, @incs;
-$F_LIBS = join(' ',map "-L$_", map / / ? qq{"$_"} : $_,
- grep !$deflib{$_}++, @libs) . $F_LIBS;
-
my $OSLIBS = '';
my $OSDEF = "-DOS_$^O";
if ($^O eq 'hpux') { $OSLIBS .= ' -ldld'; }
if (defined $Config{'d_dlsymun'}) { $OSDEF .= ' -DDLSYMUN'; }
-my @objs = qw(Imager.o context.o draw.o polygon.o image.o io.o iolayer.o
- log.o gaussian.o conv.o pnm.o raw.o feat.o combine.o
- filters.o dynaload.o stackmach.o datatypes.o
- regmach.o trans2.o quant.o error.o convert.o
- map.o tags.o palimg.o maskimg.o img8.o img16.o rotate.o
- bmp.o tga.o color.o fills.o imgdouble.o limits.o hlines.o
- imext.o scale.o rubthru.o render.o paste.o compose.o flip.o
- perlio.o);
-
if ($Config{useithreads}) {
if ($Config{i_pthread}) {
print "POSIX threads\n";
$CFLAGS .= " -DIMAGER_TRACE_CONTEXT";
}
+my $tests = 't/*.t t/*/*.t';
+if (-d "xt" && scalar(() = glob("xt/*.t"))) {
+ $tests .= " xt/*.t";
+}
+
my %opts=
(
- 'NAME' => 'Imager',
- 'VERSION_FROM' => 'Imager.pm',
- 'LIBS' => "$LFLAGS -lm $lib_lflags $OSLIBS $F_LIBS",
- 'DEFINE' => "$OSDEF $CFLAGS",
- 'INC' => "$lib_cflags $DFLAGS $F_INC",
- 'OBJECT' => join(' ', @objs, $F_OBJECT),
+ NAME => 'Imager',
+ VERSION_FROM => 'Imager.pm',
+ LIBS => "$LFLAGS -lm $lib_libs $OSLIBS",
+ DEFINE => "$OSDEF $lib_define $CFLAGS",
+ INC => "$lib_inc $DFLAGS",
+ OBJECT => join(' ', @objs),
+ DIR => [ sort grep -d, @enabled_bundled, @extras ],
clean => { FILES=>'testout rubthru.c scale.c conv.c filters.c gaussian.c render.c rubthru.c' },
PM => gen_PM(),
PREREQ_PM =>
{
- 'Test::More' => 0.47,
+ 'Test::More' => 0.99,
'Scalar::Util' => 1.00,
'XSLoader' => 0,
},
TYPEMAPS => \@typemaps,
+ test => { TESTS => $tests },
);
if ($coverage) {
Please answer the following questions about
which formats are avaliable on your computer
+ Warning: if you use manual configuration you are responsible for
+ configuring extra include/library directories as necessary using
+ INC and LIBS command-line assignments.
+
press <return> to continue
EOF
my $gz = <STDIN>;
chomp($gz);
if ($gz =~ m/^(y|yes|n|no)/i) {
- $gz=substr(lc($gz),0,1);
- if ($gz eq 'n') {
- delete $formats{$frm};
+ if ($gz =~ /y/i) {
+ $formats{$frm}{enabled} = 1;
+ $IMAGER_LIBS{$frm} = 1;
}
} else { goto SWX; }
}
sub automatic {
print "Automatic probing:\n" if $VERBOSE;
- for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
- delete $formats{$frm} if !checkformat($frm);
- }
-}
-
-sub grep_directory {
- my($path, $chk)=@_;
-
-# print "checking path $path\n";
- if ( !opendir(DH,$path) ) {
- warn "Cannot open dir $path: $!\n";
- return;
- }
- my @l=grep { $chk->($_) } readdir(DH);
- # print @l;
- close(DH);
- return map $path, @l;
-}
-
-sub _probe_default {
- my ($format, $frm) = @_;
- my $lib_check=$formats{$frm}{'libcheck'};
- my $inc_check=$formats{$frm}{'inccheck'};
-
- if ($lib_check) {
- my @l;
- for my $lp (@libs) {
- push(@l, grep_directory($lp,$lib_check));
- }
-
- my @i;
- for my $ip (@incs) {
- push(@i, $ip) if $inc_check->($ip,$frm);
+ if (grep $_ eq "FT1", @enabled_bundled) {
+ my %probe =
+ (
+ name => "FT1",
+ inccheck => sub { -e File::Spec->catfile($_[0], "ftnameid.h") },
+ libbase => "ttf",
+ testcode => _ft1_test_code(),
+ testcodeheaders => [ "freetype.h", "stdio.h" ],
+ incpaths => \@incpaths,
+ libpaths => \@libpaths,
+ alternatives =>
+ [
+ {
+ incsuffix => "freetype",
+ }
+ ],
+ verbose => $VERBOSE,
+ );
+ my $probe_res = Imager::Probe->probe(\%probe);
+ $IMAGER_LIBS{FT1} = defined $probe_res;
+ if ($probe_res) {
+ $formats{FT1}{enabled} = 1;
+ @{$formats{FT1}}{qw/DEFINE INC LIBS/} =
+ @$probe_res{qw/DEFINE INC LIBS/};
}
-
- printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
- $formats{$frm}{incdir} = \@i;
- $formats{$frm}{libdir} = \@l;
- return 1 if scalar(@i && @l);
}
- else {
- printf("%10s: not available\n", $frm);
- }
-
- return 0;
}
-sub checkformat {
- my $frm=shift;
-
- print " checkformat($frm)\n" if $VERBOSE;
-
- my $format = $formats{$frm};
-
- my @probes;
- if (my $code = $format->{'code'}) {
- if (ref $code eq 'ARRAY') {
- push @probes, @$code;
- }
- else {
- push @probes, $code;
- }
- }
- push @probes, \&_probe_default;
-
- print " Calling probe function\n" if $VERBOSE;
- my $found;
- for my $func (@probes) {
- if ($func->($format, $frm)) {
- ++$found;
- last;
- }
- }
-
- $found or return;
-
- if ($format->{postcheck}) {
- print " Calling postcheck function\n" if $VERBOSE;
- $format->{postcheck}->($format, $frm)
- or return;
- }
-
- return 1;
-}
-
-
sub pathcheck {
if ($VERBOSE) {
print "pathcheck\n";
}
push @libs, grep -d, qw(/usr/local/lib);
- $formats{'TT-fonts'}=
+ $formats{FT1}=
{
order=>'31',
def=>'HAVE_LIBTT',
- inccheck=>sub { -e catfile($_[0], 'freetype.h')
- && !-e catfile($_[0], 'fterrors.h') },
- libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
- libfiles=>'-lttf',
objfiles=>'fontft1.o',
- code => \&freetype1_probe,
+ LIBS => "-lttf",
docs=>q{
-Truetype fonts are scalable fonts. They can include
-kerning and hinting information and generally yield good
-visual quality esp on low resultions. The freetype library is
-used to rasterize for us. The only drawback is that there
-are alot of badly designed fonts out there.}
+Freetype 1.x supports Truetype fonts and is obsoleted by Freetype 2.x.
+
+It's probably insecure.
+}
};
# Make fix indent
for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
sub gen {
my $V = $ENV{$_[0]};
+ print " $_[0]: '$V'\n"
+ if $VERBOSE && defined $V;
defined($V) ? $V : "";
}
sub getenv {
- ($VERBOSE,
- $INCPATH,
+ $VERBOSE ||= gen("IM_VERBOSE");
+
+ print "Environment config:\n" if $VERBOSE;
+
+ ($INCPATH,
$LIBPATH,
$NOLOG,
$DEBUG_MALLOC,
$MANUAL,
$CFLAGS,
$LFLAGS,
- $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
- IM_INCPATH
+ $DFLAGS) = map { gen $_ } qw(IM_INCPATH
IM_LIBPATH
IM_NOLOG
IM_DEBUG_MALLOC
IM_CFLAGS
IM_LFLAGS
IM_DFLAGS);
-
}
# populate the environment so that sub-modules get the same info
close CONFIG;
}
-# probes for freetype1 by scanning @incs for the includes and
-# @libs for the libs. This is done separately because freetype's headers
-# are stored in a freetype or freetype1 directory under PREFIX/include.
-#
-# we could find the files with the existing mechanism, but it won't set
-# -I flags correctly.
-#
-# This could be extended to freetype2 too, but freetype-config catches
-# that
-sub freetype1_probe {
- my ($frm, $frmkey) = @_;
-
- my $found_inc;
- INCS:
- for my $inc (@incs) {
- for my $subdir (qw/freetype freetype1/) {
- my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
- -e $path or next;
- $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
- -e $path and next;
-
- $found_inc = File::Spec->catdir($inc, $subdir);
- last INCS;
- }
- }
-
- my $found_lib;
- LIBS:
- for my $lib (@libs) {
- my $a_path = File::Spec->catfile($lib, "libttf$aext");
- my $l_path = File::Spec->catfile($lib, "libttf.$lext");
- if (-e $a_path || -e $l_path) {
- $found_lib = $lib;
- last LIBS;
- }
- }
-
- return unless $found_inc && $found_lib;
- printf("%10s: includes %s - libraries %s\n", $frmkey,
- ($found_inc ? 'found' : 'not found'),
- ($found_lib ? 'found' : 'not found'));
-
- $frm->{cflags} = "-I$found_inc";
- $frm->{libfiles} = "-lttf";
-
- return 1;
-}
-
-sub catfile {
- return File::Spec->catfile(@_);
-}
-
sub usage {
print STDERR <<EOS;
Usage: $0 [--enable feature1,feature2,...] [other options]
$path;
}
+sub _ft1_test_code {
+ return <<'CODE';
+TT_Engine engine;
+TT_Error error;
+
+error = TT_Init_FreeType(&engine);
+if (error) {
+ printf("FT1: Could not initialize engine\n");
+ exit(1);
+}
+
+return 0;
+CODE
+}
+
+sub map_bundled {
+ my (@names) = @_;
+
+ @names = map { split /,/ } @names;
+
+ my @outnames;
+ for my $name (@names) {
+ push @outnames, $name;
+ push @outnames, $bundled_names{$name}
+ if $bundled_names{$name};
+ }
+
+ @outnames;
+}
+
1;