Harbor

branch main
showing the latest snapshot on main
svg.odin 2.2 KB · Plain text
font/svg.odin 0644 Raw
package font

// ============================================================================
// SVG FONTS (Phase 7)
// ============================================================================

// Private: lazy-init SVG table offset
// Since most people won't use this, find this table the first time it's needed
@(private)
get_svg :: proc(info: ^Font_Info) -> i32 {
	if info.svg < 0 {
		t := find_table(info.data, u32(info.fontstart), "SVG ")
		if t != 0 {
			offset := ttULONG(info.data[t+2:])
			info.svg = i32(t + offset)
		} else {
			info.svg = 0
		}
	}
	return info.svg
}

// Find SVG document record for glyph
// Returns pointer to the document record (12 bytes: startGlyph, endGlyph, offset, length)
// or nil if not found
@(private)
find_svg_doc :: proc(info: ^Font_Info, gl: i32) -> [^]u8 {
	svg_offset := get_svg(info)

	// If no SVG table, return nil (matches C behavior for subsequent calls)
	// Note: C doesn't have this check in FindSVGDoc, but has it in GetGlyphSVG
	// We add it here to avoid reading garbage from font header
	if svg_offset == 0 {
		return nil
	}

	data := info.data
	svg_doc_list := data[svg_offset:]

	num_entries := i32(ttUSHORT(svg_doc_list))
	svg_docs := svg_doc_list[2:]

	for i in 0..<num_entries {
		svg_doc := svg_docs[12*i:]
		start_glyph := i32(ttUSHORT(svg_doc))
		end_glyph := i32(ttUSHORT(svg_doc[2:]))
		if gl >= start_glyph && gl <= end_glyph {
			return svg_doc
		}
	}
	return nil
}

// Get SVG data for a glyph
// Fills svg with pointer to SVG document data
// Returns data size or 0 if SVG not found
get_glyph_svg :: proc(info: ^Font_Info, gl: i32, svg: ^[^]u8) -> i32 {
	// Early check if SVG table already known to not exist
	if info.svg == 0 {
		return 0
	}

	svg_doc := find_svg_doc(info, gl)
	if svg_doc != nil {
		// Use get_svg to ensure svg offset is initialized
		svg_offset := get_svg(info)
		svg^ = info.data[svg_offset + i32(ttULONG(svg_doc[4:])):]
		return i32(ttULONG(svg_doc[8:]))
	}
	return 0
}

// Get SVG data for a codepoint
// Fills svg with pointer to SVG document data
// Returns data size or 0 if SVG not found
get_codepoint_svg :: proc(info: ^Font_Info, codepoint: i32, svg: ^[^]u8) -> i32 {
	return get_glyph_svg(info, find_glyph_index(info, codepoint), svg)
}