extern "C" void gxpport_render_immutableimage
(gxpport_image_native_handle immutableImagePtr,
 gxpport_mutableimage_native_handle dstMutableImagePtr,
 const jshort *clip,
 jint x_dest, jint y_dest) {

    _Platform_ImmutableImage* immutableImage = 
        (_Platform_ImmutableImage*)immutableImagePtr;
    QPixmap *qpixmapDst =
      gxpportqt_get_mutableimage_pixmap(dstMutableImagePtr);

    if (NULL == immutableImage || immutableImage->qimage->isNull()) {
        /* not a valid image should not happen, log this */
        return;
    }

    MScreen * mscreen = qteapp_get_mscreen();
    QPainter *gc = mscreen->setupGC(-1, -1, clip, 
                                    (QPaintDevice *)qpixmapDst, 
                                    0);
    if (immutableImage->qimage->hasAlphaBuffer()) {
        gc->drawImage(x_dest, y_dest, *immutableImage->qimage);
        return;
    }

    gc->drawPixmap(x_dest, y_dest,
        *(gxpportqt_get_immutableimage_pixmap(immutableImagePtr)));
}
/**
 * Sets the content buffer. All paints are done to that buffer.
 * When paint is processed snapshot of the buffer is flushed to
 * the native resource content area.
 * 
 * @param ciPtr pointer to the custom item's MidpItem structure.
 * @param imgPtr pointer to the native resource corresponding
 *        to the Java offcreen buffer for CustomItem content
 */
extern "C" MidpError
lfpport_customitem_set_content_buffer(MidpItem* ciPtr, unsigned char* imgPtr) {
  REPORT_INFO1(LC_HIGHUI, "[lfpport_qte_customitem.cpp:%d] "
	       "lfpport_customitem_SetContentBuffer", __LINE__);
  
  ((CustomItem *)ciPtr->widgetPtr)->
    setContentBuffer(gxpportqt_get_mutableimage_pixmap(imgPtr));

  return KNI_OK;
}
extern "C" void gxpport_createimmutable_from_mutable
(gxpport_mutableimage_native_handle srcMutableImagePtr,
 gxpport_image_native_handle *newImmutableImagePtr,
 gxutl_native_image_error_codes* creationErrorPtr) {

    /* Convert from source QPixmap to destination QImage */
    QPixmap* srcPixmap = gxpportqt_get_mutableimage_pixmap(srcMutableImagePtr);

    int rscSize = ImgRscSize(srcPixmap); /* new img is the same size */

    /* Check resource limit before copying */
    if (midpCheckResourceLimit(RSC_TYPE_IMAGE_IMMUT, rscSize) == 0) {
        /* Exceeds resource limit */
        *creationErrorPtr  = GXUTL_NATIVE_IMAGE_RESOURCE_LIMIT;
        return;
    }

    _Platform_ImmutableImage* immutableImage =
        (_Platform_ImmutableImage*)midpMalloc(sizeof(_Platform_ImmutableImage));
    if (immutableImage == NULL) {
        *creationErrorPtr = GXUTL_NATIVE_IMAGE_OUT_OF_MEMORY_ERROR;
        return;
    }

    immutableImage->qimage = new QImage(srcPixmap->convertToImage());
    if (NULL == immutableImage->qimage) {
	midpFree(immutableImage);
        *creationErrorPtr = GXUTL_NATIVE_IMAGE_OUT_OF_MEMORY_ERROR;
        return;
    }

    if (immutableImage->qimage->isNull()) {
        delete immutableImage->qimage;
	midpFree(immutableImage);
        *creationErrorPtr = GXUTL_NATIVE_IMAGE_OUT_OF_MEMORY_ERROR;
        return;    
    }

    /* Copying succeeds */
    if (midpIncResourceCount(RSC_TYPE_IMAGE_IMMUT, rscSize) == 0) {
        REPORT_ERROR(LC_LOWUI, "Error in updating resource limit"
                     " for Immutable image");
    }

    immutableImage->marker = 1;
    immutableImage->qpixmap = NULL;

    *newImmutableImagePtr = immutableImage;
    *creationErrorPtr = GXUTL_NATIVE_IMAGE_NO_ERROR;
}
/**
 * Draw the first n characters in charArray, with the anchor point of the
 * entire (sub)string located at x, y.
 */
extern "C" void
gxpport_draw_chars(
  jint pixel, const jshort *clip, 
  gxpport_mutableimage_native_handle dst,
  int dotted,
  int face, int style, int size,
  int x, int y, int anchor, 
  const jchar *charArray, int n) {
    QPixmap* qpixmap = gxpportqt_get_mutableimage_pixmap(dst);
    QString s(make_string(charArray, n));

    REPORT_INFO4(LC_LOWUI, "gxpport_draw_chars(%d, %d, %x, [chars...], %d)", 
		 x, y, anchor, n); 

    find_font(face, style, size);

    switch (anchor & (LEFT | RIGHT | HCENTER)) {
    case LEFT:
        break;

    case RIGHT:
        x -= qfontInfo->width(s);
        break;

    case HCENTER:
        x -= (qfontInfo->width(s) >> 1);
        break;
    }

    switch (anchor & (TOP | BOTTOM | BASELINE)) {
    case BOTTOM:
      /* 1 pixel has to be added to account for baseline in Qt */
        y -= qfontInfo->descent()+1;

    case BASELINE:
        break;

    case TOP:
    default:
        y += qfontInfo->ascent();
        break;
    }

    MScreen * mscreen = qteapp_get_mscreen();
    QPainter *gc = mscreen->setupGC(pixel, -1, clip, (QPaintDevice*)qpixmap, 
				    dotted);
    gc->setFont(find_font(face, style, size));
    gc->drawText(x, y, s, n);
}
extern "C" void gxpport_render_immutableregion
(gxpport_image_native_handle immutableImagePtr,
 gxpport_mutableimage_native_handle dstMutableImagePtr,
 const jshort *clip,
 jint x_dest, jint y_dest, 
 jint width, jint height,
 jint x_src, jint y_src,
 jint transform) {

    _Platform_ImmutableImage* immutableImage = 
        (_Platform_ImmutableImage*)immutableImagePtr;
    QPixmap *qpixmapDst =
    gxpportqt_get_mutableimage_pixmap(dstMutableImagePtr);

    if (NULL == immutableImagePtr || immutableImage->qimage->isNull()) {
      /* not a valid image should not happen, log this */
        return;
    }

    MScreen * mscreen = qteapp_get_mscreen();
    QPainter *gc = mscreen->setupGC(-1, -1, clip, 
                                    (QPaintDevice *)qpixmapDst, 
                                    0);
    if (0 == transform) {
        gc->drawImage(x_dest, y_dest,
                      *immutableImage->qimage,
                      x_src, y_src,
                      width, height,
                      0);
        return;
    }

    QImage image = immutableImage->qimage->copy(x_src, y_src, 
                                               width, height);

    transform_image(&image, transform);
    
    if (!image.isNull()) {
        gc->drawImage(x_dest, y_dest, image);
    }
}
/**
 * Helper function.
 * Retrieve buffer for the specified graphics.
 *
 * @param graphicshandle   A KNI handle to a graphics object.
 * @return QPixmap that represents the graphics buffer.
 */
static QPixmap* getGraphicsBuffer(jobject graphicsHandle) {
    QPixmap* pixmap;
    java_image* image;

    image = GXAPI_GET_GRAPHICS_PTR(graphicsHandle)->img;
    if (image != NULL) {
        /*
         * If the graphics context has a parent image bound to it,
         * pick up the pixmap.
         */
        pixmap = gxpportqt_get_mutableimage_pixmap(
            (gxpport_mutableimage_native_handle)
                (image->imageData->nativeImageData));

    } else {
        /* If no image is bound, render to back buffer */
        pixmap = qteapp_get_mscreen()->getBackBuffer();
    }

    return pixmap;
}
extern "C" void gxpport_createimmutable_from_mutableregion
(gxpport_mutableimage_native_handle srcMutableImagePtr,
 int src_x, int src_y, 
 int src_width, int src_height,
 int transform,
 gxpport_image_native_handle* newImmutableImagePtr,
 gxutl_native_image_error_codes* creationErrorPtr) {

    QPixmap *srcqpixmap =
    gxpportqt_get_mutableimage_pixmap(srcMutableImagePtr);

    int rscSize = ImgRegionRscSize(srcqpixmap, src_width, src_height);

    /* Check resource limit */
    if (midpCheckResourceLimit(RSC_TYPE_IMAGE_IMMUT, rscSize) == 0) {
        /* Exceed Resource limit */
        *creationErrorPtr = GXUTL_NATIVE_IMAGE_RESOURCE_LIMIT;
        return;
    }

    QImage srcQImage = srcqpixmap->convertToImage();
    if (srcQImage.isNull()) {
        *creationErrorPtr = GXUTL_NATIVE_IMAGE_OUT_OF_MEMORY_ERROR;
        return;
    }

    _Platform_ImmutableImage* immutableImage = 
      (_Platform_ImmutableImage*)midpMalloc(sizeof(_Platform_ImmutableImage));
    if (immutableImage == NULL) {
	*creationErrorPtr = GXUTL_NATIVE_IMAGE_OUT_OF_MEMORY_ERROR;
	return;
    }

    immutableImage->qimage = new QImage(srcQImage.copy(src_x,
                                                       src_y, 
                                                       src_width, 
                                                       src_height));
    if (NULL == immutableImage->qimage) {
	midpFree(immutableImage);
        *creationErrorPtr = GXUTL_NATIVE_IMAGE_OUT_OF_MEMORY_ERROR;
        return;
    }

    if (immutableImage->qimage->isNull()) {
        delete immutableImage->qimage;
	midpFree(immutableImage);
        *creationErrorPtr = GXUTL_NATIVE_IMAGE_OUT_OF_MEMORY_ERROR;
        return;
    }

    if (transform != 0) {
        transform_image(immutableImage->qimage, transform);
    }

    /* Copy succeeds */
    if (midpIncResourceCount(RSC_TYPE_IMAGE_IMMUT, rscSize) == 0) {
        REPORT_ERROR(LC_LOWUI, "Error in updating resource limit"
                     " for Immutable image");
    }

    immutableImage->marker = 3;
    immutableImage->qpixmap = NULL;
    
    *newImmutableImagePtr = immutableImage;
    *creationErrorPtr = GXUTL_NATIVE_IMAGE_NO_ERROR;
}