/* Herramientas de dibujo. * Capa 1 (primitivas): funciones sobre un tgb_canvas, sin historial. * Capa 2 (sesión de edición): tgb_edit_* conecta una celda del documento * con el historial: todo lo dibujado entre begin y end es UNA operación * que se puede deshacer. Solo puede haber una sesión abierta por documento. */ #ifndef TAHGIBU_DRAWING_H #define TAHGIBU_DRAWING_H #include "tahgibu/document.h" #ifdef __cplusplus extern "C" { #endif typedef enum tgb_brush_mode { TGB_BRUSH_PAINT = 0, TGB_BRUSH_ERASE = 1 } tgb_brush_mode; typedef struct tgb_brush { float size; /* diámetro en píxeles (1..512) */ float hardness; /* 0 (muy suave) .. 1 (borde duro) */ bool antialias; /* false = lápiz de píxeles exactos */ tgb_color color; tgb_brush_mode mode; } tgb_brush; tgb_brush tgb_brush_pencil(tgb_color color, int size); /* sin suavizado */ tgb_brush tgb_brush_soft(tgb_color color, float size, float hardness); tgb_brush tgb_brush_eraser(float size, float hardness); /* ---- Primitivas (marcan la zona modificada del lienzo) ---- */ void tgb_draw_dab(tgb_canvas *c, const tgb_brush *b, float x, float y); void tgb_draw_line(tgb_canvas *c, const tgb_brush *b, float x0, float y0, float x1, float y1); void tgb_draw_rect(tgb_canvas *c, const tgb_brush *b, tgb_rect r, bool filled); void tgb_draw_ellipse(tgb_canvas *c, const tgb_brush *b, tgb_rect bounds, bool filled); /* Curva de Bézier cúbica con puntos de control p1 y p2. */ void tgb_draw_bezier(tgb_canvas *c, const tgb_brush *b, float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3); /* Relleno por inundación; tolerance 0..255 (por canal). Devuelve píxeles cambiados. */ size_t tgb_flood_fill(tgb_canvas *c, int x, int y, tgb_color fill, int tolerance); tgb_color tgb_eyedropper(const tgb_canvas *c, int x, int y); /* Transformaciones de una región (selección rectangular). */ tgb_status tgb_region_move(tgb_canvas *c, tgb_rect src, int dx, int dy); /* mueve y deja hueco */ tgb_status tgb_region_flip(tgb_canvas *c, tgb_rect r, bool horizontal); tgb_status tgb_region_scale(tgb_canvas *c, tgb_rect r, int new_w, int new_h); /* vecino más cercano, ancla arriba-izquierda */ tgb_status tgb_region_clear(tgb_canvas *c, tgb_rect r); /* ---- Sesión de edición ligada al documento ---- */ /* Abre la sesión sobre la celda (frame_id, layer_id). Crea la celda si estaba * vacía. Errores: TGB_ERR_LOCKED (capa bloqueada), TGB_ERR_STATE (ya hay * sesión), TGB_ERR_NOT_FOUND. */ tgb_status tgb_edit_begin(tgb_document *doc, uint32_t frame_id, uint32_t layer_id, const char *label); /* Lienzo editable de la sesión (NULL si no hay sesión). NO lo liberes. */ tgb_canvas *tgb_edit_canvas(tgb_document *doc); /* Vuelve al estado del principio de la sesión (útil para previsualizar formas). */ tgb_status tgb_edit_reset(tgb_document *doc); /* Cierra y registra UNA operación en el historial si hubo cambios reales. * Devuelve TGB_WARN_HISTORY_LOST si el cambio se aplicó pero no cabe en el * historial. Si falla por memoria, deja la celda como estaba. */ tgb_status tgb_edit_end(tgb_document *doc); tgb_status tgb_edit_cancel(tgb_document *doc); /* descarta los cambios */ bool tgb_edit_active(const tgb_document *doc); #ifdef __cplusplus } #endif #endif