|
@@ -42,6 +42,7 @@ type
|
|
|
EFresnel = class(Exception)
|
|
|
end;
|
|
|
|
|
|
+
|
|
|
EFresnelFont = class(EFresnel)
|
|
|
end;
|
|
|
|
|
@@ -113,7 +114,8 @@ type
|
|
|
fcaPaddingRight,
|
|
|
fcaPaddingBottom,
|
|
|
fcaVisibility,
|
|
|
- fcaBackgroundColor
|
|
|
+ fcaBackgroundColor,
|
|
|
+ fcaColor
|
|
|
);
|
|
|
TFresnelCSSAttributes = set of TFresnelCSSAttribute;
|
|
|
|
|
@@ -181,7 +183,8 @@ const
|
|
|
'padding-right',
|
|
|
'padding-bottom',
|
|
|
'visibility',
|
|
|
- 'background-color'
|
|
|
+ 'background-color',
|
|
|
+ 'color'
|
|
|
);
|
|
|
|
|
|
type
|
|
@@ -357,6 +360,7 @@ type
|
|
|
function CheckOrSetCSSPadding(const AValue: string; Check: boolean): boolean; virtual;
|
|
|
function CheckCSSVisibility(const AValue: string): boolean; virtual;
|
|
|
function CheckCSSBackgroundColor(const AValue: string): boolean; virtual;
|
|
|
+ function CheckCSSColor(const AValue: string): boolean; virtual;
|
|
|
function GetComputedCSSValue(AttrID: TCSSNumericalID): TCSSString;
|
|
|
procedure SetComputedCSSValue(AttrID: TCSSNumericalID; const Value: TCSSString);
|
|
|
procedure SetCSSClasses(const AValue: TStrings);
|
|
@@ -581,6 +585,9 @@ function CSSStrToFloat(const s: string; out l: TFresnelLength): boolean;
|
|
|
function CompareFresnelPoint(const A, B: TFresnelPoint): integer;
|
|
|
function CompareFresnelRect(const A, B: TFresnelRect): integer;
|
|
|
|
|
|
+function FPColorToCSS(const c: TFPColor): string;
|
|
|
+function CSSToFPColor(const s: string; out c: TFPColor): boolean;
|
|
|
+
|
|
|
implementation
|
|
|
|
|
|
function FloatToCSSStr(const f: TFresnelLength): string;
|
|
@@ -638,6 +645,159 @@ begin
|
|
|
Result:=0;
|
|
|
end;
|
|
|
|
|
|
+function FPColorToCSS(const c: TFPColor): string;
|
|
|
+const
|
|
|
+ hex: array[0..15] of char = '0123456789abcdef';
|
|
|
+var
|
|
|
+ br, bg, bb, ba: Byte;
|
|
|
+begin
|
|
|
+ if (lo(c.Red)=hi(c.Red))
|
|
|
+ and (lo(c.Green)=hi(c.Green))
|
|
|
+ and (lo(c.Blue)=hi(c.Blue))
|
|
|
+ and (lo(c.Alpha)=hi(c.Alpha)) then
|
|
|
+ begin
|
|
|
+ br:=lo(c.Red);
|
|
|
+ bg:=lo(c.Green);
|
|
|
+ bb:=lo(c.Blue);
|
|
|
+ ba:=lo(c.Alpha);
|
|
|
+ if (br and 15 = br shr 4)
|
|
|
+ and (bg and 15 = bg shr 4)
|
|
|
+ and (bb and 15 = bb shr 4)
|
|
|
+ and (ba and 15 = ba shr 4) then
|
|
|
+ begin
|
|
|
+ Result:='#'+hex[br and 15]+hex[bg and 15]+hex[bb and 15];
|
|
|
+ if c.Alpha<>alphaOpaque then
|
|
|
+ Result:=Result+hex[ba and 15];
|
|
|
+ end else begin
|
|
|
+ Result:='#'+hex[br shr 4]+hex[br and 15]
|
|
|
+ +hex[bg shr 4]+hex[bg and 15]
|
|
|
+ +hex[bb shr 4]+hex[bb and 15];
|
|
|
+ if c.Alpha<>alphaOpaque then
|
|
|
+ Result:=Result+hex[ba shr 4]+hex[ba and 15];
|
|
|
+ end;
|
|
|
+ end else begin
|
|
|
+ Result:='#'+HexStr(c.Red,4)+HexStr(c.Green,4)+HexStr(c.Blue,4);
|
|
|
+ if c.Alpha<>alphaOpaque then
|
|
|
+ Result:=Result+HexStr(c.Alpha,4);
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+function CSSToFPColor(const s: string; out c: TFPColor): boolean;
|
|
|
+
|
|
|
+ function ReadColor(var p: PChar; Count: byte): word;
|
|
|
+ var
|
|
|
+ i: Integer;
|
|
|
+ ch: Char;
|
|
|
+ v: word;
|
|
|
+ begin
|
|
|
+ Result:=0;
|
|
|
+ for i:=1 to Count do
|
|
|
+ begin
|
|
|
+ ch:=p^;
|
|
|
+ case ch of
|
|
|
+ '0'..'9': v:=ord(ch)-ord('0');
|
|
|
+ 'a'..'f': v:=ord(ch)-ord('a')+10;
|
|
|
+ 'A'..'F': v:=ord(ch)-ord('A')+10;
|
|
|
+ end;
|
|
|
+ Result:=Result shl 4+v;
|
|
|
+ inc(p);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+var
|
|
|
+ HexPerColor: byte;
|
|
|
+ p, StartP: PChar;
|
|
|
+ HasAlpha: Boolean;
|
|
|
+begin
|
|
|
+ Result := False;
|
|
|
+ c.Red := 0;
|
|
|
+ c.Green := 0;
|
|
|
+ c.Blue := 0;
|
|
|
+ c.Alpha := alphaOpaque;
|
|
|
+ if s='' then
|
|
|
+ exit;
|
|
|
+ p:=@s[1];
|
|
|
+ if p^='#' then
|
|
|
+ begin
|
|
|
+ inc(p);
|
|
|
+ StartP:=p;
|
|
|
+ repeat
|
|
|
+ case p^ of
|
|
|
+ #0:
|
|
|
+ if p-StartP+1=length(s) then
|
|
|
+ break
|
|
|
+ else
|
|
|
+ exit;
|
|
|
+ '0'..'9','a'..'f','A'..'F': inc(p);
|
|
|
+ else
|
|
|
+ exit;
|
|
|
+ end;
|
|
|
+ until false;
|
|
|
+ p:=StartP;
|
|
|
+ case length(s) of
|
|
|
+ 4:
|
|
|
+ begin
|
|
|
+ HexPerColor:=1;
|
|
|
+ HasAlpha:=false;
|
|
|
+ end;
|
|
|
+ 5:
|
|
|
+ begin
|
|
|
+ HexPerColor:=1;
|
|
|
+ HasAlpha:=true;
|
|
|
+ end;
|
|
|
+ 7:
|
|
|
+ begin
|
|
|
+ HexPerColor:=2;
|
|
|
+ HasAlpha:=false;
|
|
|
+ end;
|
|
|
+ 9:
|
|
|
+ begin
|
|
|
+ HexPerColor:=2;
|
|
|
+ HasAlpha:=true;
|
|
|
+ end;
|
|
|
+ 13:
|
|
|
+ begin
|
|
|
+ HexPerColor:=4;
|
|
|
+ HasAlpha:=false;
|
|
|
+ end;
|
|
|
+ 17:
|
|
|
+ begin
|
|
|
+ HexPerColor:=4;
|
|
|
+ HasAlpha:=true;
|
|
|
+ end;
|
|
|
+ else
|
|
|
+ exit;
|
|
|
+ end;
|
|
|
+ c.Red:=ReadColor(p,HexPerColor);
|
|
|
+ c.Green:=ReadColor(p,HexPerColor);
|
|
|
+ c.Blue:=ReadColor(p,HexPerColor);
|
|
|
+ if HasAlpha then
|
|
|
+ c.Alpha:=ReadColor(p,HexPerColor);
|
|
|
+ end else begin
|
|
|
+ case LowerCase(s) of
|
|
|
+ 'aqua' : c := colAqua;
|
|
|
+ 'black' : c := colBlack;
|
|
|
+ 'blue' : c := colBlue;
|
|
|
+ 'fuchsia': c := colFuchsia;
|
|
|
+ 'gray' : c := colGray;
|
|
|
+ 'green' : c := colGreen;
|
|
|
+ 'lime' : c := colLime;
|
|
|
+ 'maroon' : c := colMaroon;
|
|
|
+ 'navy' : c := colNavy;
|
|
|
+ 'olive' : c := colOlive;
|
|
|
+ 'purple' : c := colPurple;
|
|
|
+ 'red' : c := colRed;
|
|
|
+ 'silver' : c := colSilver;
|
|
|
+ 'teal' : c := colTeal;
|
|
|
+ 'white' : c := colWhite;
|
|
|
+ 'yellow' : c := colYellow;
|
|
|
+ else
|
|
|
+ exit;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ Result:=true;
|
|
|
+end;
|
|
|
+
|
|
|
{ TFresnelLayoutNode }
|
|
|
|
|
|
procedure TFresnelLayoutNode.SetElement(const AValue: TFresnelElement);
|
|
@@ -931,6 +1091,7 @@ begin
|
|
|
FCSSComputed[fcaHeight]:=FloatToCSSStr(Height);
|
|
|
FCSSComputed[fcaFontFamily]:='arial';
|
|
|
FCSSComputed[fcaFontSize]:='12';
|
|
|
+ FCSSComputed[fcaColor]:='#000';
|
|
|
end;
|
|
|
|
|
|
procedure TFresnelViewport.DomChanged;
|
|
@@ -1486,7 +1647,7 @@ function TFresnelElement.CheckCSSBorderColor(const AValue: string): boolean;
|
|
|
var
|
|
|
aColor: TFPColor;
|
|
|
begin
|
|
|
- Result:=TryHtmlToFPColor(AValue,aColor);
|
|
|
+ Result:=CSSToFPColor(AValue,aColor);
|
|
|
end;
|
|
|
|
|
|
function TFresnelElement.CheckCSSBoxSizing(const AValue: string): boolean;
|
|
@@ -1895,7 +2056,15 @@ begin
|
|
|
// ToDo: hsl(), hsla()
|
|
|
// ToDo: transparent
|
|
|
// ToDo: currentcolor
|
|
|
- Result:=TryHtmlToFPColor(AValue,aColor);
|
|
|
+ Result:=CSSToFPColor(AValue,aColor);
|
|
|
+end;
|
|
|
+
|
|
|
+function TFresnelElement.CheckCSSColor(const AValue: string): boolean;
|
|
|
+var
|
|
|
+ aColor: TFPColor;
|
|
|
+begin
|
|
|
+ // ToDo: rgb(r,g,b), rgba(r,g,b,a), ...
|
|
|
+ Result:=CSSToFPColor(AValue,aColor);
|
|
|
end;
|
|
|
|
|
|
function TFresnelElement.GetComputedCSSValue(AttrID: TCSSNumericalID
|
|
@@ -2926,6 +3095,7 @@ begin
|
|
|
fcaPaddingBottom: Result:=CheckCSSLength(Attr,s,[flcNoNegative]);
|
|
|
fcaVisibility: Result:=CheckCSSVisibility(s);
|
|
|
fcaBackgroundColor: Result:=CheckCSSBackgroundColor(s);
|
|
|
+ fcaColor: Result:=CheckCSSColor(s);
|
|
|
end;
|
|
|
finally
|
|
|
FCSSPosElement:=nil;
|
|
@@ -2953,6 +3123,7 @@ begin
|
|
|
fcaPaddingTop,
|
|
|
fcaPaddingRight,
|
|
|
fcaPaddingBottom: Result:='0';
|
|
|
+ fcaColor: Result:='#000';
|
|
|
else
|
|
|
Result:='';
|
|
|
end;
|