ClipPath() performs low-quality clipping (without anti-aliasing).

Just starting out? Need help? Post your questions and find answers here.
Webarion
User
User
Posts: 43
Joined: Tue Sep 14, 2021 8:50 pm

ClipPath() performs low-quality clipping (without anti-aliasing).

Post by Webarion »

Hi, I'm trying to create a shadow for a complex vector RoundBox shape with different corner radii.
There's no issue when the background color of the RoundBox has no transparency.
But I also need to draw semi-transparent shapes, while clipping the shadow shape in the region of the main shape using ClipPath(), which performs this without anti-aliasing. Therefore, it looks ugly.

I'm looking for ways and options to achieve higher quality clipping. Maybe someone has already solved this problem and can help me? Here's an example:

Code: Select all

Procedure AddPathRoundBox(x.f, y.f, w.f, h.f, r_lt.f, r_rt.f, r_rb.f, r_lb.f)
  MovePathCursor(x + r_lt, y)
  ; Top line and top-right corner
  AddPathLine(x + w - r_rt, y)
  AddPathArc(x + w, y, x + w, y + r_rt, r_rt)
  ; Right line and bottom-right corner
  AddPathLine(x + w, y + h - r_rb)
  AddPathArc(x + w, y + h, x + w - r_rb, y + h, r_rb)
  ; Bottom line and bottom-left corner
  AddPathLine(x + r_lb, y + h)
  AddPathArc(x, y + h, x, y + h - r_lb, r_lb)
  ; Left line and top-left corner
  AddPathLine(x, y + r_lt)
  AddPathArc(x, y, x + r_lt, y, r_lt)
  
  ClosePath()
EndProcedure



Procedure RoundBoxShadow(x.f, y.f, w.f, h.f, r_lt.f, r_rt.f, r_rb.f, r_lb.f, offsetX.f, offsetY.f, colorMain.l, colorShadow.l = $A0000000 )
  
  Protected Alpha.a = Alpha(colorMain)
  
  If Alpha < 255
    
    SaveVectorState()
    
    ; mask for proper clipping, it captures the maximum area of the main shape together with the shadow
    AddPathBox( x+(offsetX-Abs(offsetX))/2, y+(offsetY-Abs(offsetY))/2, w+Abs(offsetX), h+Abs(offsetY) )
    
    ; subtract the main shape
    AddPathRoundBox( x, y, w, h, r_lt, r_rt, r_rb, r_lb )
    
    ; Apply clipping
    ClipPath()
    
  EndIf
  
  ; shadow shape (with clipping from the main shape)
  AddPathRoundBox( x + offsetX, y + offsetY, w, h, r_lt, r_rt, r_rb, r_lb )
  VectorSourceColor( colorShadow )
  FillPath()
  
  If Alpha < 255
    RestoreVectorState()
  EndIf
  
  ; draw the main shape
  AddPathRoundBox( x, y, w, h, r_lt, r_rt, r_rb, r_lb ) 
  VectorSourceColor( colorMain )
  FillPath()
  
  
EndProcedure



If OpenWindow(0, 0, 0, 500, 300, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 0, 0, 500, 300)
  
  If StartVectorDrawing(CanvasVectorOutput(0))
    
    AddPathBox( 100, 10, 230, 230 )
    VectorSourceColor( $40FF0000 )
    FillPath()
    
    
    RoundBoxShadow( 40, 40, 150, 150,    20, 60, 40, 8,    30, 10, $90E16941, $890000FF )

    RoundBoxShadow( 250, 40, 150, 150,   20, 60, 40, 8,    30, 10, $FFE16941, $890000FF )
    
    
    StopVectorDrawing()
  EndIf
  
  Repeat
    Event = WaitWindowEvent()
  Until Event = #PB_Event_CloseWindow
EndIf