scissor command

c3
Alessandro Mauri 1 week ago
parent 6d8300f9d9
commit bca29c537c
  1. 13
      src/main.c3
  2. 22
      src/ugui_cmd.c3
  3. 12
      src/ugui_data.c3
  4. 49
      src/ugui_font.c3
  5. 2
      src/ugui_layout.c3
  6. 48
      src/ugui_text.c3

@ -162,7 +162,6 @@ fn int main(String[] args)
rl::unload_texture(font_texture); rl::unload_texture(font_texture);
} }
font_texture = rl::load_texture_from_image(font_atlas); font_texture = rl::load_texture_from_image(font_atlas);
//rl::draw_texture(font_texture, 0, 0, rl::WHITE);
case ugui::CmdType.CMD_SPRITE: case ugui::CmdType.CMD_SPRITE:
rl::Rectangle source = { rl::Rectangle source = {
.x = cmd.sprite.texture_rect.x, .x = cmd.sprite.texture_rect.x,
@ -176,12 +175,12 @@ fn int main(String[] args)
}; };
rl::draw_texture_rec(font_texture, source, position, rl::WHITE); rl::draw_texture_rec(font_texture, source, position, rl::WHITE);
//rl::draw_rectangle(cmd.sprite.rect.x, case ugui::CmdType.CMD_SCISSOR:
// cmd.sprite.rect.y, if (cmd.scissor.rect.w == 0 && cmd.scissor.rect.h == 0) {
// cmd.sprite.rect.w, rl::end_scissor_mode();
// cmd.sprite.rect.h, } else {
// rl::WHITE rl::begin_scissor_mode(cmd.scissor.rect.x, cmd.scissor.rect.y, cmd.scissor.rect.w, cmd.scissor.rect.h);
//); }
default: default:
io::printfn("Unknown cmd type: %s", cmd.type); io::printfn("Unknown cmd type: %s", cmd.type);
} }

@ -7,6 +7,7 @@ enum CmdType {
CMD_RECT, CMD_RECT,
CMD_UPDATE_ATLAS, CMD_UPDATE_ATLAS,
CMD_SPRITE, CMD_SPRITE,
CMD_SCISSOR,
} }
// command to draw a rect // command to draw a rect
@ -16,7 +17,6 @@ struct CmdRect {
Color color; Color color;
} }
// FIXME: For now only support black and white atlas, so PIXELFORMAT_UNCOMPRESSED_GRAYSCALE
struct CmdUpdateAtlas { struct CmdUpdateAtlas {
Id id; Id id;
char* raw_buffer; char* raw_buffer;
@ -31,6 +31,11 @@ struct CmdSprite {
Rect texture_rect; Rect texture_rect;
} }
// if rect is zero Rect{0} then reset the scissor
struct CmdScissor {
Rect rect;
}
// command structure // command structure
struct Cmd { struct Cmd {
CmdType type; CmdType type;
@ -38,6 +43,7 @@ struct Cmd {
CmdRect rect; CmdRect rect;
CmdUpdateAtlas update_atlas; CmdUpdateAtlas update_atlas;
CmdSprite sprite; CmdSprite sprite;
CmdScissor scissor;
} }
} }
@ -96,6 +102,8 @@ fn void! Ctx.push_string(&ctx, Rect bounds, String text)
return; return;
} }
ctx.push_scissor(bounds)!;
short baseline = (short)ctx.font.ascender; short baseline = (short)ctx.font.ascender;
short line_height = (short)ctx.font.ascender - (short)ctx.font.descender; short line_height = (short)ctx.font.ascender - (short)ctx.font.descender;
short line_gap = (short)ctx.font.linegap; short line_gap = (short)ctx.font.linegap;
@ -135,6 +143,9 @@ fn void! Ctx.push_string(&ctx, Rect bounds, String text)
continue; continue;
} }
} }
// FIXME: we never get here if an error was thrown before
ctx.push_scissor(Rect{})!;
} }
fn void! Ctx.push_update_atlas(&ctx, Atlas* atlas) fn void! Ctx.push_update_atlas(&ctx, Atlas* atlas)
@ -150,4 +161,13 @@ fn void! Ctx.push_update_atlas(&ctx, Atlas* atlas)
}, },
}; };
ctx.cmd_queue.enqueue(&up)!; ctx.cmd_queue.enqueue(&up)!;
}
fn void! Ctx.push_scissor(&ctx, Rect rect)
{
Cmd sc = {
.type = CMD_SCISSOR,
.scissor.rect = rect,
};
ctx.cmd_queue.enqueue(&sc)!;
} }

@ -54,7 +54,7 @@ enum DivLayout {
} }
// div element // div element
struct Div { struct ElemDiv {
DivLayout layout; DivLayout layout;
struct scroll { struct scroll {
bool can_x; bool can_x;
@ -70,12 +70,12 @@ struct Div {
} }
// slider element // slider element
struct Slider { struct ElemSlider {
float value; float value;
Rect handle; Rect handle;
} }
struct Text { struct ElemText {
char* str; char* str;
} }
@ -87,9 +87,9 @@ struct Elem {
Rect bounds; Rect bounds;
ElemType type; ElemType type;
union { union {
Div div; ElemDiv div;
Slider slider; ElemSlider slider;
Text text; ElemText text;
} }
} }

@ -1,9 +1,12 @@
module ugui; module ugui;
import schrift; import schrift;
import grapheme;
import std::collections::map; import std::collections::map;
import std::core::mem; import std::core::mem;
import std::io; import std::io;
import std::ascii;
// unicode code point, different type for a different hash // unicode code point, different type for a different hash
def Codepoint = uint; def Codepoint = uint;
@ -161,4 +164,50 @@ fn void Font.free(&font)
fn void! Ctx.load_font(&ctx, String name, String path, uint height, float scale = 1.0) fn void! Ctx.load_font(&ctx, String name, String path, uint height, float scale = 1.0)
{ {
return ctx.font.load(name, path, height, scale); return ctx.font.load(name, path, height, scale);
}
<*
@require off != null
*>
fn Codepoint str_to_codepoint(char[] str, usz* off)
{
Codepoint cp;
isz b = grapheme::decode_utf8(str, str.len, &cp);
if (b == 0 || b > str.len) {
return 0;
}
*off = b;
return cp;
}
fn Rect! Ctx.get_text_bounds(&ctx, String text)
{
Rect text_bounds;
short line_height = (short)ctx.font.ascender - (short)ctx.font.descender;
short line_gap = (short)ctx.font.linegap;
text_bounds.h = line_height;
Glyph* gp;
// TODO: account for unicode codepoints
short line_len;
Codepoint cp;
usz off, x;
while ((cp = str_to_codepoint(text[off..], &x)) != 0) {
off += x;
bool n;
if (!ascii::is_cntrl((char)cp)) {
gp = ctx.font.get_glyph(cp)!;
line_len += gp.adv;
} else if (cp == '\n'){
text_bounds.h += line_height + line_gap;
line_len = 0;
} else {
continue;
}
if (line_len > text_bounds.w) {
text_bounds.w = line_len;
}
}
return text_bounds;
} }

@ -86,7 +86,7 @@ fn Rect Ctx.position_element(&ctx, Elem *parent, Rect rect, bool style = false)
{ {
Rect placement; Rect placement;
Point origin; Point origin;
Div* div = &parent.div; ElemDiv* div = &parent.div;
// 1. Select the right origin // 1. Select the right origin
switch (div.layout) { switch (div.layout) {

@ -1,54 +1,6 @@
module ugui; module ugui;
import std::io; import std::io;
import std::ascii;
import grapheme;
<*
@require off != null
*>
fn Codepoint str_to_codepoint(char[] str, usz* off)
{
Codepoint cp;
isz b = grapheme::decode_utf8(str, str.len, &cp);
if (b == 0 || b > str.len) {
return 0;
}
*off = b;
return cp;
}
fn Rect! Ctx.get_text_bounds(&ctx, String text)
{
Rect text_bounds;
short line_height = (short)ctx.font.ascender - (short)ctx.font.descender;
short line_gap = (short)ctx.font.linegap;
text_bounds.h = line_height;
Glyph* gp;
// TODO: account for unicode codepoints
short line_len;
Codepoint cp;
usz off, x;
while ((cp = str_to_codepoint(text[off..], &x)) != 0) {
off += x;
bool n;
if (!ascii::is_cntrl((char)cp)) {
gp = ctx.font.get_glyph(cp)!;
line_len += gp.adv;
} else if (cp == '\n'){
text_bounds.h += line_height + line_gap;
line_len = 0;
} else {
continue;
}
if (line_len > text_bounds.w) {
text_bounds.w = line_len;
}
}
return text_bounds;
}
fn void! Ctx.text_unbounded(&ctx, String label, String text) fn void! Ctx.text_unbounded(&ctx, String label, String text)
{ {

Loading…
Cancel
Save