|
@@ -312,7 +312,7 @@ type
|
|
TFresnelElementAttrDesc = class(TCSSAttributeDesc)
|
|
TFresnelElementAttrDesc = class(TCSSAttributeDesc)
|
|
public
|
|
public
|
|
type
|
|
type
|
|
- TComputeEvent = procedure(Desc: TFresnelElementAttrDesc; El: TFresnelElement;
|
|
|
|
|
|
+ TComputeEvent = procedure(El: TFresnelElement;
|
|
var Value: string; // returns empty for invalid
|
|
var Value: string; // returns empty for invalid
|
|
out Complete: boolean) of object;
|
|
out Complete: boolean) of object;
|
|
TGetAsStringEvent = function(El: TFresnelElement): string of object;
|
|
TGetAsStringEvent = function(El: TFresnelElement): string of object;
|
|
@@ -447,6 +447,7 @@ type
|
|
function GetMarginInline(El: TFresnelElement): string; virtual;
|
|
function GetMarginInline(El: TFresnelElement): string; virtual;
|
|
function GetOverflow(El: TFresnelElement): string; virtual;
|
|
function GetOverflow(El: TFresnelElement): string; virtual;
|
|
function GetPadding(El: TFresnelElement): string; virtual;
|
|
function GetPadding(El: TFresnelElement): string; virtual;
|
|
|
|
+
|
|
public
|
|
public
|
|
// keywords
|
|
// keywords
|
|
const
|
|
const
|
|
@@ -596,7 +597,47 @@ type
|
|
afRepeatingLinearGradient = afConicGradient+1; // repeating-linear-gradient
|
|
afRepeatingLinearGradient = afConicGradient+1; // repeating-linear-gradient
|
|
afRepeatingRadialGradient = afRepeatingLinearGradient+1; // repeating-radial-gradient
|
|
afRepeatingRadialGradient = afRepeatingLinearGradient+1; // repeating-radial-gradient
|
|
afRepeatingConicGradient = afRepeatingRadialGradient+1; // repeating-conic-gradient
|
|
afRepeatingConicGradient = afRepeatingRadialGradient+1; // repeating-conic-gradient
|
|
-
|
|
|
|
|
|
+ public
|
|
|
|
+ // font-width
|
|
|
|
+ type
|
|
|
|
+ TFontWidthName = (
|
|
|
|
+ fntwnUltraCondensed,
|
|
|
|
+ fntwnExtraCondensed,
|
|
|
|
+ fntwnCondensed,
|
|
|
|
+ fntwnSemiCondensed,
|
|
|
|
+ fntwnNormal,
|
|
|
|
+ fntwnSemiExpanded,
|
|
|
|
+ fntwnExpanded,
|
|
|
|
+ fntwnExtraExpanded,
|
|
|
|
+ fntwnUltraExpanded
|
|
|
|
+ );
|
|
|
|
+ TFontWidthNames = set of TFontWidthName;
|
|
|
|
+ const
|
|
|
|
+ FontWidths: array[TFontWidthName] of TFresnelLength = (
|
|
|
|
+ 0.5, // UltraCondensed
|
|
|
|
+ 0.625, // ExtraCondensed
|
|
|
|
+ 0.75, // Condensed
|
|
|
|
+ 0.875, // SemiCondensed
|
|
|
|
+ 1, // Normal
|
|
|
|
+ 1.125, // SemiExpanded
|
|
|
|
+ 1.25, // Expanded
|
|
|
|
+ 1.5, // ExtraExpanded
|
|
|
|
+ 2 // UltraExpanded
|
|
|
|
+ );
|
|
|
|
+ FontWidthKeywords: array[TFontWidthName] of TCSSNumericalID = (
|
|
|
|
+ kwUltraCondensed,
|
|
|
|
+ kwExtraCondensed,
|
|
|
|
+ kwCondensed,
|
|
|
|
+ kwSemiCondensed,
|
|
|
|
+ kwNormal,
|
|
|
|
+ kwSemiExpanded,
|
|
|
|
+ kwExpanded,
|
|
|
|
+ kwExtraExpanded,
|
|
|
|
+ kwUltraExpanded
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ function RoundFontWidth(aWidth: TFresnelLength): TFontWidthName; virtual;
|
|
|
|
+ function RoundFontWidthToKeyword(aWidth: TFresnelLength): TCSSNumericalID; virtual;
|
|
public
|
|
public
|
|
FresnelAttrIDBase: TCSSNumericalID;
|
|
FresnelAttrIDBase: TCSSNumericalID;
|
|
FresnelAttrs: array[TFresnelCSSAttribute] of TFresnelCSSAttrDesc;
|
|
FresnelAttrs: array[TFresnelCSSAttribute] of TFresnelCSSAttrDesc;
|
|
@@ -2706,31 +2747,34 @@ function TFresnelCSSRegistry.GetFont(El: TFresnelElement): string;
|
|
var
|
|
var
|
|
aSize, aWeight, aLineHeight: TFresnelLength;
|
|
aSize, aWeight, aLineHeight: TFresnelLength;
|
|
aFamily, aStyle, aVariant: String;
|
|
aFamily, aStyle, aVariant: String;
|
|
|
|
+ aWidth: TCSSNumericalID;
|
|
begin
|
|
begin
|
|
Result:='';
|
|
Result:='';
|
|
|
|
|
|
aSize:=El.Font.GetSize;
|
|
aSize:=El.Font.GetSize;
|
|
aFamily:=El.Font.GetFamily;
|
|
aFamily:=El.Font.GetFamily;
|
|
aStyle:=El.Font.GetStyle;
|
|
aStyle:=El.Font.GetStyle;
|
|
-
|
|
|
|
aVariant:=El.Font.GetVariant;
|
|
aVariant:=El.Font.GetVariant;
|
|
|
|
+ aWeight:=El.Font.GetWeight;
|
|
|
|
+ aLineHeight:=El.GetComputedLength(fcaLineHeight);
|
|
|
|
+
|
|
case aVariant of
|
|
case aVariant of
|
|
'normal','small-caps': ; // only these are allowed in font shorthand
|
|
'normal','small-caps': ; // only these are allowed in font shorthand
|
|
else aVariant:='';
|
|
else aVariant:='';
|
|
end;
|
|
end;
|
|
|
|
|
|
- aWeight:=El.Font.GetWeight;
|
|
|
|
- // todo font-width, must be a single keyword
|
|
|
|
- aLineHeight:=El.GetComputedLength(fcaLineHeight);
|
|
|
|
-
|
|
|
|
// style, variant and weight must preced size
|
|
// style, variant and weight must preced size
|
|
Add(aStyle,FresnelAttrs[fcaFontStyle].InitialValue);
|
|
Add(aStyle,FresnelAttrs[fcaFontStyle].InitialValue);
|
|
Add(aVariant,FresnelAttrs[fcaFontVariant].InitialValue);
|
|
Add(aVariant,FresnelAttrs[fcaFontVariant].InitialValue);
|
|
Add(FloatToCSSStr(aWeight),'');
|
|
Add(FloatToCSSStr(aWeight),'');
|
|
|
|
|
|
// font-size/line-height
|
|
// font-size/line-height
|
|
- Add(FloatToCSSStr(aSize),'');
|
|
|
|
- Result+='/'+FloatToCSSStr(aLineHeight);
|
|
|
|
|
|
+ Add(FloatToCSSPx(aSize),'');
|
|
|
|
+ Result+='/'+FloatToCSSPx(aLineHeight);
|
|
|
|
+
|
|
|
|
+ aWidth:=RoundFontWidthToKeyword(El.Font.GetWidth);
|
|
|
|
+ if aWidth<>kwNormal then
|
|
|
|
+ Result+=' '+Keywords[aWidth];
|
|
|
|
|
|
Add(aFamily,'');
|
|
Add(aFamily,'');
|
|
end;
|
|
end;
|
|
@@ -2907,6 +2951,22 @@ begin
|
|
Result:=GetSideLengths(El,fcaPaddingTop);
|
|
Result:=GetSideLengths(El,fcaPaddingTop);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TFresnelCSSRegistry.RoundFontWidth(aWidth: TFresnelLength): TFontWidthName;
|
|
|
|
+var
|
|
|
|
+ fw: TFontWidthName;
|
|
|
|
+begin
|
|
|
|
+ fw:=Low(TFontWidthName);
|
|
|
|
+ for fw:=Low(TFontWidthName) to Pred(high(TFontWidthName)) do
|
|
|
|
+ if aWidth<(FontWidths[fw]+FontWidths[Succ(fw)])/2 then
|
|
|
|
+ exit(fw);
|
|
|
|
+ Result:=high(TFontWidthName);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TFresnelCSSRegistry.RoundFontWidthToKeyword(aWidth: TFresnelLength): TCSSNumericalID;
|
|
|
|
+begin
|
|
|
|
+ Result:=FontWidthKeywords[RoundFontWidth(aWidth)];
|
|
|
|
+end;
|
|
|
|
+
|
|
constructor TFresnelCSSRegistry.Create;
|
|
constructor TFresnelCSSRegistry.Create;
|
|
begin
|
|
begin
|
|
Attribute_ClassOf:=TFresnelCSSAttrDesc;
|
|
Attribute_ClassOf:=TFresnelCSSAttrDesc;
|
|
@@ -4618,7 +4678,7 @@ function TFresnelElement.GetComputedLength(Attr: TFresnelCSSAttribute; UseNaNOnF
|
|
|
|
|
|
function GetIsHorizontal: boolean;
|
|
function GetIsHorizontal: boolean;
|
|
begin
|
|
begin
|
|
- case Attr of
|
|
|
|
|
|
+ Result:=Attr in [
|
|
fcaLeft,
|
|
fcaLeft,
|
|
fcaRight,
|
|
fcaRight,
|
|
fcaMinWidth,
|
|
fcaMinWidth,
|
|
@@ -4628,13 +4688,14 @@ function TFresnelElement.GetComputedLength(Attr: TFresnelCSSAttribute; UseNaNOnF
|
|
fcaBorderRightWidth,
|
|
fcaBorderRightWidth,
|
|
fcaMarginLeft,
|
|
fcaMarginLeft,
|
|
fcaMarginRight,
|
|
fcaMarginRight,
|
|
|
|
+ fcaMarginTop, // margin-top, -bottom percentage uses the container width
|
|
|
|
+ fcaMarginBottom,
|
|
fcaPaddingLeft,
|
|
fcaPaddingLeft,
|
|
fcaPaddingRight,
|
|
fcaPaddingRight,
|
|
|
|
+ fcaPaddingTop, // padding-top, -bottom percentage uses the container width
|
|
|
|
+ fcaPaddingBottom,
|
|
fcaBackgroundPositionX,
|
|
fcaBackgroundPositionX,
|
|
- fcaBackgroundSize:
|
|
|
|
- exit(true);
|
|
|
|
- end;
|
|
|
|
- Result:=false;
|
|
|
|
|
|
+ fcaBackgroundSize];
|
|
end;
|
|
end;
|
|
|
|
|
|
var
|
|
var
|
|
@@ -4766,7 +4827,7 @@ begin
|
|
writeln('TFresnelElement.WriteComputedAttributes ',Title,' ',GetPath,'================');
|
|
writeln('TFresnelElement.WriteComputedAttributes ',Title,' ',GetPath,'================');
|
|
for Attr in TFresnelCSSAttribute do
|
|
for Attr in TFresnelCSSAttribute do
|
|
begin
|
|
begin
|
|
- writeln('TFresnelElement.WriteComputedAttributes ',Attr);
|
|
|
|
|
|
+ //writeln('TFresnelElement.WriteComputedAttributes ',Attr);
|
|
CurValue:=GetComputedString(Attr);
|
|
CurValue:=GetComputedString(Attr);
|
|
DefValue:=GetUnsetCSSString(Attr);
|
|
DefValue:=GetUnsetCSSString(Attr);
|
|
if CurValue<>DefValue then
|
|
if CurValue<>DefValue then
|
|
@@ -5436,15 +5497,15 @@ begin
|
|
case aComp.Kind of
|
|
case aComp.Kind of
|
|
rvkKeyword:
|
|
rvkKeyword:
|
|
case aComp.KeywordID of
|
|
case aComp.KeywordID of
|
|
- CSSRegistry.kwUltraCondensed: FFontDesc.Width:=0.5;
|
|
|
|
- CSSRegistry.kwExtraCondensed: FFontDesc.Width:=0.625;
|
|
|
|
- CSSRegistry.kwCondensed: FFontDesc.Width:=0.75;
|
|
|
|
- CSSRegistry.kwSemiCondensed: FFontDesc.Width:=0.875;
|
|
|
|
- CSSRegistry.kwNormal: FFontDesc.Width:=1;
|
|
|
|
- CSSRegistry.kwSemiExpanded: FFontDesc.Width:=1.125;
|
|
|
|
- CSSRegistry.kwExpanded: FFontDesc.Width:=1.25;
|
|
|
|
- CSSRegistry.kwExtraExpanded: FFontDesc.Width:=1.5;
|
|
|
|
- CSSRegistry.kwUltraExpanded: FFontDesc.Width:=2;
|
|
|
|
|
|
+ CSSRegistry.kwUltraCondensed: FFontDesc.Width:=CSSRegistry.FontWidths[fntwnUltraCondensed];
|
|
|
|
+ CSSRegistry.kwExtraCondensed: FFontDesc.Width:=CSSRegistry.FontWidths[fntwnExtraCondensed];
|
|
|
|
+ CSSRegistry.kwCondensed: FFontDesc.Width:=CSSRegistry.FontWidths[fntwnCondensed];
|
|
|
|
+ CSSRegistry.kwSemiCondensed: FFontDesc.Width:=CSSRegistry.FontWidths[fntwnSemiCondensed];
|
|
|
|
+ CSSRegistry.kwNormal: FFontDesc.Width:=CSSRegistry.FontWidths[fntwnNormal];
|
|
|
|
+ CSSRegistry.kwSemiExpanded: FFontDesc.Width:=CSSRegistry.FontWidths[fntwnSemiExpanded];
|
|
|
|
+ CSSRegistry.kwExpanded: FFontDesc.Width:=CSSRegistry.FontWidths[fntwnExpanded];
|
|
|
|
+ CSSRegistry.kwExtraExpanded: FFontDesc.Width:=CSSRegistry.FontWidths[fntwnExtraExpanded];
|
|
|
|
+ CSSRegistry.kwUltraExpanded: FFontDesc.Width:=CSSRegistry.FontWidths[fntwnUltraExpanded];
|
|
end;
|
|
end;
|
|
rvkFloat:
|
|
rvkFloat:
|
|
if (aComp.FloatUnit=cuPercent) and (aComp.Float>=0) then
|
|
if (aComp.FloatUnit=cuPercent) and (aComp.Float>=0) then
|
|
@@ -5762,17 +5823,21 @@ function TFresnelElement.ComputeAttribute(aDesc: TCSSAttributeDesc; var aValue:
|
|
): TCSSAttributeValue.TState;
|
|
): TCSSAttributeValue.TState;
|
|
var
|
|
var
|
|
ElAttrDesc: TFresnelElementAttrDesc;
|
|
ElAttrDesc: TFresnelElementAttrDesc;
|
|
|
|
+ Complete: boolean;
|
|
begin
|
|
begin
|
|
if aValue='' then exit(cavsInvalid);
|
|
if aValue='' then exit(cavsInvalid);
|
|
-
|
|
|
|
Result:=cavsComputed;
|
|
Result:=cavsComputed;
|
|
-
|
|
|
|
if aDesc is TFresnelElementAttrDesc then
|
|
if aDesc is TFresnelElementAttrDesc then
|
|
begin
|
|
begin
|
|
ElAttrDesc:=TFresnelElementAttrDesc(aDesc);
|
|
ElAttrDesc:=TFresnelElementAttrDesc(aDesc);
|
|
if ElAttrDesc.OnCompute<>nil then
|
|
if ElAttrDesc.OnCompute<>nil then
|
|
begin
|
|
begin
|
|
-
|
|
|
|
|
|
+ ElAttrDesc.OnCompute(Self,aValue,Complete);
|
|
|
|
+ if aValue='' then exit(cavsInvalid);
|
|
|
|
+ if Complete then
|
|
|
|
+ exit(cavsComputed)
|
|
|
|
+ else
|
|
|
|
+ exit(cavsBaseKeywords);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
@@ -5987,7 +6052,7 @@ var
|
|
AttrDesc: TCSSAttributeDesc;
|
|
AttrDesc: TCSSAttributeDesc;
|
|
aComp: TCSSResCompValue;
|
|
aComp: TCSSResCompValue;
|
|
s: TCSSString;
|
|
s: TCSSString;
|
|
- UseInherits, Complete: Boolean;
|
|
|
|
|
|
+ Complete, UseInherit: Boolean;
|
|
AttrID: TCSSNumericalID;
|
|
AttrID: TCSSNumericalID;
|
|
begin
|
|
begin
|
|
Exclude(FStates,fesFontDescValid);
|
|
Exclude(FStates,fesFontDescValid);
|
|
@@ -5998,12 +6063,13 @@ begin
|
|
// Note: var() and shorthands are already substituted
|
|
// Note: var() and shorthands are already substituted
|
|
|
|
|
|
// apply base keywords 'initial', 'inherit', 'unset', ...
|
|
// apply base keywords 'initial', 'inherit', 'unset', ...
|
|
- for i:=length(FCSSValues.Values)-1 downto 0 do
|
|
|
|
|
|
+ for i:=0 to length(FCSSValues.Values)-1 do
|
|
begin
|
|
begin
|
|
aValue:=FCSSValues.Values[i];
|
|
aValue:=FCSSValues.Values[i];
|
|
if aValue.State<>cavsSource then continue;
|
|
if aValue.State<>cavsSource then continue;
|
|
AttrID:=aValue.AttrID;
|
|
AttrID:=aValue.AttrID;
|
|
- if AttrID>=CSSRegistry.AttributeCount then continue;
|
|
|
|
|
|
+ if AttrID>=CSSRegistry.AttributeCount then
|
|
|
|
+ continue; // custom attributes are not parsed, their values were already copied
|
|
AttrDesc:=CSSRegistry.Attributes[AttrID];
|
|
AttrDesc:=CSSRegistry.Attributes[AttrID];
|
|
s:=aValue.Value;
|
|
s:=aValue.Value;
|
|
{$IFDEF VerboseCSSAttr}
|
|
{$IFDEF VerboseCSSAttr}
|
|
@@ -6016,29 +6082,29 @@ begin
|
|
aValue.State:=cavsInvalid;
|
|
aValue.State:=cavsInvalid;
|
|
continue;
|
|
continue;
|
|
end;
|
|
end;
|
|
|
|
+ aValue.State:=cavsBaseKeywords;
|
|
|
|
+
|
|
if aComp.Kind<>rvkKeyword then continue;
|
|
if aComp.Kind<>rvkKeyword then continue;
|
|
- UseInherits:=true;
|
|
|
|
|
|
+ UseInherit:=false;
|
|
case aComp.KeywordID of
|
|
case aComp.KeywordID of
|
|
CSSKeywordInitial:
|
|
CSSKeywordInitial:
|
|
- UseInherits:=false;
|
|
|
|
|
|
+ UseInherit:=false;
|
|
CSSKeywordInherit:
|
|
CSSKeywordInherit:
|
|
- UseInherits:=true;
|
|
|
|
|
|
+ UseInherit:=true;
|
|
CSSKeywordUnset,
|
|
CSSKeywordUnset,
|
|
CSSKeywordRevert, CSSKeywordRevertLayer:
|
|
CSSKeywordRevert, CSSKeywordRevertLayer:
|
|
- UseInherits:=AttrDesc.Inherits;
|
|
|
|
- else continue;
|
|
|
|
|
|
+ UseInherit:=AttrDesc.Inherits;
|
|
|
|
+ else
|
|
|
|
+ continue;
|
|
end;
|
|
end;
|
|
- if UseInherits=AttrDesc.Inherits then
|
|
|
|
|
|
+ if UseInherit=AttrDesc.Inherits then
|
|
begin
|
|
begin
|
|
// unset
|
|
// unset
|
|
aValue.State:=cavsInvalid;
|
|
aValue.State:=cavsInvalid;
|
|
- continue;
|
|
|
|
- end else if UseInherits and (Parent<>nil) then begin
|
|
|
|
|
|
+ end else if UseInherit and (Parent<>nil) then begin
|
|
aValue.Value:=Parent.GetCSSString(aValue.AttrID,false,Complete);
|
|
aValue.Value:=Parent.GetCSSString(aValue.AttrID,false,Complete);
|
|
- aValue.State:=cavsBaseKeywords;
|
|
|
|
end else begin
|
|
end else begin
|
|
aValue.Value:=AttrDesc.InitialValue;
|
|
aValue.Value:=AttrDesc.InitialValue;
|
|
- aValue.State:=cavsBaseKeywords;
|
|
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|