- Imager::Font::BBox objects now have right_bearing() and display_width()
methods. Hopefully this and the advance_width() method fills out
the Imager bounding box interface to a useful state.
- Implemented for FT2, FT1.x, T1Lib so far.
+ Implemented for all four font drivers.
+- Win32 font bounding_box() method now supports the advance width
+ and right bearing values.
=================================================================
OUTPUT:
RETVAL
+undef_int
+i_wf_addfont(font)
+ char *font
#endif
int size, char *text, int len, int align, int aa);
extern int i_wf_cp(char *face, i_img *im, int tx, int ty, int channel,
int size, char *text, int len, int align, int aa);
+extern int i_wf_addfont(char const *file);
#endif
#!perl -w
use strict;
use lib 't';
-use Test::More tests => 7;
+use Test::More tests => 18;
BEGIN { use_ok(Imager => ':all') }
+++$|;
init_log("testout/t37w32font.log",1);
SKIP:
{
- i_has_format('w32') or skip("no MS Windows", 6);
+ i_has_format('w32') or skip("no MS Windows", 17);
print "# has w32\n";
my $fontname=$ENV{'TTFONTTEST'} || 'Times New Roman Bold';
or print "# ",$img->errstr,"\n";
$img->write(file=>'testout/t37_oo.ppm') or print "not ";
my @bbox2 = $font->bounding_box(string=>'Imager');
- is(@bbox2, 6, "got 6 values from bounding_box");
+ is(@bbox2, 8, "got 8 values from bounding_box");
# this only applies while the Win32 driver returns 6 values
# at this point we don't return the advance width from the low level
ok($bbox, "got the bounding box object");
is($bbox->advance_width, $bbox->end_offset,
"check advance_width fallback correct");
+
+ ok(Imager::i_wf_addfont("fontfiles/ExistenceTest.ttf"), "add test font");
+
+ my $namefont = Imager::Font->new(face=>"ExistenceTest");
+ ok($namefont, "create font based on added font");
+
+ # the test font is known to have a shorter advance width for that char
+ @bbox = $namefont->bounding_box(string=>"/", size=>100);
+ print "# / box: @bbox\n";
+ is(@bbox, 8, "should be 8 entries");
+ isnt($bbox[6], $bbox[2], "different advance width");
+ $bbox = $namefont->bounding_box(string=>"/", size=>100);
+ 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)");
+
+ my $im = Imager->new(xsize=>200, ysize=>200);
+ $im->string(font=>$namefont, text=>"/", x=>20, y=>100, color=>'white', size=>100);
+ $im->line(color=>'blue', x1=>20, y1=>0, x2=>20, y2=>199);
+ my $right = 20 + $bbox->advance_width;
+ $im->line(color=>'blue', x1=>$right, y1=>0, x2=>$right, y2=>199);
+ $im->write(file=>'testout/t37w32_slash.ppm');
+
+ # check with a char that fits inside the box
+ $bbox = $namefont->bounding_box(string=>"!", size=>100);
+ print "# pos width ", $bbox->pos_width, "\n";
+ print "# ! box: @$bbox\n";
+ is($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");
+
+
}
+#define _WIN32_WINNT 0x500
#include "image.h"
#define STRICT
#include <windows.h>
int i;
MAT2 mat;
+ mm_log((1, "i_wf_bbox(face %s, size %d, text %p, length %d, bbox %p)\n", face, size, text, length, bbox));
+
set_logfont(face, size, &lf);
font = CreateFontIndirect(&lf);
if (!font)
dc = GetDC(NULL);
oldFont = (HFONT)SelectObject(dc, font);
+ {
+ char facename[100];
+ if (GetTextFace(dc, sizeof(facename), facename)) {
+ mm_log((1, " face: %s\n", facename));
+ }
+ }
+
if (!GetTextExtentPoint32(dc, text, length, &sz)
|| !GetTextMetrics(dc, &tm)) {
SelectObject(dc, oldFont);
see it. GetGlyphOutline() seems to return the same size for
all characters.
*/
- bbox[1] = bbox[4] = tm.tmDescent;
- bbox[2] = sz.cx;
- bbox[3] = bbox[5] = tm.tmAscent;
+ bbox[BBOX_GLOBAL_DESCENT] = bbox[BBOX_DESCENT] = tm.tmDescent;
+ bbox[BBOX_POS_WIDTH] = sz.cx;
+ bbox[BBOX_ADVANCE_WIDTH] = sz.cx;
+ bbox[BBOX_GLOBAL_ASCENT] = bbox[BBOX_ASCENT] = tm.tmAscent;
- if (GetCharABCWidths(dc, text[0], text[0], &first)
+ if (length
+ && GetCharABCWidths(dc, text[0], text[0], &first)
&& GetCharABCWidths(dc, text[length-1], text[length-1], &last)) {
- bbox[0] = first.abcA;
+ mm_log((1, "first: %d A: %d B: %d C: %d\n", text[0],
+ first.abcA, first.abcB, first.abcC));
+ mm_log((1, "first: %d A: %d B: %d C: %d\n", text[length-1],
+ last.abcA, last.abcB, last.abcC));
+ bbox[BBOX_NEG_WIDTH] = first.abcA;
+ bbox[BBOX_RIGHT_BEARING] = last.abcC;
if (last.abcC < 0)
- bbox[2] -= last.abcC;
+ bbox[BBOX_POS_WIDTH] -= last.abcC;
}
else {
- bbox[0] = 0;
+ bbox[BBOX_NEG_WIDTH] = 0;
+ bbox[BBOX_RIGHT_BEARING] = 0;
}
SelectObject(dc, oldFont);
ReleaseDC(NULL, dc);
DeleteObject(font);
- return 6;
+ mm_log((1, " bbox=> negw=%d glob_desc=%d pos_wid=%d glob_asc=%d desc=%d asc=%d adv_width=%d rightb=%d\n", bbox[0], bbox[1], bbox[2], bbox[3], bbox[4], bbox[5], bbox[6], bbox[7]));
+
+ return BBOX_RIGHT_BEARING + 1;
}
/*
return 1;
}
+/*
+=item i_wf_addfont(char const *filename, char const *resource_file)
+
+Adds a TTF font file as usable by the application.
+
+The font is always added as private to the application.
+
+=cut
+ */
+int
+i_wf_addfont(char const *filename) {
+ i_clear_error();
+
+ if (AddFontResourceEx(filename, FR_PRIVATE, 0)) {
+ return 1;
+ }
+ else {
+ i_push_errorf(0, "Could not add resource: %ld", GetLastError());
+ return 0;
+ }
+}
+
/*
=back