/// <summary> /// Paint the density image in the layer. /// </summary> /// <param name="gfrx">The graphics context painting in.</param> /// <param name="gl">The layer painting in.</param> /// <param name="plotObject">The data to plot.</param> public void Paint(Graphics gfrx, IPlotArea gl, object plotObject) // plots the curve with the choosen style { if (!(plotObject is XYZMeshedColumnPlotData)) { return; // we cannot plot any other than a TwoDimMeshDataAssociation now } var myPlotAssociation = (XYZMeshedColumnPlotData)plotObject; myPlotAssociation.DataTableMatrix.GetWrappers( gl.XAxis.PhysicalVariantToNormal, // transformation function for row header values Altaxo.Calc.RMath.IsFinite, // selection functiton for row header values gl.YAxis.PhysicalVariantToNormal, // transformation function for column header values Altaxo.Calc.RMath.IsFinite, // selection functiton for column header values out var matrix, out var logicalRowHeaderValues, out var logicalColumnHeaderValues ); int cols = matrix.ColumnCount; int rows = matrix.RowCount; if (cols <= 0 || rows <= 0) { return; // we cannot show a picture if one length is zero } // there is a need for rebuilding the bitmap only if the data are invalid for some reason // if the cached image is valid, then test if the conditions hold any longer switch (_imageType) { case CachedImageType.LinearEquidistant: { var memento = new ImageTypeEquiLinearMemento(gl); if (!memento.Equals(_imageConditionMemento)) { _imageType = CachedImageType.None; } } break; case CachedImageType.Other: { var memento = new ImageTypeOtherMemento(gl); if (!memento.Equals(_imageConditionMemento)) { _imageType = CachedImageType.None; } } break; } // now build the image // note that the image type can change during the call of BuildImage if (_imageType == CachedImageType.None || _cachedImage == null) { BuildImage(gfrx, gl, myPlotAssociation, matrix, logicalRowHeaderValues, logicalColumnHeaderValues); switch (_imageType) { case CachedImageType.LinearEquidistant: _imageConditionMemento = new ImageTypeEquiLinearMemento(gl); break; case CachedImageType.Other: _imageConditionMemento = new ImageTypeOtherMemento(gl); break; } } // and now draw the image { // Three tricks are neccessary to get the bitmap drawn smooth and uniformly: // Everything other than this will result in distorted image, or soft (unsharp) edges var graphicsState = gfrx.Save(); // Of course, save the graphics state so we can make our tricks undone afterwards gfrx.InterpolationMode = InterpolationMode.Default; // Trick1: Set the interpolation mode, whatever it was before, back to default gfrx.PixelOffsetMode = PixelOffsetMode.Default; // Trick2: Set the PixelOffsetMode, whatever it was before, back to default switch (_imageType) { case CachedImageType.LinearEquidistant: { double xOrgRel = logicalRowHeaderValues[0]; double xEndRel = logicalRowHeaderValues[rows - 1]; double yOrgRel = logicalColumnHeaderValues[0]; double yEndRel = logicalColumnHeaderValues[cols - 1]; bool isConvertible = true; isConvertible &= gl.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(xOrgRel, yEndRel), out var x0, out var y0); isConvertible &= gl.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(xOrgRel, yOrgRel), out var x1, out var y1); isConvertible &= gl.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(xEndRel, yEndRel), out var x2, out var y2); if (isConvertible) { if (_clipToLayer) { gfrx.Clip = gl.CoordinateSystem.GetRegion(); } var pts = new PointF[] { new PointF((float)x0, (float)y0), new PointF((float)x2, (float)y2), new PointF((float)x1, (float)y1) }; gfrx.DrawImage(_cachedImage, pts, new RectangleF(0, 0, _cachedImage.Width - 1, _cachedImage.Height - 1), GraphicsUnit.Pixel); // Trick3: Paint both in X and Y direction one pixel less than the source bitmap acually has, this prevents soft edges } } break; case CachedImageType.Other: { gfrx.DrawImage(_cachedImage, 0, 0, (float)gl.Size.X, (float)gl.Size.Y); } break; } gfrx.Restore(graphicsState); } }
/// <summary> /// Paint the density image in the layer. /// </summary> /// <param name="gfrx">The graphics context painting in.</param> /// <param name="gl">The layer painting in.</param> /// <param name="plotObject">The data to plot.</param> public void Paint(Graphics gfrx, IPlotArea gl, object plotObject) // plots the curve with the choosen style { if (!(plotObject is XYZMeshedColumnPlotData)) return; // we cannot plot any other than a TwoDimMeshDataAssociation now XYZMeshedColumnPlotData myPlotAssociation = (XYZMeshedColumnPlotData)plotObject; IROMatrix matrix; IROVector logicalRowHeaderValues, logicalColumnHeaderValues; myPlotAssociation.DataTableMatrix.GetWrappers( gl.XAxis.PhysicalVariantToNormal, // transformation function for row header values Altaxo.Calc.RMath.IsFinite, // selection functiton for row header values gl.YAxis.PhysicalVariantToNormal, // transformation function for column header values Altaxo.Calc.RMath.IsFinite, // selection functiton for column header values out matrix, out logicalRowHeaderValues, out logicalColumnHeaderValues ); int cols = matrix.Columns; int rows = matrix.Rows; if (cols <= 0 || rows <= 0) return; // we cannot show a picture if one length is zero // there is a need for rebuilding the bitmap only if the data are invalid for some reason // if the cached image is valid, then test if the conditions hold any longer switch (_imageType) { case CachedImageType.LinearEquidistant: { ImageTypeEquiLinearMemento memento = new ImageTypeEquiLinearMemento(gl); if (!memento.Equals(_imageConditionMemento)) this._imageType = CachedImageType.None; } break; case CachedImageType.Other: { ImageTypeOtherMemento memento = new ImageTypeOtherMemento(gl); if (!memento.Equals(_imageConditionMemento)) this._imageType = CachedImageType.None; } break; } // now build the image // note that the image type can change during the call of BuildImage if (_imageType == CachedImageType.None || _cachedImage == null) { BuildImage(gfrx, gl, myPlotAssociation, matrix, logicalRowHeaderValues, logicalColumnHeaderValues); switch (_imageType) { case CachedImageType.LinearEquidistant: _imageConditionMemento = new ImageTypeEquiLinearMemento(gl); break; case CachedImageType.Other: _imageConditionMemento = new ImageTypeOtherMemento(gl); break; } } // and now draw the image { // Three tricks are neccessary to get the bitmap drawn smooth and uniformly: // Everything other than this will result in distorted image, or soft (unsharp) edges var graphicsState = gfrx.Save(); // Of course, save the graphics state so we can make our tricks undone afterwards gfrx.InterpolationMode = InterpolationMode.Default; // Trick1: Set the interpolation mode, whatever it was before, back to default gfrx.PixelOffsetMode = PixelOffsetMode.Default; // Trick2: Set the PixelOffsetMode, whatever it was before, back to default switch (_imageType) { case CachedImageType.LinearEquidistant: { double xOrgRel = logicalRowHeaderValues[0]; double xEndRel = logicalRowHeaderValues[rows - 1]; double yOrgRel = logicalColumnHeaderValues[0]; double yEndRel = logicalColumnHeaderValues[cols - 1]; double x0, y0, x1, y1, x2, y2; bool isConvertible = true; isConvertible &= gl.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(xOrgRel, yEndRel), out x0, out y0); isConvertible &= gl.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(xOrgRel, yOrgRel), out x1, out y1); isConvertible &= gl.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(xEndRel, yEndRel), out x2, out y2); if (isConvertible) { if (this._clipToLayer) gfrx.Clip = gl.CoordinateSystem.GetRegion(); var pts = new PointF[] { new PointF((float)x0, (float)y0), new PointF((float)x2, (float)y2), new PointF((float)x1, (float)y1) }; gfrx.DrawImage(_cachedImage, pts, new RectangleF(0, 0, _cachedImage.Width - 1, _cachedImage.Height - 1), GraphicsUnit.Pixel); // Trick3: Paint both in X and Y direction one pixel less than the source bitmap acually has, this prevents soft edges } } break; case CachedImageType.Other: { gfrx.DrawImage(_cachedImage, 0, 0, (float)gl.Size.X, (float)gl.Size.Y); } break; } gfrx.Restore(graphicsState); } }