module Otfm:sig
..end
WARNING. This interface is subject to change in the future.
Otfm
is an in-memory decoder for the OpenType font data format.
It provides low-level access to OpenType fonts tables and functions
to decode some of them.
Consult the limitations and example of use.
Note. Unless otherwise specified the strings returned are UTF-8 encoded.
Release 0.1.0 — Daniel Bünzli <daniel.buenzl i@erratique.ch>
type
tag
module Tag:sig
..end
For some reason OpenType allows the (textually meaningless)
surrogate
code points to be mapped to glyphs. Hence we deal with Unicode
code points not
scalar
values.
typecp =
int
0x0000
to 0x10_FFFF
. Any code point returned by
Otfm
is guaranteed to be in the range.typecp_range =
cp * cp
(u0, u1)
returned by Otfm
has u0 <= u1
.val is_cp : int -> bool
typeerror_ctx =
[ `Offset_table | `Table of tag | `Table_directory ]
typeerror =
[ `Invalid_cp of int
| `Invalid_cp_range of int * int
| `Invalid_offset of error_ctx * int
| `Invalid_postscript_name of string
| `Missing_required_table of tag
| `Unexpected_eoi of error_ctx
| `Unknown_flavour of tag
| `Unknown_version of error_ctx * int32
| `Unsupported_TTC
| `Unsupported_cmaps of (int * int * int) list ]
Note. In case of `Invalid_poscript_name
a string of bytes is
returned.
val pp_error : Format.formatter -> [< error ] -> unit
pp_error ppf e
prints an uspecified representation of e
on ppf
.typesrc =
[ `String of string ]
type
decoder
val decoder : [< src ] -> decoder
decoder src
is a decoder decoding from src
.val decoder_src : decoder -> src
decoder_src d
is d
's input source.
These functions can be used in any order and are robust: when they
return an error the decoder is back to a consistant state and can
be used further. However if Otfm.flavour
or Otfm.table_list
returns an
error you can safely assume that all other functions will. The
fields are in general not documented please refer to the OpenType
specification for details.
typeflavour =
[ `CFF | `TTF ]
val flavour : decoder -> [> `Error of error | `Ok of flavour ]
decode_flavour d
is the flavour of the font decoded by d
.val table_list : decoder -> [> `Error of error | `Ok of tag list ]
table_list t
is the list of tables of the font decoded by d
.val table_mem : decoder -> tag -> [> `Error of error | `Ok of bool ]
table_mem d t
is true
if table t
is in the font decoded by d
.val table_raw : decoder -> tag -> [> `Error of error | `Ok of string option ]
table_raw d t
is the (unpadded) data of the table t
as a
string if the table t
exists.
These functions lookup data in the right table.
val glyph_count : decoder -> [> `Error of error | `Ok of int ]
glyph_count d
is the number of glyphs in the font (bounded by 65535
).val postscript_name : decoder -> [> `Error of error | `Ok of string option ]
poscript_name d
is the PostScript name of d
. Looks up and validates
as mandated by the OTF standard, don't rely on Otfm.name
if you really
need this information.typeglyph_id =
int
0
to 65534
.typemap_kind =
[ `Glyph | `Glyph_range ]
Determines how an unicode range (u0, u1)
and a glyph id gid
must be interpreted in the folding function of Otfm.cmap
.
`Glyph
all characters in the range map to to gid
.`Glyph_range
, u0
maps to gid
, u0 + 1
to gid + 1
, ...
and u1
to gid + (u1 - u0)
val cmap : decoder ->
('a -> map_kind -> cp_range -> glyph_id -> 'a) ->
'a -> [> `Error of error | `Ok of (int * int * int) * 'a ]
cmap d f acc
folds over a mapping from unicode
scalar values to glyph ids by reading the
cmap table.
The returned triple of integer indicates the platform id, encoding
id and format of the cmap used.
Limitations. Only the format 13 (last resort font), format 12 (UCS-4) and format 4 (UCS-2) cmap table formats are supported.
If multiple tables are present, it favours 13 over 12 over 4. If multiple tables of the same format are present it takes the first one it finds.
If no supported cmap table is found the error `Unsupported_cmaps
is returned with the list of platform id, encoding id, format
available in the font.
type
head = {
|
head_font_revision : |
|||
|
head_flags : |
|||
|
head_units_per_em : |
|||
|
head_created : |
(* | Unix timestamp. | *) |
|
head_modified : |
(* | Unix timestamp. | *) |
|
head_xmin : |
|||
|
head_ymin : |
|||
|
head_xmax : |
|||
|
head_ymax : |
|||
|
head_mac_style : |
|||
|
head_lowest_rec_ppem : |
|||
|
head_index_to_loc_format : |
val head : decoder -> [> `Error of error | `Ok of head ]
head d
is the head table.type
hhea = {
|
hhea_ascender : |
|
hhea_descender : |
|
hhea_line_gap : |
|
hhea_advance_width_max : |
|
hhea_min_left_side_bearing : |
|
hhea_min_right_side_bearing : |
|
hhea_xmax_extent : |
|
hhea_caret_slope_rise : |
|
hhea_caret_slope_run : |
|
hhea_caret_offset : |
val hhea : decoder -> [> `Error of error | `Ok of hhea ]
hhea d
is the hhea table.val hmtx : decoder ->
('a -> glyph_id -> int -> int -> 'a) ->
'a -> [> `Error of error | `Ok of 'a ]
hmtx d f acc
folds over the horizontal metrics of the font by
reading the
hmtx
table. f
is applied on each entry with f acc' gid adv lsb
with gid
the glyph id (guaranteed to range, in order, from
0
to glyph count minus one), adv
the (unsigned) advance width,
and lsb
the (signed) left side bearing.typelang =
string
val name : decoder ->
('a -> int -> lang -> string -> 'a) ->
'a -> [> `Error of error | `Ok of 'a ]
name d f acc
folds over the name records of the font by
reading the name
table. f
is applied on each name id entry with f acc' nid lang name
with nid
the name id, lang the language tag, and name
the UTF-8
encoded name value.
Note. The module normalizes Windows language ids to lowercased BCP 47 ids. Language tags found in language tag records should be BCP 47 language tags but are not checked for conformance.
Tip. If you are looking for the postcript name use
Otfm.postscript_name
.
Limitations. Lookups data only in platform ids 0, 2 and 3 (Unicode,
ISO and Windows) with UTF-16BE encoding and reports only the data of
the first one it finds for a given name id.
type
os2 = {
|
os2_x_avg_char_width : |
|||
|
os2_us_weight_class : |
|||
|
os2_us_width_class : |
|||
|
os2_fs_type : |
|||
|
os2_y_subscript_x_size : |
|||
|
os2_y_subscript_y_size : |
|||
|
os2_y_subscript_x_offset : |
|||
|
os2_y_subscript_y_offset : |
|||
|
os2_y_superscript_x_size : |
|||
|
os2_y_superscript_y_size : |
|||
|
os2_y_superscript_x_offset : |
|||
|
os2_y_superscript_y_offset : |
|||
|
os2_y_strikeout_size : |
|||
|
os2_y_strikeout_position : |
|||
|
os2_family_class : |
|||
|
os2_panose : |
(* | 10 bytes | *) |
|
os2_ul_unicode_range1 : |
|||
|
os2_ul_unicode_range2 : |
|||
|
os2_ul_unicode_range3 : |
|||
|
os2_ul_unicode_range4 : |
|||
|
os2_ach_vend_id : |
|||
|
os2_fs_selection : |
|||
|
os2_us_first_char_index : |
|||
|
os2_us_last_char_index : |
|||
|
os2_s_typo_ascender : |
|||
|
os2_s_type_descender : |
|||
|
os2_s_typo_linegap : |
|||
|
os2_us_win_ascent : |
|||
|
os2_us_win_descent : |
|||
|
os2_ul_code_page_range_1 : |
|||
|
os2_ul_code_page_range_2 : |
|||
|
os2_s_x_height : |
|||
|
os2_s_cap_height : |
|||
|
os2_us_default_char : |
|||
|
os2_us_break_char : |
|||
|
os2_us_max_context : |
val os2 : decoder -> [> `Error of error | `Ok of os2 ]
os2 d
is the OS/2 table.type
kern_info = {
|
kern_dir : |
|
kern_kind : |
|
kern_cross_stream : |
val kern : decoder ->
('a -> kern_info -> [ `Fold | `Skip ] * 'a) ->
('a -> glyph_id -> glyph_id -> int -> 'a) ->
'a -> [> `Error of error | `Ok of 'a ]
kern d t p acc
folds over the kerning tables of d
by
reading the kern
table. t
is called on each new (sub)table, the table pairs are skipped if
it returns `Skip
otherwise p acc' left right value
is called on
each kerning pair of the table. The function returns acc
if there
is no kern table.
Limitations. Only format 0 kerning tables are supported.
As it stands Otfm
has the following limitations. Some of these
may be lifted in the future and a few of these can be overcome
by pre-processing your font (e.g. extract .ttc
files to .ttf
, or
removing hinting information to reduce the font size). See also
the individual table decoding functions for other limitations.
.ttc
files) are not supported.ttc
font
files tend to be smaller than 16 Mo).The following code prints the postscript name of the font on stdout.
let otf_postscript_name bytes =
let d = Otfm.decoder (`String bytes) in
match Otfm.postscript_name d with
| `Error e -> Format.eprintf "@[%a@]@." Otfm.pp_error e
| `Ok (Some n) -> Format.printf "%s@." n;
| `Ok None -> ()