mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-09 10:04:51 +01:00
fpvectorial-svg: Structural work for linear gradient support
git-svn-id: trunk@47214 -
This commit is contained in:
parent
acfee8fe08
commit
5969afd322
@ -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 }
|
||||
|
||||
@ -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 id="grad1" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
|
||||
</linearGradient>
|
||||
}
|
||||
'lineargradient':
|
||||
begin
|
||||
lBrushEntity := TvEntityWithPenAndBrush.Create(nil);
|
||||
|
||||
// <linearGradient id="grad1" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
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;
|
||||
|
||||
// <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
|
||||
// <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
|
||||
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':
|
||||
|
||||
Loading…
Reference in New Issue
Block a user