| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #include "sys-defines.h" |
| #include "extern.h" |
| |
| #include "xmi.h" |
| #include "mi_spans.h" |
| #include "mi_api.h" |
| |
| |
| static miPixmap * miNewPixmap (unsigned int width, unsigned int height, miPixel initPixel); |
| static miPixmap * miCopyPixmap (const miPixmap *pPixmap); |
| static void miDeletePixmap (miPixmap *pPixmap); |
| #if 0 |
| static miBitmap * miNewBitmap (unsigned int width, unsigned int height, int initBit); |
| #endif |
| static miBitmap * miCopyBitmap (const miBitmap *pBitmap); |
| static void miDeleteBitmap (miBitmap *pBitmap); |
| static void miPaintCanvas (miCanvas *canvas, miPixel pixel, int n, const miPoint *ppt, const unsigned int *pwidth, miPoint offset); |
| |
| |
| |
| |
| |
| |
| |
| #ifndef MI_CANVAS_DRAWABLE_TYPE |
| |
| |
| miCanvas * |
| miNewCanvas (unsigned int width, unsigned int height, miPixel initPixel) |
| { |
| miCanvas *new_pCanvas; |
| |
| if (width < 1 || height < 1) |
| return (miCanvas *)NULL; |
| |
| new_pCanvas = (miCanvas *)mi_xmalloc (sizeof (miCanvas)); |
| new_pCanvas->drawable = miNewPixmap (width, height, initPixel); |
| |
| |
| new_pCanvas->texture = (miPixmap *)NULL; |
| new_pCanvas->stipple = (miBitmap *)NULL; |
| new_pCanvas->pixelMerge2 = (miPixelMerge2)NULL; |
| new_pCanvas->pixelMerge3 = (miPixelMerge3)NULL; |
| |
| return new_pCanvas; |
| } |
| |
| |
| miCanvas * |
| miCopyCanvas (const miCanvas *pCanvas) |
| { |
| miCanvas *new_pCanvas; |
| |
| if (pCanvas == (const miCanvas *)NULL) |
| return (miCanvas *)NULL; |
| |
| new_pCanvas = (miCanvas *)mi_xmalloc (sizeof (miCanvas)); |
| new_pCanvas->drawable = miCopyPixmap (pCanvas->drawable); |
| new_pCanvas->pixelMerge2 = pCanvas->pixelMerge2; |
| new_pCanvas->pixelMerge3 = pCanvas->pixelMerge3; |
| new_pCanvas->texture = miCopyPixmap (pCanvas->texture); |
| new_pCanvas->stipple = miCopyBitmap (pCanvas->stipple); |
| |
| return new_pCanvas; |
| } |
| |
| |
| void |
| miDeleteCanvas (miCanvas *pCanvas) |
| { |
| if (pCanvas == (miCanvas *)NULL) |
| return; |
| |
| miDeletePixmap (pCanvas->drawable); |
| miDeletePixmap (pCanvas->texture); |
| miDeleteBitmap (pCanvas->stipple); |
| free (pCanvas); |
| } |
| |
| #endif |
| |
| |
| static miPixmap * |
| miNewPixmap (unsigned int width, unsigned int height, miPixel initPixel) |
| { |
| miPixmap *new_pPixmap; |
| miPixel **pixmap; |
| int i, j; |
| |
| new_pPixmap = (miPixmap *)mi_xmalloc (sizeof(miPixmap)); |
| |
| |
| pixmap = (miPixel **)mi_xmalloc (height * sizeof(miPixel *)); |
| for (j = 0; j < (int)height; j++) |
| { |
| pixmap[j] = (miPixel *)mi_xmalloc (width * sizeof(miPixel)); |
| for (i = 0; i < (int)width; i++) |
| pixmap[j][i] = initPixel; |
| } |
| |
| new_pPixmap->pixmap = pixmap; |
| new_pPixmap->width = width; |
| new_pPixmap->height = height; |
| |
| return new_pPixmap; |
| } |
| |
| |
| static miPixmap * |
| miCopyPixmap (const miPixmap *pPixmap) |
| { |
| miPixmap *new_pPixmap; |
| miPixel **pixmap; |
| miPixel * const *old_pixmap; |
| int i, j; |
| |
| if (pPixmap == (const miPixmap *)NULL) |
| return (miPixmap *)NULL; |
| |
| new_pPixmap = (miPixmap *)mi_xmalloc (sizeof(miPixmap)); |
| |
| |
| pixmap = (miPixel **)mi_xmalloc (pPixmap->height * sizeof(miPixel *)); |
| old_pixmap = pPixmap->pixmap; |
| for (j = 0; j < (int)(pPixmap->height); j++) |
| { |
| pixmap[j] = (miPixel *)mi_xmalloc (pPixmap->width * sizeof(miPixel)); |
| for (i = 0; i < (int)(pPixmap->width); i++) |
| pixmap[j][i] = old_pixmap[j][i]; |
| } |
| |
| new_pPixmap->pixmap = pixmap; |
| new_pPixmap->width = pPixmap->width; |
| new_pPixmap->height = pPixmap->height; |
| |
| return new_pPixmap; |
| } |
| |
| |
| static void |
| miDeletePixmap (miPixmap *pPixmap) |
| { |
| int j; |
| |
| if (pPixmap == (miPixmap *)NULL) |
| return; |
| |
| |
| for (j = 0; j < (int)(pPixmap->height); j++) |
| free (pPixmap->pixmap[j]); |
| free (pPixmap->pixmap); |
| |
| free (pPixmap); |
| } |
| |
| #if 0 |
| |
| |
| static miBitmap * |
| miNewBitmap (unsigned int width, unsigned int height, int initBit) |
| { |
| miBitmap *new_pBitmap; |
| int **bitmap; |
| int i, j; |
| |
| new_pBitmap = (miBitmap *)mi_xmalloc (sizeof(miBitmap)); |
| |
| |
| bitmap = (int **)mi_xmalloc (height * sizeof(int *)); |
| for (j = 0; j < (int)height; j++) |
| { |
| bitmap[j] = (int *)mi_xmalloc (width * sizeof(int)); |
| for (i = 0; i < (int)width; i++) |
| bitmap[j][i] = initBit; |
| } |
| |
| new_pBitmap->bitmap = bitmap; |
| new_pBitmap->width = width; |
| new_pBitmap->height = height; |
| |
| return new_pBitmap; |
| } |
| #endif |
| |
| |
| static miBitmap * |
| miCopyBitmap (const miBitmap *pBitmap) |
| { |
| miBitmap *new_pBitmap; |
| int **bitmap; |
| int * const *old_bitmap; |
| int i, j; |
| |
| if (pBitmap == (const miBitmap *)NULL) |
| return (miBitmap *)NULL; |
| |
| new_pBitmap = (miBitmap *)mi_xmalloc (sizeof(miBitmap)); |
| |
| |
| bitmap = (int **)mi_xmalloc (pBitmap->height * sizeof(int *)); |
| old_bitmap = pBitmap->bitmap; |
| for (j = 0; j < (int)(pBitmap->height); j++) |
| { |
| bitmap[j] = (int *)mi_xmalloc (pBitmap->width * sizeof(int)); |
| for (i = 0; i < (int)(pBitmap->width); i++) |
| bitmap[j][i] = old_bitmap[j][i]; |
| } |
| |
| new_pBitmap->bitmap = bitmap; |
| new_pBitmap->width = pBitmap->width; |
| new_pBitmap->height = pBitmap->height; |
| |
| return new_pBitmap; |
| } |
| |
| |
| static void |
| miDeleteBitmap (miBitmap *pBitmap) |
| { |
| int j; |
| |
| if (pBitmap == (miBitmap *)NULL) |
| return; |
| |
| |
| for (j = 0; j < (int)(pBitmap->height); j++) |
| free (pBitmap->bitmap[j]); |
| free (pBitmap->bitmap); |
| |
| free (pBitmap); |
| } |
| |
| |
| void |
| miSetPixelMerge2 (miCanvas *pCanvas, miPixelMerge2 pixelMerge2) |
| { |
| if (pCanvas == (miCanvas *)NULL) |
| return; |
| pCanvas->pixelMerge2 = pixelMerge2; |
| } |
| |
| |
| void |
| miSetPixelMerge3 (miCanvas *pCanvas, miPixelMerge3 pixelMerge3) |
| { |
| if (pCanvas == (miCanvas *)NULL) |
| return; |
| pCanvas->pixelMerge3 = pixelMerge3; |
| } |
| |
| |
| |
| void |
| miSetCanvasStipple (miCanvas *pCanvas, const miBitmap *pstipple, miPoint stippleOrigin) |
| { |
| if (pCanvas == (miCanvas *)NULL) |
| return; |
| |
| miDeleteBitmap (pCanvas->stipple); |
| pCanvas->stipple = miCopyBitmap (pstipple); |
| pCanvas->stippleOrigin = stippleOrigin; |
| } |
| |
| |
| |
| void |
| miSetCanvasTexture (miCanvas *pCanvas, const miPixmap *pTexture, miPoint textureOrigin) |
| { |
| if (pCanvas == (miCanvas *)NULL) |
| return; |
| |
| miDeletePixmap (pCanvas->texture); |
| pCanvas->texture = miCopyPixmap (pTexture); |
| pCanvas->textureOrigin = textureOrigin; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| static void |
| miPaintCanvas (miCanvas *canvas, miPixel pixel, int n, const miPoint *ppt, const unsigned int *pwidth, miPoint offset) |
| { |
| int i; |
| int xleft, xright, ybottom, ytop; |
| unsigned int stippleWidth = 0, stippleHeight = 0; |
| unsigned int textureWidth = 0, textureHeight = 0; |
| int stippleXOrigin = 0, stippleYOrigin = 0; |
| int textureXOrigin = 0, textureYOrigin = 0; |
| int xstart, xend, xstart_clip, xend_clip, xoffset, yoffset, x, y; |
| unsigned int width; |
| const miCanvas *pCanvas; |
| miPixelMerge2 pixelMerge2; |
| miPixelMerge3 pixelMerge3; |
| |
| pCanvas = canvas; |
| xoffset = offset.x; |
| yoffset = offset.y; |
| |
| |
| MI_GET_CANVAS_DRAWABLE_BOUNDS(pCanvas, xleft, ytop, xright, ybottom) |
| |
| |
| if (ppt[0].y + yoffset > ybottom || ppt[n-1].y + yoffset < ytop) |
| return; |
| |
| |
| pixelMerge2 = pCanvas->pixelMerge2; |
| pixelMerge3 = pCanvas->pixelMerge3; |
| |
| #define MI_MERGE_CANVAS_PIXEL(pCanvas, x, y, sourcePixel, texturePixel, have_texturePixel) \ |
| { \ |
| miPixel destinationPixel, newPixel; \ |
| MI_GET_CANVAS_DRAWABLE_PIXEL((pCanvas), (x), (y), destinationPixel); \ |
| if (!have_texturePixel) \ |
| { \ |
| if (pixelMerge2 != (miPixelMerge2)NULL) \ |
| newPixel = (*pixelMerge2)((sourcePixel), destinationPixel); \ |
| else \ |
| MI_DEFAULT_MERGE2_PIXEL(newPixel, (sourcePixel), destinationPixel); \ |
| } \ |
| else \ |
| { \ |
| if (pixelMerge3 != (miPixelMerge3)NULL) \ |
| newPixel = (*pixelMerge3)((texturePixel), (sourcePixel), destinationPixel); \ |
| else \ |
| MI_DEFAULT_MERGE3_PIXEL(newPixel, (texturePixel), (sourcePixel), destinationPixel); \ |
| } \ |
| MI_SET_CANVAS_DRAWABLE_PIXEL((pCanvas), (x), (y), newPixel); \ |
| } |
| |
| if (pCanvas->stipple) |
| { |
| stippleWidth = pCanvas->stipple->width; |
| stippleHeight = pCanvas->stipple->height; |
| stippleXOrigin = pCanvas->stippleOrigin.x; |
| stippleYOrigin = pCanvas->stippleOrigin.y; |
| while (stippleXOrigin > 0) |
| stippleXOrigin -= stippleWidth; |
| while (stippleYOrigin > 0) |
| stippleYOrigin -= stippleHeight; |
| } |
| |
| if (pCanvas->texture) |
| { |
| textureWidth = pCanvas->texture->width; |
| textureHeight = pCanvas->texture->height; |
| textureXOrigin = pCanvas->textureOrigin.x; |
| textureYOrigin = pCanvas->textureOrigin.y; |
| while (textureXOrigin > 0) |
| textureXOrigin -= textureWidth; |
| while (textureYOrigin > 0) |
| textureYOrigin -= textureHeight; |
| } |
| |
| for (i = 0; i < n; i++) |
| { |
| y = ppt[i].y + yoffset; |
| if (y > ybottom) |
| return; |
| if (y >= ytop) |
| { |
| width = pwidth[i]; |
| xstart = ppt[i].x + xoffset; |
| xend = xstart + (int)width - 1; |
| |
| xstart_clip = IMAX(xstart,xleft); |
| xend_clip = IMIN(xend,xright); |
| |
| for (x = xstart_clip; x <= xend_clip; x++) |
| |
| { |
| miPixel texturePixel, sourcePixel; |
| bool have_texturePixel = false; |
| |
| if (pCanvas->texture) |
| { |
| texturePixel = pCanvas->texture->pixmap[(y-textureYOrigin) % textureHeight][(x-textureXOrigin) % textureWidth]; |
| have_texturePixel = true; |
| } |
| else |
| texturePixel = pixel; |
| |
| sourcePixel = pixel; |
| |
| if (pCanvas->stipple == (miBitmap *)NULL |
| || pCanvas->stipple->bitmap[(y-stippleYOrigin) % stippleHeight][(x-stippleXOrigin) % stippleWidth] != 0) |
| MI_MERGE_CANVAS_PIXEL(pCanvas, x, y, sourcePixel, texturePixel, have_texturePixel) |
| } |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| void |
| miCopyPaintedSetToCanvas (const miPaintedSet *paintedSet, miCanvas *canvas, miPoint offset) |
| { |
| int i; |
| |
| |
| |
| |
| |
| |
| for (i = 0; i < paintedSet->ngroups; i++) |
| if (paintedSet->groups[i]->group[0].count > 0) |
| miPaintCanvas (canvas, paintedSet->groups[i]->pixel, |
| paintedSet->groups[i]->group[0].count, |
| paintedSet->groups[i]->group[0].points, |
| paintedSet->groups[i]->group[0].widths, offset); |
| } |