FAQ - Advanced Topics
This page covers advanced usage scenarios, troubleshooting, and best practices for the SVGIconImageList library.
Architecture and Design
Q. What is the difference between TSVGIconImageList and TSVGIconImageCollection?
A. They serve different purposes in the architecture:
TSVGIconImageList: Self-contained component that stores AND renders SVG icons. Suitable for simple scenarios and all Delphi versions (XE6+). Each image list has its own icon storage.
TSVGIconImageCollection (Delphi 10.3+): Storage-only component that holds SVG icons without rendering. Used with TSVGIconVirtualImageList for rendering. Multiple virtual lists can share one collection, saving memory when you need the same icons at different sizes.
When to use each:
- Use TSVGIconImageList for single-size icon lists, quick prototyping, or Delphi versions before 10.3
- Use TSVGIconImageCollection + TSVGIconVirtualImageList for modern applications needing multiple sizes, centralized management, or memory efficiency
Q. How do the four rendering engines (Image32, Skia, Direct2D, SVGMagic) compare?
A. Here's a detailed comparison:
| Feature | Image32 | Skia4Delphi | Direct2D | SVGMagic |
|---|---|---|---|---|
| Platform | Windows, All | Windows, All | Windows only | Windows only |
| Performance | Good | Excellent | Excellent | Good |
| SVG Compliance | High | Highest | High | Medium |
| Memory Usage | Low | Medium | Low | Low |
| Dependencies | None | Skia DLL | Windows 7+ | SVGMagic DLL |
| Setup Complexity | Easy | Medium | Easy | Medium |
| Best For | General use | High quality | Native Windows | Legacy projects |
Recommendations:
- Image32: Default choice, good all-around performance, no dependencies
- Skia4Delphi: Best rendering quality, cross-platform, worth the setup for production apps
- Direct2D: Excellent for Windows-only apps using modern OS features
- SVGMagic: Available for compatibility, consider migrating to Image32/Skia
Q. Can I switch rendering engines at runtime?
A. Yes, but with limitations:
// Switch global factory
SetGlobalSvgFactory(GetSkiaSVGFactory);
// Existing icons must be reloaded or updated
SVGIconImageList1.RecreateBitmaps;
// New icons will automatically use the new factoryImportant notes:
- Only one engine can be active at a time per application
- Switching engines clears the SVG cache
- Some engine-specific features may not transfer
- Best practice: Choose engine at application startup
Performance Optimization
Q. How can I improve icon rendering performance?
A. Follow these optimization strategies:
1. Use Appropriate Icon Sizes
// Good: Use standard sizes that match UI elements
SVGIconImageList1.Size := 16; // For toolbars
SVGIconImageList2.Size := 32; // For buttons
// Avoid: Constantly changing sizes
for I := 16 to 128 do
SVGIconImageList1.Size := I; // Regenerates bitmaps each time!2. Leverage Bitmap Caching
// Icons are cached after first render
// Requesting the same size again is fast
SVGIconImageList1.Size := 32; // Renders and caches
// ... later ...
SVGIconImageList1.Size := 48; // Renders and caches
// ... later ...
SVGIconImageList1.Size := 32; // Uses cache, very fast!3. Use Virtual ImageLists
// Memory efficient for multiple sizes
SVGIconImageCollection1.LoadFromFiles(Files); // Load once
SmallList.ImageCollection := SVGIconImageCollection1;
SmallList.Size := 16;
LargeList.ImageCollection := SVGIconImageCollection1;
LargeList.Size := 48;
// Storage shared, minimal overhead for multiple sizes4. Avoid Unnecessary Redraws
// Bad: Triggers redraw on each property change
SVGIconImageList1.BeginUpdate;
try
SVGIconImageList1.FixedColor := clBlue;
SVGIconImageList1.Opacity := 200;
SVGIconImageList1.GrayScale := True;
finally
SVGIconImageList1.EndUpdate; // Single redraw
end;5. Preload Icons
procedure TForm1.FormCreate(Sender: TObject);
begin
// Load all icons at startup
SVGIconImageList1.LoadFromFiles(GetAllIconFiles);
// Now switching icons is instant (just bitmap copy)
Button1.ImageIndex := 0; // Fast
Button2.ImageIndex := 1; // Fast
end;Q. My application loads slowly with many SVG icons. How can I improve startup time?
A. Consider these approaches:
1. Lazy Loading
procedure TForm1.LoadIconsOnDemand;
begin
// Don't load all icons at startup
// Load when needed
if not IconsLoaded then
begin
SVGIconImageList1.LoadFromFiles(CommonIcons);
IconsLoaded := True;
end;
end;2. Background Loading
procedure TForm1.LoadIconsInThread;
begin
TTask.Run(
procedure
var
Files: TStringList;
begin
Files := GetAllIconFiles;
TThread.Synchronize(nil,
procedure
begin
SVGIconImageList1.LoadFromFiles(Files);
end
);
end
);
end;3. Use Resource Loading
// Faster than file loading
// Icons embedded in executable
function LoadIconsFromResources: Integer;
begin
Result := 0;
Inc(Result, SVGIconCollection1.LoadFromResource(HInstance, 'ICON_HOME', 'home'));
Inc(Result, SVGIconCollection1.LoadFromResource(HInstance, 'ICON_SETTINGS', 'settings'));
// ... more icons ...
end;4. Optimize SVG Files
- Simplify paths (use SVGO optimizer)
- Remove unnecessary metadata
- Minimize decimal precision
- Remove comments and whitespace
Advanced Styling
Q. How can I implement a complete dark/light theme system?
A. Here's a comprehensive theming approach:
type
TThemeMode = (tmLight, tmDark, tmSystem);
TThemeManager = class
private
FCurrentTheme: TThemeMode;
procedure ApplyThemeToImageList(AImageList: TSVGIconImageListBase; AIsDark: Boolean);
public
procedure SetTheme(ATheme: TThemeMode);
property CurrentTheme: TThemeMode read FCurrentTheme;
end;
procedure TThemeManager.ApplyThemeToImageList(AImageList: TSVGIconImageListBase; AIsDark: Boolean);
begin
AImageList.BeginUpdate;
try
if AIsDark then
begin
AImageList.FixedColor := clWhite;
AImageList.AntiAliasColor := $202020;
AImageList.DisabledOpacity := 100;
end
else
begin
AImageList.FixedColor := clBlack;
AImageList.AntiAliasColor := clWhite;
AImageList.DisabledOpacity := 125;
end;
finally
AImageList.EndUpdate;
end;
end;
procedure TThemeManager.SetTheme(ATheme: TThemeMode);
var
IsDark: Boolean;
Component: TComponent;
begin
// Determine if dark mode
case ATheme of
tmLight: IsDark := False;
tmDark: IsDark := True;
tmSystem: IsDark := IsWindowsDarkModeEnabled; // Implement this
end;
// Apply to all image lists in application
for var I := 0 to Screen.FormCount - 1 do
for var J := 0 to Screen.Forms[I].ComponentCount - 1 do
begin
Component := Screen.Forms[I].Components[J];
if Component is TSVGIconImageListBase then
ApplyThemeToImageList(TSVGIconImageListBase(Component), IsDark);
end;
FCurrentTheme := ATheme;
end;Q. Can I apply different colors to different parts of an SVG icon?
A. The ApplyFixedColorToRootOnly property provides limited control:
// Apply red to root element only
SVGIconImage1.FixedColor := clRed;
SVGIconImage1.ApplyFixedColorToRootOnly := True;For more complex colorization, you need to:
- Modify the SVG source directly:
procedure ColorizeIconParts(Item: TSVGIconItem);
var
SVGText: string;
begin
SVGText := Item.SVGText;
// Replace specific colors in SVG
SVGText := StringReplace(SVGText, 'fill="#000000"', 'fill="#FF0000"', [rfReplaceAll]);
SVGText := StringReplace(SVGText, 'fill="#FFFFFF"', 'fill="#0000FF"', [rfReplaceAll]);
Item.SVGText := SVGText;
end;- Use multiple icon variations:
// Keep separate icons for different color schemes
Collection.Add(RedHomeIcon, 'home-red');
Collection.Add(BlueHomeIcon, 'home-blue');Memory Management
Q. How much memory do SVG icons use compared to PNG bitmaps?
A. Memory usage comparison:
PNG Bitmaps (Traditional ImageList):
16x16 @ 32bpp = 1,024 bytes per icon
32x32 @ 32bpp = 4,096 bytes per icon
64x64 @ 32bpp = 16,384 bytes per icon
128x128 @ 32bpp = 65,536 bytes per icon
For 100 icons at multiple sizes:
100 icons × (1KB + 4KB + 16KB + 64KB) = 8.5 MBSVG Icons (SVGIconImageList):
SVG source text = ~1-5 KB per icon (stored once)
Cached bitmaps = Generated on demand for active size only
For 100 icons:
100 icons × 3KB average = 300 KB (source)
+ Current size bitmaps = 300 KB + 100-6500 KB = ~400KB to 7MB total
Memory savings: Significant when not all sizes are needed simultaneouslyBest Practice:
- Use TSVGIconImageCollection with Virtual ImageLists for maximum efficiency
- Icons stored once, rendered at requested sizes only
- Unused sizes are not kept in memory
Q. How can I reduce memory usage in my application?
A. Strategies to minimize memory footprint:
1. Use Virtual ImageLists
// Instead of multiple TSVGIconImageList instances
// Use one collection with multiple virtual lists
SVGIconImageCollection1.LoadFromFiles(Files); // ~500KB for 100 icons
VirtualList16.ImageCollection := SVGIconImageCollection1; // +100KB
VirtualList32.ImageCollection := SVGIconImageCollection1; // +400KB
VirtualList48.ImageCollection := SVGIconImageCollection1; // +900KB
// Total: ~2MB instead of ~9MB with separate lists2. Clear Unused Icons
// Remove icons no longer needed
SVGIconImageList1.Delete(UnusedIndex);
SVGIconImageList1.ClearIcons; // Remove all3. Optimize SVG Source
// Minimize SVG file size before loading
// Use SVGO or similar optimizer
// Remove unnecessary attributes, comments, metadataTroubleshooting
Q. Icons appear blurry or pixelated. What's wrong?
A. Common causes and solutions:
1. DPI Scaling Issues
// Ensure Scaled property is True
SVGIconImageList1.Scaled := True;
// For DataModules, manually handle DPI
procedure TDataModule1.DataModuleCreate(Sender: TObject);
begin
if Screen.PixelsPerInch <> 96 then
SVGIconImageList1.Size := MulDiv(16, Screen.PixelsPerInch, 96);
end;2. Size Mismatch
// Icons are scaled down/up from rendered size
// Always render at target size for best quality
// Bad: Rendering 16px icons and displaying at 64px
SVGIconImageList1.Size := 16;
LargeButton.Width := 64;
LargeButton.Height := 64;
// Good: Render at display size
SVGIconImageList1.Size := 64;3. AntiAlias Color
// AntiAliasColor should match background
// Wrong antialiasing causes edge artifacts
Panel1.Color := clBlack;
SVGIconImageList1.AntiAliasColor := clBlack; // Match panel colorQ. Some icons display incorrectly or not at all. How can I debug this?
A. Diagnostic steps:
1. Check SVG Validity
procedure TestSVGLoading(const AFileName: string);
var
SVG: ISVG;
begin
SVG := GlobalSVGFactory.NewSvg;
try
SVG.LoadFromFile(AFileName);
if SVG.IsEmpty then
ShowMessage('SVG is empty or failed to load')
else
ShowMessage(Format('SVG loaded: %.0fx%.0f', [SVG.Width, SVG.Height]));
except
on E: Exception do
ShowMessage('Error loading SVG: ' + E.Message);
end;
end;2. Try Different Engines
// Test with Image32
SetGlobalSvgFactory(GetImage32SVGFactory);
TestIcon;
// Test with Skia
SetGlobalSvgFactory(GetSkiaSVGFactory);
TestIcon;
// Different engines have different SVG feature support3. Examine SVG Source
// Check for unsupported features
var Item := SVGIconImageList1.SVGIconItems[0];
Memo1.Lines.Text := Item.SVGText;
// Common issues:
// - External references (<use xlink:href="">)
// - Unsupported filters
// - Complex gradients
// - Embedded images4. Simplify SVG
// Optimize SVG using online tools:
// - SVGO: https://jakearchibald.github.io/svgomg/
// - Removes unnecessary attributes
// - Simplifies paths
// - Improves compatibilityQ. Can I use icon fonts instead of SVG files?
A. The library is specifically designed for SVG files, not icon fonts. However, you can:
Convert icon fonts to SVG using tools like:
- IcoMoon (export as SVG)
- FontForge (export glyphs)
- Online converters
Use dedicated icon font libraries for VCL/FMX that support fonts directly
Advantages of SVG over icon fonts:
- Multi-color support
- Complex shapes and gradients
- No font installation required
- Better for custom graphics
- Easier to edit and customize
Q. How do I handle SVG icons in a multi-language application?
A. Approaches for internationalization:
1. Language-Specific Icons
procedure TForm1.LoadLocalizedIcons;
var
LangCode: string;
IconPath: string;
begin
LangCode := GetCurrentLanguage; // 'en', 'it', 'fr', etc.
IconPath := Format('icons\%s\', [LangCode]);
SVGIconImageList1.LoadFromFiles(GetFilesInPath(IconPath));
end;2. Dynamic Text Replacement
// For icons containing text elements
procedure UpdateIconText(Item: TSVGIconItem; const AText: string);
var
SVGText: string;
begin
SVGText := Item.SVGText;
// Replace text in <text> elements
SVGText := ReplaceTextInSVG(SVGText, AText);
Item.SVGText := SVGText;
end;3. Fallback Icons
procedure LoadIconWithFallback(const ALocalizedName, ADefaultName: string);
begin
if FileExists(GetLocalizedIconPath(ALocalizedName)) then
LoadIcon(GetLocalizedIconPath(ALocalizedName))
else
LoadIcon(GetDefaultIconPath(ADefaultName));
end;Best Practices
Q. What are the recommended best practices for using SVG icons in production applications?
A. Follow these guidelines:
1. Standardize Icon Sizes
// Define standard sizes for consistency
const
ICON_SIZE_SMALL = 16;
ICON_SIZE_MEDIUM = 24;
ICON_SIZE_LARGE = 32;
ICON_SIZE_XLARGE = 48;
// Use throughout application
ToolBar1.Images.Size := ICON_SIZE_SMALL;
Ribbon1.Images.Size := ICON_SIZE_LARGE;2. Organize Icons with Categories
// Use consistent naming
Collection.Add(HomeIcon, 'home', 'Navigation');
Collection.Add(BackIcon, 'back', 'Navigation');
Collection.Add(SaveIcon, 'save', 'Actions');
Collection.Add(DeleteIcon, 'delete', 'Actions');3. Centralize Icon Management
// Create a DataModule for shared icons
type
TdmIcons = class(TDataModule)
IconCollection: TSVGIconImageCollection;
VirtualImageList16: TSVGIconVirtualImageList;
VirtualImageList32: TSVGIconVirtualImageList;
procedure DataModuleCreate(Sender: TObject);
end;
// Use throughout application
Button1.Images := dmIcons.VirtualImageList16;4. Version Control SVG Files
- Store original SVG files in source control
- Keep optimized versions separately
- Document any manual modifications
- Use consistent file naming conventions
5. Test Across DPI Settings
// Test at different DPI scales
// Windows: 100%, 125%, 150%, 200%
// Ensure icons remain sharp at all scales6. Implement Graceful Fallbacks
procedure LoadIconSafely(Item: TSVGIconItem; const AFileName: string);
begin
try
Item.SVG.LoadFromFile(AFileName);
except
// Load default placeholder icon
Item.SVG.Source := GetDefaultIconSVG;
end;
end;