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)); }
private bool Try_Match(Document document) { switch (Context) { case EMediaFeatureContext.Boolean: { /* * ...the media feature is evaluated in a boolean context. * If the feature would be true for any value other than the number 0, a <dimension> with the value 0, or the keyword none, the media feature evaluates to true. * Otherwise, it evaluates to false. */ CssValue value = Values[0]; if (!Lookup.TryEnum(value.AsString(), out EMediaFeatureName nameLookup)) { /* This feature is not supported (or maybe valid) so we need to treat it as if it simply doesnt match */ IsValid = false; return(false); } // CssValue valueA = Values[0]; CssValue valueB = Values[1]; switch (valueB.Type) { case ECssValueTypes.KEYWORD: { return(Compare_Keyword(document, nameLookup, valueB.AsString())); } case ECssValueTypes.INTEGER: case ECssValueTypes.NUMBER: { double A = (double)Resolve_Media_Name_Value(document, nameLookup); double B = valueB.AsDecimal(); return(!(A == B)); } case ECssValueTypes.DIMENSION: case ECssValueTypes.RESOLUTION: { double A = (double)Resolve_Media_Name_Value(document, nameLookup); double B = valueB.Resolve(document.cssUnitResolver); return(!(A == B)); } } } break; case EMediaFeatureContext.Range: { /* Compare all value/operator pairs */ for (int i = 1; i < Operators.Length; i++) { CssValue A = Values[i - 1]; CssValue B = Values[i]; var op = Operators[i - 1]; if (!Compare(document, A, B, op)) { return(false); } } return(true); } } return(false); }