From 4d065d3fc6364127d78faef549e915acc53e3fb4 Mon Sep 17 00:00:00 2001
From: Vladimir Ananiev <vovan888 at gmail com>
Date: Sat, 22 Dec 2007 23:54:12 +0300
Subject: [PATCH 7/7] [neuros] add GrDrawImagePartToFit function

Signed-off-by: Vladimir Ananiev <vovan888 at gmail com>
---
 src/engine/devimage.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/include/device.h  |    2 +
 src/include/nano-X.h  |    3 ++
 src/nanox/client.c    |   44 ++++++++++++++++++++++++++++
 src/nanox/nxproto.h   |   20 ++++++++++++-
 src/nanox/srvfunc.c   |   21 +++++++++++++
 src/nanox/srvnet.c    |   12 ++++++++
 7 files changed, 177 insertions(+), 1 deletions(-)

diff --git a/src/engine/devimage.c b/src/engine/devimage.c
index 2c1a55d..0950670 100644
--- a/src/engine/devimage.c
+++ b/src/engine/devimage.c
@@ -415,6 +415,82 @@ GdDrawImageToFit(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width, MWCOORD height,
 }
 
 /**
+ * Draw part of the image.
+ *
+ * @param psd Drawing surface.
+ * @param x X destination co-ordinate.
+ * @param y Y destination co-ordinate.
+ * @param width If >=0, the image will be scaled to this width.
+ * If <0, the image will not be scaled horiziontally.
+ * @param height If >=0, the image will be scaled to this height.
+ * If <0, the image will not be scaled vertically.
+ * @param sx source X co-ordinate.
+ * @param sy source Y co-ordinate.
+ * @param swidth source width.
+ * @param sheight source height.
+ * @param id Image to draw.
+ */
+void
+GdDrawImagePartToFit(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width, MWCOORD height,
+								MWCOORD sx, MWCOORD sy, MWCOORD swidth, MWCOORD sheight,
+	int id)
+{
+	PIMAGEITEM	pItem;
+	PMWIMAGEHDR	pimage;
+
+	pItem = findimage(id);
+	if (!pItem)
+		return;
+	pimage = pItem->pimage;
+
+	/*
+	 * Display image, possibly stretch/shrink to resize
+	 */
+	if (height < 0)
+		height = pimage->height;
+	if (width < 0)
+		width = pimage->width;
+
+	if (height != pimage->height || width != pimage->width) {
+		MWCLIPRECT	rcDst,rcSrc;
+		MWIMAGEHDR	image2;
+
+		/* create similar image, different width/height*/
+
+		image2.width = width;
+		image2.height = height;
+		image2.planes = pimage->planes;
+		image2.bpp = pimage->bpp;
+		GdComputeImagePitch(pimage->bpp, width, &image2.pitch,
+			&image2.bytesperpixel);
+		image2.compression = pimage->compression;
+		image2.palsize = pimage->palsize;
+		image2.palette = pimage->palette;	/* already allocated*/
+		image2.transcolor = pimage->transcolor;
+		if( (image2.imagebits = malloc(image2.pitch*height)) == NULL) {
+			EPRINTF("GdDrawImageToFit: no memory\n");
+			return;
+		}
+
+		rcDst.x = 0;
+		rcDst.y = 0;
+		rcDst.width = width;
+		rcDst.height = height;
+
+		rcSrc.x = sx;
+		rcSrc.y = sy;
+		rcSrc.width = swidth;
+		rcSrc.height = sheight;
+
+		/* Stretch full source to destination rectangle*/
+		GdStretchImage(pimage, &rcSrc, &image2, &rcDst);
+		GdDrawImage(psd, x, y, &image2);
+		free(image2.imagebits);
+	} else
+		GdDrawImage(psd, x, y, pimage);
+}
+
+/**
  * Destroy an image.
  *
  * @param id Image to free.
diff --git a/src/include/device.h b/src/include/device.h
index 180a609..4b2a81a 100644
--- a/src/include/device.h
+++ b/src/include/device.h
@@ -920,6 +920,8 @@ void	GdFreeImage(int id);
 MWBOOL	GdGetImageInfo(int id, PMWIMAGEINFO pii);
 void	GdStretchImage(PMWIMAGEHDR src, MWCLIPRECT *srcrect, PMWIMAGEHDR dst,
 		MWCLIPRECT *dstrect);
+void	GdDrawImagePartToFit(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width, MWCOORD height,
+		MWCOORD sx, MWCOORD sy, MWCOORD swidth, MWCOORD sheight, int id);
 void	GdComputeImagePitch(int bpp, int width, int *pitch, int *bytesperpixel);
 
 /* Buffered input functions to replace stdio functions*/
diff --git a/src/include/nano-X.h b/src/include/nano-X.h
index 723ca83..6ff3bf6 100644
--- a/src/include/nano-X.h
+++ b/src/include/nano-X.h
@@ -862,6 +862,9 @@ GR_IMAGE_ID	GrLoadImageFromBuffer(void *buffer, int size, int flags);
 void		GrDrawImageToFit(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x,
 			GR_COORD y, GR_SIZE width, GR_SIZE height,
 			GR_IMAGE_ID imageid);
+void		GrDrawImagePartToFit(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD dx, GR_COORD dy,
+			GR_SIZE dwidth, GR_SIZE dheight, GR_COORD sx, GR_COORD sy,
+			GR_SIZE swidth, GR_SIZE sheight, GR_IMAGE_ID imageid);
 void		GrFreeImage(GR_IMAGE_ID id);
 void		GrGetImageInfo(GR_IMAGE_ID id, GR_IMAGE_INFO *iip);
 void		GrText(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
diff --git a/src/nanox/client.c b/src/nanox/client.c
index 90d97a7..316d079 100644
--- a/src/nanox/client.c
+++ b/src/nanox/client.c
@@ -3203,6 +3203,50 @@ GrDrawImageToFit(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
 	req->imageid = imageid;
 	UNLOCK(&nxGlobalLock);
 }
+
+/**
+ * Draws specified part of the image from the specified image buffer at the specified position
+ * on the specified drawable using the specified graphics context. The
+ * width and height values specify the size of the image to draw- if the
+ * actual image is a different size, it will be scaled to fit.
+ *
+ * @param id  the ID of the drawable to draw the image onto
+ * @param gc  the ID of the graphics context to use when drawing the image
+ * @param x  the X coordinate to draw the image at relative to the drawable
+ * @param y  the Y coordinate to draw the image at relative to the drawable
+ * @param width  the maximum image width
+ * @param height  the maximum image height
+ * @param sx  the X coordinate at the source pixmap to draw from
+ * @param sy  the Y coordinate at the source pixmap to draw from
+ * @param swidth  the maximum source image width
+ * @param sheight  the maximum source image height
+ * @param imageid  the ID of the image buffer containing the image to display
+ *
+ * @ingroup nanox_image
+ */ 
+void
+GrDrawImagePartToFit(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD dx, GR_COORD dy,
+	GR_SIZE dwidth, GR_SIZE dheight, GR_COORD sx, GR_COORD sy,
+	GR_SIZE swidth, GR_SIZE sheight, GR_IMAGE_ID imageid)
+{
+	nxDrawImagePartToFitReq *req;
+	LOCK(&nxGlobalLock);
+	req = AllocReq(DrawImagePartToFit);
+	req->drawid = id;
+	req->gcid = gc;
+	req->dx = dx;
+	req->dy = dy;
+	req->dwidth = dwidth;
+	req->dheight = dheight;
+	req->sx = sx;
+	req->sy = sy;
+	req->swidth = swidth;
+	req->sheight = sheight;
+	req->imageid = imageid;
+	UNLOCK(&nxGlobalLock);
+
+}
+
 #endif /* MW_FEATURE_IMAGES */
 
 #if MW_FEATURE_IMAGES
diff --git a/src/nanox/nxproto.h b/src/nanox/nxproto.h
index b394e5b..cc46baf 100644
--- a/src/nanox/nxproto.h
+++ b/src/nanox/nxproto.h
@@ -1366,4 +1366,22 @@ typedef struct {
 	INT16 height;
 } nxCopyFontReq;
 
-#define GrTotalNumCalls         125
+#define GrNumDrawImagePartToFit     125
+typedef struct {
+	BYTE8	reqType;
+	BYTE8	hilength;
+	UINT16	length;
+	IDTYPE	drawid;
+	IDTYPE	gcid;
+	INT16	dx;
+	INT16	dy;
+	INT16	dwidth;
+	INT16	dheight;
+	INT16   sx;
+	INT16   sy;
+	INT16   swidth;
+	INT16   sheight;
+	IDTYPE	imageid;
+} nxDrawImagePartToFitReq;
+
+#define GrTotalNumCalls         126
diff --git a/src/nanox/srvfunc.c b/src/nanox/srvfunc.c
index 60a0710..d909819 100644
--- a/src/nanox/srvfunc.c
+++ b/src/nanox/srvfunc.c
@@ -2970,6 +2970,27 @@ GrDrawImageToFit(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
 	SERVER_UNLOCK();
 }
 
+/* draw part of the cached image*/
+void
+GrDrawImagePartToFit(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD dx, GR_COORD dy,
+	GR_SIZE dwidth, GR_SIZE dheight, GR_COORD sx, GR_COORD sy,
+	GR_SIZE swidth, GR_SIZE sheight, GR_IMAGE_ID imageid)
+{
+	GR_DRAWABLE	*dp;
+	SERVER_LOCK();
+
+	switch (GsPrepareDrawing(id, gc, &dp)) {
+		case GR_DRAW_TYPE_WINDOW:
+ 	        case GR_DRAW_TYPE_PIXMAP:
+			GdDrawImagePartToFit(dp->psd, dp->x + dx, dp->y + dy,
+				dwidth, dheight,sx,sy,swidth,sheight, imageid);
+			break;
+	   
+	}
+
+	SERVER_UNLOCK();
+}
+
 /* free cached image*/
 void
 GrFreeImage(GR_IMAGE_ID id)
diff --git a/src/nanox/srvnet.c b/src/nanox/srvnet.c
index dafc776..3afb1fc 100644
--- a/src/nanox/srvnet.c
+++ b/src/nanox/srvnet.c
@@ -1104,6 +1104,16 @@ GrDrawImageToFitWrapper(void *r)
 }
 
 static void
+GrDrawImagePartToFitWrapper(void *r)
+{
+	nxDrawImagePartToFitReq *req = r;
+
+	GrDrawImagePartToFit(req->drawid, req->gcid, req->dx, req->dy, req->dwidth,
+		req->dheight,req->sx, req->sy, req->swidth,
+		req->sheight, req->imageid);
+}
+
+static void
 GrFreeImageWrapper(void *r)
 {
 	nxFreeImageReq *req = r;
@@ -1123,6 +1133,7 @@ GrGetImageInfoWrapper(void *r)
 }
 #else /* if ! MW_FEATURE_IMAGES */
 #define GrDrawImageToFitWrapper GrNotImplementedWrapper
+#define GrDrawImagePartToFitWrapper GrNotImplementedWrapper
 #define GrFreeImageWrapper GrNotImplementedWrapper
 #define GrGetImageInfoWrapper GrNotImplementedWrapper
 #endif
@@ -1729,6 +1740,7 @@ static const struct GrFunction GrFunctions[] = {
 	/* 122 */ {GrSetTransformWrapper, "GrSetTransform" },
 	/* 123 */ {GrCreateFontFromBufferWrapper, "GrCreateFontFromBuffer"},
 	/* 124 */ {GrCopyFontWrapper, "GrCopyFont"},
+	/* 125 */ {GrDrawImagePartToFitWrapper, "GrDrawImagePartToFit"},
 };
 
 void
-- 
1.5.1.6

