#include "rgl.h" void RGL_DrawRect(RGL_Buffer *buf, RGL_Command *cmd) { unsigned int x, y, insideX, insideY; RGL_ASSERT(cmd->type != Rect, "expected rectangle type"); for (y = 0; y < buf->height; ++y) { for (x = 0; x < buf->width; ++x) { insideX = x >= cmd->data.rect.x && x <= (cmd->data.rect.x + cmd->data.rect.width); insideY = y >= cmd->data.rect.y && y <= (cmd->data.rect.y + cmd->data.rect.height); if (insideX && insideY) { buf->data[x + (y * buf->width)] = cmd->data.rect.color; } } } } void RGL_DrawStroke(RGL_Buffer *buf, RGL_PathHeader *path, RGL_Point *points) { RGL_Point p1, p2; unsigned int i; int x0, x1, y0, y1, dx, dy, sx, sy, idx, err, e2; for (i = 0; i < path->size; ++i) { p1 = points[i], p2 = points[(i + 1) % path->size]; x0 = RGL_FixedToInt(p1.x), y0 = RGL_FixedToInt(p1.y); x1 = RGL_FixedToInt(p2.x), y1 = RGL_FixedToInt(p2.y); dx = RGL_ABS(x1 - x0); sx = x0 < x1 ? 1 : -1; dy = -RGL_ABS(y1 - y0); sy = y0 < y1 ? 1 : -1; err = dx + dy; while (1) { idx = x0 + (y0 * buf->width); if (idx < buf->width * buf->height) { buf->data[idx] = path->color; } if (x0 == x1 && y0 == y1) break; e2 = err * 2; if (e2 >= dy) { err += dy; x0 += sx; } if (e2 <= dx) { err += dx; y0 += sy; } } } } void RGL_DrawPath(RGL_Buffer *buf, RGL_PathHeader *path, RGL_Point *points) { switch (path->verb) { case PathStroke: { RGL_DrawStroke(buf, path, points); } break; case PathFill: { /* RGL_DrawFill(buf, path, points, col); */ RGL_CRASH("`RGL_DrawFill` not implemented"); } break; default: { RGL_CRASH("tried to handle unknown `path->verb`"); } break; } } void RGL_Draw(RGL_Context *ctx, RGL_Buffer *buf) { RGL_Command cmd; int i; for (i = 0; i < ctx->queue.size; ++i) { cmd = ctx->queue.commands[i]; switch (cmd.type) { case Rect: { RGL_DrawRect(buf, &cmd); } break; case Path: { RGL_Point *points = (RGL_Point *)&(ctx->queue.commands[i + 1]); RGL_DrawPath(buf, &cmd.data.path, points); /* Skip point list, so it points to a valid command */ ctx->queue.commands = (RGL_Command *)((char *)ctx->queue.commands + cmd.data.path.size * sizeof(RGL_Point)); } break; default: { RGL_CRASH("unknown `cmd.type`"); } break; } } }