Author: Tim Felgentreff <[email protected]>
Branch: bitblt
Changeset: r170:5c391af99cfc
Date: 2013-03-13 15:29 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/5c391af99cfc/
Log: Apply fixes from Smalltalk
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -932,7 +932,7 @@
class BitBltShadow(AbstractCachingShadow):
_attrs_ = [# From BitBlt
- "dest_form", "source_form", "halftone_bits",
+ "dest_form", "source_form", "halftone_form",
"combination_rule", "dest_x", "dest_y", "width",
"height", "source_x", "source_y", "clip_x", "clip_y",
"clip_width", "clip_height", "color_map",
@@ -943,26 +943,36 @@
"n_words", "h_dir", "v_dir", "preload", "source_index",
"dest_index", "source_delta", "dest_delta"]
- RightMasks = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511,
- 1023, 2047, 4095, 8191, 16383, 32767, 65535]
- AllOnes = 65535
+ WordSize = 32
+ RightMasks = [0]
+ for i in xrange(WordSize):
+ RightMasks.append((2 ** (i + 1)) - 1)
+ AllOnes = (2 ** WordSize) - 1
def sync_cache(self):
- self.dest_form = self.fetch(0).as_form_get_shadow(self.space)
+ try:
+ self.dest_form = self.fetch(0).as_form_get_shadow(self.space)
+ except error.PrimitiveFailedError, e:
+ self.detach_shadow()
+ raise e
w_source_form = self.fetch(1)
if w_source_form is self.space.w_nil:
- self.source_form = None
+ self.source_form = self.dest_form
else:
- self.source_form = w_source_form.as_form_get_shadow(self.space)
+ try:
+ self.source_form = w_source_form.as_form_get_shadow(self.space)
+ except error.PrimitiveFailedError, e:
+ self.detach_shadow()
+ raise e
w_halftone_form = self.fetch(2)
- if w_halftone_form is self.space.w_nil:
+ if w_halftone_form is not self.space.w_nil:
+ if isinstance(w_halftone_form, model.W_WordsObject):
+ # Already a bitmap
+ self.halftone_bits = w_halftone_form.words
+ else:
+ self.halftone_bits =
w_halftone_form.as_form_get_shadow(self.space).bits
+ else:
self.halftone_bits = None
- elif isinstance(w_halftone_form, model.W_PointersObject):
- self.halftone_bits =
w_halftone_form.as_form_get_shadow(self.space).bits
- elif isinstance(w_halftone_form, model.W_WordsObject):
- self.halftone_bits = w_halftone_form.words
- elif isinstance(w_halftone_form, model.W_BytesObject):
- self.halftone_bits = [ord(byte) for byte in w_halftone_form.bytes]
self.combination_rule = self.space.unwrap_int(self.fetch(3))
self.dest_x = self.space.unwrap_int(self.fetch(4))
self.dest_y = self.space.unwrap_int(self.fetch(5))
@@ -1001,36 +1011,35 @@
self.dx = self.dx - self.sx
self.w = self.w + self.sx
self.sx = 0
- if self.source_form and self.sx + self.w > self.source_form.width:
+ if self.sx + self.w > self.source_form.width:
self.w = self.w - (self.sx + self.w - self.source_form.width)
if self.sy < 0:
self.dy = self.dy - self.su
self.h = self.h + self.sy
self.sy = 0
- if self.source_form and self.sy + self.h > self.source_form.height:
+ if self.sy + self.h > self.source_form.height:
self.h = self.h - (self.sy + self.h - self.source_form.height)
def compute_masks(self):
self.dest_bits = self.dest_form.bits
- self.dest_raster = (self.dest_form.width - 1) / 16 + 1
- if self.source_form:
- self.source_bits = self.source_form.bits
- self.source_raster = (self.source_form.width - 1) / 16 + 1
- self.skew = (self.sx - self.dx) & 15
- start_bits = 16 - (self.dx & 15)
+ self.dest_raster = (self.dest_form.width - 1) / BitBltShadow.WordSize
+ 1
+ self.source_bits = self.source_form.bits
+ self.source_raster = (self.source_form.width - 1) /
BitBltShadow.WordSize + 1
+ self.skew = (self.sx - self.dx) & (BitBltShadow.WordSize - 1)
+ start_bits = BitBltShadow.WordSize - (self.dx & (BitBltShadow.WordSize
- 1))
self.mask1 = BitBltShadow.RightMasks[start_bits]
- end_bits = 15 - ((self.dx + self.w - 1) & 15)
+ end_bits = (BitBltShadow.WordSize - 1) - ((self.dx + self.w - 1) &
(BitBltShadow.WordSize - 1))
self.mask2 = ~BitBltShadow.RightMasks[end_bits]
if self.skew == 0:
self.skew_mask = 0
else:
- self.skew_mask = BitBltShadow.RightMasks[16 - self.skew]
+ self.skew_mask = BitBltShadow.RightMasks[BitBltShadow.WordSize -
self.skew]
if self.w < start_bits:
self.mask1 = self.mask1 & self.mask2
self.mask2 = 0
self.n_words = 1
else:
- self.n_words = (self.w - start_bits - 1) / 16 + 2
+ self.n_words = (self.w - start_bits - 1) / BitBltShadow.WordSize +
2
def check_overlap(self):
self.h_dir = 1
@@ -1049,11 +1058,12 @@
self.mask1, self.mask2 = self.mask2, self.mask1
def calculate_offsets(self):
- self.preload = self.source_form and self.skew_mask != 0 and self.skew
<= (self.sx & 15)
+ self.preload = (self.skew_mask != 0 and
+ self.skew <= (self.sx & (BitBltShadow.WordSize - 1)))
if self.h_dir < 0:
self.preload = not self.preload
- self.source_index = self.sy * self.source_raster + self.sx / 16
- self.dest_index = self.dy * self.dest_raster + self.dx / 16
+ self.source_index = self.sy * self.source_raster + self.sx /
BitBltShadow.WordSize
+ self.dest_index = self.dy * self.dest_raster + self.dx /
BitBltShadow.WordSize
self.source_delta = ((self.source_raster *
self.v_dir -
(self.n_words + (1 if self.preload else 0))) *
@@ -1061,9 +1071,9 @@
self.dest_delta = self.dest_raster * self.v_dir - self.n_words *
self.h_dir
def copy_loop(self):
- for i in xrange(self.h):
+ for i in xrange(self.h - 1):
if self.halftone_bits:
- halftone_word = self.halftone_bits[self.dy & 15]
+ halftone_word = self.halftone_bits[(self.dy &
(BitBltShadow.WordSize - 1)) % len(self.halftone_bits)]
self.dy = self.dy + self.v_dir
else:
halftone_word = BitBltShadow.AllOnes
@@ -1074,14 +1084,13 @@
else:
prev_word = 0
merge_mask = self.mask1
- for word in xrange(self.n_words):
- if self.source_form:
- prev_word = prev_word & self.skew_mask
- this_word = self.source_bits[self.source_index]
- skew_word = prev_word | (this_word & ~self.skew_mask)
- prev_word = this_word
- skew_word = (self.bit_shift(skew_word, self.skew) |
- self.bit_shift(skew_word, self.skew - 16))
+ for word in xrange(self.n_words - 1):
+ prev_word = prev_word & self.skew_mask
+ this_word = self.source_bits[self.source_index]
+ skew_word = prev_word | (this_word & ~self.skew_mask)
+ prev_word = this_word
+ skew_word = (self.bit_shift(skew_word, self.skew) |
+ self.bit_shift(skew_word, self.skew - 16))
merge_word = self.merge(
skew_word & halftone_word,
self.dest_bits[self.dest_index]
@@ -1145,11 +1154,12 @@
_attrs_ = ["bits", "width", "height", "depth", "offset_x", "offset_y"]
def sync_cache(self):
- w_bits = self.fetch(0)
- if isinstance(w_bits, model.W_WordsObject):
- self.bits = w_bits.words
+ self.w_bits = self.fetch(0)
+ if isinstance(self.w_bits, model.W_WordsObject):
+ self.bits = self.w_bits.words
else:
- self.bits = [ord(byte) for byte in w_bits.bytes]
+ self.detach_shadow()
+ raise error.PrimitiveFailedError
self.width = self.space.unwrap_int(self.fetch(1))
self.height = self.space.unwrap_int(self.fetch(2))
self.depth = self.space.unwrap_int(self.fetch(3))
@@ -1159,8 +1169,8 @@
self.offset_y = self.space.unwrap_int(w_offset._fetch(1))
def replace_bits(self, bits):
- w_bits = self.fetch(0)
- if isinstance(bits, model.W_WordsObject):
- w_bits.words[:] = bits
+ if isinstance(self.w_bits, model.W_WordsObject):
+ self.w_bits.words[:] = bits
else:
- w_bits.bytes[:] = [chr(byte) for byte in bits]
+ self.detach_shadow()
+ raise error.PrimitiveFailedError
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit