ADD: SVG icon theme support in Qt version

This commit is contained in:
Alexander Koblov 2014-02-13 15:16:32 +00:00
commit 45efa97049
3 changed files with 64 additions and 45 deletions

View file

@ -4,7 +4,7 @@
Simple implementation of Icon Theme based on FreeDesktop.org specification
(http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html)
Copyright (C) 2009-2011 Koblov Alexander (Alexx2000@mail.ru)
Copyright (C) 2009-2014 Alexander Koblov (alexx2000@mail.ru)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -83,6 +83,7 @@ type
function DirectoryMatchesSize(SubDirIndex: Integer; AIconSize: Integer): Boolean;
function DirectorySizeDistance(SubDirIndex: Integer; AIconSize: Integer): Integer;
class function CutTrailingExtension(const AIconName: String): String;
class procedure RegisterExtension(const AExtension: String);
property ThemeName: String read FThemeName;
property Directories: TIconDirList read FDirectories;
end;
@ -90,10 +91,10 @@ type
implementation
uses
LCLProc, StrUtils, uDebug, uFindEx, DCOSUtils, DCStrUtils;
LCLProc, StrUtils, uDebug, uFindEx, DCBasicTypes, DCOSUtils, DCStrUtils;
const
IconExtensionList: array[0..1] of String = ('png', 'xpm');
var
IconExtensionList: TDynamicStringArray;
{ TIconTheme }
@ -459,6 +460,18 @@ begin
Result := AIconName;
end;
class procedure TIconTheme.RegisterExtension(const AExtension: String);
var
I: Integer;
ExtList: TDynamicStringArray;
begin
ExtList:= SplitString(AExtension, ';');
for I:= Low(ExtList) to High(ExtList) do
begin
AddString(IconExtensionList, ExtList[I]);
end;
end;
{ TIconDirList }
function TIconDirList.Add(IconDirName: String; IconDirInfo: PIconDirInfo): Integer;
@ -489,4 +502,8 @@ begin
inherited Destroy;
end;
initialization
AddString(IconExtensionList, 'png');
AddString(IconExtensionList, 'xpm');
end.

View file

@ -51,17 +51,14 @@ type
class function GetFileExtensions: string; override;
end;
{ TBitmapHelper }
TBitmapHelper = class helper for TBitmap
public
procedure LoadFromScalable(const FileName: String; AWidth, AHeight: Integer);
end;
function BitmapLoadFromScalable(const FileName: String; AWidth, AHeight: Integer): TBitmap;
implementation
uses
DynLibs, IntfGraphics, GraphType, Types, CTypes, LazUTF8, DCOSUtils, uThumbnails;
DynLibs, IntfGraphics, GraphType, Types, CTypes, LazUTF8, DCOSUtils,
uThumbnails, uIconTheme;
type
cairo_format_t = (
@ -147,6 +144,39 @@ begin
end;
end;
function BitmapLoadFromScalable(const FileName: String; AWidth, AHeight: Integer): TBitmap;
var
Cairo: Pcairo_t;
RsvgHandle: Pointer;
Image: TLazIntfImage;
CairoSurface: Pcairo_surface_t;
RsvgDimensionData: TRsvgDimensionData;
begin
Result:= nil;
RsvgHandle:= rsvg_handle_new_from_file(PAnsiChar(UTF8ToSys(FileName)), nil);
if Assigned(RsvgHandle) then
begin
Image:= TLazIntfImage.Create(AWidth, AHeight);
try
// Get the SVG's size
rsvg_handle_get_dimensions(RsvgHandle, @RsvgDimensionData);
// Creates an image surface of the specified format and dimensions
CairoSurface:= cairo_image_surface_create(CAIRO_FORMAT_ARGB32, Image.Width, Image.Height);
Cairo:= cairo_create(CairoSurface);
// Scale image if needed
if (Image.Width <> RsvgDimensionData.width) or (Image.Height <> RsvgDimensionData.height) then
begin
cairo_scale(Cairo, Image.Width / RsvgDimensionData.width, Image.Height / RsvgDimensionData.height);
end;
RsvgHandleRender(RsvgHandle, CairoSurface, Cairo, Image);
Result:= TBitmap.Create;
Result.LoadFromIntfImage(Image);
finally
Image.Free;
end;
end;
end;
function GetThumbnail(const aFileName: UTF8String; aSize: TSize): Graphics.TBitmap;
var
Scale: Boolean;
@ -240,40 +270,6 @@ begin
Result:= 'svg;svgz';
end;
{ TBitmapHelper }
procedure TBitmapHelper.LoadFromScalable(const FileName: String; AWidth,
AHeight: Integer);
var
Cairo: Pcairo_t;
RsvgHandle: Pointer;
Image: TLazIntfImage;
CairoSurface: Pcairo_surface_t;
RsvgDimensionData: TRsvgDimensionData;
begin
RsvgHandle:= rsvg_handle_new_from_file(PAnsiChar(UTF8ToSys(FileName)), nil);
if Assigned(RsvgHandle) then
begin
Image:= TLazIntfImage.Create(AWidth, AHeight);
try
// Get the SVG's size
rsvg_handle_get_dimensions(RsvgHandle, @RsvgDimensionData);
// Creates an image surface of the specified format and dimensions
CairoSurface:= cairo_image_surface_create(CAIRO_FORMAT_ARGB32, Image.Width, Image.Height);
Cairo:= cairo_create(CairoSurface);
// Scale image if needed
if (Image.Width <> RsvgDimensionData.width) or (Image.Height <> RsvgDimensionData.height) then
begin
cairo_scale(Cairo, Image.Width / RsvgDimensionData.width, Image.Height / RsvgDimensionData.height);
end;
RsvgHandleRender(RsvgHandle, CairoSurface, Cairo, Image);
LoadFromIntfImage(Image);
finally
Image.Free;
end;
end;
end;
const
cairolib = 'libcairo.so.2';
rsvglib = 'librsvg-2.so.2';
@ -307,6 +303,7 @@ begin
g_type_init();
// Register image handler and format
TIconTheme.RegisterExtension('svg;svgz');
TThumbnailManager.RegisterProvider(@GetThumbnail);
ImageHandlers.RegisterImageReader ('Scalable Vector Graphics', 'SVG;SVGZ', TDCReaderSVG);
TPicture.RegisterFileFormat('svg;svgz', 'Scalable Vector Graphics', TScalableVectorGraphics);

View file

@ -987,7 +987,12 @@ begin
{$ELSE}
sIconFileName:= FIconTheme.FindIcon(AIconName, AIconSize);
if sIconFileName <> EmptyStr then
Result := CheckLoadPixmapFromFile(sIconFileName);
begin
if TScalableVectorGraphics.IsFileExtensionSupported(ExtractFileExt(sIconFileName)) then
Result := BitmapLoadFromScalable(sIconFileName, AIconSize, AIconSize)
else
Result := CheckLoadPixmapFromFile(sIconFileName);
end;
{$ENDIF}
if not Assigned(Result) then
{$ENDIF}