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 + -
显示快捷键?