📄 devdraw.c
字号:
if (MWIMAGE_TESTBIT(bitvalue)) psd->DrawPixel(psd, x, y, gr_foreground); bitvalue = MWIMAGE_SHIFTBIT(bitvalue); bitcount--; if (x++ == maxx) { x = minx; y++; --height; bitcount = 0; } }}voidGdBitmap(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width, MWCOORD height, const MWIMAGEBITS *imagebits){ MWCOORD minx; MWCOORD maxx; MWPIXELVAL savecolor; /* saved foreground color */ MWIMAGEBITS bitvalue = 0; /* bitmap word value */ int bitcount; /* number of bits left in bitmap word */ if (width <= 0 || height <= 0) return; switch (GdClipArea(psd, x, y, x + width - 1, y + height - 1)) { case CLIP_VISIBLE: drawbitmap(psd, x, y, width, height, imagebits); GdFixCursor(psd); return; case CLIP_INVISIBLE: return; } /* The rectangle is partially visible, so must do clipping. First * fill a rectangle in the background color if necessary. */ if (gr_usebg) { savecolor = gr_foreground; gr_foreground = gr_background; /* note: change to fillrect*/ GdFillRect(psd, x, y, width, height); gr_foreground = savecolor; } minx = x; maxx = x + width - 1; bitcount = 0; while (height > 0) { if (bitcount <= 0) { bitcount = MWIMAGE_BITSPERIMAGE; bitvalue = *imagebits++; } if (MWIMAGE_TESTBIT(bitvalue) && GdClipPoint(psd, x, y)) psd->DrawPixel(psd, x, y, gr_foreground); bitvalue = MWIMAGE_SHIFTBIT(bitvalue); bitcount--; if (x++ == maxx) { x = minx; y++; --height; bitcount = 0; } } GdFixCursor(psd);}/** * Return true if color is in palette * * @param cr Color to look for. * @param palette Palette to look in. * @param palsize Size of the palette. * @return TRUE iff the color is in palette. */MWBOOLGdColorInPalette(MWCOLORVAL cr,MWPALENTRY *palette,int palsize){ int i; for(i=0; i<palsize; ++i) if(GETPALENTRY(palette, i) == cr) return TRUE; return FALSE;}/** * Create a MWPIXELVAL conversion table between the passed palette * and the in-use palette. The system palette is loaded/merged according * to fLoadType. * * FIXME: LOADPALETTE and MERGEPALETTE are defined in "device.h" * * @param psd Drawing surface. * @param palette Palette to look in. * @param palsize Size of the palette. * @param convtable Destination for the conversion table. Will hold palsize * entries. * @param fLoadType LOADPALETTE to set the surface's palette to the passed * palette, MERGEPALETTE to add the passed colors to the surface * palette without removing existing colors, or 0. */voidGdMakePaletteConversionTable(PSD psd,MWPALENTRY *palette,int palsize, MWPIXELVAL *convtable,int fLoadType){ int i; MWCOLORVAL cr; int newsize, nextentry; MWPALENTRY newpal[256]; /* * Check for load palette completely, or add colors * from passed palette to system palette until full. */ if(psd->pixtype == MWPF_PALETTE) { switch(fLoadType) { case LOADPALETTE: /* Load palette from beginning with image's palette. * First palette entries are Microwindows colors * and not changed. */ GdSetPalette(psd, gr_firstuserpalentry, palsize, palette); break; case MERGEPALETTE: /* get system palette*/ for(i=0; i<(int)psd->ncolors; ++i) newpal[i] = gr_palette[i]; /* merge passed palette into system palette*/ newsize = 0; nextentry = gr_nextpalentry; /* if color missing and there's room, add it*/ for(i=0; i<palsize && nextentry < (int)psd->ncolors; ++i) { cr = GETPALENTRY(palette, i); if(!GdColorInPalette(cr, newpal, nextentry)) { newpal[nextentry++] = palette[i]; ++newsize; } } /* set the new palette if any color was added*/ if(newsize) { GdSetPalette(psd, gr_nextpalentry, newsize, &newpal[gr_nextpalentry]); gr_nextpalentry += newsize; } break; } } /* * Build conversion table from inuse system palette and * passed palette. This will load RGB values directly * if running truecolor, otherwise it will find the * nearest color from the inuse palette. * FIXME: tag the conversion table to the bitmap image */ for(i=0; i<palsize; ++i) { cr = GETPALENTRY(palette, i); convtable[i] = GdFindColor(psd, cr); }}/** * Draw a color bitmap image in 1, 4, 8, 24 or 32 bits per pixel. The * Microwindows color image format is DWORD padded bytes, with * the upper bits corresponding to the left side (identical to * the MS Windows format). This format is currently different * than the MWIMAGEBITS format, which uses word-padded bits * for monochrome display only, where the upper bits in the word * correspond with the left side. * * @param psd Drawing surface. * @param x Destination X co-ordinate for left of image. * @param y Destination Y co-ordinate for top of image. * @param pimage Structure describing the image. */voidGdDrawImage(PSD psd, MWCOORD x, MWCOORD y, PMWIMAGEHDR pimage){ MWCOORD minx; MWCOORD maxx; MWUCHAR bitvalue = 0; int bitcount; MWUCHAR *imagebits; MWCOORD height, width; int bpp; MWPIXELVAL pixel; int clip; int extra, linesize; int rgborder; MWCOLORVAL cr; MWCOORD yoff; unsigned long transcolor; MWPIXELVAL convtable[256]; assert(pimage); height = pimage->height; width = pimage->width; /* determine if entire image is clipped out, save clipresult for later*/ clip = GdClipArea(psd, x, y, x + width - 1, y + height - 1); if(clip == CLIP_INVISIBLE) return; transcolor = pimage->transcolor; bpp = pimage->bpp; /* * Merge the images's palette and build a palette index conversion table. */ if (pimage->bpp <= 8) { if(!pimage->palette) { /* for jpeg's without a palette*/ for(yoff=0; yoff<pimage->palsize; ++yoff) convtable[yoff] = yoff; } else GdMakePaletteConversionTable(psd, pimage->palette, pimage->palsize, convtable, MERGEPALETTE); /* The following is no longer used. One reason is that it required */ /* the transparent color to be unique, which was unnessecary */ /* convert transcolor to converted palette index for speed*/ /* if (transcolor != -1L) transcolor = (unsigned long) convtable[transcolor]; */ } minx = x; maxx = x + width - 1; imagebits = pimage->imagebits; /* check for bottom-up image*/ if(pimage->compression & MWIMAGE_UPSIDEDOWN) { y += height - 1; yoff = -1; } else yoff = 1;#define PIX2BYTES(n) (((n)+7)/8) /* imagebits are dword aligned*/ switch(pimage->bpp) { default: case 8: linesize = width; break; case 32: linesize = width*4; break; case 24: linesize = width*3; break; case 4: linesize = PIX2BYTES(width<<2); break; case 1: linesize = PIX2BYTES(width); break; } extra = pimage->pitch - linesize; /* 24bpp RGB rather than BGR byte order?*/ rgborder = pimage->compression & MWIMAGE_RGB; if ((bpp == 32) && ((pimage->compression & MWIMAGE_ALPHA_CHANNEL) != 0)) { long *data = (long *) imagebits; /* DPRINTF("Nano-X: GdDrawImage (%d,%d) %dx%d x=%d-%d\n ", x,y,width,height,minx,maxx); */ while (height > 0) { cr = *data++;#if MW_CPU_BIG_ENDIAN if (rgborder) { /* Fix endian and swap R/B order */ cr = ((cr & 0xFFFFFF00UL) >> 8) | ((cr & 0x000000FFUL) << 24); } else { /* Fix endian */ cr = ((cr & 0xFF000000UL) >> 24) | ((cr & 0x00FF0000UL) >> 8) | ((cr & 0x0000FF00UL) << 8) | ((cr & 0x000000FFUL) << 24); }#else /* little endian*/ if (rgborder) { /* Swap R/B order */ cr = (cr & 0xFF00FF00UL) | ((cr & 0x00FF0000UL) >> 16) | ((cr & 0x000000FFUL) << 16); }#endif switch (psd->pixtype) { case MWPF_PALETTE: default: pixel = GdFindColor(psd, cr); break; case MWPF_TRUECOLOR8888: pixel = COLOR2PIXEL8888(cr); break; case MWPF_TRUECOLOR0888: case MWPF_TRUECOLOR888: pixel = COLOR2PIXEL888(cr); break; case MWPF_TRUECOLOR565: pixel = COLOR2PIXEL565(cr); break; case MWPF_TRUECOLOR555: pixel = COLOR2PIXEL555(cr); break; case MWPF_TRUECOLOR332: pixel = COLOR2PIXEL332(cr); break; } if (clip == CLIP_VISIBLE || GdClipPoint(psd, x, y)) psd->DrawPixel(psd, x, y, pixel); if (x++ == maxx) { /* printf("EOL\n "); */ x = minx; y += yoff; height--; data = (long *) (((char *) data) + extra); } } /* printf("End of image\n"); */ } else if ((bpp == 24) || (bpp == 32)) { long trans; while (height > 0) { /* RGB rather than BGR byte order? */ trans = cr = rgborder ? MWRGB(imagebits[0], imagebits[1], imagebits[2]) : MWRGB(imagebits[2], imagebits[1], imagebits[0]); imagebits += 3; if (bpp == 32) { /* * FIXME Currently, XPM is the only image * decoder that creates 32bpp images with * transparency. This is done specifying the * transparent color 0x01000000, using 0x01 * in the alpha channel as the indicator. */ if (*imagebits++ == 0x01) trans = 0x01000000; } /* handle transparent color */ if (transcolor != trans) { switch (psd->pixtype) { case MWPF_PALETTE: default: pixel = GdFindColor(psd, cr); break; case MWPF_TRUECOLOR8888: pixel = COLOR2PIXEL8888(cr); break; case MWPF_TRUECOLOR0888: case MWPF_TRUECOLOR888: pixel = COLOR2PIXEL888(cr); break; case MWPF_TRUECOLOR565: pixel = COLOR2PIXEL565(cr); break; case MWPF_TRUECOLOR555: pixel = COLOR2PIXEL555(cr); break; case MWPF_TRUECOLOR332: pixel = COLOR2PIXEL332(cr); break; } if (clip == CLIP_VISIBLE || GdClipPoint(psd, x, y)) psd->DrawPixel(psd, x, y, pixel);#if 0 /* fix: use clipmaxx to clip quicker */ else if (clip != CLIP_VISIBLE && !clipresult && x > clipmaxx) { x = maxx; }#endif } if (x++ == maxx) { x = minx; y += yoff; height--; imagebits += extra; } } } else { /* bpp == 8, 4, or 1, palettized image. */ bitcount = 0; while (height > 0) { if (bitcount <= 0) { bitcount = sizeof(MWUCHAR) * 8; bitvalue = *imagebits++; } switch (bpp) { default: case 8: bitcount = 0; if (bitvalue == transcolor) goto next; pixel = convtable[bitvalue]; break; case 4: if (((bitvalue & 0xf0) >> 4) == transcolor) { bitvalue <<= 4; bitcount -= 4; goto next; } pixel = convtable[(bitvalue & 0xf0) >> 4]; bitvalue <<= 4; bitcount -= 4; break; case 1: --bitcount; if (((bitvalue & 0x80) ? 1 : 0) == transcolor) { bitvalue <<= 1; goto next; } pixel = convtable[(bitvalue & 0x80) ? 1 : 0]; bitvalue <<= 1; break; } if (clip == CLIP_VISIBLE || GdClipPoint(psd, x, y)) psd->DrawPixel(psd, x, y, pixel);#if 0 /* fix: use clipmaxx to clip quicker */ else if (clip != CLIP_VISIBLE && !clipresult && x > clipmaxx) { x = maxx; }#endif next: if (x++ == maxx) { x = minx; y += yoff; height--; bitcount = 0; imagebits += extra; } } } GdFixCursor(psd);}/** * Read a rectangular area of the screen. * The color table is indexed row by row. * * @param psd Drawing surface. * @param x Left edge of rectangle to read. * @param y Top edge of rectangle to read. * @param width Width of rectangle to read. * @param height Height of rectangle to read. * @param pixels Destination for screen grab. */voidGdReadArea(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width, MWCOORD height, MWPIXELVAL *pixels){ MWCOORD row; MWCOORD col; if (width <= 0 || height <= 0) return; GdCheckCursor(psd, x, y, x+width-1, y+height-1); for (row = y; row < height+y; row++) for (col = x; col < width+x; col++) if (row < 0 || row >= psd->yvirtres || col < 0 || col >= psd->xvirtres) *pixels++ = 0; else *pixels++ = psd->ReadPixel(psd, col, row); GdFixCursor(psd);}/* * A wrapper for psd->DrawArea which performs clipping. * The gc->dst[x,y,w,h] values are clipped. The gc->src[x,y] * values are adjusted accordingly. * * This function does NOT have a fallback implementation * if the function is not supported by the driver. * * It is the caller's responsibility to GdFixCursor(psd). * * This is a low-level function. */voidGdDrawAreaInternal(PSD psd, driver_gc_t * gc, int op){ MWCOORD x = gc->dstx; MWCOORD y = gc->dsty; MWCOORD width = gc->dstw; MWCOORD height = gc->dsth; MWCOORD srcx; MWCOORD srcy; int clipped; int rx1, rx2, ry1, ry2, rw, rh; int count;#if DYNAMICREGIONS MWRECT *prc; extern MWCLIPREGION *clipregion;#else MWCLIPRECT *prc; extern MWCLIPRECT cliprects[]; extern int clipcount;#endif if (!psd->DrawArea) return; /* Set up area clipping, and just return if nothing is visible */ clipped = GdClipArea(psd, x, y, x + width - 1, y + height - 1); if (clipped == CLIP_INVISIBLE) { return; } else if (clipped == CLIP_VISIBLE) { psd->DrawArea(psd, gc, op); return; } /* Partially clipped. */ /* Save srcX/Y so we can change the originals. */ srcx = gc->srcx; srcy = gc->srcy;#if DYNAMICREGIONS prc = clipregion->rects; count = clipregion->numRects;#else prc = cliprects; count = clipcount;#endif while (count-- > 0) {#if DYNAMICREGIONS rx1 = prc->left; ry1 = prc->top; rx2 = prc->right; ry2 = prc->bottom;#else /* New clip-code by Morten */ rx1 = prc->x; ry1 = prc->y; rx2 = prc->x + prc->width; ry2 = prc->y + prc->height;#endif /* Check if this rect intersects with the one we draw */ if (rx1 < x) rx1 = x; if (ry1 < y) ry1 = y; if (rx2 > x + width) rx2 = x + width; if (ry2 > y + height) ry2 = y + height; rw = rx2 - rx1; rh = ry2 - ry1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -