Example #1
0
        private NSAttributedString GetAttributedText(NSAttributedStringTarget target)
        {
            if (target == NSAttributedStringTarget.UILabel && UseInlinesFastPath && LineHeight == 0 && CharacterSpacing == 0)
            {
                // Fast path in case everything can be set directly on UILabel without using NSAttributedString.
                return(null);
            }
            else
            {
                var mutableAttributedString = new NSMutableAttributedString(Text);
                mutableAttributedString.BeginEditing();

                mutableAttributedString.AddAttributes(GetAttributes(target), new NSRange(0, mutableAttributedString.Length));

                // Apply Inlines
                foreach (var inline in GetEffectiveInlines())
                {
                    mutableAttributedString.AddAttributes(inline.inline.GetAttributes(), new NSRange(inline.start, inline.end - inline.start));
                }

                mutableAttributedString.EndEditing();
                return(mutableAttributedString);
            }
        }
Example #2
0
        private UIStringAttributes GetAttributes(NSAttributedStringTarget target)
        {
            var attributes = new UIStringAttributes();

            // We only apply these values to NSTextStorage, as they're already applied to UILabel.
            // See: UpdateFont, UpdateTextColor, etc.
            if (target == NSAttributedStringTarget.NSTextStorage)
            {
                attributes.Font            = _currentFont;
                attributes.ForegroundColor = _currentColor;
            }

            if (target == NSAttributedStringTarget.NSTextStorage || LineHeight != 0)
            {
                var paragraphStyle = new NSMutableParagraphStyle()
                {
                    MinimumLineHeight = (nfloat)LineHeight,
                    Alignment         = TextAlignment.ToNativeTextAlignment(),
                    LineBreakMode     = GetLineBreakMode(),
                };

                // For unknown reasons, the LineBreakMode must be set to WordWrap
                // when applied to a NSTextStorage for text to wrap (but not when applied to a UILabel).
                if (target == NSAttributedStringTarget.NSTextStorage)
                {
                    paragraphStyle.LineBreakMode = UILineBreakMode.WordWrap;
                }

                if (LineStackingStrategy != LineStackingStrategy.MaxHeight)
                {
                    paragraphStyle.MaximumLineHeight = (nfloat)LineHeight;
                }
                attributes.ParagraphStyle = paragraphStyle;

                if (Font != null)
                {
                    // iOS puts text at the bottom of the line box, whereas Windows puts it at the top.
                    // Empirically this offset gives similar positioning to Windows.
                    // Note: Descender is typically a negative value.
                    var verticalOffset = LineHeight - Font.LineHeight + Font.Descender;

                    // For unknown reasons, the verticalOffset must be divided by 2
                    // when applied to a UILabel (but not when applied to a NSTextStorage).
                    if (target == NSAttributedStringTarget.UILabel)
                    {
                        verticalOffset /= 2;
                    }

                    // Because we're trying to move the text up (toward the top of the line box),
                    // we only set BaselineOffset to a positive value.
                    // A negative value indicates that the the text is already bottom-aligned.
                    attributes.BaselineOffset = Math.Max(0, (float)verticalOffset);
                }
            }

            if (CharacterSpacing != 0)
            {
                //CharacterSpacing is in 1/1000 of an em, iOS KerningAdjustment is in points. 1 em = 12 points
                attributes.KerningAdjustment = (CharacterSpacing / 1000f) * 12;
            }

            return(attributes);
        }