glyph cache progress
This commit is contained in:
parent
c8a9970438
commit
77434a988b
@ -1020,11 +1020,6 @@ Vec2 RoundVec2(Vec2 a)
|
|||||||
return VEC2(RoundF32(a.x), RoundF32(a.y));
|
return VEC2(RoundF32(a.x), RoundF32(a.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2I32 RoundVec2ToVec2I32(Vec2 a)
|
|
||||||
{
|
|
||||||
return VEC2I32(RoundF32ToI32(a.x), RoundF32ToI32(a.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2 FloorVec2(Vec2 a)
|
Vec2 FloorVec2(Vec2 a)
|
||||||
{
|
{
|
||||||
return VEC2(FloorF32(a.x), FloorF32(a.y));
|
return VEC2(FloorF32(a.x), FloorF32(a.y));
|
||||||
@ -1035,6 +1030,21 @@ Vec2 CeilVec2(Vec2 a)
|
|||||||
return VEC2(CeilF32(a.x), CeilF32(a.y));
|
return VEC2(CeilF32(a.x), CeilF32(a.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec2I32 RoundVec2ToI32(Vec2 a)
|
||||||
|
{
|
||||||
|
return VEC2I32(RoundF32ToI32(a.x), RoundF32ToI32(a.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec2I32 FloorVec2ToI32(Vec2 a)
|
||||||
|
{
|
||||||
|
return VEC2I32(FloorF32ToI32(a.x), FloorF32ToI32(a.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec2I32 CeilVec2ToI32(Vec2 a)
|
||||||
|
{
|
||||||
|
return VEC2I32(CeilF32ToI32(a.x), CeilF32ToI32(a.y));
|
||||||
|
}
|
||||||
|
|
||||||
//- Angle
|
//- Angle
|
||||||
|
|
||||||
/* Returns 1 if winding between vectors a & b is clockwise or straight, -1 if counter-clockwise */
|
/* Returns 1 if winding between vectors a & b is clockwise or straight, -1 if counter-clockwise */
|
||||||
@ -1184,16 +1194,16 @@ Rng2 UnionRng2(Rng2 a, Rng2 b)
|
|||||||
Rng2 AddRng2Vec2(Rng2 r, Vec2 v)
|
Rng2 AddRng2Vec2(Rng2 r, Vec2 v)
|
||||||
{
|
{
|
||||||
Rng2 result = ZI;
|
Rng2 result = ZI;
|
||||||
result.p0 = AddVec2(result.p0, v);
|
result.p0 = AddVec2(r.p0, v);
|
||||||
result.p1 = AddVec2(result.p1, v);
|
result.p1 = AddVec2(r.p1, v);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rng2 DivRng2Vec2(Rng2 r, Vec2 v)
|
Rng2 DivRng2Vec2(Rng2 r, Vec2 v)
|
||||||
{
|
{
|
||||||
Rng2 result = ZI;
|
Rng2 result = ZI;
|
||||||
result.p0 = DivVec2Vec2(result.p0, v);
|
result.p0 = DivVec2Vec2(r.p0, v);
|
||||||
result.p1 = DivVec2Vec2(result.p1, v);
|
result.p1 = DivVec2Vec2(r.p1, v);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1220,16 +1230,16 @@ Rng2I32 UnionRng2I32(Rng2I32 a, Rng2I32 b)
|
|||||||
Rng2I32 AddRng2I32Vec2I32(Rng2I32 r, Vec2I32 v)
|
Rng2I32 AddRng2I32Vec2I32(Rng2I32 r, Vec2I32 v)
|
||||||
{
|
{
|
||||||
Rng2I32 result = ZI;
|
Rng2I32 result = ZI;
|
||||||
result.p0 = AddVec2I32(result.p0, v);
|
result.p0 = AddVec2I32(r.p0, v);
|
||||||
result.p1 = AddVec2I32(result.p1, v);
|
result.p1 = AddVec2I32(r.p1, v);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rng2I32 DivRng2I32Vec2I32(Rng2I32 r, Vec2I32 v)
|
Rng2I32 DivRng2I32Vec2I32(Rng2I32 r, Vec2I32 v)
|
||||||
{
|
{
|
||||||
Rng2I32 result = ZI;
|
Rng2I32 result = ZI;
|
||||||
result.p0 = DivVec2I32Vec2I32(result.p0, v);
|
result.p0 = DivVec2I32Vec2I32(r.p0, v);
|
||||||
result.p1 = DivVec2I32Vec2I32(result.p1, v);
|
result.p1 = DivVec2I32Vec2I32(r.p1, v);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -349,9 +349,11 @@ Vec2 PerpVec2TowardsDir(Vec2 v, Vec2 dir);
|
|||||||
|
|
||||||
//- Round / floor / ceil
|
//- Round / floor / ceil
|
||||||
Vec2 RoundVec2(Vec2 a);
|
Vec2 RoundVec2(Vec2 a);
|
||||||
Vec2I32 RoundVec2ToVec2I32(Vec2 a);
|
|
||||||
Vec2 FloorVec2(Vec2 a);
|
Vec2 FloorVec2(Vec2 a);
|
||||||
Vec2 CeilVec2(Vec2 a);
|
Vec2 CeilVec2(Vec2 a);
|
||||||
|
Vec2I32 RoundVec2ToI32(Vec2 a);
|
||||||
|
Vec2I32 FloorVec2ToI32(Vec2 a);
|
||||||
|
Vec2I32 CeilVec2ToI32(Vec2 a);
|
||||||
|
|
||||||
//- Angle
|
//- Angle
|
||||||
i32 WindingFromVec2(Vec2 a, Vec2 b);
|
i32 WindingFromVec2(Vec2 a, Vec2 b);
|
||||||
|
|||||||
@ -69,8 +69,8 @@
|
|||||||
|
|
||||||
#define FLOOD_DEBUG 0
|
#define FLOOD_DEBUG 0
|
||||||
|
|
||||||
#define GPU_DEBUG 1
|
#define GPU_DEBUG 0
|
||||||
#define GPU_DEBUG_VALIDATION 1
|
#define GPU_DEBUG_VALIDATION 0
|
||||||
|
|
||||||
#define GPU_SHADER_PRINT 1
|
#define GPU_SHADER_PRINT 1
|
||||||
#define GPU_SHADER_PRINT_BUFFER_SIZE Kibi(64);
|
#define GPU_SHADER_PRINT_BUFFER_SIZE Kibi(64);
|
||||||
|
|||||||
@ -172,8 +172,8 @@ GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size
|
|||||||
GC_RunRect *rect = &result.rects[glyph_idx];
|
GC_RunRect *rect = &result.rects[glyph_idx];
|
||||||
|
|
||||||
rect->tex = glyph->tex_ref;
|
rect->tex = glyph->tex_ref;
|
||||||
rect->tex_uv = glyph->tex_uv;
|
rect->tex_slice = glyph->tex_slice;
|
||||||
rect->tex_rect = glyph->tex_rect;
|
rect->tex_slice_uv = glyph->tex_slice_uv;
|
||||||
|
|
||||||
rect->baseline_pos = baseline_pos;
|
rect->baseline_pos = baseline_pos;
|
||||||
rect->advance = glyph->advance;
|
rect->advance = glyph->advance;
|
||||||
@ -202,7 +202,7 @@ GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size
|
|||||||
result.font_cap = glyph->font_cap;
|
result.font_cap = glyph->font_cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.ready = uncached_codepoints_count == 0 && pending_glyphs_count;
|
result.ready = uncached_codepoints_count == 0 && pending_glyphs_count == 0;
|
||||||
|
|
||||||
EndScratch(scratch);
|
EndScratch(scratch);
|
||||||
return result;
|
return result;
|
||||||
@ -251,17 +251,22 @@ void GC_TickAsync(WaveLaneCtx *lane, AsyncTickCtx *tick)
|
|||||||
{
|
{
|
||||||
/* TODO: Remove this */
|
/* TODO: Remove this */
|
||||||
/* Create atlas */
|
/* Create atlas */
|
||||||
Vec2I32 atlas_size = VEC2I32(8192, 8192);
|
Vec2I32 atlas_dims = VEC2I32(1024, 1024);
|
||||||
if (G_IsResourceNil(GC.atlas))
|
if (G_IsResourceNil(GC.atlas))
|
||||||
{
|
{
|
||||||
G_ArenaHandle gpu_arena = G_PermArena();
|
G_ArenaHandle gpu_perm = G_PermArena();
|
||||||
GC.atlas = G_PushTexture2D(
|
GC.atlas = G_PushTexture2D(
|
||||||
gpu_arena,
|
gpu_perm,
|
||||||
G_Format_R8G8B8A8_Unorm_Srgb,
|
G_Format_R8G8B8A8_Unorm_Srgb,
|
||||||
atlas_size,
|
atlas_dims,
|
||||||
/* FIXME: We may need simultaneous access? */
|
/* FIXME: We may need simultaneous access? */
|
||||||
G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present,
|
// G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present,
|
||||||
|
|
||||||
|
|
||||||
|
G_Layout_Simultaneous,
|
||||||
|
.flags = G_ResourceFlag_HostMemory,
|
||||||
);
|
);
|
||||||
|
GC.atlas_ref = G_PushTexture2DRef(gpu_perm, GC.atlas);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u64 cmd_idx = 0; cmd_idx < async->cmds.count; ++cmd_idx)
|
for (u64 cmd_idx = 0; cmd_idx < async->cmds.count; ++cmd_idx)
|
||||||
@ -275,52 +280,51 @@ void GC_TickAsync(WaveLaneCtx *lane, AsyncTickCtx *tick)
|
|||||||
|
|
||||||
GC_GlyphDesc desc = glyph->desc;
|
GC_GlyphDesc desc = glyph->desc;
|
||||||
|
|
||||||
TTF_GlyphDesc ttf_desc = TTF_GlyphDescFromCodepoint(desc.codepoint, resource, desc.font_size);
|
TTF_GlyphResult ttf_info = TTF_RasterizeGlyphFromCodepoint(tick->arena, desc.codepoint, resource, desc.font_size);
|
||||||
glyph->font_size = ttf_desc.font_size;
|
glyph->font_size = desc.font_size;
|
||||||
glyph->font_ascent = ttf_desc.font_ascent;
|
glyph->font_ascent = ttf_info.font_ascent;
|
||||||
glyph->font_descent = ttf_desc.font_descent;
|
glyph->font_descent = ttf_info.font_descent;
|
||||||
glyph->font_cap = ttf_desc.font_cap;
|
glyph->font_cap = ttf_info.font_cap;
|
||||||
|
glyph->advance = ttf_info.advance;
|
||||||
|
glyph->bounds = ttf_info.bounds;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
u32 *image_pixels = ttf_info.image_pixels;
|
||||||
|
Vec2I32 image_dims = ttf_info.image_dims;
|
||||||
|
|
||||||
|
|
||||||
glyph->advance = ttf_desc.advance;
|
|
||||||
glyph->bounds = ttf_desc.bounds;
|
|
||||||
Vec2 dims = DimsFromRng2(glyph->bounds);
|
|
||||||
|
|
||||||
Vec2I32 atlas_offset = GC.atlas_pos;
|
Vec2I32 atlas_offset = GC.atlas_pos;
|
||||||
GC.atlas_row_height = MaxI32(GC.atlas_row_height, dims.y);
|
GC.atlas_row_height = MaxI32(GC.atlas_row_height, image_dims.y);
|
||||||
if (atlas_offset.x + dims.x > atlas_size.x);
|
if (atlas_offset.x + image_dims.x > atlas_dims.x);
|
||||||
{
|
{
|
||||||
GC.atlas_pos.x = 0;
|
GC.atlas_pos.x = 0;
|
||||||
GC.atlas_pos.y += GC.atlas_row_height;
|
GC.atlas_pos.y += GC.atlas_row_height;
|
||||||
GC.atlas_row_height = dims.y;
|
GC.atlas_row_height = image_dims.y;
|
||||||
}
|
}
|
||||||
GC.atlas_pos.x += dims.x;
|
GC.atlas_pos.x += image_dims.x;
|
||||||
|
|
||||||
Rng2I32 src_slice = ZI;
|
/* Atlas info */
|
||||||
src_slice.p0.x = 0;
|
glyph->tex_ref = GC.atlas_ref;
|
||||||
src_slice.p0.y = 0;
|
glyph->tex_slice = RNG2I32(atlas_offset, AddVec2I32(atlas_offset, image_dims));
|
||||||
src_slice.p1.x = RoundF32ToI32(dims.x);
|
glyph->tex_slice_uv.p0.x = (f32)glyph->tex_slice.p0.x / (f32)atlas_dims.x;
|
||||||
src_slice.p1.y = RoundF32ToI32(dims.y);
|
glyph->tex_slice_uv.p0.y = (f32)glyph->tex_slice.p0.y / (f32)atlas_dims.x;
|
||||||
|
glyph->tex_slice_uv.p1.x = (f32)glyph->tex_slice.p1.x / (f32)atlas_dims.x;
|
||||||
|
glyph->tex_slice_uv.p1.y = (f32)glyph->tex_slice.p1.y / (f32)atlas_dims.x;
|
||||||
|
|
||||||
Vec2I32 src_dims = DimsFromRng2I32(src_slice);
|
if (image_dims.x > 0 && image_dims.y > 0)
|
||||||
if (src_dims.x > 0 && src_dims.y > 0)
|
|
||||||
{
|
{
|
||||||
u64 src_pixels_count = src_dims.x * src_dims.y;
|
|
||||||
u32 *src_pixels = PushStructsNoZero(tick->arena, u32, src_pixels_count);
|
|
||||||
TTF_RasterizeGlyph(src_pixels, src_dims, src_slice, ttf_desc);
|
|
||||||
|
|
||||||
DEBUGBREAKABLE;
|
|
||||||
|
|
||||||
|
|
||||||
// G_CommandListHandle cl = G_PrepareCommandList(G_QueueKind_AsyncCopy);
|
// G_CommandListHandle cl = G_PrepareCommandList(G_QueueKind_AsyncCopy);
|
||||||
G_CommandListHandle cl = G_PrepareCommandList(G_QueueKind_Direct);
|
G_CommandListHandle cl = G_PrepareCommandList(G_QueueKind_Direct);
|
||||||
{
|
{
|
||||||
G_CopyCpuToTexture(
|
G_CopyCpuToTexture(
|
||||||
cl,
|
cl,
|
||||||
GC.atlas, VEC3I32(atlas_offset.x, atlas_offset.y, 0),
|
GC.atlas, VEC3I32(atlas_offset.x, atlas_offset.y, 0),
|
||||||
src_pixels, VEC3I32(src_dims.x, src_dims.y, 0),
|
image_pixels, VEC3I32(image_dims.x, image_dims.y, 0),
|
||||||
RNG3I32(
|
RNG3I32(
|
||||||
VEC3I32(src_slice.p0.x, src_slice.p0.y, 0),
|
VEC3I32(0, 0, 0),
|
||||||
VEC3I32(src_slice.p1.x, src_slice.p1.y, 1)
|
VEC3I32(image_dims.x, image_dims.y, 1)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -330,14 +334,105 @@ void GC_TickAsync(WaveLaneCtx *lane, AsyncTickCtx *tick)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Atomic32Set(&glyph->ready, 1);
|
Atomic32Set(&glyph->ready, 1);
|
||||||
|
|
||||||
// ResourceKey resource = desc.font.r;
|
|
||||||
// String resource_data = DataFromResource(resource);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WaveSync(lane);
|
WaveSync(lane);
|
||||||
|
|
||||||
|
// //////////////////////////////
|
||||||
|
// //- Allocate atlas rects
|
||||||
|
|
||||||
|
// if (lane->idx == 0)
|
||||||
|
// {
|
||||||
|
// /* TODO: Remove this */
|
||||||
|
// /* Create atlas */
|
||||||
|
// Vec2I32 atlas_dims = VEC2I32(8192, 8192);
|
||||||
|
// if (G_IsResourceNil(GC.atlas))
|
||||||
|
// {
|
||||||
|
// G_ArenaHandle gpu_perm = G_PermArena();
|
||||||
|
// GC.atlas = G_PushTexture2D(
|
||||||
|
// gpu_perm,
|
||||||
|
// G_Format_R8G8B8A8_Unorm_Srgb,
|
||||||
|
// atlas_dims,
|
||||||
|
// /* FIXME: We may need simultaneous access? */
|
||||||
|
// G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for (u64 cmd_idx = 0; cmd_idx < async->cmds.count; ++cmd_idx)
|
||||||
|
// {
|
||||||
|
// GC_Cmd *cmd = &async->cmds.v[cmd_idx];
|
||||||
|
// GC_Glyph *glyph = cmd->glyph;
|
||||||
|
|
||||||
|
// ResourceKey resource = glyph->desc.font.r;
|
||||||
|
// String resource_data = DataFromResource(resource);
|
||||||
|
// String resource_name = NameFromResource(resource);
|
||||||
|
|
||||||
|
// GC_GlyphDesc desc = glyph->desc;
|
||||||
|
|
||||||
|
// TTF_GlyphDesc ttf_desc = TTF_GlyphDescFromCodepoint(desc.codepoint, resource, desc.font_size);
|
||||||
|
// glyph->font_size = ttf_desc.font_size;
|
||||||
|
// glyph->font_ascent = ttf_desc.font_ascent;
|
||||||
|
// glyph->font_descent = ttf_desc.font_descent;
|
||||||
|
// glyph->font_cap = ttf_desc.font_cap;
|
||||||
|
|
||||||
|
// glyph->advance = ttf_desc.advance;
|
||||||
|
// glyph->bounds = ttf_desc.bounds;
|
||||||
|
// Vec2 dims = DimsFromRng2(glyph->bounds);
|
||||||
|
|
||||||
|
// Vec2I32 atlas_offset = GC.atlas_pos;
|
||||||
|
// GC.atlas_row_height = MaxI32(GC.atlas_row_height, dims.y);
|
||||||
|
// if (atlas_offset.x + dims.x > atlas_dims.x);
|
||||||
|
// {
|
||||||
|
// GC.atlas_pos.x = 0;
|
||||||
|
// GC.atlas_pos.y += GC.atlas_row_height;
|
||||||
|
// GC.atlas_row_height = dims.y;
|
||||||
|
// }
|
||||||
|
// GC.atlas_pos.x += dims.x;
|
||||||
|
|
||||||
|
// Rng2I32 src_slice = ZI;
|
||||||
|
// src_slice.p0.x = 0;
|
||||||
|
// src_slice.p0.y = 0;
|
||||||
|
// src_slice.p1.x = RoundF32ToI32(dims.x);
|
||||||
|
// src_slice.p1.y = RoundF32ToI32(dims.y);
|
||||||
|
|
||||||
|
// Vec2I32 src_dims = DimsFromRng2I32(src_slice);
|
||||||
|
// if (src_dims.x > 0 && src_dims.y > 0)
|
||||||
|
// {
|
||||||
|
// u64 src_pixels_count = src_dims.x * src_dims.y;
|
||||||
|
// u32 *src_pixels = PushStructsNoZero(tick->arena, u32, src_pixels_count);
|
||||||
|
// TTF_RasterizeGlyph(src_pixels, src_dims, src_slice, ttf_desc);
|
||||||
|
|
||||||
|
// DEBUGBREAKABLE;
|
||||||
|
|
||||||
|
|
||||||
|
// // G_CommandListHandle cl = G_PrepareCommandList(G_QueueKind_AsyncCopy);
|
||||||
|
// G_CommandListHandle cl = G_PrepareCommandList(G_QueueKind_Direct);
|
||||||
|
// {
|
||||||
|
// G_CopyCpuToTexture(
|
||||||
|
// cl,
|
||||||
|
// GC.atlas, VEC3I32(atlas_offset.x, atlas_offset.y, 0),
|
||||||
|
// src_pixels, VEC3I32(src_dims.x, src_dims.y, 0),
|
||||||
|
// RNG3I32(
|
||||||
|
// VEC3I32(src_slice.p0.x, src_slice.p0.y, 0),
|
||||||
|
// VEC3I32(src_slice.p1.x, src_slice.p1.y, 1)
|
||||||
|
// )
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// G_CommitCommandList(cl);
|
||||||
|
|
||||||
|
// G_SyncCpu(G_QueueMask_All);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Atomic32Set(&glyph->ready, 1);
|
||||||
|
|
||||||
|
// // ResourceKey resource = desc.font.r;
|
||||||
|
// // String resource_data = DataFromResource(resource);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// WaveSync(lane);
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Process cmds
|
//- Process cmds
|
||||||
|
|
||||||
@ -365,253 +460,3 @@ void GC_TickAsync(WaveLaneCtx *lane, AsyncTickCtx *tick)
|
|||||||
|
|
||||||
WaveSync(lane);
|
WaveSync(lane);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////
|
|
||||||
// //~ Font load job
|
|
||||||
|
|
||||||
// JobImpl(F_Load, sig, _)
|
|
||||||
// {
|
|
||||||
// TempArena scratch = BeginScratchNoConflict();
|
|
||||||
|
|
||||||
// PERSIST Readonly u32 font_codes[] = {
|
|
||||||
// 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,
|
|
||||||
// 0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,
|
|
||||||
// 0x3C,0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
|
|
||||||
// 0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
|
|
||||||
// 0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,0x60,0x61,0x62,0x63,0x64,0x65,
|
|
||||||
// 0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,0x73,
|
|
||||||
// 0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,0x80,0x81,
|
|
||||||
// 0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
|
|
||||||
// 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,
|
|
||||||
// 0x9E,0x9F,0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,
|
|
||||||
// 0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,
|
|
||||||
// 0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
|
|
||||||
// 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,
|
|
||||||
// 0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,0xE2,0xE3,
|
|
||||||
// 0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,
|
|
||||||
// 0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
|
|
||||||
// };
|
|
||||||
|
|
||||||
// ResourceKey resource = sig->resource;
|
|
||||||
// String name = NameFromResource(resource);
|
|
||||||
// f32 font_size = sig->size;
|
|
||||||
// f32 em_size = font_size * (3.0 / 4.0);
|
|
||||||
// AC_Asset *asset = sig->asset;
|
|
||||||
|
|
||||||
// LogInfoF("Loading font \"%F\" (font size: %F, em size: %F)", FmtString(name), FmtFloat((f64)font_size), FmtFloat((f64)em_size));
|
|
||||||
// i64 start_ns = TimeNs();
|
|
||||||
|
|
||||||
// Assert(StringEndsWith(name, Lit(".ttf")));
|
|
||||||
// Assert(countof(font_codes) < F_LookupTableSize);
|
|
||||||
|
|
||||||
// /* Decode */
|
|
||||||
// String resource_data = DataFromResource(resource);
|
|
||||||
// if (resource_data.len == 0)
|
|
||||||
// {
|
|
||||||
// /* FIME: Load baked font instead of panicking */
|
|
||||||
// Panic(StringF(scratch.arena,
|
|
||||||
// "Font \"%F\" not found",
|
|
||||||
// FmtString(name)));
|
|
||||||
// }
|
|
||||||
// TTF_Decoded decoded = TTF_Decode(scratch.arena, resource_data, em_size, font_codes, countof(font_codes));
|
|
||||||
|
|
||||||
// /* Upload texture to GPU */
|
|
||||||
// Fence completion_fence = ZI;
|
|
||||||
// {
|
|
||||||
// GPU_CommandList *cl = GPU_BeginCommandList(GPU_QueueKind_BackgroundCopy);
|
|
||||||
// GPU_Arena *gpu_temp = GPU_AcquireArena();
|
|
||||||
// {
|
|
||||||
// GpuTexture gpu_texture = ZI;
|
|
||||||
// {
|
|
||||||
// GPU_Arena *gpu_perm = GPU_Perm();
|
|
||||||
// GPU_ResourceDesc desc = ZI;
|
|
||||||
// desc.texture.format = GPU_Format_R8G8B8A8_Unorm_Srgb;
|
|
||||||
// desc.texture.size = VEC3I32(decoded.image_width, decoded.image_height, 1);
|
|
||||||
// gpu_texture = GPU_PushTexture(gpu_perm, GPU_TextureKind_2D, desc);
|
|
||||||
// }
|
|
||||||
// texture->gpu_texture = gpu_texture;
|
|
||||||
// texture->width = decoded.width;
|
|
||||||
// texture->height = decoded.height;
|
|
||||||
// GpuBuffer src_buff = GPU_PushBuffer(gpu_temp, GPU_GetFootprintSize(gpu_texture), GPU_BufferFlag_CpuWritable);
|
|
||||||
// GpuAddress src_addr = ZI;
|
|
||||||
// {
|
|
||||||
// u32 *p = GPU_PushStructsNoZero(src_buff, u32, decoded.width * decoded.height);
|
|
||||||
// CopyStructs(p, decoded.pixels, decoded.width * decoded.heigth);
|
|
||||||
// GPU_TransitionBufferToCopySrc(src_buff);
|
|
||||||
// GPU_TransitionTextureToCopyDst(gpu_texture);
|
|
||||||
// GPU_CopyBytesToFootprint(gpu_texture, src_buff, src_addr, decoded.width * decoded.height * 4);
|
|
||||||
// GPU_TransitionTextureToReadonly(gpu_texture);
|
|
||||||
// }
|
|
||||||
// GPU_SetFence(&completion_fence, 1);
|
|
||||||
// }
|
|
||||||
// GPU_ReleaseArena(gpu_temp);
|
|
||||||
// GPU_EndCommandList(cl);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* Acquire store memory */
|
|
||||||
// F_Font *font = 0;
|
|
||||||
// {
|
|
||||||
// AC_Store store = AC_OpenStore();
|
|
||||||
// font = PushStruct(store.arena, F_Font);
|
|
||||||
// font->glyphs = PushStructsNoZero(store.arena, F_Glyph, decoded.glyphs_count);
|
|
||||||
// font->lookup = PushStructs(store.arena, u16, F_LookupTableSize);
|
|
||||||
// AC_CloseStore(&store);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* Set font data */
|
|
||||||
// font->texture = texture;
|
|
||||||
// font->image_width = decoded.image_width;
|
|
||||||
// font->image_height = decoded.image_height;
|
|
||||||
// font->glyphs_count = decoded.glyphs_count;
|
|
||||||
// font->size = font_size;
|
|
||||||
// font->ascent = decoded.ascent;
|
|
||||||
// font->descent = decoded.descent;
|
|
||||||
// font->cap = decoded.cap;
|
|
||||||
|
|
||||||
// /* FIXME: Load baked font instead of panicking */
|
|
||||||
// if (font->glyphs_count <= 0)
|
|
||||||
// {
|
|
||||||
// Panic(StringF(scratch.arena,
|
|
||||||
// "Parsed 0 glyphs from font \"%F\"!",
|
|
||||||
// FmtString(name)));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* Copy glyphs from decode decoded */
|
|
||||||
// /* NOTE: Font glyph size must match TTF glyph size for memcpy */
|
|
||||||
// StaticAssert(sizeof(*font->glyphs) == sizeof(*decoded.glyphs));
|
|
||||||
// CopyBytes(font->glyphs, decoded.glyphs, sizeof(*font->glyphs) * decoded.glyphs_count);
|
|
||||||
|
|
||||||
// /* Build lookup table */
|
|
||||||
// for (u64 i = 0; i < countof(font_codes); ++i)
|
|
||||||
// {
|
|
||||||
// u32 codepoint = font_codes[i];
|
|
||||||
// font->lookup[codepoint] = decoded.cache_indices[i];
|
|
||||||
// }
|
|
||||||
|
|
||||||
// YieldOnFence(&completion_fence, 1);
|
|
||||||
|
|
||||||
// LogSuccessF("Loaded font \"%F\" (font size: %F, em size: %F) in %F seconds", FmtString(name), FmtFloat((f64)font_size), FmtFloat((f64)em_size), FmtFloat(SecondsFromNs(TimeNs() - start_ns)));
|
|
||||||
// AC_MarkReady(asset, font);
|
|
||||||
|
|
||||||
// EndScratch(scratch);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ////////////////////////////////////////////////////////////
|
|
||||||
// //~ Font load
|
|
||||||
|
|
||||||
// /* Returns the asset from the asset cache */
|
|
||||||
// AC_Asset *F_LoadAsset(ResourceKey resource, f32 size, b32 wait)
|
|
||||||
// {
|
|
||||||
// TempArena scratch = BeginScratchNoConflict();
|
|
||||||
// String name = NameFromResource(resource);
|
|
||||||
|
|
||||||
// /* Concatenate size to name for key */
|
|
||||||
// String key = StringF(scratch.arena,
|
|
||||||
// "%F%F_font",
|
|
||||||
// FmtString(name),
|
|
||||||
// FmtFloatP((f64)size, 1));
|
|
||||||
// u64 hash = AC_HashFromKey(key);
|
|
||||||
// b32 is_first_touch;
|
|
||||||
// AC_Asset *asset = AC_TouchCache(key, hash, &is_first_touch);
|
|
||||||
|
|
||||||
// if (is_first_touch)
|
|
||||||
// {
|
|
||||||
// AC_MarkLoading(asset);
|
|
||||||
// {
|
|
||||||
// Job *job = OpenJob(F_Load, AsyncPool());
|
|
||||||
// F_Load_Sig *sig = PushStruct(job->arena, F_Load_Sig);
|
|
||||||
// job->sig = sig;
|
|
||||||
// sig->asset = asset;
|
|
||||||
// sig->resource = resource;
|
|
||||||
// sig->size = size;
|
|
||||||
// CloseJob(job);
|
|
||||||
// }
|
|
||||||
// if (wait)
|
|
||||||
// {
|
|
||||||
// AC_YieldOnAssetReady(asset);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// EndScratch(scratch);
|
|
||||||
// return asset;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// F_Font *F_LoadFontAsync(ResourceKey resource, f32 point_size)
|
|
||||||
// {
|
|
||||||
// AC_Asset *asset = F_LoadAsset(resource, point_size, 0);
|
|
||||||
// F_Font *f = (F_Font *)AC_DataFromStore(asset);
|
|
||||||
// return f;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// F_Font *F_LoadFontWait(ResourceKey resource, f32 point_size)
|
|
||||||
// {
|
|
||||||
// AC_Asset *asset = F_LoadAsset(resource, point_size, 1);
|
|
||||||
// AC_YieldOnAssetReady(asset);
|
|
||||||
// F_Font *f = (F_Font *)AC_DataFromStore(asset);
|
|
||||||
// return f;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ////////////////////////////////////////////////////////////
|
|
||||||
// //~ Font data
|
|
||||||
|
|
||||||
// F_Glyph F_GlyphFromCodepoint(F_Font *font, u32 codepoint)
|
|
||||||
// {
|
|
||||||
// if (codepoint < F_LookupTableSize)
|
|
||||||
// {
|
|
||||||
// u16 index = font->lookup[codepoint];
|
|
||||||
// if (index < font->glyphs_count)
|
|
||||||
// {
|
|
||||||
// return font->glyphs[index];
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (codepoint == '?')
|
|
||||||
// {
|
|
||||||
// return font->glyphs[font->lookup[0]];
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// return font->glyphs[font->lookup['?']];
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// F_Run F_RunFromString(Arena *arena, F_Font *font, String str)
|
|
||||||
// {
|
|
||||||
// F_Run result = ZI;
|
|
||||||
// result.rects = ArenaNext(arena, F_RunRect);
|
|
||||||
|
|
||||||
// f32 baseline_length = 0;
|
|
||||||
// for (CodepointIter it = InitCodepointIter(str); NextCodepoint(&it);)
|
|
||||||
// {
|
|
||||||
// u32 codepoint = it.codepoint;
|
|
||||||
// if (font->glyphs_count <= codepoint)
|
|
||||||
// {
|
|
||||||
// codepoint = '?';
|
|
||||||
// }
|
|
||||||
// if (codepoint < font->glyphs_count)
|
|
||||||
// {
|
|
||||||
// u16 index = font->lookup[codepoint];
|
|
||||||
// F_Glyph glyph = font->glyphs[index];
|
|
||||||
// F_RunRect *rect = PushStruct(arena, F_RunRect);
|
|
||||||
// ++result.count;
|
|
||||||
|
|
||||||
// rect->atlas_p0 = glyph.atlas_p0;
|
|
||||||
// rect->atlas_p1 = glyph.atlas_p1;
|
|
||||||
// Vec2I32 size = SubVec2I32(glyph.atlas_p1, glyph.atlas_p0);
|
|
||||||
|
|
||||||
// rect->pos = baseline_length;
|
|
||||||
// rect->offset = glyph.baseline_offset;
|
|
||||||
// rect->advance = glyph.advance;
|
|
||||||
|
|
||||||
// result.p0.x = MinF32(result.p0.x, rect->offset.x + rect->pos); /* Left run bounds */
|
|
||||||
// result.p1.x = MaxF32(result.p1.x, rect->offset.x + rect->pos + size.x); /* Right run bounds */
|
|
||||||
// result.p0.y = MinF32(result.p0.y, rect->offset.y); /* Top run bounds */
|
|
||||||
// result.p1.y = MaxF32(result.p1.y, rect->offset.y + size.y); /* Bottom run bounds */
|
|
||||||
|
|
||||||
// baseline_length += rect->advance;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
|
|||||||
@ -33,12 +33,12 @@ Struct(GC_Glyph)
|
|||||||
|
|
||||||
/* Layout info */
|
/* Layout info */
|
||||||
f32 advance;
|
f32 advance;
|
||||||
Rng2 bounds; /* Bounds relative to baseline position */
|
Rng2 bounds;
|
||||||
|
|
||||||
/* Atlas info */
|
/* Atlas info */
|
||||||
G_Texture2DRef tex_ref;
|
G_Texture2DRef tex_ref;
|
||||||
Rng2 tex_uv;
|
Rng2I32 tex_slice;
|
||||||
Rng2 tex_rect;
|
Rng2 tex_slice_uv;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(GC_GlyphBin)
|
Struct(GC_GlyphBin)
|
||||||
@ -63,8 +63,8 @@ Struct(GC_RunRect)
|
|||||||
f32 advance;
|
f32 advance;
|
||||||
|
|
||||||
G_Texture2DRef tex;
|
G_Texture2DRef tex;
|
||||||
Rng2 tex_uv;
|
Rng2I32 tex_slice;
|
||||||
Rng2 tex_rect;
|
Rng2 tex_slice_uv;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(GC_Run)
|
Struct(GC_Run)
|
||||||
@ -161,77 +161,3 @@ GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size
|
|||||||
//~ Async
|
//~ Async
|
||||||
|
|
||||||
void GC_TickAsync(WaveLaneCtx *lane, AsyncTickCtx *ctx);
|
void GC_TickAsync(WaveLaneCtx *lane, AsyncTickCtx *ctx);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ////////////////////////////////////////////////////////////
|
|
||||||
// //~ Font types
|
|
||||||
|
|
||||||
// Struct(GC_FontKey)
|
|
||||||
// {
|
|
||||||
// u64 v;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Struct(GC_Glyph)
|
|
||||||
// {
|
|
||||||
// i32 advance;
|
|
||||||
// Vec2 baseline_offset;
|
|
||||||
// Vec2I32 atlas_p0;
|
|
||||||
// Vec2I32 atlas_p1;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Struct(GC_Font)
|
|
||||||
// {
|
|
||||||
// GPU_Resource *texture;
|
|
||||||
// u32 image_width;
|
|
||||||
// u32 image_height;
|
|
||||||
// u16 glyphs_count;
|
|
||||||
// F_Glyph *glyphs;
|
|
||||||
// u16 *lookup;
|
|
||||||
|
|
||||||
// /* Metrics */
|
|
||||||
// f32 size;
|
|
||||||
// f32 ascent;
|
|
||||||
// f32 descent;
|
|
||||||
// f32 cap;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// ////////////////////////////////////////////////////////////
|
|
||||||
// //~ Run types
|
|
||||||
|
|
||||||
// Struct(F_RunRect)
|
|
||||||
// {
|
|
||||||
// Vec2 offset; /* Vector from baseline offset to top left of glyph rect */
|
|
||||||
// f32 pos; /* Horizontal distance from start of baseline */
|
|
||||||
// f32 advance;
|
|
||||||
// Vec2I32 atlas_p0;
|
|
||||||
// Vec2I32 atlas_p1;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Struct(F_Run)
|
|
||||||
// {
|
|
||||||
// Vec2 p0; /* Start of baseline to top-left-most rect */
|
|
||||||
// Vec2 p1; /* Start of baseline to bottom-right-most rect corner */
|
|
||||||
// u32 count;
|
|
||||||
// F_RunRect *rects;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// ////////////////////////////////////////////////////////////
|
|
||||||
// //~ Font load job
|
|
||||||
|
|
||||||
// JobDecl(F_Load, { AC_Asset *asset; f32 size; ResourceKey resource; });
|
|
||||||
|
|
||||||
// ////////////////////////////////////////////////////////////
|
|
||||||
// //~ Font load
|
|
||||||
|
|
||||||
// AC_Asset *F_LoadAsset(ResourceKey resource, f32 size, b32 wait);
|
|
||||||
// F_Font *F_LoadFontAsync(ResourceKey resource, f32 size);
|
|
||||||
// F_Font *F_LoadFontWait(ResourceKey resource, f32 size);
|
|
||||||
|
|
||||||
// ////////////////////////////////////////////////////////////
|
|
||||||
// //~ Run
|
|
||||||
|
|
||||||
// F_Glyph F_GlyphFromCodepoint(F_Font *font, u32 codepoint);
|
|
||||||
// F_Run F_RunFromString(Arena *arena, F_Font *font, String str);
|
|
||||||
|
|||||||
@ -2331,8 +2331,8 @@ void G_CopyBufferToBuffer(G_CommandListHandle cl_handle, G_ResourceHandle dst_ha
|
|||||||
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
|
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
|
||||||
G_D12_Cmd *cmd = G_D12_PushCmd(cl);
|
G_D12_Cmd *cmd = G_D12_PushCmd(cl);
|
||||||
cmd->kind = G_D12_CmdKind_CopyBytes;
|
cmd->kind = G_D12_CmdKind_CopyBytes;
|
||||||
cmd->copy_bytes.dst = G_D12_ResourceFromHandle(dst_handle);
|
|
||||||
cmd->copy_bytes.src = G_D12_ResourceFromHandle(src_handle);
|
cmd->copy_bytes.src = G_D12_ResourceFromHandle(src_handle);
|
||||||
|
cmd->copy_bytes.dst = G_D12_ResourceFromHandle(dst_handle);
|
||||||
cmd->copy_bytes.dst_offset = dst_offset;
|
cmd->copy_bytes.dst_offset = dst_offset;
|
||||||
cmd->copy_bytes.src_copy_range = src_copy_range;
|
cmd->copy_bytes.src_copy_range = src_copy_range;
|
||||||
}
|
}
|
||||||
@ -2341,13 +2341,13 @@ void G_CopyBufferToTexture(G_CommandListHandle cl_handle, G_ResourceHandle dst_h
|
|||||||
{
|
{
|
||||||
G_D12_SharedState *g = &G_D12_shared_state;
|
G_D12_SharedState *g = &G_D12_shared_state;
|
||||||
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
|
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
|
||||||
G_D12_Resource *dst = G_D12_ResourceFromHandle(dst_handle);
|
|
||||||
G_D12_Resource *src = G_D12_ResourceFromHandle(src_handle);
|
G_D12_Resource *src = G_D12_ResourceFromHandle(src_handle);
|
||||||
Assert(dst->is_texture);
|
G_D12_Resource *dst = G_D12_ResourceFromHandle(dst_handle);
|
||||||
Assert(!src->is_texture);
|
Assert(!src->is_texture);
|
||||||
|
Assert(dst->is_texture);
|
||||||
|
|
||||||
/* Grab footprint info */
|
/* Grab footprint info */
|
||||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT footprint = ZI;
|
D3D12_PLACED_SUBRESOURCE_FOOTPRINT src_footprint = ZI;
|
||||||
{
|
{
|
||||||
D3D12_RESOURCE_DESC src_desc = ZI;
|
D3D12_RESOURCE_DESC src_desc = ZI;
|
||||||
{
|
{
|
||||||
@ -2356,21 +2356,21 @@ void G_CopyBufferToTexture(G_CommandListHandle cl_handle, G_ResourceHandle dst_h
|
|||||||
src_desc.Height = src_dims.y;
|
src_desc.Height = src_dims.y;
|
||||||
src_desc.DepthOrArraySize = src_dims.z;
|
src_desc.DepthOrArraySize = src_dims.z;
|
||||||
}
|
}
|
||||||
ID3D12Device_GetCopyableFootprints(g->device, &src_desc, 0, 1, 0, &footprint, 0, 0, 0);
|
ID3D12Device_GetCopyableFootprints(g->device, &src_desc, 0, 1, 0, &src_footprint, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION dst_loc = ZI;
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION src_loc = ZI;
|
D3D12_TEXTURE_COPY_LOCATION src_loc = ZI;
|
||||||
|
D3D12_TEXTURE_COPY_LOCATION dst_loc = ZI;
|
||||||
|
{
|
||||||
|
src_loc.pResource = src->d3d_resource;
|
||||||
|
src_loc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||||
|
src_loc.PlacedFootprint = src_footprint;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
dst_loc.pResource = dst->d3d_resource;
|
dst_loc.pResource = dst->d3d_resource;
|
||||||
dst_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
dst_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||||
dst_loc.SubresourceIndex = 0;
|
dst_loc.SubresourceIndex = 0;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
src_loc.pResource = src->d3d_resource;
|
|
||||||
src_loc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
|
||||||
src_loc.PlacedFootprint = footprint;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_D12_Cmd *cmd = G_D12_PushCmd(cl);
|
G_D12_Cmd *cmd = G_D12_PushCmd(cl);
|
||||||
cmd->kind = G_D12_CmdKind_CopyTexels;
|
cmd->kind = G_D12_CmdKind_CopyTexels;
|
||||||
@ -2386,23 +2386,23 @@ void G_CopyTextureToTexture(G_CommandListHandle cl_handle, G_ResourceHandle dst_
|
|||||||
{
|
{
|
||||||
G_D12_SharedState *g = &G_D12_shared_state;
|
G_D12_SharedState *g = &G_D12_shared_state;
|
||||||
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
|
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
|
||||||
G_D12_Resource *dst = G_D12_ResourceFromHandle(dst_handle);
|
|
||||||
G_D12_Resource *src = G_D12_ResourceFromHandle(src_handle);
|
G_D12_Resource *src = G_D12_ResourceFromHandle(src_handle);
|
||||||
Assert(dst->is_texture);
|
G_D12_Resource *dst = G_D12_ResourceFromHandle(dst_handle);
|
||||||
Assert(src->is_texture);
|
Assert(src->is_texture);
|
||||||
|
Assert(dst->is_texture);
|
||||||
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION dst_loc = ZI;
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION src_loc = ZI;
|
D3D12_TEXTURE_COPY_LOCATION src_loc = ZI;
|
||||||
{
|
D3D12_TEXTURE_COPY_LOCATION dst_loc = ZI;
|
||||||
dst_loc.pResource = dst->d3d_resource;
|
|
||||||
dst_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
|
||||||
dst_loc.SubresourceIndex = 0;
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
src_loc.pResource = dst->d3d_resource;
|
src_loc.pResource = dst->d3d_resource;
|
||||||
src_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
src_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||||
src_loc.SubresourceIndex = 0;
|
src_loc.SubresourceIndex = 0;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
dst_loc.pResource = dst->d3d_resource;
|
||||||
|
dst_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||||
|
dst_loc.SubresourceIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
G_D12_Cmd *cmd = G_D12_PushCmd(cl);
|
G_D12_Cmd *cmd = G_D12_PushCmd(cl);
|
||||||
cmd->kind = G_D12_CmdKind_CopyTexels;
|
cmd->kind = G_D12_CmdKind_CopyTexels;
|
||||||
@ -2900,7 +2900,7 @@ void G_D12_CollectionWorkerEntryPoint(WaveLaneCtx *lane)
|
|||||||
TempArena scratch = BeginScratchNoConflict();
|
TempArena scratch = BeginScratchNoConflict();
|
||||||
u8 *at = start;
|
u8 *at = start;
|
||||||
{
|
{
|
||||||
for (u32 print_num = 1; print_num <= prints_count; ++print_num)
|
for (u32 print_idx = 0; print_idx < prints_count; ++print_idx)
|
||||||
{
|
{
|
||||||
u32 chars_count = 0;
|
u32 chars_count = 0;
|
||||||
u32 args_count = 0;
|
u32 args_count = 0;
|
||||||
|
|||||||
@ -249,7 +249,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
{
|
{
|
||||||
/* TODO: Don't rely on ui report for draw size since it introduces one frame of delay when resizing */
|
/* TODO: Don't rely on ui report for draw size since it introduces one frame of delay when resizing */
|
||||||
UI_Report vis_rep = UI_ReportFromKey(vis_box);
|
UI_Report vis_rep = UI_ReportFromKey(vis_box);
|
||||||
draw_size = RoundVec2ToVec2I32(DimsFromRng2(vis_rep.screen_rect));
|
draw_size = RoundVec2ToI32(DimsFromRng2(vis_rep.screen_rect));
|
||||||
}
|
}
|
||||||
draw_size.x = MaxI32(draw_size.x, 1);
|
draw_size.x = MaxI32(draw_size.x, 1);
|
||||||
draw_size.y = MaxI32(draw_size.y, 1);
|
draw_size.y = MaxI32(draw_size.y, 1);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Glyph types
|
//~ Glyph types
|
||||||
|
|
||||||
Struct(TTF_GlyphDesc)
|
Struct(TTF_GlyphResult)
|
||||||
{
|
{
|
||||||
ResourceKey ttf;
|
ResourceKey ttf;
|
||||||
u32 codepoint;
|
u32 codepoint;
|
||||||
@ -13,15 +13,18 @@ Struct(TTF_GlyphDesc)
|
|||||||
f32 font_ascent;
|
f32 font_ascent;
|
||||||
f32 font_descent;
|
f32 font_descent;
|
||||||
f32 font_cap;
|
f32 font_cap;
|
||||||
|
|
||||||
|
/* Rasterization output */
|
||||||
|
Vec2I32 image_dims;
|
||||||
|
u32 *image_pixels;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Bootstrap
|
//~ @hookdecl Bootstrap
|
||||||
|
|
||||||
void TTF_Bootstrap(void);
|
void TTF_Bootstrap(void);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Decode
|
//~ @hookdecl Rasterize
|
||||||
|
|
||||||
TTF_GlyphDesc TTF_GlyphDescFromCodepoint(u32 codepoint, ResourceKey ttf, f32 font_size);
|
TTF_GlyphResult TTF_RasterizeGlyphFromCodepoint(Arena *arena, u32 codepoint, ResourceKey ttf, f32 font_size);
|
||||||
void TTF_RasterizeGlyph(u32 *dst, Vec2I32 dst_size, Rng2I32 dst_slice, TTF_GlyphDesc glyph_desc);
|
|
||||||
|
|||||||
@ -24,23 +24,21 @@ void TTF_Bootstrap(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ @hookimpl Decode
|
//~ @hookimpl Rasterize
|
||||||
|
|
||||||
TTF_GlyphDesc TTF_GlyphDescFromCodepoint(u32 codepoint, ResourceKey ttf, f32 font_size)
|
TTF_GlyphResult TTF_RasterizeGlyphFromCodepoint(Arena *arena, u32 codepoint, ResourceKey ttf, f32 font_size)
|
||||||
{
|
{
|
||||||
String encoded = DataFromResource(ttf);
|
COLORREF bg_color = 0xFF000000;
|
||||||
|
COLORREF fg_color = 0xFFFFFFFF;
|
||||||
/* TODO: Handle errors */
|
|
||||||
HRESULT hr = 0;
|
|
||||||
|
|
||||||
TTF_GlyphDesc result = ZI;
|
|
||||||
result.font_size = font_size;
|
|
||||||
result.ttf = ttf;
|
|
||||||
result.codepoint = codepoint;
|
|
||||||
|
|
||||||
f32 em_size = font_size * (3.0 / 4.0);
|
f32 em_size = font_size * (3.0 / 4.0);
|
||||||
f32 pixel_per_em = em_size * (TTF_DW_Dpi / 72.0f);
|
f32 pixel_per_em = em_size * (TTF_DW_Dpi / 72.0f);
|
||||||
|
|
||||||
|
/* TODO: handle errors */
|
||||||
|
HRESULT hr = 0;
|
||||||
|
|
||||||
|
String encoded = DataFromResource(ttf);
|
||||||
|
|
||||||
/* File */
|
/* File */
|
||||||
IDWriteFontFile *font_file = 0;
|
IDWriteFontFile *font_file = 0;
|
||||||
{
|
{
|
||||||
@ -61,88 +59,39 @@ TTF_GlyphDesc TTF_GlyphDescFromCodepoint(u32 codepoint, ResourceKey ttf, f32 fon
|
|||||||
hr = IDWriteFactory5_CreateFontFace(TTF_DW.factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &font_file, 0, DWRITE_FONT_SIMULATIONS_NONE, &font_face);
|
hr = IDWriteFactory5_CreateFontFace(TTF_DW.factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &font_file, 0, DWRITE_FONT_SIMULATIONS_NONE, &font_face);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Glyph idx */
|
||||||
|
u16 glyph_idx = 0;
|
||||||
|
{
|
||||||
|
hr = IDWriteFontFace_GetGlyphIndices(font_face, &codepoint, 1, &glyph_idx);
|
||||||
|
}
|
||||||
|
|
||||||
/* Font metrics */
|
/* Font metrics */
|
||||||
DWRITE_FONT_METRICS font_metrics = ZI;
|
DWRITE_FONT_METRICS font_metrics = ZI;
|
||||||
{
|
{
|
||||||
IDWriteFontFace_GetMetrics(font_face, &font_metrics);
|
IDWriteFontFace_GetMetrics(font_face, &font_metrics);
|
||||||
}
|
}
|
||||||
f32 pixel_per_design_unit = pixel_per_em / ((f32)font_metrics.designUnitsPerEm);
|
f32 pixel_per_design_unit = pixel_per_em / ((f32)font_metrics.designUnitsPerEm);
|
||||||
result.font_ascent = font_metrics.ascent * pixel_per_design_unit;
|
f32 font_ascent = font_metrics.ascent * pixel_per_design_unit;
|
||||||
result.font_descent = font_metrics.descent * pixel_per_design_unit;
|
f32 font_descent = font_metrics.descent * pixel_per_design_unit;
|
||||||
result.font_cap = font_metrics.capHeight * pixel_per_design_unit;
|
f32 font_cap = font_metrics.capHeight * pixel_per_design_unit;
|
||||||
|
|
||||||
/* Glyph idx */
|
|
||||||
u16 glyph_idx = 0;
|
|
||||||
{
|
|
||||||
hr = IDWriteFontFace_GetGlyphIndices(font_face, &codepoint, 1, &glyph_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Glyph metrics */
|
/* Glyph metrics */
|
||||||
{
|
|
||||||
DWRITE_GLYPH_METRICS m = ZI;
|
DWRITE_GLYPH_METRICS m = ZI;
|
||||||
{
|
{
|
||||||
hr = IDWriteFontFace_GetDesignGlyphMetrics(font_face, &glyph_idx, 1, &m, 0);
|
hr = IDWriteFontFace_GetDesignGlyphMetrics(font_face, &glyph_idx, 1, &m, 0);
|
||||||
}
|
}
|
||||||
Rng2 bounds = ZI;
|
f32 advance = (f32)m.advanceWidth * pixel_per_design_unit;
|
||||||
{
|
|
||||||
bounds.p0.x = (f32)m.leftSideBearing;
|
|
||||||
bounds.p1.x = (f32)m.advanceWidth - (f32)m.rightSideBearing;
|
|
||||||
bounds.p0.y = (f32)m.verticalOriginY - (f32)m.advanceHeight + m.bottomSideBearing;
|
|
||||||
bounds.p1.y = (f32)m.verticalOriginY - (f32)m.topSideBearing;
|
|
||||||
}
|
|
||||||
result.bounds.p0.x = bounds.p0.x * pixel_per_design_unit;
|
|
||||||
result.bounds.p0.y = bounds.p0.y * pixel_per_design_unit;
|
|
||||||
result.bounds.p1.x = bounds.p1.x * pixel_per_design_unit;
|
|
||||||
result.bounds.p1.y = bounds.p1.y * pixel_per_design_unit;
|
|
||||||
result.advance = (f32)m.advanceWidth * pixel_per_design_unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TTF_RasterizeGlyph(u32 *dst, Vec2I32 dst_size, Rng2I32 dst_slice, TTF_GlyphDesc glyph_desc)
|
|
||||||
{
|
|
||||||
COLORREF bg_color = 0xFF000000;
|
|
||||||
COLORREF fg_color = 0xFFFFFFFF;
|
|
||||||
|
|
||||||
f32 em_size = glyph_desc.font_size * (3.0 / 4.0);
|
|
||||||
f32 pixel_per_em = em_size * (TTF_DW_Dpi / 72.0f);
|
|
||||||
|
|
||||||
/* TODO: handle errors */
|
|
||||||
HRESULT hr = 0;
|
|
||||||
|
|
||||||
String encoded = DataFromResource(glyph_desc.ttf);
|
|
||||||
|
|
||||||
/* File */
|
|
||||||
IDWriteFontFile *font_file = 0;
|
|
||||||
{
|
|
||||||
/* Create in memory loader */
|
|
||||||
IDWriteInMemoryFontFileLoader *loader = 0;
|
|
||||||
hr = IDWriteFactory5_CreateInMemoryFontFileLoader(TTF_DW.factory, &loader);
|
|
||||||
hr = IDWriteFactory5_RegisterFontFileLoader(TTF_DW.factory, (IDWriteFontFileLoader *)loader);
|
|
||||||
|
|
||||||
IDWriteFontSetBuilder1 *builder = 0;
|
|
||||||
hr = IDWriteFactory5_CreateFontSetBuilder1(TTF_DW.factory, &builder);
|
|
||||||
hr = IDWriteInMemoryFontFileLoader_CreateInMemoryFontFileReference(loader, (IDWriteFactory *)TTF_DW.factory, encoded.text, (u32)encoded.len, 0, &font_file);
|
|
||||||
hr = IDWriteFontSetBuilder1_AddFontFile(builder, font_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Face */
|
|
||||||
IDWriteFontFace *font_face = 0;
|
|
||||||
{
|
|
||||||
hr = IDWriteFactory5_CreateFontFace(TTF_DW.factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &font_file, 0, DWRITE_FONT_SIMULATIONS_NONE, &font_face);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Glyph idx */
|
|
||||||
u16 glyph_idx = 0;
|
|
||||||
{
|
|
||||||
hr = IDWriteFontFace_GetGlyphIndices(font_face, &glyph_desc.codepoint, 1, &glyph_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -159,8 +108,10 @@ void TTF_RasterizeGlyph(u32 *dst, Vec2I32 dst_size, Rng2I32 dst_slice, TTF_Glyph
|
|||||||
/* FIXME: Dynamic render target */
|
/* FIXME: Dynamic render target */
|
||||||
i32 render_target_w = 256;
|
i32 render_target_w = 256;
|
||||||
i32 render_target_h = 256;
|
i32 render_target_h = 256;
|
||||||
i32 render_target_baseline_x = (render_target_w / 2) - DimsFromRng2I32(dst_slice).x;
|
|
||||||
i32 render_target_baseline_y = (render_target_h / 2) - DimsFromRng2I32(dst_slice).y;
|
/* Best-guess a position in the middle of the render target based on metrics */
|
||||||
|
i32 render_target_baseline_x = (render_target_w / 2) - (advance / 2);
|
||||||
|
i32 render_target_baseline_y = (render_target_h / 2) - (font_cap / 2);
|
||||||
|
|
||||||
/* Create render target */
|
/* Create render target */
|
||||||
IDWriteBitmapRenderTarget *render_target = 0;
|
IDWriteBitmapRenderTarget *render_target = 0;
|
||||||
@ -222,7 +173,7 @@ void TTF_RasterizeGlyph(u32 *dst, Vec2I32 dst_size, Rng2I32 dst_slice, TTF_Glyph
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Render glyph to target */
|
/* Render glyph to target */
|
||||||
Rng2I32 src_slice = ZI;
|
Rng2I32 rt_slice = ZI;
|
||||||
{
|
{
|
||||||
DWRITE_GLYPH_RUN glyph_run = ZI;
|
DWRITE_GLYPH_RUN glyph_run = ZI;
|
||||||
{
|
{
|
||||||
@ -242,563 +193,54 @@ void TTF_RasterizeGlyph(u32 *dst, Vec2I32 dst_size, Rng2I32 dst_slice, TTF_Glyph
|
|||||||
fg_color,
|
fg_color,
|
||||||
&bounding_box
|
&bounding_box
|
||||||
);
|
);
|
||||||
src_slice.p0.x = bounding_box.left;
|
rt_slice.p0.x = bounding_box.left;
|
||||||
src_slice.p0.y = bounding_box.top;
|
rt_slice.p0.y = bounding_box.top;
|
||||||
src_slice.p1.x = bounding_box.right;
|
rt_slice.p1.x = bounding_box.right;
|
||||||
src_slice.p1.y = bounding_box.bottom;
|
rt_slice.p1.y = bounding_box.bottom;
|
||||||
}
|
}
|
||||||
|
rt_slice.p0.x = MaxI32(rt_slice.p0.x, 0);
|
||||||
|
rt_slice.p0.y = MaxI32(rt_slice.p0.y, 0);
|
||||||
|
rt_slice.p1.x = MinI32(rt_slice.p1.x, render_target_w);
|
||||||
|
rt_slice.p1.y = MinI32(rt_slice.p1.y, render_target_h);
|
||||||
|
|
||||||
Vec2I32 src_slice_dims = DimsFromRng2I32(src_slice);
|
Vec2I32 dst_dims = DimsFromRng2I32(rt_slice);
|
||||||
Vec2I32 dst_slice_dims = DimsFromRng2I32(dst_slice);
|
u32 *dst_pixels = PushStructsNoZero(arena, u32, dst_dims.x * dst_dims.y);
|
||||||
|
|
||||||
/* FIXME: Handle gracefully */
|
/* Copy from target to result */
|
||||||
Assert(src_slice_dims.x <= dst_slice_dims.x);
|
|
||||||
Assert(src_slice_dims.y <= dst_slice_dims.y);
|
|
||||||
|
|
||||||
/* FIXME: Account for render target overrun */
|
|
||||||
/* Copy result from target */
|
|
||||||
{
|
{
|
||||||
u64 src_pitch = (u64)dib.dsBm.bmWidthBytes / 4;
|
u64 src_pitch = (u64)dib.dsBm.bmWidthBytes / 4;
|
||||||
u32 *src_pixels = (u32 *)dib.dsBm.bmBits;
|
u32 *src_pixels = (u32 *)dib.dsBm.bmBits;
|
||||||
for (i32 y = 0; y < src_slice_dims.y; ++y)
|
for (i32 y = 0; y < dst_dims.y; ++y)
|
||||||
{
|
{
|
||||||
u64 src_y = src_slice.p0.y + y;
|
u64 src_y = rt_slice.p0.y + y;
|
||||||
u64 dst_y = dst_slice.p0.y + y;
|
u64 dst_y = y;
|
||||||
for (i32 x = 0; x < src_slice_dims.x; ++x)
|
for (i32 x = 0; x < dst_dims.x; ++x)
|
||||||
{
|
{
|
||||||
u64 src_x = src_slice.p0.x + x;
|
u64 src_x = rt_slice.p0.x + x;
|
||||||
u64 dst_x = dst_slice.p0.x + x;
|
u64 dst_x = x;
|
||||||
u32 *src_pixel = src_pixels + (src_x + (src_y * src_pitch));
|
u32 *src_pixel = src_pixels + (src_x + (src_y * src_pitch));
|
||||||
u32 *dst_pixel = dst + (dst_x + (dst_y * dst_size.x));
|
u32 *dst_pixel = dst_pixels + (dst_x + (dst_y * dst_dims.x));
|
||||||
*dst_pixel = 0x00FFFFFF | ((*src_pixel & 0xFF) << 24);
|
*dst_pixel = 0x00FFFFFF | ((*src_pixel & 0xFF) << 24);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TTF_GlyphResult result = ZI;
|
||||||
|
{
|
||||||
|
result.ttf = ttf;
|
||||||
|
result.codepoint = codepoint;
|
||||||
|
|
||||||
|
result.advance = advance;
|
||||||
|
result.bounds.p0 = VEC2(0, 0);
|
||||||
|
result.bounds.p1 = Vec2FromVec(dst_dims);
|
||||||
|
|
||||||
|
result.font_size = font_size;
|
||||||
|
result.font_ascent = font_ascent;
|
||||||
|
result.font_descent = font_descent;
|
||||||
|
result.font_cap = font_cap;
|
||||||
|
|
||||||
|
result.image_dims = dst_dims;
|
||||||
// //- Create face
|
result.image_pixels = dst_pixels;
|
||||||
// IDWriteFontFace *font_face = 0;
|
}
|
||||||
// error = IDWriteFactory5_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &font_file, 0, DWRITE_FONT_SIMULATIONS_NONE, &font_face);
|
return result;
|
||||||
|
|
||||||
// //- Setup rendering params
|
|
||||||
// IDWriteRenderingParams *default_rendering_params = 0;
|
|
||||||
// error = IDWriteFactory5_CreateRenderingParams(factory, &default_rendering_params);
|
|
||||||
// IDWriteRenderingParams *rendering_params = 0;
|
|
||||||
// FLOAT gamma = IDWriteRenderingParams_GetGamma(default_rendering_params);
|
|
||||||
// FLOAT enhanced_contrast = IDWriteRenderingParams_GetEnhancedContrast(default_rendering_params);
|
|
||||||
// FLOAT clear_type_level = IDWriteRenderingParams_GetClearTypeLevel(default_rendering_params);
|
|
||||||
// error = IDWriteFactory5_CreateCustomRenderingParams(factory, gamma,
|
|
||||||
// enhanced_contrast,
|
|
||||||
// clear_type_level,
|
|
||||||
// DWRITE_PIXEL_GEOMETRY_FLAT,
|
|
||||||
// DWRITE_RENDERING_MODE_DEFAULT,
|
|
||||||
// &rendering_params);
|
|
||||||
|
|
||||||
// //- Setup interop
|
|
||||||
// IDWriteGdiInterop *dwrite_gdi_interop = 0;
|
|
||||||
// error = IDWriteFactory5_GetGdiInterop(factory, &dwrite_gdi_interop);
|
|
||||||
|
|
||||||
// //- Get metrics
|
|
||||||
// DWRITE_FONT_METRICS metrics = ZI;
|
|
||||||
// IDWriteFontFace_GetMetrics(font_face, &metrics);
|
|
||||||
|
|
||||||
// u16 glyph_count = IDWriteFontFace_GetGlyphCount(font_face);
|
|
||||||
|
|
||||||
// f32 pixel_per_em = em_size * (TTF_DW_Dpi / 72.0f);
|
|
||||||
// f32 pixel_per_design_unit = pixel_per_em / ((f32)metrics.designUnitsPerEm);
|
|
||||||
|
|
||||||
// i32 raster_target_w = (i32)(8.0f * ((f32)metrics.capHeight) * pixel_per_design_unit);
|
|
||||||
// i32 raster_target_h = raster_target_w;
|
|
||||||
|
|
||||||
// f32 raster_target_x = (f32)(raster_target_w / 2);
|
|
||||||
// f32 raster_target_y = raster_target_x;
|
|
||||||
|
|
||||||
// Assert((f32)((i32)raster_target_x) == raster_target_x);
|
|
||||||
// Assert((f32)((i32)raster_target_y) == raster_target_y);
|
|
||||||
|
|
||||||
// //- Setup render target
|
|
||||||
// IDWriteBitmapRenderTarget *render_target = 0;
|
|
||||||
// /* FIXME: errors when em_size too high */
|
|
||||||
// error = IDWriteGdiInterop_CreateBitmapRenderTarget(dwrite_gdi_interop, 0, (UINT32)raster_target_w, (UINT32)raster_target_h, &render_target);
|
|
||||||
// IDWriteBitmapRenderTarget_SetPixelsPerDip(render_target, 1.0);
|
|
||||||
|
|
||||||
// /* Clear the render target */
|
|
||||||
// HDC dc = 0;
|
|
||||||
// {
|
|
||||||
// dc = IDWriteBitmapRenderTarget_GetMemoryDC(render_target);
|
|
||||||
// HGDIOBJ original = SelectObject(dc, GetStockObject(DC_PEN));
|
|
||||||
// SetDCPenColor(dc, bg_color);
|
|
||||||
// SelectObject(dc, GetStockObject(DC_BRUSH));
|
|
||||||
// SetDCBrushColor(dc, bg_color);
|
|
||||||
// Rectangle(dc, 0, 0, raster_target_w, raster_target_h);
|
|
||||||
// SelectObject(dc, original);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //- Setup atlas
|
|
||||||
// /* Acquire font memory */
|
|
||||||
// TTF_Glyph *glyphs = (TTF_Glyph *)PushStructs(arena, TTF_Glyph, glyph_count);
|
|
||||||
|
|
||||||
// /* Acquire (starting) atlas memory
|
|
||||||
// * NOTE: This is unnecessary since atlas memory will grow anyway. Could
|
|
||||||
// * just start w/ atlas height 0.
|
|
||||||
// */
|
|
||||||
// u64 atlas_w = 1024;
|
|
||||||
// u64 atlas_h = 1;
|
|
||||||
// u32 *atlas_memory = PushStructs(arena, u32, atlas_w * atlas_h);
|
|
||||||
|
|
||||||
// i32 ascent = 0;
|
|
||||||
// i32 descent = 0;
|
|
||||||
// i32 cap = 0;
|
|
||||||
|
|
||||||
// //- Fill atlas & metric data
|
|
||||||
// u32 out_offset_x = 0;
|
|
||||||
// u32 out_offset_y = 0;
|
|
||||||
// u32 row_height = 0;
|
|
||||||
// {
|
|
||||||
// for (u16 i = 0; i < glyph_count; ++i)
|
|
||||||
// {
|
|
||||||
// //- Render glyph to render target
|
|
||||||
// DWRITE_GLYPH_RUN glyph_run = ZI;
|
|
||||||
// glyph_run.fontFace = font_face;
|
|
||||||
// glyph_run.fontEmSize = pixel_per_em;
|
|
||||||
// glyph_run.glyphCount = 1;
|
|
||||||
// glyph_run.glyphIndices = &i;
|
|
||||||
|
|
||||||
// RECT bounding_box = ZI;
|
|
||||||
// error = IDWriteBitmapRenderTarget_DrawGlyphRun(render_target,
|
|
||||||
// raster_target_x,
|
|
||||||
// raster_target_y,
|
|
||||||
// DWRITE_MEASURING_MODE_NATURAL,
|
|
||||||
// &glyph_run,
|
|
||||||
// rendering_params,
|
|
||||||
// fg_color,
|
|
||||||
// &bounding_box
|
|
||||||
// );
|
|
||||||
|
|
||||||
// if (bounding_box.left < 0
|
|
||||||
// || bounding_box.top < 0
|
|
||||||
// || bounding_box.right > raster_target_w
|
|
||||||
// || bounding_box.bottom > raster_target_h)
|
|
||||||
// {
|
|
||||||
// /* Skip */
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //- Compute glyph metrics
|
|
||||||
// DWRITE_GLYPH_METRICS glyph_metrics = ZI;
|
|
||||||
// error = IDWriteFontFace_GetDesignGlyphMetrics(font_face, &i, 1, &glyph_metrics, 0);
|
|
||||||
// ascent = metrics.ascent * pixel_per_design_unit;
|
|
||||||
// descent = metrics.descent * pixel_per_design_unit;
|
|
||||||
// cap = metrics.capHeight * pixel_per_design_unit;
|
|
||||||
|
|
||||||
// f32 off_x = (f32)bounding_box.left - raster_target_x;
|
|
||||||
// f32 off_y = (f32)bounding_box.top - raster_target_y;
|
|
||||||
// i32 tex_w = bounding_box.right - bounding_box.left;
|
|
||||||
// i32 tex_h = bounding_box.bottom - bounding_box.top;
|
|
||||||
// f32 advance = CeilF32ToI32((f32)glyph_metrics.advanceWidth * pixel_per_design_unit);
|
|
||||||
|
|
||||||
// TTF_Glyph *glyph = &glyphs[i];
|
|
||||||
// glyph->baseline_offset = VEC2(off_x, off_y);
|
|
||||||
// glyph->advance = advance;
|
|
||||||
|
|
||||||
// /* Get the bitmap */
|
|
||||||
// HBITMAP bitmap = (HBITMAP)GetCurrentObject(dc, OBJ_BITMAP);
|
|
||||||
// DIBSECTION dib = ZI;
|
|
||||||
// GetObject(bitmap, sizeof(dib), &dib);
|
|
||||||
|
|
||||||
// /* Start new row if necessary */
|
|
||||||
// if ((out_offset_x + tex_w) >= atlas_w)
|
|
||||||
// {
|
|
||||||
// out_offset_y += row_height;
|
|
||||||
// out_offset_x = 0;
|
|
||||||
// row_height = 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* Grow atlas height */
|
|
||||||
// if ((out_offset_y + tex_h) > atlas_h)
|
|
||||||
// {
|
|
||||||
// u64 diff = (out_offset_y + tex_h) - atlas_h;
|
|
||||||
// /* NOTE: This allocation must be contiguous with the initial atlas
|
|
||||||
// * allocation (IE: No non-atlas arena PUSHes) */
|
|
||||||
// PushStructs(arena, u32, diff * atlas_w);
|
|
||||||
// atlas_h += diff;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* Set bounding box metrics (now that we know atlas x & y) */
|
|
||||||
// glyph->atlas_p0 = VEC2I32(out_offset_x, out_offset_y);
|
|
||||||
// glyph->atlas_p1 = VEC2I32(out_offset_x + tex_w, out_offset_y + tex_h);
|
|
||||||
|
|
||||||
// //- Fill atlas
|
|
||||||
// u64 in_pitch = (u64)dib.dsBm.bmWidthBytes / 4;
|
|
||||||
// u32 *in_data = (u32 *)dib.dsBm.bmBits;
|
|
||||||
// u32 *out_data = atlas_memory;
|
|
||||||
// for (i32 y = 0; y < tex_h; ++y)
|
|
||||||
// {
|
|
||||||
// u64 out_y = out_offset_y + y;
|
|
||||||
// u64 in_y = (u64)bounding_box.top + y;
|
|
||||||
// for (i32 x = 0; x < tex_w; ++x)
|
|
||||||
// {
|
|
||||||
// u64 out_x = out_offset_x + x;
|
|
||||||
// u64 in_x = (u64)bounding_box.left + x;
|
|
||||||
// u32 *out_pixel = out_data + (out_x + (out_y * atlas_w));
|
|
||||||
// u32 *in_pixel = in_data + (in_x + (in_y * in_pitch));
|
|
||||||
// *out_pixel = 0x00FFFFFF | ((*in_pixel & 0xFF) << 24);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// out_offset_x += tex_w;
|
|
||||||
|
|
||||||
// /* Grow row height */
|
|
||||||
// if ((u32)tex_h > row_height)
|
|
||||||
// {
|
|
||||||
// row_height = (u32)tex_h;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //- Clear render target
|
|
||||||
// {
|
|
||||||
// HGDIOBJ original = SelectObject(dc, GetStockObject(DC_PEN));
|
|
||||||
// SetDCPenColor(dc, bg_color);
|
|
||||||
// SelectObject(dc, GetStockObject(DC_BRUSH));
|
|
||||||
// SetDCBrushColor(dc, bg_color);
|
|
||||||
// Rectangle(dc, bounding_box.left, bounding_box.top, bounding_box.right, bounding_box.bottom);
|
|
||||||
// SelectObject(dc, original);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //- Construct indices
|
|
||||||
// u16 *cache_indices = 0;
|
|
||||||
// if (cache_codes_count > 0)
|
|
||||||
// {
|
|
||||||
// cache_indices = PushStructs(arena, u16, cache_codes_count);
|
|
||||||
// IDWriteFontFace_GetGlyphIndices(font_face, cache_codes, cache_codes_count, cache_indices);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //- Release
|
|
||||||
// /* FIXME: Check for leaks */
|
|
||||||
// IDWriteGdiInterop_Release(dwrite_gdi_interop);
|
|
||||||
// IDWriteRenderingParams_Release(rendering_params);
|
|
||||||
// IDWriteRenderingParams_Release(default_rendering_params);
|
|
||||||
// // NOTE FROM ALLEN: We don't release font face because we intend to keep the font face around after the baking process
|
|
||||||
// // IDWriteFontFace_Release(font_face);
|
|
||||||
// IDWriteFontFile_Release(font_file);
|
|
||||||
// //loader->Release();
|
|
||||||
// IDWriteFactory5_Release(factory);
|
|
||||||
|
|
||||||
// /* Return */
|
|
||||||
// TTF_Decoded result = ZI;
|
|
||||||
// result.glyphs = glyphs;
|
|
||||||
// result.glyphs_count = glyph_count;
|
|
||||||
// result.cache_indices = cache_indices;
|
|
||||||
// result.image_width = (u32)atlas_w;
|
|
||||||
// result.image_height = (u32)atlas_h;
|
|
||||||
// result.image_pixels = (u32 *)atlas_memory;
|
|
||||||
// result.ascent = ascent;
|
|
||||||
// result.descent = descent;
|
|
||||||
// result.cap = cap;
|
|
||||||
// return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// /* Based on Allen Webster's dwrite rasterizer example -
|
|
||||||
// * https://github.com/4th-dimention/examps */
|
|
||||||
|
|
||||||
// extern TTF_DW_Ctx TTF_DW = ZI;
|
|
||||||
|
|
||||||
// ////////////////////////////////////////////////////////////
|
|
||||||
// //~ @hookimpl Bootstrap
|
|
||||||
|
|
||||||
// void TTF_Bootstrap(void)
|
|
||||||
// {
|
|
||||||
// TTF_DW_SharedState *g = &TTF_DW_shared_state;
|
|
||||||
// Assert(!g->factory);
|
|
||||||
// /* FIXME: I think IDWriteFactory5 only exists on later updates of windows
|
|
||||||
// * 10? Need to verify. Maybe should just use a custom loader. (We're only
|
|
||||||
// * using a factory5 since I think WriteInMemoryFileLoader wasn't
|
|
||||||
// * implemented until then) */
|
|
||||||
// HRESULT error = DWriteCreateFactory(
|
|
||||||
// DWRITE_FACTORY_TYPE_SHARED,
|
|
||||||
// &IID_IDWriteFactory5,
|
|
||||||
// (void **)&g->factory
|
|
||||||
// );
|
|
||||||
// if (!SUCCEEDED(error))
|
|
||||||
// {
|
|
||||||
// Panic(Lit("Error creating DWrite factory"));
|
|
||||||
// (*(volatile int *)0) = 0;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ////////////////////////////////////////////////////////////
|
|
||||||
// //~ @hookimpl Decode
|
|
||||||
|
|
||||||
// TTF_Decoded TTF_Decode(Arena *arena, String encoded, f32 em_size, u32 *cache_codes, u32 cache_codes_count)
|
|
||||||
// {
|
|
||||||
// TTF_DW_SharedState *g = &TTF_DW_shared_state;
|
|
||||||
// COLORREF bg_color = 0xFF000000;
|
|
||||||
// COLORREF fg_color = 0xFFFFFFFF;
|
|
||||||
|
|
||||||
// IDWriteFactory5 *factory = g->factory;
|
|
||||||
|
|
||||||
// /* TODO: handle errors */
|
|
||||||
// HRESULT error = 0;
|
|
||||||
|
|
||||||
// /* File */
|
|
||||||
// IDWriteFontFile *font_file = 0;
|
|
||||||
// {
|
|
||||||
// /* Create in memory loader */
|
|
||||||
// IDWriteInMemoryFontFileLoader *loader = 0;
|
|
||||||
// error = IDWriteFactory5_CreateInMemoryFontFileLoader(factory, &loader);
|
|
||||||
// error = IDWriteFactory5_RegisterFontFileLoader(factory, (IDWriteFontFileLoader *)loader);
|
|
||||||
|
|
||||||
// IDWriteFontSetBuilder1 *builder = 0;
|
|
||||||
// error = IDWriteFactory5_CreateFontSetBuilder1(factory, &builder);
|
|
||||||
// error = IDWriteInMemoryFontFileLoader_CreateInMemoryFontFileReference(loader, (IDWriteFactory *)factory, encoded.text, (u32)encoded.len, 0, &font_file);
|
|
||||||
// error = IDWriteFontSetBuilder1_AddFontFile(builder, font_file);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //- Create face
|
|
||||||
// IDWriteFontFace *font_face = 0;
|
|
||||||
// error = IDWriteFactory5_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &font_file, 0, DWRITE_FONT_SIMULATIONS_NONE, &font_face);
|
|
||||||
|
|
||||||
// //- Setup rendering params
|
|
||||||
// IDWriteRenderingParams *default_rendering_params = 0;
|
|
||||||
// error = IDWriteFactory5_CreateRenderingParams(factory, &default_rendering_params);
|
|
||||||
// IDWriteRenderingParams *rendering_params = 0;
|
|
||||||
// FLOAT gamma = IDWriteRenderingParams_GetGamma(default_rendering_params);
|
|
||||||
// FLOAT enhanced_contrast = IDWriteRenderingParams_GetEnhancedContrast(default_rendering_params);
|
|
||||||
// FLOAT clear_type_level = IDWriteRenderingParams_GetClearTypeLevel(default_rendering_params);
|
|
||||||
// error = IDWriteFactory5_CreateCustomRenderingParams(factory, gamma,
|
|
||||||
// enhanced_contrast,
|
|
||||||
// clear_type_level,
|
|
||||||
// DWRITE_PIXEL_GEOMETRY_FLAT,
|
|
||||||
// DWRITE_RENDERING_MODE_DEFAULT,
|
|
||||||
// &rendering_params);
|
|
||||||
|
|
||||||
// //- Setup interop
|
|
||||||
// IDWriteGdiInterop *dwrite_gdi_interop = 0;
|
|
||||||
// error = IDWriteFactory5_GetGdiInterop(factory, &dwrite_gdi_interop);
|
|
||||||
|
|
||||||
// //- Get metrics
|
|
||||||
// DWRITE_FONT_METRICS metrics = ZI;
|
|
||||||
// IDWriteFontFace_GetMetrics(font_face, &metrics);
|
|
||||||
|
|
||||||
// u16 glyph_count = IDWriteFontFace_GetGlyphCount(font_face);
|
|
||||||
|
|
||||||
// f32 pixel_per_em = em_size * (TTF_DW_Dpi / 72.0f);
|
|
||||||
// f32 pixel_per_design_unit = pixel_per_em / ((f32)metrics.designUnitsPerEm);
|
|
||||||
|
|
||||||
// i32 raster_target_w = (i32)(8.0f * ((f32)metrics.capHeight) * pixel_per_design_unit);
|
|
||||||
// i32 raster_target_h = raster_target_w;
|
|
||||||
|
|
||||||
// f32 raster_target_x = (f32)(raster_target_w / 2);
|
|
||||||
// f32 raster_target_y = raster_target_x;
|
|
||||||
|
|
||||||
// Assert((f32)((i32)raster_target_x) == raster_target_x);
|
|
||||||
// Assert((f32)((i32)raster_target_y) == raster_target_y);
|
|
||||||
|
|
||||||
// //- Setup render target
|
|
||||||
// IDWriteBitmapRenderTarget *render_target = 0;
|
|
||||||
// /* FIXME: errors when em_size too high */
|
|
||||||
// error = IDWriteGdiInterop_CreateBitmapRenderTarget(dwrite_gdi_interop, 0, (UINT32)raster_target_w, (UINT32)raster_target_h, &render_target);
|
|
||||||
// IDWriteBitmapRenderTarget_SetPixelsPerDip(render_target, 1.0);
|
|
||||||
|
|
||||||
// /* Clear the render target */
|
|
||||||
// HDC dc = 0;
|
|
||||||
// {
|
|
||||||
// dc = IDWriteBitmapRenderTarget_GetMemoryDC(render_target);
|
|
||||||
// HGDIOBJ original = SelectObject(dc, GetStockObject(DC_PEN));
|
|
||||||
// SetDCPenColor(dc, bg_color);
|
|
||||||
// SelectObject(dc, GetStockObject(DC_BRUSH));
|
|
||||||
// SetDCBrushColor(dc, bg_color);
|
|
||||||
// Rectangle(dc, 0, 0, raster_target_w, raster_target_h);
|
|
||||||
// SelectObject(dc, original);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //- Setup atlas
|
|
||||||
// /* Acquire font memory */
|
|
||||||
// TTF_Glyph *glyphs = (TTF_Glyph *)PushStructs(arena, TTF_Glyph, glyph_count);
|
|
||||||
|
|
||||||
// /* Acquire (starting) atlas memory
|
|
||||||
// * NOTE: This is unnecessary since atlas memory will grow anyway. Could
|
|
||||||
// * just start w/ atlas height 0.
|
|
||||||
// */
|
|
||||||
// u64 atlas_w = 1024;
|
|
||||||
// u64 atlas_h = 1;
|
|
||||||
// u32 *atlas_memory = PushStructs(arena, u32, atlas_w * atlas_h);
|
|
||||||
|
|
||||||
// i32 ascent = 0;
|
|
||||||
// i32 descent = 0;
|
|
||||||
// i32 cap = 0;
|
|
||||||
|
|
||||||
// //- Fill atlas & metric data
|
|
||||||
// u32 out_offset_x = 0;
|
|
||||||
// u32 out_offset_y = 0;
|
|
||||||
// u32 row_height = 0;
|
|
||||||
// {
|
|
||||||
// for (u16 i = 0; i < glyph_count; ++i)
|
|
||||||
// {
|
|
||||||
// //- Render glyph to render target
|
|
||||||
// DWRITE_GLYPH_RUN glyph_run = ZI;
|
|
||||||
// glyph_run.fontFace = font_face;
|
|
||||||
// glyph_run.fontEmSize = pixel_per_em;
|
|
||||||
// glyph_run.glyphCount = 1;
|
|
||||||
// glyph_run.glyphIndices = &i;
|
|
||||||
|
|
||||||
// RECT bounding_box = ZI;
|
|
||||||
// error = IDWriteBitmapRenderTarget_DrawGlyphRun(render_target,
|
|
||||||
// raster_target_x,
|
|
||||||
// raster_target_y,
|
|
||||||
// DWRITE_MEASURING_MODE_NATURAL,
|
|
||||||
// &glyph_run,
|
|
||||||
// rendering_params,
|
|
||||||
// fg_color,
|
|
||||||
// &bounding_box
|
|
||||||
// );
|
|
||||||
|
|
||||||
// if (bounding_box.left < 0
|
|
||||||
// || bounding_box.top < 0
|
|
||||||
// || bounding_box.right > raster_target_w
|
|
||||||
// || bounding_box.bottom > raster_target_h)
|
|
||||||
// {
|
|
||||||
// /* Skip */
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //- Compute glyph metrics
|
|
||||||
// DWRITE_GLYPH_METRICS glyph_metrics = ZI;
|
|
||||||
// error = IDWriteFontFace_GetDesignGlyphMetrics(font_face, &i, 1, &glyph_metrics, 0);
|
|
||||||
// ascent = metrics.ascent * pixel_per_design_unit;
|
|
||||||
// descent = metrics.descent * pixel_per_design_unit;
|
|
||||||
// cap = metrics.capHeight * pixel_per_design_unit;
|
|
||||||
|
|
||||||
// f32 off_x = (f32)bounding_box.left - raster_target_x;
|
|
||||||
// f32 off_y = (f32)bounding_box.top - raster_target_y;
|
|
||||||
// i32 tex_w = bounding_box.right - bounding_box.left;
|
|
||||||
// i32 tex_h = bounding_box.bottom - bounding_box.top;
|
|
||||||
// f32 advance = CeilF32ToI32((f32)glyph_metrics.advanceWidth * pixel_per_design_unit);
|
|
||||||
|
|
||||||
// TTF_Glyph *glyph = &glyphs[i];
|
|
||||||
// glyph->baseline_offset = VEC2(off_x, off_y);
|
|
||||||
// glyph->advance = advance;
|
|
||||||
|
|
||||||
// /* Get the bitmap */
|
|
||||||
// HBITMAP bitmap = (HBITMAP)GetCurrentObject(dc, OBJ_BITMAP);
|
|
||||||
// DIBSECTION dib = ZI;
|
|
||||||
// GetObject(bitmap, sizeof(dib), &dib);
|
|
||||||
|
|
||||||
// /* Start new row if necessary */
|
|
||||||
// if ((out_offset_x + tex_w) >= atlas_w)
|
|
||||||
// {
|
|
||||||
// out_offset_y += row_height;
|
|
||||||
// out_offset_x = 0;
|
|
||||||
// row_height = 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* Grow atlas height */
|
|
||||||
// if ((out_offset_y + tex_h) > atlas_h)
|
|
||||||
// {
|
|
||||||
// u64 diff = (out_offset_y + tex_h) - atlas_h;
|
|
||||||
// /* NOTE: This allocation must be contiguous with the initial atlas
|
|
||||||
// * allocation (IE: No non-atlas arena PUSHes) */
|
|
||||||
// PushStructs(arena, u32, diff * atlas_w);
|
|
||||||
// atlas_h += diff;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* Set bounding box metrics (now that we know atlas x & y) */
|
|
||||||
// glyph->atlas_p0 = VEC2I32(out_offset_x, out_offset_y);
|
|
||||||
// glyph->atlas_p1 = VEC2I32(out_offset_x + tex_w, out_offset_y + tex_h);
|
|
||||||
|
|
||||||
// //- Fill atlas
|
|
||||||
// u64 in_pitch = (u64)dib.dsBm.bmWidthBytes / 4;
|
|
||||||
// u32 *in_data = (u32 *)dib.dsBm.bmBits;
|
|
||||||
// u32 *out_data = atlas_memory;
|
|
||||||
// for (i32 y = 0; y < tex_h; ++y)
|
|
||||||
// {
|
|
||||||
// u64 out_y = out_offset_y + y;
|
|
||||||
// u64 in_y = (u64)bounding_box.top + y;
|
|
||||||
// for (i32 x = 0; x < tex_w; ++x)
|
|
||||||
// {
|
|
||||||
// u64 out_x = out_offset_x + x;
|
|
||||||
// u64 in_x = (u64)bounding_box.left + x;
|
|
||||||
// u32 *out_pixel = out_data + (out_x + (out_y * atlas_w));
|
|
||||||
// u32 *in_pixel = in_data + (in_x + (in_y * in_pitch));
|
|
||||||
// *out_pixel = 0x00FFFFFF | ((*in_pixel & 0xFF) << 24);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// out_offset_x += tex_w;
|
|
||||||
|
|
||||||
// /* Grow row height */
|
|
||||||
// if ((u32)tex_h > row_height)
|
|
||||||
// {
|
|
||||||
// row_height = (u32)tex_h;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //- Clear render target
|
|
||||||
// {
|
|
||||||
// HGDIOBJ original = SelectObject(dc, GetStockObject(DC_PEN));
|
|
||||||
// SetDCPenColor(dc, bg_color);
|
|
||||||
// SelectObject(dc, GetStockObject(DC_BRUSH));
|
|
||||||
// SetDCBrushColor(dc, bg_color);
|
|
||||||
// Rectangle(dc, bounding_box.left, bounding_box.top, bounding_box.right, bounding_box.bottom);
|
|
||||||
// SelectObject(dc, original);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //- Construct indices
|
|
||||||
// u16 *cache_indices = 0;
|
|
||||||
// if (cache_codes_count > 0)
|
|
||||||
// {
|
|
||||||
// cache_indices = PushStructs(arena, u16, cache_codes_count);
|
|
||||||
// IDWriteFontFace_GetGlyphIndices(font_face, cache_codes, cache_codes_count, cache_indices);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //- Release
|
|
||||||
// /* FIXME: Check for leaks */
|
|
||||||
// IDWriteGdiInterop_Release(dwrite_gdi_interop);
|
|
||||||
// IDWriteRenderingParams_Release(rendering_params);
|
|
||||||
// IDWriteRenderingParams_Release(default_rendering_params);
|
|
||||||
// // NOTE FROM ALLEN: We don't release font face because we intend to keep the font face around after the baking process
|
|
||||||
// // IDWriteFontFace_Release(font_face);
|
|
||||||
// IDWriteFontFile_Release(font_file);
|
|
||||||
// //loader->Release();
|
|
||||||
// IDWriteFactory5_Release(factory);
|
|
||||||
|
|
||||||
// /* Return */
|
|
||||||
// TTF_Decoded result = ZI;
|
|
||||||
// result.glyphs = glyphs;
|
|
||||||
// result.glyphs_count = glyph_count;
|
|
||||||
// result.cache_indices = cache_indices;
|
|
||||||
// result.image_width = (u32)atlas_w;
|
|
||||||
// result.image_height = (u32)atlas_h;
|
|
||||||
// result.image_pixels = (u32 *)atlas_memory;
|
|
||||||
// result.ascent = ascent;
|
|
||||||
// result.descent = descent;
|
|
||||||
// result.cap = cap;
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
|
|||||||
@ -1350,11 +1350,13 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
if (glyph_dims.x != 0 || glyph_dims.y != 0)
|
if (glyph_dims.x != 0 || glyph_dims.y != 0)
|
||||||
{
|
{
|
||||||
UI_DRect *rect = PushStruct(frame->rects_arena, UI_DRect);
|
UI_DRect *rect = PushStruct(frame->rects_arena, UI_DRect);
|
||||||
rect->bounds = AddRng2Vec2(rr.bounds, baseline);
|
|
||||||
rect->debug_lin = LinearFromSrgb(box->desc.debug_color);
|
rect->debug_lin = LinearFromSrgb(box->desc.debug_color);
|
||||||
rect->tint_lin = LinearFromSrgb(box->desc.tint);
|
rect->tint_lin = LinearFromSrgb(box->desc.tint);
|
||||||
rect->tex = rr.tex;
|
rect->tex = rr.tex;
|
||||||
rect->tex_slice_uv = rr.tex_uv;
|
rect->tex_slice_uv = rr.tex_slice_uv;
|
||||||
|
rect->bounds = rr.bounds;
|
||||||
|
rect->bounds = AddRng2Vec2(rect->bounds, baseline);
|
||||||
|
rect->bounds = AddRng2Vec2(rect->bounds, VEC2(rr.baseline_pos, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user