file-parser/OpenFontFormat/erl/font_directory.erl

91 lines
2.8 KiB
Erlang
Raw Normal View History

2024-05-03 21:04:21 +10:00
-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}
].