void p_bitblt(p_win *w, int x, int y, p_win *offscreen, int x0, int y0, int x1, int y1) { HDC dc = w_getdc(w, 0); HDC dc2 = w_getdc(offscreen, 0); if (dc && dc2) BitBlt(dc, x, y, x1-x0, y1-y0, dc2, x0, y0, SRCCOPY); }
void p_rgb_read(p_win *w, unsigned char *rgbs, int x0, int y0, int x1, int y1) { HDC dc = w_getdc(w, 0); x1 -= x0; y1 -= y0; if (dc) { BITMAPINFO bmi; HDC bmdc; HBITMAP bm; DWORD *bmrgb = wbm_alloc(dc, wbm_head(&bmi, x1, y1, 32), &bmdc, &bm); if (bmrgb) { int i; long j, npix = (long)x1 * (long)y1; BitBlt(bmdc, 0, 0, x1, y1, dc, x0, y0, SRCCOPY); for (j=0 ; j<npix ; j+=x1) { for (i=0 ; i<x1 ; i++,rgbs+=3) { rgbs[0] = GetBValue(bmrgb[i+j]); /* yes, backwards */ rgbs[1] = GetGValue(bmrgb[i+j]); rgbs[2] = GetRValue(bmrgb[i+j]); } } wbm_free(bmdc, bm); } } }
void p_ellipse(p_win *w, int x0, int y0, int x1, int y1, int border) { HDC dc = w_getdc(w, border? 18 : 12); if (dc) Ellipse(dc, x0, y0, x1+1+(!border), y1+1+(!border)); }
/* ARGSUSED */ void p_fill(p_win *w, int convexity) { int n = w_pt_count; HDC dc = w_getdc(w, 12); if (dc) { /* SetPolyFillMode(dc, ALTERNATE); */ Polygon(dc, w_pt_list, n); } }
void p_text(p_win *w, int x0, int y0, const char *text, int n) { HDC dc = w_getdc(w, 1); if (dc) { int i; if (n <= 0) n = 16350; for (i=0 ; i<n ; i++) if (!text[i]) break; n = i; if (!w->orient) { TextOut(dc, x0, y0, text, n); } else { /* only do this with opaque background, * since only 8x8 patterned brushes supported under Win95 * (could read screen, rotate, TextOut, rotate back) */ TEXTMETRIC tm; SIZE sz; if (n>0 && GetTextMetrics(dc, &tm) && GetTextExtentPoint32(dc, text, n, &sz) && sz.cx>0) { int width = sz.cx; int height = tm.tmHeight + 1; int base = tm.tmAscent; int scandx = ((width-1)/(8*sizeof(DWORD)) + 1)*(8*sizeof(DWORD)); int scandy = ((height-1)/(8*sizeof(DWORD)) + 1)*(8*sizeof(DWORD)); HDC offdc = CreateCompatibleDC(dc); HBITMAP offbm = CreateCompatibleBitmap(dc, scandx, scandy); HFONT font = GetCurrentObject(dc, OBJ_FONT); void *monodat = p_malloc(scandx*scandy/4); void *monorot = (char *)monodat + (scandx*scandy/8); struct { BITMAPINFOHEADER bmiHeader; DWORD bmiColors[2]; } mono; mono.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); mono.bmiHeader.biWidth = scandx; mono.bmiHeader.biHeight = -scandy; mono.bmiHeader.biPlanes = 1; mono.bmiHeader.biBitCount = 1; mono.bmiHeader.biCompression = BI_RGB; mono.bmiHeader.biSizeImage = 0; mono.bmiHeader.biXPelsPerMeter = 0; mono.bmiHeader.biYPelsPerMeter = 0; mono.bmiHeader.biClrUsed = 0; mono.bmiHeader.biClrImportant = 0; /* apparently, bmiColors ignored on read * -white bits are set, black bits reset no matter what */ mono.bmiColors[0] = RGB(0,0,0); mono.bmiColors[1] = RGB(255,255,255); if (offdc && offbm && font && monodat) { RECT r; SelectObject(offdc, offbm); SelectObject(offdc, font); SetBkMode(offdc, TRANSPARENT); SetTextColor(offdc, RGB(255,255,255)); SetTextAlign(offdc, TA_LEFT | TA_BASELINE | TA_NOUPDATECP); r.left = r.top = 0; r.right = scandx; r.bottom = scandy; FillRect(offdc, &r, GetStockObject(BLACK_BRUSH)); if (w->orient == 2) { TextOut(offdc, scandx-width, base, text, n); } else if (w->orient == 1) { TextOut(offdc, scandx-width, base, text, n); } else { TextOut(offdc, 0, scandy-height+base, text, n); } GetDIBits(offdc, offbm, 0, scandy, monodat, (BITMAPINFO *)&mono, DIB_RGB_COLORS); } if (offdc) DeleteDC(offdc); if (offbm) DeleteObject(offbm); if (monodat) { COLORREF bg = w_color(w,w->bg); COLORREF fg = w_color(w,w->color); if (w->orient == 2) { p_mrot180(monodat, monorot, scandx, height); x0 -= width-1; y0 -= (height-base)-1; scandx = width, width = height, height = scandx; } else if (w->orient == 1) { p_mrot090(monodat, monorot, scandx, scandy); x0 -= base; y0 -= width-1; } else { p_mrot270(monodat, monorot, scandx, scandy); x0 -= (height-base)-1; } mono.bmiColors[0] = W_SWAPRGB(bg); mono.bmiColors[1] = W_SWAPRGB(fg); mono.bmiHeader.biWidth = height; mono.bmiHeader.biHeight = -width; /* prefer this to SetDIBitsToDevice? */ StretchDIBits(dc, x0, y0, height, width, 0, 0, height, width, monorot, (BITMAPINFO *)&mono, DIB_RGB_COLORS, SRCCOPY); p_free(monodat); } } } } }
static void w_cell(p_win *w, unsigned char *ndxs, unsigned char *rgbs, int ncols, int nrows, int x0, int y0, int x1, int y1) { /* huge effort here failed to make 8-bit DIBs work when the * system is set to 256-color mode (w->s->sys_pal!=0) * -- expect this to perform poorly in that mode */ HDC dc = w_getdc(w, 0); if (dc) { struct { BITMAPINFOHEADER bmih; WORD ndx[256]; } h; BITMAPINFO *bmi = (BITMAPINFO *)&h; int nbits = (w->s->sys_pal && w->palette)? 8 : 32; HDC bmdc; HBITMAP bm; DWORD *bmrgb = wbm_alloc(dc, wbm_head(bmi, ncols, nrows, nbits), &bmdc, &bm); if (bmrgb) { long i, j; if (nbits == 8) { unsigned int offset = w->s->sys_offset; COLORREF cr, *sys_index = w->s->sys_index; int n = w->rgb_mode? 225 : (w->parent? w->parent->n_pixels : w->n_pixels); for (i=0 ; i<n ; i++) h.ndx[i] = (WORD)(offset + i); for (; i<=P_EXTRA ; i++) h.ndx[i] = 0; /* black */ for (; i<256 ; i++) { cr = w->s->sys_index[255-i] & 0xff; if (cr < offset) h.ndx[i] = (WORD)cr; else h.ndx[i] = (WORD)(n+(cr & 0xff)); } } if (ndxs) { if (nbits != 8) { long npix = (long)ncols * (long)nrows; COLORREF pxl, *pixels = w->parent? w->parent->pixels : w->pixels; for (j=0 ; j<npix ; j+=ncols) { for (i=0 ; i<ncols ; i++,ndxs++) { pxl = pixels[ndxs[0]]; bmrgb[i+j] = W_SWAPRGB(pxl); /* yes, backwards */ } } } else { int nc = (ncols+3) & ~3; long npix = (long)nc * (long)nrows; unsigned char *bmbyt = (unsigned char *)bmrgb; for (j=0 ; j<npix ; j+=nc) { for (i=0 ; i<ncols ; i++,ndxs++) bmbyt[i+j] = ndxs[0]; } } } else { if (nbits != 8) { long npix = (long)ncols * (long)nrows; for (j=0 ; j<npix ; j+=ncols) { for (i=0 ; i<ncols ; i++,rgbs+=3) bmrgb[i+j] = RGB(rgbs[2],rgbs[1],rgbs[0]); /* yes, backwards */ } } else { int nc = (ncols+3) & ~3; long npix = (long)nc * (long)nrows; unsigned char *bmbyt = (unsigned char *)bmrgb; unsigned int r, g, b; for (j=0 ; j<npix ; j+=nc) { for (i=0 ; i<ncols ; i++,rgbs+=3) { r = rgbs[0], g = rgbs[1], b = rgbs[2]; r = (r+32)>>6; g = (g+16)>>5; b = (b+32)>>6; g += b+(b<<3); bmbyt[i+j] = (unsigned char)(r+g+(g<<2)); } } } } StretchDIBits(dc, x0, y0, x1-x0, y1-y0, 0, 0, ncols, nrows, bmrgb, bmi, nbits!=8? DIB_RGB_COLORS : DIB_PAL_COLORS, SRCCOPY); wbm_free(bmdc, bm); } } }