static void PrepareGlyphArcInfo (CTLine line, long glyphCount, GlyphArcInfo[] glyphArcInfo) { var runArray = line.GetGlyphRuns (); // Examine each run in the line, updating glyphOffset to track how far along the run is // in terms of glyphCount. long glyphOffset = 0; nfloat ascent = 0; nfloat descent = 0; nfloat leading = 0; foreach (var run in runArray) { var runGlyphCount = run.GlyphCount; // Ask for the width of each glyph in turn. var runGlyphIndex = 0; for (; runGlyphIndex < runGlyphCount; runGlyphIndex++) { glyphArcInfo [runGlyphIndex + glyphOffset].width = (float)run.GetTypographicBounds (new NSRange (runGlyphIndex, 1), out ascent, out descent, out leading); } glyphOffset += runGlyphCount; } var lineLength = line.GetTypographicBounds (out ascent, out descent, out leading); var prevHalfWidth = glyphArcInfo [0].width / 2.0; glyphArcInfo [0].angle = (float)((prevHalfWidth / lineLength) * Math.PI); var lineGlyphIndex = 1; for (; lineGlyphIndex < glyphCount; lineGlyphIndex++) { var halfWidth = glyphArcInfo [lineGlyphIndex].width / 2.0; var prevCenterToCenter = prevHalfWidth + halfWidth; glyphArcInfo [lineGlyphIndex].angle = (float)((prevCenterToCenter / lineLength) * Math.PI); prevHalfWidth = halfWidth; } }
public void DrawText(string text, Rect frame, Font font, TextAlignment alignment = TextAlignment.Left, Pen pen = null, Brush brush = null) { if (string.IsNullOrEmpty(text)) { return; } if (font == null) { throw new ArgumentNullException("font"); } SetBrush(brush); var pt = frame.TopLeft; using (var atext = new NSMutableAttributedString(text)) { atext.AddAttributes(new CTStringAttributes { ForegroundColorFromContext = true, Font = font.GetCTFont(), }, new NSRange(0, text.Length)); using (var l = new CTLine(atext)) { context.SaveState(); context.TranslateCTM((nfloat)(pt.X), (nfloat)(pt.Y)); context.TextPosition = CGPoint.Empty; l.Draw(context); context.RestoreState(); } } }
public float GetTypographicWidth(TFont font, AttributedGlyphRun <TFont, TGlyph> run) { var aString = run.ToNsAttributedString(); using (var ctLine = new CTLine(aString)) return((float)ctLine.GetTypographicBounds()); }
public override void Draw(CGRect rect) { base.Draw(rect); var gctx = UIGraphics.GetCurrentContext(); gctx.TranslateCTM(10, 0.5f * Bounds.Height); gctx.ScaleCTM(1, -1); gctx.RotateCTM((float)Math.PI * 315 / 180); gctx.SetFillColor(UIColor.Green.CGColor); string text = "Alfatraining"; var attributedString = new NSAttributedString(text, new CoreText.CTStringAttributes { ForegroundColorFromContext = true, Font = new CTFont("Arial", 24) }); using (var textLine = new CTLine(attributedString)) { textLine.Draw(gctx); } }
public Task <NSImage> LoadImageAsync( ImageSource imagesource, CancellationToken cancelationToken = default(CancellationToken), float scale = 1f) { NSImage image = null; var fontsource = imagesource as FontImageSource; if (fontsource != null) { var font = NSFont.FromFontName(fontsource.FontFamily ?? string.Empty, (float)fontsource.Size) ?? NSFont.SystemFontOfSize((float)fontsource.Size); var iconcolor = fontsource.Color.IsDefault ? _defaultColor : fontsource.Color; var attString = new NSAttributedString(fontsource.Glyph, font: font, foregroundColor: iconcolor.ToNSColor()); var imagesize = ((NSString)fontsource.Glyph).StringSize(attString.GetAttributes(0, out _)); using (var context = new CGBitmapContext(IntPtr.Zero, (nint)imagesize.Width, (nint)imagesize.Height, 8, (nint)imagesize.Width * 4, NSColorSpace.GenericRGBColorSpace.ColorSpace, CGImageAlphaInfo.PremultipliedFirst)) { using (var ctline = new CTLine(attString)) { ctline.Draw(context); } using (var cgImage = context.ToImage()) { image = new NSImage(cgImage, imagesize); } } } return(Task.FromResult(image)); }
public override void Draw(CGRect rect) { base.Draw(rect); var cgContext = UIGraphics.GetCurrentContext(); if (_mathList != null) { var appleContext = new AppleGraphicsContext() { CgContext = cgContext }; cgContext.SaveState(); cgContext.SetStrokeColor(TextColor.CGColor); cgContext.SetFillColor(TextColor.CGColor); _displayList.Draw(appleContext); cgContext.RestoreState(); } else if (ErrorMessage.IsNonEmpty()) { cgContext.SaveState(); float errorFontSize = 20; var attributes = new UIStringAttributes { ForegroundColor = NColor.Red, Font = UIFont.SystemFontOfSize(errorFontSize), }; var attributedString = new NSAttributedString(ErrorMessage, attributes); var ctLine = new CTLine(attributedString); cgContext.TextPosition = new CGPoint(0, Bounds.Size.Height - errorFontSize); ctLine.Draw(cgContext); cgContext.RestoreState(); } }
// Public method to create a rect for a given range in the text contents // Called by our EditableTextRange to implement the required // UITextInput:firstRectForRange method public CGRect FirstRect(NSRange range) { int index = (int)range.Location; // Iterate over our CTLines, looking for the line that encompasses the given range var lines = frame.GetLines(); for (int i = 0; i < lines.Length; i++) { CTLine line = lines [i]; NSRange lineRange = line.StringRange; int localIndex = index - (int)lineRange.Location; if (localIndex >= 0 && localIndex < lineRange.Length) { // For this sample, we use just the first line that intersects range int finalIndex = (int)Math.Min(lineRange.Location + lineRange.Length, range.Location + range.Length); // Create a rect for the given range within this line nfloat xStart = line.GetOffsetForStringIndex(index); nfloat xEnd = line.GetOffsetForStringIndex(finalIndex); var origins = new CGPoint [lines.Length]; frame.GetLineOrigins(new NSRange(i, 0), origins); nfloat ascent, descent, leading; line.GetTypographicBounds(out ascent, out descent, out leading); return(new CGRect(xStart, origins [0].Y - descent, xEnd - xStart, ascent + descent)); } } return(CGRect.Empty); }
public void DrawText(FormattedText formattedText, Point point, Rect?clipRect) { context.SaveState(); context.ScaleCTM(1, -1); context.SetFillColor(formattedText.Brush.Color.ToiOS()); var sizeOfText = formattedText.DesiredSize; var ctFont = new CTFont(formattedText.FontName, formattedText.FontSize); var attributedString = new NSAttributedString(formattedText.Text, new CTStringAttributes { ForegroundColor = formattedText.Brush.Color.ToiOS(), Font = ctFont }); context.TextPosition = new CGPoint(point.X, -(point.Y + sizeOfText.Height - ctFont.DescentMetric)); using (var textLine = new CTLine(attributedString)) { textLine.Draw(context); } context.RestoreState(); }
public void GetImageBounds() { using (var a = new NSAttributedString()) using (var l = new CTLine(a)) { Assert.True(l.GetImageBounds(null).IsEmpty, "GetImageBounds"); } }
public void EnumerateCaretOffsets() { if (!TestRuntime.CheckXcodeVersion(7, 0)) { Assert.Ignore("Requires iOS9+ or macOS 10.11+"); } var sa = new CTStringAttributes(); sa.ForegroundColor = UIColor.Blue.CGColor; sa.Font = new CTFont("Georgia-BoldItalic", 24); sa.UnderlineStyle = CTUnderlineStyle.Double; // It does not seem to do anything sa.UnderlineColor = UIColor.Blue.CGColor; sa.UnderlineStyleModifiers = CTUnderlineStyleModifiers.PatternDashDotDot; var attributedString = new NSAttributedString("Hello world.\nWoohooo!\nThere", sa); var line = new CTLine(attributedString); bool executed = false; #if XAMCORE_2_0 line.EnumerateCaretOffsets((double o, nint charIndex, bool leadingEdge, ref bool stop) => { #else line.EnumerateCaretOffsets((double o, int charIndex, bool leadingEdge, ref bool stop) => { #endif executed = true; }); Assert.IsTrue(executed); }
/// <summary> /// Measures the text. /// </summary> /// <param name="text">The text.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <returns> /// The size of the text. /// </returns> public override OxySize MeasureText(string text, string fontFamily, double fontSize, double fontWeight) { if (string.IsNullOrEmpty(text) || fontFamily == null) { return(OxySize.Empty); } var fontName = GetActualFontName(fontFamily, fontWeight); var font = this.GetCachedFont(fontName, (float)fontSize); using (var attributedString = new NSAttributedString(text, new CTStringAttributes { ForegroundColorFromContext = true, Font = font })) { using (var textLine = new CTLine(attributedString)) { float lineHeight, delta; this.GetFontMetrics(font, out lineHeight, out delta); // the text position must be set to get the correct bounds this.gctx.TextPosition = new CGPoint(0, 0); var bounds = textLine.GetImageBounds(this.gctx); var width = bounds.Left + bounds.Width; return(new OxySize(width, lineHeight)); } } }
public override void Draw(CGRect rect) { base.Draw(rect); using (CGContext context = UIGraphics.GetCurrentContext()) { var radius = this.Frame.Width / 2; CGPath path = new CGPath(); path.AddArc(this.Frame.Width / 2, this.Frame.Height / 2, radius - 1, 0, (nfloat)(360 * radians), true); ViewColor.SetColor(); context.AddPath(path); context.DrawPath(CGPathDrawingMode.FillStroke); UIColor.White.SetColor(); CTFont font = new CTFont("Arial", 20); NSAttributedString stringToBeDrawn = new NSAttributedString(text, new CTStringAttributes() { Font = font, ForegroundColorFromContext = true, }); context.TranslateCTM(this.Frame.Width / 2 - stringToBeDrawn.Size.Width / 2, this.Frame.Height / 2 + stringToBeDrawn.Size.Height / 4); context.ScaleCTM(1, -1); CTLine line = new CTLine(stringToBeDrawn); line.Draw(context); font = null; stringToBeDrawn = null; path = null; } }
public static TextMetrics GlobalMeasureText(string text, Font font) { if (string.IsNullOrEmpty(text)) { return(new TextMetrics()); } if (font == null) { throw new ArgumentNullException("font"); } using (var atext = new NSMutableAttributedString(text)) { atext.AddAttributes(new CTStringAttributes { ForegroundColorFromContext = true, Font = font.GetCTFont(), }.Dictionary, new NSRange(0, text.Length)); using (var l = new CTLine(atext)) { nfloat asc, desc, lead; var len = l.GetTypographicBounds(out asc, out desc, out lead); return(new TextMetrics { Width = len, Ascent = asc, Descent = desc, }); } } }
public void SimpleValuesSet() { var sa = new CTStringAttributes(); sa.ForegroundColor = UIColor.Blue.CGColor; sa.Font = new CTFont("Georgia-BoldItalic", 24); sa.UnderlineStyle = CTUnderlineStyle.Double; // It does not seem to do anything sa.UnderlineColor = UIColor.Blue.CGColor; sa.UnderlineStyleModifiers = CTUnderlineStyleModifiers.PatternDashDotDot; Assert.IsNull(sa.BaselineClass, "#0"); sa.BaselineClass = CTBaselineClass.IdeographicHigh; Assert.AreEqual(CTBaselineClass.IdeographicHigh, sa.BaselineClass, "#1"); sa.SetBaselineInfo(CTBaselineClass.Roman, 13); sa.SetBaselineInfo(CTBaselineClass.IdeographicHigh, 3); sa.SetWritingDirection(CTWritingDirection.LeftToRight); var size = new SizeF(300, 300); UIGraphics.BeginImageContext(size); var gctx = UIGraphics.GetCurrentContext(); gctx.SetFillColor(UIColor.Green.CGColor); var attributedString = new NSAttributedString("Test_ME~`", sa); using (var textLine = new CTLine(attributedString)) { textLine.Draw(gctx); } UIGraphics.EndImageContext(); }
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 double GetBaseLine() { using (var line = new CTLine(TextStorage)) { nfloat ascent, descent, leading; line.GetTypographicBounds(out ascent, out descent, out leading); return(ascent); } }
public override double GetBaseline(object backend) { LayoutInfo li = (LayoutInfo)backend; using (var line = new CTLine(CreateAttributedString(li))) { nfloat ascent, descent, leading; line.GetTypographicBounds(out ascent, out descent, out leading); return((double)ascent); } }
public void DrawGlyphRunWithOffset(AttributedGlyphRun <TFont, TGlyph> run, PointF offset, Color?color) { DebugWriteLine($"Text {run} {offset.X} {offset.Y}"); CgContext.TextPosition = new CGPoint(CgContext.TextPosition.X + offset.X, CgContext.TextPosition.Y + offset.Y); if (color.HasValue) { CgContext.SetFillColor(color.Value.ToCgColor()); } using (var textLine = new CTLine(run.ToNsAttributedString())) textLine.Draw(CgContext); }
public void DrawGlyphRunWithOffset(AttributedGlyphRun <TFont, TGlyph> run, PointF offset, Color?color) { CgContext.TextPosition = new CGPoint (CgContext.TextPosition.X + offset.X, CgContext.TextPosition.Y + offset.Y); if (color.HasValue) { CgContext.SetFillColor(color.GetValueOrDefault().ToCGColor()); } using var textLine = new CTLine(run.ToNsAttributedString()); textLine.Draw(CgContext); }
public void DrawString(string s, float x, float y) { var attributedString = new NSAttributedString(s, _ct_attr); _c.TextPosition = new PointF((float)x, (float)/*height -*/ y); // I think that by using CTLine() below, we are preventing multi-line text. :-( using (var textLine = new CTLine(attributedString)) { textLine.Draw(_c); } }
partial void MeasureCharacterRangeImp(string str, Font font, StringFormat format, CharacterRange range, ref RectangleF ret) { var attributedString = CreateAttributedString(str, font, format, null); CTLine line = new CTLine(attributedString); CTRun[] runArray = line.GetGlyphRuns(); if (runArray.Length > 0) { context.TextPosition = new CGPoint(); ret = runArray[0].GetImageBounds(context, new NSRange(range.First, range.Length)).ToRectangle(); } }
public void GetBaseAdvancesAndOrigins() { TestRuntime.AssertXcodeVersion(11, 0); using (var attributedString = new NSAttributedString("Hello world.")) using (var line = new CTLine(attributedString)) { var runs = line.GetGlyphRuns(); Assert.That(runs.Length, Is.EqualTo(1), "runs"); runs [0].GetBaseAdvancesAndOrigins(new NSRange(0, 10), out var advances, out var origins); Assert.IsNotNull(advances, "advances"); Assert.IsNotNull(origins, "origins"); } }
internal static void Draw(CGContext ctx, object layout, double x, double y) { LayoutInfo li = (LayoutInfo)layout; using (CTFrame frame = CreateFrame(li)) { if (frame == null) { return; } CTLine ellipsis = null; bool ellipsize = li.Width.HasValue && li.TextTrimming == TextTrimming.WordElipsis; if (ellipsize) { ellipsis = new CTLine(CreateAttributedString(li, "...")); } nfloat lineHeight = li.Font.Ascender - li.Font.Descender + li.Font.Leading; ctx.SaveState(); ctx.TextMatrix = CGAffineTransform.MakeScale(1f, -1f); ctx.TranslateCTM((float)x, (float)y + li.Font.Ascender); foreach (var line in frame.GetLines()) { ctx.TextPosition = CGPoint.Empty; // Determine final line var ln = line; if (ellipsize) { // we need to create a new CTLine here because the framesetter already truncated the text for the line ln = new CTLine(CreateAttributedString(li, li.Text.Substring((int)line.StringRange.Location))) .GetTruncatedLine(li.Width.Value, CTLineTruncation.End, ellipsis); line.Dispose(); } else if (li.Width.HasValue && li.TextAlignment != Alignment.Start) { var tx = li.Width.Value - GetLineWidth(ln); if (li.TextAlignment == Alignment.Center) { tx /= 2d; } ctx.TextPosition = new CGPoint((nfloat)tx, 0); } ln.Draw(ctx); ctx.TranslateCTM(0, lineHeight); ln.Dispose(); } ctx.RestoreState(); } }
public override Size GetSize(object backend) { LayoutInfo li = (LayoutInfo)backend; using (CTFrame frame = CreateFrame(li)) { if (frame == null) { return(Size.Zero); } Size result = Size.Zero; CTLine [] lines = frame.GetLines(); nfloat lineHeight = li.Font.Ascender - li.Font.Descender + li.Font.Leading; CTLine ellipsis = null; bool ellipsize = li.Width.HasValue && li.TextTrimming == TextTrimming.WordElipsis; if (ellipsize) { ellipsis = new CTLine(CreateAttributedString(li, "...")); } // try to approximate Pango's layout foreach (var line in lines) { var l = line; if (ellipsize) // we need to create a new CTLine here because the framesetter already truncated the text for the line { l = new CTLine(CreateAttributedString(li, li.Text.Substring((int)line.StringRange.Location))) .GetTruncatedLine(li.Width.Value, CTLineTruncation.End, ellipsis); line.Dispose(); } result.Width = Math.Max(result.Width, l.GetTypographicBounds()); result.Height += lineHeight; // clean up after ourselves as we go l.Dispose(); } // CoreText throws away trailing line breaks.. if (li.Text.EndsWith("\n")) { result.Height += lineHeight; } result.Width = Math.Ceiling(result.Width); result.Height = Math.Ceiling(result.Height); return(result); } }
public void DrawText(string text, Rect frame, Font font, TextAlignment alignment = TextAlignment.Left, Pen pen = null, Brush brush = null) { if (string.IsNullOrEmpty(text)) { return; } if (font == null) { throw new ArgumentNullException("font"); } SetBrush(brush); using (var atext = new NSMutableAttributedString(text)) { atext.AddAttributes(new CTStringAttributes { ForegroundColorFromContext = true, Font = font.GetCTFont(), }, new NSRange(0, text.Length)); using (var l = new CTLine(atext)) { nfloat asc, desc, lead; var len = l.GetTypographicBounds(out asc, out desc, out lead); var pt = frame.TopLeft; switch (alignment) { case TextAlignment.Left: pt.X = frame.X; break; case TextAlignment.Center: pt.X = frame.X + (frame.Width - len) / 2; break; case TextAlignment.Right: pt.X = frame.Right - len; break; } context.SaveState(); context.TranslateCTM((nfloat)(pt.X), (nfloat)(pt.Y)); context.TextPosition = CGPoint.Empty; l.Draw(context); context.RestoreState(); } } }
// This only handles one character for right now internal static void GetCharABCWidthsFloat(char characters, CTFont font, out ABCFloat[] abc) { var atts = buildAttributedString(characters.ToString(), font); // for now just a line not sure if this is going to work CTLine line = new CTLine(atts); float ascent; float descent; float leading; abc = new ABCFloat[1]; abc[0].abcfB = (float)line.GetTypographicBounds(out ascent, out descent, out leading); abc [0].abcfB += leading; }
// Public method to determine the CGRect for the insertion point or selection, used // when creating or updating our SimpleCaretView instance public CGRect CaretRect(int index) { var lines = frame.GetLines(); // Special case, no text if (text.Length == 0) { CGPoint origin = new CGPoint(Bounds.GetMinX(), Bounds.GetMinY() - font.Leading); // Note: using fabs() for typically negative descender from fonts return(new CGRect(origin.X, origin.Y - (nfloat)Math.Abs(font.Descender), 3, font.Ascender + (nfloat)Math.Abs(font.Descender))); } // Special case, insertion point at final position in text after newline if (index == text.Length && text.EndsWith("\n")) { CTLine line = lines [lines.Length - 1]; NSRange range = line.StringRange; nfloat xPos = line.GetOffsetForStringIndex(range.Location); var origins = new CGPoint [lines.Length]; nfloat ascent, descent, leading; line.GetTypographicBounds(out ascent, out descent, out leading); frame.GetLineOrigins(new NSRange(lines.Length - 1, 0), origins); // Place point after last line, including any font leading spacing if applicable origins[0].Y -= font.Leading; return(new CGRect(xPos, origins [0].Y - descent, 3, ascent + descent)); } // Regular case, caret somewhere within our text content range for (int i = 0; i < lines.Length; i++) { CTLine line = lines [i]; NSRange range = line.StringRange; int localIndex = index - (int)range.Location; if (localIndex >= 0 && localIndex <= range.Length) { // index is in the range for this line nfloat xPos = line.GetOffsetForStringIndex(index); var origins = new CGPoint [lines.Length]; nfloat ascent, descent, leading; line.GetTypographicBounds(out ascent, out descent, out leading); frame.GetLineOrigins(new NSRange(i, 0), origins); // Make a small "caret" rect at the index position return(new CGRect(xPos, origins [0].Y - descent, 3, ascent + descent)); } } return(CGRect.Empty); }
public static ABC GetCharWidthABC(char ch, Font font, System.Drawing.Graphics gr) { ABC[] _temp = new ABC[1]; var nativFont = CreateFont(font.Name, font.Size, font.Style, font.GdiCharSet, font.GdiVerticalFont); var atts = buildAttributedString(ch.ToString(), nativFont); // for now just a line not sure if this is going to work CTLine line = new CTLine(atts); float ascent; float descent; float leading; _temp[0].abcB = (uint)line.GetTypographicBounds(out ascent, out descent, out leading); return(_temp[0]); }
internal static CCSize MeasureString(string textg, CTFont font, CCRect rect) { var atts = buildAttributedString(textg, font); // for now just a line not sure if this is going to work CTLine line = new CTLine(atts); // Create and initialize some values from the bounds. float ascent; float descent; float leading; double lineWidth = line.GetTypographicBounds(out ascent, out descent, out leading); var measure = new CCSize((float)lineWidth + leading, ascent + descent); return(measure); }
void DrawTexts(List<string> tagStrings, List<RectangleF> rects) { using (CGContext gctx = UIGraphics.GetCurrentContext ()) { gctx.SaveState (); gctx.ScaleCTM (1f, -1f); gctx.TranslateCTM (0, Frame.Height); gctx.SetFillColor (UIColor.Green.CGColor); for (int i = 0; i < tagStrings.Count; i++) { gctx.SaveState (); var attributedString = new NSAttributedString (tagStrings[i], new CTStringAttributes { ForegroundColorFromContext = true, Font = new CTFont ("ArialMT", 48) }); gctx.TextPosition = new PointF (rects[i].X, rects[i].Y); using (var textLine = new CTLine (attributedString)) { textLine.Draw (gctx); } gctx.RestoreState (); } gctx.RestoreState (); } }
public override void Draw(CGRect rect) { base.Draw (rect); var gctx = UIGraphics.GetCurrentContext (); gctx.TranslateCTM (10, 0.5f * Bounds.Height); gctx.ScaleCTM (1, -1); gctx.RotateCTM ((float)Math.PI * 315 / 180); gctx.SetFillColor (UIColor.Green.CGColor); string someText = "你好世界"; var attributedString = new NSAttributedString (someText, new CTStringAttributes{ ForegroundColorFromContext = true, Font = new CTFont ("Arial", 24) }); using (var textLine = new CTLine (attributedString)) { textLine.Draw (gctx); } }
/// <summary> /// Measures the text. /// </summary> /// <param name="text">The text.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <returns> /// The size of the text. /// </returns> public override OxySize MeasureText(string text, string fontFamily, double fontSize, double fontWeight) { if (string.IsNullOrEmpty(text) || fontFamily == null) { return OxySize.Empty; } var fontName = GetActualFontName(fontFamily, fontWeight); using (var attributedString = new NSAttributedString(text, new CTStringAttributes { ForegroundColorFromContext = true, Font = new CTFont(fontName, (float)fontSize) })) { using (var textLine = new CTLine(attributedString)) { var bounds = textLine.GetImageBounds(this.gctx); return new OxySize(bounds.Width, bounds.Height); } } }
public override void Draw (RectangleF rect) { var context = UIGraphics.GetCurrentContext (); context.TextMatrix = CGAffineTransform.MakeScale (1f, -1f); context.TextPosition = new PointF (10f, base.Center.Y); var attrString = new NSAttributedString ("my Arial 20 label!", new CTStringAttributes () { Font = new CTFont ("Arial", 20f), }); using (var line = new CTLine (attrString)) line.Draw (context); }
protected override void DrawParagraph(Paragraph paragraph) { int currentRegionLeft = SecondsToXPosition(paragraph.StartTime.TotalSeconds - StartPositionSeconds); int currentRegionRight = SecondsToXPosition(paragraph.EndTime.TotalSeconds - StartPositionSeconds); int currentRegionWidth = currentRegionRight - currentRegionLeft; // background _context.SetFillColor(new CGColor(1, 1, 1, (System.nfloat)0.2)); _context.FillRect(new CGRect(currentRegionLeft, 0, currentRegionWidth, Height)); // using (var brush = new SolidBrush(Color.FromArgb(42, 255, 255, 255))) // graphics.FillRectangle(brush, currentRegionLeft, 0, currentRegionWidth, graphics.VisibleClipBounds.Height); // // left edge _context.SetStrokeColor(Color.FromArgb(175, 0, 100, 0).ToCGColor()); DrawLine(currentRegionLeft, 0, currentRegionLeft, Height); // using (var pen = new Pen(new SolidBrush(Color.FromArgb(175, 0, 100, 0))) { DashStyle = DashStyle.Solid, Width = 2 }) // graphics.DrawLine(pen, currentRegionLeft, 0, currentRegionLeft, graphics.VisibleClipBounds.Height); // // right edge _context.SetStrokeColor(Color.FromArgb(175, 110, 10, 10).ToCGColor()); DrawLine(currentRegionRight - 1, 0, currentRegionRight - 1, Height); // using (var pen = new Pen(new SolidBrush(Color.FromArgb(175, 110, 10, 10))) { DashStyle = DashStyle.Dash, Width = 2 }) // graphics.DrawLine(pen, currentRegionRight - 1, 0, currentRegionRight - 1, graphics.VisibleClipBounds.Height); // using (var font = new Font(Configuration.Settings.General.SubtitleFontName, TextSize, TextBold ? FontStyle.Bold : FontStyle.Regular)) // using (var textBrush = new SolidBrush(TextColor)) // using (var outlineBrush = new SolidBrush(Color.Black)) // { // Action<string, int, int> drawStringOutlined = (text, x, y) => // { // // poor mans outline + text // graphics.DrawString(text, font, outlineBrush, new PointF(x, y - 1)); // graphics.DrawString(text, font, outlineBrush, new PointF(x, y + 1)); // graphics.DrawString(text, font, outlineBrush, new PointF(x - 1, y)); // graphics.DrawString(text, font, outlineBrush, new PointF(x + 1, y)); // graphics.DrawString(text, font, textBrush, new PointF(x, y)); // }; // const int padding = 3; double n = _zoomFactor * _wavePeaks.SampleRate; _context.SelectFont("Arial", 12f, CGTextEncoding.MacRoman); _context.SetTextDrawingMode(CGTextDrawingMode.FillStroke); _context.SetStrokeColor(TextColor.ToCGColor()); // paragraph text if (n > 80) { string text = HtmlUtil.RemoveHtmlTags(paragraph.Text, true).Replace(Environment.NewLine, " "); // int removeLength = 1; // while (text.Length > removeLength && graphics.MeasureString(text, font).Width > currentRegionWidth - padding - 1) // { // text = text.Remove(text.Length - removeLength).TrimEnd() + "…"; // removeLength = 2; // } var attributedString = new NSAttributedString (text, new CTStringAttributes{ ForegroundColorFromContext = true, Font = new CTFont ("Arial", 12) }); _context.TextPosition = new CGPoint(currentRegionLeft + padding, padding); using (var textLine = new CTLine (attributedString)) { textLine.Draw (_context); } // drawStringOutlined(text, currentRegionLeft + padding, padding); } // // // paragraph number if (n > 25) { string text = "#" + paragraph.Number + " " + paragraph.Duration.ToShortDisplayString(); // if (n <= 51 || graphics.MeasureString(text, font).Width >= currentRegionWidth - padding - 1) // text = "#" + paragraph.Number; // drawStringOutlined(text, currentRegionLeft + padding, Height - 14 - (int)graphics.MeasureString("#", font).Height); _context.ShowTextAtPoint(currentRegionLeft + padding, Height - 14, text); } // } }
public void DrawText(string text, Rect frame, Font font, TextAlignment alignment = TextAlignment.Left, Pen pen = null, Brush brush = null) { if (string.IsNullOrEmpty (text)) return; if (font == null) throw new ArgumentNullException ("font"); SetBrush (brush); // string fontName = font.Name; // context.SelectFont (font.Name, (nfloat)font.Size, CGTextEncoding.MacRoman); // // context.ShowTextAtPoint ((nfloat)frame.X, (nfloat)frame.Y, text); var pt = frame.TopLeft; using (var atext = new NSMutableAttributedString (text)) { atext.AddAttributes (new CTStringAttributes { ForegroundColorFromContext = true, Font = font.GetCTFont (), }, new NSRange (0, text.Length)); using (var l = new CTLine (atext)) { nfloat asc, desc, lead; var width = l.GetTypographicBounds (out asc, out desc, out lead); context.SaveState (); context.TranslateCTM ((nfloat)(pt.X - width / 2), (nfloat)(pt.Y + desc)); context.TextPosition = CGPoint.Empty; l.Draw (context); context.RestoreState (); } } }
private static void DrawText(this CGContext context, string source, float x, float y, string fontName, float fontSize, bool isCenter) { var stringAttributes = new CTStringAttributes { ForegroundColorFromContext = true, Font = new CTFont(fontName, fontSize) }; var attributedString = new NSAttributedString(source, stringAttributes); context.TextPosition = new PointF(x, y); using (var textLine = new CTLine(attributedString)) { if (isCenter) context.TextPosition = new PointF((float)(x - (textLine.GetTypographicBounds() / 2)), y); textLine.Draw(context); } }
public void DrawText(string text, Rect frame, Font font, TextAlignment alignment = TextAlignment.Left, Pen pen = null, Brush brush = null) { if (string.IsNullOrEmpty (text)) return; if (font == null) throw new ArgumentNullException ("font"); SetBrush (brush); var pt = frame.TopLeft; using (var atext = new NSMutableAttributedString (text)) { atext.AddAttributes (new CTStringAttributes { ForegroundColorFromContext = true, Font = font.GetCTFont (), }, new NSRange (0, text.Length)); using (var l = new CTLine (atext)) { context.SaveState (); context.TranslateCTM ((nfloat)(pt.X), (nfloat)(pt.Y)); context.TextPosition = CGPoint.Empty; l.Draw (context); context.RestoreState (); } } }
public static TextMetrics GlobalMeasureText (string text, Font font) { if (string.IsNullOrEmpty(text)) return new TextMetrics (); if (font == null) throw new ArgumentNullException("font"); using (var atext = new NSMutableAttributedString (text)) { atext.AddAttributes (new CTStringAttributes { ForegroundColorFromContext = true, Font = font.GetCTFont (), }, new NSRange (0, text.Length)); using (var l = new CTLine (atext)) { nfloat asc, desc, lead; var len = l.GetTypographicBounds (out asc, out desc, out lead); return new TextMetrics { Width = len, Ascent = asc, Descent = desc, }; } } }
/// <summary> /// Measures the text. /// </summary> /// <param name="text">The text.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <returns> /// The size of the text. /// </returns> public override OxySize MeasureText(string text, string fontFamily, double fontSize, double fontWeight) { if (string.IsNullOrEmpty(text) || fontFamily == null) { return OxySize.Empty; } var fontName = GetActualFontName(fontFamily, fontWeight); var font = this.GetCachedFont(fontName, (float)fontSize); using (var attributedString = new NSAttributedString(text, new CTStringAttributes { ForegroundColorFromContext = true, Font = font })) { using (var textLine = new CTLine(attributedString)) { nfloat lineHeight, delta; this.GetFontMetrics(font, out lineHeight, out delta); this.gctx.TextPosition = new CGPoint(0, 0); var bounds = textLine.GetImageBounds(this.gctx); return new OxySize(bounds.Left + bounds.Width, lineHeight); } } }
/// <summary> /// Draws the text. /// </summary> /// <param name="p">The position of the text.</param> /// <param name="text">The text.</param> /// <param name="fill">The fill color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="rotate">The rotation angle.</param> /// <param name="halign">The horizontal alignment.</param> /// <param name="valign">The vertical alignment.</param> /// <param name="maxSize">The maximum size of the text.</param> public override void DrawText(ScreenPoint p, string text, OxyColor fill, string fontFamily, double fontSize, double fontWeight, double rotate, HorizontalAlignment halign, VerticalAlignment valign, OxySize? maxSize) { if (string.IsNullOrEmpty(text)) { return; } var fontName = GetActualFontName(fontFamily, fontWeight); var font = this.GetCachedFont(fontName, fontSize); using (var attributedString = new NSAttributedString(text, new CTStringAttributes { ForegroundColorFromContext = true, Font = font })) { using (var textLine = new CTLine(attributedString)) { nfloat width; nfloat height; this.gctx.TextPosition = new CGPoint(0, 0); nfloat lineHeight, delta; this.GetFontMetrics(font, out lineHeight, out delta); var bounds = textLine.GetImageBounds(this.gctx); if (maxSize.HasValue || halign != HorizontalAlignment.Left || valign != VerticalAlignment.Bottom) { width = bounds.Left + bounds.Width; height = lineHeight; } else { width = height = 0f; } if (maxSize.HasValue) { if (width > maxSize.Value.Width) { width = (float)maxSize.Value.Width; } if (height > maxSize.Value.Height) { height = (float)maxSize.Value.Height; } } var dx = halign == HorizontalAlignment.Left ? 0d : (halign == HorizontalAlignment.Center ? -width * 0.5 : -width); var dy = valign == VerticalAlignment.Bottom ? 0d : (valign == VerticalAlignment.Middle ? height * 0.5 : height); var x0 = -bounds.Left; var y0 = delta; this.SetFill(fill); this.SetAlias(false); this.gctx.SaveState(); this.gctx.TranslateCTM((float)p.X, (float)p.Y); if (!rotate.Equals(0)) { this.gctx.RotateCTM((float)(rotate / 180 * Math.PI)); } this.gctx.TranslateCTM((float)dx + x0, (float)dy + y0); this.gctx.ScaleCTM(1f, -1f); if (maxSize.HasValue) { var clipRect = new CGRect (-x0, y0, (float)Math.Ceiling (width), (float)Math.Ceiling (height)); this.gctx.ClipToRect(clipRect); } textLine.Draw(this.gctx); this.gctx.RestoreState(); } } }
public void DrawText (string text, Rect frame, Font font, TextAlignment alignment = TextAlignment.Left, Pen pen = null, Brush brush = null) { if (string.IsNullOrEmpty (text)) return; if (font == null) throw new ArgumentNullException ("font"); SetBrush (brush); using (var atext = new NSMutableAttributedString (text)) { atext.AddAttributes (new CTStringAttributes { ForegroundColorFromContext = true, StrokeColor = pen != null ? pen.Color.GetCGColor () : null, Font = font.GetCTFont (), }, new NSRange (0, text.Length)); using (var l = new CTLine (atext)) { nfloat asc, desc, lead; var len = l.GetTypographicBounds (out asc, out desc, out lead); var pt = frame.TopLeft; switch (alignment) { case TextAlignment.Left: pt.X = frame.X; break; case TextAlignment.Center: pt.X = frame.X + (frame.Width - len) / 2; break; case TextAlignment.Right: pt.X = frame.Right - len; break; } context.SaveState (); context.TranslateCTM ((nfloat)(pt.X), (nfloat)(pt.Y)); context.TextPosition = CGPoint.Empty; l.Draw (context); context.RestoreState (); } } }
/// <summary> /// Draws the text. /// </summary> /// <param name="p">The position of the text.</param> /// <param name="text">The text.</param> /// <param name="fill">The fill color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="rotate">The rotation angle.</param> /// <param name="halign">The horizontal alignment.</param> /// <param name="valign">The vertical alignment.</param> /// <param name="maxSize">The maximum size of the text.</param> public override void DrawText(ScreenPoint p, string text, OxyColor fill, string fontFamily, double fontSize, double fontWeight, double rotate, HorizontalAlignment halign, VerticalAlignment valign, OxySize? maxSize) { if (string.IsNullOrEmpty(text) || fontFamily == null) { return; } var fontName = GetActualFontName(fontFamily, fontWeight); using (var attributedString = new NSAttributedString(text, new CTStringAttributes { ForegroundColorFromContext = true, Font = new CTFont(fontName, (float)fontSize) })) { using (var textLine = new CTLine(attributedString)) { float width; float height; if (maxSize.HasValue || halign != HorizontalAlignment.Left || valign != VerticalAlignment.Bottom) { var bounds = textLine.GetImageBounds(this.gctx); width = bounds.Width; height = bounds.Height; } else { width = height = 0f; } if (maxSize.HasValue) { if (width > maxSize.Value.Width) { width = (float)maxSize.Value.Width; } if (height > maxSize.Value.Height) { height = (float)maxSize.Value.Height; } } var x = p.X; var y = p.Y; this.gctx.SaveState(); this.SetFill(fill); this.SetAlias(false); this.gctx.SetTextDrawingMode(CGTextDrawingMode.Fill); this.gctx.TextPosition = new PointF(0, 0); var dx = halign == HorizontalAlignment.Left ? 0d : (halign == HorizontalAlignment.Center ? -width * 0.5 : -width); var dy = valign == VerticalAlignment.Bottom ? 0d : (valign == VerticalAlignment.Middle ? height * 0.5 : height); this.gctx.TranslateCTM((float)x, (float)y); this.gctx.RotateCTM((float)(rotate / 180 * Math.PI)); this.gctx.TranslateCTM((float)dx, (float)dy); this.gctx.ScaleCTM(1f, -1f); if (maxSize.HasValue) { this.gctx.ClipToRect(new RectangleF(0, 0, width, height)); } textLine.Draw(this.gctx); this.gctx.RestoreState(); } } }
public override void DrawRect (CGRect dirtyRect) { // Don't draw if we don't have a font or a title. if (Font == null || Title == string.Empty) return; // Initialize the text matrix to a known value CGContext context = NSGraphicsContext.CurrentContext.GraphicsPort; context.TextMatrix = CGAffineTransform.MakeIdentity (); // Draw a white background NSColor.White.Set (); context.FillRect (dirtyRect); CTLine line = new CTLine (AttributedString); int glyphCount = (int)line.GlyphCount; if (glyphCount == 0) return; GlyphArcInfo[] glyphArcInfo = new GlyphArcInfo[glyphCount]; PrepareGlyphArcInfo (line, glyphCount, glyphArcInfo); // Move the origin from the lower left of the view nearer to its center. context.SaveState (); context.TranslateCTM (dirtyRect.GetMidX (), dirtyRect.GetMidY () - Radius / 2); // Stroke the arc in red for verification. context.BeginPath (); context.AddArc (0, 0, Radius, (float)Math.PI, 0, true); context.SetStrokeColor (1, 0, 0, 1); context.StrokePath (); // Rotate the context 90 degrees counterclockwise. context.RotateCTM ((float)PI_2); /* Now for the actual drawing. The angle offset for each glyph relative to the previous glyph has already been calculated; with that information in hand, draw those glyphs overstruck and centered over one another, making sure to rotate the context after each glyph so the glyphs are spread along a semicircular path. */ CGPoint textPosition = new CGPoint (0, Radius); context.TextPosition = textPosition; var runArray = line.GetGlyphRuns (); var runCount = runArray.Count (); var glyphOffset = 0; var runIndex = 0; for (; runIndex < runCount; runIndex++) { var run = runArray [runIndex]; var runGlyphCount = run.GlyphCount; bool drawSubstitutedGlyphsManually = false; CTFont runFont = run.GetAttributes ().Font; // Determine if we need to draw substituted glyphs manually. Do so if the runFont is not // the same as the overall font. var description = NSFontDescriptor.FromNameSize (runFont.FamilyName, runFont.Size); NSFont rrunFont = NSFont.FromDescription (description, runFont.Size); // used for comparison if (DimsSubstitutedGlyphs && Font != rrunFont) { drawSubstitutedGlyphsManually = true; } var runGlyphIndex = 0; for (; runGlyphIndex < runGlyphCount; runGlyphIndex++) { var glyphRange = new NSRange (runGlyphIndex, 1); context.RotateCTM (-(glyphArcInfo [runGlyphIndex + glyphOffset].angle)); // Center this glyph by moving left by half its width. var glyphWidth = glyphArcInfo [runGlyphIndex + glyphOffset].width; var halfGlyphWidth = glyphWidth / 2.0; var positionForThisGlyph = new CGPoint (textPosition.X - (float)halfGlyphWidth, textPosition.Y); // Glyphs are positioned relative to the text position for the line, so offset text position leftwards by this glyph's // width in preparation for the next glyph. textPosition.X -= glyphWidth; CGAffineTransform textMatrix = run.TextMatrix; textMatrix.x0 = positionForThisGlyph.X; textMatrix.y0 = positionForThisGlyph.Y; context.TextMatrix = textMatrix; if (!drawSubstitutedGlyphsManually) { run.Draw (context, glyphRange); } else { // We need to draw the glyphs manually in this case because we are effectively applying a graphics operation by // setting the context fill color. Normally we would use kCTForegroundColorAttributeName, but this does not apply // as we don't know the ranges for the colors in advance, and we wanted demonstrate how to manually draw. var cgFont = runFont.ToCGFont (); var glyph = run.GetGlyphs (glyphRange); var position = run.GetPositions (glyphRange); context.SetFont (cgFont); context.SetFontSize (runFont.Size); context.SetFillColor (0.25f, 0.25f, 0.25f, 1); context.ShowGlyphsAtPositions (glyph, position, 1); } // Draw the glyph bounds if (ShowsGlyphBounds) { var glyphBounds = run.GetImageBounds (context, glyphRange); context.SetStrokeColor (0, 0, 1, 1); context.StrokeRect (glyphBounds); } // Draw the bounding boxes defined by the line metrics if (ShowsLineMetrics) { var lineMetrics = new CGRect (); nfloat ascent = 0; nfloat descent = 0; nfloat leading = 0; run.GetTypographicBounds (glyphRange, out ascent, out descent, out leading); // The glyph is centered around the y-axis lineMetrics.Location = new CGPoint (-(float)halfGlyphWidth, positionForThisGlyph.Y - descent); lineMetrics.Size = new CGSize (glyphWidth, ascent + descent); context.SetStrokeColor (0, 1, 0, 1); context.StrokeRect (lineMetrics); } } glyphOffset += (int)runGlyphCount; } context.RestoreState (); }
public override void Draw (RectangleF rect) { var context = UIGraphics.GetCurrentContext (); context.TextMatrix = CGAffineTransform.MakeScale (1f, -1f); context.TextPosition = new PointF (10f, base.Center.Y); var attrString = new NSAttributedString ("This space intentionally blank. See stdout.", new CTStringAttributes () { Font = new CTFont ("Arial", 8f), }); using (var line = new CTLine (attrString)) { // line.Draw (context); // Get the offset needed to center the line: var flush = 0.5f; // centered var penOffset = line.GetPenOffsetForFlush (flush, Frame.Width); // Move the given text drawing position by the calculated offset and draw context.TextPosition = new PointF ((float) penOffset, base.Center.Y); line.Draw (context); } FontDescriptorChecks (); FontCollectionChecks (); ParagraphStyleChecks (); }