Esempio n. 1
0
        internal void Launch()
        {
            Console.WriteLine("Bezier...");
            Console.WriteLine("    'i': Image.");
            Console.WriteLine("    's': SVG tiger.");
            Console.WriteLine("    't': Text.");

            using var windowServer     = new WindowServer();
            using var renderingContext = new RenderingContext { Settings = new RenderingSettings { Samples = 8 } };
            using var window           = windowServer.CreateWindow(renderingContext);

            window.Title                   = "Bézier";
            window.BorderStyle             = WindowBorderStyle.Sizable;
            window.Size                    = (900, 900);
            renderingContext.CurrentWindow = window;

            var viewportSize       = window.ViewportSize;
            var windowSize         = window.Size;
            var backend            = new DrawingBackend(new EntryPointLoader(renderingContext));
            var openTypeCollection = new OpenTypeCollection();
            var nameId             = typeof(VectorGraphicsLauncher).Namespace + ".Resources.ebrima.ttf";

            openTypeCollection.AddFontResource(nameId, () => Assembly.GetExecutingAssembly().GetManifestResourceStream(nameId) !);
            using var sharedContext  = new SharedDrawingContext(backend, openTypeCollection);
            using var drawingContext = new DrawingContext(sharedContext)
                  {
                      ClearColor = new RgbaColor(155, 155, 155, 255)
                  };
            var redrawRequired = true;

            var images = new List <ImageDrawing>();
            var paths  = new List <PathDrawing>();
            var labels = new List <LabelDrawing>();

            window.TextInput += (sender, e) =>
            {
                switch (e.CodePoint)
                {
                case 'i':
                {
                    var image      = new RasterImage();
                    var namePrefix = typeof(DrawTextureLauncher).Namespace + ".Resources.";
                    using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(namePrefix + "kitten.png"))
                    {
                        image.LoadPng(stream ?? throw new InvalidOperationException());
                    }
                    var imageDrawing = new ImageDrawing()
                    {
                        Image = image
                    };
                    images.Add(imageDrawing);
                    redrawRequired = true;
                }
                break;

                case 's':
                {
                    images.Clear();
                    paths.Clear();
                    labels.Clear();

                    var sw = new System.Diagnostics.Stopwatch();
                    sw.Start();

                    var pathReader = new SvgPathReader();
                    var transform  = new AffineTransform(m11: 1.76, m22: 1.76, m31: 325, m32: 255);

                    var       namePrefix = typeof(VectorGraphicsLauncher).Namespace + ".Resources.";
                    XDocument document;
                    using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(namePrefix + "Ghostscript_Tiger.svg"))
                    {
                        document = XDocument.Load(stream);
                    }
                    XNamespace ns    = "http://www.w3.org/2000/svg";
                    var        rootG = document.Element(ns + "svg").Element(ns + "g");
                    foreach (var g in rootG.Elements(ns + "g"))
                    {
                        var path = new PathDrawing
                        {
                            Transform = transform
                        };
                        paths.Add(path);
                        foreach (var a in g.Attributes())
                        {
                            switch (a.Name.LocalName)
                            {
                            case "fill":
                                path.FillColor = ParseSvgColor(a.Value);
                                break;

                            case "stroke":
                                path.StrokeColor = ParseSvgColor(a.Value);
                                break;

                            case "stroke-width":
                                path.StrokeWidth = float.Parse(a.Value);
                                break;
                            }
                        }
                        pathReader.PathData = g.Element(ns + "path").Attribute("d").Value;
                        var x        = 0f;
                        var y        = 0f;
                        var initialX = 0f;
                        var initialY = 0f;
                        (double x, double y)c2 = (0, 0);
                        bool hasPreviousC2 = false;
                        while (pathReader.Read())
                        {
                            switch (pathReader.PathCommand)
                            {
                            case PathCommandType.MoveTo:
                                x = pathReader.X;
                                y = pathReader.Y;
                                path.Move((x, y));
                                initialX      = x;
                                initialY      = y;
                                hasPreviousC2 = false;
                                break;

                            case PathCommandType.MoveToRelative:
                                x += pathReader.X;
                                y += pathReader.Y;
                                path.Move((x, y));
                                initialX      = x;
                                initialY      = y;
                                hasPreviousC2 = false;
                                break;

                            case PathCommandType.LineToRelative:
                                x += pathReader.X;
                                y += pathReader.Y;
                                path.AddLine((x, y));
                                hasPreviousC2 = false;
                                break;

                            case PathCommandType.CurveToRelative:
                            {
                                var c1 = ((double)x + pathReader.X1, (double)y + pathReader.Y1);
                                c2 = (x + pathReader.X2, y + pathReader.Y2);
                                x += pathReader.X;
                                y += pathReader.Y;
                                path.AddCubicBezier(c1, c2, (x, y));
                                hasPreviousC2 = true;
                            }
                            break;

                            case PathCommandType.SmoothCurveToRelative:
                            {
                                (double x, double y)c1;
                                if (hasPreviousC2)
                                {
                                    c1 = (2 * x - c2.x, 2 * y - c2.y);
                                }
                                else
                                {
                                    c1 = (x, y);
                                }
                                c2 = (x + pathReader.X2, y + pathReader.Y2);
                                x += pathReader.X;
                                y += pathReader.Y;
                                path.AddCubicBezier(c1, c2, (x, y));
                                hasPreviousC2 = true;
                            }
                            break;

                            case PathCommandType.VerticalLineToRelative:
                                y += pathReader.Y;
                                path.AddLine((x, y));
                                hasPreviousC2 = false;
                                break;

                            case PathCommandType.Closepath:
                                path.AddLine((initialX, initialY));
                                hasPreviousC2 = false;
                                break;

                            default:
                                Console.WriteLine("Unhandled command: " + pathReader.PathCommand);
                                break;
                            }
                        }
                    }
                    sw.Stop();
                    Console.WriteLine($"SVG file decoded in {sw.ElapsedMilliseconds}ms ({paths.Count} paths).");
                    redrawRequired = true;
                }
                break;

                case 't':
                {
                    images.Clear();
                    paths.Clear();
                    labels.Clear();

                    var label = new LabelDrawing
                    {
                        Transform     = new AffineTransform(m11: 4, m22: 4, m31: 20, m32: 50),
                        FontFamily    = "Ebrima",
                        FontSubfamily = FontSubfamily.Normal,
                        FontPoints    = 8
                    };
                    label.AppendString("The quick brown fox jumps over the lazy dog.");
                    labels.Add(label);

                    for (int i = 0; i < 15; i++)
                    {
                        label = new LabelDrawing
                        {
                            Transform     = new AffineTransform(m11: 1, m22: 1, m31: 20, m32: 100 + i * 30),
                            FontFamily    = "Ebrima",
                            FontSubfamily = FontSubfamily.Normal,
                            FontPoints    = 32 - i * 2
                        };
                        label.AppendString("The quick brown fox jumps over the lazy dog.");
                        labels.Add(label);
                    }
                    redrawRequired = true;
                }
                break;
                }
            };

            void draw()
            {
                var sw = new System.Diagnostics.Stopwatch();

                sw.Start();

                renderingContext.CurrentWindow            = window;
                drawingContext.SharedContext.PixelScaling = viewportSize.height / windowSize.height;

                drawingContext.StartDrawing();

                foreach (var image in images)
                {
                    image.Draw(drawingContext);
                }
                foreach (var path in paths)
                {
                    path.Draw(drawingContext);
                }
                foreach (var label in labels)
                {
                    label.Draw(drawingContext, 0, 0);
                }

                drawingContext.FinishDrawing();
                renderingContext.SwapBuffers(window);

                sw.Stop();
                Console.WriteLine($"Drawn in {sw.ElapsedMilliseconds}ms.");
            }

            void resize()
            {
                viewportSize       = window.ViewportSize;
                windowSize         = window.Size;
                backend.WindowSize = windowSize;
            }

            window.Resize += (sender, e) =>
            {
                resize();
                draw();
            };

            var runLoop = MainRunLoop.Create(windowServer);

            window.Closed += (sender, e) =>
            {
                drawingContext.Dispose();
                backend.Dispose();
                runLoop.Interrupt();
            };

            resize();
            runLoop.RecurringActions.Add((delay) =>
            {
                if (redrawRequired)
                {
                    draw();
                    redrawRequired = false;
                }
            });

            window.Visible = true;
            runLoop.Run();
            Console.WriteLine("Bezier done.");
        }
Esempio n. 2
0
        internal void Launch()
        {
            Console.WriteLine("Text Area...");

            using var windowServer = new WindowServer();
            using var renderingContext = new RenderingContext { Settings = new RenderingSettings { Samples = 8 } };
            using var window = windowServer.CreateWindow(renderingContext);

            window.Title = "Text Area";
            window.BorderStyle = WindowBorderStyle.Sizable;
            window.Size = (900, 900);
            renderingContext.CurrentWindow = window;

            var viewportSize = window.ViewportSize;
            var windowSize = window.Size;
            var backend = new DrawingBackend(new EntryPointLoader(renderingContext))
            {
                PixelScaling = viewportSize.height / windowSize.height
            };

            var openTypeCollection = new OpenTypeCollection();
            var nameId = typeof(VectorGraphicsLauncher).Namespace + ".Resources.Hack-Regular.ttf";
            openTypeCollection.AddFontResource(nameId, () => Assembly.GetExecutingAssembly().GetManifestResourceStream(nameId)!);

            using var sharedContext = new SharedDrawingContext(backend, openTypeCollection);
            using var drawingContext = new DrawingContext(sharedContext)
            {
                ClearColor = new RgbaColor(35, 35, 35, 255)
            };

            var styles = new MonospaceTextStyles(256);
            var fontSubfamily = openTypeCollection.LookupFontSubfamily("Hack", FontSubfamily.Normal);
            styles.GetStyle(fontSubfamily, new RgbaColor(255, 255, 255, 255), new RgbaColor(0, 0, 0, 0));
            var textArea = new TextArea(styles, "Hack", fontSubfamily, 9);
            var path = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly()!.Location)!, "..", "..", "..", "TextAreaLauncher.cs");
            textArea.Load(path);
            const int textLeft = 20;
            const int textTop = 30;

            window.Scroll += (sender, e) =>
            {
                textArea.ScrollVertically(e.DeltaY * 30);
            };

            var hideCaret = true;

            window.KeyDown += (sender, e) =>
            {
                switch (e.Keycode)
                {
                    case Keycode.Up:
                        textArea.MoveUp();
                        hideCaret = false;
                        break;
                    case Keycode.Down:
                        textArea.MoveDown();
                        hideCaret = false;
                        break;
                    case Keycode.Left:
                        textArea.MoveLeft();
                        hideCaret = false;
                        break;
                    case Keycode.Right:
                        textArea.MoveRight();
                        hideCaret = false;
                        break;
                    case Keycode.F11:
                        textArea.FontPoints--;
                        break;
                    case Keycode.F12:
                        textArea.FontPoints++;
                        break;
                    case Keycode.Backspace:
                        textArea.Backspace();
                        hideCaret = false;
                        break;
                    case Keycode.Tab:
                        textArea.Tab();
                        hideCaret = false;
                        break;
                    case Keycode.Enter:
                        textArea.Enter();
                        hideCaret = false;
                        break;
                }
            };

            window.TextInput += (sender, e) =>
            {
                textArea.Insert(e.CodePoint);
                hideCaret = false;
            };

            window.MouseDown += (sender, e) =>
            {
                if (e.ChangedButton == MouseButton.Left)
                {
                    var (x, y) = window.CursorPosition;
                    textArea.LeftMouseDown(x, y);
                    hideCaret = false;
                }
            };

            var interruptThread = false;

            void draw()
            {
                renderingContext.CurrentWindow = window;
                drawingContext.SharedContext.PixelScaling = viewportSize.height / windowSize.height;

                drawingContext.StartDrawing();

                textArea.Render(drawingContext);

                drawingContext.FinishDrawing();

                renderingContext.SwapBuffers(window);
            }

            void resize()
            {
                viewportSize = window.ViewportSize;
                windowSize = window.Size;
                renderingContext.CurrentWindow = window;
                backend.WindowSize = windowSize;
                textArea.SetViewRectangle(textLeft, textTop, (windowSize.width - textLeft - 30), (windowSize.height - textTop - 50));
            }

            window.Resize += (sender, e) =>
            {
                resize();
                draw();
            };

            var runLoop = MainRunLoop.Create(windowServer);
            var text = default(DecoratedText<byte>);
            var version = 0;
            var th = new Thread(() =>
            {
                var regexList = new List<Regex>();
                var styleList = new List<MonospaceTextStyle>();

                regexList.Add(new Regex("\\b(break|case|class|const|else|false|float|for|foreach|" +
                    "if|int|internal|public|namespace|new|unsafe|using|string|switch|true|var|void)\\b"));
                styleList.Add(styles.GetStyle(fontSubfamily, new RgbaColor(81, 153, 213, 255), new RgbaColor(0, 0, 0, 0)));

                regexList.Add(new Regex(@"\b-?\d+(,\d+)*(\.\d+((e|E)\d+)?)?\b"));
                styleList.Add(styles.GetStyle(fontSubfamily, new RgbaColor(0, 0, 0, 255), new RgbaColor(230, 180, 50, 255)));

                regexList.Add(new Regex(@"""(\\.|[^""\\])*"""));
                styleList.Add(styles.GetStyle(fontSubfamily, new RgbaColor(250, 180, 230, 255), new RgbaColor(0, 0, 0, 0)));

                while (!interruptThread)
                {
                    var t = text;
                    text = null;
                    var v = version;
                    if (t != null)
                    {
                        var txt = new StyledMonospaceText(t, styles);
                        var builder = new StringBuilder();
                        for (int i = 0; i < txt.LineCount; i++)
                        {
                            builder.Clear();
                            txt.CopyLineTo(i, builder);
                            var str = builder.ToString();
                            for (int j = 0; j < regexList.Count; j++)
                            {
                                var m = regexList[j].Match(str);
                                var s = styleList[j];
                                while (m.Success)
                                {
                                    txt.StyleRange(s, (i, m.Index), (i, m.Index + m.Length));
                                    m = m.NextMatch();
                                }
                            }
                        }
                        void f(int currentVersion, StyledMonospaceText newText)
                        {
                            runLoop.InvokeLater(0, (lag) =>
                            {
                                if (textArea.Version == currentVersion)
                                {
                                    textArea.SetText(newText);
                                }
                            });
                        }
                        f(v, txt);
                    }
                    Thread.Sleep(500);
                }
            });

            void blink(long lag)
            {
                textArea.HideCaret = hideCaret;
                hideCaret = !hideCaret;
                if (textArea.RequireRestyle)
                {
                    text = textArea.GetText();
                    version = textArea.Version;
                }
                runLoop.InvokeLater(500, blink);
            }

            runLoop.InvokeLater(500, blink);

            window.Closed += (sender, e) =>
            {
                backend.Dispose();
                runLoop.Interrupt();
                interruptThread = true;
            };

            resize();
            runLoop.RecurringActions.Add((time) =>
            {
                if (textArea.RequireRender)
                {
                    draw();
                }
            });
            th.Start();
            window.Visible = true;
            runLoop.Run();

            Console.WriteLine("Text Area done.");
        }