예제 #1
0
        private void TestRun()
        {
            outputPictureBox?.Image?.Dispose();
            var img = new Bitmap(1024, 600, PixelFormat.Format24bppRgb);

            using (var g = Graphics.FromImage(img)){
                g.FillRectangle(Brushes.White, 0, 400, 1024, 600);
            }

            var daveFnt   = new TrueTypeFont("dave.ttf");             // a font that uses only straight edges (easy to render)
            var notoFnt   = new TrueTypeFont("NotoSans-Regular.ttf"); // standard professional font
            var bendyFnt  = new TrueTypeFont("bendy.ttf");            // a font with extreme curves for testing segmentation
            var guthenFnt = new TrueTypeFont("guthen_bloots.ttf");    // a curvy font

            _infoWindow = new FontInfoWindow();
            _infoWindow.SetFont(daveFnt);
            _infoWindow.Show();

            _glyphWindow = new GlyphView();
            _glyphWindow.SetFont(notoFnt);
            _glyphWindow.Show();

            var msg_1 = "Hello, world! i0($} ▚ ¾ ∜ -_¬~";
            var msg_2 = "Got to be funky. CQUPOJ8";
            var msg_3 = "0123456789\nBut, in a larger sense, we can not dedicate - we can not consecrate—we can not hallow—this ground. The brave men,\n" +
                        "living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will\n" +
                        "little note, nor long remember what we say here, but it can never forget what they did here.";
            var msg_4 = "ABCDE";

            var memBefore = GC.GetTotalMemory(false);

            var sw = new Stopwatch();

            sw.Start();

            var   prox        = new FormsBitmap(img);
            float left        = 25;
            float baseline    = 140f;
            float scale       = 48f / daveFnt.Height();
            float letterSpace = 5;

            // Draw first message with angular font
            for (int i = 0; i < msg_1.Length; i++)
            {
                var glyph = daveFnt.ReadGlyph(msg_1[i]);

                Renderers.DrawGlyph(prox, left, baseline, scale, glyph, false);
                left += (float)glyph.xMax * scale;
                left += letterSpace;
            }

            // Draw second message with curvy font
            left     = 25;
            baseline = 200f;
            scale    = 0.05f;
            for (int i = 0; i < msg_2.Length; i++)
            {
                var glyph = guthenFnt.ReadGlyph(msg_2[i]);

                Renderers.DrawGlyph(prox, left, baseline, scale, glyph, false);
                left += (float)glyph.xMax * scale;
                left += letterSpace;
            }

            // Draw second message with very curvy font
            left     = 25;
            baseline = 280f;
            scale    = 0.05f;
            for (int i = 0; i < msg_4.Length; i++)
            {
                var glyph = bendyFnt.ReadGlyph(msg_4[i]);

                Renderers.DrawGlyph(prox, left, baseline, scale, glyph, false);
                left += (float)glyph.xMax * scale;
                left += letterSpace;
            }

            // Draw a much longer message in the angular font
            left        = 5;
            baseline    = 50f;
            scale       = 16f / daveFnt.Height();
            letterSpace = 1.6f;
            for (int i = 0; i < msg_3.Length; i++)
            {
                if (msg_3[i] == '\n')
                {
                    left = 5; baseline += 16; continue;
                }
                var glyph = daveFnt.ReadGlyph(msg_3[i]);

                Renderers.DrawGlyph(prox, left, baseline, scale, glyph, false);
                left += (float)glyph.xMax * scale;
                left += letterSpace;
            }


            // Show a sample of the sub-pixel AA strategy
            left        = 5;
            baseline    = 300f;
            scale       = 16f / daveFnt.Height(); // about 11pt
            letterSpace = 2;
            for (int i = 0; i < 58; i++)
            {
                var glyph = daveFnt.ReadGlyph((char)('A' + i));
                Renderers.RenderSubPixel_RGB_Super3(prox, left, baseline + 20, scale, glyph, false);
                left += (float)glyph.xMax * scale;
                left += letterSpace;
            }

            left     = 5;
            baseline = 320f;
            scale    = 12f / notoFnt.Height();
            for (int i = 0; i < 58; i++)
            {
                var glyph = notoFnt.ReadGlyph((char)('A' + i));
                Renderers.RenderSubPixel_RGB_Super3(prox, left, baseline + 20, scale, glyph, false);
                left += (float)glyph.xMax * scale;
                left += letterSpace;
            }
            left     = 5;
            baseline = 340f;
            scale    = 10f / notoFnt.Height();
            for (int i = 0; i < 58; i++)
            {
                var glyph = notoFnt.ReadGlyph((char)('A' + i));
                Renderers.RenderSubPixel_RGB_Super3(prox, left, baseline + 20, scale, glyph, false);
                left += (float)glyph.xMax * scale;
                left += letterSpace;
            }

            left        = 5;
            baseline    = 350f;
            scale       = 10f / daveFnt.Height(); // very small.
            letterSpace = 1.5f;
            for (int i = 0; i < 58; i++)
            {
                var glyph = daveFnt.ReadGlyph((char)('A' + i));
                Renderers.RenderSubPixel_RGB_Super3(prox, left, baseline + 30, scale, glyph, false);
                left += (float)glyph.xMax * scale;
                left += letterSpace;
            }


            // Demonstrate black-on-white
            left        = 5;
            baseline    = 400f;
            scale       = 16f / daveFnt.Height(); // about 11pt
            letterSpace = 2.1f;
            for (int i = 0; i < 58; i++)
            {
                var glyph = daveFnt.ReadGlyph((char)('A' + i));
                Renderers.RenderSubPixel_RGB_Super3(prox, left, baseline + 20, scale, glyph, true);
                Renderers.RenderSubPixel_RGB_Super3(prox, left, baseline + 35, scale * 0.6f, glyph, true);
                left += (float)glyph.xMax * scale;
                left += letterSpace;
            }

            // Varying size
            left        = 5;
            baseline    = 480f;
            scale       = 4f / notoFnt.Height();
            letterSpace = 0.8f;
            var ampGlyph = notoFnt.ReadGlyph('&');//daveFnt.ReadGlyph('Η');

            for (int i = 0; i < 50; i++)
            {
                scale += 0.001f;
                Renderers.DrawGlyph(prox, left, baseline, scale, ampGlyph, true);
                left += (float)ampGlyph.xMax * scale;
                left += letterSpace;
            }

            // Large black-on-white
            left        = 25;
            baseline    = 540f;
            scale       = 70f / notoFnt.Height();
            letterSpace = 5;
            for (int i = 0; i < msg_1.Length; i++)
            {
                var glyph = notoFnt.ReadGlyph(msg_1[i]);

                Renderers.DrawGlyph(prox, left, baseline, scale, glyph, true);
                left += (float)glyph.xMax * scale;
                left += letterSpace;
            }

            // Huge curve
            scale = 370f / notoFnt.Height();
            for (int i = 0; i < 1; i++)
            {
                var glyph = notoFnt.ReadGlyph('&'); // Show quality of curve-to-line interpolation
                Renderers.DrawGlyph(prox, 600, 350, scale, glyph, false);
            }


            sw.Stop();
            Text = "Glyph find & render took: " + sw.Elapsed;

            // Prove that the render cache works:
            scale = 10f / notoFnt.Height();
            var nullProx = new NullProxy();

            sw.Reset();
            sw.Start();
            for (int i = 0; i < 200_000; i++)
            {
                var glyph = notoFnt.ReadGlyph((char)('a' + (i % 52)));
                Renderers.RenderSubPixel_RGB_Super3(nullProx, 0, 0, scale, glyph, false);
            }
            sw.Stop();
            Text += "; Render stress test: " + sw.Elapsed;

            var memAfter = GC.GetTotalMemory(false);

            Text += "; Memory use: " + ((memAfter - memBefore) / 1048576) + "MB";

            outputPictureBox.Image = img;
            Width  = img.Width + 18;
            Height = img.Height + 41;
        }