/// <summary> /// Transforms the y-coordinate to screen coordinates. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="offsetX">offset by x</param> /// <param name="offsetY">offset by y</param> /// <returns></returns> private Point Tranform(double x, double y, double offsetX = 0, double offsetY = 0) { double newX, newY; _toView.Apply(x, y, out newX, out newY); return(new Point(newX + offsetX, newY + offsetY)); }
/// <summary> /// Transforms the y-coordinate to screen coordinates. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> private double[] Tranform(double x, double y) { double newX, newY; _toView.Apply(x, y, out newX, out newY); return(new double[] { newX, newY }); }
/// <summary> /// Draws the line text segment. /// </summary> /// <param name="target">Target.</param> /// <param name="xTransformed">X transformed.</param> /// <param name="yTransformed">Y transformed.</param> /// <param name="text">Text.</param> /// <param name="color">Color.</param> /// <param name="size">Size.</param> /// <param name="haloColor">Halo color.</param> /// <param name="haloRadius">Halo radius.</param> /// <param name="middlePosition">Middle position.</param> /// <param name="characterWidths">Character widths.</param> /// <param name="textLength">Text length.</param> /// <param name="characterHeight">Character height.</param> public void DrawLineTextSegment(Target2DWrapper <global::Android.Graphics.Canvas> target, double[] xTransformed, double[] yTransformed, string text, int color, double size, int?haloColor, int?haloRadius, double middlePosition, float[] characterWidths, double textLength, float characterHeight) { _paint.Color = new global::Android.Graphics.Color(color); _paint.SetStyle(global::Android.Graphics.Paint.Style.Fill); // see if the text is 'upside down'. double averageAngle = 0; double first = middlePosition - (textLength / 2.0); PointF2D current = Polyline2D.PositionAtPosition(xTransformed, yTransformed, first); bool isVisible = false; for (int idx = 0; idx < text.Length; idx++) { double nextPosition = middlePosition - (textLength / 2.0) + ((textLength / (text.Length)) * (idx + 1)); PointF2D next = Polyline2D.PositionAtPosition(xTransformed, yTransformed, nextPosition); // calculate the angle. VectorF2D vector = next - current; VectorF2D horizontal = new VectorF2D(1, 0); double angleDegrees = ((Degree)horizontal.Angle(vector)).Value; averageAngle = averageAngle + angleDegrees; current = next; double untransformed_0, untransformed_1; _fromViewPort.Apply(next[0], next[1], out untransformed_0, out untransformed_1); // double[] untransformed = this.TransformReverse (next [0], next [1]); if (_view.Contains(untransformed_0, untransformed_1)) { isVisible = true; } } averageAngle = averageAngle / text.Length; if (!isVisible) { return; } // reverse if 'upside down'. double[] xText = xTransformed; double[] yText = yTransformed; // calculate a central position along the line. first = middlePosition - (textLength / 2.0); current = Polyline2D.PositionAtPosition(xText, yText, first); double nextPosition2 = first; for (int idx = 0; idx < text.Length; idx++) { nextPosition2 = nextPosition2 + characterWidths[idx]; //double nextPosition = middle - (textLength / 2.0) + ((textLength / (text.Length)) * (idx + 1)); PointF2D next = Polyline2D.PositionAtPosition(xText, yText, nextPosition2); char currentChar = text[idx]; global::Android.Graphics.Path characterPath = new global::Android.Graphics.Path();; _paint.GetTextPath(text, idx, idx + 1, 0, 0, characterPath); using (characterPath) { // Transformation matrix to move the character to the correct location. // Note that all actions on the Matrix class are prepended, so we apply them in reverse. using (var transform = new Matrix()) { // Translate to the final position, the center of line-segment between 'current' and 'next' PointF2D position = current; //PointF2D position = current + ((next - current) / 2.0); //double[] transformed = this.Tranform(position[0], position[1]); transform.SetTranslate((float)position [0], (float)position [1]); // calculate the angle. VectorF2D vector = next - current; VectorF2D horizontal = new VectorF2D(1, 0); double angleDegrees = ((Degree)horizontal.Angle(vector)).Value; // Rotate the character transform.PreRotate((float)angleDegrees); // Translate the character so the centre of its base is over the origin transform.PreTranslate(0, characterHeight / 2.5f); //transform.Scale((float)this.FromPixels(_target, _view, 1), // (float)this.FromPixels(_target, _view, 1)); characterPath.Transform(transform); if (haloColor.HasValue && haloRadius.HasValue && haloRadius.Value > 0) { _paint.SetStyle(global::Android.Graphics.Paint.Style.FillAndStroke); _paint.StrokeWidth = haloRadius.Value; _paint.Color = new global::Android.Graphics.Color(haloColor.Value); using (global::Android.Graphics.Path haloPath = new global::Android.Graphics.Path()) { _paint.GetFillPath(characterPath, haloPath); // Draw the character target.Target.DrawPath(haloPath, _paint); } } // Draw the character _paint.SetStyle(global::Android.Graphics.Paint.Style.Fill); _paint.StrokeWidth = 0; _paint.Color = new global::Android.Graphics.Color(color); target.Target.DrawPath(characterPath, _paint); } } current = next; } }
/// <summary> /// Draws a point on the target. The coordinates given are scene coordinates. /// </summary> /// <param name="x">The x coordinate.</param> /// <param name="y">The y coordinate.</param> /// <param name="color">Color.</param> /// <param name="size">Size.</param> protected override void DrawPoint(Target2DWrapper <global::Android.Graphics.Canvas> target, double x, double y, int color, double size) { float sizeInPixels = this.ToPixels(size) * this.Density; _paint.Color = new global::Android.Graphics.Color(color); _paint.StrokeWidth = 1; _paint.SetStyle(global::Android.Graphics.Paint.Style.Fill); double transformedX, transformedY; _toViewPort.Apply(x, y, out transformedX, out transformedY); target.Target.DrawCircle((float)transformedX, (float)transformedY, sizeInPixels, _paint); }