Esempio n. 1
0
        public static RectangleF GetTextSize(CTFrame frame)
        {
            var   minY  = float.MaxValue;
            var   maxY  = float.MinValue;
            float width = 0;

            var lines   = frame.GetLines();
            var origins = new CGPoint[lines.Length];

            frame.GetLineOrigins(new NSRange(0, 0), origins);

            for (var i = 0; i < lines.Length; i++)
            {
                var line      = lines[i];
                var lineWidth = (float)line.GetTypographicBounds(out var ascent, out var descent, out var leading);

                if (lineWidth > width)
                {
                    width = lineWidth;
                }

                var origin = origins[i];

                minY = (float)Math.Min(minY, origin.Y - ascent);
                maxY = (float)Math.Max(maxY, origin.Y + descent);

                lines[i].Dispose();
            }

            return(new RectangleF(0f, minY, width, Math.Max(0, maxY - minY)));
        }
Esempio n. 2
0
        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();
                float     lineHeight = li.Font.Ascender - li.Font.Descender + li.Font.Leading;

                // try to approximate Pango's layout
                foreach (var line in lines)
                {
                    result.Width   = Math.Max(result.Width, line.GetTypographicBounds());
                    result.Height += lineHeight;

                    // clean up after ourselves as we go
                    line.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);
            }
        }
		void TextChanged ()
		{
			SetNeedsDisplay ();
			ClearPreviousLayoutInformation ();

			attributedString = new NSAttributedString (Text, attributes);
			framesetter = new CTFramesetter (attributedString);

			UIBezierPath path = UIBezierPath.FromRect (Bounds);
			frame = framesetter.GetFrame (new NSRange (0, 0), path.CGPath, null);
		}
Esempio n. 4
0
        void TextChanged()
        {
            SetNeedsDisplay();
            ClearPreviousLayoutInformation();

            attributedString = new NSAttributedString(Text, attributes);
            framesetter      = new CTFramesetter(attributedString);

            UIBezierPath path = UIBezierPath.FromRect(Bounds);

            frame = framesetter.GetFrame(new NSRange(0, 0), path.CGPath, null);
        }
		void ClearPreviousLayoutInformation ()
		{
			if (framesetter != null) {
				framesetter.Dispose ();
				framesetter = null;
			}

			if (frame != null) {
				frame.Dispose ();
				frame = null;
			}
		}
        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);
            }
        }
Esempio n. 7
0
        void ClearPreviousLayoutInformation()
        {
            if (framesetter != null)
            {
                framesetter.Dispose();
                framesetter = null;
            }

            if (frame != null)
            {
                frame.Dispose();
                frame = null;
            }
        }
Esempio n. 8
0
        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();
            }
        }
Esempio n. 9
0
        void drawLabel(CGContext ctx, CGRect rect, nfloat yCoord, nfloat xCoord, UITextAlignment alignment, string label, bool flipContext = true, bool centerVertical = false)
        {
            // Draw light the sunrise and Sunset labels at the ends of the light box
            using (UIColor fontColor = UIColor.White, shadowColor = UIColor.Black.ColorWithAlpha(0.1f)) {
                var fontAttributes = new UIFontAttributes(new UIFontFeature(CTFontFeatureNumberSpacing.Selector.ProportionalNumbers));

                using (var desc = UIFont.SystemFontOfSize(fontSize).FontDescriptor.CreateWithAttributes(fontAttributes)) {
                    using (UIFont font = UIFont.FromDescriptor(desc, fontSize)) {
                        // calculating the range of our attributed string
                        var range = new NSRange(0, label.Length);

                        // set justification for text block
                        using (var alignStyle = new NSMutableParagraphStyle {
                            Alignment = alignment
                        }) {
                            // add stylistic attributes to out attributed string
                            var stringAttributes = new UIStringAttributes {
                                ForegroundColor = fontColor,
                                Font            = font,
                                ParagraphStyle  = alignStyle
                            };

                            var target = new CGSize(float.MaxValue, float.MaxValue);

                            NSRange fit;

                            using (NSMutableAttributedString attrString = new NSMutableAttributedString(label, stringAttributes)) {
                                //creating a container for out attributed string
                                using (CTFramesetter framesetter = new CTFramesetter(attrString)) {
                                    CGSize frameSize = framesetter.SuggestFrameSize(range, null, target, out fit);


                                    if (alignment == UITextAlignment.Center)
                                    {
                                        xCoord -= (frameSize.Width / 2);
                                    }

                                    if (alignment == UITextAlignment.Right)
                                    {
                                        xCoord -= frameSize.Width;
                                    }


                                    // subtract the frameSize so the flipped context behaves as expected
                                    yCoord -= frameSize.Height;

                                    if (centerVertical)
                                    {
                                        yCoord += (frameSize.Height / 2);
                                    }


                                    var textRect = new CGRect(xCoord, yCoord, frameSize.Width, frameSize.Height);

                                    using (CGPath path = new CGPath()) {
                                        path.AddRect(textRect);

                                        ctx.SetShadow(new CGSize(0.0f, 1.0f), 0.0f, shadowColor.CGColor);

                                        using (CTFrame frame = framesetter.GetFrame(range, path, null)) {
                                            if (flipContext)
                                            {
                                                ctx.SaveState();
                                                ctx.TranslateCTM(0, rect.Height);
                                                ctx.ScaleCTM(1, -1);

                                                frame.Draw(ctx);

                                                ctx.RestoreState();
                                            }
                                            else
                                            {
                                                frame.Draw(ctx);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }