public void Test_BakePackedCodepoint() { #region Init string assemblyDir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); string solution_dir = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(assemblyDir))); #endregion //Read ttf file into byte array byte[] ttfFileContent = File.ReadAllBytes(solution_dir + @"\FontSamples\Windsong.ttf"); using (var ttf = new PinnedArray <byte>(ttfFileContent)) { //get pointer of the ttf file content var ttf_buffer = ttf.Pointer; //Initialize fontinfo FontInfo font = new FontInfo(); STBTrueType.InitFont(ref font, ttf_buffer, STBTrueType.GetFontOffsetForIndex(ttf_buffer, 0)); //set bitmap size const int BITMAP_W = 512; const int BITMAP_H = 512; //allocate bitmap buffer byte[] bitmapBuffer = new byte[BITMAP_W * BITMAP_H]; //Initialize a pack context PackContext pc = new PackContext(); STBTrueType.PackBegin(ref pc, bitmapBuffer, BITMAP_W, BITMAP_H, 0, 1, IntPtr.Zero); //allocate packed char buffer PackedChar[] pdata = new PackedChar[256 * 2]; using (var pin_pdata = new PinnedArray <PackedChar>(pdata)) { //get pointer of the pdata var ptr_pdata = pin_pdata.Pointer; //set pack ranges PackRange[] ranges = new PackRange[2]; ranges[0].chardata_for_range = ptr_pdata; ranges[0].first_unicode_char_in_range = 32; ranges[0].num_chars_in_range = 95; ranges[0].font_size = 20.0f; ranges[1].chardata_for_range = IntPtr.Add(ptr_pdata, 256 * Marshal.SizeOf(pdata[0])); ranges[1].first_unicode_char_in_range = 0xa0; ranges[1].num_chars_in_range = 0x100 - 0xa0; ranges[1].font_size = 20.0f; //Bake bitmap STBTrueType.PackFontRanges(ref pc, ttf_buffer, 0, ranges, 2); //Clean up STBTrueType.PackEnd(ref pc); } //output the bitmap to a text file WriteBitmapToFileAsText("testOuput.txt", BITMAP_H, BITMAP_W, bitmapBuffer); //Open the text file OpenFile("testOuput.txt"); } }
public bool CreatePackedGlyphMap(string charactersToPack, int fontSize, int width, int height) { width = 512; height = 512; var bitmapData = new byte[width * height]; using (var ttf = new PinnedArray <byte>(_data)) { //get pointer of the ttf file content var ttfBuffer = ttf.Pointer; //Begin pack PackContext pc = new PackContext(); STBTrueType.PackBegin(ref pc, bitmapData, width, height, 0, 1, IntPtr.Zero); //Ref: https://github.com/nothings/stb/blob/bdef693b7cc89efb0c450b96a8ae4aecf27785c8/tests/test_truetype.c //allocate packed char buffer PackedCharData = new PackedChar[charactersToPack.Length]; using (var pin_pdata = new PinnedArray <PackedChar>(PackedCharData)) { //get pointer of the pdata var ptr_pdata = pin_pdata.Pointer; PackRange[] vPackRange = new PackRange[charactersToPack.Length]; for (var i = 0; i < charactersToPack.Length; ++i) { //create a PackRange of one character PackRange pr = new PackRange { chardata_for_range = IntPtr.Add(ptr_pdata, i * Marshal.SizeOf(typeof(PackedChar))), first_unicode_char_in_range = charactersToPack[i] & 0xFFFF, num_chars_in_range = 1, font_size = fontSize }; //add it to the range list vPackRange[i] = pr; } //STBTrueType.PackSetOversampling(ref pc, 2, 2); STBTrueType.PackFontRanges(ref pc, ttfBuffer, 0, vPackRange, vPackRange.Length); STBTrueType.PackEnd(ref pc); } } PackedCharBitmap = CreateBitmapFromRawData(bitmapData, width, height); return(true); }
private byte[] CreateGlyph(string charactersToPack, ref int width, ref int height) { byte[] bitmapData = null; //Read ttf file into byte array byte[] ttfFileContent = File.ReadAllBytes(ttfSampleDir + '\\' + FontSelectorComboBox.SelectedItem as string); using (var ttf = new PinnedArray <byte>(ttfFileContent)) { //get pointer of the ttf file content var ttf_buffer = ttf.Pointer; //Initialize fontinfo FontInfo font = new FontInfo(); STBTrueType.InitFont(ref font, ttf_buffer, STBTrueType.GetFontOffsetForIndex(ttf_buffer, 0)); PackContext pc = new PackContext(); width = 512; height = 512; bitmapData = new byte[width * height]; STBTrueType.PackBegin(ref pc, bitmapData, width, height, 0, 1, IntPtr.Zero); //Ref: https://github.com/nothings/stb/blob/bdef693b7cc89efb0c450b96a8ae4aecf27785c8/tests/test_truetype.c //allocate packed char buffer PackedChar[] pdata = new PackedChar[charactersToPack.Length]; using (var pin_pdata = new PinnedArray <PackedChar>(pdata)) { //get pointer of the pdata var ptr_pdata = pin_pdata.Pointer; PackRange[] vPackRange = new PackRange[charactersToPack.Length]; for (var i = 0; i < charactersToPack.Length; ++i) { //create a PackRange of one character PackRange pr = new PackRange(); pr.chardata_for_range = IntPtr.Add(ptr_pdata, i * Marshal.SizeOf(typeof(PackedChar))); pr.first_unicode_char_in_range = charactersToPack[i] & 0xFFFF; pr.num_chars_in_range = 1; pr.font_size = pixelHeight; //add it to the range list vPackRange[i] = pr; } //STBTrueType.PackSetOversampling(ref pc, 2, 2); STBTrueType.PackFontRanges(ref pc, ttf_buffer, 0, vPackRange, vPackRange.Length); STBTrueType.PackEnd(ref pc); } } return(bitmapData); }
private Bitmap CreateGlyphForText(string text, ref int width, ref int height) { byte[] bitmapData = null; Bitmap bmp = new Bitmap(512, 512, PixelFormat.Format24bppRgb); //Read ttf file into byte array byte[] ttfFileContent = File.ReadAllBytes(ttfSampleDir + '\\' + FontSelectorComboBox.SelectedItem as string); using (var ttf = new PinnedArray <byte>(ttfFileContent)) { //get pointer of the ttf file content var ttf_buffer = ttf.Pointer; //Initialize fontinfo FontInfo font = new FontInfo(); STBTrueType.InitFont(ref font, ttf_buffer, STBTrueType.GetFontOffsetForIndex(ttf_buffer, 0)); } //TODO build packed characters' bitmap for ASCII/Chinese/Japanse/Korean characters etc. PackContext pc = new PackContext(); width = 512; height = 512; bitmapData = new byte[width * height]; STBTrueType.PackBegin(ref pc, bitmapData, width, height, 0, 1, IntPtr.Zero); //Ref: https://github.com/nothings/stb/blob/bdef693b7cc89efb0c450b96a8ae4aecf27785c8/tests/test_truetype.c //allocate packed char buffer PackedChar[] pdata = new PackedChar[text.Length]; using (var pin_pdata = new PinnedArray <PackedChar>(pdata)) { //get pointer of the pdata var ptr_pdata = pin_pdata.Pointer; PackRange[] vPackRange = new PackRange[text.Length]; for (var i = 0; i < text.Length; ++i) { //create a PackRange of one character PackRange pr = new PackRange(); pr.chardata_for_range = IntPtr.Add(ptr_pdata, i * Marshal.SizeOf(typeof(PackedChar))); pr.first_unicode_char_in_range = text[i] & 0xFFFF; pr.num_chars_in_range = 1; pr.font_size = pixelHeight; //add it to the range list vPackRange[i] = pr; } STBTrueType.PackSetOversampling(ref pc, 2, 2); using (var ttf = new PinnedArray <byte>(ttfFileContent)) { //get pointer of the ttf file content var ttf_buffer = ttf.Pointer; STBTrueType.PackFontRanges(ref pc, ttf_buffer, 0, vPackRange, vPackRange.Length); } STBTrueType.PackEnd(ref pc); } var bitmapPackedCharacters = CreateBitmapFromRawData(bitmapData, width, height); //ref //https://github.com/nothings/stb/blob/bdef693b7cc89efb0c450b96a8ae4aecf27785c8/tests/oversample/main.c //Draw characters to a bitmap by order Graphics g = Graphics.FromImage(bmp); g.Clear(Color.White); float x = 0, y = 0; for (var i = 0; i < text.Length; ++i) { var character = text[i]; AlignedQuad aq; //get character bitmaps in packed bitmap STBTrueType.GetPackedQuad(pdata, width, height, i, ref x, ref y, out aq, 0); #if DebugOutput Debug.WriteLine(i); Debug.WriteLine("x: {0}, y: {1}", x, y); Debug.WriteLine("src: left-top: ({0}, {1}), right-bottom: ({2}, {3})", aq.s0 * width, aq.t0 * height, aq.s1 * width, aq.t1 * height); Debug.WriteLine("dest: left-top: ({0}, {1}), right-bottom: ({2}, {3})", aq.x0, aq.y0, aq.x1, aq.y1); #endif var rectSrc = RectangleF.FromLTRB(aq.s0 * width, aq.t0 * height, aq.s1 * width, aq.t1 * height); var rectDest = RectangleF.FromLTRB(aq.x0, aq.y0, aq.x1, aq.y1); rectDest.Offset(x, y + pixelHeight);//ATTENTION! The offset of lineHeight(pixelHeight here) should be appended. #if DebugOutput Debug.WriteLine("rectSrc {0}", rectSrc); Debug.WriteLine("rectDest {0}", rectDest); #endif g.DrawImage(bitmapPackedCharacters, rectDest, rectSrc, GraphicsUnit.Pixel); } g.Flush(); return(bmp); }