예제 #1
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);
        }
      }
    }
  }
예제 #2
0
MyCanvas::MyCanvas(const GBitmap& bitmap):
	Bitmap(bitmap),
	BmpRect(GIRect::MakeWH(bitmap.width(), bitmap.height())),
	CTM()
{
  /* Push the identity matrix onto the matrix stack */
  MatrixStack.push(CTM);
}
예제 #3
0
파일: image.cpp 프로젝트: msarett/575
static void draw_bitmaps(GCanvas* canvas) {
    GBitmap tex;
    tex.readFromFile("spock_png");

    canvas->fillRectBitmap(GRect::MakeWH(tex.width(), tex.height()), tex);
    canvas->fillRectBitmap(GRect::MakeLTRB(10, 140, 138, 500), tex);
    canvas->fillRectBitmap(GRect::MakeLTRB(140, 10, 500, 138), tex);
    canvas->fillRectBitmap(GRect::MakeXYWH(256, 256, 512, 512), tex);
}
예제 #4
0
 void scaleAboutCenter(GContext* ctx) {
     GBitmap bm;
     ctx->getBitmap(&bm);
     
     float cx = bm.width() * 0.5f;
     float cy = bm.height() * 0.5f;
     
     ctx->translate(cx, cy);
     ctx->scale(fScale, fScale);
     ctx->translate(-cx, -cy);
 }
예제 #5
0
static void draw_ramp(const GBitmap& bitmap) {
    const float g0 = 0;
    const float g1 = 255;
    const float dg = (g1 - g0) / bitmap.width();

    const float b0 = 0;
    const float b1 = 255;
    const float db = (b1 - b0) / bitmap.height();

    GPixel* dst = bitmap.fPixels;
    float g = g0 + dg/2;
    for (int y = 0; y < bitmap.height(); ++y) {
        float b = b0 + db/2;
        for (int x = 0; x < bitmap.width(); ++x) {
            dst[x] = GPixel_PackARGB(0xFF, 0, (int)g, (int)b);
            b += db;
        }
        g += dg;
        dst = (GPixel*)((char*)dst + bitmap.rowBytes());
    }
}
예제 #6
0
static void draw_circle(const GBitmap& bitmap) {
    const GPixel px = GPixel_PackARGB(0xFF, 0xFF, 0, 0);
    const float cx = (float)bitmap.width() / 2;
    const float cy = (float)bitmap.height() / 2;
    const float radius = cx * 5 / 6;
    const float radius2 = radius * radius;
    
    GPixel* dst = bitmap.pixels();
    for (int y = 0; y < bitmap.height(); ++y) {
        const float dy = y - cy;
        for (int x = 0; x < bitmap.width(); ++x) {
            const float dx = x - cx;
            const float dist2 = dx*dx + dy*dy;
            if (dist2 <= radius2) {
                dst[x] = px;
            } else {
                dst[x] = 0; // transparent
            }
        }
        dst = (GPixel*)((char*)dst + bitmap.rowBytes());
    }
}
예제 #7
0
파일: xapp.cpp 프로젝트: Mokosha/COMP590
 PolyShape(const GBitmap& bm, int x, int y) : Shape(x, y) {
     fCount = gRand.nextRange(3, 20);
     fPts = new GPoint[fCount];
     
     float scaleX = bm.width() * .5f;
     float scaleY = bm.height() * .5f;
     for (int i = 0; i < fCount; ++i) {
         float angle = i * 2 * 3.14159265359 / fCount;
         float sv, cv;
         cv = cos_sin(angle, &sv);
         fPts[i].set(scaleX * sv, scaleY * cv);
     }
     fPaint.setRGB(gRand.nextF(), gRand.nextF(), gRand.nextF());
 }
예제 #8
0
static void make_circle(const GBitmap& bitmap, const GColor& color) {
    const GPixel px = pin_and_premul_to_pixel(color);
    
    const float cx = (float)bitmap.width() / 2;
    const float cy = (float)bitmap.height() / 2;
    const float radius = cx - 1;
    const float radius2 = radius * radius;
    
    GPixel* dst = bitmap.pixels();
    for (int y = 0; y < bitmap.height(); ++y) {
        const float dy = y - cy;
        for (int x = 0; x < bitmap.width(); ++x) {
            const float dx = x - cx;
            const float dist2 = dx*dx + dy*dy;
            if (dist2 <= radius2) {
                dst[x] = px;
            } else {
                dst[x] = 0; // transparent
            }
        }
        dst = (GPixel*)((char*)dst + bitmap.rowBytes());
    }
}
예제 #9
0
/*
 *  The bitmap has already been sized and allocated. This function's job is to fill in the
 *  pixels to create the custom image. See src/image.cpp for examples.
 */
void cs575_draw_into_bitmap(const GBitmap& bitmap) {
    //
    // Your code goes here
    //
  const float rx = 200;
  const float ry = 50;
  const float rz = (rx - ry)/bitmap.width();

  const float bx = 50;
  const float by = 200;
  const float bz = (by - bx)/bitmap.width();

  GPixel* dst = bitmap.fPixels;
  float r = rx + rz/4;
  for (int y = 0; y < bitmap.height(); ++y) {
  	float b = bx + bz/4;
	for (int x = 0; x < bitmap.width(); ++x) {
		dst[x] = GPixel_PackARGB(0xFF, (int)r, 0, (int)b);
		b += bz;
	}
	r += rz;
	dst = (GPixel*)((char*)dst + bitmap.rowBytes());
  }
}
예제 #10
0
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;
}
예제 #11
0
파일: xapp.cpp 프로젝트: Mokosha/COMP590
static void fill_circle(const GBitmap& bm) {
    int w = bm.width();
    int h = bm.height();
    int r = (w < h ? w : h) >> 1;
    float cx = w/2;
    float cy = h/2;
    float rr = (float)r * r;

    GPixel* row = bm.fPixels;
    for (int y = 0; y < h; ++y) {
        float dy2 = (y - cy) * (y - cy);
        for (int x = 0; x < w; ++x) {
            float dx2 = (x - cx) * (x - cx);
            if (dx2 + dy2 > rr) {
                row[x] = 0;
            }
        }
        row = next_row(bm, row);
    }
}
예제 #12
0
파일: xapp.cpp 프로젝트: Mokosha/COMP590
 RectShape(const GBitmap& bm, int x, int y) : Shape(x, y) {
     fRect.setXYWH(x, y, bm.width(), bm.height());
     fRect.offset(-fRect.centerX(), -fRect.centerY());
     fPaint.setRGB(gRand.nextF(), gRand.nextF(), gRand.nextF());
 }
예제 #13
0
	/**
	 *	Scale and translate the bitmap such that is fills the specific rectangle.
	 *
	 *	Any area in the rectangle that is outside of the bounds of the canvas is ignored.
	 *
	 *	If a given pixel in the bitmap is not opaque (e.g. GPixel_GetA() < 255) then blend it
	 *	using SRCOVER blend mode.
	 */
	void fillBitmapRect(const GBitmap& src, const GRect& dst) {
		// Store dimensions of dst rectangle
		int left = dst.left();
		int top = dst.top();
		int right = dst.right();
		int bottom = dst.bottom();
		int rW = dst.width();
		int rH = dst.height();

		// Store dimensions of src bitmap
		int bW = src.width();
		int bH = src.height();

		// Find necessary scale factor for both width and height
		float sx = (float)bW/(float)rW;
		float sy = (float)bH/(float)rH;

		float tx = 0 - left;
		float ty = 0 - top;

		// Create matrix for scaling
		float scale[6] = 
			{sx, 0, 0, 
			 0, sy, 0};

		// Create matrix for translating
		float translate[6] =
			{1, 0, tx,
			 0, 1, ty};

		// Combine the matrices
		float both[6] = 
			{sx, 0, sx*tx,
			 0, sy, sy*ty};

		// For loop that takes each point in dst and find corresponding point in src
		GPixel* d = draw.fPixels;
		d = (GPixel*)((char*)d + (int)top * draw.rowBytes());
		for (int y = top; y < bottom; ++y) {
			for (int x = left; x < right; ++x) {
				// Only map pixels that are in the bitmap
				if ((x >= 0 && x < draw.width()) && (y >= 0 && y < draw.height())) {
					// Find corresponding point in src bitmap
					int xP;
					int yP;

					xP = both[0] * x + both[1] * y + both[2];
					yP = both[3] * x + both[4] * y + both[5];

					// Apply CTM to x and y
					int nX = (CTM[0] * x) + (CTM[1] * y) + (CTM[2]);
					int nY = (CTM[3] * x) + (CTM[4] * y) + (CTM[5]);

					// Prepare color to fill
					unsigned a = GPixel_GetA(*src.getAddr(xP, yP));
					unsigned r = GPixel_GetR(*src.getAddr(xP, yP));
					unsigned g = GPixel_GetG(*src.getAddr(xP, yP));
					unsigned b = GPixel_GetB(*src.getAddr(xP, yP));

					unsigned nA = a;
					unsigned nR = r;
					unsigned nG = g;
					unsigned nB = b;

					if (GPixel_GetA(*draw.getAddr(x, y)) > 0) {
	    	    		// blend
						float lA = GPixel_GetA(*src.getAddr(xP, yP)) / 255.99999;
						float lR = GPixel_GetR(*src.getAddr(xP, yP)) / 255.99999;
						float lG = GPixel_GetG(*src.getAddr(xP, yP)) / 255.99999;
						float lB = GPixel_GetB(*src.getAddr(xP, yP)) / 255.99999;

						
						float sA = lA + ((GPixel_GetA(*draw.getAddr(x, y)) / 255.99999) * (1.0f - lA));
						float sR = lR + ((GPixel_GetR(*draw.getAddr(x, y)) / 255.99999) * (1.0f - lA));
						float sG = lG + ((GPixel_GetG(*draw.getAddr(x, y)) / 255.99999) * (1.0f - lA));
						float sB = lB + ((GPixel_GetB(*draw.getAddr(x, y)) / 255.99999) * (1.0f - lA));
						

						/*
						float sA = lA + ((GPixel_GetA(*draw.getAddr(nX, nY)) / 255.99999) * (1.0f - lA));
						float sR = lR + ((GPixel_GetR(*draw.getAddr(nX, nY)) / 255.99999) * (1.0f - lA));
						float sG = lG + ((GPixel_GetG(*draw.getAddr(nX, nY)) / 255.99999) * (1.0f - lA));
						float sB = lB + ((GPixel_GetB(*draw.getAddr(nX, nY)) / 255.99999) * (1.0f - lA));
						*/
										
						nA = (int)(sA * 255.99999);
						nR = (int)(sR * 255.99999);
						nG = (int)(sG * 255.99999);
						nB = (int)(sB * 255.99999);

	    	    		d[x] = GPixel_PackARGB(nA, nR, nG, nB);
	    	    		//d = (GPixel*)((char*)d + (int)nY * draw.rowBytes());
	    	    		//d[nX] = GPixel_PackARGB(nA, nR, nG, nB);
	    	    		//d = (GPixel*)((char*)d - (int)nY * draw.rowBytes());
    	    		} else {
    	    			d[x] = GPixel_PackARGB(a, r, g, b);
    	    			//d = (GPixel*)((char*)d + (int)nY * draw.rowBytes());
	    	    		//d[nX] = GPixel_PackARGB(a, r, g, b);
	    	    		//d = (GPixel*)((char*)d - (int)nY * draw.rowBytes());
    	    		}	    		
				}
			}
			d = (GPixel*)((char*)d + draw.rowBytes());
		}
	}
예제 #14
0
 BitmapShape(const GBitmap& bm) : fBM(bm) {
     const int w = std::max(bm.width(), 100);
     const int h = std::max(bm.height(), 100);
     fRect = GRect::MakeXYWH(100, 100, w, h);
 }
예제 #15
0
  // This code draws a bitmap assuming that we only have translation and scale,
  // which allows us to perform certain optimizations...
  void drawBitmapSimple(const GBitmap &bm, const GPaint &paint) {
    const GBitmap &ctxbm = GetInternalBitmap();
    GRect ctxRect = GRect::MakeXYWH(0, 0, ctxbm.width(), ctxbm.height());
    GRect bmRect = GRect::MakeXYWH(0, 0, bm.width(), bm.height());
    GRect pixelRect = GetTransformedBoundingBox(bmRect);

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

    // We know that since we're only doing scale and translation, that all of the pixel
    // centers contained in rect are going to be drawn, so we only need to know the
    // dimensions of the mapping...
    GVec3f origin(0, 0, 1);
    GVec3f offset(1, 1, 1);

    origin = m_CTM * origin;
    offset = m_CTM * offset;

    float xScale = 1.0f / (offset.X() - origin.X());
    float yScale = 1.0f / (offset.Y() - origin.Y());

    GVec2f start = GVec2f(0, 0);
    if(xScale < 0.0f) {
      start.X() = pixelRect.fRight - 1.0f;
    }
    if(yScale < 0.0f) {
      start.Y() = pixelRect.fBottom - 1.0f;
    }

    GIRect dstRect = rect.round();

    // Construct new bitmap
    int32_t offsetX = ::std::max(0, -dstRect.fLeft);
    int32_t offsetY = ::std::max(0, -dstRect.fTop);
    GBitmap fbm;
    fbm.fWidth = bm.width();
    fbm.fHeight = bm.height();
    fbm.fPixels = GetRow(bm, offsetY) + offsetX;
    fbm.fRowBytes = bm.fRowBytes;

    BlendFunc blend = blend_srcover;

    float alpha = paint.getAlpha();
    if(alpha >= kOpaqueAlpha) {
      for(uint32_t j = 0; j < dstRect.height(); j++) {

        uint32_t srcIdxY = static_cast<uint32_t>(start.Y() + static_cast<float>(j) * yScale);
        GPixel *srcPixels = GetRow(fbm, Clamp<int>(srcIdxY, 0, fbm.height()));
        GPixel *dstPixels = GetRow(ctxbm, dstRect.fTop + j) + dstRect.fLeft;

        for(uint32_t i = 0; i < dstRect.width(); i++) {
          uint32_t srcIdxX = static_cast<uint32_t>(start.X() + static_cast<float>(i) * xScale);
          dstPixels[i] = blend(dstPixels[i], srcPixels[Clamp<int>(srcIdxX, 0, fbm.width())]);
        }
      }
    } else {
      const uint32_t alphaVal = static_cast<uint32_t>((alpha * 255.0f) + 0.5f);
      for(uint32_t j = 0; j < dstRect.height(); j++) {

        uint32_t srcIdxY = static_cast<uint32_t>(start.Y() + static_cast<float>(j) * yScale);
        GPixel *srcPixels = GetRow(fbm, srcIdxY);
        GPixel *dstPixels = GetRow(ctxbm, dstRect.fTop + j) + dstRect.fLeft;

        for(uint32_t i = 0; i < dstRect.width(); i++) {
          uint32_t srcIdxX = static_cast<uint32_t>(start.X() + static_cast<float>(i) * xScale);
          uint32_t srcA = fixed_multiply(GPixel_GetA(srcPixels[srcIdxX]), alphaVal);
          uint32_t srcR = fixed_multiply(GPixel_GetR(srcPixels[srcIdxX]), alphaVal);
          uint32_t srcG = fixed_multiply(GPixel_GetG(srcPixels[srcIdxX]), alphaVal);
          uint32_t srcB = fixed_multiply(GPixel_GetB(srcPixels[srcIdxX]), alphaVal);
          GPixel src = GPixel_PackARGB(srcA, srcR, srcG, srcB);
          dstPixels[i] = blend(dstPixels[i], src);
        }
      }
    }
  }