void cdfSimPutImageRectRGBA(cdCanvas* canvas, int iw, int ih, const unsigned char *r, const unsigned char *g, const unsigned char *b, const unsigned char *a, double x, double y, double w, double h, int xmin, int xmax, int ymin, int ymax) { int size, i, j, dst, src, *fx, *fy, rw, rh; unsigned char *ar, *ag, *ab, al; int zw = _cdRound(w); int zh = _cdRound(h); (void)ih; size = zw * zh; ar = (unsigned char*)malloc(size * 3); if (!ar) return; ag = ar + size; ab = ag + size; canvas->cxGetImageRGB(canvas->ctxcanvas, ar, ag, ab, _cdRound(x), _cdRound(y), zw, zh); rw = xmax - xmin + 1; rh = ymax - ymin + 1; fx = cdGetZoomTable(zw, rw, xmin); fy = cdGetZoomTable(zh, rh, ymin); for (j = 0; j < zh; j++) { for (i = 0; i < zw; i++) { dst = j * zw + i; src = fy[j] * iw + fx[i]; al = a[src]; ar[dst] = CD_ALPHA_BLEND(r[src], ar[dst], al); ag[dst] = CD_ALPHA_BLEND(g[src], ag[dst], al); ab[dst] = CD_ALPHA_BLEND(b[src], ab[dst], al); } } canvas->cxFPutImageRectRGB(canvas->ctxcanvas, zw, zh, ar, ag, ab, x, y, w, h, 0, 0, 0, 0); free(ar); free(fx); free(fy); }
void cdSimPutImageRectRGBA(cdCanvas* canvas, int iw, int ih, const unsigned char *r, const unsigned char *g, const unsigned char *b, const unsigned char *a, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax) { int size, i, j, dst, src, *fx, *fy, rw, rh; unsigned char *ar, *ag, *ab, al; (void)ih; size = w * h; ar = (unsigned char*)malloc(size*3); if (!ar) return; ag = ar + size; ab = ag + size; canvas->cxGetImageRGB(canvas->ctxcanvas, ar, ag, ab, x, y, w, h); rw = xmax-xmin+1; rh = ymax-ymin+1; fx = cdGetZoomTable(w, rw, xmin); fy = cdGetZoomTable(h, rh, ymin); for (j = 0; j < h; j++) { for (i = 0; i < w; i++) { dst = j * w + i; src = fy[j] * iw + fx[i]; al = a[src]; ar[dst] = CD_ALPHA_BLEND(r[src], ar[dst], al); ag[dst] = CD_ALPHA_BLEND(g[src], ag[dst], al); ab[dst] = CD_ALPHA_BLEND(b[src], ab[dst], al); } } canvas->cxPutImageRectRGB(canvas->ctxcanvas, w, h, ar, ag, ab, x, y, w, h, 0, 0, 0, 0); free(ar); free(fx); free(fy); }
static void simDrawTextBitmap(cdSimulation* simulation, FT_Bitmap* bitmap, int x, int y) { unsigned char *red, *green, *blue, *alpha, *bitmap_data; int width = bitmap->width; int height = bitmap->rows; int size = width*height; int rgba_data_size = size*4; int old_use_matrix = simulation->canvas->use_matrix; /* avoid spaces */ if (width == 0 || height == 0) return; if (!simulation->tt_text->rgba_data) simulation->tt_text->rgba_data = malloc(rgba_data_size); else if (rgba_data_size > simulation->tt_text->rgba_data_size) { simulation->tt_text->rgba_data = realloc(simulation->tt_text->rgba_data, rgba_data_size); simulation->tt_text->rgba_data_size = rgba_data_size; } /* disable image transformation */ simulation->canvas->use_matrix = 0; /* this is the char bitmap, contains an alpha map of the char to be combined with the foreground color */ bitmap_data = bitmap->buffer + (height-1)*width; /* bitmap is top down. */ /* this is the image used to draw the char with the foreground color */ red = simulation->tt_text->rgba_data; green = red + size; blue = green + size; alpha = blue + size; if (!simulation->canvas->cxPutImageRectRGBA && !simulation->canvas->cxGetImageRGB) { int i, j; unsigned char bg_red, bg_green, bg_blue, fg_red, fg_green, fg_blue, fg_alpha, calpha; long int c; /* must manually combine using only the background color, ignore canvas contents */ c = simulation->canvas->background; bg_red = cdRed(c); bg_green = cdGreen(c); bg_blue = cdBlue(c); c = simulation->canvas->foreground; fg_red = cdRed(c); fg_green = cdGreen(c); fg_blue = cdBlue(c); fg_alpha = cdAlpha(c); for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { if (simulation->antialias) { if (fg_alpha == 255) calpha = bitmap_data[j]; else calpha = (fg_alpha*bitmap_data[j])/255; } else { if (bitmap_data[j] > 128) /* behave as 255 */ calpha = fg_alpha; else calpha = 0; } *red++ = CD_ALPHA_BLEND(fg_red, bg_red, calpha); *green++ = CD_ALPHA_BLEND(fg_green, bg_green, calpha); *blue++ = CD_ALPHA_BLEND(fg_blue, bg_blue, calpha); } bitmap_data -= width; } /* reset pointers */ red = simulation->tt_text->rgba_data; green = red + size; blue = green + size; /* draw the char */ simulation->canvas->cxPutImageRectRGB(simulation->canvas->ctxcanvas, width,height,red,green,blue,x,y,width,height,0,width-1,0,height-1); } else { int i, j; long int fg = simulation->canvas->foreground; unsigned char fg_alpha = cdAlpha(fg); memset(red, cdRed(fg), size); memset(green, cdGreen(fg), size); memset(blue, cdBlue(fg), size); /* alpha is the bitmap_data itself if the foreground color does not contains alpha. Also must invert since it is top-down. */ for (i = 0; i < height; i++) { if (simulation->antialias) { if (fg_alpha == 255) { memcpy(alpha, bitmap_data, width); alpha += width; } else { for (j = 0; j < width; j++) { *alpha++ = (fg_alpha*bitmap_data[j])/255; } } } else { for (j = 0; j < width; j++) { if (bitmap_data[j] > 128) /* behave as 255 */ *alpha++ = fg_alpha; else *alpha++ = 0; } } bitmap_data -= width; } /* reset alpha pointer */ alpha = blue + size; /* draw the char */ simulation->canvas->cxPutImageRectRGBA(simulation->canvas->ctxcanvas, width,height,red,green,blue,alpha,x,y,width,height,0,width-1,0,height-1); } simulation->canvas->use_matrix = old_use_matrix; }
void cdwDIBEncodeRGBARectZoom(cdwDIB* dib, const unsigned char *red, const unsigned char *green, const unsigned char *blue, const unsigned char *alpha, int w, int h, int xi, int yi, int wi, int hi) { int x,y, resto1, resto2, offset; BYTE* bits; const unsigned char *_red, *_green, *_blue, *_alpha; unsigned char a; bits = dib->bits; resto1 = cdwDIBLineSize(dib->w, 24) - dib->w * 3; if (dib->w != wi || dib->h != hi) { int* XTab = cdGetZoomTable(dib->w, wi, xi); int* YTab = cdGetZoomTable(dib->h, hi, yi); for (y = 0; y < dib->h; y++) { offset = YTab[y] * w; _red = red + offset; _green = green + offset; _blue = blue + offset; _alpha = alpha + offset; for (x = 0; x < dib->w; x++) { offset = XTab[x]; a = _alpha[offset]; *bits++ = CD_ALPHA_BLEND(_blue[offset], *bits, a); *bits++ = CD_ALPHA_BLEND(_green[offset], *bits, a); *bits++ = CD_ALPHA_BLEND(_red[offset], *bits, a); } bits += resto1; } free(XTab); free(YTab); } else { resto2 = w - wi; offset = w * yi + xi; red = red + offset; green = green + offset; blue = blue + offset; alpha = alpha + offset; for (y = 0; y < dib->h; y++) { for (x = 0; x < dib->w; x++) { a = *alpha++; *bits++ = CD_ALPHA_BLEND(*blue++, *bits, a); *bits++ = CD_ALPHA_BLEND(*green++, *bits, a); *bits++ = CD_ALPHA_BLEND(*red++, *bits, a); } bits += resto1; red += resto2; green += resto2; blue += resto2; alpha += resto2; } } }