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

📄 graphicsmodule.cpp

📁 python s60 1.4.5版本的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
      Py_INCREF(self);      
      return ret;
    } else 
      return NULL;
  } else {
    SPyErr_SetFromSymbianOSErr(error);
    return NULL;
  }
}

static void _Image__bitmapapi_dealloc(void *gc, void *a2)
{
  Py_DECREF((PyObject *)a2);
}

extern "C" PyObject*
Image__bitmapapi(Image_object *self, PyObject * /*args*/)
{
  Py_INCREF(self);
  return PyCObject_FromVoidPtrAndDesc(self->data->GetBitmap(), self,_Image__bitmapapi_dealloc);
}

/*
static void _graphics_rawscreen_dealloc(void *gc_)
{
  CBitmapContext *gc=STATIC_CAST(CBitmapContext *,gc_);
  CFbsScreenDevice *device=STATIC_CAST(CFbsScreenDevice *,gc->Device());  
  delete gc;
  delete device;
}

extern "C" PyObject*
graphics_rawscreen(PyObject *args)
{
  CFbsScreenDevice *dev;
  dev=CFbsScreenDevice::NewL(TPtr(NULL,0),EColor64K);
  //RHardwareBitmap hwbm=dev->HardwareBitmap();
  //CBitmapDevice *dev=CCoeEnv::Static()->ScreenDevice();
  CGraphicsContext *gc;
  dev->CreateContext(gc);  
  gc->CancelClippingRect();
  return PyCObject_FromVoidPtr(STATIC_CAST(CBitmapContext *,gc), _graphics_rawscreen_dealloc);
}
*/

/* LRU cache that maps Python level font specification objects to CFont objects. */
#ifdef EKA2
NONSHARABLE_CLASS(CPyFontCache) : public CBase {
#else
    class CPyFontCache : public CBase {
#endif  
    
public:
    CPyFontCache(CBitmapDevice *aDevice):iDevice(aDevice) {}
    ~CPyFontCache();
    int CFont_from_python_fontspec(PyObject *aArg, CFont *&aFont);
private:
    /* This seems like a reasonable balance. 
     * It's probably rare for applications to constantly need more than 8 fonts. */
    #define FONTCACHE_SIZE 8

    struct TPyFontCacheEntry {
        PyObject *pyfontspec;
        CFont *cfont;        
        int last_access;
    } iEntries[FONTCACHE_SIZE];
    CBitmapDevice *iDevice;
    int iTime;
};

CPyFontCache::~CPyFontCache(void) 
{
    for (int i=0; i<FONTCACHE_SIZE; i++) {
               Py_XDECREF(iEntries[i].pyfontspec);        
        if (iEntries[i].cfont) 
            iDevice->ReleaseFont(iEntries[i].cfont);            
    }
}

int 
CPyFontCache::CFont_from_python_fontspec(PyObject *aArg, CFont *&aFont)
{
    int i;
    for (i=0; i<FONTCACHE_SIZE; i++) {
        if (iEntries[i].pyfontspec == aArg) {
            iEntries[i].last_access = iTime;
            aFont=iEntries[i].cfont;
            return 0;
        }
    }
    // No match found, find the oldest entry.
    int oldestentry_time=0;
    int oldestentry_index=0;
    for (i=0; i<FONTCACHE_SIZE; i++)
        /* Not doing oldestentry_time > iEntries[i].last_access since 
         * that wouldn't handle iTime wraparound correctly. 
         * At a hypothetical rate of 1000 font lookups a second 
         * we'd run into trouble already in 22 days :) */
        if ((oldestentry_time - iEntries[i].last_access) >= 0) {
            oldestentry_time=iEntries[i].last_access;
            oldestentry_index=i;
        }
    
    // Lookup the font.
    CFont *font;
    int error = ::CFont_from_python_fontspec(aArg, font, *iDevice);
    if (error != 0)
        return error;
    
    // If lookup was successful, release the old cache entry.
    TPyFontCacheEntry &oldest=iEntries[oldestentry_index];
    Py_XDECREF(oldest.pyfontspec);
    if (oldest.cfont)
        iDevice->ReleaseFont(oldest.cfont);
    
    // Place font in cache.
    iTime++;
    oldest.pyfontspec = aArg;
    Py_INCREF(aArg);
    oldest.cfont = font;
    oldest.last_access = iTime;
    
    // All done.
    aFont = font;
    return 0;
}

// ******** Draw object

#define Draw_type ((PyTypeObject*)SPyGetGlobalString("DrawType"))
struct Draw_object {
  PyObject_VAR_HEAD  
  PyObject *drawapi_cobject;
  CBitmapContext *gc;
  PyObject *font_spec_object;
  CFont *cfont;
  CPyFontCache *fontcache;
};


extern "C" PyObject *
graphics_Draw(PyObject* /*self*/, PyObject* args)
{
  PyObject *drawable=NULL;
  if (!PyArg_ParseTuple(args, "O", &drawable))
    return NULL;
  PyObject *drawapi_cobject=PyCAPI_GetCAPI(drawable,"_drawapi");
  if (!drawapi_cobject) {
    PyErr_SetString(PyExc_TypeError, 
		    "Expected a drawable object as argument");
    return NULL;
  }
  Draw_object *obj = PyObject_New(Draw_object, Draw_type);
  if (obj == NULL)
    return PyErr_NoMemory();    
  obj->gc=STATIC_CAST(CBitmapContext *,PyCObject_AsVoidPtr(drawapi_cobject));
  obj->drawapi_cobject = drawapi_cobject;
  obj->font_spec_object=NULL; 
  obj->cfont=NULL;
  obj->fontcache=new CPyFontCache(static_cast<CBitmapDevice *>(obj->gc->Device()));
  if (!obj->fontcache) 
      return PyErr_NoMemory();
  return (PyObject *)obj;
}




extern "C" PyObject*
Draw_blit(Draw_object *self, PyObject *args, PyObject *keywds)
{
  CBitmapContext *gc=self->gc;
  PyObject *image_object=NULL; 
  PyObject *source_object=NULL;
  PyObject *target_object=NULL;
  int scaling=0;
  PyObject *mask_object=NULL;
  static const char *const kwlist[] = 
    {"image", "source", "target", "scale", "mask", NULL};  
  if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|OOiO", (char**)kwlist,
                                   &image_object, 
                                   &source_object, 
                                   &target_object,
				   &scaling,
				   &mask_object)){ 
    return NULL;
  }  
  CFbsBitmap *source_bitmap=Bitmap_AsFbsBitmap(image_object);
  if (!source_bitmap) {
    PyErr_SetString(PyExc_TypeError, "Image object expected as 1st argument"); 
    return NULL;
  }
  CFbsBitmap *mask_bitmap=NULL;
  // If a mask is given, it must be a bitmap.
  if (mask_object) {
    mask_bitmap=Bitmap_AsFbsBitmap(mask_object);
    if (!mask_bitmap) {
      PyErr_SetString(PyExc_TypeError, "Mask must be an Image object");
      return NULL;
    }
#if S60_VERSION < 26
    if (mask_bitmap->DisplayMode() != EGray2) {
        PyErr_SetString(PyExc_ValueError, "Mask must be a binary (1-bit) Image. Partial transparency is not supported in S60 before 2nd edition FP2.");
        return NULL;            
    }    
#else    
    if (mask_bitmap->DisplayMode() != EGray2 && mask_bitmap->DisplayMode() != EGray256) {
        PyErr_SetString(PyExc_ValueError, "Mask must be a binary (1-bit) or grayscale (8-bit) Image");
        return NULL;
    }
#endif
  }
  
  TSize target_size=gc->Device()->SizeInPixels();
  TSize source_size=source_bitmap->SizeInPixels();
  int fx1=0,fy1=0,fx2=source_size.iWidth,fy2=source_size.iHeight;
  int tx1=0,ty1=0,tx2=target_size.iWidth,ty2=target_size.iHeight;
  int n=0;
  if (source_object) {
    if (!PyCoordSeq_Length(source_object,&n) ||
	!PyCoordSeq_GetItem(source_object,0,&fx1,&fy1) ||
	((n==2) && !PyCoordSeq_GetItem(source_object,1,&fx2,&fy2))) {
      PyErr_SetString(PyExc_TypeError, "invalid 'source' specification");
      return NULL;
    }
  }
  if (target_object) {
    if (!PyCoordSeq_Length(target_object,&n) ||
	!PyCoordSeq_GetItem(target_object,0,&tx1,&ty1) ||
	((n==2) && !PyCoordSeq_GetItem(target_object,1,&tx2,&ty2))) {
      PyErr_SetString(PyExc_TypeError, "invalid 'target' specification");
      return NULL;
    }
  }
  TRect fromRect(fx1,fy1,fx2,fy2);
  TRect toRect(tx1,ty1,tx2,ty2);
 
  if (scaling) {
    if (mask_bitmap) {
      PyErr_SetString(PyExc_ValueError, 
		      "sorry, scaling and masking is not supported at the same time.");
      return NULL;
    }
    gc->DrawBitmap(toRect,source_bitmap,fromRect);            
  } else {
    if (mask_bitmap) 
      gc->BitBltMasked(TPoint(tx1,ty1),source_bitmap,fromRect,mask_bitmap,EFalse);
    else
      gc->BitBlt(TPoint(tx1,ty1),source_bitmap,fromRect);        
  }    
  PY_RETURN_NONE;
}


/* Note: All drawing functions are allowed to change pen and brush
   color and pen size without restoring them. Other settings must be
   restored to defaults on exit. */

static int
Graphics_ParseAndSetParams(Draw_object *self, PyObject *args, PyObject *keywds, 
			   PyObject **coordseq_obj, int *n_coords, 
			   float *start=NULL, float *end=NULL)
{
  CBitmapContext *gc=self->gc;
  PyObject 
    *outline_obj=NULL, 
    *fill_obj=NULL,
    *pattern_obj=NULL;
  int pen_width=1;
  TRgb outline_color(0,0,0);
  TRgb fill_color(0,0,0);
  
  if (start && end) {
    static const char *const kwlist[] = {"coords", "start", "end", "outline", "fill", 
					 "width", "pattern", NULL};
    if (!PyArg_ParseTupleAndKeywords(args, keywds, "Off|OOiO", (char**)kwlist,
				     coordseq_obj,
				     start,
				     end,
				     &outline_obj,
				     &fill_obj,
				     &pen_width,
				     &pattern_obj) ||
	!PyCoordSeq_Length(*coordseq_obj, n_coords) ||
	(outline_obj && outline_obj != Py_None && !ColorSpec_AsRgb(outline_obj,&outline_color)) ||
	(fill_obj && fill_obj != Py_None && !ColorSpec_AsRgb(fill_obj,&fill_color)) ||
	(pattern_obj && !Bitmap_Check(pattern_obj)))
      return 0;    
  } else {
    static const char *const kwlist[] = {"coords", "outline", "fill", "width", "pattern",
					 NULL};
    if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|OOiO", (char**)kwlist,
				     coordseq_obj,
				     &outline_obj,
				     &fill_obj,
				     &pen_width,
				     &pattern_obj) ||
	!PyCoordSeq_Length(*coordseq_obj, n_coords) ||
	(outline_obj && outline_obj != Py_None && !ColorSpec_AsRgb(outline_obj,&outline_color)) ||
	(fill_obj && fill_obj != Py_None && !ColorSpec_AsRgb(fill_obj,&fill_color)) ||
	(pattern_obj && !Bitmap_Check(pattern_obj)))
      return 0;    
  }

  if (outline_obj == Py_None)
    outline_obj=NULL;
  if (fill_obj == Py_None)
    fill_obj=NULL;

  gc->SetPenColor(outline_color);
  gc->SetPenSize(TSize(pen_width,pen_width));  
  gc->SetPenStyle(outline_obj ? CGraphicsContext::ESolidPen   : CGraphicsContext::ENullPen);
  gc->SetBrushColor(fill_color);
  if (pattern_obj) {
    gc->UseBrushPattern(Bitmap_AsFbsBitmap(pattern_obj));
    gc->SetBrushStyle(CGraphicsContext::EPatternedBrush);
  } else {
    gc->SetBrushStyle(fill_obj ? CGraphicsContext::ESolidBrush : CGraphicsContext::ENullBrush);  
  }
  return 1;
}

static void
Graphics_ResetParams(Draw_object *self)
{
  CBitmapContext *gc=self->gc;
  gc->SetPenStyle(CGraphicsContext::ESolidPen);
  gc->SetBrushStyle(CGraphicsContext::ENullBrush);
  // Should we gc->DiscardBrushPattern() here?
}

extern "C" PyObject*
Draw_rectangle(Draw_object *self, PyObject *args, PyObject *keywds)
{
  /*
  {
    CBitmapContext *gc=self->gc;
    PyObject 
      *outline_obj=NULL, 
      *fill_obj=NULL,
      *pattern_obj=NULL;
    int i;
    int pen_width=1;
    TRgb outline_color(0,0,0);
    TRgb fill_color(0,0,0);
    
    static const char *const kwlist[] = {"coords", "outline", "fill", "width", "pattern",
					 NULL};
    PyObject *coordseq_obj=NULL;
    int n_coords=0;
    PyArg_ParseTupleAndKeywords(args, keywds, "O|OOiO", (char**)kwlist,
				&coordseq_obj,
				&outline_obj,
				&fill_obj,
				&pen_width,
				&pattern_obj);
  }
  */
  /*
  CBitmapContext *gc=self->gc;
  PyObject 
    *outline_obj=NULL, 
    *fill_obj=NULL,
    *pattern_obj=NULL;
  int i;
  int pen_width=1;
  TRgb outline_color(0,0,0);
  TRgb fill_color(0,0,0);
  
  static const char *const kwlist[] = {"coords", "outline", "fill", "width", "pattern",
				       NULL};
  PyObject *coordseq_obj=NULL;
  int n_coords=0;
  if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|OOiO", (char**)kwlist,
				   &coordseq_obj,
				   &outline_obj,
				   &fill_obj,
				   &pen_width,
				   &pattern_obj) ||
      !PyCoordSeq_Length(coordseq_obj, &n_coords) ||
      (outline_obj && !ColorSpec_AsRgb(outline_obj,&outline_color)) ||
      (fill_obj && !ColorSpec_AsRgb(fill_obj,&fill_color)) ||
      (pattern_obj && !Bitmap_Check(pattern_obj))) {
    return NULL;
  }

  gc->SetPenColor(outline_color);
  gc->SetPenSize(TSize(pen_width,pen_width));  
  gc->SetPenStyle(outline_obj ? CGraphicsContext::ESolidPen   : CGraphicsContext::ENullPen);
  gc->SetBrushColor(fill_color);
  gc->SetBrushStyle(fill_obj ? CGraphicsContext::ESolidBrush : CGraphicsContext::ENullBrush);  
*/  
  //PY_RETURN_NONE;

  //PY_RETURN_NONE;
  
  CBitmapContext *gc=self->gc;
  PyObject *coordseq_obj=NULL;
  int n_coords,i;
  if (!Graphics_ParseAndSetParams(self,args,keywds,&coordseq_obj,&n_coords))
    return NULL;  
  
  /*PyObject *coordseq_obj=NULL;
  int n_coords=2,i;
  if (!PyArg_ParseTuple(args,"O", &coordseq_obj)) {
    return NULL;
  }
  CBitmapContext *gc=self->gc;
  gc->SetPenColor(TRgb(0,0,0));
  gc->SetPenSize(TSize(1,1));
  gc->SetPenStyle(CGraphicsContext::ENullPen);
  gc->SetBrushColor(TRgb(255,0,0));
  gc->SetBrushStyle(CGraphicsContext::ESolidBrush);
  */
  if (n_coords % 2 != 0) {
    PyErr_SetString(PyExc_ValueError, "even number of coordinates expected");
    goto error;
  }
  for (i=0; i<n_coords/2; i++) {
    int x1,y1,x2,y2;
    if (!PyCoordSeq_GetItem(coordseq_obj,i*2,&x1,&y1)||
	!PyCoordSeq_GetItem(coordseq_obj,i*2+1,&x2,&y2))
      goto error;
    //sum += x1+y1+x2+y2;
    gc->DrawRect(TRect(x1,y1,x2,y2));
  }    
  //  if (sum == 12332)  // to defeat possible optimizer
  //  Py_INCREF(Py_None);
  Graphics_ResetParams(self);
  PY_RETURN_NONE;
 error:
  Graphics_ResetParams(self);
  return NULL;
}

extern "C" PyObject*
Draw_ellipse(Draw_object *self, PyObject *args, PyObject *keywds)
{
  CBitmapContext *gc=self->gc;
  PyObject *coordseq_obj=NULL;
  int n_coords,i;
  if (!Graphics_ParseAndSetParams(self,args,keywds,&coordseq_obj,&n_coords))
    return NULL;
  
  if (n_coords % 2 != 0) {
    PyErr_SetString(PyExc_ValueError, "even number of coordinates expected");
    goto error;
  }
  for (i=0; i<n_coords/2; i++) {
    int x1,y1,x2,y2;
    if (!PyCoordSeq_GetItem(coordseq_obj,i*2,&x1,&y1)||
	!PyCoordSeq_GetItem(coordseq_obj,i*2+1,&x2,&y2))
      goto error;
    gc->DrawEllipse(TRect(x1,y1,x2,y2));
  }    
  Graphics_ResetParams(self);
  PY_RETURN_NONE;
 error:
  Graphics_ResetParams(self);
  return NULL;
}

static TPoint
TPoint_FromAngleAndBoundingBox(TRect bbox, float angle)
{
  TInt cx=bbox.iTl.iX+((bbox.iBr.iX-bbox.iTl.iX)/2);
  TInt cy=bbox.iTl.iY+((bbox.iBr.iY-bbox.iTl.iY)/2);
  return TPoint((TInt)(cx+cos(angle)*1024), (TInt)(cy-sin(angle)*1024));
}

extern "C" PyObject*
Draw_arc(Draw_object *self, PyObject *args, PyObject *keywds)
{
  CBitmapContext *gc=self->gc;
  PyObject *coordseq_obj=NULL;
  int n_coords,i;
  float start_angle,end_angle;
  if (!Graphics_ParseAndSetParams(self,args,keywds,&coordseq_obj,&n_coords,&start_angle,&end_angle))
    return NULL;
  
  if (n_coords % 2 != 0) {
    PyErr_SetString(PyExc_ValueError, "even number of coordinates expected");
    goto error;

⌨️ 快捷键说明

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