summaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2026-10-15 14:46:34 +0200
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2026-10-15 14:46:34 +0200
commit909ef3c352e947517b3cab6ecdb8c64ea9677705 (patch)
tree87ecc10f874345882e3137268cfe6408dbab895f
parent6ddc3fb585a106d37b35356e12e02761a39f9aa2 (diff)
svg process_elt new_sub_path cmd, rename text_run cmd to text
-rw-r--r--docker-compose.build.yml2
-rw-r--r--gunit_tests/context.cpp6
-rw-r--r--gunit_tests/pathDraw.cpp62
-rw-r--r--gunit_tests/textDraw.cpp47
-rw-r--r--include/vkvg.h14
-rw-r--r--samples/tests/circles.cpp17
-rw-r--r--samples/tests/gradient.cpp72
-rw-r--r--src/array.h10
-rw-r--r--src/svg/svg-parse.c10
-rw-r--r--src/vkvg_context.c54
-rw-r--r--src/vkvg_context_internal.c2
-rw-r--r--src/vkvg_device_internal.h27
-rw-r--r--src/vkvg_fonts.c10
-rw-r--r--src/vkvg_fonts.h4
-rw-r--r--tests/data/text.svg4
-rw-r--r--tests/fonts/allfont.c66
-rw-r--r--tests/fonts/fontquery.c8
-rw-r--r--tests/text.c63
18 files changed, 356 insertions, 122 deletions
diff --git a/docker-compose.build.yml b/docker-compose.build.yml
index 4afe72c..9ab4731 100644
--- a/docker-compose.build.yml
+++ b/docker-compose.build.yml
@@ -25,7 +25,7 @@ services:
image: debian-c-builder:trixie
environment:
- DISTRO=debian
- - BUILD_DOC=off
+ - BUILD_DOC=on
deploy:
resources:
limits:
diff --git a/gunit_tests/context.cpp b/gunit_tests/context.cpp
index 4b3a438..9f68a6b 100644
--- a/gunit_tests/context.cpp
+++ b/gunit_tests/context.cpp
@@ -170,11 +170,11 @@ TEST_F(ContextTest, CtxDrawBasicNullContext) {
EXPECT_NO_FATAL_FAILURE(vkvg_text_extents(ctx, NULL, NULL));
EXPECT_NO_FATAL_FAILURE(vkvg_font_extents(ctx, NULL));
- vkvg_text_run_create(ctx, NULL);
- vkvg_text_run_create_with_length(ctx, NULL, 10);
+ vkvg_text_create(ctx, NULL);
+ vkvg_text_create_with_length(ctx, NULL, 10);
// vkvg_text_run_destroy(NULL);
- vkvg_text_run_render(ctx, NULL);
+ vkvg_text_render(ctx, NULL);
}
diff --git a/gunit_tests/pathDraw.cpp b/gunit_tests/pathDraw.cpp
index 8399ddf..9f37ee7 100644
--- a/gunit_tests/pathDraw.cpp
+++ b/gunit_tests/pathDraw.cpp
@@ -117,24 +117,64 @@ TEST_F(PathDrawTest, CircleFillStrokeScaleDown10) {
compareWithRefImage();
}
-TEST_F(PathDrawTest, curved_rect) {
+TEST_F(PathDrawTest, CircleCurve) {
VkvgContext ctx = vkvg_create(surf);
vkvg_set_source_rgb(ctx, 0.8,0.8,0.8);
vkvg_paint(ctx);
+ vkvg_scale(ctx,0.1,0.1);
+ vkvg_set_source_rgb(ctx, 0.5, 0.5, 1);
+ vkvg_arc(ctx, 1280, 1280, 1000, 0, M_PI * 2);
+ vkvg_fill_preserve(ctx);
+ vkvg_set_source_rgb(ctx, 0, 0, 0);
+ vkvg_set_line_width(ctx, 100);
+ vkvg_stroke(ctx);
vkvg_destroy(ctx);
+
compareWithRefImage();
}
-TEST_F(PathDrawTest, CircleCurve) {
+TEST_F(PathDrawTest, CircleLargerStrokeThanR0) {
VkvgContext ctx = vkvg_create(surf);
vkvg_set_source_rgb(ctx, 0.8,0.8,0.8);
vkvg_paint(ctx);
- vkvg_scale(ctx,0.1,0.1);
- vkvg_set_source_rgb(ctx, 0.5, 0.5, 1);
- vkvg_arc(ctx, 1280, 1280, 1000, 0, M_PI * 2);
+
+ vkvg_set_source_rgb(ctx, 0, 0, 1);
+ vkvg_arc(ctx, 128, 128, 50.f, 0, M_PI * 1.5f);
vkvg_fill_preserve(ctx);
- vkvg_set_source_rgb(ctx, 0, 0, 0);
- vkvg_set_line_width(ctx, 100);
+ vkvg_set_source_rgba(ctx, 0, 1, 0, 0.3f);
+ vkvg_set_line_width(ctx, 150);
+ vkvg_stroke(ctx);
+
+ vkvg_destroy(ctx);
+
+ compareWithRefImage();
+}
+TEST_F(PathDrawTest, CircleLargerStrokeThanR1) {
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_set_source_rgb(ctx, 0.8,0.8,0.8);
+ vkvg_paint(ctx);
+
+ vkvg_set_source_rgb(ctx, 0, 0, 1);
+ vkvg_arc(ctx, 128, 128, 10.f, 0, M_PI * 1.5f);
+ vkvg_fill_preserve(ctx);
+ vkvg_set_source_rgba(ctx, 0, 1, 0, 0.3f);
+ vkvg_set_line_width(ctx, 150);
+ vkvg_stroke(ctx);
+
+ vkvg_destroy(ctx);
+
+ compareWithRefImage();
+}
+TEST_F(PathDrawTest, CircleLargerStrokeThanR2) {
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_set_source_rgb(ctx, 0.8,0.8,0.8);
+ vkvg_paint(ctx);
+
+ vkvg_set_source_rgb(ctx, 0, 0, 1);
+ vkvg_arc(ctx, 128, 128, 01.f, 0, M_PI * 1.5f);
+ vkvg_fill_preserve(ctx);
+ vkvg_set_source_rgba(ctx, 0, 1, 0, 0.3f);
+ vkvg_set_line_width(ctx, 150);
vkvg_stroke(ctx);
vkvg_destroy(ctx);
@@ -292,3 +332,11 @@ TEST_F(PathDrawTest, curve3) {
compareWithRefImage();
}
+TEST_F(PathDrawTest, curved_rect) {
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_set_source_rgb(ctx, 0.8,0.8,0.8);
+ vkvg_paint(ctx);
+
+ vkvg_destroy(ctx);
+ compareWithRefImage();
+} \ No newline at end of file
diff --git a/gunit_tests/textDraw.cpp b/gunit_tests/textDraw.cpp
index 8e40294..25b43a9 100644
--- a/gunit_tests/textDraw.cpp
+++ b/gunit_tests/textDraw.cpp
@@ -6,7 +6,7 @@ class TextDrawTest : public DrawTestBase {
protected:
void SetUp() override {
- surf = vkvg_surface_create(dev, 512, 512);
+ surf = vkvg_surface_create(dev, 512, 512);
}
void TearDown() override {
@@ -14,6 +14,19 @@ class TextDrawTest : public DrawTestBase {
}
};
TEST_F(TextDrawTest, References) {
+ VkvgFont font = vkvg_font_create(dev, "sans", 12);
+ EXPECT_EQ(VKVG_STATUS_SUCCESS, vkvg_font_status(font));
+ vkvg_font_destroy(font);
+
+ font = vkvg_font_create(dev, "Sans", 12);
+ EXPECT_EQ(VKVG_STATUS_SUCCESS, vkvg_font_status(font));
+ vkvg_font_destroy(font);
+
+ font = vkvg_font_create(dev, "noto sans jp", 12);
+ EXPECT_EQ(VKVG_STATUS_SUCCESS, vkvg_font_status(font));
+ vkvg_font_destroy(font);
+
+
/*EXPECT_EQ(VKVG_STATUS_NULL_POINTER, vkvg_font_status(NULL));
EXPECT_EQ(0, vkvg_pattern_get_reference_count(NULL));
EXPECT_NO_FATAL_FAILURE(vkvg_pattern_reference(NULL));
@@ -38,10 +51,40 @@ TEST_F(TextDrawTest, References) {
vkvg_pattern_destroy(pat);*/
}
-TEST_F(TextDrawTest, PaintImgPattern) {
+TEST_F(TextDrawTest, ShowText) {
VkvgContext ctx = vkvg_create(surf);
+ vkvg_paint(ctx);
+ VkvgFont font = vkvg_font_create(dev, "sans", 30);
+ vkvg_set_font(ctx, font);
+ vkvg_font_extents_t fe = {0};
+ vkvg_font_extents(ctx, &fe);
+ vkvg_set_source_rgb(ctx,1,1,1);
+ float penY = fe.ascent;
+ vkvg_move_to(ctx, 40, penY);
+ vkvg_show_text(ctx, "Galvanized by the quartz, the white rabbit just jumped on the red fox for the sake of the crows");
+ penY += fe.height;
+
+ vkvg_font_destroy(font);
+
+ font = vkvg_font_create(dev, "noto sans jp", 30);
+ vkvg_set_font(ctx, font);
+ vkvg_move_to(ctx, 40, penY);
+ vkvg_show_text(ctx, "Galvanized by the quartz, The white rabbit just jumped on the red fox for the sake of the crows");
+ vkvg_font_extents(ctx, &fe);
+ penY += fe.height;
+
+ vkvg_move_to(ctx, 40, penY);
+ vkvg_show_text(ctx, "いろはにほへと ちりぬるを わかよたれそ つねならむ");
+ vkvg_font_extents(ctx, &fe);
+ penY += fe.height;
+ vkvg_set_text_direction(ctx, VKVG_VERTICAL);
+ vkvg_move_to(ctx, 20, 60);
+ vkvg_show_text(ctx, "石英に刺激され、白ウサギはカラスたちのために、赤ギツネの上に飛び乗った。");
+
+
vkvg_destroy(ctx);
compareWithRefImage();
}
+
diff --git a/include/vkvg.h b/include/vkvg.h
index 1ca2522..c457060 100644
--- a/include/vkvg.h
+++ b/include/vkvg.h
@@ -1780,7 +1780,7 @@ vkvg_public void vkvg_font_extents(VkvgContext ctx, vkvg_font_extents_t* extents
* @param text Null terminated utf8 string.
* @return VkvgText
*/
-vkvg_public VkvgText vkvg_text_run_create(VkvgContext ctx, const char* text);
+vkvg_public VkvgText vkvg_text_create(VkvgContext ctx, const char* text);
/**
* @brief Create a new text run for a non null terminated string.
*
@@ -1789,40 +1789,40 @@ vkvg_public VkvgText vkvg_text_run_create(VkvgContext ctx, const char* text);
* @param length glyphs count, not to be confused with byte length.
* @return VkvgText
*/
-vkvg_public VkvgText vkvg_text_run_create_with_length(VkvgContext ctx, const char* text, uint32_t length);
+vkvg_public VkvgText vkvg_text_create_with_length(VkvgContext ctx, const char* text, uint32_t length);
/**
* @brief Release resources holded by the text run.
*
* @param VkvgtextRun A valid VkvgText pointer.
*/
-vkvg_public void vkvg_text_run_destroy(VkvgText textRun);
+vkvg_public void vkvg_text_destroy(VkvgText textRun);
/**
* @brief
*
* @param ctx a valid vkvg @ref context
* @param textRun
*/
-vkvg_public void vkvg_text_run_render(VkvgContext ctx, VkvgText textRun);
+vkvg_public void vkvg_text_render(VkvgContext ctx, VkvgText textRun);
/**
* @brief
*
* @param textRun
* @param extents
*/
-vkvg_public void vkvg_text_run_get_extents(VkvgText textRun, vkvg_text_extents_t* extents);
+vkvg_public void vkvg_text_get_extents(VkvgText textRun, vkvg_text_extents_t* extents);
/**
* @brief Get glyph count of text run.
*
* @return glyph count
*/
-vkvg_public uint32_t vkvg_text_run_get_glyph_count(VkvgText textRun);
+vkvg_public uint32_t vkvg_text_get_glyph_count(VkvgText textRun);
/**
* @brief Get glyph position at the provided index
* @param textRun A valid @ref VkvgText
* @param index index of the glyph to get position for.
* @return the glyph structure with position and glyph index.
*/
-vkvg_public vkvg_glyph_info_t vkvg_text_run_get_glyph_position(VkvgText textRun, uint32_t index);
+vkvg_public vkvg_glyph_info_t vkvg_text_get_glyph_position(VkvgText textRun, uint32_t index);
/** @}*/
/**
diff --git a/samples/tests/circles.cpp b/samples/tests/circles.cpp
index a302ec8..a03963f 100644
--- a/samples/tests/circles.cpp
+++ b/samples/tests/circles.cpp
@@ -44,3 +44,20 @@ TEST(circles_sizes) {
vkvg_destroy(ctx);
}
+TEST(circles_stroke_larger_than_r) {
+ VkvgContext ctx = vkvg_create(test->surf);
+ vkvg_clear(ctx);
+
+ vkvg_set_source_rgb(ctx, 1, 0, 0);
+
+ vkvg_arc(ctx, test->app->width / 2, test->app->height / 2, 1.f, 0, M_PIF * 1.5f);
+ vkvg_fill_preserve(ctx);
+
+ vkvg_set_source_rgba(ctx, 0, 1, 0, 0.3f);
+ vkvg_set_line_width(ctx, 300);
+ vkvg_stroke(ctx);
+
+ vkvg_destroy(ctx);
+
+ vkvg_destroy(ctx);
+} \ No newline at end of file
diff --git a/samples/tests/gradient.cpp b/samples/tests/gradient.cpp
index 37379b3..90a55c1 100644
--- a/samples/tests/gradient.cpp
+++ b/samples/tests/gradient.cpp
@@ -8,6 +8,67 @@ VkvgPattern create_grad(VkvgContext ctx, float x) {
return pat;
}
+
+void draw_gradient1(VkvgContext cr)
+{
+ VkvgPattern pat1;
+ pat1 = vkvg_pattern_create_linear(0.0, 0.0, 350.0, 350.0);
+
+ double j;
+ int count = 1;
+ for ( j = 0.1; j < 1; j += 0.1 ) {
+ if (( count % 2 )) {
+ vkvg_pattern_add_color_stop(pat1, j, 0, 0, 0, 1);
+ } else {
+ vkvg_pattern_add_color_stop(pat1, j, 1, 0, 0, 1);
+ }
+ count++;
+ }
+
+ vkvg_rectangle(cr, 20, 20, 300, 100);
+ vkvg_set_source(cr, pat1);
+ vkvg_fill(cr);
+
+ vkvg_pattern_destroy(pat1);
+}
+void draw_gradient2(VkvgContext cr)
+{
+ VkvgPattern pat2;
+ pat2 = vkvg_pattern_create_linear(0.0, 0.0, 350.0, 0.0);
+
+ double i;
+ int count = 1;
+ for ( i = 0.05; i < 0.95; i += 0.075 ) {
+ if (( count % 2 )) {
+ vkvg_pattern_add_color_stop(pat2, i, 0, 0, 0, 1);
+ } else {
+ vkvg_pattern_add_color_stop(pat2, i, 0, 0, 1, 1);
+ }
+ count++;
+ }
+
+ vkvg_rectangle(cr, 20, 140, 300, 100);
+ vkvg_set_source(cr, pat2);
+ vkvg_fill(cr);
+
+ vkvg_pattern_destroy(pat2);
+}
+void draw_gradient3(VkvgContext cr)
+{
+ VkvgPattern pat3;
+ pat3 = vkvg_pattern_create_linear(20.0, 260.0, 20.0, 360.0);
+
+ vkvg_pattern_add_color_stop(pat3, 0.1, 0, 0, 0, 1);
+ vkvg_pattern_add_color_stop(pat3, 0.5, 1, 1, 0, 1);
+ vkvg_pattern_add_color_stop(pat3, 0.9, 0, 0, 0, 1);
+
+ vkvg_rectangle(cr, 20, 260, 300, 100);
+ vkvg_set_source(cr, pat3);
+ vkvg_fill(cr);
+
+ vkvg_pattern_destroy(pat3);
+}
+
TEST(gradient_paint) {
VkvgContext ctx = vkvg_create(test->surf);
vkvg_clear(ctx);
@@ -172,3 +233,14 @@ TEST(gradient_radial) {
vkvg_destroy(ctx);
}
+
+TEST(gradient_cairo) {
+ VkvgContext ctx = vkvg_create(test->surf);
+ vkvg_set_source_rgb(ctx, 0.7f, 0.7f, 0.7f);
+ vkvg_paint(ctx);
+
+ draw_gradient1(ctx);
+ draw_gradient2(ctx);
+ draw_gradient3(ctx);
+ vkvg_destroy(ctx);
+} \ No newline at end of file
diff --git a/src/array.h b/src/array.h
index fc3a8ce..041d05f 100644
--- a/src/array.h
+++ b/src/array.h
@@ -31,10 +31,12 @@ static type* array_last_##type (array_##type* arr) { \
return &arr->elements[arr->count - 1]; \
} \
static void array_destroy_##type (array_##type* arr) { \
- free(arr->elements); \
- arr->elements = NULL; \
- arr->count = 0; \
- arr->size = 0; \
+ if (arr && arr->size > 0) { \
+ free(arr->elements); \
+ arr->elements = NULL; \
+ arr->count = 0; \
+ arr->size = 0; \
+ } \
}
#define ARRAY_DEL_ELT(type) \
static void array_del_##type (array_##type* arr, type elt) { \
diff --git a/src/svg/svg-parse.c b/src/svg/svg-parse.c
index 9761050..90b019f 100644
--- a/src/svg/svg-parse.c
+++ b/src/svg/svg-parse.c
@@ -1459,6 +1459,7 @@ void draw(svg_context *svg, SvgPresentationAttributes *const attribs) {
}
}
void process_element(svg_context *const svg, SvgPresentationAttributes *const attribs, void *elt, bool use) {
+ vkvg_new_sub_path(svg->ctx);
if (!(svg->inDefs || !attribs->visibility)) {
LOG("process element: %.*s \n", (int)svg->elt_len, svg->elt);
switch (_get_element_type(elt)) {
@@ -1673,17 +1674,16 @@ void draw_text(SVG_COMMON_SIG, svg_text_coords* coords, const uint8_t *buff, con
else
len = buff_end - buff;
- tr = vkvg_text_run_create_with_length(svg->ctx, (char*)buff, len);
- vkvg_text_run_render(svg->ctx, tr);
- charI += vkvg_text_run_get_glyph_count(tr);
- vkvg_text_run_destroy(tr);
+ tr = vkvg_text_create_with_length(svg->ctx, (char*)buff, len);
+ vkvg_text_render(svg->ctx, tr);
+ charI += vkvg_text_get_glyph_count(tr);
+ vkvg_text_destroy(tr);
buff += len;
}
coords->charIndex = charI;
}
-
void process_innerText(SVG_COMMON_SIG, const uint8_t *innerText, size_t txt_len) {
if (!parentData)
return;
diff --git a/src/vkvg_context.c b/src/vkvg_context.c
index 0c49c8d..16e31d5 100644
--- a/src/vkvg_context.c
+++ b/src/vkvg_context.c
@@ -1238,7 +1238,16 @@ void vkvg_set_text_direction(vkvg_context* ctx, vkvg_direction_t direction) {
RECORD(ctx, VKVG_CMD_SET_TEXT_DIRECTION, size);
ctx->textDirection = direction;
}
-
+void vkvg_text_extents(VkvgContext ctx, const char* text, vkvg_text_extents_t* extents) {
+ if (vkvg_status(ctx))
+ return;
+ _font_cache_text_extents(ctx, text, -1, extents);
+}
+void vkvg_font_extents(VkvgContext ctx, vkvg_font_extents_t* extents) {
+ if (vkvg_status(ctx) || vkvg_font_status(ctx->currentFont))
+ return;
+ _font_cache_font_extents(ctx->currentFont, extents);
+}
void vkvg_show_text(VkvgContext ctx, const char* text) {
if (vkvg_status(ctx) || vkvg_font_status(ctx->currentFont))
return;
@@ -1249,23 +1258,33 @@ void vkvg_show_text(VkvgContext ctx, const char* text) {
//_flush_undrawn_vertices (ctx);
}
-VkvgText vkvg_text_run_create(VkvgContext ctx, const char* text) {
+VkvgText vkvg_text_create(VkvgContext ctx, const char* text) {
if (vkvg_status(ctx) || vkvg_font_status(ctx->currentFont))
return NULL;
VkvgText tr = (vkvg_text_run_t*)calloc(1, sizeof(vkvg_text_run_t));
- text_run_init(ctx->currentFont, ctx->textDirection, text, -1, tr);
+ if (!tr) {
+ LOGE("vkvg_text_create error, no memory\n");
+ return NULL;
+ }
+ text_run_init(tr, ctx->currentFont, ctx->textDirection, text, -1);
return tr;
}
-VkvgText vkvg_text_run_create_with_length(VkvgContext ctx, const char* text, uint32_t length) {
+VkvgText vkvg_text_create_with_length(VkvgContext ctx, const char* text, uint32_t length) {
if (vkvg_status(ctx) || vkvg_font_status(ctx->currentFont))
return NULL;
VkvgText tr = (vkvg_text_run_t*)calloc(1, sizeof(vkvg_text_run_t));
- text_run_init(ctx->currentFont, ctx->textDirection, text, length, tr);
+ if (!tr) {
+ LOGE("vkvg_text_create error, no memory\n");
+ return NULL;
+ }
+ text_run_init(tr, ctx->currentFont, ctx->textDirection, text, length);
return tr;
}
-uint32_t vkvg_text_run_get_glyph_count(VkvgText textRun) { return textRun ? textRun->glyph_count : 0; }
-vkvg_glyph_info_t vkvg_text_run_get_glyph_position(VkvgText textRun, uint32_t index) {
- if (index >= textRun->glyph_count) {
+uint32_t vkvg_text_get_glyph_count(VkvgText textRun) {
+ return textRun ? textRun->glyph_count : 0;
+}
+vkvg_glyph_info_t vkvg_text_get_glyph_position(VkvgText textRun, uint32_t index) {
+ if (!textRun || index >= textRun->glyph_count) {
return (vkvg_glyph_info_t){0};
}
#if VKVG_USE_HARFBUZZ
@@ -1275,28 +1294,19 @@ vkvg_glyph_info_t vkvg_text_run_get_glyph_position(VkvgText textRun, uint32_t in
return textRun->glyphs[index];
#endif
}
-void vkvg_text_run_destroy(VkvgText textRun) {
+void vkvg_text_destroy(VkvgText textRun) {
if (!textRun)
return;
text_run_term(textRun);
free(textRun);
}
-void vkvg_text_run_render(VkvgContext ctx, VkvgText textRun) {
+void vkvg_text_render(VkvgContext ctx, VkvgText textRun) {
if (vkvg_status(ctx) || !textRun)
return;
- text_run_render(ctx, textRun);
+ text_run_render(textRun, ctx);
}
-void vkvg_text_run_get_extents(VkvgText textRun, vkvg_text_extents_t* extents) { *extents = textRun->extents; }
-
-void vkvg_text_extents(VkvgContext ctx, const char* text, vkvg_text_extents_t* extents) {
- if (vkvg_status(ctx))
- return;
- _font_cache_text_extents(ctx, text, -1, extents);
-}
-void vkvg_font_extents(VkvgContext ctx, vkvg_font_extents_t* extents) {
- if (vkvg_status(ctx) || vkvg_font_status(ctx->currentFont))
- return;
- _font_cache_font_extents(ctx->currentFont, extents);
+void vkvg_text_get_extents(VkvgText textRun, vkvg_text_extents_t* extents) {
+ *extents = textRun->extents;
}
void vkvg_save(VkvgContext ctx) {
diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c
index 2d2a600..47f274b 100644
--- a/src/vkvg_context_internal.c
+++ b/src/vkvg_context_internal.c
@@ -1273,7 +1273,7 @@ void _draw_segment(VkvgContext ctx, stroke_context_t* str, dash_context_t* dc, b
else
_build_vb_step(ctx, str, isCurve);
str->iL = str->cp++;
- if (ctx->vertCount - ctx->curVertOffset > VKVG_IBO_MAX / 3) {
+ if (ctx->vertCount - ctx->curVertOffset > VKVG_IBO_MAX / 3) {//TODO:should unit test that case
Vertex v0 = ctx->vertexCache[ctx->curVertOffset + str->firstIdx];
Vertex v1 = ctx->vertexCache[ctx->curVertOffset + str->firstIdx + 1];
_emit_draw_cmd_undrawn_vertices(ctx);
diff --git a/src/vkvg_device_internal.h b/src/vkvg_device_internal.h
index 5dced18..a436cd9 100644
--- a/src/vkvg_device_internal.h
+++ b/src/vkvg_device_internal.h
@@ -72,22 +72,21 @@ typedef struct _vkvg_device_t {
VkFormat stencilFormat; /**< Supported vulkan image format for stencil */
VkImageAspectFlags stencilAspectFlag; /**< stencil only or depth stencil, could be solved by
VK_KHR_separate_depth_stencil_layouts*/
- VkFormat pngStagFormat; /**< Supported vulkan image format png write staging img */
- VkImageTiling pngStagTiling; /**< tiling for the blit operation */
+ VkFormat pngStagFormat; /**< Supported vulkan image format png write staging img */
+ VkImageTiling pngStagTiling; /**< tiling for the blit operation */
- mtx_t mutex; /**< protect device access (queue, cahes, ...)from ctxs in separate threads */
- bool threadAware; /**< if true, mutex is created and guard device queue and caches access */
- VkhQueue gQueue; /**< Vulkan Queue with Graphic flag */
+ mtx_t mutex; /**< protect device access (queue, cahes, ...)from ctxs in separate threads */
+ bool threadAware; /**< if true, mutex is created and guard device queue and caches access */
+ VkhQueue gQueue; /**< Vulkan Queue with Graphic flag */
- VkRenderPass renderPass; /**< Vulkan render pass, common for all surfaces */
- VkRenderPass
- renderPass_ClearStencil; /**< Vulkan render pass for first draw with context, stencil has to be cleared */
- VkRenderPass renderPass_ClearAll; /**< Vulkan render pass for new surface, clear all attacments*/
+ VkRenderPass renderPass; /**< Vulkan render pass, common for all surfaces */
+ VkRenderPass renderPass_ClearStencil; /**< Vulkan render pass for first draw with context, stencil has to be cleared */
+ VkRenderPass renderPass_ClearAll; /**< Vulkan render pass for new surface, clear all attacments*/
uint32_t references; /**< Reference count, prevent destroying device if still in use */
VkCommandPool cmdPool; /**< Global command pool for processing on surfaces without context */
VkCommandBuffer cmd; /**< Global command buffer */
- VkFence fence; /**< this fence is kept signaled when idle, wait and reset are called before each recording. */
+ VkFence fence; /**< this fence is kept signaled when idle, wait and reset are called before each recording. */
VkPipeline pipe_OVER; /**< default operator */
VkPipeline pipe_SUB;
@@ -107,11 +106,11 @@ typedef struct _vkvg_device_t {
VkhDevice vkhDev; /**< old VkhDev created during vulkan context creation by @ref vkvg_device_create. */
- VkhImage emptyImg; /**< prevent unbound descriptor to trigger Validation error 61 */
- VkSampleCountFlags samples; /**< samples count common to all surfaces */
- bool deferredResolve; /**< if true, resolve only on context destruction and set as source */
+ VkhImage emptyImg; /**< prevent unbound descriptor to trigger Validation error 61 */
+ VkSampleCountFlags samples; /**< samples count common to all surfaces */
+ bool deferredResolve; /**< if true, resolve only on context destruction and set as source */
- _font_cache_t* fontCache; /**< Store everything relative to common font caching system */
+ _font_cache_t* fontCache; /**< Store everything relative to common font caching system */
VkvgContext lastCtx; /**< last element of double linked list of context, used to trigger font caching system update
on all contexts*/
diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c
index 8098a28..7d7c356 100644
--- a/src/vkvg_fonts.c
+++ b/src/vkvg_fonts.c
@@ -802,7 +802,7 @@ void _font_cache_text_extents(VkvgContext ctx, const char* text, int length, vkv
}
vkvg_text_run_t tr = {0};
- text_run_init(ctx->currentFont, ctx->textDirection, text, length, &tr);
+ text_run_init(&tr, ctx->currentFont, ctx->textDirection, text, length);
if (ctx->status)
return;
@@ -814,18 +814,18 @@ void _font_cache_text_extents(VkvgContext ctx, const char* text, int length, vkv
// text is expected as utf8 encoded
void _font_cache_show_text(VkvgContext ctx, const char* text) {
vkvg_text_run_t tr = {0};
- text_run_init(ctx->currentFont, ctx->textDirection, text, -1, &tr);
+ text_run_init(&tr, ctx->currentFont, ctx->textDirection, text, -1);
if (ctx->status)
return;
- text_run_render(ctx, &tr);
+ text_run_render(&tr, ctx);
text_run_term(&tr);
//_show_texture(ctx); return;
}
// if length is < 0, text must be null terminated, else it contains glyph count
-void text_run_init(VkvgFont font, vkvg_direction_t textDirection, const char* text, int length, VkvgText textRun) {
+void text_run_init(VkvgText textRun, VkvgFont font, vkvg_direction_t textDirection, const char* text, int length) {
textRun->font = font;
textRun->textDirection = textDirection;
vkvg_font_reference (textRun->font);
@@ -897,7 +897,7 @@ void text_run_term(VkvgText textRun) {
vkvg_font_destroy(textRun->font);
}
-void text_run_render(VkvgContext ctx, VkvgText tr) {
+void text_run_render(VkvgText tr, VkvgContext ctx) {
unsigned int glyph_count;
#ifdef VKVG_USE_HARFBUZZ
hb_glyph_info_t* glyph_info = hb_buffer_get_glyph_infos(tr->hbBuf, &glyph_count);
diff --git a/src/vkvg_fonts.h b/src/vkvg_fonts.h
index 09a57d0..66f8612 100644
--- a/src/vkvg_fonts.h
+++ b/src/vkvg_fonts.h
@@ -312,7 +312,7 @@ void _font_cache_text_extents(VkvgContext ctx, const char* text, int length, vkv
void _font_cache_font_extents(VkvgFont font, vkvg_font_extents_t* extents);
void _font_cache_update_context_descset(VkvgContext ctx);
-void text_run_init(VkvgFont font, vkvg_direction_t textDirection, const char* text, int length, VkvgText textRun);
+void text_run_init(VkvgText textRun, VkvgFont font, vkvg_direction_t textDirection, const char* text, int length);
void text_run_term(VkvgText textRun);
-void text_run_render(VkvgContext ctx, VkvgText tr); // Draw text run
+void text_run_render(VkvgText tr, VkvgContext ctx); // Draw text run
#endif
diff --git a/tests/data/text.svg b/tests/data/text.svg
index 91c2505..0be89d8 100644
--- a/tests/data/text.svg
+++ b/tests/data/text.svg
@@ -1,4 +1,4 @@
-<svg xmlns="http://w3.org" width="800" height="600" viewBox="0 0 800 600">
+<svg width="800" height="600" viewBox="0 0 800 600">
<!-- Visual grid lines for debugging alignments -->
<g stroke="#e0e0e0" stroke-width="1">
<line x1="50" y1="0" x2="50" y2="600" />
@@ -21,7 +21,7 @@
<!-- TEST 1: Comma/Space Separators & List Exhaustion -->
<!-- 'S' at 50, 'P' at 100, 'A' at 150, 'C' at 200. 'E' and 'S' should rely on default font advances. -->
- <text x="50, 100 150,200" y="100" font-family="sans-serif" font-size="24" fill="black">
+ <text x="50, 100 150,200" y="100" font-family="sans" font-size="52" fill="black">
SPACES
</text>
diff --git a/tests/fonts/allfont.c b/tests/fonts/allfont.c
index 00eb19d..4e79fa3 100644
--- a/tests/fonts/allfont.c
+++ b/tests/fonts/allfont.c
@@ -31,7 +31,6 @@ typedef struct {
// A localized library of pan-unicode text variations
static const LocaleSample script_samples[] = {
- { "en", "The quick brown fox jumps over the lazy dog." }, // Latin Fallback
{ "ja", "いろはにほへと ちりぬるを わかよたれそ つねならむ" }, // Japanese Hiragana
{ "zh", "天地玄黃,宇宙洪荒。日月盈昃,辰宿列張。" }, // Chinese Hanzi
{ "ko", "다람쥐 쳇바퀴에 타고파" }, // Korean Hangul
@@ -42,14 +41,16 @@ static const LocaleSample script_samples[] = {
{ "el", "διαφυλάξτε γενικά τη ζωή σας από τον φόβο" }, // Greek
{ "th", "เป็นมนุษย์สุดประเสริฐเลิIศคุณค่า" }, // Thai
{ "hy", "Ֆիզիկոս Մկրտիչը օճառաջուր ցողելով բժշկում է գնդապետ Հայկի փքված ձախ թևը։" }, // Armenian
+ { "pa", "ਘੁਮਿਆਰ ਨੇ ਮਿੱਟੀ ਚੁੱਕ ਕੇ ਇੱਕ ਬਹੁਤ ਹੀ ਸੁੰਦਰ ਘੜਾ ਬਣਾਇਆ।" }, // Punjabi (Gurmukhi script)
+ { "te", "కచ్ఛపము మందగమనముతో చెరువు వైపు వెళుతోంది." }, // Telugu (Telugu script)
+ { "ta", "தமிழ் மொழி உலகினில் மிக தொன்மையான மற்றும் அழகான மொழியாகும்." }, // Tamil (Tamil script)
+ { "ber-ma", "ⵎⴰⵕⵕⴰ ⵉⵎᏓⵏⵏ ⴷⴳ ⵓⵍⵉⴼ ⴷ ⵉⵣⵔⴼⴰⵏ ⴷ ⵍⵃⵇⵇ ⵜⵜⵍⴰⵍⴰⵏ ⴷ ⵉⵍⴻⵍⵍⵉⵢⵏ." }, // Moroccan Berber (Tifinagh script)
+ { "en", "The quick brown fox jumps over the lazy dog." }, // Latin Fallback
{ "agr", "Agatjai juuk tusha numpanum ijuaku jintanum pujawai" }, // Aguaruna (Latin script variation)
//{ "aa", "Afari fanta asat darih doro dahanik xisbisa" }, // Afar (Latin script variation)
{ "bem", "Abantu bonse bafyalwa abalubuka no kulingana mu mucinshi" }, // Bemba (Bantu Latin script)
- { "pa", "ਘੁਮਿਆਰ ਨੇ ਮਿੱਟੀ ਚੁੱਕ ਕੇ ਇੱਕ ਬਹੁਤ ਹੀ ਸੁੰਦਰ ਘੜਾ ਬਣਾਇਆ।" }, // Punjabi (Gurmukhi script)
- { "te", "కచ్ఛపము మందగమనముతో చెరువు వైపు వెళుతోంది." }, // Telugu (Telugu script)
{ "km", "ខ្យល់បក់បោកបបួលបក្សីហើរទៅកាន់ព្រៃព្រឹក្សាដ៏ស្ងប់ស្ងាត់។" }, // Khmer (Khmer script)
{ "lo", "ນົກກາງແກບິນຂ້າມທົ່ງນາທີ່ກວ້າງໃຫຍ່ໄພສານຢ່າງສະຫງ່າງາມ." }, // Lao (Lao script)
- { "ta", "தமிழ் மொழி உலகினில் மிக தொன்மையான மற்றும் அழகான மொழியாகும்." }, // Tamil (Tamil script)
{ "or", "ଋଷିମାନେ ଅରଣ୍ୟ ମଧ୍ୟରେ ଧ୍ୟାନ କରି ଶାନ୍ତି ଲାଭ କରନ୍ତି।" }, // Odia/Oriya (Odia script)
{ "ml", "ഭൂമിയിലെ എല്ലാ മനുഷ്യരും തുല്യ അവകാശങ്ങളോടെ ജനിക്കുന്നു." }, // Malayalam (Malayalam script)
{ "as", "শৰৎকালৰ স্নিগ্ধ জোনাক ৰাতি আকাশখন বৰ ধুনীয়া দেখায়।" }, // Assamese (Bengali-Assamese script)
@@ -63,7 +64,6 @@ static const LocaleSample script_samples[] = {
{ "mnw", "မန်ဝံသဂမၠိုၚ် က္တဵုဒှ်ကၠုၚ် နကဵုဂုဏ်သိက္ခာ ညဳသၟဟ်ဂမၠိုၚ်။" }, // Mon (Mon-Burmese script)
{ "ii", "ꊿꊪꉼꆹꊪꊪꊿꐊꐥꌋꅍꐛꐹꂿꆪꄮꄯꉼꆹꄮꄯꂿꆪꊨꏦꍏꆪꐥꌋꅍꐛꐹꏦꍏꅪꏦꍏꅪꐨꏦꍏꄮꄯꅪ" }, // Nuosu / Liangshan Yi (Yi syllabary)
{ "chr", "ᏂᎦᏛ ᎠᏂᏰᎸᎢ ᎤᏂᎲᏓ ᏂᎨᏒᎾ ᎤᎾᏕᎲᎩ ᎢᏳᏍᏗᏉ ᎨᏒ ᎦᎸᏉᏗᏳ" }, // Cherokee (Cherokee syllabary)
- { "ber-ma", "ⵎⴰⵕⵕⴰ ⵉⵎᏓⵏⵏ ⴷⴳ ⵓⵍⵉⴼ ⴷ ⵉⵣⵔⴼⴰⵏ ⴷ ⵍⵃⵇⵇ ⵜⵜⵍⴰⵍⴰⵏ ⴷ ⵉⵍⴻⵍⵍⵉⵢⵏ." }, // Moroccan Berber (Tifinagh script)
{ "ab", "Дарбанზаалак ауаҩы дшоуп ихы ақәgenericуи иҳаgenericти." }, // Abkhaz (Cyrillic variation)
{ "syr", "ܟܠ ܒܪܢܫܐ ܡܬܝܠܕ ܚܐܪܐ ܘܫܘܝܐ ܒܐܝܩܪܐ ܘܒܙܕܩܐ." }, // Syriac (Syriac script, right-to-left)
{ "iu", "ᐃᓅᔪᓕᒫᑦ ᐊᓂᖅᑎᕆᔪᓕᒫᑦ ᐃᓅᕗᑦ ᐃᓱᒪᕐᓱᕐᖢᑎᒃ ᐊᒻᒪ ᐊᔾᔨᒌᒃᑐᒥᒃ" }, // Inuktitut (Canadian Aboriginal Syllabics)
@@ -71,27 +71,6 @@ static const LocaleSample script_samples[] = {
{ "mn-cn", "Хүн бүр төрөхDiscussion эрх чөлөөтэй, нэр төр, эрхийн хувьд адилхан." }, // Mongolian - Inner Mongolia (Cyrillic fallback)
};
-bool try_get_sample_by_fc_lang(const char* fc_lang, char* str) {
- const char* sample = NULL;
- if (fc_lang) {
- for (int i = 0; i < 37; i++) {
- if (!strncmp(fc_lang, script_samples[i].lang_code, strlen(script_samples[i].lang_code)) &&
- strlen(script_samples[i].lang_code) == strlen(fc_lang)) {
- sample = script_samples[i].sample_text;
-
- break;
- }
- }
- if (!sample) {
- sample = script_samples[0].sample_text;
- return false;
- }
- }
-
- strncpy(str, sample, strlen(sample)+1);
- return true;
-}
-
#ifdef VKVG_USE_FREETYPE
void convert_utf16be_to_utf8(const FT_Byte* src, FT_UInt src_len, char* dest, FT_UInt dest_max_len) {
FT_UInt d_idx = 0;
@@ -146,6 +125,7 @@ bool try_get_sample_string(FcPattern* font_entry, FT_Face face, char* str) {
}
FcLangSet* langset = NULL;
FcChar8* lang = NULL;
+ const char* sample = NULL;
if (FcPatternGetLangSet(font_entry, FC_LANG, 0, &langset) == FcResultMatch) {
FcStrSet *lang_set = FcLangSetGetLangs(langset);
if (!lang_set)
@@ -155,13 +135,23 @@ bool try_get_sample_string(FcPattern* font_entry, FT_Face face, char* str) {
FcStrListDone(lang_list);
return false;
}
-
- while ((lang = FcStrListNext(lang_list))) {
- if (!lang)
- continue;
- if (try_get_sample_by_fc_lang((char*)lang, str))
- printf("sample found for %s\n", lang);
+ for (int i = 0; i < 37; i++) {
+ while ((lang = FcStrListNext(lang_list))) {
+ if (!lang)
+ continue;
+ if (!strncmp((char*)lang, script_samples[i].lang_code, strlen(script_samples[i].lang_code)) &&
+ strlen(script_samples[i].lang_code) == strlen((char*)lang)) {
+ sample = (char*)script_samples[i].sample_text;
+ break;
+ }
+ }
+ if (sample)
+ break;
+ FcStrListFirst(lang_list);
}
+ if (!sample)
+ sample = (char*)script_samples[14].sample_text;
+ strncpy(str, sample, strlen(sample)+1);
FcStrListDone(lang_list);
FcStrSetDestroy(lang_set);
@@ -234,9 +224,9 @@ void draw(VkvgSurface surfFont) {
vkvg_font_extents_t fe = {0};
vkvg_font_extents(ctx, &fe);
- VkvgText tr = vkvg_text_run_create(ctx, tmp);
+ VkvgText tr = vkvg_text_create(ctx, tmp);
vkvg_text_extents_t extents = {0};
- vkvg_text_run_get_extents(tr, &extents);
+ vkvg_text_get_extents(tr, &extents);
vkvg_rectangle(ctx, penX, penY - fe.ascent, extents.width, extents.height);
vkvg_set_line_width(ctx, 1);
vkvg_set_source_rgba(ctx,0.5f,0.5f,1, 0.7f);
@@ -249,11 +239,11 @@ void draw(VkvgSurface surfFont) {
vkvg_move_to (ctx, penX, penY);
vkvg_set_source_rgb(ctx,1,1,1);
- vkvg_text_run_render(ctx,tr);
+ vkvg_text_render(ctx,tr);
vkvg_flush(ctx);
- penY += fe.height;
+ penY += fe.height * 1.5f;
if (vkvg_font_status(font)) {
printf("Font in error %s\n", file_path);
@@ -264,7 +254,7 @@ void draw(VkvgSurface surfFont) {
}
vkvg_font_destroy(font);
- vkvg_text_run_destroy(tr);
+ vkvg_text_destroy(tr);
if (penY > test_height - 100)
break;
@@ -350,7 +340,7 @@ int main(int argc, char* argv[]) {
e->gQFamIdx, 0, false };//, TESTS_DATA_ROOT "/fonts"};
device = vkvg_device_create(&info);
- vkvg_device_set_dpy(device, 140,140);
+ vkvg_device_set_dpy(device, 96,96);
surf = vkvg_surface_create(device, test_width, test_height);
VkvgSurface surfFont = vkvg_surface_create(device, test_width, test_height);
diff --git a/tests/fonts/fontquery.c b/tests/fonts/fontquery.c
index bf979ab..c4ab1f9 100644
--- a/tests/fonts/fontquery.c
+++ b/tests/fonts/fontquery.c
@@ -298,9 +298,9 @@ void draw(VkvgSurface surfFont) {
vkvg_font_extents_t fe = {0};
vkvg_font_extents(ctx, &fe);
- VkvgText tr = vkvg_text_run_create(ctx, txtBuffCopy);
+ VkvgText tr = vkvg_text_create(ctx, txtBuffCopy);
vkvg_text_extents_t extents = {0};
- vkvg_text_run_get_extents(tr, &extents);
+ vkvg_text_get_extents(tr, &extents);
vkvg_rectangle(ctx, penX, penY - fe.ascent, extents.width, extents.height);
vkvg_set_line_width(ctx, 1);
vkvg_set_source_rgba(ctx,0.5f,0.5f,1, 0.7f);
@@ -313,7 +313,7 @@ void draw(VkvgSurface surfFont) {
vkvg_move_to (ctx, penX, penY);
vkvg_set_source_rgb(ctx,1,1,1);
- vkvg_text_run_render(ctx,tr);
+ vkvg_text_render(ctx,tr);
penX = 50;
penY = 150;
@@ -371,7 +371,7 @@ void draw(VkvgSurface surfFont) {
vkvg_fill(ctx);*/
vkvg_flush(ctx);
- vkvg_text_run_destroy(tr);
+ vkvg_text_destroy(tr);
vkvg_font_destroy(f);
} else {
for (int i = curFontStartIdx; i < font_database->nfont; i++) {
diff --git a/tests/text.c b/tests/text.c
index 4d3e948..6e131ce 100644
--- a/tests/text.c
+++ b/tests/text.c
@@ -1,6 +1,7 @@
#include "test.h"
static const char* txt = "The quick brown fox jumps over the lazy dog";
+static const char* txt2 = "いろはにほへと ちりぬるを わかよたれそ つねならむ";
void print(VkvgContext ctx, float penY, uint32_t size) {
vkvg_set_font_size(ctx, size);
@@ -193,12 +194,62 @@ void simple_text() {
vkvg_paint(ctx);
vkvg_set_source_rgb(ctx, 1, 1, 1);
- vkvg_load_font_from_path(ctx, "data/DancingScript-Regular.ttf", "dancing");
+ VkvgFont mono = vkvg_font_create(device, "mono", 12);
+ VkvgFont norm = vkvg_font_create_from_file(device, "data/Proto-Sinaitic15.ttf", 0, 24);
+ vkvg_set_font (ctx, mono);
+ vkvg_move_to(ctx, 20, 50);
+ vkvg_show_text(ctx, "hwhy");
+
+ vkvg_move_to(ctx, 100, 50);
+ vkvg_show_text(ctx, "efgh");
+
+ vkvg_move_to(ctx, 180, 50);
+ vkvg_show_text(ctx, "ijkl");
+
+ vkvg_set_font (ctx, norm);
+ vkvg_move_to(ctx, 20, 100);
+ vkvg_show_text(ctx, "ABCD");
+
+ /*vkvg_load_font_from_path(ctx, "data/DancingScript-Regular.ttf", "dancing");
print_boxed(ctx, "abcdefghijklmnopqrstuvwxyz", 20, 60, 20);
print_boxed(ctx, "ABC", 20, 160, 60);
vkvg_select_font_face(ctx, "mono");
print_boxed(ctx, "This is a test string!", 20, 250, 20);
- print_boxed(ctx, "ANOTHER ONE TO CHECK..", 20, 350, 20);
+ print_boxed(ctx, "ANOTHER ONE TO CHECK..", 20, 350, 20);*/
+
+ vkvg_flush(ctx);
+
+ vkvg_font_destroy(mono);
+ /*vkvg_font_destroy(norm);*/
+ vkvg_destroy(ctx);
+}
+void variable_text() {
+ VkvgContext ctx = vkvg_create(surf);
+ vkvg_paint(ctx);
+ vkvg_set_source_rgb(ctx, 1, 1, 1);
+
+ VkvgFont noto = vkvg_font_create(device, "Noto Sans JP:fontvariations=wght=150", 30);
+
+ vkvg_set_font (ctx, noto);
+ vkvg_move_to(ctx, 20, 50);
+ vkvg_show_text(ctx, txt2);
+
+ vkvg_font_destroy(noto);
+
+ noto = vkvg_font_create(device, "Noto Sans JP:fontvariations=wght=900", 30);
+ vkvg_set_font (ctx, noto);
+ vkvg_move_to(ctx, 20, 150);
+ vkvg_show_text(ctx, txt2);
+
+ vkvg_font_destroy(noto);
+
+ noto = vkvg_font_create(device, "Cantarell:fontvariations=wght=900", 30);
+ vkvg_set_font (ctx, noto);
+ vkvg_move_to(ctx, 20, 200);
+ vkvg_show_text(ctx, txt);
+
+ vkvg_font_destroy(noto);
+
vkvg_destroy(ctx);
}
@@ -266,15 +317,17 @@ void proto_sinaitic() {
}
int main(int argc, char* argv[]) {
no_test_size = true;
- PERFORM_TEST(simple_text, argc, argv);
- PERFORM_TEST(font_file_path, argc, argv);
+ vkh_log_level = VKVG_LOG_INFO;
+ //PERFORM_TEST(simple_text, argc, argv);
+ PERFORM_TEST(variable_text, argc, argv);
+ /*PERFORM_TEST(font_file_path, argc, argv);
PERFORM_TEST(single_font_and_size, argc, argv);
PERFORM_TEST(random_size, argc, argv);
PERFORM_TEST(random_font_and_size, argc, argv);
PERFORM_TEST(test, argc, argv);
PERFORM_TEST(test1, argc, argv);
PERFORM_TEST(test2, argc, argv);
- PERFORM_TEST(proto_sinaitic, argc, argv);
+ PERFORM_TEST(proto_sinaitic, argc, argv);*/
return 0;
}