/usr/share/sugar/activities/Physics.activity/olpcgames/_cairoimage.py is in sugar-physics-activity 7+dfsg-1.2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | """Utility functions for cairo-specific operations
USE_BASE_ARRAY -- if False (default), uses numpy arrays,
currently this is the only version that works on 32-bit
machines.
"""
import pygame, struct, logging
big_endian = struct.pack( '=i', 1 ) == struct.pack( '>i', 1 )
log = logging.getLogger( 'olpcgames._cairoimage' )
##log.setLevel( logging.DEBUG )
USE_BASE_ARRAY = False
def newContext( width, height ):
"""Create a new render-to-image context
width, height -- pixel dimensions to be rendered
Produces an ARGB format Cairo ImageSurface for
rendering your data into using rsvg, Cairo or Pango.
returns (ImageSurface, CairoContext) for rendering
"""
import cairo
csrf = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
context = cairo.Context (csrf)
#log.info( 'Format (expect: %s): %s', cairo.FORMAT_ARGB32, csrf.get_format())
return csrf, context
def mangle_color(color):
"""Mange a colour depending on endian-ness, and swap-necessity
Converts a 3 or 4 int (or float) value in the range 0-255 into a
4-float value in the range 0.0-1.0
"""
r,g,b = color[:3]
if len(color) > 3:
a = color[3]
else:
a = 255.0
return map(_fixColorBase, (r,g,b,a) )
def _fixColorBase( v ):
"""Return a properly clamped colour in floating-point space"""
return max((0,min((v,255.0))))/255.0
def asImage( csrf ):
"""Get the pixels in csrf as a Pygame image
Note that Pygame 1.7.1 on (Gentoo Linux) AMD64 is incorrectly
calculating the required size ARGB images, so this code will *not* work
on that platform with that version of the library. Pygame-ctypes
does work correctly there.
Note also that Pygame 1.7.1 is showing a strange colour rotation
bug on 32-bit platforms, such that ARGB mode cannot be used for
images there. Instead we have to do an expensive bit-shift operation
to produce an RGBA image from the ARGB native Cairo format.
Will raise a ValueError if passed a Null image (i.e. dimension of 0)
returns Pygame.Surface (image) with convert_alpha() called for it.
"""
# Create and return a new Pygame Image derived from the Cairo Surface
format = 'ARGB'
if hasattr(csrf,'get_data'):
# more recent API, native-format, but have to (potentially) convert the format...
log.debug( 'Native-mode api (get_data)' )
data = csrf.get_data()
if not big_endian:
# we use array here because it's considerably lighter-weight
# to import than the numpy module
log.debug( 'Not big-endian, byte-swapping array' )
if USE_BASE_ARRAY:
import array
a = array.array( 'I' )
a.fromstring( data )
a.byteswap()
data = a.tostring()
else:
import numpy
n = numpy.fromstring( data, dtype='I' )
n = ((n & 0xff000000) >> 24 ) | ((n & 0x00ffffff) << 8 )
n = n.byteswap()
data = n.tostring()
format = 'RGBA'
else:
log.debug( 'Big-endian, array unchanged' )
data = str(data) # there's one copy
else:
# older api, not native, but we know what it is...
log.debug( 'Non-native mode api, explicitly RGBA' )
data = csrf.get_data_as_rgba()
data = str(data) # there's one copy
format = 'RGBA'
width, height = csrf.get_width(),csrf.get_height()
try:
log.info( 'Format = %s', format )
return pygame.image.fromstring(
data,
(width,height),
format
) # there's the next
except ValueError, err:
err.args += (len(data), (width,height), width*height*4,format )
raise
if __name__ == "__main__":
import unittest
logging.basicConfig()
class Tests( unittest.TestCase ):
def test_colours( self ):
"""Test that colours are correctly translated
If we draw a given colour in cairo, we want the same
colour to show up in Pygame, let's test that...
"""
for sourceColour in [
(255,0,0, 255),
(0,255,0, 255),
(0,0,255, 255),
(255,255,0, 255),
(0,255,255,255),
(255,0,255,255),
]:
csrf,cctx = newContext( 1,1 )
background = mangle_color( sourceColour )
cctx.set_source_rgba(*background)
cctx.paint()
img = asImage( csrf )
colour = img.get_at( (0,0))
assert colour == sourceColour, (sourceColour,mangle_color(sourceColour),colour)
unittest.main()
|