void UpdateCache(ref CachedRenderString cache, string fontName, float size, string text, bool underline, TextAlignment alignment) { if (cache == null) { cache = new DirectWriteCachedText() { FontName = fontName, FontSize = size, Text = text, Underline = underline, Alignment = alignment }; } if (cache is not DirectWriteCachedText pc) { throw new ArgumentException("cache"); } if (pc.quads == null || pc.Update(fontName, text, size, underline, alignment)) { using (var layout = new TextLayout(dwFactory, text, GetFormat(fontName, ConvertSize(size)), float.MaxValue, float.MaxValue)) { layout.TextAlignment = CastAlignment(alignment); layout.SetDrawingEffect(new ColorDrawingEffect(Color4.White, new TextShadow()), new TextRange(0, text.Length)); layout.Draw(Renderer, 0, 0); pc.quads = Renderer.Quads.ToArray(); Renderer.Quads = new List <DrawQuad>(); var metrics = layout.Metrics; pc.size = new Point((int)metrics.WidthIncludingTrailingWhitespace, (int)metrics.Height); } } }
public override void DrawStringCached(ref CachedRenderString cache, string fontName, float size, string text, float x, float y, Color4 color, bool underline = false, TextShadow shadow = default, TextAlignment alignment = TextAlignment.Left) { UpdateCache(ref cache, fontName, size, text, underline, alignment); var pc = (PangoRenderCache)cache; drawX = (int)x; drawY = (int)y; if (shadow.Enabled) { for (int i = 0; i < pc.quads.Length; i++) { var q = pc.quads[i]; q.Dest.X += drawX + 2; q.Dest.Y += drawY + 2; var t = textures[(int)q.Texture->UserData]; ren.Draw(t, q.Source, q.Dest, shadow.Color); } } for (int i = 0; i < pc.quads.Length; i++) { var q = pc.quads[i]; q.Dest.X += drawX; q.Dest.Y += drawY; var t = textures[(int)q.Texture->UserData]; ren.Draw(t, q.Source, q.Dest, color); } }
void UpdateCache(ref CachedRenderString cache, string fontName, float size, string text, bool underline, TextAlignment alignment) { if (cache == null) { cache = new PangoRenderCache() { FontName = fontName, FontSize = size, Text = text, Underline = underline, Alignment = alignment }; } if (cache is not PangoRenderCache pc) { throw new ArgumentException("cache"); } if (pc.quads == null || pc.Update(fontName, text, size, underline, alignment)) { var pixels = size * (96.0f / 72.0f); drawX = int.MaxValue; drawY = int.MaxValue; using var textConv = new UTF8ZHelper(stackalloc byte[256], text); using var fontConv = new UTF8ZHelper(stackalloc byte[256], fontName); float szX, szY; fixed(byte *tC = &textConv.ToUTF8Z().GetPinnableReference(), tF = &fontConv.ToUTF8Z().GetPinnableReference()) { pg_drawstring(ctx, (IntPtr)tC, (IntPtr)tF, pixels, alignment, underline ? 1 : 0, 1, 1, 1, 1, (Color4 *)0, &szX, &szY); } pc.quads = lastQuads; pc.size = new Point((int)szX, (int)szY); lastQuads = null; } }
public override Point MeasureStringCached(ref CachedRenderString cache, string fontName, float size, string text, bool underline, TextAlignment alignment) { UpdateCache(ref cache, fontName, size, text, underline, alignment); var pc = (PangoRenderCache)cache; return(pc.size); }
public override Point MeasureStringCached(ref CachedRenderString cache, string fontName, float size, string text, bool underline, TextAlignment alignment) { if (string.IsNullOrEmpty(text)) { return(Point.Zero); } UpdateCache(ref cache, fontName, size, text, underline, alignment); return(((DirectWriteCachedText)cache).size); }
public override void DrawStringCached(ref CachedRenderString cache, string fontName, float size, string text, float x, float y, Color4 color, bool underline = false, TextShadow shadow = default, TextAlignment alignment = TextAlignment.Left) { if (string.IsNullOrEmpty(text)) { return; } UpdateCache(ref cache, fontName, size, text, underline, alignment); var pc = (DirectWriteCachedText)cache; if (shadow.Enabled) { foreach (var q in pc.quads) { var d = q.Destination; d.X += (int)x + 2; d.Y += (int)y + 2; if (q.Texture == null) { render2d.FillRectangle(d, shadow.Color); } else { render2d.Draw(q.Texture, q.Source, d, shadow.Color); } } } foreach (var q in pc.quads) { var d = q.Destination; d.X += (int)x; d.Y += (int)y; if (q.Texture == null) { render2d.FillRectangle(d, color); } else { render2d.Draw(q.Texture, q.Source, d, color); } } }
protected void DrawText( UiContext context, ref CachedRenderString cache, RectangleF myRectangle, float textSize, string font, InterfaceColor textColor, InterfaceColor shadowColor, HorizontalAlignment horizontalAlign, VerticalAlignment verticalAlign, bool clip, string text ) { if (string.IsNullOrEmpty(text)) { return; } if (myRectangle.Width <= 1 || myRectangle.Height <= 1) { return; } if (string.IsNullOrEmpty(font)) { font = "$Normal"; } if (textSize <= 0) { textSize = 10; } var color = (textColor ?? InterfaceColor.White).GetColor(context.GlobalTime); if (color.A < float.Epsilon) { return; } var fnt = context.Data.GetFont(font); var size = context.TextSize(textSize); var lineHeight = context.RenderContext.Renderer2D.LineHeight(fnt, size); var drawRect = context.PointsToPixels(myRectangle); var sz = context.RenderContext.Renderer2D.MeasureStringCached(ref cache, fnt, size, text, false, CastAlign(horizontalAlign)); //workaround for font substitution causing layout issues - e.g. CJK //TODO: How to get max lineheight of fonts in string? if (sz.Y > lineHeight && sz.Y < (lineHeight * 2)) { lineHeight = sz.Y; } float drawX, drawY; switch (horizontalAlign) { case HorizontalAlignment.Left: drawX = drawRect.X; break; case HorizontalAlignment.Right: { drawX = drawRect.X + drawRect.Width - sz.X; break; } default: // Center { drawX = drawRect.X + (drawRect.Width / 2f) - (sz.X / 2f); break; } } switch (verticalAlign) { case VerticalAlignment.Top: drawY = drawRect.Y; break; case VerticalAlignment.Bottom: drawY = drawRect.Y + drawRect.Height - lineHeight; break; default: //Center drawY = drawRect.Y + (drawRect.Height / 2) - lineHeight / 2; break; } var shadow = new TextShadow(); if (shadowColor != null) { shadow = new TextShadow(shadowColor.Color); } if (clip) { context.RenderContext.ScissorEnabled = true; context.RenderContext.ScissorRectangle = drawRect; } context.RenderContext.Renderer2D.DrawStringCached(ref cache, fnt, size, text, drawX, drawY, color, false, shadow, CastAlign(horizontalAlign)); if (clip) { context.RenderContext.ScissorEnabled = false; } }