Custom shape of forms with X11 lazarus / 30-Other ---------------------------------------------------------------------- Fred vS · 2022-06-15 02:02 Hello. I try to find a nice way to do custom shapes of forms for X11/XWayland. X11 gives XDrawRectangle, XFillRectangle and  XDrawArc, XFillArc for this. Example, a from with shape ellipse: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  XDrawarc(appdisp, pmap, shape_gc, 0, 0, width-1 , height-1,  0, 360*64); XFillarc(appdisp, pmap, shape_gc, 0, 0, width-1 , height-1,  0, 360*64); Now for complex shapes, other developers advice to use many XDrawRectangle+XFillRectangle of different sizes. And all those rectangles will do the wanted custom form. Example of a rectangle: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  XDrawRectangle(appdisp, pmap, shape_gc, width div 2, 0,  width , height div 3); XFillRectangle(appdisp, pmap, shape_gc, width div 2, 0,  width , height div 3); OK, but using a bitmap monochrome b/w where all the black shapes should be replaced by those rectangles, what would be the steps? Maybe using BGRABitmap to scan the monochrome bitmap and then create the rectangles? Any idea is welcome. Thanks. Fre;D ---------------------------------------------------------------------- Aruna · 2025-08-25 02:59 Quote from: Fred vS on June 15, 2022, 04:02:49 amHello. I try to find a nice way to do custom shapes of forms for X11/XWayland. X11 gives XDrawRectangle, XFillRectangle and  XDrawArc, XFillArc for this. Example, a from with shape ellipse: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  XDrawarc(appdisp, pmap, shape_gc, 0, 0, width-1 , height-1,  0, 360*64); XFillarc(appdisp, pmap, shape_gc, 0, 0, width-1 , height-1,  0, 360*64); Now for complex shapes, other developers advice to use many XDrawRectangle+XFillRectangle of different sizes. And all those rectangles will do the wanted custom form. Example of a rectangle: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  XDrawRectangle(appdisp, pmap, shape_gc, width div 2, 0,  width , height div 3); XFillRectangle(appdisp, pmap, shape_gc, width div 2, 0,  width , height div 3); OK, but using a bitmap monochrome b/w where all the black shapes should be replaced by those rectangles, what would be the steps? Maybe using BGRABitmap to scan the monochrome bitmap and then create the rectangles? Any idea is welcome. Thanks. Fre;D Hello Fred vS I came across  your post while searching for information on how to go about creating custom forms. I have had some limited success so decided to send the zips your way. Yes I know it is 3 years ago but I guess better late than never eh? Screenshot is attached. This is pure Lazarus+FPC. ---------------------------------------------------------------------- d2010 · 2025-08-25 05:42 Quote from: Fred vS on June 15, 2022, 04:02:49 amHello. I try to find a nice way to do custom shapes of forms for X11/XWayland. X11 gives XDrawRectangle, XFillRectangle and  XDrawArc, XFillArc for this. You can previous the shapes . You draw incremental the shapes, with the one-button. :'( Please , you wait 2-3 days, I need fix same bugs, because today I must have a trip ..with train to other City. You can play short.avi to roll-on-shape-of-MainForm.lpr Please you wait, I upload the full-source.lpr for other Hintal= The Image with "Tarom" is not bmp or jpeg, is bin_tarom2.avi Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Var   m_facetsIndices:integer=random(15);Type TMainForm=class(Tform).....................    procedure BitBtn2Click(Sender: TObject);    Function  FastOpen_exe(const filename:string):integer;.............................    procedure Qquit1Click(Sender: TObject);  protected    procedure DrawRndRectRegion(wnd : HWND; rect : TRect);    procedure OdDbEllipse(wnd : HWND; rect : TRect);    procedure OdDbSpline(wnd : HWND; rect : TRect;fat16,fat32:boolean;ntfs:integer);    Function  get ClipSpaceToWCSMatrix(bx,by,dx,dy:integer;rtExtended,m_FrameStyledbl:bo olean;ShapeType: integer): HRGN;    Function  dfn_openttd1_6_0RC1_wind owswin32(filef:integer;MyHan:THandle):string; End;Implementation proce dure TFormMain.BitBtn2Click(Sender: TObject);begin  BitBtn2.caption:='Hdi ArsenieBoca Multumesc Tie'+kTwoDigitLookup[m_facetsIndices and 127];  Case m_facetsIndices of  0: OdDbEllipse(Handle, FormMain.ClientRect);  1: OdDbSpline(Handle,FormMain.ClientRect,fals,fals,0);  2: OdDbSpline(Handle,FormMain.ClientRect,true,fals,0);  3: OdDbSpline(Handle,FormMain.ClientRect,fals,true,0);  4: OdDbSpline(Handle,FormMain.ClientRect,true,true,0);  5: OdDbSpline(Handle,FormMain.ClientRect,true,true,1);  6: OdDbSpline(Handle,FormMain.ClientRect,fals,true,1);  7: OdDbSpline(Handle,FormMain.ClientRect,true,fals,1);  8: OdDbSpline(Handle,FormMain.ClientRect,true,true,1);  9: OdDbSpline(Handle,FormMain.ClientRect,true,true,2); 10: OdDbSpline(Handle,FormMain.ClientRect,fals,true,2); 11: OdDbSpline(Handle,FormMain.ClientRect,true,fals,2); 12: OdDbSpline(Handle,FormMain.ClientRect,fals,fals,2); 13: OdDbSpline(Handle,FormMain.ClientRect,fals,fals,3); 14: OdDbSpline(Handle,FormMain.ClientRect,true,fals,3); 15: OdDbSpline(Handle,FormMain.ClientRect,true,true,3);  End;  inc(m_facetsIndices);  m_facetsIndices:=m_facetsIndices and 15;end;{--}procedure TFormMain.OdDbSpline(wnd : HWND; rect : TRect;fat16,fat32:boolean;ntfs:integer);Begin  rgn := getClipSpaceToWCSMatrix(rect.left, rect.top, rect.right, rect.bottom,fat16,fat32,ntfs);  SetWindowRgn(wnd, rgn, TRUE);End;{--}procedure TFormMain.OdDbEllipse(wnd : HWND; rect : TRect);begin  rgn := CreateEllipticRgn(rect.left, rect.top, rect.right, rect.bottom);  SetWindowRgn(wnd, rgn, TRUE);end;  Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Function TF ormMain.getClipSpaceToWCSMatrix(bx,by,dx,dy:integer;rtExtended,m_Frame Styledbl:boolean;ShapeType: integer): HRGN;Const  Delta = 10;var  xp : Integer;  Pts         : Array[0..6] of TPoint;  min, bx1, by1, w1, w2, fw: Integer;begin  w1 := Round(Width shr 1);  w2 := Round((Width - 1) shr 1);  fw := Round(Width);  bx1:=bx+dx+1;  by1:=by+dy+1;   case ShapeType of//    frstRoundRect:    00:      begin        Inc(bx1, w2);        Inc(by1, w2);        Dec(bx, w1);        Dec(by, w1);       if m_FrameStyledbl then        begin          Dec(bx, fw);        Dec(by, fw);          Inc(bx1, fw);          Inc(by1, fw);        end;         min := dx;        if dy < dx then          min := dy;       if rtExtended then begin          min := min + 2 * delta;        result := CreateRoundRectRgn(bx-delta, by-delta, bx1+delta, by1+delta, min div 4, min div 4)        end        else          result := CreateRoundRectRgn(bx, by, bx1, by1, min div 4, min div 4);      end;    1,2://    frstEllipse, frstRectangle:      begin        Inc(bx1, w2);        Inc(by1, w2);        Dec(bx, w1);        Dec(by, w1);        if m_FrameStyleDbl then        begin          Dec(bx, fw);        Dec(by, fw);          Inc(bx1, fw);          Inc(by1, fw);        end;         if rtExtended then begin          if odd(ShapeType) then            result := CreateRectRgn(bx-Delta, by-Delta, bx1 + Delta, by1 + Delta)          else            result := CreateEllipticRgn(bx- Delta, by-Delta, bx1 + Delta, by1 + Delta)        end else begin        if odd(ShapeType) then            result := CreateRectRgn(bx, by, bx1, by1)          else            result := CreateEllipticRgn(bx, by, bx1, by1);        end;      end;     3:      begin        Inc(bx1, w2);        Inc(by1, w2);        Dec(bx, w1);        Dec(by, w1);       if m_FrameStyleDbl then        begin          Dec(bx, fw * 2);        Dec(by, fw * 2);          Inc(bx1, fw * 2);          Inc(by1, fw * 2);        end;         xp := bx + (bx1 - bx) div 2;        if rtExtended then        begin          Pts[0]:=Point(bx1+Delta, by1+Delta);          Pts[1]:=Point(bx-Delta, by1+Delta);          Pts[2]:=Point(xp, by-Delta);          Pts[3]:=Point(bx1+Delta, by1+Delta);        end else begin          Pts[0]:=Point(bx1, by1);        Pts[1]:=Point(bx, by1);          Pts[2]:=Point(xp, by);        Pts[3]:=Point(bx1, by1);        end;        result := CreatePolygonRgn(Pts, 4, 1);      end; //    frstDiagonal1: //Line(x,y,x1,y1);4:      begin        if m_FrameStyleDbl then        begin          Dec(by, fw);          Inc(by1, fw);        end;        if w1=0 then          w1 := 1; // avoid disappearing  line        if rtExtended then        begin          Pts[0]:=Point(bx-w1-Delta, by);          Pts[1]:=Point(bx+w2+Delta, by);          Pts[2]:=Point(bx1+w2+Delta, by1);          Pts[3]:=Point(bx1-w1-Delta, by1);          Pts[4]:=Point(bx-w1-Delta, by);        end else begin        Pts[0]:=Point(bx-w1, by);          Pts[1]:=Point(bx+w2, by);        Pts[2]:=Point(bx1+w2, by1);          Pts[3]:=Point(bx1-w1, by1);          Pts[4]:=Point(bx-w1, by);        end;        result := CreatePolygonRgn(Pts, 5, 1);      end;5:      //    frstDiagonal2: //Line(x,y1,x1,y);      begin        if m_FrameStyleDbl  then        begin          Dec(by, fw);          Inc(by1, fw);        end;        if w1=0 then          w1 := 1; // avoid disappearing  line        if rtExtended then begin          Pts[0]:=Point(bx-w1-Delta, by1);        Pts[1]:=Point(bx+w2+Delta, by1);          Pts[2]:=Point(bx1+w2+Delta, by);          Pts[3]:=Point(bx1-w1-Delta, by);          Pts[4]:=Point(bx-w1-Delta,by);        end else begin        Pts[0]:=Point(bx-w1, by1);          Pts[1]:=Point(bx+w2, by1);        Pts[2]:=Point(bx1+w2, by);          Pts[3]:=Point(bx1-w1, by);        Pts[4]:=Point(bx-w1,by1);        end;        result := CreatePolygonRgn(Pts, 5, 1);      end  end;end; ---------------------------------------------------------------------- Fred vS · 2026-02-19 11:00 Hello. Finally I found  a way to create form with custom shape for X11 (Unix) and gdi (Windows) using a b/w png image.. For X11: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i if (wo_customshape in options.options) and (mse_shapefile <> '') then  begin    shapebmp := tmaskedbitmap.Create(bmk_mono);  // Monochrome mode    try      shapebmp.LoadFromFile(mse_shapefile);  // Load b/w PNG image      shapebmp.MaskKind := bmk_mono;  // Ensure 1-bit mask    // Copy mask to pmap (1=visible/opaque, 0=transparent/clipped)      // Assumes mask bits are set correctly (black=1/visible, white=0/transparent)    finally      shapebmp.Free;    end; and for gdi: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i if (wo_customshape in options) and (mse_shapefile <> '') thenbegin  shapebmp := tmaskedbitmap.Create(bmk_mono);  try    shapebmp.LoadFromFile(mse_shapefile);    shapebmp.maskkind := bmk_mono;    shapebmp.mask.size := shapebmp.size;      region := CreateRectRgn(0, 0, 0, 0);        for y := 0 to shapebmp.size.cy - 1 do    begin      x := 0;      while x < shapebmp.size.cx do      begin        if (shapebmp.pixels[x, y] and $FFFFFF) > $7F7F7F then       begin          Inc(x);          Continue;        end;        startx := x;        // Collect everything that is "dark"        while (x < shapebmp.size.cx) and ((shapebmp.pixels[x, y] and $FFFFFF) <= $7F7F7F) do          Inc(x);         region2 := CreateRectRgn(startx, y, x, y + 1);        CombineRgn(region, region, region2, RGN_OR);      DeleteObject(region2);      end;    end;     // Apply the custom region to the window handle    SetWindowRgn(id, region, True);      finally    shapebmp.Free;  end; And now you can do custom shapes with MSEgui. ---------------------------------------------------------------------- LV · 2026-02-19 14:15 Hello! I had fun with movable custom shapes at Christmas. ☺️ https://forum.lazarus.freepascal.org/index.php/topic,73079.msg573067.h tml#msg573067