freetype: render all Unicode characters

pull/1755/head
Alexander Medvednikov 2019-08-26 22:40:07 +03:00
parent 99c9410cc2
commit d4b6b6c833
2 changed files with 25 additions and 22 deletions

View File

@ -99,7 +99,7 @@ typedef map map_string;
#define _PUSH_MANY(arr, val, tmp, tmp_typ) {tmp_typ tmp = (val); array__push_many(arr, tmp.data, tmp.len);} #define _PUSH_MANY(arr, val, tmp, tmp_typ) {tmp_typ tmp = (val); array__push_many(arr, tmp.data, tmp.len);}
#define _IN(typ, val, arr) array_##typ##_contains(arr, val) #define _IN(typ, val, arr) array_##typ##_contains(arr, val)
#define _IN_MAP(val, m) map__exists(m, val) #define _IN_MAP(val, m) map__exists(m, val)
#define ALLOC_INIT(type, ...) (type *)memdup((type[]){ __VA_ARGS__ }, sizeof(type)) //#define ALLOC_INIT(type, ...) (type *)memdup((type[]){ __VA_ARGS__ }, sizeof(type))
//================================== GLOBALS =================================*/ //================================== GLOBALS =================================*/
//int V_ZERO = 0; //int V_ZERO = 0;

View File

@ -46,10 +46,6 @@ struct Character {
advance u32 advance u32
} }
struct Face {
cobj voidptr
}
[typedef] [typedef]
struct C.FT_Library { struct C.FT_Library {
@ -69,7 +65,7 @@ struct Context {
chars []Character chars []Character
utf_runes []string utf_runes []string
utf_chars []Character utf_chars []Character
face Face face C.FT_Face
scale int // retina = 2 , normal = 1 scale int // retina = 2 , normal = 1
} }
@ -95,11 +91,14 @@ struct C.FT_Face {
glyph *Glyph glyph *Glyph
} }
fn ft_load_char(_face Face, code i64) Character { fn C.FT_Load_Char(voidptr, i64, int) int
//println('ftload_char( code=$code)')
//C.printf('face=%p\n', _face) fn ft_load_char(face C.FT_Face, code i64) Character {
face := FT_Face(_face.cobj) //println('\nftload_char( code=$code)')
ret := int(C.FT_Load_Char(face, code, C.FT_LOAD_RENDER)) //C.printf('face=%p\n', face)
//C.printf('cobj=%p\n', _face.cobj)
ret := C.FT_Load_Char(face, code, C.FT_LOAD_RENDER)
//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)')
@ -191,11 +190,8 @@ pub fn new_context(cfg gg.Cfg) *Context {
// Gen texture // Gen texture
// Load first 128 characters of ASCII set // Load first 128 characters of ASCII set
mut chars := []Character{} mut chars := []Character{}
f := Face {
cobj: &face
}
for c := 0; c < 128; c++ { for c := 0; c < 128; c++ {
mut ch := ft_load_char(f, i64(c)) mut ch := ft_load_char(face, i64(c))
// s := utf32_to_str(uint(0x043f)) // s := utf32_to_str(uint(0x043f))
// s := 'п' // s := 'п'
// ch = ft_load_char(f, s.utf32_code()) // ch = ft_load_char(f, s.utf32_code())
@ -227,14 +223,15 @@ pub fn new_context(cfg gg.Cfg) *Context {
vao: vao vao: vao
vbo: vbo vbo: vbo
chars: chars chars: chars
face: f face: face
} }
ctx.init_utf8_runes() //ctx.init_utf8_runes()
return ctx return ctx
} }
/*
// A dirty hack to implement rendering of cyrillic letters. // A dirty hack to implement rendering of cyrillic letters.
// All UTF-8 must be supported. // All UTF-8 must be supported. update: no longer needed
fn (ctx mut Context) init_utf8_runes() { fn (ctx mut Context) init_utf8_runes() {
s := 'йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ' s := 'йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ'
print('init utf8 runes: ') print('init utf8 runes: ')
@ -248,6 +245,7 @@ fn (ctx mut Context) init_utf8_runes() {
ctx.utf_chars << ch ctx.utf_chars << ch
} }
} }
*/
pub fn (ctx mut Context) draw_text(_x, _y int, text string, cfg gx.TextCfg) { pub fn (ctx mut Context) draw_text(_x, _y int, text string, cfg gx.TextCfg) {
//utext := text.ustring_tmp() //utext := text.ustring_tmp()
@ -295,12 +293,14 @@ fn (ctx mut Context) _draw_text(_x, _y int, utext ustring, cfg gx.TextCfg) {
_rune := utext.at(i) _rune := utext.at(i)
// println('$i => $_rune') // println('$i => $_rune')
mut ch := Character{} mut ch := Character{}
mut found := false
if _rune.len == 1 { if _rune.len == 1 {
idx := _rune[0] idx := _rune[0]
if idx < 0 || idx >= ctx.chars.len { if idx < 0 || idx >= ctx.chars.len {
println('BADE RUNE $_rune') println('BADE RUNE $_rune')
continue continue
} }
found = true
ch = ctx.chars[_rune[0]] ch = ctx.chars[_rune[0]]
} }
else if _rune.len > 1 { else if _rune.len > 1 {
@ -309,18 +309,21 @@ fn (ctx mut Context) _draw_text(_x, _y int, utext ustring, cfg gx.TextCfg) {
rune_j := ctx.utf_runes[j] rune_j := ctx.utf_runes[j]
if rune_j==_rune { if rune_j==_rune {
ch = ctx.utf_chars[j] ch = ctx.utf_chars[j]
found = true
break break
} }
} }
} }
if ch.size.x == 0 && _rune.len > 1{ // A new Unicode character. Load it and cache it.
if !found && _rune.len > 0 && _rune[0] > 32 {
c := _rune[0] c := _rune[0]
println('cant draw rune "$_rune" code=$c, loading') //println('cant draw rune "$_rune" code=$c, loading')
continue //continue
ch = ft_load_char(ctx.face, _rune.utf32_code()) ch = ft_load_char(ctx.face, _rune.utf32_code())
println('done loading') //println('done loading')
ctx.utf_runes << _rune ctx.utf_runes << _rune
ctx.utf_chars << ch ctx.utf_chars << ch
//exit(1)
// continue // continue
} }
xpos := x + f32(ch.bearing.x) * 1 xpos := x + f32(ch.bearing.x) * 1