Пример #1
0
  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);
        }
      }
    }
  }
Пример #2
0
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;
                }
            }
        }
    }
}
Пример #3
0
  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;
    }
  }