1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

x.ttf: fix a bug in TTF fixed point data management (#14987)

This commit is contained in:
penguindark 2022-07-08 08:20:59 +02:00 committed by GitHub
parent 5aa6ec0693
commit df4bd88d45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -90,6 +90,8 @@ pub mut:
kern []Kern0Table kern []Kern0Table
// cache // cache
glyph_cache map[int]Glyph glyph_cache map[int]Glyph
// font widths array scale for PDF export
width_scale f32 = 1.0
} }
pub fn (mut tf TTF_File) init() { pub fn (mut tf TTF_File) init() {
@ -103,6 +105,8 @@ pub fn (mut tf TTF_File) init() {
tf.length = tf.glyph_count() tf.length = tf.glyph_count()
dprintln('Number of symbols: $tf.length') dprintln('Number of symbols: $tf.length')
dprintln('*****************************') dprintln('*****************************')
dprintln('Unit per em: $tf.units_per_em')
dprintln('advance_width_max: $tf.advance_width_max')
} }
/****************************************************************************** /******************************************************************************
@ -159,7 +163,7 @@ pub fn (mut tf TTF_File) get_horizontal_metrics(glyph_index u16) (int, int) {
tf.pos = offset tf.pos = offset
advance_width = tf.get_u16() advance_width = tf.get_u16()
left_side_bearing = tf.get_i16() left_side_bearing = tf.get_i16()
// dprintln("Found h_metric aw: $advance_width lsb: $left_side_bearing") // dprintln("${glyph_index} aw:${advance_width} lsb:${left_side_bearing}")
} else { } else {
// read the last entry of the hMetrics array // read the last entry of the hMetrics array
tf.pos = offset + (tf.num_of_long_hor_metrics - 1) * 4 tf.pos = offset + (tf.num_of_long_hor_metrics - 1) * 4
@ -200,7 +204,7 @@ fn (mut tf TTF_File) get_glyph_offset(index u32) u32 {
return offset + tf.tables['glyf'].offset return offset + tf.tables['glyf'].offset
} }
fn (mut tf TTF_File) glyph_count() u16 { pub fn (mut tf TTF_File) glyph_count() u16 {
assert 'maxp' in tf.tables assert 'maxp' in tf.tables
old_pos := tf.pos old_pos := tf.pos
tf.pos = tf.tables['maxp'].offset + 4 tf.pos = tf.tables['maxp'].offset + 4
@ -233,6 +237,58 @@ pub fn (mut tf TTF_File) read_glyph_dim(index u16) (int, int, int, int) {
return x_min, x_max, y_min, y_max return x_min, x_max, y_min, y_max
} }
pub fn (mut tf TTF_File) get_ttf_widths() ([]int, int, int) {
mut space_cw, _ := tf.get_horizontal_metrics(u16(` `))
// div_space_cw := int((f32(space_cw) * 0.3))
// count := int(tf.glyph_count())
mut min_code := 0xFFFF + 1
mut max_code := 0
for i in 0 .. 300 {
glyph_index := tf.map_code(i)
if glyph_index == 0 {
continue
}
// dprintln("$i = glyph_index: $glyph_index ${i:c}")
if i > max_code {
max_code = i
}
if i < min_code {
min_code = i
}
}
// dprintln("min_code: $min_code max_code: $max_code")
mut widths := []int{len: max_code - min_code + 1, init: 0}
for i in min_code .. max_code {
pos := i - min_code
glyph_index := tf.map_code(i)
if glyph_index == 0 || i == 32 {
widths[pos] = space_cw
continue
}
x_min, x_max, _, _ := tf.read_glyph_dim(glyph_index)
aw, lsb := tf.get_horizontal_metrics(u16(glyph_index))
w := x_max - x_min
rsb := aw - (lsb + w)
// pp1 := x_min - lsb
// pp2 := pp1 + aw
w1 := w + lsb + rsb
widths[pos] = int(w1 / tf.width_scale)
// if i >= int(`A`) && i <= int(`Z`) {
// dprintln("${i:c}|$glyph_index [$pos] => width:${x_max-x_min} aw:${aw}|w1:${w1} lsb:${lsb} rsb:${rsb} pp1:${pp1} pp2:${pp2}")
//}
}
// dprintln("Widths: ${widths.len}")
return widths, min_code, max_code
}
pub fn (mut tf TTF_File) read_glyph(index u16) Glyph { pub fn (mut tf TTF_File) read_glyph(index u16) Glyph {
index_int := int(index) // index.str() index_int := int(index) // index.str()
if index_int in tf.glyph_cache { if index_int in tf.glyph_cache {
@ -511,7 +567,12 @@ fn (mut tf TTF_File) get_ufword() u16 {
} }
fn (mut tf TTF_File) get_i16() i16 { fn (mut tf TTF_File) get_i16() i16 {
return i16(tf.get_u16()) // return i16(tf.get_u16())
mut res := u32(tf.get_u16())
if (res & 0x8000) > 0 {
res -= (u32(1) << 16)
}
return i16(res)
} }
fn (mut tf TTF_File) get_fword() i16 { fn (mut tf TTF_File) get_fword() i16 {
@ -526,7 +587,11 @@ fn (mut tf TTF_File) get_u32() u32 {
} }
fn (mut tf TTF_File) get_i32() int { fn (mut tf TTF_File) get_i32() int {
return int(tf.get_u32()) mut res := u64(tf.get_u32())
if (res & 0x8000_0000) > 0 {
res -= (u64(1) << 32)
}
return int(res)
} }
fn (mut tf TTF_File) get_2dot14() f32 { fn (mut tf TTF_File) get_2dot14() f32 {