L'Unité Fast bitmap adresse un Bitmap avec ces fonctions

Contenu du snippet

unit U_fast_bitmap;

  {L'Unité Fast bitmap adresse un Bitmap avec ces fonctions élémentaire comme circle}
  {Une unité écrite par denis bertin pour accéler le mode Alias, écrit par denis bertin}
  {L'accès à la lecture ou l'écriture de pixel dans une image. (c) db 15-07-2009}
  {Et améliorer après l'avoir poster sur internet pour obtenir TFastBitmap2}
  
interface

uses Windows, Graphics, Classes, Contnrs, SysUtils, my_math;

var globale_stop : boolean;

const max_size_vertical = 32000;

type PTStyle = (PTS_Square,PTS_round,PTS_Triangle);

//Utilisation : Créer l'object avec sa méthode create
//et assigner lui un bitmap de chez Borland
//Faire des opérations sur les pixels Get et Set Pixels
//Puis assigner en retour le bitmap à obtenir à partir de celui dessinné.
//Normalement Pixel:=adresse_base_du_bitmap + largeur de l'image * Y + X;

type

  Parray_maxi = ^Tarray_maxi;
  Tarray_maxi = array[00..max_size_vertical] of pointer;

  pointer_array_matrice = ^type_array_matrice;
  type_array_matrice = array [0..24] of integer;    // coefficients matrice filtre maxi 5x5


type

  TTable=array[0..0] of integer;
  PTable = ^TTable;

  TFastBitmap = class {gagne 2000% en lecture le dbs:15-07-2009}
    abitmap:Graphics.TBitmap;
    awindow:hwnd;
    constructor Create(window:hwnd);
    destructor  Destroy; override;
    procedure   Assign(Source: TPersistent);
    function    Lecture_de_la_scanline:boolean;
    procedure   Liberation_de_la_scanline;
    function    Height:integer;
    function    Width:integer;
    function    Get_pixel(x,y:integer):TColor;
    procedure   Set_pixel(x,y:integer; color:TColor);
    procedure   For_a_rectangle_filling(sa_couleur:TColor);
    //procedure   Resize(byx,byy:integer);
    private
      size : integer;
      scan : Parray_maxi;
    end; {TFastBitmap}

  TFastBitmap_base = object
    public
    Bmp : Graphics.TBitMap;
    W,H,Scan0,MLS:integer;
    end;

  TFastBitmap_8bits = object(TFastBitmap_base)
    procedure Copy(iBmp : Graphics.tBitMap);
    function  GetPixel(X,Y : Integer):byte;
    procedure SetPixel(X,Y : Integer; alpha:byte);
    end;

 TFastBitmap2 = object(TFastBitmap_base)
  public
    BPP : integer;
  procedure Creer(x,y:integer);
  procedure Copy(iBmp : Graphics.tBitMap);
  procedure Init(iBmp : Graphics.tBitMap);
  procedure Handle(A:hbitmap);
  procedure Free_bmp;
  procedure Determine;
  procedure Free;
  procedure Set_Pixel_in_limite_variation_Y(xx,y :integer; color : TColor);
  procedure Set_Pixel_in_limite_variation_Y_sans_tab(xx,y :integer; color : TColor);
  function  GetPixel_in_limite_variation_Y(xx,y : Integer) : tColor;
  function  GetPixel_in_limite_variation_Y_sans_tab(xx,y : Integer) : tColor;
  function  GetPixel_in_limite(X,Y : Integer) : tColor;
  procedure SetPixel_in_limite(x,y :integer; color : TColor);
  function  GetPixel(X,Y : Integer) : tColor;
  procedure SetPixel(x,y :integer; color : TColor);
  procedure RectangleFilling(color : TColor);
  procedure ligne_horizontale(y:integer; color : TColor);
  procedure ligne_vertical(x:integer; color : TColor);
  procedure ligne_horizontale_fromage(a,b,y:integer; color : TColor);
  procedure ligne_verticale_fromage(x,a,b:integer; color : TColor);
  end;

  Tdbbitmap = class
    public
      constructor Create(un_bitmap:tbitmap);
      destructor Destroy; override;
      procedure Initialise;
      procedure Setpixel_in_limite(x,y:integer; une_couleur:tcolorref);
      procedure Setpixel(x,y:integer; une_couleur:tcolorref);
      procedure Setpixel_transparent(x,y:integer; une_couleur:tcolorref; transparent:real);
      function  Getpixel(x,y:integer):tcolorref;
      procedure Cross_pixel(x,y:integer; une_couleur:tcolorref);
      procedure Drawrect(x,y,xx,yy:integer; une_couleur:tcolorref);
      procedure Drawrect_round(x,y,xx,yy:real; une_couleur:tcolorref);
      procedure Drawrect_transparent(x,y,xx,yy:integer; une_couleur:tcolorref; transparent:real);
      procedure FillCircle(x,y,rayon:integer; une_couleur:tcolorref; light:boolean); 
      procedure FillCircle_single(x,y,rayon:single; une_couleur:tcolorref; light:boolean);
      procedure FillRectSoft(x,y,xx,yy:integer; une_couleur:tcolorref); //Le 15.12.2019
      procedure Fillrect_real(x,y,xx,yy:real; une_couleur:tcolorref);
      procedure Fillrect(x,y,xx,yy:integer; une_couleur:tcolorref);
      procedure CrossRect(x,y,xx,yy,alpha:integer; une_couleur:tcolorref);
      procedure RoundRect(x,y,xx,yy,alpha:integer; une_couleur:tcolorref);
      Procedure Denis_line_hori(x,y,xx:integer; une_couleur:tcolorref);
      Procedure Denis_line_hori_square_gradian(x,y,xx:integer; m:real; rect:trect;
        une_couleur:tcolorref; collection:contnrs.TObjectList; hue_lum_sat:boolean);
      Procedure Denis_line_hori_parralelle(x,y,xx:integer; rect:trect; angle:integer;
        une_couleur:tcolorref; collection:contnrs.TObjectList; hue_lum_sat:boolean);
      Procedure Denis_line_hori_graduate(x,y,xx:integer; ptA,ptB:my_math.Point2D; m:real;
        une_couleur:tcolorref; collection:contnrs.TObjectList; hue_lum_sat:boolean);
      Procedure Denis_line_hori_circulaire(x,y,xx:integer; borne_central:tpoint; m:real;
        une_couleur:tcolorref; collection:contnrs.TObjectList; hue_lum_sat:boolean);
      Procedure Denis_line(a,b,c,d:real; color:tcolorref);
      Procedure Denis_line_single_epaisseur(a,b,c,d:real; color:tcolorref; width:integer; style:U_fast_bitmap.PTStyle);
      Procedure Denis_line_single(a,b,c,d:real; color:tcolorref);
      Procedure Denis_line_alias(a,b,c,d:real; color:tcolorref);
      Procedure Denis_line_in_between(a,b,c,d:real; depart,color:tcolorref; stroke_mitter,stroke_bold:boolean; stroke_width:integer);
      Procedure Denis_line_limite(a,b,c,d:real; color:tcolorref; maxix,maxiy:real; with_sinusoide,spectral,smooth:boolean;
        Repetition,Amplitude,lumiere,saturation:real);
      Procedure Denis_line_progressive(a,b,c,d:real; color,second_color:tcolorref; stroke_width:integer);
      Procedure Flood_Fill(x,y:integer);
      procedure Applique_bitmap;
    public
      abitmap:tbitmap;
      bitmap_struct:TBitmapInfo;
      taille_bitmap:integer;
      pointer_bitmap:PTable;
      flood_color:tcolorref;
    end; {Tdbbitmap-intégré par denis Bertin le 17.3.2014}

implementation

uses k_erreur,g_base,math,wutil,utile,hls_rvb,deformat,u_object;

constructor TFastBitmap.Create(window:hwnd);
  begin
  inherited Create;
  self.abitmap:=Graphics.tbitmap.create;
  self.scan:=nil;
  self.size:=0;
  self.awindow:=window;
  end;

destructor TFastBitmap.Destroy;
 begin
 self.Liberation_de_la_scanline;
 self.abitmap.free;
 inherited Destroy;
 end;

procedure TFastBitmap.Assign(Source: TPersistent);
 begin
 self.abitmap.Assign(Source);
 self.Liberation_de_la_scanline;
 end;

function TFastBitmap.lecture_de_la_scanline:boolean;
 var i:integer;
 begin
 try
    begin
 if self.abitmap.PixelFormat<>pf24bit then
  self.abitmap.PixelFormat:=graphics.pf24bit;
    end
 except
  on EOutOfResources do
   begin
   //spécifique à l'application
   k_erreur.MessageBox(self.awindow,k_erreur.Err_Fichier_trop_volumineux,mb_iconstop+id_ok);
   lecture_de_la_scanline:=false;
   exit;
   end;
  end;
 size:=self.abitmap.Height*sizeof(pointer);
 getmem(self.scan,size);
 for i:=0 to pred(self.abitmap.Height) do self.scan[i]:=Self.abitmap.scanline[i];
 lecture_de_la_scanline:=true;
 end; {TFastBitmap.lecture_de_la_scanline}

procedure TFastBitmap.Liberation_de_la_scanline;
 begin
 if self.scan<>nil then
  freemem(self.scan,self.size);
 self.scan:=nil;
 self.size:=0;
 end;

function TFastBitmap.get_pixel(x,y:integer):TColor;
 var p:^byte;
   color:tcolorref;
 begin
 if self.scan=nil then
  lecture_de_la_scanline;
 if (y>=self.abitmap.height) or (x>=self.abitmap.width) or (x<0) or (y<0) then
  begin
  get_pixel:=g_base.rgb_noir;
    end
  else
    begin
    p:=self.scan^[y];
    inc(p,x*3);
    color:=P^ shl 16;
    inc(p);
    inc(color,p^ shl 8);
    inc(p);
    inc(color,p^);
    get_pixel:=color;
    end;
  end; {TFastBitmap.get_pixel}

function TFastBitmap.width:integer;
  begin
  result:=self.abitmap.Width;
  end;

function TFastBitmap.Height:integer;
  begin
  result:=self.abitmap.Height;
  end;

procedure TFastBitmap.set_pixel(x,y:integer; color:TColor);
  var p:pchar; {PByteArray;}
      q:pbytearray;
      d:integer;
  begin
  if self.scan=nil then
    lecture_de_la_scanline;
  if not ((y>=self.abitmap.height) or (x>=self.abitmap.width) or (y<0) or (x<0)) then
    begin
    q:=Self.scan[y];
    d:=x*3;
    q[d]:=(color shr 16) and 255;
    q[d+1]:=(color shr 8) and 255;
    q[d+2]:=color and 255;
    end;
  end; {TFastBitmap.set_pixel}

procedure TFastBitmap.For_a_rectangle_filling(sa_couleur:TColor);
  var i,j,ii,jj:integer;
  begin
  ii:=self.width-1;
  jj:=self.Height-1;
  for i:=0 to ii do for j:=0 to jj do self.Set_pixel(i,j,sa_couleur);
  end;

procedure TFastBitmap_8bits.Copy(iBmp : Graphics.tBitMap);
  begin
  try
  if iBmp.PixelFormat<>pf8bit then
  iBmp.PixelFormat:=pf8bit;
  Bmp:=iBmp;
 Scan0:=Integer(BMP.ScanLine[0]);
  if Bmp.height=1 then
    MLS:=Integer(Scan0)
  else
    MLS:=Integer(BMP.ScanLine[1]) - Scan0;
  W:=Bmp.width;
  H:=Bmp.Height;
  except Scan0:=0; end;
 end;

function TFastBitmap_8bits.GetPixel(X,Y : Integer):byte;
  begin
  if Scan0=0 then begin result:=0; exit; end;
 if (x>=0) and (y>=0) and (x<self.W) and (y<self.H) then
  Result:=pbyte(Scan0+Y*MLS+X)^
  else
    Result:=0;
  end;

procedure TFastBitmap_8bits.SetPixel(X,Y:Integer; alpha:byte);
  begin
  if Scan0=0 then exit;
 if (x>=0) and (y>=0) and (x<self.W) and (y<self.H) then
  pbyte(Scan0+Y*MLS+X)^:=alpha;
  end;

{--------------------------- TFastBitmap2 -------------------------------------}
{Amélioration des fonctions Get/SET BitMap en utilisant le langage d'assemblage}

procedure TFastBitmap2.creer(x,y:integer);
 begin
 Bmp:=Graphics.tBitMap.create;
 Bmp.width:=x;
 Bmp.height:=y;
 Self.determine;
 end;

procedure TFastBitmap2.Copy(iBmp:Graphics.tBitMap);
 begin
 Bmp:=iBmp;
 Self.determine;
 end;

procedure TFastBitmap2.Handle(a:hbitmap);
  begin
  Bmp:=Graphics.tBitMap.create;
  Bmp.Handle:=a;
  Self.determine;
  end;

procedure TFastBitmap2.Free_bmp;
  begin
  try self.bmp.free; except end;
  end;

procedure TFastBitmap2.Init(iBmp : Graphics.tBitMap);
 begin
 Bmp:=Graphics.tBitMap.create;
 Bmp.Assign(iBmp);
 Self.determine;
 end;

procedure TFastBitmap2.determine;
 begin
  try
  if (Bmp=nil) or (Bmp.width=0) then
    begin
    Scan0:=0; exit;
    end;
  if Bmp.PixelFormat<>pf24bit then
  Bmp.PixelFormat:=pf24bit;
 Scan0:=Integer(BMP.ScanLine[0]);
  if Bmp.height=1 then
    MLS  :=Integer(Scan0)
  else
    MLS  :=Integer(BMP.ScanLine[1]) - Scan0;
 BPP  := 3; // pour pf24bit
  W:=Bmp.width;
  H:=Bmp.Height;
  except
    Scan0:=0;
    end;
  end;

procedure TFastBitmap2.free;
  begin
  self.bmp.free;
  end;

(*
function tFastBitmap2.GetPixel(X,Y : Integer) : tColor; {Fonctionne}
var      Scan : integer; {$IFOPT O-} pRGB3 : pRGBTriple; {$ENDIF}
begin    Scan:=Scan0 + Y*MLS + X*BPP;
         {$IFOPT O+}
         asm
         mov eax,Scan; //Obtenir l'adresse
         mov ebx,[eax]; //Lire le mot dans EBX
         mov eax,ebx; //Déplacer ce mot dans EAX
         mov ecx,ebx; //Déplacer ce mot dans ECX
         shr eax,$10; //tourner de 16 bits
         and eax,$ff;
         and ebx,$ff00
         or  ebx,eax;
         shl ecx,$10;
         and ecx,$ff0000;
         or  ebx,ecx;
         end; {asm}
         {$ELSE}
         pRGB3 := pRGBTriple(Scan);
         with pRGB3^ do Result:=RGB(rgbtRed,rgbtGreen,rgbtBlue);
         {$ENDIF}
end;
*)

(*
function tFastBitmap2.GetPixel(X,Y : Integer) : tColor; {Fonctionne}
var      Scan : integer; {$IFOPT O-} pRGB3 : pRGBTriple; {$ENDIF}
begin    Scan:=Scan0 + Y*MLS + X*BPP;
         {$IFOPT O+}
         asm
         mov eax,Scan; //Obtenir l'adresse
         mov bx,[eax]; //Lire le mot dans EBX
         mov cl,[eax+2];
         mov al,bl;
         shl eax,$10;
         and ebx,$0000ff00;
         add ebx,eax;
         add ebx,ecx;
         end; {asm}
         {$ELSE}
         pRGB3 := pRGBTriple(Scan);
         with pRGB3^ do Result:=RGB(rgbtRed,rgbtGreen,rgbtBlue);
         {$ENDIF}
end;
*)

(*
function tFastBitmap2.GetPixel(X,Y : Integer) : tColor; {Fonctionne}
var      Scan : integer; {$IFOPT O-} pRGB3 : pRGBTriple; {$ENDIF}
begin    Scan:=Scan0 + Y*MLS + X*BPP;
         {$IFOPT O+}
         asm
            mov eax,Scan;
            mov cl,[eax];
            mov dl,[eax+$01];
            mov al,[eax+$02];
            and eax,$000000ff;
            and edx,$000000ff;
            shl edx,$08;
            or eax,edx;
            xor edx,edx;
            mov dl,cl;
            shl edx,$10;
            or eax,edx;
            mov ebx,eax;
         end; {asm}
         {$ELSE}
         pRGB3 := pRGBTriple(Scan);
         with pRGB3^ do Result:=RGB(rgbtRed,rgbtGreen,rgbtBlue);
         {$ENDIF}
end;
*)

procedure tFastBitmap2.Set_Pixel_in_limite_variation_Y(xx,y :integer; color : TColor);
  begin
  if Scan0=0 then exit;
  with pRGBTriple(Scan0 + Y*MLS + XX)^ do //la voilà.
    begin
    rgbtRed  :=color; // and $ff;
    rgbtGreen:=color shr 8; // and $ff;
    rgbtBlue :=color shr 16; // and $ff;
    end;
  end;

procedure tFastBitmap2.Set_Pixel_in_limite_variation_Y_sans_tab(xx,y :integer; color : TColor);
  begin
  if Scan0=0 then exit;
  with pRGBTriple(Y*MLS+XX)^ do
    begin
    rgbtRed  :=color;
    rgbtGreen:=(color shr 8);
    rgbtBlue :=(color shr 16);
    end;
  end;

function tFastBitmap2.GetPixel_in_limite_variation_Y(xx,y : Integer) : tColor;
  begin
  if Scan0=0 then begin result:=0; exit; end;
  with pRGBTriple(Scan0 + Y*MLS + xx)^ do
    Result:=rgbtRed or (rgbtGreen shl 8) or (rgbtBlue shl 16); {and $00ff00 and $ff0000}
    //Result:=RGB(rgbtRed,rgbtGreen,rgbtBlue);
  end;

function tFastBitmap2.GetPixel_in_limite_variation_Y_sans_tab(xx,y : Integer) : tColor;
  begin
  if Scan0=0 then begin result:=0; exit; end;
  with pRGBTriple(Y*MLS + xx)^ do
    Result:=rgbtRed or (rgbtGreen shl 8) or (rgbtBlue shl 16); {and $00ff00 and $ff0000}
  end;

procedure tFastBitmap2.SetPixel_in_limite(x,y :integer; color : TColor);
  begin
  if Scan0=0 then exit;
  try
  with pRGBTriple(Scan0 + Y*MLS + X*BPP)^ do
    begin
    rgbtRed  :=color; // and $ff;
    rgbtGreen:=color shr 8; // and $ff;
    rgbtBlue :=color shr 16; //and $ff;
    (*
  rgbtRed  :=GetRValue(color);
  rgbtGreen:=GetGValue(color);
  rgbtBlue :=GetBValue(color);
    *)
  end;
  except end;
  end;

function tFastBitmap2.GetPixel_in_limite(X,Y : Integer) : tColor;
  begin
  if Scan0=0 then begin result:=0; exit; end;
  try
    with pRGBTriple(Scan0 + Y*MLS + X*BPP)^ do
      Result:=rgbtRed or (rgbtGreen shl 8) or (rgbtBlue shl 16);
      //Result:=RGB(rgbtRed,rgbtGreen,rgbtBlue);
  except end;
  end;

function tFastBitmap2.GetPixel(X,Y : Integer) : tColor;
 begin
  if Scan0=0 then begin result:=0; exit; end;
  try
 if (x>=0) and (y>=0) and (x<self.W) and (y<self.H) then
  begin
   with pRGBTriple(Scan0 + Y*MLS + X*BPP)^ do
      Result:=rgbtRed or (rgbtGreen shl 8) or (rgbtBlue shl 16);
        //Result:=RGB(rgbtRed,rgbtGreen,rgbtBlue);
  end
 else
  GetPixel:=g_base.rgb_blanc;
  except
    Scan0:=0;
    end;
  end;

procedure tFastBitmap2.SetPixel(x,y :integer; color : TColor);
  //{$IFOPT O+} var scan:integer; ENDIF}
  begin
  if Scan0=0 then exit;
  if (x>=0) and (y>=0) and (x<self.W) and (y<self.H) then
  begin
    if false then
      begin
      {$IFOPT O+}
      Scan:=Scan0 + Y*MLS + X*BPP;
      {$ENDIF}
      if false then
      begin
      {$IFOPT O+}
      asm
      mov ebx,Scan;
      add ebx,2;
      mov eax,color;
      mov [ebx],al;
      dec ebx;
      shr eax,$08;
      mov [ebx],al;
      dec ebx;
      shr eax,$08;
      mov [ebx],al;
      end; {asm}
      {$ELSE}
      {$ENDIF}
     end
      end
  else
   begin
   with pRGBTriple(Scan0 + Y*MLS + X*BPP)^ do
    begin
        rgbtRed  :=color; // and $ff;
        rgbtGreen:=(color shr 8); // and $ff;
        rgbtBlue :=(color shr 16); // and $ff;
        (*
    rgbtRed  :=GetRValue(color);
    rgbtGreen:=GetGValue(color);
    rgbtBlue :=GetBValue(color);
        *)
    end;
   end;
  end
  end;

(*
procedure tFastBitmap2.SetPixel(x,y :integer; color : TColor);
var       Scan : integer;
begin
          Scan:=Scan0 + Y*MLS + X*BPP;
            with pRGBTriple(Scan)^ do begin
                 rgbtRed  :=GetRValue(color);
                 rgbtGreen:=GetGValue(color);
                 rgbtBlue :=GetBValue(color);
            end;
end;
*)

procedure tFastBitmap2.ligne_horizontale(y:integer; color : TColor);
  var x:integer;
  begin
  for x:=0 to pred(self.w) do SetPixel(x,y,color);
  end; {ligne_horizontale}

procedure tFastBitmap2.ligne_vertical(x:integer; color : TColor);
  var y:integer;
  begin
  for y:=0 to pred(self.h) do SetPixel(x,y,color);
  end; {ligne_vertical}

procedure tFastBitmap2.ligne_horizontale_fromage(a,b,y:integer; color : TColor);
  var x:integer;
  begin
  for x:=a to b do SetPixel(x,y,color);
  end;

procedure tFastBitmap2.ligne_verticale_fromage(x,a,b:integer; color : TColor);
  var y:integer;
  begin
  for y:=a to b do SetPixel(x,y,color);
  end;

procedure tFastBitmap2.RectangleFilling(color : TColor);
var       y,x, ScanY,ScanYX : integer; R,G,B : byte;
begin     R:=GetRValue(color);
          G:=GetGValue(color);
          B:=GetBValue(color);
          for y:=0 to pred(H) do begin
              ScanY:=Scan0 + Y*MLS;
              for x:=0 to pred(W) do begin
                  ScanYX:=ScanY + X*BPP;
                  with pRGBTriple(ScanYX)^ do begin
                       rgbtRed  :=R;
                       rgbtGreen:=G;
                       rgbtBlue :=B;
                  end;
              end;
          end;
end;

constructor Tdbbitmap.create(un_bitmap:tbitmap);
  begin
  inherited create;
  self.abitmap:=un_bitmap;
  self.initialise;
  end;

procedure Tdbbitmap.initialise;
  begin
  taille_bitmap:=(self.abitmap.Width*self.abitmap.Height) shl 2;
  getmem(pointer_bitmap,taille_bitmap);
  with bitmap_struct.bmiHeader do
    begin
    bisize:=sizeof(bitmap_struct.bmiHeader);
    biWidth:=self.abitmap.Width;
    biHeight:=self.abitmap.Height;
    biPlanes:=1;
    bibitcount:=32;
    bicompression:=BI_RGB;
    biSizeImage:=0;
    biXPelspermeter:=1;
    biYPelspermeter:=1;
    biClrUsed:=0;
    biClrImportant:=0;
    end;
  GetDIBits(self.abitmap.Canvas.Handle,self.abitmap.Handle,
    0,bitmap_struct.bmiHeader.biHeight,pointer_bitmap,bitmap_struct,DIB_RGB_COLORS);
  end;

destructor Tdbbitmap.destroy;
  begin
  freemem(pointer_bitmap,taille_bitmap);
  inherited destroy;
  end;

function Tdbbitmap.Getpixel(x,y:integer):tcolorref;
  var color:tcolorref;
  begin
  if (x>=0) and (y>=0) and (x<self.abitmap.Width) and (y<self.abitmap.Height) then
    begin
    color:=pointer_bitmap[(pred(self.abitmap.Height)-y)*self.abitmap.Width+x];
    result:=rgb((color shr 16) and $ff,(color shr 8) and $ff,color and $ff);
    end
  else
    result:=g_base.rgb_noir;
  end; {Tdbbitmap.Getpixel}

procedure Tdbbitmap.Cross_pixel(x,y:integer; une_couleur:tcolorref);
  begin
  self.Setpixel(x,y,une_couleur);
  self.Setpixel(x-1,y-1,une_couleur);
  self.Setpixel(x+1,y+1,une_couleur);
  self.Setpixel(x-1,y+1,une_couleur);
  self.Setpixel(x+1,y-1,une_couleur);
  end; {Tdbbitmap.Cross_pixel}

Procedure Tdbbitmap.Flood_Fill(x,y:integer);
  begin
  if Getpixel(x,y)=g_base.rgb_blanc then ///<>color
    begin
    Setpixel(x,y,self.flood_color);
    if x-1>=0 then Flood_Fill(x-1,y);
    if x+1<self.abitmap.Width then Flood_Fill(x+1,y);
    if y-1>=0 then Flood_Fill(x,y-1);
    if y+1<self.abitmap.Height then Flood_Fill(x,y+1);
    end;
  end;

procedure Tdbbitmap.setpixel_in_limite(x,y:integer; une_couleur:tcolorref);
  var color:tcolorref;
  begin
  color:=rgb((une_couleur shr 16) and $ff,(une_couleur shr 8) and $ff,une_couleur and $ff);
  pointer_bitmap[(pred(self.abitmap.Height)-y)*self.abitmap.Width+x]:=color;
  end;

procedure Tdbbitmap.Setpixel_transparent(x,y:integer; une_couleur:tcolorref; transparent:real);
  var dos_couleur:tcolorref;
      coefficient_alpha:real;
  begin
  if (x>=0) and (y>=0) and (x<self.abitmap.Width) and (y<self.abitmap.Height) then
    begin
    dos_couleur:=self.Getpixel(x,y);
    coefficient_alpha:=1-transparent;    ;
    self.Setpixel_in_limite(x,y,
      rgb(
        min(255,max(0,round(getrvalue(une_couleur)*coefficient_alpha+getrvalue(dos_couleur)*transparent))),
        min(255,max(0,round(getgvalue(une_couleur)*coefficient_alpha+getgvalue(dos_couleur)*transparent))),
        min(255,max(0,round(getbvalue(une_couleur)*coefficient_alpha+getbvalue(dos_couleur)*transparent)))));
    end; //Dans les limite
  end; {Tdbbitmap.Setpixel_transparent}

procedure Tdbbitmap.setpixel(x,y:integer; une_couleur:tcolorref);
  var color:tcolorref;
  begin
  if (x>=0) and (y>=0) and (x<self.abitmap.Width) and (y<self.abitmap.Height) then
    begin
    color:=rgb((une_couleur shr 16) and $ff,(une_couleur shr 8) and $ff,une_couleur and $ff);
    pointer_bitmap[(pred(self.abitmap.Height)-y)*self.abitmap.Width+x]:=color;
    end;
  end;

procedure Tdbbitmap.Fillrect_real(x,y,xx,yy:real; une_couleur:tcolorref);
  begin
  self.Fillrect(round(x),round(y),round(xx),round(yy),une_couleur);
  end; {Tdbbitmap.Fillrect_real}

procedure Tdbbitmap.Fillrect(x,y,xx,yy:integer; une_couleur:tcolorref);
  var i,j:integer;
  begin
  for i:=math.max(0,x) to math.min(xx,self.bitmap_struct.bmiHeader.biWidth) do
    for j:=math.max(0,y) to math.min(yy,self.bitmap_struct.bmiHeader.biHeight) do
      Self.setpixel(i,j,une_couleur);
  end;

procedure Tdbbitmap.CrossRect(x,y,xx,yy,alpha:integer; une_couleur:tcolorref);
  var i,j:integer;
      apt:tpoint;
      rect_un,rect_deux,rect_trois,rect_quatre:trect;
  begin
  for i:=math.max(0,x) to pred(math.min(xx,self.bitmap_struct.bmiHeader.biWidth)) do
    for j:=math.max(0,y) to pred(math.min(yy,self.bitmap_struct.bmiHeader.biHeight)) do
      begin
      apt.x:=i; apt.y:=j;
      setrect(rect_un,x,y,x+alpha,y+alpha);
      setrect(rect_deux,xx-alpha,y,xx,y+alpha);
      setrect(rect_trois,xx-alpha,yy-alpha,xx,yy);
      setrect(rect_quatre,x,yy-alpha,x+alpha,yy);
      if ptinrect(rect_un,apt) then
        begin
        end
      else if ptinrect(rect_deux,apt) then
        begin
        end
      else if ptinrect(rect_trois,apt) then
        begin
        end
      else if ptinrect(rect_quatre,apt) then
        begin
        end
      else
        Self.setpixel(i,j,une_couleur);
      end;
  end; {Tdbbitmap.Roundrect- écrit par denis B}

procedure Tdbbitmap.RoundRect(x,y,xx,yy,alpha:integer; une_couleur:tcolorref);
  var i,j:integer;
      apt:tpoint;
      rect_un,rect_deux,rect_trois,rect_quatre:trect;
  begin
  for i:=math.max(0,x) to math.min(xx,self.bitmap_struct.bmiHeader.biWidth) do
    for j:=math.max(0,y) to math.min(yy,self.bitmap_struct.bmiHeader.biHeight) do
      begin
      apt.x:=i; apt.y:=j;
      setrect(rect_un,x,y,x+alpha,y+alpha);
      setrect(rect_deux,xx-alpha,y,succ(xx),y+alpha);
      setrect(rect_trois,succ(xx)-alpha,succ(yy)-alpha,succ(xx),succ(yy));
      setrect(rect_quatre,x,succ(yy)-alpha,x+alpha,succ(yy));
      if ptinrect(rect_un,apt) then
        begin
        if utile.distance(i,j,x+alpha,y+alpha)<=alpha then
          Self.setpixel(i,j,une_couleur);
        end
      else if ptinrect(rect_deux,apt) then
        begin
        if utile.distance(i,j,xx-alpha,y+alpha)<=alpha then
          Self.setpixel(i,j,une_couleur);
        end
      else if ptinrect(rect_trois,apt) then
        begin
        if utile.distance(i,j,xx-alpha,yy-alpha)<=alpha then
          Self.setpixel(i,j,une_couleur);
        end
      else if ptinrect(rect_quatre,apt) then
        begin
        if utile.distance(i,j,x+alpha,yy-alpha)<=alpha then
          Self.setpixel(i,j,une_couleur);
        end
      else
        Self.setpixel(i,j,une_couleur);
      end;
  end; {Tdbbitmap.RoundRect}

procedure Tdbbitmap.Drawrect_transparent(x,y,xx,yy:integer; une_couleur:tcolorref; transparent:real);
  var i:integer;
  begin
  for i:=x to xx do
    begin
    Self.Setpixel_transparent(i,y,une_couleur,transparent);
    Self.Setpixel_transparent(i,yy,une_couleur,transparent);
    end;
  for i:=y to yy do
    begin
    Self.Setpixel_transparent(x,i,une_couleur,transparent);
    Self.Setpixel_transparent(xx,i,une_couleur,transparent);
    end;
  end;

procedure Tdbbitmap.Drawrect(x,y,xx,yy:integer; une_couleur:tcolorref);
  var i:integer;
  begin
  for i:=x to xx do
    begin
    Self.setpixel(i,y,une_couleur);
    Self.setpixel(i,yy,une_couleur);
    end;
  for i:=y to yy do
    begin
    Self.setpixel(x,i,une_couleur);
    Self.setpixel(xx,i,une_couleur);
    end;
  end;

procedure Tdbbitmap.FillCircle_single(x,y,rayon:single; une_couleur:tcolorref; light:boolean);
 begin
  FillCircle(round(x),round(y),round(rayon),une_couleur,light);
  end;

procedure Tdbbitmap.FillCircle(x,y,rayon:integer; une_couleur:tcolorref; light:boolean);
  var i,j,k,etendu,hauteur,posit_vertical:integer; r:trect; inside:boolean;
      la_distance_de_ce_point_au_centre:integer; h,l,s:real;
  begin
  if not ((x+rayon>=0) and (y+rayon>=0)) then exit;
  if not ((x-rayon<=self.abitmap.Width) and (y-rayon<=self.abitmap.Height)) then exit;
  setrect(r,x-rayon,y-rayon,x+rayon,y+rayon);
  etendu:=r.left+r.right; hauteur:=r.top+r.bottom;
  if true then
    begin
    if light then hls_rvb.tcolorref_to_hls(une_couleur,h,l,s);
    for j:=r.top to y do //r.bottom do
      begin
      posit_vertical:=hauteur-j;
      i:=r.left;
      inside:=false;
      while not inside and (i<=x) do
        begin
        la_distance_de_ce_point_au_centre:=utile.idistance(i,j,x,y);
        if la_distance_de_ce_point_au_centre<rayon then //Use 1/4 Square root function less
          begin
          inside:=true;
           for k:=i to (etendu-i) do
            begin
            if not light then
              begin
              self.Setpixel(k,j,une_couleur);
              self.Setpixel(k,posit_vertical,une_couleur);
              end
            else
              begin
              la_distance_de_ce_point_au_centre:=utile.idistance(k,j,x,y);
              une_couleur:=hls_rvb.Get_HLS_RGB(h,0.5+0.5*(la_distance_de_ce_point_au_centre/rayon),1);
              self.Setpixel(k,j,une_couleur);
              self.Setpixel(k,posit_vertical,une_couleur);
              end;
            end; {for k}
          end; {la_distance_de_ce_point_au_centre<rayon}
        inc(i);
        end //While
      end {for j}
    end
  else
    for i:=r.left to r.right do for j:=r.top to r.bottom do
      if utile.idistance(i,j,x,y)<rayon then
        self.Setpixel(i,j,une_couleur);
  end; {Tdbbitmap.FillCircle}

procedure Tdbbitmap.FillRectSoft(x,y,xx,yy:integer; une_couleur:tcolorref);
  var borne_central:tpoint; m,n,h,l,s:real; i,j,miny,maxy:integer;
  begin
  borne_central.x:=(x+xx) div 2; borne_central.y:=(y+yy) div 2;
  m:=utile.single_distance(x,y,borne_central.x,borne_central.y);
  hls_rvb.tcolorref_to_hls(une_couleur,h,l,s);
  miny:=max(0,y); maxy:=min(abitmap.Height,yy);
  for i:=max(0,x) to min(abitmap.Width,xx) do for j:=miny to maxy do
    begin
    with borne_central do n:=utile.single_distance(i,j,x,y);
    self.Setpixel(i,j,hls_rvb.Get_HLS_RGB(h,0.5+0.5*(n/m),1));
    end;
  end; {Tdbbitmap.FillRectSoft}

procedure Tdbbitmap.Drawrect_round(x,y,xx,yy:real; une_couleur:tcolorref);
  begin
  self.Drawrect(round(x),round(y),round(xx),round(yy),une_couleur);
  end; {Tdbbitmap.Drawrect}

procedure Tdbbitmap.applique_bitmap;
  begin
  SetDIBits(self.abitmap.Canvas.Handle,self.abitmap.Handle,0,self.abitmap.height,pointer_bitmap,bitmap_struct,DIB_RGB_COLORS);
  end;

Procedure Tdbbitmap.Denis_line_progressive(a,b,c,d:real; color,second_color:tcolorref; stroke_width:integer);
  var longeur_effective:integer;
      position:integer;
      i,j:integer;
     dx,dy:real;
      old_a,old_b,old_c,old_d:real;
      depart,arriver,maximum,deplacement:integer;
  begin
  old_a:=a;
  old_b:=b;
  old_c:=c;
  old_d:=d;
  longeur_effective:=0;
  if (a-c)=0 then
  begin {vertical}
  j:=round(a);
  for i:=math.min(round(b),round(d)) to math.max(round(b),round(d)) do
    inc(longeur_effective);
  end {vertical}
  else if (b-d)=0 then
  begin {horizontal}
  j:=round(b);
  for i:=math.min(round(a),round(c)) to math.max(round(a),round(c)) do
    inc(longeur_effective);
  end {horizontal}
  else
    begin
    {delta - différence}
    dx:=(b-d)/(a-c);
    dy:=(a-c)/(b-d);
    if abs(dx)<abs(dy) then
   begin {progression horizontal}
   if a<c then
    begin {quartier 0-45°}
    for i:=round(a) to round(c) do
      begin
      b:=b+dx;
       inc(longeur_effective);
      end
    end {quartier 0-45°}
   else
    begin {quartier 180°-135°}
    for i:=round(c) to round(a) do
      begin
      d:=d+dx;
       inc(longeur_effective);
      end
    end; {quartier 180°-135}
   end {progression horizontal}
  else
   begin {progression vertical}
   if b<d then
    begin {quartier 45°-90°}
    for i:=round(b) to round(d) do
     begin
     a:=a+dy;
      inc(longeur_effective);
     end;
    end {quartier 45°-90°}
   else
    begin {quartier 90°-135°}
    for i:=round(d) to round(b) do
     begin
     c:=c+dy;
      inc(longeur_effective);
     end;
    end; {quartier 90°-135°}
   end; {progression vertical}
  end;
  position:=-1;
  a:=old_a;
  b:=old_b;
  c:=old_c;
  d:=old_d;
  if (a-c)=0 then
  begin {vertical}
  j:=round(a);
   depart:=math.min(round(b),round(d));
   arriver:=math.max(round(b),round(d));
   maximum:=arriver-depart;
   deplacement:=0;
  for i:=depart to arriver do
    begin
    inc(position);
    if color=second_color then
      self.Setpixel(j,i,hls_rvb.Get_HLS_RGB(360*position/longeur_effective,0.50,1))
    else
      begin
      self.Setpixel(j,i,deformat.IN_Between_longint_RGB(color,second_color,deplacement,maximum));
      if (stroke_width>=10) and (stroke_width<18) then
        self.Setpixel(j+1,i,deformat.IN_Between_longint_RGB(color,second_color,deplacement,maximum))
      else if stroke_width>=18 then
        begin
        self.Setpixel(j-1,i,deformat.IN_Between_longint_RGB(color,second_color,deplacement,maximum));
        self.Setpixel(j+1,i+1,deformat.IN_Between_longint_RGB(color,second_color,deplacement,maximum));
        end;
      inc(deplacement);
      end;
    end;
  exit;
  end; {vertical}
  if (b-d)=0 then
  begin {horizontal}
  j:=round(b);
   depart:=math.min(round(a),round(c));
   arriver:=math.max(round(a),round(c));
   maximum:=arriver-depart;
   deplacement:=0;
  for i:=depart to arriver do
    begin
    inc(position);
    if color=second_color then
    self.Setpixel(i,j,hls_rvb.Get_HLS_RGB(360*position/longeur_effective,0.50,1))
    else
      begin
      self.Setpixel(i,j,deformat.IN_Between_longint_RGB(color,second_color,i-depart,maximum));
      if (stroke_width>=10) and (stroke_width<18) then
        self.Setpixel(i,j+1,deformat.IN_Between_longint_RGB(color,second_color,i-depart,maximum))
      else if stroke_width>=18 then
        begin
        self.Setpixel(i,j-1,deformat.IN_Between_longint_RGB(color,second_color,i-depart,maximum));
        self.Setpixel(i,j+1,deformat.IN_Between_longint_RGB(color,second_color,i-depart,maximum));
        end;
      inc(deplacement);
      end;
    end;
  exit;
  end; {horizontal}
  {delta - différence}
  dx:=(b-d)/(a-c);
  dy:=(a-c)/(b-d);
  if abs(dx)<abs(dy) then
 begin {progression horizontal}
  if a<c then
  begin {quartier 0-45°}
  for i:=round(a) to round(c) do
    begin
    b:=b+dx;
      inc(position);
     self.Setpixel(i,round(b),hls_rvb.Get_HLS_RGB(360*position/longeur_effective,0.50,1));
    end
  end {quartier 0-45°}
  else
  begin {quartier 180°-135°}
  for i:=round(c) to round(a) do
    begin
    d:=d+dx;
      inc(position);
     self.Setpixel(i,round(d),hls_rvb.Get_HLS_RGB(360*position/longeur_effective,0.50,1));
    end
  end; {quartier 180°-135}
 end {progression horizontal}
  else
 begin {progression vertical}
 if b<d then
  begin {quartier 45°-90°}
  for i:=round(b) to round(d) do
   begin
   a:=a+dy;
      inc(position);
    self.Setpixel(round(a),i,hls_rvb.Get_HLS_RGB(360*position/longeur_effective,0.50,1));
   end;
  end {quartier 45°-90°}
 else
  begin {quartier 90°-135°}
  for i:=round(d) to round(b) do
   begin
   c:=c+dy;
      inc(position);
    self.Setpixel(round(c),i,hls_rvb.Get_HLS_RGB(360*position/longeur_effective,0.50,1));
   end;
  end; {quartier 90°-135°}
 end; {progression vertical}
end; {Tdbbitmap.Denis_line_progressive}

Procedure Tdbbitmap.Denis_line_limite(a,b,c,d:real; color:tcolorref; maxix,maxiy:real;
    with_sinusoide,spectral,smooth:boolean; repetition,amplitude,lumiere,saturation:real);
  var i,j:integer;
    dx,dy:real;
     ma_couleur,une_couleur:TColorRef;

  procedure My_Setpixel(j,i:integer);
    var h,l,s:real;
    begin
    if smooth then
      begin
      hls_rvb.tcolorref_to_hls(ma_couleur,h,l,s);
      une_couleur:=hls_rvb.Get_HLS_RGB(h,0.75,1);
      self.Setpixel(j-1,i-1,une_couleur);
      self.Setpixel(j-1,i+1,une_couleur);
      self.Setpixel(j+1,i-1,une_couleur);
      self.Setpixel(j+1,i+1,une_couleur);
      end;
    self.Setpixel(j,i,ma_couleur);
    end;

  begin
  ma_couleur:=color;
  if (a-c)=0 then
  begin {vertical}
  j:=round(a);
  for i:=math.min(round(b),round(d)) to math.max(round(b),round(d)) do
    begin
    if spectral then ma_couleur:=hls_rvb.Get_HLS_RGB(360*i/maxiy,lumiere,saturation);
    if with_sinusoide then
      My_Setpixel(j+round(cos(pi/4*repetition*i/maxiy)*amplitude),i)
    else
      My_Setpixel(j,i);
    end;
  end {vertical}
  else if (b-d)=0 then
  begin {horizontal}
  j:=round(b);
  for i:=math.min(round(a),round(c)) to math.max(round(a),round(c)) do
      begin
      if spectral then ma_couleur:=hls_rvb.Get_HLS_RGB(360*i/maxix,lumiere,saturation);
      if with_sinusoide then
        My_Setpixel(i,j+round(cos(pi/4*repetition*i/maxix)*amplitude))
      else
        My_Setpixel(i,j);
      end;
    end; {horizontal}
  end; {Tdbbitmap.Denis_line_limite, le 19.11.2019-denis B}

Procedure Tdbbitmap.Denis_line_single(a,b,c,d:real; color:tcolorref);
  var i,j:integer;
   dx,dy:real;
  begin
  if (a-c)=0 then
    begin {verticalement}
   j:=round(a);
   for i:=math.min(round(b),round(d)) to math.max(round(b),round(d)) do
      self.Setpixel(j,i,color);
   end {vertical}
  else if (b-d)=0 then
    begin {horizontalement}
    j:=round(b);
    for i:=math.min(round(a),round(c)) to math.max(round(a),round(c)) do
      self.Setpixel(i,j,color);
    end
  else
    begin //Les quatre quartiers
    {delta - différence}
    dx:=(b-d)/(a-c);
    dy:=(a-c)/(b-d);
    if abs(dx)<abs(dy) then
     begin {progression horizontal}
      if a<c then
      begin {quartier 0-45°}
      for i:=round(a) to round(c) do
        begin
        b:=b+dx;
          self.Setpixel(i,round(b),color); //round
          end
      end {quartier 0-45°}
     else
      begin {quartier 180°-135°}
      for i:=round(c) to round(a) do
        begin
        d:=d+dx;
          self.Setpixel(i,round(d),color);
        end
      end; {quartier 180°-135}
     end {progression horizontal}
    else
     begin {progression vertical}
     if b<d then
      begin {quartier 45°-90°}
      for i:=round(b) to round(d) do
       begin
       a:=a+dy;
          self.Setpixel(round(a),i,color);
       end;
      end {quartier 45°-90°}
     else
      begin {quartier 90°-135°}
      for i:=round(d) to round(b) do
       begin
       c:=c+dy;
          self.Setpixel(round(c),i,color);
       end;
      end; {quartier 90°-135°}
      end;
    end;
  end; {Tdbbitmap.Denis_line_single}

Procedure Tdbbitmap.Denis_line_hori(x,y,xx:integer; une_couleur:tcolorref);
  var i:integer;
  begin
  for i:=math.max(0,x) to math.min(xx,pred(self.abitmap.Width)) do
    self.Setpixel(i,y,une_couleur);
  end; {Tdbbitmap.Denis_line_hori}

Procedure Tdbbitmap.Denis_line_hori_square_gradian(x,y,xx:integer; m:real; rect:trect;
    une_couleur:tcolorref; collection:contnrs.TObjectList; hue_lum_sat:boolean);
  var i,ratio,obtenir:integer; center:tpoint; une_distance,dos_distance,coefficient:real;
  begin
  center.x:=(rect.left+rect.right) div 2;
  center.y:=(rect.bottom+rect.top) div 2;
  une_distance:=utile.single_distance(0,y,center.x,center.y);
  if une_distance>=1 then
    begin
    coefficient:=1000/une_distance; {1000 et une distance ne varient pas dans cette boucle for i}
    for i:=math.max(0,x) to math.min(xx,pred(self.abitmap.Width)) do
      begin
      dos_distance:=abs(center.x-i);
      ratio:=math.min(1000,math.max(0,round(dos_distance*coefficient)));
      self.Setpixel_in_limite(i,y,
        u_object.T_Col_point_couleur(collection).in_between_color(ratio,hue_lum_sat,false,obtenir));
      end {délice thé end ? ou pas}
    end
  else
    Denis_line_hori(x,y,xx,une_couleur);
  end; {Tdbbitmap.Denis_line_hori_square_gradian}

Procedure Tdbbitmap.Denis_line_hori_parralelle(x,y,xx:integer; rect:trect; angle:integer;
    une_couleur:tcolorref; collection:contnrs.TObjectList; hue_lum_sat:boolean);
  var i,ratio,obtenir:integer; center:tpoint;
      une_distance,dos_distance,tres_distance,alpha:real;
      pt,ptA,ptB:Point2D;
  begin
  alpha:=angle*pi/180;
  center.x:=(rect.left+rect.right) div 2;
  center.y:=(rect.bottom+rect.top) div 2;
  une_distance:=utile.distance(rect.left,rect.top,rect.right,rect.bottom);

  ptA.x:=center.x+cos(alpha)*une_distance;
  ptA.y:=center.y-sin(alpha)*une_distance;
  ptB.x:=center.x+cos(alpha+Pi)*une_distance;
  ptB.y:=center.y-sin(alpha+Pi)*une_distance;

  pt.x:=0; pt.y:=0; dos_distance:=DistDroite(pt,ptA,ptB); //thé end ?

  for i:=math.max(0,x) to math.min(xx,pred(self.abitmap.Width)) do
    begin
    if ((angle=0) or (angle=180)) and (rect.bottom<>rect.top) then
      begin
      ratio:=math.min(1000,math.max(0,round(y/(rect.bottom-rect.top)*1000)));
      if collection=nil then
        self.Setpixel(i,y,une_couleur)
      else
        self.Setpixel_in_limite(i,y,
          u_object.T_Col_point_couleur(collection).in_between_color(ratio,hue_lum_sat,false,obtenir));
      end
    else if ((angle=90) or (angle=270)) and (rect.right<>rect.left) then
      begin
      ratio:=math.min(1000,math.max(0,round(y/(rect.right-rect.left)*1000)));
      if collection=nil then
        self.Setpixel_in_limite(i,y,une_couleur)
      else
        self.Setpixel_in_limite(i,y,
          u_object.T_Col_point_couleur(collection).in_between_color(ratio,hue_lum_sat,false,obtenir));
      end
    else
      begin
      pt.y:=y; pt.x:=i; tres_distance:=DistDroite(pt,ptA,ptB); //thé end ?
      ratio:=math.max(0,math.min(1000,round(1000*tres_distance/dos_distance)));
      if collection=nil then
        self.Setpixel(i,y,une_couleur)
      else
        self.Setpixel(i,y,u_object.T_Col_point_couleur(collection).in_between_color(ratio,hue_lum_sat,false,obtenir));
      end;
    end;
  end; {Tdbbitmap.Denis_line_hori_parralelle-delice le 8.2.2020}

Procedure Tdbbitmap.Denis_line_hori_graduate(x,y,xx:integer; ptA,ptB:my_math.Point2D; m:real;
    une_couleur:tcolorref; collection:contnrs.TObjectList; hue_lum_sat:boolean);
  var h,l,s,n:real; i,ratio,obtenir:integer; pt:my_math.Point2D;
  begin
  pt.y:=y;
  hls_rvb.tcolorref_to_hls(une_couleur,h,l,s);
  for i:=math.max(0,x) to math.min(xx,pred(self.abitmap.Width)) do
    begin
    if collection.count=0 then
      self.Setpixel_in_limite(i,y,hls_rvb.Get_HLS_RGB(h,0.5+0.5*(n/m),1)) {De denis bertin}
    else
      begin
      pt.x:=i;
      n:=DistDroite(pt,ptA,ptB);
      ratio:=math.min(1000,math.max(0,round(n/m*1000)));
      self.Setpixel_in_limite(i,y,
        u_object.T_Col_point_couleur(collection).in_between_color(ratio,hue_lum_sat,false,obtenir));
      end;
    end;
  end; {Tdbbitmap.Denis_line_hori_graduate}

Procedure Tdbbitmap.Denis_line_hori_circulaire(x,y,xx:integer; borne_central:tpoint; m:real;
    une_couleur:tcolorref; collection:contnrs.TObjectList; hue_lum_sat:boolean);
  var i,obtenir:integer; h,l,s,n:real;
  begin
  try
  hls_rvb.tcolorref_to_hls(une_couleur,h,l,s);
  for i:=math.max(0,x) to math.min(xx,pred(self.abitmap.Width)) do
    begin
    n:=utile.single_distance(i,y,borne_central.x,borne_central.y);
    if collection.count=0 then
      self.Setpixel_in_limite(i,y,hls_rvb.Get_HLS_RGB(h,0.5+0.5*(n/m),1)) {De denis bertin}
    else
      self.Setpixel_in_limite(i,y,
        u_object.T_Col_point_couleur(collection).in_between_color(round(n/m*1000),hue_lum_sat,false,obtenir));
    end;
  except end;
  end; {Tdbbitmap.Denis_line_hori_circulaire}

Procedure Tdbbitmap.Denis_line_single_epaisseur(a,b,c,d:real; color:tcolorref; width:integer; style:U_fast_bitmap.PTStyle);
  var i,j:integer;
   dx,dy:real;

    procedure local_Setpixel(x,y:integer);
      var i,j:integer;
    begin
    case style of
      PTS_Square,PTS_Triangle:
        for i:=-width to width do for j:=-width to width do
          self.Setpixel(x+i,y+j,color);
      PTS_round:
        for i:=-width to width do for j:=-width to width do
          if utile.distance(x+i,y+j,x,y)<width then
            self.Setpixel(x+i,y+j,color);
      end; {case}
    end; {local_Setpixel}

  begin
  if (a-c)=0 then
  begin {vertical}
  j:=round(a);
  for i:=math.min(round(b),round(d)) to math.max(round(b),round(d)) do
    local_Setpixel(j,i);
  exit;
  end; {vertical}
  if (b-d)=0 then
  begin {horizontal}
  j:=round(b);
  for i:=math.min(round(a),round(c)) to math.max(round(a),round(c)) do
  local_Setpixel(i,j);
  exit;
  end; {horizontal}
  {delta - différence}
  dx:=(b-d)/(a-c);
  dy:=(a-c)/(b-d);
  if abs(dx)<abs(dy) then
 begin {progression horizontal}
  if a<c then
  begin {quartier 0-45°}
  for i:=round(a) to round(c) do
    begin
    b:=b+dx;
     local_Setpixel(i,round(b));
    end
  end {quartier 0-45°}
  else
  begin {quartier 180°-135°}
  for i:=round(c) to round(a) do
    begin
    d:=d+dx;
     local_Setpixel(i,round(d));
    end
  end; {quartier 180°-135}
 end {progression horizontal}
  else
 begin {progression vertical}
 if b<d then
  begin {quartier 45°-90°}
  for i:=round(b) to round(d) do
   begin
   a:=a+dy;
    local_Setpixel(round(a),i);
   end;
  end {quartier 45°-90°}
 else
  begin {quartier 90°-135°}
  for i:=round(d) to round(b) do
   begin
   c:=c+dy;
    local_Setpixel(round(c),i);
   end;
  end; {quartier 90°-135°}
 end; {progression vertical}
  end; {Tdbbitmap.Denis_line_single_epaisseur}

{L'algorythme de Bresenham le parcours d'une droite divisé en quatre quartiers de progression}
Procedure Tdbbitmap.Denis_line(a,b,c,d:real; color:tcolorref);
var i,j:integer;
   dx,dy:real;
  begin
  if (a-c)=0 then
  begin {vertical}
  j:=round(a);
  for i:=math.min(round(b),round(d)) to math.max(round(b),round(d)) do
    self.Setpixel(j,i,color);
  exit;
  end; {vertical}
  if (b-d)=0 then
  begin {horizontal}
  j:=round(b);
  for i:=math.min(round(a),round(c)) to math.max(round(a),round(c)) do
  self.Setpixel(i,j,color);
  exit;
  end; {horizontal}
  {delta - différence}
  dx:=(b-d)/(a-c);
  dy:=(a-c)/(b-d);
  if abs(dx)<abs(dy) then
 begin {progression horizontal}
  if a<c then
  begin {quartier 0-45°}
  for i:=round(a) to round(c) do
    begin
    b:=b+dx;
     self.Setpixel(i,round(b),color);
    end
  end {quartier 0-45°}
  else
  begin {quartier 180°-135°}
  for i:=round(c) to round(a) do
    begin
    d:=d+dx;
     self.Setpixel(i,round(d),color);
    end
  end; {quartier 180°-135}
 end {progression horizontal}
  else
 begin {progression vertical}
 if b<d then
  begin {quartier 45°-90°}
  for i:=round(b) to round(d) do
   begin
   a:=a+dy;
    self.Setpixel(round(a),i,color);
   end;
  end {quartier 45°-90°}
 else
  begin {quartier 90°-135°}
  for i:=round(d) to round(b) do
   begin
   c:=c+dy;
    self.Setpixel(round(c),i,color);
   end;
  end; {quartier 90°-135°}
 end; {progression vertical}
end; {denis_line}

Procedure Tdbbitmap.Denis_line_in_between(a,b,c,d:real; depart,color:tcolorref; stroke_mitter,stroke_bold:boolean; stroke_width:integer);
  var i,j,k,kk:integer;
   dx,dy:real;
    rb,rd,ra,rc:integer;
    une_color:tcolorref;
    mini,maxi,posit:integer;
    decalage,obtenue:integer;
  begin
  decalage:=-stroke_width div 2; obtenue:=stroke_width div 2;
  if (a-c)=0 then
  begin {vertical}
  j:=round(a);
   mini:=math.min(round(b),round(d));
   maxi:=math.max(round(b),round(d));
   posit:=round(a);
  for i:=mini to maxi do
    begin
    une_color:=IN_Between_longint_RGB(depart,color,i-mini,maxi-mini);
    if (stroke_mitter and (round(i) mod 10<=5)) or not stroke_mitter then
      begin
      self.Setpixel(posit,i,une_color);
      if stroke_bold then
        begin
        self.Setpixel(posit-1,i,une_color);
        self.Setpixel(posit+1,i,une_color);
        self.Setpixel(posit,i-1,une_color);
        self.Setpixel(posit,i+1,une_color);
        for k:=decalage to obtenue do for kk:=decalage to obtenue do self.Setpixel(posit+k,i+kk,une_color);
        end;
      end;
    end;
  exit;
  end; {vertical}
  if (b-d)=0 then
  begin {horizontal}
  j:=round(b);
   mini:=math.min(round(a),round(c));
   maxi:=math.max(round(a),round(c));
   posit:=round(b);
  for i:=mini to maxi do
    begin
    une_color:=IN_Between_longint_RGB(depart,color,i-mini,maxi-mini);
    if (stroke_mitter and (round(i) mod 10<=5)) or not stroke_mitter then
      begin
    self.Setpixel(i,posit,une_color);
      if stroke_bold then
        begin
        self.Setpixel(i-1,posit,une_color);
        self.Setpixel(i+1,posit,une_color);
        self.Setpixel(i,posit-1,une_color);
        self.Setpixel(i,posit+1,une_color);
        end;
      for k:=decalage to obtenue do for kk:=decalage to obtenue do self.Setpixel(i+k,posit+kk,une_color);
      end;
    end;
  exit;
  end; {horizontal}
  {delta - différence}
  dx:=(b-d)/(a-c);
  dy:=(a-c)/(b-d);
  if abs(dx)<abs(dy) then
 begin {progression horizontal}
  if a<c then
  begin {quartier 0-45°}
  for i:=round(a) to round(c) do
    begin
    b:=b+dx;
      rb:=round(b);
      une_color:=IN_Between_longint_RGB(depart,color,i-round(a),round(c)-round(a));
      if (stroke_mitter and (round(i) mod 10<=5)) or not stroke_mitter then
        begin
       self.Setpixel(i,rb,color);
        if stroke_bold then
          begin
          self.Setpixel(i-1,rb,une_color);
          self.Setpixel(i+1,rb,une_color);
          self.Setpixel(i,rb-1,une_color);
          self.Setpixel(i,rb+1,une_color);
          end;
        for k:=decalage to obtenue do for kk:=decalage to obtenue do self.Setpixel(i+k,rb+kk,une_color);
        end;
    end
  end {quartier 0-45°}
  else
  begin {quartier 180°-135°}
  for i:=round(c) to round(a) do
    begin
    d:=d+dx;
      rd:=round(d);
      une_color:=IN_Between_longint_RGB(depart,color,i-round(c),round(a)-round(c));
      if (stroke_mitter and (round(i) mod 10<=5)) or not stroke_mitter then
        begin
       self.Setpixel(i,rd,color);
        if stroke_bold then
          begin
          self.Setpixel(i+1,rd,une_color);
          self.Setpixel(i-1,rd,une_color);
          self.Setpixel(i,rd+1,une_color);
          self.Setpixel(i,rd-1,une_color);
          end;
        for k:=decalage to obtenue do for kk:=decalage to obtenue do self.Setpixel(i+k,rd+kk,une_color);
        end;
    end
  end; {quartier 180°-135}
 end {progression horizontal}
  else
 begin {progression vertical}
 if b<d then
  begin {quartier 45°-90°}
  for i:=round(b) to round(d) do
   begin
   a:=a+dy;
      ra:=round(a);
      une_color:=IN_Between_longint_RGB(depart,color,i-round(b),round(d)-round(b));
      if (stroke_mitter and (round(i) mod 10<=5)) or not stroke_mitter then
        begin
        self.Setpixel(ra,i,une_color);
        if stroke_bold then
          begin
        self.Setpixel(ra,i,une_color);
          self.Setpixel(ra+1,i,une_color);
          self.Setpixel(ra-1,i,une_color);
          self.Setpixel(ra,i+1,une_color);
          self.Setpixel(ra,i-1,une_color);
          end;
        for k:=decalage to obtenue do for kk:=decalage to obtenue do self.Setpixel(ra+k,i+kk,une_color);
        end;
   end;
  end {quartier 45°-90°}
 else
  begin {quartier 90°-135°}
  for i:=round(d) to round(b) do
   begin
   c:=c+dy;
      rc:=round(c);
      une_color:=IN_Between_longint_RGB(depart,color,i-round(d),round(b)-round(d));
      if (stroke_mitter and (round(i) mod 10<=5)) or not stroke_mitter then
        begin
        self.Setpixel(rc,i,une_color);
        if stroke_bold then
          begin
          self.Setpixel(rc+1,i,une_color);
          self.Setpixel(rc-1,i,une_color);
          self.Setpixel(rc,i+1,une_color);
          self.Setpixel(rc,i-1,une_color);
          end;
        for k:=decalage to obtenue do for kk:=decalage to obtenue do self.Setpixel(rc+k,i+kk,une_color);
        end;
   end;
  end; {quartier 90°-135°}
 end; {progression vertical}
  end; {Tdbbitmap.Denis_line_in_between}

{L'algorythme de Bresenham le parcours d'une droite divisé en quatre quartiers de progression}
Procedure Tdbbitmap.Denis_line_alias(a,b,c,d:real; color:tcolorref);
var i,j:integer;
   dx,dy:real;
    rb,rd,ra,rc:integer;
    une_color:tcolorref;
  begin
  if (a-c)=0 then
  begin {vertical}
  j:=round(a);
  for i:=math.min(round(b),round(d)) to math.max(round(b),round(d)) do
    begin
    self.Setpixel(j,i,color);
    une_color:=self.Getpixel(j-1,i);
    self.Setpixel(j-1,i,
      rgb(
        (getrvalue(color)+getrvalue(une_color)) div 2,
        (getgvalue(color)+getgvalue(une_color)) div 2,
        (getbvalue(color)+getbvalue(une_color)) div 2));
    une_color:=self.Getpixel(j+1,i);
    self.Setpixel(j+1,i,
      rgb(
        (getrvalue(color)+getrvalue(une_color)) div 2,
        (getgvalue(color)+getgvalue(une_color)) div 2,
        (getbvalue(color)+getbvalue(une_color)) div 2));
    end;
  exit;
  end; {vertical}
  if (b-d)=0 then
  begin {horizontal}
  j:=round(b);
  for i:=math.min(round(a),round(c)) to math.max(round(a),round(c)) do
    begin
  self.Setpixel(i,j,color);
    une_color:=self.Getpixel(i,j-1);
    self.Setpixel(i,j-1,
      rgb(
        (getrvalue(color)+getrvalue(une_color)) div 2,
        (getgvalue(color)+getgvalue(une_color)) div 2,
        (getbvalue(color)+getbvalue(une_color)) div 2));
    une_color:=self.Getpixel(i,j+1);
    self.Setpixel(i,j+1,
      rgb(
        (getrvalue(color)+getrvalue(une_color)) div 2,
        (getgvalue(color)+getgvalue(une_color)) div 2,
        (getbvalue(color)+getbvalue(une_color)) div 2));
    end;
  exit;
  end; {horizontal}
  {delta - différence}
  dx:=(b-d)/(a-c);
  dy:=(a-c)/(b-d);
  if abs(dx)<abs(dy) then
 begin {progression horizontal}
  if a<c then
  begin {quartier 0-45°}
  for i:=round(a) to round(c) do
    begin
    b:=b+dx;
      rb:=round(b);
     self.Setpixel(i,rb,color);
      une_color:=self.Getpixel(i,rb-1);
      self.Setpixel(i,rb-1,
        rgb(
          (getrvalue(color)+getrvalue(une_color)) div 2,
          (getgvalue(color)+getgvalue(une_color)) div 2,
          (getbvalue(color)+getbvalue(une_color)) div 2));
      une_color:=self.Getpixel(i,rb+1);
      self.Setpixel(i,rb+1,
        rgb(
          (getrvalue(color)+getrvalue(une_color)) div 2,
          (getgvalue(color)+getgvalue(une_color)) div 2,
          (getbvalue(color)+getbvalue(une_color)) div 2));
    end
  end {quartier 0-45°}
  else
  begin {quartier 180°-135°}
  for i:=round(c) to round(a) do
    begin
    d:=d+dx;
      rd:=round(d);
     self.Setpixel(i,rd,color);
      une_color:=self.Getpixel(i,rd-1);
      self.Setpixel(i,rd-1,
        rgb(
          (getrvalue(color)+getrvalue(une_color)) div 2,
          (getgvalue(color)+getgvalue(une_color)) div 2,
          (getbvalue(color)+getbvalue(une_color)) div 2));
      une_color:=self.Getpixel(i,rd+1);
      self.Setpixel(i,rd+1,
        rgb(
          (getrvalue(color)+getrvalue(une_color)) div 2,
          (getgvalue(color)+getgvalue(une_color)) div 2,
          (getbvalue(color)+getbvalue(une_color)) div 2));
    end
  end; {quartier 180°-135}
 end {progression horizontal}
  else
 begin {progression vertical}
 if b<d then
  begin {quartier 45°-90°}
  for i:=round(b) to round(d) do
   begin
   a:=a+dy;
      ra:=round(a);
    self.Setpixel(ra,i,color);
      une_color:=self.Getpixel(ra-1,i);
      self.Setpixel(ra-1,i,
        rgb(
          (getrvalue(color)+getrvalue(une_color)) div 2,
          (getgvalue(color)+getgvalue(une_color)) div 2,
          (getbvalue(color)+getbvalue(une_color)) div 2));
      une_color:=self.Getpixel(ra+1,i);
      self.Setpixel(ra+1,i,
        rgb(
          (getrvalue(color)+getrvalue(une_color)) div 2,
          (getgvalue(color)+getgvalue(une_color)) div 2,
          (getbvalue(color)+getbvalue(une_color)) div 2));
   end;
  end {quartier 45°-90°}
 else
  begin {quartier 90°-135°}
  for i:=round(d) to round(b) do
   begin
   c:=c+dy;
      rc:=round(c);
    self.Setpixel(rc,i,color);
      une_color:=self.Getpixel(rc-1,i);
      self.Setpixel(rc-1,i,
        rgb(
          (getrvalue(color)+getrvalue(une_color)) div 2,
          (getgvalue(color)+getgvalue(une_color)) div 2,
          (getbvalue(color)+getbvalue(une_color)) div 2));
      une_color:=self.Getpixel(rc+1,i);
      self.Setpixel(rc+1,i,
        rgb(
          (getrvalue(color)+getrvalue(une_color)) div 2,
          (getgvalue(color)+getgvalue(une_color)) div 2,
          (getbvalue(color)+getbvalue(une_color)) div 2));
   end;
  end; {quartier 90°-135°}
 end; {progression vertical}
end; {denis_line_alias} {le 11.10.2018}

end.

Compatibilité : 1.0

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.