00001
00048 #ifndef OPC_H
00049 #include "opc.h"
00050 #endif
00051
00052 #ifndef PIXEL
00053 #error 'PIXEL' must be defined. It specifies the pixel format (i.e. uint8, uint16, uint32).
00054 #endif
00055
00056 #ifndef OPC_DIRTY
00057
00062
00063 #endif
00064
00065 #ifndef OPC_PTR
00066
00071 #define OPC_PTR( opc, x,y ) ((OPC_NAMING(Pixel)*)((opc)->origin + ((y)*(opc)->pitch)) + (x))
00072 #endif
00073
00074 #ifndef OPC_COPY
00075
00080 #define OPC_COPY_PIXEL(dst,src) {(dst)=(src);}
00081 #endif
00082
00083 #ifndef OPC_HLINE
00084
00090 #define HLINE_GENERIC(dst,color,width) \
00091 { \
00092 register OPC_NAMING(Pixel)* hlpdst = (OPC_NAMING(Pixel)*)(dst); \
00093 register OPC_NAMING(Pixel) hcpixel = (OPC_NAMING(Pixel))(color); \
00094 ppDuff( 16, (int)(width), *hlpdst++ = hcpixel );\
00095 }
00096 #define OPC_HLINE(dst,color,width) ppConcat( HLINE_FOR_ , PIXEL )(dst,color,width)
00097 #define HLINE_FOR_int8 memset
00098 #define HLINE_FOR_uint8 memset
00099 #define HLINE_FOR_int16 HLINE_GENERIC
00100 #define HLINE_FOR_uint16 HLINE_GENERIC
00101 #define HLINE_FOR_int32 HLINE_GENERIC
00102 #define HLINE_FOR_uint32 HLINE_GENERIC
00103 #define HLINE_FOR_int64 HLINE_GENERIC
00104 #define HLINE_FOR_uint64 HLINE_GENERIC
00105 #define HLINE_FOR_float32 HLINE_GENERIC
00106 #define HLINE_FOR_float64 HLINE_GENERIC
00107 #endif
00108
00109 #ifndef OPC_HCOPY
00110
00115 #define HCOPY_GENERIC(dst,src,width) \
00116 { \
00117 register OPC_NAMING(Pixel)* hcpdst = (OPC_NAMING(Pixel)*)(dst); \
00118 register const OPC_NAMING(Pixel)* hcpsrc = (const OPC_NAMING(Pixel)*)(src); \
00119 ppDuff( 16, (int)(width), *hcpdst++ = *hcpsrc++ );\
00120 }
00121 #define OPC_HCOPY(dst,src,width) ppConcat( HCOPY_FOR_ , PIXEL )(dst,src,width)
00122 #define HCOPY_FOR_int8 memcpy
00123 #define HCOPY_FOR_uint8 memcpy
00124 #define HCOPY_FOR_int16(dst,src,width) memcpy(dst,src,(width)<<1)
00125 #define HCOPY_FOR_uint16(dst,src,width) memcpy(dst,src,(width)<<1)
00126 #define HCOPY_FOR_int32 HCOPY_GENERIC
00127 #define HCOPY_FOR_uint32 HCOPY_GENERIC
00128 #define HCOPY_FOR_int64 HCOPY_GENERIC
00129 #define HCOPY_FOR_uint64 HCOPY_GENERIC
00130 #define HCOPY_FOR_float32 HCOPY_GENERIC
00131 #define HCOPY_FOR_float64 HCOPY_GENERIC
00132 #endif
00133
00134
00135 static OPC_NAMING(Pixel) OPC_NAMING(maskcolor) = 0;
00136
00143 size_t OPC_NAMING(Needs)( int wide, int high )
00144 {
00145 return (((wide*sizeof(OPC_NAMING(Pixel))) + sizeof(int) - 1) / sizeof(int) * sizeof(int)) * high;
00146 }
00147
00161 void OPC_NAMING(Init)( OPC* opc, int xOff, int yOff, const Rect* clip, void* buffer )
00162 {
00163 opc->clip = *clip;
00164 opc->pitch = ((RectWide(*clip)*sizeof(OPC_NAMING(Pixel))) + sizeof(int)-1) / sizeof(int) * sizeof(int);
00165 opc->origin = ((uint8*)buffer + (opc->pitch*yOff)) + (sizeof(PIXEL)*xOff);
00166 }
00167
00174 void OPC_NAMING(Clip)( OPC* opc, const OPC* src, const Rect* clip )
00175 {
00176 *opc = *src;
00177 if( clip )
00178 RectIntRect(opc->clip,*clip);
00179 }
00180
00181
00190 void OPC_NAMING(Window)( OPC* opc, const OPC* src, const Rect* clip, int orgX, int orgY )
00191 {
00192 *opc = *src;
00193 RectIntRect(opc->clip,*clip);
00194 opc->origin = (uint8*)OPC_PTR( opc, orgX, orgY );
00195 RectMoveBy( opc->clip, -orgX, -orgY );
00196 }
00197
00204 OPC_NAMING(Pixel)* OPC_NAMING(Ptr)( const OPC* dst, int x, int y )
00205 {
00206 return OPC_PTR(dst,x,y);
00207 }
00208
00215 void OPC_NAMING(Plot)( const OPC* dst, int x, int y, OPC_NAMING(Pixel) color )
00216 {
00217 if( RectPtInRect(dst->clip,x,y) )
00218 OPC_COPY_PIXEL(*OPC_PTR( dst, x,y ),color);
00219 }
00220
00227 OPC_NAMING(Pixel) OPC_NAMING(Peek)( const OPC* dst, int x, int y )
00228 {
00229 if( RectPtInRect(dst->clip,x,y) )
00230 return *OPC_PTR( dst, x,y );
00231 return 0;
00232 }
00233
00241 void OPC_NAMING(HLine)( const OPC* dst, int x, int y, int wide, OPC_NAMING(Pixel) color )
00242 {
00243 if( y < dst->clip.top || y >= dst->clip.bottom )
00244 return;
00245 if( x < dst->clip.left )
00246 {
00247 wide -= dst->clip.left - x;
00248 x = dst->clip.left;
00249 }
00250 if( x + wide > dst->clip.right )
00251 {
00252 wide = dst->clip.right - x;
00253 }
00254 if( wide > 0 )
00255 {
00256 OPC_HLINE(OPC_PTR( dst, x, y ),color,wide);
00257 }
00258 }
00259
00268 void OPC_NAMING(VLine)( const OPC* dst, int x, int y, int high, OPC_NAMING(Pixel) color )
00269 {
00270 if( x < dst->clip.left || x >= dst->clip.right )
00271 return;
00272 if( y < dst->clip.top )
00273 {
00274 high -= dst->clip.top - y;
00275 y = dst->clip.top;
00276 }
00277 if( y + high > dst->clip.bottom )
00278 {
00279 high = dst->clip.bottom - y;
00280 }
00281 if( high > 0 )
00282 {
00283 OPC_NAMING(Pixel)* pdst = OPC_PTR( dst, x, y );
00284 int remain = high;
00285 int offset = dst->pitch;
00286 while( remain-- )
00287 {
00288 OPC_COPY_PIXEL(*pdst,color);
00289 pdst = (OPC_NAMING(Pixel)*)((uint8*)pdst + offset);
00290 }
00291 }
00292 }
00293
00303 void OPC_NAMING(HCopy)( const OPC* dst, int x, int y, int wide, const OPC_NAMING(Pixel)* src )
00304 {
00305 if( y < dst->clip.top || y >= dst->clip.bottom )
00306 return;
00307 if( x < dst->clip.left )
00308 {
00309 int offset = dst->clip.left - x;
00310 wide -= offset;
00311 src += offset;
00312 x = dst->clip.left;
00313 }
00314 if( x + wide > dst->clip.right )
00315 {
00316 wide = dst->clip.right - x;
00317 }
00318 if( wide > 0 )
00319 {
00320 OPC_HCOPY(OPC_PTR( dst, x, y ),src,wide);
00321 }
00322 }
00323
00324 #if 0
00325
00326
00327
00328 size_t NONE_Reserve( size_t len );
00329 size_t NONE_Pack( const PIXEL* pdstBase, PIXEL* pdst, PIXEL* psrc, size_t len );
00330 void NONE_Unpack( const PIXEL* psrcBase, PIXEL* psrc, PIXEL* pdst, size_t len );
00331 void NONE_UnpackClip( const PIXEL* psrcBase, PIXEL* psrc, PIXEL* pdst, size_t len, size_t offset, size_t clipLen );
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341 size_t LZRLE_Reserve( size_t len );
00342 size_t LZRLE_Pack( const PIXEL* pdstBase, PIXEL* pdst, PIXEL* psrc, size_t len );
00343 void LZRLE_Unpack( const PIXEL* psrcBase, PIXEL* psrc, PIXEL* pdst, size_t len );
00344 void LZRLE_UnpackClip( const PIXEL* psrcBase, PIXEL* psrc, PIXEL* pdst, size_t len, size_t offset, size_t clipLen );
00345
00346 #endif
00347
00348
00358 void OPC_NAMING(Blit)( const OPC* dst, const Rect* rdst, const OPC* src, int sx, int sy )
00359 {
00360
00361 Rect dstblit = *rdst;
00362 RectIntRect(dstblit,dst->clip);
00363 if( !RectEmpty(dstblit) )
00364 {
00365
00366 Rect orgsrcblit = RectAutoXYWH( sx, sy, RectWide(dstblit), RectHigh(dstblit) );
00367 Rect srcblit = orgsrcblit;
00368
00369 srcblit.left += dstblit.left - rdst->left;
00370 srcblit.top += dstblit.top - rdst->top;
00371 srcblit.right += dstblit.right - rdst->right;
00372 srcblit.bottom += dstblit.bottom - rdst->bottom;
00373
00374 RectIntRect(srcblit,src->clip);
00375 dstblit.left += srcblit.left - orgsrcblit.left;
00376 dstblit.top += srcblit.top - orgsrcblit.top;
00377 if( !RectEmpty(srcblit) )
00378 {
00379
00380 int wide = RectWide(srcblit);
00381 int high = RectHigh(srcblit);
00382 int offsrc = src->pitch;
00383 int offdst = dst->pitch;
00384 const OPC_NAMING(Pixel)* pSrc = OPC_PTR( src, srcblit.left, srcblit.top );
00385 OPC_NAMING(Pixel)* pDst = OPC_PTR( dst, dstblit.left, dstblit.top );
00386 while( high-- )
00387 {
00388 OPC_HCOPY(pDst,pSrc,wide);
00389 pDst = (OPC_NAMING(Pixel)*)((uint8*)pDst + offdst);
00390 pSrc = (const OPC_NAMING(Pixel)*)((const uint8*)pSrc + offsrc);
00391 }
00392 #ifdef OPC_DIRTY
00393
00394 OPC_DIRTY(dstblit);
00395 #endif
00396 }
00397 }
00398 }
00399
00406 void OPC_NAMING(Stamp)( const OPC* dst, int dx, int dy, const OPC* src )
00407 {
00408 Rect rdst = src->clip;
00409 RectMove(rdst,dx,dy);
00410 OPC_NAMING(Blit)( dst, &rdst, src, 0,0 );
00411 }
00412
00419 void OPC_NAMING(Fill)( const OPC* dst, const Rect* rdst, OPC_NAMING(Pixel) color )
00420 {
00421
00422 Rect dstblit = *rdst;
00423 RectIntRect(dstblit,dst->clip);
00424 if( !RectEmpty(dstblit) )
00425 {
00426
00427 int wide = RectWide(dstblit);
00428 int high = RectHigh(dstblit);
00429 int offdst = dst->pitch;
00430 OPC_NAMING(Pixel)* pDst = OPC_PTR( dst, dstblit.left, dstblit.top );
00431 while( high-- )
00432 {
00433 OPC_HLINE(pDst,color,wide);
00434 pDst = (OPC_NAMING(Pixel)*)((uint8*)pDst + offdst);
00435 }
00436
00437 #ifdef OPC_DIRTY
00438 OPC_DIRTY(dstblit);
00439 #endif
00440 }
00441 }
00442
00449 void OPC_NAMING(Shape)( const OPC* dst, const OPCShape* shape, int x, int y )
00450 {
00451 if( !shape )
00452 return;
00453 if( shape->data )
00454 {
00455 #ifdef OPC_POINTERS
00456 const int8* pCode = shape->code;
00457 const OPC_NAMING(Pixel)* pData = (const OPC_NAMING(Pixel)*)shape->data;
00458 const opc_pack_type* plut = (const uint8*)shape->pack;
00459 #else
00460 const int8* pCode = (int8*)shape + shape->code;
00461 const OPC_NAMING(Pixel)* pData = (const OPC_NAMING(Pixel)*)((uint8*)shape + shape->data);
00462 const opc_pack_type* plut = shape->pack ? (const uint8*)shape + shape->pack : NULL;
00463 #endif
00464 Rect bound;
00465 OPC_NAMING(Shape_Bound)( &bound, shape, x, y );
00466
00467
00468 if( RectInRect(dst->clip,bound) )
00469 {
00470
00471 if( RectContainsRect(dst->clip,bound) )
00472 {
00473
00474 OPC_NAMING(Pixel)* pDst = OPC_PTR( dst, bound.left,bound.top );
00475 OPC_NAMING(Pixel)* pSpan = pDst;
00476 #ifdef OPC_DIRTY
00477 OPC_DIRTY(bound);
00478 #endif
00479 for( ; ; )
00480 {
00481 int curr = *pCode++;
00482 if( curr <= 0 )
00483 {
00484 if( curr == -128 )
00485 pSpan = pDst = (OPC_NAMING(Pixel)*)((uint8*)pDst + dst->pitch);
00486 else if( 0 == curr )
00487 break;
00488 else
00489 pSpan -= curr;
00490 }
00491 else
00492 {
00493 if( IS_RUN(curr) )
00494 {
00495 OPC_HLINE(pSpan,*pData,curr);
00496 pData++;
00497 pSpan += curr;
00498 }
00499 else
00500 {
00501 if( plut )
00502 {
00503 OPC_HCOPY(pSpan,pData-*plut,curr);
00504 if( curr > *plut )
00505 pData = (pData - *plut) + curr;
00506 plut++;
00507 pSpan += curr;
00508 }
00509 else
00510 {
00511 OPC_HCOPY(pSpan,pData,curr);
00512 pData += curr;
00513 pSpan += curr;
00514 }
00515 }
00516 }
00517 }
00518 }
00519 else
00520 {
00521
00522 OPC_NAMING(Pixel)* pDst = OPC_PTR( dst, bound.left, bound.top );
00523 OPC_NAMING(Pixel)* pSpan = pDst;
00524 int xCurr = bound.left;
00525 int yCurr = bound.top;
00526 RectIntRect(bound,dst->clip);
00527 #ifdef OPC_DIRTY
00528
00529 OPC_DIRTY(bound);
00530 #endif
00531 while( yCurr < bound.bottom )
00532 {
00533 int curr = *pCode++;
00534 if( curr <= 0 )
00535 {
00536 if( IS_EOL(curr) )
00537 {
00538 pSpan = pDst = (OPC_NAMING(Pixel)*)((uint8*)pDst + dst->pitch);
00539 yCurr++;
00540 xCurr = x+shape->xOff;
00541 }
00542 else if( IS_EOS(curr) )
00543 break;
00544 else
00545 {
00546 xCurr += SKIP_LEN(curr);
00547 pSpan += SKIP_LEN(curr);
00548 }
00549 }
00550 else
00551 {
00552 if( yCurr >= bound.top )
00553 {
00554 int wide = RUN_LEN(curr);
00555 const OPC_NAMING(Pixel)* ppData = pData;
00556 OPC_NAMING(Pixel)* ppSpan = pSpan;
00557 if( plut )
00558 ppData -= *plut;
00559 if( xCurr + wide > bound.right )
00560 wide = bound.right - xCurr;
00561 if( xCurr < bound.left )
00562 {
00563 int offset = bound.left - xCurr;
00564 wide -= offset;
00565 ppData += offset;
00566 ppSpan += offset;
00567 }
00568 if( wide > 0 )
00569 {
00570 if( IS_RUN(curr) )
00571 {
00572 OPC_HLINE(ppSpan,*pData,wide);
00573 }
00574 else
00575 {
00576 OPC_HCOPY(ppSpan,ppData,wide);
00577 }
00578 }
00579 }
00580 if( IS_RUN(curr) )
00581 {
00582 pData++;
00583 }
00584 else if( plut )
00585 {
00586 if( curr > *plut )
00587 pData = (pData - *plut) + curr;
00588 plut++;
00589 }
00590 else
00591 {
00592 pData += curr;
00593 }
00594 xCurr += curr;
00595 pSpan += curr;
00596 }
00597 }
00598 }
00599 }
00600 }
00601 else
00602 {
00603 OPC_NAMING(Shape_Mask)( dst, shape, x, y, OPC_NAMING(maskcolor) );
00604 }
00605 }
00606
00615 void OPC_NAMING(Shape_Mask)( const OPC* dst, const OPCShape* shape, int x, int y, OPC_NAMING(Pixel) color )
00616 {
00617 if( shape )
00618 {
00619 #ifdef OPC_POINTERS
00620 const int8* pCode = shape->code;
00621 #else
00622 const int8* pCode = (int8*)shape + shape->code;
00623 #endif
00624
00625 Rect bound;
00626 OPC_NAMING(Shape_Bound)( &bound, shape, x, y );
00627
00628 if( RectInRect(dst->clip,bound) )
00629 {
00630
00631 if( RectContainsRect(dst->clip,bound) )
00632 {
00633
00634 OPC_NAMING(Pixel)* pDst = OPC_PTR( dst, bound.left, bound.top );
00635 OPC_NAMING(Pixel)* pSpan = pDst;
00636 #ifdef OPC_DIRTY
00637 OPC_DIRTY(bound);
00638 #endif
00639 for( ; ; )
00640 {
00641 int curr = *pCode++;
00642 if( curr <= 0 )
00643 {
00644 if( curr == -128 )
00645 pSpan = pDst = (OPC_NAMING(Pixel)*)((uint8*)pDst + dst->pitch);
00646 else if( 0 == curr )
00647 break;
00648 else
00649 pSpan -= curr;
00650 }
00651 else
00652 {
00653 OPC_HLINE(pSpan,color,curr);
00654 pSpan += curr;
00655 }
00656 }
00657 }
00658 else
00659 {
00660
00661 OPC_NAMING(Pixel)* pDst = OPC_PTR( dst, bound.left, bound.top );
00662 OPC_NAMING(Pixel)* pSpan = pDst;
00663 int xCurr = bound.left;
00664 int yCurr = bound.top;
00665 RectIntRect(bound,dst->clip);
00666 #ifdef OPC_DIRTY
00667
00668 OPC_DIRTY(bound);
00669 #endif
00670 while( yCurr < bound.bottom )
00671 {
00672 int curr = *pCode++;
00673 if( curr <= 0 )
00674 {
00675 if( curr == -128 )
00676 {
00677 yCurr++;
00678 xCurr = x;
00679 pSpan = pDst = (OPC_NAMING(Pixel)*)((uint8*)pDst + dst->pitch);
00680 }
00681 else if( 0 == curr )
00682 break;
00683 else
00684 {
00685 xCurr -= curr;
00686 pSpan -= curr;
00687 }
00688 }
00689 else
00690 {
00691 if( yCurr >= bound.top )
00692 {
00693 int wide = curr;
00694 OPC_NAMING(Pixel)* ppSpan = pSpan;
00695 if( xCurr + wide > bound.right )
00696 wide = bound.right - xCurr;
00697 if( xCurr < bound.left )
00698 {
00699 int offset = bound.left - xCurr;
00700 wide -= offset;
00701 ppSpan += offset;
00702 }
00703 if( wide > 0 )
00704 OPC_HLINE(ppSpan,color,wide);
00705 }
00706 xCurr += curr;
00707 pSpan += curr;
00708 }
00709 }
00710 }
00711 }
00712 }
00713 }
00714
00721 void OPC_NAMING(Shape_Bound)( Rect* posn, const OPCShape* shape, int x, int y )
00722 {
00723 if( shape )
00724 {
00725 posn->left = x + shape->xOff;
00726 posn->top = y + shape->yOff;
00727 posn->right = posn->left + shape->wide;
00728 posn->bottom = posn->top + shape->high;
00729 }
00730 else
00731 {
00732 RectClear(*posn);
00733 }
00734 }
00735
00740 size_t OPC_NAMING(Shape_TotalSize)( const OPCShape* shape )
00741 {
00742 if( shape )
00743 return sizeof(OPCShape) + ((OPC_NAMING(Shape_CodeSize)( shape )+3)&~3) + OPC_NAMING(Shape_PackLutSize)( shape ) + OPC_NAMING(Shape_DataSize)( shape );
00744 return 0;
00745 }
00746
00751 size_t OPC_NAMING(Shape_CodeSize)( const OPCShape* shape )
00752 {
00753 if( shape )
00754 {
00755 #ifdef OPC_POINTERS
00756 const int8* pCode = shape->code;
00757 #else
00758 const int8* pCode = (int8*)shape + shape->code;
00759 #endif
00760 return 1 + strlen( (char*)pCode );
00761 }
00762 return 0;
00763 }
00764
00769 size_t OPC_NAMING(Shape_PackLutSize)( const OPCShape* shape )
00770 {
00771 if( shape && shape->data )
00772 {
00773 #ifdef OPC_POINTERS
00774 const int8* pCode = shape->code;
00775 const opc_pack_type* plut = (const uint8*)shape->pack;
00776 #else
00777 const int8* pCode = (int8*)shape + shape->code;
00778 const opc_pack_type* plut = (const uint8*)shape + shape->pack;
00779 #endif
00780 if( plut )
00781 {
00782 size_t dumps = 0;
00783 while( *pCode )
00784 {
00785 if( IS_RUNDUMP(*pCode) )
00786 {
00787 if( IS_DUMP(*pCode) )
00788 {
00789 dumps++;
00790 }
00791 }
00792 pCode++;
00793 }
00794 return ((sizeof(opc_pack_type) * dumps) + 3) & ~3;
00795 }
00796 }
00797 return 0;
00798 }
00799
00804 size_t OPC_NAMING(Shape_DataSize)( const OPCShape* shape )
00805 {
00806 if( shape && shape->data )
00807 {
00808 #ifdef OPC_POINTERS
00809 const int8* pCode = shape->code;
00810 const opc_pack_type* plut = (const uint8*)shape->pack;
00811 #else
00812 const int8* pCode = (int8*)shape + shape->code;
00813 const opc_pack_type* plut = shape->pack ? (const uint8*)shape + shape->pack : NULL;
00814 #endif
00815 if( plut )
00816 {
00817 size_t pixels = 0;
00818 size_t luts = 0;
00819 while( *pCode )
00820 {
00821 if( IS_RUNDUMP(*pCode) )
00822 {
00823 if( IS_RUN(*pCode) )
00824 {
00825 pixels++;
00826 }
00827 else
00828 {
00829 if( *pCode > *plut )
00830 {
00831 pixels += *pCode - *plut;
00832 }
00833 plut++;
00834 luts++;
00835 }
00836 }
00837 pCode++;
00838 }
00839 return pixels * sizeof(PIXEL);
00840 }
00841 else
00842 {
00843 size_t pixels = 0;
00844 while( *pCode )
00845 {
00846 if( IS_RUNDUMP(*pCode) )
00847 {
00848 if( IS_RUN(*pCode) )
00849 {
00850 pixels++;
00851 }
00852 else
00853 {
00854 pixels += *pCode;
00855 }
00856 }
00857 pCode++;
00858 }
00859 return pixels * sizeof(PIXEL);
00860 }
00861 }
00862 return 0;
00863 }
00864
00870 OPC_NAMING(Pixel) OPC_NAMING(Shape_MaskColor)( OPC_NAMING(Pixel) color )
00871 {
00872 OPC_NAMING(Pixel) ret = OPC_NAMING(maskcolor);
00873 OPC_NAMING(maskcolor) = color;
00874 return ret;
00875 }