public static CssValue Color_Specified(ICssProperty Property) { if (Property == null) { throw new ArgumentNullException(nameof(Property)); } Contract.EndContractBlock(); var prop = (Property as CssProperty); if (prop.Specified.Type != ECssValueTypes.KEYWORD) { return(prop.Specified); } CssValue Value = prop.Specified; var keyword = Value.AsEnum <EColor>(); switch (keyword) { case EColor.CurrentColor: { /* If the ‘currentColor’ keyword is set on the ‘color’ property itself, it is treated as ‘color: inherit’. */ if (Property.CssName == ECssPropertyID.Color) { return(Property.Find_Inherited_Value()); } } break; } return(Value); }
public static CssValue Color_Used(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: { /* The used value of the ‘currentColor’ keyword is the computed value of the ‘color’ property. */ return(Property.Owner.Style.Cascaded.Color.Computed); } } } return(Value); }
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); }
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); }
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)); }
static bool Compare(Document document, CssValue ValueA, CssValue ValueB, EMediaOperator Op) { /* An Excerpt: * "If a media feature references a concept which does not exist on the device where the UA is running (for example, speech UAs do not have a concept of “width”), the media feature must always evaluate to false." */ double A, B; /* First resolve these values to numbers we can compare */ if (ValueA.Type == ECssValueTypes.KEYWORD) { if (!Lookup.TryEnum(ValueA.AsString(), out EMediaFeatureName _)) {/* If we cant find this keyword then we treat it as if it were an unsupported feature */ return(false); } A = (double)Resolve_Media_Name_Value(document, ValueA.AsEnum <EMediaFeatureName>()); } else { A = ValueA.AsDecimal(); } if (ValueB.Type == ECssValueTypes.KEYWORD) { if (!Lookup.TryEnum(ValueB.AsString(), out EMediaFeatureName _)) {/* If we cant find this keyword then we treat it as if it were an unsupported feature */ return(false); } B = (double)Resolve_Media_Name_Value(document, ValueB.AsEnum <EMediaFeatureName>()); } else { B = ValueB.AsDecimal(); } /* Compare them and return the result */ switch (Op) { case EMediaOperator.EqualTo: { return(A == B); } case EMediaOperator.LessThan: { return(A < B); } case EMediaOperator.GreaterThan: { return(A > B); } case EMediaOperator.LessThanEq: { return(A < B || (A == B)); } case EMediaOperator.GreaterThanEq: { return(A > B || (A == B)); } } return(false); }
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); }