-
-
Notifications
You must be signed in to change notification settings - Fork 213
Fix rect drawing issues around surface edges #1972
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
MyreMylar
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work on fixing the reported issue on the left hand side of the clip surface, and generally improving the drawn rect's surface edge clipping.
Unfortunately there still remain some issues with clipping wide lines I can still see disappearing line chunks on the right hand side/bottom of surfaces.
I adapted this test program to demonstrate:
import pygame
WIDTH, HEIGHT = 800, 600
FPS = 60
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
test_surf = pygame.Surface((100, 100))
test_surf.fill((255, 255, 255))
rect = pygame.Rect(0, 0, 100, 100)
test_surf_pos = (150, 150)
running = True
while running:
clock.tick(FPS)
screen.fill("black")
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
running = False
test_surf.fill("white")
rect.center = pygame.mouse.get_pos()[0] - test_surf_pos[0], pygame.mouse.get_pos()[1] - test_surf_pos[0]
pygame.draw.rect(test_surf, "red", rect, 30, 0, 0, 20, 0, 20)
screen.blit(test_surf, test_surf_pos)
pygame.display.flip()
Just try moving the D shaped rect with the mouse towards the bottom right of the white square surface.
see:
and:
I'm also a little unsure what is happening with the multiple calls to clip line. I understood the purpose of clip line to be 'clipping a line to be drawn to the surface passed in', I can see why the function needs the line width parameter to determine when to clip or not with wide lines, but not why it has to be called three times.
Perhaps we need some diagrams here to help clarify things?
src_c/draw.c
Outdated
| clip = clip_line(surf, &x1, &y1, &x2, &y2, width, xinc) || | ||
| clip_line(surf, &x1 + width, &y1, &x2, &y2, -width, xinc) || | ||
| clip_line(surf, &x1, &y1, &x2, &y2, 0, 0); | ||
| if (clip) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand why we have three calls to clip line here. The purpose of clip line appears to be to clip a line to a surface, if it is not doing it right I think that should probably be fixed inside clip_line not by calling it three times with different parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's mostly a workaround for the clip_line function to check if the edges of the line intersect with the surface as well to determine whether it is within bounds (which in itself could have some issues if all three lines were not within the surface), I'll see about rewriting the clip_line entirely to remove the excess number of calls.
|
Alright I have made those changes, this method checks if the bounding box of the line intersects with the surface to decide if it draws it. It will also trim the excess off in cases where the line is vertical or horizontal but does not do so otherwise. I could look into implementing a more rigorous check to see where the line intersects along the surface and calculate where to cut it off based on the width for non orthogonal cases but I worry that would introduce too much overhead into the check where it won't be needed since the line won't be drawn outside the surface anyway. |
|
Closing since #1998 supersedes this PR. |


This resolves #1968 and a similar issue encountered where the drawn rect would be stretched to the edge of the screen when in close proximity.