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; for (double n = 0; n <= end; n += 5) { ctx.Save(); ctx.Rotate(n); ctx.MoveTo(0, 0); ctx.RelLineTo(30, 0); double c = n / end; ctx.SetColor(new Color(c, c, c)); ctx.Stroke(); ctx.Restore(); } //ctx.ResetTransform(); ctx.Restore(); }
public void PatternsAndImages (Context ctx, double x, double y) { ctx.Save (); ctx.Translate (x, y); ctx.SetColor (Colors.Black); // Dashed lines ctx.SetLineWidth (2); ctx.SetLineDash (15, 10, 10, 5, 5); ctx.Rectangle (10, 10, 100, 100); ctx.Stroke (); ctx.SetLineDash (0); // Image var arcColor = new Color (1, 0, 1); ImageBuilder ib = new ImageBuilder (30, 30); ib.Context.Arc (15, 15, 15, 0, 360); ib.Context.SetColor (arcColor); ib.Context.Fill (); ib.Context.SetColor (Colors.DarkKhaki); ib.Context.Rectangle (0, 0, 5, 5); ib.Context.Fill (); var img = ib.ToVectorImage (); ctx.DrawImage (img, 0, 0); ctx.DrawImage (img, 0, 50, 50, 10); ctx.Arc (100, 100, 15, 0, 360); arcColor.Alpha = 0.4; ctx.SetColor (arcColor); ctx.Fill (); // ImagePattern ctx.Save (); ctx.Translate (x + 130, y); ctx.Pattern = new ImagePattern (img); ctx.Rectangle (0, 0, 100, 100); ctx.Fill (); ctx.Restore (); ctx.Restore (); // Setting pixels ctx.SetLineWidth (1); for (int i=0; i<50;i++) { for (var j=0; j<50;j++) { Color c = Color.FromHsl (0.5, (double)i / 50d, (double)j / 50d); ctx.Rectangle (i, j, 1, 1); ctx.SetColor (c); ctx.Fill (); } } }
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(); }
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 (); }
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 }
protected internal override void DrawBackground(Context cr, Xwt.Rectangle area, DocumentLine line, int lineNumber, double x, double y, double height) { cr.Save(); cr.SetColor(Colors.LightGray); cr.Rectangle(x, y, Width, height + 1); cr.Fill(); cr.Restore(); }
protected override void OnDraw (Context ctx, Rectangle bounds) { ctx.Save (); ctx.Translate (bounds.Location); ctx.Scale (bounds.Width / Size.Width, bounds.Height / Size.Height); ToolkitEngine.VectorImageRecorderContextHandler.Draw (ctx.Handler, Toolkit.GetBackend (ctx), data); ctx.Restore (); }
void Draw(object ctx, Rectangle bounds, ImageDescription idesc, Toolkit toolkit) { var c = new Context (ctx, toolkit); if (idesc.Styles != StyleSet.Empty) c.SetStyles (idesc.Styles); c.Reset (null); c.Save (); c.GlobalAlpha = idesc.Alpha; OnDraw (c, bounds); c.Restore (); }
protected override void OnDraw(Context ctx, Rectangle dirtyRect) { base.OnDraw(ctx, dirtyRect); ctx.Save(); ctx.SetColor(editor.Options.Background); ctx.Rectangle(dirtyRect); ctx.Fill(); ctx.Restore(); UpdateMarginXOffsets(); RenderMargins(ctx, dirtyRect); }
protected void TestDrawing(Xwt.Drawing.Context ctx, double x, double y) { ctx.Save(); ctx.Translate(x, y); var tl = new TextLayout(ctx); tl.Text = "\nX\n"; tl.Width = 200; new ReferencePainter().DrawText(ctx, tl, ref y); 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(); }
protected void TestDrawing2(Xwt.Drawing.Context ctx, double x, double y) { ctx.Save(); ctx.Translate(x, y); var arcColor = new Color(1, 0, 1); ctx.Arc(100, 100, 15, 0, 360); ctx.ClosePath(); arcColor.Alpha = 0.4; ctx.SetColor(arcColor); ctx.StrokePreserve(); ctx.Fill(); ctx.Restore(); }
protected override void OnDraw(Xwt.Drawing.Context ctx) { base.OnDraw(ctx); ctx.Translate(30, 30); double end = 270; for (double n = 0; n <= end; n += 5) { ctx.Save(); ctx.Rotate(n); ctx.MoveTo(0, 0); ctx.RelLineTo(30, 0); double c = n / end; ctx.SetColor(new Color(c, c, c)); ctx.Stroke(); ctx.Restore(); } }
protected void TestDrawing1(Xwt.Drawing.Context ctx, double x, double y) { ctx.Save(); ctx.Translate(x, y); var r = 5; var l = 10; var t = 10; var w = 50; var h = 30; // top left //ctx.Arc(l + r, t + r, r, 180, 270); ctx.Rectangle(l, t, w, h); ctx.SetColor(Colors.Black); ctx.Stroke(); ctx.Restore(); }
internal protected override void Draw(Xwt.Drawing.Context cr, Rectangle area, DocumentLine lineSegment, int line, double x, double y, double lineHeight) { var gutterMarker = lineSegment != null ? (MarginMarker)lineSegment.Markers.FirstOrDefault(marker => marker is MarginMarker && ((MarginMarker)marker).CanDraw(this)) : null; if (gutterMarker != null && gutterMarker.CanDrawBackground(this)) { bool hasDrawn = gutterMarker.DrawBackground(editor, cr, new MarginDrawMetrics(this, area, lineSegment, line, x, y, lineHeight)); if (!hasDrawn) { DrawGutterBackground(cr, line, x, y, lineHeight); } } else { DrawGutterBackground(cr, line, x, y, lineHeight); } if (gutterMarker != null && gutterMarker.CanDrawForeground(this)) { gutterMarker.DrawForeground(editor, cr, new MarginDrawMetrics(this, area, lineSegment, line, x, y, lineHeight)); return; } if (line <= editor.Document.LineCount) { // Due to a mac? gtk bug I need to re-create the layout here // otherwise I get pango exceptions. using (var layout = editor.LayoutCache.RequestLayout()) { layout.Font = gutterFont; layout.Width = (int)Width; layout.Alignment = Alignment.End; layout.SetText(line.ToString()); cr.Save(); cr.Translate(x + (int)Width + (editor.Options.ShowFoldMargin ? 0 : -2), y); cr.SetSourceColor(lineNumberGC); cr.ShowLayout(layout); cr.Restore(); } } }
/// <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 (); }
protected override void OnDraw(Context ctx, Rectangle bounds) { var size = !Size.IsZero ? Size : images [0].Size; ctx.Save(); ctx.Translate(bounds.Location); if (!size.IsZero) { ctx.Scale(bounds.Width / size.Width, bounds.Height / size.Height); } for (int n = 0; n < images.Length; n++) { var image = images [n]; if (image.Size != size) { image = image.WithSize(size); } ctx.DrawImage(image, 0, 0); } ctx.Restore(); }
public override void DrawForeground(TextEditor editor, Xwt.Drawing.Context cr, MarginDrawMetrics metrics) { var width = metrics.Width; var lineNumberBgGC = editor.ColorStyle.LineNumbers.Background; if (metrics.LineNumber <= editor.Document.LineCount) { // Due to a mac? gtk bug I need to re-create the layout here // otherwise I get pango exceptions. using (var layout = PangoUtil.CreateLayout(editor)) { layout.Font = editor.Options.Font; layout.Width = (int)width; layout.TextAlignment = Alignment.End; layout.Text = metrics.LineNumber.ToString(); cr.Save(); cr.Translate(metrics.X + (int)width + (editor.Options.ShowFoldMargin ? 0 : -2), metrics.Y); cr.SetSourceColor(lineNumberBgGC); cr.ShowLayout(layout); cr.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> /// Draw the ticks. /// </summary> /// <param name="ctx">The Drawing Context with which to draw.</param> /// <param name="physicalMin">The minimum physical extent of the axis.</param> /// <param name="physicalMax">The maximum physical extent of the axis.</param> /// <param name="boundingBox">out: smallest box that completely encompasses all of the ticks and tick labels.</param> /// <param name="labelOffset">out: a suitable offset from the axis to draw the axis label.</param> /// <returns> An ArrayList containing the offset from the axis required for an axis label /// to miss this tick, followed by a bounding rectangle for the tick and tickLabel drawn.</returns> protected override void DrawTicks( Context ctx, Point physicalMin, Point physicalMax, out object labelOffset, out object boundingBox ) { Point tLabelOffset; Rectangle tBoundingBox; labelOffset = getDefaultLabelOffset( physicalMin, physicalMax ); boundingBox = null; ArrayList largeTickPositions; ArrayList smallTickPositions; WorldTickPositions (physicalMin, physicalMax, out largeTickPositions, out smallTickPositions); ctx.Save (); //Point offset = new Point( 0, 0 ); object bb = null; // Missed this protection if (largeTickPositions.Count > 0) { for (int i=0; i<largeTickPositions.Count; ++i) { StringBuilder label = new StringBuilder(); // do google search for "format specifier writeline" for help on this. label.AppendFormat (NumberFormat, (double)largeTickPositions[i]); DrawTick (ctx, (double)largeTickPositions[i], LargeTickSize, label.ToString(), new Point(0,0), physicalMin, physicalMax, out tLabelOffset, out tBoundingBox ); Axis.UpdateOffsetAndBounds (ref labelOffset, ref boundingBox, tLabelOffset, tBoundingBox); } } else { // just get the axis bounding box) Point dir = Utils.UnitVector(physicalMin,physicalMax); Rectangle rr = new Rectangle (physicalMin.X, ((physicalMax.X-physicalMin.X)*dir.X), physicalMin.Y, ((physicalMax.Y-physicalMin.Y)*dir.Y) ); bb = rr; } // missed protection for zero ticks if (smallTickPositions.Count > 0) { for (int i=0; i<smallTickPositions.Count; ++i) { DrawTick (ctx, (double)smallTickPositions[i], SmallTickSize, "", new Point(0,0), physicalMin, physicalMax, out tLabelOffset, out tBoundingBox ); // ignore r for now - assume bb unchanged by small tick bounds. } } ctx.Restore (); }
/// <summary> /// Draw the the PlotSurface2D and contents (axes, drawables, and legend) using the /// Drawing Context supplied and the bounding rectangle for the PlotSurface to cover /// </summary> /// <param name="ctx">The Drawing Context with which to draw.</param> /// <param name="bounds">The rectangle within which to draw</param> public void Draw(Context ctx, Rectangle bounds) { Point titleOrigin = Point.Zero; ctx.Save (); // determine font sizes and tick scale factor. double scale = DetermineScaleFactor (bounds.Width, bounds.Height); // if there is nothing to plot, draw title and return. if (drawables.Count == 0) { // draw title //TODO: Title should be centred here - not its origin Point origin = Point.Zero; titleOrigin.X = bounds.Width/2; titleOrigin.Y = bounds.Height/2; DrawTitle (ctx, titleOrigin, scale); ctx.Restore (); return; } // determine the [non physical] axes to draw based on the axis properties set. Axis xAxis1 = null; Axis xAxis2 = null; Axis yAxis1 = null; Axis yAxis2 = null; DetermineAxesToDraw (out xAxis1, out xAxis2, out yAxis1, out yAxis2); // apply scale factor to axes as desired. if (xAxis1.AutoScaleTicks) { xAxis1.TickScale = scale; } if (xAxis1.AutoScaleText) { xAxis1.FontScale = scale; } if (yAxis1.AutoScaleTicks) { yAxis1.TickScale = scale; } if (yAxis1.AutoScaleText) { yAxis1.FontScale = scale; } if (xAxis2.AutoScaleTicks) { xAxis2.TickScale = scale; } if (xAxis2.AutoScaleText) { xAxis2.FontScale = scale; } if (yAxis2.AutoScaleTicks) { yAxis2.TickScale = scale; } if (yAxis2.AutoScaleText) { yAxis2.FontScale = scale; } // determine the default physical positioning of those axes. PhysicalAxis pXAxis1 = null; PhysicalAxis pYAxis1 = null; PhysicalAxis pXAxis2 = null; PhysicalAxis pYAxis2 = null; DeterminePhysicalAxesToDraw ( bounds, xAxis1, xAxis2, yAxis1, yAxis2, out pXAxis1, out pXAxis2, out pYAxis1, out pYAxis2 ); double oldXAxis2Height = pXAxis2.PhysicalMin.Y; // Apply axes constraints for (int i=0; i<axesConstraints.Count; ++i) { ((AxesConstraint)axesConstraints[i]).ApplyConstraint( pXAxis1, pYAxis1, pXAxis2, pYAxis2 ); } // draw legend if have one. // Note: this will update axes if necessary. Point legendPosition = new Point(0,0); if (legend != null) { legend.UpdateAxesPositions ( pXAxis1, pYAxis1, pXAxis2, pYAxis2, drawables, scale, padding, bounds, out legendPosition ); } double newXAxis2Height = pXAxis2.PhysicalMin.Y; double titleExtraOffset = oldXAxis2Height - newXAxis2Height; // now we are ready to define the bounding box for the plot area (to use in clipping // operations. plotAreaBoundingBoxCache = new Rectangle ( Math.Min (pXAxis1.PhysicalMin.X, pXAxis1.PhysicalMax.X), Math.Min (pYAxis1.PhysicalMax.Y, pYAxis1.PhysicalMin.Y), Math.Abs (pXAxis1.PhysicalMax.X - pXAxis1.PhysicalMin.X + 1), Math.Abs (pYAxis1.PhysicalMin.Y - pYAxis1.PhysicalMax.Y + 1) ); bbXAxis1Cache = pXAxis1.GetBoundingBox (); bbXAxis2Cache = pXAxis2.GetBoundingBox (); bbYAxis1Cache = pYAxis1.GetBoundingBox (); bbYAxis2Cache = pYAxis2.GetBoundingBox (); // Fill in the background. if (plotBackImage != null) { Rectangle imageRect = (Rectangle)plotAreaBoundingBoxCache; ctx.DrawImage (Utils.TiledImage (plotBackImage , imageRect.Size), imageRect); } //else if (plotBackBrush_ != null) { // g.FillRectangle( // plotBackBrush_.Get( (Rectangle)plotAreaBoundingBoxCache ), // (Rectangle)plotAreaBoundingBoxCache ); //} else { ctx.SetColor (plotBackColor); ctx.Rectangle ((Rectangle)plotAreaBoundingBoxCache); ctx.Fill (); } // draw title at centre of Physical X-axis and at top of plot titleOrigin.X = (pXAxis2.PhysicalMax.X + pXAxis2.PhysicalMin.X)/2.0; titleOrigin.Y = bounds.Top + padding - titleExtraOffset; Size s = DrawTitle (ctx, titleOrigin, scale); bbTitleCache = new Rectangle (titleOrigin.X-s.Width/2, titleOrigin.Y, s.Width, s.Height); // draw drawables.. bool legendDrawn = false; for (int i_o = 0; i_o < ordering.Count; ++i_o) { int i = (int)ordering.GetByIndex (i_o); double zOrder = (double)ordering.GetKey (i_o); if (zOrder > legendZOrder) { // draw legend. if (!legendDrawn && legend != null) { legend.Draw (ctx, legendPosition, drawables, scale); legendDrawn = true; } } IDrawable drawable = (IDrawable)drawables[i]; XAxisPosition xap = (XAxisPosition)xAxisPositions[i]; YAxisPosition yap = (YAxisPosition)yAxisPositions[i]; PhysicalAxis drawXAxis; PhysicalAxis drawYAxis; if (xap == XAxisPosition.Bottom) { drawXAxis = pXAxis1; } else { drawXAxis = pXAxis2; } if (yap == YAxisPosition.Left) { drawYAxis = pYAxis1; } else { drawYAxis = pYAxis2; } // set the clipping region.. (necessary for zoom) ///TODO: g.Clip = new Region((Rectangle)plotAreaBoundingBoxCache); // plot. drawable.Draw (ctx, drawXAxis, drawYAxis); // reset it.. //g.ResetClip(); } if (!legendDrawn && legend != null) { legend.Draw (ctx, legendPosition, drawables, scale); } // cache the physical axes we used on this draw; pXAxis1Cache = pXAxis1; pYAxis1Cache = pYAxis1; pXAxis2Cache = pXAxis2; pYAxis2Cache = pYAxis2; // now draw axes. Rectangle axisBounds; pXAxis1.Draw (ctx, out axisBounds); pXAxis2.Draw (ctx, out axisBounds); pYAxis1.Draw (ctx, out axisBounds); pYAxis2.Draw (ctx, out axisBounds); #if DEBUG_BOUNDING_BOXES ctx.SetColor (Colors.Orange); ctx.Rectangle ((Rectangle)bbXAxis1Cache); ctx.Rectangle ((Rectangle)bbXAxis2Cache); ctx.Rectangle ((Rectangle)bbYAxis1Cache); ctx.Rectangle ((Rectangle)bbYAxis2Cache); ctx.Stroke (); ctx.SetColor (Colors.Red); ctx.Rectangle ((Rectangle)plotAreaBoundingBoxCache); ctx.Rectangle ((Rectangle)bbTitleCache); ctx.Stroke (); #endif ctx.Restore (); }
/// <summary> /// Draw The legend /// </summary> /// <param name="ctx">The Drawing Context with on which to draw</param> /// <param name="position">The position of the top left of the axis.</param> /// <param name="plots">Array of plot objects to appear in the legend.</param> /// <param name="scale">if the legend is set to scale, the amount to scale by.</param> /// <returns>bounding box</returns> public Rectangle Draw(Context ctx, Point position, ArrayList plots, double scale ) { // first of all determine the Font to use in the legend. Font textFont; if (AutoScaleText) { textFont = font_.WithScaledSize (scale); } else { textFont = font_; } ctx.Save (); // determine max width and max height of label strings and // count the labels. int labelCount = 0; int unnamedCount = 0; double maxHt = 0; double maxWd = 0; TextLayout layout = new TextLayout (); layout.Font = textFont; for (int i=0; i<plots.Count; ++i) { if (!(plots[i] is IPlot)) { continue; } IPlot p = (IPlot)plots[i]; if (!p.ShowInLegend) { continue; } string label = p.Label; if (label == "") { unnamedCount += 1; label = "Series " + unnamedCount.ToString(); } layout.Text = label; Size labelSize = layout.GetSize (); if (labelSize.Height > maxHt) { maxHt = labelSize.Height; } if (labelSize.Width > maxWd) { maxWd = labelSize.Width; } ++labelCount; } bool extendingHorizontally = numberItemsHorizontally_ == -1; bool extendingVertically = numberItemsVertically_ == -1; // determine width in legend items count units. int widthInItemCount = 0; if (extendingVertically) { if (labelCount >= numberItemsHorizontally_) { widthInItemCount = numberItemsHorizontally_; } else { widthInItemCount = labelCount; } } else if (extendingHorizontally) { widthInItemCount = labelCount / numberItemsVertically_; if (labelCount % numberItemsVertically_ != 0) widthInItemCount += 1; } else { throw new NPlotException( "logic error in legend base" ); } // determine height of legend in items count units. int heightInItemCount = 0; if (extendingHorizontally) { if (labelCount >= numberItemsVertically_) { heightInItemCount = numberItemsVertically_; } else { heightInItemCount = labelCount; } } else { // extendingVertically heightInItemCount = labelCount / numberItemsHorizontally_; if (labelCount % numberItemsHorizontally_ != 0) heightInItemCount += 1; } double lineLength = 20; double hSpacing = (int)(5.0f * scale); double vSpacing = (int)(3.0f * scale); double boxWidth = (int) ((float)widthInItemCount * (lineLength + maxWd + hSpacing * 2.0f ) + hSpacing); double boxHeight = (int)((float)heightInItemCount * (maxHt + vSpacing) + vSpacing); double totalWidth = boxWidth; double totalHeight = boxHeight; // draw box around the legend. if (BorderStyle == BorderType.Line) { ctx.SetColor (bgColor_); ctx.Rectangle (position.X, position.Y, boxWidth, boxHeight); ctx.FillPreserve (); ctx.SetColor (borderColor_); ctx.Stroke (); } else if (BorderStyle == BorderType.Shadow) { double offset = (4.0 * scale); Color shade = Colors.Gray; shade.Alpha = 0.5; ctx.SetColor (Colors.Gray); ctx.Rectangle (position.X+offset, position.Y+offset, boxWidth, boxHeight); ctx.Fill (); ctx.SetColor (bgColor_); ctx.Rectangle (position.X, position.Y, boxWidth, boxHeight); ctx.FillPreserve (); ctx.SetColor (borderColor_); ctx.Stroke (); totalWidth += offset; totalHeight += offset; } /* else if ( this.BorderStyle == BorderType.Curved ) { // TODO. make this nice. } */ else { // do nothing. } // now draw entries in box.. labelCount = 0; unnamedCount = 0; int plotCount = -1; for (int i=0; i<plots.Count; ++i) { if (!(plots[i] is IPlot)) { continue; } IPlot p = (IPlot)plots[i]; if (!p.ShowInLegend) { continue; } plotCount += 1; double xpos, ypos; if (extendingVertically) { xpos = plotCount % numberItemsHorizontally_; ypos = plotCount / numberItemsHorizontally_; } else { xpos = plotCount / numberItemsVertically_; ypos = plotCount % numberItemsVertically_; } double lineXPos = (position.X + hSpacing + xpos * (lineLength + maxWd + hSpacing * 2.0)); double lineYPos = (position.Y + vSpacing + ypos * (vSpacing + maxHt)); p.DrawInLegend (ctx, new Rectangle (lineXPos, lineYPos, lineLength, maxHt)); double textXPos = lineXPos + hSpacing + lineLength; double textYPos = lineYPos; string label = p.Label; if (label == "") { unnamedCount += 1; label = "Series " + unnamedCount.ToString(); } layout.Text = label; ctx.DrawTextLayout (layout, textXPos, textYPos); ++labelCount; } ctx.Restore (); return new Rectangle (position.X, position.Y, totalWidth, totalHeight); }
/// <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> /// Draw the Axis Label /// </summary> /// <param name="ctx>The Drawing Context with which to draw.</param> /// <param name="offset">offset from axis. Should be calculated so as to make sure axis label misses tick labels.</param> /// <param name="axisPhysicalMin">The physical position corresponding to the world minimum of the axis.</param> /// <param name="axisPhysicalMax">The physical position corresponding to the world maximum of the axis.</param> /// <returns>boxed Rectangle indicating bounding box of label. null if no label printed.</returns> public object DrawLabel(Context ctx, Point offset, Point axisPhysicalMin, Point axisPhysicalMax) { if (Label != "") { // first calculate any extra offset for axis label spacing. double extraOffsetAmount = LabelOffset; extraOffsetAmount += 2; // empirically determed - text was too close to axis before this. if (AutoScaleText && LabelOffsetScaled) { extraOffsetAmount *= FontScale; } // now extend offset. double offsetLength = Math.Sqrt (offset.X*offset.X + offset.Y*offset.Y); if (offsetLength > 0.01) { double x_component = offset.X / offsetLength; double y_component = offset.Y / offsetLength; x_component *= extraOffsetAmount; y_component *= extraOffsetAmount; if (LabelOffsetAbsolute) { offset.X = x_component; offset.Y = y_component; } else { offset.X += x_component; offset.Y += y_component; } } // determine angle of axis in degrees double theta = Math.Atan2 ( axisPhysicalMax.Y - axisPhysicalMin.Y, axisPhysicalMax.X - axisPhysicalMin.X); theta = theta * 180.0 / Math.PI; Point average = new Point ( (axisPhysicalMax.X + axisPhysicalMin.X)/2, (axisPhysicalMax.Y + axisPhysicalMin.Y)/2); ctx.Save (); ctx.Translate (average.X + offset.X , average.Y + offset.Y); // this is done last. ctx.Rotate (theta); // this is done first. TextLayout layout = new TextLayout (); layout.Font = labelFontScaled; layout.Text = Label; Size labelSize = layout.GetSize (); //Draw label centered around zero. ctx.DrawTextLayout (layout, -labelSize.Width/2, -labelSize.Height/2); // now work out physical bounds of Rotated and Translated label. Point [] recPoints = new Point [2]; recPoints[0] = new Point (-labelSize.Width/2, -labelSize.Height/2); recPoints[1] = new Point ( labelSize.Width/2, labelSize.Height/2); ctx.TransformPoints (recPoints); double x1 = Math.Min (recPoints[0].X, recPoints[1].X); double x2 = Math.Max (recPoints[0].X, recPoints[1].X); double y1 = Math.Min (recPoints[0].Y, recPoints[1].Y); double y2 = Math.Max (recPoints[0].Y, recPoints[1].Y); ctx.Restore (); // and return label bounding box. return new Rectangle (x1, y1, (x2-x1), (y2-y1)); } return null; }
protected override void OnDraw(Context ctx, Rectangle dirtyRect) { ctx.Save (); ctx.Translate (-hscroll.Value, -vscroll.Value); ctx.Rectangle (new Rectangle (0, 0, imageSize, imageSize)); ctx.SetColor (Xwt.Drawing.Colors.White); ctx.Fill (); ctx.Arc (imageSize / 2, imageSize / 2, imageSize / 2 - 20, 0, 360); ctx.SetColor (new Color (0,0,1)); ctx.Fill (); ctx.Restore (); ctx.Rectangle (0, 0, Bounds.Width, 30); ctx.SetColor (new Color (1, 0, 0, 0.5)); ctx.Fill (); }
/// <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 (); } }
/// <summary> /// Draws the title using the Drawing Context, Origin (x,y) and scale /// </summary> /// <returns> /// The Size required for the title /// </returns> /// TODO: Add a MeasureTitle routine, since can measure TextLayout now /// private Size DrawTitle(Context ctx, Point origin, double scale) { ctx.Save (); ctx.SetColor (TitleColor); Font scaled_font; if (AutoScaleTitle) { scaled_font = titleFont.WithScaledSize (scale); } else { scaled_font = titleFont; } TextLayout layout = new TextLayout (); layout.Font = scaled_font; layout.Text = Title; Size titleSize = layout.GetSize (); origin.X -= titleSize.Width/2; ctx.DrawTextLayout (layout, origin); ctx.Restore (); return titleSize; }
/// <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 (); }
/// <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> /// 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. }
protected override sealed void OnDraw(Context ctx, Rectangle bounds) { var frame = GetFrame (ctx.ScaleFactor); var fixedWidth = frame.Bitmap.Width - 2 - frame.StretchableWidth; var fixedHeight = frame.Bitmap.Height - 2 - frame.StretchableHeight; double totalVariableWidth = bounds.Width - fixedWidth / frame.ScaleFactor; double totalVariableHeight = bounds.Height - fixedHeight / frame.ScaleFactor; double remainingVariableHeight = totalVariableHeight; double y = bounds.Y, yb = 1; int tileIndex = 0; ctx.Save (); if (totalVariableWidth < 0) { if (fixedWidth > 0) ctx.Scale (bounds.Width / fixedWidth, 1); totalVariableWidth = 0; } if (totalVariableHeight < 0) { if (fixedHeight > 0) ctx.Scale (1, bounds.Height / fixedHeight); totalVariableHeight = 0; } foreach (var vs in frame.VerticalSections) { double sh = CalcSectionSize (frame, vs, totalVariableHeight, frame.StretchableHeight, ref remainingVariableHeight); double x = bounds.X, xb = 1; double remainingVariableWidth = totalVariableWidth; foreach (var hs in frame.HorizontalSections) { var sourceRegion = new Rectangle (xb, yb, hs.Size, vs.Size); double sw = CalcSectionSize (frame, hs, totalVariableWidth, frame.StretchableWidth, ref remainingVariableWidth); var targetRegion = new Rectangle (x, y, sw, sh); if (vs.Mode != RenderMode.Tile && hs.Mode != RenderMode.Tile) { var t = GetTile (frame, tileIndex, sourceRegion); ctx.DrawImage (t, targetRegion); } else { double pw = hs.Size / frame.ScaleFactor; double ph = vs.Size / frame.ScaleFactor; if (hs.Mode == RenderMode.Stretch) { pw = targetRegion.Width; } if (vs.Mode == RenderMode.Stretch) { ph = targetRegion.Height; } ctx.Save (); ctx.Translate (targetRegion.Location); targetRegion.Location = Point.Zero; ctx.Pattern = new ImagePattern (GetTile (frame, tileIndex, sourceRegion).WithSize (pw, ph)); ctx.NewPath (); ctx.Rectangle (targetRegion); ctx.Fill (); ctx.Restore (); } x += sw; xb += hs.Size; tileIndex++; } yb += vs.Size; y += sh; } 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="r"> /// A rectangle specifying the bounds of the area in the legend set aside for drawing /// </param> public void DrawInLegend(Context ctx, Rectangle r) { ctx.Save (); ctx.SetLineWidth (1); ctx.Rectangle (r); if (Filled) { if (FillGradient != null) { // Scale FillGradient to bar rectangle double sX = r.X + fillGradient.StartPoint.X * r.Width; double sY = r.Y + fillGradient.StartPoint.Y * r.Height; double eX = r.X + fillGradient.EndPoint.X * r.Width; double eY = r.Y + fillGradient.EndPoint.Y * r.Height; LinearGradient g = new LinearGradient (sX, sY, eX, eY); g.AddColorStop (0, FillGradient.StartColor); g.AddColorStop (1, FillGradient.EndColor); ctx.Pattern = g; } else { ctx.SetColor (FillColor); } ctx.FillPreserve (); } ctx.SetColor (BorderColor); ctx.Stroke (); ctx.Restore (); }
public void Path (Context ctx, double px, double py) { ctx.Save (); ctx.Translate (px, py); var path = new DrawingPath (); path.MoveTo (0.44, 18); path.LineTo (-1, 18); path.LineTo (-1, 26); path.LineTo (0.44, 26); path.LineTo (0, 42); path.LineTo (29, 21.98); path.LineTo (29, 21.98); path.LineTo (0, 2); path.LineTo (0.44, 18); ctx.AppendPath (path); ctx.SetColor (Colors.Black); ctx.SetLineWidth (2); ctx.Stroke (); var path2 = path.CopyPath (); path2.LineTo (15, 8); path2.ClosePath (); ctx.Rotate (180); ctx.AppendPath (path2); ctx.SetColor (Colors.Red); ctx.SetLineDash (0, 5); 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 (); }
public virtual void Rectangles (Context ctx, double x, double y) { ctx.Save (); ctx.Translate (x, y); // Simple rectangles ctx.SetLineWidth (1); ctx.Rectangle (0, 0, 10, 10); ctx.SetColor (Colors.Black); ctx.Fill (); ctx.Rectangle (15, 0, 10, 10); ctx.SetColor (Colors.Black); ctx.Stroke (); ctx.SetLineWidth (3); ctx.Rectangle (0, 15, 10, 10); ctx.SetColor (Colors.Black); ctx.Fill (); ctx.Rectangle (15, 15, 10, 10); ctx.SetColor (Colors.Black); ctx.Stroke (); ctx.Restore (); // Rectangle with hole ctx.Save (); ctx.Translate (x + 50, y); ctx.Rectangle (0, 0, 40, 40); ctx.MoveTo (35, 35); ctx.RelLineTo (0, -20); ctx.RelLineTo (-20, 0); ctx.RelLineTo (0, 20); ctx.ClosePath (); ctx.SetColor (Colors.Black); ctx.Fill (); ctx.Restore (); // Rounded Rectangle with Arcs ctx.Save (); ctx.Translate (x + 120, y); var r = 5; var l = 0; var t = 0; var w = 50; var h = 30; ctx.SetColor (Colors.Black); // top left ctx.Arc (l + r, t + r, r, 180, 270); // top right ctx.Arc (l + w - r, t + r, r, 270, 0); // bottom right ctx.Arc (l + w - r, t + h - r, r, 0, 90); // bottom left ctx.Arc (l + r, t + h - r, r, 90, 180); ctx.ClosePath (); ctx.StrokePreserve (); ctx.SetColor (Colors.AntiqueWhite); 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 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; }
protected sealed override void OnDraw(Context ctx, Rectangle bounds) { if (bounds.Width <= 0 || bounds.Height <= 0) { return; } var frame = GetFrame(ctx.ScaleFactor); var fixedWidth = frame.Bitmap.Width - 2 - frame.StretchableWidth; var fixedHeight = frame.Bitmap.Height - 2 - frame.StretchableHeight; double totalVariableWidth = bounds.Width - fixedWidth / frame.ScaleFactor; double totalVariableHeight = bounds.Height - fixedHeight / frame.ScaleFactor; double remainingVariableHeight = totalVariableHeight; double y = bounds.Y, yb = 1; int tileIndex = 0; ctx.Save(); if (totalVariableWidth < 0) { if (fixedWidth > 0) { ctx.Scale(bounds.Width / fixedWidth, 1); } totalVariableWidth = 0; } if (totalVariableHeight < 0) { if (fixedHeight > 0) { ctx.Scale(1, bounds.Height / fixedHeight); } totalVariableHeight = 0; } foreach (var vs in frame.VerticalSections) { double sh = CalcSectionSize(frame, vs, totalVariableHeight, frame.StretchableHeight, ref remainingVariableHeight); double x = bounds.X, xb = 1; double remainingVariableWidth = totalVariableWidth; foreach (var hs in frame.HorizontalSections) { var sourceRegion = new Rectangle(xb, yb, hs.Size, vs.Size); double sw = CalcSectionSize(frame, hs, totalVariableWidth, frame.StretchableWidth, ref remainingVariableWidth); var targetRegion = new Rectangle(x, y, sw, sh); if (vs.Mode != RenderMode.Tile && hs.Mode != RenderMode.Tile) { var t = GetTile(frame, tileIndex, sourceRegion); ctx.DrawImage(t, targetRegion); } else { double pw = hs.Size / frame.ScaleFactor; double ph = vs.Size / frame.ScaleFactor; if (hs.Mode == RenderMode.Stretch) { pw = targetRegion.Width; } if (vs.Mode == RenderMode.Stretch) { ph = targetRegion.Height; } if (pw <= 0 || ph <= 0) { continue; } ctx.Save(); ctx.Translate(targetRegion.Location); targetRegion.Location = Point.Zero; ctx.Pattern = new ImagePattern(GetTile(frame, tileIndex, sourceRegion).WithSize(pw, ph)); ctx.NewPath(); ctx.Rectangle(targetRegion); ctx.Fill(); ctx.Restore(); } x += sw; xb += hs.Size; tileIndex++; } yb += vs.Size; y += sh; } ctx.Restore(); }
/// <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); } } }
protected override void OnDraw(Xwt.Drawing.Context ctx) { base.OnDraw(ctx); // Simple rectangles ctx.SetLineWidth(1); ctx.Rectangle(100, 5, 10, 10); ctx.SetColor(Color.Black); ctx.Fill(); ctx.Rectangle(115, 5, 10, 10); ctx.SetColor(Color.Black); ctx.Stroke(); // ctx.SetLineWidth(3); ctx.Rectangle(100, 20, 10, 10); ctx.SetColor(Color.Black); ctx.Fill(); ctx.Rectangle(115, 20, 10, 10); ctx.SetColor(Color.Black); ctx.Stroke(); // Rectangle with hole ctx.Rectangle(10, 100, 40, 40); ctx.MoveTo(45, 135); ctx.RelLineTo(0, -20); ctx.RelLineTo(-20, 0); ctx.RelLineTo(0, 20); ctx.ClosePath(); ctx.SetColor(Color.Black); ctx.Fill(); // Dashed lines ctx.SetLineDash(15, 10, 10, 5, 5); ctx.Rectangle(100, 100, 100, 100); ctx.Stroke(); ctx.SetLineDash(0); ImageBuilder ib = new ImageBuilder(30, 30, ImageFormat.ARGB32); ib.Context.Arc(15, 15, 15, 0, 360); ib.Context.SetColor(new Color(1, 0, 1)); ib.Context.Rectangle(0, 0, 5, 5); ib.Context.Fill(); var img = ib.ToImage(); ctx.DrawImage(img, 90, 90); ctx.DrawImage(img, 90, 140, 50, 10); ctx.Arc(190, 190, 15, 0, 360); ctx.SetColor(new Color(1, 0, 1, 0.4)); ctx.Fill(); ctx.Save(); ctx.Translate(90, 220); ctx.Pattern = new ImagePattern(img); ctx.Rectangle(0, 0, 100, 70); ctx.Fill(); ctx.Restore(); ctx.Translate(30, 30); double end = 270; for (double n = 0; n <= end; n += 5) { ctx.Save(); ctx.Rotate(n); ctx.MoveTo(0, 0); ctx.RelLineTo(30, 0); double c = n / end; ctx.SetColor(new Color(c, c, c)); ctx.Stroke(); ctx.Restore(); } ctx.ResetTransform(); }
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 virtual void Scale(Context ctx, double ax, double ay) { ctx.Save (); ctx.Translate (ax, ay); ctx.SetColor (Colors.Black); ctx.SetLineWidth (1); var x = 0d; var y = 0d; var w = 10d; var inc = .1d; for (var i = inc; i < 3.5d; i +=inc) { ctx.Save (); ctx.Scale (i, i); ctx.Rectangle (x, y, w, w); ctx.SetColor (Colors.Yellow.WithAlpha (1 / i)); ctx.FillPreserve (); ctx.SetColor (Colors.Red.WithAlpha (1 / i)); ctx.Stroke (); ctx.MoveTo (x += w * inc, y += w * inc / 3); ctx.Restore (); } ctx.Restore (); }
/// <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 (); }
protected override void OnDraw (Context ctx, Rectangle dirtyRect) { base.OnDraw (ctx, dirtyRect); ctx.Save (); if (parent.CurrentRow < 0) return; var row_bounds = parent.ListView.GetRowBounds (parent.CurrentRow, false); var row_bg_bounds = parent.ListView.GetRowBounds (parent.CurrentRow, true); if (TrackerBg != null) { ctx.DrawImage (TrackerBg, row_bg_bounds, new Rectangle (0, 0, row_bg_bounds.Width, row_bg_bounds.Height)); } foreach (var col in parent.ListView.Columns) { foreach (var cell in col.Views) { var cell_bg_bounds = parent.ListView.GetCellBounds (parent.CurrentRow, cell, true); var cell_bounds = parent.ListView.GetCellBounds (parent.CurrentRow, cell, false); cell_bounds.Y -= row_bg_bounds.Y; cell_bounds.X += parent.ListView.HorizontalScrollControl.Value; cell_bg_bounds.Y -= row_bg_bounds.Y; cell_bg_bounds.X += parent.ListView.HorizontalScrollControl.Value; ctx.SetColor (Colors.Red); ctx.Rectangle (cell_bg_bounds); ctx.Stroke (); ctx.SetColor (Colors.Green); ctx.Rectangle (cell_bounds); ctx.Stroke (); } } row_bounds.Y -= row_bg_bounds.Y; row_bounds.X += parent.ListView.HorizontalScrollControl.Value; row_bg_bounds.Y = 0; row_bg_bounds.X += parent.ListView.HorizontalScrollControl.Value; ctx.SetColor (Colors.Red); ctx.Rectangle (row_bg_bounds); ctx.Stroke (); ctx.SetColor (Colors.Blue); ctx.Rectangle (row_bounds); ctx.Stroke (); ctx.Restore (); }