2021-01-10 21:14:41 +03:00
|
|
|
module ttf
|
2021-01-26 17:43:10 +03:00
|
|
|
|
2021-01-10 21:14:41 +03:00
|
|
|
/**********************************************************************
|
|
|
|
*
|
|
|
|
* 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:
|
|
|
|
*
|
2021-04-07 21:39:23 +03:00
|
|
|
* TODO:
|
2021-01-10 21:14:41 +03:00
|
|
|
**********************************************************************/
|
|
|
|
import math
|
|
|
|
import gg
|
|
|
|
import sokol.sgl
|
2022-01-02 21:36:01 +03:00
|
|
|
import sokol.gfx
|
2021-01-10 21:14:41 +03:00
|
|
|
|
2021-01-26 17:43:10 +03:00
|
|
|
pub struct TTF_render_Sokol {
|
2021-01-10 21:14:41 +03:00
|
|
|
pub mut:
|
2022-09-15 07:59:31 +03:00
|
|
|
bmp &BitMap = unsafe { nil } // Base bitmap render
|
2021-01-10 21:14:41 +03:00
|
|
|
// rendering fields
|
2022-01-02 21:36:01 +03:00
|
|
|
sg_img gfx.Image // sokol image
|
2021-01-26 17:43:10 +03:00
|
|
|
scale_reduct f32 = 2.0 // scale of the cpu texture for filtering
|
|
|
|
device_dpi int = 72 // device DPI
|
2021-01-10 21:14:41 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* Render functions
|
|
|
|
*
|
|
|
|
******************************************************************************/
|
2021-06-28 13:32:17 +03:00
|
|
|
pub fn (mut tf_skl TTF_render_Sokol) format_texture() {
|
2021-01-17 05:11:47 +03:00
|
|
|
tf_skl.bmp.format_texture()
|
2021-01-10 21:14:41 +03:00
|
|
|
}
|
|
|
|
|
2021-01-26 17:43:10 +03:00
|
|
|
pub fn (mut tf_skl TTF_render_Sokol) create_text(in_txt string, in_font_size f32) {
|
2021-01-10 21:14:41 +03:00
|
|
|
scale_reduct := tf_skl.scale_reduct
|
|
|
|
device_dpi := tf_skl.device_dpi
|
|
|
|
font_size := in_font_size //* scale_reduct
|
2021-01-26 17:43:10 +03:00
|
|
|
|
2021-01-10 21:14:41 +03:00
|
|
|
// Formula: (font_size * device dpi) / (72dpi * em_unit)
|
2021-01-26 17:43:10 +03:00
|
|
|
// scale := ((1.0 * devide_dpi )/ f32(72 * tf_skl.bmp.tf.units_per_em))* font_size
|
2021-01-10 21:14:41 +03:00
|
|
|
scale := f32(font_size * device_dpi) / f32(72 * tf_skl.bmp.tf.units_per_em)
|
2021-01-26 17:43:10 +03:00
|
|
|
// dprintln("Scale: $scale")
|
|
|
|
|
|
|
|
tf_skl.bmp.scale = scale * scale_reduct
|
2021-01-10 21:14:41 +03:00
|
|
|
w, h := tf_skl.bmp.get_bbox(in_txt)
|
2021-01-26 17:43:10 +03:00
|
|
|
tf_skl.bmp.width = int(w)
|
|
|
|
tf_skl.bmp.height = int((h + 8))
|
2021-01-10 21:14:41 +03:00
|
|
|
sz := tf_skl.bmp.width * tf_skl.bmp.height * tf_skl.bmp.bp
|
2021-01-26 17:43:10 +03:00
|
|
|
|
2021-01-10 21:14:41 +03:00
|
|
|
// RAM buffer
|
|
|
|
if sz > tf_skl.bmp.buf_size {
|
|
|
|
if sz > 0 {
|
2021-03-19 10:49:26 +03:00
|
|
|
unsafe { free(tf_skl.bmp.buf) }
|
2021-01-10 21:14:41 +03:00
|
|
|
}
|
2022-11-15 16:53:13 +03:00
|
|
|
dprintln('create_text Alloc: ${sz} bytes')
|
2021-06-15 14:47:11 +03:00
|
|
|
tf_skl.bmp.buf = unsafe { malloc_noscan(sz) }
|
2021-01-10 21:14:41 +03:00
|
|
|
tf_skl.bmp.buf_size = sz
|
|
|
|
}
|
|
|
|
|
|
|
|
tf_skl.bmp.init_filler()
|
2021-01-26 17:43:10 +03:00
|
|
|
|
2021-01-10 21:14:41 +03:00
|
|
|
// draw the text
|
|
|
|
mut y_base := int((tf_skl.bmp.tf.y_max - tf_skl.bmp.tf.y_min) * tf_skl.bmp.scale)
|
2021-01-26 17:43:10 +03:00
|
|
|
tf_skl.bmp.set_pos(0, y_base)
|
2021-01-10 21:14:41 +03:00
|
|
|
tf_skl.bmp.clear()
|
|
|
|
tf_skl.bmp.draw_text(in_txt)
|
|
|
|
tf_skl.format_texture()
|
|
|
|
}
|
|
|
|
|
2021-01-26 17:43:10 +03:00
|
|
|
pub fn (mut tf_skl TTF_render_Sokol) create_text_block(in_txt string, in_w int, in_h int, in_font_size f32) {
|
2021-01-10 21:14:41 +03:00
|
|
|
scale_reduct := tf_skl.scale_reduct
|
|
|
|
device_dpi := tf_skl.device_dpi
|
|
|
|
font_size := in_font_size //* scale_reduct
|
|
|
|
// Formula: (font_size * device dpi) / (72dpi * em_unit)
|
2021-01-26 17:43:10 +03:00
|
|
|
// scale := ((1.0 * devide_dpi )/ f32(72 * tf_skl.bmp.tf.units_per_em))* font_size
|
2021-01-10 21:14:41 +03:00
|
|
|
scale := f32(font_size * device_dpi) / f32(72 * tf_skl.bmp.tf.units_per_em)
|
2021-01-26 17:43:10 +03:00
|
|
|
// dprintln("Scale: $scale")
|
|
|
|
|
|
|
|
tf_skl.bmp.scale = scale * scale_reduct
|
2021-01-10 21:14:41 +03:00
|
|
|
w := in_w
|
|
|
|
h := in_h
|
2021-01-26 17:43:10 +03:00
|
|
|
tf_skl.bmp.width = int(w * scale_reduct + 0.5)
|
|
|
|
tf_skl.bmp.height = int((h + 2) * scale_reduct + 0.5)
|
2021-01-10 21:14:41 +03:00
|
|
|
sz := tf_skl.bmp.width * tf_skl.bmp.height * tf_skl.bmp.bp
|
2021-01-26 17:43:10 +03:00
|
|
|
|
|
|
|
// if true { return }
|
|
|
|
|
2021-01-10 21:14:41 +03:00
|
|
|
// RAM buffer
|
|
|
|
if sz > tf_skl.bmp.buf_size {
|
|
|
|
if sz > 0 {
|
2021-03-19 10:49:26 +03:00
|
|
|
unsafe { free(tf_skl.bmp.buf) }
|
2021-01-10 21:14:41 +03:00
|
|
|
}
|
2022-11-15 16:53:13 +03:00
|
|
|
dprintln('Alloc: ${sz} bytes')
|
2021-06-15 14:47:11 +03:00
|
|
|
tf_skl.bmp.buf = unsafe { malloc_noscan(sz) }
|
2021-01-10 21:14:41 +03:00
|
|
|
tf_skl.bmp.buf_size = sz
|
|
|
|
}
|
|
|
|
|
|
|
|
tf_skl.bmp.init_filler()
|
2021-01-26 17:43:10 +03:00
|
|
|
|
2021-01-10 21:14:41 +03:00
|
|
|
// draw the text
|
|
|
|
mut y_base := int((tf_skl.bmp.tf.y_max - tf_skl.bmp.tf.y_min) * tf_skl.bmp.scale)
|
2021-01-26 17:43:10 +03:00
|
|
|
tf_skl.bmp.set_pos(0, y_base)
|
2021-01-10 21:14:41 +03:00
|
|
|
tf_skl.bmp.clear()
|
2021-01-26 17:43:10 +03:00
|
|
|
|
|
|
|
tf_skl.bmp.draw_text_block(in_txt, x: 0, y: 0, w: w, h: h)
|
2021-01-10 21:14:41 +03:00
|
|
|
tf_skl.format_texture()
|
|
|
|
}
|
2021-01-26 17:43:10 +03:00
|
|
|
|
2021-01-10 21:14:41 +03:00
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* Sokol Render functions
|
|
|
|
*
|
|
|
|
******************************************************************************/
|
2021-01-26 17:43:10 +03:00
|
|
|
pub fn (mut tf_skl TTF_render_Sokol) create_texture() {
|
2021-01-10 21:14:41 +03:00
|
|
|
w := tf_skl.bmp.width
|
|
|
|
h := tf_skl.bmp.height
|
|
|
|
sz := tf_skl.bmp.width * tf_skl.bmp.height * tf_skl.bmp.bp
|
2022-01-02 21:36:01 +03:00
|
|
|
mut img_desc := gfx.ImageDesc{
|
2021-01-10 21:14:41 +03:00
|
|
|
width: w
|
|
|
|
height: h
|
|
|
|
num_mipmaps: 0
|
2021-01-26 17:43:10 +03:00
|
|
|
min_filter: .linear
|
|
|
|
mag_filter: .linear
|
|
|
|
// usage: .dynamic
|
2021-01-10 21:14:41 +03:00
|
|
|
wrap_u: .clamp_to_edge
|
|
|
|
wrap_v: .clamp_to_edge
|
2021-04-19 15:38:48 +03:00
|
|
|
label: &char(0)
|
2021-01-10 21:14:41 +03:00
|
|
|
d3d11_texture: 0
|
|
|
|
}
|
|
|
|
// comment for dynamic
|
2022-01-02 21:36:01 +03:00
|
|
|
img_desc.data.subimage[0][0] = gfx.Range{
|
2021-01-10 21:14:41 +03:00
|
|
|
ptr: tf_skl.bmp.buf
|
2021-09-08 13:09:32 +03:00
|
|
|
size: usize(sz)
|
2021-01-10 21:14:41 +03:00
|
|
|
}
|
2021-01-26 17:43:10 +03:00
|
|
|
|
2022-01-02 21:36:01 +03:00
|
|
|
simg := gfx.make_image(&img_desc)
|
2021-01-26 17:43:10 +03:00
|
|
|
// free(tf_skl.bmp.buf) // DONT FREE IF Dynamic
|
2021-01-10 21:14:41 +03:00
|
|
|
tf_skl.sg_img = simg
|
|
|
|
}
|
|
|
|
|
2021-01-26 17:43:10 +03:00
|
|
|
pub fn (tf_skl TTF_render_Sokol) destroy_texture() {
|
2022-01-02 21:36:01 +03:00
|
|
|
gfx.destroy_image(tf_skl.sg_img)
|
2021-01-10 21:14:41 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Use only if usage: .dynamic
|
2021-01-26 17:43:10 +03:00
|
|
|
pub fn (mut tf_skl TTF_render_Sokol) update_text_texture() {
|
2021-01-10 21:14:41 +03:00
|
|
|
sz := tf_skl.bmp.width * tf_skl.bmp.height * tf_skl.bmp.bp
|
2022-01-02 21:36:01 +03:00
|
|
|
mut tmp_sbc := gfx.ImageData{}
|
|
|
|
tmp_sbc.subimage[0][0] = gfx.Range{
|
2021-01-10 21:14:41 +03:00
|
|
|
ptr: tf_skl.bmp.buf
|
2021-09-08 13:09:32 +03:00
|
|
|
size: usize(sz)
|
2021-01-10 21:14:41 +03:00
|
|
|
}
|
2022-01-02 21:36:01 +03:00
|
|
|
gfx.update_image(tf_skl.sg_img, &tmp_sbc)
|
2021-01-10 21:14:41 +03:00
|
|
|
}
|
|
|
|
|
2021-01-26 17:43:10 +03:00
|
|
|
pub fn (tf_skl TTF_render_Sokol) draw_text_bmp(ctx &gg.Context, x f32, y f32) {
|
|
|
|
// width := tf_skl.bmp.width >> 1
|
|
|
|
// height := tf_skl.bmp.height >> 1
|
2021-01-10 21:14:41 +03:00
|
|
|
sgl.push_matrix()
|
2021-01-26 17:43:10 +03:00
|
|
|
|
|
|
|
width := tf_skl.bmp.width / (tf_skl.scale_reduct)
|
2021-01-10 21:14:41 +03:00
|
|
|
height := tf_skl.bmp.height / (tf_skl.scale_reduct)
|
2021-01-26 17:43:10 +03:00
|
|
|
|
2021-01-10 21:14:41 +03:00
|
|
|
u0 := f32(0.0)
|
|
|
|
v0 := f32(0.0)
|
|
|
|
u1 := f32(1.0)
|
|
|
|
v1 := f32(1.0)
|
|
|
|
x0 := f32(0)
|
|
|
|
y0 := f32(0)
|
|
|
|
x1 := f32(width) * ctx.scale
|
|
|
|
y1 := f32(height) * ctx.scale
|
|
|
|
|
|
|
|
ca := f32(math.cos(tf_skl.bmp.angle))
|
|
|
|
sa := f32(math.sin(tf_skl.bmp.angle))
|
|
|
|
m := [
|
2021-01-26 17:43:10 +03:00
|
|
|
f32(ca),
|
|
|
|
-sa,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
sa,
|
|
|
|
ca,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
1,
|
|
|
|
0,
|
2021-06-28 13:32:17 +03:00
|
|
|
x * ctx.scale,
|
|
|
|
y * ctx.scale,
|
2021-01-26 17:43:10 +03:00
|
|
|
0,
|
|
|
|
1,
|
2021-01-10 21:14:41 +03:00
|
|
|
]
|
|
|
|
sgl.mult_matrix(m)
|
|
|
|
//
|
2022-11-12 10:39:18 +03:00
|
|
|
sgl.load_pipeline(ctx.pipeline.alpha)
|
2021-01-10 21:14:41 +03:00
|
|
|
sgl.enable_texture()
|
|
|
|
sgl.texture(tf_skl.sg_img)
|
|
|
|
sgl.begin_quads()
|
|
|
|
sgl.c4b(255, 255, 255, 255)
|
|
|
|
sgl.v2f_t2f(x0, y0, u0, v0)
|
|
|
|
sgl.v2f_t2f(x1, y0, u1, v0)
|
|
|
|
sgl.v2f_t2f(x1, y1, u1, v1)
|
|
|
|
sgl.v2f_t2f(x0, y1, u0, v1)
|
|
|
|
sgl.end()
|
|
|
|
sgl.disable_texture()
|
|
|
|
sgl.pop_matrix()
|
|
|
|
}
|