Sometimes you want to be able to change an SVG element's appearance and rapidly redraw only that element. By using the TSVGDocument.DrawBeforeElement method and the TSVGDocument.DrawAfterElement methods, you can draw the "background" and "foreground" for an element to bitmap buffers. Then, when a SVG element changes, you just draw the background bitmap, call TSVGDocument.DrawElement for the changing element, and then draw the foreground bitmap.
The following example uses the DrawBeforeElement, DrawElement, and DrawAfterElement methods to optimize the drawing of an SVG where one element may be changed often (such as in an editor):
procedure TfrmSVGEditor.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
var
aRect: TSVGRect;
begin
// do we need to update the background (elements before) and foreground (elements
// after) the current Element. By creating a bitmap of the background and
// foreground, we can optimize the drawing of the SVG as the current Element
// changes
if UpdateBackground then
begin
// draw background and foreground
Background.Canvas.BeginScene;
try
Background.Clear(TAlphaColorRec.Null);
if Element is TSVGGraphicElement then
SVG.DrawBeforeElement(TSVGGraphicElement(Element), Background.Canvas, RectF(0,0,Background.Width, Background.Height));
finally
Background.Canvas.EndScene;
end;
Foreground.Canvas.BeginScene;
try
Foreground.Clear(TAlphaColorRec.Null);
if Element is TSVGGraphicElement then
SVG.DrawAfterElement(TSVGGraphicElement(Element), Foreground.Canvas, RectF(0,0,Foreground.Width, Foreground.Height));
finally
Foreground.Canvas.EndScene;
end;
FUpdateBackground := False;
end;
if Element is TSVGGraphicElement then
begin
// if current Element is a graphical element, draw the background
aRect := RectF(0, 0, Background.Width, Background.Height);
Canvas.DrawBitmap(Background, aRect, aRect, 1);
// draw the element
SVG.DrawElement(TSVGGraphicElement(Element), Canvas, PaintBox1.ClipRect);
// draw the foreground
Canvas.DrawBitmap(Foreground, aRect, aRect, 1);
end
else
// just draw the entire SVG without any background/foreground caching
SVG.Draw(Canvas, PaintBox1.ClipRect);
// draw the focus rectangle
Canvas.DrawFocusRect(SelectRect);
end;
The SVGEditorFMX demo project uses this technique to provide rapid response to user changes.
|