Пример #1
0
        public static CssValue Font_Size_Used(ICssProperty Property)
        {/* Docs: https://www.w3.org/TR/css-fonts-3/#font-size-prop */
            if (Property == null)
            {
                throw new ArgumentNullException(nameof(Property));
            }
            Contract.EndContractBlock();

            double?v = (Property as CssProperty).Computed.Resolve();

            if (!v.HasValue)
            {
                throw new CssException($"Unable to resolve absolute length for Used \"{Property.CssName}\" value.");
            }
            Contract.EndContractBlock();

            double Size = v.Value;

            if (Size < 9.0)// The specifications say we shouldnt render a font less than 9px in size
            {
                Size = 9.0;
            }

            // Round the size up to the nearest whole pixel value
            Size = Math.Round(Size, MidpointRounding.AwayFromZero);

            return(CssValue.From(Size));
        }
Пример #2
0
        /// <summary>
        /// Properties that are defined in the CSS fonts module
        /// </summary>
        static IEnumerable <StyleDefinition> Create_Font_Property_Definitions()
        {
            return(new StyleDefinition[] {
                // SEE: https://www.w3.org/TR/CSS2/visudet.html#propdef-line-height
                new StyleDefinition(ECssPropertyID.LineHeight, true, EPropertyDirtFlags.Flow, CssValue.From(1.0), Percentage_Resolver: (Prop, Pct) => CssValue.From(Pct * Prop.Owner.Style.FontSize)),

                new StyleDefinition(ECssPropertyID.FontFamily, true, EPropertyDirtFlags.Text | EPropertyDirtFlags.Flow, CssValue.From(EGenericFontFamily.SansSerif), ECssValueTypes.STRING | ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EGenericFontFamily>(), Resolvers: new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Font_Family_Used)
                                    ),


                new StyleDefinition(ECssPropertyID.FontWeight, true, EPropertyDirtFlags.Text | EPropertyDirtFlags.Flow, CssValue.From(EFontWeight.Normal), ECssValueTypes.KEYWORD | ECssValueTypes.INTEGER, Lookup.Get_Keywords <EFontWeight>(), Resolvers: new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Computed, CssPropertyResolver.Font_Weight_Computed)
                                    ),


                new StyleDefinition(ECssPropertyID.FontStyle, true, EPropertyDirtFlags.Text | EPropertyDirtFlags.Flow, CssValue.From(EFontStyle.Normal), ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EFontStyle>()),
                //new StyleDefinition(ECssProperty.FontSize, true, EPropertyDirtFlags.Text | EPropertyDirtFlags.Flow, CssValue.From(12),
                new StyleDefinition(ECssPropertyID.FontSize, true, EPropertyDirtFlags.Text | EPropertyDirtFlags.Flow, CssValue.From(EFontSize.Medium), ECssValueTypes.DIMENSION | ECssValueTypes.PERCENT | ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EFontSize>(), false, Percentage_Resolver: (Prop, Pct) => {
                    if (!Prop.Owner.isRoot)
                    {
                        return CssValue.From(Pct * Prop.Owner.Style.FontSize);
                    }
                    else
                    {    // fallback to definition
                        var def = StyleDefinitions[ECssPropertyID.FontSize];
                        //double r = def.Initial.Resolve() ?? throw new Exception("Failed to resolve default value from 'fontSize' definition");
                        var r = def.Initial.AsDecimal();
                        return CssValue.From(Pct * r);
                    }
                },
                                    new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Computed, CssPropertyResolver.Font_Size_Computed),
                                    new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Font_Size_Used)
                                    ),
            });
        }
Пример #3
0
 public static CssValue Containing_Block_Logical_Height(ICssProperty Property, double Percent)
 {
     if (!Property.Owner.Box.Containing_Box_Explicit_Height)
     {
         return(CssValue.Zero);
     }
     else
     {
         var resolved = Percent * CssCommon.Get_Logical_Height(Property.Owner.Style.WritingMode, Property.Owner.Box.Containing_Box);
         return(CssValue.From(resolved, ECssUnit.PX));
     }
 }
Пример #4
0
        public static CssValue Max_Height_Used(ICssProperty Property)
        {// Docs: https://www.w3.org/TR/css-sizing-3/#min-size-properties
            if (Property == null)
            {
                throw new ArgumentNullException(nameof(Property));
            }
            Contract.EndContractBlock();

            var      prop  = (Property as CssProperty);
            CssValue Value = prop.Computed;

            if (Value.Type == ECssValueTypes.KEYWORD)
            {
                var keyword = Value.AsEnum <EBoxSize>();
                switch (keyword)
                {
                case EBoxSize.Min_Content:
                {
                    if (prop.Owner.Style.WritingMode != EWritingMode.Horizontal_TB)
                    {
                        return(prop.Definition.Initial);
                    }

                    return(CssValue.From(prop.Owner.Box.Min_Content.Height));
                }

                case EBoxSize.Max_Content:
                {
                    if (prop.Owner.Style.WritingMode != EWritingMode.Horizontal_TB)
                    {
                        return(prop.Definition.Initial);
                    }

                    return(CssValue.From(prop.Owner.Box.Max_Content.Height));
                }

                case EBoxSize.Fit_Content:
                {        // XXX: Implement this!
                    throw new NotImplementedException();
                }

                default:
                    throw new NotImplementedException($"Keyword '{keyword}' is not implemented!");
                }
            }

            return(Value);
        }
Пример #5
0
        public static CssValue Position_Used(ICssProperty Property)
        {
            if (Property == null)
            {
                throw new ArgumentNullException(nameof(Property));
            }
            Contract.EndContractBlock();

            var      prop  = (Property as CssProperty);
            CssValue Value = prop.Computed;

            if (!Value.IsDefinite)
            {
                return(CssValue.From(0));
            }
            return(Value);
        }
Пример #6
0
        public static CssValue Color_Computed(ICssProperty Property)
        {
            if (Property == null)
            {
                throw new ArgumentNullException(nameof(Property));
            }
            Contract.EndContractBlock();

            var      prop  = (Property as CssProperty);
            CssValue Value = prop.Computed;

            if (Value.Type == ECssValueTypes.KEYWORD)
            {
                var keyword = Value.AsEnum <EColor>();
                switch (keyword)
                {
                case EColor.CurrentColor:
                {        /* This gets translated in the "Used" stage */
                    return(Value);
                }

                case EColor.Transparent:
                {        /* The computed value of the keyword ‘transparent’ is the quadruplet of all zero numerical RGBA values, e.g. rgba(0,0,0,0). */
                    return(new CssValue(ECssValueTypes.COLOR, 0x0));
                }

                default:
                {
                    if (!Lookup.TryData(keyword, out EnumData outData))
                    {
                        throw new CssPropertyException($"No meta-enum data found for keyword '{keyword}'");
                    }

                    return(CssValue.From(new Color((int)outData.Data[1], (int)outData.Data[2], (int)outData.Data[3], (int)outData.Data[4])));
                }
                }
            }

            return(Value);
        }
Пример #7
0
        // private bool IsNegated = false;
        #endregion

        #region Constructors
        /// <summary>
        /// Creates a new 'boolean' type media feature
        /// </summary>
        /// <param name="name"></param>
        public MediaFeature(EMediaFeatureName Name)
        {
            Context = EMediaFeatureContext.Boolean;

            MediaDefinition def = MediaDefinition.Lookup(Name);

            if (def != null)
            {
                IsValid = true;
                /* if an allowed type is keywords and 'none' is an option then we match it against that keyword */
                if (0 != (def.AllowedTypes & ECssValueTypes.KEYWORD) && def.KeywordWhitelist.Contains("none"))
                {
                    Values = new CssValue[] { CssValue.From(Name), CssValue.None };
                }
                else if (0 != (def.AllowedTypes & ECssValueTypes.INTEGER))
                {
                    Values = new CssValue[] { CssValue.From(Name), CssValue.From(0) };
                }
                else if (0 != (def.AllowedTypes & ECssValueTypes.DIMENSION))
                {
                    Values = new CssValue[] { CssValue.From(Name), CssValue.From(0, ECssUnit.PX) };
                }
                else if (0 != (def.AllowedTypes & ECssValueTypes.RESOLUTION))
                {
                    Values = new CssValue[] { CssValue.From(Name), CssValue.From(0, ECssUnit.DPPX) };
                }
            }
            else
            {
                /* This isnt a supported feature, therefore it should always evaluate to false */
                IsValid = false;
            }

            /* For sanity just catch the case where we dont have values to compare here */
            if (Values.Length <= 0)
            {
                IsValid = false;
            }
        }
Пример #8
0
        public static CssValue Opacity_Computed(ICssProperty Property)
        {/* Docs: https://www.w3.org/TR/css-color-3/#opacity */
            if (Property == null)
            {
                throw new ArgumentNullException(nameof(Property));
            }
            Contract.EndContractBlock();

            var      prop  = (Property as CssProperty);
            CssValue Value = prop.Computed;

            double n = Value.AsDecimal();

            if (n < 0d)
            {
                return(CssValue.From(0d));
            }
            else if (n > 1d)
            {
                return(CssValue.From(1d));
            }

            return(Value);
        }
Пример #9
0
        static IMediaCondition Consume_Media_Feature(DataConsumer <CssToken> Stream)
        {/* Docs: https://drafts.csswg.org/mediaqueries-4/#mq-syntax */
            if (Stream is null)
            {
                throw new CssParserException(CssErrors.STREAM_IS_NULL);
            }


            /* Consume feature name */
            if (ParserCommon.Starts_Boolean_Feature(Stream.AsSpan()))
            {
                /* Consume feature name */
                IdentToken nameTok = Stream.Consume() as IdentToken;

                /* Resolve the name */
                if (!Lookup.TryEnum(nameTok.Value, out EMediaFeatureName Name))
                {
                    throw new CssParserException(String.Format(CultureInfo.InvariantCulture, CssErrors.INVALID_MEDIA_TYPE, nameTok.Value), Stream);
                }

                return(new MediaFeature(Name));
            }
            else if (ParserCommon.Starts_Discreet_Feature(Stream.AsSpan()))
            {
                /* Consume feature name */
                IdentToken nameTok = Stream.Consume() as IdentToken;

                /* Resolve the name */
                if (!Lookup.TryEnum(nameTok.Value, out EMediaFeatureName Name))
                {
                    throw new CssParserException(String.Format(CultureInfo.InvariantCulture, CssErrors.INVALID_MEDIA_TYPE, nameTok.Value), Stream);
                }

                /* Consume the value to match */
                Consume_All_Whitespace(Stream);
                var value = Consume_MediaFeature_Value(Stream);

                return(new MediaFeature(new CssValue[] { CssValue.From(Name), value }, new EMediaOperator[] { EMediaOperator.EqualTo }));
            }
            else if (ParserCommon.Starts_Range_Feature(Stream.AsSpan()))
            {
                /* This is a range feature of some sort, it could be a short one or a long one */
                /* Repeatedly consume CssValues, operator, and a single ident */
                LinkedList <CssValue>       Values = new LinkedList <CssValue>();
                LinkedList <EMediaOperator> Ops    = new LinkedList <EMediaOperator>();
                bool firstToken        = true;
                bool lastWasComparator = false;

                while (Stream.Next != CssToken.EOF)
                {
                    Consume_All_Whitespace(Stream);

                    if (Stream.Next.Type == ECssTokenType.Parenth_Close)
                    {
                        break;
                    }
                    else if (Stream.Next.Type == ECssTokenType.Ident)
                    {
                        if (!firstToken && !lastWasComparator)
                        {
                            throw new CssSyntaxErrorException(CssErrors.EXPECTING_COMPARATOR, Stream);
                        }

                        var nameTok = (IdentToken)Stream.Consume();
                        /* Resolve the name */
                        if (!Lookup.TryEnum(nameTok.Value, out EMediaFeatureName Name))
                        {
                            throw new CssParserException(String.Format(CultureInfo.InvariantCulture, CssErrors.INVALID_MEDIA_TYPE, nameTok.Value), Stream);
                        }

                        var value = CssValue.From(Name);
                        Values.AddLast(value);
                        lastWasComparator = false;
                    }
                    else if (ParserCommon.Starts_MF_Ident_Or_Value(Stream.AsSpan()))
                    {
                        if (!firstToken && !lastWasComparator)
                        {
                            throw new CssSyntaxErrorException(CssErrors.EXPECTING_COMPARATOR, Stream);
                        }

                        CssValue value = Consume_MediaFeature_Value(Stream);
                        Values.AddLast(value);
                        lastWasComparator = false;
                    }
                    else if (ParserCommon.Is_Comparator(Stream.Next))
                    {
                        if (lastWasComparator || firstToken)
                        {
                            throw new CssSyntaxErrorException(CssErrors.UNEXPECTED_TOKEN, Stream);
                        }

                        var comparatorTok = (ValuedTokenBase)Stream.Consume();
                        if (!Lookup.TryEnum(comparatorTok.Value, out EMediaOperator outComparator))
                        {
                            throw new CssParserException(CssErrors.EXPECTING_COMPARATOR, Stream);
                        }

                        Ops.AddLast(outComparator);
                        lastWasComparator = true;
                    }

                    firstToken = false;
                }

                return(new MediaFeature(Values.ToArray(), Ops.ToArray()));
            }

            return(null);
        }
Пример #10
0
        public static CssValue Min_Width_Used(ICssProperty Property)
        {// Docs: https://www.w3.org/TR/css-sizing-3/#min-size-properties
            if (Property == null)
            {
                throw new ArgumentNullException(nameof(Property));
            }
            Contract.EndContractBlock();

            var      prop  = (Property as CssProperty);
            CssValue Value = prop.Computed;

            if (Value.Type == ECssValueTypes.KEYWORD)
            {
                var keyword = Value.AsEnum <EBoxSize>();
                switch (keyword)
                {
                case EBoxSize.Min_Content:
                {
                    if (prop.Owner.Style.WritingMode != EWritingMode.Horizontal_TB)
                    {
                        return(prop.Definition.Initial);
                    }

                    return(CssValue.From(prop.Owner.Box.Min_Content.Width));
                }

                case EBoxSize.Max_Content:
                {
                    if (prop.Owner.Style.WritingMode != EWritingMode.Horizontal_TB)
                    {
                        return(prop.Definition.Initial);
                    }

                    return(CssValue.From(prop.Owner.Box.Max_Content.Width));
                }

                case EBoxSize.Fit_Content:
                {        // XXX: Implement this!
                    throw new NotImplementedException();
                }

                default:
                    throw new NotImplementedException($"Keyword '{keyword}' is not implemented!");
                }
            }
            else if (Value.Type == ECssValueTypes.AUTO)
            {
                /*
                 * For min-width/min-height, specifies an automatic minimum size.
                 * Unless otherwise defined by the relevant layout module, however, it resolves to a used value of 0.
                 * For backwards-compatibility, the resolved value of this keyword is zero for boxes of all [CSS2] display types: block and inline boxes, inline blocks, and all the table layout boxes.
                 * It also resolves to zero when no box is generated.
                 */

                switch (prop.Owner.Box.DisplayGroup)
                {
                case EBoxDisplayGroup.BLOCK:
                case EBoxDisplayGroup.INLINE:
                case EBoxDisplayGroup.INLINE_BLOCK:
                default:
                {
                    return(CssValue.Zero);
                }
                }
            }

            return(Value);
        }
Пример #11
0
        /// <summary>
        /// Properties that directly determine the size or position of an elements box
        /// </summary>
        static IEnumerable <StyleDefinition> Create_Block_Property_Definitions()
        {
            return(new StyleDefinition[] {
                new StyleDefinition(ECssPropertyID.Display, false, EPropertyDirtFlags.Box, CssValue.From(EDisplayMode.INLINE_BLOCK), ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EDisplayMode>()),
                new StyleDefinition(ECssPropertyID.BoxSizing, false, EPropertyDirtFlags.Content_Area | EPropertyDirtFlags.Border_Area, CssValue.From(EBoxSizingMode.BorderBox), ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EBoxSizingMode>()),

                new StyleDefinition(ECssPropertyID.Positioning, false, EPropertyDirtFlags.Margin_Area, CssValue.From(EBoxPositioning.Relative), ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EBoxPositioning>()),

                new StyleDefinition(ECssPropertyID.ObjectPosition, false, EPropertyDirtFlags.Replaced_Area, CssValue.From(CssValue.Percent_50, CssValue.Percent_50), ECssValueTypes.COLLECTION | ECssValueTypes.KEYWORD | ECssValueTypes.INTEGER | ECssValueTypes.NUMBER | ECssValueTypes.PERCENT, Lookup.Get_Keywords <EPosition>(), false, Percentage_Resolver: (Prop, Pct) => CssValue.From(CssAlgorithms.Solve_Object_Axis_Position((float)Pct, Prop.Owner.Style.Box.Content.Width, Prop.Owner.Style.Box.Get_Replaced_Block_Size().Width)), new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Computed, CssPropertyResolver.Position_Computed), new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Position_Used)),
                // new StyleDefinition(ECssPropertyID.ObjectPositionX, false, EPropertyDirtFlags.Replaced_Area, CssValue.From_Percent(50.0), ECssValueTypes.POSITION, Percentage_Resolver: (Prop, Pct) => CssValue.From(CssAlgorithms.Solve_Object_Axis_Position((float)Pct, Prop.Owner.Style.Box.Content.Width, Prop.Owner.Style.Box.Get_Replaced_Block_Size().Width))),
                // new StyleDefinition(ECssPropertyID.ObjectPositionY, false, EPropertyDirtFlags.Replaced_Area, CssValue.From_Percent(50.0), ECssValueTypes.POSITION, Percentage_Resolver: (Prop, Pct) => CssValue.From(CssAlgorithms.Solve_Object_Axis_Position((float)Pct, Prop.Owner.Style.Box.Content.Height, Prop.Owner.Style.Box.Get_Replaced_Block_Size().Height))),

                new StyleDefinition(ECssPropertyID.Top, false, EPropertyDirtFlags.Margin_Area, CssValue.Auto, ECssValueTypes.AUTO | ECssValueTypes.DIMENSION | ECssValueTypes.PERCENT, null, false, CssPercentageResolvers.Containing_Block_Logical_Height, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Definite_Or_Zero_Used)),
                new StyleDefinition(ECssPropertyID.Right, false, EPropertyDirtFlags.Margin_Area, CssValue.Auto, ECssValueTypes.AUTO | ECssValueTypes.DIMENSION | ECssValueTypes.PERCENT, null, false, CssPercentageResolvers.Containing_Block_Logical_Width, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Definite_Or_Zero_Used)),
                new StyleDefinition(ECssPropertyID.Bottom, false, EPropertyDirtFlags.Margin_Area, CssValue.Auto, ECssValueTypes.AUTO | ECssValueTypes.DIMENSION | ECssValueTypes.PERCENT, null, false, CssPercentageResolvers.Containing_Block_Logical_Height, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Definite_Or_Zero_Used)),
                new StyleDefinition(ECssPropertyID.Left, false, EPropertyDirtFlags.Margin_Area, CssValue.Auto, ECssValueTypes.AUTO | ECssValueTypes.DIMENSION | ECssValueTypes.PERCENT, null, false, CssPercentageResolvers.Containing_Block_Logical_Width, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Definite_Or_Zero_Used)),


                new StyleDefinition(ECssPropertyID.Width, false, EPropertyDirtFlags.Content_Area, CssValue.Auto, ECssValueTypes.DIMENSION | ECssValueTypes.PERCENT | ECssValueTypes.AUTO | ECssValueTypes.INHERIT, null, false, CssPercentageResolvers.Containing_Block_Logical_Width),
                new StyleDefinition(ECssPropertyID.Height, false, EPropertyDirtFlags.Content_Area, CssValue.Auto, ECssValueTypes.DIMENSION | ECssValueTypes.PERCENT | ECssValueTypes.AUTO | ECssValueTypes.INHERIT, null, false, CssPercentageResolvers.Containing_Block_Logical_Height),


                new StyleDefinition(ECssPropertyID.MinWidth, false, EPropertyDirtFlags.Content_Area, CssValue.Auto, ECssValueTypes.DIMENSION | ECssValueTypes.PERCENT | ECssValueTypes.AUTO, Lookup.Get_Keywords <EBoxSize>(), false, CssPercentageResolvers.Containing_Block_Logical_Width, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Min_Width_Used)),
                new StyleDefinition(ECssPropertyID.MinHeight, false, EPropertyDirtFlags.Content_Area, CssValue.Auto, ECssValueTypes.DIMENSION | ECssValueTypes.PERCENT | ECssValueTypes.AUTO, Lookup.Get_Keywords <EBoxSize>(), false, CssPercentageResolvers.Containing_Block_Logical_Height, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Min_Height_Used)),

                new StyleDefinition(ECssPropertyID.MaxWidth, false, EPropertyDirtFlags.Content_Area, CssValue.None, ECssValueTypes.DIMENSION | ECssValueTypes.PERCENT | ECssValueTypes.NONE, Lookup.Get_Keywords <EBoxSize>(), false, CssPercentageResolvers.Containing_Block_Logical_Width, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Max_Width_Used)),
                new StyleDefinition(ECssPropertyID.MaxHeight, false, EPropertyDirtFlags.Content_Area, CssValue.None, ECssValueTypes.DIMENSION | ECssValueTypes.PERCENT | ECssValueTypes.NONE, Lookup.Get_Keywords <EBoxSize>(), false, CssPercentageResolvers.Containing_Block_Logical_Height, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Max_Height_Used)),


                // Padding percentages are all calculated against the containing block's width so it is possible to create elements which conform to an aspect ratio
                new StyleDefinition(ECssPropertyID.PaddingTop, false, EPropertyDirtFlags.Padding_Area, CssValue.Zero, AllowedTypes: ECssValueTypes.PERCENT | ECssValueTypes.DIMENSION, Percentage_Resolver: CssPercentageResolvers.Containing_Block_Logical_Width),
                new StyleDefinition(ECssPropertyID.PaddingRight, false, EPropertyDirtFlags.Padding_Area, CssValue.Zero, AllowedTypes: ECssValueTypes.PERCENT | ECssValueTypes.DIMENSION, Percentage_Resolver: CssPercentageResolvers.Containing_Block_Logical_Width),
                new StyleDefinition(ECssPropertyID.PaddingBottom, false, EPropertyDirtFlags.Padding_Area, CssValue.Zero, AllowedTypes: ECssValueTypes.PERCENT | ECssValueTypes.DIMENSION, Percentage_Resolver: CssPercentageResolvers.Containing_Block_Logical_Width),
                new StyleDefinition(ECssPropertyID.PaddingLeft, false, EPropertyDirtFlags.Padding_Area, CssValue.Zero, AllowedTypes: ECssValueTypes.PERCENT | ECssValueTypes.DIMENSION, Percentage_Resolver: CssPercentageResolvers.Containing_Block_Logical_Width),

                new StyleDefinition(ECssPropertyID.BorderTopWidth, false, EPropertyDirtFlags.Border_Area, CssValue.From(EBorderSize.Medium), ECssValueTypes.DIMENSION | ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EBorderSize>(), false, null, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Border_Width_Used)),
                new StyleDefinition(ECssPropertyID.BorderRightWidth, false, EPropertyDirtFlags.Border_Area, CssValue.From(EBorderSize.Medium), ECssValueTypes.DIMENSION | ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EBorderSize>(), false, null, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Border_Width_Used)),
                new StyleDefinition(ECssPropertyID.BorderBottomWidth, false, EPropertyDirtFlags.Border_Area, CssValue.From(EBorderSize.Medium), ECssValueTypes.DIMENSION | ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EBorderSize>(), false, null, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Border_Width_Used)),
                new StyleDefinition(ECssPropertyID.BorderLeftWidth, false, EPropertyDirtFlags.Border_Area, CssValue.From(EBorderSize.Medium), ECssValueTypes.DIMENSION | ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EBorderSize>(), false, null, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Border_Width_Used)),

                // Margin percentages are all calculated against the containing block's width so it is possible to create elements which conform to an aspect ratio
                new StyleDefinition(ECssPropertyID.MarginTop, false, EPropertyDirtFlags.Margin_Area, CssValue.Zero, AllowedTypes: ECssValueTypes.AUTO | ECssValueTypes.PERCENT | ECssValueTypes.DIMENSION, Keywords: null, IsPrivate: false, Percentage_Resolver: CssPercentageResolvers.Containing_Block_Logical_Width),
                new StyleDefinition(ECssPropertyID.MarginRight, false, EPropertyDirtFlags.Margin_Area, CssValue.Zero, AllowedTypes: ECssValueTypes.AUTO | ECssValueTypes.PERCENT | ECssValueTypes.DIMENSION, Keywords: null, IsPrivate: false, Percentage_Resolver: CssPercentageResolvers.Containing_Block_Logical_Width),
                new StyleDefinition(ECssPropertyID.MarginBottom, false, EPropertyDirtFlags.Margin_Area, CssValue.Zero, AllowedTypes: ECssValueTypes.AUTO | ECssValueTypes.PERCENT | ECssValueTypes.DIMENSION, Keywords: null, IsPrivate: false, Percentage_Resolver: CssPercentageResolvers.Containing_Block_Logical_Width),
                new StyleDefinition(ECssPropertyID.MarginLeft, false, EPropertyDirtFlags.Margin_Area, CssValue.Zero, AllowedTypes: ECssValueTypes.AUTO | ECssValueTypes.PERCENT | ECssValueTypes.DIMENSION, Keywords: null, IsPrivate: false, Percentage_Resolver: CssPercentageResolvers.Containing_Block_Logical_Width)
            });
        }
Пример #12
0
 /// <summary>
 /// Properties that affect the sizing of sub elements
 /// </summary>
 static IEnumerable <StyleDefinition> Create_Sizing_Property_Definitions()
 {
     return(new StyleDefinition[] {
         // The ‘object-fit’ property specifies how the contents of a replaced element should be fitted to the box established by its used height and width.
         new StyleDefinition(ECssPropertyID.ObjectFit, false, EPropertyDirtFlags.Replaced_Area, CssValue.From(EObjectFit.Fill), ECssValueTypes.KEYWORD)
     });
 }
Пример #13
0
 /// <summary>
 /// Properties that affect the way elements position their sub elements
 /// </summary>
 static IEnumerable <StyleDefinition> Create_Layout_Property_Definitions()
 {
     return(new StyleDefinition[] {
         new StyleDefinition(ECssPropertyID.Direction, true, EPropertyDirtFlags.Flow, CssValue.From(EDirection.LTR), ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EDirection>()),
         new StyleDefinition(ECssPropertyID.WritingMode, true, EPropertyDirtFlags.Flow, CssValue.From(EWritingMode.Horizontal_TB), 0x0, Lookup.Get_Keywords <EWritingMode>()),
         new StyleDefinition(ECssPropertyID.TextAlign, true, EPropertyDirtFlags.Flow, CssValue.From(ETextAlign.Start), ECssValueTypes.KEYWORD, Lookup.Get_Keywords <ETextAlign>())
     });
 }
Пример #14
0
        /// <summary>
        /// Properties that affect the way something is rendered
        /// </summary>
        static IEnumerable <StyleDefinition> Create_Rendering_Property_Definitions()
        {
            return(new StyleDefinition[] {
                new StyleDefinition(ECssPropertyID.ScrollBehavior, false, EPropertyDirtFlags.Visual, CssValue.From(EScrollBehavior.Auto), ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EScrollBehavior>()),
                new StyleDefinition(ECssPropertyID.OverflowX, false, EPropertyDirtFlags.Visual, CssValue.From(EOverflowMode.Visible), ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EOverflowMode>()),
                new StyleDefinition(ECssPropertyID.OverflowY, false, EPropertyDirtFlags.Visual, CssValue.From(EOverflowMode.Visible), ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EOverflowMode>()),

                new StyleDefinition(ECssPropertyID.Color, true, EPropertyDirtFlags.Visual, CssValue.From(EColor.Black), ECssValueTypes.KEYWORD | ECssValueTypes.COLOR | ECssValueTypes.INHERIT, Lookup.Get_Keywords <EColor>(), false, null, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Specified, CssPropertyResolver.Color_Specified), new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Computed, CssPropertyResolver.Color_Computed), new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Color_Used)),
                new StyleDefinition(ECssPropertyID.Opacity, false, EPropertyDirtFlags.Visual, CssValue.From(1.0), ECssValueTypes.NUMBER | ECssValueTypes.INTEGER, null, false, null, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Computed, CssPropertyResolver.Opacity_Computed)),

                new StyleDefinition(ECssPropertyID.BorderTopColor, false, EPropertyDirtFlags.Visual, CssValue.From(EColor.CurrentColor), ECssValueTypes.KEYWORD | ECssValueTypes.COLOR | ECssValueTypes.INHERIT, Lookup.Get_Keywords <EColor>(), false, null, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Specified, CssPropertyResolver.Color_Specified), new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Computed, CssPropertyResolver.Color_Computed), new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Color_Used)),
                new StyleDefinition(ECssPropertyID.BorderRightColor, false, EPropertyDirtFlags.Visual, CssValue.From(EColor.CurrentColor), ECssValueTypes.KEYWORD | ECssValueTypes.COLOR | ECssValueTypes.INHERIT, Lookup.Get_Keywords <EColor>(), false, null, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Specified, CssPropertyResolver.Color_Specified), new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Computed, CssPropertyResolver.Color_Computed), new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Color_Used)),
                new StyleDefinition(ECssPropertyID.BorderBottomColor, false, EPropertyDirtFlags.Visual, CssValue.From(EColor.CurrentColor), ECssValueTypes.KEYWORD | ECssValueTypes.COLOR | ECssValueTypes.INHERIT, Lookup.Get_Keywords <EColor>(), false, null, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Specified, CssPropertyResolver.Color_Specified), new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Computed, CssPropertyResolver.Color_Computed), new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Color_Used)),
                new StyleDefinition(ECssPropertyID.BorderLeftColor, false, EPropertyDirtFlags.Visual, CssValue.From(EColor.CurrentColor), ECssValueTypes.KEYWORD | ECssValueTypes.COLOR | ECssValueTypes.INHERIT, Lookup.Get_Keywords <EColor>(), false, null, new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Specified, CssPropertyResolver.Color_Specified), new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Computed, CssPropertyResolver.Color_Computed), new Tuple <EPropertyStage, PropertyResolverFunc>(EPropertyStage.Used, CssPropertyResolver.Color_Used)),

                new StyleDefinition(ECssPropertyID.BorderTopStyle, false, EPropertyDirtFlags.Visual | EPropertyDirtFlags.Border_Area, CssValue.From(EBorderStyle.None), ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EBorderStyle>()),
                new StyleDefinition(ECssPropertyID.BorderRightStyle, false, EPropertyDirtFlags.Visual | EPropertyDirtFlags.Border_Area, CssValue.From(EBorderStyle.None), ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EBorderStyle>()),
                new StyleDefinition(ECssPropertyID.BorderBottomStyle, false, EPropertyDirtFlags.Visual | EPropertyDirtFlags.Border_Area, CssValue.From(EBorderStyle.None), ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EBorderStyle>()),
                new StyleDefinition(ECssPropertyID.BorderLeftStyle, false, EPropertyDirtFlags.Visual | EPropertyDirtFlags.Border_Area, CssValue.From(EBorderStyle.None), ECssValueTypes.KEYWORD, Lookup.Get_Keywords <EBorderStyle>()),

                // Was concerned about using CssValue.None as the initial value but thats what the specs say
                // SEE: https://www.w3.org/TR/css-transforms-1/#transform-property
                // The transform property is completely visual and does not change an elements box
                new StyleDefinition(ECssPropertyID.Transform, false, EPropertyDirtFlags.Visual, CssValue.None)
            });
        }
Пример #15
0
 /// <summary>
 /// Properties that can ONLY be set by the CssUI system
 /// </summary>
 static IEnumerable <StyleDefinition> Create_System_Property_Definitions()
 {
     return(new StyleDefinition[] {
         new StyleDefinition(ECssPropertyID.DpiX, true, EPropertyDirtFlags.Text | EPropertyDirtFlags.Flow, CssValue.Null, ECssValueTypes.NUMBER, null, false, (E, Pct) => CssValue.From(Pct * 72.0)),
         new StyleDefinition(ECssPropertyID.DpiY, true, EPropertyDirtFlags.Text | EPropertyDirtFlags.Flow, CssValue.Null, ECssValueTypes.NUMBER, null, false, (E, Pct) => CssValue.From(Pct * 72.0)),
     });
 }
Пример #16
0
        public static CssValue Font_Weight_Computed(ICssProperty Property)
        {/* Docs: https://drafts.csswg.org/css-fonts-4/#valdef-font-weight-bolder */
            if (Property == null)
            {
                throw new ArgumentNullException(nameof(Property));
            }
            Contract.EndContractBlock();

            // handle font-weight related keywords
            // This function wouldnt even be called if the value werent a keyword
            var keyword = (Property as CssProperty).Specified.AsEnum <EFontWeight>();
            int Weight  = 400;

            switch (keyword)
            {
            case EFontWeight.Normal:
                Weight = 400;
                break;

            case EFontWeight.Bold:
                Weight = 700;
                break;

            case EFontWeight.Bolder:
            {        /* Docs: https://drafts.csswg.org/css-fonts-4/#relative-weights */
                CssValue inherited = Property.Find_Inherited_Value();
                int      w         = inherited.AsInteger();

                if (w < 100)
                {
                    Weight = 400;
                }
                else if (w >= 100 && w < 350)
                {
                    Weight = 400;
                }
                else if (w >= 350 && w < 550)
                {
                    Weight = 700;
                }
                else if (w >= 550 && w < 750)
                {
                    Weight = 900;
                }
                else if (w >= 750 && w < 900)
                {
                    Weight = 900;
                }
                else
                {
                    Weight = 900;
                }
            }
            break;

            case EFontWeight.Lighter:
            {        /* Docs: https://drafts.csswg.org/css-fonts-4/#relative-weights */
                CssValue inherited = Property.Find_Inherited_Value();
                int      w         = inherited.AsInteger();

                if (w < 100)
                {
                    Weight = 100;
                }
                else if (w >= 100 && w < 350)
                {
                    Weight = 100;
                }
                else if (w >= 350 && w < 550)
                {
                    Weight = 100;
                }
                else if (w >= 550 && w < 750)
                {
                    Weight = 400;
                }
                else if (w >= 750 && w < 900)
                {
                    Weight = 700;
                }
                else
                {
                    Weight = 700;
                }
            }
            break;
            }

            return(CssValue.From(Weight));
        }
Пример #17
0
        public static CssValue Font_Size_Computed(ICssProperty Property)
        {/* Docs: https://www.w3.org/TR/css-fonts-3/#font-size-prop */
            if (Property == null)
            {
                throw new ArgumentNullException(nameof(Property));
            }
            Contract.EndContractBlock();

            CssValue value = (Property as CssProperty).Specified;

            if (value is null)
            {
                throw new CssException($"Unable to resolve absolute length for Computed \"{Property.CssName}\" value.");
            }
            Contract.EndContractBlock();

            double Size    = UserAgent.DEFAULT_FONT_SIZE; /* CssUIs' base font size */
            double Scaling = 1.0;                         /* Scaling to apply to our base size, used if the specified value is a keyword */


            if (value.HasValue)
            {
                if (value.IsDefinite)
                {
                    Size = value.AsDecimal();
                }
                else
                {
                    switch (value.Type)
                    {
                    case ECssValueTypes.DIMENSION:
                    {
                        Scaling = 1.0;
                        Size    = value.Resolve(Property.Owner.ownerDocument.cssUnitResolver);
                    }
                    break;

                    case ECssValueTypes.KEYWORD:
                    {
                        var keyword = value.AsEnum <EFontSize>();
                        switch (keyword)
                        {
                        /* First off, if the value is an <absolute> size keyword we associate it with a scale and apply it to our base size */
                        case EFontSize.XXSmall:
                        case EFontSize.XSmall:
                        case EFontSize.Small:
                        case EFontSize.Medium:
                        case EFontSize.Large:
                        case EFontSize.XLarge:
                        case EFontSize.XXLarge:
                            Scaling = CssCommon.Get_Font_Size_Keyword_Scaling_Factor(keyword);
                            break;

                        /* Second, if the value is a <relative> size keyword we find the computed font size of our parent and increase/decrease it to get our value  */
                        case EFontSize.Smaller:
                        {
                            double parentSize = Property.Owner.Style.Cascaded.FontSize.Computed.AsDecimal();
                            int    scaleIndex = CssCommon.Get_Font_Scaling_Step_Index_From_Size(parentSize);
                            Scaling = CssCommon.Get_Font_Scaling_From_Step_Index(scaleIndex - 1);
                        }
                        break;

                        case EFontSize.Larger:
                        {
                            double parentSize = Property.Owner.Style.Cascaded.FontSize.Computed.AsDecimal();
                            int    scaleIndex = CssCommon.Get_Font_Scaling_Step_Index_From_Size(parentSize);
                            Scaling = CssCommon.Get_Font_Scaling_From_Step_Index(scaleIndex + 1);
                        }
                        break;
                        }
                    }
                    break;
                    }


                    double finalSize = Size * Scaling;
                    return(CssValue.From(finalSize));
                }
            }



            // Round the size up to the nearest whole pixel value
            Size = CssCommon.SnapToPixel(Size);
            return(CssValue.From(Size));
        }
Пример #18
0
        public static CssValue Border_Width_Used(ICssProperty Property)
        {// Docs: https://www.w3.org/TR/css-backgrounds-3/#the-border-width
            if (Property == null)
            {
                throw new ArgumentNullException(nameof(Property));
            }
            Contract.EndContractBlock();

            var prop = (Property as CssProperty);

            if (prop.Computed.Type != ECssValueTypes.KEYWORD)
            {
                return(prop.Computed);
            }


            var keyword = prop.Specified.AsEnum <EBorderSize>();
            int Width   = 0;


            switch (keyword)
            {
            case EBorderSize.Thin:
            {
                Width = 1;
                break;
            }

            case EBorderSize.Medium:
            {
                Width = 3;
                break;
            }

            case EBorderSize.Thick:
            {
                Width = 5;
                break;
            }
            }

            switch (Property.CssName.EnumValue)
            {
            case ECssPropertyID.BorderLeftWidth:
            {
                if (0 != (Property.Owner.Style.Border_Left_Style & ((EBorderStyle.None | EBorderStyle.Hidden))))
                {
                    return(CssValue.From(0, ECssUnit.PX));
                }
            }
            break;

            case ECssPropertyID.BorderTopWidth:
            {
                if (0 != (Property.Owner.Style.Border_Top_Style & ((EBorderStyle.None | EBorderStyle.Hidden))))
                {
                    return(CssValue.From(0, ECssUnit.PX));
                }
            }
            break;

            case ECssPropertyID.BorderRightWidth:
            {
                if (0 != (Property.Owner.Style.Border_Right_Style & ((EBorderStyle.None | EBorderStyle.Hidden))))
                {
                    return(CssValue.From(0, ECssUnit.PX));
                }
            }
            break;

            case ECssPropertyID.BorderBottomWidth:
            {
                if (0 != (Property.Owner.Style.Border_Bottom_Style & ((EBorderStyle.None | EBorderStyle.Hidden))))
                {
                    return(CssValue.From(0, ECssUnit.PX));
                }
            }
            break;
            }

            return(CssValue.From(Width, ECssUnit.PX));
        }