Skip to content
Browse files

[rt #73359] draw non-AA text using FT2 in normal mode

  • Loading branch information...
1 parent e1317da commit b9459ada03d420d01b90b4c814b9d6efddabb0c8 @tonycoz committed Jun 10, 2013
Showing with 100 additions and 15 deletions.
  1. +6 −0 FT2/Changes
  2. +1 −1 FT2/FT2.pm
  3. +28 −12 FT2/freetyp2.c
  4. +65 −2 FT2/t/t10ft2.t
View
6 FT2/Changes
@@ -1,3 +1,9 @@
+Imager-Font-FT2 0.92
+====================
+
+ - drawing non-AA text is now done in alpha-combining mode
+ https://rt.cpan.org/Ticket/Display.html?id=73359
+
Imager-Font-FT2 0.91
====================
View
2 FT2/FT2.pm
@@ -6,7 +6,7 @@ use vars qw($VERSION @ISA);
@ISA = qw(Imager::Font);
BEGIN {
- $VERSION = "0.91";
+ $VERSION = "0.92";
require XSLoader;
XSLoader::load('Imager::Font::FT2', $VERSION);
View
40 FT2/freetyp2.c
@@ -739,15 +739,18 @@ i_ft2_text(FT2_Fonthandle *handle, i_img *im, i_img_dim tx, i_img_dim ty, const
i_img_dim bbox[BOUNDING_BOX_COUNT];
FT_GlyphSlot slot;
int x, y;
- unsigned char *bmp;
unsigned char map[256];
char last_mode = ft_pixel_mode_none;
int last_grays = -1;
int loadFlags = FT_LOAD_DEFAULT;
i_render *render = NULL;
+ unsigned char *work_bmp = NULL;
+ size_t work_bmp_size = 0;
- mm_log((1, "i_ft2_text(handle %p, im %p, (tx,ty) (" i_DFp "), cl %p, cheight %f, cwidth %f, text %p, len %u, align %d, aa %d, vlayout %d, utf8 %d)\n",
- handle, im, i_DFcp(tx, ty), cl, cheight, cwidth, text, (unsigned)len, align, aa, vlayout, utf8));
+ mm_log((1, "i_ft2_text(handle %p, im %p, (tx,ty) (" i_DFp "), cl %p (#%02x%02x%02x%02x), cheight %f, cwidth %f, text %p, len %u, align %d, aa %d, vlayout %d, utf8 %d)\n",
+ handle, im, i_DFcp(tx, ty), cl, cl->rgba.r, cl->rgba.g, cl->rgba.b,
+ cl->rgba.a, cheight, cwidth, text, (unsigned)len, align, aa,
+ vlayout, utf8));
i_clear_error();
@@ -765,8 +768,10 @@ i_ft2_text(FT2_Fonthandle *handle, i_img *im, i_img_dim tx, i_img_dim ty, const
if (!i_ft2_bbox(handle, cheight, cwidth, text, len, bbox, utf8))
return 0;
- if (aa)
- render = i_render_new(im, bbox[BBOX_POS_WIDTH] - bbox[BBOX_NEG_WIDTH]);
+ render = i_render_new(im, bbox[BBOX_POS_WIDTH] - bbox[BBOX_NEG_WIDTH]);
+
+ work_bmp_size = bbox[BBOX_POS_WIDTH] - bbox[BBOX_NEG_WIDTH];
+ work_bmp = mymalloc(work_bmp_size);
if (!align) {
/* this may need adjustment */
@@ -805,29 +810,38 @@ i_ft2_text(FT2_Fonthandle *handle, i_img *im, i_img_dim tx, i_img_dim ty, const
if (error) {
ft2_push_message(error);
i_push_errorf(0, "rendering glyph 0x%04lX (character \\x%02X)", c, index);
- if (render)
- i_render_delete(render);
+ if (render)
+ i_render_delete(render);
return 0;
}
if (slot->bitmap.pixel_mode == ft_pixel_mode_mono) {
- bmp = slot->bitmap.buffer;
+ unsigned char *bmp = slot->bitmap.buffer;
+ if (work_bmp_size < slot->bitmap.width) {
+ work_bmp_size = slot->bitmap.width;
+ work_bmp = myrealloc(work_bmp, work_bmp_size);
+ }
for (y = 0; y < slot->bitmap.rows; ++y) {
int pos = 0;
int bit = 0x80;
+ unsigned char *p = work_bmp;
for (x = 0; x < slot->bitmap.width; ++x) {
- if (bmp[pos] & bit)
- i_ppix(im, tx+x+slot->bitmap_left, ty+y-slot->bitmap_top, cl);
-
+ *p++ = (bmp[pos] & bit) ? 0xff : 0;
+
bit >>= 1;
if (bit == 0) {
bit = 0x80;
++pos;
}
}
+ i_render_color(render, tx + slot->bitmap_left, ty-slot->bitmap_top+y,
+ slot->bitmap.width, work_bmp, cl);
+
bmp += slot->bitmap.pitch;
}
}
else {
+ unsigned char *bmp = slot->bitmap.buffer;
+
/* grey scale or something we can treat as greyscale */
/* we create a map to convert from the bitmap values to 0-255 */
if (last_mode != slot->bitmap.pixel_mode
@@ -838,7 +852,6 @@ i_ft2_text(FT2_Fonthandle *handle, i_img *im, i_img_dim tx, i_img_dim ty, const
last_grays = slot->bitmap.num_grays;
}
- bmp = slot->bitmap.buffer;
for (y = 0; y < slot->bitmap.rows; ++y) {
if (last_mode == ft_pixel_mode_grays &&
last_grays != 255) {
@@ -859,6 +872,9 @@ i_ft2_text(FT2_Fonthandle *handle, i_img *im, i_img_dim tx, i_img_dim ty, const
if (render)
i_render_delete(render);
+ if (work_bmp)
+ myfree(work_bmp);
+
return 1;
}
View
67 FT2/t/t10ft2.t
@@ -1,6 +1,6 @@
#!perl -w
use strict;
-use Test::More tests => 193;
+use Test::More tests => 204;
use Cwd qw(getcwd abs_path);
use Imager qw(:all);
@@ -9,7 +9,11 @@ use Imager::Test qw(diff_text_with_nul is_color3 is_color4 isnt_image is_image);
-d "testout" or mkdir "testout";
-init_log("testout/t38ft2font.log",2);
+my @test_output;
+
+push @test_output, "t38ft2font.log";
+
+Imager->open_log(log => "testout/t38ft2font.log");
my $deffont = "fontfiles/dodge.ttf";
@@ -42,6 +46,7 @@ SKIP:
ok(Imager::Font::FT2::i_ft2_cp($ttraw,$overlay,5,50,1,50.0,50, 'XMCLH',1,1, 0, 0), "drawn to channel");
i_line($overlay,0,50,100,50,$bgcolor,1);
+ push @test_output, "t38ft2font.ppm";
open(FH,">testout/t38ft2font.ppm") || die "cannot open testout/t38ft2font.ppm\n";
binmode(FH);
my $IO = Imager::io_new_fd(fileno(FH));
@@ -57,6 +62,7 @@ SKIP:
ok(Imager::Font::FT2::i_ft2_text($ttraw,$backgr,100,150,NC(0, 128, 0),200.0,50, 'MAW',0,1, 0, 0), "drew rotated MAW");
i_line($backgr, 0,150, 499, 150, NC(0, 0, 255),1);
+ push @test_output, "t38ft2font2.ppm";
open(FH,">testout/t38ft2font2.ppm") || die "cannot open testout/t38ft2font.ppm\n";
binmode(FH);
$IO = Imager::io_new_fd(fileno(FH));
@@ -174,6 +180,7 @@ SKIP:
align=>0, );
}
+ push @test_output, "t38_oo.ppm";
$im->write(file=>'testout/t38_oo.ppm')
or print "# could not save OO output: ",$im->errstr,"\n";
@@ -216,6 +223,7 @@ SKIP:
align_test('center', 'bottom', 150, 220, $oof, $alimg);
align_test('center', 'baseline', 150, 250, $oof, $alimg);
+ push @test_output, "t38aligned.ppm";
ok($alimg->write(file=>'testout/t38aligned.ppm'),
"saving aligned output image");
@@ -374,6 +382,7 @@ SKIP:
}
}
+ push @test_output, "t38mm.ppm";
ok($mmim->write(file=>"testout/t38mm.ppm"), "save MM output");
SKIP:
@@ -399,6 +408,7 @@ SKIP:
ok($im->string(%common, @$args, 'y'=>90, align=>1), "A align=1");
ok($im->string(%common, @$args, 'y'=>110, align=>0), "A align=0");
}
+ push @test_output, "t38align.ppm";
ok($im->write(file=>'testout/t38align.ppm'), "save align image");
}
@@ -536,6 +546,59 @@ SKIP:
isnt_image($work, $cmp, "make sure something was drawn");
}
}
+
+ { # RT 73359
+ # non-AA font drawing isn't normal mode
+
+ Imager->log("testing no-aa normal output\n");
+
+ my $font = Imager::Font->new(file => "fontfiles/ImUgly.ttf", type => "ft2");
+
+ ok($font, "make a work font");
+
+ my %common =
+ (
+ x => 10,
+ font => $font,
+ size => 25,
+ aa => 0,
+ align => 0,
+ );
+
+ # build our comparison image
+ my $cmp = Imager->new(xsize => 120, ysize => 100);
+ my $layer = Imager->new(xsize => 120, ysize => 100, channels => 4);
+ ok($layer->string(%common, y => 10, text => "full", color => "#8080FF"),
+ "draw non-aa text at full coverage to layer image");
+ ok($layer->string(%common, y => 40, text => "half", color => "#FF808080"),
+ "draw non-aa text at half coverage to layer image");
+ ok($layer->string(%common, y => 70, text => "quarter", color => "#80FF8040"),
+ "draw non-aa text at zero coverage to layer image");
+ ok($cmp->rubthrough(src => $layer), "rub layer onto comparison image");
+
+ my $im = Imager->new(xsize => 120, ysize => 100);
+ ok($im->string(%common, y => 10, text => "full", color => "#8080FF"),
+ "draw non-aa text at full coverage");
+ ok($im->string(%common, y => 40, text => "half", color => "#FF808080"),
+ "draw non-aa text at half coverage");
+ ok($im->string(%common, y => 70, text => "quarter", color => "#80FF8040"),
+ "draw non-aa text at zero coverage");
+ is_image($im, $cmp, "check the result");
+
+ push @test_output, "noaanorm.ppm", "noaacmp.ppm";
+ ok($cmp->write(file => "testout/noaacmp.ppm"), "save cmp image")
+ or diag "Saving cmp image: ", $cmp->errstr;
+ ok($im->write(file => "testout/noaanorm.ppm"), "save test image")
+ or diag "Saving result image: ", $im->errstr;
+ }
+}
+
+Imager->close_log();
+
+END {
+ unless ($ENV{IMAGER_KEEP_FILES}) {
+ unlink map "testout/$_", @test_output;
+ }
}
sub align_test {

0 comments on commit b9459ad

Please sign in to comment.
Something went wrong with that request. Please try again.