示例#1
0
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);
}
示例#2
0
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;
}
示例#3
0
  // This code draws a bitmap using the full m_CTM transform without any thought
  // to whether or not the transform has any special properties.
  void drawBitmapXForm(const GBitmap &bm, const GPaint &paint) {
    const GBitmap &ctxbm = GetInternalBitmap();
    GRect ctxRect = GRect::MakeXYWH(0, 0, ctxbm.width(), ctxbm.height());
    GIRect bmRect = GIRect::MakeXYWH(0, 0, bm.width(), bm.height());
    GRect pixelRect = GetTransformedBoundingBox(bmRect);

    GRect rect;
    if(!(rect.setIntersection(ctxRect, pixelRect))) {
      return;
    }

    // Rein everything back into integer land
    GIRect dstRect = rect.round();
    if(dstRect.isEmpty()) {
      return;
    }

    float alpha = paint.getAlpha();
    if(alpha >= kOpaqueAlpha) {
      for(uint32_t j = 0; j < dstRect.height(); j++) {
        for(uint32_t i = 0; i < dstRect.width(); i++) {
          drawXFormPixel(i, j, dstRect, bmRect, bm, ctxbm);
        }
      }
    } else {
      const uint32_t alphaVal = static_cast<uint32_t>((alpha * 255.0f) + 0.5f);
      for(uint32_t j = 0; j < dstRect.height(); j++) {
        for(uint32_t i = 0; i < dstRect.width(); i++) {
          drawXFormPixelWithAlpha(i, j, dstRect, bmRect, bm, ctxbm, alphaVal);
        }
      }
    }
  }
示例#4
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);
        }
      }
    }
  }