wip generating fonts
This commit is contained in:
parent
f4fd444e8c
commit
6e0ab0d9a3
|
@ -2,3 +2,8 @@
|
||||||
(name gen_sprite_map)
|
(name gen_sprite_map)
|
||||||
(modules gen_sprite_map)
|
(modules gen_sprite_map)
|
||||||
(libraries xmlm sexplib))
|
(libraries xmlm sexplib))
|
||||||
|
|
||||||
|
(executable
|
||||||
|
(name gen_glyph_map)
|
||||||
|
(modules gen_glyph_map)
|
||||||
|
(libraries yojson sexplib))
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
msdf="msdf-atlas-gen"
|
||||||
|
gen_glyph_map="dune exec --no-print-directory --display=quiet scripts/gen_glyph_map.exe"
|
||||||
|
|
||||||
|
out_dir=assets/fonts/
|
||||||
|
|
||||||
|
mkdir -p $out_dir
|
||||||
|
|
||||||
|
function gen() {
|
||||||
|
echo "$1..."
|
||||||
|
|
||||||
|
dst_png=$out_dir/$1.png
|
||||||
|
dst_map=$out_dir/$1.map
|
||||||
|
src=$(find /usr/share/fonts -name $2)
|
||||||
|
emsize=$3
|
||||||
|
|
||||||
|
[[ "$src" -nt "$dst_png" ]] &&
|
||||||
|
($msdf \
|
||||||
|
-font $src \
|
||||||
|
-imageout $dst_png \
|
||||||
|
-json >($gen_glyph_map > $dst_map) \
|
||||||
|
-size $emsize \
|
||||||
|
-yorigin top \
|
||||||
|
| exit 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
gen liberation LiberationMono-Regular.ttf 64
|
|
@ -0,0 +1,123 @@
|
||||||
|
[@@@warning "-32-69"]
|
||||||
|
|
||||||
|
module Sexp = Sexplib.Sexp
|
||||||
|
module Json = Yojson.Basic
|
||||||
|
|
||||||
|
type atlas = {
|
||||||
|
size : int;
|
||||||
|
width : int;
|
||||||
|
height : int;
|
||||||
|
y_origin : [`bottom | `top];
|
||||||
|
}
|
||||||
|
|
||||||
|
(* type metrics = { *)
|
||||||
|
(* line_height : float; *)
|
||||||
|
(* ascender : float; *)
|
||||||
|
(* descender : float; *)
|
||||||
|
(* underline_y : float; *)
|
||||||
|
(* } *)
|
||||||
|
|
||||||
|
type bounds = {
|
||||||
|
left : float;
|
||||||
|
bottom : float;
|
||||||
|
right : float;
|
||||||
|
top : float;
|
||||||
|
}
|
||||||
|
|
||||||
|
type glyph = {
|
||||||
|
unicode : int;
|
||||||
|
advance : float;
|
||||||
|
plane_bounds : bounds option;
|
||||||
|
atlas_bounds : bounds option;
|
||||||
|
}
|
||||||
|
|
||||||
|
type msdf = {
|
||||||
|
atlas : atlas;
|
||||||
|
glyphs : glyph list;
|
||||||
|
}
|
||||||
|
|
||||||
|
let invalid_json f x =
|
||||||
|
invalid_arg (f ^ ": unexpected json: " ^ Json.to_string x)
|
||||||
|
|
||||||
|
let int_of_json = function `Int i -> i |
|
||||||
|
x -> invalid_json "int_of_json" x
|
||||||
|
let float_of_json = function `Int i -> float_of_int i | `Float f -> f |
|
||||||
|
x -> invalid_json "float_of_json" x
|
||||||
|
let string_of_json = function `String s -> s |
|
||||||
|
x -> invalid_json "string_of_json" x
|
||||||
|
let list_of_json = function `List l -> l |
|
||||||
|
x -> invalid_json "list_of_json" x
|
||||||
|
let json_assoc_opt k = function
|
||||||
|
| `Assoc kv -> List.assoc_opt k kv
|
||||||
|
| x -> invalid_json "json_assoc" x
|
||||||
|
let json_assoc k js = match json_assoc_opt k js with
|
||||||
|
| Some v -> v
|
||||||
|
| None -> invalid_arg ("no key " ^ k)
|
||||||
|
|
||||||
|
let atlas_of_json = function
|
||||||
|
| `Assoc kv ->
|
||||||
|
let size = int_of_json (List.assoc "size" kv) in
|
||||||
|
let width = int_of_json (List.assoc "width" kv) in
|
||||||
|
let height = int_of_json (List.assoc "height" kv) in
|
||||||
|
let y_origin = match List.assoc "yOrigin" kv with
|
||||||
|
| `String "bottom" -> `bottom
|
||||||
|
| `String "top" -> `top
|
||||||
|
| x -> invalid_json "yOrigin" x
|
||||||
|
in
|
||||||
|
{ size; width; height; y_origin }
|
||||||
|
| x -> invalid_json "atlas_of_json" x
|
||||||
|
|
||||||
|
let bounds_of_json js =
|
||||||
|
let left = float_of_json (json_assoc "left" js) in
|
||||||
|
let right = float_of_json (json_assoc "right" js) in
|
||||||
|
let top = float_of_json (json_assoc "top" js) in
|
||||||
|
let bottom = float_of_json (json_assoc "bottom" js) in
|
||||||
|
{ left; right; top; bottom }
|
||||||
|
|
||||||
|
let glyph_of_json js =
|
||||||
|
let unicode = int_of_json (json_assoc "unicode" js) in
|
||||||
|
let advance = float_of_json (json_assoc "advance" js) in
|
||||||
|
let plane_bounds = Option.map bounds_of_json (json_assoc_opt "planeBounds" js) in
|
||||||
|
let atlas_bounds = Option.map bounds_of_json (json_assoc_opt "atlasBounds" js) in
|
||||||
|
{ unicode; advance; plane_bounds; atlas_bounds }
|
||||||
|
|
||||||
|
let msdf_of_json js =
|
||||||
|
let atlas = atlas_of_json (json_assoc "atlas" js) in
|
||||||
|
let glyphs = List.map glyph_of_json (list_of_json (json_assoc "glyphs" js)) in
|
||||||
|
{ atlas; glyphs }
|
||||||
|
|
||||||
|
let sexp_of_bounds b =
|
||||||
|
Sexp.List [
|
||||||
|
Atom (Printf.sprintf "%.4f" b.left);
|
||||||
|
Atom (Printf.sprintf "%.4f" b.top);
|
||||||
|
Atom (Printf.sprintf "%.4f" b.right);
|
||||||
|
Atom (Printf.sprintf "%.4f" b.bottom);
|
||||||
|
]
|
||||||
|
|
||||||
|
let sexp_of_glyph g =
|
||||||
|
let chr = Char.chr g.unicode in
|
||||||
|
Sexp.List (
|
||||||
|
Atom "glyph" ::
|
||||||
|
Atom (String.make 1 chr) ::
|
||||||
|
List [Atom "advance"; Atom (Printf.sprintf "%.4f" g.advance)] ::
|
||||||
|
(
|
||||||
|
(g.plane_bounds |> Option.map sexp_of_bounds |> Option.to_list) @
|
||||||
|
(g.atlas_bounds |> Option.map sexp_of_bounds |> Option.to_list)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
let sexp_of_msdf msdf =
|
||||||
|
Sexp.List (
|
||||||
|
Atom "msdf" ::
|
||||||
|
List.map sexp_of_glyph
|
||||||
|
(List.sort (fun a b -> compare a.unicode b.unicode)
|
||||||
|
msdf.glyphs)
|
||||||
|
)
|
||||||
|
|
||||||
|
let () =
|
||||||
|
let inp = Json.from_channel stdin in
|
||||||
|
let msdf = msdf_of_json inp in
|
||||||
|
if msdf.atlas.y_origin <> `top then
|
||||||
|
failwith "origin must be top";
|
||||||
|
Format.printf "%a\n"
|
||||||
|
Sexp.pp_hum (sexp_of_msdf msdf)
|
Loading…
Reference in New Issue