diff options
Diffstat (limited to 'v_windows/v/vlib/gg/text_rendering.v')
-rw-r--r-- | v_windows/v/vlib/gg/text_rendering.v | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/v_windows/v/vlib/gg/text_rendering.v b/v_windows/v/vlib/gg/text_rendering.v new file mode 100644 index 0000000..a34bbbb --- /dev/null +++ b/v_windows/v/vlib/gg/text_rendering.v @@ -0,0 +1,150 @@ +// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license that can be found in the LICENSE file. +module gg + +import os +import gx + +enum FontVariant { + normal = 0 + bold + mono + italic +} + +struct FTConfig { + font_path string + custom_bold_font_path string + scale f32 = 1.0 + font_size int + bytes_normal []byte + bytes_bold []byte + bytes_mono []byte + bytes_italic []byte +} + +struct StringToRender { + x int + y int + text string + cfg gx.TextCfg +} + +pub fn system_font_path() string { + env_font := os.getenv('VUI_FONT') + if env_font != '' && os.exists(env_font) { + return env_font + } + $if windows { + return 'C:\\Windows\\Fonts\\arial.ttf' + } + mut fonts := ['Ubuntu-R.ttf', 'Arial.ttf', 'LiberationSans-Regular.ttf', 'NotoSans-Regular.ttf', + 'FreeSans.ttf', 'DejaVuSans.ttf'] + $if macos { + fonts = ['/System/Library/Fonts/SFNS.ttf', '/System/Library/Fonts/SFNSText.ttf', + '/Library/Fonts/Arial.ttf', + ] + for font in fonts { + if os.is_file(font) { + return font + } + } + } + $if android { + xml_files := ['/system/etc/system_fonts.xml', '/system/etc/fonts.xml', + '/etc/system_fonts.xml', '/etc/fonts.xml', '/data/fonts/fonts.xml', + '/etc/fallback_fonts.xml', + ] + font_locations := ['/system/fonts', '/data/fonts'] + for xml_file in xml_files { + if os.is_file(xml_file) && os.is_readable(xml_file) { + xml := os.read_file(xml_file) or { continue } + lines := xml.split('\n') + mut candidate_font := '' + for line in lines { + if line.contains('<font') { + candidate_font = line.all_after('>').all_before('<').trim(' \n\t\r') + if candidate_font.contains('.ttf') { + for location in font_locations { + candidate_path := os.join_path(location, candidate_font) + if os.is_file(candidate_path) && os.is_readable(candidate_path) { + return candidate_path + } + } + } + } + } + } + } + } + s := os.execute('fc-list') + if s.exit_code != 0 { + panic('failed to fetch system fonts') + } + system_fonts := s.output.split('\n') + for line in system_fonts { + for font in fonts { + if line.contains(font) && line.contains(':') { + res := line.all_before(':') + println('Using font $res') + return res + } + } + } + panic('failed to init the font') +} + +fn get_font_path_variant(font_path string, variant FontVariant) string { + // TODO: find some way to make this shorter and more eye-pleasant + // NotoSans, LiberationSans, DejaVuSans, Arial and SFNS should work + mut file := os.file_name(font_path) + mut fpath := font_path.replace(file, '') + file = file.replace('.ttf', '') + + match variant { + .normal {} + .bold { + if fpath.ends_with('-Regular') { + file = file.replace('-Regular', '-Bold') + } else if file.starts_with('DejaVuSans') { + file += '-Bold' + } else if file.to_lower().starts_with('arial') { + file += 'bd' + } else { + file += '-bold' + } + $if macos { + if os.exists('SFNS-bold') { + file = 'SFNS-bold' + } + } + } + .italic { + if file.ends_with('-Regular') { + file = file.replace('-Regular', '-Italic') + } else if file.starts_with('DejaVuSans') { + file += '-Oblique' + } else if file.to_lower().starts_with('arial') { + file += 'i' + } else { + file += 'Italic' + } + } + .mono { + if !file.ends_with('Mono-Regular') && file.ends_with('-Regular') { + file = file.replace('-Regular', 'Mono-Regular') + } else if file.to_lower().starts_with('arial') { + // Arial has no mono variant + } else { + file += 'Mono' + } + } + } + return fpath + file + '.ttf' +} + +fn debug_font_println(s string) { + $if debug_font ? { + println(s) + } +} |