From e1c8ea4fa60c71f4079e513ed36e13aa0ff8a87a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Mon, 19 Jul 2021 16:56:12 +0200 Subject: [PATCH] save fontconfig results in _vkvg_font_t; status check on facade fnt call, vkcmd dbg labels --- include/vkvg.h | 5 +- src/vkvg_context.c | 198 +++++++++++++++++++++++++++++++----- src/vkvg_context_internal.c | 21 ++-- src/vkvg_context_internal.h | 6 +- src/vkvg_fonts.c | 146 ++++++++++++++++---------- src/vkvg_fonts.h | 7 +- src/vkvg_surface.c | 5 +- tests/img_surf.c | 19 ++-- tests/paint_surf.c | 11 +- tests/text.c | 71 ++++++++++--- 10 files changed, 360 insertions(+), 129 deletions(-) diff --git a/include/vkvg.h b/include/vkvg.h index 46798ec..217bf1a 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -77,7 +77,8 @@ extern "C" { #define VKVG_LOG_ERR 0x10 #define VKVG_LOG_DEBUG 0x20 #define VKVG_LOG_INFO 0x40 -#define VKVG_LOG_INFO_PATH 0x41 +#define VKVG_LOG_INFO_PTS 0x41 +#define VKVG_LOG_INFO_PATH 0x42 #define VKVG_LOG_DBG_ARRAYS 0x80 #define VKVG_LOG_FULL 0xff @@ -112,7 +113,7 @@ typedef enum { VKVG_STATUS_INVALID_VISUAL, /*!< */ VKVG_STATUS_FILE_NOT_FOUND, /*!< */ VKVG_STATUS_INVALID_DASH, /*!< invalid value for a dash setting */ - VKVG_STATUS_INVALID_RECT, /*!< invalid value for a dash setting */ + VKVG_STATUS_INVALID_RECT, /*!< rectangle with height or width equal to 0. */ }vkvg_status_t; typedef enum { diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 00f3932..e87c3b7 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -29,13 +29,18 @@ #ifdef DEBUG static vec2 debugLinePoints[1000]; static uint32_t dlpCount = 0; +#if defined (VKVG_DBG_UTILS) +const float DBG_LAB_COLOR_SAV[4] = {1,0,1,1}; +const float DBG_LAB_COLOR_CLIP[4] = {0,1,1,1}; #endif +#endif + //todo:this could be used to define a default background static VkClearValue clearValues[3] = { - { {{0}} }, - { {{1.0f, 0}} }, - { {{0}} } + { .color.float32 = {0,0,0,0} }, + { .depthStencil = {1.0f, 0} }, + { .color.float32 = {0,0,0,0} } }; VkvgContext vkvg_create(VkvgSurface surf) @@ -99,10 +104,11 @@ VkvgContext vkvg_create(VkvgSurface surf) ctx->indexCache = (VKVG_IBO_INDEX_TYPE*)malloc(ctx->sizeIndices * sizeof(VKVG_IBO_INDEX_TYPE)); ctx->savedStencils = malloc(0); - ctx->selectedFont.fontFile = (char*)calloc(FONT_FILE_NAME_MAX_SIZE,sizeof(char)); + ctx->selectedFontName = (char*)calloc(FONT_NAME_MAX_SIZE, sizeof(char)); + ctx->selectedCharSize = 10 << 6; ctx->currentFont = NULL; - if (!ctx->points || !ctx->pathes || !ctx->vertexCache || !ctx->indexCache || !ctx->savedStencils || !ctx->selectedFont.fontFile) { + if (!ctx->points || !ctx->pathes || !ctx->vertexCache || !ctx->indexCache || !ctx->savedStencils || !ctx->selectedFontName) { dev->status = VKVG_STATUS_NO_MEMORY; if (ctx->points) free(ctx->points); @@ -114,8 +120,8 @@ VkvgContext vkvg_create(VkvgSurface surf) free(ctx->indexCache); if (ctx->savedStencils) free(ctx->savedStencils); - if (ctx->selectedFont.fontFile) - free(ctx->selectedFont.fontFile); + if (ctx->selectedFontName) + free(ctx->selectedFontName); return NULL; } @@ -156,9 +162,14 @@ VkvgContext vkvg_create(VkvgSurface surf) vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_BUFFER, (uint64_t)ctx->vertices.buffer, "CTX Vertex Buff"); #endif + //force run of one renderpass (even empty) to perform clear load op + //_start_cmd_for_render_pass(ctx); + return ctx; } void vkvg_flush (VkvgContext ctx){ + if (ctx->status) + return; _flush_cmd_buff(ctx); _wait_flush_fence(ctx); /* @@ -238,7 +249,7 @@ void vkvg_destroy (VkvgContext ctx) //TODO:check this for source counter //vkh_image_destroy (ctx->source); - free(ctx->selectedFont.fontFile); + free(ctx->selectedFontName); free(ctx->pathes); free(ctx->points); if (ctx->dashCount > 0) @@ -283,26 +294,39 @@ uint32_t vkvg_get_reference_count (VkvgContext ctx) { return ctx->references; } void vkvg_new_sub_path (VkvgContext ctx){ + if (ctx->status) + return; _finish_path(ctx); } void vkvg_new_path (VkvgContext ctx){ + if (ctx->status) + return; _clear_path(ctx); } void vkvg_close_path (VkvgContext ctx){ + if (ctx->status) + return; + if (ctx->pathes[ctx->pathPtr] & PATH_CLOSED_BIT) //already closed + return; //check if at least 3 points are present if (ctx->pathes[ctx->pathPtr] < 3) return; //prevent closing on the same point if (vec2_equ(ctx->points[ctx->pointCount-1], - ctx->points[ctx->pointCount - ctx->pathes[ctx->pathPtr]])) + ctx->points[ctx->pointCount - ctx->pathes[ctx->pathPtr]])) { + if (ctx->pathes[ctx->pathPtr] < 4)//ensure enough points left for closing + return; _remove_last_point(ctx); + } ctx->pathes[ctx->pathPtr] |= PATH_CLOSED_BIT; _finish_path(ctx); } void vkvg_rel_line_to (VkvgContext ctx, float dx, float dy){ + if (ctx->status) + return; if (_current_path_is_empty(ctx)){ ctx->status = VKVG_STATUS_NO_CURRENT_POINT; return; @@ -312,6 +336,8 @@ void vkvg_rel_line_to (VkvgContext ctx, float dx, float dy){ } void vkvg_line_to (VkvgContext ctx, float x, float y) { + if (ctx->status) + return; vec2 p = {x,y}; if (!_current_path_is_empty (ctx)){ //prevent adding the same point @@ -321,6 +347,8 @@ void vkvg_line_to (VkvgContext ctx, float x, float y) _add_point (ctx, x, y); } void vkvg_arc (VkvgContext ctx, float xc, float yc, float radius, float a1, float a2){ + if (ctx->status) + return; while (a2 < a1)//positive arc must have a1status) + return; while (a2 > a1) a2 -= 2.f*M_PIF; if (a1 - a2 > a1 + 2.f * M_PIF) //limit arc to 2PI @@ -409,6 +439,8 @@ void vkvg_arc_negative (VkvgContext ctx, float xc, float yc, float radius, float } void vkvg_rel_move_to (VkvgContext ctx, float x, float y) { + if (ctx->status) + return; if (_current_path_is_empty(ctx)){ ctx->status = VKVG_STATUS_NO_CURRENT_POINT; return; @@ -418,11 +450,15 @@ void vkvg_rel_move_to (VkvgContext ctx, float x, float y) } void vkvg_move_to (VkvgContext ctx, float x, float y) { + if (ctx->status) + return; _finish_path(ctx); _add_point (ctx, x, y); } void vkvg_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) { + if (ctx->status) + return; //prevent running _recursive_bezier when all 4 curve points are equal if (EQUF(x1,x2) && EQUF(x2,x3) && EQUF(y1,y2) && EQUF(y2,y3)) { if (_current_path_is_empty(ctx) || (EQUF(_get_current_position(ctx).x,x1) && EQUF(_get_current_position(ctx).y,y1))) @@ -442,6 +478,8 @@ void vkvg_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, flo _set_curve_end (ctx); } void vkvg_rel_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x3, float y3) { + if (ctx->status) + return; if (_current_path_is_empty(ctx)){ ctx->status = VKVG_STATUS_NO_CURRENT_POINT; return; @@ -450,11 +488,15 @@ void vkvg_rel_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, vkvg_curve_to (ctx, cp.x + x1, cp.y + y1, cp.x + x2, cp.y + y2, cp.x + x3, cp.y + y3); } void vkvg_fill_rectangle (VkvgContext ctx, float x, float y, float w, float h){ + if (ctx->status) + return; _vao_add_rectangle (ctx,x,y,w,h); //_record_draw_cmd(ctx); } void vkvg_rectangle (VkvgContext ctx, float x, float y, float w, float h){ + if (ctx->status) + return; _finish_path (ctx); if (w <= 0 || h <= 0) { @@ -473,6 +515,8 @@ static const VkClearAttachment clearStencil = {VK_IMAGE_ASPECT_STENCIL_BI static const VkClearAttachment clearColorAttach = {VK_IMAGE_ASPECT_COLOR_BIT, 0, {{{0}}}}; void vkvg_reset_clip (VkvgContext ctx){ + if (ctx->status) + return; _emit_draw_cmd_undrawn_vertices(ctx); if (!ctx->cmdStarted) { //if command buffer is not already started and in a renderpass, we use the renderpass @@ -485,6 +529,8 @@ void vkvg_reset_clip (VkvgContext ctx){ vkCmdClearAttachments(ctx->cmd, 1, &clearStencil, 1, &ctx->clearRect); } void vkvg_clear (VkvgContext ctx){ + if (ctx->status) + return; _emit_draw_cmd_undrawn_vertices(ctx); if (!ctx->cmdStarted) { ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass_ClearAll; @@ -509,17 +555,23 @@ void vkvg_fill (VkvgContext ctx){ _clear_path(ctx); } void vkvg_clip_preserve (VkvgContext ctx){ - if (ctx->pathPtr == 0 && _current_path_is_empty(ctx))//nothing to clip + if (ctx->status) return; _emit_draw_cmd_undrawn_vertices(ctx); _finish_path(ctx); + vkvg_close_path (ctx); + LOG(VKVG_LOG_INFO, "CLIP: ctx = %p; path cpt = %d;\n", ctx, ctx->pathPtr / 2); _ensure_renderpass_is_started(ctx); +#if defined(DEBUG) && defined (VKVG_DBG_UTILS) + vkh_cmd_label_start(ctx->cmd, "clip", DBG_LAB_COLOR_CLIP); +#endif + if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD){ _poly_fill (ctx); CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); @@ -539,13 +591,19 @@ void vkvg_clip_preserve (VkvgContext ctx){ _bind_draw_pipeline (ctx); CmdSetStencilCompareMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); + +#if defined(DEBUG) && defined (VKVG_DBG_UTILS) + vkh_cmd_label_end (ctx->cmd); +#endif } void vkvg_fill_preserve (VkvgContext ctx){ - if (ctx->pathPtr == 0 && _current_path_is_empty(ctx))//nothing to fill + if (ctx->status) return; _finish_path(ctx); + vkvg_close_path (ctx); + LOG(VKVG_LOG_INFO, "FILL: ctx = %p; path cpt = %d;\n", ctx, ctx->pathPtr / 2); if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD){ @@ -677,6 +735,9 @@ void _draw_segment (VkvgContext ctx, float hw, bool isCurve) { void vkvg_stroke_preserve (VkvgContext ctx) { + if (ctx->status) + return; + if (ctx->pathPtr == 0 && _current_path_is_empty(ctx))//nothing to stroke return; _finish_path(ctx); @@ -793,9 +854,16 @@ void vkvg_stroke_preserve (VkvgContext ctx) } void vkvg_paint (VkvgContext ctx){ - if (ctx->pathPtr || ctx->segmentPtr){//path to fill - vkvg_fill(ctx); + if (ctx->status) return; + + if (!_current_path_is_empty(ctx)){//maybe path to fill + vkvg_close_path(ctx); + if (ctx->pathes[ctx->pathPtr] & PATH_CLOSED_BIT) { + vkvg_fill(ctx); + return; + } + _clear_path (ctx); } _ensure_renderpass_is_started (ctx); _draw_full_screen_quad (ctx, true); @@ -805,16 +873,22 @@ void vkvg_set_source_rgb (VkvgContext ctx, float r, float g, float b) { } void vkvg_set_source_rgba (VkvgContext ctx, float r, float g, float b, float a) { + if (ctx->status) + return; ctx->curColor = CreateRgbaf(r,g,b,a); _update_cur_pattern (ctx, NULL); } void vkvg_set_source_surface(VkvgContext ctx, VkvgSurface surf, float x, float y){ + if (ctx->status) + return; _update_cur_pattern (ctx, vkvg_pattern_create_for_surface(surf)); ctx->pushConsts.source.x = x; ctx->pushConsts.source.y = y; ctx->pushCstDirty = true; } void vkvg_set_source (VkvgContext ctx, VkvgPattern pat){ + if (ctx->status) + return; _update_cur_pattern (ctx, pat); vkvg_pattern_reference (pat); } @@ -828,6 +902,8 @@ void vkvg_set_line_join (VkvgContext ctx, vkvg_line_join_t join){ ctx->lineJoin = join; } void vkvg_set_operator (VkvgContext ctx, vkvg_operator_t op){ + if (ctx->status) + return; if (op == ctx->curOperator) return; @@ -850,6 +926,8 @@ float vkvg_get_line_width (VkvgContext ctx){ return ctx->lineWidth; } void vkvg_set_dash (VkvgContext ctx, const float* dashes, uint32_t num_dashes, float offset){ + if (ctx->status) + return; if (ctx->dashCount > 0) free (ctx->dashes); ctx->dashCount = num_dashes; @@ -883,13 +961,20 @@ VkvgPattern vkvg_get_source (VkvgContext ctx){ } void vkvg_select_font_face (VkvgContext ctx, const char* name){ + if (ctx->status) + return; _select_font_face (ctx, name); } void vkvg_select_font_path (VkvgContext ctx, const char* path){ - _select_font_path (ctx, path); + if (ctx->status) + return; + //_select_font_path (ctx, path); } void vkvg_set_font_size (VkvgContext ctx, uint32_t size){ - _set_font_size (ctx,size); + if (ctx->status) + return; + ctx->selectedCharSize = size << 6; + ctx->currentFont = NULL; } void vkvg_set_text_direction (vkvg_context* ctx, vkvg_direction_t direction){ @@ -897,12 +982,16 @@ void vkvg_set_text_direction (vkvg_context* ctx, vkvg_direction_t direction){ } void vkvg_show_text (VkvgContext ctx, const char* text){ + if (ctx->status) + return; //_ensure_renderpass_is_started(ctx); _show_text (ctx, text); //_flush_undrawn_vertices (ctx); } VkvgText vkvg_text_run_create (VkvgContext ctx, const char* text) { + if (ctx->status) + return NULL; VkvgText tr = (vkvg_text_run_t*)calloc(1, sizeof(vkvg_text_run_t)); _create_text_run(ctx, text, tr); return tr; @@ -912,6 +1001,8 @@ void vkvg_text_run_destroy (VkvgText textRun) { free (textRun); } void vkvg_show_text_run (VkvgContext ctx, VkvgText textRun) { + if (ctx->status) + return; _show_text_run(ctx, textRun); } void vkvg_text_run_get_extents (VkvgText textRun, vkvg_text_extents_t* extents) { @@ -919,9 +1010,13 @@ void vkvg_text_run_get_extents (VkvgText textRun, vkvg_text_extents_t* extents) } void vkvg_text_extents (VkvgContext ctx, const char* text, vkvg_text_extents_t* extents) { + if (ctx->status) + return; _text_extents(ctx, text, extents); } void vkvg_font_extents (VkvgContext ctx, vkvg_font_extents_t* extents) { + if (ctx->status) + return; _font_extents(ctx, extents); } @@ -953,6 +1048,10 @@ void vkvg_save (VkvgContext ctx){ vkh_cmd_begin (ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); ctx->cmdStarted = true; +#if defined(DEBUG) && defined (VKVG_DBG_UTILS) + vkh_cmd_label_start(ctx->cmd, "new save/restore stencil", DBG_LAB_COLOR_SAV); +#endif + vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); @@ -972,6 +1071,10 @@ void vkvg_save (VkvgContext ctx){ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); +#if defined(DEBUG) && defined (VKVG_DBG_UTILS) + vkh_cmd_label_end (ctx->cmd); +#endif + VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd)); _wait_and_submit_cmd(ctx); } @@ -980,6 +1083,10 @@ void vkvg_save (VkvgContext ctx){ _start_cmd_for_render_pass (ctx); +#if defined(DEBUG) && defined (VKVG_DBG_UTILS) + vkh_cmd_label_start(ctx->cmd, "save rp", DBG_LAB_COLOR_SAV); +#endif + CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); CmdSetStencilReference (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|curSaveBit); @@ -991,6 +1098,10 @@ void vkvg_save (VkvgContext ctx){ _bind_draw_pipeline (ctx); CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); +#if defined(DEBUG) && defined (VKVG_DBG_UTILS) + vkh_cmd_label_end (ctx->cmd); +#endif + sav->dashOffset = ctx->dashOffset; sav->dashCount = ctx->dashCount; if (ctx->dashCount > 0) { @@ -1003,23 +1114,26 @@ void vkvg_save (VkvgContext ctx){ sav->lineWidth = ctx->lineWidth; sav->curFillRule= ctx->curFillRule; - sav->selectedFont = ctx->selectedFont; - sav->selectedFont.fontFile = (char*)calloc(FONT_FILE_NAME_MAX_SIZE,sizeof(char)); - strcpy (sav->selectedFont.fontFile, ctx->selectedFont.fontFile); + sav->selectedCharSize = ctx->selectedCharSize; + sav->selectedFontName = (char*)calloc(FONT_NAME_MAX_SIZE,sizeof(char)); + strcpy (sav->selectedFontName, ctx->selectedFontName); sav->currentFont = ctx->currentFont; sav->textDirection= ctx->textDirection; sav->pushConsts = ctx->pushConsts; - sav->pattern = ctx->pattern; + //sav->pattern = ctx->pattern;//TODO:pattern sav must be imutable (copy?) sav->pNext = ctx->pSavedCtxs; ctx->pSavedCtxs = sav; ctx->curSavBit++; - if (ctx->pattern) - vkvg_pattern_reference (ctx->pattern); + /*if (ctx->pattern) + vkvg_pattern_reference (ctx->pattern);*/ } void vkvg_restore (VkvgContext ctx){ + if (ctx->status) + return; + if (ctx->pSavedCtxs == NULL){ ctx->status = VKVG_STATUS_INVALID_RESTORE; return; @@ -1027,16 +1141,16 @@ void vkvg_restore (VkvgContext ctx){ LOG(VKVG_LOG_INFO, "RESTORE CONTEXT: ctx = %p\n", ctx); + _flush_cmd_buff (ctx); + _wait_flush_fence (ctx); + vkvg_context_save_t* sav = ctx->pSavedCtxs; ctx->pSavedCtxs = sav->pNext; ctx->pushConsts = sav->pushConsts; - if (sav->pattern) - _update_cur_pattern (ctx, sav->pattern); - - _flush_cmd_buff (ctx); - _wait_flush_fence (ctx); + /*if (sav->pattern) + _update_cur_pattern (ctx, sav->pattern);*/ ctx->curSavBit--; @@ -1044,6 +1158,10 @@ void vkvg_restore (VkvgContext ctx){ _start_cmd_for_render_pass (ctx); +#if defined(DEBUG) && defined (VKVG_DBG_UTILS) + vkh_cmd_label_start(ctx->cmd, "restore rp", DBG_LAB_COLOR_SAV); +#endif + CmdBindPipeline (ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineClipping); CmdSetStencilReference (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT|curSaveBit); @@ -1055,6 +1173,10 @@ void vkvg_restore (VkvgContext ctx){ _bind_draw_pipeline (ctx); CmdSetStencilCompareMask (ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); +#if defined(DEBUG) && defined (VKVG_DBG_UTILS) + vkh_cmd_label_end (ctx->cmd); +#endif + _flush_cmd_buff (ctx); _wait_flush_fence (ctx); @@ -1065,6 +1187,10 @@ void vkvg_restore (VkvgContext ctx){ vkh_cmd_begin (ctx->cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); ctx->cmdStarted = true; +#if defined(DEBUG) && defined (VKVG_DBG_UTILS) + vkh_cmd_label_start(ctx->cmd, "additional stencil copy while restoring", DBG_LAB_COLOR_SAV); +#endif + vkh_image_set_layout (ctx->cmd, ctx->pSurf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); @@ -1083,6 +1209,10 @@ void vkvg_restore (VkvgContext ctx){ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); +#if defined(DEBUG) && defined (VKVG_DBG_UTILS) + vkh_cmd_label_end (ctx->cmd); +#endif + VK_CHECK_RESULT(vkEndCommandBuffer(ctx->cmd)); _wait_and_submit_cmd (ctx); _wait_flush_fence (ctx); @@ -1104,8 +1234,8 @@ void vkvg_restore (VkvgContext ctx){ ctx->lineJoin = sav->lineJoint; ctx->curFillRule= sav->curFillRule; - ctx->selectedFont.charSize = sav->selectedFont.charSize; - strcpy (ctx->selectedFont.fontFile, sav->selectedFont.fontFile); + ctx->selectedCharSize = sav->selectedCharSize; + strcpy (ctx->selectedFontName, sav->selectedFontName); ctx->currentFont = sav->currentFont; ctx->textDirection= sav->textDirection; @@ -1114,21 +1244,29 @@ void vkvg_restore (VkvgContext ctx){ } void vkvg_translate (VkvgContext ctx, float dx, float dy){ + if (ctx->status) + return; _emit_draw_cmd_undrawn_vertices(ctx); vkvg_matrix_translate (&ctx->pushConsts.mat, dx, dy); _set_mat_inv_and_vkCmdPush (ctx); } void vkvg_scale (VkvgContext ctx, float sx, float sy){ + if (ctx->status) + return; _emit_draw_cmd_undrawn_vertices(ctx); vkvg_matrix_scale (&ctx->pushConsts.mat, sx, sy); _set_mat_inv_and_vkCmdPush (ctx); } void vkvg_rotate (VkvgContext ctx, float radians){ + if (ctx->status) + return; _emit_draw_cmd_undrawn_vertices(ctx); vkvg_matrix_rotate (&ctx->pushConsts.mat, radians); _set_mat_inv_and_vkCmdPush (ctx); } void vkvg_transform (VkvgContext ctx, const vkvg_matrix_t* matrix) { + if (ctx->status) + return; _emit_draw_cmd_undrawn_vertices(ctx); vkvg_matrix_t res; vkvg_matrix_multiply (&res, &ctx->pushConsts.mat, matrix); @@ -1136,12 +1274,16 @@ void vkvg_transform (VkvgContext ctx, const vkvg_matrix_t* matrix) { _set_mat_inv_and_vkCmdPush (ctx); } void vkvg_identity_matrix (VkvgContext ctx) { + if (ctx->status) + return; _emit_draw_cmd_undrawn_vertices(ctx); vkvg_matrix_t im = VKVG_IDENTITY_MATRIX; ctx->pushConsts.mat = im; _set_mat_inv_and_vkCmdPush (ctx); } void vkvg_set_matrix (VkvgContext ctx, const vkvg_matrix_t* matrix){ + if (ctx->status) + return; _emit_draw_cmd_undrawn_vertices(ctx); ctx->pushConsts.mat = (*matrix); _set_mat_inv_and_vkCmdPush (ctx); diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index 9481f90..384805a 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -186,6 +186,7 @@ bool _path_is_closed (VkvgContext ctx, uint32_t ptrPath){ return ctx->pathes[ptrPath] & PATH_CLOSED_BIT; } void _resetMinMax (VkvgContext ctx) { + LOG(VKVG_LOG_INFO_PTS, "_resetMinMax (scissor)\n"); ctx->xMin = ctx->yMin = FLT_MAX; ctx->xMax = ctx->yMax = FLT_MIN; } @@ -203,6 +204,8 @@ void _add_point (VkvgContext ctx, float x, float y){ //that speed up fill drastically. vkvg_matrix_transform_point (&ctx->pushConsts.mat, &x, &y); + LOG(VKVG_LOG_INFO_PTS, "_add_point transformed: (%f, %f)\n", x, y); + if (x < ctx->xMin) ctx->xMin = x; if (x > ctx->xMax) @@ -629,10 +632,10 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { filter = VK_FILTER_NEAREST; break; } - vkh_image_create_sampler(ctx->source, filter, filter, - VK_SAMPLER_MIPMAP_MODE_NEAREST, addrMode); + vkh_image_create_sampler (ctx->source, filter, filter, + VK_SAMPLER_MIPMAP_MODE_NEAREST, addrMode); - _update_descriptor_set (ctx, ctx->source, ctx->dsSrc); + _update_descriptor_set (ctx, ctx->source, ctx->dsSrc); vec4 srcRect = {{0},{0},{(float)surf->width},{(float)surf->height}}; ctx->pushConsts.source = srcRect; @@ -649,19 +652,19 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { //transform control point with current ctx matrix vkvg_gradient_t grad = {0}; - memcpy(&grad, pat->data, sizeof(vkvg_gradient_t)); + memcpy (&grad, pat->data, sizeof(vkvg_gradient_t)); - vkvg_matrix_transform_point(&ctx->pushConsts.mat, &grad.cp[0].x, &grad.cp[0].y); - vkvg_matrix_transform_point(&ctx->pushConsts.mat, &grad.cp[1].x, &grad.cp[1].y); + vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[0].x, &grad.cp[0].y); + vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[1].x, &grad.cp[1].y); //to do, scale radial radiuses in cp[2] - memcpy(ctx->uboGrad.allocInfo.pMappedData , &grad, sizeof(vkvg_gradient_t)); + memcpy (ctx->uboGrad.allocInfo.pMappedData , &grad, sizeof(vkvg_gradient_t)); break; } ctx->pushConsts.patternType = newPatternType; ctx->pushCstDirty = true; if (lastPat) - vkvg_pattern_destroy (lastPat); + vkvg_pattern_destroy (lastPat); } void _update_descriptor_set (VkvgContext ctx, VkhImage img, VkDescriptorSet ds){ _wait_flush_fence(ctx);//descriptorSet update invalidate cmd buffs @@ -868,7 +871,7 @@ 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->selectedFontName); free (sav); } diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index 1b302ba..6c87485 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -87,6 +87,8 @@ typedef struct _vkvg_context_save_t{ vkvg_line_join_t lineJoint; vkvg_fill_rule_t curFillRule; + FT_F26Dot6 selectedCharSize; /* Font size*/ + char* selectedFontName; _vkvg_font_t selectedFont; //hold current face and size before cache addition _vkvg_font_t* currentFont; //font ready for lookup vkvg_direction_t textDirection; @@ -164,7 +166,9 @@ typedef struct _vkvg_context_t { vkvg_line_join_t lineJoin; vkvg_fill_rule_t curFillRule; - _vkvg_font_t selectedFont; //hold current face and size before cache addition + FT_F26Dot6 selectedCharSize; /* Font size*/ + char* selectedFontName; + //_vkvg_font_t selectedFont; //hold current face and size before cache addition _vkvg_font_t* currentFont; //font pointing to cached fonts ready for lookup vkvg_direction_t textDirection; diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c index d9e2cfa..4ac2fe2 100644 --- a/src/vkvg_fonts.c +++ b/src/vkvg_fonts.c @@ -167,18 +167,22 @@ void _destroy_font_cache (VkvgDevice dev){ free (cache->hostBuff); for (int i = 0; i < cache->fontsCount; ++i) { - _vkvg_font_t f = cache->fonts[i]; + _vkvg_font_t* f = &cache->fonts[i]; - for (int g = 0; g < f.face->num_glyphs; ++g) { - if (f.charLookup[g]!=NULL) - free(f.charLookup[g]); + for (int g = 0; g < f->face->num_glyphs; ++g) { + if (f->charLookup[g]!=NULL) + free(f->charLookup[g]); } - FT_Done_Face (f.face); - hb_font_destroy (f.hb_font); + FT_Done_Face (f->face); + hb_font_destroy (f->hb_font); - free(f.charLookup); - free(f.fontFile); + free(f->charLookup); + free(f->fontFile); + for (uint32_t j = 0; j < f->fcNamesCount; j++) + free (f->fcNames[j]); + if (f->fcNamesCount > 0) + free (f->fcNames); } free(cache->fonts); @@ -316,25 +320,34 @@ _char_ref* _prepare_char (VkvgDevice dev, _vkvg_font_t* f, FT_UInt gindex){ dev->fontCache->stagingX += bmpWidth; return cr; } -//set current font size for context -void _set_font_size (VkvgContext ctx, uint32_t size){ - ctx->selectedFont.charSize = size << 6; - ctx->currentFont = NULL; -} - void _select_font_path (VkvgContext ctx, const char* fontFile){ - memset (ctx->selectedFont.fontFile, 0, FONT_FILE_NAME_MAX_SIZE); - memcpy (ctx->selectedFont.fontFile, fontFile, FONT_FILE_NAME_MAX_SIZE); ctx->currentFont = NULL; } //select current font for context void _select_font_face (VkvgContext ctx, const char* name){ - _font_cache_t* cache = (_font_cache_t*)ctx->pSurf->dev->fontCache; - - char* fontFile; + strcpy (ctx->selectedFontName, name); +} +void _font_add_fc_name (_vkvg_font_t* font, const char* fcname) { + if (++font->fcNamesCount == 1) + font->fcNames = (char**) malloc (sizeof(char*)); + else + font->fcNames = (char**) realloc (font->fcNames, font->fcNamesCount * sizeof(char*)); + font->fcNames[font->fcNamesCount-1] = (char*)calloc(FONT_NAME_MAX_SIZE, sizeof (char)); + strcpy (font->fcNames[font->fcNamesCount-1], fcname); +} - //make pattern from font name - FcPattern* pat = FcNameParse((const FcChar8*)name); +//try to find font in cache with same font file path and font size as selected in context. +_vkvg_font_t* _tryFindVkvgFont (VkvgContext ctx){ + _font_cache_t* cache = (_font_cache_t*)ctx->pSurf->dev->fontCache; + //try find font already resolved with fontconfig by font name + for (int i = 0; i < cache->fontsCount; ++i) { + for (uint32_t j = 0; j < cache->fonts[i].fcNamesCount; j++) { + if (strcmp (cache->fonts[i].fcNames[j], ctx->selectedFontName) == 0 && cache->fonts[i].charSize == ctx->selectedCharSize) + return &cache->fonts[i]; + } + } + //try resolve name with fontconfig + FcPattern* pat = FcNameParse((const FcChar8*)ctx->selectedFontName); FcConfigSubstitute(cache->config, pat, FcMatchPattern); FcDefaultSubstitute(pat); // find the font @@ -342,61 +355,70 @@ void _select_font_face (VkvgContext ctx, const char* name){ FcPattern* font = FcFontMatch(cache->config, pat, &result); if (font) { - if (FcPatternGetString(font, FC_FILE, 0, (FcChar8 **)&fontFile) == FcResultMatch) - _select_font_path (ctx, fontFile); + char* fontFile; + if (FcPatternGetString(font, FC_FILE, 0, (FcChar8 **)&fontFile) == FcResultMatch) { + //try find font in cache by path + for (int i = 0; i < cache->fontsCount; ++i) { + if (strcmp (cache->fonts[i].fontFile, fontFile) == 0 && cache->fonts[i].charSize == ctx->selectedCharSize) { + _font_add_fc_name (&cache->fonts[i], ctx->selectedFontName); + FcPatternDestroy(pat); + FcPatternDestroy(font); + return &cache->fonts[i]; + } + } + //if not found, create a new vkvg_font + cache->fontsCount++; + + if (cache->fontsCount == 1) + cache->fonts = (_vkvg_font_t*) malloc (cache->fontsCount * sizeof(_vkvg_font_t)); + else + cache->fonts = (_vkvg_font_t*) realloc (cache->fonts, cache->fontsCount * sizeof(_vkvg_font_t)); + + _vkvg_font_t* nf = &cache->fonts[cache->fontsCount-1]; + memset (nf, 0, sizeof(_vkvg_font_t)); + + nf->charSize = ctx->selectedCharSize; + nf->fontFile = (char*)malloc (FONT_FILE_NAME_MAX_SIZE * sizeof(char)); + memcpy (nf->fontFile, fontFile, FONT_FILE_NAME_MAX_SIZE); + _font_add_fc_name (nf, ctx->selectedFontName); + FcPatternDestroy(pat); + FcPatternDestroy(font); + return nf; + } } FcPatternDestroy(pat); FcPatternDestroy(font); -} -//try to find font in cache with same font file path and font size as selected in context. -_vkvg_font_t* _tryFindVkvgFont (VkvgContext ctx){ - _font_cache_t* cache = (_font_cache_t*)ctx->pSurf->dev->fontCache; - for (int i = 0; i < cache->fontsCount; ++i) { - if (strcmp (cache->fonts[i].fontFile, ctx->selectedFont.fontFile)==0 && cache->fonts[i].charSize == ctx->selectedFont.charSize) - return &cache->fonts[i]; - } + return NULL; } //try to find corresponding font in cache (defined by context selectedFont) and create a new font entry if not found. void _update_current_font (VkvgContext ctx) { VkvgDevice dev = ctx->pSurf->dev; + if (ctx->currentFont == NULL){ - if (ctx->selectedFont.fontFile[0] == 0) { - ctx->selectedFont.charSize = 10 << 6; + if (ctx->selectedFontName[0] == 0) _select_font_face (ctx, "sans"); - } + ctx->currentFont = _tryFindVkvgFont (ctx); - if (ctx->currentFont == NULL){ + + if (ctx->currentFont->face == NULL){ //create new font in cache _font_cache_t* cache = dev->fontCache; - cache->fontsCount++; - if (cache->fontsCount == 1) - cache->fonts = (_vkvg_font_t*) malloc (cache->fontsCount * sizeof(_vkvg_font_t)); - else - cache->fonts = (_vkvg_font_t*) realloc (cache->fonts, cache->fontsCount * sizeof(_vkvg_font_t)); - - _vkvg_font_t nf = ctx->selectedFont; - if (nf.charSize == 0) - nf.charSize = defaultFontCharSize; - nf.fontFile = (char*)calloc(FONT_FILE_NAME_MAX_SIZE,sizeof(char)); - strcpy (nf.fontFile, ctx->selectedFont.fontFile); - FT_CHECK_RESULT(FT_New_Face(cache->library, nf.fontFile, 0, &nf.face)); - FT_CHECK_RESULT(FT_Set_Char_Size(nf.face, 0, nf.charSize, dev->hdpi, dev->vdpi )); - nf.hb_font = hb_ft_font_create(nf.face, NULL); - nf.charLookup = (_char_ref**)calloc(nf.face->num_glyphs,sizeof(_char_ref*)); + FT_CHECK_RESULT(FT_New_Face(cache->library, ctx->currentFont->fontFile, 0, &ctx->currentFont->face)); + FT_CHECK_RESULT(FT_Set_Char_Size(ctx->currentFont->face, 0, ctx->currentFont->charSize, dev->hdpi, dev->vdpi )); + ctx->currentFont->hb_font = hb_ft_font_create(ctx->currentFont->face, NULL); + ctx->currentFont->charLookup = (_char_ref**)calloc(ctx->currentFont->face->num_glyphs,sizeof(_char_ref*)); //nf.curLine.height = (nf.face->bbox.xMax - nf.face->bbox.xMin) >> 6; - if (FT_IS_SCALABLE(nf.face)) - nf.curLine.height = FT_MulFix(nf.face->height, nf.face->size->metrics.y_scale) >> 6;// nf.face->size->metrics.height >> 6; + if (FT_IS_SCALABLE(ctx->currentFont->face)) + ctx->currentFont->curLine.height = FT_MulFix(ctx->currentFont->face->height, ctx->currentFont->face->size->metrics.y_scale) >> 6;// nf.face->size->metrics.height >> 6; else - nf.curLine.height = nf.face->height >> 6; + ctx->currentFont->curLine.height = ctx->currentFont->face->height >> 6; - _init_next_line_in_tex_cache (dev, &nf); - cache->fonts[cache->fontsCount-1] = nf; - ctx->currentFont = &cache->fonts[cache->fontsCount-1]; + _init_next_line_in_tex_cache (dev, ctx->currentFont); } } } @@ -422,6 +444,9 @@ hb_buffer_t * _get_hb_buffer (_vkvg_font_t* font, const char* text) { void _font_extents (VkvgContext ctx, vkvg_font_extents_t *extents) { _update_current_font (ctx); + if (ctx->status) + return; + //TODO: ensure correct metrics are returned (scalled/unscalled, etc..) FT_BBox* bbox = &ctx->currentFont->face->bbox; FT_Size_Metrics* metrics = &ctx->currentFont->face->size->metrics; @@ -435,6 +460,9 @@ void _font_extents (VkvgContext ctx, vkvg_font_extents_t *extents) { void _text_extents (VkvgContext ctx, const char* text, vkvg_text_extents_t *extents) { _update_current_font (ctx); + if (ctx->status) + return; + vkvg_text_run_t tr = {0}; _create_text_run (ctx, text, &tr); @@ -446,6 +474,9 @@ void _create_text_run (VkvgContext ctx, const char* text, VkvgText textRun) { _update_current_font (ctx); + if (ctx->status) + return; + textRun->hbBuf = _get_hb_buffer (ctx->currentFont, text); textRun->font = ctx->currentFont; textRun->dev = ctx->pSurf->dev; @@ -551,6 +582,9 @@ void _show_text (VkvgContext ctx, const char* text){ vkvg_text_run_t tr = {0}; _create_text_run (ctx, text, &tr); + if (ctx->status) + return; + _show_text_run (ctx, &tr); _destroy_text_run (&tr); diff --git a/src/vkvg_fonts.h b/src/vkvg_fonts.h index 4f5211d..11f9434 100644 --- a/src/vkvg_fonts.h +++ b/src/vkvg_fonts.h @@ -40,6 +40,7 @@ #define FONT_PAGE_SIZE 1024 #define FONT_CACHE_INIT_LAYERS 1 #define FONT_FILE_NAME_MAX_SIZE 1024 +#define FONT_NAME_MAX_SIZE 128 #include "vkvg_internal.h" #include "vkvg.h" @@ -72,6 +73,8 @@ typedef struct { }_tex_ref_t; // Loaded font structure, holds informations for glyphes upload in cache and the lookup table of characters. typedef struct { + char** fcNames; /* Resolved Input names to this font by fontConfig */ + uint32_t fcNamesCount; /* Count of resolved names by fontConfig */ char* fontFile; /* Font file full path*/ FT_F26Dot6 charSize; /* Font size*/ hb_font_t* hb_font; /* HarfBuzz font instance*/ @@ -98,7 +101,7 @@ typedef struct { VkFence uploadFence; /* Signaled when upload is finished */ _vkvg_font_t* fonts; /* Loaded fonts structure array */ - uint8_t fontsCount; /* Loaded fonts array count*/ + int32_t fontsCount; /* Loaded fonts array count*/ }_font_cache_t; // Precompute everything necessary to draw one line of text, usefull to draw the same text multiple times. typedef struct _vkvg_text_run_t { @@ -117,8 +120,6 @@ void _destroy_font_cache (VkvgDevice dev); //Select current font for context from font name, create new font entry in cache if required void _select_font_face (VkvgContext ctx, const char* name); void _select_font_path (VkvgContext ctx, const char* fontFile); -//Set current font size for context -void _set_font_size (VkvgContext ctx, uint32_t size); //Draw text void _show_text (VkvgContext ctx, const char* text); //Get text dimmensions diff --git a/src/vkvg_surface.c b/src/vkvg_surface.c index 593a582..19bbaa4 100644 --- a/src/vkvg_surface.c +++ b/src/vkvg_surface.c @@ -81,7 +81,6 @@ VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, surf->height = height; _create_surface_images (surf); - _clear_surface(surf, VK_IMAGE_ASPECT_COLOR_BIT); uint32_t imgSize = width * height * 4; VkImageSubresourceLayers imgSubResLayers = {VK_IMAGE_ASPECT_COLOR_BIT,0,0,1}; @@ -99,7 +98,7 @@ VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, vkvg_buff buff = {0}; vkvg_buffer_create(dev, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU, imgSize, &buff); - memcpy (buff.allocInfo.pMappedData, img, imgSize); + memcpy (buff.allocInfo.pMappedData, img, imgSize); VkCommandBuffer cmd = dev->cmd; @@ -147,6 +146,8 @@ VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, vkvg_buffer_destroy (&buff); vkh_image_destroy (stagImg); + surf->new = false; + //create tmp context with rendering pipeline to create the multisample img VkvgContext ctx = vkvg_create (surf); diff --git a/tests/img_surf.c b/tests/img_surf.c index 11557c0..af6f9a6 100644 --- a/tests/img_surf.c +++ b/tests/img_surf.c @@ -1,8 +1,9 @@ #include "test.h" + +const char* imgPath = "data/miroir.jpg"; void paint () { VkvgContext ctx = vkvg_create(surf); - VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); - //vkvg_surface_write_to_png(imgSurf, "/tmp/test.png"); + VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath); vkvg_set_source_surface(ctx, imgSurf, 0, 0); vkvg_paint(ctx); @@ -12,7 +13,7 @@ void paint () { } void paint_offset () { VkvgContext ctx = vkvg_create(surf); - VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); + VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath); vkvg_set_source_surface(ctx, imgSurf, 100, 100); vkvg_paint(ctx); @@ -23,7 +24,7 @@ void paint_offset () { void paint_with_scale(){ VkvgContext ctx = vkvg_create(surf); vkvg_scale (ctx, 0.2f,0.2f); - VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); + VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath); vkvg_set_source_surface(ctx, imgSurf, 0, 0); vkvg_paint(ctx); @@ -34,7 +35,7 @@ void paint_with_scale(){ void paint_pattern () { VkvgContext ctx = vkvg_create(surf); - VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); + VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath); VkvgPattern pat = vkvg_pattern_create_for_surface(imgSurf); vkvg_set_source(ctx, pat); vkvg_paint(ctx); @@ -44,7 +45,7 @@ void paint_pattern () { } void paint_patt_repeat () { VkvgContext ctx = vkvg_create(surf); - VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); + VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath); VkvgPattern pat = vkvg_pattern_create_for_surface(imgSurf); vkvg_pattern_set_extend(pat,VKVG_EXTEND_REPEAT); vkvg_set_source(ctx, pat); @@ -56,7 +57,7 @@ void paint_patt_repeat () { void paint_patt_repeat_scalled () { VkvgContext ctx = vkvg_create(surf); vkvg_scale (ctx, 0.2f,0.2f); - VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); + VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath); VkvgPattern pat = vkvg_pattern_create_for_surface(imgSurf); vkvg_pattern_set_extend(pat,VKVG_EXTEND_REPEAT); vkvg_set_source(ctx, pat); @@ -67,7 +68,7 @@ void paint_patt_repeat_scalled () { } void paint_patt_pad () { VkvgContext ctx = vkvg_create(surf); - VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); + VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath); VkvgPattern pat = vkvg_pattern_create_for_surface(imgSurf); vkvg_pattern_set_extend(pat,VKVG_EXTEND_PAD); vkvg_set_source(ctx, pat); @@ -80,7 +81,7 @@ void paint_patt_pad () { void test(){ VkvgContext ctx = vkvg_create(surf); vkvg_set_fill_rule(ctx,VKVG_FILL_RULE_EVEN_ODD); - VkvgSurface imgSurf = vkvg_surface_create_from_image(device, "data/miroir.jpg"); + VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath); vkvg_translate(ctx,200,200); //vkvg_rotate(ctx,M_PI_4); diff --git a/tests/paint_surf.c b/tests/paint_surf.c index c945305..0347df9 100644 --- a/tests/paint_surf.c +++ b/tests/paint_surf.c @@ -1,7 +1,7 @@ #include "test.h" vkvg_fill_rule_t fillrule = VKVG_FILL_RULE_NON_ZERO; -float lineWidth = 20.f; +float lineWidth = 10.f; VkvgSurface createSurf (uint32_t width, uint32_t height) { VkvgSurface s = vkvg_surface_create(device, width, height); @@ -9,10 +9,13 @@ VkvgSurface createSurf (uint32_t width, uint32_t height) { vkvg_set_fill_rule(ctx,fillrule); vkvg_set_line_width(ctx,lineWidth); float hlw = lineWidth/2.f; - vkvg_rectangle(ctx,hlw,hlw,(float)width-hlw,(float)height-hlw); + /* vkvg_set_source_rgba(ctx,0,1,0,0.5); - vkvg_fill_preserve(ctx); + vkvg_fill_preserve(ctx);*/ + vkvg_set_source_rgba(ctx,1,0,0,0.5); + vkvg_paint(ctx); vkvg_set_source_rgba(ctx,0,0,1,0.5); + vkvg_rectangle(ctx,hlw,hlw,(float)width-lineWidth,(float)height-lineWidth); vkvg_stroke(ctx); vkvg_destroy(ctx); return s; @@ -30,6 +33,8 @@ void paint(){ void paint_with_offset(){ VkvgSurface src = createSurf(256,256); VkvgContext ctx = vkvg_create(surf); + vkvg_set_source_rgba(ctx,0,1,0,0.5); + vkvg_paint(ctx); vkvg_set_fill_rule(ctx,fillrule); vkvg_set_source_surface(ctx, src, 100, 100); vkvg_paint(ctx); diff --git a/tests/text.c b/tests/text.c index fa21ad8..293e63a 100644 --- a/tests/text.c +++ b/tests/text.c @@ -4,7 +4,7 @@ static const char* txt = "The quick brown fox jumps over the lazy dog"; void print(VkvgContext ctx, float penY, uint32_t size) { vkvg_set_font_size(ctx,size); - vkvg_move_to(ctx, 10,penY); + vkvg_move_to(ctx, 10, penY); vkvg_show_text (ctx,txt); } @@ -23,7 +23,7 @@ void test2() { float penY = 10.f; - for (uint32_t size=4;size<39;size++) { + for (uint32_t size = 4; size < 39; size++) { print(ctx,(float)penY,size); penY+=size; } @@ -82,19 +82,19 @@ void test(){ //vkvg_select_font_face(ctx, "/usr/local/share/fonts/DroidSansMono.ttf"); //vkvg_select_font_face(ctx, "/usr/share/fonts/truetype/unifont/unifont.ttf"); - vkvg_set_font_size(ctx,12); - vkvg_select_font_face(ctx, "droid"); + vkvg_set_font_size (ctx, 12); + vkvg_select_font_face (ctx, "droid"); vkvg_font_extents_t fe; - vkvg_font_extents (ctx,&fe); - vkvg_move_to(ctx, penX,penY); - vkvg_set_source_rgba(ctx,fg.r,fg.g,fg.b,fg.a); + vkvg_font_extents (ctx, &fe); + vkvg_move_to (ctx, penX,penY); + vkvg_set_source_rgba (ctx, fg.r, fg.g, fg.b, fg.a); vkvg_text_extents_t te; - vkvg_text_extents(ctx,"abcdefghijk",&te); - vkvg_show_text (ctx,"abcdefghijk"); - penX+= te.x_advance; + vkvg_text_extents (ctx, "abcdefghijk", &te); + vkvg_show_text (ctx, "abcdefghijk"); + penX += te.x_advance; vkvg_move_to(ctx, penX,penY); vkvg_show_text (ctx,"*abcdefghijk2"); - penY+=2.f*size; + penY += 2.f*size; vkvg_select_font_face(ctx, "times"); vkvg_move_to(ctx, penX,penY); @@ -152,15 +152,30 @@ void test(){ vkvg_destroy(ctx); } -void random_text () { +void single_font_and_size () { + VkvgContext ctx = vkvg_create(surf); + vkvg_clear(ctx); + for (uint32_t i=0; i