Recent

Author Topic: Custom shape of forms with X11  (Read 3970 times)

Fred vS

  • Hero Member
  • *****
  • Posts: 3716
    • StrumPract is the musicians best friend
Custom shape of forms with X11
« on: June 15, 2022, 04:02:49 am »
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][+][-]
  1.  XDrawarc(appdisp, pmap, shape_gc, 0, 0, width-1 , height-1,  0, 360*64);
  2.  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][+][-]
  1.  XDrawRectangle(appdisp, pmap, shape_gc, width div 2, 0,  width , height div 3);
  2.  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
« Last Edit: June 15, 2022, 04:20:46 am by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Aruna

  • Hero Member
  • *****
  • Posts: 748
Re: Custom shape of forms with X11
« Reply #1 on: August 25, 2025, 04:59:12 am »
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][+][-]
  1.  XDrawarc(appdisp, pmap, shape_gc, 0, 0, width-1 , height-1,  0, 360*64);
  2.  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][+][-]
  1.  XDrawRectangle(appdisp, pmap, shape_gc, width div 2, 0,  width , height div 3);
  2.  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.
« Last Edit: August 25, 2025, 05:05:15 am by Aruna »

d2010

  • Full Member
  • ***
  • Posts: 230
Re: Custom shape of forms with X11
« Reply #2 on: August 25, 2025, 07:42:12 am »
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.

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][+][-]
  1. Var   m_facetsIndices:integer=random(15);
  2. Type TMainForm=class(Tform)
  3. .....................
  4.     procedure BitBtn2Click(Sender: TObject);
  5.     Function  FastOpen_exe(const filename:string):integer;
  6. .............................
  7.     procedure Qquit1Click(Sender: TObject);
  8.   protected
  9.     procedure DrawRndRectRegion(wnd : HWND; rect : TRect);
  10.     procedure OdDbEllipse(wnd : HWND; rect : TRect);
  11.     procedure OdDbSpline(wnd : HWND; rect : TRect;fat16,fat32:boolean;ntfs:integer);
  12.     Function  getClipSpaceToWCSMatrix(bx,by,dx,dy:integer;rtExtended,m_FrameStyledbl:boolean;ShapeType: integer): HRGN;
  13.     Function  dfn_openttd1_6_0RC1_windowswin32(filef:integer;MyHan:THandle):string;
  14.  
  15. End;
  16. Implementation
  17.  
  18. procedure TFormMain.BitBtn2Click(Sender: TObject);
  19. begin
  20.   BitBtn2.caption:='Hdi ArsenieBoca Multumesc Tie'+kTwoDigitLookup[m_facetsIndices and 127];
  21.   Case m_facetsIndices of
  22.   0: OdDbEllipse(Handle, FormMain.ClientRect);
  23.   1: OdDbSpline(Handle,FormMain.ClientRect,fals,fals,0);
  24.   2: OdDbSpline(Handle,FormMain.ClientRect,true,fals,0);
  25.   3: OdDbSpline(Handle,FormMain.ClientRect,fals,true,0);
  26.   4: OdDbSpline(Handle,FormMain.ClientRect,true,true,0);
  27.   5: OdDbSpline(Handle,FormMain.ClientRect,true,true,1);
  28.   6: OdDbSpline(Handle,FormMain.ClientRect,fals,true,1);
  29.   7: OdDbSpline(Handle,FormMain.ClientRect,true,fals,1);
  30.   8: OdDbSpline(Handle,FormMain.ClientRect,true,true,1);
  31.   9: OdDbSpline(Handle,FormMain.ClientRect,true,true,2);
  32.  10: OdDbSpline(Handle,FormMain.ClientRect,fals,true,2);
  33.  11: OdDbSpline(Handle,FormMain.ClientRect,true,fals,2);
  34.  12: OdDbSpline(Handle,FormMain.ClientRect,fals,fals,2);
  35.  13: OdDbSpline(Handle,FormMain.ClientRect,fals,fals,3);
  36.  14: OdDbSpline(Handle,FormMain.ClientRect,true,fals,3);
  37.  15: OdDbSpline(Handle,FormMain.ClientRect,true,true,3);
  38.   End;
  39.   inc(m_facetsIndices);
  40.   m_facetsIndices:=m_facetsIndices and 15;
  41. end;
  42. {--}
  43. procedure TFormMain.OdDbSpline(wnd : HWND; rect : TRect;fat16,fat32:boolean;ntfs:integer);
  44. Begin
  45.   rgn := getClipSpaceToWCSMatrix(rect.left, rect.top, rect.right, rect.bottom,fat16,fat32,ntfs);
  46.   SetWindowRgn(wnd, rgn, TRUE);
  47. End;
  48. {--}
  49. procedure TFormMain.OdDbEllipse(wnd : HWND; rect : TRect);
  50. begin
  51.   rgn := CreateEllipticRgn(rect.left, rect.top, rect.right, rect.bottom);
  52.   SetWindowRgn(wnd, rgn, TRUE);
  53. end;
  54.  


Code: Pascal  [Select][+][-]
  1. Function TFormMain.getClipSpaceToWCSMatrix(bx,by,dx,dy:integer;rtExtended,m_FrameStyledbl:boolean;ShapeType: integer): HRGN;
  2. Const
  3.   Delta = 10;
  4. var
  5.   xp : Integer;
  6.   Pts         : Array[0..6] of TPoint;
  7.   min, bx1, by1, w1, w2, fw: Integer;
  8. begin
  9.   w1 := Round(Width shr 1);
  10.   w2 := Round((Width - 1) shr 1);
  11.   fw := Round(Width);
  12.   bx1:=bx+dx+1;
  13.   by1:=by+dy+1;
  14.  
  15.   case ShapeType of
  16. //    frstRoundRect:
  17.     00:
  18.       begin
  19.         Inc(bx1, w2);
  20.         Inc(by1, w2);
  21.         Dec(bx, w1);
  22.         Dec(by, w1);
  23.  
  24.         if m_FrameStyledbl then
  25.         begin
  26.           Dec(bx, fw);
  27.           Dec(by, fw);
  28.           Inc(bx1, fw);
  29.           Inc(by1, fw);
  30.         end;
  31.  
  32.         min := dx;
  33.         if dy < dx then
  34.           min := dy;
  35.  
  36.         if rtExtended then begin
  37.           min := min + 2 * delta;
  38.           result := CreateRoundRectRgn(bx-delta, by-delta, bx1+delta, by1+delta, min div 4, min div 4)
  39.         end
  40.         else
  41.           result := CreateRoundRectRgn(bx, by, bx1, by1, min div 4, min div 4);
  42.       end;
  43.     1,2:
  44. //    frstEllipse, frstRectangle:
  45.       begin
  46.         Inc(bx1, w2);
  47.         Inc(by1, w2);
  48.         Dec(bx, w1);
  49.         Dec(by, w1);
  50.  
  51.  
  52.         if m_FrameStyleDbl then
  53.         begin
  54.           Dec(bx, fw);
  55.           Dec(by, fw);
  56.           Inc(bx1, fw);
  57.           Inc(by1, fw);
  58.         end;
  59.  
  60.         if rtExtended then begin
  61.           if odd(ShapeType) then
  62.             result := CreateRectRgn(bx-Delta, by-Delta, bx1 + Delta, by1 + Delta)
  63.           else
  64.             result := CreateEllipticRgn(bx-Delta, by-Delta, bx1 + Delta, by1 + Delta)
  65.         end else begin
  66.           if odd(ShapeType) then
  67.             result := CreateRectRgn(bx, by, bx1, by1)
  68.           else
  69.             result := CreateEllipticRgn(bx, by, bx1, by1);
  70.         end;
  71.       end;
  72.  
  73.     3:
  74.       begin
  75.         Inc(bx1, w2);
  76.         Inc(by1, w2);
  77.         Dec(bx, w1);
  78.         Dec(by, w1);
  79.  
  80.         if m_FrameStyleDbl then
  81.         begin
  82.           Dec(bx, fw * 2);
  83.           Dec(by, fw * 2);
  84.           Inc(bx1, fw * 2);
  85.           Inc(by1, fw * 2);
  86.         end;
  87.  
  88.         xp := bx + (bx1 - bx) div 2;
  89.         if rtExtended then
  90.         begin
  91.           Pts[0]:=Point(bx1+Delta, by1+Delta);
  92.           Pts[1]:=Point(bx-Delta, by1+Delta);
  93.           Pts[2]:=Point(xp, by-Delta);
  94.           Pts[3]:=Point(bx1+Delta, by1+Delta);
  95.         end else begin
  96.           Pts[0]:=Point(bx1, by1);
  97.           Pts[1]:=Point(bx, by1);
  98.           Pts[2]:=Point(xp, by);
  99.           Pts[3]:=Point(bx1, by1);
  100.         end;
  101.         result := CreatePolygonRgn(Pts, 4, 1);
  102.       end;
  103.  
  104. //    frstDiagonal1: //Line(x,y,x1,y1);
  105. 4:
  106.       begin
  107.         if m_FrameStyleDbl then
  108.         begin
  109.           Dec(by, fw);
  110.           Inc(by1, fw);
  111.         end;
  112.         if w1=0 then
  113.           w1 := 1; // avoid disappearing  line
  114.         if rtExtended then
  115.         begin
  116.           Pts[0]:=Point(bx-w1-Delta, by);
  117.           Pts[1]:=Point(bx+w2+Delta, by);
  118.           Pts[2]:=Point(bx1+w2+Delta, by1);
  119.           Pts[3]:=Point(bx1-w1-Delta, by1);
  120.           Pts[4]:=Point(bx-w1-Delta, by);
  121.         end else begin
  122.           Pts[0]:=Point(bx-w1, by);
  123.           Pts[1]:=Point(bx+w2, by);
  124.           Pts[2]:=Point(bx1+w2, by1);
  125.           Pts[3]:=Point(bx1-w1, by1);
  126.           Pts[4]:=Point(bx-w1, by);
  127.         end;
  128.         result := CreatePolygonRgn(Pts, 5, 1);
  129.       end;
  130. 5:      
  131. //    frstDiagonal2: //Line(x,y1,x1,y);
  132.       begin
  133.         if m_FrameStyleDbl  then
  134.         begin
  135.           Dec(by, fw);
  136.           Inc(by1, fw);
  137.         end;
  138.         if w1=0 then
  139.           w1 := 1; // avoid disappearing  line
  140.         if rtExtended then begin
  141.           Pts[0]:=Point(bx-w1-Delta, by1);
  142.           Pts[1]:=Point(bx+w2+Delta, by1);
  143.           Pts[2]:=Point(bx1+w2+Delta, by);
  144.           Pts[3]:=Point(bx1-w1-Delta, by);
  145.           Pts[4]:=Point(bx-w1-Delta,by);
  146.         end else begin
  147.           Pts[0]:=Point(bx-w1, by1);
  148.           Pts[1]:=Point(bx+w2, by1);
  149.           Pts[2]:=Point(bx1+w2, by);
  150.           Pts[3]:=Point(bx1-w1, by);
  151.           Pts[4]:=Point(bx-w1,by1);
  152.         end;
  153.         result := CreatePolygonRgn(Pts, 5, 1);
  154.       end
  155.   end;
  156. end;
  157.  
« Last Edit: August 25, 2025, 10:46:24 am by d2010 »

 

TinyPortal © 2005-2018