mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-08 11:58:12 +02:00
lcl: apply Mark patch
- CreateCompatibleBitmaps - separate MaskHandleNeeded of icon from BitmapHandleNeeded - simplify TRasterImage.BitmapHandleNeeded from me: - fix TRawImageLineStarts.GetPosition git-svn-id: trunk@16262 -
This commit is contained in:
parent
09225df31f
commit
d173c2f1ae
@ -12,7 +12,7 @@
|
||||
* *
|
||||
* This file is part of the Lazarus Component Library (LCL) *
|
||||
* *
|
||||
* See the file COPYING.modifiedLGPL.txt, included in this distribution, *
|
||||
* See the file COPYING.modifiedLGPL.txt, included in this distribution, *
|
||||
* for details about the copyright. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
@ -1892,6 +1892,76 @@ begin
|
||||
CB.Free;
|
||||
end;
|
||||
|
||||
//TODO: publish ?? (as RawImage_CreateCompatibleBitmaps)
|
||||
function CreateCompatibleBitmaps(const ARawImage: TRawImage; out ABitmap, AMask: HBitmap; ASkipMask: Boolean = False): Boolean;
|
||||
var
|
||||
Desc: TRawImageDescription absolute ARawimage.Description;
|
||||
|
||||
ImgHandle, ImgMaskHandle: HBitmap;
|
||||
ImagePtr: PRawImage;
|
||||
DevImage: TRawImage;
|
||||
DevDesc: TRawImageDescription;
|
||||
SrcImage, DstImage: TLazIntfImage;
|
||||
QueryFlags: TRawImageQueryFlags;
|
||||
W, H: Integer;
|
||||
begin
|
||||
ImgMaskHandle := 0;
|
||||
|
||||
W := Desc.Width;
|
||||
if W < 1 then W := 1;
|
||||
H := Desc.Height;
|
||||
if H < 1 then H := 1;
|
||||
|
||||
if Desc.Depth = 1
|
||||
then QueryFlags := [riqfMono]
|
||||
else QueryFlags := [riqfRGB];
|
||||
if Desc.AlphaPrec <> 0
|
||||
then Include(QueryFlags, riqfAlpha);
|
||||
if Desc.MaskBitsPerPixel <> 0
|
||||
then Include(QueryFlags, riqfMask);
|
||||
QueryDescription(DevDesc, QueryFlags, W, H);
|
||||
|
||||
if DevDesc.IsEqual(Desc)
|
||||
then begin
|
||||
// image is compatible, so use it
|
||||
DstImage := nil;
|
||||
ImagePtr := @ARawImage;
|
||||
end
|
||||
else begin
|
||||
// create compatible copy
|
||||
SrcImage := TLazIntfImage.Create(ARawImage, False);
|
||||
DstImage := TLazIntfImage.Create(0, 0);
|
||||
// create mask for alphachannel when device has no alpha support
|
||||
if (DevDesc.AlphaPrec = 0) and (riqfAlpha in QueryFlags)
|
||||
then begin
|
||||
//add mask if not already queried
|
||||
if not (riqfMask in QueryFlags)
|
||||
then QueryDescription(DevDesc, [riqfMask, riqfUpdate]);
|
||||
DstImage.DataDescription := DevDesc;
|
||||
DstImage.CopyPixels(SrcImage, 0, 0, True, $8000);
|
||||
end
|
||||
else begin
|
||||
DstImage.DataDescription := DevDesc;
|
||||
DstImage.CopyPixels(SrcImage);
|
||||
end;
|
||||
SrcImage.Free;
|
||||
DstImage.GetRawImage(DevImage);
|
||||
ImagePtr := @DevImage;
|
||||
end;
|
||||
|
||||
try
|
||||
Result := RawImage_CreateBitmaps(ImagePtr^, ImgHandle, ImgMaskHandle, ASkipMask);
|
||||
if not Result then Exit;
|
||||
|
||||
ABitmap := ImgHandle;
|
||||
if not ASkipMask
|
||||
then AMask := ImgMaskHandle;
|
||||
finally
|
||||
DstImage.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure Register;
|
||||
begin
|
||||
RegisterClasses([TBitmap,TPixmap,TPortableNetworkGraphic,
|
||||
|
206
lcl/graphtype.pp
206
lcl/graphtype.pp
@ -1572,7 +1572,7 @@ var
|
||||
BitOffset: Cardinal;
|
||||
begin
|
||||
if FLineOrder = riloBottomToTop then
|
||||
y := FHeight - y;
|
||||
y := FHeight - y - 1;
|
||||
Result := Positions[y];
|
||||
BitOffset := x * FBitsPerPixel + Result.Bit;
|
||||
Result.Bit := BitOffset and 7;
|
||||
@ -1622,210 +1622,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{$ifdef OldRawImageProcs}
|
||||
function RawImageMaskIsEmpty(RawImage: PRawImage; TestPixels: boolean): boolean;
|
||||
begin
|
||||
Result := not RawImage^.IsMasked(TestPixels);
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
{$ifdef OldRawImageProcs}
|
||||
function RawImageDescriptionAsString(Desc: PRawImageDescription): string;
|
||||
begin
|
||||
Result := Desc^.AsString;
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
{$ifdef OldRawImageProcs}
|
||||
procedure FreeRawImageData(RawImage: PRawImage);
|
||||
begin
|
||||
RawImage^.FreeData;
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
{$ifdef OldRawImageProcs}
|
||||
procedure ReleaseRawImageData(RawImage: PRawImage);
|
||||
begin
|
||||
RawImage^.ReleaseData;
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
{-------------------------------------------------------------------------------
|
||||
Beware: Data is used in ReallocMem
|
||||
|
||||
-------------------------------------------------------------------------------}
|
||||
{$ifdef OldRawImageProcs}
|
||||
procedure CreateRawImageData(Width, Height, BitsPerPixel: cardinal;
|
||||
LineEnd: TRawImageLineEnd; var Data: Pointer; var DataSize: PtrUInt);
|
||||
var
|
||||
PixelCount: PtrUInt;
|
||||
BitsPerLine: PtrUInt;
|
||||
DataBits: QWord;
|
||||
begin
|
||||
// get current size
|
||||
PixelCount:=Width*Height;
|
||||
if PixelCount=0 then exit;
|
||||
|
||||
// calculate BitsPerLine
|
||||
BitsPerLine:=GetBitsPerLine(Width,BitsPerPixel,LineEnd);
|
||||
|
||||
// create pixels
|
||||
DataBits:=QWord(BitsPerLine)*Height;
|
||||
DataSize:=cardinal((DataBits+7) shr 3);
|
||||
ReAllocMem(Data,DataSize);
|
||||
FillChar(Data^,DataSize,0);
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
{$ifdef OldRawImageProcs}
|
||||
procedure CreateRawImageDescFromMask(SrcRawImageDesc,
|
||||
DestRawImageDesc: PRawImageDescription);
|
||||
begin
|
||||
// original code raises an exception, imo it is perfectly valid
|
||||
// to create a black image (MWE)
|
||||
if (SrcRawImageDesc^.MaskBitsPerPixel = 0) then
|
||||
RaiseGDBException('CreateRawImageFromMask Alpha not separate');
|
||||
|
||||
DestRawImageDesc^ := SrcRawImageDesc^.GetDescriptionFromMask;
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
{$ifdef OldRawImageProcs}
|
||||
procedure GetRawImageXYPosition(RawImageDesc: PRawImageDescription;
|
||||
LineStarts: PRawImagePosition; x, y: cardinal;
|
||||
var Position: TRawImagePosition);
|
||||
var
|
||||
BitOffset: cardinal;
|
||||
begin
|
||||
if RawImageDesc^.LineOrder=riloBottomToTop then
|
||||
y:=RawImageDesc^.Height-y;
|
||||
Position:=LineStarts[y];
|
||||
BitOffset:=RawImageDesc^.BitsPerPixel*cardinal(x)+Position.Bit;
|
||||
Position.Bit:=(BitOffset and 7);
|
||||
inc(Position.Byte,BitOffset shr 3);
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
{$ifdef OldRawImageProcs}
|
||||
procedure ExtractRawImageRect(SrcRawImage: PRawImage; const SrcRect: TRect;
|
||||
DestRawImage: PRawImage);
|
||||
begin
|
||||
SrcRawImage^.ExtractRect(SrcRect, DestRawImage^);
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
{$ifdef OldRawImageProcs}
|
||||
procedure CreateRawImageLineStarts(Width, Height, BitsPerPixel: cardinal;
|
||||
LineEnd: TRawImageLineEnd; var LineStarts: PRawImagePosition);
|
||||
// LineStarts is recreated, so make sure it is nil or a valid mem
|
||||
var
|
||||
PixelCount: cardinal;
|
||||
BitsPerLine: cardinal;
|
||||
CurLine: cardinal;
|
||||
BytesPerLine: cardinal;
|
||||
ExtraBitsPerLine: cardinal;
|
||||
CurBitOffset: cardinal;
|
||||
begin
|
||||
// get current size
|
||||
PixelCount:=Width*Height;
|
||||
if PixelCount=0 then exit;
|
||||
|
||||
// calculate BitsPerLine, BytesPerLine and ExtraBitsPerLine
|
||||
BitsPerLine:=GetBitsPerLine(Width,BitsPerPixel,LineEnd);
|
||||
BytesPerLine:=BitsPerLine shr 3;
|
||||
ExtraBitsPerLine:=BitsPerLine and 7;
|
||||
|
||||
// create line start array
|
||||
ReAllocMem(LineStarts,Height*SizeOf(TRawImagePosition));
|
||||
LineStarts[0].Byte:=0;
|
||||
LineStarts[0].Bit:=0;
|
||||
for CurLine:=1 to Height-1 do begin
|
||||
CurBitOffset:=LineStarts[CurLine-1].Bit+ExtraBitsPerLine;
|
||||
LineStarts[CurLine].Byte:=LineStarts[CurLine-1].Byte+BytesPerLine
|
||||
+(CurBitOffset shr 3);
|
||||
LineStarts[CurLine].Bit:=CurBitOffset and 7;
|
||||
end;
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
{$ifdef OldRawImageProcs}
|
||||
procedure ReadRawImageBits(TheData: PByte;
|
||||
const Position: TRawImagePosition;
|
||||
BitsPerPixel, Prec, Shift: cardinal; BitOrder: TRawImageBitOrder;
|
||||
var Bits: word);
|
||||
begin
|
||||
RawImage_ReadBits(TheData, Position, BitsPerPixel, Prec, Shift, BitOrder, Bits);
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
{$ifdef OldRawImageProcs}
|
||||
procedure WriteRawImageBits(TheData: PByte;
|
||||
const Position: TRawImagePosition;
|
||||
BitsPerPixel, Prec, Shift: cardinal; BitOrder: TRawImageBitOrder; Bits: word);
|
||||
begin
|
||||
RawImage_WriteBits(TheData, Position, BitsPerPixel, Prec, Shift, BitOrder, Bits);
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
{$ifdef OldRawImageProcs}
|
||||
procedure ReAlignRawImageLines(var Data: Pointer; var Size: PtrUInt;
|
||||
Width, Height, BitsPerPixel: cardinal;
|
||||
var OldLineEnd: TRawImageLineEnd; NewLineEnd: TRawImageLineEnd);
|
||||
var
|
||||
OldBytesPerLine: PtrUInt;
|
||||
OldSize: PtrUInt;
|
||||
NewBytesPerLine: PtrUInt;
|
||||
NewSize: PtrUInt;
|
||||
y: Integer;
|
||||
OldPos: Pointer;
|
||||
NewPos: Pointer;
|
||||
begin
|
||||
if OldLineEnd=NewLineEnd then exit;
|
||||
if (Width=0) or (Height=0) then exit;
|
||||
OldBytesPerLine:=GetBytesPerLine(Width,BitsPerPixel,OldLineEnd);
|
||||
OldSize:=OldBytesPerLine*PtrUInt(Height);
|
||||
if OldSize<>Size then
|
||||
RaiseGDBException('ReAlignRawImageLines OldSize<>Size');
|
||||
NewBytesPerLine:=GetBytesPerLine(Width,BitsPerPixel,NewLineEnd);
|
||||
NewSize:=NewBytesPerLine*PtrUInt(Height);
|
||||
//DebugLn(['ReAlignRawImageLines OldBytesPerLine=',OldBytesPerLine,' NewBytesPerLine=',NewBytesPerLine]);
|
||||
|
||||
// enlarge before
|
||||
if OldSize<NewSize then
|
||||
ReAllocMem(Data,NewSize);
|
||||
|
||||
// move data
|
||||
OldPos:=Data;
|
||||
NewPos:=Data;
|
||||
if OldBytesPerLine>NewBytesPerLine then begin
|
||||
// compress
|
||||
for y:=0 to Height-1 do begin
|
||||
System.Move(OldPos^,NewPos^,NewBytesPerLine);
|
||||
inc(OldPos,OldBytesPerLine);
|
||||
inc(NewPos,NewBytesPerLine);
|
||||
end;
|
||||
end else begin
|
||||
// expand
|
||||
inc(OldPos,OldSize);
|
||||
inc(NewPos,NewSize);
|
||||
for y:=Height-1 downto 0 do begin
|
||||
dec(OldPos,OldBytesPerLine);
|
||||
dec(NewPos,NewBytesPerLine);
|
||||
System.Move(OldPos^,NewPos^,OldBytesPerLine);
|
||||
end;
|
||||
end;
|
||||
|
||||
// shrink after
|
||||
if OldSize>NewSize then
|
||||
ReAllocMem(Data,NewSize);
|
||||
|
||||
Size:=NewSize;
|
||||
OldLineEnd:=NewLineEnd;
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
procedure InternalInit;
|
||||
var
|
||||
|
@ -534,9 +534,24 @@ begin
|
||||
end;
|
||||
|
||||
procedure TCustomIcon.MaskHandleNeeded;
|
||||
var
|
||||
ImgHandle, dummy: HBITMAP;
|
||||
begin
|
||||
// Created by bitmaphandle
|
||||
BitmapHandleNeeded;
|
||||
//!!! BitmapHandleNeeded;
|
||||
|
||||
if FCurrent = -1 then Exit;
|
||||
if MaskHandleAllocated then exit;
|
||||
|
||||
if not CreateCompatibleBitmaps(GetRawImagePtr^, Dummy, ImgHandle)
|
||||
then begin
|
||||
DebugLn('TCustomIcon.MaskHandleNeeded: Unable to create makshandle');
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if BitmapHandleAllocated
|
||||
then UpdateHandles(BitmapHandle, ImgHandle)
|
||||
else UpdateHandles(0, ImgHandle);
|
||||
end;
|
||||
|
||||
function TCustomIcon.PaletteAllocated: boolean;
|
||||
|
@ -170,9 +170,7 @@ procedure TRasterImage.BitmapHandleNeeded;
|
||||
var
|
||||
ImgHandle, ImgMaskHandle: HBitmap;
|
||||
ImagePtr: PRawImage;
|
||||
DevImage: TRawImage;
|
||||
DevDesc: TRawImageDescription;
|
||||
SrcImage, DstImage: TLazIntfImage;
|
||||
QueryFlags: TRawImageQueryFlags;
|
||||
W, H: Integer;
|
||||
SkipMask: Boolean;
|
||||
@ -180,77 +178,41 @@ begin
|
||||
if BitmapHandleAllocated then exit;
|
||||
|
||||
ImagePtr := GetRawImagePtr;
|
||||
if ImagePtr = nil then Exit;
|
||||
|
||||
ImgMaskHandle := 0;
|
||||
|
||||
// create a device compatible image
|
||||
W := Width;
|
||||
if W < 1 then W := 1;
|
||||
H := Height;
|
||||
if H < 1 then H := 1;
|
||||
// we must skip mask creation if
|
||||
// a) we already have mask
|
||||
// b) mask needs to be created another way - using TransparentColor
|
||||
SkipMask := MaskHandleAllocated
|
||||
or (TransparentMode = tmFixed)
|
||||
or (ImagePtr^.Description.MaskBitsPerPixel = 0);
|
||||
|
||||
if ImagePtr^.Description.Depth = 1
|
||||
then QueryFlags := [riqfMono]
|
||||
else QueryFlags := [riqfRGB];
|
||||
if ImagePtr^.Description.AlphaPrec <> 0
|
||||
then Include(QueryFlags, riqfAlpha);
|
||||
if ImagePtr^.Description.MaskBitsPerPixel <> 0
|
||||
then Include(QueryFlags, riqfMask);
|
||||
QueryDescription(DevDesc, QueryFlags, W, H);
|
||||
|
||||
if DevDesc.IsEqual(ImagePtr^.Description)
|
||||
if not CreateCompatibleBitmaps(ImagePtr^, ImgHandle, ImgMaskHandle, SkipMask)
|
||||
then begin
|
||||
// image is compatible, so use it
|
||||
DstImage := nil;
|
||||
end
|
||||
else begin
|
||||
// create compatible copy
|
||||
SrcImage := TLazIntfImage.Create(ImagePtr^, False);
|
||||
DstImage := TLazIntfImage.Create(0, 0);
|
||||
// create mask for alphachannel when device has no alpha support
|
||||
if (DevDesc.AlphaPrec = 0) and (riqfAlpha in QueryFlags)
|
||||
then begin
|
||||
//add mask if not already queried
|
||||
if not (riqfMask in QueryFlags)
|
||||
then QueryDescription(DevDesc, [riqfMask, riqfUpdate]);
|
||||
DstImage.DataDescription := DevDesc;
|
||||
DstImage.CopyPixels(SrcImage, 0, 0, True, $8000);
|
||||
end
|
||||
else begin
|
||||
DstImage.DataDescription := DevDesc;
|
||||
DstImage.CopyPixels(SrcImage);
|
||||
end;
|
||||
SrcImage.Free;
|
||||
DstImage.GetRawImage(DevImage);
|
||||
ImagePtr := @DevImage;
|
||||
DebugLn('TRasterImage.BitmapHandleNeeded: Unable to create handles, using default');
|
||||
// create a default handle
|
||||
W := Width;
|
||||
if W < 1 then W := 1;
|
||||
H := Height;
|
||||
if H < 1 then H := 1;
|
||||
|
||||
if ImagePtr^.Description.Depth = 1
|
||||
then QueryFlags := [riqfMono]
|
||||
else QueryFlags := [riqfRGB];
|
||||
if ImagePtr^.Description.AlphaPrec <> 0
|
||||
then Include(QueryFlags, riqfAlpha);
|
||||
if ImagePtr^.Description.MaskBitsPerPixel <> 0
|
||||
then Include(QueryFlags, riqfMask);
|
||||
QueryDescription(DevDesc, QueryFlags, W, H);
|
||||
ImgHandle := CreateDefaultBitmapHandle(DevDesc);
|
||||
end;
|
||||
|
||||
try
|
||||
// we must skip mask creation if
|
||||
// a) we already have mask
|
||||
// b) mask needs to be created another way - using TransparentColor
|
||||
// c) we dont have mask in the description
|
||||
SkipMask := MaskHandleAllocated or
|
||||
(TransparentMode = tmFixed) or
|
||||
(DevDesc.MaskBitsPerPixel = 0);
|
||||
if not RawImage_CreateBitmaps(ImagePtr^, ImgHandle, ImgMaskHandle, SkipMask)
|
||||
then begin
|
||||
DebugLn('TRasterImage.BitmapHandleNeeded: Unable to create handles, using default');
|
||||
// create a default handle
|
||||
ImgHandle := CreateDefaultBitmapHandle(DevDesc);
|
||||
end;
|
||||
|
||||
if SkipMask
|
||||
then begin
|
||||
// if we dont have new mask then either use old one or use none
|
||||
if MaskHandleAllocated
|
||||
then UpdateHandles(ImgHandle, MaskHandle)
|
||||
else UpdateHandles(ImgHandle, 0);
|
||||
end
|
||||
else UpdateHandles(ImgHandle, ImgMaskHandle);
|
||||
|
||||
finally
|
||||
DstImage.Free;
|
||||
end;
|
||||
// if we dont have new mask then either use old one or use none
|
||||
if SkipMask and MaskHandleAllocated
|
||||
then UpdateHandles(ImgHandle, MaskHandle)
|
||||
else UpdateHandles(ImgHandle, ImgMaskHandle);
|
||||
end;
|
||||
|
||||
function TRasterImage.CanShareImage(AClass: TSharedRasterImageClass): Boolean;
|
||||
|
Loading…
Reference in New Issue
Block a user