ttf: improvement on not found glyphs (#8050)
							parent
							
								
									5f95dd54bd
								
							
						
					
					
						commit
						55e3e50b9b
					
				|  | @ -111,23 +111,23 @@ fn fabs(a f32) f32 { | |||
| // integer part of x
 | ||||
| [inline] | ||||
| fn ipart(x f32) f32 { | ||||
|     return f32(math.floor(x)) | ||||
| 	return f32(math.floor(x)) | ||||
| } | ||||
| 
 | ||||
| [inline] | ||||
| fn round(x f32) f32 { | ||||
|     return ipart(x + 0.5) | ||||
| 	return ipart(x + 0.5) | ||||
| } | ||||
| 
 | ||||
| // fractional part of x
 | ||||
| [inline] | ||||
| fn fpart(x f32) f32 { | ||||
|     return x - f32(math.floor(x)) | ||||
| 	return x - f32(math.floor(x)) | ||||
| } | ||||
| 
 | ||||
| [inline] | ||||
| 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)) | ||||
| 		// 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) | ||||
| 		//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 | ||||
| 	} | ||||
|   return res | ||||
| 	return res | ||||
| } | ||||
| 
 | ||||
| pub  | ||||
|  | @ -581,6 +588,12 @@ fn (mut bmp BitMap) get_bbox(in_string string) (int, int){ | |||
| 		} | ||||
| 		 | ||||
| 		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) | ||||
| 		//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 | ||||
| 	} | ||||
|      | ||||
| 
 | ||||
| 	//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) | ||||
|  | @ -623,6 +636,25 @@ fn (mut bmp BitMap) get_bbox(in_string string) (int, int){ | |||
| * 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 | ||||
| fn (mut bmp BitMap) draw_text(in_string string) (int, int){ | ||||
| 	mut w := 0 | ||||
|  | @ -652,45 +684,52 @@ fn (mut bmp BitMap) draw_text(in_string string) (int, int){ | |||
| 			char = u16(tmp_char) | ||||
| 		} | ||||
| 		 | ||||
| 	    c_index := bmp.tf.map_code(int(char)) | ||||
| 	    ax , ay := bmp.tf.next_kern(c_index) | ||||
| 	    //dprintln("char_index: $c_index ax: $ax ay: $ay")
 | ||||
| 		c_index := bmp.tf.map_code(int(char)) | ||||
| 		// Glyph not found
 | ||||
| 		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)) | ||||
| 			//cw, lsb := bmp.tf.get_horizontal_metrics(u16(char))
 | ||||
| 	    //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) | ||||
| 		ax , ay := bmp.tf.next_kern(c_index) | ||||
| 		//dprintln("char_index: $c_index ax: $ax ay: $ay")
 | ||||
| 
 | ||||
| 	    x_min, x_max := bmp.draw_glyph(c_index) | ||||
| 	    // x_min := 1
 | ||||
| 			// x_max := 2
 | ||||
| 			//-----------------
 | ||||
| 		cw, _ := bmp.tf.get_horizontal_metrics(u16(char)) | ||||
| 		//cw, lsb := bmp.tf.get_horizontal_metrics(u16(char))
 | ||||
| 		//dprintln("metrics: [${u16(char):c}] cw:$cw lsb:$lsb")
 | ||||
| 
 | ||||
| 			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 | ||||
| 		//----- Draw_Glyph transformations -----
 | ||||
| 		mut x0 := w + int(ax * bmp.scale) | ||||
| 		mut y0 := 0 + int(ay * bmp.scale) | ||||
| 
 | ||||
| 	    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) | ||||
| 		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) | ||||
| 		// 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 | ||||
|  | @ -759,13 +798,13 @@ fn (mut bmp BitMap) draw_glyph(index u16) (int, int){ | |||
| 			} else { | ||||
| 				//dprintln("HERE2")
 | ||||
| 				// ctx.quadraticCurveTo(prev.x + x, prev.y + y,
 | ||||
| 	            //            (prev.x + point.x) / 2 + x,
 | ||||
| 	            //            (prev.y + point.y) / 2 + y);
 | ||||
| 	             | ||||
| 	            //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, color) | ||||
| 	            x0 = (prev.x + point.x)/2 | ||||
| 				//            (prev.x + point.x) / 2 + x,
 | ||||
| 				//            (prev.y + point.y) / 2 + y);
 | ||||
| 
 | ||||
| 				//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, color) | ||||
| 				x0 = (prev.x + point.x)/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]")
 | ||||
| 			if s == 2 { // final point was off-curve. connect to start
 | ||||
| 				 | ||||
|                 mut start_point := glyph.points[contour_start] | ||||
|                 start_point.x, start_point.y = bmp.trf_ch(start_point) | ||||
|                 if point.on_curve { | ||||
| 				mut start_point := glyph.points[contour_start] | ||||
| 				start_point.x, start_point.y = bmp.trf_ch(start_point) | ||||
| 				if point.on_curve { | ||||
| 					//ctx.quadraticCurveTo(prev.x + x, prev.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.quadratic(x0, y0, start_point.x, start_point.y ,  | ||||
| 			//	start_point.x + in_x, start_point.y + in_y, u32(0xFF00FF00))
 | ||||
| 				start_point.x, start_point.y, color)             | ||||
| 					//point.x + x, point.y + y);
 | ||||
| 					//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 ,  | ||||
| 					//	start_point.x + in_x, start_point.y + in_y, u32(0xFF00FF00))
 | ||||
| 						start_point.x, start_point.y, color)             | ||||
| 				} else { | ||||
| 					//ctx.quadraticCurveTo(prev.x + x, prev.y + y,
 | ||||
|                     //        (prev.x + point.x) / 2 + x,
 | ||||
|                     //        (prev.y + point.y) / 2 + y);
 | ||||
|                      | ||||
|                     //bmp.line(x0, y0, start_point.x, start_point.y, u32(0x00FF0000)
 | ||||
|                     bmp.quadratic(x0, y0, start_point.x, start_point.y,  | ||||
| 			(point.x + start_point.x)/2, | ||||
| 			(point.y + start_point.y)/2, | ||||
| 			//u32(0xFF000000))              
 | ||||
| 					//        (prev.x + point.x) / 2 + x,
 | ||||
| 					//        (prev.y + point.y) / 2 + y);
 | ||||
| 
 | ||||
| 					//bmp.line(x0, y0, start_point.x, start_point.y, u32(0x00FF0000)
 | ||||
| 					bmp.quadratic(x0, y0, start_point.x, start_point.y,  | ||||
| 						(point.x + start_point.x)/2, | ||||
| 						(point.y + start_point.y)/2, | ||||
| 						//u32(0xFF000000))              
 | ||||
| 						color) | ||||
| 				} | ||||
| 			}else{ | ||||
| 			} else { | ||||
| 				// 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, color) | ||||
|  |  | |||
|  | @ -156,7 +156,7 @@ fn (mut tf_skl TTF_render_Sokol) create_texture(){ | |||
| 		height: h | ||||
| 		num_mipmaps: 0 | ||||
| 		min_filter:   .linear | ||||
|     mag_filter:   .linear | ||||
| 		mag_filter:   .linear | ||||
| 		//usage: .dynamic
 | ||||
| 		wrap_u: .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 { | ||||
| mut: | ||||
|     id_range_offset u32 | ||||
|     start_code      u16 | ||||
|     end_code        u16 | ||||
|     id_delta        u16 | ||||
| 	id_range_offset u32 | ||||
| 	start_code      u16 | ||||
| 	end_code        u16 | ||||
| 	id_delta        u16 | ||||
| } | ||||
| 
 | ||||
| struct TrueTypeCmap { | ||||
|  | @ -220,8 +220,8 @@ fn (mut tf TTF_File) glyph_count() u16{ | |||
| 	old_pos := tf.pos | ||||
| 	tf.pos = tf.tables["maxp"].offset + 4 | ||||
| 	count := tf.get_u16() | ||||
|     tf.pos = old_pos | ||||
|     return count | ||||
| 	tf.pos = old_pos | ||||
| 	return count | ||||
| } | ||||
| 
 | ||||
| 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) | ||||
| 		if simple_glyph.valid_glyph { | ||||
| 			point_offset := in_glyph.points.len | ||||
|             for i in 0..simple_glyph.contour_ends.len { | ||||
| 		in_glyph.contour_ends << u16(simple_glyph.contour_ends[i] + point_offset) | ||||
|             } | ||||
| 			for i in 0..simple_glyph.contour_ends.len { | ||||
| 				in_glyph.contour_ends << u16(simple_glyph.contour_ends[i] + point_offset) | ||||
| 			} | ||||
| 
 | ||||
|             for p in simple_glyph.points { | ||||
| 		mut x := f32(p.x) | ||||
| 		mut y := f32(p.y) | ||||
| 		x = component.matrix[0] * x + component.matrix[1] * y + component.matrix[4] | ||||
| 		y = component.matrix[2] * x + component.matrix[3] * y + component.matrix[5]            	 | ||||
| 		in_glyph.points << Point{ | ||||
| 			x: int(x) | ||||
| 			y: int(y) | ||||
| 			on_curve: p.on_curve | ||||
| 		} | ||||
| 		 | ||||
|             } | ||||
| 			for p in simple_glyph.points { | ||||
| 				mut x := f32(p.x) | ||||
| 				mut y := f32(p.y) | ||||
| 				x = component.matrix[0] * x + component.matrix[1] * y + component.matrix[4] | ||||
| 				y = component.matrix[2] * x + component.matrix[3] * y + component.matrix[5]            	 | ||||
| 				in_glyph.points << Point{ | ||||
| 					x: int(x) | ||||
| 					y: int(y) | ||||
| 					on_curve: p.on_curve | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		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
 | ||||
|     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.mac_style           = tf.get_u16() | ||||
| 	tf.lowest_rec_ppem     = tf.get_u16() | ||||
|     tf.font_direction_hint = tf.get_i16() | ||||
|     tf.index_to_loc_format = tf.get_i16() | ||||
|     tf.glyph_data_format   = tf.get_i16() | ||||
| 	tf.font_direction_hint = tf.get_i16() | ||||
| 	tf.index_to_loc_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() | ||||
| 		/*language_id          :=*/ tf.get_u16() | ||||
| 		name_id              := tf.get_u16() | ||||
|         length               := tf.get_u16() | ||||
|         offset               := tf.get_u16() | ||||
| 		length               := tf.get_u16() | ||||
| 		offset               := tf.get_u16() | ||||
| 
 | ||||
|         old_pos              := tf.pos | ||||
|         tf.pos = table_offset + string_offset + offset | ||||
| 		old_pos              := tf.pos | ||||
| 		tf.pos = table_offset + string_offset + offset | ||||
| 
 | ||||
|         mut name := "" | ||||
|         if platform_id == 0 || platform_id == 3 { | ||||
| 		mut name := "" | ||||
| 		if platform_id == 0 || platform_id == 3 { | ||||
| 			name = tf.get_unicode_string(length) | ||||
| 	} else { | ||||
|             name = tf.get_string(length) | ||||
|         } | ||||
|         //dprintln("Name [${platform_id} / ${platform_specific_id}] id:[$name_id] language:[$language_id] [$name]")
 | ||||
|         tf.pos = old_pos | ||||
| 		} else { | ||||
| 			name = tf.get_string(length) | ||||
| 		} | ||||
| 		//dprintln("Name [${platform_id} / ${platform_specific_id}] id:[$name_id] language:[$language_id] [$name]")
 | ||||
| 		tf.pos = old_pos | ||||
| 
 | ||||
|         match name_id { | ||||
| 		1 { | ||||
| 			tf.font_family = name | ||||
| 		match name_id { | ||||
| 			1 { | ||||
| 				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
 | ||||
| 	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
 | ||||
|     // encoding.
 | ||||
|     for _ in 0..number_sub_tables { | ||||
| 	// platforms are:
 | ||||
|         // 0 - Unicode -- use specific id 6 for full coverage. 0/4 common.
 | ||||
|         // 1 - Macintosh (Discouraged)
 | ||||
|         // 2 - reserved
 | ||||
|         // 3 - Microsoft
 | ||||
|         platform_id          := tf.get_u16() | ||||
| 	// encoding.
 | ||||
| 	for _ in 0..number_sub_tables { | ||||
| 		// platforms are:
 | ||||
| 		// 0 - Unicode -- use specific id 6 for full coverage. 0/4 common.
 | ||||
| 		// 1 - Macintosh (Discouraged)
 | ||||
| 		// 2 - reserved
 | ||||
| 		// 3 - Microsoft
 | ||||
| 		platform_id          := tf.get_u16() | ||||
| 		platform_specific_id := tf.get_u16() | ||||
| 		offset               := tf.get_u32() | ||||
| 		dprintln("CMap platform_id=${platform_id} specific_id=${platform_specific_id} offset=${offset}") | ||||
|         if platform_id == 3 && platform_specific_id <= 1 { | ||||
|             tf.read_cmap(table_offset + offset) | ||||
|         } | ||||
|     } | ||||
| 		if platform_id == 3 && platform_specific_id <= 1 { | ||||
| 			tf.read_cmap(table_offset + offset) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 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{ | ||||
| 	mut index := 0 | ||||
|     for i in 0..tf.cmaps.len { | ||||
| 	mut cmap := tf.cmaps[i] | ||||
| 	if cmap.format == 0 { | ||||
| 		//dprintln("format 0")
 | ||||
| 		index = cmap.map_0(char_code) | ||||
| 	} else if cmap.format == 4 { | ||||
| 		//dprintln("format 4")
 | ||||
| 		index = cmap.map_4(char_code, mut tf) | ||||
| 	for i in 0..tf.cmaps.len { | ||||
| 		mut cmap := tf.cmaps[i] | ||||
| 		if cmap.format == 0 { | ||||
| 			//dprintln("format 0")
 | ||||
| 			index = cmap.map_0(char_code) | ||||
| 		} else if cmap.format == 4 { | ||||
| 			//dprintln("format 4")
 | ||||
| 			index = cmap.map_4(char_code, mut tf) | ||||
| 		} | ||||
| 	} | ||||
|     } | ||||
|     return u16(index) | ||||
| 	return u16(index) | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| 
 | ||||
| 	// 2x segcount
 | ||||
|     seg_count      := tf.get_u16() >> 1 | ||||
|     /*search_range   :=*/ tf.get_u16() | ||||
|     /*entry_selector :=*/ tf.get_u16() | ||||
|     /*range_shift    :=*/ tf.get_u16() | ||||
| 	seg_count      := tf.get_u16() >> 1 | ||||
| 	/*search_range   :=*/ tf.get_u16() | ||||
| 	/*entry_selector :=*/ tf.get_u16() | ||||
| 	/*range_shift    :=*/ tf.get_u16() | ||||
| 
 | ||||
| 
 | ||||
|     // Ending character code for each segment, last is 0xffff
 | ||||
|     for _ in 0..seg_count { | ||||
| 	// Ending character code for each segment, last is 0xffff
 | ||||
| 	for _ in 0..seg_count { | ||||
| 	tm.segments << Segment{0, 0, tf.get_u16(), 0} | ||||
|     } | ||||
| 	} | ||||
| 
 | ||||
|     // reservePAD
 | ||||
|     tf.get_u16() | ||||
| 	// reservePAD
 | ||||
| 	tf.get_u16() | ||||
| 
 | ||||
|     // starting character code for each segment
 | ||||
|     for i in 0..seg_count { | ||||
| 	// starting character code for each segment
 | ||||
| 	for i in 0..seg_count { | ||||
| 	tm.segments[i].start_code = tf.get_u16() | ||||
|     } | ||||
| 	} | ||||
| 
 | ||||
|     // Delta for all character codes in segment
 | ||||
|     for i in 0..seg_count { | ||||
| 	// Delta for all character codes in segment
 | ||||
| 	for i in 0..seg_count { | ||||
| 	tm.segments[i].id_delta = tf.get_u16() | ||||
|     } | ||||
| 	} | ||||
| 
 | ||||
|     // offset in bytes to glyph indexArray, or 0
 | ||||
|     for i in 0..seg_count { | ||||
| 	// offset in bytes to glyph indexArray, or 0
 | ||||
| 	for i in 0..seg_count { | ||||
| 		ro := u32(tf.get_u16()) | ||||
| 		if ro != 0 { | ||||
| 		tm.segments[i].id_range_offset = tf.pos - 2 + ro | ||||
| 		} else { | ||||
| 		tm.segments[i].id_range_offset = 0 | ||||
| 		} | ||||
|     } | ||||
| 	} | ||||
| /* | ||||
|     // DEBUG LOG
 | ||||
|     for i in 0..seg_count { | ||||
| 	// DEBUG LOG
 | ||||
| 	for i in 0..seg_count { | ||||
| 	seg := tm.segments[i] | ||||
| 	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
 | ||||
| 	 | ||||
| 	tf.ascent                  = tf.get_fword() | ||||
|     tf.descent                 = tf.get_fword() | ||||
|     tf.line_gap                = tf.get_fword() | ||||
|     tf.advance_width_max       = tf.get_ufword() | ||||
|     tf.min_left_side_bearing   = tf.get_fword() | ||||
|     tf.min_right_side_bearing  = tf.get_fword() | ||||
|     tf.x_max_extent            = tf.get_fword() | ||||
|     tf.caret_slope_rise        = tf.get_i16() | ||||
|     tf.caret_slope_run         = tf.get_i16() | ||||
|     tf.caret_offset            = tf.get_fword() | ||||
|     tf.get_i16() // reserved
 | ||||
|     tf.get_i16() // reserved
 | ||||
|     tf.get_i16() // reserved
 | ||||
|     tf.get_i16() // reserved
 | ||||
|     tf.metric_data_format      = tf.get_i16() | ||||
|     tf.num_of_long_hor_metrics = tf.get_u16() | ||||
| 	tf.descent                 = tf.get_fword() | ||||
| 	tf.line_gap                = tf.get_fword() | ||||
| 	tf.advance_width_max       = tf.get_ufword() | ||||
| 	tf.min_left_side_bearing   = tf.get_fword() | ||||
| 	tf.min_right_side_bearing  = tf.get_fword() | ||||
| 	tf.x_max_extent            = tf.get_fword() | ||||
| 	tf.caret_slope_rise        = tf.get_i16() | ||||
| 	tf.caret_slope_run         = tf.get_i16() | ||||
| 	tf.caret_offset            = tf.get_fword() | ||||
| 	tf.get_i16() // reserved
 | ||||
| 	tf.get_i16() // reserved
 | ||||
| 	tf.get_i16() // reserved
 | ||||
| 	tf.get_i16() // reserved
 | ||||
| 	tf.metric_data_format      = tf.get_i16() | ||||
| 	tf.num_of_long_hor_metrics = tf.get_u16() | ||||
| } | ||||
| 
 | ||||
| /****************************************************************************** | ||||
|  | @ -959,11 +958,11 @@ fn (mut tf TTF_File) read_hhea_table() { | |||
| ******************************************************************************/ | ||||
| struct Kern0Table { | ||||
| mut: | ||||
|     swap       bool | ||||
|     offset     u32 | ||||
|     n_pairs    int | ||||
|     kmap       map[u32]i16 | ||||
|     old_index  int = -1 | ||||
| 	swap       bool | ||||
| 	offset     u32 | ||||
| 	n_pairs    int | ||||
| 	kmap       map[u32]i16 | ||||
| 	old_index  int = -1 | ||||
| } | ||||
| 
 | ||||
| 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") | ||||
| 
 | ||||
|     for _ in 0..n_tables{ | ||||
| 	st_version := tf.get_u16() // sub table version
 | ||||
| 	length     := tf.get_u16() | ||||
| 	coverage   := tf.get_u16() | ||||
| 	format     := coverage >> 8 | ||||
| 	cross      := coverage & 4 | ||||
| 	vertical   := (coverage & 0x1) == 0 | ||||
| 	dprintln("Kerning subtable version [$st_version] format [$format] length [$length] coverage: [${coverage.hex()}]") | ||||
| 	if format == 0 { | ||||
| 		dprintln("kern format: 0") | ||||
| 		kern := tf.create_kern_table0(vertical, cross != 0) | ||||
| 		tf.kern << kern | ||||
| 	} else { | ||||
| 		dprintln("Unknown format -- skip") | ||||
| 		tf.pos = tf.pos + length | ||||
| 	for _ in 0..n_tables{ | ||||
| 		st_version := tf.get_u16() // sub table version
 | ||||
| 		length     := tf.get_u16() | ||||
| 		coverage   := tf.get_u16() | ||||
| 		format     := coverage >> 8 | ||||
| 		cross      := coverage & 4 | ||||
| 		vertical   := (coverage & 0x1) == 0 | ||||
| 		dprintln("Kerning subtable version [$st_version] format [$format] length [$length] coverage: [${coverage.hex()}]") | ||||
| 		if format == 0 { | ||||
| 			dprintln("kern format: 0") | ||||
| 			kern := tf.create_kern_table0(vertical, cross != 0) | ||||
| 			tf.kern << kern | ||||
| 		} else { | ||||
| 			dprintln("Unknown format -- skip") | ||||
| 			tf.pos = tf.pos + length | ||||
| 		} | ||||
| 	} | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn (mut tf TTF_File) reset_kern() { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue