Set glyph_padding to 4 (when using 8x8 over_sample we need more padding)
This commit is contained in:
parent
e6ccdd90d1
commit
86d6adc931
@ -6,8 +6,6 @@ Its original purpose was for use in game engines, however its rendeirng quality
|
||||
|
||||
TODO (Making it a more idiomatic library):
|
||||
|
||||
* Use Odin's builtin dynamic arrays
|
||||
* Use Odin's builtin map type
|
||||
* Setup freetype, harfbuzz, depedency management within the library
|
||||
|
||||
TODO Documentation:
|
||||
|
@ -21,8 +21,8 @@ Vec2 :: [2]f32
|
||||
Vec2i :: [2]i32
|
||||
Vec2_64 :: [2]f64
|
||||
|
||||
vec2_from_scalar :: #force_inline proc( scalar : f32 ) -> Vec2 { return { scalar, scalar } }
|
||||
vec2_64_from_vec2 :: #force_inline proc( v2 : Vec2 ) -> Vec2_64 { return { f64(v2.x), f64(v2.y) }}
|
||||
vec2_from_scalar :: #force_inline proc "contextless" ( scalar : f32 ) -> Vec2 { return { scalar, scalar } }
|
||||
vec2_64_from_vec2 :: #force_inline proc "contextless" ( v2 : Vec2 ) -> Vec2_64 { return { f64(v2.x), f64(v2.y) }}
|
||||
vec2_from_vec2i :: #force_inline proc( v2i : Vec2i ) -> Vec2 { return { f32(v2i.x), f32(v2i.y) }}
|
||||
|
||||
FontID :: distinct i64
|
||||
@ -104,7 +104,7 @@ InitAtlasParams :: struct {
|
||||
InitAtlasParams_Default :: InitAtlasParams {
|
||||
width = 4096,
|
||||
height = 2048,
|
||||
glyph_padding = 1,
|
||||
glyph_padding = 4,
|
||||
|
||||
region_a = {
|
||||
width = 32,
|
||||
|
@ -41,7 +41,7 @@ atlas_bbox :: proc( atlas : ^Atlas, region : AtlasRegionKind, local_idx : i32 )
|
||||
{
|
||||
case .A:
|
||||
width = f32(atlas.region_a.width)
|
||||
height = f32(atlas.region_b.height)
|
||||
height = f32(atlas.region_a.height)
|
||||
|
||||
position.x = cast(f32) (( local_idx % atlas.region_a.capacity.x ) * i32(atlas.region_a.width))
|
||||
position.y = cast(f32) (( local_idx / atlas.region_a.capacity.x ) * i32(atlas.region_a.height))
|
||||
@ -123,7 +123,7 @@ can_batch_glyph :: #force_inline proc( ctx : ^Context, font : FontID, entry : ^E
|
||||
return true
|
||||
}
|
||||
|
||||
decide_codepoint_region :: #force_inline proc( ctx : ^Context, entry : ^Entry, glyph_index : Glyph
|
||||
decide_codepoint_region :: proc( ctx : ^Context, entry : ^Entry, glyph_index : Glyph
|
||||
) -> (region_kind : AtlasRegionKind, region : ^AtlasRegion, over_sample : Vec2)
|
||||
{
|
||||
if parser_is_glyph_empty( & entry.parser_info, glyph_index ) {
|
||||
@ -131,14 +131,16 @@ decide_codepoint_region :: #force_inline proc( ctx : ^Context, entry : ^Entry, g
|
||||
}
|
||||
|
||||
bounds_0, bounds_1 := parser_get_glyph_box( & entry.parser_info, glyph_index )
|
||||
bounds_width := bounds_1.x - bounds_0.x
|
||||
bounds_height := bounds_1.y - bounds_0.y
|
||||
bounds_width := f32(bounds_1.x - bounds_0.x)
|
||||
bounds_height := f32(bounds_1.y - bounds_0.y)
|
||||
|
||||
atlas := & ctx.atlas
|
||||
glyph_buffer := & ctx.glyph_buffer
|
||||
|
||||
bounds_width_scaled := cast(u32) (f32(bounds_width) * entry.size_scale + 2.0 * f32(atlas.glyph_padding))
|
||||
bounds_height_scaled := cast(u32) (f32(bounds_height) * entry.size_scale + 2.0 * f32(atlas.glyph_padding))
|
||||
glyph_padding := f32(atlas.glyph_padding) * 2
|
||||
|
||||
bounds_width_scaled := cast(u32) (bounds_width * entry.size_scale + glyph_padding)
|
||||
bounds_height_scaled := cast(u32) (bounds_height * entry.size_scale + glyph_padding)
|
||||
|
||||
if bounds_width_scaled <= atlas.region_a.width && bounds_height_scaled <= atlas.region_a.height
|
||||
{
|
||||
|
@ -70,4 +70,6 @@ Will update the draw list layer with the latest offset based on the current leng
|
||||
|
||||
Provides a Vec2 the width and height occupied by the provided text string. The y is measured to be the the largest glyph box bounds height of the text. The width is derived from the `end_cursor_pos` field from a `ShapedText` entry.
|
||||
|
||||
## get_font_vertical_metrics
|
||||
|
||||
A wrapper for `parser_get_font_vertical_metrics`. Will provide the ascent, descent, and line_gap for a font entry.
|
||||
|
@ -224,7 +224,7 @@ cache_glyph_to_atlas :: proc( ctx : ^Context,
|
||||
region : ^AtlasRegion,
|
||||
over_sample : Vec2 )
|
||||
{
|
||||
// profile(#procedure)
|
||||
profile(#procedure)
|
||||
|
||||
// Get hb_font text metrics. These are unscaled!
|
||||
bounds_0, bounds_1 := parser_get_glyph_box( & entry.parser_info, glyph_index )
|
||||
@ -283,8 +283,8 @@ cache_glyph_to_atlas :: proc( ctx : ^Context,
|
||||
glyph_draw_translate.y = cast(f32) (i32(glyph_draw_translate.y + 0.9999999))
|
||||
|
||||
// Allocate a glyph_update_FBO region
|
||||
gwidth_scaled_px := i32( bounds_width * glyph_draw_scale.x + 1.0 ) + i32(over_sample.x * glyph_padding)
|
||||
if i32(glyph_buffer.batch_x + gwidth_scaled_px) >= i32(glyph_buffer.width) {
|
||||
gwidth_scaled_px := bounds_width * glyph_draw_scale.x + 1.0 + over_sample.x * glyph_padding
|
||||
if i32(f32(glyph_buffer.batch_x) + gwidth_scaled_px) >= i32(glyph_buffer.width) {
|
||||
flush_glyph_buffer_to_atlas( ctx )
|
||||
}
|
||||
|
||||
@ -311,7 +311,7 @@ cache_glyph_to_atlas :: proc( ctx : ^Context,
|
||||
|
||||
// Advance glyph_update_batch_x and calculate final glyph drawing transform
|
||||
glyph_draw_translate.x += f32(glyph_buffer.batch_x)
|
||||
glyph_buffer.batch_x += gwidth_scaled_px
|
||||
glyph_buffer.batch_x += i32(gwidth_scaled_px)
|
||||
screenspace_x_form( & glyph_draw_translate, & glyph_draw_scale, glyph_buffer_width, glyph_buffer_height )
|
||||
|
||||
call : DrawCall
|
||||
@ -524,7 +524,7 @@ draw_filled_path :: proc( draw_list : ^DrawList, outside_point : Vec2, path : []
|
||||
append( & draw_list.vertices, vertex )
|
||||
}
|
||||
|
||||
for index : u32 = 1; index < u32(len(path)); index += 1 {
|
||||
for index : u32 = 1; index < cast(u32) len(path); index += 1 {
|
||||
indices := & draw_list.indices
|
||||
append( indices, outside_vertex )
|
||||
append( indices, v_offset + index - 1 )
|
||||
@ -577,7 +577,7 @@ draw_text_shape :: proc( ctx : ^Context,
|
||||
// position := position //+ ctx.cursor_pos * scale
|
||||
// profile(#procedure)
|
||||
batch_start_idx : i32 = 0
|
||||
for index : i32 = 0; index < i32(len(shaped.glyphs)); index += 1
|
||||
for index : i32 = 0; index < cast(i32) len(shaped.glyphs); index += 1
|
||||
{
|
||||
glyph_index := shaped.glyphs[ index ]
|
||||
if is_empty( ctx, entry, glyph_index ) do continue
|
||||
@ -602,7 +602,7 @@ draw_text_shape :: proc( ctx : ^Context,
|
||||
}
|
||||
|
||||
// flush_glyph_buffer_to_atlas(ctx)
|
||||
draw_text_batch( ctx, entry, shaped, batch_start_idx, i32(len(shaped.glyphs)), position, scale, snap_width , snap_height )
|
||||
draw_text_batch( ctx, entry, shaped, batch_start_idx, cast(i32) len(shaped.glyphs), position, scale, snap_width , snap_height )
|
||||
reset_batch_codepoint_state( ctx )
|
||||
cursor_pos = shaped.end_cursor_pos
|
||||
return
|
||||
|
@ -30,10 +30,10 @@ shape_lru_hash :: #force_inline proc "contextless" ( label : string ) -> u64 {
|
||||
// ve_fontcache_eval_bezier (quadratic)
|
||||
eval_point_on_bezier3 :: #force_inline proc "contextless" ( p0, p1, p2 : Vec2, alpha : f32 ) -> Vec2
|
||||
{
|
||||
// p0 := vec2_64_from_vec2(p0)
|
||||
// p1 := vec2_64_from_vec2(p1)
|
||||
// p2 := vec2_64_from_vec2(p2)
|
||||
// alpha := f64(alpha)
|
||||
p0 := vec2_64(p0)
|
||||
p1 := vec2_64(p1)
|
||||
p2 := vec2_64(p2)
|
||||
alpha := f64(alpha)
|
||||
|
||||
weight_start := (1 - alpha) * (1 - alpha)
|
||||
weight_control := 2.0 * (1 - alpha) * alpha
|
||||
@ -52,11 +52,11 @@ eval_point_on_bezier3 :: #force_inline proc "contextless" ( p0, p1, p2 : Vec2, a
|
||||
// ve_fontcache_eval_bezier (cubic)
|
||||
eval_point_on_bezier4 :: #force_inline proc "contextless" ( p0, p1, p2, p3 : Vec2, alpha : f32 ) -> Vec2
|
||||
{
|
||||
// p0 := vec2_64_from_vec2(p0)
|
||||
// p1 := vec2_64_from_vec2(p1)
|
||||
// p2 := vec2_64_from_vec2(p2)
|
||||
// p3 := vec2_64_from_vec2(p3)
|
||||
// alpha := f64(alpha)
|
||||
p0 := vec2_64(p0)
|
||||
p1 := vec2_64(p1)
|
||||
p2 := vec2_64(p2)
|
||||
p3 := vec2_64(p3)
|
||||
alpha := f64(alpha)
|
||||
|
||||
weight_start := (1 - alpha) * (1 - alpha) * (1 - alpha)
|
||||
weight_c_a := 3 * (1 - alpha) * (1 - alpha) * alpha
|
||||
@ -91,7 +91,7 @@ reset_batch_codepoint_state :: #force_inline proc( ctx : ^Context ) {
|
||||
}
|
||||
|
||||
screenspace_x_form :: #force_inline proc "contextless" ( position, scale : ^Vec2, width, height : f32 ) {
|
||||
when false
|
||||
when true
|
||||
{
|
||||
pos_64 := vec2_64_from_vec2(position^)
|
||||
scale_64 := vec2_64_from_vec2(scale^)
|
||||
@ -108,15 +108,13 @@ screenspace_x_form :: #force_inline proc "contextless" ( position, scale : ^Vec2
|
||||
else
|
||||
{
|
||||
quotient : Vec2 = 1.0 / { width, height }
|
||||
pos := position^ * quotient * 2.0 - 1.0
|
||||
s := scale^ * quotient * 2.0
|
||||
(position^) = { f32(pos.x), f32(pos.y) }
|
||||
(scale^) = { f32(s.x), f32(s.y) }
|
||||
(position^) *= quotient * 2.0 - 1.0
|
||||
(scale^) *= quotient * 2.0
|
||||
}
|
||||
}
|
||||
|
||||
textspace_x_form :: #force_inline proc "contextless" ( position, scale : ^Vec2, width, height : f32 ) {
|
||||
when false
|
||||
when true
|
||||
{
|
||||
pos_64 := vec2_64_from_vec2(position^)
|
||||
scale_64 := vec2_64_from_vec2(scale^)
|
||||
@ -132,13 +130,8 @@ textspace_x_form :: #force_inline proc "contextless" ( position, scale : ^Vec2,
|
||||
}
|
||||
else
|
||||
{
|
||||
pos := position^
|
||||
s := scale^
|
||||
|
||||
quotient : Vec2 = 1.0 / { width, height }
|
||||
pos *= quotient
|
||||
s *= quotient
|
||||
(position^) = { f32(pos.x), f32(pos.y) }
|
||||
(scale^) = { f32(s.x), f32(s.y) }
|
||||
(position^) *= quotient
|
||||
(scale^) *= quotient
|
||||
}
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ shape_text_cached :: proc( ctx : ^Context, font : FontID, text_utf8 : string, en
|
||||
return & shape_cache.storage[ shape_cache_idx ]
|
||||
}
|
||||
|
||||
// TODO(Ed): Make position rounding an option
|
||||
shape_text_uncached :: proc( ctx : ^Context, font : FontID, text_utf8 : string, entry : ^Entry, output : ^ShapedText )
|
||||
{
|
||||
// profile(#procedure)
|
||||
@ -105,7 +106,7 @@ shape_text_uncached :: proc( ctx : ^Context, font : FontID, text_utf8 : string,
|
||||
{
|
||||
position.x = 0.0
|
||||
position.y -= (ascent - descent + line_gap) * entry.size_scale
|
||||
position.y = cast(f32) i32( position.y + 0.5 )
|
||||
position.y = ceil(position.y)
|
||||
prev_codepoint = rune(0)
|
||||
continue
|
||||
}
|
||||
@ -116,11 +117,11 @@ shape_text_uncached :: proc( ctx : ^Context, font : FontID, text_utf8 : string,
|
||||
append( & output.glyphs, parser_find_glyph_index( & entry.parser_info, codepoint ))
|
||||
advance, to_left_side_glyph = parser_get_codepoint_horizontal_metrics( & entry.parser_info, codepoint )
|
||||
|
||||
// append( & output.positions, Vec2 {
|
||||
// cast(f32) i32(position.x + 0.5),
|
||||
// position.y
|
||||
// })
|
||||
append( & output.positions, position )
|
||||
append( & output.positions, Vec2 {
|
||||
ceil(position.x),
|
||||
position.y
|
||||
})
|
||||
// append( & output.positions, position )
|
||||
|
||||
position.x += f32(advance) * entry.size_scale
|
||||
prev_codepoint = codepoint
|
||||
|
Loading…
Reference in New Issue
Block a user