import x.ttf import os import strings /********************************************************************** * * BMP render module utility functions * * Copyright (c) 2021 Dario Deledda. All rights reserved. * Use of this source code is governed by an MIT license * that can be found in the LICENSE file. * * Note: * use `v -d create_data vlib/x/ttf/ttf_test.v` to generate binary data for this test file * * TODO: * - manage text directions R to L **********************************************************************/ const font_path = 'Qarmic_sans_Abridged.ttf' const font_bytes = $embed_file('ttf_test_data.bin') const test_data = ' 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 00bf bfbf bfbf bfbf bfbf bfbf bf00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 00bf bfbf bfbf bfbf bfbf bfbf bf00 0000 bfff ffff ffff ffff ffff ffff ffbf 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 bfff ffff ffff ffff ffff ffff ffbf 0000 00bf ffff ffbf ffff bfff ffff bf00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 00bf ffff ffbf ffff bfff ffff bf00 0000 0000 0000 00bf ffff bf00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 bf00 0000 0000 0000 0000 0000 0000 0000 0000 0000 00bf ffff bf00 0000 0000 0000 0000 0000 00bf ffff bf00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 00bf ffbf 0000 0000 0000 0000 0000 0000 0000 0000 0000 00bf ffff bf00 0000 0000 0000 0000 0000 00bf ffff bf00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 00bf ffbf 0000 0000 0000 0000 0000 0000 0000 0000 0000 00bf ffff bf00 0000 0000 0000 0000 0000 00bf ffff bf00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 bfbf ffbf bfbf bf00 0000 0000 0000 0000 0000 0000 0000 00bf ffff bf00 0000 0000 0000 0000 0000 00bf ffff bf00 0000 0032 72bf bfbf 0000 0000 bfbf bfbf 5400 00bf ffff ffff ffff ffbf 0000 0000 0000 0000 0000 0000 0000 00bf ffff bf00 0000 0032 72bf 0000 0000 00bf ffff bf00 0065 9999 ffff ffff bf00 00bf ffff ffff ff7f 0000 bfff bfff bfff bf00 0000 0000 0000 0000 0000 0000 0000 00bf ffff bf00 0065 9999 6500 0000 0000 00bf ffff bf00 bfff ffff ffbf ffff ffbf bfff bfff bfbf ffff bf00 bfff bf00 0000 0000 0000 0000 0000 0000 0000 0000 0000 00bf ffff bf00 bf72 3300 7fbf 0000 0000 00bf ffff bf7f 5fff ffbf 3f7f 8fbf ffbf ffbf 5500 0000 5fbf 0000 bfff bf00 0000 0000 0000 0000 0000 0000 0000 0000 0000 00bf ffff bf7f 5fff ffbf 3f7f 0000 0000 00bf ffff bfbf ffbf bfbf ffff ffff ffbf ffff ff7f 0000 0000 0000 bfff bf00 0000 0000 0000 0000 0000 0000 0000 0000 0000 00bf ffff bfbf 00bf bfbf 8f5f 0000 0000 00bf ffff 7f5f ffff ffff ffff ffff ffbf 5fbf ffff bfbf bfbf 0000 bfff bf00 0000 0000 0000 0000 0000 0000 0000 0000 0000 00bf ffff 7f5f 0000 0000 0000 0000 0000 00bf ffff bfff bfff ffbf ffff ffff ffbf 0000 5fbf ffff ffff bf00 bfff bf00 0000 0000 0000 0000 0000 0000 0000 0000 0000 00bf ffff bfff bfff ffbf ffff 0000 0000 00bf ffff bfff bf00 0000 0000 0000 0000 0000 0000 7f7f ffff bf00 bfff bf00 0000 bf00 0000 0000 0000 0000 0000 0000 0000 00bf ffff bfff bf00 0000 0000 0000 0000 00bf ffff bfff bf00 0000 0000 0000 bf00 bf00 0000 0055 bfff ffbf bfff ff7f 00bf ff5f 0000 0000 0000 0000 0000 0000 0000 00bf ffff bfff bf00 0000 0000 0000 0000 00bf ffff bfbf ffbf 0000 0055 7fbf ffbf ffbf 7f55 00bf ffff bf00 7f5f ff7f 7f5f ffbf 0000 0000 0000 0000 0000 0000 0000 00bf ffff bfbf ffbf 0000 0055 0000 0000 00bf ffff bfbf ffff bfbf bfff ffff bfbf ffff ffff ffff ffff bf00 00bf ffff ffff ffbf 0000 0000 0000 0000 0000 0000 0000 00bf ffff bfbf 0000 bfbf bf7f 0000 0000 00bf ffff bf00 bfff ffff ffff ffbf 0000 bfbf ffff ffff bfbf 0000 00bf ffbf ffff bf00 0000 0000 0000 0000 0000 0000 0000 00bf ffff bf00 bf00 0000 3f7f 0000 0000 0000 5fbf 0000 00bf ffbf 8f5f 3f00 0000 0000 5fbf bf5f 0000 0000 0000 0000 bf5f 0000 0000 0000 0000 0000 0000 0000 0000 0000 5fbf 0000 00bf ffbf 8f5f 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 ' fn save_raw_data_as_array(buf_bin []byte, file_name string) { mut buf := strings.new_builder(buf_bin.len * 5) for x in buf_bin { buf.write_string('0x${x:02x},') } os.write_file_array(file_name, buf) or { panic(err) } } fn test_main() { mut tf := ttf.TTF_File{} $if create_data ? { tf.buf = os.read_bytes(font_path) or { panic(err) } println('TrueTypeFont file [$font_path] len: $tf.buf.len') save_raw_data_as_array(tf.buf, 'test_ttf_Font_arr.bin') } $else { mut mut_font_bytes := font_bytes tf.buf = unsafe { mut_font_bytes.data().vbytes(font_bytes.len) } } tf.init() // println("Unit per EM: $tf.units_per_em") w := 64 h := 32 bp := 4 sz := w * h * bp font_size := 20 device_dpi := 72 scale := f32(font_size * device_dpi) / f32(72 * tf.units_per_em) mut bmp := ttf.BitMap{ tf: &tf buf: unsafe { malloc(sz) } buf_size: sz scale: scale width: w height: h } y_base := int((tf.y_max - tf.y_min) * bmp.scale) bmp.clear() bmp.set_pos(0, y_base) bmp.init_filler() bmp.draw_text('Test Text') mut test_buf := get_raw_data(test_data) $if create_data ? { bmp.save_as_ppm('test_ttf.ppm') bmp.save_raw_data('test_ttf.bin') test_buf = os.read_bytes('test_ttf.bin') or { panic(err) } } ram_buf := bmp.get_raw_bytes() assert ram_buf.len == test_buf.len for i in 0 .. ram_buf.len { if test_buf[i] != ram_buf[i] { assert false } } } fn get_raw_data(data string) []byte { mut buf := []byte{} mut c := 0 mut b := u32(0) for ch in data { if ch >= `0` && ch <= `9` { b = b << 4 b += u32(ch - `0`) c++ } else if ch >= `a` && ch <= `f` { b = b << 4 b += u32(ch - `a` + 10) c++ } if c == 2 { buf << byte(b) b = 0 c = 0 } } return buf }