public override Size MeasureText(Font font, string text) { CTFont sysFont = font.RendererData as CTFont; if (sysFont == null || Math.Abs(font.RealSize - font.Size * Scale) > 2) { FreeFont(font); LoadFont(font); sysFont = font.RendererData as CTFont; } var key = new Tuple <String, Font>(text, font); if (m_StringCache.ContainsKey(key)) { var tex = m_StringCache[key].Texture; return(new Size(tex.Width, tex.Height)); } text = text.Replace("\t", " "); var attributedString = new NSAttributedString(text, new CTStringAttributes() { Font = sysFont, UnderlineStyle = font.Underline ? CTUnderlineStyle.Single : CTUnderlineStyle.None }); CTLine ctLine = new CTLine(attributedString); CGRect cgRect = ctLine.GetBounds(CTLineBoundsOptions.IncludeLanguageExtents | CTLineBoundsOptions.UseHangingPunctuation); ctLine.Dispose(); attributedString.Dispose(); return(new Size(Util.Ceil((float)cgRect.Width), Util.Ceil((float)cgRect.Height))); }
void ComputeCellDimensions () { var line = new CTLine (new NSAttributedString ("W", new NSStringAttributes () { Font = fontNormal })); var bounds = line.GetBounds (CTLineBoundsOptions.UseOpticalBounds); cellWidth = bounds.Width; cellHeight = bounds.Height; cellDelta = bounds.Y; }
/// <summary> /// Computes the cell dimensions for a given font /// </summary> static CGRect ComputeCellDimensions(NSFont font) { var line = new CTLine(new NSAttributedString("W", new NSStringAttributes() { Font = font })); return(line.GetBounds(CTLineBoundsOptions.UseOpticalBounds)); }
public override void RenderText(Font font, Point position, string text) { Flush(); CTFont sysFont = font.RendererData as CTFont; if (sysFont == null || Math.Abs(font.RealSize - font.Size * Scale) > 2) { FreeFont(font); LoadFont(font); sysFont = font.RendererData as CTFont; } var key = new Tuple <String, Font>(text, font); if (!m_StringCache.ContainsKey(key)) { // not cached - create text renderer text = text.Replace("\t", " "); var attributedString = new NSAttributedString(text, new CTStringAttributes() { ForegroundColorFromContext = true, Font = sysFont, UnderlineStyle = font.Underline ? CTUnderlineStyle.Single : CTUnderlineStyle.None }); CTLine ctLine = new CTLine(attributedString); CGRect cgRect = ctLine.GetBounds(CTLineBoundsOptions.IncludeLanguageExtents | CTLineBoundsOptions.UseHangingPunctuation); TextRenderer tr = new TextRenderer(Util.Ceil((float)cgRect.Width), Util.Ceil((float)cgRect.Height), this); tr.DrawString(ctLine, new Point(0, (int)sysFont.DescentMetric)); // renders string on the texture ctLine.Dispose(); attributedString.Dispose(); DrawTexturedRect(tr.Texture, new Rectangle(position.X, position.Y, tr.Texture.Width, tr.Texture.Height)); m_StringCache[key] = tr; } else { TextRenderer tr = m_StringCache[key]; DrawTexturedRect(tr.Texture, new Rectangle(position.X, position.Y, tr.Texture.Width, tr.Texture.Height)); } }
/// <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(); }
public static double WidthIncludingTrailingWhitespace(this CTLine line) => line.GetBounds(0).Width;
/// <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(); }