ttf: improvement on not found glyphs (#8050)
parent
5f95dd54bd
commit
55e3e50b9b
|
@ -111,23 +111,23 @@ fn fabs(a f32) f32 {
|
||||||
// integer part of x
|
// integer part of x
|
||||||
[inline]
|
[inline]
|
||||||
fn ipart(x f32) f32 {
|
fn ipart(x f32) f32 {
|
||||||
return f32(math.floor(x))
|
return f32(math.floor(x))
|
||||||
}
|
}
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
fn round(x f32) f32 {
|
fn round(x f32) f32 {
|
||||||
return ipart(x + 0.5)
|
return ipart(x + 0.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fractional part of x
|
// fractional part of x
|
||||||
[inline]
|
[inline]
|
||||||
fn fpart(x f32) f32 {
|
fn fpart(x f32) f32 {
|
||||||
return x - f32(math.floor(x))
|
return x - f32(math.floor(x))
|
||||||
}
|
}
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
fn rfpart(x f32) f32 {
|
fn rfpart(x f32) f32 {
|
||||||
return 1 - fpart(x)
|
return 1 - fpart(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|
|
@ -515,6 +515,13 @@ fn (mut bmp BitMap) get_chars_bbox(in_string string) []int {
|
||||||
}
|
}
|
||||||
|
|
||||||
c_index := bmp.tf.map_code(int(char))
|
c_index := bmp.tf.map_code(int(char))
|
||||||
|
// Glyph not found
|
||||||
|
if c_index == 0 {
|
||||||
|
w += int(space_cw * bmp.space_cw)
|
||||||
|
i += c_len
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
ax , ay := bmp.tf.next_kern(c_index)
|
ax , ay := bmp.tf.next_kern(c_index)
|
||||||
//dprintln("char_index: $c_index ax: $ax ay: $ay")
|
//dprintln("char_index: $c_index ax: $ax ay: $ay")
|
||||||
|
|
||||||
|
@ -548,7 +555,7 @@ fn (mut bmp BitMap) get_chars_bbox(in_string string) []int {
|
||||||
|
|
||||||
i+= c_len
|
i+= c_len
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub
|
pub
|
||||||
|
@ -581,6 +588,12 @@ fn (mut bmp BitMap) get_bbox(in_string string) (int, int){
|
||||||
}
|
}
|
||||||
|
|
||||||
c_index := bmp.tf.map_code(int(char))
|
c_index := bmp.tf.map_code(int(char))
|
||||||
|
// Glyph not found
|
||||||
|
if c_index == 0 {
|
||||||
|
w += int(space_cw * bmp.space_cw)
|
||||||
|
i += c_len
|
||||||
|
continue
|
||||||
|
}
|
||||||
ax , ay := bmp.tf.next_kern(c_index)
|
ax , ay := bmp.tf.next_kern(c_index)
|
||||||
//dprintln("char_index: $c_index ax: $ax ay: $ay")
|
//dprintln("char_index: $c_index ax: $ax ay: $ay")
|
||||||
|
|
||||||
|
@ -612,7 +625,7 @@ fn (mut bmp BitMap) get_bbox(in_string string) (int, int){
|
||||||
|
|
||||||
i+= c_len
|
i+= c_len
|
||||||
}
|
}
|
||||||
|
|
||||||
//dprintln("y_min: $bmp.tf.y_min y_max: $bmp.tf.y_max res: ${int((bmp.tf.y_max - bmp.tf.y_min)*buf.scale)} width: ${int( (cw) * buf.scale)}")
|
//dprintln("y_min: $bmp.tf.y_min y_max: $bmp.tf.y_max res: ${int((bmp.tf.y_max - bmp.tf.y_min)*buf.scale)} width: ${int( (cw) * buf.scale)}")
|
||||||
//buf.box(0,y_base - int((bmp.tf.y_min)*buf.scale), int( (x_max) * buf.scale), y_base-int((bmp.tf.y_max)*buf.scale), u32(0xFF00_0000) )
|
//buf.box(0,y_base - int((bmp.tf.y_min)*buf.scale), int( (x_max) * buf.scale), y_base-int((bmp.tf.y_max)*buf.scale), u32(0xFF00_0000) )
|
||||||
return w , int(abs(int(bmp.tf.y_max - bmp.tf.y_min)) * bmp.scale)
|
return w , int(abs(int(bmp.tf.y_max - bmp.tf.y_min)) * bmp.scale)
|
||||||
|
@ -623,6 +636,25 @@ fn (mut bmp BitMap) get_bbox(in_string string) (int, int){
|
||||||
* TTF draw glyph
|
* TTF draw glyph
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
fn (mut bmp BitMap) draw_notdef_glyph(in_x int, in_w int) {
|
||||||
|
mut p := Point{in_x, 0, false}
|
||||||
|
x1 , y1 := bmp.trf_txt(p)
|
||||||
|
// init ch_matrix
|
||||||
|
bmp.ch_matrix[0] = bmp.tr_matrix[0] * bmp.scale * bmp.scale_x
|
||||||
|
bmp.ch_matrix[1] = bmp.tr_matrix[1] * bmp.scale * bmp.scale_x
|
||||||
|
bmp.ch_matrix[3] = bmp.tr_matrix[3] * -bmp.scale * bmp.scale_y
|
||||||
|
bmp.ch_matrix[4] = bmp.tr_matrix[4] * -bmp.scale * bmp.scale_y
|
||||||
|
bmp.ch_matrix[6] = int(x1)
|
||||||
|
bmp.ch_matrix[7] = int(y1)
|
||||||
|
x,y := bmp.trf_ch(p)
|
||||||
|
|
||||||
|
y_h := fabs(bmp.tf.y_max-bmp.tf.y_min)* bmp.scale * 0.5
|
||||||
|
|
||||||
|
bmp.box(int(x), int(y), int(x - in_w), int(y - y_h), bmp.color)
|
||||||
|
bmp.line(int(x), int(y), int(x - in_w ), int(y - y_h), bmp.color)
|
||||||
|
bmp.line(int(x - in_w ), int(y), int(x), int(y - y_h), bmp.color)
|
||||||
|
}
|
||||||
|
|
||||||
pub
|
pub
|
||||||
fn (mut bmp BitMap) draw_text(in_string string) (int, int){
|
fn (mut bmp BitMap) draw_text(in_string string) (int, int){
|
||||||
mut w := 0
|
mut w := 0
|
||||||
|
@ -652,45 +684,52 @@ fn (mut bmp BitMap) draw_text(in_string string) (int, int){
|
||||||
char = u16(tmp_char)
|
char = u16(tmp_char)
|
||||||
}
|
}
|
||||||
|
|
||||||
c_index := bmp.tf.map_code(int(char))
|
c_index := bmp.tf.map_code(int(char))
|
||||||
ax , ay := bmp.tf.next_kern(c_index)
|
// Glyph not found
|
||||||
//dprintln("char_index: $c_index ax: $ax ay: $ay")
|
if c_index == 0 {
|
||||||
|
bmp.draw_notdef_glyph(w, int(space_cw * bmp.space_cw))
|
||||||
|
w += int(space_cw * bmp.space_cw)
|
||||||
|
i += c_len
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
cw, _ := bmp.tf.get_horizontal_metrics(u16(char))
|
ax , ay := bmp.tf.next_kern(c_index)
|
||||||
//cw, lsb := bmp.tf.get_horizontal_metrics(u16(char))
|
//dprintln("char_index: $c_index ax: $ax ay: $ay")
|
||||||
//dprintln("metrics: [${u16(char):c}] cw:$cw lsb:$lsb")
|
|
||||||
|
|
||||||
//----- Draw_Glyph transformations -----
|
|
||||||
mut x0 := w + int(ax * bmp.scale)
|
|
||||||
mut y0 := 0 + int(ay * bmp.scale)
|
|
||||||
|
|
||||||
p := Point{x0,y0,false}
|
|
||||||
x1 , y1 := bmp.trf_txt(p)
|
|
||||||
// init ch_matrix
|
|
||||||
bmp.ch_matrix[0] = bmp.tr_matrix[0] * bmp.scale * bmp.scale_x
|
|
||||||
bmp.ch_matrix[1] = bmp.tr_matrix[1] * bmp.scale * bmp.scale_x
|
|
||||||
bmp.ch_matrix[3] = bmp.tr_matrix[3] * -bmp.scale * bmp.scale_y
|
|
||||||
bmp.ch_matrix[4] = bmp.tr_matrix[4] * -bmp.scale * bmp.scale_y
|
|
||||||
bmp.ch_matrix[6] = int(x1)
|
|
||||||
bmp.ch_matrix[7] = int(y1)
|
|
||||||
|
|
||||||
x_min, x_max := bmp.draw_glyph(c_index)
|
cw, _ := bmp.tf.get_horizontal_metrics(u16(char))
|
||||||
// x_min := 1
|
//cw, lsb := bmp.tf.get_horizontal_metrics(u16(char))
|
||||||
// x_max := 2
|
//dprintln("metrics: [${u16(char):c}] cw:$cw lsb:$lsb")
|
||||||
//-----------------
|
|
||||||
|
|
||||||
mut width := int( (abs(x_max + x_min) + ax) * bmp.scale)
|
//----- Draw_Glyph transformations -----
|
||||||
if bmp.use_font_metrics {
|
mut x0 := w + int(ax * bmp.scale)
|
||||||
width = int((cw+ax) * bmp.scale)
|
mut y0 := 0 + int(ay * bmp.scale)
|
||||||
}
|
|
||||||
w += width + div_space_cw
|
|
||||||
|
|
||||||
i+= c_len
|
p := Point{x0,y0,false}
|
||||||
}
|
x1 , y1 := bmp.trf_txt(p)
|
||||||
|
// init ch_matrix
|
||||||
//dprintln("y_min: $bmp.tf.y_min y_max: $bmp.tf.y_max res: ${int((bmp.tf.y_max - bmp.tf.y_min)*buf.scale)} width: ${int( (cw) * buf.scale)}")
|
bmp.ch_matrix[0] = bmp.tr_matrix[0] * bmp.scale * bmp.scale_x
|
||||||
//buf.box(0,y_base - int((bmp.tf.y_min)*buf.scale), int( (x_max) * buf.scale), y_base-int((bmp.tf.y_max)*buf.scale), u32(0xFF00_0000) )
|
bmp.ch_matrix[1] = bmp.tr_matrix[1] * bmp.scale * bmp.scale_x
|
||||||
return w , int(abs(int(bmp.tf.y_max - bmp.tf.y_min)) * bmp.scale)
|
bmp.ch_matrix[3] = bmp.tr_matrix[3] * -bmp.scale * bmp.scale_y
|
||||||
|
bmp.ch_matrix[4] = bmp.tr_matrix[4] * -bmp.scale * bmp.scale_y
|
||||||
|
bmp.ch_matrix[6] = int(x1)
|
||||||
|
bmp.ch_matrix[7] = int(y1)
|
||||||
|
|
||||||
|
x_min, x_max := bmp.draw_glyph(c_index)
|
||||||
|
// x_min := 1
|
||||||
|
// x_max := 2
|
||||||
|
//-----------------
|
||||||
|
|
||||||
|
mut width := int( (abs(x_max + x_min) + ax) * bmp.scale)
|
||||||
|
if bmp.use_font_metrics {
|
||||||
|
width = int((cw+ax) * bmp.scale)
|
||||||
|
}
|
||||||
|
w += width + div_space_cw
|
||||||
|
i+= c_len
|
||||||
|
}
|
||||||
|
|
||||||
|
//dprintln("y_min: $bmp.tf.y_min y_max: $bmp.tf.y_max res: ${int((bmp.tf.y_max - bmp.tf.y_min)*buf.scale)} width: ${int( (cw) * buf.scale)}")
|
||||||
|
//buf.box(0,y_base - int((bmp.tf.y_min)*buf.scale), int( (x_max) * buf.scale), y_base-int((bmp.tf.y_max)*buf.scale), u32(0xFF00_0000) )
|
||||||
|
return w , int(abs(int(bmp.tf.y_max - bmp.tf.y_min)) * bmp.scale)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub
|
pub
|
||||||
|
@ -759,13 +798,13 @@ fn (mut bmp BitMap) draw_glyph(index u16) (int, int){
|
||||||
} else {
|
} else {
|
||||||
//dprintln("HERE2")
|
//dprintln("HERE2")
|
||||||
// ctx.quadraticCurveTo(prev.x + x, prev.y + y,
|
// ctx.quadraticCurveTo(prev.x + x, prev.y + y,
|
||||||
// (prev.x + point.x) / 2 + x,
|
// (prev.x + point.x) / 2 + x,
|
||||||
// (prev.y + point.y) / 2 + y);
|
// (prev.y + point.y) / 2 + y);
|
||||||
|
|
||||||
//bmp.line(x0, y0, (prev.x + point.x)/2, (prev.y + point.y)/2, color2)
|
//bmp.line(x0, y0, (prev.x + point.x)/2, (prev.y + point.y)/2, color2)
|
||||||
//bmp.quadratic(x0, y0, (prev.x + point.x)/2, (prev.y + point.y)/2, prev.x, prev.y, color2)
|
//bmp.quadratic(x0, y0, (prev.x + point.x)/2, (prev.y + point.y)/2, prev.x, prev.y, color2)
|
||||||
bmp.quadratic(x0, y0, (prev.x + point.x)/2, (prev.y + point.y)/2, prev.x, prev.y, color)
|
bmp.quadratic(x0, y0, (prev.x + point.x)/2, (prev.y + point.y)/2, prev.x, prev.y, color)
|
||||||
x0 = (prev.x + point.x)/2
|
x0 = (prev.x + point.x)/2
|
||||||
y0 = (prev.y + point.y)/2
|
y0 = (prev.y + point.y)/2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -774,29 +813,29 @@ fn (mut bmp BitMap) draw_glyph(index u16) (int, int){
|
||||||
//dprintln("count == glyph.contour_ends[count]")
|
//dprintln("count == glyph.contour_ends[count]")
|
||||||
if s == 2 { // final point was off-curve. connect to start
|
if s == 2 { // final point was off-curve. connect to start
|
||||||
|
|
||||||
mut start_point := glyph.points[contour_start]
|
mut start_point := glyph.points[contour_start]
|
||||||
start_point.x, start_point.y = bmp.trf_ch(start_point)
|
start_point.x, start_point.y = bmp.trf_ch(start_point)
|
||||||
if point.on_curve {
|
if point.on_curve {
|
||||||
//ctx.quadraticCurveTo(prev.x + x, prev.y + y,
|
//ctx.quadraticCurveTo(prev.x + x, prev.y + y,
|
||||||
// point.x + x, point.y + y);
|
//point.x + x, point.y + y);
|
||||||
//bmp.line(x0, y0, start_point.x + in_x, start_point.y + in_y, u32(0x00FF0000))
|
//bmp.line(x0, y0, start_point.x + in_x, start_point.y + in_y, u32(0x00FF0000))
|
||||||
|
|
||||||
bmp.quadratic(x0, y0, start_point.x, start_point.y ,
|
bmp.quadratic(x0, y0, start_point.x, start_point.y ,
|
||||||
// start_point.x + in_x, start_point.y + in_y, u32(0xFF00FF00))
|
// start_point.x + in_x, start_point.y + in_y, u32(0xFF00FF00))
|
||||||
start_point.x, start_point.y, color)
|
start_point.x, start_point.y, color)
|
||||||
} else {
|
} else {
|
||||||
//ctx.quadraticCurveTo(prev.x + x, prev.y + y,
|
//ctx.quadraticCurveTo(prev.x + x, prev.y + y,
|
||||||
// (prev.x + point.x) / 2 + x,
|
// (prev.x + point.x) / 2 + x,
|
||||||
// (prev.y + point.y) / 2 + y);
|
// (prev.y + point.y) / 2 + y);
|
||||||
|
|
||||||
//bmp.line(x0, y0, start_point.x, start_point.y, u32(0x00FF0000)
|
//bmp.line(x0, y0, start_point.x, start_point.y, u32(0x00FF0000)
|
||||||
bmp.quadratic(x0, y0, start_point.x, start_point.y,
|
bmp.quadratic(x0, y0, start_point.x, start_point.y,
|
||||||
(point.x + start_point.x)/2,
|
(point.x + start_point.x)/2,
|
||||||
(point.y + start_point.y)/2,
|
(point.y + start_point.y)/2,
|
||||||
//u32(0xFF000000))
|
//u32(0xFF000000))
|
||||||
color)
|
color)
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
// last point not in a curve
|
// last point not in a curve
|
||||||
//bmp.line(point.x, point.y, sp_x, sp_y, u32(0x00FF0000))
|
//bmp.line(point.x, point.y, sp_x, sp_y, u32(0x00FF0000))
|
||||||
bmp.line(point.x, point.y, sp_x, sp_y, color)
|
bmp.line(point.x, point.y, sp_x, sp_y, color)
|
||||||
|
|
|
@ -156,7 +156,7 @@ fn (mut tf_skl TTF_render_Sokol) create_texture(){
|
||||||
height: h
|
height: h
|
||||||
num_mipmaps: 0
|
num_mipmaps: 0
|
||||||
min_filter: .linear
|
min_filter: .linear
|
||||||
mag_filter: .linear
|
mag_filter: .linear
|
||||||
//usage: .dynamic
|
//usage: .dynamic
|
||||||
wrap_u: .clamp_to_edge
|
wrap_u: .clamp_to_edge
|
||||||
wrap_v: .clamp_to_edge
|
wrap_v: .clamp_to_edge
|
||||||
|
|
259
vlib/x/ttf/ttf.v
259
vlib/x/ttf/ttf.v
|
@ -24,10 +24,10 @@ import strings
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
struct Segment {
|
struct Segment {
|
||||||
mut:
|
mut:
|
||||||
id_range_offset u32
|
id_range_offset u32
|
||||||
start_code u16
|
start_code u16
|
||||||
end_code u16
|
end_code u16
|
||||||
id_delta u16
|
id_delta u16
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TrueTypeCmap {
|
struct TrueTypeCmap {
|
||||||
|
@ -220,8 +220,8 @@ fn (mut tf TTF_File) glyph_count() u16{
|
||||||
old_pos := tf.pos
|
old_pos := tf.pos
|
||||||
tf.pos = tf.tables["maxp"].offset + 4
|
tf.pos = tf.tables["maxp"].offset + 4
|
||||||
count := tf.get_u16()
|
count := tf.get_u16()
|
||||||
tf.pos = old_pos
|
tf.pos = old_pos
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
pub
|
pub
|
||||||
|
@ -474,22 +474,21 @@ fn (mut tf TTF_File) read_compound_glyph(mut in_glyph Glyph){
|
||||||
simple_glyph := tf.read_glyph(component.glyph_index)
|
simple_glyph := tf.read_glyph(component.glyph_index)
|
||||||
if simple_glyph.valid_glyph {
|
if simple_glyph.valid_glyph {
|
||||||
point_offset := in_glyph.points.len
|
point_offset := in_glyph.points.len
|
||||||
for i in 0..simple_glyph.contour_ends.len {
|
for i in 0..simple_glyph.contour_ends.len {
|
||||||
in_glyph.contour_ends << u16(simple_glyph.contour_ends[i] + point_offset)
|
in_glyph.contour_ends << u16(simple_glyph.contour_ends[i] + point_offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
for p in simple_glyph.points {
|
for p in simple_glyph.points {
|
||||||
mut x := f32(p.x)
|
mut x := f32(p.x)
|
||||||
mut y := f32(p.y)
|
mut y := f32(p.y)
|
||||||
x = component.matrix[0] * x + component.matrix[1] * y + component.matrix[4]
|
x = component.matrix[0] * x + component.matrix[1] * y + component.matrix[4]
|
||||||
y = component.matrix[2] * x + component.matrix[3] * y + component.matrix[5]
|
y = component.matrix[2] * x + component.matrix[3] * y + component.matrix[5]
|
||||||
in_glyph.points << Point{
|
in_glyph.points << Point{
|
||||||
x: int(x)
|
x: int(x)
|
||||||
y: int(y)
|
y: int(y)
|
||||||
on_curve: p.on_curve
|
on_curve: p.on_curve
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
tf.pos = old_pos
|
tf.pos = old_pos
|
||||||
}
|
}
|
||||||
|
@ -501,7 +500,7 @@ fn (mut tf TTF_File) read_compound_glyph(mut in_glyph Glyph){
|
||||||
}
|
}
|
||||||
|
|
||||||
// ok we have a valid glyph
|
// ok we have a valid glyph
|
||||||
in_glyph.valid_glyph = true
|
in_glyph.valid_glyph = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -695,9 +694,9 @@ fn (mut tf TTF_File) read_head_table() {
|
||||||
tf.y_max = tf.get_i16()
|
tf.y_max = tf.get_i16()
|
||||||
tf.mac_style = tf.get_u16()
|
tf.mac_style = tf.get_u16()
|
||||||
tf.lowest_rec_ppem = tf.get_u16()
|
tf.lowest_rec_ppem = tf.get_u16()
|
||||||
tf.font_direction_hint = tf.get_i16()
|
tf.font_direction_hint = tf.get_i16()
|
||||||
tf.index_to_loc_format = tf.get_i16()
|
tf.index_to_loc_format = tf.get_i16()
|
||||||
tf.glyph_data_format = tf.get_i16()
|
tf.glyph_data_format = tf.get_i16()
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -721,36 +720,36 @@ fn (mut tf TTF_File) read_name_table() {
|
||||||
/*platform_specific_id :=*/ tf.get_u16()
|
/*platform_specific_id :=*/ tf.get_u16()
|
||||||
/*language_id :=*/ tf.get_u16()
|
/*language_id :=*/ tf.get_u16()
|
||||||
name_id := tf.get_u16()
|
name_id := tf.get_u16()
|
||||||
length := tf.get_u16()
|
length := tf.get_u16()
|
||||||
offset := tf.get_u16()
|
offset := tf.get_u16()
|
||||||
|
|
||||||
old_pos := tf.pos
|
old_pos := tf.pos
|
||||||
tf.pos = table_offset + string_offset + offset
|
tf.pos = table_offset + string_offset + offset
|
||||||
|
|
||||||
mut name := ""
|
mut name := ""
|
||||||
if platform_id == 0 || platform_id == 3 {
|
if platform_id == 0 || platform_id == 3 {
|
||||||
name = tf.get_unicode_string(length)
|
name = tf.get_unicode_string(length)
|
||||||
} else {
|
} else {
|
||||||
name = tf.get_string(length)
|
name = tf.get_string(length)
|
||||||
}
|
}
|
||||||
//dprintln("Name [${platform_id} / ${platform_specific_id}] id:[$name_id] language:[$language_id] [$name]")
|
//dprintln("Name [${platform_id} / ${platform_specific_id}] id:[$name_id] language:[$language_id] [$name]")
|
||||||
tf.pos = old_pos
|
tf.pos = old_pos
|
||||||
|
|
||||||
match name_id {
|
match name_id {
|
||||||
1 {
|
1 {
|
||||||
tf.font_family = name
|
tf.font_family = name
|
||||||
|
}
|
||||||
|
2 {
|
||||||
|
tf.font_sub_family = name
|
||||||
|
}
|
||||||
|
4 {
|
||||||
|
tf.full_name = name
|
||||||
|
}
|
||||||
|
6 {
|
||||||
|
tf.postscript_name = name
|
||||||
|
}
|
||||||
|
else {}
|
||||||
}
|
}
|
||||||
2 {
|
|
||||||
tf.font_sub_family = name
|
|
||||||
}
|
|
||||||
4 {
|
|
||||||
tf.full_name = name
|
|
||||||
}
|
|
||||||
6 {
|
|
||||||
tf.postscript_name = name
|
|
||||||
}
|
|
||||||
else {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -767,24 +766,24 @@ fn (mut tf TTF_File) read_cmap_table() {
|
||||||
|
|
||||||
version := tf.get_u16() // must be 0
|
version := tf.get_u16() // must be 0
|
||||||
assert version == 0
|
assert version == 0
|
||||||
number_sub_tables := tf.get_u16()
|
number_sub_tables := tf.get_u16()
|
||||||
|
|
||||||
// tables must be sorted by platform id and then platform specific
|
// tables must be sorted by platform id and then platform specific
|
||||||
// encoding.
|
// encoding.
|
||||||
for _ in 0..number_sub_tables {
|
for _ in 0..number_sub_tables {
|
||||||
// platforms are:
|
// platforms are:
|
||||||
// 0 - Unicode -- use specific id 6 for full coverage. 0/4 common.
|
// 0 - Unicode -- use specific id 6 for full coverage. 0/4 common.
|
||||||
// 1 - Macintosh (Discouraged)
|
// 1 - Macintosh (Discouraged)
|
||||||
// 2 - reserved
|
// 2 - reserved
|
||||||
// 3 - Microsoft
|
// 3 - Microsoft
|
||||||
platform_id := tf.get_u16()
|
platform_id := tf.get_u16()
|
||||||
platform_specific_id := tf.get_u16()
|
platform_specific_id := tf.get_u16()
|
||||||
offset := tf.get_u32()
|
offset := tf.get_u32()
|
||||||
dprintln("CMap platform_id=${platform_id} specific_id=${platform_specific_id} offset=${offset}")
|
dprintln("CMap platform_id=${platform_id} specific_id=${platform_specific_id} offset=${offset}")
|
||||||
if platform_id == 3 && platform_specific_id <= 1 {
|
if platform_id == 3 && platform_specific_id <= 1 {
|
||||||
tf.read_cmap(table_offset + offset)
|
tf.read_cmap(table_offset + offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut tf TTF_File) read_cmap(offset u32) {
|
fn (mut tf TTF_File) read_cmap(offset u32) {
|
||||||
|
@ -817,17 +816,17 @@ fn (mut tf TTF_File) read_cmap(offset u32) {
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
fn (mut tf TTF_File) map_code(char_code int) u16{
|
fn (mut tf TTF_File) map_code(char_code int) u16{
|
||||||
mut index := 0
|
mut index := 0
|
||||||
for i in 0..tf.cmaps.len {
|
for i in 0..tf.cmaps.len {
|
||||||
mut cmap := tf.cmaps[i]
|
mut cmap := tf.cmaps[i]
|
||||||
if cmap.format == 0 {
|
if cmap.format == 0 {
|
||||||
//dprintln("format 0")
|
//dprintln("format 0")
|
||||||
index = cmap.map_0(char_code)
|
index = cmap.map_0(char_code)
|
||||||
} else if cmap.format == 4 {
|
} else if cmap.format == 4 {
|
||||||
//dprintln("format 4")
|
//dprintln("format 4")
|
||||||
index = cmap.map_4(char_code, mut tf)
|
index = cmap.map_4(char_code, mut tf)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return u16(index)
|
||||||
return u16(index)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut tm TrueTypeCmap) init_0(mut tf TTF_File) {
|
fn (mut tm TrueTypeCmap) init_0(mut tf TTF_File) {
|
||||||
|
@ -851,45 +850,45 @@ fn (mut tm TrueTypeCmap) init_4(mut tf TTF_File) {
|
||||||
tm.format = 4
|
tm.format = 4
|
||||||
|
|
||||||
// 2x segcount
|
// 2x segcount
|
||||||
seg_count := tf.get_u16() >> 1
|
seg_count := tf.get_u16() >> 1
|
||||||
/*search_range :=*/ tf.get_u16()
|
/*search_range :=*/ tf.get_u16()
|
||||||
/*entry_selector :=*/ tf.get_u16()
|
/*entry_selector :=*/ tf.get_u16()
|
||||||
/*range_shift :=*/ tf.get_u16()
|
/*range_shift :=*/ tf.get_u16()
|
||||||
|
|
||||||
|
|
||||||
// Ending character code for each segment, last is 0xffff
|
// Ending character code for each segment, last is 0xffff
|
||||||
for _ in 0..seg_count {
|
for _ in 0..seg_count {
|
||||||
tm.segments << Segment{0, 0, tf.get_u16(), 0}
|
tm.segments << Segment{0, 0, tf.get_u16(), 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reservePAD
|
// reservePAD
|
||||||
tf.get_u16()
|
tf.get_u16()
|
||||||
|
|
||||||
// starting character code for each segment
|
// starting character code for each segment
|
||||||
for i in 0..seg_count {
|
for i in 0..seg_count {
|
||||||
tm.segments[i].start_code = tf.get_u16()
|
tm.segments[i].start_code = tf.get_u16()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delta for all character codes in segment
|
// Delta for all character codes in segment
|
||||||
for i in 0..seg_count {
|
for i in 0..seg_count {
|
||||||
tm.segments[i].id_delta = tf.get_u16()
|
tm.segments[i].id_delta = tf.get_u16()
|
||||||
}
|
}
|
||||||
|
|
||||||
// offset in bytes to glyph indexArray, or 0
|
// offset in bytes to glyph indexArray, or 0
|
||||||
for i in 0..seg_count {
|
for i in 0..seg_count {
|
||||||
ro := u32(tf.get_u16())
|
ro := u32(tf.get_u16())
|
||||||
if ro != 0 {
|
if ro != 0 {
|
||||||
tm.segments[i].id_range_offset = tf.pos - 2 + ro
|
tm.segments[i].id_range_offset = tf.pos - 2 + ro
|
||||||
} else {
|
} else {
|
||||||
tm.segments[i].id_range_offset = 0
|
tm.segments[i].id_range_offset = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
// DEBUG LOG
|
// DEBUG LOG
|
||||||
for i in 0..seg_count {
|
for i in 0..seg_count {
|
||||||
seg := tm.segments[i]
|
seg := tm.segments[i]
|
||||||
dprintln(" segments[$i] = $seg.start_code $seg.end_code $seg.id_delta $seg.id_range_offset")
|
dprintln(" segments[$i] = $seg.start_code $seg.end_code $seg.id_delta $seg.id_range_offset")
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,21 +934,21 @@ fn (mut tf TTF_File) read_hhea_table() {
|
||||||
/*version :=*/ tf.get_fixed() // 0x00010000
|
/*version :=*/ tf.get_fixed() // 0x00010000
|
||||||
|
|
||||||
tf.ascent = tf.get_fword()
|
tf.ascent = tf.get_fword()
|
||||||
tf.descent = tf.get_fword()
|
tf.descent = tf.get_fword()
|
||||||
tf.line_gap = tf.get_fword()
|
tf.line_gap = tf.get_fword()
|
||||||
tf.advance_width_max = tf.get_ufword()
|
tf.advance_width_max = tf.get_ufword()
|
||||||
tf.min_left_side_bearing = tf.get_fword()
|
tf.min_left_side_bearing = tf.get_fword()
|
||||||
tf.min_right_side_bearing = tf.get_fword()
|
tf.min_right_side_bearing = tf.get_fword()
|
||||||
tf.x_max_extent = tf.get_fword()
|
tf.x_max_extent = tf.get_fword()
|
||||||
tf.caret_slope_rise = tf.get_i16()
|
tf.caret_slope_rise = tf.get_i16()
|
||||||
tf.caret_slope_run = tf.get_i16()
|
tf.caret_slope_run = tf.get_i16()
|
||||||
tf.caret_offset = tf.get_fword()
|
tf.caret_offset = tf.get_fword()
|
||||||
tf.get_i16() // reserved
|
tf.get_i16() // reserved
|
||||||
tf.get_i16() // reserved
|
tf.get_i16() // reserved
|
||||||
tf.get_i16() // reserved
|
tf.get_i16() // reserved
|
||||||
tf.get_i16() // reserved
|
tf.get_i16() // reserved
|
||||||
tf.metric_data_format = tf.get_i16()
|
tf.metric_data_format = tf.get_i16()
|
||||||
tf.num_of_long_hor_metrics = tf.get_u16()
|
tf.num_of_long_hor_metrics = tf.get_u16()
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -959,11 +958,11 @@ fn (mut tf TTF_File) read_hhea_table() {
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
struct Kern0Table {
|
struct Kern0Table {
|
||||||
mut:
|
mut:
|
||||||
swap bool
|
swap bool
|
||||||
offset u32
|
offset u32
|
||||||
n_pairs int
|
n_pairs int
|
||||||
kmap map[u32]i16
|
kmap map[u32]i16
|
||||||
old_index int = -1
|
old_index int = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut kt Kern0Table) reset() {
|
fn (mut kt Kern0Table) reset() {
|
||||||
|
@ -1027,23 +1026,23 @@ fn (mut tf TTF_File) read_kern_table() {
|
||||||
|
|
||||||
dprintln("Kern Table version: $version Kern nTables: $n_tables")
|
dprintln("Kern Table version: $version Kern nTables: $n_tables")
|
||||||
|
|
||||||
for _ in 0..n_tables{
|
for _ in 0..n_tables{
|
||||||
st_version := tf.get_u16() // sub table version
|
st_version := tf.get_u16() // sub table version
|
||||||
length := tf.get_u16()
|
length := tf.get_u16()
|
||||||
coverage := tf.get_u16()
|
coverage := tf.get_u16()
|
||||||
format := coverage >> 8
|
format := coverage >> 8
|
||||||
cross := coverage & 4
|
cross := coverage & 4
|
||||||
vertical := (coverage & 0x1) == 0
|
vertical := (coverage & 0x1) == 0
|
||||||
dprintln("Kerning subtable version [$st_version] format [$format] length [$length] coverage: [${coverage.hex()}]")
|
dprintln("Kerning subtable version [$st_version] format [$format] length [$length] coverage: [${coverage.hex()}]")
|
||||||
if format == 0 {
|
if format == 0 {
|
||||||
dprintln("kern format: 0")
|
dprintln("kern format: 0")
|
||||||
kern := tf.create_kern_table0(vertical, cross != 0)
|
kern := tf.create_kern_table0(vertical, cross != 0)
|
||||||
tf.kern << kern
|
tf.kern << kern
|
||||||
} else {
|
} else {
|
||||||
dprintln("Unknown format -- skip")
|
dprintln("Unknown format -- skip")
|
||||||
tf.pos = tf.pos + length
|
tf.pos = tf.pos + length
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut tf TTF_File) reset_kern() {
|
fn (mut tf TTF_File) reset_kern() {
|
||||||
|
|
Loading…
Reference in New Issue