📄 devdraw.c
字号:
count -= cc; x += cc; if (x > maxx) { x = minx; y++; } } /* Now the x value is at the beginning of a row if there are * any points left to be drawn. Draw all the complete rows * with one call. */ rows = count / width; if (rows > 0) { if (dodraw) { /* note: change to fillrect, (parm types changed)*/ /*GdFillRect(psd, x, y, maxx, y + rows - 1);*/ GdFillRect(psd, x, y, maxx - x + 1, rows); } count %= width; y += rows; } /* If there is a final partial row of pixels left to be * drawn, then do that. */ if (count > 0) { if (dodraw) drawrow(psd, x, x + count - 1, y); x += count; } } gr_foreground = savecolor; GdFixCursor(psd);}#if NOTYET/* Copy a rectangular area from one screen area to another. * This bypasses clipping. */voidGdCopyArea(PSD psd, MWCOORD srcx, MWCOORD srcy, MWCOORD width, MWCOORD height, MWCOORD destx, MWCOORD desty){ if (width <= 0 || height <= 0) return; if (srcx == destx && srcy == desty) return; GdCheckCursor(psd, srcx, srcy, srcx + width - 1, srcy + height - 1); GdCheckCursor(psd, destx, desty, destx + width - 1, desty + height - 1); psd->CopyArea(psd, srcx, srcy, width, height, destx, desty); GdFixCursor(psd);}#endif/* Copy source rectangle of pixels to destination rectangle quickly*/voidGdBlit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD width, MWCOORD height, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long rop){ int rx1, rx2, ry1, ry2; int px1, px2, py1, py2; int pw, ph; int count;#if DYNAMICREGIONS MWRECT * prc; extern MWCLIPREGION *clipregion;#else MWCLIPRECT * prc; extern MWCLIPRECT cliprects[]; extern int clipcount;#endif /*FIXME: compare bpp's and convert if necessary*/ assert(dstpsd->planes == srcpsd->planes); assert(dstpsd->bpp == srcpsd->bpp); /* temporary assert() until rotation blits completed*/ assert(dstpsd->portrait == srcpsd->portrait); /* clip blit rectangle to source screen/bitmap size*/ /* we must do this because there isn't any source clipping setup*/ if(srcx < 0) { width += srcx; dstx -= srcx; srcx = 0; } if(srcy < 0) { height += srcy; dsty -= srcy; srcy = 0; } if(srcx+width > srcpsd->xvirtres) width = srcpsd->xvirtres - srcx; if(srcy+height > srcpsd->yvirtres) height = srcpsd->yvirtres - srcy; switch(GdClipArea(dstpsd, dstx, dsty, dstx+width-1, dsty+height-1)) { case CLIP_VISIBLE: /* check cursor in src region*/ GdCheckCursor(dstpsd, srcx, srcy, srcx+width-1, srcy+height-1); dstpsd->Blit(dstpsd, dstx, dsty, width, height, srcpsd, srcx, srcy, rop); GdFixCursor(dstpsd); return; case CLIP_INVISIBLE: return; } /* Partly clipped, we'll blit using destination clip * rectangles, and offset the blit accordingly. * Since the destination is already clipped, we * only need to clip the source here. */#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 rx1 = prc->x; ry1 = prc->y; rx2 = prc->x + prc->width; ry2 = prc->y + prc->height;#endif /* Check: does this rect intersect the one we want to draw? */ px1 = dstx; py1 = dsty; px2 = dstx + width; py2 = dsty + height; if (px1 < rx1) px1 = rx1; if (py1 < ry1) py1 = ry1; if (px2 > rx2) px2 = rx2; if (py2 > ry2) py2 = ry2; pw = px2 - px1; ph = py2 - py1; if(pw > 0 && ph > 0) { /* check cursor in dest and src regions*/ GdCheckCursor(dstpsd, px1, py1, px2-1, py2-1); GdCheckCursor(dstpsd, srcx, srcy, srcx+width, srcy+height); dstpsd->Blit(dstpsd, px1, py1, pw, ph, srcpsd, srcx + (px1-dstx), srcy + (py1-dsty), rop); } ++prc; } GdFixCursor(dstpsd);}/* experimental globals for ratio bug when src != 0*/int g_row_inc, g_col_inc;/* Stretch source rectangle of pixels to destination rectangle quickly*/voidGdStretchBlit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD dstw, MWCOORD dsth, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, MWCOORD srcw, MWCOORD srch, long rop){ int count;#if DYNAMICREGIONS MWRECT * prc; extern MWCLIPREGION *clipregion;#else MWCLIPRECT * prc; extern MWCLIPRECT cliprects[]; extern int clipcount;#endifg_row_inc = g_col_inc = 0; /* check for driver stretch blit implementation*/ if (!dstpsd->StretchBlit) return; /*FIXME: compare bpp's and convert if necessary*/ assert(dstpsd->planes == srcpsd->planes); assert(dstpsd->bpp == srcpsd->bpp); /* clip blit rectangle to source screen/bitmap size*/ /* we must do this because there isn't any source clipping setup*/ if(srcx < 0) { srcw += srcx; /*dstx -= srcx;*/ srcx = 0; } if(srcy < 0) { srch += srcy; /*dsty -= srcy;*/ srcy = 0; } if(srcx+srcw > srcpsd->xvirtres) srcw = srcpsd->xvirtres - srcx; if(srcy+srch > srcpsd->yvirtres) srch = srcpsd->yvirtres - srcy; /* temp dest clipping for partially visible case*/ if(dstx+dstw > dstpsd->xvirtres) dstw = dstpsd->xvirtres - dstx; if(dsty+dsth > dstpsd->yvirtres) dsth = dstpsd->yvirtres - dsty; switch(GdClipArea(dstpsd, dstx, dsty, dstx+dstw-1, dsty+dsth-1)) { case CLIP_VISIBLE: /* check cursor in src region*/ GdCheckCursor(dstpsd, srcx, srcy, srcx+srcw-1, srcy+srch-1); dstpsd->StretchBlit(dstpsd, dstx, dsty, dstw, dsth, srcpsd, srcx, srcy, srcw, srch, rop); GdFixCursor(dstpsd); return; case CLIP_INVISIBLE: return; } /* Partly clipped, we'll blit using destination clip * rectangles, and offset the blit accordingly. * Since the destination is already clipped, we * only need to clip the source here. */#if DYNAMICREGIONS prc = clipregion->rects; count = clipregion->numRects;#else prc = cliprects; count = clipcount;#endif while(--count >= 0) { int rx1, rx2, ry1, ry2; int px1, px2, py1, py2; int pw, ph; int sx, sy, sw, sh;#if DYNAMICREGIONS rx1 = prc->left; ry1 = prc->top; rx2 = prc->right; ry2 = prc->bottom;#else rx1 = prc->x; ry1 = prc->y; rx2 = prc->x + prc->width; ry2 = prc->y + prc->height;#endif /* Check: does this rect intersect the one we want to draw? */ px1 = dstx; py1 = dsty; px2 = dstx + dstw; py2 = dsty + dsth; if (px1 < rx1) px1 = rx1; if (py1 < ry1) py1 = ry1; if (px2 > rx2) px2 = rx2; if (py2 > ry2) py2 = ry2; pw = px2 - px1; ph = py2 - py1; if(pw > 0 && ph > 0) { /* calc proper src/dst offset for stretch rect*/g_row_inc = (srch << 16) / dsth;g_col_inc = (srcw << 16) / dstw; sw = pw * srcw / dstw; sh = ph * srch / dsth; if (sw > 0 && sh > 0) { sx = srcx + (px1-dstx) * srcw / dstw; sy = srcy + (py1-dsty) * srch / dsth;/*printf("P %d,%d,%d,%d %d,%d\n", sx, sy, sw, sh, g_row_inc, g_col_inc);*/ /* check cursor in dest and src regions*/ GdCheckCursor(dstpsd, px1, py1, px2-1, py2-1); GdCheckCursor(dstpsd, srcx, srcy, srcx+srcw, srcy+srch); dstpsd->StretchBlit(dstpsd, px1, py1, pw, ph, srcpsd, sx, sy, sw, sh, rop); } } ++prc; } GdFixCursor(dstpsd);}/* * Calculate size and linelen of memory gc. * If bpp or planes is 0, use passed psd's bpp/planes. * Note: linelen is calculated to be DWORD aligned for speed * for bpp <= 8. Linelen is converted to bytelen for bpp > 8. */intGdCalcMemGCAlloc(PSD psd, unsigned int width, unsigned int height, int planes, int bpp, int *psize, int *plinelen){ int bytelen, linelen, tmp; if(!planes) planes = psd->planes; if(!bpp) bpp = psd->bpp; /* * swap width and height in left/right portrait modes, * so imagesize is calculated properly */ if(psd->portrait & (MWPORTRAIT_LEFT|MWPORTRAIT_RIGHT)) { tmp = width; width = height; height = tmp; } /* * use bpp and planes to create size and linelen. * linelen is in bytes for bpp 1, 2, 4, 8, and pixels for bpp 16,24,32. */ if(planes == 1) { switch(bpp) { case 1: linelen = (width+7)/8; bytelen = linelen = (linelen+3) & ~3; break; case 2: linelen = (width+3)/4; bytelen = linelen = (linelen+3) & ~3; break; case 4: linelen = (width+1)/2; bytelen = linelen = (linelen+3) & ~3; break; case 8: bytelen = linelen = (width+3) & ~3; break; case 16: linelen = width; bytelen = width * 2; break; case 24: linelen = width; bytelen = width * 3; break; case 32: linelen = width; bytelen = width * 4; break; default: return 0; } } else if(planes == 4) { /* FIXME assumes VGA 4 planes 4bpp*/ /* we use 4bpp linear for memdc format*/ linelen = (width+1)/2; linelen = (linelen+3) & ~3; bytelen = linelen; } else { *psize = *plinelen = 0; return 0; } *plinelen = linelen; *psize = bytelen * height; return 1;}/* Translate a rectangle of color values * * The pixels are packed according to inpixtype/outpixtype: * * pixtype array of * MWPF_RGB MWCOLORVAL (unsigned long) * MWPF_PIXELVAL MWPIXELVAL (compile-time dependent) * MWPF_PALETTE unsigned char * MWPF_TRUECOLOR0888 unsigned long * MWPF_TRUECOLOR888 packed struct {char r,char g,char b} (24 bits) * MWPF_TRUECOLOR565 unsigned short * MWPF_TRUECOLOR555 unsigned short * MWPF_TRUECOLOR332 unsigned char */voidGdTranslateArea(MWCOORD width, MWCOORD height, void *in, int inpixtype, MWCOORD inpitch, void *out, int outpixtype, int outpitch){ unsigned char * inbuf = in; unsigned char * outbuf = out; unsigned long pixelval; MWCOLORVAL colorval; MWCOORD x, y; unsigned char r, g, b; extern MWPALENTRY gr_palette[256]; int gr_palsize = 256; /* FIXME*/ for(y=0; y<height; ++y) { for(x=0; x<width; ++x) { /* read pixel value and convert to BGR colorval (0x00BBGGRR)*/ switch (inpixtype) { case MWPF_RGB: colorval = *(MWCOLORVAL *)inbuf; inbuf += sizeof(MWCOLORVAL); break; case MWPF_PIXELVAL: pixelval = *(MWPIXELVAL *)inbuf; inbuf += sizeof(MWPIXELVAL); /* convert based on compile-time MWPIXEL_FORMAT*/#if MWPIXEL_FORMAT == MWPF_PALETTE colorval = GETPALENTRY(gr_palette, pixelval);#else colorval = PIXELVALTOCOLORVAL(pixelval);#endif break; case MWPF_PALETTE: pixelval = *inbuf++; colorval = GETPALENTRY(gr_palette, pixelval); break; case MWPF_TRUECOLOR332: pixelval = *inbuf++; colorval = PIXEL332TOCOLORVAL(pixelval); break; case MWPF_TRUECOLOR0888: pixelval = *(unsigned long *)inbuf; colorval = PIXEL888TOCOLORVAL(pixelval); inbuf += sizeof(unsigned long); break; case MWPF_TRUECOLOR888: r = *inbuf++; g = *inbuf++; b = *inbuf++; colorval = (MWPIXELVAL)MWRGB(r, g, b); break; case MWPF_TRUECOLOR565: pixelval = *(unsigned short *)inbuf; colorval = PIXEL565TOCOLORVAL(pixelval); inbuf += sizeof(unsigned short); break; case MWPF_TRUECOLOR555: pixelval = *(unsigned short *)inbuf; colorval = PIXEL555TOCOLORVAL(pixelval); inbuf += sizeof(unsigned short); break; default: return; } /* convert from BGR colorval to desired output pixel format*/ switch (outpixtype) { case MWPF_RGB: *(MWCOLORVAL *)outbuf = colorval; outbuf += sizeof(MWCOLORVAL); break; case MWPF_PIXELVAL: /* convert based on compile-time MWPIXEL_FORMAT*/#if MWPIXEL_FORMAT == MWPF_PALETTE *(MWPIXELVAL *)outbuf = GdFindNearestColor(gr_palette, gr_palsize, colorval);#else *(MWPIXELVAL *)outbuf = COLORVALTOPIXELVAL(colorval);#endif outbuf += sizeof(MWPIXELVAL); break; case MWPF_PALETTE: *outbuf++ = GdFindNearestColor(gr_palette, gr_palsize, colorval); break; case MWPF_TRUECOLOR332: *outbuf++ = COLOR2PIXEL332(colorval); break; case MWPF_TRUECOLOR0888: *(unsigned long *)outbuf = COLOR2PIXEL888(colorval); outbuf += sizeof(unsigned long); break; case MWPF_TRUECOLOR888: *outbuf++ = REDVALUE(colorval); *outbuf++ = GREENVALUE(colorval); *outbuf++ = BLUEVALUE(colorval); break; case MWPF_TRUECOLOR565: *(unsigned short *)outbuf = COLOR2PIXEL565(colorval); outbuf += sizeof(unsigned short); break; case MWPF_TRUECOLOR555: *(unsigned short *)outbuf = COLOR2PIXEL555(colorval); outbuf += sizeof(unsigned short); break; } } /* adjust line widths, if necessary*/ if(inpitch > width) inbuf += inpitch - width; if(outpitch > width) outbuf += outpitch - width; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -