graphicsmodule.cpp

来自「python s60 1.4.5版本的源代码」· C++ 代码 · 共 1,932 行 · 第 1/4 页

CPP
1,932
字号
    case EInvalid:
      break;
#ifdef ICL_SUPPORT
    case EPendingLoad: 
      iDecoder->Cancel(); 
      delete iDecoder; iDecoder=NULL;
      iState=ENormalIdle;
      break;
    case EPendingSave: 
      iEncoder->Cancel(); 
      delete iEncoder; iEncoder=NULL;
      delete iFrameImageData; iFrameImageData=NULL;
      iState=ENormalIdle;      
      break;
    case EPendingScale: 
      iScaler->Cancel(); 
      delete iScaler;
      iScaler=NULL;
      iState=ENormalIdle;      
      break;
    case EPendingRotate: 
      iRotator->Cancel(); 
      delete iRotator;
      iRotator=NULL;
      iState=ENormalIdle;      
      break;
#endif // ICL_SUPPORT
    default: PANIC("ImageObject");
    }
  }
  /*  CBitmapDevice *GetDeviceL() {    
      CBitmapDevice *device=CFbsBitmapDevice::NewL(iBitmap);
      return device;
      } */   
  CFbsBitmap *GetBitmap() {
    return iBitmap;
  }    
  void GetPixel(TRgb &aColor, const TPoint &aPixel) const {
    EnsureFbsSessionIsOpen();
    iBitmap->GetPixel(aColor, aPixel);
  }

  void SetCompletionCallback(PyObject *callback) {
    Py_XDECREF(iCompletionCallback);
    iCompletionCallback=callback;
    Py_XINCREF(callback);
  }  
  
private:
  void InvokeCompletionCallback() {
    if (iCompletionCallback) {
      PyObject *arg=Py_BuildValue("(i)",iStatus.Int());
      app_callback_handler(iCompletionCallback,arg);
      if (PyErr_Occurred())
	PyErr_Print();
      Py_DECREF(arg);
      Py_DECREF(iCompletionCallback);
      iCompletionCallback=NULL;
    }
  }
  RFs &FsSession();
  PyObject *iCompletionCallback;
  CFbsBitmap *iBitmap;
#ifdef ICL_SUPPORT
  CImageDecoder *iDecoder;
  CImageEncoder *iEncoder;
  CBitmapScaler *iScaler;
  CBitmapRotator *iRotator;
  CFrameImageData *iFrameImageData;
#endif // ICL_SUPPORT
  RFs *iFsSession;
};

RFs &
ImageObject::FsSession()
{
  if (!iFsSession) {
    iFsSession=new RFs;
    iFsSession->Connect();
  }
  return *iFsSession;
}


struct Image_object {
  PyObject_VAR_HEAD
  ImageObject* data;
};

/* Create an ImageObject from a CObject that contains a CFbsBitmap *.
   The ImageObject assumes ownership of the CFbsBitmap. */
extern "C" PyObject *
graphics_ImageFromCFbsBitmap(PyObject* /*self*/, PyObject* args)
{
  PyObject *bitmap_object=NULL;
  if (!PyArg_ParseTuple(args, "O",&bitmap_object))
    return NULL;  
  if (!PyCObject_Check(bitmap_object)) {
    PyErr_SetString(PyExc_TypeError, 
		    "Expected CObject containing a pointer to CFbsBitmap");
    return NULL;
  }
  CFbsBitmap *bitmap=(CFbsBitmap *)PyCObject_AsVoidPtr(bitmap_object);
  Image_object *obj;
  if (!(obj = PyObject_New(Image_object, Image_type))) 
    return PyErr_NoMemory();    
  TRAPD(error, {
      obj->data = new (ELeave) ImageObject();
      CleanupStack::PushL(obj->data);
      obj->data->ConstructL(bitmap);
      CleanupStack::Pop();
    });
  if(error != KErrNone){
    PyObject_Del(obj);   
    return SPyErr_SetFromSymbianOSErr(error);
  }
  return (PyObject*)obj;
}


#ifdef EKA2
/* Create an ImageObject from an Icon file. */
extern "C" PyObject *
graphics_ImageFromIcon(PyObject* /*self*/, PyObject* args)
{
  TInt width = 0;
  TInt height = 0;
  TInt image_id = 0;
  PyObject* filename;
  CFbsBitmap* bitmap = NULL;
  
  
  if (!PyArg_ParseTuple(args, "Uiii", &filename, &image_id, &width, &height))
    return NULL;  

  TPtrC filenamePtr((TUint16*) PyUnicode_AsUnicode(filename), 
                    PyUnicode_GetSize(filename));
             
                    
  Image_object *obj;
  if (!(obj = PyObject_New(Image_object, Image_type))){
    return PyErr_NoMemory();    
  }
  
  TRAPD(error, {
      bitmap = AknIconUtils::CreateIconL(filenamePtr, image_id);
      CleanupStack::PushL(bitmap);
      obj->data = new (ELeave) ImageObject();
      CleanupStack::PushL(obj->data);
      User::LeaveIfError(AknIconUtils::SetSize(bitmap, TSize(width, height)));
      obj->data->ConstructL(bitmap);
      CleanupStack::Pop();
      CleanupStack::Pop();
    });

  if(error != KErrNone){ 
    PyObject_Del(obj);   
    return SPyErr_SetFromSymbianOSErr(error);
  }
  return (PyObject*)obj;  
}
#endif


extern "C" PyObject *
graphics_ImageNew(PyObject* /*self*/, PyObject* args)
{
  int xSize,ySize;
  enum TDisplayMode mode=EColor64K;
  if (!PyArg_ParseTuple(args, "(ii)i",&xSize,&ySize,&mode)) 
    return NULL;  
  switch (mode) {
  case EGray2:
  case EGray256:
  case EColor4K:
  case EColor64K:
  case EColor16M:
    break;
  default:
    PyErr_SetString(PyExc_ValueError, "Invalid mode specifier");
    return NULL;
  }
  Image_object *obj;
  if (!(obj = PyObject_New(Image_object, Image_type))) 
    return PyErr_NoMemory();    
  TRAPD(error, {
      obj->data = new (ELeave) ImageObject();
      CleanupStack::PushL(obj->data);
      obj->data->ConstructL(xSize,ySize,mode);
      CleanupStack::Pop();
    });
  if(error != KErrNone){
    PyObject_Del(obj);   
    return SPyErr_SetFromSymbianOSErr(error);
  }
  return (PyObject*)obj;
}

/*
static void
pyprintf(const char *format, ...)
{
  va_list args;
  va_start(args,format);
  char buf[128];
  // Unfortunately Symbian doesn't seem to support the vsnprintf
  // function, which would allow us to specify the length of the
  // buffer we are writing to. As a result using this function is
  // unsafe and will lead to a buffer overflow if given an argument
  // that is too big. Do not use this function in production code.
  vsprintf(buf, format, args);    
  char buf2[128];
  sprintf(buf2, "print '%s'", buf);
  PyRun_SimpleString(buf2);
}
*/

extern "C" PyObject*
Image_getpixel(Image_object *self, PyObject *args)
{
  PyObject *coordseq_obj=NULL;
  PyObject *retval=NULL;
  int n_coords=0,i;
  
  if (!PyArg_ParseTuple(args, "O", &coordseq_obj) ||
      !PyCoordSeq_Length(coordseq_obj, &n_coords))
    return 0;
  
  if (!(retval=PyList_New(n_coords)))
    goto error;
  
  for (i=0; i<n_coords; i++) {
    TPoint point;
    if (!PyCoordSeq_GetItem(coordseq_obj, i, &point.iX, &point.iY)) 
      goto error;
    TRgb color;
    self->data->GetPixel(color,point);
    
    PyObject *coordpair=Py_BuildValue("(iii)",
				     color.Red(), 
				     color.Green(), 
				     color.Blue());
    if (!coordpair)
      goto error;
    if (-1==PyList_SetItem(retval, i, coordpair))
      goto error;
  }
  return retval;
 error:
  Py_XDECREF(retval);
  return 0;
}


#ifdef ICL_SUPPORT
extern "C" PyObject *
graphics_ImageOpen(PyObject* /*self*/, PyObject* args)
{
  Image_object *obj;
  PyObject *filename=NULL;
  PyObject *callback=NULL;
  
  if (!PyArg_ParseTuple(args, "U|O", &filename, &callback)) 
    return NULL;  
  TPtrC filenamePtr((TUint16*)PyUnicode_AsUnicode(filename), 
		    PyUnicode_GetSize(filename));
  if (!(obj = PyObject_New(Image_object, Image_type))) 
    return PyErr_NoMemory();    
  TRAPD(error, {
      obj->data = new (ELeave) ImageObject();
      CleanupStack::PushL(obj->data);
      if (callback)
	obj->data->SetCompletionCallback(callback);
      obj->data->ConstructL(filenamePtr);
      CleanupStack::Pop();
    });
  if(error != KErrNone){
    PyObject_Del(obj);
    return SPyErr_SetFromSymbianOSErr(error);
  }
  return (PyObject *)obj;
}

extern "C" PyObject *
graphics_ImageInspect(PyObject* /*self*/, PyObject* args)
{
  PyObject *filename=NULL;
  if (!PyArg_ParseTuple(args, "U", &filename)) 
    return NULL;  
  TPtrC filenamePtr((TUint16*)PyUnicode_AsUnicode(filename), 
		    PyUnicode_GetSize(filename));
  int width,height,mode;
  TRAPD(error, {
      ImageObject::InspectFileL(filenamePtr,width, height, mode);
    });
  if(error != KErrNone){
    return SPyErr_SetFromSymbianOSErr(error);
  }
  return Py_BuildValue("(ii)i",width,height,mode);
}


extern "C" PyObject*
Image_load(Image_object *self, PyObject *args)
{
  PyObject *filename;
  ImageObject *image=self->data;
  PyObject *callback=NULL;
  int sizeMatches=1;
  if (!PyArg_ParseTuple(args, "UO", &filename, &callback)) 
    return NULL;
  
  TPtrC filenamePtr((TUint16*) PyUnicode_AsUnicode(filename), 
		    PyUnicode_GetSize(filename));  
  TRAPD(error, {
      if (callback)
	image->SetCompletionCallback(callback);      
      sizeMatches=image->StartLoadL(filenamePtr);      
    });
  if (!error && !sizeMatches) {
    PyErr_SetString(PyExc_RuntimeError, "file size doesn't match image size");
    return NULL;
  }
  RETURN_ERROR_OR_PYNONE(error);
}


#define ERROR(msg) do { PyErr_SetString(PyExc_ValueError, msg); goto error; } while(0)

extern "C" PyObject*
Image_save(Image_object *self, PyObject *args)
{
  PyObject *filename;
  ImageObject *image=self->data;
  PyObject *callback=NULL;
  char *formatstring, *compressionstring;
  int quality, bpp, color=0;;
    if (!PyArg_ParseTuple(args, "UOsisi", &filename, &callback,
			&formatstring, &quality, &compressionstring, &bpp)) 
    return NULL;  

  TPtrC filenamePtr((TUint16*) PyUnicode_AsUnicode(filename), 
		    PyUnicode_GetSize(filename));  
  ImageObject::ImageFormat format;
  TPngEncodeData::TPngCompressLevel compression=TPngEncodeData::EDefaultCompression;

  if (!strcmp(formatstring,"JPEG")) {
    if (quality < 0 || quality > 100) 
      ERROR("invalid quality");    
    format=ImageObject::EJpeg;
  } else if (!strcmp(formatstring,"PNG")) {
    format=ImageObject::EPng;
    if (!strcmp(compressionstring,"default")) {
      compression=TPngEncodeData::EDefaultCompression;
    } else if (!strcmp(compressionstring,"no")) {
      compression=TPngEncodeData::ENoCompression;
    } else if (!strcmp(compressionstring,"fast")) {
      compression=TPngEncodeData::EBestSpeed;
    } else if (!strcmp(compressionstring,"best")) {
      compression=TPngEncodeData::EBestCompression;
    } else {
      ERROR("invalid compression level");
    }
    switch (bpp) {
    case 1:
    case 8:
      color=0;
      break;
    case 24:
      color=1;
      break;
    default:
      ERROR("invalid number of bits per pixel");
    }
  } else {
    ERROR("invalid format");
  }
  
  TRAPD(error, {
      if (callback)
	image->SetCompletionCallback(callback);
      image->StartSaveL(filenamePtr,format,quality,compression,bpp,color);
    });
  RETURN_ERROR_OR_PYNONE(error);
 error:
  return NULL;
}
#undef ERROR

extern "C" PyObject*
Image_resize(Image_object *self, PyObject *args)
{
  ImageObject *image=self->data;
  PyObject *callback=NULL;
  int maintainAspect=0;
  PyObject *target_bitmap_object=NULL;
  if (!PyArg_ParseTuple(args, "OiO", &target_bitmap_object, &maintainAspect, &callback))
    return NULL;
  
  CFbsBitmap *target_bitmap=Bitmap_AsFbsBitmap(target_bitmap_object);
  if (!target_bitmap) 
    return NULL;
  TRAPD(error, {
      if (callback)
	image->SetCompletionCallback(callback);
      image->StartScaleL(target_bitmap,maintainAspect?ETrue:EFalse);
    });
  RETURN_ERROR_OR_PYNONE(error);
}

#define FLIP_LEFT_RIGHT 1
#define FLIP_TOP_BOTTOM 2
#define ROTATE_90 3
#define ROTATE_180 4
#define ROTATE_270 5

extern "C" PyObject*
Image_transpose(Image_object *self, PyObject *args)
{
  ImageObject *image=self->data;
  PyObject *callback=NULL;
  int direction;
  PyObject *target_bitmap_object=NULL;
  if (!PyArg_ParseTuple(args, "OiO", &target_bitmap_object, &direction, &callback))
    return NULL;
  
  CBitmapRotator::TRotationAngle angle;
  switch (direction) {
  case FLIP_LEFT_RIGHT: angle=CBitmapRotator::EMirrorVerticalAxis; break;
  case FLIP_TOP_BOTTOM: angle=CBitmapRotator::EMirrorHorizontalAxis; break;
  case ROTATE_90:       angle=CBitmapRotator::ERotation270DegreesClockwise; break;
  case ROTATE_180:      angle=CBitmapRotator::ERotation180DegreesClockwise; break;
  case ROTATE_270:      angle=CBitmapRotator::ERotation90DegreesClockwise; break;
  default:
    PyErr_SetString(PyExc_ValueError, "invalid transpose direction");
    return NULL;
  }

  CFbsBitmap *target_bitmap=Bitmap_AsFbsBitmap(target_bitmap_object);
  if (!target_bitmap) 
    return NULL;
  TRAPD(error, {
      if (callback)
	image->SetCompletionCallback(callback);
      image->StartRotateL(target_bitmap, angle);
    });
  RETURN_ERROR_OR_PYNONE(error);
}

extern "C" PyObject*
Image_stop(Image_object *self, PyObject * /* args */)
{
  ImageObject *image=self->data;
  image->Stop();
  PY_RETURN_NONE;
}
#endif /* ICL_SUPPORT */

static void _Image__gc_dealloc(void *gc, void *a2)
{
  CFbsBitGc *context=STATIC_CAST(CFbsBitGc *,gc);
  CGraphicsDevice *device=context->Device();
  delete context;
  delete device;
  Py_DECREF((PyObject *)a2);
}


extern "C" PyObject*
Image__drawapi(Image_object *self, PyObject * /*args*/)
{
  PyObject *ret=NULL;
  CFbsBitmapDevice *device=NULL;
  CFbsBitGc *gc=NULL;
  TRAPD(error, {
      device=CFbsBitmapDevice::NewL(self->data->GetBitmap());
      CleanupStack::PushL(device);
      User::LeaveIfError(device->CreateContext(gc));
      CleanupStack::Pop(device);
    });
  if (error == KErrNone) {
    ret=PyCObject_FromVoidPtrAndDesc(gc, self,_Image__gc_dealloc);
    if (ret) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?