コード例 #1
0
        public float GetTypographicWidth(TFont font, AttributedGlyphRun <TFont, TGlyph> run)
        {
            var aString = run.ToNsAttributedString();

            using (var ctLine = new CTLine(aString))
                return((float)ctLine.GetTypographicBounds());
        }
コード例 #2
0
        // 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);
        }
コード例 #3
0
        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,
                    });
                }
            }
        }
コード例 #4
0
		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;
			}
		}
コード例 #5
0
 public double GetBaseLine()
 {
     using (var line = new CTLine(TextStorage))
     {
         nfloat ascent, descent, leading;
         line.GetTypographicBounds(out ascent, out descent, out leading);
         return(ascent);
     }
 }
コード例 #6
0
        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);
            }
        }
コード例 #7
0
        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();
                }
            }
        }
コード例 #8
0
        // 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;
        }
コード例 #9
0
        // 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);
        }
コード例 #10
0
        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]);
        }
コード例 #11
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);
        }
コード例 #12
0
        public void DrawText(string text, float x, float y, float width, float height, Xamarin.Forms.TextAlignment hAlignment, Xamarin.Forms.TextAlignment vAlignment)
        {
            if (font == null || font.NativeFont == null)
            {
                return;
            }

            var attributedString = new NSAttributedString(text, new CTStringAttributes()
            {
                Font = font.NativeFont, ForegroundColorFromContext = true
            });
            CTLine ctLine = new CTLine(attributedString);

            CGSize size = new CGSize((float)ctLine.GetTypographicBounds(), font.NativeFont.CapHeightMetric + font.NativeFont.DescentMetric);

            if ((hAlignment & Xamarin.Forms.TextAlignment.Center) != 0)
            {
                x += (width - (float)size.Width) / 2;
            }
            else if ((hAlignment & Xamarin.Forms.TextAlignment.End) != 0)
            {
                x += width - (float)size.Width;
            }

            if ((vAlignment & Xamarin.Forms.TextAlignment.Center) != 0)
            {
                y += (height - (float)size.Height) / 2;
            }
            else if ((vAlignment & Xamarin.Forms.TextAlignment.End) != 0)
            {
                y += height - (float)size.Height;
            }

            context.SaveState();
            context.ScaleCTM(1f, -1f);

            context.TextPosition = new CGPoint(x, -y - font.NativeFont.CapHeightMetric);
            ctLine.Draw(context);

            context.RestoreState();

            ctLine.Dispose();
            attributedString.Dispose();
        }
コード例 #13
0
        // Helper method for drawing the current selection range (as a simple filled rect)
        void DrawRangeAsSelection(NSRange selectionRange)
        {
            // If not in editing mode, we do not draw selection rects
            if (!IsEditing)
            {
                return;
            }

            // If selection range empty, do not draw
            if (selectionRange.Length == 0 || selectionRange.Location == NSRange.NotFound)
            {
                return;
            }

            // set the fill color to the selection color
            SelectionColor.SetFill();

            // Iterate over the lines in our CTFrame, looking for lines that intersect
            // with the given selection range, and draw a selection rect for each intersection
            var lines = frame.GetLines();

            for (int i = 0; i < lines.Length; i++)
            {
                CTLine  line         = lines [i];
                NSRange lineRange    = line.StringRange;
                NSRange range        = new NSRange(lineRange.Location, lineRange.Length);
                NSRange intersection = RangeIntersection(range, selectionRange);
                if (intersection.Location != NSRange.NotFound && intersection.Length > 0)
                {
                    // The text range for this line intersects our selection range
                    nfloat xStart = line.GetOffsetForStringIndex(intersection.Location);
                    nfloat xEnd   = line.GetOffsetForStringIndex(intersection.Location + intersection.Length);
                    var    origin = new CGPoint [lines.Length];
                    // Get coordinate and bounds information for the intersection text range
                    frame.GetLineOrigins(new NSRange(i, 0), origin);
                    nfloat ascent, descent, leading;
                    line.GetTypographicBounds(out ascent, out descent, out leading);
                    // Create a rect for the intersection and draw it with selection color
                    CGRect selectionRect = new CGRect(xStart, origin [0].Y - descent, xEnd - xStart, ascent + descent);
                    UIGraphics.RectFill(selectionRect);
                }
            }
        }
コード例 #14
0
ファイル: CoreTextArcView.cs プロジェクト: spica/mac-samples
        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;
            }
        }
コード例 #15
0
        public Xamarin.Forms.Size MeasureText(string text)
        {
            if (font == null || font.NativeFont == null)
            {
                return(Xamarin.Forms.Size.Zero);
            }

            var attributedString = new NSAttributedString(text, new CTStringAttributes()
            {
                Font = font.NativeFont, ForegroundColorFromContext = true
            });
            CTLine ctLine = new CTLine(attributedString);

            Xamarin.Forms.Size size = new Xamarin.Forms.Size((float)ctLine.GetTypographicBounds(), font.NativeFont.CapHeightMetric + font.NativeFont.DescentMetric);

            ctLine.Dispose();
            attributedString.Dispose();

            return(size);
        }
コード例 #16
0
        public SizeF MeasureString(string textg, Font font, RectangleF rect)
        {
            // As per documentation
            // https://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_text/dq_text.html#//apple_ref/doc/uid/TP30001066-CH213-TPXREF101
            //
            // * Note * Not sure if we should save off the graphic state, set context transform to identity
            //  and restore state to do the measurement.  Something to be looked into.
            //			context.TextPosition = rect.Location;
            //			var startPos = context.TextPosition;
            //			context.SelectFont ( font.nativeFont.PostScriptName,
            //			                    font.SizeInPoints,
            //			                    CGTextEncoding.MacRoman);
            //			context.SetTextDrawingMode(CGTextDrawingMode.Invisible);
            //
            //			context.SetCharacterSpacing(1);
            //			var textMatrix = CGAffineTransform.MakeScale(1f,-1f);
            //			context.TextMatrix = textMatrix;
            //
            //			context.ShowTextAtPoint(rect.X, rect.Y, textg, textg.Length);
            //			var endPos = context.TextPosition;
            //
            //			var measure = new SizeF(endPos.X - startPos.X, font.nativeFont.CapHeightMetric);

            var atts = buildAttributedString(textg, font);

            // for now just a line not sure if this is going to work
            CTLine line       = new CTLine(atts);
            var    lineBounds = line.GetImageBounds(context);
            // 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 SizeF((float)lineWidth, ascent + descent);

            return(measure);
        }
コード例 #17
0
        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();
                }
            }
        }
コード例 #18
0
ファイル: ApplePlatform.cs プロジェクト: nakijun/NGraphics
        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 ();
                }
            }
        }
コード例 #19
0
		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 ();
				}
			}
		}
コード例 #20
0
		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,
					};
				}
			}

		}
コード例 #21
0
 static double GetLineWidth(CTLine l)
 {
     // Pango does not consider trailing whitespace in its size
     return(l.GetTypographicBounds() - l.TrailingWhitespaceWidth);
 }
コード例 #22
0
        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);
            }
        }