예제 #1
0
파일: Resources.cs 프로젝트: fealty/Frost
        public static Canvas CreateIcon(Device2D device2D)
        {
            Contract.Requires(device2D != null);

            int width;
            int height;

            byte[] rgbaData;

            using(Icon icon = new Icon(Properties.Resources.frost_icon, 256, 256))
            {
                using(Bitmap bitmap = icon.ToBitmap())
                {
                    width = bitmap.Width;
                    height = bitmap.Height;

                    rgbaData = new byte[width * height * 4];

                    int index = 0;

                    for(int y = 0; y < height; ++y)
                    {
                        for(int x = 0; x < width; ++x)
                        {
                            System.Drawing.Color pixel = bitmap.GetPixel(x, y);

                            float alpha = pixel.A / 255.0f;

                            rgbaData[index + 0] = Convert.ToByte(pixel.R * alpha);
                            rgbaData[index + 1] = Convert.ToByte(pixel.G * alpha);
                            rgbaData[index + 2] = Convert.ToByte(pixel.B * alpha);
                            rgbaData[index + 3] = pixel.A;

                            index += 4;
                        }
                    }
                }
            }

            Canvas canvas = new Canvas(new Size(width, height), SurfaceUsage.Normal);

            device2D.Resources.Copy(rgbaData, canvas);

            return canvas;
        }
예제 #2
0
        public Canvas CreateField(Shape geometry, double normalizedBaseline, Device2D device2D)
        {
            Rectangle normalizedRegion = device2D.Geometry.MeasureRegion(geometry);

            Matrix3X2 transform = Matrix3X2.Identity;

            transform.Translate(
                (0.5f - (normalizedRegion.Width / 2.0f)) * EmLength,
                (0.5f - (normalizedRegion.Height / 2.0f)) * EmLength,
                out transform);

            transform.Translate(
                -normalizedRegion.X * EmLength, -normalizedRegion.Y * EmLength, out transform);

            transform.Scale(EmLength, EmLength, out transform);

            mDecomposer.Decompose(geometry, ref transform, device2D);

            Rectangle newReg = new Rectangle(0, 0, EmLength, EmLength);

            mSample = ComputeTree(ref newReg, device2D);

            float maxNegative = float.MinValue;

            float pixel = EmLength / ResolvedLength;

            for(int y = 0; y < ResolvedLength; ++y)
            {
                for(int x = 0; x < ResolvedLength; ++x)
                {
                    float distance = 0.0f;

                    Point point = new Point((pixel * x), (pixel * y));

                    distance += mSample.SampleSample(ref point);

                    maxNegative = Math.Max(maxNegative, distance);

                    mField[y, x] = distance;
                }
            }

            int rgbaIndex = 0;

            for(int y = 0; y < ResolvedLength; ++y)
            {
                for(int x = 0; x < ResolvedLength; ++x)
                {
                    double distance = mField[y, x];

                    const double test = 0.5;

                    if(distance < 0.0)
                    {
                        distance = Math.Abs(distance) / Math.Abs(maxNegative);

                        distance = test + ((1.0 - test) * distance);
                    }
                    else
                    {
                        distance = Math.Abs(distance) / Math.Abs(maxNegative);

                        distance = test - (test * distance);
                    }

                    distance = Math.Min(1.0, distance);
                    distance = Math.Max(0.0, distance);

                    byte value = Convert.ToByte(255 - (distance * 255));

                    //byte[] bytes = BitConverter.GetBytes(value);

                    mRgbaData[rgbaIndex + 0] = 0;
                    mRgbaData[rgbaIndex + 1] = 0;
                    mRgbaData[rgbaIndex + 2] = 0;
                    mRgbaData[rgbaIndex + 3] = value;

                    rgbaIndex += 4;
                }
            }

            Canvas newCanvas = new Canvas(new Size(ResolvedLength, ResolvedLength), Frost.Surfacing.SurfaceUsage.Normal);

            device2D.Resources.Copy(mRgbaData, newCanvas);

            return newCanvas;
        }
예제 #3
0
        public void Render(Canvas canvas, Device2D device2D)
        {
            Contract.Requires(canvas != null);
            Contract.Requires(device2D != null);

            IntPtr sharedHandle = canvas.GetDeviceHandle(device2D);

            if(sharedHandle != _SharedHandle)
            {
                _SharedMutex.SafeDispose();
                _DependentView.SafeDispose();
                _SharedTexture.SafeDispose();

                _SharedMutex = null;
                _DependentView = null;
                _SharedTexture = null;

                if(sharedHandle != IntPtr.Zero)
                {
                    _SharedTexture = _Device3D.OpenSharedResource<Texture2D>(sharedHandle);

                    _SharedMutex = _SharedTexture.QueryInterface<KeyedMutex>();

                    _DependentView = new ShaderResourceView(_Device3D, _SharedTexture);

                    _SharedHandle = sharedHandle;
                }
            }

            if(_SharedMutex != null)
            {
                _SharedMutex.AcquireSync();

                try
                {
                    if(_SharedTexture != null)
                    {
                        var textureVariable = _Effect.GetVariableByName("tex2D");

                        Contract.Assert(textureVariable != null);

                        var shaderResource = textureVariable.AsShaderResource();

                        Contract.Assert(shaderResource != null);

                        shaderResource.SetResource(_DependentView);

                        _EffectPass.Apply();

                        _Device3D.Draw(_VertexCount, 0);
                    }
                }
                finally
                {
                    _SharedMutex.ReleaseSync();
                }
            }
        }
예제 #4
0
파일: Program.cs 프로젝트: fealty/Frost
        public void Reset(Canvas target, Device2D device2D)
        {
            ShapedText shapedOutput = new ShapedText();

            const string plainText = "Hello world!";

            device2D.TextShaper.Begin(shapedOutput, plainText);

            device2D.TextShaper.AnalyzeScripts();

            device2D.TextShaper.SetPointSize(plainText, 95.0f);

            device2D.TextShaper.End();

            List<GlyphOutline> outlines = new List<GlyphOutline>();

            foreach(TextShaper.Span span in shapedOutput.Spans)
            {
                foreach(int clusterIndex in span.Clusters)
                {
                    TextShaper.Cluster cluster = shapedOutput.Clusters[clusterIndex];

                    outlines.Add(
                        device2D.Resources.GetGlyphOutline(
                            cluster.Glyphs,
                            false,
                            false,
                            span.FontMetrics.FontId,
                            shapedOutput.Glyphs));
                }
            }

            device2D.Painter.Begin(target);

            device2D.Painter.SetBrush(Resources.Foreground);

            foreach(TextShaper.Span span in shapedOutput.Spans)
            {
                float emSize = span.FontMetrics.MeasureEm(span.PointSize);

                foreach(int clusterIndex in span.Clusters)
                {
                    float advance = shapedOutput.Clusters[clusterIndex].Advance;

                    if (_AreRegionsDisplayed)
                    {
                        device2D.Painter.SaveState();

                        device2D.Painter.StrokeWidth = 0.5f;
                        device2D.Painter.LineStyle = LineStyle.Dash;

                        device2D.Painter.SetBrush(Color.Red);
                        device2D.Painter.StrokeRectangle(0, 0, advance, emSize);
                        device2D.Painter.SetBrush(Resources.Foreground);

                        device2D.Painter.RestoreState();
                    }

                    float baseline = outlines[clusterIndex].Baseline;

                    device2D.Painter.SaveState();

                    device2D.Painter.Scale(emSize, emSize);
                    device2D.Painter.Translate(0, baseline);

                    if(outlines[clusterIndex].Shape != null)
                    {
                        device2D.Painter.Fill(outlines[clusterIndex].Shape);
                    }

                    device2D.Painter.RestoreState();

                    device2D.Painter.Translate(advance, 0);
                }
            }

            device2D.Painter.End();
        }
예제 #5
0
        private void HandleClientSizeChanged(object sender, EventArgs e)
        {
            // reconfigure the direct3d rendering surface
            _Device.OutputMerger.SetTargets((RenderTargetView)null);

            if(_RenderView != null)
            {
                _RenderView.Dispose();
            }

            _SwapChain.ResizeBuffers(
                1,
                Math.Max(1, _Form.ClientSize.Width),
                Math.Max(1, _Form.ClientSize.Height),
                Format.R8G8B8A8_UNorm,
                0);

            using(var backBuffer = Resource.FromSwapChain<Texture2D>(_SwapChain, 0))
            {
                _RenderView = new RenderTargetView(_Device, backBuffer);
            }

            _Device.OutputMerger.SetTargets(_RenderView);

            Viewport view = new Viewport
            {
                X = 0,
                Y = 0,
                Width = _Form.ClientSize.Width,
                Height = _Form.ClientSize.Height,
                MinDepth = 0.0f,
                MaxDepth = 1.0f
            };

            _Device.Rasterizer.SetViewports(view);

            // reconfigure the Frost rendering surface
            Size formSize = new Size(_Form.ClientSize.Width, _Form.ClientSize.Height);

            if(_Target != null)
            {
                _Target.Forget();
            }

            _Target = new Canvas(formSize, SurfaceUsage.External);

            formSize = new Size(Math.Max(formSize.Width, 640), Math.Max(formSize.Height, 480));

            _Device2D.Resources.PageSize = new Size(formSize.Width * 2, formSize.Height * 2);

            _IsResetQueued = true;
        }
예제 #6
0
        public static void ResetDemo(
			IDemoContext context, Canvas target, Device2D device2D)
        {
            Contract.Requires(context != null);
            Contract.Requires(target != null);
            Contract.Requires(device2D != null);

            Rectangle left = Rectangle.FromEdges(
                0, 0, 213, target.Region.Bottom);
            Rectangle middle = Rectangle.FromEdges(
                left.Right, 0, target.Region.Right - 213, target.Region.Bottom);
            Rectangle right = Rectangle.FromEdges(
                middle.Right, 0, target.Region.Right, target.Region.Bottom);

            Rectangle demoRegion = middle.Contract(25);

            // create a new canvas for the demo contents
            Canvas demoTarget = new Canvas(demoRegion.Size);

            // resolve the new resource to avoid timing problems
            device2D.Resources.ResolveCanvas(demoTarget);

            // track memory usage and reset the clock
            long oldMemoryUsage = GC.GetTotalMemory(true);

            _Watch.Reset();
            _Watch.Start();

            // execute the demo
            context.Reset(demoTarget, device2D);

            // stop the clock and determine the garbage produced
            _Watch.Stop();

            long memoryDelta = GC.GetTotalMemory(false) - oldMemoryUsage;

            // query the subsystem timers
            IDeviceCounter<TimeSpan> compositionFrameDuration;
            IDeviceCounter<TimeSpan> paintingFrameDuration;

            device2D.Diagnostics.Query(
                "Composition", "FrameDuration", out compositionFrameDuration);
            device2D.Diagnostics.Query(
                "Painting", "FrameDuration", out paintingFrameDuration);

            ////////////////////////////////
            string timeString = string.Format(
                "Time Taken: {0} ms", _Watch.ElapsedMilliseconds);

            Rectangle timeMetrics = MeasureText(timeString, device2D);

            Rectangle timeRegion = timeMetrics.AlignRelativeTo(
                middle, Alignment.Center, Axis.Horizontal);

            /////////////////////////////
            string subsystemString =
                string.Format(
                    "Painting: {0} ms \u2219 Composition: {1} ms",
                    paintingFrameDuration.Value.Milliseconds,
                    compositionFrameDuration.Value.Milliseconds);

            Rectangle subsystemMetrics = MeasureText(subsystemString, device2D);

            Rectangle subsystemRegion = subsystemMetrics.AlignRelativeTo(
                middle, Alignment.Center, Axis.Horizontal);

            subsystemRegion = subsystemRegion.Translate(
                0, middle.Bottom - subsystemRegion.Height);

            ////////////////////////////////
            string memoryString = string.Format(
                "Memory: {0:N0} KB", GC.GetTotalMemory(true) / 1024);

            string garbageString = string.Format(
                "Garbage: {0:N0} KB", memoryDelta / 1024);

            const string snapshotString = "SNAPSHOT";

            Rectangle snapshotMetrics = MeasureText(snapshotString, device2D);

            const string optionsString = "OPTIONS";

            Rectangle optionsMetrics = MeasureText(optionsString, device2D);

            snapshotMetrics = snapshotMetrics.AlignRelativeTo(
                right, Alignment.Center, Axis.Horizontal);
            optionsMetrics = optionsMetrics.AlignRelativeTo(
                left, Alignment.Center, Axis.Horizontal);

            device2D.Painter.Begin(target);

            // clear the background to the background color
            device2D.Painter.SetBrush(Resources.Background);
            device2D.Painter.FillRectangle(target.Region);

            device2D.Painter.SetBrush(Resources.UIColor);

            device2D.Painter.FillRectangle(left);
            device2D.Painter.FillRectangle(right);

            Rectangle timePanel = timeRegion.Expand(
                timeRegion.Height,
                timeRegion.Height,
                timeRegion.Height,
                timeRegion.Height / 4.0f);

            device2D.Painter.FillRectangle(
                timePanel, new Size(timeRegion.Height / 2.0f));

            Rectangle subsystemPanel = subsystemRegion.Expand(
                subsystemRegion.Height,
                subsystemRegion.Height / 4.0f,
                subsystemRegion.Height,
                subsystemRegion.Height);

            device2D.Painter.FillRectangle(
                subsystemPanel, new Size(subsystemRegion.Height / 2.0f));

            device2D.Painter.SetBrush(Resources.ActiveButton);

            device2D.Painter.SaveState();
            device2D.Painter.LineStyle = LineStyle.Dash;
            device2D.Painter.StrokeRectangle(demoRegion.Expand(1));
            device2D.Painter.RestoreState();

            device2D.Painter.StrokeLine(
                left.Right, left.Top, left.Right, left.Bottom);
            device2D.Painter.StrokeLine(
                right.Left, right.Top, right.Left, right.Bottom);

            device2D.Painter.SetBrush(Resources.Foreground);

            device2D.Painter.SaveState();
            device2D.Painter.Translate(timeRegion.X, timeRegion.Y);
            DrawText(Point.Empty, timeString, device2D);
            device2D.Painter.RestoreState();

            device2D.Painter.SaveState();
            device2D.Painter.Translate(subsystemRegion.X, subsystemRegion.Y);
            DrawText(Point.Empty, subsystemString, device2D);
            device2D.Painter.RestoreState();

            device2D.Painter.SaveState();

            device2D.Painter.Translate(0, timeRegion.Height);

            DrawText(snapshotMetrics.Location, snapshotString, device2D);

            device2D.Painter.StrokeLine(
                snapshotMetrics.Left,
                snapshotMetrics.Bottom,
                snapshotMetrics.Right,
                snapshotMetrics.Bottom);

            device2D.Painter.Translate(
                right.Left + (timeRegion.Height / 2.0f),
                (timeRegion.Height * 2) + (timeRegion.Height * 0.25f));

            DrawText(Point.Empty, memoryString, device2D);

            device2D.Painter.Translate(
                0, (timeRegion.Height * 2) + (timeRegion.Height * 0.25f));

            DrawText(Point.Empty, garbageString, device2D);

            device2D.Painter.RestoreState();

            device2D.Painter.SaveState();

            device2D.Painter.Translate(0, timeRegion.Height);

            DrawText(optionsMetrics.Location, optionsString, device2D);

            device2D.Painter.StrokeLine(
                optionsMetrics.Left,
                optionsMetrics.Bottom,
                optionsMetrics.Right,
                optionsMetrics.Bottom);

            device2D.Painter.RestoreState();

            GenerateMenu(
                context,
                target,
                device2D,
                (timeRegion.Height * 3) + (timeRegion.Height * 0.25f),
                left.Width);

            device2D.Painter.End();

            device2D.Compositor.Begin(target, Retention.RetainData);
            device2D.Compositor.Composite(demoTarget, demoRegion.Location);
            device2D.Compositor.End();
        }
예제 #7
0
        private static void GenerateMenu(
			IDemoContext context,
			Canvas target,
			Device2D device2D,
			float listTop,
			float listWidth)
        {
            Contract.Requires(context != null);
            Contract.Requires(target != null);
            Contract.Requires(device2D != null);

            var items = new List<KeyValuePair<string, KeyValuePair<Rectangle, bool>>>();

            Rectangle region = target.Region;

            region = region.Translate(0, listTop);

            float itemHeight = 0.0f;
            float itemSpacing = 0.0f;

            Thickness itemExpansion = Thickness.Empty;

            foreach(var item in context.Settings)
            {
                string currentText = item.IsActive ? item.ActiveText : item.InactiveText;

                string finalText = string.Format(
                    "[{0}] {1}", items.Count + 1, currentText);

                var metrics = MeasureText(finalText, device2D);

                metrics = metrics.Translate(region.Location);

                if(itemHeight.Equals(0.0f) && itemSpacing.Equals(0.0f))
                {
                    itemHeight = metrics.Height * 2.00f;
                    itemSpacing = metrics.Height * 0.25f;
                    itemExpansion = new Thickness(itemHeight / 4.0f);
                }

                items.Add(
                    new KeyValuePair<string, KeyValuePair<Rectangle, bool>>(
                        finalText, new KeyValuePair<Rectangle, bool>(metrics, item.IsActive)));

                region = region.Translate(0, itemHeight + itemSpacing);
            }

            for(int index = 0; index < items.Count; index++)
            {
                var item = items[index];

                Rectangle settingRegion = item.Value.Key.Expand(itemExpansion);

                settingRegion = settingRegion.Resize(listWidth, settingRegion.Height);
                settingRegion = settingRegion.Expand(itemHeight, 0, 0, 0);

                device2D.Painter.SetBrush(
                    item.Value.Value ? Resources.ActiveButton : Resources.UIColor);
                device2D.Painter.FillRectangle(settingRegion, new Size(itemHeight / 3.0f));

                device2D.Painter.SetBrush(Resources.ActiveButton);
                device2D.Painter.StrokeRectangle(
                    settingRegion, new Size(itemHeight / 3.0f));

                device2D.Painter.SetBrush(
                    item.Value.Value ? Resources.InactiveButton : Resources.Foreground);

                DrawText(item.Value.Key.Location, item.Key, device2D);
            }
        }
예제 #8
0
파일: Program.cs 프로젝트: fealty/Frost
        public void Reset(Canvas target, Device2D device2D)
        {
            if(device2D.Resources.FindEffect<DistanceEffectSettings>() == null)
            {
                device2D.Resources.RegisterEffect<DistanceFieldEffect>();
            }

            ShapedText output = new ShapedText();

            const string text = "M";

            device2D.TextShaper.Begin(output, text);
            device2D.TextShaper.AnalyzeScripts();
            device2D.TextShaper.SetFamily(text, "Arno Pro");
            device2D.TextShaper.SetPointSize(text, 12.0f);
            device2D.TextShaper.SetFeatures(text, new FontFeatureCollection(new[] {new FontFeature("swsh")}));
            device2D.TextShaper.End();

            GlyphOutline outline =
                device2D.Resources.GetGlyphOutline(
                    new IndexedRange(0, 1),
                    false,
                    false,
                    output.Spans[0].FontMetrics.FontId,
                    output.Glyphs);

            GC.Collect(4);

            Canvas test2 = new Canvas(new Size(128, 128), SurfaceUsage.Normal);

            Stopwatch watch = new Stopwatch();
            watch.Start();
            Canvas test = _Distance.CreateField(
                outline.Shape, outline.Baseline, device2D);
            watch.Stop();

            //mForm.Text = string.Format("Time: {0}", watch.ElapsedMilliseconds);

            Debug.WriteLine("Time: {0}", watch.ElapsedMilliseconds);

            Rectangle reg = device2D.Geometry.MeasureRegion(outline.Shape);

            device2D.Painter.Begin(target);
            device2D.Painter.Translate(test.Region.X, test.Region.Y);

            device2D.Painter.Translate((0.5f - (reg.Width / 2.0f)) * 400, (0.5f - (reg.Height / 2.0f)) * 400);

            // translate the glyph to the left corner of the EM square
            device2D.Painter.Translate(-reg.X * 400, -reg.Y * 400);
            device2D.Painter.SetBrush(Color.Black);
            device2D.Painter.Scale(400, 400);
            device2D.Painter.Fill(outline.Shape);
            device2D.Painter.End(); //*/

            device2D.Compositor.Begin(target, Retention.RetainData);

            DistanceEffectSettings settings;
            device2D.Compositor.Translate(400, 0);
            device2D.Compositor.Scale(3.125f, 3.125f);
            device2D.Compositor.ApplyEffect(settings);
            device2D.Compositor.Composite(test);
            device2D.Compositor.End();

            device2D.Painter.Begin(target, Retention.RetainData);
            device2D.Painter.SetBrush(Color.IndianRed);
            device2D.Painter.IsAntialiased = Antialiasing.Aliased;
            device2D.Painter.StrokeWidth = DistanceField.EmLength / 400;
            device2D.Painter.Scale(1.0f / DistanceField.EmLength, 1.0f / DistanceField.EmLength);
            device2D.Painter.Scale(400, 400);
            TestTest(_Distance.Sample, device2D);
            device2D.Painter.End();

            //device2D.Resources.DumpToFiles(null, SurfaceUsage.Normal); //*/
        }