Модератор: Модераторы
procedure TRasterImage.Draw(DestCanvas: TCanvas; const DestRect: TRect);
var
UseMaskHandle: HBitmap;
SrcDC: hDC;
DestDC: hDC;
DstBmp:TBitmap;
RShift, GShift, BShift, AShift, DstRShift, DstGShift, DstBShift:Integer;
RWidth, RHeight:integer;
ix, iy, iyStartByte, dstiyStartByte:integer;
srcdata, dstdata: PByteArray;
tmpdc:HDC;
bmp, old: HBitmap;
msk: HBitmap;
FinishX:Integer;
FinishY:Integer;
DP, SP:integer;
SrcPR, DstPR:byte;
SrcWidthPR,SrcHeightPR:single;
begin
if (Width=0) or (Height=0)
then Exit;
BitmapHandleNeeded;
if not BitmapHandleAllocated then Exit;
if Masked then
UseMaskHandle:=MaskHandle
else
UseMaskHandle:=0;
DestCanvas.Changing;
DestDC := DestCanvas.GetUpdatedHandle([csHandleValid]);
if ((WidgetSet.LCLPlatform = lpGtk) or (WidgetSet.LCLPlatform = lpGtk2)) and
(PixelFormat = pf32bit) and (RawImage.Description.BitsPerPixel = 32) and
(RawImage.Description.Format = ricfRGBA) then
begin
RWidth:= DestRect.Right-DestRect.Left;
RHeight:= DestRect.Bottom-DestRect.Top;
DstBmp := TBitmap.Create;
DstBmp.PixelFormat:=pf32bit;
DstBmp.SetSize(RWidth,RHeight);
DstBmp.Canvas.CopyRect(rect(0,0,DstBmp.Width,DstBmp.Height),DestCanvas,DestRect);
try
srcdata:=PByteArray(RawImage.Data);
dstdata:=PByteArray(DstBmp.RawImage.Data);
RShift:=RawImage.Description.RedShift div 8;
GShift:=RawImage.Description.GreenShift div 8;
BShift:=RawImage.Description.BlueShift div 8;
AShift:=RawImage.Description.AlphaShift div 8;
DstRShift:=DstBmp.RawImage.Description.RedShift div 8;
DstGShift:=DstBmp.RawImage.Description.GreenShift div 8;
DstBShift:=DstBmp.RawImage.Description.BlueShift div 8;
FinishY:=min(rHeight,DstBmp.RawImage.Description.Height);
FinishX:=min(rWidth,DstBmp.RawImage.Description.Width);
if (Height = rHeight)and(Width = rWidth) then
begin
for iy := 0 to FinishY-1 do
begin
iyStartByte := iy*RawImage.Description.Width;
dstiyStartByte := iy*dstBmp.RawImage.Description.Width;
for ix := 0 to FinishX-1 do
begin
DP :=((ix+dstiyStartByte)*4);
SP :=((ix+iyStartByte)*4);
SrcPR:=srcdata^[SP+AShift];
DstPR:=255-SrcPR;
dstdata^[DP+DstRShift]:=((srcdata^[SP+RShift]*SrcPR)+(dstdata^[DP+DstRShift]*DstPR)) div 255;
dstdata^[DP+DstGShift]:=((srcdata^[SP+GShift]*SrcPR)+(dstdata^[DP+DstGShift]*DstPR)) div 255;
dstdata^[DP+DstBShift]:=((srcdata^[SP+BShift]*SrcPR)+(dstdata^[DP+DstBShift]*DstPR)) div 255;
end;
end;
end else
begin
SrcWidthPR:=Width/RWidth;
SrcHeightPR:=Height/RHeight;
for iy := 0 to FinishY-1 do
begin
iyStartByte := trunc(iy*SrcHeightPR)*RawImage.Description.Width;
dstiyStartByte := iy*dstBmp.RawImage.Description.Width;
for ix := 0 to FinishX-1 do
begin
DP :=((ix+dstiyStartByte)*4);
SP :=((trunc(ix*SrcWidthPR)+iyStartByte)*4);
SrcPR:=srcdata^[SP+AShift];
DstPR:=255-SrcPR;
dstdata^[DP+RShift]:=((srcdata^[SP+RShift]*SrcPR)+(dstdata^[DP+RShift]*DstPR))div 255;
dstdata^[DP+GShift]:=((srcdata^[SP+GShift]*SrcPR)+(dstdata^[DP+GShift]*DstPR))div 255;
dstdata^[DP+BShift]:=((srcdata^[SP+BShift]*SrcPR)+(dstdata^[DP+BShift]*DstPR))div 255;
end;
end;
end;
WidgetSet.RawImage_CreateBitmaps(dstBmp.RawImage, bmp, msk, false);
tmpDC := CreateCompatibleDC(DestDC);
old := SelectObject(tmpDC, bmp);
StretchMaskBlt(DestDC, DestRect.Left, DestRect.Top, DstBmp.RawImage.Description.Width, DstBmp.RawImage.Description.Height, TmpDC, 0, 0, DstBmp.RawImage.Description.Width, DstBmp.RawImage.Description.Height,
0, 0,0,DestCanvas.CopyMode);
finally
DeleteObject(SelectObject(tmpDC, old));
DeleteObject(msk);
DeleteDC(tmpDC);
DstBmp.Free;
end;
end else
begin
SrcDC := Canvas.GetUpdatedHandle([csHandleValid]);
StretchMaskBlt(DestDC,
DestRect.Left,DestRect.Top,
DestRect.Right-DestRect.Left,DestRect.Bottom-DestRect.Top,
SrcDC,0,0,Width,Height, UseMaskHandle,0,0,DestCanvas.CopyMode);
end;
DestCanvas.Changed;
end;
carrots писал(а):... под suse, mandriva, debian, под gnome и KDE, везде работает, так что причина наверное в старом lazarus и FPC
Andreich писал(а):Возможно действительно это из-за того, что я использую 0.9.26,..
Logo писал(а):Работает.
Хотя это и не поддерживает идеологию разработчиков, но на данный момент нормальное решение
carrots писал(а):Не в виджетсете написано?
carrots писал(а):В lazarus 9.26 возвращаться нет смысла, так что работает под ним или нет не имеет особого значения.
Интересно они вообще собираются эту проблему решать?
carrots писал(а):Уже 0.2.29 делают, а прозрачности как не было так и нет.
До сих пор приходится патчить.
Интересно они вообще собираются эту проблему решать?
carrots писал(а):Ага, маска ему не понравилась, а с хандела в GTK вытянуть альфу не возможно
Вот более чистый вариант
Заменяем только процедуру TRasterImage.Draw в rasterimage.inc
- Код: Выделить всё
procedure TRasterImage.Draw(DestCanvas: TCanvas; const DestRect: TRect);
var
UseMaskHandle: HBitmap;
SrcDC: hDC;
DestDC: hDC;
DstBmp:TBitmap;
RShift, GShift, BShift, AShift, DstRShift, DstGShift, DstBShift:Integer;
RWidth, RHeight:integer;
ix, iy, iyStartByte, dstiyStartByte:integer;
srcdata, dstdata: PByteArray;
tmpdc:HDC;
bmp, old: HBitmap;
msk: HBitmap;
FinishX:Integer;
FinishY:Integer;
DP, SP:integer;
SrcPR, DstPR:byte;
SrcWidthPR,SrcHeightPR:single;
begin
if (Width=0) or (Height=0)
then Exit;
BitmapHandleNeeded;
if not BitmapHandleAllocated then Exit;
if Masked then
UseMaskHandle:=MaskHandle
else
UseMaskHandle:=0;
DestCanvas.Changing;
DestDC := DestCanvas.GetUpdatedHandle([csHandleValid]);
if ((WidgetSet.LCLPlatform = lpGtk) or (WidgetSet.LCLPlatform = lpGtk2)) and
(PixelFormat = pf32bit) and (RawImage.Description.BitsPerPixel = 32) and
(RawImage.Description.Format = ricfRGBA) then
begin
RWidth:= DestRect.Right-DestRect.Left;
RHeight:= DestRect.Bottom-DestRect.Top;
DstBmp := TBitmap.Create;
DstBmp.PixelFormat:=pf32bit;
DstBmp.SetSize(RWidth,RHeight);
DstBmp.Canvas.CopyRect(rect(0,0,DstBmp.Width,DstBmp.Height),DestCanvas,DestRect);
try
srcdata:=PByteArray(RawImage.Data);
dstdata:=PByteArray(DstBmp.RawImage.Data);
RShift:=RawImage.Description.RedShift div 8;
GShift:=RawImage.Description.GreenShift div 8;
BShift:=RawImage.Description.BlueShift div 8;
AShift:=RawImage.Description.AlphaShift div 8;
DstRShift:=DstBmp.RawImage.Description.RedShift div 8;
DstGShift:=DstBmp.RawImage.Description.GreenShift div 8;
DstBShift:=DstBmp.RawImage.Description.BlueShift div 8;
FinishY:=min(rHeight,DstBmp.RawImage.Description.Height);
FinishX:=min(rWidth,DstBmp.RawImage.Description.Width);
if (Height = rHeight)and(Width = rWidth) then
begin
for iy := 0 to FinishY-1 do
begin
iyStartByte := iy*RawImage.Description.Width;
dstiyStartByte := iy*dstBmp.RawImage.Description.Width;
for ix := 0 to FinishX-1 do
begin
DP :=((ix+dstiyStartByte)*4);
SP :=((ix+iyStartByte)*4);
SrcPR:=srcdata^[SP+AShift];
DstPR:=255-SrcPR;
dstdata^[DP+DstRShift]:=((srcdata^[SP+RShift]*SrcPR)+(dstdata^[DP+DstRShift]*DstPR)) div 255;
dstdata^[DP+DstGShift]:=((srcdata^[SP+GShift]*SrcPR)+(dstdata^[DP+DstGShift]*DstPR)) div 255;
dstdata^[DP+DstBShift]:=((srcdata^[SP+BShift]*SrcPR)+(dstdata^[DP+DstBShift]*DstPR)) div 255;
end;
end;
end else
begin
SrcWidthPR:=Width/RWidth;
SrcHeightPR:=Height/RHeight;
for iy := 0 to FinishY-1 do
begin
iyStartByte := trunc(iy*SrcHeightPR)*RawImage.Description.Width;
dstiyStartByte := iy*dstBmp.RawImage.Description.Width;
for ix := 0 to FinishX-1 do
begin
DP :=((ix+dstiyStartByte)*4);
SP :=((trunc(ix*SrcWidthPR)+iyStartByte)*4);
SrcPR:=srcdata^[SP+AShift];
DstPR:=255-SrcPR;
dstdata^[DP+RShift]:=((srcdata^[SP+RShift]*SrcPR)+(dstdata^[DP+RShift]*DstPR))div 255;
dstdata^[DP+GShift]:=((srcdata^[SP+GShift]*SrcPR)+(dstdata^[DP+GShift]*DstPR))div 255;
dstdata^[DP+BShift]:=((srcdata^[SP+BShift]*SrcPR)+(dstdata^[DP+BShift]*DstPR))div 255;
end;
end;
end;
WidgetSet.RawImage_CreateBitmaps(dstBmp.RawImage, bmp, msk, false);
tmpDC := CreateCompatibleDC(DestDC);
old := SelectObject(tmpDC, bmp);
StretchMaskBlt(DestDC, DestRect.Left, DestRect.Top, DstBmp.RawImage.Description.Width, DstBmp.RawImage.Description.Height, TmpDC, 0, 0, DstBmp.RawImage.Description.Width, DstBmp.RawImage.Description.Height,
0, 0,0,DestCanvas.CopyMode);
finally
DeleteObject(SelectObject(tmpDC, old));
DeleteObject(msk);
DeleteDC(tmpDC);
DstBmp.Free;
end;
end else
begin
SrcDC := Canvas.GetUpdatedHandle([csHandleValid]);
StretchMaskBlt(DestDC,
DestRect.Left,DestRect.Top,
DestRect.Right-DestRect.Left,DestRect.Bottom-DestRect.Top,
SrcDC,0,0,Width,Height, UseMaskHandle,0,0,DestCanvas.CopyMode);
end;
DestCanvas.Changed;
end;
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 33