public override IEnumerable <GdiRenderObject> RenderSymbols(IEnumerable <Point2D> locations, Symbol2D symbol, Symbol2D highlightSymbol, Symbol2D selectSymbol, RenderState renderState) { if (renderState == RenderState.Selected) { symbol = selectSymbol; } if (renderState == RenderState.Highlighted) { symbol = highlightSymbol; } foreach (Point2D location in locations) { Bitmap bitmapSymbol = getSymbol(symbol); if (bitmapSymbol.PixelFormat != PixelFormat.Undefined) { System.Drawing.Drawing2D.Matrix transform = ViewConverter.Convert(symbol.AffineTransform); System.Drawing.Imaging.ColorMatrix colorTransform = ViewConverter.Convert(symbol.ColorTransform); RectangleF bounds = new RectangleF(ViewConverter.Convert(location), bitmapSymbol.Size); GdiRenderObject holder = new GdiRenderObject(bitmapSymbol, bounds, transform, colorTransform); holder.State = renderState; yield return(holder); } else { Debug.WriteLine("Unkbown pixel format"); } } }
public void RenderPathOutlineTest() { GdiVectorRenderer renderer = new GdiVectorRenderer(); Point2D[] points = new Point2D[] { new Point2D(1, 0), new Point2D(0, 1), new Point2D(-1, 0), new Point2D(0, -1) }; Path2D path = new Path2D(points, true); StylePen outline = new StylePen(new SolidStyleBrush(StyleColor.Blue), 1); StylePen highlight = new StylePen(new SolidStyleBrush(StyleColor.Red), 1); StylePen selected = new StylePen(new SolidStyleBrush(StyleColor.Green), 1); IEnumerable <GdiRenderObject> renderObjects = renderer.RenderPaths( new Path2D[] { path }, outline, highlight, selected, RenderState.Normal); IEnumerator <GdiRenderObject> enumertor = renderObjects.GetEnumerator(); enumertor.MoveNext(); GdiRenderObject ro = enumertor.Current; Assert.AreEqual(RenderState.Normal, ro.State); Assert.IsInstanceOfType(typeof(SolidBrush), ro.Fill); Assert.IsNotNull(ro.GdiPath); Assert.AreEqual(4, ro.GdiPath.PointCount); Assert.AreEqual(new RectangleF(-1, -1, 2, 2), ro.GdiPath.GetBounds()); PathData data = ro.GdiPath.PathData; for (Int32 i = 0; i < 4; i++) { Assert.AreEqual(points[i].X, data.Points[i].X, _e); Assert.AreEqual(points[i].Y, data.Points[i].Y, _e); } Assert.AreEqual(0, data.Types[0]); Assert.AreEqual(1, data.Types[1]); Assert.AreEqual(1, data.Types[2]); Assert.AreEqual(129, data.Types[3]); Pen expectedOutline = new Pen(Brushes.Blue, 1.0f); Pen expectedHighlight = new Pen(Brushes.Red, 1.0f); Pen expectedSelected = new Pen(Brushes.Green, 1.0f); Assert.IsTrue(pensAreEqual(expectedOutline, ro.Outline)); Assert.IsTrue(pensAreEqual(expectedHighlight, ro.HighlightOutline)); Assert.IsTrue(pensAreEqual(expectedSelected, ro.SelectOutline)); expectedOutline.Dispose(); expectedHighlight.Dispose(); expectedSelected.Dispose(); renderer.Dispose(); }
/// <summary> /// Draws the rendered object to the view. /// </summary> /// <param name="renderedObjects">The rendered objects to draw.</param> public void ShowRenderedObjects(IEnumerable <GdiRenderObject> renderedObjects) { if (renderedObjects == null) { throw new ArgumentNullException("renderedObjects"); } foreach (GdiRenderObject ro in renderedObjects) { GdiRenderObject go = ro; _renderObjectQueue.Enqueue(go); } }
/// <summary> /// Without this change, labels render upside down and don't all scale readably. /// </summary> /// <param name="g"></param> /// <param name="ro"></param> /// <returns></returns> protected RectangleF AdjustForLabel(Graphics g, GdiRenderObject ro) { // this transform goes from the underlying coordinates to // screen coordinates, but for some reason renders text upside down // we cannot just scale by 1, -1 because offsets are affected also GdiMatrix m = g.Transform; // used to scale text size for the current zoom level float scale = Math.Abs(m.Elements[0]); // get the bounds of the label in the underlying coordinate space Point ll = new Point((Int32)ro.Bounds.X, (Int32)ro.Bounds.Y); Point ur = new Point((Int32)(ro.Bounds.X + ro.Bounds.Width), (Int32)(ro.Bounds.Y + ro.Bounds.Height)); Point[] transformedPoints1 = { new Point((Int32)ro.Bounds.X, (Int32)ro.Bounds.Y), new Point((Int32)(ro.Bounds.X + ro.Bounds.Width), (Int32)(ro.Bounds.Y + ro.Bounds.Height)) }; // get the label bounds transformed into screen coordinates // note that if we just render this as-is the label is upside down m.TransformPoints(transformedPoints1); // for labels, we're going to use an identity matrix and screen coordinates GdiMatrix newM = new GdiMatrix(); Boolean scaleText = true; /* * if (ro.Layer != null) * { * Double min = ro.Layer.Style.MinVisible; * Double max = ro.Layer.Style.MaxVisible; * float scaleMult = Double.IsInfinity(max) ? 2.0f : 1.0f; * * //max = Math.Min(max, _presenter.MaximumWorldWidth); * max = Math.Min(max, Map.Extents.Width); * //Double pct = (max - _presenter.WorldWidth) / (max - min); * Double pct = 1 - (Math.Min(_presenter.WorldWidth, Map.Extents.Width) - min) / (max - min); * * if (scaleMult > 1) * { * pct = Math.Max(.5, pct * 2); * } * * scale = (float)pct*scaleMult; * labelScale = scale; * } */ // ok, I lied, if we're scaling labels we need to scale our new matrix, but still no offsets if (scaleText) { newM.Scale(scale, scale); } else { scale = 1.0f; } g.Transform = newM; Int32 pixelWidth = ur.X - ll.X; Int32 pixelHeight = ur.Y - ll.Y; // if we're scaling text, then x,y position will get multiplied by our // scale, so adjust for it here so that we can use actual pixel x,y // Also center our label on the coordinate instead of putting the label origin on the coordinate RectangleF newBounds = new RectangleF(transformedPoints1[0].X / scale, (transformedPoints1[0].Y / scale) - pixelHeight, pixelWidth, pixelHeight); //RectangleF newBounds = new RectangleF(transformedPoints1[0].X / scale - (pixelWidth / 2), transformedPoints1[0].Y / scale - (pixelHeight / 2), pixelWidth, pixelHeight); return(newBounds); }
protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; Graphics screenGraphics = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias; if (DesignMode || _presenter == null) { g.Clear(BackColor); return; } // dump to screen and return if (_bufferedMapImage != null) { g.Clear(BackColor); g.DrawImageUnscaled(_bufferedMapImage, (Int32)((Width - _bufferedMapImage.Width) / 2.0f), (Int32)((Height - _bufferedMapImage.Height) / 2.0f)); if (_renderObjectQueue.Count == 0) { return; } } if (_bufferedMapImage != null && (_bufferedMapImage.Width != Width || _bufferedMapImage.Height != Height)) { _bufferedMapImage.Dispose(); _bufferedMapImage = null; } if (_bufferedMapImage == null) { _bufferedMapImage = new Bitmap(Width, Height); } g = Graphics.FromImage(_bufferedMapImage); g.SmoothingMode = SmoothingMode.AntiAlias; // kbd4hire Leave GDI transform at identity. //g.Transform = getGdiViewTransform(); if (!_presenter.IsRenderingSelection) { g.Clear(BackColor); } while (_renderObjectQueue.Count > 0) { GdiRenderObject ro = _renderObjectQueue.Dequeue(); if (ro.State == RenderState.Unknown) { continue; } try { switch (ro.State) { case RenderState.Normal: if (ro.GdiPath != null) { if (ro.Line != null) { if (ro.Outline != null) { g.DrawPath(ro.Outline, ro.GdiPath); } g.DrawPath(ro.Line, ro.GdiPath); } else if (ro.Fill != null) { g.FillPath(ro.Fill, ro.GdiPath); if (ro.Outline != null) { g.DrawPath(ro.Outline, ro.GdiPath); } } } if (ro.Text != null) { RectangleF newBounds = AdjustForLabel(g, ro); g.DrawString(ro.Text, ro.Font, ro.Fill, newBounds.Location); // kbd4hire Leave GDI transform at identity. //g.Transform = getGdiViewTransform(); } break; case RenderState.Highlighted: if (ro.GdiPath != null) { if (ro.HighlightLine != null) { if (ro.HighlightOutline != null) { g.DrawPath(ro.HighlightOutline, ro.GdiPath); } g.DrawPath(ro.HighlightLine, ro.GdiPath); } else if (ro.HighlightFill != null) { g.FillPath(ro.HighlightFill, ro.GdiPath); if (ro.HighlightOutline != null) { g.DrawPath(ro.HighlightOutline, ro.GdiPath); } } } if (ro.Text != null) { RectangleF newBounds = AdjustForLabel(g, ro); g.DrawString(ro.Text, ro.Font, ro.HighlightFill, newBounds); // kbd4hire 20090318 Leave transfrom at identity //g.Transform = getGdiViewTransform(); } break; case RenderState.Selected: if (ro.GdiPath != null) { if (ro.SelectLine != null) { if (ro.SelectOutline != null) { g.DrawPath(ro.SelectOutline, ro.GdiPath); } g.DrawPath(ro.SelectLine, ro.GdiPath); } else if (ro.SelectFill != null) { g.FillPath(ro.SelectFill, ro.GdiPath); if (ro.SelectOutline != null) { g.DrawPath(ro.SelectOutline, ro.GdiPath); } } } if (ro.Text != null) { RectangleF newBounds = AdjustForLabel(g, ro); g.DrawString(ro.Text, ro.Font, ro.SelectFill, newBounds); // kbd4hire 20090318 Leave transfrom at identity //g.Transform = getGdiViewTransform(); } break; case RenderState.Unknown: default: break; } } catch (OverflowException) {} if (ro.Image != null) { ImageAttributes imageAttributes = null; if (ro.ColorTransform != null) { imageAttributes = new ImageAttributes(); imageAttributes.SetColorMatrix(ro.ColorTransform); } if (imageAttributes != null) { g.DrawImage(ro.Image, getPoints(ro.Bounds), getSourceRegion(ro.Image), GraphicsUnit.Pixel, imageAttributes); } else { g.DrawImage(ro.Image, getPoints(ro.Bounds), getSourceRegion(ro.Image), GraphicsUnit.Pixel); } } } g.ResetTransform(); if (g != screenGraphics) { screenGraphics.DrawImageUnscaled(_bufferedMapImage, 0, 0); } }
private void RenderObject(GdiRenderObject ro, Graphics g) { if (ro.State == RenderState.Unknown) { return; } switch (ro.State) { case RenderState.Normal: if (ro.GdiPath != null) { if (ro.Line != null) { if (ro.Outline != null) { g.DrawPath(ro.Outline, ro.GdiPath); } g.DrawPath(ro.Line, ro.GdiPath); } else if (ro.Fill != null) { g.FillPath(ro.Fill, ro.GdiPath); if (ro.Outline != null) { g.DrawPath(ro.Outline, ro.GdiPath); } } } if (ro.Text != null) { RectangleF newBounds = AdjustForLabel(g, ro); g.DrawString(ro.Text, ro.Font, ro.Fill, newBounds.Location); //g.Transform = GetGdiViewTransform(); } break; case RenderState.Highlighted: if (ro.GdiPath != null) { if (ro.HighlightLine != null) { if (ro.HighlightOutline != null) { g.DrawPath(ro.HighlightOutline, ro.GdiPath); } g.DrawPath(ro.HighlightLine, ro.GdiPath); } else if (ro.HighlightFill != null) { g.FillPath(ro.HighlightFill, ro.GdiPath); if (ro.HighlightOutline != null) { g.DrawPath(ro.HighlightOutline, ro.GdiPath); } } } if (ro.Text != null) { RectangleF newBounds = AdjustForLabel(g, ro); g.DrawString(ro.Text, ro.Font, ro.HighlightFill, newBounds); //g.Transform = GetGdiViewTransform(); } break; case RenderState.Selected: if (ro.GdiPath != null) { if (ro.SelectLine != null) { if (ro.SelectOutline != null) { g.DrawPath(ro.SelectOutline, ro.GdiPath); } g.DrawPath(ro.SelectLine, ro.GdiPath); } else if (ro.SelectFill != null) { g.FillPath(ro.SelectFill, ro.GdiPath); if (ro.SelectOutline != null) { g.DrawPath(ro.SelectOutline, ro.GdiPath); } } } if (ro.Text != null) { RectangleF newBounds = AdjustForLabel(g, ro); g.DrawString(ro.Text, ro.Font, ro.SelectFill, newBounds); //g.Transform = GetGdiViewTransform(); } break; default: break; } if (ro.Image == null) { return; } ImageAttributes imageAttributes = null; if (ro.ColorTransform != null) { imageAttributes = new ImageAttributes(); imageAttributes.SetColorMatrix(ro.ColorTransform); } if (imageAttributes != null) { g.DrawImage(ro.Image, GetPoints(ro.Bounds), GetSourceRegion(ro.Image.Size), GraphicsUnit.Pixel, imageAttributes); } else { g.DrawImage(ro.Image, GetPoints(ro.Bounds), GetSourceRegion(ro.Image.Size), GraphicsUnit.Pixel); } }