VEFC: Added bad edge case to handle parsing conic curves, progess on cache_glyph
This commit is contained in:
parent
c182ab7173
commit
38ebed8874
@ -530,7 +530,8 @@ cache_glyph :: proc( ctx : ^Context, font : FontID, glyph_index : Glyph, scale,
|
||||
|
||||
if ctx.debug_print_verbose
|
||||
{
|
||||
|
||||
log( "shape: \n")
|
||||
// for
|
||||
}
|
||||
|
||||
/*
|
||||
@ -538,8 +539,26 @@ cache_glyph :: proc( ctx : ^Context, font : FontID, glyph_index : Glyph, scale,
|
||||
We need a random point that is outside our shape. We simply pick something diagonally across from top-left bound corner.
|
||||
Note that this outside point is scaled alongside the glyph in ve_fontcache_draw_filled_path, so we don't need to handle that here.
|
||||
*/
|
||||
bounds_0, bounds_1 : Vec2i
|
||||
// success := parser_get_glyph_box()
|
||||
bounds_0, bounds_1 := parser_get_glyph_box( entry.parser_info, glyph_index )
|
||||
|
||||
outside := Vec2 {
|
||||
f32(bounds_0.x - 21),
|
||||
f32(bounds_0.y - 33),
|
||||
}
|
||||
|
||||
// Note(Original Author): Figure out scaling so it fits within our box.
|
||||
draw : DrawCall
|
||||
draw.pass = FrameBufferPass.Glyph
|
||||
draw.start_index = u32(ctx.draw_list.indices.num)
|
||||
|
||||
// Note(Original Author);
|
||||
// Draw the path using simplified version of https://medium.com/@evanwallace/easy-scalable-text-rendering-on-the-gpu-c3f4d782c5ac.
|
||||
// Instead of involving fragment shader code we simply make use of modern GPU ability to crunch triangles and brute force curve definitions.
|
||||
path := ctx.temp_path
|
||||
clear(path)
|
||||
for vertex in shape {
|
||||
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package VEFontCache
|
||||
|
||||
FrameBufferPass :: enum {
|
||||
FrameBufferPass :: enum u32 {
|
||||
None = 0,
|
||||
Glyph = 1,
|
||||
Atlas = 2,
|
||||
Target = 3,
|
||||
@ -8,7 +9,7 @@ FrameBufferPass :: enum {
|
||||
}
|
||||
|
||||
DrawCall :: struct {
|
||||
pass : u32,
|
||||
pass : FrameBufferPass,
|
||||
start_index : u32,
|
||||
end_index : u32,
|
||||
clear_before_draw : b32,
|
||||
@ -17,7 +18,7 @@ DrawCall :: struct {
|
||||
}
|
||||
|
||||
DrawCall_Default :: DrawCall {
|
||||
pass = 0,
|
||||
pass = .None,
|
||||
start_index = 0,
|
||||
end_index = 0,
|
||||
clear_before_draw = false,
|
||||
|
@ -7,6 +7,11 @@ import "core:mem"
|
||||
|
||||
Kilobyte :: mem.Kilobyte
|
||||
|
||||
Arena :: mem.Arena
|
||||
|
||||
arena_allocator :: mem.arena_allocator
|
||||
arena_init :: mem.arena_init
|
||||
|
||||
Allocator :: mem.Allocator
|
||||
AllocatorError :: mem.Allocator_Error
|
||||
|
||||
|
@ -8,6 +8,7 @@ That interface is not exposed from this parser but could be added to parser_init
|
||||
*/
|
||||
|
||||
import "core:c"
|
||||
import "core:math"
|
||||
import stbtt "vendor:stb/truetype"
|
||||
import freetype "thirdparty:freetype"
|
||||
|
||||
@ -169,11 +170,50 @@ parser_is_glyph_empty :: proc( font : ^ParserFontInfo, glyph_index : Glyph ) ->
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO(Ed): This makes freetype second class I guess but VEFontCache doesn't have native support for freetype originally so....
|
||||
// parser_convert_freetype_outline_to_stb_truetype_shape :: proc( outline : freetype.Outline ) -> (shape : ParserGlyphShape, error : AllocatorError)
|
||||
// {
|
||||
when false {
|
||||
parser_convert_conic_to_cubic_freetype :: proc( vertices : Array(ParserGlyphVertex), p0, p1, p2 : freetype.Vector, tolerance : f32 )
|
||||
{
|
||||
scratch : [Kilobyte * 4]u8
|
||||
scratch_arena : Arena; arena_init(& scratch_arena, scratch[:])
|
||||
|
||||
// }
|
||||
points, error := make( Array(freetype.Vector), 256, allocator = arena_allocator( &scratch_arena) )
|
||||
assert(error != .None)
|
||||
|
||||
append( & points, p0)
|
||||
append( & points, p1)
|
||||
append( & points, p2)
|
||||
|
||||
to_float : f32 = 1.0 / 64.0
|
||||
control_conv :: f32(2.0 / 3.0) // Conic to cubic control point distance
|
||||
|
||||
for ; points.num > 1; {
|
||||
p0 := points.data[0]
|
||||
p1 := points.data[1]
|
||||
p2 := points.data[2]
|
||||
|
||||
fp0 := Vec2{ f32(p0.x), f32(p0.y) } * to_float
|
||||
fp1 := Vec2{ f32(p1.x), f32(p1.y) } * to_float
|
||||
fp2 := Vec2{ f32(p2.x), f32(p2.y) } * to_float
|
||||
|
||||
delta_x := fp0.x - 2 * fp1.x + fp2.x;
|
||||
delta_y := fp0.y - 2 * fp1.y + fp2.y;
|
||||
distance := math.sqrt(delta_x * delta_x + delta_y * delta_y);
|
||||
|
||||
if distance <= tolerance
|
||||
{
|
||||
control1 := {
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
control2 := {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parser_get_glyph_shape :: proc( font : ^ParserFontInfo, glyph_index : Glyph ) -> (shape : ParserGlyphShape, error : AllocatorError)
|
||||
{
|
||||
@ -261,6 +301,34 @@ parser_get_glyph_shape :: proc( font : ^ParserFontInfo, glyph_index : Glyph ) ->
|
||||
})
|
||||
index += 2
|
||||
}
|
||||
else if (tag & FT_CURVE_TAG_CONIC) != 0
|
||||
{
|
||||
// TODO(Ed): This is using a very dead simple algo to convert the conic to a cubic curve
|
||||
// not sure if we need something more sophisticaated
|
||||
point1 := points[ index + 1 ]
|
||||
|
||||
control_conv :: f32(0.5) // Conic to cubic control point distance
|
||||
to_float := f32(1.0 / 64.0)
|
||||
|
||||
fp := Vec2 { f32(point.x), f32(point.y) } * to_float
|
||||
fp1 := Vec2 { f32(point1.x), f32(point1.y) } * to_float
|
||||
|
||||
control1 := freetype.Vector {
|
||||
point.x + freetype.Pos( (fp1.x - fp.x) * control_conv * 64.0 ),
|
||||
point.y + freetype.Pos( (fp1.y - fp.y) * control_conv * 64.0 ),
|
||||
}
|
||||
control2 := freetype.Vector {
|
||||
point1.x + freetype.Pos( (fp.x - fp1.x) * control_conv * 64.0 ),
|
||||
point1.y + freetype.Pos( (fp.y - fp1.y) * control_conv * 64.0 ),
|
||||
}
|
||||
append(& vertices, ParserGlyphVertex { type = .Cubic,
|
||||
x = u16(point1.x), y = u16(point1.y),
|
||||
contour_x0 = u16(control1.x), contour_y0 = u16(control1.y),
|
||||
contour_x1 = u16(control2.x), contour_y1 = u16(control2.y),
|
||||
padding = 0,
|
||||
})
|
||||
index += 1
|
||||
}
|
||||
else
|
||||
{
|
||||
append(& vertices, ParserGlyphVertex { type = .Line,
|
||||
@ -280,6 +348,8 @@ parser_get_glyph_shape :: proc( font : ^ParserFontInfo, glyph_index : Glyph ) ->
|
||||
padding = 0,
|
||||
})
|
||||
}
|
||||
|
||||
shape = array_to_slice(vertices)
|
||||
}
|
||||
|
||||
case .STB_TrueType:
|
||||
@ -298,8 +368,17 @@ parser_get_glyph_shape :: proc( font : ^ParserFontInfo, glyph_index : Glyph ) ->
|
||||
|
||||
parser_free_shape :: proc( font : ^ParserFontInfo, shape : ParserGlyphShape )
|
||||
{
|
||||
// switch font.kind
|
||||
// {
|
||||
// case .Freetype
|
||||
// }
|
||||
switch font.kind
|
||||
{
|
||||
case .Freetype:
|
||||
delete( array_underlying_slice(shape) )
|
||||
|
||||
case .STB_TrueType:
|
||||
stbtt.FreeShape( & font.stbtt_info, transmute( [^]stbtt.vertex) raw_data(shape) )
|
||||
}
|
||||
}
|
||||
|
||||
parser_get_glyph_box :: proc( font : ^ParserFontInfo, glyph_index : Glyph ) -> (bounds_0, bounds_1 : Vec2i)
|
||||
{
|
||||
return
|
||||
}
|
Loading…
Reference in New Issue
Block a user