Virtual U.org
Get Personal Training on VU Today
    
Top shadow
 
 register/help
User Name:

Password:

OBLOB2W.CPP Source File
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

OBLOB2W.CPP

Go to the documentation of this file.
00001 // Filename    : OBLOB2.CPP
00002 // Description : 2D binary block, four side extensible
00003 
00004 #include <OBLOB2W.H>
00005 #include <ALL.H>
00006 #include <COLCODE.H>
00007 #include <IMGFUN.H>
00008 
00009 // ------- define constant -------//
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     // ((BitmapW *)ptr)->init(width, height);
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     // ((BitmapW *)ptr)->init(width, height);
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;                                     // unchange
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;                   // must keep the old instant
00088             height = destHeight;                        // as height must be change to make fill_area correct
00089 
00090             // extend, then fill the new with the background color
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         // clipping
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         // ptr = (BitmapW *)mem_resize(ptr, ptr->size());
00107     }
00108     else {
00109         // general resize, new another buffer
00110         // copy range, intersection of two area :
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                     // unsigned char *src = (yCount+copyTop-top_edge)*width + copyLeft-left_edge;
00129                     // unsigned char *dest = (yCount+copyTop-destTop)*destWdith + copyLeft-destLeft;
00130                     memcpy(dest, src, copyWidth * sizeof(short));
00131                 }
00132             }
00133 
00134             // assign to the newPtr now
00135             left_edge = destLeft;
00136             top_edge = destTop;
00137             width = destWidth;
00138             height = destHeight;
00139             mem_del(ptr);
00140             ptr = newPtr;
00141         }
00142 
00143         // fill rest area with background color
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         // fill bottom
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         // fill left
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         // fill right
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         // adjust x1, y1, x2 ,y2
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     // int y = y1;
00274     //  short *dest = ptr->get_ptr( x1 - left_edge, y - top_edge );
00275     //  for( ; y <= y2; ++y, dest += width )
00276     //          memset(dest, color, x2-x1+1);
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     // clip bottom
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;                                    // dirty
00296         }
00297         if( x <= x2 )
00298             break;                                      // dirty
00299     }                                               // y2 is now the bottom margin
00300 
00301     // clip top
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;                                    // dirty
00308         }
00309         if( x <= x2 )
00310             break;                                      // dirty
00311     }                                               // y1 is now the top margin
00312 
00313     // clip right
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;                                    // dirty
00320         }
00321         if( y <= y2 )
00322             break;                                      // dirty
00323     }                                               // x2 is now the right margin
00324 
00325     // clip left
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;                                    // dirty
00332         }
00333         if( y <= y2 )
00334             break;                                      // dirty
00335     }                                               // x1 is now the left margin
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 }

Generated on Fri Aug 23 01:37:16 2002 for VirtualU by doxygen1.2.17