static void Main(string[] args) { Console.WriteLine("Version string: " + HB.VersionString); Version v = HB.Version; Console.WriteLine("Version: " + v.Major + "." + v.Minor + "." + v.Build); Console.WriteLine("VersionCheck: " + HB.VersionAtLeast(v)); var lib = new Library(); var face = new SharpFont.Face(lib, @"C:\Windows\Fonts\tahoma.ttf"); face.SetCharSize(0, 50, 72, 72); var font = HarfBuzz.Font.FromFTFace(face); var buf = new HarfBuzz.Buffer(); buf.Direction = Direction.RightToLeft; buf.Script = Script.Arabic; buf.AddText("متن"); font.Shape(buf); var glyphInfos = buf.GlyphInfo(); var glyphPositions = buf.GlyphPositions(); int height = (face.MaxAdvanceHeight - face.Descender) >> 6; int width = 0; for (int i = 0; i < glyphInfos.Length; ++i) { width += glyphPositions[i].xAdvance >> 6; } Bitmap bmp = new Bitmap(width, height); Graphics g = Graphics.FromImage(bmp); g.Clear(Color.Gray); int penX = 0, penY = face.MaxAdvanceHeight >> 6; //draw the string for (int i = 0; i < glyphInfos.Length; ++i) { face.LoadGlyph(glyphInfos[i].codepoint, LoadFlags.Default, LoadTarget.Normal); face.Glyph.RenderGlyph(RenderMode.Normal); Bitmap cBmp = face.Glyph.Bitmap.ToGdipBitmap(Color.Firebrick); g.DrawImageUnscaled(cBmp, penX + (glyphPositions[i].xOffset >> 6) + face.Glyph.BitmapLeft, penY - (glyphPositions[i].yOffset >> 6) - face.Glyph.BitmapTop); penX += glyphPositions[i].xAdvance >> 6; penY -= glyphPositions[i].yAdvance >> 6; } g.Dispose(); bmp.Save("output.bmp"); }
public static void Text(string str, float startX, float startY, uint c, Direction dir = Direction.LeftToRight, Script script = Script.Latin) { var buf = new SharpFont.HarfBuzz.Buffer { Direction = dir, Script = script }; buf.AddText(str); fixedsysFont.Shape(buf); var glyphInfos = buf.GlyphInfo(); var glyphPositions = buf.GlyphPositions(); int penX = 0, penY = 0; //draw the string for (int i = 0; i < glyphInfos.Length; ++i) { fixedsysFace.LoadGlyph(glyphInfos[i].codepoint, LoadFlags.Monochrome, LoadTarget.Mono); fixedsysFace.Glyph.RenderGlyph(RenderMode.Mono); var bmap = fixedsysFace.Glyph.Bitmap; // Console.WriteLine("{2} bmap {0} {1}", i, bmap.Width, str); // https://dbader.org/blog/monochrome-font-rendering-with-freetype-and-python for (int y = 0; y < bmap.Rows; y++) { for (int byteIndex = 0; byteIndex < bmap.Pitch; byteIndex++) { var bval = bmap.BufferData[y * bmap.Pitch + byteIndex]; var numDone = byteIndex * 8; for (int bitIndex = 0; bitIndex < Math.Min(8, bmap.Width - numDone); bitIndex++) { var bit = bval & (1 << (7 - bitIndex)); if (bit != 0) { var xxx = penX + bitIndex + numDone + (glyphPositions[i].xOffset >> 6) + fixedsysFace.Glyph.BitmapLeft; var yyy = penY - y - (glyphPositions[i].yOffset >> 6) + fixedsysFace.Glyph.BitmapTop; Set(startX + xxx, startY - yyy, c); } } } } penX += glyphPositions[i].xAdvance >> 6; penY -= glyphPositions[i].yAdvance >> 6; } }