GlyphInfo CreateGlyph(Pair<char, Color> c) { face.LoadChar(c.First, LoadFlags.Default, LoadTarget.Normal); face.Glyph.RenderGlyph(RenderMode.Normal); var size = new Size((int)face.Glyph.Metrics.Width, (int)face.Glyph.Metrics.Height); var s = builder.Allocate(size); var g = new GlyphInfo { Sprite = s, Advance = (float)face.Glyph.Metrics.HorizontalAdvance, Offset = new int2(face.Glyph.BitmapLeft, -face.Glyph.BitmapTop) }; // A new bitmap is generated each time this property is accessed, so we do need to dispose it. using (var bitmap = face.Glyph.Bitmap) { unsafe { var p = (byte*)bitmap.Buffer; var dest = s.Sheet.GetData(); var destStride = s.Sheet.Size.Width * 4; for (var j = 0; j < s.Size.Y; j++) { for (var i = 0; i < s.Size.X; i++) { if (p[i] != 0) { var q = destStride * (j + s.Bounds.Top) + 4 * (i + s.Bounds.Left); var pmc = Util.PremultiplyAlpha(Color.FromArgb(p[i], c.Second)); dest[q] = pmc.B; dest[q + 1] = pmc.G; dest[q + 2] = pmc.R; dest[q + 3] = pmc.A; } } p += bitmap.Pitch; } } } s.Sheet.CommitBufferedData(); return g; }
GlyphInfo CreateGlyph(Pair <char, Color> c) { try { face.LoadChar(c.First, LoadFlags.Default, LoadTarget.Normal); } catch (FreeTypeException) { return(new GlyphInfo { Sprite = null, Advance = 0, Offset = int2.Zero }); } face.Glyph.RenderGlyph(RenderMode.Normal); var size = new Size((int)face.Glyph.Metrics.Width, (int)face.Glyph.Metrics.Height); var s = builder.Allocate(size); var g = new GlyphInfo { Sprite = s, Advance = (float)face.Glyph.Metrics.HorizontalAdvance, Offset = new int2(face.Glyph.BitmapLeft, -face.Glyph.BitmapTop) }; // A new bitmap is generated each time this property is accessed, so we do need to dispose it. using (var bitmap = face.Glyph.Bitmap) { unsafe { var p = (byte *)bitmap.Buffer; var dest = s.Sheet.GetData(); var destStride = s.Sheet.Size.Width * 4; for (var j = 0; j < s.Size.Y; j++) { for (var i = 0; i < s.Size.X; i++) { if (p[i] != 0) { var q = destStride * (j + s.Bounds.Top) + 4 * (i + s.Bounds.Left); var pmc = Util.PremultiplyAlpha(Color.FromArgb(p[i], c.Second)); dest[q] = pmc.B; dest[q + 1] = pmc.G; dest[q + 2] = pmc.R; dest[q + 3] = pmc.A; } } p += bitmap.Pitch; } } } s.Sheet.CommitBufferedData(); return(g); }
GlyphInfo CreateGlyph(Pair<char,Color> c) { var index = FT.FT_Get_Char_Index(face, (uint)c.First); if (0 != FT.FT_Load_Glyph(face, index, FT.FT_LOAD_RENDER)) throw new InvalidOperationException( "FT_Load_Glyph failed." ); var _face = (FT_FaceRec)Marshal.PtrToStructure(face, typeof(FT_FaceRec)); var _glyph = (FT_GlyphSlotRec)Marshal.PtrToStructure(_face.glyph, typeof(FT_GlyphSlotRec)); var s = builder.Allocate( new Size(_glyph.metrics.width.ToInt32() >> 6, _glyph.metrics.height.ToInt32() >> 6)); var g = new GlyphInfo { Sprite = s, Advance = _glyph.metrics.horiAdvance.ToInt32() / 64f, Offset = { X = _glyph.bitmap_left, Y = -_glyph.bitmap_top } }; unsafe { var p = (byte*)_glyph.bitmap.buffer; var dest = s.sheet.Data; var destStride = s.sheet.Size.Width * 4; for (var j = 0; j < s.size.Y; j++) { for (var i = 0; i < s.size.X; i++) if (p[i] != 0) { var q = destStride * (j + s.bounds.Top) + 4 * (i + s.bounds.Left); dest[q] = c.Second.B; dest[q + 1] = c.Second.G; dest[q + 2] = c.Second.R; dest[q + 3] = p[i]; } p += _glyph.bitmap.pitch; } } return g; }
public void DrawText(string text, float2 location, Color c) { if (text.Contains("Cyril")) { } // Offset from the baseline position to the top-left of the glyph for rendering location += new float2(0, size); var p = new float2(location.X, location.Y); float scale = 1; foreach (var s in text) { if (s == '\n') { location += new float2(0, size); p = location; continue; } GlyphInfo gli = glyphs[Pair.New(s, c)]; //размер квада буквы равен размеру текстуры * масштаб. float3 tempXY = new float2(); if (gli.Sprite != null) { gli.Sprite.SpriteType = 1; // 1 будет для FontMSDF gli.Sprite.SpriteArrayNum = (int)s; scale = (FontMSDF.Size * font.Height) / 18f; //scale = (FontMSDF.Size * gli.fg.Size.Height) / 18f; //scale = (FontMSDF.Size * gli.fg.Size.Height) / 18f; float scalex = (FontMSDF.Size * gli.fg.Size.Width) / 18f; //scale = (FontMSDF.Size / this.size); ///scale = 64; //tempXY = new float2((int)Math.Round(p.X -6 , 0) / deviceScale, (p.Y - scale+6) / deviceScale); tempXY = new float2((p.X - 1) / deviceScale, (p.Y - scale + 5) / deviceScale); // -5 -5 потому, что -translate 5 5 был задан в msdfgen // деление на 64 ,это приведение к шкале глифа SDF, который 64 на 64 //tempXY = new float2((int)Math.Round(p.X , 0) / deviceScale, (p.Y ) / deviceScale); gli.Sprite.Left = 0f; gli.Sprite.Bottom = 0f; gli.Sprite.Top = 1f; gli.Sprite.Right = 1f; //Sprite ничего не значит тут. Он нужен лишь для определения размера полигона Game.Renderer.FontSpriteRenderer.SetFontMSDF(Mfont.Texture); //assign texture arg for shader text.vert. Game.Renderer.FontSpriteRenderer.DrawTextSprite(gli.Sprite, tempXY, 0, new float3(scale, scale, 0)); } float coof = (FontMSDF.Size * font.Height) / 18f; if (s == 'm') { //gli.Advance = 15; } p += new float2((gli.Advance) / deviceScale, 0); } Game.Renderer.FontSpriteRenderer.SetTextColor(c); // + добавить юсда передачу параметра в шейдер , цвет шрифта. }
GlyphInfo CreateGlyph(Pair<char, Color> c) { var index = face.GetCharIndex(c.First); face.LoadGlyph(index, LoadFlags.Default, LoadTarget.Normal); face.Glyph.RenderGlyph(RenderMode.Normal); var size = new Size((int)face.Glyph.Metrics.Width >> 6, (int)face.Glyph.Metrics.Height >> 6); var s = builder.Allocate(size); var g = new GlyphInfo { Sprite = s, Advance = (int)face.Glyph.Metrics.HorizontalAdvance / 64f, Offset = { X = face.Glyph.BitmapLeft, Y = -face.Glyph.BitmapTop } }; // A new bitmap is generated each time this property is accessed, so we do need to dispose it. using (var bitmap = face.Glyph.Bitmap) unsafe { var p = (byte*)bitmap.Buffer; var dest = s.sheet.Data; var destStride = s.sheet.Size.Width * 4; for (var j = 0; j < s.size.Y; j++) { for (var i = 0; i < s.size.X; i++) if (p[i] != 0) { var q = destStride * (j + s.bounds.Top) + 4 * (i + s.bounds.Left); dest[q] = c.Second.B; dest[q + 1] = c.Second.G; dest[q + 2] = c.Second.R; dest[q + 3] = p[i]; } p += bitmap.Pitch; } } s.sheet.CommitData(); return g; }
GlyphInfo CreateGlyph(char c) { var index = FT.FT_Get_Char_Index(face, (uint)c); FT.FT_Load_Glyph(face, index, FT.FT_LOAD_RENDER); var _face = (FT_FaceRec)Marshal.PtrToStructure(face, typeof(FT_FaceRec)); var _glyph = (FT_GlyphSlotRec)Marshal.PtrToStructure(_face.glyph, typeof(FT_GlyphSlotRec)); var s = builder.Allocate(new Size(_glyph.metrics.width >> 6, _glyph.metrics.height >> 6)); var g = new GlyphInfo { Sprite = s, Advance = _glyph.metrics.horiAdvance / 64f, Offset = { X = _glyph.bitmap_left, Y = -_glyph.bitmap_top } }; unsafe { var p = (byte*)_glyph.bitmap.buffer; for (var j = 0; j < s.size.Y; j++) { for (var i = 0; i < s.size.X; i++) if (p[i] != 0) s.sheet.Bitmap.SetPixel(i + s.bounds.Left, j + s.bounds.Top, Color.FromArgb(p[i], 0xff, 0xff, 0xff)); p += _glyph.bitmap.pitch; } } return g; }
GlyphInfo CreateGlyph(Pair<char, Color> c) { uint index = face.GetCharIndex(c.First); face.LoadGlyph(index, LoadFlags.Default, LoadTarget.Normal); face.Glyph.RenderGlyph(RenderMode.Normal); var s = builder.Allocate( new Size((int)face.Glyph.Metrics.Width >> 6, (int)face.Glyph.Metrics.Height >> 6)); var g = new GlyphInfo { Sprite = s, Advance = (int)face.Glyph.Metrics.HorizontalAdvance / 64f, Offset = { X = face.Glyph.BitmapLeft, Y = -face.Glyph.BitmapTop } }; unsafe { var p = (byte*)face.Glyph.Bitmap.Buffer; var dest = s.sheet.Data; var destStride = s.sheet.Size.Width * 4; for (var j = 0; j < s.size.Y; j++) { for (var i = 0; i < s.size.X; i++) if (p[i] != 0) { var q = destStride * (j + s.bounds.Top) + 4 * (i + s.bounds.Left); dest[q] = c.Second.B; dest[q + 1] = c.Second.G; dest[q + 2] = c.Second.R; dest[q + 3] = p[i]; } p += face.Glyph.Bitmap.Pitch; } } return g; }