diff --git a/example/demo.c b/example/demo.c index d5632ce..d3d6620 100644 --- a/example/demo.c +++ b/example/demo.c @@ -827,11 +827,6 @@ void drawParagraph(struct NVGcontext* vg, float x, float y, float width, float h nvgTextAlign(vg, NVG_ALIGN_LEFT|NVG_ALIGN_TOP); nvgTextMetrics(vg, NULL, NULL, &lineh); -/* nvgBeginPath(vg); - nvgFillColor(vg, nvgRGBA(255,255,0,128)); - nvgRect(vg, x, y, width, height); - nvgFill(vg);*/ - // The text break API can be used to fill a large buffer of rows, // or to iterate over the text just few lines (or just one) at a time. // The "next" variable of the last returned item tells where to continue. @@ -857,14 +852,14 @@ void drawParagraph(struct NVGcontext* vg, float x, float y, float width, float h for (j = 0; j < nglyphs; j++) { float x0 = glyphs[j].x; float x1 = (j+1 < nglyphs) ? glyphs[j+1].x : x+row->width; - float gx = (x0 + x1)/2; - if (mx > px && mx <= gx) + float gx = x0 * 0.3f + x1 * 0.7f; + if (mx >= px && mx < gx) caretx = glyphs[j].x; px = gx; } nvgBeginPath(vg); nvgFillColor(vg, nvgRGBA(255,192,0,255)); - nvgRect(vg, caretx, y, 2, lineh); + nvgRect(vg, caretx, y, 1, lineh); nvgFill(vg); } y += lineh; diff --git a/example/perf.c b/example/perf.c index 9b0780f..bf36a61 100644 --- a/example/perf.c +++ b/example/perf.c @@ -17,25 +17,26 @@ // timer query support #ifndef GL_ARB_timer_query #define GL_TIME_ELAPSED 0x88BF -typedef void (APIENTRY *pfnGLGETQUERYOBJECTUI64V)(GLuint id, GLenum pname, GLuint64* params); -pfnGLGETQUERYOBJECTUI64V glGetQueryObjectui64v = 0; +//typedef void (APIENTRY *pfnGLGETQUERYOBJECTUI64V)(GLuint id, GLenum pname, GLuint64* params); +//pfnGLGETQUERYOBJECTUI64V glGetQueryObjectui64v = 0; #endif void initGPUTimer(struct GPUtimer* timer) { memset(timer, 0, sizeof(*timer)); - timer->supported = glfwExtensionSupported("GL_ARB_timer_query"); +/* timer->supported = glfwExtensionSupported("GL_ARB_timer_query"); if (timer->supported) { #ifndef GL_ARB_timer_query glGetQueryObjectui64v = (pfnGLGETQUERYOBJECTUI64V)glfwGetProcAddress("glGetQueryObjectui64v"); + printf("glGetQueryObjectui64v=%p\n", glGetQueryObjectui64v); if (!glGetQueryObjectui64v) { timer->supported = GL_FALSE; return; } #endif glGenQueries(GPU_QUERY_COUNT, timer->queries); - } + }*/ } void startGPUTimer(struct GPUtimer* timer) @@ -58,13 +59,13 @@ int stopGPUTimer(struct GPUtimer* timer, float* times, int maxTimes) // check for results if there are any glGetQueryObjectiv(timer->queries[timer->ret % GPU_QUERY_COUNT], GL_QUERY_RESULT_AVAILABLE, &available); if (available) { - GLuint64 timeElapsed = 0; +/* GLuint64 timeElapsed = 0; glGetQueryObjectui64v(timer->queries[timer->ret % GPU_QUERY_COUNT], GL_QUERY_RESULT, &timeElapsed); timer->ret++; if (n < maxTimes) { times[n] = (float)((double)timeElapsed * 1e-9); n++; - } + }*/ } } return n; diff --git a/src/nanovg.c b/src/nanovg.c index f49b79e..d02baf7 100644 --- a/src/nanovg.c +++ b/src/nanovg.c @@ -1304,7 +1304,6 @@ static int nvg__expandStrokeAndFill(struct NVGcontext* ctx, int feats, float w, float wo = 0, iw = 0, aa = ctx->fringeWidth; int ncap = nvg__curveDivs(w, NVG_PI, ctx->tessTol / 4.0f); int nleft = 0; - struct NVGstate* state = nvg__getState(ctx); if (w > 0.0f) iw = 1.0f / w; @@ -1791,7 +1790,6 @@ void nvgCircle(struct NVGcontext* ctx, float cx, float cy, float r) void nvgDebugDumpPathCache(struct NVGcontext* ctx) { - struct NVGstate* state = nvg__getState(ctx); const struct NVGpath* path; int i, j; @@ -2038,6 +2036,8 @@ void nvgTextBox(struct NVGcontext* ctx, float x, float y, float width, const cha int nvgTextGlyphPositions(struct NVGcontext* ctx, const char* string, const char* end, float x, float y, struct NVGglyphPosition* positions, int maxPositions) { struct NVGstate* state = nvg__getState(ctx); + float scale = nvg__getFontScale(state) * ctx->devicePxRatio; + float invscale = 1.0f / scale; struct FONStextIter iter; struct FONSquad q; int npos = 0; @@ -2051,19 +2051,17 @@ int nvgTextGlyphPositions(struct NVGcontext* ctx, const char* string, const char if (string == end) return 0; - // TODO: should use scaled text to better match with rendering. - - fonsSetSize(ctx->fs, state->fontSize); - fonsSetSpacing(ctx->fs, state->letterSpacing); - fonsSetBlur(ctx->fs, state->fontBlur); + fonsSetSize(ctx->fs, state->fontSize*scale); + fonsSetSpacing(ctx->fs, state->letterSpacing*scale); + fonsSetBlur(ctx->fs, state->fontBlur*scale); fonsSetAlign(ctx->fs, state->textAlign); fonsSetFont(ctx->fs, state->fontId); - px = x; - fonsTextIterInit(ctx->fs, &iter, x, y, string, end); + px = x*scale; + fonsTextIterInit(ctx->fs, &iter, x*scale, y*scale, string, end); while (fonsTextIterNext(ctx->fs, &iter, &q)) { positions[npos].str = iter.str; - positions[npos].x = px; + positions[npos].x = px * invscale; px = iter.x; npos++; if (npos >= maxPositions) @@ -2082,6 +2080,8 @@ enum NVGcodepointType { int nvgTextBreakLines(struct NVGcontext* ctx, const char* string, const char* end, float maxRowWidth, struct NVGtextRow* rows, int maxRows) { struct NVGstate* state = nvg__getState(ctx); + float scale = nvg__getFontScale(state) * ctx->devicePxRatio; + float invscale = 1.0f / scale; struct FONStextIter iter; struct FONSquad q; int nrows = 0; @@ -2104,14 +2104,14 @@ int nvgTextBreakLines(struct NVGcontext* ctx, const char* string, const char* en if (string == end) return 0; - // TODO: should use scaled text to better match with rendering. - - fonsSetSize(ctx->fs, state->fontSize); - fonsSetSpacing(ctx->fs, state->letterSpacing); - fonsSetBlur(ctx->fs, state->fontBlur); + fonsSetSize(ctx->fs, state->fontSize*scale); + fonsSetSpacing(ctx->fs, state->letterSpacing*scale); + fonsSetBlur(ctx->fs, state->fontBlur*scale); fonsSetAlign(ctx->fs, state->textAlign); fonsSetFont(ctx->fs, state->fontId); + maxRowWidth *= scale; + fonsTextIterInit(ctx->fs, &iter, 0, 0, string, end); while (fonsTextIterNext(ctx->fs, &iter, &q)) { switch (iter.codepoint) { @@ -2140,7 +2140,7 @@ int nvgTextBreakLines(struct NVGcontext* ctx, const char* string, const char* en // Always handle new lines. rows[nrows].start = rowStart != NULL ? rowStart : iter.str; rows[nrows].end = rowEnd != NULL ? rowEnd : iter.str; - rows[nrows].width = rowWidth; + rows[nrows].width = rowWidth * invscale; rows[nrows].next = iter.next; nrows++; if (nrows >= maxRows) @@ -2173,7 +2173,7 @@ int nvgTextBreakLines(struct NVGcontext* ctx, const char* string, const char* en // The current word is longer than the row length, just break it from here. rows[nrows].start = rowStart; rows[nrows].end = iter.str; - rows[nrows].width = rowWidth; + rows[nrows].width = rowWidth * invscale; rows[nrows].next = iter.str; nrows++; if (nrows >= maxRows) @@ -2188,7 +2188,7 @@ int nvgTextBreakLines(struct NVGcontext* ctx, const char* string, const char* en // Break the line from the end of the last word, and start new line from the begining of the new. rows[nrows].start = rowStart; rows[nrows].end = breakEnd; - rows[nrows].width = breakWidth; + rows[nrows].width = breakWidth * invscale; rows[nrows].next = wordStart; nrows++; if (nrows >= maxRows) @@ -2230,7 +2230,7 @@ int nvgTextBreakLines(struct NVGcontext* ctx, const char* string, const char* en if (rowStart != NULL) { rows[nrows].start = rowStart; rows[nrows].end = rowEnd; - rows[nrows].width = rowWidth; + rows[nrows].width = rowWidth * invscale; rows[nrows].next = end; nrows++; } @@ -2241,33 +2241,47 @@ int nvgTextBreakLines(struct NVGcontext* ctx, const char* string, const char* en float nvgTextBounds(struct NVGcontext* ctx, const char* string, const char* end, float* bounds) { struct NVGstate* state = nvg__getState(ctx); + float scale = nvg__getFontScale(state) * ctx->devicePxRatio; + float invscale = 1.0f / scale; + float width; if (state->fontId == FONS_INVALID) return 0; - // TODO: should use scaled text to better match with rendering. - - fonsSetSize(ctx->fs, state->fontSize); - fonsSetSpacing(ctx->fs, state->letterSpacing); - fonsSetBlur(ctx->fs, state->fontBlur); + fonsSetSize(ctx->fs, state->fontSize*scale); + fonsSetSpacing(ctx->fs, state->letterSpacing*scale); + fonsSetBlur(ctx->fs, state->fontBlur*scale); fonsSetAlign(ctx->fs, state->textAlign); fonsSetFont(ctx->fs, state->fontId); - return fonsTextBounds(ctx->fs, string, end, bounds); + width = fonsTextBounds(ctx->fs, string, end, bounds); + if (bounds != NULL) { + bounds[0] *= invscale; + bounds[1] *= invscale; + bounds[2] *= invscale; + bounds[3] *= invscale; + } + return width * invscale; } void nvgTextMetrics(struct NVGcontext* ctx, float* ascender, float* descender, float* lineh) { struct NVGstate* state = nvg__getState(ctx); + float scale = nvg__getFontScale(state) * ctx->devicePxRatio; + float invscale = 1.0f / scale; if (state->fontId == FONS_INVALID) return; - // TODO: should use scaled text to better match with rendering. - - fonsSetSize(ctx->fs, state->fontSize); - fonsSetSpacing(ctx->fs, state->letterSpacing); - fonsSetBlur(ctx->fs, state->fontBlur); + fonsSetSize(ctx->fs, state->fontSize*scale); + fonsSetSpacing(ctx->fs, state->letterSpacing*scale); + fonsSetBlur(ctx->fs, state->fontBlur*scale); fonsSetAlign(ctx->fs, state->textAlign); fonsSetFont(ctx->fs, state->fontId); fonsVertMetrics(ctx->fs, ascender, descender, lineh); + if (ascender != NULL) + *ascender *= invscale; + if (descender != NULL) + *descender *= invscale; + if (lineh != NULL) + *lineh *= invscale; }