mirror of
https://github.com/zlgopen/awtk.git
synced 2025-05-08 11:33:48 +08:00
improve nanovg
This commit is contained in:
parent
a6a06a3380
commit
deeb5c3546
@ -305,6 +305,14 @@ static NVGstate* nvg__getState(NVGcontext* ctx)
|
||||
return &ctx->states[ctx->nstates-1];
|
||||
}
|
||||
|
||||
static NVGstate* nvg__getStateByIndex(NVGcontext* ctx, int idx)
|
||||
{
|
||||
if (idx < 0 || idx >= ctx->nstates) {
|
||||
return NULL;
|
||||
}
|
||||
return &ctx->states[idx];
|
||||
}
|
||||
|
||||
void nvgGetStateXfrom(NVGcontext* ctx, float* xform)
|
||||
{
|
||||
if(xform != NULL) {
|
||||
@ -1089,6 +1097,7 @@ void nvgScissor(NVGcontext* ctx, float x, float y, float w, float h)
|
||||
|
||||
state->scissor.extent[0] = w*0.5f*scale_x;
|
||||
state->scissor.extent[1] = h*0.5f*scale_y;
|
||||
state->scissor.state_index = ctx->nstates - 1;
|
||||
}
|
||||
|
||||
static void nvg__isectRects(float* dst,
|
||||
@ -1108,8 +1117,11 @@ static void nvg__isectRects(float* dst,
|
||||
int nvgGetCurrScissor(NVGcontext* ctx, float* x, float* y, float* w, float* h)
|
||||
{
|
||||
NVGstate* state = nvg__getState(ctx);
|
||||
NVGstate* scissorState = nvg__getStateByIndex(ctx, state->scissor.state_index);
|
||||
float pxform[6], invxorm[6];
|
||||
float ex, ey, tex, tey;
|
||||
float scale_x = 0.0f;
|
||||
float scale_y = 0.0f;
|
||||
|
||||
// If no previous scissor has been set, set the scissor as current scissor.
|
||||
if (state->scissor.extent[0] < 0) {
|
||||
@ -1117,13 +1129,17 @@ int nvgGetCurrScissor(NVGcontext* ctx, float* x, float* y, float* w, float* h)
|
||||
*h = 0;
|
||||
return 0;
|
||||
}
|
||||
scissorState = scissorState == NULL ? state : scissorState;
|
||||
|
||||
scale_x = sqrtf(state->scissor.xform[0]*state->scissor.xform[0] + state->scissor.xform[2]*state->scissor.xform[2]);
|
||||
scale_y = sqrtf(state->scissor.xform[1]*state->scissor.xform[1] + state->scissor.xform[3]*state->scissor.xform[3]);
|
||||
|
||||
// Transform the current scissor rect into current transform space.
|
||||
// If there is difference in rotation, this will be approximation.
|
||||
memcpy(pxform, state->scissor.xform, sizeof(float)*6);
|
||||
ex = state->scissor.extent[0];
|
||||
ey = state->scissor.extent[1];
|
||||
nvgTransformInverse(invxorm, state->xform);
|
||||
ex = state->scissor.extent[0] / scale_x;
|
||||
ey = state->scissor.extent[1] / scale_y;
|
||||
nvgTransformInverse(invxorm, scissorState->xform);
|
||||
nvgTransformMultiply(pxform, invxorm);
|
||||
tex = ex*nvg__absf(pxform[0]) + ey*nvg__absf(pxform[2]);
|
||||
tey = ex*nvg__absf(pxform[1]) + ey*nvg__absf(pxform[3]);
|
||||
@ -1162,9 +1178,12 @@ void nvgIntersectScissorForOtherRect(NVGcontext* ctx, float x, float y, float w,
|
||||
void nvgIntersectScissor_ex(NVGcontext* ctx, float* x, float* y, float* w, float* h)
|
||||
{
|
||||
NVGstate* state = nvg__getState(ctx);
|
||||
NVGstate* scissorState = nvg__getStateByIndex(ctx, state->scissor.state_index);
|
||||
float pxform[6], invxorm[6];
|
||||
float rect[4];
|
||||
float ex, ey, tex, tey;
|
||||
float scale_x = 0.0f;
|
||||
float scale_y = 0.0f;
|
||||
|
||||
// If no previous scissor has been set, set the scissor as current scissor.
|
||||
if (state->scissor.extent[0] < 0) {
|
||||
@ -1172,12 +1191,16 @@ void nvgIntersectScissor_ex(NVGcontext* ctx, float* x, float* y, float* w, float
|
||||
return;
|
||||
}
|
||||
|
||||
scissorState = scissorState == NULL ? state : scissorState;
|
||||
scale_x = sqrtf(state->scissor.xform[0]*state->scissor.xform[0] + state->scissor.xform[2]*state->scissor.xform[2]);
|
||||
scale_y = sqrtf(state->scissor.xform[1]*state->scissor.xform[1] + state->scissor.xform[3]*state->scissor.xform[3]);
|
||||
|
||||
// Transform the current scissor rect into current transform space.
|
||||
// If there is difference in rotation, this will be approximation.
|
||||
memcpy(pxform, state->scissor.xform, sizeof(float)*6);
|
||||
ex = state->scissor.extent[0];
|
||||
ey = state->scissor.extent[1];
|
||||
nvgTransformInverse(invxorm, state->xform);
|
||||
ex = state->scissor.extent[0] / scale_x;
|
||||
ey = state->scissor.extent[1] / scale_y;
|
||||
nvgTransformInverse(invxorm, scissorState->xform);
|
||||
nvgTransformMultiply(pxform, invxorm);
|
||||
tex = ex*nvg__absf(pxform[0]) + ey*nvg__absf(pxform[2]);
|
||||
tey = ex*nvg__absf(pxform[1]) + ey*nvg__absf(pxform[3]);
|
||||
@ -1197,9 +1220,12 @@ void nvgIntersectScissor_ex(NVGcontext* ctx, float* x, float* y, float* w, float
|
||||
void nvgIntersectScissor(NVGcontext* ctx, float x, float y, float w, float h)
|
||||
{
|
||||
NVGstate* state = nvg__getState(ctx);
|
||||
NVGstate* scissorState = nvg__getStateByIndex(ctx, state->scissor.state_index);
|
||||
float pxform[6], invxorm[6];
|
||||
float rect[4];
|
||||
float ex, ey, tex, tey;
|
||||
float scale_x = 0.0f;
|
||||
float scale_y = 0.0f;
|
||||
|
||||
// If no previous scissor has been set, set the scissor as current scissor.
|
||||
if (state->scissor.extent[0] < 0) {
|
||||
@ -1207,12 +1233,16 @@ void nvgIntersectScissor(NVGcontext* ctx, float x, float y, float w, float h)
|
||||
return;
|
||||
}
|
||||
|
||||
scissorState = scissorState == NULL ? state : scissorState;
|
||||
scale_x = sqrtf(state->scissor.xform[0]*state->scissor.xform[0] + state->scissor.xform[2]*state->scissor.xform[2]);
|
||||
scale_y = sqrtf(state->scissor.xform[1]*state->scissor.xform[1] + state->scissor.xform[3]*state->scissor.xform[3]);
|
||||
|
||||
// Transform the current scissor rect into current transform space.
|
||||
// If there is difference in rotation, this will be approximation.
|
||||
memcpy(pxform, state->scissor.xform, sizeof(float)*6);
|
||||
ex = state->scissor.extent[0];
|
||||
ey = state->scissor.extent[1];
|
||||
nvgTransformInverse(invxorm, state->xform);
|
||||
ex = state->scissor.extent[0] / scale_x;
|
||||
ey = state->scissor.extent[1] / scale_y;
|
||||
nvgTransformInverse(invxorm, scissorState->xform);
|
||||
nvgTransformMultiply(pxform, invxorm);
|
||||
tex = ex*nvg__absf(pxform[0]) + ey*nvg__absf(pxform[2]);
|
||||
tey = ex*nvg__absf(pxform[1]) + ey*nvg__absf(pxform[3]);
|
||||
|
@ -696,6 +696,7 @@ enum NVGtexture {
|
||||
struct NVGscissor {
|
||||
float xform[6];
|
||||
float extent[2];
|
||||
int state_index;
|
||||
};
|
||||
typedef struct NVGscissor NVGscissor;
|
||||
|
||||
|
@ -153,6 +153,10 @@ static nvgp_state_t* nvgp_get_state(nvgp_context_t* ctx) {
|
||||
return nvgp_darray_get_ptr(&ctx->states, ctx->states.size - 1, nvgp_state_t);
|
||||
}
|
||||
|
||||
static nvgp_state_t* nvgp_get_state_by_index(nvgp_context_t* ctx, int idx) {
|
||||
return nvgp_darray_get_ptr(&ctx->states, idx, nvgp_state_t);
|
||||
}
|
||||
|
||||
static nvgp_state_t* nvgp_get_empty_state_by_tail(nvgp_context_t* ctx) {
|
||||
return nvgp_darray_get_empty_by_tail(&ctx->states, nvgp_state_t);
|
||||
}
|
||||
@ -1098,23 +1102,32 @@ nvgp_error_t nvgp_scissor(nvgp_context_t* ctx, float x, float y, float w, float
|
||||
|
||||
state->scissor.extent[0] = w * 0.5f * scale_x;
|
||||
state->scissor.extent[1] = h * 0.5f * scale_y;
|
||||
state->scissor.state_index = ctx->states.size - 1;
|
||||
return NVGP_OK;
|
||||
}
|
||||
return NVGP_FAIL;
|
||||
}
|
||||
|
||||
nvgp_error_t nvgp_get_curr_clip_rect(nvgp_context_t* ctx, float* x, float* y, float* w, float* h) {
|
||||
float scale_x = 0.0f;
|
||||
float scale_y = 0.0f;
|
||||
nvgp_state_t* state = NULL;
|
||||
nvgp_state_t* scissor_state = NULL;
|
||||
CHECK_OBJECT_IS_NULL(ctx);
|
||||
state = nvgp_get_state(ctx);
|
||||
if (state != NULL) {
|
||||
float ex, ey, tex, tey;
|
||||
nvgp_matrix_t pxform, invxorm;
|
||||
scissor_state = nvgp_get_state_by_index(ctx, state->scissor.state_index);
|
||||
scissor_state = scissor_state == NULL ? state : scissor_state;
|
||||
|
||||
scale_x = sqrtf(state->scissor.matrix.mat.scale_x * state->scissor.matrix.mat.scale_x + state->scissor.matrix.mat.skew_x * state->scissor.matrix.mat.skew_x);
|
||||
scale_y = sqrtf(state->scissor.matrix.mat.scale_y * state->scissor.matrix.mat.scale_y + state->scissor.matrix.mat.skew_y * state->scissor.matrix.mat.skew_y);
|
||||
|
||||
NVGP_MEMCPY(&pxform, &state->scissor.matrix, sizeof(nvgp_matrix_t));
|
||||
ex = state->scissor.extent[0];
|
||||
ey = state->scissor.extent[1];
|
||||
nvgp_transform_inverse(&invxorm, &state->matrix);
|
||||
ex = state->scissor.extent[0] / scale_x;
|
||||
ey = state->scissor.extent[1] / scale_y;
|
||||
nvgp_transform_inverse(&invxorm, &scissor_state->matrix);
|
||||
nvgp_transform_multiply_to_t(&pxform, &invxorm);
|
||||
tex = ex * nvgp_abs(pxform.mat.scale_x) + ey * nvgp_abs(pxform.mat.skew_x);
|
||||
tey = ex * nvgp_abs(pxform.mat.skew_y) + ey * nvgp_abs(pxform.mat.scale_y);
|
||||
@ -1130,7 +1143,10 @@ nvgp_error_t nvgp_get_curr_clip_rect(nvgp_context_t* ctx, float* x, float* y, fl
|
||||
}
|
||||
|
||||
nvgp_error_t nvgp_intersect_scissor(nvgp_context_t* ctx, float* x, float* y, float* w, float* h) {
|
||||
float scale_x = 0.0f;
|
||||
float scale_y = 0.0f;
|
||||
nvgp_state_t* state = NULL;
|
||||
nvgp_state_t* scissor_state = NULL;
|
||||
CHECK_OBJECT_IS_NULL(ctx);
|
||||
state = nvgp_get_state(ctx);
|
||||
if (state != NULL) {
|
||||
@ -1143,13 +1159,19 @@ nvgp_error_t nvgp_intersect_scissor(nvgp_context_t* ctx, float* x, float* y, flo
|
||||
nvgp_scissor(ctx, *x, *y, *w, *h);
|
||||
return NVGP_OK;
|
||||
}
|
||||
|
||||
scissor_state = nvgp_get_state_by_index(ctx, state->scissor.state_index);
|
||||
scissor_state = scissor_state == NULL ? state : scissor_state;
|
||||
|
||||
scale_x = sqrtf(state->scissor.matrix.mat.scale_x * state->scissor.matrix.mat.scale_x + state->scissor.matrix.mat.skew_x * state->scissor.matrix.mat.skew_x);
|
||||
scale_y = sqrtf(state->scissor.matrix.mat.scale_y * state->scissor.matrix.mat.scale_y + state->scissor.matrix.mat.skew_y * state->scissor.matrix.mat.skew_y);
|
||||
|
||||
// Transform the current scissor rect into current transform space.
|
||||
// If there is difference in rotation, this will be approximation.
|
||||
NVGP_MEMCPY(&pxform, &state->scissor.matrix, sizeof(nvgp_matrix_t));
|
||||
ex = state->scissor.extent[0];
|
||||
ey = state->scissor.extent[1];
|
||||
nvgp_transform_inverse(&invxorm, &state->matrix);
|
||||
ex = state->scissor.extent[0] / scale_x;
|
||||
ey = state->scissor.extent[1] / scale_y;
|
||||
nvgp_transform_inverse(&invxorm, &scissor_state->matrix);
|
||||
nvgp_transform_multiply_to_t(&pxform, &invxorm);
|
||||
tex = ex * nvgp_abs(pxform.mat.scale_x) + ey * nvgp_abs(pxform.mat.skew_x);
|
||||
tey = ex * nvgp_abs(pxform.mat.skew_y) + ey * nvgp_abs(pxform.mat.scale_y);
|
||||
|
@ -138,6 +138,7 @@ typedef union _nvgp_matrix_t {
|
||||
} nvgp_matrix_t;
|
||||
|
||||
typedef struct _nvgp_scissor_t {
|
||||
int state_index;
|
||||
float extent[2];
|
||||
nvgp_matrix_t matrix;
|
||||
} nvgp_scissor_t;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
2025/04/27
|
||||
* 增加value_replace,用于避免value\ data的内存地址相同导致先reset后deep_copy出现野指针的问题(感谢兆坤提供补丁)。
|
||||
* 修复先设置裁剪区后再设置缩放导致获取裁剪区不正常的问题(感谢智明提供补丁)
|
||||
|
||||
2025/04/25
|
||||
* object有属性删除时发送EVT_PROPS_CHANGED事件(感谢兆坤提供补丁)。
|
||||
|
Loading…
x
Reference in New Issue
Block a user