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; }
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; }
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(); } } }
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(); }
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; }
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(); }
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); } }
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); //*/ }