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);
}
font_texture = rl::load_texture_from_image(font_atlas);
//rl::draw_texture(font_texture, 0, 0, rl::WHITE);
case ugui::CmdType.CMD_SPRITE:
rl::Rectangle source = {
.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_rectangle(cmd.sprite.rect.x,
// cmd.sprite.rect.y,
// cmd.sprite.rect.w,
// cmd.sprite.rect.h,
// rl::WHITE
//);
case ugui::CmdType.CMD_SCISSOR:
if (cmd.scissor.rect.w == 0 && cmd.scissor.rect.h == 0) {
rl::end_scissor_mode();
} else {
rl::begin_scissor_mode(cmd.scissor.rect.x, cmd.scissor.rect.y, cmd.scissor.rect.w, cmd.scissor.rect.h);
}
default:
io::printfn("Unknown cmd type: %s", cmd.type);
}

@ -7,6 +7,7 @@ enum CmdType {
CMD_RECT,
CMD_UPDATE_ATLAS,
CMD_SPRITE,
CMD_SCISSOR,
}
// command to draw a rect
@ -16,7 +17,6 @@ struct CmdRect {
Color color;
}
// FIXME: For now only support black and white atlas, so PIXELFORMAT_UNCOMPRESSED_GRAYSCALE
struct CmdUpdateAtlas {
Id id;
char* raw_buffer;
@ -31,6 +31,11 @@ struct CmdSprite {
Rect texture_rect;
}
// if rect is zero Rect{0} then reset the scissor
struct CmdScissor {
Rect rect;
}
// command structure
struct Cmd {
CmdType type;
@ -38,6 +43,7 @@ struct Cmd {
CmdRect rect;
CmdUpdateAtlas update_atlas;
CmdSprite sprite;
CmdScissor scissor;
}
}
@ -96,6 +102,8 @@ fn void! Ctx.push_string(&ctx, Rect bounds, String text)
return;
}
ctx.push_scissor(bounds)!;
short baseline = (short)ctx.font.ascender;
short line_height = (short)ctx.font.ascender - (short)ctx.font.descender;
short line_gap = (short)ctx.font.linegap;
@ -135,6 +143,9 @@ fn void! Ctx.push_string(&ctx, Rect bounds, String text)
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)
@ -150,4 +161,13 @@ fn void! Ctx.push_update_atlas(&ctx, Atlas* atlas)
},
};
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
struct Div {
struct ElemDiv {
DivLayout layout;
struct scroll {
bool can_x;
@ -70,12 +70,12 @@ struct Div {
}
// slider element
struct Slider {
struct ElemSlider {
float value;
Rect handle;
}
struct Text {
struct ElemText {
char* str;
}
@ -87,9 +87,9 @@ struct Elem {
Rect bounds;
ElemType type;
union {
Div div;
Slider slider;
Text text;
ElemDiv div;
ElemSlider slider;
ElemText text;
}
}

@ -1,9 +1,12 @@
module ugui;
import schrift;
import grapheme;
import std::collections::map;
import std::core::mem;
import std::io;
import std::ascii;
// unicode code point, different type for a different hash
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)
{
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;
Point origin;
Div* div = &parent.div;
ElemDiv* div = &parent.div;
// 1. Select the right origin
switch (div.layout) {

@ -1,54 +1,6 @@
module ugui;
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)
{

Loading…
Cancel
Save