diff --git a/components/fpvectorial/fpvectorial.pas b/components/fpvectorial/fpvectorial.pas
index 8cfd594de8..12a33946d7 100644
--- a/components/fpvectorial/fpvectorial.pas
+++ b/components/fpvectorial/fpvectorial.pas
@@ -118,7 +118,7 @@ type
Width: Integer;
end;
- TvBrushKind = (bkSimpleBrush, bkRadialGradient);
+ TvBrushKind = (bkSimpleBrush, bkHorizontalGradient, bkVerticalGradient, vkOtherLinearGradient, bkRadialGradient);
TvCoordinateUnit = (vcuDocumentUnit, vcuPercentage);
TvBrush = record
@@ -150,7 +150,7 @@ type
TvSetStyleElement = (
// Pen, Brush and Font
spbfPenColor, spbfPenStyle, spbfPenWidth,
- spbfBrushColor, spbfBrushStyle, spbfBrushGradient,
+ spbfBrushColor, spbfBrushStyle, spbfBrushGradient, spbfBrushKind,
spbfFontColor, spbfFontSize, spbfFontName, spbfFontBold, spbfFontItalic,
spbfFontUnderline, spbfFontStrikeThrough, spbfAlignment,
// TextAnchor
@@ -1809,6 +1809,8 @@ begin
Brush.Style := AFrom.Brush.Style;
{if spbfBrushGradient in AFrom.SetElements then
Brush.Gra := AFrom.Brush.Style;}
+ if spbfBrushKind in AFrom.SetElements then
+ Brush.Kind := AFrom.Brush.Kind;
// Font
@@ -1871,6 +1873,8 @@ begin
ADest.Brush.Style := Brush.Style;
{if spbfBrushGradient in SetElements then
Brush.Gra := AFrom.Brush.Style;}
+ if spbfBrushKind in SetElements then
+ ADest.Brush.Kind := Brush.Kind;
// Font
@@ -3723,6 +3727,14 @@ begin
begin
ADest.Ellipse(x1, y1, x2, y2);
end;
+ // Apply brush gradient
+ if Brush.Kind in [bkHorizontalGradient, bkVerticalGradient] then
+ begin
+ {PrepareBrushBitmap(x2, y2);
+ BrushBitmap.Canvas.Ellipse(0, 0, x2-x1, y2-y1);
+ AlphaBlendBrushBitmap(ADest, x1, y1);
+ FreeAndNil(BrushBitmap);}
+ end;
end;
{ TvRectangle }
diff --git a/components/fpvectorial/svgvectorialreader.pas b/components/fpvectorial/svgvectorialreader.pas
index 1ef5caf6ae..a03da56988 100644
--- a/components/fpvectorial/svgvectorialreader.pas
+++ b/components/fpvectorial/svgvectorialreader.pas
@@ -935,10 +935,34 @@ function TvSVGVectorialReader.ReadSVGBrushStyleWithKeyAndValue(AKey,
AValue: string; ADestEntity: TvEntityWithPenAndBrush): TvSetPenBrushAndFontElements;
var
OldAlpha: Word;
+ Len: Integer;
+ lDefName: String;
+ i: Integer;
+ lCurBrush: TvEntityWithPenAndBrush;
begin
Result := [];
if AKey = 'fill' then
begin
+ // Suppose for fill="url(#grad2)"
+ lDefName := Trim(AValue);
+ if Copy(lDefName, 0, 3) = 'url' then
+ begin
+ lDefName := StringReplace(AValue, 'url(#', '', []);
+ lDefName := StringReplace(lDefName, ')', '', []);
+ if lDefName = '' then Exit;
+
+ for i := 0 to FBrushDefs.Count-1 do
+ begin
+ lCurBrush := TvEntityWithPenAndBrush(FBrushDefs.Items[i]);
+ if lCurBrush.Name = lDefName then
+ begin
+ ADestEntity.Brush := lCurBrush.Brush;
+ Exit;
+ end;
+ end;
+ Exit;
+ end;
+
// We store and restore the old alpha to support the "-opacity" element
OldAlpha := ADestEntity.Brush.Color.Alpha;
if ADestEntity.Brush.Style = bsClear then ADestEntity.Brush.Style := bsSolid;
@@ -953,7 +977,14 @@ begin
Result := Result + [spbfBrushColor, spbfBrushStyle];
end
else if AKey = 'fill-opacity' then
- ADestEntity.Brush.Color.Alpha := StringFloatZeroToOneToWord(AValue);
+ ADestEntity.Brush.Color.Alpha := StringFloatZeroToOneToWord(AValue)
+ // For linear gradient => stop-color:rgb(255,255,0);stop-opacity:1
+ else if AKey = 'stop-color' then
+ begin
+ Len := Length(ADestEntity.Brush.Gradient_colors);
+ SetLength(ADestEntity.Brush.Gradient_colors, Len+1);
+ ADestEntity.Brush.Gradient_colors[Len] := ReadSVGColor(AValue);
+ end;
end;
function TvSVGVectorialReader.ReadSVGFontStyleWithKeyAndValue(AKey,
@@ -1232,13 +1263,15 @@ var
lCurNode, lCurSubNode: TDOMNode;
lBrushEntity: TvEntityWithPenAndBrush;
lCurEntity: TvEntity;
+ lOffset: Double;
+ x1, x2, y1, y2: string;
begin
lCurNode := ANode.FirstChild;
while Assigned(lCurNode) do
begin
lEntityName := LowerCase(lCurNode.NodeName);
case lEntityName of
- 'RadialGradient':
+ 'radialgradient':
begin
lBrushEntity := TvEntityWithPenAndBrush.Create(nil);
lBrushEntity.Brush.Kind := bkRadialGradient;
@@ -1292,6 +1325,59 @@ begin
FBrushDefs.Add(lBrushEntity);
end;
+ {
+
+
+
+
+ }
+ 'lineargradient':
+ begin
+ lBrushEntity := TvEntityWithPenAndBrush.Create(nil);
+
+ //
+ for i := 0 to lCurNode.Attributes.Length - 1 do
+ begin
+ lAttrName := lCurNode.Attributes.Item[i].NodeName;
+ lAttrValue := lCurNode.Attributes.Item[i].NodeValue;
+ if lAttrName = 'id' then
+ lBrushEntity.Name := lAttrValue
+ else if lAttrName = 'x1' then
+ x1 := lAttrValue
+ else if lAttrName = 'x2' then
+ x2 := lAttrValue
+ else if lAttrName = 'y1' then
+ y1 := lAttrValue
+ else if lAttrName = 'y2' then
+ y2 := lAttrValue;
+ end;
+ if x2 = '0%' then lBrushEntity.Brush.Kind := bkVerticalGradient
+ else lBrushEntity.Brush.Kind := bkHorizontalGradient;
+
+ //
+ //
+ lCurSubNode := lCurNode.FirstChild;
+ while Assigned(lCurSubNode) do
+ begin
+ lNodeName := LowerCase(lCurSubNode.NodeName);
+
+ for i := 0 to lCurSubNode.Attributes.Length - 1 do
+ begin
+ lAttrName := lCurSubNode.Attributes.Item[i].NodeName;
+ lAttrValue := lCurSubNode.Attributes.Item[i].NodeValue;
+ if lAttrName = 'offset' then
+ begin
+ lOffset := StringWithUnitToFloat(lAttrValue);
+ end
+ else if lAttrName = 'style' then
+ ReadSVGStyle(lAttrValue, lBrushEntity);
+ end;
+
+ lCurSubNode := lCurSubNode.NextSibling;
+ end;
+
+ FBrushDefs.Add(lBrushEntity);
+ end;
// Sometime entities are also put in the defs
'circle', 'ellipse', 'g', 'line', 'path',
'polygon', 'polyline', 'rect', 'text', 'use', 'symbol':