Recent

Author Topic: Clipping Regions  (Read 4213 times)

taazz

  • Hero Member
  • *****
  • Posts: 5363
Clipping Regions
« on: July 15, 2013, 11:36:35 am »
I need a fresh pair of eyes on this. I have a problem with clipping regions that manifests it self only on QT. The problem is that after I select a clipping region stretch draw a bitmap in there and then deleted all other objects that are near a rectangular area around that region do not show on screen. If I do not use a clipping region everything works.

I'm getting light headed so I'm going to stop here for today, any idea is most welcome, does not matter if it helps or not.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Blaazen

  • Hero Member
  • *****
  • Posts: 2782
  • POKE 54296,15
    • Eye-Candy Controls
Re: Clipping Regions
« Reply #1 on: July 15, 2013, 01:27:06 pm »
I have only experience with InvalidateRect which works well on Qt.
Lazarus 2.1.0 r59757M FPC 3.3.1 r40507 x86_64-linux-qt Chakra, Qt 4.8.7/5.11.2, Plasma 5.14.2
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

taazz

  • Hero Member
  • *****
  • Posts: 5363
Re: Clipping Regions
« Reply #2 on: July 15, 2013, 08:49:37 pm »
I really needed a break it seems, I didn't post any code. :/ Here it goes.

Code: [Select]
procedure TEvsGraphNode.DrawBackground(aCanvas: TCanvas);
var
  ClipRgn: HRGN;
  Bitmap: Graphics.TBitmap;
  Graphic: TGraphic;
  ImageRect: TRect;
  vPts : array[0..1] of TPoint absolute ImageRect;
begin
  if Background.Graphic <> nil then
  begin
    ImageRect.Left := Left + MulDiv(Width, BackgroundMargins.Left, 100);
    ImageRect.Top := Top + MulDiv(Height, BackgroundMargins.Top, 100);
    ImageRect.Right := Left + Width - MulDiv(Width, BackgroundMargins.Right, 100);
    ImageRect.Bottom := Top + Height - MulDiv(Height, BackgroundMargins.Bottom, 100);
    //OffsetRectByOwner(ImageRect,True);
  //  Owner.GPToCP(ImageRect, 2); {$MESSAGE WARN 'GPTOCP CHANGE'}
    Owner.GPtoCL(vPts);

    ClipRgn := CreateClipRgn(aCanvas);
    try
      SelectClipRgn(aCanvas.Handle, ClipRgn);
      try
        Graphic := Background.Graphic;
        Background.OnChange := nil;
        try
          {$IFDEF METAFILE_SUPPORT} //JKOZ:Metafile
          if (Graphic is TMetafile) and (aCanvas is TMetafileCanvas) and
            ((ImageRect.Left >= Screen.Width) or (ImageRect.Top >= Screen.Height)) then
          begin // Workaround Windows bug!
            Bitmap := TBitmap.Create;
            try
              Bitmap.Transparent := True;
              Bitmap.TransparentColor := aCanvas.Brush.Color;
              Bitmap.aCanvas.Brush.Color := aCanvas.Brush.Color;
              Bitmap.Width := ImageRect.Right - ImageRect.Left;
              Bitmap.Height := ImageRect.Bottom - ImageRect.Top;
              Bitmap.PixelFormat := pf32bit;
              Bitmap.aCanvas.StretchDraw(Rect(0, 0, Bitmap.Width,
                Bitmap.Height), Graphic);
              aCanvas.Draw(ImageRect.Left, ImageRect.Top, Bitmap);
            finally
              Bitmap.Free;
            end;
          end
          else
          {$ENDIF}
            aCanvas.StretchDraw(ImageRect, Graphic);
        finally
          Background.OnChange := @BackgroundChanged;
        end;
      finally
              //aCanvas.Clipping := False;
       // SelectClipRgn(aCanvas.Handle, CreateEmptyRgn);
       SelectClipRgn(aCanvas.Handle, 0);
      end;
    finally
      DeleteObject(ClipRgn);
    end;
    aCanvas.Brush.Style := bsClear;
    DrawBorder(aCanvas);
  end;
end; 

I have only experience with InvalidateRect which works well on Qt.

If I'm not mistaken invalidaterect is instructing the widgetset that a specific rectangular area on the screen needs refreshing. That keeps the redraw to a minimum if the underline widgets respect the rect coordinates. In any case it is used internally from SimpleGraph as well and yes it works as expected on QT. I wouldn't have any problem with the region code as well sincethere are 2 main uses of it. One when the mouse passes over the controls to decide if the mouse is in a controls client area on the border or header /text etc and this is working well with QT as well the other is when you select an image for background then you need to confine the image inside the controls client area then the region becomes a clipping region and this point is working as long as the clipping region is on top of the screen if you put it at the bottom all hell breaks loose. Since my development does not require and image support I was close to removing it from the component but since it works well on GTK2 and Win32 I left it on and I'll be searching for a ay to solve this on QT as well. Hopefully some one knowledgeable with QT might come along and give me an aha moment or teach me something new.

In any way this is going to be left in at the moment just don't use image inside the controls ad everything will work fine.

Thank you.
« Last Edit: July 16, 2013, 12:27:31 am by taazz »
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64