/// <summary> /// Draws text string at specified location. Only the sub-string up to the end is drawn. /// </summary> public static float Text(this Nvg nvg, Vector2D <float> pos, string @string, string end) { Fontstash fons = nvg.fontManager.Fontstash; State state = nvg.stateStack.CurrentState; FonsQuad q = new(); float scale = nvg.fontManager.GetFontScale() * nvg.pixelRatio.DevicePxRatio; float invscale = 1.0f / scale; bool isFlipped = Maths.IsTransformFlipped(state.Transform); if (state.FontId == Fontstash.INVALID) { return(pos.X); } fons.SetSize(state.FontSize * scale); fons.SetSpacing(state.LetterSpacing * scale); fons.SetBlur(state.FontBlur * scale); fons.SetAlign((int)state.TextAlign); fons.SetFont(state.FontId); List <Vertex> vertices = new(); fons.TextIterInit(out FonsTextIter iter, pos.X * scale, pos.Y * scale, @string, end, FonsGlyphBitmap.Requiered); FonsTextIter prevIter = iter; while (fons.TextIterNext(ref iter, ref q)) { Vector2D <float>[] c = new Vector2D <float> [4]; if (iter.prevGlyphIndex == -1) { if (vertices.Count != 0) { nvg.fontManager.RenderText(vertices); vertices.Clear(); } if (!nvg.fontManager.AllocTextAtlas()) // no memory { break; } iter = prevIter; _ = fons.TextIterNext(ref iter, ref q); if (iter.prevGlyphIndex == -1) { break; } } prevIter = iter; if (isFlipped) { float tmp = q.y0; q.y0 = q.y1; q.y1 = tmp; tmp = q.t0; q.t0 = q.t1; q.t1 = tmp; } c[0] = nvg.TransformPoint(state.Transform, q.x0 * invscale, q.y0 * invscale); c[1] = nvg.TransformPoint(state.Transform, q.x1 * invscale, q.y0 * invscale); c[2] = nvg.TransformPoint(state.Transform, q.x1 * invscale, q.y1 * invscale); c[3] = nvg.TransformPoint(state.Transform, q.x0 * invscale, q.y1 * invscale); vertices.Add(new Vertex(c[0], q.s0, q.t0)); vertices.Add(new Vertex(c[2], q.s1, q.t1)); vertices.Add(new Vertex(c[1], q.s1, q.t0)); vertices.Add(new Vertex(c[0], q.s0, q.t0)); vertices.Add(new Vertex(c[3], q.s0, q.t1)); vertices.Add(new Vertex(c[2], q.s1, q.t1)); } nvg.fontManager.FlushTextTexture(); nvg.fontManager.RenderText(vertices); return(iter.nextx / scale); }