Skip to content

Conversation

@Temmie3754
Copy link
Member

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.

@Temmie3754 Temmie3754 requested a review from a team as a code owner March 3, 2023 17:29
Copy link
Member

@MyreMylar MyreMylar left a 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:

image

and:

image

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
Comment on lines 1503 to 1506
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) {
Copy link
Member

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.

Copy link
Member Author

@Temmie3754 Temmie3754 Mar 4, 2023

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.

@Temmie3754
Copy link
Member Author

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.

@Temmie3754
Copy link
Member Author

Closing since #1998 supersedes this PR.

@Temmie3754 Temmie3754 closed this Mar 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Only 4 pixels show when drawing a rect on the edge of the screen

2 participants