216 lines
6.5 KiB
C++
216 lines
6.5 KiB
C++
|
/*
|
||
|
* Mr. 4th Dimention - Allen Webster
|
||
|
*
|
||
|
* 12.17.2014
|
||
|
*
|
||
|
* Rendering layer for project codename "4ed"
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
// TOP
|
||
|
|
||
|
inline void
|
||
|
draw_push_clip(Render_Target *target, i32_Rect clip_box){
|
||
|
target->push_clip(target, clip_box);
|
||
|
}
|
||
|
|
||
|
inline void
|
||
|
draw_pop_clip(Render_Target *target){
|
||
|
target->pop_clip(target);
|
||
|
}
|
||
|
|
||
|
internal void
|
||
|
draw_rectangle(Render_Target *target, i32_Rect rect, u32 color){
|
||
|
Render_Piece_Combined piece;
|
||
|
piece.header.type = piece_type_rectangle;
|
||
|
piece.rectangle.rect = f32R(rect);
|
||
|
piece.rectangle.color = color;
|
||
|
target->push_piece(target, piece);
|
||
|
}
|
||
|
|
||
|
internal void
|
||
|
draw_rectangle(Render_Target *target, f32_Rect rect, u32 color){
|
||
|
Render_Piece_Combined piece;
|
||
|
piece.header.type = piece_type_rectangle;
|
||
|
piece.rectangle.rect = rect;
|
||
|
piece.rectangle.color = color;
|
||
|
target->push_piece(target, piece);
|
||
|
}
|
||
|
|
||
|
internal void
|
||
|
draw_gradient_2corner_clipped(Render_Target *target, f32_Rect rect,
|
||
|
Vec4 left_color, Vec4 right_color){
|
||
|
Render_Piece_Combined piece;
|
||
|
piece.header.type = piece_type_gradient;
|
||
|
piece.gradient.rect = rect;
|
||
|
piece.gradient.left_color = pack_color4(left_color);
|
||
|
piece.gradient.right_color = pack_color4(right_color);
|
||
|
target->push_piece(target, piece);
|
||
|
}
|
||
|
|
||
|
inline void
|
||
|
draw_gradient_2corner_clipped(Render_Target *target, f32 l, f32 t, f32 r, f32 b,
|
||
|
Vec4 color_left, Vec4 color_right){
|
||
|
draw_gradient_2corner_clipped(target, f32R(l,t,r,b), color_left, color_right);
|
||
|
}
|
||
|
|
||
|
internal void
|
||
|
draw_rectangle_outline(Render_Target *target, f32_Rect rect, u32 color){
|
||
|
Render_Piece_Combined piece;
|
||
|
piece.header.type = piece_type_outline;
|
||
|
piece.rectangle.rect = rect;
|
||
|
piece.rectangle.color = color;
|
||
|
target->push_piece(target, piece);
|
||
|
}
|
||
|
|
||
|
inline void
|
||
|
draw_rectangle_outline(Render_Target *target, i32_Rect rect, u32 color){
|
||
|
draw_rectangle_outline(target, f32R(rect), color);
|
||
|
}
|
||
|
|
||
|
internal void
|
||
|
draw_margin(Render_Target *target, i32_Rect outer, i32_Rect inner, u32 color){
|
||
|
draw_rectangle(target, i32R(outer.x0, outer.y0, outer.x1, inner.y0), color);
|
||
|
draw_rectangle(target, i32R(outer.x0, inner.y1, outer.x1, outer.y1), color);
|
||
|
draw_rectangle(target, i32R(outer.x0, inner.y0, inner.x0, inner.y1), color);
|
||
|
draw_rectangle(target, i32R(inner.x1, inner.y0, outer.x1, inner.y1), color);
|
||
|
}
|
||
|
|
||
|
inline internal i32
|
||
|
font_predict_size(i32 pt_size){
|
||
|
return pt_size*pt_size*128;
|
||
|
}
|
||
|
|
||
|
internal i32
|
||
|
font_load(Render_Target *target, System_Functions *system,
|
||
|
Render_Font *font_out, char *filename, i32 pt_size,
|
||
|
void *font_block, i32 font_block_size,
|
||
|
i32 *memory_used_out, i32 tab_width){
|
||
|
i32 result =
|
||
|
target->font_load(system, font_out, filename, pt_size,
|
||
|
font_block, font_block_size, memory_used_out, tab_width);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
internal void
|
||
|
font_set_tabwidth(Render_Font *font, i32 tab_width){
|
||
|
font->chardata['\t'].xadvance *= font->chardata[' '].xadvance * tab_width;
|
||
|
}
|
||
|
|
||
|
// TODO(allen): Abstract Render_Font all the fucking way out of the app side code.
|
||
|
internal void
|
||
|
font_draw_glyph_mono(Render_Target *target, Render_Font *font, u16 character,
|
||
|
f32 x, f32 y, f32 advance, u32 color){
|
||
|
Render_Piece_Combined piece;
|
||
|
piece.header.type = piece_type_mono_glyph;
|
||
|
piece.glyph.pos.x = x;
|
||
|
piece.glyph.pos.y = y;
|
||
|
piece.glyph.color = color;
|
||
|
piece.glyph.font_id = font;
|
||
|
piece.glyph.character = character;
|
||
|
target->push_piece(target, piece);
|
||
|
}
|
||
|
|
||
|
inline void
|
||
|
font_draw_glyph_mono(Render_Target *target, Render_Font *font, u16 character,
|
||
|
real32 x, real32 y, u32 color){
|
||
|
font_draw_glyph_mono(target, font, character, x, y, (real32)font->advance, color);
|
||
|
}
|
||
|
|
||
|
internal void
|
||
|
font_draw_glyph(Render_Target *target, Render_Font *font, u16 character,
|
||
|
f32 x, f32 y, u32 color){
|
||
|
Render_Piece_Combined piece;
|
||
|
piece.header.type = piece_type_glyph;
|
||
|
piece.glyph.pos.x = x;
|
||
|
piece.glyph.pos.y = y;
|
||
|
piece.glyph.color = color;
|
||
|
piece.glyph.font_id = font;
|
||
|
piece.glyph.character = character;
|
||
|
target->push_piece(target, piece);
|
||
|
}
|
||
|
|
||
|
inline real32
|
||
|
font_get_glyph_width(Render_Font *font, u16 character){
|
||
|
return font->chardata[character].xadvance;
|
||
|
}
|
||
|
|
||
|
internal real32
|
||
|
font_string_width(Render_Font *font, char *str){
|
||
|
real32 x = 0;
|
||
|
for (i32 i = 0; str[i]; ++i){
|
||
|
x += font_get_glyph_width(font, str[i]);
|
||
|
}
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
internal i32
|
||
|
draw_string(Render_Target *target, Render_Font *font, char *str,
|
||
|
i32 x_, i32 y, u32 color){
|
||
|
real32 x = (real32)x_;
|
||
|
for (i32 i = 0; str[i]; ++i){
|
||
|
char c = str[i];
|
||
|
font_draw_glyph(target, font, c,
|
||
|
x, (real32)y, color);
|
||
|
x += font_get_glyph_width(font, c);
|
||
|
}
|
||
|
return CEIL32(x);
|
||
|
}
|
||
|
|
||
|
internal real32
|
||
|
draw_string_mono(Render_Target *target, Render_Font *font, char *str,
|
||
|
real32 x, real32 y, real32 advance, u32 color){
|
||
|
for (i32 i = 0; str[i]; ++i){
|
||
|
font_draw_glyph_mono(target, font, str[i],
|
||
|
x, y, advance, color);
|
||
|
x += advance;
|
||
|
}
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
internal i32
|
||
|
draw_string(Render_Target *target, Render_Font *font, String str,
|
||
|
i32 x_, i32 y, u32 color){
|
||
|
real32 x = (real32)x_;
|
||
|
for (i32 i = 0; i < str.size; ++i){
|
||
|
char c = str.str[i];
|
||
|
font_draw_glyph(target, font, c,
|
||
|
x, (real32)y, color);
|
||
|
x += font_get_glyph_width(font, c);
|
||
|
}
|
||
|
return CEIL32(x);
|
||
|
}
|
||
|
|
||
|
internal real32
|
||
|
draw_string_mono(Render_Target *target, Render_Font *font, String str,
|
||
|
real32 x, real32 y, real32 advance, u32 color){
|
||
|
for (i32 i = 0; i < str.size; ++i){
|
||
|
font_draw_glyph_mono(target, font, str.str[i],
|
||
|
x, y, advance, color);
|
||
|
x += advance;
|
||
|
}
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
internal real32
|
||
|
font_get_max_width(Render_Font *font, char *characters){
|
||
|
stbtt_bakedchar *chardata = font->chardata;
|
||
|
real32 cx, x = 0;
|
||
|
for (i32 i = 0; characters[i]; ++i){
|
||
|
cx = chardata[characters[i]].xadvance;
|
||
|
if (x < cx) x = cx;
|
||
|
}
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
internal real32
|
||
|
font_get_string_width(Render_Font *font, String string){
|
||
|
real32 result = 0;
|
||
|
for (i32 i = 0; i < string.size; ++i){
|
||
|
font_get_glyph_width(font, string.str[i]);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
// BOTTOM
|