Exemple #1
0
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            string hello = "The quick brown fox jumps over the lazy dog.";

            charCache = new Dictionary <char, GlyphData>();

            Library lib      = new Library();
            Face    fontFace = new Face(lib, "fonts/roboto-regular.ttf");

            fontFace.SetCharSize(0, 18 * 64, 0, 96);

            int wX = 0;
            int wY = 0;

            int xB = 0;

            int pX = 0;
            int pY = 0;

            uint current  = 0;
            uint previous = 0;

            GlyphData data;

            DateTime iTimeS = DateTime.Now;

            foreach (var item in hello)
            {
                current = fontFace.GetCharIndex(item);

                if (!charCache.ContainsKey(item))
                {
                    fontFace.LoadGlyph(current, LoadFlags.Default, LoadTarget.Normal);
                    fontFace.Glyph.RenderGlyph(RenderMode.Normal);

                    FTBitmap bitmap = fontFace.Glyph.Bitmap;

                    data = new GlyphData();

                    if (item != ' ')
                    {
                        data.buffer = bitmap.BufferData;
                    }

                    data.charIndex = current;

                    data.metrics = fontFace.Glyph.Metrics;

                    data.height = fontFace.Glyph.Metrics.Height / 64;
                    data.width  = fontFace.Glyph.Metrics.Width / 64;

                    data.pitch   = fontFace.Glyph.BitmapTop;
                    data.forward = fontFace.Glyph.BitmapLeft;

                    data.aX = fontFace.Glyph.Metrics.HorizontalAdvance;
                    data.aY = fontFace.Glyph.Metrics.VerticalAdvance;

                    charCache.Add(item, data);
                }
                else
                {
                    data = charCache[item];
                }

                wX += data.aX / 64;

                if (fontFace.HasKerning && previous != 0 && current != 0)
                {
                    var kInfo = fontFace.GetKerning(previous, current, KerningMode.Default);

                    wX += kInfo.X / 64;

                    data.kX = kInfo.X / 64;
                    data.kY = kInfo.Y / 64;
                }

                previous = current;
            }

            xB = Math.Abs(fontFace.Size.Metrics.Descender / 64);
            wY = fontFace.Size.Metrics.Height / 64;

            DateTime iTimeF = DateTime.Now;

            Console.WriteLine("Time in letting freetype render the glyphs: {0} milliseconds.", (iTimeF - iTimeS).TotalMilliseconds);

            bmp = new Bitmap(wX, wY);

            int[] map = new int[wX * wY];

            for (int i = 0; i < map.Length; i++)
            {
                map[i] = 0;
            }

            current  = 0;
            previous = 0;

            DateTime timeS = DateTime.Now;

            for (int i = 0; i < hello.Length; i++)
            {
                GlyphData pdata = charCache[hello[i]];

                for (int y = 0; y < pdata.height; y++)
                {
                    for (int x = 0; x < pdata.width; x++)
                    {
                        int fx = x + pX + pdata.forward;
                        int fy = wY - pdata.pitch + y - xB;

                        fy = y + (wY - pdata.pitch - xB);

                        if (fy < 0 || fy >= wY)
                        {
                            //Console.WriteLine("Overflow on fy! :(");
                            continue;
                        }

                        if (fx < 0 || fx >= wX)
                        {
                            //Console.WriteLine("Overflow on fx! :(");
                            continue;
                        }

                        int fdata = pdata.buffer[y * pdata.width + x] + map[fy * wX + fx];

                        if (fdata >= 255)
                        {
                            fdata = 255;
                        }

                        map[fy * wX + fx] = (fdata << 24);
                    }
                }

                pX += pdata.aX / 64;
                pX += pdata.kX;
            }

            BitmapData bData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

            Marshal.Copy(map, 0, bData.Scan0, map.Length);

            bmp.UnlockBits(bData);

            map = null;

            DateTime timeF = DateTime.Now;

            Console.WriteLine("Time in mapping them pixels: {0} milliseconds.", (timeF - timeS).TotalMilliseconds);

            GC.Collect();

            ClientSize    = new System.Drawing.Size(wX, wY);
            StartPosition = FormStartPosition.CenterScreen;

            BackColor = Color.White;

            Invalidate();
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            string hello = "The quick brown fox jumps over the lazy dog.";

            charCache = new Dictionary<char, GlyphData>();

            Library lib = new Library();
            Face fontFace = new Face(lib, "fonts/roboto-regular.ttf");

            fontFace.SetCharSize(0, 18 * 64, 0, 96);

            int wX          = 0;
            int wY          = 0;

            int xB          = 0;

            int pX          = 0;
            int pY          = 0;

            uint current    = 0;
            uint previous   = 0;

            GlyphData       data;

            DateTime iTimeS = DateTime.Now;

            foreach (var item in hello)
            {
                current = fontFace.GetCharIndex(item);

                if (!charCache.ContainsKey(item))
                {
                    fontFace.LoadGlyph(current, LoadFlags.Default, LoadTarget.Normal);
                    fontFace.Glyph.RenderGlyph(RenderMode.Normal);

                    FTBitmap bitmap = fontFace.Glyph.Bitmap;

                    data = new GlyphData();

                    if (item != ' ')
                        data.buffer = bitmap.BufferData;

                    data.charIndex  = current;

                    data.metrics    = fontFace.Glyph.Metrics;

                    data.height     = fontFace.Glyph.Metrics.Height / 64;
                    data.width      = fontFace.Glyph.Metrics.Width / 64;

                    data.pitch      = fontFace.Glyph.BitmapTop;
                    data.forward    = fontFace.Glyph.BitmapLeft;

                    data.aX         = fontFace.Glyph.Metrics.HorizontalAdvance;
                    data.aY         = fontFace.Glyph.Metrics.VerticalAdvance;

                    charCache.Add(item, data);
                }
                else
                {
                    data = charCache[item];
                }

                wX     += data.aX / 64;

                if (fontFace.HasKerning && previous != 0 && current != 0)
                {
                    var kInfo = fontFace.GetKerning(previous, current, KerningMode.Default);

                    wX += kInfo.X / 64;

                    data.kX = kInfo.X / 64;
                    data.kY = kInfo.Y / 64;
                }

                previous = current;
            }

            xB = Math.Abs(fontFace.Size.Metrics.Descender / 64);
            wY = fontFace.Size.Metrics.Height / 64;

            DateTime iTimeF = DateTime.Now;

            Console.WriteLine("Time in letting freetype render the glyphs: {0} milliseconds.", (iTimeF - iTimeS).TotalMilliseconds);

            bmp = new Bitmap(wX, wY);

            int[] map = new int[wX * wY];

            for (int i = 0; i < map.Length; i++ )
            {
                map[i] = 0;
            }

            current     = 0;
            previous    = 0;

            DateTime timeS = DateTime.Now;

            for (int i = 0; i < hello.Length; i++)
            {
                GlyphData pdata = charCache[hello[i]];

                for (int y = 0; y < pdata.height; y++)
                {
                    for (int x = 0; x < pdata.width; x++)
                    {
                        int fx = x + pX + pdata.forward;
                        int fy = wY - pdata.pitch + y - xB;

                        fy = y + (wY - pdata.pitch - xB);

                        if (fy < 0 || fy >= wY)
                        {
                            //Console.WriteLine("Overflow on fy! :(");
                            continue;
                        }

                        if (fx < 0 || fx >= wX)
                        {
                            //Console.WriteLine("Overflow on fx! :(");
                            continue;
                        }

                        int fdata = pdata.buffer[y * pdata.width + x] + map[fy * wX + fx];

                        if (fdata >= 255)
                            fdata = 255;

                        map[fy * wX + fx] = (fdata << 24);
                    }
                }

                pX += pdata.aX / 64;
                pX += pdata.kX;
            }

            BitmapData bData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

            Marshal.Copy(map, 0, bData.Scan0, map.Length);

            bmp.UnlockBits(bData);

            map = null;

            DateTime timeF = DateTime.Now;

            Console.WriteLine("Time in mapping them pixels: {0} milliseconds.", (timeF- timeS).TotalMilliseconds);

            GC.Collect();

            ClientSize      = new System.Drawing.Size(wX, wY);
            StartPosition   = FormStartPosition.CenterScreen;

            BackColor       = Color.White;

            Invalidate();
        }