Skip to content

Commit

Permalink
[rt #73359] draw non-AA text using FT2 in normal mode
Browse files Browse the repository at this point in the history
  • Loading branch information
tonycoz committed Jun 10, 2013
1 parent e1317da commit b9459ad
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 15 deletions.
6 changes: 6 additions & 0 deletions 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
====================

Expand Down
2 changes: 1 addition & 1 deletion FT2/FT2.pm
Expand Up @@ -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);
Expand Down
40 changes: 28 additions & 12 deletions FT2/freetyp2.c
Expand Up @@ -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();

Expand All @@ -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 */
Expand Down Expand Up @@ -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
Expand All @@ -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) {
Expand All @@ -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;
}

Expand Down
67 changes: 65 additions & 2 deletions 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);
Expand 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";

Expand Down Expand Up @@ -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));
Expand All @@ -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));
Expand Down Expand Up @@ -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";

Expand Down Expand Up @@ -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");

Expand Down Expand Up @@ -374,6 +382,7 @@ SKIP:
}
}

push @test_output, "t38mm.ppm";
ok($mmim->write(file=>"testout/t38mm.ppm"), "save MM output");

SKIP:
Expand All @@ -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");
}

Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit b9459ad

Please sign in to comment.