/usr/share/pyshared/childsplay_sp/cairoimage.py is in childsplay 1.6-1.
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 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | # This module comes from the OLPC project and is licensed under the BSD license.
# The changes are minimal and only done to let it work outside Sugar.
# Below is the original COPYING file.
##* Copyright (c) 2007, One Laptop Per Child.
##* All rights reserved.
##*
##* Redistribution and use in source and binary forms, with or without
##* modification, are permitted provided that the following conditions are met:
##* * Redistributions of source code must retain the above copyright
##* notice, this list of conditions and the following disclaimer.
##* * Redistributions in binary form must reproduce the above copyright
##* notice, this list of conditions and the following disclaimer in the
##* documentation and/or other materials provided with the distribution.
##* * Neither the name of One Laptop Per Child nor the
##* names of its contributors may be used to endorse or promote products
##* derived from this software without specific prior written permission.
##*
##* THIS SOFTWARE IS PROVIDED BY ONE LAPTOP PER CHILD ``AS IS'' AND ANY
##* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
##* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
##* DISCLAIMED. IN NO EVENT SHALL ONE LAPTOP PER CHILD BE LIABLE FOR ANY
##* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
##* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
##* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
##* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
##* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
##* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""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( 'schoolsplay._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()
|