@ISA
=
qw(PDF::API2::Basic::TTF::Table)
;
sub
read
{
my
(
$self
) =
@_
;
my
(
$dat
,
$i
,
$j
,
$k
,
$id
,
@ids
,
$s
);
my
(
$start
,
$end
,
$range
,
$delta
,
$form
,
$len
,
$num
,
$ver
);
my
(
$fh
) =
$self
->{
' INFILE'
};
$self
->SUPER::
read
or
return
$self
;
$fh
->
read
(
$dat
, 4);
$self
->{
'Num'
} =
unpack
(
"x2n"
,
$dat
);
$self
->{
'Tables'
} = [];
for
(
$i
= 0;
$i
<
$self
->{
'Num'
};
$i
++)
{
$s
= {};
$fh
->
read
(
$dat
, 8);
(
$s
->{
'Platform'
},
$s
->{
'Encoding'
},
$s
->{
'LOC'
}) = (
unpack
(
"nnN"
,
$dat
));
$s
->{
'LOC'
} +=
$self
->{
' OFFSET'
};
push
(@{
$self
->{
'Tables'
}},
$s
);
}
for
(
$i
= 0;
$i
<
$self
->{
'Num'
};
$i
++)
{
$s
=
$self
->{
'Tables'
}[
$i
];
$fh
->
seek
(
$s
->{
'LOC'
}, 0);
$fh
->
read
(
$dat
, 6);
(
$form
,
$len
,
$ver
) = (
unpack
(
"n3"
,
$dat
));
$s
->{
'Format'
} =
$form
;
$s
->{
'Ver'
} =
$ver
;
if
(
$form
== 0)
{
$s
->{
'val'
} = PDF::API2::Basic::TTF::Segarr->new;
$fh
->
read
(
$dat
, 256);
$s
->{
'val'
}->fastadd_segment(0, 2,
unpack
(
"C*"
,
$dat
));
$s
->{
'Start'
} = 0;
$s
->{
'Num'
} = 256;
}
elsif
(
$form
== 6)
{
my
(
$start
,
$ecount
);
$fh
->
read
(
$dat
, 4);
(
$start
,
$ecount
) =
unpack
(
"n2"
,
$dat
);
$fh
->
read
(
$dat
,
$ecount
<< 1);
$s
->{
'val'
} = PDF::API2::Basic::TTF::Segarr->new;
$s
->{
'val'
}->fastadd_segment(
$start
, 2,
unpack
(
"n*"
,
$dat
));
$s
->{
'Start'
} =
$start
;
$s
->{
'Num'
} =
$ecount
;
}
elsif
(
$form
== 2)
{
}
elsif
(
$form
== 4)
{
$fh
->
read
(
$dat
, 8);
$num
=
unpack
(
"n"
,
$dat
);
$num
>>= 1;
$fh
->
read
(
$dat
,
$len
- 14);
$s
->{
'val'
} = PDF::API2::Basic::TTF::Segarr->new;
for
(
$j
= 0;
$j
<
$num
;
$j
++)
{
$end
=
unpack
(
"n"
,
substr
(
$dat
,
$j
<< 1, 2));
$start
=
unpack
(
"n"
,
substr
(
$dat
, (
$j
<< 1) + (
$num
<< 1) + 2, 2));
$delta
=
unpack
(
"n"
,
substr
(
$dat
, (
$j
<< 1) + (
$num
<< 2) + 2, 2));
$delta
-= 65536
if
$delta
> 32767;
$range
=
unpack
(
"n"
,
substr
(
$dat
, (
$j
<< 1) +
$num
* 6 + 2, 2));
@ids
= ();
for
(
$k
=
$start
;
$k
<=
$end
;
$k
++)
{
if
(
$range
== 0)
{
$id
=
$k
+
$delta
; }
else
{
$id
=
unpack
(
"n"
,
substr
(
$dat
, (
$j
<< 1) +
$num
* 6 +
2 + (
$k
-
$start
) * 2 +
$range
, 2)) +
$delta
; }
$id
-= 65536
if
$id
> 65536;
push
(
@ids
,
$id
);
}
$s
->{
'val'
}->fastadd_segment(
$start
, 0,
@ids
);
}
$s
->{
'val'
}->tidy;
$s
->{
'Num'
} = 0x10000;
$s
->{
'Start'
} =
$s
->{
'val'
}[0]{
'START'
};
}
}
$self
;
}
sub
ms_lookup
{
my
(
$self
,
$uni
) =
@_
;
$self
->find_ms ||
return
undef
unless
(
defined
$self
->{
' mstable'
});
return
$self
->{
' mstable'
}{
'val'
}->at(
$uni
);
}
sub
find_ms
{
my
(
$self
) =
@_
;
my
(
$i
,
$s
,
$alt
);
return
$self
->{
' mstable'
}
if
defined
$self
->{
' mstable'
};
$self
->
read
;
for
(
$i
= 0;
$i
<
$self
->{
'Num'
};
$i
++)
{
$s
=
$self
->{
'Tables'
}[
$i
];
if
(
$s
->{
'Platform'
} == 3)
{
$self
->{
' mstable'
} =
$s
;
last
if
(
$s
->{
'Encoding'
} == 1);
}
elsif
(
$s
->{
'Platform'
} == 0 || (
$s
->{
'Platform'
} == 2 &&
$s
->{
'Encoding'
} == 1))
{
$self
->{
' mstable'
} =
$s
; }
}
$self
->{
' mstable'
};
}
sub
out
{
my
(
$self
,
$fh
) =
@_
;
my
(
$loc
,
$s
,
$i
,
$base_loc
,
$j
);
return
$self
->SUPER::out(
$fh
)
unless
$self
->{
' read'
};
$base_loc
=
$fh
->
tell
();
$fh
->
print
(
pack
(
"n2"
, 0,
$self
->{
'Num'
}));
for
(
$i
= 0;
$i
<
$self
->{
'Num'
};
$i
++)
{
$fh
->
print
(
pack
(
"nnN"
,
$self
->{
'Tables'
}[
$i
]{
'Platform'
},
$self
->{
'Tables'
}[
$i
]{
'Encoding'
}, 0)); }
for
(
$i
= 0;
$i
<
$self
->{
'Num'
};
$i
++)
{
$s
=
$self
->{
'Tables'
}[
$i
];
$s
->{
'val'
}->tidy;
$s
->{
' outloc'
} =
$fh
->
tell
();
$fh
->
print
(
pack
(
"n3"
,
$s
->{
'Format'
}, 0,
$s
->{
'Ver'
}));
if
(
$s
->{
'Format'
} == 0)
{
$fh
->
print
(
pack
(
"C256"
,
$s
->{
'val'
}->at(0, 256)));
}
elsif
(
$s
->{
'Format'
} == 6)
{
$fh
->
print
(
pack
(
"n2"
,
$s
->{
'Start'
},
$s
->{
'Num'
}));
$fh
->
print
(
pack
(
"n*"
,
$s
->{
'val'
}->at(
$s
->{
'Start'
},
$s
->{
'Num'
})));
}
elsif
(
$s
->{
'Format'
} == 2)
{
}
elsif
(
$s
->{
'Format'
} == 4)
{
my
(
$num
,
$sRange
,
$eSel
);
my
(
@deltas
,
$delta
,
@range
,
$flat
,
$k
,
$segs
,
$count
);
$num
= $
$segs
=
$s
->{
'val'
};
for
(
$sRange
= 1,
$eSel
= 0;
$sRange
<=
$num
;
$eSel
++)
{
$sRange
<<= 1;}
$eSel
--;
$fh
->
print
(
pack
(
"n4"
,
$num
* 2,
$sRange
,
$eSel
, (
$num
* 2) -
$sRange
));
$fh
->
print
(
pack
(
"n*"
,
map
{
$_
->{
'START'
} +
$_
->{
'LEN'
} - 1}
@$segs
));
$fh
->
print
(
pack
(
"n"
, 0));
$fh
->
print
(
pack
(
"n*"
,
map
{
$_
->{
'START'
}}
@$segs
));
for
(
$j
= 0;
$j
<
$num
;
$j
++)
{
$delta
=
$segs
->[
$j
]{
'VAL'
}[0];
$flat
= 1;
for
(
$k
= 1;
$k
<
$segs
->[
$j
]{
'LEN'
};
$k
++)
{
if
(
$segs
->[
$j
]{
'VAL'
}[
$k
] == 0)
{
$flat
= 0; }
if
(
$delta
+
$k
!=
$segs
->[
$j
]{
'VAL'
}[
$k
])
{
$delta
= 0;
last
;
}
}
push
(
@range
,
$flat
);
push
(
@deltas
, (
$delta
?
$delta
-
$segs
->[
$j
]{
'START'
} : 0));
}
$fh
->
print
(
pack
(
"n*"
,
@deltas
));
$count
= 0;
for
(
$j
= 0;
$j
<
$num
;
$j
++)
{
$delta
=
$deltas
[
$j
];
if
(
$delta
!= 0 &&
$range
[
$j
] == 1)
{
$range
[
$j
] = 0; }
else
{
$range
[
$j
] = (
$count
+
$num
-
$j
) << 1;
$count
+=
$segs
->[
$j
]{
'LEN'
};
}
}
$fh
->
print
(
pack
(
"n*"
,
@range
));
for
(
$j
= 0;
$j
<
$num
;
$j
++)
{
next
if
(
$range
[
$j
] == 0);
for
(
$k
= 0;
$k
<
$segs
->[
$j
]{
'LEN'
};
$k
++)
{
$fh
->
print
(
pack
(
"n"
,
$segs
->[
$j
]{
'VAL'
}[
$k
])); }
}
}
$loc
=
$fh
->
tell
();
$fh
->
seek
(
$s
->{
' outloc'
} + 2, 0);
$fh
->
print
(
pack
(
"n"
,
$loc
-
$s
->{
' outloc'
}));
$fh
->
seek
(
$base_loc
+ 8 + (
$i
<< 3), 0);
$fh
->
print
(
pack
(
"N"
,
$s
->{
' outloc'
} -
$base_loc
));
$fh
->
seek
(
$loc
, 0);
}
$self
;
}
sub
reverse
{
my
(
$self
,
$tnum
) =
@_
;
my
(
$table
) =
defined
$tnum
?
$self
->{
'Tables'
}[
$tnum
] :
$self
->find_ms;
my
(
@res
,
$i
,
$s
,
$first
);
foreach
$s
(@{
$table
->{
'val'
}})
{
$first
=
$s
->{
'START'
};
map
{
$res
[
$_
] =
$first
unless
$res
[
$_
];
$first
++;} @{
$s
->{
'VAL'
}};
}
@res
;
}
1;