void MyCanvas::shadeRect(const GRect& rect, GShader* shader) { assert(shader != nullptr); if (rect.isEmpty()) { printf("Error: ShadeRect rectangle is empty\n"); return; } /* Convert the rectangle into points, then CTM the resulting points */ auto Points = Utility::RectToPoints(rect); CTMPoints(Points); if ( !CTM.preservesRect()) //If the CTM does not preserve a rectangle, draw a polygon { auto Edges = pointsToEdges(Points); shadeDevicePolygon(Edges, shader); return; } //Convert the CTM'd points back into a rect since we know it preserves it GIRect ConvertedRect = Utility::PointsToRect(Points).round(); // Make sure rect is not an empty one and clip the edges from the bitmap with intersect if (ConvertedRect.isEmpty() || !ConvertedRect.intersect(BmpRect)) { return; } shadeDeviceRect(ConvertedRect, shader); }
void drawRect(const GRect &rect, const GPaint &p) { const GBitmap &ctxbm = GetInternalBitmap(); GRect ctxRect = GRect::MakeXYWH(0, 0, ctxbm.width(), ctxbm.height()); GRect pixelRect = GetTransformedBoundingBox(rect); if(pixelRect.isEmpty()) { return; } GRect trRect; if(!(trRect.setIntersection(ctxRect, pixelRect))) { return; } // Rein everything back into integer land GIRect dstRect = trRect.round(); if(dstRect.isEmpty()) { return; } if(!(CheckSkew(m_CTM))) { fillIRect(dstRect, p.getColor(), eBlendOp_SrcOver); return; } GPixel clearValue = ColorToPixel(p.getColor()); // If the alpha value is above this value, then it will round to // an opaque pixel during quantization. const float kOpaqueAlpha = (254.5f / 255.0f); float alpha = p.getAlpha(); // Blend func is currently just srcover BlendFunc blend = blend_srcover; for(uint32_t j = 0; j < dstRect.height(); j++) { for(uint32_t i = 0; i < dstRect.width(); i++) { GVec3f ctxPt(static_cast<float>(dstRect.fLeft + i) + 0.5f, static_cast<float>(dstRect.fTop + j) + 0.5f, 1.0f); ctxPt = m_CTMInv * ctxPt; if(ContainsPoint(rect, ctxPt[0], ctxPt[1])) { uint32_t x = static_cast<uint32_t>(ctxPt[0] - rect.fLeft); uint32_t y = static_cast<uint32_t>(ctxPt[1] - rect.fTop); GPixel *dstRow = GetRow(ctxbm, j+dstRect.fTop) + dstRect.fLeft; dstRow[i] = blend(dstRow[i], clearValue); } } } }
bool GRect::isInRect(const GRect &rc) const { if(isEmpty() || rc.isEmpty()) return false; if(xMin > rc.xMin) return false; if(xMax < rc.xMax) return false; if(yMin > rc.yMin) return false; if(yMax < rc.yMax) return false; return true; }
void MyCanvas::fillRect(const GRect& rect, const GColor& color) { if (rect.isEmpty()) { printf("Error: FillRect input rect is empty\n"); return; } GShader* shader = GShader::FromColor(color); shadeRect(rect, shader); delete shader; }
void GRect::expandRect(const GRect &rc) { if(rc.isEmpty()) return; if(isEmpty()) { set(rc.xMin, rc.yMin, rc.xMax, rc.yMax); } else set(min(xMin, rc.xMin),min(yMin, rc.yMin), max(xMax, rc.xMax),max(yMax, rc.yMax)); }
void GContext4::drawRect(const GRect& rect, const GPaint& bucket){ if((int)(bucket.getAlpha()*255 + .5) > 0){ //only do something if the alpha is greater than zero const GColor& color = bucket.getColor(); if(helper.isLegalColor(color)){ if(!rect.isEmpty()){ float rTop=rect.fTop,rBottom=rect.fBottom,rLeft=rect.fLeft,rRight=rect.fRight; mapping.vectorMult(&rLeft, &rTop); mapping.vectorMult(&rRight, &rBottom); if(rLeft>rRight){ rLeft += rRight; rRight = rLeft - rRight; rLeft = rLeft - rRight; } if (rTop > rBottom){ rTop += rBottom; rBottom = rTop - rBottom; rTop = rTop - rBottom; } int left = helper.roundToInt(rLeft); int right = helper.roundToInt(rRight); int top = helper.roundToInt(rTop); int bottom = helper.roundToInt(rBottom); helper.findIntersection(&left, &right, &top, &bottom, Btmp.fHeight, Btmp.fWidth); uint32_t storedResult = 0x01; uint32_t storedDestination = 0x01; uint32_t DstColor; uint32_t rectColor = helper.packARGB(color); char* row = ((char*) Btmp.fPixels) + top*Btmp.fRowBytes; for(int j = top; j<bottom; j++){ for(int i=left ; i<right; i++){ DstColor = *((GPixel*) row + i); if(storedDestination == DstColor){ //if we have the value already, don't do the math *((GPixel*) row + i) = storedResult; } else{ storedDestination = DstColor; storedResult = helper.blendColor(DstColor, rectColor); *((GPixel*) row + i) = storedResult; //blends the two colors } } row += Btmp.fRowBytes; } } } } }
void MyCanvas::fillBitmapRect(const GBitmap& src, const GRect& dst) { if (dst.isEmpty()) { printf("Error: FillBitmapRect dst rect is empty\n"); return; } /* Get the matrix of the conversion from src to dst rect * Use the rect to rect matrix to create bitmap shader */ auto LocalMatrix = Utility::RectToRect(GRect::MakeWH(src.width(), src.height()), dst); float localArr[6]; LocalMatrix.GetTwoRows(localArr); GShader* shader = GShader::FromBitmap(src, localArr); shadeRect(dst, shader); delete shader; }