1. Clip Anomaly:
when a surface .set_clip is called with a rect which have negative width or
height,
seems natural that following fills or blits don't touch at all the surface.
But
width<0 --> surface.get_clip().width == surface.get_width()
height<0 --> surface.get_clip().height == surface.get_height()
so if the left,top of the clip area is not too far you get the surface
partially
blited/filled.
The attached clip_test.py demoes this.
Use case:
resizing the clip area in a loop can get the last loop iteration with a
degenerated clip rect.
The natural control variable for the loop is not the width.
Expectation on set_clip behavior with negative width was that nothing would
write
to the surface, hence garbage in the screen. Because of unexpected, toke
some time
to find the problem.
there is any rationale for the current behavior ?
wouldn't be better my expected behavior ?
If the current behavior will be kept, please mention it in the docs for
set_clip
and get_clip, and maybe blit / fill
2. Rect anomaly when width or height is negative:
Look at this:
>>> clip_rect = pygame.Rect(1,1,-100,-100)
>>> clip_rect.width
-100
>>> clip_rect.left
1
>>> clip_rect.right
-99
>>>
Its reasonable that a Rect can serve a width<0 ?
Its reasonable that rect.left>rect.right ?
To me, this behavior broke the user expectations. Even if the 1.8.1 docs
tells
that "The size values can be programmed to have negative values, but these
are
considered illegal Rects for most operations. "
Much better would be: Accept width or height negative, BUT convert to 0
before
store it internally.
With that, the prev interpreter session would look:
>>> clip_rect = pygame.Rect(1,1,-100,-100)
>>> clip_rect.width
0
>>> clip_rect.left
1
>>> clip_rect.right
1
>>>
As a side effect, opers that uses rects like blit, fill, set_clip... don't
need to
be extended to the degenerate cases.
comments ?
--
claxo
# clip_test.py begin
import pygame
from pygame.constants import *
def main():
pygame.init()
screen = pygame.display.set_mode((800,600))
screen.fill((109,152,6))
dst_surf = pygame.Surface((400,400))
dst_surf.fill((0,0,255))
src_surf = pygame.Surface((200,200))
src_surf.fill((255,0,0))
print 'Initial, undisturbed dst_surf real clip rect:',dst_surf.get_clip()
clip_rect = pygame.Rect(0,0,200,100)
dst_surf.set_clip(clip_rect)
print "After set_clip with a 'good' rect:",dst_surf.get_clip()
clip_rect = pygame.Rect(0,0,-100,-100) # not ok , negative width or height ignored
print 'setting dst_surf clip rect to:',clip_rect
dst_surf.set_clip(clip_rect)
print 'results in dst_surf real clip rect:',dst_surf.get_clip()
dst_surf.blit(src_surf, (0,0))
screen.blit(dst_surf,(0,0))
pygame.display.flip()
bRun = True
while bRun:
pygame.event.pump()
for ev in pygame.event.get():
if (ev.type == pygame.KEYDOWN
and ev.key == pygame.K_ESCAPE):
bRun = False
pygame.quit()
if __name__ == '__main__':
main()
# clip_test.py ends