# Conflicts:
#	code/win32_main.cpp
main
sixten.hugosson 2023-06-18 16:49:51 +02:00
commit d70b6db7af
5 changed files with 993 additions and 938 deletions

View File

@ -19,50 +19,50 @@
struct vn_state struct vn_state
{ {
memory_arena Arena; memory_arena Arena;
glyph_atlas *GlyphAtlas; glyph_atlas *GlyphAtlas;
config *Config; config *Config;
ui UI; ui UI;
workspace Workspace; workspace Workspace;
animation_curve_state AnimationCurveState; animation_curve_state AnimationCurveState;
}; };
VN_UPDATE_AND_RENDER(VN_UpdateAndRender) VN_UPDATE_AND_RENDER(VN_UpdateAndRender)
{ {
SetThreadContext(ThreadContext); SetThreadContext(ThreadContext);
Platform = Memory->PlatformAPI; Platform = Memory->PlatformAPI;
vn_state *State = Memory->State; vn_state *State = Memory->State;
if(!Memory->State) if(!Memory->State)
{ {
State = Memory->State = BootstrapPushStruct(vn_state, Arena); State = Memory->State = BootstrapPushStruct(vn_state, Arena);
State->GlyphAtlas = CreateGlyphAtlas(RenderCommands); State->GlyphAtlas = CreateGlyphAtlas(RenderCommands);
State->Config = BootstrapPushStruct(config, Arena); State->Config = BootstrapPushStruct(config, Arena);
Config_BindEntry(State->Config, StrLit("Platform/RefreshRate"), Config_Entry_S32, &Input->RefreshRate); Config_BindEntry(State->Config, StrLit("Platform/RefreshRate"), Config_Entry_S32, &Input->RefreshRate);
Workspace_Init(&State->Workspace); Workspace_Init(&State->Workspace);
} }
AnimationCurve_NewFrame(&State->AnimationCurveState, Input->dtForFrame); AnimationCurve_NewFrame(&State->AnimationCurveState, Input->dtForFrame);
UI_NewFrame(&State->UI, Input->EventList, Input->MouseP); UI_NewFrame(&State->UI, Input->EventList, Input->MouseP);
Workspace_Update(&State->Workspace, RenderCommands, Input, State->GlyphAtlas); Workspace_Update(&State->Workspace, RenderCommands, Input, State->GlyphAtlas);
UI_SignalFromBox(UI_GetState()->ContainerNode); // sixten(TODO): Move elsewhere. UI_SignalFromBox(UI_GetState()->ContainerNode); // sixten(TODO): Move elsewhere.
for(platform_event *Event = Input->EventList->First; for(platform_event *Event = Input->EventList->First;
Event != 0; Event != 0;
Event = Event->Next) Event = Event->Next)
{ {
Platform_ConsumeEvent(Input->EventList, Event); Platform_ConsumeEvent(Input->EventList, Event);
} }
render_group Group = BeginRenderGroup(RenderCommands); render_group Group = BeginRenderGroup(RenderCommands);
PushClear(&Group, V3(0.1, 0.1, 0.1)); PushClear(&Group, V3(0.1, 0.1, 0.1));
UI_RenderFrame(&Group, State->GlyphAtlas); UI_RenderFrame(&Group, State->GlyphAtlas);
} }

View File

@ -2,223 +2,223 @@
inline s32 GetSubpixelSegmentAtP(r32 Value) inline s32 GetSubpixelSegmentAtP(r32 Value)
{ {
s32 Result = (s32)(Value - Floor(Value))*GLYPH_SUBPIXEL_SEGMENTS; s32 Result = (s32)(Value - Floor(Value))*GLYPH_SUBPIXEL_SEGMENTS;
return(Result); return(Result);
} }
static void RasterizeGlyph(glyph_atlas *Atlas, font_id Font, glyph *Glyph, u32 Codepoint, r32 Size, s32 Subpixel) static void RasterizeGlyph(glyph_atlas *Atlas, font_id Font, glyph *Glyph, u32 Codepoint, r32 Size, s32 Subpixel)
{ {
Glyph->Font = Font; Glyph->Font = Font;
Glyph->Codepoint = Codepoint; Glyph->Codepoint = Codepoint;
Glyph->Size = Size; Glyph->Size = Size;
Glyph->Subpixel = Subpixel; Glyph->Subpixel = Subpixel;
Assert(Subpixel < GLYPH_SUBPIXEL_SEGMENTS); Assert(Subpixel < GLYPH_SUBPIXEL_SEGMENTS);
loaded_font *LoadedFont = Atlas->Fonts + Font; loaded_font *LoadedFont = Atlas->Fonts + Font;
stbtt_fontinfo *Info = &LoadedFont->Info; stbtt_fontinfo *Info = &LoadedFont->Info;
r32 Scale = stbtt_ScaleForMappingEmToPixels(Info, Size); r32 Scale = stbtt_ScaleForMappingEmToPixels(Info, Size);
s32 InternalIndex = (s32)(Glyph - Atlas->Glyphs); s32 InternalIndex = (s32)(Glyph - Atlas->Glyphs);
s32 GlyphsPerRow = Atlas->BitmapSize / Atlas->GlyphSize; s32 GlyphsPerRow = Atlas->BitmapSize / Atlas->GlyphSize;
v2s BaseTextureOffset = V2S((InternalIndex % GlyphsPerRow)*Atlas->GlyphSize, v2s BaseTextureOffset = V2S((InternalIndex % GlyphsPerRow)*Atlas->GlyphSize,
(InternalIndex / GlyphsPerRow)*Atlas->GlyphSize); (InternalIndex / GlyphsPerRow)*Atlas->GlyphSize);
int GlyphIndex = stbtt_FindGlyphIndex(Info, Codepoint); int GlyphIndex = stbtt_FindGlyphIndex(Info, Codepoint);
stbtt_GetGlyphBitmapBoxSubpixel(Info, GlyphIndex, Scale, Scale, stbtt_GetGlyphBitmapBoxSubpixel(Info, GlyphIndex, Scale, Scale,
(r32)Subpixel/GLYPH_SUBPIXEL_SEGMENTS, 0,
&Glyph->P0.x, &Glyph->P0.y, &Glyph->P1.x, &Glyph->P1.y);
ZeroSize(Atlas->BitmapBuffer, Atlas->GlyphSize*Atlas->GlyphSize);
stbtt_MakeGlyphBitmapSubpixel(Info, Atlas->BitmapBuffer,
Atlas->GlyphSize, Atlas->GlyphSize, Atlas->GlyphSize,
Scale, Scale,
(r32)Subpixel/GLYPH_SUBPIXEL_SEGMENTS, 0, (r32)Subpixel/GLYPH_SUBPIXEL_SEGMENTS, 0,
GlyphIndex); &Glyph->P0.x, &Glyph->P0.y, &Glyph->P1.x, &Glyph->P1.y);
s32 Advance, LeftSideBearing; ZeroSize(Atlas->BitmapBuffer, Atlas->GlyphSize*Atlas->GlyphSize);
stbtt_GetGlyphHMetrics(Info, GlyphIndex, &Advance, &LeftSideBearing); stbtt_MakeGlyphBitmapSubpixel(Info, Atlas->BitmapBuffer,
Glyph->Advance = Advance*Scale; Atlas->GlyphSize, Atlas->GlyphSize, Atlas->GlyphSize,
Glyph->Offset.x = LeftSideBearing*Scale; Scale, Scale,
(r32)Subpixel/GLYPH_SUBPIXEL_SEGMENTS, 0,
GlyphIndex);
Glyph->Offset.y = Glyph->P0.y + (LoadedFont->Ascent + LoadedFont->LineGap)*Scale; s32 Advance, LeftSideBearing;
stbtt_GetGlyphHMetrics(Info, GlyphIndex, &Advance, &LeftSideBearing);
Glyph->Advance = Advance*Scale;
Glyph->Offset.x = LeftSideBearing*Scale;
v2s Dim = Glyph->P1 - Glyph->P0; Glyph->Offset.y = Glyph->P0.y + (LoadedFont->Ascent + LoadedFont->LineGap)*Scale;
Glyph->P0 = BaseTextureOffset; v2s Dim = Glyph->P1 - Glyph->P0;
Glyph->P1 = BaseTextureOffset + Dim + V2S(2, 2);
Atlas->RenderCommands->FillRegion(Atlas->Texture, Glyph->P0 = BaseTextureOffset;
BaseTextureOffset, V2S(Atlas->GlyphSize, Atlas->GlyphSize), Glyph->P1 = BaseTextureOffset + Dim + V2S(2, 2);
Atlas->BitmapBuffer);
Atlas->RenderCommands->FillRegion(Atlas->Texture,
BaseTextureOffset, V2S(Atlas->GlyphSize, Atlas->GlyphSize),
Atlas->BitmapBuffer);
} }
static glyph *GetGlyph(glyph_atlas *Atlas, font_id Font, u32 Codepoint, r32 Size, s32 Subpixel) static glyph *GetGlyph(glyph_atlas *Atlas, font_id Font, u32 Codepoint, r32 Size, s32 Subpixel)
{ {
glyph *Glyph = 0; glyph *Glyph = 0;
for(s32 GlyphIndex = 0; for(s32 GlyphIndex = 0;
GlyphIndex < Atlas->GlyphsUsed; GlyphIndex < Atlas->GlyphsUsed;
++GlyphIndex) ++GlyphIndex)
{
glyph *At = Atlas->Glyphs + GlyphIndex;
if((At->Font == Font) && (At->Codepoint == Codepoint) && (At->Size == Size) && (At->Subpixel == Subpixel))
{ {
glyph *At = Atlas->Glyphs + GlyphIndex; Glyph = At;
if((At->Font == Font) && (At->Codepoint == Codepoint) && (At->Size == Size) && (At->Subpixel == Subpixel)) break;
{
Glyph = At;
break;
}
} }
}
if(Glyph) if(Glyph)
{
DLLRemove_NP(Atlas->LRUFirst, Atlas->LRULast, Glyph, LRUNext, LRUPrev);
}
else
{
if(Atlas->GlyphsUsed < Atlas->MaxGlyphCount)
{ {
DLLRemove_NP(Atlas->LRUFirst, Atlas->LRULast, Glyph, LRUNext, LRUPrev); Glyph = Atlas->Glyphs + Atlas->GlyphsUsed++;
} }
else else
{ {
if(Atlas->GlyphsUsed < Atlas->MaxGlyphCount) Glyph = Atlas->LRUFirst;
{ Assert(Glyph);
Glyph = Atlas->Glyphs + Atlas->GlyphsUsed++;
}
else
{
Glyph = Atlas->LRUFirst;
Assert(Glyph);
DLLRemove_NP(Atlas->LRUFirst, Atlas->LRULast, Glyph, LRUNext, LRUPrev); DLLRemove_NP(Atlas->LRUFirst, Atlas->LRULast, Glyph, LRUNext, LRUPrev);
}
RasterizeGlyph(Atlas, Font, Glyph, Codepoint, Size, Subpixel);
} }
DLLInsertLast_NP(Atlas->LRUFirst, Atlas->LRULast, Glyph, LRUNext, LRUPrev); RasterizeGlyph(Atlas, Font, Glyph, Codepoint, Size, Subpixel);
}
return(Glyph); DLLInsertLast_NP(Atlas->LRUFirst, Atlas->LRULast, Glyph, LRUNext, LRUPrev);
return(Glyph);
} }
static glyph_atlas *CreateGlyphAtlas(vn_render_commands *RenderCommands, static glyph_atlas *CreateGlyphAtlas(vn_render_commands *RenderCommands,
s32 BitmapSize = DEFAULT_GLYPH_ATLAS_DIM, s32 BitmapSize = DEFAULT_GLYPH_ATLAS_DIM,
s32 GlyphSize = MAX_GLYPH_SIZE) s32 GlyphSize = MAX_GLYPH_SIZE)
{ {
glyph_atlas *Atlas = BootstrapPushStruct(glyph_atlas, Arena); glyph_atlas *Atlas = BootstrapPushStruct(glyph_atlas, Arena);
Atlas->BitmapSize = BitmapSize; Atlas->BitmapSize = BitmapSize;
Atlas->GlyphSize = GlyphSize; Atlas->GlyphSize = GlyphSize;
Atlas->MaxGlyphCount = (DEFAULT_GLYPH_ATLAS_DIM / MAX_GLYPH_SIZE)*(DEFAULT_GLYPH_ATLAS_DIM / MAX_GLYPH_SIZE); Atlas->MaxGlyphCount = (DEFAULT_GLYPH_ATLAS_DIM / MAX_GLYPH_SIZE)*(DEFAULT_GLYPH_ATLAS_DIM / MAX_GLYPH_SIZE);
Atlas->Glyphs = PushArray(&Atlas->Arena, glyph, Atlas->MaxGlyphCount); Atlas->Glyphs = PushArray(&Atlas->Arena, glyph, Atlas->MaxGlyphCount);
Atlas->RenderCommands = RenderCommands; Atlas->RenderCommands = RenderCommands;
Atlas->Texture = RenderCommands->AllocateTexture(V2S(BitmapSize, BitmapSize), Render_TextureFormat_R8, 0); Atlas->Texture = RenderCommands->AllocateTexture(V2S(BitmapSize, BitmapSize), Render_TextureFormat_R8, 0);
Atlas->Fonts[Font_Regular].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("../fonts/Roboto-Regular.ttf")); Atlas->Fonts[Font_Regular].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/Roboto-Regular.ttf"));
Atlas->Fonts[Font_Bold].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("../fonts/Roboto-Bold.ttf")); Atlas->Fonts[Font_Bold].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/Roboto-Bold.ttf"));
Atlas->Fonts[Font_Monospace].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("../fonts/Liberation-Mono.ttf")); Atlas->Fonts[Font_Monospace].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/Liberation-Mono.ttf"));
Atlas->Fonts[Font_Icons].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("../fonts/icons.ttf")); Atlas->Fonts[Font_Icons].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/icons.ttf"));
for(s32 FontIndex = 0; for(s32 FontIndex = 0;
FontIndex < Font_Count; FontIndex < Font_Count;
++FontIndex) ++FontIndex)
{ {
loaded_font *Font = Atlas->Fonts + FontIndex; loaded_font *Font = Atlas->Fonts + FontIndex;
stbtt_InitFont(&Font->Info, stbtt_InitFont(&Font->Info,
Font->Data.Data, Font->Data.Data,
stbtt_GetFontOffsetForIndex(Font->Data.Data, 0)); stbtt_GetFontOffsetForIndex(Font->Data.Data, 0));
stbtt_GetFontVMetrics(&Font->Info, &Font->Ascent, &Font->Descent, &Font->LineGap); stbtt_GetFontVMetrics(&Font->Info, &Font->Ascent, &Font->Descent, &Font->LineGap);
} }
Atlas->BitmapBuffer = PushArray(&Atlas->Arena, u8, GlyphSize*GlyphSize); Atlas->BitmapBuffer = PushArray(&Atlas->Arena, u8, GlyphSize*GlyphSize);
return(Atlas); return(Atlas);
} }
static void PushText(render_group *Group, glyph_atlas *Atlas, font_id Font, static void PushText(render_group *Group, glyph_atlas *Atlas, font_id Font,
v2 P, r32 Size, v4 Color, v2 P, r32 Size, v4 Color,
string Text) string Text)
{ {
r32 Oversample = 2; r32 Oversample = 2;
for(utf8_iterator Iter = IterateUTF8String(Text); for(utf8_iterator Iter = IterateUTF8String(Text);
Iter.Codepoint != 0; Iter.Codepoint != 0;
Advance(&Iter)) Advance(&Iter))
{ {
u32 Codepoint = Iter.Codepoint; u32 Codepoint = Iter.Codepoint;
glyph *Glyph = GetGlyph(Atlas, Font, Codepoint, Size*Oversample, GetSubpixelSegmentAtP(P.x*Oversample)); glyph *Glyph = GetGlyph(Atlas, Font, Codepoint, Size*Oversample, GetSubpixelSegmentAtP(P.x*Oversample));
Assert(Glyph); Assert(Glyph);
v2 GlyphP = P; v2 GlyphP = P;
GlyphP.x += Glyph->Offset.x/Oversample; GlyphP.x += Glyph->Offset.x/Oversample;
GlyphP.y += Glyph->Offset.y/Oversample; GlyphP.y += Glyph->Offset.y/Oversample;
v2 RenderDim = V2(Glyph->P1 - Glyph->P0); v2 RenderDim = V2(Glyph->P1 - Glyph->P0);
v2 Dim = RenderDim; v2 Dim = RenderDim;
Dim.x /= Oversample; Dim.x /= Oversample;
Dim.y /= Oversample; Dim.y /= Oversample;
PushTexturedQuad(Group, GlyphP, Dim, V2(Glyph->P0), RenderDim, Color, Color, Color, Color, 0, 0, 0, Atlas->Texture); PushTexturedQuad(Group, GlyphP, Dim, V2(Glyph->P0), RenderDim, Color, Color, Color, Color, 0, 0, 0, Atlas->Texture);
P.x += Glyph->Advance/Oversample; P.x += Glyph->Advance/Oversample;
} }
} }
static void PushTextF(render_group *Group, glyph_atlas *Atlas, font_id Font, static void PushTextF(render_group *Group, glyph_atlas *Atlas, font_id Font,
v2 P, r32 Size, v4 Color, v2 P, r32 Size, v4 Color,
char *Format, ...) char *Format, ...)
{ {
temporary_memory Scratch = GetScratch(0, 0); temporary_memory Scratch = GetScratch(0, 0);
va_list Arguments; va_list Arguments;
va_start(Arguments, Format); va_start(Arguments, Format);
string String = PushFormatVariadic(Scratch.Arena, Format, Arguments); string String = PushFormatVariadic(Scratch.Arena, Format, Arguments);
va_end(Arguments); va_end(Arguments);
PushText(Group, Atlas, Font, P, Size, Color, String); PushText(Group, Atlas, Font, P, Size, Color, String);
ReleaseScratch(Scratch); ReleaseScratch(Scratch);
} }
inline r32 CalculateRasterizedTextWidth(glyph_atlas *Atlas, font_id Font, r32 Size, string Text) inline r32 CalculateRasterizedTextWidth(glyph_atlas *Atlas, font_id Font, r32 Size, string Text)
{ {
r32 Oversample = 2; r32 Oversample = 2;
r32 X = 0; r32 X = 0;
for(utf8_iterator Iter = IterateUTF8String(Text); for(utf8_iterator Iter = IterateUTF8String(Text);
Iter.Codepoint != 0; Iter.Codepoint != 0;
Advance(&Iter)) Advance(&Iter))
{ {
u32 Codepoint = Iter.Codepoint; u32 Codepoint = Iter.Codepoint;
glyph *Glyph = GetGlyph(Atlas, Font, Codepoint, Size*Oversample, GetSubpixelSegmentAtP(X*Oversample)); glyph *Glyph = GetGlyph(Atlas, Font, Codepoint, Size*Oversample, GetSubpixelSegmentAtP(X*Oversample));
Assert(Glyph); Assert(Glyph);
X += Glyph->Advance/Oversample; X += Glyph->Advance/Oversample;
} }
return(X); return(X);
} }
inline r32 CalculateRasterizedTextHeight(glyph_atlas *Atlas, font_id Font, r32 Size, string Text) inline r32 CalculateRasterizedTextHeight(glyph_atlas *Atlas, font_id Font, r32 Size, string Text)
{ {
r32 Scale = stbtt_ScaleForMappingEmToPixels(&Atlas->Fonts[Font].Info, Size)/ r32 Scale = stbtt_ScaleForMappingEmToPixels(&Atlas->Fonts[Font].Info, Size)/
stbtt_ScaleForPixelHeight(&Atlas->Fonts[Font].Info, Size); stbtt_ScaleForPixelHeight(&Atlas->Fonts[Font].Info, Size);
r32 Y = Size*Scale; r32 Y = Size*Scale;
for(utf8_iterator Iter = IterateUTF8String(Text); for(utf8_iterator Iter = IterateUTF8String(Text);
Iter.Codepoint != 0; Iter.Codepoint != 0;
Advance(&Iter)) Advance(&Iter))
{
u32 Codepoint = Iter.Codepoint;
if(Codepoint == '\n')
{ {
u32 Codepoint = Iter.Codepoint; Y += Size*Scale;
if(Codepoint == '\n')
{
Y += Size*Scale;
}
} }
return(Y); }
return(Y);
} }

View File

@ -5,161 +5,181 @@
inline b32 IsWhitespace(char C) inline b32 IsWhitespace(char C)
{ {
b32 Result = ((C == ' ') || b32 Result = ((C == ' ') ||
(C == '\n') || (C == '\n') ||
(C == '\t') || (C == '\t') ||
(C == '\r')); (C == '\r'));
return(Result); return(Result);
} }
inline s64 StringLength(char *String) inline s64 StringLength(char *String)
{ {
s64 Result = 0; s64 Result = 0;
while(*String++) while(*String++)
{ {
++Result; ++Result;
} }
return(Result); return(Result);
} }
inline u64 HashString(string String) inline u64 HashString(string String)
{ {
u64 Result = 5731; u64 Result = 5731;
for(s64 Index = 0; for(s64 Index = 0;
Index < String.Count; Index < String.Count;
++Index) ++Index)
{ {
Result += String.Data[Index]; Result += String.Data[Index];
Result ^= Result << 13; Result ^= Result << 13;
Result ^= Result >> 7; Result ^= Result >> 7;
Result ^= Result << 17; Result ^= Result << 17;
} }
return(Result); return(Result);
} }
inline string MakeStringFromCString(char *Data) inline string MakeStringFromCString(char *Data)
{ {
string Result = {StringLength(Data), (u8 *)Data}; string Result = {StringLength(Data), (u8 *)Data};
return(Result); return(Result);
}
inline s64 FirstIndexOf(string String, char Char)
{
s64 Result = -1;
for(s64 Index = 0;
Index < String.Count;
++Index)
{
if(String.Data[Index] == Char)
{
Result = Index;
break;
}
}
return(Result);
}
inline s64 LastIndexOf(string String, char Char)
{
s64 Result = -1;
for(s64 Index = String.Count-1;
Index >= 0;
--Index)
{
if(String.Data[Index] == Char)
{
Result = Index;
break;
}
}
return(Result);
} }
inline b32 AreEqual(string A, string B) inline b32 AreEqual(string A, string B)
{ {
b32 Result = false; b32 Result = false;
if(A.Count == B.Count) if(A.Count == B.Count)
{
Result = true;
for(s64 Index = 0;
Index < A.Count;
++Index)
{ {
Result = true; if(A.Data[Index] != B.Data[Index])
{
for(s64 Index = 0; Result = false;
Index < A.Count; break;
++Index) }
{
if(A.Data[Index] != B.Data[Index])
{
Result = false;
break;
}
}
} }
}
return(Result); return(Result);
}
inline s64 FirstIndexOf(string String, char Char)
{
s64 Result = -1;
for(s64 Index = 0;
Index < String.Count;
++Index)
{
if(String.Data[Index] == Char)
{
Result = Index;
break;
}
}
return(Result);
}
inline s64 LastIndexOf(string String, char Char)
{
s64 Result = -1;
for(s64 Index = String.Count-1;
Index >= 0;
--Index)
{
if(String.Data[Index] == Char)
{
Result = Index;
break;
}
}
return(Result);
}
inline s64 LastIndexOf(string String, string Substring)
{
s64 Result = -1;
if(String.Count >= Substring.Count)
{
for(s64 Index = String.Count-Substring.Count;
Index >= 0;
--Index)
{
string ToCheck = MakeString((char *)String.Data + Index, Substring.Count);
if(AreEqual(ToCheck, Substring))
{
Result = Index;
break;
}
}
}
return(Result);
} }
static s64 UTF8FromCodepoint(u8 *Out, u32 Codepoint) static s64 UTF8FromCodepoint(u8 *Out, u32 Codepoint)
{ {
s64 Length = 0; s64 Length = 0;
if(Codepoint <= 0x7F) if(Codepoint <= 0x7F)
{ {
Out[0] = (u8)Codepoint; Out[0] = (u8)Codepoint;
Length = 1; Length = 1;
} }
else if(Codepoint <= 0x7FF) else if(Codepoint <= 0x7FF)
{ {
Out[0] = (0x3 << 6) | ((Codepoint >> 6) & 0x1F); Out[0] = (0x3 << 6) | ((Codepoint >> 6) & 0x1F);
Out[1] = 0x80 | ( Codepoint & 0x3F); Out[1] = 0x80 | ( Codepoint & 0x3F);
Length = 2; Length = 2;
} }
else if(Codepoint <= 0xFFFF) else if(Codepoint <= 0xFFFF)
{ {
Out[0] = (0x7 << 5) | ((Codepoint >> 12) & 0x0F); Out[0] = (0x7 << 5) | ((Codepoint >> 12) & 0x0F);
Out[1] = 0x80 | ((Codepoint >> 6) & 0x3F); Out[1] = 0x80 | ((Codepoint >> 6) & 0x3F);
Out[2] = 0x80 | ( Codepoint & 0x3F); Out[2] = 0x80 | ( Codepoint & 0x3F);
Length = 3; Length = 3;
} }
else if(Codepoint <= 0x10FFFF) else if(Codepoint <= 0x10FFFF)
{ {
Out[0] = (0xF << 4) | ((Codepoint >> 12) & 0x07); Out[0] = (0xF << 4) | ((Codepoint >> 12) & 0x07);
Out[1] = 0x80 | ((Codepoint >> 12) & 0x3F); Out[1] = 0x80 | ((Codepoint >> 12) & 0x3F);
Out[2] = 0x80 | ((Codepoint >> 6) & 0x3F); Out[2] = 0x80 | ((Codepoint >> 6) & 0x3F);
Out[3] = 0x80 | ( Codepoint & 0x3F); Out[3] = 0x80 | ( Codepoint & 0x3F);
Length = 4; Length = 4;
} }
else else
{ {
Out[0] = '?'; Out[0] = '?';
Length = 1; Length = 1;
} }
return(Length); return(Length);
} }
inline s64 GetCodepointSize(u32 Codepoint) inline s64 GetCodepointSize(u32 Codepoint)
{ {
s64 Result = 0; s64 Result = 0;
if(Codepoint <= 0x7F) if(Codepoint <= 0x7F)
{ {
Result = 1; Result = 1;
} }
else if(Codepoint <= 0x7FF) else if(Codepoint <= 0x7FF)
{ {
Result = 2; Result = 2;
} }
else if(Codepoint <= 0xFFFF) else if(Codepoint <= 0xFFFF)
{ {
Result = 3; Result = 3;
} }
else if(Codepoint <= 0x10FFFF) else if(Codepoint <= 0x10FFFF)
{ {
Result = 4; Result = 4;
} }
else else
{ {
Result = 1; Result = 1;
} }
return(Result); return(Result);
} }
// sixten(TODO): Remove this forward decl. // sixten(TODO): Remove this forward decl.
@ -167,61 +187,61 @@ inline string PushCString(struct memory_arena *Arena, char *CString);
inline string StringFromCodepoint(struct memory_arena *Arena, u32 Codepoint) inline string StringFromCodepoint(struct memory_arena *Arena, u32 Codepoint)
{ {
char Buffer[5] = {}; char Buffer[5] = {};
UTF8FromCodepoint((u8 *)Buffer, Codepoint); UTF8FromCodepoint((u8 *)Buffer, Codepoint);
string Result = PushCString(Arena, Buffer); string Result = PushCString(Arena, Buffer);
return(Result); return(Result);
} }
struct utf8_iterator struct utf8_iterator
{ {
string Data; string Data;
s64 Index; s64 Index;
u32 Codepoint; u32 Codepoint;
}; };
inline void Advance(utf8_iterator *Iter) inline void Advance(utf8_iterator *Iter)
{ {
u8 *At = Iter->Data.Data + Iter->Index; u8 *At = Iter->Data.Data + Iter->Index;
if(Iter->Index < Iter->Data.Count) if(Iter->Index < Iter->Data.Count)
{
if((At[0] & 0x80) == 0x00)
{ {
if((At[0] & 0x80) == 0x00) Iter->Codepoint = (At[0] & 0x7F);
{ Iter->Index += 1;
Iter->Codepoint = (At[0] & 0x7F);
Iter->Index += 1;
}
else if((At[0] & 0xE0) == 0xC0)
{
Iter->Codepoint = ((At[0] & 0x1F) << 6)|(At[1] & 0x3F);
Iter->Index += 2;
}
else if((At[0] & 0xF0) == 0xE0)
{
Iter->Codepoint = ((At[0] & 0x0F) << 12)|((At[1] & 0x3F) << 6)|(At[2] & 0x3F);
Iter->Index += 3;
}
else if((Iter->Data.Data[Iter->Index] & 0xF8) == 0xF0)
{
Iter->Codepoint = ((At[0] & 0x0F) << 18)|((At[1] & 0x3F) << 12)|((At[2] & 0x3F) << 6)|(At[3] & 0x3F);
Iter->Index += 4;
}
} }
else else if((At[0] & 0xE0) == 0xC0)
{ {
Iter->Codepoint = 0; Iter->Codepoint = ((At[0] & 0x1F) << 6)|(At[1] & 0x3F);
Iter->Index += 2;
} }
else if((At[0] & 0xF0) == 0xE0)
{
Iter->Codepoint = ((At[0] & 0x0F) << 12)|((At[1] & 0x3F) << 6)|(At[2] & 0x3F);
Iter->Index += 3;
}
else if((Iter->Data.Data[Iter->Index] & 0xF8) == 0xF0)
{
Iter->Codepoint = ((At[0] & 0x0F) << 18)|((At[1] & 0x3F) << 12)|((At[2] & 0x3F) << 6)|(At[3] & 0x3F);
Iter->Index += 4;
}
}
else
{
Iter->Codepoint = 0;
}
} }
inline utf8_iterator IterateUTF8String(string String) inline utf8_iterator IterateUTF8String(string String)
{ {
utf8_iterator Iter = {}; utf8_iterator Iter = {};
Iter.Data = String; Iter.Data = String;
Advance(&Iter); Advance(&Iter);
return(Iter); return(Iter);
} }
#endif //VN_STRING_H #endif //VN_STRING_H

File diff suppressed because it is too large Load Diff

View File

@ -5,43 +5,44 @@
struct win32_memory_block struct win32_memory_block
{ {
platform_memory_block Block; platform_memory_block Block;
win32_memory_block *Next; win32_memory_block *Next;
win32_memory_block *Prev; win32_memory_block *Prev;
u64 Padding[2]; u64 Padding[2];
}; };
CTAssert(sizeof(win32_memory_block) == 64); CTAssert(sizeof(win32_memory_block) == 64);
struct win32_state struct win32_state
{ {
win32_memory_block MemorySentinel; win32_memory_block MemorySentinel;
ticket_mutex MemoryMutex; ticket_mutex MemoryMutex;
u64 PerformanceFrequency; u64 PerformanceFrequency;
b32 SleepIsGranular; b32 SleepIsGranular;
HWND Window; HWND Window;
memory_arena EventArena; memory_arena EventArena;
temporary_memory EventArenaTemp; temporary_memory EventArenaTemp;
platform_event_list EventList; platform_event_list EventList;
char EXEPath[512]; char EXEPath[512];
char DLLPath[512]; char DLLPath[512];
char TempDLLPath[512]; char TempDLLPath[512];
string ContentsPath;
platform_cursor Cursor; platform_cursor Cursor;
}; };
struct win32_loaded_code struct win32_loaded_code
{ {
HMODULE DLL; HMODULE DLL;
FILETIME LastWriteTime; FILETIME LastWriteTime;
vn_update_and_render *UpdateAndRender; vn_update_and_render *UpdateAndRender;
b32 IsValid; b32 IsValid;
}; };
#endif //WIN32_MAIN_H #endif //WIN32_MAIN_H