feat: add shape transforms

This commit is contained in:
2026-03-11 14:11:03 +00:00
parent 562cbc12da
commit 237bb02a8c
7 changed files with 129 additions and 110 deletions

View File

@@ -161,7 +161,7 @@ begin_click_dispatch:
vektor_shapes_update_bbox(state->shapeBuffer); vektor_shapes_update_bbox(state->shapeBuffer);
// polygon's handle count is not fixed, so we have to add them manually // polygon's handle count is not fixed, so we have to add them manually
vektor_shape_add_handle(state->selectedShape, pos); vektor_shape_add_handle(state->selectedShape, pos);
} else if (state->selectedTool == VektorCircleTool) { } else if (state->selectedTool == VektorCircleTool) {
@@ -183,11 +183,9 @@ begin_click_dispatch:
vektor_shapes_update_bbox(state->shapeBuffer); vektor_shapes_update_bbox(state->shapeBuffer);
vektor_circle_create_handles( vektor_circle_create_handles(&state->selectedShape->primitive.circle,
&state->selectedShape->primitive.circle, &state->selectedShape->handles,
&state->selectedShape->handles, &state->selectedShape->handleCount);
&state->selectedShape->handleCount
);
} else if (state->selectedTool == VektorRectangleTool) { } else if (state->selectedTool == VektorRectangleTool) {
VektorRectangle* rect = vektor_rectangle_new(); VektorRectangle* rect = vektor_rectangle_new();
@@ -208,10 +206,8 @@ begin_click_dispatch:
vektor_rectangle_set_end(&state->selectedShape->primitive.rectangle, vektor_rectangle_set_end(&state->selectedShape->primitive.rectangle,
vec2_add(pos, (V2){0.1f, 0.1f})); vec2_add(pos, (V2){0.1f, 0.1f}));
vektor_rectangle_create_handles( vektor_rectangle_create_handles(
&state->selectedShape->primitive.rectangle, &state->selectedShape->primitive.rectangle,
&state->selectedShape->handles, &state->selectedShape->handles, &state->selectedShape->handleCount);
&state->selectedShape->handleCount
);
// state->selectedShape = NULL; // state->selectedShape = NULL;
vektor_shapes_update_bbox(state->shapeBuffer); vektor_shapes_update_bbox(state->shapeBuffer);
@@ -228,7 +224,7 @@ begin_click_dispatch:
state->selectedShape = NULL; state->selectedShape = NULL;
} }
if(state->selectedShape != NULL) if (state->selectedShape != NULL)
g_print("%zu\n", state->selectedShape->handleCount); g_print("%zu\n", state->selectedShape->handleCount);
} }
@@ -242,12 +238,10 @@ void vektor_appstate_canvas_drag_begin(GtkGestureDrag* gesture, gdouble x,
V2 normalized_coords = V2 normalized_coords =
(V2){(2 * (x / widget_w)) - 1, 1 - (2 * (y / widget_h))}; (V2){(2 * (x / widget_w)) - 1, 1 - (2 * (y / widget_h))};
} }
void vektor_appstate_canvas_drag_update(GtkGestureDrag* gesture, void vektor_appstate_canvas_drag_update(GtkGestureDrag* gesture, gdouble x,
gdouble x, gdouble y, gdouble y, gpointer user_data) {
gpointer user_data) {
gdouble start_x, start_y; gdouble start_x, start_y;
gtk_gesture_drag_get_start_point(gesture, &start_x, &start_y); gtk_gesture_drag_get_start_point(gesture, &start_x, &start_y);
@@ -257,9 +251,8 @@ void vektor_appstate_canvas_drag_update(GtkGestureDrag* gesture,
int widget_w = gtk_widget_get_width(widget); int widget_w = gtk_widget_get_width(widget);
int widget_h = gtk_widget_get_height(widget); int widget_h = gtk_widget_get_height(widget);
V2 norm = V2 norm = (V2){(2 * ((x + start_x) / widget_w)) - 1,
(V2){(2 * ( (x+start_x) / widget_w)) - 1, 1 - (2 * ( (y+start_y) / widget_h))}; 1 - (2 * ((y + start_y) / widget_h))};
} }
void vektor_appstate_new(VektorWidgetState* wstate, VektorAppState* stateOut) { void vektor_appstate_new(VektorWidgetState* wstate, VektorAppState* stateOut) {

View File

@@ -1,5 +1,6 @@
#include "primitives.h" #include "primitives.h"
#include "glib.h" #include "glib.h"
#include "src/core/matrix.h"
#include "src/core/vector.h" #include "src/core/vector.h"
#include <assert.h> #include <assert.h>
#include <math.h> #include <math.h>
@@ -78,9 +79,7 @@ void vektor_circle_set_radius(VektorCircle* circle, double radius) {
circle->radius = radius; circle->radius = radius;
} }
void vektor_circle_free(VektorCircle* circle) { void vektor_circle_free(VektorCircle* circle) { free(circle); }
free(circle);
}
VektorRectangle* vektor_rectangle_new(void) { VektorRectangle* vektor_rectangle_new(void) {
VektorRectangle* rct = malloc(sizeof(VektorRectangle)); VektorRectangle* rct = malloc(sizeof(VektorRectangle));
@@ -146,9 +145,8 @@ VektorBBox vektor_rectangle_get_bbox(VektorPrimitive prim) {
VektorBBox vektor_circle_get_bbox(VektorPrimitive prim) { VektorBBox vektor_circle_get_bbox(VektorPrimitive prim) {
return (VektorBBox){ return (VektorBBox){
vec2_sub(prim.circle.center, vec2_fromfloat(prim.circle.radius)), vec2_sub(prim.circle.center, vec2_fromfloat(prim.circle.radius)),
vec2_add(prim.circle.center, vec2_fromfloat(prim.circle.radius)) vec2_add(prim.circle.center, vec2_fromfloat(prim.circle.radius))};
};
} }
VektorBBox vektor_primitive_get_bbox(VektorPrimitive prim) { VektorBBox vektor_primitive_get_bbox(VektorPrimitive prim) {
@@ -178,84 +176,95 @@ VektorBBox vektor_primitive_get_bbox(VektorPrimitive prim) {
// ------ PRIMITIVE HANDLES GENERATION ------ // ------ PRIMITIVE HANDLES GENERATION ------
/* [n]: polyline vertices */ /* [n]: polyline vertices */
void vektor_polyline_create_handles(VektorPolyline* polyline, V2** handleArr, size_t* count) { void vektor_polyline_create_handles(VektorPolyline* polyline, V2** handleArr,
size_t* count) {
*count = 0; *count = 0;
*handleArr = NULL; *handleArr = NULL;
} }
/* [n]: polygon vertices */ /* [n]: polygon vertices */
void vektor_polygon_create_handles(VektorPolygon* polygon, V2** handleArr, size_t* count) { void vektor_polygon_create_handles(VektorPolygon* polygon, V2** handleArr,
size_t* count) {
*count = 0; *count = 0;
*handleArr = NULL; *handleArr = NULL;
} }
/* [0]: center; [1]: radius */ /* [0]: center; [1]: radius */
void vektor_circle_create_handles(VektorCircle* circle, V2** handleArr, size_t* count) { void vektor_circle_create_handles(VektorCircle* circle, V2** handleArr,
size_t* count) {
*count = 2; *count = 2;
*handleArr = (V2*)malloc(sizeof(V2)*(*count)); *handleArr = (V2*)malloc(sizeof(V2) * (*count));
(*handleArr)[0] = circle->center; (*handleArr)[0] = circle->center;
(*handleArr)[1] = (V2){circle->radius + circle->center.x, circle->center.y}; (*handleArr)[1] = (V2){circle->radius + circle->center.x, circle->center.y};
} }
/* [0]: center; [1-4]: corners (l2r, t2b); */ /* [0]: center; [1-4]: corners (l2r, t2b); */
void vektor_rectangle_create_handles(VektorRectangle* rectangle, V2** handleArr, size_t* count) { void vektor_rectangle_create_handles(VektorRectangle* rectangle, V2** handleArr,
size_t* count) {
*count = 5; *count = 5;
free(*handleArr); free(*handleArr);
*handleArr = (V2*)malloc(sizeof(V2)*(*count)); *handleArr = (V2*)malloc(sizeof(V2) * (*count));
V2 halfdist = vec2_scale(vec2_sub(rectangle->end, rectangle->start), 0.5f); V2 halfdist = vec2_scale(vec2_sub(rectangle->end, rectangle->start), 0.5f);
V2 center = vec2_add(rectangle->start, halfdist); V2 center = vec2_add(rectangle->start, halfdist);
g_print("boobs: %f %f\n", rectangle->start.x, rectangle->start.y); g_print("boobs: %f %f\n", rectangle->start.x, rectangle->start.y);
g_print("pussy: %f %f\n", rectangle->end.x, rectangle->end.y); g_print("pussy: %f %f\n", rectangle->end.x, rectangle->end.y);
(*handleArr)[0] = center; (*handleArr)[0] = center;
(*handleArr)[1] = vec2_add( center, vec2_mul(halfdist, (V2){-1.0f, 1.0f}) ); (*handleArr)[1] = vec2_add(center, vec2_mul(halfdist, (V2){-1.0f, 1.0f}));
(*handleArr)[2] = vec2_add( center, halfdist); (*handleArr)[2] = vec2_add(center, halfdist);
(*handleArr)[3] = vec2_add( center, vec2_mul(halfdist, (V2){-1.0f, -1.0f}) ); (*handleArr)[3] = vec2_add(center, vec2_mul(halfdist, (V2){-1.0f, -1.0f}));
(*handleArr)[4] = vec2_add( center, vec2_mul(halfdist, (V2){1.0f, -1.0f}) ); (*handleArr)[4] = vec2_add(center, vec2_mul(halfdist, (V2){1.0f, -1.0f}));
} }
void vektor_shape_create_handles(VektorShape* shape) { void vektor_shape_create_handles(VektorShape* shape) {
switch(shape->primitive.kind) { switch (shape->primitive.kind) {
case VEKTOR_POLYLINE: case VEKTOR_POLYLINE:
vektor_polyline_create_handles(shape->primitive.polyline, &shape->handles, &shape->handleCount); vektor_polyline_create_handles(shape->primitive.polyline,
break; &shape->handles, &shape->handleCount);
case VEKTOR_POLYGON: break;
vektor_polygon_create_handles(shape->primitive.polygon, &shape->handles, &shape->handleCount); case VEKTOR_POLYGON:
break; vektor_polygon_create_handles(shape->primitive.polygon, &shape->handles,
case VEKTOR_CIRCLE: &shape->handleCount);
vektor_circle_create_handles(&shape->primitive.circle, &shape->handles, &shape->handleCount); break;
break; case VEKTOR_CIRCLE:
case VEKTOR_RECTANGLE: vektor_circle_create_handles(&shape->primitive.circle, &shape->handles,
vektor_rectangle_create_handles(&shape->primitive.rectangle, &shape->handles, &shape->handleCount); &shape->handleCount);
break; break;
case VEKTOR_RECTANGLE:
vektor_rectangle_create_handles(&shape->primitive.rectangle,
&shape->handles, &shape->handleCount);
break;
} }
} }
// ------ PRIMITIVE HANDLES UPDATING ------ // ------ PRIMITIVE HANDLES UPDATING ------
void vektor_polyline_handles_updated(VektorPolyline* polyline, V2** handles, size_t* count) { void vektor_polyline_handles_updated(VektorPolyline* polyline, V2** handles,
if(*count != polyline->count) { size_t* count) {
if (*count != polyline->count) {
g_warning("handle count & point count mismatch in polyline"); g_warning("handle count & point count mismatch in polyline");
return; return;
} }
for(size_t i = 0; i < *count; i++) { for (size_t i = 0; i < *count; i++) {
polyline->points[i] = (*handles)[i]; polyline->points[i] = (*handles)[i];
} }
} }
void vektor_polygon_handles_updated(VektorPolygon* polygon, V2** handles, size_t* count) { void vektor_polygon_handles_updated(VektorPolygon* polygon, V2** handles,
if(*count != polygon->count) { size_t* count) {
if (*count != polygon->count) {
g_warning("handle count & point count mismatch in polygon"); g_warning("handle count & point count mismatch in polygon");
return; return;
} }
for(size_t i = 0; i < *count; i++) { for (size_t i = 0; i < *count; i++) {
polygon->points[i] = (*handles)[i]; polygon->points[i] = (*handles)[i];
} }
} }
void vektor_circle_handles_updated(VektorCircle* circle, V2** handles, size_t* count) { void vektor_circle_handles_updated(VektorCircle* circle, V2** handles,
if(*count != 2) { size_t* count) {
if (*count != 2) {
g_warning("unexpected circle handle count (%zu)", *count); g_warning("unexpected circle handle count (%zu)", *count);
return; return;
} }
@@ -263,12 +272,13 @@ void vektor_circle_handles_updated(VektorCircle* circle, V2** handles, size_t* c
circle->radius = vec2_length(vec2_sub((*handles)[0], (*handles)[1])); circle->radius = vec2_length(vec2_sub((*handles)[0], (*handles)[1]));
} }
void vektor_rectangle_handles_updated(VektorRectangle* rectangle, V2** handles, size_t* count) { void vektor_rectangle_handles_updated(VektorRectangle* rectangle, V2** handles,
if(*count != 5) { size_t* count) {
if (*count != 5) {
g_warning("unexpected rectangle handle count (%zu)", *count); g_warning("unexpected rectangle handle count (%zu)", *count);
return; return;
} }
// get rectangle center // get rectangle center
V2 halfdist = vec2_scale(vec2_sub(rectangle->end, rectangle->start), 0.5f); V2 halfdist = vec2_scale(vec2_sub(rectangle->end, rectangle->start), 0.5f);
V2 rectcenter = vec2_add(rectangle->start, halfdist); V2 rectcenter = vec2_add(rectangle->start, halfdist);
@@ -276,7 +286,7 @@ void vektor_rectangle_handles_updated(VektorRectangle* rectangle, V2** handles,
// center according to handles // center according to handles
V2 center = (*handles)[0]; V2 center = (*handles)[0];
if(vec2_equals(center, rectcenter)) { // corner handles were changed if (vec2_equals(center, rectcenter)) { // corner handles were changed
V2 p1 = (*handles)[1]; V2 p1 = (*handles)[1];
V2 p2 = (*handles)[2]; V2 p2 = (*handles)[2];
V2 p3 = (*handles)[3]; V2 p3 = (*handles)[3];
@@ -290,7 +300,7 @@ void vektor_rectangle_handles_updated(VektorRectangle* rectangle, V2** handles,
V2 min = (V2){min_x, min_y}; V2 min = (V2){min_x, min_y};
V2 max = (V2){max_x, max_y}; V2 max = (V2){max_x, max_y};
VektorRectangle propertRect = (VektorRectangle){min,max}; VektorRectangle propertRect = (VektorRectangle){min, max};
// overwrite handles array (create_handles() frees the passed one) // overwrite handles array (create_handles() frees the passed one)
vektor_rectangle_create_handles(&propertRect, handles, count); vektor_rectangle_create_handles(&propertRect, handles, count);
@@ -299,26 +309,29 @@ void vektor_rectangle_handles_updated(VektorRectangle* rectangle, V2** handles,
V2 newmax = vec2_add((*handles)[2], translation); V2 newmax = vec2_add((*handles)[2], translation);
V2 newmin = vec2_add((*handles)[3], translation); V2 newmin = vec2_add((*handles)[3], translation);
VektorRectangle propertRect = (VektorRectangle){newmin,newmax}; VektorRectangle propertRect = (VektorRectangle){newmin, newmax};
vektor_rectangle_create_handles(&propertRect, handles, count); vektor_rectangle_create_handles(&propertRect, handles, count);
} }
} }
void vektor_shape_handles_updated(VektorShape* shape) { void vektor_shape_handles_updated(VektorShape* shape) {
switch(shape->primitive.kind) { switch (shape->primitive.kind) {
case VEKTOR_POLYLINE: case VEKTOR_POLYLINE:
vektor_polyline_handles_updated(shape->primitive.polyline, &shape->handles, &shape->handleCount); vektor_polyline_handles_updated(shape->primitive.polyline,
break; &shape->handles, &shape->handleCount);
case VEKTOR_POLYGON: break;
vektor_polygon_handles_updated(shape->primitive.polygon, &shape->handles, &shape->handleCount); case VEKTOR_POLYGON:
break; vektor_polygon_handles_updated(shape->primitive.polygon,
case VEKTOR_CIRCLE: &shape->handles, &shape->handleCount);
vektor_circle_handles_updated(&shape->primitive.circle, &shape->handles, &shape->handleCount); break;
break; case VEKTOR_CIRCLE:
case VEKTOR_RECTANGLE: vektor_circle_handles_updated(&shape->primitive.circle, &shape->handles,
vektor_rectangle_handles_updated(&shape->primitive.rectangle, &shape->handles, &shape->handleCount); &shape->handleCount);
break; break;
case VEKTOR_RECTANGLE:
vektor_rectangle_handles_updated(&shape->primitive.rectangle,
&shape->handles, &shape->handleCount);
break;
} }
} }
@@ -327,7 +340,8 @@ void vektor_shape_add_handle(VektorShape* shape, V2 handle) {
// but this function is only called when adding new // but this function is only called when adding new
// points to polyline and polygon, so it should // points to polyline and polygon, so it should
// not be that much of an overhead // not be that much of an overhead
shape->handles = realloc(shape->handles, sizeof(V2) * shape->handleCount + 1); shape->handles =
realloc(shape->handles, sizeof(V2) * shape->handleCount + 1);
shape->handles[shape->handleCount++] = handle; shape->handles[shape->handleCount++] = handle;
} }
@@ -342,14 +356,12 @@ VektorBBox vektor_bbox_fromcenter(V2 center, float dist) {
V2 v2dist = vec2_fromfloat(dist); V2 v2dist = vec2_fromfloat(dist);
V2 min = vec2_sub(center, v2dist); V2 min = vec2_sub(center, v2dist);
V2 max = vec2_add(center, v2dist); V2 max = vec2_add(center, v2dist);
return (VektorBBox){min,max}; return (VektorBBox){min, max};
} }
VektorBBox vektor_bbox_expand(VektorBBox bbox, float val) { VektorBBox vektor_bbox_expand(VektorBBox bbox, float val) {
return (VektorBBox){ return (VektorBBox){vec2_sub(bbox.min, vec2_fromfloat(val)),
vec2_sub(bbox.min, vec2_fromfloat(val)), vec2_add(bbox.max, vec2_fromfloat(val))};
vec2_add(bbox.max, vec2_fromfloat(val))
};
} }
// ------ SHAPE METHODS ------ // ------ SHAPE METHODS ------
@@ -357,14 +369,16 @@ VektorBBox vektor_bbox_expand(VektorBBox bbox, float val) {
VektorShape vektor_shape_new(VektorPrimitive prim, VektorStyle style, VektorShape vektor_shape_new(VektorPrimitive prim, VektorStyle style,
int z_index) { int z_index) {
VektorShape shape = (VektorShape){.primitive = prim, VektorShape shape = (VektorShape){.primitive = prim,
.style = style, .style = style,
.z_index = z_index, .transform = m33_identity(),
.bbox = vektor_primitive_get_bbox(prim)}; .z_index = z_index,
.bbox = vektor_primitive_get_bbox(prim)};
/* /*
create_handles() allocates new buffer for handles, create_handles() allocates new buffer for handles,
and even if the local shape variable goes out of scope and deallocates, and even if the local shape variable goes out of scope and deallocates,
the passed value's pointer to an array of handles remains valid in the passed copy. the passed value's pointer to an array of handles remains valid in the
passed copy.
*/ */
vektor_shape_create_handles(&shape); vektor_shape_create_handles(&shape);
return shape; return shape;

View File

@@ -1,6 +1,7 @@
#ifndef PRIMITIVES_H_ #ifndef PRIMITIVES_H_
#define PRIMITIVES_H_ #define PRIMITIVES_H_
#include "src/core/matrix.h"
#include "src/util/color.h" #include "src/util/color.h"
#include "stddef.h" #include "stddef.h"
#include "stdlib.h" #include "stdlib.h"
@@ -58,6 +59,7 @@ typedef struct {
typedef struct { typedef struct {
VektorStyle style; VektorStyle style;
int z_index; int z_index;
M33 transform;
VektorBBox bbox; VektorBBox bbox;
VektorPrimitive primitive; VektorPrimitive primitive;
@@ -83,7 +85,8 @@ void vektor_rectangle_set_end(VektorRectangle* rct, V2 point);
void vektor_rectangle_set_start(VektorRectangle* rct, V2 point); void vektor_rectangle_set_start(VektorRectangle* rct, V2 point);
void vektor_rectangle_free(VektorRectangle* rct); void vektor_rectangle_free(VektorRectangle* rct);
VektorShape vektor_shape_new(VektorPrimitive prim, VektorStyle style, int z_index); VektorShape vektor_shape_new(VektorPrimitive prim, VektorStyle style,
int z_index);
VektorBBox vektor_polyline_get_bbox(VektorPrimitive prim); VektorBBox vektor_polyline_get_bbox(VektorPrimitive prim);
VektorBBox vektor_polygon_get_bbox(VektorPrimitive prim); VektorBBox vektor_polygon_get_bbox(VektorPrimitive prim);
@@ -96,18 +99,26 @@ VektorBBox vektor_bbox_fromcenter(V2 center, float dist);
VektorBBox vektor_bbox_expand(VektorBBox bbox, float val); VektorBBox vektor_bbox_expand(VektorBBox bbox, float val);
// shape handles // shape handles
void vektor_polyline_create_handles(VektorPolyline* polyline, V2** handleArr, size_t* count); void vektor_polyline_create_handles(VektorPolyline* polyline, V2** handleArr,
void vektor_polygon_create_handles(VektorPolygon* polygon, V2** handleArr, size_t* count); size_t* count);
void vektor_circle_create_handles(VektorCircle* circle, V2** handleArr, size_t* count); void vektor_polygon_create_handles(VektorPolygon* polygon, V2** handleArr,
void vektor_rectangle_create_handles(VektorRectangle* rectangle, V2** handleArr, size_t* count); size_t* count);
void vektor_circle_create_handles(VektorCircle* circle, V2** handleArr,
size_t* count);
void vektor_rectangle_create_handles(VektorRectangle* rectangle, V2** handleArr,
size_t* count);
void vektor_shape_create_handles(VektorShape* shape); void vektor_shape_create_handles(VektorShape* shape);
void vektor_shape_add_handle(VektorShape* shape, V2 handle); void vektor_shape_add_handle(VektorShape* shape, V2 handle);
/* reconstructs the shape based on handles alone */ /* reconstructs the shape based on handles alone */
void vektor_polyline_handles_updated(VektorPolyline* polyline, V2** handles, size_t* count); void vektor_polyline_handles_updated(VektorPolyline* polyline, V2** handles,
void vektor_polygon_handles_updated(VektorPolygon* polygon, V2** handles, size_t* count); size_t* count);
void vektor_circle_handles_updated(VektorCircle* circle, V2** handles, size_t* count); void vektor_polygon_handles_updated(VektorPolygon* polygon, V2** handles,
void vektor_rectangle_handles_updated(VektorRectangle* rectangle, V2** handles, size_t* count); size_t* count);
void vektor_circle_handles_updated(VektorCircle* circle, V2** handles,
size_t* count);
void vektor_rectangle_handles_updated(VektorRectangle* rectangle, V2** handles,
size_t* count);
void vektor_shape_handles_updated(VektorShape* shape); void vektor_shape_handles_updated(VektorShape* shape);
typedef struct { typedef struct {

View File

@@ -1,6 +1,7 @@
#include "raster.h" #include "raster.h"
#include "epoxy/gl.h" #include "epoxy/gl.h"
#include "primitives.h" #include "primitives.h"
#include "src/core/matrix.h"
#include "src/core/vector.h" #include "src/core/vector.h"
#include "stddef.h" #include "stddef.h"
#include <math.h> #include <math.h>
@@ -144,10 +145,14 @@ void vektor_edge_to_triangles(VertexBuffer* vb, Edge e,
float py = float py =
dx / len * (shape_buffer->shapes[e.shape_id].style.stroke_width / 2); dx / len * (shape_buffer->shapes[e.shape_id].style.stroke_width / 2);
V2 v0 = {e.p1.x + px, e.p1.y + py}; V2 v0 = m33_transform(shape_buffer->shapes[e.shape_id].transform,
V2 v1 = {e.p1.x - px, e.p1.y - py}; (V2){e.p1.x + px, e.p1.y + py});
V2 v2 = {e.p2.x + px, e.p2.y + py}; V2 v1 = m33_transform(shape_buffer->shapes[e.shape_id].transform,
V2 v3 = {e.p2.x - px, e.p2.y - py}; (V2){e.p1.x - px, e.p1.y - py});
V2 v2 = m33_transform(shape_buffer->shapes[e.shape_id].transform,
(V2){e.p2.x + px, e.p2.y + py});
V2 v3 = m33_transform(shape_buffer->shapes[e.shape_id].transform,
(V2){e.p2.x - px, e.p2.y - py});
vektor_vb_add_triangle(vb, v0, v1, v2, vektor_vb_add_triangle(vb, v0, v1, v2,
shape_buffer->shapes[e.shape_id].style.stroke_color); shape_buffer->shapes[e.shape_id].style.stroke_color);

View File

@@ -14,7 +14,7 @@ typedef struct {
double z; double z;
} V3; } V3;
static inline V2 vec2_fromfloat(const float f) { return (V2){f,f}; } static inline V2 vec2_fromfloat(const float f) { return (V2){f, f}; }
static inline V3 vec2_vector(const V2 v) { return (V3){v.x, v.y, 0}; } static inline V3 vec2_vector(const V2 v) { return (V3){v.x, v.y, 0}; }

View File

@@ -7,7 +7,6 @@
#include "./application/applicationstate.h" #include "./application/applicationstate.h"
#include "./ui/uicontroller.h" #include "./ui/uicontroller.h"
static int update_callback(gpointer data) { static int update_callback(gpointer data) {
VektorAppState* appstate = (VektorAppState*)data; VektorAppState* appstate = (VektorAppState*)data;
gtk_gl_area_queue_render( gtk_gl_area_queue_render(

View File

@@ -140,19 +140,20 @@ static gboolean render(GtkGLArea* a, GdkGLContext* ctx,
vb.count = 0; vb.count = 0;
vektor_rasterize(&vb, renderInfo->shapes, renderInfo->zoom); vektor_rasterize(&vb, renderInfo->shapes, renderInfo->zoom);
size_t shape_vertex_count = vb.count; // remember how many vertices belong to shapes size_t shape_vertex_count =
vb.count; // remember how many vertices belong to shapes
if (renderInfo->selectedShape != NULL && if (renderInfo->selectedShape != NULL &&
*(renderInfo->selectedShape) != NULL) { *(renderInfo->selectedShape) != NULL) {
VektorShape* selectedShape = *renderInfo->selectedShape; VektorShape* selectedShape = *renderInfo->selectedShape;
// create handle quads if a shape is selected // create handle quads if a shape is selected
for(size_t i = 0; i < selectedShape->handleCount; i++) { for (size_t i = 0; i < selectedShape->handleCount; i++) {
V2 handle = selectedShape->handles[i]; V2 handle = selectedShape->handles[i];
VektorBBox handleBbox = vektor_bbox_fromcenter(handle, 0.01f); VektorBBox handleBbox = vektor_bbox_fromcenter(handle, 0.01f);
vektor_vb_add_quad(&vb, handleBbox.min, handleBbox.max, vektor_color_new(255, 255, 255, 255)); vektor_vb_add_quad(&vb, handleBbox.min, handleBbox.max,
vektor_color_new(255, 255, 255, 255));
} }
shape_vertex_count = vb.count; shape_vertex_count = vb.count;
@@ -164,12 +165,8 @@ static gboolean render(GtkGLArea* a, GdkGLContext* ctx,
vektor_vb_add_quad(&vb, bbox.min, bbox.max, vektor_vb_add_quad(&vb, bbox.min, bbox.max,
vektor_color_new(255, 255, 255, 255)); vektor_color_new(255, 255, 255, 255));
} }
glBufferData(GL_ARRAY_BUFFER, vb.count * sizeof(Vertex), vb.vertices, glBufferData(GL_ARRAY_BUFFER, vb.count * sizeof(Vertex), vb.vertices,
GL_STATIC_DRAW); GL_STATIC_DRAW);