From a569dc17e86da2fc4d1dd1ba3bc2761cee16e758 Mon Sep 17 00:00:00 2001 From: shadowninja55 <49539636+shadowninja55@users.noreply.github.com> Date: Thu, 21 Jan 2021 16:07:47 -0500 Subject: [PATCH] gg: allow fonts loaded with $embed_file() to be used (#8263) --- examples/snek/snek.v | 20 +++++++++++------- vlib/gg/gg.v | 34 ++++++++++++++++++++++-------- vlib/gg/text_rendering.v | 45 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 81 insertions(+), 18 deletions(-) diff --git a/examples/snek/snek.v b/examples/snek/snek.v index efe82f4ac8..43b28af610 100644 --- a/examples/snek/snek.v +++ b/examples/snek/snek.v @@ -3,7 +3,6 @@ import gx import sokol.sapp import time import rand -import os // constants const ( @@ -37,11 +36,11 @@ enum Direction { struct App { mut: - gg &gg.Context - score int - snake []Pos - dir Direction - food Pos + gg &gg.Context + score int + snake []Pos + dir Direction + food Pos start_time i64 last_tick i64 } @@ -166,6 +165,8 @@ fn on_frame(mut app App) { app.gg.end() } +const font = $embed_file('../assets/fonts/RobotoMono-Regular.ttf') + // setup fn main() { mut app := App{ @@ -173,6 +174,11 @@ fn main() { } app.reset_game() + mut font_copy := font + font_bytes := unsafe { + font_copy.data().vbytes(font_copy.len) + } + app.gg = gg.new_context( bg_color: gx.white frame_fn: on_frame @@ -184,7 +190,7 @@ fn main() { create_window: true resizable: false window_title: 'snek' - font_path: os.resource_abs_path(os.join_path('../assets/fonts/', 'RobotoMono-Regular.ttf')) + font_bytes_normal: font_bytes ) app.gg.run() diff --git a/vlib/gg/gg.v b/vlib/gg/gg.v index e35540015a..e27d8d0cd1 100644 --- a/vlib/gg/gg.v +++ b/vlib/gg/gg.v @@ -60,6 +60,11 @@ pub: font_path string custom_bold_font_path string ui_mode bool // refreshes only on events to save CPU usage + // font bytes for embedding + font_bytes_normal []byte + font_bytes_bold []byte + font_bytes_mono []byte + font_bytes_italic []byte } pub struct Context { @@ -131,14 +136,25 @@ fn gg_init_sokol_window(user_data voidptr) { g.font_inited = true } else { if !exists { - sfont := system_font_path() - eprintln('font file "$g.config.font_path" does not exist, the system font was used instead.') - g.ft = new_ft( - font_path: sfont - custom_bold_font_path: g.config.custom_bold_font_path - scale: sapp.dpi_scale() - ) or { panic(err) } - g.font_inited = true + if g.config.font_bytes_normal.len > 0 { + g.ft = new_ft( + bytes_normal: g.config.font_bytes_normal + bytes_bold: g.config.font_bytes_bold + bytes_mono: g.config.font_bytes_mono + bytes_italic: g.config.font_bytes_italic + scale: sapp.dpi_scale() + ) or { panic(err) } + g.font_inited = true + } else { + sfont := system_font_path() + eprintln('font file "$g.config.font_path" does not exist, the system font was used instead.') + g.ft = new_ft( + font_path: sfont + custom_bold_font_path: g.config.custom_bold_font_path + scale: sapp.dpi_scale() + ) or { panic(err) } + g.font_inited = true + } } } // @@ -237,7 +253,7 @@ pub fn new_context(cfg Config) &Context { width: cfg.width height: cfg.height config: cfg - render_text: cfg.font_path != '' + render_text: cfg.font_path != '' || cfg.font_bytes_normal.len > 0 ft: 0 ui_mode: cfg.ui_mode } diff --git a/vlib/gg/text_rendering.v b/vlib/gg/text_rendering.v index 3094dc68a4..da301a422b 100644 --- a/vlib/gg/text_rendering.v +++ b/vlib/gg/text_rendering.v @@ -29,11 +29,51 @@ struct FTConfig { custom_bold_font_path string scale f32 = 1.0 font_size int + bytes_normal []byte + bytes_bold []byte + bytes_mono []byte + bytes_italic []byte } fn new_ft(c FTConfig) ?&FT { if c.font_path == '' { - // Load default font + if c.bytes_normal.len > 0 { + fons := sfons.create(512, 512, 1) + bytes_normal := c.bytes_normal + bytes_bold := if c.bytes_bold.len > 0 { + c.bytes_bold + } else { + debug_font_println('setting bold variant to normal') + bytes_normal + } + bytes_mono := if c.bytes_mono.len > 0 { + c.bytes_mono + } else { + debug_font_println('setting mono variant to normal') + bytes_normal + } + bytes_italic := if c.bytes_italic.len > 0 { + c.bytes_italic + } else { + debug_font_println('setting italic variant to normal') + bytes_normal + } + + return &FT{ + fons: fons + font_normal: C.fonsAddFontMem(fons, 'sans', bytes_normal.data, bytes_normal.len, + false) + font_bold: C.fonsAddFontMem(fons, 'sans', bytes_bold.data, bytes_bold.len, + false) + font_mono: C.fonsAddFontMem(fons, 'sans', bytes_mono.data, bytes_mono.len, + false) + font_italic: C.fonsAddFontMem(fons, 'sans', bytes_italic.data, bytes_italic.len, + false) + scale: c.scale + } + } else { + // Load default font + } } $if !android { if c.font_path == '' || !os.exists(c.font_path) { @@ -144,7 +184,8 @@ pub fn (ctx &Context) text_width(s string) int { mut buf := [4]f32{} C.fonsTextBounds(ctx.ft.fons, 0, 0, s.str, 0, buf) if s.ends_with(' ') { - return int((buf[2] - buf[0]) / ctx.scale) + ctx.text_width('i') // TODO fix this in fontstash? + return int((buf[2] - buf[0]) / + ctx.scale) + ctx.text_width('i') // TODO fix this in fontstash? } return int((buf[2] - buf[0]) / ctx.scale) }