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); } } } }
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 WalkEdges(const GEdge e1, const GEdge e2, const GPaint &paint) { const GBitmap &bm = GetInternalBitmap(); int h = bm.fHeight; int w = bm.fWidth; GASSERT(e1.p1.y() == e2.p1.y()); int startY = Clamp(static_cast<int>(e1.p1.y() + 0.5f), 0, h-1); GASSERT(e1.p2.y() == e2.p2.y()); int endY = Clamp(static_cast<int>(e1.p2.y() + 0.5f), 0, h-1); if(endY == startY) { return; } GASSERT(endY > startY); // Initialize to NAN float m1 = 0.0f/0.0f, b1; float m2 = 0.0f/0.0f, b2; bool vert1 = e1.ComputeLine(m1, b1); bool vert2 = e2.ComputeLine(m2, b2); if(m1 == 0 || m2 == 0) { return; } // Collinear? if(vert2 && vert1 && e1.p1.x() == e2.p1.x()) { return; } else if(m1 == m2 && b1 == b2) { return; } float stepX1 = vert1? 0 : 1/m1; float stepX2 = vert2? 0 : 1/m2; GPoint p1, p2; float sY = static_cast<float>(startY) + 0.5f; if(vert1) { p1.set(e1.p1.x(), sY); } else { p1.set((sY - b1) / m1, sY); } if(vert2) { p2.set(e2.p1.x(), sY); } else { p2.set((sY - b2) / m2, sY); } // Make sure that p1 is always less than p2 to avoid // doing a min/max in the inner loop if(p1.x() > p2.x()) { std::swap(p1, p2); std::swap(stepX1, stepX2); } GPixel color = ColorToPixel(paint.getColor()); BlendFunc blend = GetBlendFunc(eBlendOp_SrcOver); uint32_t nSteps = endY - startY; for(uint32_t i = 0; i < nSteps; i++) { // Since we haven't implemented clipping yet, take care // not to go beyond our bounds... const int x1 = Clamp<int>(p1.fX + 0.5f, 0, w-1); const int x2 = Clamp<int>(p2.fX + 0.5f, 0, w-1); GPixel *row = GetRow(bm, startY + i); for(int x = x1; x < x2; x++) { row[x] = blend(row[x], color); } p1.fX += stepX1; p2.fX += stepX2; } }