X-Git-Url: https://git.mdrn.pl/librarian.git/blobdiff_plain/e9aeedc51047d8d5e9e45c5253c776f8994da965..3a0c83394d5783715fab2be29fa1a9cfc3574e28:/src/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/Segarr.pm diff --git a/src/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/Segarr.pm b/src/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/Segarr.pm deleted file mode 100644 index 980188d..0000000 --- a/src/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/Segarr.pm +++ /dev/null @@ -1,376 +0,0 @@ -package Font::TTF::Segarr; - -=head1 NAME - -Font::TTF::Segarr - Segmented array - -=head1 DESCRIPTION - -Holds data either directly or indirectly as a series of arrays. This class -looks after the set of arrays and masks the individual sub-arrays, thus saving -a class, we hope. - -=head1 INSTANCE VARIABLES - -All instance variables do not start with a space. - -The segmented array is simply an array of segments - -Each segment is a more complex affair: - -=over 4 - -=item START - -In terms of the array, the address for the 0th element in this segment. - -=item LEN - -Number of elements in this segment - -=item VAL - -The array which contains the elements - -=back - -=head1 METHODS - -=cut - -use strict; -use vars qw(@types $VERSION); -$VERSION = 0.0001; - -@types = ('', 'C', 'n', '', 'N'); - -=head2 Font::TTF::Segarr->new($size) - -Creates a new segmented array with a given data size - -=cut - -sub new -{ - my ($class) = @_; - my ($self) = []; - - bless $self, (ref($class) || $class); -} - - -=head2 $s->fastadd_segment($start, $is_sparse, @dat) - -Creates a new segment and adds it to the array assuming no overlap between -the new segment and any others in the array. $is_sparse indicates whether the -passed in array contains Cs or not. If false no checking is done (which -is faster, but riskier). If equal to 2 then 0 is considered undef as well. - -Returns the number of segments inserted. - -=cut - -sub fastadd_segment -{ - my ($self) = shift; - my ($start) = shift; - my ($sparse) = shift; - my ($p, $i, $seg, @seg); - - - if ($sparse) - { - for ($i = 0; $i <= $#_; $i++) - { - if (!defined $seg && (($sparse != 2 && defined $_[$i]) || $_[$i] != 0)) - { $seg->{'START'} = $start + $i; $seg->{'VAL'} = []; } - - if (defined $seg && (($sparse == 2 && $_[$i] == 0) || !defined $_[$i])) - { - $seg->{'LEN'} = $start + $i - $seg->{'START'}; - push(@seg, $seg); - $seg = undef; - } elsif (defined $seg) - { push (@{$seg->{'VAL'}}, $_[$i]); } - } - if (defined $seg) - { - push(@seg, $seg); - $seg->{'LEN'} = $start + $i - $seg->{'START'}; - } - } else - { - $seg->{'START'} = $start; - $seg->{'LEN'} = $#_ + 1; - $seg->{'VAL'} = [@_]; - @seg = ($seg); - } - - for ($i = 0; $i <= $#$self; $i++) - { - if ($self->[$i]{'START'} > $start) - { - splice(@$self, $i, 0, @seg); - return wantarray ? @seg : scalar(@seg); - } - } - push(@$self, @seg); - return wantarray ? @seg : scalar(@seg); -} - - -=head2 $s->add_segment($start, $overwrite, @dat) - -Creates a new segment and adds it to the array allowing for possible overlaps -between the new segment and the existing ones. In the case of overlaps, elements -from the new segment are deleted unless $overwrite is set in which case the -elements already there are over-written. - -This method also checks the data coming in to see if it is sparse (i.e. contains -undef values). Gaps cause new segments to be created or not to over-write existing -values. - -=cut - -sub add_segment -{ - my ($self) = shift; - my ($start) = shift; - my ($over) = shift; - my ($seg, $i, $s, $offset, $j, $newi); - - return $self->fastadd_segment($start, $over, @_) if ($#$self < 0); - $offset = 0; - for ($i = 0; $i <= $#$self && $offset <= $#_; $i++) - { - $s = $self->[$i]; - if ($s->{'START'} <= $start + $offset) # only < for $offset == 0 - { - if ($s->{'START'} + $s->{'LEN'} > $start + $#_) - { - for ($j = $offset; $j <= $#_; $j++) - { - if ($over) - { $s->{'VAL'}[$start - $s->{'START'} + $j] = $_[$j] if defined $_[$j]; } - else - { $s->{'VAL'}[$start - $s->{'START'} + $j] ||= $_[$j] if defined $_[$j]; } - } - $offset = $#_ + 1; - last; - } elsif ($s->{'START'} + $s->{'LEN'} > $start + $offset) # is $offset needed here? - { - for ($j = $offset; $j < $s->{'START'} + $s->{'LEN'} - $start; $j++) - { - if ($over) - { $s->{'VAL'}[$start - $s->{'START'} + $j] = $_[$j] if defined $_[$j]; } - else - { $s->{'VAL'}[$start - $s->{'START'} + $j] ||= $_[$j] if defined $_[$j]; } - } - $offset = $s->{'START'} + $s->{'LEN'} - $start; - } - } else # new seg please - { - if ($s->{'START'} > $start + $#_ + 1) - { - $i += $self->fastadd_segment($start + $offset, 1, @_[$offset .. $#_]) - 1; - $offset = $#_ + 1; - } - else - { - $i += $self->fastadd_segment($start + $offset, 1, @_[$offset .. $s->{'START'} - $start]) - 1; - $offset = $s->{'START'} - $start + 1; - } - } - } - if ($offset <= $#_) - { - $seg->{'START'} = $start + $offset; - $seg->{'LEN'} = $#_ - $offset + 1; - $seg->{'VAL'} = [@_[$offset .. $#_]]; - push (@$self, $seg); - } - $self->tidy; -} - - -=head2 $s->tidy - -Merges any immediately adjacent segments - -=cut - -sub tidy -{ - my ($self) = @_; - my ($i, $sl, $s); - - for ($i = 1; $i <= $#$self; $i++) - { - $sl = $self->[$i - 1]; - $s = $self->[$i]; - if ($s->{'START'} == $sl->{'START'} + $sl->{'LEN'}) - { - $sl->{'LEN'} += $s->{'LEN'}; - push (@{$sl->{'VAL'}}, @{$s->{'VAL'}}); - splice(@$self, $i, 1); - $i--; - } - } - $self; -} - - -=head2 $s->at($addr, [$len]) - -Looks up the data held at the given address by locating the appropriate segment -etc. If $len > 1 then returns an array of values, spaces being filled with undef. - -=cut - -sub at -{ - my ($self, $addr, $len) = @_; - my ($i, $dat, $s, @res, $offset); - - $len = 1 unless defined $len; - $offset = 0; - for ($i = 0; $i <= $#$self; $i++) - { - $s = $self->[$i]; - next if ($s->{'START'} + $s->{'LEN'} < $addr + $offset); # only fires on $offset == 0 - if ($s->{'START'} > $addr + $offset) - { - push (@res, (undef) x ($s->{'START'} > $addr + $len ? - $len - $offset : $s->{'START'} - $addr - $offset)); - $offset = $s->{'START'} - $addr; - } - last if ($s->{'START'} >= $addr + $len); - - if ($s->{'START'} + $s->{'LEN'} >= $addr + $len) - { - push (@res, @{$s->{'VAL'}}[$addr + $offset - $s->{'START'} .. - $addr + $len - $s->{'START'} - 1]); - $offset = $len; - last; - } else - { - push (@res, @{$s->{'VAL'}}[$addr + $offset - $s->{'START'} .. $s->{'LEN'} - 1]); - $offset = $s->{'START'} + $s->{'LEN'} - $addr; - } - } - push (@res, (undef) x ($len - $offset)) if ($offset < $len); - return wantarray ? @res : $res[0]; -} - - -=head2 $s->remove($addr, [$len]) - -Removes the item or items from addr returning them as an array or the first -value in a scalar context. This is very like C, including padding with -undef, but it deletes stuff as it goes. - -=cut - -sub remove -{ - my ($self, $addr, $len) = @_; - my ($i, $dat, $s, @res, $offset); - - $len = 1 unless defined $len; - $offset = 0; - for ($i = 0; $i <= $#$self; $i++) - { - $s = $self->[$i]; - next if ($s->{'START'} + $s->{'LEN'} < $addr + $offset); - if ($s->{'START'} > $addr + $offset) - { - push (@res, (undef) x ($s->{'START'} > $addr + $len ? - $len - $offset : $s->{'START'} - $addr - $offset)); - $offset = $s->{'START'} - $addr; - } - last if ($s->{'START'} >= $addr + $len); - - unless ($s->{'START'} == $addr + $offset) - { - my ($seg) = {}; - - $seg->{'START'} = $s->{'START'}; - $seg->{'LEN'} = $addr + $offset - $s->{'START'}; - $seg->{'VAL'} = [splice(@{$s->{'VAL'}}, 0, $addr + $offset - $s->{'START'})]; - $s->{'LEN'} -= $addr + $offset - $s->{'START'}; - $s->{'START'} = $addr + $offset; - - splice(@$self, $i, 0, $seg); - $i++; - } - - if ($s->{'START'} + $s->{'LEN'} >= $addr + $len) - { - push (@res, splice(@{$s->{'VAL'}}, 0, $len - $offset)); - $s->{'LEN'} -= $len - $offset; - $s->{'START'} += $len - $offset; - $offset = $len; - last; - } else - { - push (@res, @{$s->{'VAL'}}); - $offset = $s->{'START'} + $s->{'LEN'} - $addr; - splice(@$self, $i, 0); - $i--; - } - } - push (@res, (undef) x ($len - $offset)) if ($offset < $len); - return wantarray ? @res : $res[0]; -} - - -=head2 $s->copy - -Deep copies this array - -=cut - -sub copy -{ - my ($self) = @_; - my ($res, $p); - - $res = []; - foreach $p (@$self) - { push (@$res, $self->copy_seg($p)); } - $res; -} - - -=head2 $s->copy_seg($seg) - -Creates a deep copy of a segment - -=cut - -sub copy_seg -{ - my ($self, $seg) = @_; - my ($p, $res); - - $res = {}; - $res->{'VAL'} = [@{$seg->{'VAL'}}]; - foreach $p (keys %$seg) - { $res->{$p} = $seg->{$p} unless defined $res->{$p}; } - $res; -} - - -1; - -=head1 BUGS - -No known bugs. - -=head1 AUTHOR - -Martin Hosken Martin_Hosken@sil.org. See L for copyright and -licensing. - -=cut -