freetype: text_size() so that users can retrieve the vertical size of a text too
parent
09e390eac5
commit
8c1b03c731
|
@ -46,10 +46,16 @@ pub const (
|
||||||
)
|
)
|
||||||
|
|
||||||
struct Character {
|
struct Character {
|
||||||
|
code i64
|
||||||
|
|
||||||
texture_id u32
|
texture_id u32
|
||||||
size gg.Vec2
|
size gg.Vec2
|
||||||
bearing gg.Vec2
|
|
||||||
advance u32
|
horizontal_bearing_px gg.Vec2
|
||||||
|
horizontal_advance_px u32
|
||||||
|
|
||||||
|
vertical_bearing_px gg.Vec2
|
||||||
|
vertical_advance_px u32
|
||||||
}
|
}
|
||||||
|
|
||||||
[typedef]
|
[typedef]
|
||||||
|
@ -84,6 +90,19 @@ struct C.Bitmap {
|
||||||
|
|
||||||
struct C.Advance {
|
struct C.Advance {
|
||||||
x int
|
x int
|
||||||
|
y int
|
||||||
|
}
|
||||||
|
|
||||||
|
[typedef]
|
||||||
|
struct C.FT_Glyph_Metrics {
|
||||||
|
width int
|
||||||
|
height int
|
||||||
|
horiBearingX int
|
||||||
|
horiBearingY int
|
||||||
|
horiAdvance int
|
||||||
|
vertBearingX int
|
||||||
|
vertBearingY int
|
||||||
|
vertAdvance int
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.Glyph {
|
struct C.Glyph {
|
||||||
|
@ -91,11 +110,14 @@ struct C.Glyph {
|
||||||
bitmap_left int
|
bitmap_left int
|
||||||
bitmap_top int
|
bitmap_top int
|
||||||
advance Advance
|
advance Advance
|
||||||
|
metrics FT_Glyph_Metrics
|
||||||
}
|
}
|
||||||
|
|
||||||
[typedef]
|
[typedef]
|
||||||
struct C.FT_Face {
|
struct C.FT_Face {
|
||||||
glyph &Glyph
|
glyph &Glyph
|
||||||
|
family_name charptr
|
||||||
|
style_name charptr
|
||||||
}
|
}
|
||||||
|
|
||||||
fn C.FT_Load_Char(voidptr, i64, int) int
|
fn C.FT_Load_Char(voidptr, i64, int) int
|
||||||
|
@ -104,12 +126,12 @@ fn ft_load_char(face C.FT_Face, code i64) Character {
|
||||||
//println('\nftload_char( code=$code)')
|
//println('\nftload_char( code=$code)')
|
||||||
//C.printf('face=%p\n', face)
|
//C.printf('face=%p\n', face)
|
||||||
//C.printf('cobj=%p\n', _face.cobj)
|
//C.printf('cobj=%p\n', _face.cobj)
|
||||||
ret := C.FT_Load_Char(face, code, C.FT_LOAD_RENDER)
|
ret := C.FT_Load_Char(face, code, C.FT_LOAD_RENDER|C.FT_LOAD_FORCE_AUTOHINT)
|
||||||
//println('ret=$ret')
|
//println('ret=$ret')
|
||||||
if ret != 0 {
|
if ret != 0 {
|
||||||
println('freetype: failed to load glyph (utf32 code=$code, ' +
|
println('freetype: failed to load glyph (utf32 code=$code, ' +
|
||||||
'error code=$ret)')
|
'error code=$ret)')
|
||||||
return Character{}
|
return Character{code: code}
|
||||||
}
|
}
|
||||||
// Generate texture
|
// Generate texture
|
||||||
mut texture := 0
|
mut texture := 0
|
||||||
|
@ -124,14 +146,19 @@ fn ft_load_char(face C.FT_Face, code i64) Character {
|
||||||
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_WRAP_T, C.GL_CLAMP_TO_EDGE)
|
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_WRAP_T, C.GL_CLAMP_TO_EDGE)
|
||||||
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MIN_FILTER, C.GL_LINEAR)
|
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MIN_FILTER, C.GL_LINEAR)
|
||||||
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MAG_FILTER, C.GL_LINEAR)
|
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MAG_FILTER, C.GL_LINEAR)
|
||||||
fgleft := face.glyph.bitmap_left
|
|
||||||
fgtop := face.glyph.bitmap_top
|
|
||||||
// Create the character
|
// Create the character
|
||||||
return Character {
|
return Character {
|
||||||
|
code: code
|
||||||
texture_id: u32(texture)
|
texture_id: u32(texture)
|
||||||
size: gg.vec2(int(u32(fgwidth)), int(u32(fgrows)))
|
size: gg.vec2(fgwidth, fgrows)
|
||||||
bearing: gg.vec2(int(u32(fgleft)), int(u32(fgtop)))
|
|
||||||
advance: (u32(face.glyph.advance.x))
|
// Note: advance is number of 1/64 pixels
|
||||||
|
// Bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by 64 to get amount of pixels))
|
||||||
|
horizontal_bearing_px: gg.vec2(face.glyph.metrics.horiBearingX >> 6, face.glyph.metrics.horiBearingY >> 6)
|
||||||
|
vertical_bearing_px: gg.vec2(face.glyph.metrics.vertBearingX >> 6, face.glyph.metrics.vertBearingY >> 6) // not used for now
|
||||||
|
|
||||||
|
horizontal_advance_px: face.glyph.metrics.horiAdvance >> 6
|
||||||
|
vertical_advance_px: face.glyph.metrics.vertAdvance >> 6
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,8 +343,8 @@ fn (ctx mut FreeType) private_draw_text(_x, _y int, utext ustring, cfg gx.TextCf
|
||||||
//exit(1)
|
//exit(1)
|
||||||
// continue
|
// continue
|
||||||
}
|
}
|
||||||
xpos := x + f32(ch.bearing.x) * 1
|
xpos := x + f32(ch.horizontal_bearing_px.x) * 1
|
||||||
ypos := y - f32(ch.size.y - ch.bearing.y) * 1
|
ypos := y - f32(ch.size.y - ch.horizontal_bearing_px.y) * 1
|
||||||
w := f32(ch.size.x) * 1
|
w := f32(ch.size.x) * 1
|
||||||
h := f32(ch.size.y) * 1
|
h := f32(ch.size.y) * 1
|
||||||
// Update VBO for each character
|
// Update VBO for each character
|
||||||
|
@ -337,9 +364,7 @@ fn (ctx mut FreeType) private_draw_text(_x, _y int, utext ustring, cfg gx.TextCf
|
||||||
C.glBufferData(C.GL_ARRAY_BUFFER, 96, vertices.data, C.GL_DYNAMIC_DRAW)
|
C.glBufferData(C.GL_ARRAY_BUFFER, 96, vertices.data, C.GL_DYNAMIC_DRAW)
|
||||||
// Render quad
|
// Render quad
|
||||||
gl.draw_arrays(C.GL_TRIANGLES, 0, 6)
|
gl.draw_arrays(C.GL_TRIANGLES, 0, 6)
|
||||||
// Now advance cursors for next glyph (note that advance is number of 1/64 pixels)
|
x += f32(ch.horizontal_advance_px)
|
||||||
// Bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by 64 to get amount of pixels))
|
|
||||||
x += ch.advance >> u32(6)
|
|
||||||
}
|
}
|
||||||
gl.bind_vao(u32(0))
|
gl.bind_vao(u32(0))
|
||||||
C.glBindTexture(C.GL_TEXTURE_2D, 0)
|
C.glBindTexture(C.GL_TEXTURE_2D, 0)
|
||||||
|
@ -355,12 +380,25 @@ pub fn (ctx mut FreeType) draw_text_def(x, y int, text string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (ctx mut FreeType) text_width(s string) int {
|
pub fn (ctx mut FreeType) text_width(s string) int {
|
||||||
|
x, _ := ctx.text_size(s)
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (ctx mut FreeType) text_height(s string) int {
|
||||||
|
_, y := ctx.text_size(s)
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (ctx mut FreeType) text_size(s string) (int, int) {
|
||||||
//t := time.ticks()
|
//t := time.ticks()
|
||||||
utext := s.ustring()
|
utext := s.ustring()
|
||||||
mut x := f64(0)
|
mut x := u32(0)
|
||||||
|
mut maxy := u32(0)
|
||||||
|
mut _rune := ''
|
||||||
|
mut ch := Character{}
|
||||||
for i := 0; i < utext.len; i++ {
|
for i := 0; i < utext.len; i++ {
|
||||||
_rune := utext.at(i)
|
_rune = utext.at(i)
|
||||||
mut ch := Character{}
|
ch = Character{}
|
||||||
mut found := false
|
mut found := false
|
||||||
if _rune.len == 1 {
|
if _rune.len == 1 {
|
||||||
idx := _rune[0]
|
idx := _rune[0]
|
||||||
|
@ -387,10 +425,25 @@ pub fn (ctx mut FreeType) text_width(s string) int {
|
||||||
ctx.utf_runes << _rune
|
ctx.utf_runes << _rune
|
||||||
ctx.utf_chars << ch
|
ctx.utf_chars << ch
|
||||||
}
|
}
|
||||||
x += ch.advance >> u32(6)
|
x += ch.horizontal_advance_px
|
||||||
|
if maxy < ch.vertical_advance_px {
|
||||||
|
maxy = ch.vertical_advance_px
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//println('text width "$s" = ${time.ticks() - t} ms')
|
//println('text width "$s" = ${time.ticks() - t} ms')
|
||||||
return int(x) / ctx.scale
|
scaled_x := int(f64(x) / ctx.scale)
|
||||||
|
scaled_y := int(f64(maxy) / ctx.scale)
|
||||||
|
//println('text_size of "${s}" | x,y: $x,$maxy | scaled_x: ${scaled_x:3d} | scaled_y: ${scaled_y:3d} ')
|
||||||
|
return scaled_x, scaled_y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (f FT_Face) str() string {
|
||||||
|
return 'FT_Face{ style_name: ${ptr_str(f.style_name)} family_name: ${ptr_str(f.family_name)} }'
|
||||||
|
}
|
||||||
|
pub fn (ac []Character) str() string {
|
||||||
|
mut res := []string
|
||||||
|
for c in ac {
|
||||||
|
res << ' Character{ code: $c.code , texture_id: $c.texture_id }'
|
||||||
|
}
|
||||||
|
return '[\n' + res.join(',\n') + ']'
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,10 @@ pub:
|
||||||
y int
|
y int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (v Vec2) str() string {
|
||||||
|
return 'Vec2{ x: $v.x y: $v.y }'
|
||||||
|
}
|
||||||
|
|
||||||
pub fn vec2(x, y int) Vec2 {
|
pub fn vec2(x, y int) Vec2 {
|
||||||
res := Vec2 {
|
res := Vec2 {
|
||||||
x: x
|
x: x
|
||||||
|
|
|
@ -13,6 +13,9 @@ import glm
|
||||||
pub struct Shader {
|
pub struct Shader {
|
||||||
program_id int
|
program_id int
|
||||||
}
|
}
|
||||||
|
pub fn (s Shader) str() string {
|
||||||
|
return 'Shader{ program_id: s.program_id }'
|
||||||
|
}
|
||||||
|
|
||||||
pub const (
|
pub const (
|
||||||
TEXT_VERT = '#version 330 core
|
TEXT_VERT = '#version 330 core
|
||||||
|
|
Loading…
Reference in New Issue