/// <summary> /// Draws text along a given line. /// </summary> /// <param name="target"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="color"></param> /// <param name="size"></param> /// <param name="text">Text.</param> protected override void DrawLineText(Target2DWrapper <global::Android.Graphics.Canvas> target, double[] xa, double[] ya, string text, int color, double size, int?haloColor, int?haloRadius, string fontName) { if (xa.Length > 1) { float sizeInPixels = this.ToPixels(size); _paint.SubpixelText = true; _paint.TextSize = (float)sizeInPixels; _paint.AntiAlias = true; // transform first. double[] xTransformed = new double[xa.Length]; double[] yTransformed = new double[ya.Length]; for (int idx = 0; idx < xa.Length; idx++) { double[] transformed = this.Tranform(xa[idx], ya[idx]); xTransformed [idx] = transformed [0]; yTransformed [idx] = transformed [1]; } // get some metrics on the texts. float[] characterWidths = new float[text.Length]; _paint.GetTextWidths(text, characterWidths); // for (int idx = 0; idx < characterWidths.Length; idx++) // { // characterWidths[idx] = _target, _view, characterWidths[idx]; // } var characterHeight = (float)sizeInPixels; var textLength = characterWidths.Sum(); // calculate line length. var lineLength = Polyline2D.Length(xTransformed, yTransformed); if (lineLength > textLength * 1.2f) { // calculate the number of labels. int labelCount = (int)System.Math.Floor(lineLength / (textLength * 10)) + 1; // calculate positions of label(s). double positionGap = lineLength / (labelCount + 1); // draw each label. for (double position = positionGap; position < lineLength; position = position + positionGap) { this.DrawLineTextSegment(target, xTransformed, yTransformed, text, color, size, haloColor, haloRadius, position, characterWidths, textLength, characterHeight); } } } }
/// <summary> /// Draws text along a line. /// </summary> /// <param name="target"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="text"></param> /// <param name="color"></param> /// <param name="size"></param> /// <param name="haloColor"></param> /// <param name="haloRadius"></param> /// <param name="fontName"></param> protected override void DrawLineText(Target2DWrapper <Graphics> target, double[] x, double[] y, string text, int color, double size, int?haloColor, int?haloRadius, string fontName) { if (x.Length > 1) { float sizeInPixels = this.ToPixels(size); Color textColor = Color.FromArgb(color); Brush brush = new SolidBrush(textColor); Brush haloBrush = null; if (haloColor.HasValue && haloRadius.HasValue && haloRadius.Value > 0) { haloBrush = new SolidBrush(Color.FromArgb(haloColor.Value)); } Font font = new Font(FontFamily.GenericSansSerif, sizeInPixels); // get some metrics on the texts. var characterWidths = GetCharacterWidths(target.Target, text, font); for (int idx = 0; idx < characterWidths.Length; idx++) { characterWidths[idx] = (float)this.FromPixels(_target, _view, characterWidths[idx]); } var characterHeight = target.Target.MeasureString(text, font).Height; var textLength = characterWidths.Sum(); // var avgCharacterWidth = textLength / characterWidths.Length; // calculate line length. var lineLength = Polyline2D.Length(x, y); if (lineLength > textLength * 1.1f) { // calculate the number of labels. int labelCount = (int)System.Math.Floor(lineLength / (textLength * 10)) + 1; // calculate positions of label(s). double positionGap = lineLength / (labelCount + 1); // draw each label. for (double position = positionGap; position < lineLength; position = position + positionGap) { this.DrawLineTextSegment(target, x, y, text, color, size, haloColor, haloRadius, position, characterWidths, textLength, font, characterHeight, haloBrush, brush); } } } }
/// <summary> /// Draws text along a given line. /// </summary> /// <param name="target"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="color"></param> /// <param name="size"></param> /// <param name="text">Text.</param> protected override void DrawLineText(Target2DWrapper <CGContextWrapper> target, double[] xa, double[] ya, string text, int color, double size, int?haloColor, int?haloRadius, string fontName) { float textSize = this.ToPixels(size) * _scaleFactor; // transform first. double[] xTransformed = new double[xa.Length]; double[] yTransformed = new double[ya.Length]; for (int idx = 0; idx < xa.Length; idx++) { double[] transformed = this.Transform(xa[idx], ya[idx]); xTransformed[idx] = transformed[0]; yTransformed[idx] = transformed[1]; } // set the fill color as the regular text-color. target.Target.CGContext.InterpolationQuality = CGInterpolationQuality.High; target.Target.CGContext.SetAllowsFontSubpixelQuantization(true); target.Target.CGContext.SetAllowsFontSmoothing(true); target.Target.CGContext.SetAllowsAntialiasing(true); target.Target.CGContext.SetAllowsSubpixelPositioning(true); target.Target.CGContext.SetShouldAntialias(true); // get the glyhps/paths from the font. CTFont font = this.GetFont(fontName, textSize); CTStringAttributes stringAttributes = new CTStringAttributes { ForegroundColorFromContext = true, Font = font }; NSAttributedString attributedString = new NSAttributedString(text, stringAttributes); CTLine line = new CTLine(attributedString); RectangleF textBounds = line.GetBounds(CTLineBoundsOptions.UseOpticalBounds); CTRun[] runs = line.GetGlyphRuns(); var lineLength = Polyline2D.Length(xTransformed, yTransformed); // set the correct tranformations to draw the resulting paths. target.Target.CGContext.SaveState(); //target.Target.CGContext.TranslateCTM (xPixels, yPixels); //target.Target.CGContext.ConcatCTM (new CGAffineTransform (1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f)); foreach (CTRun run in runs) { ushort[] glyphs = run.GetGlyphs(); PointF[] positions = run.GetPositions(); float[] characterWidths = new float[glyphs.Length]; float previous = 0; float textLength = (float)positions[positions.Length - 1].X; //float textLength = (float)this.FromPixels(_target, _view, positions [positions.Length - 1].X); if (lineLength > textLength * 1.2f) { for (int idx = 0; idx < characterWidths.Length - 1; idx++) { //characterWidths [idx] = (float)this.FromPixels(_target, _view, positions [idx + 1].X - previous); characterWidths[idx] = (float)(positions[idx + 1].X - previous); previous = positions[idx + 1].X; } characterWidths[characterWidths.Length - 1] = characterWidths[characterWidths.Length - 2]; float characterHeight = textBounds.Height; this.DrawLineTextSegment(target, xTransformed, yTransformed, glyphs, color, haloColor, haloRadius, lineLength / 2f, characterWidths, textLength, characterHeight, font); } } target.Target.CGContext.RestoreState(); }
/// <summary> /// Draws text along a given line. /// </summary> /// <param name="target"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="color"></param> /// <param name="size"></param> /// <param name="text">Text.</param> protected override void DrawLineText(Target2DWrapper <CGContextWrapper> target, double[] x, double[] y, string text, int color, double size, int?haloColor, int?haloRadius, string fontName) { double[] transformed = this.Tranform(x[0], y[0]); float xPixels = (float)transformed[0]; float yPixels = (float)transformed[1]; float textSize = this.ToPixels(size); // set the fill color as the regular text-color. SimpleColor simpleColor = SimpleColor.FromArgb(color); target.Target.CGContext.InterpolationQuality = CGInterpolationQuality.High; target.Target.CGContext.SetAllowsFontSubpixelQuantization(true); target.Target.CGContext.SetAllowsFontSmoothing(true); target.Target.CGContext.SetFillColor(simpleColor.R / 256.0f, simpleColor.G / 256.0f, simpleColor.B / 256.0f, simpleColor.A / 256.0f); if (haloColor.HasValue) // set the stroke color as the halo color. { SimpleColor haloSimpleColor = SimpleColor.FromArgb(haloColor.Value); target.Target.CGContext.SetStrokeColor(haloSimpleColor.R / 256.0f, haloSimpleColor.G / 256.0f, haloSimpleColor.B / 256.0f, haloSimpleColor.A / 256.0f); } if (haloRadius.HasValue) // set the halo radius as line width. { target.Target.CGContext.SetLineWidth(haloRadius.Value); } // get the glyhps/paths from the font. if (string.IsNullOrWhiteSpace(fontName)) { fontName = "Arial"; } CTFont font = new CTFont(fontName, textSize); CTStringAttributes stringAttributes = new CTStringAttributes { ForegroundColorFromContext = true, Font = font }; NSAttributedString attributedString = new NSAttributedString(text, stringAttributes); CTLine line = new CTLine(attributedString); RectangleF textBounds = line.GetBounds(CTLineBoundsOptions.UseOpticalBounds); CTRun[] runs = line.GetGlyphRuns(); var lineLength = Polyline2D.Length(x, y); // set the correct tranformations to draw the resulting paths. target.Target.CGContext.SaveState(); //target.Target.CGContext.TranslateCTM (xPixels, yPixels); //target.Target.CGContext.ConcatCTM (new CGAffineTransform (1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f)); foreach (CTRun run in runs) { ushort[] glyphs = run.GetGlyphs(); PointF[] positions = run.GetPositions(); float[] characterWidths = new float[glyphs.Length]; float previous = 0; float textLength = (float)this.FromPixels(_target, _view, positions [positions.Length - 1].X); if (lineLength > textLength * 1.2f) { for (int idx = 0; idx < characterWidths.Length - 1; idx++) { characterWidths [idx] = (float)this.FromPixels(_target, _view, positions [idx + 1].X - previous); previous = positions [idx + 1].X; } characterWidths [characterWidths.Length - 1] = characterWidths[characterWidths.Length - 2]; float characterHeight = textBounds.Height; this.DrawLineTextSegment(target, x, y, glyphs, color, haloColor, haloRadius, lineLength / 2f, characterWidths, textLength, characterHeight, font); } } target.Target.CGContext.RestoreState(); }