public virtual void SpeedTest(Xwt.Drawing.Context ctx, double sx, double sy) { ctx.Save(); ctx.Translate(sx, sy); var n = 1000; var ll = 80; var p = new Point(0, 0); for (double i = 1; i < n; i++) { ctx.MoveTo(p.X, p.Y); ctx.SetColor(new Color(i / n, i / n, i / n)); ctx.LineTo(p.X + ll, p.Y + ll); ctx.Stroke(); if (p.Y + ll > this.Bounds.Bottom) { p.Y = 0; p.X += ll + 5; } else { p.Y++; } } ctx.Restore(); }
internal protected override void Draw(Xwt.Drawing.Context cr, Rectangle area, DocumentLine lineSegment, int line, double x, double y, double lineHeight) { cr.MoveTo(x + 0.5, y); cr.LineTo(x + 0.5, y + lineHeight); cr.SetSourceColor(color); cr.Stroke(); }
public static void DrawLine(this Xwt.Drawing.Context cr, Color color, double x1, double y1, double x2, double y2) { cr.SetSourceColor(color); cr.MoveTo(x1, y1); cr.LineTo(x2, y2); cr.Stroke(); }
void InternalDraw(int markerStart, int markerEnd, TextEditor editor, Xwt.Drawing.Context cr, TextLayout layout, bool selected, int startOffset, int endOffset, double y, double startXPos, double endXPos) { if (markerStart >= markerEnd) { return; } double @from; double to; if (markerStart < startOffset && endOffset < markerEnd) { @from = startXPos; to = endXPos; } else { int start = startOffset < markerStart ? markerStart : startOffset; int end = endOffset < markerEnd ? endOffset : markerEnd; double /*lineNr,*/ x_pos; x_pos = layout.GetCoordinateFromIndex(start - startOffset).X; @from = startXPos + (int)(x_pos); x_pos = layout.GetCoordinateFromIndex(end - startOffset).X; to = startXPos + (int)(x_pos); } @from = System.Math.Max(@from, editor.TextViewMargin.XOffset); to = System.Math.Max(to, editor.TextViewMargin.XOffset); if (@from >= to) { return; } double height = editor.LineHeight / 5; if (selected) { cr.SetSourceColor(editor.ColorStyle.SelectedText.Foreground); } else { cr.SetSourceColor(ColorName == null ? Color : editor.ColorStyle.GetChunkStyle(ColorName).Foreground); } if (Wave) { //Pango.CairoHelper.ShowErrorUnderline(cr, @from, y + editor.LineHeight - height, to - @from, height); } else { cr.SetLineWidth(1); cr.MoveTo(@from, y + editor.LineHeight - 1.5); cr.LineTo(to, y + editor.LineHeight - 1.5); cr.Stroke(); } }
public virtual void Rotate(Xwt.Drawing.Context ctx, double x, double y) { // draws a line along the x-axis from (0,0) to (r,0) with a constant translation and an increasing // rotational component. This composite transform is then applied to a vertical line, with inverse // color, and an additional x-offset, to form a mirror image figure for easy visual comparison. // These transformed points must be drawn with the identity CTM, hence the Restore() each time. ctx.Save(); // save caller's context (assumed to be the Identity CTM) ctx.SetLineWidth(3); // should align exactly if drawn with half-pixel coordinates // Vector length (pixels) and rotation limit (degrees) double r = 30; double end = 270; for (double n = 0; n <= end; n += 5) { ctx.Save(); // save context and identity CTM for each line // Set up translation to centre point of first figure, ensuring pixel alignment ctx.Translate(x + 30.5, y + 30.5); ctx.Rotate(n); ctx.MoveTo(0, 0); ctx.RelLineTo(r, 0); double c = n / end; ctx.SetColor(new Color(c, c, c)); ctx.Stroke(); // stroke first figure with composite Translation and Rotation CTM // Generate mirror image figure as a visual test of TransformPoints Point p0 = new Point(0, 0); Point p1 = new Point(0, -r); Point[] p = new Point[] { p0, p1 }; ctx.TransformPoints(p); // using composite transformation ctx.Restore(); // restore identity CTM ctx.Save(); // save again (to restore after additional Translation) ctx.Translate(2 * r + 1, 0); // extra x-offset to clear first figure ctx.MoveTo(p[0]); ctx.LineTo(p[1]); c = 1 - c; ctx.SetColor(new Color(c, c, c)); ctx.Stroke(); // stroke transformed points with offset in CTM ctx.Restore(); // restore identity CTM for next line } ctx.Restore(); // restore caller's context }
internal protected override void Draw (Context win, Rectangle area, long line, double x, double y) { win.Rectangle (x, y, Width, Editor.LineHeight); win.SetColor (Style.IconBarBg); win.Fill (); win.MoveTo (x + Width - 1, y); win.LineTo (x + Width - 1, y + Editor.LineHeight); win.SetColor (Style.IconBarSeperator); win.Stroke (); foreach (long bookmark in Data.Bookmarks) { if (line * Editor.BytesInRow <= bookmark && bookmark < line * Editor.BytesInRow + Editor.BytesInRow) { DrawBookmark (win, x, y); return; } } }
internal protected override void Draw(Xwt.Drawing.Context ctx, Rectangle area, DocumentLine lineSegment, int line, double x, double y, double lineHeight) { bool backgroundIsDrawn = false; if (lineSegment != null) { foreach (var marker in lineSegment.Markers) { var marginMarker = marker as MarginMarker; if (marginMarker != null && marginMarker.CanDrawBackground(this)) { backgroundIsDrawn = marginMarker.DrawBackground(editor, ctx, new MarginDrawMetrics(this, area, lineSegment, line, x, y, lineHeight)); } } } if (!backgroundIsDrawn) { ctx.Rectangle(x, y, Width, lineHeight); ctx.SetSourceColor(backgroundColor); ctx.Fill(); ctx.MoveTo(x + Width - 0.5, y); ctx.LineTo(x + Width - 0.5, y + lineHeight); ctx.SetSourceColor(separatorColor); ctx.Stroke(); } if (lineSegment != null && line <= editor.Document.LineCount) { foreach (var marker in lineSegment.Markers) { var marginMarker = marker as MarginMarker; if (marginMarker != null && marginMarker.CanDrawForeground(this)) { marginMarker.DrawForeground(editor, ctx, new MarginDrawMetrics(this, area, lineSegment, line, x, y, lineHeight)); } } if (DrawEvent != null) { DrawEvent(this, new BookmarkMarginDrawEventArgs(editor, ctx, lineSegment, line, x, y)); } } }
/// <summary> /// Visual test for pixel alignment and odd/even line widths /// </summary> public void Lines (Context ctx) { ctx.Save (); ctx.SetColor (Colors.Black); int nPairs = 4; double length = 90; double gap = 2; // set half-pixel y-coordinate for sharp single-pixel-wide line // on first line of Canvas, extending to match line pairs below ctx.SetLineWidth (1); double x = 0; double y = 0.5; double end = x + 2*(length - 1) + gap; ctx.MoveTo (x, y); ctx.LineTo (end, y); ctx.Stroke (); // draw pairs of lines with odd and even widths, // each pair aligned on half-pixel y-coordinates y = 4.5; for (int w = 1; w <= nPairs; ++w) { x = 0; ctx.SetLineWidth (w); ctx.MoveTo (x, y); ctx.RelLineTo (length-1, 0); ctx.Stroke (); ctx.SetLineWidth (w + 1); x += (gap + length - 1); ctx.MoveTo (x, y); ctx.RelLineTo (length-1, 0); ctx.Stroke (); y += w * 2 + gap; } ctx.Restore (); }
public virtual void Rotate(Xwt.Drawing.Context ctx, double x, double y) { ctx.Save(); ctx.Translate(x + 30, y + 30); ctx.SetLineWidth(3); // Rotation double end = 270; double r = 30; for (double n = 0; n <= end; n += 5) { ctx.Save(); ctx.Rotate(n); ctx.MoveTo(0, 0); ctx.RelLineTo(r, 0); double c = n / end; ctx.SetColor(new Color(c, c, c)); ctx.Stroke(); // Visual test for TransformPoints Point p0 = new Point(0, 0); Point p1 = new Point(0, -r); Point[] p = new Point[] { p0, p1 }; ctx.TransformPoints(p); ctx.ResetTransform(); ctx.Translate(2 * r + 1, 0); ctx.MoveTo(p[0]); ctx.LineTo(p[1]); c = 1 - c; ctx.SetColor(new Color(c, c, c)); ctx.Stroke(); ctx.Restore(); } ctx.Restore(); }
public virtual void Curves1(Context ctx, double x, double y) { ctx.Save (); ctx.Translate (x, y); ctx.SetLineWidth (1); Action curve1 = () => { ctx.MoveTo (0, 30); ctx.CurveTo (20, 0, 50, 0, 60, 25); }; // curve2 with lineTo; curve1 is closed Action curve2 = () => { ctx.LineTo (0, 0); ctx.CurveTo (20, 30, 50, 30, 60, 5); }; Action paint = () => { curve1 (); curve2 (); ctx.ClosePath (); ctx.SetColor (new Color (0, 0, 0, .5)); ctx.StrokePreserve (); ctx.SetColor (new Color (1, 0, 1, .5)); ctx.Fill (); }; paint (); ctx.Translate (0, 40); // curve2 with moveTo; curve1 is open curve2 = () => { ctx.MoveTo (0, 0); ctx.CurveTo (20, 30, 50, 30, 60, 5); }; paint (); ctx.Restore (); //Todo: same stuff with arc }
/// <summary> /// Draws the candle plot with the specified Drawing Context and X,Y axes /// </summary> /// <param name="ctx">The Drawing Context with which to draw</param> /// <param name="xAxis">The physical X-Axis to draw against</param> /// <param name="yAxis">The physical Y-Axis to draw against</param> public void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis) { CandleDataAdapter cd = new CandleDataAdapter (DataSource, DataMember, AbscissaData, OpenData, LowData, HighData, CloseData); double offset = 0; if (Centered) { offset = CalculatePhysicalSeparation (cd,xAxis)/2; } double addAmount = StickWidth/2; double stickWidth = StickWidth; if (StickWidth == AutoScaleStickWidth) { // default addAmount = 2; stickWidth = 4; double minDist = CalculatePhysicalSeparation (cd, xAxis); addAmount = minDist / 3; stickWidth = addAmount * 2; } ctx.Save (); ctx.SetLineWidth (1); /* // brant hyatt proposed. if (Style == Styles.Stick) { p.Width = stickWidth; addAmount = stickWidth + 2; } */ for (int i=0; i<cd.Count; ++i) { PointOLHC point = (PointOLHC)cd [i]; if ((!double.IsNaN (point.Open)) && (!double.IsNaN(point.High)) && (!double.IsNaN (point.Low)) && (!double.IsNaN(point.Close))) { double xPos = (xAxis.WorldToPhysical (point.X, false)).X; if (xPos + offset + addAmount < xAxis.PhysicalMin.X || xAxis.PhysicalMax.X < xPos + offset - addAmount) { continue; } double yLo = (yAxis.WorldToPhysical (point.Low, false)).Y; double yHi = (yAxis.WorldToPhysical (point.High, false)).Y; double yOpn = (yAxis.WorldToPhysical (point.Open, false)).Y; double yCls = (yAxis.WorldToPhysical (point.Close,false)).Y; if (Style == Styles.Stick) { /* // brant hyatt proposed. if (i > 0) { if ( ((PointOLHC)cd[i]).Close > ((PointOLHC)cd[i-1]).Close) { p.Color = BullishColor; } else { p.Color = BearishColor; } } */ ctx.SetColor (Color); ctx.MoveTo (xPos+offset, yLo); ctx.LineTo (xPos+offset, yHi); // Low to High line ctx.MoveTo (xPos-addAmount+offset, yOpn); ctx.LineTo (xPos+offset, yOpn); // Open line ctx.MoveTo (xPos+addAmount+offset, yCls); ctx.LineTo (xPos+offset, yCls); // Close line ctx.Stroke (); } else if (Style == Styles.Filled) { ctx.MoveTo (xPos+offset, yLo); ctx.LineTo (xPos+offset, yHi); ctx.Stroke (); if (yOpn > yCls) { ctx.SetColor (BullishColor); ctx.Rectangle (xPos-addAmount+offset, yCls, stickWidth, yOpn - yCls); ctx.FillPreserve (); ctx.SetColor (Color); ctx.Stroke (); } else if (yOpn < yCls) { ctx.SetColor (BearishColor); ctx.Rectangle (xPos-addAmount+offset, yOpn, stickWidth, yCls - yOpn); ctx.FillPreserve (); ctx.SetColor (Color); ctx.Stroke (); } else { // Cls == Opn ctx.MoveTo (xPos-addAmount+offset, yOpn); ctx.LineTo (xPos-addAmount+stickWidth+offset, yCls); ctx.Stroke (); } } } } ctx.Restore (); }
/// <summary> /// Does all the work in drawing grid lines. /// </summary> /// <param name="ctx">The graphics context with which to draw</param> /// <param name="axis">TODO</param> /// <param name="orthogonalAxis">TODO</param> /// <param name="a">the list of world values to draw grid lines at.</param> /// <param name="horizontal">true if want horizontal lines, false otherwise.</param> /// <param name="color">the color to draw the grid lines.</param> private void DrawGridLines(Context ctx, PhysicalAxis axis, PhysicalAxis orthogonalAxis, System.Collections.ArrayList a, bool horizontal) { for (int i=0; i<a.Count; ++i) { Point p1 = axis.WorldToPhysical ((double)a[i], true); Point p2 = p1; Point p3 = orthogonalAxis.PhysicalMax; Point p4 = orthogonalAxis.PhysicalMin; if (horizontal) { p1.Y = p4.Y; p2.Y = p3.Y; } else { p1.X = p4.X; p2.X = p3.X; } ctx.MoveTo (p1); ctx.LineTo (p2); } ctx.SetLineWidth (1); ctx.SetColor (gridColor); ctx.SetLineDash (0, gridDash); ctx.Stroke (); }
/// <summary> /// Draw the filled region /// </summary> /// <param name="g">The Drawing Context with which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> public void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis) { ITransform2D t = Transform2D.GetTransformer (xAxis, yAxis); ctx.Save (); if (hl1 != null && hl2 != null) { ctx.MoveTo (t.Transform (xAxis.Axis.WorldMin, hl1.OrdinateValue)); ctx.LineTo (t.Transform (xAxis.Axis.WorldMax, hl1.OrdinateValue)); ctx.LineTo (t.Transform (xAxis.Axis.WorldMax, hl2.OrdinateValue)); ctx.LineTo (t.Transform (xAxis.Axis.WorldMin, hl2.OrdinateValue)); ctx.ClosePath (); } else if (vl1 != null && vl2 != null) { ctx.MoveTo (t.Transform (vl1.AbscissaValue, yAxis.Axis.WorldMin)); ctx.LineTo (t.Transform (vl1.AbscissaValue, yAxis.Axis.WorldMax)); ctx.LineTo (t.Transform (vl2.AbscissaValue, yAxis.Axis.WorldMax)); ctx.LineTo (t.Transform (vl2.AbscissaValue, yAxis.Axis.WorldMin)); ctx.ClosePath (); } else if (lp1 != null && lp2 != null) { SequenceAdapter a1 = new SequenceAdapter (lp1.DataSource, lp1.DataMember, lp1.OrdinateData, lp1.AbscissaData); SequenceAdapter a2 = new SequenceAdapter (lp2.DataSource, lp2.DataMember, lp2.OrdinateData, lp2.AbscissaData); // Start at first point of LinePlot 1 within plot bounds int start = 0; while (t.Transform (a1 [start]).X < xAxis.PhysicalMin.X) { ++start; } Point first = t.Transform (a1 [start]); ctx.MoveTo (first); // Join LinePlot 1 points in ascending order Point next; for (int i = start+1; i < a1.Count-1; ++i) { next = t.Transform (a1 [i]); if (next.X > xAxis.PhysicalMax.X) break; ctx.LineTo (next); } // Then join LinePlot 2 points in descending order int end = a2.Count-1; while (t.Transform (a2 [end]).X > xAxis.PhysicalMax.X) { --end; } for (int i = end; i > 0; --i) { next = t.Transform (a2 [i]); if (next.X < xAxis.PhysicalMin.X) break; ctx.LineTo (next); } ctx.LineTo (first); ctx.ClosePath (); } else { throw new XwPlotException ("Filled Region bounds not defined"); } ctx.SetColor (FillColor); ctx.Fill (); ctx.Restore (); }
protected override void OnDraw(Context ctx, Rectangle dirtyRect) { base.OnDraw(ctx, dirtyRect); if (image != null) { if (Heighlighted && IsThumbnail) { ctx.RoundRectangle(new Rectangle(Point.Zero, image.Size), 3); ctx.SetColor(Colors.LightSteelBlue); ctx.Fill(); } ctx.DrawImage(image, (new Rectangle(Point.Zero, image.Size)).Inflate(-3, -3)); if (mask != null && ShowMask) { ctx.DrawImage(MaskBitmap, (new Rectangle(Point.Zero, image.Size)).Inflate(-3, -3), 0.6); } } if (isEditMode) { Point scaleFactor = new Point( scan.Size.Width / image.Size.Width, scan.Size.Height / image.Size.Height); ctx.SetColor(Mask.maskColor); foreach (MaskEntry p in scan.Mask.MaskPositions) { switch (p.type) { case MaskEntryType.Point: ctx.SetLineWidth(p.pointerSize / scaleFactor.Y * 2); ctx.LineTo(p.position.X / scaleFactor.X, p.position.Y / scaleFactor.Y); ctx.Stroke(); ctx.Arc( p.position.X / scaleFactor.X, p.position.Y / scaleFactor.Y, p.pointerSize / scaleFactor.Y, 0, 360); ctx.Fill(); ctx.MoveTo(p.position.X / scaleFactor.X, p.position.Y / scaleFactor.Y); break; case MaskEntryType.Space: ctx.Stroke(); ctx.ClosePath(); break; case MaskEntryType.Delete: ctx.Arc( p.position.X / scaleFactor.X, p.position.Y / scaleFactor.Y, p.pointerSize / scaleFactor.Y, 0, 360); ctx.Save(); ctx.Clip(); int newX = (int) Math.Min(Math.Max( p.position.X / scaleFactor.X - pointerSize / scaleFactor.Y, 0), scan.Size.Width); int newY = (int) Math.Min(Math.Max( p.position.Y / scaleFactor.Y - pointerSize / scaleFactor.Y, 0), scan.Size.Height); using (ImageBuilder ib = new ImageBuilder((pointerSize / scaleFactor.Y * 2), (pointerSize / scaleFactor.Y * 2))) { BitmapImage bi = ib.ToBitmap(); image.WithBoxSize(image.Size).ToBitmap().CopyArea( newX, newY, (int) (pointerSize / scaleFactor.Y * 2), (int) (pointerSize / scaleFactor.Y * 2), bi, 0, 0); ctx.DrawImage(bi, new Point(newX, newY)); } ctx.Restore(); ctx.ClosePath(); break; } } ctx.Stroke(); if (mousePosition != Point.Zero) { ctx.Arc(mousePosition.X, mousePosition.Y, pointerSize / Math.Max(scaleFactor.X, scaleFactor.Y), 0, 360); ctx.Fill(); if (mousePositionStart != Point.Zero) { ctx.SetLineWidth((pointerSize / Math.Max(scaleFactor.X, scaleFactor.Y)) * 2); ctx.SetColor(Mask.maskColor); ctx.Arc(mousePositionStart.X, mousePositionStart.Y, pointerSize / Math.Max(scaleFactor.X, scaleFactor.Y), 0, 360); ctx.Fill(); ctx.MoveTo(mousePosition); ctx.LineTo(mousePositionStart); ctx.Stroke(); } } } }
/// <summary> /// Draw the marker. /// </summary> /// <param name="ctx">Context.</param> public override void Draw(Context ctx) { ctx.SetColor(PipelineNode.NodeColorBorder); Rectangle bndTmp = Bounds; ctx.RoundRectangle(bndTmp.Inflate(-2, -2), 2); if (compatible.IsFinal()) { ctx.SetColor(Colors.LightGray); } else { ctx.RoundRectangle(bndTmp.Inflate(-1, -1), 3); using (LinearGradient g = new LinearGradient(bndTmp.Left, bndTmp.Top, bndTmp.Right, bndTmp.Bottom)) { g.AddColorStop(0, Colors.Black.BlendWith(NodeColor, 0.7)); g.AddColorStop(1, NodeColor); ctx.Pattern = g; ctx.Fill(); } ctx.SetColor(NodeColor); } ctx.Fill(); if (IsInput) { int inputBufferSize = inputData.Count; List<Result> ihCopy; lock (inputHistoryLock) { ihCopy = new List<Result>(inputHistory); } foreach (Result input in ihCopy) { if (input.IsUsed(parent)) { inputBufferSize++; } else { lock (inputHistoryLock) { inputHistory.Remove(input); } } } if (inputBufferSize > 0) { bool sourceNodeIsAbove = true; if (edges.Count > 0 && edges[0] != null) { if (edges[0].to.Bounds.Center.Y > Bounds.Center.Y - 4.0) { sourceNodeIsAbove = false; } } textLayout.Text = inputBufferSize.ToString(); double textWidth = textLayout.GetSize().Width; double textHeight = textLayout.GetSize().Height; Point inputbufferSizeLocation = Bounds.Location.Offset( -24 -(textWidth/2), sourceNodeIsAbove ? textHeight + 6 : -6 - textHeight); ctx.Arc( inputbufferSizeLocation.X + textWidth / 2, inputbufferSizeLocation.Y + textHeight / 2, Math.Max(textHeight, textWidth) / 2 + 1, 0, 360 ); ctx.Fill(); ctx.SetColor(PipelineNode.NodeColor); ctx.DrawTextLayout(textLayout, inputbufferSizeLocation); } } else { // if this is a final node if (parent.algorithm.Output[positionNo].IsFinal()) { ctx.MoveTo(bndTmp.Right + 4, bndTmp.Top); ctx.LineTo(bndTmp.Right + 4, bndTmp.Bottom); ctx.Stroke(); // draw output size on end nodes (= number of features if (parent.results != null && parent.results.Count > 0 && parent.results[0].Item1 != null && parent.results[0].Item1.Length - 1 >= Position) { textLayout.Text = parent.results.Count.ToString(); double textWidth = textLayout.GetSize().Width; double textHeight = textLayout.GetSize().Height; Point outputbufferSizeLocation = Bounds.Location.Offset(Bounds.Width * 1.8, 0); ctx.Arc( outputbufferSizeLocation.X + textWidth / 2, outputbufferSizeLocation.Y + textHeight / 2, Math.Max(textHeight, textWidth) / 2 + 1, 0, 360 ); ctx.Fill(); ctx.SetColor(PipelineNode.NodeColor); ctx.DrawTextLayout(textLayout, outputbufferSizeLocation); } } } }
/// <summary> /// Draws the horizontal line plot using the Context and the x and y axes specified /// </summary> /// <param name="ctx">The Context with which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> public void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis) { double xMin = xAxis.PhysicalMin.X; double xMax = xAxis.PhysicalMax.X; xMin += pixelIndent_; xMax -= pixelIndent_; double length = Math.Abs (xMax - xMin); double lengthDiff = length - length*scale_; double indentAmount = lengthDiff/2; xMin += indentAmount; xMax -= indentAmount; double yPos = yAxis.WorldToPhysical (value_, false).Y; ctx.Save (); ctx.SetLineWidth (1); ctx.SetColor (color_); ctx.MoveTo (xMin, yPos); ctx.LineTo (xMax, yPos); ctx.Stroke (); ctx.Restore (); // todo: clip and proper logic for flipped axis min max. }
public virtual void Texts(Xwt.Drawing.Context ctx, double x, double y) { ctx.Save(); ctx.Translate(x, y); ctx.SetColor(Colors.Black); var col1 = new Rectangle(); var col2 = new Rectangle(); var text = new TextLayout(); text.Font = this.Font.WithSize(24); Console.WriteLine(text.Font.Size); // first text text.Text = "Lorem ipsum dolor sit amet,"; var size1 = text.GetSize(); col1.Width = size1.Width; col1.Height += size1.Height + 10; ctx.DrawTextLayout(text, 0, 0); // proofing width; test should align with text above ctx.SetColor(Colors.DarkMagenta); text.Text = "consetetur sadipscing elitr, sed diam nonumy"; text.Width = col1.Width; var size2 = text.GetSize(); ctx.DrawTextLayout(text, 0, col1.Bottom); col1.Height += size2.Height + 10; ctx.SetColor(Colors.Black); // proofing scale, on second col ctx.Save(); ctx.SetColor(Colors.Red); col2.Left = col1.Right + 10; text.Text = "eirmod tempor invidunt ut."; var scale = 1.2; text.Width = text.Width / scale; var size3 = text.GetSize(); col2.Height = size3.Height * scale; col2.Width = size3.Width * scale + 5; ctx.Scale(scale, scale); ctx.DrawTextLayout(text, col2.Left / scale, col2.Top / scale); ctx.Restore(); // proofing heigth, on second col ctx.Save(); ctx.SetColor(Colors.DarkCyan); text.Text = "Praesent ac lacus nec dolor pulvinar feugiat a id elit."; var size4 = text.GetSize(); text.Height = size4.Height / 2; text.Trimming = TextTrimming.WordElipsis; ctx.DrawTextLayout(text, col2.Left, col2.Bottom + 5); ctx.SetLineWidth(1); ctx.SetColor(Colors.Blue); ctx.Rectangle(new Rectangle(col2.Left, col2.Bottom + 5, text.Width, text.Height)); ctx.Stroke(); ctx.Restore(); // drawing col line ctx.SetLineWidth(1); ctx.SetColor(Colors.Black.WithAlpha(.5)); ctx.MoveTo(col1.Right + 5, col1.Top); ctx.LineTo(col1.Right + 5, col1.Bottom); ctx.Stroke(); ctx.MoveTo(col2.Right + 5, col2.Top); ctx.LineTo(col2.Right + 5, col2.Bottom); ctx.Stroke(); ctx.SetColor(Colors.Black); // proofing rotate, and printing size to see the values ctx.Save(); text.Font = this.Font.WithSize(10); text.Text = string.Format("Size 1 {0}\r\nSize 2 {1}\r\nSize 3 {2} Scale {3}", size1, size2, size3, scale); text.Width = -1; // this clears textsize text.Height = -1; ctx.Rotate(5); // maybe someone knows a formula with angle and textsize to calculyte ty var ty = 30; ctx.DrawTextLayout(text, ty, col1.Bottom + 10); ctx.Restore(); // scale example here: ctx.Restore(); TextLayout tl0 = new TextLayout(this); tl0.Font = this.Font.WithSize(10); tl0.Text = "This text contains attributes."; tl0.SetUnderline(0, "This".Length); tl0.SetForeground(new Color(0, 1.0, 1.0), "This ".Length, "text".Length); tl0.SetBackground(new Color(0, 0, 0), "This ".Length, "text".Length); tl0.SetFontWeight(FontWeight.Bold, "This text ".Length, "contains".Length); tl0.SetFontStyle(FontStyle.Italic, "This text ".Length, "contains".Length); tl0.SetStrikethrough("This text contains ".Length, "attributes".Length); ctx.DrawTextLayout(tl0, col2.Left, col2.Bottom + 100); // Text boces y = 180; // Without wrapping TextLayout tl = new TextLayout(this); tl.Text = "Stright text"; DrawText(ctx, tl, ref y); // With wrapping tl = new TextLayout(this); tl.Text = "The quick brown fox jumps over the lazy dog"; tl.Width = 100; DrawText(ctx, tl, ref y); // With blank lines tl = new TextLayout(this); tl.Text = "\nEmpty line above\nLine break above\n\nEmpty line above\n\n\nTwo empty lines above\nEmpty line below\n"; tl.Width = 200; DrawText(ctx, tl, ref y); }
public static void DrawRoundRectangle(Xwt.Drawing.Context cr, bool topLeftRound, bool topRightRound, bool bottomLeftRound, bool bottomRightRound, double x, double y, double r, double w, double h) { // UA****BQ // H C // * * // G D // TF****ES cr.NewPath(); if (topLeftRound) { cr.MoveTo(x + r, y); // Move to A } else { cr.MoveTo(x, y); // Move to U } if (topRightRound) { cr.LineTo(x + w - r, y); // Straight line to B cr.CurveTo(x + w, y, x + w, y, x + w, y + r); // Curve to C, Control points are both at Q } else { cr.LineTo(x + w, y); // Straight line to Q } if (bottomRightRound) { cr.LineTo(x + w, y + h - r); // Move to D cr.CurveTo(x + w, y + h, x + w, y + h, x + w - r, y + h); // Curve to E } else { cr.LineTo(x + w, y + h); // Move to S } if (bottomLeftRound) { cr.LineTo(x + r, y + h); // Line to F cr.CurveTo(x, y + h, x, y + h, x, y + h - r); // Curve to G } else { cr.LineTo(x, y + h); // Line to T } if (topLeftRound) { cr.LineTo(x, y + r); // Line to H cr.CurveTo(x, y, x, y, x + r, y); // Curve to A } else { cr.LineTo(x, y); // Line to U } cr.ClosePath(); }
void PathTo (Context ctx, double x, double y, bool stroke) { if (stroke) ctx.LineTo (x, y); else ctx.MoveTo (x, y); }
/// <summary> /// Called when the widget needs to be redrawn /// </summary> /// <param name='ctx'> /// Drawing context /// </param> /// <param name="dirtyRect"></param> protected override void OnDraw(Context ctx, Rectangle dirtyRect) { if (Bounds.IsEmpty) return; base.OnDraw(ctx, dirtyRect); // apply scale factor dirtyRect.X /= scaleFactor; dirtyRect.Y /= scaleFactor; dirtyRect.Width /= scaleFactor; dirtyRect.Height /= scaleFactor; // actual drawing bool redraw = Draw(ctx, dirtyRect, scaleFactor); // draw minimap if (ShowMiniMap && MinWidth > 0 && MinHeight > 0) { Point size = new Point(180.0, 180.0 * (MinHeight / MinWidth)); double minimapScale = Math.Min(size.X / MinWidth, size.Y / MinHeight); Point minimapPosition = new Point( scrollview.HorizontalScrollControl.Value + scrollview.HorizontalScrollControl.PageSize - size.X - 16, scrollview.VerticalScrollControl.Value + 16); ctx.RoundRectangle(minimapPosition, size.X, size.Y, 6); ctx.SetColor(Colors.LightGray.WithAlpha(0.4)); ctx.Fill(); ctx.Save(); ctx.Translate(minimapPosition); Draw(ctx, new Rectangle(0, 0, MinWidth, MinHeight), minimapScale); ctx.Restore(); } // set canvas min size foreach (PipelineNode node in nodes) { Rectangle boundwe = node.BoundWithExtras; if (boundwe.Right * scaleFactor > MinWidth) { MinWidth = boundwe.Right * scaleFactor + PipelineNode.NodeMargin.Right; } if (boundwe.Bottom * scaleFactor > MinHeight) { MinHeight = boundwe.Bottom * scaleFactor + PipelineNode.NodeMargin.Bottom; } Point offset = new Point(Math.Max(0, -boundwe.Left), Math.Max(0, -boundwe.Top)); if (offset != Point.Zero) { TranslateAllNodesBy(offset); redraw = true; QueueDraw(); } } // update things if (mouseAction.HasFlag(MouseAction.MoveNode)) { // move scrollbar Rectangle boundwe = lastSelectedNode.BoundWithExtras; boundwe.X *= scaleFactor; boundwe.Y *= scaleFactor; boundwe.Height *= scaleFactor; boundwe.Width *= scaleFactor; double viewportRight = scrollview.HorizontalScrollControl.Value + scrollview.Size.Width; double offsetH = (nodeToMoveOffset.X + boundwe.Width) * 0.5 / scaleFactor; if (boundwe.Right - offsetH > viewportRight) { scrollview.HorizontalScrollControl.Value += boundwe.Right - offsetH - viewportRight; } else if (boundwe.Left + offsetH < scrollview.HorizontalScrollControl.Value) { scrollview.HorizontalScrollControl.Value -= scrollview.HorizontalScrollControl.Value - offsetH - boundwe.Left; } double viewportBottom = scrollview.VerticalScrollControl.Value + scrollview.Size.Height; double offsetV = (nodeToMoveOffset.Y + boundwe.Height) * 0.5; if (boundwe.Bottom - offsetV > viewportBottom) { scrollview.VerticalScrollControl.Value += boundwe.Bottom - offsetV - viewportBottom; } else if (boundwe.Top + offsetV < scrollview.VerticalScrollControl.Value) { scrollview.VerticalScrollControl.Value -= scrollview.VerticalScrollControl.Value - offsetV - boundwe.Top; } } if ((mouseAction.HasFlag(MouseAction.AddEdge) || mouseAction.HasFlag(MouseAction.MoveEdge)) && !mouseAction.HasFlag(MouseAction.AddEdgeNew)) { ctx.MoveTo( connectNodesStartMarker.IsInput ? connectNodesStartMarker.Bounds.Left * scaleFactor : connectNodesStartMarker.Bounds.Right * scaleFactor, connectNodesStartMarker.Bounds.Center.Y * scaleFactor ); ctx.LineTo(connectNodesEnd.X * scaleFactor, connectNodesEnd.Y * scaleFactor); ctx.Stroke(); } // set redraw finish? redrawQueued = redraw; // initial scroll position if (!initialScrollPosition.IsEmpty && !redraw && (scrollview.HorizontalScrollControl.Value < 1.0 || scrollview.VerticalScrollControl.Value < 1.0)) { scrollview.HorizontalScrollControl.Value = Math.Min( initialScrollPosition.X, scrollview.HorizontalScrollControl.UpperValue - scrollview.HorizontalScrollControl.PageSize ); scrollview.VerticalScrollControl.Value = Math.Min( initialScrollPosition.Y, scrollview.VerticalScrollControl.UpperValue - scrollview.VerticalScrollControl.PageSize ); } }
public static void SharpLineY(this Xwt.Drawing.Context cr, double x1, double y1, double x2, double y2) { cr.MoveTo(x1, y1 + 0.5); cr.LineTo(x2, y2 + 0.5); }
/// <summary> /// Draws the marker at the given position /// </summary> /// <param name="ctx">The Drawing Context with which to draw.</param> /// <param name="x">The [physical] x position to draw the marker.</param> /// <param name="y">The [physical] y position to draw the marker.</param> public void Draw(Context ctx, double x, double y ) { ctx.Save (); ctx.SetLineWidth (lineWidth); ctx.SetColor (lineColor); switch (markerType) { case MarkerType.Cross1: ctx.MoveTo (x-h, y+h); ctx.LineTo (x+h, y-h); ctx.MoveTo (x+h, y+h); ctx.LineTo (x-h, y-h); ctx.Stroke (); break; case MarkerType.Cross2: ctx.MoveTo (x, y-h); ctx.LineTo (x, y+h); ctx.MoveTo (x-h, y); ctx.LineTo (x+h, y); ctx.Stroke (); break; case MarkerType.Circle: ctx.MoveTo (x+h,y); ctx.Arc (x, y, h, 0, 360); ctx.ClosePath (); if (filled ) { ctx.SetColor (fillColor); ctx.FillPreserve (); } ctx.SetColor (lineColor); ctx.Stroke (); break; case MarkerType.Square: ctx.Rectangle (x-h, y-h, size, size); ctx.ClosePath (); if (filled) { ctx.SetColor (fillColor); ctx.FillPreserve (); } ctx.SetColor (lineColor); ctx.Stroke (); break; case MarkerType.Triangle: ctx.MoveTo (x-h, y+h); ctx.LineTo (x, y-h); ctx.LineTo (x+h, y+h); ctx.ClosePath (); if (filled) { ctx.SetColor (fillColor); ctx.FillPreserve (); } ctx.SetColor (lineColor); ctx.Stroke (); break; case MarkerType.TriangleDown: ctx.MoveTo (x-h, y-h); ctx.LineTo (x, y+h); ctx.LineTo (x+h, y-h); ctx.ClosePath (); if (filled) { ctx.SetColor (fillColor); ctx.FillPreserve (); } ctx.SetColor (lineColor); ctx.Stroke (); break; case MarkerType.FilledCircle: ctx.MoveTo (x+h,y); ctx.Arc (x, y, h, 0, 360); ctx.ClosePath (); ctx.SetColor (fillColor); ctx.FillPreserve (); ctx.SetColor (lineColor); ctx.Stroke (); break; case MarkerType.FilledSquare: ctx.Rectangle (x-h, y-h, size, size); ctx.ClosePath (); ctx.SetColor (fillColor); ctx.FillPreserve (); ctx.SetColor (lineColor); ctx.Stroke (); break; case MarkerType.FilledTriangle: ctx.MoveTo (x-h, y+h); ctx.LineTo (x, y-h); ctx.LineTo (x+h, y+h); ctx.ClosePath (); ctx.SetColor (fillColor); ctx.FillPreserve (); ctx.SetColor (lineColor); ctx.Stroke (); break; case MarkerType.Diamond: ctx.MoveTo (x-h, y); ctx.LineTo (x, y-h); ctx.LineTo (x+h, y); ctx.LineTo (x, y+h); ctx.ClosePath (); if (filled) { ctx.SetColor (fillColor); ctx.FillPreserve (); } ctx.SetColor (lineColor); ctx.Stroke (); break; case MarkerType.Flag: ctx.MoveTo (x, y-size); ctx.LineTo (x+size, y-size+size/3); ctx.LineTo (x, y-size+2*size/3); ctx.ClosePath (); ctx.MoveTo (x, y); ctx.LineTo (x, y-size); if (filled) { ctx.SetColor (fillColor); ctx.FillPreserve (); } ctx.SetColor (lineColor); ctx.Stroke (); break; case MarkerType.FlagDown: ctx.MoveTo (x, y+size); ctx.LineTo (x+size, y+size-size/3); ctx.LineTo (x, y+size-2*size/3); ctx.ClosePath (); ctx.MoveTo (x, y); ctx.LineTo (x, y+size); if (filled) { ctx.SetColor (fillColor); ctx.FillPreserve (); } ctx.SetColor (lineColor); ctx.Stroke (); break; case MarkerType.FilledFlag: ctx.MoveTo (x, y-size); ctx.LineTo (x+size, y-size+size/3); ctx.LineTo (x, y-size+2*size/3); ctx.ClosePath (); ctx.MoveTo (x, y); ctx.LineTo (x, y-size); ctx.SetColor (fillColor); ctx.FillPreserve (); ctx.SetColor (lineColor); ctx.Stroke (); break; case MarkerType.None: break; } ctx.Restore (); }
static void DrawBorder(Context ctx, double x, double y, double w, double h, double radius) { ctx.NewPath (); // test limits (without using multiplication) if (radius > w - radius) radius = w / 2; if (radius > h - radius) radius = h / 2; // approximate (quite close) the arc using a bezier curve double arc = ArcToBezier * radius; // top-left corner ctx.MoveTo (x + radius, y); // top edge ctx.LineTo (x + w - radius, y); // top-right corner ctx.CurveTo (x + w - radius + arc, y, x + w, y + arc, x + w, y + radius); // right edge ctx.LineTo (x + w, y + h - radius); // bottom-right corner ctx.CurveTo (x + w, y + h - radius + arc, x + w + arc - radius, y + h, x + w - radius, y + h); // bottom edge ctx.LineTo (x + radius, y + h); // bottom-left corner ctx.CurveTo (x + radius - arc, y + h, x, y + h - arc, x, y + h - radius); // left edge ctx.LineTo (x, y + radius); // top-left corner ctx.CurveTo (x, y + radius - arc, x + radius - arc, y, x + radius, y); }
/// <summary> /// Draws the point plot using the Drawing Context and x and y axes supplied /// </summary> /// <param name="ctx">The Drawing Context with which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> public virtual void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis) { SequenceAdapter data_ = new SequenceAdapter (DataSource, DataMember, OrdinateData, AbscissaData ); double leftCutoff_ = xAxis.PhysicalMin.X - marker.Size; double rightCutoff_ = xAxis.PhysicalMax.X + marker.Size; ctx.Save (); ctx.SetColor (marker.LineColor); ctx.SetLineWidth (marker.LineWidth); for (int i=0; i<data_.Count; ++i) { if (!Double.IsNaN(data_[i].X) && !Double.IsNaN(data_[i].Y)) { Point xPos = xAxis.WorldToPhysical (data_[i].X, false); if (xPos.X < leftCutoff_ || rightCutoff_ < xPos.X) { continue; } Point yPos = yAxis.WorldToPhysical (data_[i].Y, false); marker.Draw (ctx, xPos.X, yPos.Y); if (marker.DropLine) { Point yMin = new Point (data_[i].X, Math.Max (0.0, yAxis.Axis.WorldMin)); Point yStart = yAxis.WorldToPhysical (yMin.Y, false); ctx.MoveTo (xPos.X, yStart.Y); ctx.LineTo (xPos.X, yPos.Y); ctx.Stroke (); } } } ctx.Restore (); }
/// <summary> /// Draws a representation of this plot in the legend. /// </summary> /// <param name="ctx">The Drawing Context with which to draw.</param> /// <param name="startEnd">A rectangle specifying the bounds of the area in the legend set aside for drawing.</param> public void DrawInLegend(Context ctx, Rectangle startEnd ) { ctx.Save (); if (marker.Size > 0) { marker.Draw (ctx, (startEnd.Left + startEnd.Right) / 2, (startEnd.Top + startEnd.Bottom) / 2); } else if (marker.LineWidth > 0) { ctx.SetLineWidth (marker.LineWidth); ctx.SetColor (marker.LineColor); ctx.MoveTo ((startEnd.Left + startEnd.Right)/2, (startEnd.Top + startEnd.Bottom - marker.LineWidth)/2); ctx.LineTo ((startEnd.Left + startEnd.Right)/2, (startEnd.Top + startEnd.Bottom + marker.LineWidth)/2); ctx.Stroke (); } ctx.Restore (); }
void Draw (Context ctx, bool fill) { var parent = (RoundedFrameBox)Parent; var border = parent.BorderSpacing; var radius = parent.cornerRadius; var rect = Bounds; ctx.MoveTo (rect.X, rect.Y); if (border.Top > 0) { ctx.NewPath (); if (radius.TopLeft > 0) ctx.Arc (rect.Left + radius.TopLeft + border.Left / 2, rect.Top + radius.TopLeft + border.Top / 2, radius.TopLeft, 180, 270); else PathTo (ctx, rect.Left, rect.Top + border.Top / 2, fill); if (radius.TopRight > 0) { ctx.LineTo (rect.Right - (radius.TopRight + border.Right / 2), rect.Top + border.Top / 2); ctx.Arc (rect.Right - (radius.TopRight + border.Right / 2), rect.Top + radius.TopRight + border.Top / 2, radius.TopRight, 270, 0); } else ctx.LineTo (rect.Right, rect.Top + border.Top / 2); } else PathTo (ctx, rect.Right - border.Right / 2, rect.Top, fill); if (border.Right > 0) // TODO: round corners if top/bottom border disabled ctx.LineTo (rect.Right - border.Right / 2, rect.Bottom - (border.Bottom > 0 ? radius.BottomRight : 0)); else PathTo (ctx, rect.Right - border.Right / 2, rect.Bottom - (border.Bottom > 0 ? radius.BottomRight : 0), fill); if (border.Bottom > 0) { if (radius.BottomRight > 0) ctx.Arc (rect.Right - (radius.BottomRight + border.Right / 2), rect.Bottom - (radius.BottomRight + border.Bottom / 2), radius.BottomRight, 0, 90); else PathTo (ctx, rect.Right, rect.Bottom - border.Bottom / 2, fill); if (radius.BottomLeft > 0) { ctx.LineTo (rect.Left + (radius.BottomLeft + border.Left / 2), rect.Bottom - border.Bottom / 2); ctx.Arc (rect.Left + radius.BottomLeft + border.Left / 2, rect.Bottom - (radius.BottomLeft + border.Bottom / 2), radius.BottomLeft, 90, 180); } else ctx.LineTo (rect.Left + border.Left / 2, rect.Bottom - border.Bottom / 2); } else PathTo (ctx, rect.Left + border.Left / 2, rect.Bottom - border.Bottom / 2, fill); if (border.Left > 0) // TODO: round corners if top/bottom border disabled ctx.LineTo (rect.Left + border.Left / 2, rect.Top + (border.Top > 0 ? radius.TopLeft : 0)); else PathTo (ctx, rect.Left + border.Left / 2, rect.Top + (border.Top > 0 ? radius.TopLeft : 0), fill); if (fill) { ctx.SetColor (parent.innerColor); ctx.Fill (); } else { ctx.SetColor (parent.borderColor); ctx.SetLineWidth (parent.borderWidth); ctx.Stroke (); } }
public virtual void Curves2 (Context ctx, double sx, double sy) { ctx.Save (); ctx.Translate (sx, sy); ctx.SetColor (Colors.Black); double x = 0, y = 40; double x1 = y - x, y1 = x1 + y, x2 = x + y, y2 = x, x3 = y1, y3 = y; ctx.MoveTo (x, y); ctx.CurveTo (x1, y1, x2, y2, x3, y3); ctx.SetLineWidth (2.0); ctx.Stroke (); ctx.SetColor (new Color (1, 0.2, 0.2, 0.6)); ctx.SetLineWidth (1.0); ctx.MoveTo (x, y); ctx.LineTo (x1, y1); ctx.MoveTo (x2, y2); ctx.LineTo (x3, y3); ctx.Stroke (); ctx.Restore (); }
/// <summary> /// Draw the axis. This involves three steps: /// (1) Draw the axis line. /// (2) Draw the tick marks. /// (3) Draw the label. /// </summary> /// <param name="ctx">The Drawing Context with which to draw.</param> /// <param name="physicalMin">The physical position corresponding to the world minimum of the axis.</param> /// <param name="physicalMax">The physical position corresponding to the world maximum of the axis.</param> /// <param name="boundingBox">out The bounding rectangle of the axis including axis line, label, tick marks and tick mark labels</param> public virtual void Draw(Context ctx, Point physicalMin, Point physicalMax, out Rectangle boundingBox) { // calculate the bounds of the axis line only. double x1 = Math.Min (physicalMin.X, physicalMax.X); double x2 = Math.Max (physicalMin.X, physicalMax.X); double y1 = Math.Min (physicalMin.Y, physicalMax.Y); double y2 = Math.Max (physicalMin.Y, physicalMax.Y); Rectangle bounds = new Rectangle (x1, y1, x2-x1, y2-y1); if (!Hidden) { // (1) Draw the axis line. ctx.Save (); ctx.SetLineWidth (1); ctx.SetColor (LineColor); ctx.MoveTo (physicalMin.X+0.5, physicalMin.Y+0.5); ctx.LineTo (physicalMax.X+0.5, physicalMax.Y+0.5); ctx.Stroke (); ctx.Restore (); // (2) draw tick marks (subclass responsibility). object labelOffset; object tickBounds; DrawTicks (ctx, physicalMin, physicalMax, out labelOffset, out tickBounds); // (3) draw the axis label object labelBounds = null; if (!HideTickText) { labelBounds = DrawLabel (ctx, (Point)labelOffset, physicalMin, physicalMax); } // (4) merge bounds and return. if (labelBounds != null) { bounds = Rectangle.Union (bounds, (Rectangle)labelBounds); } if (tickBounds != null) { bounds = Rectangle.Union (bounds, (Rectangle)tickBounds); } } boundingBox = bounds; }
void DrawBorder(Context ctx, double x, double y, double w, double h, double radius, double thickness) { // test limits (without using multiplication) if (radius > w - radius) radius = w / 2; if (radius > h - radius) radius = h / 2; // approximate (quite close) the arc using a bezier curve double arc = ArcToBezier * radius; ctx.SetLineWidth (thickness); // top-left corner ctx.NewPath (); ctx.MoveTo (x, y + radius); ctx.CurveTo (x, y + radius - arc, x + radius - arc, y, x + radius, y); ctx.Pattern = GetCornerGradient (x + radius, y + radius, radius, thickness / 2); ctx.Stroke (); // top edge ctx.NewPath (); ctx.MoveTo (x + radius - 0.5, y); ctx.LineTo (x + w - radius + 0.5, y); ctx.Pattern = GetTopEdgeGradient (y, thickness / 2); ctx.Stroke (); // top-right corner ctx.NewPath (); ctx.MoveTo (x + w - radius, y); ctx.CurveTo (x + w - radius + arc, y, x + w, y + arc, x + w, y + radius); ctx.Pattern = GetCornerGradient (x + w - radius, y + radius, radius, thickness / 2); ctx.Stroke (); // right edge ctx.NewPath (); ctx.MoveTo (x + w, y + radius - 0.5); ctx.LineTo (x + w, y + h - radius + 0.5); ctx.Pattern = GetRightEdgeGradient (x + w, thickness / 2); ctx.Stroke (); // bottom-right corner ctx.NewPath (); ctx.MoveTo (x + w, y + h - radius); ctx.CurveTo (x + w, y + h - radius + arc, x + w + arc - radius, y + h, x + w - radius, y + h); ctx.Pattern = GetCornerGradient (x + w - radius, y + h - radius, radius, thickness / 2); ctx.Stroke (); // bottom edge ctx.NewPath (); ctx.MoveTo (x + w - radius + 0.5, y + h); ctx.LineTo (x + radius - 0.5, y + h); ctx.Pattern = GetBottomEdgeGradient (y + h, thickness / 2); ctx.Stroke (); // bottom-left corner ctx.NewPath (); ctx.MoveTo (x + radius, y + h); ctx.CurveTo (x + radius - arc, y + h, x, y + h - arc, x, y + h - radius); ctx.Pattern = GetCornerGradient (x + radius, y + h - radius, radius, thickness / 2); ctx.Stroke (); // left edge ctx.NewPath (); ctx.MoveTo (x, y + h - radius + 0.5); ctx.LineTo (x, y + radius - 0.5); ctx.Pattern = GetLeftEdgeGradient (x, thickness / 2); ctx.Stroke (); }
/// <summary> /// Draws the arrow on a plot surface. /// </summary> /// <param name="ctx">the Drawing Context with which to draw</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> public void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis ) { if (To.X > xAxis.Axis.WorldMax || To.X < xAxis.Axis.WorldMin) { return; } if (To.Y > yAxis.Axis.WorldMax || To.Y < yAxis.Axis.WorldMin) { return; } ctx.Save (); TextLayout layout = new TextLayout (); layout.Font = textFont_; layout.Text = text_; double angle = angle_; if (angle_ < 0.0) { int mul = -(int)(angle_ / 360.0) + 2; angle = angle_ + 360.0 * (double)mul; } double normAngle = (double)angle % 360.0; // angle in range 0 -> 360. Point toPoint = new Point ( xAxis.WorldToPhysical (to_.X, true).X, yAxis.WorldToPhysical (to_.Y, true).Y); double xDir = Math.Cos (normAngle * 2.0 * Math.PI / 360.0); double yDir = Math.Sin (normAngle * 2.0 * Math.PI / 360.0); toPoint.X += xDir*headOffset_; toPoint.Y += yDir*headOffset_; double xOff = physicalLength_ * xDir; double yOff = physicalLength_ * yDir; Point fromPoint = new Point( (int)(toPoint.X + xOff), (int)(toPoint.Y + yOff) ); ctx.SetLineWidth (1); ctx.SetColor (arrowColor_); ctx.MoveTo (fromPoint); ctx.LineTo (toPoint); ctx.Stroke (); xOff = headSize_ * Math.Cos ((normAngle-headAngle_/2) * 2.0 * Math.PI / 360.0); yOff = headSize_ * Math.Sin ((normAngle-headAngle_/2) * 2.0 * Math.PI / 360.0); ctx.LineTo (toPoint.X + xOff, toPoint.Y + yOff); double xOff2 = headSize_ * Math.Cos ((normAngle+headAngle_/2) * 2.0 * Math.PI / 360.0); double yOff2 = headSize_ * Math.Sin ((normAngle+headAngle_/2) * 2.0 * Math.PI / 360.0); ctx.LineTo (toPoint.X + xOff2, toPoint.Y + yOff2); ctx.LineTo (toPoint); ctx.ClosePath (); ctx.SetColor (arrowColor_); ctx.Fill (); Size textSize = layout.GetSize (); Size halfSize = new Size (textSize.Width/2, textSize.Height/2); double quadrantSlideLength = halfSize.Width + halfSize.Height; double quadrantD = normAngle / 90.0; // integer part gives quadrant. int quadrant = (int)quadrantD; // quadrant in. double prop = quadrantD - (double)quadrant; // proportion of way through this qadrant. double dist = prop * quadrantSlideLength; // distance along quarter of bounds rectangle. // now find the offset from the middle of the text box that the // rear end of the arrow should end at (reverse this to get position // of text box with respect to rear end of arrow). // // There is almost certainly an elgant way of doing this involving // trig functions to get all the signs right, but I'm about ready to // drop off to sleep at the moment, so this blatent method will have // to do. Point offsetFromMiddle = new Point (0, 0); switch (quadrant) { case 0: if (dist > halfSize.Height) { dist -= halfSize.Height; offsetFromMiddle = new Point ( -halfSize.Width + dist, halfSize.Height ); } else { offsetFromMiddle = new Point ( -halfSize.Width, - dist ); } break; case 1: if (dist > halfSize.Width) { dist -= halfSize.Width; offsetFromMiddle = new Point ( halfSize.Width, halfSize.Height - dist ); } else { offsetFromMiddle = new Point ( dist, halfSize.Height ); } break; case 2: if (dist > halfSize.Height) { dist -= halfSize.Height; offsetFromMiddle = new Point ( halfSize.Width - dist, -halfSize.Height ); } else { offsetFromMiddle = new Point ( halfSize.Width, -dist ); } break; case 3: if (dist > halfSize.Width) { dist -= halfSize.Width; offsetFromMiddle = new Point ( -halfSize.Width, -halfSize.Height + dist ); } else { offsetFromMiddle = new Point ( -dist, -halfSize.Height ); } break; default: throw new XwPlotException( "Programmer error." ); } ctx.SetColor (textColor_); double x = fromPoint.X - halfSize.Width - offsetFromMiddle.X; double y = fromPoint.Y - halfSize.Height + offsetFromMiddle.Y; ctx.DrawTextLayout (layout, x, y); ctx.Restore (); }
public static void Line(this Xwt.Drawing.Context cr, double x1, double y1, double x2, double y2) { cr.MoveTo(x1, y1); cr.LineTo(x2, y2); }
/// <summary> /// Draws the line plot using the Context and Physical Axes provided /// </summary> /// <param name="ctx">The Drawing Context with which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> /// <param name="drawShadow">If true draw the shadow for the line. If false, draw line.</param> public void DrawLineOrShadow(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis, bool drawShadow) { SequenceAdapter data = new SequenceAdapter (DataSource, DataMember, OrdinateData, AbscissaData); ITransform2D t = Transform2D.GetTransformer (xAxis, yAxis); int numberPoints = data.Count; if (data.Count == 0) { return; } ctx.Save (); ctx.SetLineWidth (lineWidth_); // clipping is now handled assigning a clip region in the // graphic object before this call if (numberPoints == 1) { Point physical = t.Transform (data[0]); if (drawShadow) { ctx.SetColor (shadowColor_); ctx.MoveTo (physical.X - 0.5 + ShadowOffset.X, physical.Y + ShadowOffset.Y); ctx.LineTo (physical.X + 0.5 + ShadowOffset.X, physical.Y + ShadowOffset.Y); ctx.Stroke (); } else { ctx.SetColor (lineColor_); ctx.MoveTo (physical.X-0.5, physical.Y); ctx.LineTo (physical.X+0.5, physical.Y); ctx.Stroke (); } } else { // prepare for clipping double leftCutoff = xAxis.PhysicalToWorld (xAxis.PhysicalMin, false); double rightCutoff = xAxis.PhysicalToWorld (xAxis.PhysicalMax, false); if (leftCutoff > rightCutoff) { Utils.Swap (ref leftCutoff, ref rightCutoff); } if (drawShadow) { // correct cut-offs double shadowCorrection = xAxis.PhysicalToWorld (ShadowOffset, false) - xAxis.PhysicalToWorld (new Point(0,0), false); leftCutoff -= shadowCorrection; rightCutoff -= shadowCorrection; } for (int i = 1; i < numberPoints; ++i) { // check to see if any values null. If so, then continue. double dx1 = data[i-1].X; double dx2 = data[i].X; double dy1 = data[i-1].Y; double dy2 = data[i].Y; if (Double.IsNaN(dx1) || Double.IsNaN(dy1) || Double.IsNaN(dx2) || Double.IsNaN(dy2)) { continue; } // do horizontal clipping here, to speed up if ((dx1 < leftCutoff && dx2 < leftCutoff) || (rightCutoff < dx1 && rightCutoff < dx2)) { continue; } // else draw line. Point p1 = t.Transform (data[i-1]); Point p2 = t.Transform (data[i]); // when very far zoomed in, points can fall ontop of each other, // and g.DrawLine throws an overflow exception if (p1.Equals(p2)) { continue; } if (drawShadow) { ctx.SetColor (shadowColor_); ctx.MoveTo (p1.X + ShadowOffset.X, p1.Y + ShadowOffset.Y); ctx.LineTo (p2.X + ShadowOffset.X, p2.Y + ShadowOffset.Y); ctx.Stroke (); } else { ctx.SetColor (lineColor_); ctx.MoveTo (p1.X, p1.Y); ctx.LineTo (p2.X, p2.Y); ctx.Stroke (); } } } ctx.Restore (); }
/// <summary> /// Draws the step plot using a Drawing Context against the provided x and y axes. /// </summary> /// <param name="ctx">The Drawing Context with which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> public virtual void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis ) { SequenceAdapter data = new SequenceAdapter (DataSource, DataMember, OrdinateData, AbscissaData); double leftCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMin, false); double rightCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMax, false); for (int i=0; i<data.Count; ++i) { Point p1 = data[i]; if (Double.IsNaN(p1.X) || Double.IsNaN(p1.Y)) { continue; } Point p2; Point p3; if (i+1 != data.Count) { p2 = data[i+1]; if (Double.IsNaN(p2.X) || Double.IsNaN(p2.Y)) { continue; } p2.Y = p1.Y; p3 = data[i+1]; } else { // Check that we are not dealing with a DataSource of 1 point. // This check is done here so it is only checked on the end // condition and not for every point in the DataSource. if (data.Count > 1) { p2 = data[i - 1]; } else { // TODO: Once log4net is set up post a message to the user that a step-plot of 1 really does not make any sense. p2 = p1; } double offset = p1.X - p2.X; p2.X = p1.X + offset; p2.Y = p1.Y; p3 = p2; } if (center_) { double offset = ( p2.X - p1.X ) / 2.0; p1.X -= offset; p2.X -= offset; p3.X -= offset; } Point xPos1 = xAxis.WorldToPhysical (p1.X, false); Point yPos1 = yAxis.WorldToPhysical (p1.Y, false); Point xPos2 = xAxis.WorldToPhysical (p2.X, false); Point yPos2 = yAxis.WorldToPhysical (p2.Y, false); Point xPos3 = xAxis.WorldToPhysical (p3.X, false); Point yPos3 = yAxis.WorldToPhysical (p3.Y, false); // do horizontal clipping here, to speed up if ((p1.X<leftCutoff && p2.X<leftCutoff && p3.X<leftCutoff) || (p1.X>rightCutoff && p2.X>rightCutoff && p3.X>rightCutoff)) { continue; } ctx.Save (); ctx.SetColor (Color); ctx.SetLineWidth (1); if (!this.hideHorizontalSegments_) { if (scale_ != 1) { double middle = (xPos2.X + xPos1.X) / 2; double width = xPos2.X - xPos1.X; width *= this.scale_; ctx.MoveTo (middle-width/2, yPos1.Y); ctx.LineTo (middle+width/2, yPos2.Y); } else { ctx.MoveTo (xPos1.X, yPos1.Y); ctx.LineTo (xPos2.X, yPos2.Y); } ctx.Stroke (); } if (!this.hideVerticalSegments_) { ctx.MoveTo (xPos2.X, yPos2.Y); ctx.LineTo (xPos3.X, yPos3.Y); ctx.Stroke (); } ctx.Restore (); } }
void DrawFocus(Context ctx, Point p) { // Draw a 'zoom'-style Focus at specified point double focusRadius = 32; double r = 12, w = focusRadius - 1; Point o = Point.Zero; // Drawing origin // Align single-thickness lines on 0.5 pixel coords o.X += 0.5; o.Y += 0.5; ctx.Save (); ctx.Translate (p); // Final translation // Hairlines in X-direction ctx.MoveTo (o.X + r, o.Y); ctx.LineTo (o.X + w, o.Y); ctx.MoveTo (o.X - r, o.Y); ctx.LineTo (o.X - w, o.Y); // Hairlines in Y-direction ctx.MoveTo (o.X, o.Y + r); ctx.LineTo (o.X, o.Y + w); ctx.MoveTo (o.X, o.Y - r); ctx.LineTo (o.X, o.Y - w); // Inner single-thickness circle ctx.MoveTo (o.X + r, o.Y); ctx.Arc (o.X, o.Y, r, 0, 360); ctx.SetColor (Colors.Black); ctx.SetLineWidth (1); ctx.Stroke (); // Double thickness outer arcs. Draw at (0,0) and rotate o = Point.Zero; r = 22; ctx.Rotate (5); ctx.MoveTo (r, 0); ctx.Arc (o.X, o.Y, r, 0, 80); ctx.MoveTo (o.X, r); ctx.Arc (o.X, o.Y, r, 90, 170); ctx.MoveTo (-r, o.Y); ctx.Arc (o.X, o.Y, r, 180, 260); ctx.MoveTo (o.X, -r); ctx.Arc (o.X, o.Y, r, 270, 350); ctx.SetLineWidth (2); ctx.Stroke (); ctx.Restore (); }
void DrawTicks (Context ctx, TickEnumerator e, AxisPosition pos, AxisDimension ad, int tickSize, bool showLabels) { double rheight = Bounds.Height; TextLayout layout = null; if (showLabels) { layout = new TextLayout (); layout.Font = chartFont; } bool isX = pos == AxisPosition.Top || pos == AxisPosition.Bottom; bool isTop = pos == AxisPosition.Top || pos == AxisPosition.Right; double start = GetStart (ad); double end = GetEnd (ad); e.Init (GetOrigin (ad)); while (e.CurrentValue > start) e.MovePrevious (); double lastPosLabel; double lastPos; double lastTw = 0; if (isX) { lastPosLabel = reverseXAxis ? left + width + MinLabelGapX : left - MinLabelGapX; lastPos = left - minTickStep*2; } else { lastPosLabel = reverseYAxis ? top - MinLabelGapY : rheight + MinLabelGapY; lastPos = top + height + minTickStep*2; } for ( ; e.CurrentValue <= end; e.MoveNext ()) { double px, py; double tw = 0, th = 0; int tick = tickSize; GetPoint (e.CurrentValue, e.CurrentValue, out px, out py); if (showLabels) { layout.Text = e.CurrentLabel; var ts = layout.GetSize (); tw = ts.Width; th = ts.Height; } if (isX) { if (Math.Abs ((long)px - (long)lastPos) < minTickStep || px < left || px > left + width) continue; lastPos = px; bool labelFits = false; if ((Math.Abs (px - lastPosLabel) - (tw/2) - (lastTw/2)) >= MinLabelGapX) { lastPosLabel = px; lastTw = tw; labelFits = true; } if (isTop) { if (showLabels) { if (labelFits) ctx.DrawTextLayout (layout, px - (tw/2), top - AreaBorderWidth - th); else tick = tick / 2; } ctx.MoveTo (px, top); ctx.LineTo (px, top + tick); ctx.Stroke (); } else { if (showLabels) { if (labelFits) ctx.DrawTextLayout (layout, px - (tw/2), top + height + AreaBorderWidth); else tick = tick / 2; } ctx.MoveTo (px, top + height); ctx.LineTo (px, top + height - tick); ctx.Stroke (); } } else { if (Math.Abs ((long)lastPos - (long)py) < minTickStep || py < top || py > top + height) continue; lastPos = py; bool labelFits = false; if ((Math.Abs (py - lastPosLabel) - (th/2) - (lastTw/2)) >= MinLabelGapY) { lastPosLabel = py; lastTw = th; labelFits = true; } if (isTop) { if (showLabels) { if (labelFits) ctx.DrawTextLayout (layout, left + width + AreaBorderWidth + 1, py - (th/2)); else tick = tick / 2; } ctx.MoveTo (left + width, py); ctx.LineTo (left + width - tick, py); ctx.Stroke (); } else { if (showLabels) { if (labelFits) ctx.DrawTextLayout (layout, left - AreaBorderWidth - tw - 1, py - (th/2)); else tick = tick / 2; } ctx.MoveTo (left, py); ctx.LineTo (left + tick, py); ctx.Stroke (); } } } }
/// <summary> /// Draw a tick on the axis. /// </summary> /// <param name="ctx">The Drawing Context with on which to draw.</param> /// <param name="w">The tick position in world coordinates.</param> /// <param name="size">The size of the tick (in pixels)</param> /// <param name="text">The text associated with the tick</param> /// <param name="textOffset">The Offset to draw from the auto calculated position</param> /// <param name="axisPhysMin">The minimum physical extent of the axis</param> /// <param name="axisPhysMax">The maximum physical extent of the axis</param> /// <param name="boundingBox">out: The bounding rectangle for the tick and tickLabel drawn</param> /// <param name="labelOffset">out: offset from the axies required for axis label</param> public virtual void DrawTick( Context ctx, double w, double size, string text, Point textOffset, Point axisPhysMin, Point axisPhysMax, out Point labelOffset, out Rectangle boundingBox ) { // determine physical location where tick touches axis. Point tickStart = WorldToPhysical (w, axisPhysMin, axisPhysMax, true); // determine offset from start point. Point axisDir = Utils.UnitVector (axisPhysMin, axisPhysMax); // rotate axisDir anti-clockwise by TicksAngle radians to get tick direction. Note that because // the physical (pixel) origin is at the top left, a RotationTransform by a positive angle will // be clockwise. Consequently, for anti-clockwise rotations, use cos(A-B), sin(A-B) formulae double x1 = Math.Cos (TicksAngle) * axisDir.X + Math.Sin (TicksAngle) * axisDir.Y; double y1 = Math.Cos (TicksAngle) * axisDir.Y - Math.Sin (TicksAngle) * axisDir.X; // now get the scaled tick vector. Point tickVector = new Point (TickScale * size * x1, TickScale * size * y1); if (TicksCrossAxis) { tickStart.X -= tickVector.X / 2; tickStart.Y -= tickVector.Y / 2; } // and the end point [point off axis] of tick mark. Point tickEnd = new Point (tickStart.X + tickVector.X, tickStart.Y + tickVector.Y); // and draw it ctx.SetLineWidth (1); ctx.SetColor (LineColor); ctx.MoveTo (tickStart.X+0.5, tickStart.Y+0.5); ctx.LineTo (tickEnd.X+0.5, tickEnd.Y+0.5); ctx.Stroke (); // calculate bounds of tick. double minX = Math.Min (tickStart.X, tickEnd.X); double minY = Math.Min (tickStart.Y, tickEnd.Y); double maxX = Math.Max (tickStart.X, tickEnd.X); double maxY = Math.Max (tickStart.Y, tickEnd.Y); boundingBox = new Rectangle (minX, minY, maxX-minX, maxY-minY); // by default, label offset from axis is 0. TODO: revise this. labelOffset = new Point (-tickVector.X, -tickVector.Y); // ------------------------ // now draw associated text. // **** TODO **** // The following code needs revising. A few things are hard coded when // they should not be. Also, angled tick text currently just works for // the bottom x-axis. Also, it's a bit hacky. if (text != "" && !HideTickText) { TextLayout layout = new TextLayout (); layout.Font = tickTextFontScaled; layout.Text = text; Size textSize = layout.GetSize (); // determine the center point of the tick text. double textCenterX; double textCenterY; // if text is at pointy end of tick. if (!TickTextNextToAxis) { // offset due to tick. textCenterX = tickStart.X + tickVector.X*1.2; textCenterY = tickStart.Y + tickVector.Y*1.2; // offset due to text box size. textCenterX += 0.5 * x1 * textSize.Width; textCenterY += 0.5 * y1 * textSize.Height; } // else it's next to the axis. else { // start location. textCenterX = tickStart.X; textCenterY = tickStart.Y; // offset due to text box size. textCenterX -= 0.5 * x1 * textSize.Width; textCenterY -= 0.5 * y1 * textSize.Height; // bring text away from the axis a little bit. textCenterX -= x1*(2.0+FontScale); textCenterY -= y1*(2.0+FontScale); } // If tick text is angled.. if (TickTextAngle != 0) { // determine the point we want to rotate text about. Point textScaledTickVector = new Point ( TickScale * x1 * (textSize.Height/2), TickScale * y1 * (textSize.Height/2) ); Point rotatePoint; if (TickTextNextToAxis) { rotatePoint = new Point ( tickStart.X - textScaledTickVector.X, tickStart.Y - textScaledTickVector.Y); } else { rotatePoint = new Point ( tickEnd.X + textScaledTickVector.X, tickEnd.Y + textScaledTickVector.Y); } double actualAngle; if (FlipTickText) { double radAngle = TickTextAngle * Math.PI / 180; rotatePoint.X += textSize.Width * Math.Cos (radAngle); rotatePoint.Y += textSize.Width * Math.Sin (radAngle); actualAngle = TickTextAngle + 180; } else { actualAngle = TickTextAngle; } ctx.Save (); ctx.Translate (rotatePoint.X, rotatePoint.Y); ctx.Rotate (actualAngle); Point [] recPoints = new Point [2]; recPoints[0] = new Point (0.0, -textSize.Height/2); recPoints[1] = new Point (textSize.Width, textSize.Height); ctx.TransformPoints (recPoints); double t_x1 = Math.Min (recPoints[0].X, recPoints[1].X); double t_x2 = Math.Max (recPoints[0].X, recPoints[1].X); double t_y1 = Math.Min (recPoints[0].Y, recPoints[1].Y); double t_y2 = Math.Max (recPoints[0].Y, recPoints[1].Y); boundingBox = Rectangle.Union (boundingBox, new Rectangle (t_x1, t_y1, (t_x2-t_x1), (t_y2-t_y1))); ctx.DrawTextLayout (layout, 0, -textSize.Height/2); t_x2 -= tickStart.X; t_y2 -= tickStart.Y; t_x2 *= 1.25; t_y2 *= 1.25; labelOffset = new Point (t_x2, t_y2); ctx.Restore (); //ctx.Rectangle (boundingBox.X, boundingBox.Y, boundingBox.Width, boundingBox.Height); //ctx.Stroke (); } else { double bx1 = (textCenterX - textSize.Width/2); double by1 = (textCenterY - textSize.Height/2); double bx2 = textSize.Width; double by2 = textSize.Height; Rectangle drawRect = new Rectangle (bx1, by1, bx2, by2); // ctx.Rectangle (drawRect); boundingBox = Rectangle.Union (boundingBox, drawRect); // ctx.Rectangle (boundingBox); ctx.DrawTextLayout (layout, bx1, by1); textCenterX -= tickStart.X; textCenterY -= tickStart.Y; textCenterX *= 2.3; textCenterY *= 2.3; labelOffset = new Point (textCenterX, textCenterY); } } }
void DrawSerie (Context ctx, Serie serie) { ctx.NewPath (); ctx.Rectangle (left, top, width + 1, height + 1); ctx.Clip (); ctx.NewPath (); ctx.SetColor (serie.Color); ctx.SetLineWidth (serie.LineWidth); bool first = true; bool blockMode = serie.DisplayMode == DisplayMode.BlockLine; double lastY = 0; foreach (Data d in serie.GetData (startX, endX)) { double x, y; GetPoint (d.X, d.Y, out x, out y); if (first) { ctx.MoveTo (x, y); lastY = y; first = false; } else { if (blockMode) { if (lastY != y) ctx.LineTo (x, lastY); ctx.LineTo (x, y); } else ctx.LineTo (x, y); } lastY = y; } ctx.Stroke (); }
protected override void OnDraw (Context ctx, Rectangle dirtyRect) { ctx.Rectangle (Bounds); ctx.SetColor (Colors.White); ctx.Fill (); ctx.MoveTo (0, 0); ctx.LineTo (Size.Width, 0); ctx.LineTo (0, Size.Height); ctx.LineTo (0, 0); ctx.SetColor (Colors.Black); ctx.Fill (); ctx.Rectangle (Bounds); ctx.SetColor (color); ctx.Fill (); }
void DrawCursor (Context ctx, ChartCursor cursor) { ctx.SetColor (cursor.Color); double x, y; GetPoint (cursor.Value, cursor.Value, out x, out y); if (cursor.Dimension == AxisDimension.X) { double cy = top - AreaBorderWidth - 1; ctx.MoveTo (x, cy); ctx.LineTo (x + (cursor.HandleSize/2), cy - cursor.HandleSize + 1); ctx.LineTo (x - (cursor.HandleSize/2), cy - cursor.HandleSize + 1); ctx.ClosePath (); if (activeCursor == cursor) ctx.FillPreserve (); ctx.Stroke (); ctx.MoveTo (x, top); ctx.RelLineTo (0, height); ctx.Stroke (); } else { throw new NotSupportedException (); } }
/// <summary> /// Draws a representation of the horizontal line in the legend. /// </summary> /// <param name="ctx">The Drawing Context with which to draw</param> /// <param name="startEnd">A rectangle specifying the bounds of the area in the legend set aside for drawing</param> public void DrawInLegend(Context ctx, Rectangle startEnd) { ctx.Save (); ctx.MoveTo (startEnd.Left, (startEnd.Top + startEnd.Bottom)/2); ctx.LineTo (startEnd.Right, (startEnd.Top + startEnd.Bottom)/2); ctx.SetColor (color_); ctx.SetLineWidth (1); ctx.Stroke (); ctx.Restore (); }
/// <summary> /// Draws the vertical line using the Context and the x and y axes specified /// </summary> /// <param name="ctx">The Context with which to draw.</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> public void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis) { double yMin = yAxis.PhysicalMin.Y; double yMax = yAxis.PhysicalMax.Y; yMin -= PixelIndent; yMax += PixelIndent; double length = Math.Abs (yMax - yMin); double lengthDiff = length - length*LengthScale; double indentAmount = lengthDiff/2; yMin -= indentAmount; yMax += indentAmount; double xPos = xAxis.WorldToPhysical (AbscissaValue, false).X; ctx.Save (); ctx.SetLineWidth (1); ctx.SetColor (Color); ctx.MoveTo (xPos, yMin); ctx.LineTo (xPos, yMax); ctx.Stroke (); ctx.Restore (); // todo: clip and proper logic for flipped axis min max. }