91 lines
2.8 KiB
Erlang
91 lines
2.8 KiB
Erlang
|
-module(font_directory).
|
||
|
-export([parse_font_directory/1]).
|
||
|
|
||
|
-include("sizes.hrl").
|
||
|
|
||
|
-define(OFFSET_TABLE_SIZE, (?U32+4*?U16)).
|
||
|
parse_offset_table(
|
||
|
<<SfntVersion:32,
|
||
|
NumTables:16,
|
||
|
SearchRange:16,
|
||
|
EntrySelector:16,
|
||
|
RangeShift:16>>) ->
|
||
|
case lists:member(SfntVersion, [16#00010000]) of false -> throw({invalid_sfnt_version, SfntVersion}); true -> ok end,
|
||
|
[
|
||
|
{sfnt_version, SfntVersion},
|
||
|
{num_tables, NumTables},
|
||
|
{search_range, SearchRange},
|
||
|
{entry_selector, EntrySelector},
|
||
|
{range_shift, RangeShift}
|
||
|
].
|
||
|
|
||
|
%% 5.2 (Mandatory)
|
||
|
read_table_tag(<<"cmap">>) -> cmap;
|
||
|
read_table_tag(<<"head">>) -> head;
|
||
|
read_table_tag(<<"hhea">>) -> hhea;
|
||
|
read_table_tag(<<"hmtx">>) -> hmtx;
|
||
|
read_table_tag(<<"maxp">>) -> maxp;
|
||
|
read_table_tag(<<"name">>) -> name;
|
||
|
read_table_tag(<<"OS/2">>) -> os2 ;
|
||
|
read_table_tag(<<"post">>) -> post;
|
||
|
%% 5.3 (TTF)
|
||
|
read_table_tag(<<"cvt ">>) -> cvt ;
|
||
|
read_table_tag(<<"fpgm">>) -> fpgm;
|
||
|
read_table_tag(<<"glyf">>) -> glyf;
|
||
|
read_table_tag(<<"loca">>) -> loca;
|
||
|
read_table_tag(<<"prep">>) -> prep;
|
||
|
read_table_tag(<<"gasp">>) -> gasp;
|
||
|
%% TODO: 5.4 (CFF)
|
||
|
%% 5.5 (SVG)
|
||
|
read_table_tag(<<"SVG ">>) -> svg ;
|
||
|
%% 5.6 (Optional)
|
||
|
read_table_tag(<<"DSIG">>) -> dsig;
|
||
|
read_table_tag(<<"hdmx">>) -> hdmx;
|
||
|
read_table_tag(<<"Kern">>) -> kern;
|
||
|
read_table_tag(<<"LTSH">>) -> ltsh;
|
||
|
read_table_tag(<<"PCLT">>) -> pclt;
|
||
|
read_table_tag(<<"VDMX">>) -> vdmx;
|
||
|
read_table_tag(<<"vhea">>) -> vhea;
|
||
|
read_table_tag(<<"vmtx">>) -> vmtx;
|
||
|
read_table_tag(<<"COLR">>) -> colr;
|
||
|
read_table_tag(<<"CPAL">>) -> cpal;
|
||
|
%% 6.3 (Advanced Features)
|
||
|
read_table_tag(<<"BASE">>) -> base;
|
||
|
read_table_tag(<<"GDEF">>) -> gdef;
|
||
|
read_table_tag(<<"GPOS">>) -> gpos;
|
||
|
read_table_tag(<<"GSUB">>) -> gsub;
|
||
|
read_table_tag(<<"JSTF">>) -> jstf;
|
||
|
read_table_tag(<<"MATH">>) -> math;
|
||
|
%% 7.3 (Variable Fonts)
|
||
|
read_table_tag(<<"avar">>) -> avar;
|
||
|
read_table_tag(<<"cvar">>) -> cvar;
|
||
|
read_table_tag(<<"fvar">>) -> fvar;
|
||
|
read_table_tag(<<"gvar">>) -> gvar;
|
||
|
read_table_tag(<<"HVAR">>) -> hvar;
|
||
|
read_table_tag(<<"MVAR">>) -> mvar;
|
||
|
read_table_tag(<<"STAT">>) -> stat;
|
||
|
read_table_tag(<<"VVAR">>) -> vvar;
|
||
|
read_table_tag(<<TableTag:4/bytes>>) -> throw({invalid_table_tag, TableTag}).
|
||
|
|
||
|
-define(TABLE_DIRECTORY_SIZE(Count), ((?TAG_SIZE+3*?U32)*Count)).
|
||
|
parse_table_directory(
|
||
|
<<TableTag:?TAG_SIZE/binary,
|
||
|
CheckSum:32,
|
||
|
Offset:32,
|
||
|
Length:32,
|
||
|
Tail/binary>>) -> [{read_table_tag(TableTag), [
|
||
|
{check_sum, CheckSum},
|
||
|
{offset, Offset},
|
||
|
{length, Length}
|
||
|
]} | parse_table_directory(Tail)];
|
||
|
parse_table_directory(<<>>) -> [].
|
||
|
|
||
|
parse_font_directory(<<OffsetTable_:?OFFSET_TABLE_SIZE/binary, TableDirectoryAndRest/binary>>) ->
|
||
|
OffsetTable = parse_offset_table(OffsetTable_),
|
||
|
NumTables = proplists:get_value(num_tables, OffsetTable),
|
||
|
<<TableDirectory_:?TABLE_DIRECTORY_SIZE(NumTables)/binary, _/binary>> = TableDirectoryAndRest,
|
||
|
TableDirectory = parse_table_directory(TableDirectory_),
|
||
|
[
|
||
|
{offset_table, OffsetTable},
|
||
|
{table_directory, TableDirectory}
|
||
|
].
|