⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graphicsmodule.cpp

📁 python s60 1.4.5版本的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/**
 * ====================================================================
 * graphicsmodule.cpp
 *
 * Copyright (c) 2005-2008 Nokia Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Python.h"
#include "symbian_python_ext_util.h"

#if SERIES60_VERSION > 12
#define ICL_SUPPORT
#endif

#include <e32std.h>
#include <w32std.h>
#include <eikenv.h>
#include <f32file.h>
#include <s32mem.h>
#include <apmstd.h>
#include <apparc.h>
#include <aknenv.h>
#include <aknappui.h>
#include <aknapp.h>
#include <eikon.hrh>          // Form
#include <avkon.hrh>
#include <avkon.rsg>
#include <eikedwin.h>         // Form
#include <eikcapc.h>          // Form
#include <txtfrmat.h>         // Text
#include <txtfmlyr.h>         // Text
#include <eikgted.h>          // Text
#include <eikrted.h>	      // RText
#include <txtrich.h>
#include <gdi.h>	      // RText
#include <aknlists.h>
#include <aknselectionlist.h>
#include <aknquerydialog.h>
#include <akntitle.h>
#include <aknnotewrappers.h>
#include <aknPopup.h>
#include <AknForm.h>
#include <documenthandler.h>


#ifdef ICL_SUPPORT
#include <ImageConversion.h>
#include <BitmapTransforms.h>
#endif

#include "colorspec.cpp"
#include "fontspec.cpp"

//#include <ImageCodecData.h>

#ifdef EKA2
#include <akniconutils.h> 
#endif


#define PY_RETURN_NONE do {			\
    Py_INCREF(Py_None);				\
    return Py_None;				\
  } while (0)					\


// ******** Image object

/*
 * A helper function for the implementation of callbacks
 * from C/C++ code to Python callables
 */

static TInt app_callback_handler(void* func, void* arg);


static TInt app_callback_handler(void* func, void* arg)
{
  TInt error = KErrNone;
  
  PyObject* rval = PyEval_CallObject((PyObject*)func, (PyObject*)arg);
  
  if (!rval) {
    error = KErrPython;
    if (PyErr_Occurred() == PyExc_OSError) {
      PyObject *type, *value, *traceback;
      PyErr_Fetch(&type, &value, &traceback);
      if (PyInt_Check(value))
        error = PyInt_AS_LONG(value);
    }
  }
  else
    Py_DECREF(rval);

  return error;
}

// Helper function for extracting C API's from objects.
static PyObject *
PyCAPI_GetCAPI(PyObject *object, 
	       const char *apiname)
{
  PyObject *capi_func=NULL;
  PyObject *capi_cobject=NULL;
  if (!(capi_func=PyObject_GetAttrString(object,(char *)apiname)) ||
      !PyCallable_Check(capi_func) ||
      !(capi_cobject=PyObject_CallObject(capi_func,NULL)) ||
      !(PyCObject_Check(capi_cobject))) {
    Py_XDECREF(capi_func);
    Py_XDECREF(capi_cobject);
    return NULL;
  }
  Py_DECREF(capi_func);
  return capi_cobject;
}

/*
 * Compute how many coordinate pairs are in the given coordinate sequence. 
 * Store result in *length.
 * 
 * Return: 1 if successful, 0 if error.
 */
static int 
PyCoordSeq_Length(PyObject *coordseq_obj, int *length)
{
#define ERROR(msg) do { PyErr_SetString(PyExc_ValueError,"invalid coordinates: " msg); goto error; } while(0)
  PyObject *item=NULL, *subitem=NULL;
  int seq_len=0;
  if (!PySequence_Check(coordseq_obj)) 
    ERROR("not a sequence");
  seq_len=PySequence_Length(coordseq_obj);
  item=PySequence_GetItem(coordseq_obj,0);
  if (!item) 
    goto error; // propagate error;
  if (PyInt_Check(item)||PyFloat_Check(item)) { // Coordinate sequence style (x,y,x,y,x,y...)
    if (seq_len % 2) 
      ERROR("sequence length is odd"); 
    Py_DECREF(item);
    *length=seq_len/2;
    return 1;
  } else if (PySequence_Check(item)) { // Coordinate sequence style ((x,y),(x,y),(x,y)...)
    subitem=PySequence_GetItem(item,0);
    if (!subitem) 
      goto error; // propagate error;
    if (!PyInt_Check(subitem) && !PyFloat_Check(subitem)) 
      ERROR("non-number in sequence");
    Py_DECREF(subitem);
    Py_DECREF(item);
    *length=seq_len;
    return 1;
  } else
    ERROR("sequence of numbers or 2-tuples expected");
 error:
  Py_XDECREF(subitem);
  Py_XDECREF(item);
  return NULL;
}

/*
 * Get a coordinate pair out of the given coordinate sequence.
 * Store result in *x, *y.
 * Return: 1 if successful, 0 if error.
 */
static int 
PyCoordSeq_GetItem(PyObject *coordseq_obj, int index, int *x, int *y)
{
  int seq_len=PySequence_Length(coordseq_obj);
  PyObject *item=NULL, *x_obj=NULL, *y_obj=NULL;
  if (!PySequence_Check(coordseq_obj) || seq_len == 0) 
    ERROR("not a sequence or empty sequence");
  item=PySequence_GetItem(coordseq_obj,0);
  if (!item) 
    goto error; // propagate error
  if (PyInt_Check(item)||PyFloat_Check(item)) { // Coordinate sequence style (x,y,x,y,x,y...)
    if (!(x_obj=PySequence_GetItem(coordseq_obj,index*2)) ||
	!(y_obj=PySequence_GetItem(coordseq_obj,index*2+1)))
      goto error; // propagate error
  } else if (PySequence_Check(item)) { // Coordinate sequence style ((x,y),(x,y),(x,y)...)
    Py_DECREF(item);    
    if (!(item=PySequence_GetItem(coordseq_obj,index)) ||
	!(x_obj=PySequence_GetItem(item,0)) ||
	!(y_obj=PySequence_GetItem(item,1)))
      goto error;
  } else
    ERROR("sequence of numbers or 2-tuples expected");
  Py_XDECREF(item); item=NULL;

  if (PyInt_Check(x_obj))
    *x=PyInt_AsLong(x_obj);
  else if (PyFloat_Check(x_obj))
    *x=(int)PyFloat_AsDouble(x_obj);
  else 
    ERROR("X coordinate non-numeric");
  if (PyInt_Check(y_obj))
    *y=PyInt_AsLong(y_obj);
  else if (PyFloat_Check(y_obj))
    *y=(int)PyFloat_AsDouble(y_obj);
  else 
    ERROR("Y coordinate non-numeric");
  Py_XDECREF(x_obj);
  Py_XDECREF(y_obj);
  return 1;

error:
  Py_XDECREF(x_obj);
  Py_XDECREF(y_obj);
  Py_XDECREF(item);
  return NULL;
#undef ERROR
}


#define IS_OBJECT(obj,name) ((obj)->ob_type==(name##_type))

static CFbsBitmap *
Bitmap_AsFbsBitmap(PyObject *obj)
{
  PyObject *capi_object=PyCAPI_GetCAPI(obj,"_bitmapapi");
  if (!capi_object)
    return NULL;
  CFbsBitmap *bitmap=(CFbsBitmap *)PyCObject_AsVoidPtr(capi_object);
  Py_DECREF(capi_object);
  return bitmap;
}

static int 
Bitmap_Check(PyObject *obj)
{
  return Bitmap_AsFbsBitmap(obj)?1:0;
}

#define PANIC(label) User::Panic(_L(label),__LINE__)
#define DEBUG_ASSERT(expr) __ASSERT_DEBUG((expr), User::Panic(_L(#expr), __LINE__))

static void
CloseFbsSession(void)
{
  RFbsSession::Disconnect();
}

static void
EnsureFbsSessionIsOpen(void)
{
  if (!RFbsSession::GetSession()) {
    RFbsSession::Connect();
    PyThread_AtExit(CloseFbsSession);
  }
}

#define Image_type ((PyTypeObject*)SPyGetGlobalString("ImageType"))
struct ImageObject : public CActive {
  enum ImageState {
#ifdef ICL_SUPPORT
    EPendingLoad, 
    EPendingSave, 
    EPendingScale, 
    EPendingRotate, 
#endif 
    ENormalIdle, 
    EInvalid
  } iState;
  enum ImageFormat {EJpeg,EPng};

  ImageObject():
    CActive(EPriorityStandard),
    iState(EInvalid)
  {
    CActiveScheduler::Add(this);
  }
  
  void ConstructL(CFbsBitmap *aBitmap) {
    EnsureFbsSessionIsOpen();        
    iBitmap=aBitmap;
    iState=ENormalIdle;
  }

  void ConstructL(int xsize, int ysize, int mode)
  {
    EnsureFbsSessionIsOpen();    
    iBitmap=new CFbsBitmap();
    TSize sz(xsize,ysize);
    iBitmap->Create(sz,(enum TDisplayMode) mode);
    //   iBitmapDevice=CFbsBitmapDevice::NewL(iBitmap);        
    iState=ENormalIdle;
  }
#ifdef ICL_SUPPORT
  void ConstructL(TDesC& filename)
  {   
    EnsureFbsSessionIsOpen();
    iDecoder=CImageDecoder::FileNewL(FsSession(),filename);    
    const TFrameInfo *frmInfo=&iDecoder->FrameInfo();        
    iBitmap=new (ELeave) CFbsBitmap();    
    User::LeaveIfError(iBitmap->Create(frmInfo->iFrameCoordsInPixels.Size(),EColor64K));
    //iBitmapDevice=CFbsBitmapDevice::NewL(iBitmap);    
    iDecoder->Convert(&iStatus, *iBitmap);    
    iState=EPendingLoad;
    SetActive();    
  }

  int StartLoadL(TDesC& aFilename) {
    EnsureFbsSessionIsOpen();
    DEBUG_ASSERT(iState == ENormalIdle);
    iDecoder=CImageDecoder::FileNewL(FsSession(),aFilename);
    const TFrameInfo *frmInfo=&iDecoder->FrameInfo();        
    if (frmInfo->iFrameCoordsInPixels != iBitmap->SizeInPixels()) {
      delete iDecoder;
      return 0;
    }
    iDecoder->Convert(&iStatus, *iBitmap);    
    iState=EPendingLoad;
    SetActive();    
    return 1;
  }

  static void InspectFileL(TDesC& aFilename, int &aWidth, int &aHeight, int &aMode) {
    EnsureFbsSessionIsOpen();
    //RFs *rfs=&graphics_GetRFs();
    RFs rfs;
    rfs.Connect();
    CImageDecoder *decoder=
      CImageDecoder::FileNewL(rfs,aFilename);    
    const TFrameInfo *frmInfo=&decoder->FrameInfo();        
    aWidth=frmInfo->iFrameCoordsInPixels.Size().iWidth;
    aHeight=frmInfo->iFrameCoordsInPixels.Size().iHeight;
    aMode=frmInfo->iFrameDisplayMode;
    delete decoder;
    rfs.Close();
  }  
#endif // ICL_SUPPORT
  ~ImageObject() {
    Cancel();
    //delete iBitmapDevice;
    delete iBitmap;
    Py_XDECREF(iCompletionCallback); 
    iCompletionCallback=NULL;
#ifdef ICL_SUPPORT
    delete iFrameImageData;
    delete iEncoder;
    delete iDecoder;
    delete iScaler;
    delete iRotator;
    if (iFsSession) {
      iFsSession->Close();
      delete iFsSession; iFsSession=NULL;
    }    
#endif // ICL_SUPPORT
  }  
  
  TSize Size() {
    return iBitmap->SizeInPixels();
  }  
  
  TSize TwipSize() {
    return iBitmap->SizeInTwips();
  }
  
  void SetTwipSize(TInt aWidth, TInt aHeight) {
    TSize sizeInTwip(aWidth, aHeight);
    iBitmap->SetSizeInTwips(sizeInTwip);
  }

  TDisplayMode DisplayMode() {
    return iBitmap->DisplayMode();
  }  

#ifdef ICL_SUPPORT
  void StartSaveL(const TDesC& aFilename, ImageFormat aFormat, 
		  int aQuality, 
		  TPngEncodeData::TPngCompressLevel aCompressionLevel, int aBpp, int aColor) {
    DEBUG_ASSERT(iState == ENormalIdle);
    EnsureFbsSessionIsOpen();
    switch (aFormat) {
    case EJpeg: {
      // For some reason iFsSession causes a KERN-EXEC 0 panic here. I have no idea why.
      iEncoder = CImageEncoder::FileNewL(FsSession(), aFilename, 
					 CImageEncoder::EOptionNone, KImageTypeJPGUid);
      TJpegImageData *imageData=new (ELeave) TJpegImageData;
      CleanupStack::PushL(imageData);
      imageData->iSampleScheme=TJpegImageData::EColor444;
      imageData->iQualityFactor=aQuality;
      iFrameImageData=CFrameImageData::NewL();
      iFrameImageData->AppendImageData(imageData); // assumes ownership of imageData
      CleanupStack::Pop(imageData);
      break;
    }
    case EPng: {
      // For some reason iFsSession causes a KERN-EXEC 0 panic here. I have no idea why.
      iEncoder = CImageEncoder::FileNewL(FsSession(), aFilename, 
					 CImageEncoder::EOptionNone, KImageTypePNGUid);
      TPngEncodeData *frameData=new (ELeave) TPngEncodeData;
      CleanupStack::PushL(frameData);
      frameData->iLevel=aCompressionLevel;
      frameData->iBitsPerPixel=aBpp;
      frameData->iColor=aColor;
      frameData->iPaletted=EFalse;
      iFrameImageData=CFrameImageData::NewL();
      iFrameImageData->AppendFrameData(frameData); // assumes ownership of frameData
      CleanupStack::Pop(frameData);
      break;
    }
    default:
      PANIC("ImageObject");
    }
    iEncoder->Convert(&iStatus, *iBitmap, iFrameImageData);
    iState=EPendingSave;
    SetActive();
  }
  
  void StartScaleL(CFbsBitmap *aTargetBitmap,int aMaintainAspectRatio=EFalse) {
    DEBUG_ASSERT(iState == ENormalIdle);
    EnsureFbsSessionIsOpen();
    iScaler = CBitmapScaler::NewL();
    iScaler->Scale(&iStatus, *iBitmap, *aTargetBitmap, aMaintainAspectRatio); 
    iState=EPendingScale;
    SetActive();
  }  

  void StartRotateL(CFbsBitmap *aTargetBitmap, CBitmapRotator::TRotationAngle aDirection) {
    DEBUG_ASSERT(iState == ENormalIdle);
    EnsureFbsSessionIsOpen();
    iRotator = CBitmapRotator::NewL();
    iRotator->Rotate(&iStatus, *iBitmap, *aTargetBitmap, aDirection);
    iState=EPendingRotate;
    SetActive();
  }  
#endif // ICL_SUPPORT
  
  void RunL() {
    // Note: Even if save, rotation or scale fails, the original
    // bitmap should still be intact, so we are safe to switch back to
    // ENormalIdle state.
    switch (iState) {
#ifdef ICL_SUPPORT
    case EPendingLoad:
      delete iDecoder; iDecoder=NULL;      
      iState=ENormalIdle;
      break;
    case EPendingSave:
      delete iEncoder; iEncoder=NULL;
      delete iFrameImageData; iFrameImageData=NULL;
      iState=ENormalIdle; 
      break;
    case EPendingScale:
      delete iScaler; iScaler=NULL;
      iState=ENormalIdle; 
      
      break;
    case EPendingRotate:
      delete iRotator; iRotator=NULL;
      iState=ENormalIdle;       
      break;
#endif // ICL_SUPPORT
    default:
      PANIC("ImageObject");
    }
    PyEval_RestoreThread(PYTHON_TLS->thread_state);
    InvokeCompletionCallback();
    PyEval_SaveThread();
  }
  
  /* Stop the current operation, if any. If a completion callback has
     been set, DECREF it. */
  void Stop() {
    Cancel(); // DoCancel sets the proper state.
    // Note that this can indirectly cause this object to be destroyed!
    Py_XDECREF(iCompletionCallback);
    iCompletionCallback=NULL;
  }
  void DoCancel() {
    switch(iState) {
    case ENormalIdle:

⌨️ 快捷键说明

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