Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Nine Patch - Drawing issue

This thread is locked; no one can reply to it. rss feed Print
Nine Patch - Drawing issue
DanielH
Member #934
January 2001
avatar

Hello,

I'm trying to create a nine patch drawer and am having troubles. The problem is with using al_draw_scaled_bitmap. I am scaling a 1 px wide section of a bitmap and there is bleed over.

{"name":"606365","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/d\/ad6025472b156cc8f3b7f66bfae959ce.png","w":440,"h":220,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/d\/ad6025472b156cc8f3b7f66bfae959ce"}606365

The box on the left is what is being drawn. The box on the right is what is supposed to happen. If the bitmap's scalable area > 1 then there is no issue.

I attached 'button.bmp'

ALLEGRO_BITMAP *button = al_load_bitmap( "button.bmp" )
dNinePatchBitmap *nine = dNinePatchBitmap::create( button );

nine->draw( 200, 100, 200, 200 );

dNinePatchBitmap.h

#SelectExpand
1#ifndef _D_NINEPATCHBITMAP_H 2#define _D_NINEPATCHBITMAP_H 3 4#include <allegro5/allegro.h> 5#include <allegro5/allegro_image.h> 6 7class dNinePatchBitmap 8{ 9public: 10 static dNinePatchBitmap* create( ALLEGRO_BITMAP *bitmap, int x1 = -1, int y1 = -1, int x2 = -1, int y2 = -1 ); 11 ~dNinePatchBitmap(); 12 void draw( int x, int y, int w, int h ); 13 14 ALLEGRO_BITMAP *mBitmap; 15 16 int mWidth; 17 int mHeight; 18 int mStartX1; 19 int mStartX2; 20 int mStartY1; 21 int mStartY2; 22 23private: 24 dNinePatchBitmap(); 25}; 26 27#endif

dNinePatchBitmap.cpp

#SelectExpand
1#include "dNinePatchBitmap.h" 2 3dNinePatchBitmap::dNinePatchBitmap() 4{ 5 this->mBitmap = 0; 6 this->mWidth = 0; 7 this->mHeight = 0; 8 this->mStartX1 = 0; 9 this->mStartX2 = 0; 10 this->mStartY1 = 0; 11 this->mStartY2 = 0; 12} 13 14dNinePatchBitmap::~dNinePatchBitmap() 15{ 16 if ( this->mBitmap ) 17 { 18 al_destroy_bitmap( this->mBitmap ); 19 } 20} 21 22dNinePatchBitmap* dNinePatchBitmap::create( ALLEGRO_BITMAP *bitmap, int x1, int y1, int x2, int y2 ) 23{ 24 dNinePatchBitmap* ninePatch = 0; 25 26 if ( bitmap ) 27 { 28 if ( x1 == -1 ) { x1 = 0; }; 29 if ( y1 == -1 ) { y1 = 0; }; 30 if ( x2 == -1 ) { x2 = al_get_bitmap_width( bitmap ) - 1; }; 31 if ( y2 == -1 ) { y2 = al_get_bitmap_height( bitmap ) - 1; }; 32 33 ninePatch = new dNinePatchBitmap(); 34 35 if ( ninePatch ) 36 { 37 ninePatch->mWidth = ( x2 - x1 ); 38 ninePatch->mHeight = ( y2 - y1 ); 39 ninePatch->mBitmap = al_create_bitmap( ninePatch->mWidth, ninePatch->mHeight ); 40 41 if ( ninePatch->mBitmap ) 42 { 43 unsigned char r = 0; 44 unsigned char g = 0; 45 unsigned char b = 0; 46 ALLEGRO_BITMAP *target = al_get_target_bitmap(); 47 48 al_set_target_bitmap( ninePatch->mBitmap ); 49 50 al_draw_bitmap_region( bitmap, x1 + 1, y1 + 1, ninePatch->mWidth, ninePatch->mHeight, 0, 0, 0 ); 51 52 al_lock_bitmap( ninePatch->mBitmap, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY ); 53 54 for ( int i = 0; i <= ninePatch->mWidth; i++ ) 55 { 56 al_unmap_rgb( al_get_pixel( bitmap, x1 + i, 0 ), &r, &g, &b ); 57 58 if ( r == 0 && g == 0 && b == 0 ) 59 { 60 ninePatch->mStartX1 = i - 1; 61 break; 62 } 63 } 64 65 for ( int i = ninePatch->mStartX1 + 1; i <= ninePatch->mWidth; i++ ) 66 { 67 al_unmap_rgb( al_get_pixel( bitmap, x1 + i, 0 ), &r, &g, &b ); 68 69 if ( !( r == 0 && g == 0 && b == 0 ) ) 70 { 71 break; 72 } 73 74 ninePatch->mStartX2 = i; 75 } 76 77 for ( int j = 0; j <= ninePatch->mHeight; j++ ) 78 { 79 al_unmap_rgb( al_get_pixel( bitmap, 0, y1 + j ), &r, &g, &b ); 80 81 if ( r == 0 && g == 0 && b == 0 ) 82 { 83 ninePatch->mStartY1 = j - 1; 84 break; 85 } 86 } 87 88 for ( int j = ninePatch->mStartY1 + 1; j <= ninePatch->mHeight; j++ ) 89 { 90 al_unmap_rgb( al_get_pixel( bitmap, 0, y1 + j ), &r, &g, &b ); 91 92 if ( !( r == 0 && g == 0 && b == 0 ) ) 93 { 94 break; 95 } 96 97 ninePatch->mStartY2 = j; 98 } 99 100 al_unlock_bitmap( ninePatch->mBitmap ); 101 102 103 al_convert_mask_to_alpha( ninePatch->mBitmap, al_map_rgb( 255, 0, 255 ) ); 104 105 al_set_target_bitmap( target ); 106 } 107 else 108 { 109 delete ninePatch; 110 } 111 } 112 } 113 114 return ninePatch; 115} 116 117void dNinePatchBitmap::draw( int x, int y, int w, int h ) 118{ 119// s e 120// ........----------....... 121// 0123456789012345678901234 122// 1 2 3 123 124 int x1 = 0; 125 int x2 = this->mStartX1; 126 int x3 = this->mStartX2; 127 128 int y1 = 0; 129 int y2 = this->mStartY1; 130 int y3 = this->mStartY2; 131 132 int w1 = ( x2 - x1 ); 133 int w2 = ( x3 - x2 ); 134 int w3 = ( this->mWidth - x3 ); 135 136 int h1 = ( y2 - y1 ); 137 int h2 = ( y3 - y2 ); 138 int h3 = ( this->mHeight - y3 ); 139 140 int stretchW = w - ( w1 + w3 ); 141 int stretchH = h - ( h1 + h3 ); 142 143 // upper left 144 al_draw_bitmap_region( this->mBitmap, x1, y1, w1, h1, x, y, 0 ); 145 146 // upper right 147 al_draw_bitmap_region( this->mBitmap, x3, y1, w3, h1, x + w - w3, y, 0 ); 148 149 // lower left 150 al_draw_bitmap_region( this->mBitmap, x1, y3, w1, h1, x, y + h - h3, 0 ); 151 152 // lower right 153 al_draw_bitmap_region( this->mBitmap, x3, y3, w3, h1, x + w - w3, y + h - h3, 0 ); 154 155 // upper middle 156 al_draw_scaled_bitmap( this->mBitmap, x2, y1, w2, h1, x + x2, y, stretchW, h1, 0 ); 157 158 // middle left 159 al_draw_scaled_bitmap( this->mBitmap, x1, y2, w1, h2, x, y + y2, w1, stretchH, 0 ); 160 161 162 // lower middle 163 al_draw_scaled_bitmap( this->mBitmap, x2, y3, w2, h3, x + x2, y + h - h3, stretchW, h3, 0 ); 164 165 // middle right 166 al_draw_scaled_bitmap( this->mBitmap, x3, y2, w3, h2, x + w - w3, y + y2, w3, stretchH, 0 ); 167 168 // middle 169 al_draw_scaled_bitmap( this->mBitmap, x2, y2, w2, h2, x + x2, y + y2, stretchW, stretchH, 0 ); 170}

Any ideas to fix this would be appreciated.

Matthew Leverton
Supreme Loser
January 1999
avatar

You could write a C++ class over my C implementation. It supports multiple stretchable areas.

Specter Phoenix
Member #1,425
July 2001
avatar

Thought you were long gone Daniel :o.

DanielH
Member #934
January 2001
avatar

I was gone. I changed career paths. I just graduated from pharmacy school and am now a pharmacist.

Now I have a little more free time than I had and am trying to learn Allegro5.

You could write a C++ class over my C implementation ...

Thank you, I'll look through it.

GullRaDriel
Member #3,861
September 2003
avatar

Hell, whatever you do, you know on day you will be coming back to Allegro ^^

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Go to: