/// <summary> /// Draws the specified contents to a Gdk window. /// </summary> /// <param name="window">The Gdk window to work with.</param> public void Draw(Gdk.Window window) { using (var context = Gdk.CairoHelper.Create(window)) { using (var surface = context.GetTarget()) { var renderer = new ScopeRenderer(context); _currentScopeGraphicsRangeExtents = renderer.GetScopeGraphicsRangeDeviceAreaExtents(window.Width, window.Height); var currentReadoutsDeviceExtents = renderer.GetReadoutsDeviceAreaExtents(window.Width, window.Height); var userRange = _currentScopeGraphicsRangeExtents != null ? CreateScopeGraphicsRange(_currentScopeGraphicsRangeExtents, _xMinimumGraticuleUnits, _yMinimumGraticuleUnits, _userOriginOffset) : null; renderer.DrawMainBackground(window.Width, window.Height); if (userRange != null) { renderer.DrawScopeGraphics(userRange, Cursors, Graphs); } renderer.DrawReadouts(currentReadoutsDeviceExtents, Readouts); // There's a bug related to internal reference counting (already fixed on GitHub) // that causes a memory leak. Thus we use our workaround dispose method here. //surface.Dispose (); surface.DisposeHard(); } context.Dispose(); } }
/// <summary> /// Draws the readouts (i.e. some additional information regarding the scope settings and signals). /// </summary> /// <param name="extents">The extents of the device area to draw the readouts to.</param> /// <param name="readouts">The readouts to draw.</param> public void DrawReadouts(DeviceAreaExtents extents, IEnumerable <ScopeReadout> readouts) { readouts = readouts ?? new ScopeReadout[0]; foreach (var readout in readouts) { DrawReadout(extents, readout); } }
/// <summary> /// Creates a rectangle range the scope contents are rendered to, according to the specified values. /// </summary> /// <returns>The user range.</returns> /// <param name="extents">The extents of the device area to render to.</param> /// <param name="xUserMinSpan">The minimum horizontal (X) span requeste, in user-specific units.</param> /// <param name="yUserMinSpan">The minimum vertical (Y) span requeste, in user-specific units.</param> /// <param name="originOffset">The offset of the origin to the range center, in user-specific units.</param> /// <returns>The created rectangle range or <c>null</c> if no range could be created.</returns> private RectangleRange CreateScopeGraphicsRange(DeviceAreaExtents extents, double xUserMinSpan, double yUserMinSpan, Distance userOriginOffset) { var rangeWidth = extents.Width; var rangeHeight = extents.Height; // As this could result in division by zero or infinite values, // we don't create a range in this case. if (rangeWidth <= 0 || rangeHeight <= 0) { return(null); } double aspectRatioFactor; UserToDeviceStretchMode userToDeviceStretchMode; if (_stretchMode == ScopeStretchMode.Expand) { aspectRatioFactor = new AspectRatioCalculator(rangeWidth, rangeHeight, xUserMinSpan, yUserMinSpan) .UserToDeviceAspectRatioFactor; userToDeviceStretchMode = UserToDeviceStretchMode.UniformToAny; } else { aspectRatioFactor = 1; userToDeviceStretchMode = UserToDeviceStretchMode.Fill; } // Expand the width or height range to utilize any extra space available. var xUserSpan = xUserMinSpan; var yUserSpan = yUserMinSpan; if (aspectRatioFactor > 1) { xUserSpan *= aspectRatioFactor; } else { yUserSpan /= aspectRatioFactor; } var userToDeviceMatrix = CreateUserToDeviceTransformationMatrix(rangeWidth, rangeHeight, xUserSpan, yUserSpan, userToDeviceStretchMode); // Note: "if (matrix != null)" fails. Bug in the equality operator of Matrix? // Consider the origin offset (in user-specific units). userToDeviceMatrix.Translate(+userOriginOffset.Dx, +userOriginOffset.Dy); return(new RectangleRange(rangeWidth, rangeHeight, xUserSpan, yUserSpan, userOriginOffset, userToDeviceMatrix)); }
/// <summary> /// Draws a scope readout. /// </summary> private void DrawReadout(DeviceAreaExtents extents, ScopeReadout readout) { var fontHeight = GetFontExtents().Height; var lineHeight = fontHeight; var columnWidth = (extents.Width - 2 * _defaultReadoutsAlignmentDistance.Dx) / _numberOfReadoutColumns; var readoutPosition = new PointD( extents.MinX + readout.Column * columnWidth, extents.MinY + readout.Line * lineHeight ); DrawText(readout.CurrentText, readoutPosition, readout.Color, ScopeHorizontalAlignment.Left, ScopeVerticalAlignment.Top, _defaultReadoutsAlignmentDistance); }