00001
00002
00003
00004 #include <OBLOB2W.H>
00005 #include <ALL.H>
00006 #include <COLCODE.H>
00007 #include <IMGFUN.H>
00008
00009
00010
00011 #define BACKGROUND_COLOR transparent_code_w
00012 #define DEFAULT_BLOB2DW_SIZE 0x2000
00013 #define DEFAULT_BLOB2DW_INC 0x200
00014
00015 Blob2DW::Blob2DW() {
00016 left_edge = top_edge = width = height = 0;
00017 alloc_size = DEFAULT_BLOB2DW_SIZE;
00018 ptr = (BitmapW *)mem_add(alloc_size);
00019 ptr->init(width, height);
00020 }
00021
00022 Blob2DW::Blob2DW( Blob2DW &b ) {
00023 left_edge = b.left_edge;
00024 top_edge = b.top_edge;
00025 width = b.width;
00026 height = b.height;
00027 alloc_size = b.alloc_size;
00028
00029 err_when( width < 0 );
00030 err_when( height < 0 );
00031
00032 ptr = (BitmapW *)mem_add(alloc_size);
00033 memcpy(ptr, b.ptr, alloc_size);
00034
00035 }
00036
00037 Blob2DW::~Blob2DW() {
00038 mem_del(ptr);
00039 }
00040
00041 Blob2DW& Blob2DW::operator=(Blob2DW &b) {
00042 left_edge = b.left_edge;
00043 top_edge = b.top_edge;
00044 width = b.width;
00045 height = b.height;
00046
00047 err_when( width < 0 );
00048 err_when( height < 0 );
00049
00050 size_t siz = BitmapW::size(width,height);
00051 if( alloc_size < siz ) {
00052 mem_del(ptr);
00053 alloc_size = b.alloc_size;
00054 ptr = (BitmapW *)mem_add(alloc_size);
00055 }
00056 memcpy(ptr, b.ptr, siz);
00057
00058
00059
00060 return *this;
00061 }
00062
00063 void Blob2DW::resize(short destLeft, short destTop, short destWidth, short destHeight) {
00064 if( width == 0 && height == 0) {
00065 size_t siz = BitmapW::size(destWidth,destHeight);
00066 if( alloc_size < siz ) {
00067 mem_del(ptr);
00068 ptr = (BitmapW *)mem_add((alloc_size = siz + DEFAULT_BLOB2DW_INC));
00069 }
00070 ptr->init(destWidth, destHeight);
00071 IMGbar(ptr->get_ptr(), ptr->get_true_pitch(), 0, 0, destWidth-1, destHeight-1, BACKGROUND_COLOR);
00072 }
00073 else if( destWidth == 0 && destHeight == 0 ) {
00074 err_when(!ptr);
00075 ptr->init(destWidth, destHeight);
00076 }
00077 else if( left_edge == destLeft && top_edge == destTop && width == destWidth ) {
00078 if( destHeight == height )
00079 return;
00080
00081 size_t siz = BitmapW::size(destWidth,destHeight);
00082 if( alloc_size < siz ) {
00083 ptr = (BitmapW *)mem_resize(ptr, (alloc_size = siz + DEFAULT_BLOB2DW_INC));
00084 }
00085
00086 if( destHeight > height && destWidth > 0 ) {
00087 int y2 = top_edge+height;
00088 height = destHeight;
00089
00090
00091 fill_area(destLeft, top_edge+height, destLeft+destWidth-1, destTop+destHeight-1, BACKGROUND_COLOR, 0);
00092 }
00093 }
00094 else if( left_edge <= destLeft && top_edge <= destTop &&
00095 left_edge+width >= destLeft+destWidth && top_edge+height >= destTop+destHeight) {
00096
00097 short *src = ptr->get_ptr(destLeft-left_edge, destTop-top_edge);
00098 int srcPitch = ptr->get_pitch();
00099 ptr->init(destWidth, destHeight);
00100 short *dest = ptr->get_ptr();
00101 int destPitch = ptr->get_pitch();
00102
00103 for(int y = 0; y < destHeight; ++y, src += srcPitch, dest += destPitch )
00104 memmove(dest, src, destWidth * sizeof(short));
00105
00106
00107 }
00108 else {
00109
00110
00111 short copyLeft, copyTop, copyWidth, copyHeight;
00112 copyLeft = max(destLeft, left_edge);
00113 copyTop = max(destTop, top_edge);
00114 copyWidth = min(destLeft + destWidth, left_edge + width) - copyLeft;
00115 copyHeight = min(destTop + destHeight, top_edge + height) - copyTop; {
00116
00117 size_t siz = BitmapW::size(destWidth, destHeight);
00118 BitmapW *newPtr = (BitmapW *)mem_add(siz + DEFAULT_BLOB2DW_INC);
00119 newPtr->init(destWidth, destHeight);
00120 IMGbar(newPtr->get_ptr(), newPtr->get_true_pitch(), 0, 0, destWidth-1, destHeight-1, BACKGROUND_COLOR);
00121
00122 if( copyWidth > 0 && copyHeight > 0 ) {
00123 int yCount = 0;
00124 short *src = ptr->get_ptr(copyLeft-left_edge, yCount+copyTop-top_edge );
00125 short *dest = newPtr->get_ptr(copyLeft-destLeft, yCount+copyTop-destTop );
00126
00127 for( ; yCount < copyHeight; ++yCount, src += ptr->get_pitch(), dest += ptr->get_pitch() ) {
00128
00129
00130 memcpy(dest, src, copyWidth * sizeof(short));
00131 }
00132 }
00133
00134
00135 left_edge = destLeft;
00136 top_edge = destTop;
00137 width = destWidth;
00138 height = destHeight;
00139 mem_del(ptr);
00140 ptr = newPtr;
00141 }
00142
00143
00144 if( top_edge < copyTop && width > 0) {
00145 fill_area(left_edge, top_edge, left_edge+width-1, copyTop, BACKGROUND_COLOR, 0 );
00146 }
00147
00148
00149 if( top_edge+height > copyTop+copyHeight && width > 0) {
00150 fill_area(left_edge, copyTop+copyHeight, left_edge+width-1, top_edge+height-1, BACKGROUND_COLOR, 0 );
00151 }
00152
00153
00154 if( left_edge < copyLeft && destHeight > 0) {
00155 fill_area(left_edge, copyTop, copyLeft-1, copyTop+copyHeight-1,
00156 BACKGROUND_COLOR, 0);
00157 }
00158
00159
00160 if( left_edge+width > copyLeft+copyWidth && destHeight > 0 ) {
00161 fill_area(copyLeft+copyWidth, copyTop, left_edge+width, copyTop+copyHeight-1,
00162 BACKGROUND_COLOR, 0);
00163 }
00164 }
00165
00166 left_edge = destLeft;
00167 top_edge = destTop;
00168 width = destWidth;
00169 height = destHeight;
00170 }
00171
00172 int Blob2DW::extend_to(short x, short y) {
00173 int resizeFlag = 0;
00174 short newLeft = left_edge;
00175 short newTop = top_edge;
00176 short newWidth = width;
00177 short newHeight = height;
00178
00179 if( x < left_edge ) {
00180 newLeft = x;
00181 newWidth = left_edge + width - newLeft;
00182 resizeFlag = 1;
00183 }
00184 if( x >= left_edge+width ) {
00185 newWidth = x - newLeft + 1;
00186 resizeFlag = 1;
00187 }
00188 if( y < top_edge ) {
00189 newTop = y;
00190 newHeight = top_edge + height - newTop;
00191 resizeFlag = 1;
00192 }
00193 if( y >= top_edge+height ) {
00194 newHeight = y - newTop + 1;
00195 resizeFlag = 1;
00196 }
00197
00198 if( resizeFlag ) {
00199 resize( newLeft, newTop, newWidth, newHeight );
00200 }
00201
00202 return resizeFlag;
00203 }
00204
00205 int Blob2DW::extend_to(short x1, short y1, short x2, short y2) {
00206 int resizeFlag = 0;
00207 short newLeft = left_edge;
00208 short newTop = top_edge;
00209 short newWidth = width;
00210 short newHeight = height;
00211
00212 if( x1 < left_edge ) {
00213 newLeft = x1;
00214 newWidth = left_edge + width - newLeft;
00215 resizeFlag = 1;
00216 }
00217 if( x2 >= left_edge+width ) {
00218 newWidth = x2 - newLeft + 1;
00219 resizeFlag = 1;
00220 }
00221 if( y1 < top_edge ) {
00222 newTop = y1;
00223 newHeight = top_edge + height - newTop;
00224 resizeFlag = 1;
00225 }
00226 if( y2 >= top_edge+height ) {
00227 newHeight = y2 - newTop + 1;
00228 resizeFlag = 1;
00229 }
00230
00231 if( resizeFlag ) {
00232 resize( newLeft, newTop, newWidth, newHeight );
00233 }
00234
00235 return resizeFlag;
00236 }
00237
00238 short *Blob2DW::p(short x, short y, int autoExtend) {
00239 if( autoExtend ) {
00240 extend_to(x, y);
00241 }
00242 else {
00243 if( x < left_edge || x >= left_edge+width
00244 || y < top_edge || y >= top_edge+height )
00245 return NULL;
00246 }
00247
00248 return ptr->get_ptr(x-left_edge, y-top_edge);
00249 }
00250
00251 void Blob2DW::fill_area(short x1, short y1, short x2, short y2, short color,
00252 int autoExtend) {
00253 if( autoExtend ) {
00254 extend_to(x1, y1, x2, y2);
00255 }
00256 else {
00257
00258 if( x1 < left_edge )
00259 x1 = left_edge;
00260 if( x2 >= left_edge+width )
00261 x2 = left_edge+width-1;
00262 if( y1 < top_edge )
00263 y1 = top_edge;
00264 if( y2 >= top_edge+height )
00265 y2 = top_edge+height-1;
00266
00267 if( x2 < x1 || y2 < y1 )
00268 return;
00269 }
00270
00271 IMGbar(ptr->get_ptr(), ptr->get_true_pitch(), x1 - left_edge, y1 - top_edge,
00272 x2 - left_edge, y2 - top_edge, color);
00273
00274
00275
00276
00277 }
00278
00279 void Blob2DW::auto_clip( short *pLeft, short *pTop, short *pWidth, short *pHeight, int autoResize) {
00280 short x1, y1, x2, y2;
00281
00282 y1 = 0;
00283 y2 = height - 1;
00284 x1 = 0;
00285 x2 = width - 1;
00286
00287 int pitch = ptr->get_pitch();
00288
00289
00290 for( ; y1 <= y2; --y2) {
00291 int x = x1;
00292 short *src = ptr->get_ptr(x, y2);
00293 for( ; x <= x2; ++x, ++src ) {
00294 if( *src != BACKGROUND_COLOR )
00295 break;
00296 }
00297 if( x <= x2 )
00298 break;
00299 }
00300
00301
00302 for( ; y1 <= y2; ++y1 ) {
00303 int x = x1;
00304 short *src = ptr->get_ptr(x, y1);
00305 for( ; x <= x2; ++x, ++src ) {
00306 if( *src != BACKGROUND_COLOR )
00307 break;
00308 }
00309 if( x <= x2 )
00310 break;
00311 }
00312
00313
00314 for( ; x1 <= x2; --x2) {
00315 int y = y1;
00316 short *src = ptr->get_ptr(x1, y);
00317 for( ; y <= y2; ++y, src+=pitch ) {
00318 if( *src != BACKGROUND_COLOR )
00319 break;
00320 }
00321 if( y <= y2 )
00322 break;
00323 }
00324
00325
00326 for( ; x1 <= x2; ++x1 ) {
00327 int y = y1;
00328 short *src = ptr->get_ptr(x1, y);
00329 for( ; y <= y2; ++y, src+=pitch ) {
00330 if( *src != BACKGROUND_COLOR )
00331 break;
00332 }
00333 if( y <= y2 )
00334 break;
00335 }
00336
00337 if( pLeft )
00338 *pLeft = x1 + left_edge;
00339 if( pTop )
00340 *pTop = y1 + top_edge;
00341 if( pWidth )
00342 *pWidth = x2 - x1 + 1;
00343 if( pHeight )
00344 *pHeight = y2 - y1 + 1;
00345
00346 if( autoResize ) {
00347 resize(x1+left_edge, y1+top_edge, x2-x1+1, y2-y1+1);
00348 ptr = (BitmapW *)mem_resize(ptr, (alloc_size = ptr->size()) );
00349 }
00350 }
00351
00352 void Blob2DW::clear() {
00353 err_when(!ptr);
00354 ptr->init(0, 0);
00355
00356 left_edge = 0;
00357 top_edge = 0;
00358 width = 0;
00359 height = 0;
00360 }