src/ext/amaretto/graphics/src/graphics.py
changeset 0 ca70ae20a155
equal deleted inserted replaced
-1:000000000000 0:ca70ae20a155
       
     1 # Copyright (c) 2005-2009 Nokia Corporation
       
     2 #
       
     3 # Licensed under the Apache License, Version 2.0 (the "License");
       
     4 # you may not use this file except in compliance with the License.
       
     5 # You may obtain a copy of the License at
       
     6 #
       
     7 #     http://www.apache.org/licenses/LICENSE-2.0
       
     8 #
       
     9 # Unless required by applicable law or agreed to in writing, software
       
    10 # distributed under the License is distributed on an "AS IS" BASIS,
       
    11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    12 # See the License for the specific language governing permissions and
       
    13 # limitations under the License.
       
    14 
       
    15 import e32
       
    16 import _graphics
       
    17 import sysinfo
       
    18 
       
    19 Draw=_graphics.Draw
       
    20 
       
    21 def _revdict(d):
       
    22     return dict([(d[k],k) for k in d.keys()])
       
    23 
       
    24 SDK12=not hasattr(_graphics,'FLIP_LEFT_RIGHT')
       
    25 
       
    26 if not SDK12:
       
    27     FLIP_LEFT_RIGHT=_graphics.FLIP_LEFT_RIGHT
       
    28     FLIP_TOP_BOTTOM=_graphics.FLIP_TOP_BOTTOM
       
    29     ROTATE_90=_graphics.ROTATE_90
       
    30     ROTATE_180=_graphics.ROTATE_180
       
    31     ROTATE_270=_graphics.ROTATE_270
       
    32 
       
    33 class Image(object):
       
    34     _twips = sysinfo.display_twips()
       
    35     _pixels = sysinfo.display_pixels()
       
    36     _default_density = (float(_twips[0])/_pixels[0],
       
    37                         float(_twips[1])/_pixels[1])
       
    38     _modemap={'1': _graphics.EGray2,
       
    39               'L': _graphics.EGray256,
       
    40               'RGB12': _graphics.EColor4K,
       
    41               'RGB16': _graphics.EColor64K,
       
    42               'RGB': _graphics.EColor16M}
       
    43     _moderevmap=_revdict(_modemap)
       
    44     def __init__(self,img):
       
    45         self._image=img
       
    46         if img.twipsize == (0,0):
       
    47             img.twipsize = (self._default_density[0]*img.size[0],self._default_density[1]*img.size[1])
       
    48         self._drawapi=self._image._drawapi
       
    49         self._draw=_graphics.Draw(self._image)
       
    50         self._bitmapapi=self._image._bitmapapi
       
    51         self.getpixel=self._image.getpixel
       
    52         self._lock=None
       
    53         self._errcode=0
       
    54         self._waiting=0
       
    55         self._resized_image=None
       
    56         for k in _graphics._draw_methods:
       
    57             setattr(self,k,getattr(self._draw,k))
       
    58     size=property(lambda self:self._image.size)
       
    59     mode=property(lambda self:self._moderevmap[self._image.mode])
       
    60 
       
    61     twipsize=property(lambda self: self._image.twipsize,
       
    62                       lambda self, value: setattr(self._image, 
       
    63                                                   "twipsize", 
       
    64                                                   value))
       
    65     def from_cfbsbitmap(bitmap):
       
    66         return Image(_graphics.ImageFromCFbsBitmap(bitmap))
       
    67     from_cfbsbitmap=staticmethod(from_cfbsbitmap)
       
    68     def from_icon(filename,image_id,size):
       
    69         if e32.s60_version_info>=(3,0):
       
    70             return Image(_graphics.ImageFromIcon(filename,image_id,size[0],size[1]))
       
    71         else:
       
    72             raise RuntimeError('not supported')
       
    73     from_icon=staticmethod(from_icon)
       
    74     def new(size,mode='RGB16'):
       
    75         if not Image._modemap.has_key(mode):
       
    76             raise ValueError('invalid mode')
       
    77         return Image(_graphics.ImageNew(size,Image._modemap[mode]))
       
    78     new=staticmethod(new)
       
    79     if not SDK12:
       
    80         def open(filename):
       
    81             def finish_load(errcode):
       
    82                 img._errcode=errcode
       
    83                 lock.signal()
       
    84             lock=e32.Ao_lock()
       
    85             img=Image(_graphics.ImageOpen(unicode(filename),finish_load))
       
    86             lock.wait()        
       
    87             if img._errcode != 0:
       
    88                 raise SymbianError,(img._errcode,
       
    89                                     "Error loading image:"+e32.strerror(img._errcode))
       
    90             return img
       
    91         open=staticmethod(open)
       
    92         def inspect(filename):
       
    93             (size,mode)=_graphics.ImageInspect(unicode(filename))
       
    94             return {'size': size}
       
    95         inspect=staticmethod(inspect)
       
    96         def load(self,filename,callback=None):
       
    97             self._wait()
       
    98             self._filename=unicode(filename)
       
    99             self._usercallback=callback
       
   100             self._lock=e32.Ao_lock()
       
   101             self._image.load(self._filename,self._callback)
       
   102             if callback is None:
       
   103                 self._wait()
       
   104                 if self._errcode != 0:
       
   105                     err=self._errcode
       
   106                     self._errcode=0
       
   107                     raise SymbianError,(err, "Error loading image:"+e32.strerror(err))
       
   108         def save(self,filename,callback=None,format=None,quality=75,bpp=24,compression='default'):
       
   109             if format is None:
       
   110                 if filename.lower().endswith('.jpg') or filename.lower().endswith('.jpeg'):
       
   111                     format='JPEG'
       
   112                 elif filename.lower().endswith('.png'):
       
   113                     format='PNG'
       
   114                 else:
       
   115                     raise ValueError('unrecognized suffix and format not specified')
       
   116             self._wait()
       
   117             lock=e32.Ao_lock()
       
   118             self._image.save(unicode(filename),self._callback,format,quality,compression,bpp)
       
   119             # If the code above didn't raise an exception, this method
       
   120             # will succeed, so now it's safe to modify object state.
       
   121             self._usercallback=callback
       
   122             self._lock=lock
       
   123             if callback is None:
       
   124                 self._wait()
       
   125                 if self._errcode != 0:
       
   126                     err=self._errcode
       
   127                     self._errcode=0
       
   128                     raise SymbianError,(err, "Error saving image:" + e32.strerror(err))
       
   129         def resize(self,size,callback=None,keepaspect=0):
       
   130             self._wait()
       
   131             newimage=Image.new(size,self.mode) 
       
   132             lock=e32.Ao_lock()
       
   133             self._image.resize(newimage,keepaspect,self._callback)
       
   134             # If the code above didn't raise an exception, this method
       
   135             # will succeed, so now it's safe to modify object state.
       
   136             self._lock=lock
       
   137             self._usercallback=callback
       
   138             self._resized_image=newimage
       
   139             if callback is None:
       
   140                 self._wait()
       
   141                 if self._errcode != 0:
       
   142                     err=self._errcode
       
   143                     self._errcode=0
       
   144                     raise SymbianError,(err, "Error resizing image:"+e32.strerror(err))
       
   145                 t=self._resized_image
       
   146                 self._resized_image=None
       
   147                 return t
       
   148         def transpose(self,direction,callback=None):
       
   149             self._wait()
       
   150             if direction == ROTATE_90 or direction == ROTATE_270:
       
   151                 newsize=(self.size[1],self.size[0])
       
   152             else:
       
   153                 newsize=self.size
       
   154             newimage=Image.new(newsize,self.mode) 
       
   155             lock=e32.Ao_lock()
       
   156             self._image.transpose(newimage,direction,self._callback)
       
   157             # If the code above didn't raise an exception, this method
       
   158             # will succeed, so now it's safe to modify object state.
       
   159             self._lock=lock
       
   160             self._usercallback=callback
       
   161             self._resized_image=newimage
       
   162             if callback is None:
       
   163                 self._wait()
       
   164                 if self._errcode != 0:
       
   165                     err=self._errcode
       
   166                     self._errcode=0
       
   167                     raise RuntimeError("Error resizing image:"+str(err))
       
   168                 t=self._resized_image
       
   169                 self._resized_image=None
       
   170                 return t
       
   171         def _callback(self, errcode):
       
   172             self._errcode=errcode
       
   173             if self._lock:
       
   174                 self._lock.signal()
       
   175             self._lock=None
       
   176             if self._usercallback is not None:
       
   177                 t=self._usercallback
       
   178                 self._usercallback=None
       
   179                 if self._resized_image is not None: # resize in progress
       
   180                     if self._errcode == 0:
       
   181                         newimage=self._resized_image
       
   182                         self._resized_image=None
       
   183                         t(newimage)
       
   184                     else:
       
   185                         t(None)
       
   186                 else:
       
   187                     t(self._errcode)
       
   188         def _wait(self):
       
   189             if self._lock:
       
   190                 if self._waiting:
       
   191                     raise RuntimeError("Image object busy.")
       
   192                 self._waiting=1
       
   193                 self._lock.wait()
       
   194                 self._waiting=0
       
   195         def stop(self):
       
   196             self._image.stop()
       
   197             if self._lock:
       
   198                 self._errcode=0
       
   199                 self._lock.signal()
       
   200                 self._lock=None
       
   201 
       
   202 def screenshot():
       
   203     return Image(_graphics.screenshot())
       
   204 
       
   205 
       
   206 FONT_BOLD=1
       
   207 FONT_ITALIC=2
       
   208 FONT_SUBSCRIPT=4
       
   209 FONT_SUPERSCRIPT=8
       
   210 FONT_ANTIALIAS=16
       
   211 FONT_NO_ANTIALIAS=32
       
   212 
       
   213 __all__=('Draw',
       
   214          'Image',
       
   215          'screenshot',
       
   216          'FONT_BOLD',
       
   217          'FONT_ITALIC',
       
   218          'FONT_SUBSCRIPT',
       
   219          'FONT_SUPERSCRIPT',
       
   220          'FONT_ANTIALIAS',
       
   221          'FONT_NO_ANTIALIAS')
       
   222 
       
   223 if not SDK12: 
       
   224     __all__+=(('FLIP_LEFT_RIGHT',
       
   225                'FLIP_TOP_BOTTOM',
       
   226                'ROTATE_90',
       
   227                'ROTATE_180',
       
   228                'ROTATE_270'))
       
   229