diff --git a/vlib/freetype/freetype.v b/vlib/freetype/freetype.v index b43a55763b..3c44e66735 100644 --- a/vlib/freetype/freetype.v +++ b/vlib/freetype/freetype.v @@ -46,10 +46,16 @@ pub const ( ) struct Character { + code i64 + texture_id u32 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] @@ -84,6 +90,19 @@ struct C.Bitmap { struct C.Advance { 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 { @@ -91,11 +110,14 @@ struct C.Glyph { bitmap_left int bitmap_top int advance Advance + metrics FT_Glyph_Metrics } [typedef] struct C.FT_Face { glyph &Glyph + family_name charptr + style_name charptr } 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)') //C.printf('face=%p\n', face) //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') if ret != 0 { println('freetype: failed to load glyph (utf32 code=$code, ' + 'error code=$ret)') - return Character{} + return Character{code: code} } // Generate texture 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_MIN_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 return Character { + code: code texture_id: u32(texture) - size: gg.vec2(int(u32(fgwidth)), int(u32(fgrows))) - bearing: gg.vec2(int(u32(fgleft)), int(u32(fgtop))) - advance: (u32(face.glyph.advance.x)) + size: gg.vec2(fgwidth, fgrows) + + // 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) // continue } - xpos := x + f32(ch.bearing.x) * 1 - ypos := y - f32(ch.size.y - ch.bearing.y) * 1 + xpos := x + f32(ch.horizontal_bearing_px.x) * 1 + ypos := y - f32(ch.size.y - ch.horizontal_bearing_px.y) * 1 w := f32(ch.size.x) * 1 h := f32(ch.size.y) * 1 // 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) // Render quad gl.draw_arrays(C.GL_TRIANGLES, 0, 6) - // Now advance cursors for next glyph (note that 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)) - x += ch.advance >> u32(6) + x += f32(ch.horizontal_advance_px) } gl.bind_vao(u32(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 { + 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() 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++ { - _rune := utext.at(i) - mut ch := Character{} + _rune = utext.at(i) + ch = Character{} mut found := false if _rune.len == 1 { idx := _rune[0] @@ -387,10 +425,25 @@ pub fn (ctx mut FreeType) text_width(s string) int { ctx.utf_runes << _rune 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') - 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') + ']' +} diff --git a/vlib/gg/gg.v b/vlib/gg/gg.v index 2cfa940a2e..32977b78df 100644 --- a/vlib/gg/gg.v +++ b/vlib/gg/gg.v @@ -17,6 +17,10 @@ pub: y int } +pub fn (v Vec2) str() string { + return 'Vec2{ x: $v.x y: $v.y }' +} + pub fn vec2(x, y int) Vec2 { res := Vec2 { x: x diff --git a/vlib/gl/1shader.v b/vlib/gl/1shader.v index 5c6599f0cd..de02130562 100644 --- a/vlib/gl/1shader.v +++ b/vlib/gl/1shader.v @@ -13,6 +13,9 @@ import glm pub struct Shader { program_id int } +pub fn (s Shader) str() string { + return 'Shader{ program_id: s.program_id }' +} pub const ( TEXT_VERT = '#version 330 core