📄 vga16.c
字号:
} else { if (slope) { y = *_y0 + CeilDiv(dy*((x - *_x0)*2 - 1), 2*dx); } else { y = *_y0 + FloorDiv(dy*((x - *_x0)*2 - 1), 2*dx); } } } else if (code&OC_RIGHT) { x = tempclipmaxx; if (xmajor) { y = *_y0 + FloorDiv(dy*(x - *_x0)*2 + dx, 2*dx); } else { if (slope) { y = *_y0 + CeilDiv(dy*((x - *_x0)*2 + 1), 2*dx)-1; } else { y = *_y0 + FloorDiv(dy*((x - *_x0)*2 + 1), 2*dx)+1; } } } else if (code&OC_TOP) { y = tempclipminy; if (xmajor) { if (slope) { x = *_x0 + CeilDiv(dx*((y - *_y0)*2 - 1), 2*dy); } else { x = *_x0 + FloorDiv(dx*((y - *_y0)*2 - 1), 2*dy); } } else { x = *_x0 + FloorDiv( dx*(y - *_y0)*2 + dy, 2*dy); } } else { /* OC_BOTTOM */ y = tempclipmaxy; if (xmajor) { if (slope) { x = *_x0 + CeilDiv(dx*((y - *_y0)*2 + 1), 2*dy)-1; } else { x = *_x0 + FloorDiv(dx*((y - *_y0)*2 + 1), 2*dy)+1; } } else { x = *_x0 + FloorDiv(dx*(y - *_y0)*2 + dy, 2*dy); } } if (first!=0) { x0 = x; y0 = y; outcode(first,x0,y0); *clip_first = 1; } else { x1 = x; y1 = y; last = code; outcode(last,x1,y1); *clip_last = 1; } if ((first & last) != 0) { return CLIP_INVISIBLE; /* Trivially rejected! */ } if ((first | last) == 0) { *_x0=x0; *_y0=y0; *_x1=x1; *_y1=y1; return CLIP_PARTIAL; /* Trivially accepted! */ } }}static int vga16_clipline (PGC_VGA16 gc,int * px1,int * py1, int * px2,int *py2){ int w,h; int r1; int clip_first; int clip_last; if(*px1 == *px2) { if (*py1 == *py2) return vga16_clippoint (gc,*px1,*px2); if (*py1 > *py2) { h = *py1 - *py2 + 1; r1 = vga16_clipvline (gc, px1, py2, &h); if (r1 == CLIP_PARTIAL) *py1 = *py2 + h - 1; return r1; } else { h = *py2 - *py1 + 1; r1 = vga16_clipvline (gc, px1, py1, &h); if (r1 == CLIP_PARTIAL) *py2 = *py1 + h - 1; return r1; } } if(*py1 == *py2) { if (*px1 > *px2) { w = *px1 - *px2 + 1; r1 = vga16_clipvline (gc, px2, py1, &w); if (r1 == CLIP_PARTIAL) *px1 = *px2 + w - 1; return r1; } else { w = *px2 - *px1 + 1; r1 = vga16_clipvline (gc, px2, py2, &w); if (r1 == CLIP_PARTIAL) *px2 = *px1 + w - 1; return r1; } } return cs_clipline(gc,px1,py1,px2,py2,&clip_first,&clip_last); }static int vga16_clipbox (PGC_VGA16 gc,int * px,int * py, int * pw,int *ph){ if (*pw == 1) return vga16_clipvline(gc, px, py, ph); if (*ph == 1) return vga16_cliphline(gc, px, py, pw); if (gc->doclip) { if ( (*px >= gc->clipmaxx) || (*py >= gc->clipmaxy) || (*px + *pw - 1 < gc->clipminx) || (*py + *ph - 1 < gc->clipminy) ) return CLIP_INVISIBLE; if ( (*px >= gc->clipminx) && (*py >= gc->clipminy) && (*px + *pw -1 < gc->clipmaxx) && (*py + *ph - 1 < gc->clipmaxy) ) return CLIP_VISIBLE; if (*px < gc->clipminx) { *pw -= gc->clipminx - *px; *px = gc->clipminx; } if (*py < gc->clipminy) { *ph -= gc->clipminy - *py; *py = gc->clipminy; } if (*px + *pw - 1 >= gc->clipmaxx) *pw = gc->clipmaxx - *px; if (*py + *ph - 1 >= gc->clipmaxy) *ph = gc->clipmaxy - *py; } else { if ( (*px >= gc->xres) || (*py >= gc->yres) || (*px + *pw - 1 < 0) || (*py +*ph - 1 < 0) ) return CLIP_INVISIBLE; if ( (*px >= 0) && (*py >= 0) && (*px + *pw -1 < gc->xres) && (*py + *ph - 1 < gc->yres) ) return CLIP_VISIBLE; if (*px < 0) { *pw += *px; *px = 0; } if (*px + *pw - 1 >= gc->xres) *pw = gc->xres - *px; if (*py < 0) { *ph += *py; *py = 0; } if (*py + *ph - 1 >= gc->yres) *ph = gc->yres - *py; } if (*pw <= 0 || *ph <= 0) return CLIP_INVISIBLE; return CLIP_PARTIAL; }static int fillbox (GAL_GC gc, int x, int y, int w, int h, gal_pixel pixel){ GC_VGA16* mygc = gc.gc_vga16; if ((w <= 0) || (h <= 0)) return -1; BLOCK_DRAW_SEM; if (vga16_clipbox (mygc, &x, &y, &w, &h)) { memset (mygc->scanline, mygc->gr_foreground, w); if (mygc->fb_buff) { unsigned char* dst = mygc->fb_buff + y * mygc->pitch + x; while (h--) { memcpy (dst, mygc->scanline, w); dst += mygc->pitch; } } else { while (h--) { vga_drawscansegment (mygc->scanline, x, y++, w); } } } UNBLOCK_DRAW_SEM; return 0;}static gal_uint8* putbox_helper (GC_VGA16* gc, int* px, int* py, int* pw, int* ph, void* buf){ int x = *px, y = *py, w = *pw, h = *ph; gal_uint8 *src = (gal_uint8*) buf; int srcwidth = *pw; if (gc->doclip) { if (y < gc->clipminy) { h -= gc->clipminy - y; src += (gc->clipminy - y) * srcwidth; y = gc->clipminy; } if (x < gc->clipminx) { w -= gc->clipminx - x; src += gc->clipminx - x; x = gc->clipminx; } if (y + h - 1 >= gc->clipmaxy) h = gc->clipmaxy- y; if (x + w - 1 >= gc->clipmaxx) w = gc->clipmaxx- x; } else { if ( y < 0 ) { h += y; src -= y * srcwidth; y = 0; } if ( x < 0 ) { w += x; src -= x; x = 0; } if ( y + h -1 >= gc->yres) h = gc->yres - y ; if ( x + w -1 >= gc->xres) w = gc->xres - x ; } *px = x; *py = y; *pw = w; *ph = h; return src;}static int putbox (GAL_GC gc, int x, int y, int w, int h, void* buf){ GC_VGA16* mygc = gc.gc_vga16; gal_uint8* src; int srcw = w; if ((w <= 0) || (h <= 0)) return -1; BLOCK_DRAW_SEM; if (mygc->doclip) { if ((x + w - 1 < mygc->clipminx) || (x >= mygc->clipmaxx)) goto inv_args; if ((y + h - 1 < mygc->clipminy) || (y >= mygc->clipmaxy)) goto inv_args; } else { if ((x + w - 1 < 0) || (x >= mygc->xres)) goto inv_args; if ((y + h - 1 < 0) || (y >= mygc->yres)) goto inv_args; } src = putbox_helper (mygc, &x, &y, &w, &h, buf); if (mygc->fb_buff) { gal_uint8* dst; dst = mygc->fb_buff + y * mygc->pitch + x; while (h--) { memcpy (dst, src, w); dst += mygc->pitch; src += srcw; } } else { while (h--) { vga_drawscansegment (src, x, y++, w); src += srcw; } }inv_args: UNBLOCK_DRAW_SEM; return 0;}static int putboxmask (GAL_GC gc, int x, int y, int w, int h, void* buf, gal_pixel cxx){ GC_VGA16* mygc = gc.gc_vga16; gal_uint8* src; int srcw = w; if ((w <= 0) || (h <= 0)) return -1; BLOCK_DRAW_SEM; if (mygc->doclip) { if ((x + w - 1 < mygc->clipminx) || (x >= mygc->clipmaxx)) goto inv_args; if ((y + h - 1 < mygc->clipminy) || (y >= mygc->clipmaxy)) goto inv_args; } else { if ((x + w - 1 < 0) || (x >= mygc->xres)) goto inv_args; if ((y + h - 1 < 0) || (y >= mygc->yres)) goto inv_args; } src = putbox_helper (mygc, &x, &y, &w, &h, buf); if (mygc->fb_buff) { gal_uint8* dst; dst = mygc->fb_buff + y * mygc->pitch + x; while (h--) { int i; for (i = 0; i < w; i++) { if (src [i] != cxx) dst [i] = src [i]; } dst += mygc->pitch; src += srcw; } } else { // FIXME: while (h--) { vga_drawscansegment (src, x, y++, w); src += srcw; } }inv_args: UNBLOCK_DRAW_SEM; return 0;}static gal_uint8* getbox_helper (GC_VGA16* gc, int* px, int* py, int* pw, int* ph, void* buf){ int x = *px, y = *py, w = *pw, h = *ph; gal_uint8 *dst = (gal_uint8*)buf; int dstwidth = *pw; if ( y < 0 ) { h += y; dst -= y * dstwidth; y = 0; } if ( x < 0 ) { w += x; dst -= x; x = 0; } if ( y + h -1 >= gc->yres) h = gc->yres - y ; if ( x + w -1 >= gc->xres) w = gc->xres - x ; *px = x; *py = y; *pw = w; *ph = h; return dst;}static int getbox (GAL_GC gc, int x, int y, int w, int h, void* buf){ GC_VGA16* mygc = gc.gc_vga16; gal_uint8* dst; int dstw = w; if ((w <= 0) || (h <= 0)) return -1; if ((x + w - 1 < 0) || (x >= mygc->xres)) return -1; if ((y + h - 1 < 0) || (y >= mygc->yres)) return -1; dst = getbox_helper (mygc, &x, &y, &w, &h, buf); if (mygc->fb_buff) { gal_uint8* src; src = mygc->fb_buff + y * mygc->pitch + x; while (h--) { memcpy (dst, src, w); dst += dstw; src += mygc->pitch; } } else { while (h--) { vga_getscansegment (dst, x, y++, w); dst += dstw; } } return 0;}static inline int muldiv64 (int m1, int m2, int d){ long long int mul = (long long int) m1 * m2; return (int) (mul / d);}/* This is a DDA-based algorithm. *//* Iteration over target bitmap. */static int vga16_scalebox (int w1, int h1, void *_dp1, int w2, int h2, void *_dp2){ gal_uint8 *dp1 = _dp1; gal_uint8 *dp2 = _dp2; int xfactor; int yfactor; int y, sy; if (w2 == 0 || h2 == 0) return 1; xfactor = muldiv64 (w1, 65536, w2); /* scaled by 65536 */ yfactor = muldiv64 (h1, 65536, h2); /* scaled by 65536 */ sy = 0; for (y = 0; y < h2;) { int sx = 0; gal_uint8 *dp2old = dp2; int x; x = 0; while (x < w2 - 8) { *(dp2 + x) = *(dp1 + (sx >> 16)); sx += xfactor; *(dp2 + x + 1) = *(dp1 + (sx >> 16)); sx += xfactor; *(dp2 + x + 2) = *(dp1 + (sx >> 16)); sx += xfactor; *(dp2 + x + 3) = *(dp1 + (sx >> 16)); sx += xfactor; *(dp2 + x + 4) = *(dp1 + (sx >> 16)); sx += xfactor; *(dp2 + x + 5) = *(dp1 + (sx >> 16)); sx += xfactor; *(dp2 + x + 6) = *(dp1 + (sx >> 16)); sx += xfactor; *(dp2 + x + 7) = *(dp1 + (sx >> 16)); sx += xfactor; x += 8; } while (x < w2) { *(dp2 + x) = *(dp1 + (sx >> 16)); sx += xfactor; x++; } dp2 += w2; y++; while (y < h2) { int l; int syint = sy >> 16; sy += yfactor; if ((sy >> 16) != syint) break; /* Copy identical lines. */ l = dp2 - dp2old; memcpy(dp2, dp2old, l); dp2old = dp2; dp2 += l; y++; } dp1 = _dp1 + (sy >> 16) * w1; } return 0;}static int scalebox (GAL_GC gc, int sw, int sh, void* srcbuf, int dw, int dh, void* dstbuf){ return vga16_scalebox (sw, sh, srcbuf, dw, dh, dstbuf);}static void copybox_helper1 (GC_VGA16* gc, int x1, int y1, int w, int h, int x2, int y2){ gal_uint8 *svp, *dvp; if (y1 >= y2) { if (y1 == y2 && x2 >= x1) { /* tricky */ int i; if (x1 == x2) return; /* use a temporary buffer to store a line */ /* using reversed movs would be much faster */ svp = (gal_uint8 *) gc->fb_buff + y1 * gc->pitch + x1; dvp = (gal_uint8 *) gc->fb_buff + y2 * gc->pitch + x2; for (i = 0; i < h; i++) { memcpy (gc->scanline, svp, w); memcpy (dvp, gc->scanline, w); svp += gc->pitch; dvp += gc->pitch; } } else { /* copy from top to bottom */ int i; svp = (gal_uint8 *) gc->fb_buff + y1 * gc->pitch + x1; dvp = (gal_uint8 *) gc->fb_buff + y2 * gc->pitch + x2; for (i = 0; i < h; i++) { memcpy(dvp, svp, w); svp += gc->pitch; dvp += gc->pitch; } } } else { /* copy from bottom to top */ int i; svp = (gal_uint8 *) gc->fb_buff + (y1 + h) * gc->pitch + x1; dvp = (gal_uint8 *) gc->fb_buff + (y2 + h) * gc->pitch + x2; for (i = 0; i < h; i++) { svp -= gc->pitch; dvp -= gc->pitch; memcpy (dvp, svp, w); } }}static void copybox_helper2 (GC_VGA16* gc, int x1, int y1, int w, int h, int x2, int y2){ int i; if (y1 == y2 && x2 == x1) return; if (y1 >= y2) { /* copy from top to bottom */ for (i = 0; i < h; i++) { vga_getscansegment (gc->scanline, x1, y1++, w); vga_drawscansegment (gc->scanline, x2, y2++, w); } } else { /* copy from bottom to top */ y1 += h; y2 += h; for (i = 0; i < h; i++) { vga_getscansegment (gc->scanline, x1, y1--, w); vga_drawscansegment (gc->scanline, x2, y2--, w); } }}static int copybox (GAL_GC gc, int x, int y, int w, int h, int nx, int ny){ GC_VGA16* mygc = gc.gc_vga16; if ((w <= 0) || (h <= 0)) return -1; // src clip to screen if ((x >= mygc->xres) || (x + w - 1 < 0)) return -1; if ((y >= mygc->yres) || (y + h - 1 < 0)) return -1; if (x < 0) { nx -= x; w += x; x = 0; } if (y < 0) { ny -= y; h += y; y = 0; } if (x + w - 1 >= mygc->xres) w = mygc->xres - x; if (y + h - 1 >= mygc->yres) h = mygc->yres - y; BLOCK_DRAW_SEM; // dst do clip if (mygc->doclip) { if ((nx + w - 1 < mygc->clipminx) || (nx >= mygc->clipmaxx)) goto inv_args; if ((ny + h - 1 < mygc->clipminy) || (ny >= mygc->clipmaxy)) goto inv_args; if (nx < mygc->clipminx) { x += mygc->clipminx - nx; w -= mygc->clipminx - nx; nx = mygc->clipminx; } if (nx + w - 1 >= mygc->clipmaxx) { w = mygc->clipmaxx - nx; } if (ny < mygc->clipminy) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -