private static StaticSpriteFont FromBMFont(BitmapFont bmFont, Func <string, TextureWithOffset> textureGetter) { var result = new StaticSpriteFont(bmFont.LineHeight, bmFont.LineHeight); var characters = bmFont.Characters.Values.OrderBy(c => c.Char); foreach (var ch in characters) { var texture = textureGetter(bmFont.Pages[ch.TexturePage].FileName); var bounds = new Rectangle(ch.X, ch.Y, ch.Width, ch.Height); bounds.Offset(texture.Offset); var glyph = new FontGlyph { Id = ch.Char, Codepoint = ch.Char, Bounds = bounds, XOffset = ch.XOffset, YOffset = ch.YOffset, XAdvance = ch.XAdvance, Texture = texture.Texture }; result.Glyphs[glyph.Codepoint] = glyph; } foreach (var kern in bmFont.Kernings) { result.SetGlyphKernAdvance(kern.Key.FirstCharacter, kern.Key.SecondCharacter, kern.Value); } return(result); }
internal void RenderGlyphOnAtlas(FontGlyph glyph) { var currentAtlas = CurrentAtlas; int gx = 0, gy = 0; var gw = glyph.Bounds.Width; var gh = glyph.Bounds.Height; if (!currentAtlas.AddRect(gw, gh, ref gx, ref gy)) { CurrentAtlasFull?.Invoke(this, EventArgs.Empty); // This code will force creation of new atlas _currentAtlas = null; currentAtlas = CurrentAtlas; // Try to add again if (!currentAtlas.AddRect(gw, gh, ref gx, ref gy)) { throw new Exception(string.Format("Could not add rect to the newly created atlas. gw={0}, gh={1}", gw, gh)); } } glyph.Bounds.X = gx; glyph.Bounds.Y = gy; currentAtlas.RenderGlyph(_textureCreator, glyph, BlurAmount, StrokeAmount, PremultiplyAlpha); glyph.Atlas = currentAtlas; }
private void GetQuad(FontGlyph glyph, FontGlyph prevGlyph, float spacing, ref float x, ref float y, ref FontGlyphSquad q) { if (prevGlyph != null) { float adv = 0; if (UseKernings && glyph.Font == prevGlyph.Font) { adv = prevGlyph.GetKerning(glyph) * glyph.Font.Scale; } x += (int)(adv + spacing + 0.5f); } float rx = x + glyph.XOffset; float ry = y + glyph.YOffset; q.X0 = rx; q.Y0 = ry; q.X1 = rx + glyph.Bounds.Width; q.Y1 = ry + glyph.Bounds.Height; q.S0 = glyph.Bounds.X * _itw; q.T0 = glyph.Bounds.Y * _ith; q.S1 = glyph.Bounds.Right * _itw; q.T1 = glyph.Bounds.Bottom * _ith; x += (int)(glyph.XAdvance / 10.0f + 0.5f); }
private void GetQuad(FontGlyph glyph, FontGlyph prevGlyph, Vector2 scale, ref float x, ref float y, ref FontGlyphSquad q) { if (prevGlyph != null) { float adv = 0; if (FontSystem.UseKernings && glyph.Font == prevGlyph.Font) { adv = prevGlyph.Font.GetGlyphKernAdvance(prevGlyph.Id, glyph.Id, glyph.Size); } x += (int)(adv + FontSystem.CharacterSpacing + 0.5f); } float rx = x + glyph.XOffset; float ry = y + glyph.YOffset; q.X0 = rx * scale.X; q.Y0 = ry * scale.Y; q.X1 = (rx + glyph.Bounds.Width) * scale.X; q.Y1 = (ry + glyph.Bounds.Height) * scale.Y; q.S0 = glyph.Bounds.X; q.T0 = glyph.Bounds.Y; q.S1 = glyph.Bounds.Right; q.T1 = glyph.Bounds.Bottom; x += glyph.XAdvance; }
public float DrawText(IFontStashRenderer batch, float x, float y, StringBuilder str, Color[] glyphColors, Vector2 scale, float depth = 0.0f) { if (str == null || str.Length == 0) { return(0.0f); } float ascent, lineHeight; PreDraw(str, out ascent, out lineHeight); float originX = 0.0f; float originY = 0.0f; originY += ascent; FontGlyph prevGlyph = null; var pos = 0; var q = new FontGlyphSquad(); for (int i = 0; i < str.Length; i += StringBuilderIsSurrogatePair(str, i) ? 2 : 1) { var codepoint = StringBuilderConvertToUtf32(str, i); if (codepoint == '\n') { originX = 0.0f; originY += lineHeight; prevGlyph = null; ++pos; continue; } var glyph = GetGlyph(codepoint, false); if (glyph == null) { ++pos; continue; } GetQuad(glyph, prevGlyph, scale, ref originX, ref originY, ref q); if (!glyph.IsEmpty) { var destRect = new Rectangle((int)(x + q.X0), (int)(y + q.Y0), (int)(q.X1 - q.X0), (int)(q.Y1 - q.Y0)); var sourceRect = new Rectangle((int)q.S0, (int)q.T0, (int)(q.S1 - q.S0), (int)(q.T1 - q.T0)); batch.Draw(glyph.Atlas.Texture, destRect, sourceRect, glyphColors[pos], depth); } prevGlyph = glyph; ++pos; } return(x); }
/// <summary> /// Draws a text /// </summary> /// <param name="renderer">A renderer.</param> /// <param name="text">The text which will be drawn.</param> /// <param name="position">The drawing location on screen.</param> /// <param name="color">A color mask.</param> /// <param name="rotation">A rotation of this text in radians.</param> /// <param name="origin">Center of the rotation.</param> /// <param name="scale">A scaling of this text.</param> /// <param name="layerDepth">A depth of the layer of this string.</param> public float DrawText(IFontStashRenderer renderer, StringBuilder text, Vector2 position, Color color, Vector2 scale, float rotation, Vector2 origin, float layerDepth = 0.0f) { if (text == null || text.Length == 0) { return(0.0f); } float ascent, lineHeight; PreDraw(text, out ascent, out lineHeight); float originX = 0.0f; float originY = 0.0f; originY += ascent; FontGlyph prevGlyph = null; var q = new FontGlyphSquad(); for (int i = 0; i < text.Length; i += StringBuilderIsSurrogatePair(text, i) ? 2 : 1) { var codepoint = StringBuilderConvertToUtf32(text, i); if (codepoint == '\n') { originX = 0.0f; originY += lineHeight; prevGlyph = null; continue; } var glyph = GetGlyph(codepoint, false); if (glyph == null) { continue; } GetQuad(glyph, prevGlyph, scale, ref originX, ref originY, ref q); if (!glyph.IsEmpty) { var sourceRect = new Rectangle((int)q.S0, (int)q.T0, (int)(q.S1 - q.S0), (int)(q.T1 - q.T0)); renderer.Draw(glyph.Texture, position, sourceRect, color, rotation, origin - q.Offset, scale, layerDepth); } prevGlyph = glyph; } return(position.X); }
public List <Rectangle> GetGlyphRects(StringBuilder str, Vector2 position, Vector2 scale) { List <Rectangle> Rects = new List <Rectangle>(); if (str == null || str.Length == 0) { return(Rects); } int ascent, lineHeight; PreDraw(str, out ascent, out lineHeight); var q = new FontGlyphSquad(); var x = position.X; var y = position.Y; y += ascent; float minx, maxx, miny, maxy; minx = maxx = x; miny = maxy = y; float startx = x; FontGlyph prevGlyph = null; for (int i = 0; i < str.Length; i += StringBuilderIsSurrogatePair(str, i) ? 2 : 1) { var codepoint = StringBuilderConvertToUtf32(str, i); if (codepoint == '\n') { x = startx; y += lineHeight; prevGlyph = null; continue; } var glyph = GetGlyph(null, codepoint); if (glyph == null) { continue; } GetQuad(glyph, prevGlyph, ref x, y, ref q); var rect = ApplyScale(new Rectangle((int)q.X0, (int)q.Y0, (int)(q.X1 - q.X0), (int)(q.Y1 - q.Y0)), scale); Rects.Add(rect); prevGlyph = glyph; } return(Rects); }
public int GetKerning(FontGlyph nextGlyph) { if (_kernings.TryGetValue(nextGlyph.Index, out int result)) { return(result); } result = Font._font.stbtt_GetGlyphKernAdvance(Index, nextGlyph.Index); _kernings[nextGlyph.Index] = result; return(result); }
public List <Rectangle> GetGlyphRects(string str, Vector2 position, Vector2 scale) { List <Rectangle> Rects = new List <Rectangle>(); if (string.IsNullOrEmpty(str)) { return(Rects); } scale /= RenderFontSizeMultiplicator; int ascent, lineHeight; PreDraw(str, out ascent, out lineHeight); var q = new FontGlyphSquad(); var x = position.X; var y = position.Y; y += ascent * scale.Y; float startx = x; FontGlyph prevGlyph = null; for (int i = 0; i < str.Length; i += char.IsSurrogatePair(str, i) ? 2 : 1) { var codepoint = char.ConvertToUtf32(str, i); if (codepoint == '\n') { x = startx; y += lineHeight; prevGlyph = null; continue; } var glyph = GetGlyph(null, codepoint); if (glyph == null) { continue; } GetQuad(glyph, prevGlyph, ref x, y, ref q); var rect = ApplyScale(new Rectangle((int)q.X0, (int)q.Y0, (int)(q.X1 - q.X0), (int)(q.Y1 - q.Y0)), scale); Rects.Add(rect); prevGlyph = glyph; } return(Rects); }
public List <Rectangle> GetGlyphRects(float x, float y, StringBuilder str) { List <Rectangle> Rects = new List <Rectangle>(); if (str == null || str.Length == 0) { return(Rects); } Dictionary <int, FontGlyph> glyphs; float ascent, lineHeight; PreDraw(str, out glyphs, out ascent, out lineHeight); var q = new FontGlyphSquad(); y += ascent; float minx, maxx, miny, maxy; minx = maxx = x; miny = maxy = y; float startx = x; FontGlyph prevGlyph = null; for (int i = 0; i < str.Length; i += StringBuilderIsSurrogatePair(str, i) ? 2 : 1) { var codepoint = StringBuilderConvertToUtf32(str, i); if (codepoint == '\n') { x = startx; y += lineHeight; prevGlyph = null; continue; } var glyph = GetGlyph(null, glyphs, codepoint); if (glyph == null) { continue; } GetQuad(glyph, prevGlyph, Spacing, ref x, ref y, ref q); Rects.Add(new Rectangle((int)q.X0, (int)q.Y0, (int)(q.X1 - q.X0), (int)(q.Y1 - q.Y0))); prevGlyph = glyph; } return(Rects); }
public int GetKerning(FontGlyph nextGlyph) { int result; if (_kernings.TryGetValue(nextGlyph.Index, out result)) { return(result); } result = StbTrueTypeSharp.StbTrueType.stbtt_GetGlyphKernAdvance(Font._font, Index, nextGlyph.Index); _kernings[nextGlyph.Index] = result; return(result); }
internal override void GetQuad(FontGlyph glyph, FontGlyph prevGlyph, ref float x, float y, ref FontGlyphSquad q) { if (prevGlyph != null) { if (UseKernings) { x += GetGlyphKernAdvance(prevGlyph.Codepoint, glyph.Codepoint); } x += CharacterSpacing; } base.GetQuad(glyph, prevGlyph, ref x, y, ref q); }
public List <Rectangle> GetGlyphRects(float x, float y, string str, Vector2 scale) { List <Rectangle> Rects = new List <Rectangle>(); if (string.IsNullOrEmpty(str)) { return(Rects); } float ascent, lineHeight; PreDraw(str, out ascent, out lineHeight); var q = new FontGlyphSquad(); y += ascent; float startx = x; FontGlyph prevGlyph = null; for (int i = 0; i < str.Length; i += char.IsSurrogatePair(str, i) ? 2 : 1) { var codepoint = char.ConvertToUtf32(str, i); if (codepoint == '\n') { x = startx; y += lineHeight; prevGlyph = null; continue; } var glyph = GetGlyph(codepoint, true); if (glyph == null) { continue; } GetQuad(glyph, prevGlyph, scale, ref x, ref y, ref q); Rects.Add(new Rectangle((int)q.X0, (int)q.Y0, (int)(q.X1 - q.X0), (int)(q.Y1 - q.Y0))); prevGlyph = glyph; } return(Rects); }
internal virtual void GetQuad(FontGlyph glyph, FontGlyph prevGlyph, Vector2 scale, ref float x, ref float y, ref FontGlyphSquad q) { float rx = x + glyph.XOffset; float ry = y + glyph.YOffset; q.X0 = rx * scale.X; q.Y0 = ry * scale.Y; q.X1 = (rx + glyph.Bounds.Width) * scale.X; q.Y1 = (ry + glyph.Bounds.Height) * scale.Y; q.S0 = glyph.Bounds.X; q.T0 = glyph.Bounds.Y; q.S1 = glyph.Bounds.Right; q.T1 = glyph.Bounds.Bottom; q.Offset = new Vector2(rx, ry); x += glyph.XAdvance; }
private void GetQuad(Font font, int prevGlyphIndex, FontGlyph glyph, float scale, float spacing, ref float x, ref float y, FontGlyphSquad *q) { if (prevGlyphIndex != -1) { float adv = 0; if (UseKernings) { adv = font.GetKerning(prevGlyphIndex, glyph.Index) * scale; } x += (int)(adv + spacing + 0.5f); } float rx = 0; float ry = 0; if (_params_.IsAlignmentTopLeft) { rx = x + glyph.XOffset; ry = y + glyph.YOffset; q->X0 = rx; q->Y0 = ry; q->X1 = rx + (glyph.X1 - glyph.X0); q->Y1 = ry + (glyph.Y1 - glyph.Y0); q->S0 = glyph.X0 * _itw; q->T0 = glyph.Y0 * _ith; q->S1 = glyph.X1 * _itw; q->T1 = glyph.Y1 * _ith; } else { rx = x + glyph.XOffset; ry = y - glyph.YOffset; q->X0 = rx; q->Y0 = ry; q->X1 = rx + (glyph.X1 - glyph.X0); q->Y1 = ry - (glyph.Y1 + glyph.Y0); q->S0 = glyph.X0 * _itw; q->T0 = glyph.Y0 * _ith; q->S1 = glyph.X1 * _itw; q->T1 = glyph.Y1 * _ith; } x += (int)(glyph.XAdvance / 10.0f + 0.5f); }
internal override void GetQuad(FontGlyph glyph, FontGlyph prevGlyph, Vector2 scale, ref float x, ref float y, ref FontGlyphSquad q) { if (prevGlyph != null) { float adv = 0; var dynamicGlyph = (DynamicFontGlyph)glyph; var dynamicPrevGlyph = (DynamicFontGlyph)prevGlyph; if (FontSystem.UseKernings && dynamicGlyph.Font == dynamicPrevGlyph.Font) { adv = dynamicPrevGlyph.Font.GetGlyphKernAdvance(prevGlyph.Id, dynamicGlyph.Id, dynamicGlyph.Size); } x += (int)(adv + FontSystem.CharacterSpacing + 0.5f); } base.GetQuad(glyph, prevGlyph, scale, ref x, ref y, ref q); }
private FontGlyph GetGlyphWithoutBitmap(Dictionary <int, FontGlyph> glyphs, int codepoint) { FontGlyph glyph = null; if (glyphs.TryGetValue(codepoint, out glyph)) { return(glyph); } Font font; var g = GetCodepointIndex(codepoint, out font); if (g == 0) { return(null); } int advance = 0, lsb = 0, x0 = 0, y0 = 0, x1 = 0, y1 = 0; font.BuildGlyphBitmap(g, FontSize, font.Scale, ref advance, ref lsb, ref x0, ref y0, ref x1, ref y1); var pad = FontGlyph.PadFromBlur(Blur); var gw = x1 - x0 + pad * 2; var gh = y1 - y0 + pad * 2; glyph = new FontGlyph { Font = font, Codepoint = codepoint, Size = FontSize, Blur = Blur, Index = g, Bounds = new Rectangle(0, 0, gw, gh), XAdvance = (int)(font.Scale * advance * 10.0f), XOffset = x0 - pad, YOffset = y0 - pad }; glyphs[codepoint] = glyph; return(glyph); }
private FontGlyph GetGlyphWithoutBitmap(int codepoint) { FontGlyph glyph = null; if (_glyphs.TryGetValue(codepoint, out glyph)) { return(glyph); } IFontSource font; var g = FontSystem.GetCodepointIndex(codepoint, out font); if (g == null) { return(null); } int advance = 0, x0 = 0, y0 = 0, x1 = 0, y1 = 0; font.GetGlyphMetrics(g.Value, FontSize, out advance, out x0, out y0, out x1, out y1); var pad = Math.Max(FontGlyph.PadFromBlur(FontSystem.BlurAmount), FontGlyph.PadFromBlur(FontSystem.StrokeAmount)); var gw = x1 - x0 + pad * 2; var gh = y1 - y0 + pad * 2; var offset = FontGlyph.PadFromBlur(FontSystem.BlurAmount); glyph = new FontGlyph { Codepoint = codepoint, Id = g.Value, Size = FontSize, Font = font, Bounds = new Rectangle(0, 0, gw, gh), XAdvance = advance, XOffset = x0 - offset, YOffset = y0 - offset }; _glyphs[codepoint] = glyph; return(glyph); }
FontGlyph GetGlyphWithoutBitmap(GlyphCollection collection, int codepoint) { FontGlyph glyph = null; if (collection.Glyphs.TryGetValue(codepoint, out glyph)) { return(glyph); } Font font; var g = GetCodepointIndex(codepoint, out font); if (g == 0) { return(null); } int advance = 0, lsb = 0, x0 = 0, y0 = 0, x1 = 0, y1 = 0; font.BuildGlyphBitmap(g, font.Scale, ref advance, ref lsb, ref x0, ref y0, ref x1, ref y1); var pad = Math.Max(FontGlyph.PadFromBlur(BlurAmount), FontGlyph.PadFromBlur(StrokeAmount)); var gw = x1 - x0 + pad * 2; var gh = y1 - y0 + pad * 2; var offset = FontGlyph.PadFromBlur(BlurAmount); glyph = new FontGlyph { Font = font, Codepoint = codepoint, Size = FontSize, Index = g, Bounds = new Rectangle(0, 0, gw, gh), XAdvance = (int)(font.Scale * advance * 10.0f), XOffset = x0 - offset, YOffset = y0 - offset }; collection.Glyphs[codepoint] = glyph; return(glyph); }
private void GetQuad(Font font, int prevGlyphIndex, FontGlyph glyph, float scale, float spacing, ref float x, ref float y, FontGlyphSquad *q) { if (prevGlyphIndex != -1) { var adv = font._font.fons__tt_getGlyphKernAdvance(prevGlyphIndex, glyph.Index) * scale; x += (int)(adv + spacing + 0.5f); } float rx = 0; float ry = 0; if ((_params_.Flags & FONS_ZERO_TOPLEFT) != 0) { rx = x + glyph.XOffset; ry = y + glyph.YOffset; q->X0 = rx; q->Y0 = ry; q->X1 = rx + (glyph.X1 - glyph.X0); q->Y1 = ry + (glyph.Y1 - glyph.Y0); q->S0 = glyph.X0 * _itw; q->T0 = glyph.Y0 * _ith; q->S1 = glyph.X1 * _itw; q->T1 = glyph.Y1 * _ith; } else { rx = x + glyph.XOffset; ry = y - glyph.YOffset; q->X0 = rx; q->Y0 = ry; q->X1 = rx + (glyph.X1 - glyph.X0); q->Y1 = ry - (glyph.Y1 + glyph.Y0); q->S0 = glyph.X0 * _itw; q->T0 = glyph.Y0 * _ith; q->S1 = glyph.X1 * _itw; q->T1 = glyph.Y1 * _ith; } x += (int)(glyph.XAdvance / 10.0f + 0.5f); }
public void RenderGlyph(GraphicsDevice device, FontGlyph glyph) { var pad = glyph.Pad; // Render glyph to byte buffer var buffer = new byte[glyph.Bounds.Width * glyph.Bounds.Height]; Array.Clear(buffer, 0, buffer.Length); var g = glyph.Index; FakePtr <byte> dst = new FakePtr <byte>(buffer, pad + pad * glyph.Bounds.Width); glyph.Font.RenderGlyphBitmap(dst, glyph.Bounds.Width - pad * 2, glyph.Bounds.Height - pad * 2, glyph.Bounds.Width, g); if (glyph.Blur > 0) { Blur(buffer, glyph.Bounds.Width, glyph.Bounds.Height, glyph.Bounds.Width, glyph.Blur); } // Byte buffer to RGBA var colorBuffer = new Color[glyph.Bounds.Width * glyph.Bounds.Height]; for (var i = 0; i < colorBuffer.Length; ++i) { var c = buffer[i]; colorBuffer[i].R = colorBuffer[i].G = colorBuffer[i].B = 255; colorBuffer[i].A = c; } // Write to texture if (Texture == null) { Texture = new Texture2D(device, Width, Height); } Texture.SetData(0, glyph.Bounds, colorBuffer, 0, colorBuffer.Length); }
public void RenderGlyph(Font renderFont, FontGlyph glyph, int gw, int gh, float scale) { var pad = glyph.Pad; var g = glyph.Index; fixed(byte *dst = &_texData[glyph.X0 + pad + (glyph.Y0 + pad) * Width]) { renderFont._font.fons__tt_renderGlyphBitmap(dst, gw - pad * 2, gh - pad * 2, Width, scale, scale, g); } fixed(byte *dst = &_texData[glyph.X0 + glyph.Y0 *Width]) { for (var y = 0; y < gh; y++) { dst[y * Width] = 0; dst[gw - 1 + y * Width] = 0; } for (var x = 0; x < gw; x++) { dst[x] = 0; dst[x + (gh - 1) * Width] = 0; } } if (glyph.Blur > 0) { fixed(byte *bdst = &_texData[glyph.X0 + glyph.Y0 *Width]) { Blur(bdst, gw, gh, Width, glyph.Blur); } } _dirtyRect[0] = Math.Min(_dirtyRect[0], glyph.X0); _dirtyRect[1] = Math.Min(_dirtyRect[1], glyph.Y0); _dirtyRect[2] = Math.Max(_dirtyRect[2], glyph.X1); _dirtyRect[3] = Math.Max(_dirtyRect[3], glyph.Y1); }
public void RenderGlyph(GraphicsDevice device, FontGlyph glyph) { if (glyph.Bounds.Width == 0 || glyph.Bounds.Height == 0) { return; } // Render glyph to byte buffer var buffer = new byte[glyph.Bounds.Width * glyph.Bounds.Height]; Array.Clear(buffer, 0, buffer.Length); var g = glyph.Index; glyph.Font.RenderGlyphBitmap(buffer, glyph.Bounds.Width, glyph.Bounds.Height, glyph.Bounds.Width, g); // Byte buffer to RGBA var colorBuffer = new Color[glyph.Bounds.Width * glyph.Bounds.Height]; for (var i = 0; i < colorBuffer.Length; ++i) { var c = buffer[i]; colorBuffer[i].R = colorBuffer[i].G = colorBuffer[i].B = colorBuffer[i].A = c; } // Write to texture if (Texture == null) { Texture = new Texture2D(device, Width, Height); } Texture.SetData(0, glyph.Bounds, colorBuffer, 0, colorBuffer.Length); }
internal override void GetQuad(FontGlyph glyph, FontGlyph prevGlyph, ref float x, float y, ref FontGlyphSquad q) { if (prevGlyph != null) { var adv = 0; var dynamicGlyph = (DynamicFontGlyph)glyph; var dynamicPrevGlyph = (DynamicFontGlyph)prevGlyph; if (FontSystem.UseKernings && dynamicGlyph.FontSourceIndex == dynamicPrevGlyph.FontSourceIndex) { var key = GetKerningsKey(prevGlyph.Id, dynamicGlyph.Id); if (!Kernings.TryGetValue(key, out adv)) { var fontSource = FontSystem.FontSources[dynamicGlyph.FontSourceIndex]; adv = fontSource.GetGlyphKernAdvance(prevGlyph.Id, dynamicGlyph.Id, dynamicGlyph.Size); Kernings[key] = adv; } } x += adv + FontSystem.CharacterSpacing; } base.GetQuad(glyph, prevGlyph, ref x, y, ref q); }
private FontGlyph GetGlyph(Font font, int codepoint, int isize, int iblur, bool isBitmapRequired) { var g = 0; var advance = 0; var lsb = 0; var x0 = 0; var y0 = 0; var x1 = 0; var y1 = 0; var gw = 0; var gh = 0; var gx = 0; var gy = 0; float scale = 0; FontGlyph glyph = null; var size = isize / 10.0f; if (isize < 2) { return(null); } if (iblur > 20) { iblur = 20; } if (font.TryGetGlyph(codepoint, isize, iblur, out glyph)) { if (!isBitmapRequired || glyph.X0 >= 0 && glyph.Y0 >= 0) { return(glyph); } } g = font._font.fons__tt_getGlyphIndex(codepoint); if (g == 0) { throw new Exception(string.Format("Could not find glyph for codepoint {0}", codepoint)); } scale = font._font.fons__tt_getPixelHeightScale(size); font._font.fons__tt_buildGlyphBitmap(g, size, scale, &advance, &lsb, &x0, &y0, &x1, &y1); var pad = FontGlyph.PadFromBlur(iblur); gw = x1 - x0 + pad * 2; gh = y1 - y0 + pad * 2; var currentAtlas = CurrentAtlas; if (isBitmapRequired) { if (!currentAtlas.AddRect(gw, gh, ref gx, ref gy)) { var ev = CurrentAtlasFull; if (ev != null) { ev(this, EventArgs.Empty); } // This code will force creation of new atlas _currentAtlas = null; currentAtlas = CurrentAtlas; // Try to add again if (!currentAtlas.AddRect(gw, gh, ref gx, ref gy)) { throw new Exception(string.Format("Could not add rect to the newly created atlas. gw={0}, gh={1}", gw, gh)); } } } else { gx = -1; gy = -1; } if (glyph == null) { glyph = new FontGlyph { Codepoint = codepoint, Size = isize, Blur = iblur }; font.SetGlyph(codepoint, isize, iblur, glyph); } glyph.Index = g; glyph.AtlasIndex = currentAtlas.Index; glyph.X0 = gx; glyph.Y0 = gy; glyph.X1 = glyph.X0 + gw; glyph.Y1 = glyph.Y0 + gh; glyph.XAdvance = (int)(scale * advance * 10.0f); glyph.XOffset = x0 - pad; glyph.YOffset = y0 - pad; if (!isBitmapRequired) { return(glyph); } currentAtlas.RenderGlyph(font, glyph, gw, gh, scale); return(glyph); }
public float TextBounds(float x, float y, StringSegment str, ref Bounds bounds) { var q = new FontGlyphSquad(); FontGlyph glyph = null; var prevGlyphIndex = -1; var isize = (int)(Size * 10.0f); var iblur = (int)BlurValue; float scale = 0; Font font; float startx = 0; float advance = 0; float minx = 0; float miny = 0; float maxx = 0; float maxy = 0; if (FontId < 0 || FontId >= _fonts.Count) { return(0); } font = _fonts[FontId]; if (font.Data == null) { return(0); } scale = font._font.fons__tt_getPixelHeightScale(isize / 10.0f); y += GetVertAlign(font, Alignment, isize); minx = maxx = x; miny = maxy = y; startx = x; for (int i = 0; i < str.Length; i += char.IsSurrogatePair(str.String, i + str.Location) ? 2 : 1) { var codepoint = char.ConvertToUtf32(str.String, i + str.Location); glyph = GetGlyph(font, codepoint, isize, iblur, false); if (glyph != null) { GetQuad(font, prevGlyphIndex, glyph, scale, Spacing, ref x, ref y, &q); if (q.X0 < minx) { minx = q.X0; } if (x > maxx) { maxx = x; } if (_params_.IsAlignmentTopLeft) { if (q.Y0 < miny) { miny = q.Y0; } if (q.Y1 > maxy) { maxy = q.Y1; } } else { if (q.Y1 < miny) { miny = q.Y1; } if (q.Y0 > maxy) { maxy = q.Y0; } } } prevGlyphIndex = glyph != null ? glyph.Index : -1; } advance = x - startx; if ((Alignment & Alignment.Left) != 0) { } else if ((Alignment & Alignment.Right) != 0) { minx -= advance; maxx -= advance; } else if ((Alignment & Alignment.Center) != 0) { minx -= advance * 0.5f; maxx -= advance * 0.5f; } bounds.X = minx; bounds.Y = miny; bounds.X2 = maxx; bounds.Y2 = maxy; return(advance); }
public float DrawText(SpriteBatch batch, float x, float y, StringSegment str, float depth) { if (str.IsNullOrEmpty) { return(0.0f); } FontGlyph glyph = null; var q = new FontGlyphSquad(); var prevGlyphIndex = -1; var isize = (int)(Size * 10.0f); var iblur = (int)BlurValue; float scale = 0; Font font; float width = 0; if (FontId < 0 || FontId >= _fonts.Count) { return(x); } font = _fonts[FontId]; if (font.Data == null) { return(x); } scale = font._font.fons__tt_getPixelHeightScale(isize / 10.0f); if ((Alignment & Alignment.Left) != 0) { } else if ((Alignment & Alignment.Right) != 0) { var bounds = new Bounds(); width = TextBounds(x, y, str, ref bounds); x -= width; } else if ((Alignment & Alignment.Center) != 0) { var bounds = new Bounds(); width = TextBounds(x, y, str, ref bounds); x -= width * 0.5f; } float originX = 0.0f; float originY = 0.0f; originY += GetVertAlign(font, Alignment, isize); for (int i = 0; i < str.Length; i += char.IsSurrogatePair(str.String, i + str.Location) ? 2 : 1) { var codepoint = char.ConvertToUtf32(str.String, i + str.Location); glyph = GetGlyph(font, codepoint, isize, iblur, true); if (glyph != null) { GetQuad(font, prevGlyphIndex, glyph, scale, Spacing, ref originX, ref originY, &q); q.X0 = (int)(q.X0 * Scale.X); q.X1 = (int)(q.X1 * Scale.X); q.Y0 = (int)(q.Y0 * Scale.Y); q.Y1 = (int)(q.Y1 * Scale.Y); var renderItem = new RenderItem { Atlas = _atlases[glyph.AtlasIndex], _verts = new Rectangle((int)(x + q.X0), (int)(y + q.Y0), (int)(q.X1 - q.X0), (int)(q.Y1 - q.Y0)), _textureCoords = new Rectangle((int)(q.S0 * _params_.Width), (int)(q.T0 * _params_.Height), (int)((q.S1 - q.S0) * _params_.Width), (int)((q.T1 - q.T0) * _params_.Height)), _colors = Color }; _renderItems.Add(renderItem); } prevGlyphIndex = glyph != null ? glyph.Index : -1; } Flush(batch, depth); return(x); }
public float TextBounds(float x, float y, StringBuilder str, ref Bounds bounds) { if (str == null || str.Length == 0) { return(0.0f); } Dictionary <int, FontGlyph> glyphs; float ascent, lineHeight; PreDraw(str, out glyphs, out ascent, out lineHeight); var q = new FontGlyphSquad(); y += ascent; float minx, maxx, miny, maxy; minx = maxx = x; miny = maxy = y; float startx = x; FontGlyph prevGlyph = null; for (int i = 0; i < str.Length; i += StringBuilderIsSurrogatePair(str, i) ? 2 : 1) { var codepoint = StringBuilderConvertToUtf32(str, i); if (codepoint == '\n') { x = startx; y += lineHeight; prevGlyph = null; continue; } var glyph = GetGlyph(null, glyphs, codepoint); if (glyph == null) { continue; } GetQuad(glyph, prevGlyph, Spacing, ref x, ref y, ref q); if (q.X0 < minx) { minx = q.X0; } if (x > maxx) { maxx = x; } if (q.Y0 < miny) { miny = q.Y0; } if (q.Y1 > maxy) { maxy = q.Y1; } prevGlyph = glyph; } float advance = x - startx; bounds.X = minx; bounds.Y = miny; bounds.X2 = maxx; bounds.Y2 = maxy; return(advance); }
public float DrawText(SpriteBatch batch, float x, float y, StringBuilder str, Color[] glyphColors, float depth) { if (str == null || str.Length == 0) { return(0.0f); } Dictionary <int, FontGlyph> glyphs; float ascent, lineHeight; PreDraw(str, out glyphs, out ascent, out lineHeight); float originX = 0.0f; float originY = 0.0f; originY += ascent; FontGlyph prevGlyph = null; var pos = 0; var q = new FontGlyphSquad(); for (int i = 0; i < str.Length; i += StringBuilderIsSurrogatePair(str, i) ? 2 : 1) { var codepoint = StringBuilderConvertToUtf32(str, i); if (codepoint == '\n') { originX = 0.0f; originY += lineHeight; prevGlyph = null; ++pos; continue; } var glyph = GetGlyph(batch.GraphicsDevice, glyphs, codepoint); if (glyph == null) { ++pos; continue; } GetQuad(glyph, prevGlyph, Spacing, ref originX, ref originY, ref q); if (!glyph.IsEmpty) { q.X0 = (int)(q.X0 * Scale.X); q.X1 = (int)(q.X1 * Scale.X); q.Y0 = (int)(q.Y0 * Scale.Y); q.Y1 = (int)(q.Y1 * Scale.Y); var destRect = new Rectangle((int)(x + q.X0), (int)(y + q.Y0), (int)(q.X1 - q.X0), (int)(q.Y1 - q.Y0)); var sourceRect = new Rectangle((int)(q.S0 * _size.X), (int)(q.T0 * _size.Y), (int)((q.S1 - q.S0) * _size.X), (int)((q.T1 - q.T0) * _size.Y)); batch.Draw(glyph.Atlas.Texture, destRect, sourceRect, glyphColors[pos], 0f, Vector2.Zero, SpriteEffects.None, depth); } prevGlyph = glyph; ++pos; } return(x); }
public float TextBounds(float x, float y, string str, ref Bounds bounds) { if (string.IsNullOrEmpty(str)) { return(0.0f); } var glyphs = GetGlyphsCollection(FontSize); // Determine ascent and lineHeight from first character float ascent = 0, lineHeight = 0; for (int i = 0; i < str.Length; i += char.IsSurrogatePair(str, i) ? 2 : 1) { var codepoint = char.ConvertToUtf32(str, i); var glyph = GetGlyph(null, glyphs, codepoint); if (glyph == null) { continue; } ascent = glyph.Font.Ascent; lineHeight = glyph.Font.LineHeight; break; } var q = new FontGlyphSquad(); float startx = 0; float advance = 0; y += ascent; float minx, maxx, miny, maxy; minx = maxx = x; miny = maxy = y; startx = x; FontGlyph prevGlyph = null; for (int i = 0; i < str.Length; i += char.IsSurrogatePair(str, i) ? 2 : 1) { var codepoint = char.ConvertToUtf32(str, i); if (codepoint == '\n') { x = startx; y += lineHeight; prevGlyph = null; continue; } var glyph = GetGlyph(null, glyphs, codepoint); if (glyph == null) { continue; } GetQuad(glyph, prevGlyph, Spacing, ref x, ref y, ref q); if (q.X0 < minx) { minx = q.X0; } if (x > maxx) { maxx = x; } if (q.Y0 < miny) { miny = q.Y0; } if (q.Y1 > maxy) { maxy = q.Y1; } prevGlyph = glyph; } advance = x - startx; bounds.X = minx; bounds.Y = miny; bounds.X2 = maxx; bounds.Y2 = maxy; return(advance); }