Example #1
0
        public ISpanned CreateStyledString(TextStyleParameters style, string text, int startIndex = 0, int endIndex = -1)
        {
            if (text.Length == 0)
            {
                return(null);
            }

            if (endIndex == -1)
            {
                endIndex = text.Length;
            }

            if (startIndex >= endIndex)
            {
                throw new Exception("Unable to create styled string, StartIndex is too high: " + startIndex);
            }

            // Parse the text
            text = ParseString(style, text);

            // If we have HMTL
            if (!string.IsNullOrEmpty(text) && Common.MatchHtmlTags.IsMatch(text))
            {
                return(CreateHtmlString(text, style.Name));
            }
            else
            {
                var builder = new SpannableStringBuilder(text);
                var font    = GetFont(style.Font);
                var span    = new CustomTypefaceSpan("", font, style);

                builder.SetSpan(span, startIndex, endIndex, SpanTypes.ExclusiveExclusive);
                return(builder);
            }
        }
Example #2
0
 static void UpdateMargins(TextStyleParameters style, ref UIEdgeInsets inset)
 {
     inset.Top    = (style.PaddingTop > float.MinValue) ? style.PaddingTop : inset.Top;
     inset.Bottom = (style.PaddingBottom > float.MinValue) ? style.PaddingBottom : inset.Bottom;
     inset.Left   = (style.PaddingLeft > float.MinValue) ? style.PaddingLeft : inset.Left;
     inset.Right  = (style.PaddingRight > float.MinValue) ? style.PaddingRight : inset.Right;
 }
Example #3
0
        internal static string ParseString(TextStyleParameters style, string text)
        {
            // Text transformations
            if (!string.IsNullOrEmpty(text))
            {
                if (style.TextTransform != CssTextTransform.None)
                {
                    switch (style.TextTransform)
                    {
                    case CssTextTransform.UpperCase:
                        text = text.ToUpper();
                        break;

                    case CssTextTransform.LowerCase:
                        text = text.ToLower();
                        break;

                    case CssTextTransform.Capitalize:
                        text = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(text.ToLower());
                        break;
                    }
                }
            }

            return(text);
        }
Example #4
0
        /// <summary>
        /// Handles a custom tag
        /// </summary>
        /// <returns>void</returns>
        /// <param name="opening">bool</param>
        /// <param name="tag">string</param>
        /// <param name="output">IEditable</param>
        /// <param name="xmlReader">IXMLReader</param>
        public void HandleTag(bool opening, string tag, IEditable output, Org.Xml.Sax.IXMLReader xmlReader)
        {
            TextStyleParameters style = _styles.ContainsKey(tag) ? _styles [tag] : null;

            // Body overwrites the inline styles so we set that at the textview level
            if (style != null)
            {
                var text = output as SpannableStringBuilder;

                if (opening)
                {
                    Start(text, new TextStylesObject());
                }
                else
                {
                    // Retrieve font
                    Typeface font = null;
                    if (!string.IsNullOrEmpty(style.Font))
                    {
                        _instance._typeFaces.TryGetValue(style.Font, out font);
                    }

                    var customSpan = new CustomTypefaceSpan("", font, style);
                    End(style, text, Class.FromType(typeof(TextStylesObject)), customSpan);
                }
            }
        }
Example #5
0
 /// <summary>
 /// Sets the style.
 /// </summary>
 /// <param name="id">Identifier.</param>
 /// <param name="style">Style.</param>
 /// <param name="refresh">If set to <c>true</c> refresh.</param>
 public virtual void SetStyle(string id, TextStyleParameters style, bool refresh = false)
 {
     _textStyles[id] = style;
     if (refresh)
     {
         Refresh();
     }
 }
Example #6
0
        /// <summary>
        /// Merge the specified style with this instance and optionally ovwerite any conflicting parameters
        /// </summary>
        /// <param name="style">Source.</param>
        /// <param name="overwriteExisting">Overwrite existing.</param>
        public void Merge(TextStyleParameters style, bool overwriteExisting)
        {
            Type t = typeof(TextStyleParameters);

            var properties = t.GetRuntimeProperties().Where(prop => prop.CanRead && prop.CanWrite);

            foreach (var prop in properties)
            {
                var sourceValue = prop.GetValue(style, null);

                if (sourceValue != null)
                {
                    var targetValue = prop.GetValue(this, null);

                    switch (prop.Name)
                    {
                    case "TextAlign":
                        if ((CssAlign)sourceValue != CssAlign.Left)
                        {
                            targetValue = null;
                        }
                        break;

                    case "TextDecoration":
                        if ((CssDecoration)sourceValue != CssDecoration.None)
                        {
                            targetValue = null;
                        }
                        break;

                    case "TextOverflow":
                        if ((CssTextOverflow)sourceValue != CssTextOverflow.None)
                        {
                            targetValue = null;
                        }
                        break;

                    case "TextTransform":
                        if ((CssTextTransform)sourceValue != CssTextTransform.None)
                        {
                            targetValue = null;
                        }
                        break;
                    }

                    if (targetValue != null && !overwriteExisting)
                    {
                        continue;
                    }

                    prop.SetValue(this, sourceValue, null);
                }
            }
        }
Example #7
0
        internal NSAttributedString ParseHtmlString(TextStyleParameters style, string text)
        {
            var attribs = GetStringAttributes(style, DefaultTextSize);

            text = ParseString(style, text);

            var prettyString = new NSMutableAttributedString(text);

            prettyString.AddAttributes(attribs, new NSRange(0, text.Length));
            return(prettyString);
        }
Example #8
0
        public void SetDirty(bool forceUpdate)
        {
            _isDirty         = true;
            _style           = null;
            _attributedValue = null;

            if (forceUpdate)
            {
                UpdateDisplay();
            }
        }
Example #9
0
        /// <summary>
        /// Transforms the text case within the given range.
        /// </summary>
        /// <returns>The text range.</returns>
        /// <param name="text">Text.</param>
        /// <param name="style">Style.</param>
        /// <param name="startIndex">Start index.</param>
        /// <param name="endIndex">End index.</param>
        void TransformTextRange(SpannableStringBuilder text, TextStyleParameters style, int startIndex, int endIndex)

        {
            if (startIndex == endIndex)
            {
                return;
            }

            var transformed = TextStyle.ParseString(style, text.SubSequence(startIndex, endIndex));

            text.Replace(startIndex, endIndex, transformed);
        }
Example #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="T:TextStyles.Android.CustomHtmlParser"/> class.
        /// </summary>
        /// <param name="source">Source.</param>
        /// <param name="textStyles">Text styles.</param>
        /// <param name="defaultStyleID">Default style identifier.</param>
        public CustomHtmlParser(TextStyle instance, string source, Dictionary <string, TextStyleParameters> textStyles, string defaultStyleID = null)
        {
            _instance   = instance;
            _htmlSource = source;
            _styles     = textStyles;

            if (!String.IsNullOrEmpty(defaultStyleID) && _styles.ContainsKey(defaultStyleID))
            {
                _defaultStyle = _styles [defaultStyleID];
            }

            _spannableStringBuilder = new SpannableStringBuilder();
            _reader      = XMLReaderFactory.CreateXMLReader("org.ccil.cowan.tagsoup.Parser");
            _imageGetter = null;
            _tagHandler  = new CustomTagHandler(_instance, _styles);
        }
Example #11
0
        /// <summary>
        /// Creates a styled string as an NSAttibutedString
        /// </summary>
        /// <returns>The styled string.</returns>
        /// <param name="style">TextStyleParameters for styling</param>
        /// <param name="text">Text to style</param>
        /// <param name="startIndex">Style start index</param>
        /// <param name="endIndex">Style end index</param>
        public NSMutableAttributedString CreateStyledString(TextStyleParameters style, string text, int startIndex = 0, int endIndex = -1)
        {
            var attribs = GetStringAttributes(style, DefaultTextSize);

            text = ParseString(style, text);

            if (endIndex == -1)
            {
                endIndex = text.Length;
            }

            var prettyString = new NSMutableAttributedString(text);

            prettyString.SetAttributes(attribs, new NSRange(startIndex, endIndex));

            return(prettyString);
        }
Example #12
0
        /// <summary>
        /// End the specified tag
        /// </summary>
        /// <param name="style">TextStyleParameters</param>
        /// <param name="text">SpannableStringBuilder</param>
        /// <param name="kind">Class</param>
        /// <param name="newSpan">Java.Lang.Object</param>
        static void End(TextStyleParameters style, SpannableStringBuilder text, Class kind, Java.Lang.Object newSpan)
        {
            var length = text.Length();
            var span   = GetLast(text, kind);
            var start  = text.GetSpanStart(span);

            text.RemoveSpan(span);

            // Parse the text in the span
            var parsedString = TextStyle.ParseString(style, text.SubSequence(start, length));               // Note this hardcodes the text this way and only works on parsed tags!

            text.Replace(start, length, parsedString);

            if (start != length)
            {
                text.SetSpan(newSpan, start, length, SpanTypes.InclusiveExclusive);
            }
        }
Example #13
0
        /// <summary>
        /// Merges a css rule.
        /// </summary>
        /// <returns>The rule.</returns>
        /// <param name="curStyle">Target TextStyleParameters</param>
        /// <param name="css">Css value</param>
        /// <param name="clone">If set to <c>true</c> clone the style</param>
        public static TextStyleParameters MergeRule(TextStyleParameters curStyle, string css, bool clone)
        {
            var parser = new CssParser();
            var rules  = parser.ParseAll(css);

            if (rules.Count() != 1)
            {
                throw new NotSupportedException("Only a single css class may be merged at a time");
            }

            var mergedStyle = clone ? curStyle.Clone() : curStyle;

            var rule = rules.FirstOrDefault();

            if (rule != null)
            {
                ParseCSSRule(ref mergedStyle, rule, null);
            }

            return(mergedStyle);
        }
Example #14
0
        public static Dictionary <string, TextStyleParameters> Parse(CssRuleSet ruleSet)
        {
            var textStyles = new Dictionary <string, TextStyleParameters>();

            // Process all the rules
            foreach (var rule in ruleSet.Rules)
            {
                // Process each rule
                foreach (var selector in rule.Selectors)
                {
                    // If it doesnt exist, create it
                    if (!textStyles.ContainsKey(selector))
                    {
                        textStyles[selector] = new TextStyleParameters(selector);
                    }

                    var curStyle = textStyles[selector];
                    ParseCSSRule(ref curStyle, rule, ruleSet.Variables);
                }
            }

            return(textStyles);
        }
        public static bool RequiresHtmlTags(this TextStyleParameters target)
        {
            if (target.TextDecoration != CssDecoration.None)
            {
                return(true);
            }

            if (Math.Abs(target.LetterSpacing) > 0)
            {
                return(true);
            }

            if (target.FontStyle == CssFontStyle.Italic)
            {
                return(true);
            }

            if (target.FontWeight == CssFontWeight.Bold)
            {
                return(true);
            }

            return(false);
        }
Example #16
0
        internal static UIStringAttributes GetStringAttributes(TextStyleParameters style, float defaultTextSize)
        {
            var stringAttribs = new UIStringAttributes();

            var fontSize = style.FontSize;

            if (fontSize <= 0f)
            {
                fontSize = defaultTextSize;
            }

            if (!string.IsNullOrEmpty(style.Font))
            {
                stringAttribs.Font = UIFont.FromName(style.Font, fontSize);
            }

            if (style.Color != ColorRGB.Empty)
            {
                stringAttribs.ForegroundColor = style.Color.ToNative();
            }

            if (style.Color != ColorRGB.Empty)
            {
                stringAttribs.BackgroundColor = style.BackgroundColor.ToNative();
            }

            if (style.LetterSpacing > 0f)
            {
                stringAttribs.KerningAdjustment = style.LetterSpacing;
            }

            // Does nothing on the string attribs, needs to be part of a NSMutableAttributedString
            if (style.LineHeight != 0f)
            {
                var paragraphStyle = new NSMutableParagraphStyle()
                {
                    LineHeightMultiple = style.LineHeight / fontSize,
                    Alignment          = GetAlignment(style.TextAlign)
                };
                stringAttribs.ParagraphStyle = paragraphStyle;
            }

            if (style.TextDecoration != CssDecoration.None)
            {
                switch (style.TextDecoration)
                {
                case CssDecoration.LineThrough:
                    stringAttribs.StrikethroughStyle = NSUnderlineStyle.Single;
                    break;

                case CssDecoration.Underline:
                    stringAttribs.UnderlineStyle = NSUnderlineStyle.Single;
                    break;
                }

                if (!string.IsNullOrEmpty(style.TextDecorationColor))
                {
                    stringAttribs.StrikethroughColor = UIColor.Clear.FromHex(style.TextDecorationColor);
                }
            }


            return(stringAttribs);
        }
Example #17
0
        /// <summary>
        /// Parses to CSS string.
        /// </summary>
        /// <returns>The to CSS string.</returns>
        /// <param name="tagName">Tag name.</param>
        /// <param name="style">Style.</param>
        public static string ParseToCSSString(string tagName, TextStyleParameters style)
        {
            var builder = new StringBuilder();

            builder.Append(tagName + "{");

            string cast;
            var    runtimeProperties = style.GetType().GetRuntimeProperties();

            foreach (var prop in runtimeProperties)
            {
                try
                {
                    var value = prop.GetValue(style);

                    if (value != null)
                    {
                        string parsedValue = null;
                        switch (prop.PropertyType.Name)
                        {
                        case "String":
                            if ((value as string).StartsWith("#"))
                            {
                                parsedValue = (string)value;
                            }
                            else
                            {
                                parsedValue = "'" + value + "'";
                            }
                            break;

                        case "Single":
                            if (Convert.ToSingle(value) > float.MinValue)
                            {
                                parsedValue = Convert.ToString(value);
                                if (prop.Name == "FontSize")     // Dirty, I really need a list of things that can be set in pixel values
                                {
                                    parsedValue += "px";
                                }
                            }
                            break;

                        case "Int32":
                            if (Convert.ToInt32(value) > int.MinValue)
                            {
                                parsedValue = Convert.ToString(value);
                            }
                            break;

                        case "Single[]":
                            parsedValue = Convert.ToString(value);
                            break;

                        case "CssAlign":
                        case "CssDecoration":
                        case "CssTextTransform":
                        case "CssTextOverflow":
                            cast = Convert.ToString(value);
                            if (cast != "None")
                            {
                                parsedValue = cast.ToLower();
                            }
                            break;

                        case "CssFontStyle":
                        case "CssFontWeight":
                            cast = Convert.ToString(value);
                            if (cast != "Normal")
                            {
                                parsedValue = cast.ToLower();
                            }
                            break;

                        case "ColorRGB":
                            var colorRGB = (ColorRGB)value;
                            cast = colorRGB.ToString();
                            break;

                        default:
                            throw new InvalidCastException("Could not find the appropriate type " + prop.PropertyType.Name);
                        }

                        var attributes = (CssAttribute[])prop.GetCustomAttributes(
                            typeof(CssAttribute), false);

                        if (attributes.Length > 0 && parsedValue != null)
                        {
                            builder.Append(attributes[0].Name + ":" + parsedValue + ";");
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }

            builder.Append("}");

            return(builder.ToString());
        }
Example #18
0
        // TODO implement this function for styling plain text views, for html based views perhaps not
        internal void StyleTextView(TextView target, TextStyleParameters style, bool isPlainText, bool ignoreHtml = false)
        {
            var fontSize = (style.FontSize <= 0f) ? DefaultTextSize : style.FontSize;

            target.SetTextSize(ComplexUnitType.Sp, fontSize);

            // Plain text fonts and colors
            if (isPlainText)
            {
                if (style.Color != ColorRGB.Empty)
                {
                    target.SetTextColor(style.Color.ToNative());
                }

                if (!String.IsNullOrEmpty(style.Font) && _typeFaces.ContainsKey(style.Font))
                {
                    target.Typeface   = _typeFaces[style.Font];
                    target.PaintFlags = target.PaintFlags | PaintFlags.SubpixelText;
                }
            }

            // Lines
            if (style.Lines > 0)
            {
                target.SetLines(style.Lines);
            }

            if (style.BackgroundColor != ColorRGB.Empty)
            {
                target.SetBackgroundColor(style.BackgroundColor.ToNative());
            }

            // Does nothing on the string attribs, needs to be part of a NSMutableAttributedString
            if (Math.Abs(style.LineHeight) > 0)
            {
                target.SetLineSpacing(0, style.LineHeight / fontSize);
            }

            // Assing the text gravity
            target.TextAlignment = TextAlignment.Gravity;
            switch (style.TextAlign)
            {
            case CssAlign.Center:
                target.Gravity = GravityFlags.CenterHorizontal;
                break;

            case CssAlign.Justified:
                target.Gravity = GravityFlags.FillHorizontal;
                break;

            case CssAlign.Right:
                target.Gravity = GravityFlags.Right;
                break;

            default:
                target.Gravity = GravityFlags.Left;
                break;
            }

            // Padding
            target.SetPadding(
                (style.PaddingLeft > float.MinValue) ? (int)style.PaddingLeft : target.PaddingLeft,
                (style.PaddingTop > float.MinValue) ? (int)style.PaddingTop : target.PaddingTop,
                (style.PaddingRight > float.MinValue) ? (int)style.PaddingRight : target.PaddingRight,
                (style.PaddingBottom > float.MinValue) ? (int)style.PaddingBottom : target.PaddingBottom
                );

            // Overflow
            // TODO implement this fully
            switch (style.TextOverflow)
            {
            case CssTextOverflow.Ellipsis:
                target.Ellipsize = TextUtils.TruncateAt.End;
                break;

            default:
                break;
            }
        }
Example #19
0
 public CustomTypefaceSpan(String family, Typeface typeface, TextStyleParameters style) : base(family)
 {
     _typeface = typeface;
     _style    = style;
 }
Example #20
0
        /// <summary>
        /// Parses the CSS rule.
        /// </summary>
        /// <param name="curStyle">Current style.</param>
        /// <param name="rule">Rule.</param>
        internal static void ParseCSSRule(ref TextStyleParameters curStyle, CssParserRule rule, Dictionary <string, string> cssVariables)
        {
            foreach (var declaration in rule.Declarations)
            {
                if (_textStyleProperties.ContainsKey(declaration.Property))
                {
                    // Assign the variable if it exists
                    if (cssVariables != null && declaration.ReferencesVariable)
                    {
                        declaration.Value = cssVariables[declaration.Value];
                    }

                    var cleanedValue = declaration.Value.Replace("\"", "");
                    cleanedValue = cleanedValue.Trim();

                    var prop = _textStyleProperties[declaration.Property];
                    switch (prop.PropertyType.Name)
                    {
                    case "String":
                        curStyle.SetValue(prop.Name, cleanedValue);
                        break;

                    case "Int32":
                        int numInt;
                        if (int.TryParse(cleanedValue, out numInt))
                        {
                            curStyle.SetValue(prop.Name, numInt);
                        }
                        break;

                    case "Single":
                        cleanedValue = cleanedValue.Replace("px", "");
                        float numFloat;
                        if (float.TryParse(cleanedValue, out numFloat))
                        {
                            curStyle.SetValue(prop.Name, numFloat);
                        }
                        else
                        {
                            throw new Exception("Failed to Parse Single value " + cleanedValue);
                        }
                        break;

                    case "Single[]":
                        var parts        = cleanedValue.Split(new char[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
                        var parsedValues = new float[parts.Length];
                        for (int i = 0; i < parts.Length; i++)
                        {
                            float numArrayFloat;
                            if (float.TryParse(parts[i], out numArrayFloat))
                            {
                                parsedValues[i] = numArrayFloat;
                            }
                        }
                        curStyle.SetValue(prop.Name, parsedValues);
                        break;

                    case "ColorRGB":
                        curStyle.SetValue(prop.Name, ColorRGB.FromHex(cleanedValue));
                        break;

                    case "CssAlign":
                        curStyle.TextAlign = EnumUtils.FromDescription <CssAlign>(cleanedValue);
                        break;

                    case "CssDecoration":
                        curStyle.TextDecoration = EnumUtils.FromDescription <CssDecoration>(cleanedValue);
                        break;

                    case "CssTextTransform":
                        curStyle.TextTransform = EnumUtils.FromDescription <CssTextTransform>(cleanedValue);
                        break;

                    case "CssTextOverflow":
                        curStyle.TextOverflow = EnumUtils.FromDescription <CssTextOverflow>(cleanedValue);
                        break;

                    case "CssFontStyle":
                        curStyle.FontStyle = EnumUtils.FromDescription <CssFontStyle>(cleanedValue);
                        break;

                    case "CssFontWeight":
                        curStyle.FontWeight = EnumUtils.FromDescription <CssFontWeight>(cleanedValue);
                        break;

                    default:
                        throw new InvalidCastException("Could not find the appropriate type " + prop.PropertyType.Name);
                    }
                }
            }
        }