Ejemplo n.º 1
0
NinePatchBitmap::NinePatchBitmap(Graphics::TransparentSurface *bmp, bool owns_bitmap) {
	int i;
	uint8 r, g, b, a;

	_bmp = bmp;
	_destroy_bmp = owns_bitmap;
	_h._m.clear();
	_v._m.clear();
	_cached_dw = 0;
	_cached_dh = 0;
	_width = bmp->w - 2;
	_height = bmp->h - 2;

	if (_width <= 0 || _height <= 0)
		goto bad_bitmap;

	/* make sure all four corners are transparent */
#define _check_pixel(x, y) \
	bmp->format.colorToARGB(*(uint32 *)bmp->getBasePtr(x, y), a, r, g, b); \
	if (a != 0 && r + g + b + a != 4) goto bad_bitmap;

	_check_pixel(0,0);
	_check_pixel(bmp->w - 1, 0);
	_check_pixel(0, bmp->h - 1);
	_check_pixel(bmp->w - 1, bmp->h - 1);
#undef _check_pixel

	_padding.top = _padding.right = _padding.bottom = _padding.left = -1;

	i = 1;
	while (i < bmp->w) {
		bmp->format.colorToARGB(*(uint32 *)bmp->getBasePtr(i, bmp->h - 1), a, r, g, b);

		if (r + g + b == 0 && a == 1) {
			if (_padding.left == -1)
				_padding.left = i - 1;
			else if (_padding.right != -1)
				goto bad_bitmap;
		} else if (a == 0 || r + g + b + a == 4) {
			if (_padding.left != -1 && _padding.right == -1)
				_padding.right = bmp->w - i - 1;
		}
		++i;
	}

	i = 1;
	while (i < bmp->h) {
		bmp->format.colorToARGB(*(uint32 *)bmp->getBasePtr(bmp->w - 1, i), a, r, g, b);

		if (r + g + b == 0 && a == 1) {
			if (_padding.top == -1)
				_padding.top = i - 1;
			else if (_padding.bottom != -1)
				goto bad_bitmap;
		} else if (a == 0 || r + g + b + a == 4) {
			if (_padding.top != -1 && _padding.bottom == -1)
				_padding.bottom = bmp->h - i - 1;
		}
		++i;
	}

	if (!_h.init(bmp, false) || !_v.init(bmp, true)) {
bad_bitmap:
		_h._m.clear();
		_v._m.clear();
	}
}
Ejemplo n.º 2
0
NINE_PATCH_BITMAP *create_nine_patch_bitmap(ALLEGRO_BITMAP *bmp, bool owns_bitmap)
{
	int i;
	NINE_PATCH_BITMAP *p9;
	ALLEGRO_COLOR c;

	p9 = al_malloc(sizeof(*p9));
	p9->bmp = bmp;
	p9->destroy_bmp = owns_bitmap;
	p9->h.m = NULL;
	p9->v.m = NULL;
	p9->cached_dw = 0;
	p9->cached_dh = 0;
	p9->mutex = al_create_mutex();
	p9->width = al_get_bitmap_width(bmp) - 2;
	p9->height = al_get_bitmap_height(bmp) - 2;

	al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY);

	if (p9->width <= 0 || p9->height <= 0)
		goto bad_bitmap;

	/* make sure all four corners are transparent */
#define _check_pixel(x, y) \
	c = al_get_pixel(bmp, x, y); \
  if (c.a != 0 && c.r + c.g + c.b + c.a != 4) goto bad_bitmap;

  _check_pixel(0,0);
  _check_pixel(al_get_bitmap_width(bmp) - 1, 0);
	_check_pixel(0, al_get_bitmap_height(bmp) - 1);
	_check_pixel(al_get_bitmap_width(bmp) - 1, al_get_bitmap_height(bmp) - 1);
#undef _check_pixel

	p9->padding.top = p9->padding.right = p9->padding.bottom = p9->padding.left = -1;

	i = 1;
	while (i < al_get_bitmap_width(bmp))
	{
		c = al_get_pixel(bmp, i, al_get_bitmap_height(bmp) - 1);

		if (c.r + c.g + c.b == 0 && c.a == 1)
		{
			if (p9->padding.left == -1)
				p9->padding.left = i - 1;
			else if (p9->padding.right != -1)
				goto bad_bitmap;
		}
		else if (c.a == 0 || c.r + c.g + c.b + c.a == 4)
		{
			if (p9->padding.left != -1 && p9->padding.right == -1)
				p9->padding.right = al_get_bitmap_width(bmp) - i - 1;
		}
		++i;
	}

	i = 1;
	while (i < al_get_bitmap_height(bmp))
	{
		c = al_get_pixel(bmp, al_get_bitmap_width(bmp) - 1, i);

		if (c.r + c.g + c.b == 0 && c.a == 1)
		{
			if (p9->padding.top == -1)
				p9->padding.top = i - 1;
			else if (p9->padding.bottom != -1)
				goto bad_bitmap;
		}
		else if (c.a == 0 || c.r + c.g + c.b + c.a == 4)
		{
			if (p9->padding.top != -1 && p9->padding.bottom == -1)
				p9->padding.bottom = al_get_bitmap_height(bmp) - i - 1;
		}
		++i;
	}

	if (!init_nine_patch_side(&p9->h, bmp, 0) || !init_nine_patch_side(&p9->v, bmp, 1))
	{
bad_bitmap:
		al_destroy_mutex(p9->mutex);
		if (p9->h.m) al_free(p9->h.m);
		if (p9->v.m) al_free(p9->v.m);
		al_free(p9);
		p9 = NULL;
	}

	al_unlock_bitmap(bmp);
	return p9;
}