File Coverage

blib/lib/SWF/Builder/Character/Font.pm
Criterion Covered Total %
statement 78 99 78.7
branch 13 30 43.3
condition 2 6 33.3
subroutine 14 19 73.6
pod n/a
total 107 154 69.4


line stmt bran cond sub pod time code
1             package SWF::Builder::Character::Font;
2              
3 1     1   6 use strict;
  1         2  
  1         40  
4 1     1   5 use utf8;
  1         2  
  1         7  
5              
6             our $VERSION="0.091";
7              
8             our %indirect;
9              
10             @indirect{ ('_sans', '_serif', '_typewriter', "_\x{30b4}\x{30b7}\x{30c3}\x{30af}", "_\x{660e}\x{671d}", "_\x{7b49}\x{5e45}") }
11             = ('_sans', '_serif', '_typewriter', "_\x{30b4}\x{30b7}\x{30c3}\x{30af}", "_\x{660e}\x{671d}", "_\x{7b49}\x{5e45}");
12              
13             @SWF::Builder::Character::Font::ISA = qw/ SWF::Builder::Character /;
14              
15             ####
16              
17             package SWF::Builder::Character::Font::Imported;
18              
19             @SWF::Builder::Character::Font::Imported::ISA = qw/ SWF::Builder::Character::Imported SWF::Builder::Character::Font /;
20              
21 0     0   0 sub embed {1} # ??
22 0     0   0 sub add_glyph{}
23              
24             ####
25              
26             package SWF::Builder::Character::Font::Def;
27              
28 1     1   178 use Carp;
  1         1  
  1         64  
29 1     1   6 use SWF::Element;
  1         1  
  1         21  
30 1     1   5 use SWF::Builder;
  1         1  
  1         14  
31 1     1   6 use SWF::Builder::ExElement;
  1         2  
  1         1455  
32              
33             @SWF::Builder::Character::Font::Def::ISA = qw/ SWF::Builder::Character::Font /;
34              
35             sub new {
36 1     1   3 my ($class, $fontfile, $fontname) = @_;
37 1         2 my $tag;
38 1         27 my $self = bless {
39             _embed => 1,
40             _average_width => 512,
41             _read_only => 0,
42             _code_hash => {},
43             _glyph_hash => {},
44             _tag => ($tag = SWF::Element::Tag::DefineFont2->new),
45             }, $class;
46              
47 1         59 $self->_init_character;
48 1         5 $tag->FontID($self->{ID});
49              
50 1 50       16 if (exists $indirect{$fontfile}) {
51 0         0 utf2bin($fontfile);
52 0         0 $tag->FontName($fontfile);
53 0         0 $self->embed(0);
54 0         0 return $self;
55             }
56              
57 1         1 eval {$self->_init_font($fontfile, $fontname)};
  1         11  
58 1 50       4 if ($@) {
59 1 50       7 if ($@ =~ /Can\'t locate object method/) {
60 1         774 eval { require SWF::Builder::Character::Font::FreeType }
61 1 50 33     2 or eval { require SWF::Builder::Character::Font::TTF }
  1         819  
62             or croak "Failed loading font module. It is necessary to install Font-FreeType or Font-TTF to use outline fonts";
63 1         13 $self->_init_font($fontfile, $fontname);
64             } else {
65 0         0 die;
66             }
67             }
68 1         17 $self;
69             }
70              
71             sub embed {
72 1     1   3 my ($self, $embed) = @_;
73              
74 1 50       3 if (defined $embed) {
75 0         0 $self->{_embed} = $embed;
76             }
77 1         6 return $self->{_embed};
78             }
79              
80             sub is_readonly {
81 0     0   0 shift->{_read_only};
82             }
83              
84             sub get_average_width {
85 0     0   0 shift->{_average_width};
86             }
87              
88             sub glyph_shape {
89 4     4   9 my ($self, $char) = @_;
90              
91 4 50 33     20 if (exists $self->{_glyph_hash}{$char} and defined $self->{_glyph_hash}{$char}[1]) {
92 0         0 return $self->{_glyph_hash}{$char}[1];
93             } else {
94 4         22 my $gshape = SWF::Builder::Character::Font::Glyph->new;
95 4         15 $self->{_glyph_hash}{$char}[1] = $gshape;
96 4         9 return $gshape;
97             }
98             }
99              
100             sub add_glyph {
101 1     1   2 my ($self, $string, $e_char) = @_;
102 1         10 my @chars;
103              
104 1 50       4 return unless $self->{_embed};
105              
106 1         2 my $hash = $self->{_glyph_hash};
107              
108 1 50       4 if (defined $e_char) {
109 0         0 @chars = map {chr} (ord($string) .. ord($e_char));
  0         0  
110             } else {
111 1         5 @chars = split //, $string;
112             }
113              
114 1         3 for my $c (@chars) {
115 4 50       25 next if $hash->{$c};
116              
117 4         23 my $gshape = $self->glyph_shape($c);
118 4         28 my $adv = $self->_draw_glyph($c, $gshape);
119 4         29 $hash->{$c} = [$adv, $gshape];
120             }
121             }
122              
123             sub LanguageCode {
124 0     0   0 my ($self, $code) = @_;
125              
126 0 0       0 unless (defined $code) {
    0          
127 0         0 my $l = $self->{_tag}->LanguageCode->value;
128 0         0 return ('none', 'Latin', 'Japanese', 'Korean', 'Simplified Chinese', 'Traditional Chinese')[$l];
129             } elsif ($code!~/\d+/) {
130 0         0 ($code) = 'none:0 Latin:1 Japanese:2 Korean:3 Simplified Chinese:4 Traditional Chinese:5'=~/\b$code.*?:(\d)/i;
131             }
132 0         0 $self->{_tag}->LanguageCode($code);
133             }
134              
135             sub AUTOLOAD {
136 1     1   3 my $self = shift;
137 1         2 our $AUTOLOAD;
138 1         13 my ($sub) = $AUTOLOAD=~/::([^:]+)$/;
139 1 50       5 return if $sub eq 'DESTROY';
140 1         2 my $tag = $self->{_tag};
141              
142 1 50       26 if ($tag->can($sub)) {
    50          
143 0         0 $tag->$sub(@_);
144             } elsif ($tag->can(my $fsub="FontFlags$sub")) {
145 0         0 $tag->$fsub(@_);
146             } else {
147 1         275 croak "Can\'t locate object method \"$sub\" via package \"".ref($self).'"';
148             }
149             }
150              
151             my $emprect = SWF::Element::RECT->new(Xmin => 0, Ymin => 0, Xmax => 0, Ymax => 0);
152              
153             sub _pack {
154 1     1   3 my ($self, $stream) = @_;
155              
156 1         3 my $tag = $self->{_tag};
157 1         3 my $hash = $self->{_glyph_hash};
158 1         5 my ($code_t, $adv_t, $glyph_t, $bounds_t, $kern_t) =
159             ($tag->CodeTable, $tag->FontAdvanceTable, $tag->GlyphShapeTable, $tag->FontBoundsTable, $tag->FontKerningTable);
160              
161 1         156 for my $c (sort keys %{$self->{_glyph_hash}}) {
  1         11  
162 4         11 push @$code_t, ord($c);
163 4 50       26 push @$adv_t, (defined($hash->{$c}[0]) ? $hash->{$c}[0]*20 : $hash->{$c}[1]{_bounds}->Xmax);
164 4         31 push @$glyph_t, SWF::Element::SHAPE->new(ShapeRecords => $hash->{$c}[1]{_edges});
165 4         122 push @$bounds_t, $emprect;
166             }
167 1         4 @{$self->{_code_hash}}{@$code_t} = (0..$#$code_t);
  1         7  
168 1         13 $self->{_tag}->pack($stream);
169             }
170              
171             ####
172              
173             package SWF::Builder::Character::Font::Glyph;
174              
175 1     1   779 use SWF::Builder::Shape;
  1         3  
  1         130  
176              
177             @SWF::Builder::Character::Font::Glyph::ISA = ('SWF::Builder::Shape');
178              
179             sub new {
180 4     4   8 my $class = shift;
181              
182 4         25 my $self = $class->SUPER::new;
183 4         30 $self->fillstyle(1)->linestyle(0);
184             }
185              
186              
187             1;
188             __END__