uFastBitmap.pas 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048
  1. Unit uFastBitmap;
  2. (*==============================================================================
  3. DESCRIPTION : Classe de manipulation basique de bitmap en 32 bit.
  4. Basic Class for manipulating 32 bit Bitmap
  5. DATE : 17/06/2018
  6. VERSION : 1.0
  7. AUTEUR : J.Delauney (BeanzMaster)
  8. LICENCE : MPL
  9. ================================================================================
  10. *)
  11. {$mode objfpc}{$H+}
  12. {$modeswitch advancedrecords}
  13. Interface
  14. Uses
  15. LCLType, LCLIntf, Classes, SysUtils, GraphType, Graphics, Contnrs, Dialogs,
  16. IntfGraphics, FPimage;
  17. Const
  18. { Constantes utiles pour le calcul sur les masques de couleur }
  19. { Useful constants for calculation on color masks }
  20. {$IFDEF WINDOWS} // Format BGRA
  21. cBlueOrder = 0;
  22. cGreenOrder = 1;
  23. cRedOrder = 2;
  24. cAlphaOrder = 3;
  25. {$ELSE} // Format RGBA
  26. cRedOrder = 0;
  27. cGreenOrder = 1;
  28. cBlueOrder = 2;
  29. cAlphaOrder = 3;
  30. {$ENDIF}
  31. cRedShift = cRedOrder * 8;
  32. cGreenShift = cGreenOrder * 8;
  33. cBlueShift = cBlueOrder * 8;
  34. cAlphaShift = cAlphaOrder * 8;
  35. maskRed = 1;
  36. maskGreen = 2;
  37. maskBlue = 4;
  38. maskAlpha = 8;
  39. maskRGB = maskRed Or maskGreen Or maskBlue;
  40. maskRGBA = maskRGB Or maskAlpha;
  41. Type
  42. { TColorRGB24 : Définition d'un pixel sur 24 bits au format RGB }
  43. { TColorRGB24 : Definition of a 24-bit pixel in RGB format }
  44. TColorRGB24Type = packed array[0..2] of byte;
  45. TColorRGB24 = packed record
  46. { Creation de la couleur / Create Color }
  47. procedure Create(R,G,B : Byte); Overload;
  48. procedure Create(Color:TColor); Overload;
  49. { Conversion vers un TColor / Convert to TColor }
  50. function ToColor : TColor;
  51. Case Integer of
  52. 0 : (V:TColorRGB24Type); // Acces via Tableau / Array
  53. 1 : (Red, Green, Blue:Byte); // Acces via Composantes / Channel
  54. end;
  55. { TColor32 : Définition d'un pixel sur 32 bits au format RGBA ou BGRA suivant l'OS }
  56. { TColor32: Definition of a 32-bit pixel in RGBA or BGRA format depending on the OS }
  57. TColor32Type = packed array[0..3] of byte;
  58. TColor32 = Packed Record
  59. private
  60. function getColorComponent(Index : Integer): byte;
  61. procedure SetColorComponent(Index : Integer; aValue:Byte);
  62. public
  63. { Creation de la couleur / Create Color }
  64. procedure Create(R,G,B,A : Byte); Overload;
  65. procedure Create(R,G,B : Byte); Overload;
  66. procedure Create(Color : TColor); Overload;
  67. procedure Create(Color : TColorRGB24); Overload;
  68. { Conversion vers un TColor / Convert to TColor }
  69. function ToColor : TColor;
  70. { Conversion vers un TColorRGB24 / Convert to TColorRGB24 }
  71. function ToColorRGB24 : TColorRGB24;
  72. { Conversion vers un TFPColor / Convert to TFPColor }
  73. function ToFPColor : TFPColor;
  74. { Mixage de la couleur courrante avec la couleur "Color" avec prise en charge du canal Alpha }
  75. { Mix current color with 'Color' color with Alpha channel support }
  76. function Blend(Color : TColor32): TColor32;
  77. { Vérifie si 2 valeurs sont identiques / Check if 2 colors are equal }
  78. class operator =(Color1,Color2 : TColor32):Boolean;
  79. { Accès aux composantes de la couleur / Color channel access }
  80. property Red:Byte Index cRedOrder read GetColorComponent Write SetColorComponent;
  81. property Green:Byte Index cGreenOrder read GetColorComponent Write SetColorComponent;
  82. property Blue:Byte Index cBlueOrder read GetColorComponent Write SetColorComponent;
  83. property Alpha:Byte Index cAlphaOrder read GetColorComponent Write SetColorComponent;
  84. Case Integer of
  85. 0 : (V:TColor32Type); // Acces via tableau / Array
  86. 1 : (AsInteger : Integer); // Acces via Integer
  87. End;
  88. PColor32 = ^TColor32;
  89. { TColor32Item : Objet persistant englobant une couleur de type TColor32 }
  90. { TColor32Item: Persistent object that includes a TColor32 color }
  91. TColor32Item = Class(TPersistent)
  92. Private
  93. FColor: TColor32;
  94. FName: String;
  95. FTag: Integer;
  96. Procedure SetRed(Const AValue: Byte);
  97. Procedure SetGreen(Const AValue: Byte);
  98. Procedure SetBlue(Const AValue: Byte);
  99. Procedure SetAlpha(Const AValue: Byte);
  100. Procedure SetValue(Const AValue: TColor32);
  101. Procedure SetColorName(Const aName: String);
  102. Function getRed: Byte;
  103. Function getGreen: Byte;
  104. Function getBlue: Byte;
  105. Function getAlpha: Byte;
  106. Function getValue: TColor32;
  107. Protected
  108. Public
  109. Constructor Create;
  110. Destructor Destroy; override;
  111. { Valeur de la couleur / Value of the color }
  112. Property Value: TColor32 read getValue write setValue;
  113. { Nom de la couleur eg : clrRed / Name of the color}
  114. Property Name: String read FName write setColorName;
  115. Published
  116. { Valeur du canal rouge / Red channel }
  117. Property Red: Byte read getRed write setRed;
  118. { Valeur du canal vert / Green channel }
  119. Property Green: Byte read getRed write setGreen;
  120. { Valeur du canal Bleu / Blue channel }
  121. Property Blue: Byte read getRed write setBlue;
  122. { Valeur du canal alpha pour la transparence / Alpha channel for transparency }
  123. Property Alpha: Byte read getRed write setAlpha;
  124. { Valeur complémentaire personnel / User define value }
  125. Property Tag: Integer read FTag write FTag;
  126. End;
  127. { TColor32List : Classe pour la gestion d'une palette (liste) de couleurs }
  128. { TColor32List : Class for managing a palette (list) of colors }
  129. TColor32List = Class(TObjectList)
  130. Private
  131. Protected
  132. Function GetColorItem(index: Integer): TColor32Item;
  133. Procedure SetColorItem(index: Integer; val: TColor32Item);
  134. Public
  135. { Efface la liste / Clear the list }
  136. procedure Clear; override;
  137. { Ajoute une couleur à la liste / Add a color to the list }
  138. Function AddColor(Const aColor: TColor32): Integer; Overload;
  139. { Ajoute une couleur à la liste /Add a color to the list }
  140. Function AddColor(Const aName: String; Const aColor: TColor32): Integer; Overload;
  141. { Ajoute une couleur à la liste / Add a color to the list}
  142. Function AddColor(Const aColorItem: TColor32Item): Integer; Overload;
  143. { Supprime une couleur de la liste / Delete a color of the list }
  144. Procedure RemoveColor(Const aName: String);
  145. { Recherche une couleur dans la liste / Search color in list }
  146. Function FindColorByName(Const aName: String; Out Index: Integer):TColor32; Overload;
  147. { Recherche une couleur dans la liste / Search color in list }
  148. Function FindColorByName(Const aName: String): TColor32; Overload;
  149. { Colors : Acceder à la couleur "Index" de la liste / Color access with Index }
  150. Property Colors[Index: Integer]: TColor32Item read GetColorItem write setColorItem;
  151. End;
  152. Const
  153. clrTransparent : TColor32 = (v:($00,$00,$00,$00));
  154. clrBlack : TColor32 = (v:($00,$00,$00,$FF));
  155. clrWhite : TColor32 = (v:($FF,$FF,$FF,$FF));
  156. Type
  157. { TFastBitmapDrawMode : Mode d'Affichage pour la fonction PutImage de TFastBitmap }
  158. { TFastBitmapDrawMode : Display Mode for the PutImage Function of TFastBitmap }
  159. TFastBitmapDrawMode = ( dmSet, dmAlpha, dmAlphaCheck);
  160. { TFastBitmap }
  161. { Classe d'aide à la manipulation d'une image }
  162. { Help class for image manipulation }
  163. TFastBitmap = Class
  164. Strict private
  165. FTransparentColor : TColor; // Couleur transparent à pour l'affichage via TBitmap de la LCL si besoin / Transparent color for display via TBitmap of the LCL if needed
  166. FData : PDWord; // Tampon de stockage des données d'un bitmap / Buffer for storing data from a bitmap
  167. FWidth : Integer; // Largeur du bitmap / Width
  168. FHeight : Integer; // Hauteur du Bitmap / Height
  169. FSize : Int64; // Taille du tampon en octet / Size in byte
  170. protected
  171. procedure SetWidth(NewWidth : Integer);
  172. procedure SetHeight(NewHeight : Integer);
  173. function BuildBitmap : Graphics.TBitmap;
  174. function IsClipped(X,Y:Integer) : Boolean;
  175. Public
  176. Constructor Create; Overload;
  177. Constructor Create(NewWidth, NewHeight : Integer); Overload;
  178. Destructor Destroy; Override;
  179. { Assigne les donnée d'un autre TFastBitmap / Assign another TFastBitmap }
  180. procedure Assign(aFastBitmap : TFastBitmap);
  181. { Modifie les dimensions du bitmap / Change size of bitmap }
  182. procedure SetSize(NewWidth, NewHeight : Integer);
  183. { Importation des données d'un TRawImage. Retourne "TRUE" en cas de succès }
  184. { Import from RawImage. Return TRUE on success }
  185. function ImportFromRawImage(Const ARawImage : TRawImage):Boolean;
  186. { Importation des données d'un TBitmap. Retourne "TRUE" en cas de succès }
  187. { Import from TBitmap. Return TRUE on success }
  188. function ImportFromBitmap(Const ABitmap :Graphics.TBitmap):Boolean;
  189. { Efface le bitmap avec la couleur "Color" / Clear bitmap with Color }
  190. procedure Clear(Color : TColor32);
  191. { Retourne le tampon du bitmap / Return bitmap buffer }
  192. function GetSurfaceBuffer : PColor32;
  193. { Retourne l'adresse de la ligne "Y" dans le tampon / Return address in buffer of a line }
  194. function GetScanLine(Y : Integer) : PColor32;
  195. { Retourne l'adresse du pixel à la position "X,Y" dans le tampon / Return address at X,Y}
  196. function GetPixelPtr(X, Y : Integer) : PColor32;
  197. { Ecrit un pixel de couleur "Color" à la position "X,Y / Put pixel X,Y with Color }
  198. procedure PutPixel(X,Y:Integer; Color : TColor32);
  199. { Lit un pixel de couleur "Color" à la position "X,Y / Get color of pixel at X,Y }
  200. function GetPixel(X,Y:Integer): TColor32;
  201. { Ecrit un pixel de en mixant couleur "Color" avec la couleur du pixel présent dans le tampon à la position "X,Y }
  202. { Writes a pixel by mixing 'Color' color with the color of the pixel present in the buffer at the 'X, Y' position }
  203. procedure PutPixelBlend(X,Y : Integer; Color : TColor32);
  204. { Copie une image source "Src" depuis la position "SrcX,SrcY" et de dimension "SrcWidthxSrcHeight" dans le bitmap à la position "DstX, DstY
  205. et suivant le "Mode"
  206. Mode : TFastBitmapDrawMode
  207. - dmSet : Copie brute de l'image
  208. - dmAlpha : Copie les pixel de l'image source en mixant les couleurs avec celles du bitmap en fonction de leur valeur Alpha
  209. - dmAlphaCheck : Copie les pixels de l'image source seulement si le pixel est visible (Alpha <> 0)
  210. Note : les dimensions et les positions entre le bitmap et l'image source sont automatiquement ajustées si besoin.
  211. --------------------------
  212. Copy a source image 'Src' from the position 'SrcX, SrcY' and dimension 'SrcWidthxSrcHeight' into the bitmap at the position 'DstX, DstY
  213.       and following the 'Mode'
  214.        Mode: TFastBitmapDrawMode
  215.         - dmSet: Raw copy of the image
  216.         - dmAlpha: Copy the pixels of the source image by mixing the colors with those of the bitmap according to their Alpha value
  217.         - dmAlphaCheck: Copy the pixels of the source image only if the pixel is invisible (Alpha <> 0)
  218.        Note: The dimensions and positions between the bitmap and the source image are automatically adjusted if necessary.
  219. }
  220. procedure PutImage(Src : TFastBitmap; SrcX, SrcY, SrcWidth, SrcHeight, DstX, DstY : Integer; Mode : TFastBitmapDrawMode);
  221. { Creation d'un clone du bitmap (nouvelle instance) / Create clone (new instance) }
  222. function Clone : TFastBitmap;
  223. { Retourne un bitmap de type LCL ==> Graphics.TBitmap / Return a TBitmap}
  224. function GetBitmap : Graphics.TBitmap;
  225. { Dessine le bitmap sur un canvas à la position "X,Y" / Draw the bitmap on a canvas }
  226. procedure Draw(ACanvas : TCanvas; X,Y : Integer); Overload;
  227. { Dessine le bitmap sur un canvas délimité par "Rect" / Draw the bitmap on a canvas delimited by "Rect" }
  228. procedure Draw(ACanvas : TCanvas; Rect : TRect); Overload;
  229. { Inverse les composante de couleur Rouge et Bleu du bitmap / Swap Red and Blue channel }
  230. procedure SwapRB;
  231. // procedure HLine(X,Y,X2 : Integer; aColor : TColor32);
  232. { Information sur la couleur assignée à la transparence (seulement valable si différent de clrTransparent) / Return the transparency color }
  233. property TransparentColor : TColor Read FTransparentColor Write FTransparentColor;
  234. { Largeur du bitmap / Width }
  235. property Width : Integer Read FWidth Write SetWidth;
  236. { Hauteur du bitmap / Height }
  237. property Height : Integer Read FHeight Write SetHeight;
  238. { Taille du tampon en octet / Size of the buffer }
  239. property Size : Int64 Read FSize;
  240. End;
  241. Implementation
  242. Uses Types, Math, GifViewerStrConsts;
  243. {%region=====[ TColorRGB24 ]====================================================}
  244. Procedure TColorRGB24.Create(R, G, B : Byte);
  245. Begin
  246. Red := R;
  247. Green := G;
  248. Blue := B;
  249. End;
  250. Procedure TColorRGB24.Create(Color : TColor);
  251. Var
  252. lr,lg,lb : Byte;
  253. Begin
  254. lr := Color;
  255. lg := Color shr 8;
  256. lb := Color shr 16;
  257. Create(lr,lg,lb);
  258. End;
  259. Function TColorRGB24.ToColor : TColor;
  260. Begin
  261. Result := Red + (Green shl 8) + (Blue shl 16);
  262. End;
  263. {%endregion%}
  264. {%region=====[ TColor32 ]===================================================}
  265. function TColor32.getColorComponent(Index: Integer): byte;
  266. Begin
  267. result := v[Index];
  268. End;
  269. procedure TColor32.SetColorComponent(Index: Integer; aValue: Byte);
  270. Begin
  271. v[Index] := aValue;
  272. End;
  273. procedure TColor32.Create(R, G, B, A: Byte);
  274. Begin
  275. Red := R;
  276. Green := G;
  277. Blue := B;
  278. Alpha := A;
  279. End;
  280. procedure TColor32.Create(R, G, B: Byte);
  281. Begin
  282. Create(R,G,B,255);
  283. End;
  284. procedure TColor32.Create(Color: TColor);
  285. Var
  286. ColorRGB24 : TColorRGB24;
  287. Begin
  288. {%H-}ColorRGB24.Create(Color);
  289. Create(ColorRGB24);
  290. End;
  291. procedure TColor32.Create(Color: TColorRGB24);
  292. Begin
  293. Create(Color.Red,Color.Green,Color.Blue);
  294. End;
  295. function TColor32.ToColor: TColor;
  296. Begin
  297. Result := ToColorRGB24.ToColor;
  298. End;
  299. function TColor32.ToColorRGB24: TColorRGB24;
  300. Begin
  301. Result.Red := Red;
  302. Result.Green := Green;
  303. Result.Blue := Blue;
  304. End;
  305. function TColor32.ToFPColor: TFPColor;
  306. begin
  307. Result.Red := Self.Red shl 8 + Self.Red;
  308. Result.Green := Self.Green shl 8 + Self.Green;
  309. Result.Blue := Self.Blue shl 8 + Self.Blue;
  310. Result.Alpha := Self.Alpha shl 8 + Self.Alpha;
  311. end;
  312. function TColor32.Blend(Color: TColor32): TColor32;
  313. var
  314. factor, factor2:single;
  315. begin
  316. if Color.Alpha = 255 then Result := Color
  317. else if (Color.Alpha = 0) or (Self = Color) then Result:= Self
  318. else
  319. begin
  320. factor := Color.Alpha / 255;
  321. factor2 := 1 - Factor;
  322. Result.Red := Round((Self.Red*Factor)+(Color.Red*factor2));
  323. Result.Green := Round((Self.Green*Factor)+(Color.Green*Factor2));
  324. Result.Blue := Round((Self.Blue*Factor)+(Color.Blue*Factor2));
  325. Result.alpha := Round((Self.Alpha*Factor)+(Color.Alpha*Factor2));
  326. End;
  327. end;
  328. class operator TColor32.=(Color1, Color2: TColor32): Boolean;
  329. Begin
  330. Result := False;
  331. if (Color1.Alpha = 0) and (Color2.Alpha = 0) then Result :=True
  332. else Result := ((Color1.Red = Color2.Red) and (Color1.Green = Color2.Green) and (Color1.Blue = Color2.Blue) and (Color1.Alpha = Color2.Alpha))
  333. End;
  334. {%endregion%}
  335. {%region=====[ TColor32Item ]===============================================}
  336. Constructor TColor32Item.Create;
  337. Begin
  338. Inherited Create;
  339. FName := 'Black';
  340. FColor.Create(0,0,0);
  341. FTag := 0;
  342. End;
  343. Destructor TColor32Item.Destroy;
  344. Begin
  345. Inherited Destroy;
  346. End;
  347. Procedure TColor32Item.SetRed(Const AValue: Byte);
  348. Begin
  349. If AValue = FColor.red Then exit;
  350. FColor.Red := AValue;
  351. End;
  352. Procedure TColor32Item.SetGreen(Const AValue: Byte);
  353. Begin
  354. If AValue = FColor.Green Then exit;
  355. FColor.Green := AValue;
  356. End;
  357. Procedure TColor32Item.SetBlue(Const AValue: Byte);
  358. Begin
  359. If AValue = FColor.Blue Then exit;
  360. FColor.Blue := AValue;
  361. End;
  362. Procedure TColor32Item.SetAlpha(Const AValue: Byte);
  363. Begin
  364. If AValue = FColor.Alpha Then exit;
  365. FColor.Alpha := AValue;
  366. End;
  367. Procedure TColor32Item.SetValue(Const AValue: TColor32);
  368. Begin
  369. If AValue = FColor Then exit;
  370. FColor := AValue;
  371. End;
  372. Function TColor32Item.getRed: Byte;
  373. Begin
  374. Result := FColor.Red;
  375. End;
  376. Function TColor32Item.getGreen: Byte;
  377. Begin
  378. Result := FColor.Green;
  379. End;
  380. Function TColor32Item.getBlue: Byte;
  381. Begin
  382. Result := FColor.Blue;
  383. End;
  384. Function TColor32Item.getAlpha: Byte;
  385. Begin
  386. Result := FColor.Alpha;
  387. End;
  388. Function TColor32Item.getValue: TColor32;
  389. Begin
  390. Result := FColor;
  391. End;
  392. Procedure TColor32Item.SetColorName(Const aName: String);
  393. Begin
  394. If FName = aName Then exit;
  395. FName := aName;
  396. End;
  397. {%endregion%}
  398. {%region ====[ TColor32List ]===============================================}
  399. Function TColor32List.GetColorItem(index: Integer): TColor32Item;
  400. Begin
  401. Result := TColor32Item(Get(Index));
  402. End;
  403. Procedure TColor32List.SetColorItem(index: Integer; val: TColor32Item);
  404. Begin
  405. Put(Index, Val);
  406. End;
  407. procedure TColor32List.Clear;
  408. Var
  409. anItem: TColor32Item;
  410. i : Integer;
  411. Begin
  412. inherited Clear;
  413. If Count > 0 then
  414. begin
  415. For i :=Count -1 downto 0 do
  416. begin
  417. AnItem:= Colors[i];
  418. if anItem<>nil then anItem.Free;
  419. End;
  420. End;
  421. End;
  422. Function TColor32List.AddColor(Const aColor: TColor32): Integer;
  423. Var
  424. aColorItem: TColor32Item;
  425. Begin
  426. aColorItem := TColor32Item.Create;
  427. aColorItem.Value := aColor;
  428. Result := Add(aColorItem);
  429. End;
  430. Function TColor32List.AddColor(Const aName: String; Const aColor: TColor32): Integer;
  431. Var
  432. aColorItem: TColor32Item;
  433. Begin
  434. aColorItem := TColor32Item.Create;
  435. aColorItem.Value := aColor;
  436. aColorItem.Name := aName;
  437. Result := Add(aColorItem);
  438. End;
  439. Function TColor32List.AddColor(Const aColorItem: TColor32Item): Integer;
  440. Begin
  441. Result := Add(aColorItem);
  442. End;
  443. Procedure TColor32List.RemoveColor(Const aName: String);
  444. Var
  445. I: Integer;
  446. Col: TColor32Item;
  447. Begin
  448. FindColorByName(aName, I);
  449. If I > -1 Then
  450. Begin
  451. Col := GetColorItem(I);
  452. If Assigned(Col) Then
  453. Col.Free;
  454. Delete(I);
  455. End;
  456. End;
  457. Function TColor32List.FindColorByName(Const aName: String; Out Index: Integer): TColor32;
  458. Var
  459. i: Integer;
  460. Begin
  461. Result := clrTransparent;
  462. Index := -1;
  463. For i := 0 To Count - 1 Do
  464. If TColor32Item(Items[i]).Name = aName Then
  465. Begin
  466. Index := I;
  467. Result := TColor32Item(Items[i]).Value;
  468. break;
  469. End;
  470. End;
  471. Function TColor32List.FindColorByName(Const aName: String): TColor32;
  472. Var
  473. i: Integer;
  474. Begin
  475. Result := FindColorByName(aName, I);
  476. End;
  477. {%endregion%}
  478. {%region=====[ TFastBitmap ]====================================================}
  479. Constructor TFastBitmap.Create(NewWidth, NewHeight : Integer);
  480. Begin
  481. inherited Create;
  482. FWidth := Max(1,NewWidth);
  483. FHeight := Max(1,NewHeight);
  484. FData := Nil;
  485. FSize := (int64(FWidth) * int64(FHeight))*4;
  486. ReAllocMem(FData,FSize);
  487. FTransparentColor := clBlack;
  488. End;
  489. Constructor TFastBitmap.Create;
  490. Begin
  491. Create(1,1);
  492. End;
  493. Destructor TFastBitmap.Destroy;
  494. Begin
  495. FreeMem(FData);
  496. FData := Nil;
  497. inherited Destroy;
  498. End;
  499. Procedure TFastBitmap.SetWidth(NewWidth : Integer);
  500. Begin
  501. if NewWidth = FWidth then Exit;
  502. SetSize(NewWidth, FHeight);
  503. End;
  504. Procedure TFastBitmap.SetHeight(NewHeight : Integer);
  505. Begin
  506. if NewHeight = FHeight then Exit;
  507. SetSize(FWidth, NewHeight);
  508. End;
  509. Function TFastBitmap.BuildBitmap: Graphics.TBitmap;
  510. Var
  511. Temp : Graphics.TBitmap;
  512. IntfBmp : TLazIntfImage;
  513. ImgFormatDescription: TRawImageDescription;
  514. W,H,X,Y : Integer;
  515. SrcPix : PColor32;
  516. Begin
  517. (* /!\ Le code si dessous fonctionne parfaitement sous Windows et Mac.
  518. Mais sous Linux ce code produit des erreur au niveau de la transparence
  519. BmpHandle := 0;
  520. MskHandle := 0;
  521. W := FWidth;
  522. H := FHeight;
  523. Buffer := PByte(GetSurfaceBuffer);
  524. RawImage.Init;
  525. {$IFDEF WINDOWS}
  526. RawImage.Description.Init_BPP32_B8G8R8A8_BIO_TTB(W,H);
  527. {$ELSE}
  528. RawImage.Description.Init_BPP32_R8G8B8A8_BIO_TTB(W,H);
  529. {$ENDIF}
  530. RawImage.Data := Buffer;
  531. RawImage.DataSize := FSize;
  532. if not RawImage_CreateBitmaps(RawImage, BmpHandle, MskHandle,False) then
  533. Raise Exception.Create('Impossible de créer le TBitmap')
  534. else
  535. begin
  536. Temp := Graphics.TBitmap.Create;
  537. Temp.Width := W;
  538. Temp.Height := H;
  539. Temp.PixelFormat := pf32bit;
  540. Temp.Handle := BmpHandle;
  541. Temp.MaskHandle := MskHandle;
  542. Temp.Transparent := True;
  543. //Temp.TransparentColor := FTransparentColor;
  544. //temp.TransparentMode := tmAuto;
  545. Result := Temp;
  546. End;
  547. *)
  548. Result := nil;
  549. W := FWidth;
  550. H := FHeight;
  551. // Pour que la transparence soit gérée correctement sous Linux on est obligé de passer par TLazIntfImage
  552. IntfBmp := TLazIntfImage.Create(W,H);
  553. ImgFormatDescription.Init_BPP32_B8G8R8A8_BIO_TTB(W, H);
  554. IntfBmp.DataDescription := ImgFormatDescription;
  555. SrcPix := Self.GetSurfaceBuffer;
  556. For Y:=0 to H-1 do
  557. For X:=0 to W-1 do
  558. begin
  559. IntfBmp.Colors[x, y]:=SrcPix^.ToFPColor;
  560. inc(SrcPix);
  561. end;
  562. begin
  563. Temp := Graphics.TBitmap.Create;
  564. Temp.LoadFromIntfImage(IntfBmp);
  565. Result := Temp;
  566. IntfBmp.Free;
  567. End;
  568. if Result = nil then
  569. Raise Exception.Create(rsBitmapCreateError);
  570. End;
  571. Function TFastBitmap.IsClipped(X, Y : Integer) : Boolean;
  572. Begin
  573. Result := ((X>=0) and (Y>=0) and (X<FWidth) and (Y<FHeight));
  574. End;
  575. Procedure TFastBitmap.SwapRB;
  576. var
  577. Pixptr: PColor32;
  578. AIntColor : Cardinal;
  579. PixelCount : Integer;
  580. begin
  581. PixPtr := GetSurfaceBuffer;
  582. PixelCount := (FWidth * FHeight)-1;
  583. while pixelCount > 0 do
  584. begin
  585. AIntColor := PixPtr^.AsInteger;
  586. PixPtr^.AsInteger := AIntColor and $FF00FF00 or (AintColor and $000000FF SHL 16) or (AIntColor and $00FF0000 SHR 16);
  587. Inc(PixPtr);
  588. Dec(pixelCount);
  589. end;
  590. end;
  591. Procedure TFastBitmap.Assign(aFastBitmap : TFastBitmap);
  592. Begin
  593. SetSize(aFastBitMap.Width, aFastBitmap.Height);
  594. Move(PByte(aFastBitmap.GetSurfaceBuffer)^, PByte(FData)^, FSize);
  595. End;
  596. Procedure TFastBitmap.SetSize(NewWidth, NewHeight : Integer);
  597. Begin
  598. FWidth := Max(1,NewWidth);
  599. FHeight := Max(1,NewHeight);
  600. FSize :=(int64(FWidth) * int64(FHeight))*4;
  601. if (FData<>nil) then
  602. begin
  603. FreeMem(FData);
  604. FData := Nil;
  605. End;
  606. ReAllocMem(FData,FSize);
  607. Clear(clrTransparent);
  608. End;
  609. Function TFastBitmap.ImportFromRawImage(Const ARawImage: TRawImage): Boolean;
  610. var
  611. BufferData : PByte;
  612. begin
  613. SetSize(ARawImage.Description.Width,ARawImage.Description.Height);
  614. result:=false;
  615. // On verifie si la taille des deux tampons sont identique
  616. // Si ce n'est pas le cas, cela veut dire que le TRawImage n'est pas au format 32bit
  617. if (ARawImage.DataSize= FSize) then
  618. begin
  619. try
  620. BufferData := PByte(Self.getSurfaceBuffer);
  621. Move(ARawImage.Data^, BufferData^, self.Size);
  622. {$IFDEF WINDOWS}
  623. if (ARawImage.Description.RedShift = 0) and ((ARawImage.Description.BlueShift = 16)) then Self.SwapRB; // Le RawImage est-il en RGB, si oui on échange
  624. {$ELSE}
  625. if (ARawImage.Description.RedShift = 16) and ((ARawImage.Description.BlueShift = 0)) then Self.SwapRB; // Le RawImage est-il en BGR, si oui on échange
  626. {$ENDIF}
  627. finally
  628. result:=true;
  629. end;
  630. end;
  631. End;
  632. Function TFastBitmap.ImportFromBitmap(Const ABitmap: Graphics.TBitmap): Boolean;
  633. var
  634. LTempBitmap: Graphics.TBitmap;
  635. ok,ResetAlpha:Boolean;
  636. procedure SetAlpha(Value : Byte);
  637. var
  638. i : Integer;
  639. PixPtr : PColor32;
  640. maxi : Integer;
  641. begin
  642. i:=0;
  643. Maxi := (FWidth * FHeight)-1;
  644. PixPtr :=PColor32(FData);// Self.GetScanLine(0);
  645. While i<Maxi do
  646. begin
  647. PixPtr^.Alpha:= Value;
  648. inc(PixPtr);
  649. inc(i);
  650. end;
  651. end;
  652. begin
  653. ResetAlpha:=False;
  654. result:=false;
  655. if (ABitmap.PixelFormat <> pf32bit) then
  656. begin
  657. LTempBitmap := Graphics.TBitmap.Create;
  658. try
  659. ResetAlpha:=True;
  660. LTempBitmap.SetSize(ABitmap.Width, ABitmap.Height);
  661. LTempBitmap.PixelFormat := pf32bit;
  662. LTempBitmap.Canvas.Draw(0, 0, ABitmap);
  663. finally
  664. ok:=Self.ImportFromRawImage(LTempBitmap.RawImage);
  665. if ResetAlpha then SetAlpha(255);
  666. FreeAndNil(LTempBitmap);
  667. result:=true and (ok);
  668. end;
  669. end
  670. else
  671. begin
  672. ok:=Self.ImportFromRawImage(ABitmap.RawImage);
  673. result:=true and (ok);
  674. end;
  675. End;
  676. Procedure TFastBitmap.Clear(Color : TColor32);
  677. Begin
  678. FillDWord(FData^,FWidth * FHeight, DWord(Color));
  679. End;
  680. Function TFastBitmap.GetSurfaceBuffer: PColor32;
  681. Begin
  682. Result := PColor32(FData);
  683. End;
  684. Function TFastBitmap.GetScanLine(Y : Integer) : PColor32;
  685. Var
  686. yy : DWord;
  687. Begin
  688. If (Y<0) or (Y>=FHeight) then
  689. Raise Exception.Create(rsBitmapScanlineOutOfRange)
  690. else
  691. begin
  692. yy := DWord(FWidth) * DWord(Y);
  693. Result := PColor32(FData + YY);
  694. End;
  695. End;
  696. Function TFastBitmap.GetPixelPtr(X, Y : Integer) : PColor32;
  697. Begin
  698. Result := nil;
  699. if IsClipped(X,Y) then
  700. Begin
  701. Result := PColor32(FData + (FWidth * Y) + X);
  702. End;
  703. End;
  704. Procedure TFastBitmap.PutPixel(X, Y : Integer; Color : TColor32);
  705. Var
  706. PixelPtr : PColor32;
  707. Begin
  708. if IsClipped(X,Y) then
  709. Begin
  710. PixelPtr := PColor32(FData + DWord(FWidth * Y));
  711. Inc(PixelPtr,X);
  712. PixelPtr^:= Color;
  713. End;
  714. End;
  715. Function TFastBitmap.GetPixel(X, Y : Integer) : TColor32;
  716. Var
  717. PixelPtr : PColor32;
  718. Begin
  719. Result := clrTransparent;
  720. if IsClipped(X,Y) then
  721. Begin
  722. PixelPtr := PColor32(FData + (FWidth * Y) + X);
  723. Result := PixelPtr^;
  724. End;
  725. End;
  726. Procedure TFastBitmap.PutPixelBlend(X, Y : Integer; Color : TColor32);
  727. Var
  728. PixelPtr : PColor32;
  729. Begin
  730. if IsClipped(X,Y) then
  731. Begin
  732. PixelPtr := PColor32(FData + (FWidth * Y) + X);
  733. PixelPtr^:= PixelPtr^.Blend(Color);
  734. End;
  735. End;
  736. Procedure TFastBitmap.PutImage(Src : TFastBitmap; SrcX, SrcY, SrcWidth, SrcHeight, DstX, DstY : Integer; Mode : TFastBitmapDrawMode);
  737. Var
  738. SrcPtr, DstPtr : PColor32;
  739. NextSrcLine, NextDstLine : Integer;
  740. DstCol, SrcCol : TColor32;
  741. LineSize,TotalSize,xx,yy,i : Integer;
  742. Procedure ClipCopyRect(Var SrcX, SrcY, rWidth, rHeight, DstX, DstY: Integer; SrcImageWidth, SrcImageHeight: Integer; Const DstClip: Types.TRect);
  743. Var
  744. diff, OldDstPosX, OldDstPosY: Integer;
  745. Begin
  746. OldDstPosX := 0;
  747. If (DstX < 0) Then OldDstPosX := DstX;
  748. OldDstPosY := 0;
  749. If (DstY < 0) Then OldDstPosY := DstY;
  750. If DstX < DstClip.Left Then
  751. Begin
  752. Diff := DstClip.Left - DstX;
  753. rWidth := rWidth - Diff;
  754. SrcX := SrcX + Diff;
  755. DstX := DstClip.Left;
  756. End;
  757. If DstY < DstClip.Top Then
  758. Begin
  759. Diff := DstClip.Top - DstY;
  760. rHeight := rHeight - Diff;
  761. SrcY := SrcY + Diff;
  762. DstY := DstClip.Bottom;
  763. End;
  764. If SrcX < 0 Then
  765. Begin
  766. Width := Width + SrcX - OldDstPosX;
  767. DstX := DstX - SrcX + OldDstPosX;
  768. SrcX := 0;
  769. End;
  770. If SrcY < 0 Then
  771. Begin
  772. rHeight := rHeight + SrcX - OldDstPosY;
  773. DstY := DstY - SrcY + OldDstPosY;
  774. SrcY := 0;
  775. End;
  776. If ((SrcX + rWidth) > SrcImageWidth) Then rWidth := SrcImageWidth - SrcX;
  777. If ((SrcY + rHeight) > SrcImageHeight) Then rHeight := SrcImageHeight - SrcY;
  778. if DstX > FWidth then DstX := 0;
  779. if DstY > FHeight then DstY := 0;
  780. If ((DstX + rWidth) > (DstClip.Right+1)) Then rWidth := DstClip.Right - DstX;
  781. If ((DstY + rHeight) > (DstClip.Bottom+1)) Then rHeight := DstClip.Bottom - DstY;
  782. End;
  783. Begin
  784. if (SrcWidth = 0) and (SrcHeight = 0) then exit;
  785. ClipCopyRect(SrcX, SrcY, SrcWidth,SrcHeight, DstX, DstY, Src.Width, Src.Height, Types.Rect(0,0,FWidth-1, FHeight-1));
  786. if (SrcWidth = 1) and (SrcHeight = 1) then
  787. begin
  788. Case Mode of
  789. dmSet :
  790. begin
  791. SrcCol := Src.GetPixel(0,0);
  792. PutPixel(0,0,SrcCol);
  793. End;
  794. dmAlpha :
  795. begin
  796. SrcCol := Src.GetPixel(0,0);
  797. DstCol := GetPixel(0,0);
  798. PutPixel(0,0,DstCol.Blend(SrcCol));
  799. End;
  800. dmAlphaCheck :
  801. begin
  802. If SrcCol.Alpha > 0 Then
  803. begin
  804. SrcCol := Src.GetPixel(0,0);
  805. DstCol := GetPixel(0,0);
  806. PutPixel(0,0,DstCol.Blend(SrcCol));
  807. End
  808. Else
  809. begin
  810. DstCol := GetPixel(0,0);
  811. PutPixel(0,0,DstCol);
  812. End;
  813. End;
  814. End;
  815. exit;
  816. End;
  817. SrcPtr := Src.GetPixelPtr(SrcX,SrcY);
  818. DstPtr := GetPixelPtr(DstX, DstY);
  819. if SrcWidth <= Src.Width then
  820. nextSrcLine := Src.Width
  821. else
  822. nextSrcLine := SrcX + (Src.Width - (SrcX + SrcWidth));
  823. if Mode = dmSet then
  824. begin
  825. if (((Src.Width = FWidth) and (Src.Height = FHeight)) and ((SrcWidth = FWidth) and (SrcHeight = FHeight))) then
  826. Move(SrcPtr^,DstPtr^,DWord(Src.Size))
  827. else
  828. begin
  829. LineSize := SrcWidth * 4;
  830. For I := 0 to SrcHeight-1 do
  831. begin
  832. Move(SrcPtr^, DstPtr^, LineSize);
  833. Inc(SrcPtr, NextSrcLine);
  834. Inc(DstPtr, FWidth);
  835. End;
  836. End;
  837. End
  838. else
  839. begin
  840. totalsize := (Src.Width * Src.Height) - 1;
  841. Dec(SrcHeight);
  842. xx := 0;
  843. Dec(SrcWidth);
  844. nextSrcLine := SrcX + (Src.Width - (SrcX + SrcWidth));
  845. nextDstLine := DstX + (FWidth - (DstX + SrcWidth));
  846. yy := 0;
  847. xx := 0;
  848. SrcCol := clrTransparent;
  849. DstCol := clrTransparent;
  850. While (yy <= TotalSize) Do
  851. Begin
  852. DstCol := DstPtr^;
  853. SrcCol := SrcPtr^;
  854. Case Mode of
  855. dmAlpha :
  856. begin
  857. DstPtr^ := DstCol.Blend(SrcCol);
  858. End;
  859. dmAlphaCheck :
  860. begin
  861. If SrcCol.Alpha > 0 Then
  862. DstPtr^ := DstCol.Blend(SrcCol)
  863. Else
  864. DstPtr^ := DstCol;
  865. End;
  866. End;
  867. Inc(xx);
  868. Inc(yy);
  869. If (xx > SrcWidth) Then
  870. Begin
  871. xx := 0;
  872. Inc(DstPtr, NextDstLine);
  873. Inc(SrcPtr, NextSrcLine);
  874. End
  875. Else
  876. Begin
  877. Inc(SrcPtr);
  878. Inc(DstPtr);
  879. End;
  880. End;
  881. End;
  882. End;
  883. Function TFastBitmap.Clone : TFastBitmap;
  884. Var
  885. NewBmp : TFastBitmap;
  886. Begin
  887. NewBmp := TFastBitmap.Create;
  888. NewBmp.Assign(Self);
  889. Result := NewBmp;
  890. End;
  891. Function TFastBitmap.GetBitmap : Graphics.TBitmap;
  892. Begin
  893. Result := BuildBitmap;
  894. End;
  895. Procedure TFastBitmap.Draw(ACanvas : TCanvas; X, Y : Integer);
  896. Var
  897. Tmp : Graphics.TBitmap;
  898. Begin
  899. Tmp := BuildBitmap;
  900. ACanvas.Draw(X,Y,Tmp);
  901. FreeAndNil(Tmp);
  902. End;
  903. Procedure TFastBitmap.Draw(ACanvas : TCanvas; Rect : TRect);
  904. Var
  905. Tmp : Graphics.TBitmap;
  906. Begin
  907. Tmp := BuildBitmap;
  908. ACanvas.StretchDraw(Rect, Tmp);
  909. FreeAndNil(Tmp);
  910. End;
  911. {%endregion%}
  912. End.