NAME
Imager::DTP::Textbox - multi-byte text handling module with text wrapping and line alignment, for use with Imager.
SYNOPSIS
use Imager::DTP::Textbox::Horizontal; # or Vertical
# first, define font & text string
my $font = Imager::Font->new(file=>'path/to/foo.ttf',type=>'ft2',
size=>14);
my $text = 'This year\'s Thrash Domination Tour here in ';
$text .= 'Japan was great.';
$text .= "\n\n";
$text .= 'With Testament, Kreator, Destruction, and ';
$text .= 'Laaz Rockit all gathered at one place.';
# with multi-byte characters, encode it to UTF8, with internal
# utf-8 flag enabled (using utf8::decode()).
# create instance - basic way
my $tb = Imager::DTP::Textbox::Horizontal->new();
$tb->setText(text=>$text,font=>$font); # set text with font
$tb->setWspace(pixel=>5); # set space between letters
$tb->setLeading(percent=>180); # set space between lines
$tb->setAlign(halign=>'left',valign=>'top'); # set text alignment
$tb->setWrap(width=>200,height=>150); # set text wrapping
# create instance - or the shorcut way
my $tb = Imager::DTP::Textbox::Horizontal->new(text=>$text,
font=>$font, wspace=>5, leading=>180, halign=>'left',
valign=>'top', wrapWidth=>200, wrapHeight=>180);
# and draw the text string on target image
my $target = Imager->new(xsize=>250,ysize=>250);
$tb->draw(target=>$target,x=>10,y=>10);
DESCRIPTION
Imager::DTP::Textbox is a module intended for handling sentences and paragraphs consisted with multi-byte characters, such as Japanese and Chinese. It supports text wrapping and line alignment, and is able to draw text string vertically from top to bottom as well. All the text string provided (by setText() method) will be splitted by "\n", and each chunk will be turned into Imager::DTP::Line instance internally. So in another words, Imager::DTP::Textbox can be described as "a big box to put lines and letters in order". It's like WWW Browser's textarea input, or Adobe Illustrator's textbox tool.
CLASS RELATION
Imager::DTP::Textbox is an ABSTRACT CLASS. The extended class would be Imager::DTP::Textbox::Horizontal and Imager::DTP::Textbox::Vertical. (Yes, I know the package name is much longer than it should be... I took the advantage of comprehension). So you must "use" the extended class (either of Horizonal or Vertical), and not the Imager::DTP::Textbox itself. The difference between Horizontal and Vertical is as follows:
- Imager::DTP::Textbox::Horizontal
-
letters are drawn from left to right, line stacks from top to bottom.
- Imager::DTP::Textbox::Vertical
-
letters are drawn from top to bottom, line stacks from right to left.
METHODS
BASIC METHODS
new
Can be called with or without options.
use Imager::DTP::Textbox::Horizontal;
my $tb = Imager::DTP::Textbox::Horizontal->new();
# or set all/any options at the same time
my $font = Imager::Font->new(file=>'path/to/foo.ttf',type=>'ft2',
size=>14);
my $text = "Hello me... meet the real me.\n";
$text .= "And my misfits way of life.";
my $tb = Imager::DTP::Textbox::Horizontal->new(text=>$text,
font=>$font, wspace=>5, leading=>150, halign=>'left',
valign=>'top', wrapWidth=>200, wrapHeight=>180);
setText
Set text string to the instance. Text must not be undef or '', and font option is not optional either. For multi-byte letters/characters, text must be encoded to utf8, with it's internal utf8-flag ENABLED (This could be done by using utf8::decode() method).
my $font = Imager::Font->new(file=>'path/to/foo.ttf',type=>'ft2',
size=>14);
my $text = 'Smashing through the boundaries,';
$text .= 'Lunacy has found me...';
$tb->setText(text=>$text,font=>$font);
By default, each time the method is called, it replaces the previous text with the provided new text. But by putting the "add" option, it will add new text to the end of the current text.
my $moreText = 'Cannot stop the battery!';
$tb->setText(text=>$moreText,add=>1);
Font is optional this time. If there is any previous text set, the new text will automatically inherit the font preference of last line, last letter's font preference.
The following characters will be translated to corresponding string internally:
"\n" will be used as a delimiter for splitting text string to each line object, and "\t" will stay the same until the time of draw() method call (see description of Imager::DTP::Line->draw() method for what will happen then).
setWspace
Set size for blank spaces inserted in between each letters. See Imager::DTP::Line->setWspace() for more description.
# setting a 5 pixel word space
$tb->setWspace(pixel=>5);
setLeading
The word "leading" in DTP application means "space between two consecutive lines". Thus, by setting some value (in percentage) here will affect the distance between each line. The default value is 150%, so setting any value greater than this will widen the distance, and setting smaller value (like 50%) will make the lines come closer (and with 50%, it will probably end up with two lines overlapping a little).
# set leading to 180%
$tb->setLeading(percent=>180);
The percentage is based on the ascent value of a letter, which has the maximum value out of all the letters held inside.
setAlign
Set horizontal and vertical alignment of lines, as if viewed from draw() method's x and y point.
$tb->setAlign(halign=>'right',valign=>'bottom');
Available options are:
- halign (horizontal alignment)
-
left / center / right
- valign (vertical alignment)
-
top / center / bottom
The default alignment for each extended class is as follows:
- Imager::DTP::Textbox::Horizontal
-
halign => 'left' valign => 'top'
- Imager::DTP::Textbox::Vertical
-
halign => 'right' valign => 'top'
setWrap
Set the maximum width and height of the bounding box, for the lines and letters to be wrapped inside. By setting these values to 0 will disable text wrapping (which is the default setting). Width will always be the horizontal measure, and height will be the vertical measure, no matter which extended class you choose (Imager::DTP::Textbox::Horizontal or Vertical).
# set x axis bounding to 200 pixels
$tb->setWrap(width=>200);
# set both x/y axis bounding to 100 pixels
$tb->setWrap(width=>100,height=>100);
Wrapping logic is letter-based, meaning text may be wrapped right in the middle of a "word", which is a normal wrapping rule for multi-byte texts (at least for Japanese, yes) in DTP applications. But with single-byte character word, this logic will make the sentence look ugly, so I've added some logic for single-byte character words to "always wrap at the beginning of the word". With it, alphabetical sentences and paragraphs will look OK, although hyphenation is not implemented (yet).
draw
Draw all the lines and letters held with-in, to the target image (Imager object).
my $target = Imager->new(xsize=>250,ysize=>250);
$tb->draw(target=>$target,x=>10,y=>10);
Each letter is drawn with Imager::DTP::Letter->draw() method, which internally is using Imager->String() method, so you can pass any extra Imager::String options to it by setting in 'others' option (See more details in Imager::DTP::Letter->draw() method description).
# passing Imager::String options
$tb->draw(target=>$target,x=>10,y=>10,others=>{aa=>1});
There is an extra debug option, which will draw a 'width x height' dark gray box underneath the textbox, a light grax box underneath each line, and a black bounding box for each letters. Handy for checking each object's bounding size/position.
# debug mode
$tb->draw(target=>$target,x=>10,y=>10,debug=>1);
Obtaining text drawn image
By NOT passing any target option, the method will return an Imager object, with all the lines and letters drawn to it. This is usefull when you want to perform some transformation (such as X/Y scaling, cropping, color filtering) to these text string.
# obtaining text drawn image
# x/y position will be forced at (0,0)
my $newimg = $tb->draw();
# apply some Imager's transformation method
my $scaled = $newimg->scaleX(pixels=>100);
GETTER METHODS
Calling these methods will return a property value corresponding to the method name.
getLines
Returns a reference (pointer) to an array containing all the Imager::DTP::Line object held internally.
getLeading
Returns the current value of leading.
getWidth
Return the actuall width of textbox. Actuall here means "not the wrapping width", but the precise width of the lines and letters held inside.
getHeight
Return the actuall height of textbox. Actuall here means "not the wrapping height", but the precise height of the lines and letters held inside.
getHalign
Returns the current value of horizontal alignment.
getValign
Returns the current value of vertical alignment.
getWrapWidth
Returns the current value of horizontal text wrap bounding.
getWrapHeight
Returns the current value of vertical text wrap bounding.
TODO
hyphenation with single-byte characters.
change Carp-only error handling to something more elegant.
AUTHOR
Toshimasa Ishibashi, <iandeth99@ybb.ne.jp>
COPYRIGHT & LICENSE
Copyright 2005 Toshimasa Ishibashi, all rights reserved.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.