void MyCanvas::shadeDeviceRect(const GIRect& rect, GShader* shader) { assert(shader != nullptr); if (rect.isEmpty()) { printf("Error: ShadeDeviceRect rect is empty can't draw\n"); return; } // Get dst bitmap address and offset to the rect top GPixel* DstPixels = (GPixel*)((char*)Bitmap.pixels() + Bitmap.fRowBytes * rect.top()); // Set the context of the shader to the CTM float TwoRows[6]; CTM.GetTwoRows(TwoRows); shader->setContext(TwoRows); //All rows will have the same number of pixels so we can allocate once for the whole rect int count = rect.width(); GPixel* row = new GPixel[count]; for (int y = rect.top(); y < rect.bottom(); ++y) { shader->shadeRow(rect.left(), y, count, row); blendRow(DstPixels, rect.left(), row, count); DstPixels = (GPixel*)((char*)DstPixels + Bitmap.fRowBytes); } delete[] row; }
static void srcover_rect(const GBitmap& bitmap, const GIRect& rect, const GPixel& color) { unsigned a = GPixel_GetA(color); if (0 == a) { return; } RowProc proc = (255 == a) ? src_row : srcover_row; const int width = rect.width(); for (int y = rect.top(); y < rect.bottom(); ++y) { proc(get_addr(bitmap, rect.x(), y), width, color); } }
static void src_rect(const GBitmap& bitmap, const GIRect& rect, const GPixel& color) { const int width = rect.width(); for (int y = rect.top(); y < rect.bottom(); ++y) { src_row(get_addr(bitmap, rect.x(), y), width, color); } }