From 167360bd8adb769f9053f0262ce00a2a6ecd657c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=BE=D0=BD=D0=BE=D0=BD=D0=BE=D0=B2=20=D0=90=D0=BD?= =?UTF-8?q?=D0=B4=D1=80=D0=B5=D0=B9=20=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B5?= =?UTF-8?q?=D0=B2=D0=B8=D1=87?= Date: Wed, 20 Oct 2021 13:38:51 +0600 Subject: [PATCH] Draw linear gradient in block background We can draw linear gradient with 3 parameters: background-color: linear-gradient(to top, #ffffff, #6699ff); background-color: linear-gradient(to bottom, green, silver); background-color: linear-gradient(0deg, red, blue); Fix #307 --- source/HTMLSubs.pas | 71 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/source/HTMLSubs.pas b/source/HTMLSubs.pas index 5bba1898..8e9df562 100644 --- a/source/HTMLSubs.pas +++ b/source/HTMLSubs.pas @@ -5940,6 +5940,75 @@ function TBlock.Draw1(Canvas: TCanvas; const ARect: TRect; IMgr: TIndentManager; procedure TBlock.DrawBlock(Canvas: TCanvas; const ARect: TRect; IMgr: TIndentManager; X, Y, XRef, YRef: Integer); + procedure DrawBackground(R :TRect); + + procedure ParseAndDrawLinearGradient(Value: String); + + function GetAngle(FirstParam: String): Integer; + var + NumDeg: String; + begin + Result := 0; + if Pos('deg', FirstParam) > 0 then + begin + NumDeg := Copy(FirstParam, 1, Pos('deg', FirstParam)-1); + TryStrToInt(NumDeg, Result); + end + else + begin + if SameText('to right', FirstParam) then + Result := 90 + else if SameText('to bottom', FirstParam) then + Result := 180 + else if SameText('to left', FirstParam) then + Result := -90 + else if SameText('to left top', FirstParam) then + Result := -45 + else if SameText('to left bottom', FirstParam) then + Result := -135 + else if SameText('to right top', FirstParam) then + Result := 45 + else if SameText('to right bottom', FirstParam) then + Result := 135; + end; + end; // GetAngle + + var + Angle, I, J: Integer; + ColorFrom, ColorTo: TColor; + a: TStringDynArray; + begin + I := Pos('(', Value); + J := Pos(')', Value); + if (I = 0) or (J = 0) then Exit; + a := SplitString(Copy(Value, I+1, J-I-1), ','); + if Length(a) = 3 then + begin + Angle := GetAngle(Trim(a[0])); + if not TryStrToColor(Trim(a[1]), False, ColorTo) then Exit; + if not TryStrToColor(Trim(a[2]), False, ColorFrom) then Exit; + if Angle = 0 then + GradientFillCanvas(Canvas, ColorFrom, ColorTo, R, gdVertical) // gdHorizontal + else if Angle = 180 then + GradientFillCanvas(Canvas, ColorTo, ColorFrom, R, gdVertical) // gdHorizontal + end + else // todo: parse + Exit; + end; // ParseAndDrawLinearGradient + + var + V: Variant; + begin + Canvas.FillRect(R); + V := FProperties.Props[BackgroundColor]; + if VarIsNull(V) or (VarType(V) <> varUString) then Exit; + + if StartsText('linear-gradient', V) then + ParseAndDrawLinearGradient(V); +// else if StartsText('radial-gradient', V) then +// ... + end; // DrawBackground + var YOffset: Integer; XR, YB, RefX, RefY, TmpHt: Integer; @@ -6079,7 +6148,7 @@ procedure TBlock.DrawBlock(Canvas: TCanvas; const ARect: TRect; TiledImage.PrintUnstretched(Canvas, PdRect.Left, FT, IW, IH, 0, IT, HasBackgroundColor and Document.PrintBackground ) else if not Document.Printing or Document.PrintBackground then - Canvas.FillRect(Rect(PdRect.Left, FT, PdRect.Right, FT + IH)); + DrawBackground(Rect(PdRect.Left, FT, PdRect.Right, FT + IH)); except end; end;