From: Jean-Philippe Bruyère Date: Wed, 22 Jan 2020 19:50:31 +0000 (+0100) Subject: prepare set/get dash X-Git-Tag: v0.1-alpha~46 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=4c55ba663b059584cd12dec94b63b3d1f4eca237;p=jp%2Fvkvg.git prepare set/get dash --- diff --git a/include/vkvg.h b/include/vkvg.h index 4946f70..6c6684c 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -50,7 +50,7 @@ static uint8_t log_level = LOG_ERR;// | LOG_INFO | LOG_DEBUG | LOG_INFO_PATH; #define LOG #endif -typedef enum _vkvg_status { +typedef enum { VKVG_STATUS_SUCCESS = 0, VKVG_STATUS_NO_MEMORY, VKVG_STATUS_INVALID_RESTORE, @@ -73,26 +73,26 @@ typedef enum _vkvg_status { VKVG_STATUS_INVALID_DASH }vkvg_status_t; -typedef enum _vkvg_direction { +typedef enum { VKVG_HORIZONTAL = 0, VKVG_VERTICAL = 1 }vkvg_direction_t; -typedef enum _vkvg_format { +typedef enum { VKVG_FORMAT_ARGB32, VKVG_FORMAT_RGB24, VKVG_FORMAT_A8, VKVG_FORMAT_A1 } vkvg_format_t; -typedef enum _vkvg_extend { +typedef enum { VKVG_EXTEND_NONE, VKVG_EXTEND_REPEAT, VKVG_EXTEND_REFLECT, VKVG_EXTEND_PAD } vkvg_extend_t; -typedef enum _vkvg_filter { +typedef enum { VKVG_FILTER_FAST, VKVG_FILTER_GOOD, VKVG_FILTER_BEST, @@ -101,7 +101,7 @@ typedef enum _vkvg_filter { VKVG_FILTER_GAUSSIAN, } vkvg_filter_t; -typedef enum _vkvg_pattern_type { +typedef enum { VKVG_PATTERN_TYPE_SOLID, VKVG_PATTERN_TYPE_SURFACE, VKVG_PATTERN_TYPE_LINEAR, @@ -110,24 +110,24 @@ typedef enum _vkvg_pattern_type { VKVG_PATTERN_TYPE_RASTER_SOURCE, } vkvg_pattern_type_t; -typedef enum _vkvg_line_cap { +typedef enum { VKVG_LINE_CAP_BUTT, VKVG_LINE_CAP_ROUND, VKVG_LINE_CAP_SQUARE } vkvg_line_cap_t; -typedef enum _vkvg_line_join { +typedef enum { VKVG_LINE_JOIN_MITER, VKVG_LINE_JOIN_ROUND, VKVG_LINE_JOIN_BEVEL } vkvg_line_join_t; -typedef enum _vkvg_fill_rule { +typedef enum { VKVG_FILL_RULE_EVEN_ODD, VKVG_FILL_RULE_NON_ZERO } vkvg_fill_rule_t; -typedef struct _vkvg_color_t{ +typedef struct { float r; float g; float b; @@ -279,6 +279,8 @@ void vkvg_set_source (VkvgContext ctx, VkvgPattern pat); void vkvg_set_operator (VkvgContext ctx, vkvg_operator_t op); void vkvg_set_fill_rule (VkvgContext ctx, vkvg_fill_rule_t fr); +void vkvg_set_dash (VkvgContext ctx, const float* dashes, uint32_t num_dashes, float offset); +void vkvg_get_dash (VkvgContext ctx, const float *dashes, uint32_t* num_dashes, float* offset); float vkvg_get_line_width (VkvgContext ctx); vkvg_line_cap_t vkvg_get_line_cap (VkvgContext ctx); diff --git a/src/vkvg_context.c b/src/vkvg_context.c index fd2252e..c465d65 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -61,6 +61,9 @@ VkvgContext vkvg_create(VkvgSurface surf) ctx->sizeIndices = ctx->sizeIBO = VKVG_IBO_SIZE; ctx->sizePathes = VKVG_PATHES_SIZE; ctx->lineWidth = 1; + ctx->dashCount = 0; + ctx->dashOffset = 0; + ctx->dashes = NULL; ctx->pSurf = surf; ctx->curOperator = VKVG_OPERATOR_OVER; ctx->curFillRule = VKVG_FILL_RULE_NON_ZERO; @@ -216,6 +219,8 @@ void vkvg_destroy (VkvgContext ctx) free(ctx->selectedFont.fontFile); free(ctx->pathes); free(ctx->points); + if (ctx->dashCount > 0) + free(ctx->dashes); //free saved context stack elmt vkvg_context_save_t* next = ctx->pSavedCtxs; @@ -751,9 +756,47 @@ void vkvg_set_fill_rule (VkvgContext ctx, vkvg_fill_rule_t fr){ vkvg_fill_rule_t vkvg_get_fill_rule (VkvgContext ctx){ return ctx->curFillRule; } +/** + * @brief This function return the current line width use by vkvg_stroke() as set by vkvg_set_line_width(). + * @param a vkvg context. + * @return current line width. + */ float vkvg_get_line_width (VkvgContext ctx){ return ctx->lineWidth; } +/** + * @brief Sets the dash pattern to be used by vkvg_stroke(). A dash pattern is specified by dashes , an array of positive values. Each value provides the length of alternate "on" and "off" portions of the stroke. The offset specifies an offset into the pattern at which the stroke begins. + * @param a vkvg context. + * @param a pointer on an array of float values defining alternate lengths of on and off stroke portions. + * @param the length of the dash array. + * @param an offset into the dash pattern at which the stroke should start. + */ +void vkvg_set_dash (VkvgContext ctx, const float* dashes, uint32_t num_dashes, float offset){ + if (ctx->dashCount > 0) + free (ctx->dashes); + ctx->dashCount = num_dashes; + ctx->dashOffset = offset; + if (ctx->dashCount == 0) + return; + ctx->dashes = (float*)malloc (sizeof(float) * ctx->dashCount); + memcpy (ctx->dashes, dashes, sizeof(float) * ctx->dashCount); +} +/** + * @brief get dash settings. If dashes pointer is NULL, only count and offset are returned. + * @param a vkvg context. + * @param return value for the dash array. If count is 0, this pointer stay untouched. If NULL, only count and offset are returned. + * @param return length of dash array or 0 if dash not set. + * @param return value for the current dash offset + */ +void vkvg_get_dash (VkvgContext ctx, const float* dashes, uint32_t* num_dashes, float* offset){ + *num_dashes = ctx->dashCount; + *offset = ctx->dashOffset; + if (ctx->dashCount == 0 || dashes == NULL) + return; + memcpy ((float*)dashes, ctx->dashes, sizeof(float) * ctx->dashCount); +} + + vkvg_line_cap_t vkvg_get_line_cap (VkvgContext ctx){ return ctx->lineCap; } @@ -866,6 +909,12 @@ void vkvg_save (VkvgContext ctx){ _bind_draw_pipeline (ctx); CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); + sav->dashOffset = ctx->dashOffset; + sav->dashCount = ctx->dashCount; + if (ctx->dashCount > 0) { + sav->dashes = (float*)malloc (sizeof(float) * ctx->dashCount); + memcpy (sav->dashes, ctx->dashes, sizeof(float) * ctx->dashCount); + } sav->lineWidth = ctx->lineWidth; sav->curOperator= ctx->curOperator; sav->lineCap = ctx->lineCap; @@ -958,6 +1007,15 @@ void vkvg_restore (VkvgContext ctx){ vkh_image_destroy (savStencil); } + ctx->dashOffset = sav->dashOffset; + if (ctx->dashCount > 0) + free (ctx->dashes); + ctx->dashCount = sav->dashCount; + if (ctx->dashCount > 0) { + ctx->dashes = (float*)malloc (sizeof(float) * ctx->dashCount); + memcpy (ctx->dashes, sav->dashes, sizeof(float) * ctx->dashCount); + } + ctx->lineWidth = sav->lineWidth; ctx->curOperator= sav->curOperator; ctx->lineCap = sav->lineCap; diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index 08fa586..e3136a7 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -671,8 +671,6 @@ float _build_vb_step (vkvg_context* ctx, Vertex v, float hw, uint32_t iL, uint32 vec2 bisec = vec2_norm(vec2_add(v0n,v1n)); float dot = v0n.x * v1n.x + v0n.y * v1n.y; - //printf("%f\n", dot); - float alpha = acosf(dot)/2; float cross = v0n.x * v1n.y - v0n.y * v1n.x; @@ -790,6 +788,8 @@ bool ptInTriangle(vec2 p, vec2 p0, vec2 p1, vec2 p2) { } void _free_ctx_save (vkvg_context_save_t* sav){ + if (sav->dashCount > 0) + free (sav->dashes); free(sav->selectedFont.fontFile); free (sav); } diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index f7a385f..63f22dc 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -53,6 +53,10 @@ typedef struct _vkvg_context_save_t{ struct _vkvg_context_save_t* pNext; float lineWidth; + uint32_t dashCount; //value count in dash array, 0 if dash not set. + float dashOffset; //an offset for dash + float* dashes; //an array of alternate lengths of on and off stroke. + vkvg_operator_t curOperator; vkvg_line_cap_t lineCap; @@ -132,6 +136,9 @@ typedef struct _vkvg_context_t { uint32_t curvePtr; float lineWidth; + uint32_t dashCount; //value count in dash array, 0 if dash not set. + float dashOffset; //an offset for dash + float* dashes; //an array of alternate lengths of on and off stroke. vkvg_operator_t curOperator; vkvg_line_cap_t lineCap; diff --git a/tests/curved_rect.c b/tests/curved_rect.c new file mode 100644 index 0000000..34e739f --- /dev/null +++ b/tests/curved_rect.c @@ -0,0 +1,40 @@ +#include "test.h" + +void test(){ + VkvgContext ctx = vkvg_create(surf); + + float x = 50, y = 50, width = 150, height = 140, radius = 30; + + vkvg_scale(ctx,2,2); + //vkvg_rotate(ctx,0.5f); + + vkvg_set_line_width(ctx,15); + vkvg_set_source_rgba(ctx, 0, 0.5f, 0.4f, 1); + + + if ((radius > height / 2) || (radius > width / 2)) + radius = MIN(height / 2, width / 2); + + vkvg_move_to(ctx, x, y + radius); + vkvg_arc(ctx, x + radius, y + radius, radius, M_PIF, (float)-M_PI_2); + vkvg_line_to(ctx, x + width - radius, y); + vkvg_arc(ctx, x + width - radius, y + radius, radius, (float)-M_PI_2, 0); + vkvg_line_to(ctx, x + width, y + height - radius); + vkvg_arc(ctx, x + width - radius, y + height - radius, radius, 0, (float)M_PI_2); + vkvg_line_to(ctx, x + radius, y + height); + vkvg_arc(ctx, x + radius, y + height - radius, radius, (float)M_PI_2, M_PIF); + vkvg_line_to(ctx, x, y + radius); + vkvg_close_path(ctx); + vkvg_fill_preserve(ctx); + vkvg_set_source_rgba(ctx,0.5,0,0,0.5); + vkvg_stroke(ctx); + + vkvg_destroy(ctx); +} + +int main(int argc, char *argv[]) { + + perform_test (test, 1024, 768); + + return 0; +}