Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2577 lines
65 KiB

#include <platform.h>
#include <sccut.h>
#include <sccch.h>
#include <sccvw.h>
#include <sccd.h>
#include "oibdlgs.h"
#include "oibstr.h"
#ifdef WINDOWS
#include "oibnp_w.h"
#endif
#ifdef MAC
#include "oibnp_m.h"
#endif
#include "oibde.h"
#ifdef WINDOWS
#include "oibnp_w.pro"
#endif
#ifdef MAC
#include "oibnp_m.pro"
#endif
#include "oibde.pro"
BITMAPOPT Options =
{
OIBMENU_NOSCALING, // wScaleMode
0, // bPrintBorder
1, // bPrintWYSIWYG
(OIB_CLIPBITMAP | OIB_CLIPDIB | OIB_CLIPPALETTE), // Clipboard formats
0, // bDither
};
#ifndef SCCFEATURE_SELECT
#define OIBClearSelection(lpDisplay)
#define OIBStartSelection(pStart,lpDisplay)
#define OIBClearSelection(lpDisplay)
#define OIBSelectAll(lpDisplay)
#endif
#ifndef SCCFEATURE_SCALING
#define OIBNPScale(a,b,c,d)
#define OIBNPRestoreScaling(hdc,lpDisplay)
#define OIBTurnOffTheDamnZoom(lpDisplay)
#define OIBNPSetScaling(hdc,from,to)
#define OIBNPSaveScaling(hdc,lpDisplay)
#define OIBNPRestoreScaling(hdc,lpDisplay)
#define OIBNPFixScaledPoints(Points,lpDisplay,wCount)
#define OIBNPScale(hdc,Points,wCount,lpDisplay)
#define OIBNPReverseScale(hdc,Points,wCount,lpDisplay)
#endif
#ifndef SCCFEATURE_ROTATION
#define OIBSetRotation(lpDisplay,wRotation) (lpDisplay->wRotation = OIB_NOROTATION)
#define OIBCreateRotatedBmp(lpDisplay,hdc,lpTile,hChunkData)
#endif
#ifndef SCCFEATURE_MENU
#define OIBNPFillMenu(hMenu,wCommandOffset)
#endif
VOID OIBLoadInit()
{
OIBNPPlatformInit();
}
VOID OIBInitBitmapDisplay( lpDisplay, wFlags )
POIB_DISPLAY lpDisplay;
WORD wFlags;
{
CHSECTIONINFO SecInfo;
RECT rc;
DEVICE device;
SecInfo = *(CHLockSectionInfo(lpDisplay->Gen.hFilter, lpDisplay->Gen.wSection));
CHUnlockSectionInfo(lpDisplay->Gen.hFilter, lpDisplay->Gen.wSection);
lpDisplay->wFlags = wFlags;
lpDisplay->bSelecting = FALSE;
lpDisplay->bSelectionMade = FALSE;
lpDisplay->hPalMem = NULL;
lpDisplay->hDitherBuf = NULL;
lpDisplay->Image.hPalette = NULL;
lpDisplay->wScaleFrom = 1;
lpDisplay->wScaleTo = 1;
lpDisplay->wMagnification = 1;
lpDisplay->ptWinOrg.x = 0;
lpDisplay->ptWinOrg.y = 0;
lpDisplay->ptScreenClip.x = 0;
lpDisplay->ptScreenClip.y = 0;
lpDisplay->ptScaledImageSize.x = 0;
lpDisplay->ptScaledImageSize.y = 0;
lpDisplay->nVScrollMax = 0;
lpDisplay->nHScrollMax = 0;
lpDisplay->Image.wFlags = SecInfo.Attr.Bitmap.bmpHeader.wImageFlags;
lpDisplay->Image.wWidth = SecInfo.Attr.Bitmap.bmpHeader.wImageWidth;
lpDisplay->Image.wHeight = SecInfo.Attr.Bitmap.bmpHeader.wImageLength;
lpDisplay->Image.wBitCount = SecInfo.Attr.Bitmap.bmpHeader.wBitsPerPixel;
#ifdef MAC
if( lpDisplay->Image.wBitCount == 24 )
lpDisplay->Image.wBitCount = 32;
#endif
lpDisplay->Image.wOrgWidth = SecInfo.Attr.Bitmap.bmpHeader.wImageWidth;
lpDisplay->Image.wOrgHeight = SecInfo.Attr.Bitmap.bmpHeader.wImageLength;
lpDisplay->Image.DisplaySize.x = lpDisplay->Image.wWidth;
lpDisplay->Image.DisplaySize.y = lpDisplay->Image.wHeight;
lpDisplay->Image.TileCache.wSize = OIBNP_TILECACHESIZE;
lpDisplay->Image.TileCache.wCount = 0;
lpDisplay->Image.TileCache.bCacheFull = FALSE;
lpDisplay->Image.wHDpi = 0;
lpDisplay->Image.wVDpi = 0;
if( !(lpDisplay->wFlags & OIBF_RENDERIMAGEONLY) )
{
device = BUGetNewDevice(lpDisplay);
lpDisplay->bDither = Options.bDither;
// Clear out the previous rotation checkmark from the menu.
#ifdef SCCFEATURE_MENU
BUUncheckMenuItem( lpDisplay, OIBMENU_ROTATE90 );
BUUncheckMenuItem( lpDisplay, OIBMENU_ROTATE180 );
BUUncheckMenuItem( lpDisplay, OIBMENU_ROTATE270 );
BUCheckMenuItem( lpDisplay, OIBMENU_NOROTATION );
#endif
lpDisplay->wRotation = OIB_NOROTATION;
lpDisplay->wScreenWidth = BUGetScreenWidth(device);
lpDisplay->wScreenHeight = BUGetScreenHeight(device);
lpDisplay->wScreenColors = BUGetScreenColors(device);
lpDisplay->wScreenHDpi = BUGetScreenHDpi(device);
lpDisplay->wScreenVDpi = BUGetScreenVDpi(device);
DUGetDisplayRect( lpDisplay, &rc );
lpDisplay->nWindowWidth = (SHORT)(rc.right - rc.left);
lpDisplay->nWindowHeight = (SHORT)(rc.bottom - rc.top);
lpDisplay->winRect = rc;
lpDisplay->wNumMagItems = OIB_MAXZOOM;
BUReleaseNewDevice(lpDisplay,device);
}
lpDisplay->Image.wNumTiles = 0;
lpDisplay->Image.wTilesAcross = SecInfo.Attr.Bitmap.wTilesAcross;
lpDisplay->Image.wTilesDown = SecInfo.Attr.Bitmap.wVertNumChunks;
lpDisplay->Image.hTiles = NULL;
lpDisplay->Image.pBmpTiles = NULL;
OIBNPInitBitmapInfo( lpDisplay, (PCHSECTIONINFO) &SecInfo );
lpDisplay->Image.wPaletteSize = OIBNPInitPalette( lpDisplay, (PCHSECTIONINFO) &SecInfo );
}
WORD OIBScanLineSize( wWidth, wBitCount, lpDataSize )
WORD wWidth;
WORD wBitCount;
LPWORD lpDataSize;
{
WORD wTotalSize;
WORD wDataSize;
WORD wPixPerByte;
wDataSize = wWidth * wBitCount / 8;
if( wBitCount < 8 )
{
wPixPerByte = 8/wBitCount;
if( wWidth % wPixPerByte )
wDataSize++;
}
wTotalSize = wDataSize;
if( wTotalSize % 4 )
wTotalSize += 4-(wTotalSize%4);
if( lpDataSize != NULL )
*lpDataSize = wDataSize;
return( wTotalSize );
}
#ifdef SCCFEATURE_FULLSCREEN
WORD OIBShowFullScreen( lpDisplay )
POIB_DISPLAY lpDisplay;
{
WORD ret;
if( OIBNPInitFullScreen(lpDisplay) )
{
ret = 1; // Initialization failed.
}
else
{
lpDisplay->wFlags |= OIBF_FULLSCREEN;
// Center the image...
if( (WORD)lpDisplay->Image.DisplaySize.x < lpDisplay->wScreenWidth )
lpDisplay->ptFullScreenOffset.x = (lpDisplay->wScreenWidth - lpDisplay->Image.DisplaySize.x) / 2;
else
lpDisplay->ptFullScreenOffset.x = 0;
if( (WORD)lpDisplay->Image.DisplaySize.y < lpDisplay->wScreenHeight )
lpDisplay->ptFullScreenOffset.y = (lpDisplay->wScreenHeight - lpDisplay->Image.DisplaySize.y) / 2;
else
lpDisplay->ptFullScreenOffset.y = 0;
lpDisplay->ptFullScreenShift.x = 0;
lpDisplay->ptFullScreenShift.y = 0;
OIBNPDisplayFullScreen( lpDisplay );
ret=0;
}
OIBNPDeInitFullScreen( lpDisplay );
return( ret );
}
#endif // SCCFEATURE_FULLSCREEN
VOID OIBVScrollImage( wType, nNewPos, lpDisplay )
WORD wType;
SHORT nNewPos;
POIB_DISPLAY lpDisplay;
{
SHORT nScroll;
SOPOINT ptCsr;
WORD i;
// The variable nScroll is the new position of lpDisplay->ptWinOrg.y
nScroll = lpDisplay->ptWinOrg.y;
switch( wType )
{
case SCCD_VUP:
if( lpDisplay->bSelecting )
nScroll = max( 0, nScroll - nNewPos );
else if( nScroll )
{
if( lpDisplay->wMagnification )
nScroll = max( 0, (SHORT)(nScroll - OIB_SCROLLINC*lpDisplay->wMagnification) );
else
nScroll = max( 0, (nScroll - lpDisplay->nWindowHeight / 10) );
}
break;
case SCCD_VDOWN:
if( lpDisplay->bSelecting )
nScroll = min( lpDisplay->nVScrollMax, nScroll + nNewPos );
else if( lpDisplay->wMagnification )
nScroll = min( lpDisplay->nVScrollMax, (SHORT)(nScroll + (SHORT)OIB_SCROLLINC*lpDisplay->wMagnification) );
else
nScroll = min( lpDisplay->nVScrollMax, (nScroll + lpDisplay->nWindowHeight / 10) );
break;
case SCCD_VPAGEUP:
nScroll = max( 0, (SHORT)(lpDisplay->ptWinOrg.y - (SHORT)lpDisplay->nWindowHeight) );
break;
case SCCD_VPAGEDOWN:
nScroll = min( nScroll + lpDisplay->nWindowHeight, lpDisplay->nVScrollMax );
break;
case SCCD_VPOSITION:
nScroll = nNewPos;
break;
}
if( nScroll != lpDisplay->ptWinOrg.y )
{
if( lpDisplay->wScaleTo != lpDisplay->wScaleFrom )
{
ptCsr.y = nScroll;
OIBNPFixScaledPoints( &ptCsr, lpDisplay, 1 );
nScroll = ptCsr.y;
}
if( lpDisplay->bSelectionMade || lpDisplay->bSelecting )
{
for( i=0; i<5; i++ )
lpDisplay->ptSelBox[i].y += lpDisplay->ptWinOrg.y - nScroll;
}
DUScrollDisplay( lpDisplay, 0, lpDisplay->ptWinOrg.y - nScroll, NULL );
lpDisplay->ptWinOrg.y = nScroll;
#ifdef WINDOWS
if( lpDisplay->Image.wNumTiles <= lpDisplay->Image.TileCache.wSize )
DUUpdateWindow( lpDisplay );
#endif
DUSetVScrollPos( lpDisplay, nScroll );
}
}
VOID OIBHScrollImage( wType, nNewPos, lpDisplay )
WORD wType;
SHORT nNewPos;
POIB_DISPLAY lpDisplay;
{
SHORT nScroll;
SOPOINT ptCsr;
WORD i;
// The variable nScroll will be set to the new position of lpDisplay->ptWinOrg.x
nScroll = lpDisplay->ptWinOrg.x;
switch( wType )
{
case SCCD_HLEFT:
if( lpDisplay->bSelecting )
nScroll = max( nScroll - nNewPos, 0 );
else if( nScroll )
{
if( lpDisplay->wMagnification )
nScroll = max( (SHORT)(nScroll - OIB_SCROLLINC*lpDisplay->wMagnification), 0 );
else
nScroll = max( (SHORT)(nScroll - lpDisplay->nWindowWidth/10), 0 );
}
break;
case SCCD_HRIGHT:
if( lpDisplay->bSelecting )
nScroll = min( nScroll + nNewPos, lpDisplay->nHScrollMax );
else if( lpDisplay->wMagnification )
nScroll = min( (SHORT)(nScroll + OIB_SCROLLINC*lpDisplay->wMagnification), lpDisplay->nHScrollMax );
else
nScroll = min( (SHORT)(nScroll + lpDisplay->nWindowWidth/10), lpDisplay->nHScrollMax );
break;
case SCCD_HPAGELEFT:
nScroll = max( 0, (SHORT)(lpDisplay->ptWinOrg.x - (SHORT)lpDisplay->nWindowWidth) );
break;
case SCCD_HPAGERIGHT:
nScroll = min( nScroll + lpDisplay->nWindowWidth, lpDisplay->nHScrollMax );
break;
case SCCD_HPOSITION:
nScroll = nNewPos;
break;
}
if( nScroll != lpDisplay->ptWinOrg.x )
{
if( lpDisplay->wScaleTo != lpDisplay->wScaleFrom )
{
ptCsr.x = nScroll;
OIBNPFixScaledPoints( &ptCsr, lpDisplay, 1 );
nScroll = ptCsr.x;
}
if( lpDisplay->bSelectionMade || lpDisplay->bSelecting )
{
for( i=0; i<5; i++ )
lpDisplay->ptSelBox[i].x += lpDisplay->ptWinOrg.x - nScroll;
}
DUScrollDisplay( lpDisplay, lpDisplay->ptWinOrg.x - nScroll, 0, NULL );
lpDisplay->ptWinOrg.x = nScroll;
#ifdef WINDOWS
if( lpDisplay->Image.wNumTiles <= lpDisplay->Image.TileCache.wSize )
DUUpdateWindow( lpDisplay );
#endif
DUSetHScrollPos( lpDisplay, nScroll );
}
}
#ifdef WINNT
BOOL APIENTRY LibMain( HANDLE hInstance, DWORD dwReason, LPVOID lpReserved )
{
return(TRUE);
}
#endif
DE_ENTRYSC DE_LRESULT DE_ENTRYMOD DEProc( message, wParam, lParam, lpDisplay )
DE_MESSAGE message;
DE_WPARAM wParam;
DE_LPARAM lParam;
POIB_DISPLAY lpDisplay;
{
DEVICE hdc;
RECT theRect;
WORD i;
SOPOINT ptCsr;
SHORT x;
SHORT y;
switch( message )
{
case SCCD_LOADDE:
OIBLoadInit();
case SCCD_UNLOADDE:
#ifdef NEVER
((SCCDOPTIONPROC) lParam) (wParam, sizeof(BITMAPOPT), (LPBITMAPOPT) &Options );
#endif
return 0;
case SCCD_SIZE:
{
theRect = *(RECT VWPTR *)(lParam);
lpDisplay->nWindowWidth = (SHORT)(theRect.right - theRect.left);
lpDisplay->nWindowHeight = (SHORT)(theRect.bottom - theRect.top);
lpDisplay->winRect = theRect;
if( Options.wScaleMode != OIBMENU_NOSCALING &&
!(lpDisplay->wFlags & OIBF_ZOOMSELECT) )
{
OIBSetScaleValues(lpDisplay, lpDisplay->wMagnification);
OIBSetupScrollBars( lpDisplay );
}
if( lpDisplay->wFlags & OIBF_IMAGEPRESENT )
{
if( Options.wScaleMode != OIBMENU_NOSCALING && lpDisplay->wMagnification == 1 )
{
OIBClearSelection(lpDisplay);
lpDisplay->ptWinOrg.x = 0;
lpDisplay->ptWinOrg.y = 0;
DUInvalRect(lpDisplay,NULL);
}
else
{
// See if we need to shift the display around...
if( lpDisplay->ptScaledImageSize.y <= lpDisplay->nWindowHeight )
y = 0;
else
y = min( lpDisplay->ptWinOrg.y, lpDisplay->ptScaledImageSize.y - lpDisplay->nWindowHeight );
if( lpDisplay->ptScaledImageSize.x <= lpDisplay->nWindowWidth )
x = 0;
else
x = min( lpDisplay->ptWinOrg.x, lpDisplay->ptScaledImageSize.x - lpDisplay->nWindowWidth );
if( lpDisplay->ptWinOrg.x != x || lpDisplay->ptWinOrg.y != y )
{
if( lpDisplay->bSelectionMade )
{
for(i=0; i<5; i++ )
{
lpDisplay->ptSelBox[i].x += lpDisplay->ptWinOrg.x;
lpDisplay->ptSelBox[i].x -= x;
lpDisplay->ptSelBox[i].y += lpDisplay->ptWinOrg.y;
lpDisplay->ptSelBox[i].y -= y;
}
}
lpDisplay->ptWinOrg.x = x;
lpDisplay->ptWinOrg.y = y;
if( lpDisplay->wScaleTo != lpDisplay->wScaleFrom )
OIBNPFixScaledPoints( &(lpDisplay->ptWinOrg), lpDisplay, 1 );
DUInvalRect(lpDisplay,NULL);
}
}
// Set the scroll range.
OIBSetupScrollBars( lpDisplay );
}
else if( Options.wScaleMode != OIBMENU_NOSCALING )
DUInvalRect(lpDisplay,NULL);
}
return 0;
case SCCD_LBUTTONDOWN:
#ifdef SCCFEATURE_SELECT
if( !lpDisplay->bSelecting && (lpDisplay->wFlags & OIBF_IMAGEPRESENT) )
{
ptCsr.x = (SHORT) LOWORD(lParam);
ptCsr.y = (SHORT) HIWORD(lParam);
BUAdjustCursorOffset(lpDisplay,ptCsr);
if( (ptCsr.x < lpDisplay->ptScreenClip.x) &&
(ptCsr.y < lpDisplay->ptScreenClip.y) &&
!(wParam & SCCD_MOUSESHIFT) &&
!(wParam & SCCD_MOUSECONTROL) )
{
OIBClearSelection(lpDisplay);
OIBStartSelection( &ptCsr, lpDisplay );
}
}
return 0;
case SCCD_MOUSEMOVE:
if( lpDisplay->bSelecting )
{
ptCsr.x = (SHORT) LOWORD(lParam);
ptCsr.y = (SHORT) HIWORD(lParam);
BUAdjustCursorOffset(lpDisplay,ptCsr);
if( lpDisplay->wScaleTo != lpDisplay->wScaleFrom )
OIBNPFixScaledPoints( &ptCsr, lpDisplay, 1 );
if( ptCsr.x < 0 )
{
if( lpDisplay->ptWinOrg.x )
{
if( !(lpDisplay->wFlags & OIBF_BACKGROUNDSELECT) )
{
// SccBkBackgroundOn( lpDisplay->Gen.hWnd, 0 );
lpDisplay->wFlags |= OIBF_BACKGROUNDSELECT;
}
OIBHScrollImage( SCCD_HLEFT, (SHORT)(0 - ptCsr.x), lpDisplay );
}
ptCsr.x = 0;
}
else if( ptCsr.x >= (SHORT) lpDisplay->ptScreenClip.x )
{
if( lpDisplay->ptWinOrg.x+lpDisplay->nWindowWidth < (SHORT) lpDisplay->ptScaledImageSize.x )
{
if( !(lpDisplay->wFlags & OIBF_BACKGROUNDSELECT) )
{
// SccBkBackgroundOn( lpDisplay->Gen.hWnd, 0 );
lpDisplay->wFlags |= OIBF_BACKGROUNDSELECT;
}
OIBHScrollImage( SCCD_HRIGHT, (SHORT)(ptCsr.x-lpDisplay->ptScreenClip.x), lpDisplay );
}
ptCsr.x = lpDisplay->ptScreenClip.x-1;
}
if( ptCsr.y < 0 )
{
if( lpDisplay->ptWinOrg.y )
{
if( !(lpDisplay->wFlags & OIBF_BACKGROUNDSELECT) )
{
// SccBkBackgroundOn( lpDisplay->Gen.hWnd, 0 );
lpDisplay->wFlags |= OIBF_BACKGROUNDSELECT;
}
OIBVScrollImage( SCCD_VUP, (SHORT)(0 - ptCsr.y), lpDisplay );
}
ptCsr.y = 0;
}
else if( ptCsr.y >= (SHORT) lpDisplay->ptScreenClip.y )
{
if( lpDisplay->ptWinOrg.y+lpDisplay->nWindowHeight < (SHORT) lpDisplay->ptScaledImageSize.y )
{
if( !(lpDisplay->wFlags & OIBF_BACKGROUNDSELECT) )
{
// SccBkBackgroundOn( lpDisplay->Gen.hWnd, 0 );
lpDisplay->wFlags |= OIBF_BACKGROUNDSELECT;
}
OIBVScrollImage( SCCD_VDOWN, (SHORT)(ptCsr.y - lpDisplay->ptScreenClip.y +1), lpDisplay );
}
ptCsr.y = lpDisplay->ptScreenClip.y-1;
}
if( (lpDisplay->ptSelBox[2].x != ptCsr.x) || (lpDisplay->ptSelBox[2].y != ptCsr.y) )
{
DUBeginDraw ( lpDisplay );
BUAdjustWindowOffset(lpDisplay);
OIBNPDrawSelectBox(lpDisplay);
lpDisplay->ptSelBox[2] = ptCsr;
lpDisplay->ptSelBox[1].x = ptCsr.x;
lpDisplay->ptSelBox[1].y = lpDisplay->ptSelBox[0].y;
lpDisplay->ptSelBox[3].x = lpDisplay->ptSelBox[0].x;
lpDisplay->ptSelBox[3].y = ptCsr.y;
OIBNPDrawSelectBox( lpDisplay );
BURestoreWindowOffset(lpDisplay);
DUEndDraw( lpDisplay );
}
}
return 0;
#endif //SCCFEATURE_SELECT
case SCCD_LBUTTONUP:
#ifdef SCCFEATURE_SELECT
if( lpDisplay->bSelecting )
{
lpDisplay->bSelecting = FALSE;
if( (lpDisplay->ptSelBox[0].x != lpDisplay->ptSelBox[2].x) ||
(lpDisplay->ptSelBox[0].y != lpDisplay->ptSelBox[2].y) )
{
lpDisplay->bSelectionMade = TRUE;
// Relate the marked block to coordinates of the real image.
lpDisplay->rcSelect.top = min( lpDisplay->ptSelBox[0].y, lpDisplay->ptSelBox[2].y ) + lpDisplay->ptWinOrg.y;
lpDisplay->rcSelect.left = min( lpDisplay->ptSelBox[0].x, lpDisplay->ptSelBox[2].x ) + lpDisplay->ptWinOrg.x;
lpDisplay->rcSelect.bottom = max( lpDisplay->ptSelBox[0].y, lpDisplay->ptSelBox[2].y ) + lpDisplay->ptWinOrg.y +1;
lpDisplay->rcSelect.right = max( lpDisplay->ptSelBox[0].x, lpDisplay->ptSelBox[2].x ) + lpDisplay->ptWinOrg.x +1;
if( lpDisplay->wScaleTo != lpDisplay->wScaleFrom )
OIBNPReverseScaleRect( NULL, &lpDisplay->rcSelect, lpDisplay );
if( (lpDisplay->rcSelect.top == 0) && (lpDisplay->rcSelect.left == 0) &&
(lpDisplay->rcSelect.bottom == lpDisplay->Image.DisplaySize.y) &&
(lpDisplay->rcSelect.right == lpDisplay->Image.DisplaySize.x) )
{
lpDisplay->wFlags |= OIBF_SELECTALL;
}
}
if( lpDisplay->wFlags & OIBF_BACKGROUNDSELECT )
{
lpDisplay->wFlags &= ~OIBF_BACKGROUNDSELECT;
// SccBkBackgroundOff( lpDisplay->Gen.hWnd );
}
BUReleaseMouse();
return 0;
}
#endif // SCCFEATURE_SELECT
#ifdef SCCFEATURE_SCALING
if( wParam & SCCD_MOUSESHIFT && (lpDisplay->wFlags & OIBF_MAGNIFIED) )
OIBTurnOffTheDamnZoom(lpDisplay);
else if( wParam & SCCD_MOUSECONTROL && (lpDisplay->wMagnification < OIB_MAXZOOM) )
{
ptCsr.x = (SHORT) LOWORD(lParam);
ptCsr.y = (SHORT) HIWORD(lParam);
BUAdjustCursorOffset(lpDisplay,ptCsr);
if( (ptCsr.x < lpDisplay->ptScreenClip.x) &&
(ptCsr.y < lpDisplay->ptScreenClip.y) )
{
OIBMagnifyDisplay( (PSOPOINT) &ptCsr, (SHORT)(lpDisplay->wMagnification+1), lpDisplay );
}
}
#endif
return 0;
case SCCD_GETDOCDIMENSIONS:
((LPLONGPOINT)lParam)->x = lpDisplay->Image.wWidth;
((LPLONGPOINT)lParam)->y = lpDisplay->Image.wHeight;
return TRUE;
case SCCD_GETDOCORIGIN:
((LPLONGPOINT)lParam)->x = lpDisplay->ptWinOrg.x;
((LPLONGPOINT)lParam)->y = lpDisplay->ptWinOrg.y;
return TRUE;
#ifdef SCCFEATURE_SCALING
case SCCD_RBUTTONDOWN:
if( (lpDisplay->wFlags & OIBF_IMAGEPRESENT) &&
((SHORT) LOWORD(lParam) < lpDisplay->ptScreenClip.x) && ((SHORT) HIWORD(lParam) < lpDisplay->ptScreenClip.y) )
{
BUCaptureMouse(lpDisplay);
lpDisplay->wFlags |= OIBF_RBUTTONDOWN;
}
return 0;
case SCCD_RBUTTONUP:
if( lpDisplay->wFlags & OIBF_RBUTTONDOWN )
{
// Zoom, baby, zoom.
lpDisplay->wFlags &= ~OIBF_RBUTTONDOWN;
BUReleaseMouse();
if( ((SHORT) LOWORD(lParam) < lpDisplay->ptScreenClip.x) && ((SHORT) HIWORD(lParam) < lpDisplay->ptScreenClip.y) )
{
if( wParam & SCCD_MOUSESHIFT )
{
if( lpDisplay->wFlags & OIBF_MAGNIFIED )
OIBTurnOffTheDamnZoom(lpDisplay);
}
else if( lpDisplay->wMagnification < OIB_MAXZOOM )
OIBMagnifyDisplay( (PSOPOINT) &lParam, (SHORT)(lpDisplay->wMagnification+1), lpDisplay );
}
}
return 0;
#endif //SCCFEATURE_SCALING
#ifdef SCCFEATURE_SELECT
case SCCVW_SELECTALL:
if( lpDisplay->wFlags & OIBF_IMAGEPRESENT )
OIBSelectAll(lpDisplay);
return 0;
#endif
case SCCD_UPDATE:
if( lpDisplay->Image.wNumTiles )
{
OIBDisplayImage( lpDisplay, (RECT VWPTR *)(lParam) );
#ifdef SCCFEATURE_SELECT
if( lpDisplay->bSelectionMade || lpDisplay->bSelecting )
OIBNPDrawSelectBox( lpDisplay );
#endif
}
return 0;
case SCCD_UPDATERECT:
if( lpDisplay->Image.wNumTiles )
{
LONGRECT theLongRect = *((LPLONGRECT)lParam);
theRect.left = (SHORT) theLongRect.left;
theRect.top = (SHORT) theLongRect.top;
theRect.right = (SHORT) theLongRect.right;
theRect.bottom = (SHORT) theLongRect.bottom;
BUSaveWindowOrg( lpDisplay->Gen.hDC, lpDisplay );
BUSetWindowOrg( lpDisplay->Gen.hDC, theRect.left, theRect.top );
OIBNPSetPalette( lpDisplay->Gen.hDC, lpDisplay );
OIBDrawBitmap( lpDisplay->Gen.hDC, &theRect, lpDisplay );
BURestoreWindowOrg( lpDisplay->Gen.hDC, lpDisplay );
}
return 0;
case SCCD_VSCROLL:
if( !(lpDisplay->wFlags & OIBF_IMAGEPRESENT) )
return 0;
OIBVScrollImage( (WORD)wParam, (SHORT)(LOWORD(lParam)), lpDisplay );
return 0;
case SCCD_HSCROLL:
if( !(lpDisplay->wFlags & OIBF_IMAGEPRESENT) )
return 0;
OIBHScrollImage( (WORD)wParam, (SHORT)(LOWORD(lParam)), lpDisplay );
return 0;
#ifdef SCCFEATURE_CLIP
case SCCD_GETRENDERINFO:
OIBNPGetRenderInfo( lpDisplay, (PSCCDRENDERINFO) lParam, (WORD)wParam );
return 0;
case SCCD_GETRENDERCOUNT:
return OIBNP_RENDERCOUNT;
case SCCD_RENDERDATA:
{
DWORD dwRet;
if( !lpDisplay->bSelectionMade )
{
// Use i to flag this case...
OIBSelectAll( lpDisplay );
i=1;
}
else
i=0;
dwRet = OIBNPRenderData( lpDisplay, (PSCCDRENDERDATA) lParam, (WORD)wParam );
if( i )
OIBClearSelection(lpDisplay);
return dwRet;
}
#endif
#ifdef SCCFEATURE_DRAWTORECT
case SCCD_INITDRAWTORECT:
return OIBNPInitDrawToRect((PSCCDDRAWTORECT)lParam, lpDisplay);
case SCCD_MAPDRAWTORECT:
return OIBNPMapDrawToRect((PSCCDDRAWTORECT)lParam, lpDisplay);
case SCCD_DRAWTORECT:
return OIBNPDrawToRect((PSCCDDRAWTORECT)lParam, lpDisplay);
#endif
#ifdef WINDOWS
case SCCD_BACKGROUND:
if( lpDisplay->wFlags & OIBF_BACKGROUNDSELECT )
{
BUGetCursorPos( &ptCsr );
BUGlobalToLocal( lpDisplay, &ptCsr );
SendMessage( lpDisplay->Gen.hWnd, SCCD_MOUSEMOVE, MK_LBUTTON, MAKELONG(ptCsr.x,ptCsr.y) );
}
return 0;
#ifdef SCCFEATURE_MENU
case SCCD_FILLMENU:
return ( OIBNPFillMenu( (HMENU)wParam, LOWORD(lParam) ) );
#endif //SCCFEATURE_MENU
/*
| I'm not ifdef'ing the DOMENUITEM messages, because they could
| be used whether or not an actual menu is present.
|
| PJB - I am ifdef'ing so I can compile
*/
#ifdef MSCHICAGO
case SCCD_DOMENUITEM:
switch(lParam)
{
case SCCID_BMPROTATION_0:
if( OIBNPChooseRotation( lpDisplay, OIB_NOROTATION, (HANDLE)wParam, (WORD) lParam ) )
OIBSetRotation( lpDisplay, OIB_NOROTATION );
break;
case SCCID_BMPROTATION_90:
if( OIBNPChooseRotation( lpDisplay, OIBMENU_ROTATE90, (HANDLE)wParam, (WORD) lParam ) )
OIBSetRotation( lpDisplay, OIB_ROTATE90 );
break;
case SCCID_BMPROTATION_180:
if( OIBNPChooseRotation( lpDisplay, OIBMENU_ROTATE180, (HANDLE)wParam, (WORD) lParam ) )
OIBSetRotation( lpDisplay, OIB_ROTATE180 );
break;
case SCCID_BMPROTATION_270:
if( OIBNPChooseRotation( lpDisplay, OIBMENU_ROTATE270, (HANDLE)wParam, (WORD) lParam ) )
OIBSetRotation( lpDisplay, OIB_ROTATE270 );
break;
}
break;
#endif //MSCHICAGO
#ifdef SCCFEATURE_MENU
case SCCD_DOMENUITEM:
switch( (WORD)lParam )
{
#ifdef SCCFEATURE_SCALING
case OIBMENU_NOSCALING:
case OIBMENU_SCALETOWINDOW:
case OIBMENU_SCALETOWIDTH:
case OIBMENU_SCALETOHEIGHT:
// Uncheck the current selection.
BUUncheckMenuItem( lpDisplay, Options.wScaleMode );
BUCheckMenuItem( lpDisplay, (WORD)lParam );
Options.wScaleMode = (WORD)lParam;
// A scaling change resets the image's position in the window.
OIBResetDisplay( lpDisplay );
break;
#endif //SCCFEATURE_SCALING
#ifdef SCCFEATURE_FULLSCREEN
case OIBMENU_SHOWFULLSCREEN:
OIBShowFullScreen( lpDisplay );
break;
#endif //SCCFEATURE_FULLSCREEN
#ifdef SCCFEATURE_DITHER
case OIBMENU_DITHER:
OIBWToggleDithering( lpDisplay, (HMENU) wParam );
break;
#endif //SCCFEATURE_DITHER
#ifdef SCCFEATURE_ROTATION
case OIBMENU_NOROTATION:
if( OIBNPChooseRotation( lpDisplay, OIB_NOROTATION, (HANDLE)wParam, (WORD) lParam ) )
OIBSetRotation( lpDisplay, OIB_NOROTATION );
break;
case OIBMENU_ROTATE90:
if( OIBNPChooseRotation( lpDisplay, OIBMENU_ROTATE90, (HANDLE)wParam, (WORD) lParam ) )
OIBSetRotation( lpDisplay, OIB_ROTATE90 );
break;
case OIBMENU_ROTATE180:
if( OIBNPChooseRotation( lpDisplay, OIBMENU_ROTATE180, (HANDLE)wParam, (WORD) lParam ) )
OIBSetRotation( lpDisplay, OIB_ROTATE180 );
break;
case OIBMENU_ROTATE270:
if( OIBNPChooseRotation( lpDisplay, OIBMENU_ROTATE270, (HANDLE)wParam, (WORD) lParam ) )
OIBSetRotation( lpDisplay, OIB_ROTATE270 );
break;
#endif //SCCFEATURE_ROTATION
/***
case OIBMENU_CUSTOMMAG:
break;
***/
default:
#ifdef SCCFEATURE_SCALING
lParam -= OIBMENU_MAGNIFYPOPUP;
if( lParam >= 1 && lParam <= OIB_MAXZOOM )
{
// Magnification change, baby.
ptCsr.x = min(lpDisplay->nWindowWidth, lpDisplay->ptScaledImageSize.x) / 2;
ptCsr.y = min(lpDisplay->nWindowHeight, lpDisplay->ptScaledImageSize.y) / 2;
OIBClearSelection( lpDisplay );
OIBMagnifyDisplay( (PSOPOINT)&ptCsr, (WORD)lParam, lpDisplay );
}
#endif // SCCFEATURE_SCALING
break;
}
return 0;
#endif // SCCFEATURE_MENU
case WM_KEYDOWN:
switch( wParam )
{
case SCCD_KPAGEUP: // Page up.
SendMessage( lpDisplay->Gen.hWnd, SCCD_VSCROLL, SCCD_VPAGEUP, 0L );
return 0;
case SCCD_KPAGEDOWN: // Page down.
SendMessage( lpDisplay->Gen.hWnd, SCCD_VSCROLL, SCCD_VPAGEDOWN, 0L );
return 0;
case SCCD_KUP:
SendMessage( lpDisplay->Gen.hWnd, SCCD_VSCROLL, SCCD_VUP, 0L );
return 0;
case SCCD_KDOWN:
SendMessage( lpDisplay->Gen.hWnd, SCCD_VSCROLL, SCCD_VDOWN, 0L );
return 0;
case SCCD_KRIGHT:
SendMessage( lpDisplay->Gen.hWnd, SCCD_HSCROLL, SCCD_HRIGHT, 0L );
return 0;
case SCCD_KLEFT:
SendMessage( lpDisplay->Gen.hWnd, SCCD_HSCROLL, SCCD_HLEFT, 0L );
return 0;
case SCCD_KHOME:
SendMessage( lpDisplay->Gen.hWnd, SCCD_HSCROLL, SCCD_HPOSITION, 0L );
SendMessage( lpDisplay->Gen.hWnd, SCCD_VSCROLL, SCCD_VPOSITION, 0L );
return 0;
case SCCD_KEND:
SendMessage( lpDisplay->Gen.hWnd, SCCD_HSCROLL, SCCD_HPOSITION, MAKELONG(lpDisplay->nHScrollMax, 0) );
SendMessage( lpDisplay->Gen.hWnd, SCCD_VSCROLL, SCCD_VPOSITION, MAKELONG(lpDisplay->nVScrollMax, 0) );
return 0;
}
break;
case WM_PALETTECHANGED:
if( (HWND)wParam == lpDisplay->Gen.hWnd )
break;
case WM_QUERYNEWPALETTE:
if( lpDisplay->wFlags & OIBF_IMAGEPRESENT && lpDisplay->Image.hPalette != NULL )
{
HPALETTE hOldPal;
hdc = GetDC(lpDisplay->Gen.hWnd);
// hOldPal = SelectPalette( hdc, lpDisplay->Image.hPalette, 0 );
hOldPal = SelectPalette( hdc, lpDisplay->Image.hPalette, (message==WM_QUERYNEWPALETTE)?FALSE:TRUE );
i = RealizePalette( hdc );
SelectPalette( hdc, hOldPal, TRUE );
ReleaseDC( lpDisplay->Gen.hWnd, hdc );
if( i )
DUInvalRect( lpDisplay, NULL );
return( i );
}
return 0;
case WM_SETFOCUS:
if( !IsIconic(lpDisplay->Gen.hWnd) &&
lpDisplay->Image.hPalette != NULL )
{
hdc = GetDC( lpDisplay->Gen.hWnd );
SelectPalette( hdc, lpDisplay->Image.hPalette, TRUE );
RealizePalette( hdc );
ReleaseDC( lpDisplay->Gen.hWnd, hdc );
}
return 0;
#ifdef SCCFEATURE_OPTIONS
case SCCD_DOOPTION:
{
LPSCCDOPTIONINFO lpOp;
lpOp = (LPSCCDOPTIONINFO) lParam;
#ifdef SCCFEATURE_PRINT
if ( lpOp->dwType == SCCD_OPPRINT )
return( OIBNPDoPrintOptions( (LPSCCDOPTIONINFO) lParam ) );
#endif //SCCFEATURE_PRINT
#ifdef SCCFEATURE_CLIP
if ( lpOp->dwType == SCCD_OPCLIPBOARD )
return( OIBNPDoClipOptions( (LPSCCDOPTIONINFO) lParam ) );
#endif //SCCFEATURE_CLIP
}
return 0;
#endif //SCCFEATURE_OPTIONS
#endif //WINDOWS
case SCCD_OPENDISPLAY:
if( !(lpDisplay->wFlags & OIBF_RENDERIMAGEONLY) )
{
DUSetHScrollRange( lpDisplay, 0, 0);
DUSetVScrollRange( lpDisplay, 0, 0);
DUEnableHScroll( lpDisplay, 0 );
DUEnableVScroll( lpDisplay, 0 );
DUSetHScrollPos( lpDisplay, 0 );
DUSetVScrollPos( lpDisplay, 0 );
#ifdef SCCFEATURE_SELECT
DUSendParent( lpDisplay, SCCVW_SELCHANGE, 0, 0L );
#endif
BUSetWaitCursor();
OIBInitBitmapDisplay( lpDisplay, 0 );
#ifdef SCCFEATURE_MENU
if( lpDisplay->wFlags & OIBF_DITHERABLE )
BUEnableMenuItem( lpDisplay, OIBMENU_DITHER );
else
BUDisableMenuItem( lpDisplay, OIBMENU_DITHER );
#endif //SCCFEATURE_MENU
OIBSetScaleValues( lpDisplay, 1 );
}
else
OIBInitBitmapDisplay( lpDisplay, 0 );
// Fall through.
case SCCD_READAHEAD:
if( OIBHandleReadAhead( lpDisplay ) )
{
if( !(lpDisplay->wFlags & OIBF_RENDERIMAGEONLY) )
{
lpDisplay->wFlags |= OIBF_IMAGEPRESENT;
BUSetNormalCursor();
OIBSetupScrollBars( lpDisplay );
#ifdef SCCFEATURE_SELECT
DUSendParent(lpDisplay, SCCVW_SELCHANGE, 1, 0L );
#endif
}
}
return 0;
case SCCD_CLOSEDISPLAY:
case SCCD_CLOSEFATAL:
Options.bDither = lpDisplay->bDither;
OIBDeInitDisplay(lpDisplay);
return 0;
case SCCD_GETINFO:
switch( wParam )
{
case SCCD_GETVERSION:
return SCCD_CURRENTVERSION;
case SCCD_GETGENINFOSIZE:
return sizeof(SCCDGENINFO);
case SCCD_GETDISPLAYINFOSIZE:
return sizeof(OIB_DISPLAY);
case SCCD_GETDISPLAYTYPE:
return MAKELONG(SO_BITMAP,SCCD_CHUNK);
case SCCD_GETFUNCTIONS:
return (SCCD_FNCLIPBOARD | SCCD_FNPRINT | SCCD_FNPRINTSEL);
case SCCD_GETOPTIONS:
return (SCCD_OPNEEDMENU|SCCD_OPPRINT|SCCD_OPCLIPBOARD);
case SCCD_GETPOSITIONSIZE:
return( sizeof(RECT) );
case SCCD_GETNAME:
return(SCCID_BITMAPDENAME);
break;
#ifdef NEVER
#ifdef WINDOWS
locStr[0] = '\0';
//JKXXX LoadString( hInst, OIBSTR_DENAME, locStr, 100 );
lstrcpy( (LPSTR)lParam, locStr );
#endif
#endif
default:
return 0;
}
}
#ifdef WINDOWS
return( DefWindowProc( lpDisplay->Gen.hWnd, message, wParam, lParam ));
#endif
}
VOID OIBResetDisplay( lpDisplay )
POIB_DISPLAY lpDisplay;
{
OIBClearSelection(lpDisplay);
OIBSetScaleValues(lpDisplay, 1);
lpDisplay->ptWinOrg.x = 0;
lpDisplay->ptWinOrg.y = 0;
OIBSetupScrollBars( lpDisplay );
DUInvalRect(lpDisplay,NULL);
DUUpdateWindow(lpDisplay);
}
#ifdef SCCFEATURE_SELECT
VOID OIBStartSelection( pStart, lpDisplay )
PSOPOINT pStart;
POIB_DISPLAY lpDisplay;
{
SOPOINT ptCsr;
WORD i;
lpDisplay->bSelecting = TRUE;
ptCsr = *pStart;
if( lpDisplay->wScaleTo != lpDisplay->wScaleFrom )
OIBNPFixScaledPoints( &ptCsr, lpDisplay, 1 );
for( i=0; i<5; i++ )
lpDisplay->ptSelBox[i] = ptCsr;
BUCaptureMouse(lpDisplay);
}
VOID OIBSelectAll(lpDisplay)
POIB_DISPLAY lpDisplay;
{
DUBeginDraw(lpDisplay);
if( lpDisplay->bSelecting || lpDisplay->bSelectionMade )
{
OIBNPDrawSelectBox(lpDisplay);
lpDisplay->bSelecting = FALSE;
}
lpDisplay->bSelectionMade = TRUE;
lpDisplay->wFlags |= OIBF_SELECTALL;
lpDisplay->rcSelect.top = 0;
lpDisplay->rcSelect.left = 0;
lpDisplay->rcSelect.bottom = lpDisplay->Image.DisplaySize.y;
lpDisplay->rcSelect.right = lpDisplay->Image.DisplaySize.x;
lpDisplay->ptSelBox[0].x = 0;
lpDisplay->ptSelBox[0].y = 0;
lpDisplay->ptSelBox[4] = lpDisplay->ptSelBox[0];
lpDisplay->ptSelBox[2].x = lpDisplay->ptScaledImageSize.x -1;
lpDisplay->ptSelBox[2].y = lpDisplay->ptScaledImageSize.y -1;
lpDisplay->ptSelBox[1].x = lpDisplay->ptScaledImageSize.x -1;
lpDisplay->ptSelBox[1].y = 0;
lpDisplay->ptSelBox[3].x = 0;
lpDisplay->ptSelBox[3].y = lpDisplay->ptScaledImageSize.y -1;
OIBNPDrawSelectBox(lpDisplay);
DUEndDraw(lpDisplay);
}
VOID OIBClearSelection( lpDisplay )
POIB_DISPLAY lpDisplay;
{
if( lpDisplay->bSelectionMade )
{
lpDisplay->bSelectionMade = FALSE;
lpDisplay->wFlags &= ~OIBF_SELECTALL;
DUBeginDraw( lpDisplay );
OIBNPDrawSelectBox( lpDisplay );
DUEndDraw( lpDisplay );
}
}
#endif // SCCFEATURE_SELECT
#ifdef SCCFEATURE_SCALING
VOID OIBMagnifyDisplay( lpCenter, wMag, lpDisplay )
PSOPOINT lpCenter;
WORD wMag;
POIB_DISPLAY lpDisplay;
{
SOPOINT ptCenter, WinOrg, WinSize;
DEVICE hdc;
// WORD wOldMag;
ptCenter = *lpCenter;
ptCenter.x += lpDisplay->ptWinOrg.x;
ptCenter.y += lpDisplay->ptWinOrg.y;
hdc = BUGetDevice(lpDisplay);
// wOldMag = lpDisplay->wMagnification;
// Get center point in image coordinates
OIBNPSetScaling( hdc, lpDisplay->wScaleFrom, lpDisplay->wScaleTo );
OIBNPReverseScale( hdc, &ptCenter, 1, lpDisplay );
if( lpDisplay->bSelectionMade && BUPointInRect( &lpDisplay->rcSelect, ptCenter ) )
{
// Magnify the selection.
ptCenter.x = lpDisplay->rcSelect.left + (lpDisplay->rcSelect.right - lpDisplay->rcSelect.left)/2;
ptCenter.y = lpDisplay->rcSelect.top + (lpDisplay->rcSelect.bottom - lpDisplay->rcSelect.top)/2;
wMag = 0; // This will be updated in OIBSetScaleValues
}
else
lpDisplay->wFlags &= ~OIBF_ZOOMSELECT;
OIBClearSelection( lpDisplay );
// Calculate new scaling values
OIBSetScaleValues( lpDisplay, wMag );
// OIBNPUpdateMagMenu( lpDisplay, wOldMag );
WinSize.x = lpDisplay->nWindowWidth;
WinSize.y = lpDisplay->nWindowHeight;
// Get window size in image coordinates, using new scaling values.
OIBNPSetScaling( hdc, lpDisplay->wScaleFrom, lpDisplay->wScaleTo );
OIBNPReverseScale( hdc, &WinSize, 1, lpDisplay );
// Position window around center point.
WinOrg.x = ptCenter.x - WinSize.x/2;
if( WinOrg.x < 0 )
WinOrg.x = 0;
else if( WinOrg.x + WinSize.x > lpDisplay->Image.DisplaySize.x )
WinOrg.x = max( 0, lpDisplay->Image.DisplaySize.x - WinSize.x );
WinOrg.y = ptCenter.y - WinSize.y/2;
if( WinOrg.y < 0 )
WinOrg.y = 0;
else if( WinOrg.y + WinSize.y > lpDisplay->Image.DisplaySize.y )
WinOrg.y = max( 0, lpDisplay->Image.DisplaySize.y - WinSize.y );
// Get window origin in device coordinates.
OIBNPScale(hdc, &WinOrg, 1, lpDisplay );
BUReleaseDevice( lpDisplay, hdc );
lpDisplay->ptWinOrg = WinOrg;
DUInvalRect( lpDisplay, NULL );
OIBSetupScrollBars( lpDisplay );
}
VOID OIBTurnOffTheDamnZoom(lpDisplay)
POIB_DISPLAY lpDisplay;
{
SOPOINT WinOrg;
WORD wOldMag;
OIBClearSelection( lpDisplay );
wOldMag = lpDisplay->wMagnification;
WinOrg.x = lpDisplay->ptWinOrg.x;
WinOrg.y = lpDisplay->ptWinOrg.y;
/*
| Get origin in image coordinates, set new scaling values,
| scale the origin with the new values.
| (Remember that even though we're turning off magnification,
| the image may still be scaled to the window size.)
*/
OIBNPReverseScale( NULL, &WinOrg, 1, lpDisplay );
OIBSetScaleValues(lpDisplay, 1);
OIBNPScale( NULL, &WinOrg, 1, lpDisplay );
// OIBNPUpdateMagMenu( lpDisplay, wOldMag );
// Check origin values against limits.
if( WinOrg.x + lpDisplay->nWindowWidth > lpDisplay->ptScaledImageSize.x )
WinOrg.x = max( 0, lpDisplay->ptScaledImageSize.x - lpDisplay->nWindowWidth );
else if( WinOrg.x < 0 )
WinOrg.x = 0;
if( WinOrg.y + lpDisplay->nWindowHeight > lpDisplay->ptScaledImageSize.y )
WinOrg.y = max( 0, lpDisplay->ptScaledImageSize.y - lpDisplay->nWindowHeight );
else if( WinOrg.y < 0 )
WinOrg.y = 0;
lpDisplay->ptWinOrg.x = WinOrg.x;
lpDisplay->ptWinOrg.y = WinOrg.y;
OIBSetupScrollBars(lpDisplay);
DUInvalRect( lpDisplay, NULL );
}
#endif // SCCFEATURE_SCALING
#ifdef SCCFEATURE_CLIP
/*
| The clipboard routines are the only ones that use these functions.
*/
VOID OIBBitShiftCopy( lpDest, lpSource, wShift, wSize, wPixPerLine, wPixPerByte )
HPBYTE lpDest;
HPBYTE lpSource;
WORD wShift;
WORD wSize;
WORD wPixPerLine;
WORD wPixPerByte;
{
WORD i;
BYTE LowMask = 0;
BYTE HiMask;
WORD wShift2 = 8-wShift;
WORD wLimit;
for( i=0; i < wShift2; i++ )
{
LowMask |= 0x80 >> i;
}
HiMask = (BYTE) ~LowMask;
// We have to handle the end conditions separately.
wLimit = wPixPerLine / wPixPerByte;
for( i=0; i< wLimit; i++ )
{
*lpDest = (BYTE) (*lpSource << wShift) & LowMask;
lpSource++;
*lpDest |= (*lpSource >> wShift2) & HiMask;
lpDest++;
}
// Now do any remaining pixels.
if( wLimit != wSize )
*lpDest = (BYTE) (*lpSource << wShift) & LowMask;
}
#endif // SCCFEATURE_CLIP
#ifdef SCCFEATURE_ROTATION
VOID OIBUnrotateRect( lpDisplay, lpRect )
POIB_DISPLAY lpDisplay;
RECT VWPTR * lpRect;
{
RECT locRect;
locRect = *lpRect;
switch( lpDisplay->wRotation )
{
case OIB_ROTATE90:
lpRect->top = lpDisplay->Image.wWidth - locRect.right;
lpRect->bottom = lpDisplay->Image.wWidth - locRect.left;
lpRect->left = locRect.top;
lpRect->right = locRect.bottom;
break;
case OIB_ROTATE180:
lpRect->top = lpDisplay->Image.wHeight - locRect.bottom;
lpRect->bottom = lpDisplay->Image.wHeight - locRect.top;
lpRect->left = lpDisplay->Image.wWidth - locRect.right;
lpRect->right = lpDisplay->Image.wWidth - locRect.left;
break;
case OIB_ROTATE270:
lpRect->top = locRect.left;
lpRect->bottom = locRect.right;
lpRect->left = lpDisplay->Image.wHeight - locRect.bottom;
lpRect->right = lpDisplay->Image.wHeight - locRect.top;
break;
}
}
#endif //SCCFEATURE_ROTATION
VOID OIBSetScaleValues(lpDisplay, wMagnification)
POIB_DISPLAY lpDisplay;
WORD wMagnification;
{
#ifndef SCCFEATURE_SCALING
lpDisplay->wMagnification = 1;
lpDisplay->wFlags &= ~(OIBF_MAGNIFIED | OIBF_ZOOMSELECT);
lpDisplay->wScaleTo = 1;
lpDisplay->wScaleFrom = 1;
lpDisplay->ptScaledImageSize.x = lpDisplay->Image.DisplaySize.x;
lpDisplay->ptScaledImageSize.y = lpDisplay->Image.DisplaySize.y;
#else
WORD wSelWidth, wSelHeight;
DWORD dwScaleTo;
if( wMagnification == 0 )
{
// Magnify the current selection.
wSelWidth = (WORD)(lpDisplay->rcSelect.right - lpDisplay->rcSelect.left);
wSelHeight = (WORD)(lpDisplay->rcSelect.bottom - lpDisplay->rcSelect.top);
if( (DWORD)((DWORD)wSelHeight * (DWORD)lpDisplay->nWindowWidth) <
(DWORD)((DWORD)wSelWidth * (DWORD)lpDisplay->nWindowHeight) )
{
lpDisplay->wScaleTo = lpDisplay->nWindowWidth;
lpDisplay->wScaleFrom = wSelWidth;
}
else
{
lpDisplay->wScaleTo = lpDisplay->nWindowHeight;
lpDisplay->wScaleFrom = wSelHeight;
}
lpDisplay->wMagnification = lpDisplay->wScaleTo / lpDisplay->wScaleFrom;
lpDisplay->wFlags |= (OIBF_MAGNIFIED | OIBF_ZOOMSELECT);
}
else if( wMagnification > 1 )
{
// Apply magnification to current scaling factors.
// Use a DWORD to minimize rounding errors during calculation.
dwScaleTo = lpDisplay->wScaleTo * wMagnification * 1000L;
dwScaleTo /= lpDisplay->wMagnification;
lpDisplay->wScaleTo = (WORD) (dwScaleTo / 1000L);
lpDisplay->wMagnification = wMagnification;
lpDisplay->wFlags |= OIBF_MAGNIFIED;
}
else
{
lpDisplay->wMagnification = 1;
lpDisplay->wFlags &= ~(OIBF_MAGNIFIED | OIBF_ZOOMSELECT);
lpDisplay->wScaleTo = 1;
lpDisplay->wScaleFrom = 1;
// KLUDGEORAMA
// Options.wScaleMode = OIBMENU_SCALETOWINDOW;
switch( Options.wScaleMode )
{
case OIBMENU_SCALETOHEIGHT:
lpDisplay->wScaleTo = lpDisplay->nWindowHeight * lpDisplay->wMagnification;
lpDisplay->wScaleFrom = lpDisplay->Image.DisplaySize.y;
break;
case OIBMENU_SCALETOWIDTH:
lpDisplay->wScaleTo = lpDisplay->nWindowWidth * lpDisplay->wMagnification;
lpDisplay->wScaleFrom = lpDisplay->Image.DisplaySize.x;
break;
case OIBMENU_SCALETOWINDOW:
if( (DWORD)((DWORD)lpDisplay->Image.DisplaySize.y*(DWORD)lpDisplay->nWindowWidth) <
(DWORD)((DWORD)lpDisplay->Image.DisplaySize.x*(DWORD)lpDisplay->nWindowHeight) )
{
lpDisplay->wScaleTo = lpDisplay->nWindowWidth * lpDisplay->wMagnification;
lpDisplay->wScaleFrom = lpDisplay->Image.DisplaySize.x;
}
else
{
lpDisplay->wScaleTo = lpDisplay->nWindowHeight * lpDisplay->wMagnification;
lpDisplay->wScaleFrom = lpDisplay->Image.DisplaySize.y;
}
break;
default:
break;
}
}
lpDisplay->ptScaledImageSize.x = lpDisplay->Image.DisplaySize.x;
lpDisplay->ptScaledImageSize.y = lpDisplay->Image.DisplaySize.y;
if( lpDisplay->wScaleTo != lpDisplay->wScaleFrom )
OIBNPScale( NULL, &(lpDisplay->ptScaledImageSize), 1, lpDisplay );
#endif // SCCFEATURE_SCALING
}
VOID OIBDisplayImage( lpDisplay, lpUpdate )
POIB_DISPLAY lpDisplay;
RECT VWPTR * lpUpdate;
{
DEVICE hdc;
RECT UpdateRect;
SOPOINT WinOrg;
hdc = BUGetDevice( lpDisplay );
UpdateRect = *lpUpdate;
// Account for display offset, if necessary.
OIBNPGetWindowUpdate( &UpdateRect, lpDisplay );
WinOrg = lpDisplay->ptWinOrg;
OIBNPSetPalette( hdc, lpDisplay );
#ifdef SCCFEATURE_SCALING
if( lpDisplay->wScaleTo != lpDisplay->wScaleFrom )
{
OIBNPSaveScaling( hdc, lpDisplay );
OIBNPSetScaling( hdc, lpDisplay->wScaleFrom, lpDisplay->wScaleTo );
lpDisplay->ptScreenClip.x = lpDisplay->Image.DisplaySize.x;
lpDisplay->ptScreenClip.y = lpDisplay->Image.DisplaySize.y;
OIBNPScale( hdc, &lpDisplay->ptScreenClip, 1, lpDisplay );
lpDisplay->ptScreenClip.x = min( lpDisplay->ptScreenClip.x, lpDisplay->nWindowWidth );
lpDisplay->ptScreenClip.y = min( lpDisplay->ptScreenClip.y, lpDisplay->nWindowHeight );
// Reverse the scaling on our window boundaries, to make them
// relative to the original image.
OIBNPReverseScale( hdc, &WinOrg, 1, lpDisplay );
OIBNPReverseScaleRect( hdc, &UpdateRect, lpDisplay );
// Avoid rounding errors which occur when display partial pixels
// at the edges of an expanded image.
if( lpDisplay->wScaleTo > lpDisplay->wScaleFrom )
{
if( UpdateRect.left )
UpdateRect.left--;
if( UpdateRect.top )
UpdateRect.top--;
if( UpdateRect.right < lpDisplay->Image.DisplaySize.x )
UpdateRect.right++;
if( UpdateRect.bottom < lpDisplay->Image.DisplaySize.y )
UpdateRect.bottom++;
}
}
else
#endif // SCCFEATURE_SCALING
{
if( lpDisplay->Image.DisplaySize.x < lpDisplay->nWindowWidth )
lpDisplay->ptScreenClip.x = lpDisplay->Image.DisplaySize.x - lpDisplay->ptWinOrg.x;
else
lpDisplay->ptScreenClip.x = lpDisplay->nWindowWidth;
if( lpDisplay->Image.DisplaySize.y < lpDisplay->nWindowHeight )
lpDisplay->ptScreenClip.y = lpDisplay->Image.DisplaySize.y - lpDisplay->ptWinOrg.y;
else
lpDisplay->ptScreenClip.y = lpDisplay->nWindowHeight;
}
UpdateRect.left += WinOrg.x;
UpdateRect.top += WinOrg.y;
UpdateRect.right = min( UpdateRect.right+WinOrg.x, lpDisplay->Image.DisplaySize.x );
UpdateRect.bottom = min( UpdateRect.bottom+WinOrg.y, lpDisplay->Image.DisplaySize.y );
BUSaveWindowOrg( hdc, lpDisplay );
BUSetWindowOrg(hdc, WinOrg.x, WinOrg.y);
OIBDrawBitmap( hdc, &UpdateRect, lpDisplay );
if( lpDisplay->wScaleTo != lpDisplay->wScaleFrom )
OIBNPRestoreScaling( hdc, lpDisplay );
BURestoreWindowOrg( hdc, lpDisplay);
}
VOID OIBCheckVisibleTiles(lpDisplay, lpRect)
POIB_DISPLAY lpDisplay;
RECT VWPTR * lpRect;
{
WORD i;
POIBTILE pTile;
RECT TileRect;
lpDisplay->Image.wTilesVisible = 0;
pTile = lpDisplay->Image.pBmpTiles;
for( i=0; i< lpDisplay->Image.wNumTiles; i++ )
{
TileRect.top = pTile->Offset.y;
TileRect.bottom = TileRect.top + pTile->Size.y;
TileRect.left = pTile->Offset.x;
TileRect.right = TileRect.left + pTile->Size.x;
if( (pTile->bVisible = BUIntersectRect(&pTile->VisRect, &TileRect, lpRect)) )
lpDisplay->Image.wTilesVisible++;
pTile++;
}
}
/*
| OIBDrawBitmap
|
| This function draws a rectangle from the current image to the
| specified device context.
*/
VOID OIBDrawBitmap( hdc, lpRect, lpDisplay )
DEVICE hdc;
RECT VWPTR * lpRect;
POIB_DISPLAY lpDisplay;
{
DEVICE device2;
POIBTILE pTile;
WORD i;
// OIBNPSetupBitmapDisplay( hdc, lpDisplay );
device2 = BUCreateCompatibleDevice(hdc);
OIBNPSetPalette( device2, lpDisplay );
OIBCheckVisibleTiles(lpDisplay, lpRect);
pTile = lpDisplay->Image.pBmpTiles;
for( i=0; i< lpDisplay->Image.wNumTiles; i++ )
{
if( pTile->bVisible )
{
if( OIBLoadTile(lpDisplay, pTile, i) )
UTBailOut( SCCCHERR_OUTOFMEMORY );
OIBNPCopyBits( lpDisplay, pTile, hdc, device2,
(LPRECT)&(pTile->VisRect), (LPRECT)NULL );
}
pTile++;
}
BUDeleteDevice( device2 );
}
VOID OIBDeInitDisplay(lpDisplay)
POIB_DISPLAY lpDisplay;
{
if( !(lpDisplay->wFlags & OIBF_RENDERIMAGEONLY) )
{
OIBClearSelection( lpDisplay );
OIBTurnOffTheDamnZoom(lpDisplay);
}
lpDisplay->ptWinOrg.y = 0;
lpDisplay->ptWinOrg.x = 0;
lpDisplay->wFlags &= ~OIBF_IMAGEPRESENT;
OIBNPFreeImageTiles(lpDisplay);
OIBNPFreePalette(lpDisplay);
OIBNPPlatformDeInit( lpDisplay );
}
VOID OIBSetupScrollBars( lpDisplay )
POIB_DISPLAY lpDisplay;
{
lpDisplay->nVScrollMax = lpDisplay->ptScaledImageSize.y - lpDisplay->nWindowHeight;
if( lpDisplay->nVScrollMax <= 0 )
{
lpDisplay->nVScrollMax = 0;
lpDisplay->ptWinOrg.y = 0;
DUSetVScrollPos( lpDisplay, 0 );
}
else
{
if( lpDisplay->ptWinOrg.y > lpDisplay->nVScrollMax )
lpDisplay->ptWinOrg.y = lpDisplay->nVScrollMax;
DUSetVScrollPos( lpDisplay, lpDisplay->ptWinOrg.y );
}
lpDisplay->nHScrollMax = lpDisplay->ptScaledImageSize.x - lpDisplay->nWindowWidth;
if( lpDisplay->nHScrollMax <= 0 )
{
lpDisplay->nHScrollMax = 0;
lpDisplay->ptWinOrg.x = 0;
DUSetHScrollPos( lpDisplay, 0 );
}
else
{
if( lpDisplay->ptWinOrg.x > lpDisplay->nHScrollMax )
lpDisplay->ptWinOrg.x = lpDisplay->nHScrollMax;
DUSetHScrollPos( lpDisplay, lpDisplay->ptWinOrg.x );
}
if( lpDisplay->nVScrollMax > 0 )
{
DUEnableVScroll( lpDisplay, TRUE );
DUSetVScrollRange( lpDisplay, 0, lpDisplay->nVScrollMax );
}
else
DUEnableVScroll( lpDisplay, FALSE );
if( lpDisplay->nHScrollMax > 0 )
{
DUEnableHScroll( lpDisplay, TRUE );
DUSetHScrollRange( lpDisplay, 0, lpDisplay->nHScrollMax );
}
else
DUEnableHScroll( lpDisplay, FALSE );
}
HANDLE OIBCreateBitmap( lpDisplay, pTile, wTile )
POIB_DISPLAY lpDisplay;
POIBTILE pTile;
WORD wTile;
{
DEVICE hdc;
hdc = BUGetNewDevice(lpDisplay);
OIBNPLockBmInfo( lpDisplay );
OIBNPSetPalette( hdc, lpDisplay );
OIBNPSetTileBits(pTile, wTile, hdc, lpDisplay);
OIBNPUnlockBmInfo( lpDisplay );
BUReleaseNewDevice( lpDisplay, hdc);
return( pTile->hBmp );
}
#ifdef SCCFEATURE_ROTATION
VOID OIBSetRotation( lpDisplay, wRotation )
POIB_DISPLAY lpDisplay;
WORD wRotation;
{
WORD wChanges;
WORD wTemp;
wChanges = wRotation ^ lpDisplay->wRotation;
lpDisplay->wRotation = wRotation;
DUInvalRect( lpDisplay, NULL );
BUSetWaitCursor();
if( wChanges )
{
// We have to rebuild everything....
OIBClearSelection(lpDisplay);
lpDisplay->wFlags &= ~OIBF_IMAGEPRESENT;
if( wChanges & OIB_ROTATE90 )
{
wTemp = lpDisplay->Image.wWidth;
lpDisplay->Image.wWidth = lpDisplay->Image.wHeight;
lpDisplay->Image.wHeight = wTemp;
lpDisplay->Image.DisplaySize.x = lpDisplay->Image.wWidth;
lpDisplay->Image.DisplaySize.y = lpDisplay->Image.wHeight;
}
lpDisplay->ptWinOrg.x = 0;
lpDisplay->ptWinOrg.y = 0;
OIBSetScaleValues(lpDisplay, 1);
OIBNPFreeImageTiles( lpDisplay );
BUDisableScrollBar( lpDisplay->Gen.hHorzScroll );
BUDisableScrollBar( lpDisplay->Gen.hVertScroll );
BUSetScrollPos( lpDisplay->Gen.hHorzScroll, 0, TRUE );
BUSetScrollPos( lpDisplay->Gen.hVertScroll, 0, TRUE );
if( OIBHandleReadAhead( lpDisplay ) )
{
lpDisplay->wFlags |= OIBF_IMAGEPRESENT;
BUSetNormalCursor();
OIBSetupScrollBars( lpDisplay );
}
}
}
VOID OIBRotateDIBits( pOrgData, pNewData, wOrgWidth, wOrgHeight, wBitCount )
LPSTR pOrgData;
LPSTR pNewData;
WORD wOrgWidth;
WORD wOrgHeight;
WORD wBitCount;
{
WORD wOrgLineSize;
WORD wNewLineSize;
wOrgLineSize = OIBScanLineSize( wOrgWidth, wBitCount, NULL );
wNewLineSize = OIBScanLineSize( wOrgHeight, wBitCount, NULL );
switch( wBitCount )
{
case 1:
OIBRotate1BitData( (HPBYTE)pOrgData, (HPBYTE)pNewData, wOrgWidth, wOrgHeight, wOrgLineSize, wNewLineSize );
break;
case 4:
OIBRotate4BitData( (HPBYTE)pOrgData, (HPBYTE)pNewData, wOrgWidth, wOrgHeight, wOrgLineSize, wNewLineSize );
break;
case 8:
OIBRotate8BitData( (HPBYTE)pOrgData, (HPBYTE)pNewData, wOrgWidth, wOrgHeight, wOrgLineSize, wNewLineSize );
break;
case 24:
OIBRotate24BitData( (HPBYTE)pOrgData, (HPBYTE)pNewData, wOrgWidth, wOrgHeight, wOrgLineSize, wNewLineSize );
break;
}
}
VOID OIBRotateDIBits180( lpBits, wLineSize, wWidth, wNumLines, wBitCount )
HPBYTE lpBits;
WORD wLineSize;
WORD wWidth;
WORD wNumLines;
WORD wBitCount;
{
WORD i;
HANDLE hLineBuf;
DWORD dwLineSize = (DWORD) wLineSize;
HPBYTE lpBuf;
// This routine is necessary for printing and copying to the clipboard,
// because the StretchBlt flipping only works with device dependent bitmaps.
// Luckily, this won't be necessary for monochrome bitmaps, which can be
// retrieved directly from the device dependent bitmaps with no loss of
// information.
hLineBuf = UTGlobalAlloc( (DWORD)wLineSize );
if( hLineBuf == NULL )
return;
lpBuf = (HPBYTE ) UTGlobalLock( hLineBuf );
// First, let's turn this thing upside down.
for( i=0; i<wNumLines/2; i++ )
{
UTmemcpy( lpBuf, &(lpBits[(DWORD)i*dwLineSize]), wLineSize );
UTmemcpy( (HPBYTE)&(lpBits[(DWORD)i*dwLineSize]), (HPBYTE)&(lpBits[(DWORD)(wNumLines-i-1)*dwLineSize]), wLineSize );
UTmemcpy( (HPBYTE)&(lpBits[(DWORD)((DWORD)wNumLines-i-1)*dwLineSize]), (HPBYTE)lpBuf, wLineSize );
}
// Now let's reverse the pixels on each line.
switch( wBitCount )
{
case 4:
OIBFlip4BitData( lpBits, lpBuf, wLineSize, wWidth, wNumLines );
break;
case 8:
OIBFlip8BitData( lpBits, lpBuf, wLineSize, wWidth, wNumLines );
break;
case 24:
OIBFlip24BitData( lpBits, lpBuf, wLineSize, wWidth, wNumLines );
break;
}
UTGlobalUnlock( hLineBuf );
UTGlobalFree( hLineBuf );
}
VOID OIBFlip4BitData( lpBits, lpLineBuf, wLineSize, wWidth, wNumLines )
HPBYTE lpBits;
HPBYTE lpLineBuf;
WORD wLineSize;
WORD wWidth;
WORD wNumLines;
{
WORD i;
WORD wCurPix;
WORD wBufIndex = 0;
if( wWidth & 0x01 ) // Odd number of pixels
{
for( i=0; i< wNumLines; i++ )
{
wCurPix = wWidth / 2;
for( wBufIndex = 0; wBufIndex < wWidth/2; wBufIndex++ )
{
lpLineBuf[wBufIndex] = (BYTE)(lpBits[wCurPix] & 0xf0) | (lpBits[wCurPix-1] & 0x0f);
wCurPix--;
}
// Set last pixel.
lpLineBuf[wBufIndex] = lpBits[0];
UTmemcpy( lpBits, lpLineBuf, wLineSize );
lpBits += wLineSize;
}
}
else
{
for( i=0; i< wNumLines; i++ )
{
wCurPix = wWidth/2 - 1;
for( wBufIndex = 0; wBufIndex < wWidth/2; wBufIndex++ )
{
lpLineBuf[wBufIndex] = (BYTE)(((lpBits[wCurPix] & 0xf0)>>4) | ((lpBits[wCurPix] & 0x0f)<<4));
wCurPix--;
}
UTmemcpy( lpBits, lpLineBuf, wLineSize );
lpBits += wLineSize;
}
}
}
VOID OIBFlip8BitData( lpBits, lpLineBuf, wLineSize, wWidth, wNumLines )
HPBYTE lpBits;
HPBYTE lpLineBuf;
WORD wLineSize;
WORD wWidth;
WORD wNumLines;
{
WORD i;
WORD wCurPix;
WORD wBufIndex = 0;
for( i=0; i<wNumLines; i++ )
{
wCurPix = wWidth-1;
for(wBufIndex = 0; wBufIndex < wWidth; wBufIndex++ )
{
lpLineBuf[wBufIndex] = lpBits[wCurPix];
wCurPix--;
}
UTmemcpy( lpBits, lpLineBuf, wLineSize );
lpBits += wLineSize;
}
}
VOID OIBFlip24BitData( lpBits, lpLineBuf, wLineSize, wWidth, wNumLines )
HPBYTE lpBits;
HPBYTE lpLineBuf;
WORD wLineSize;
WORD wWidth;
WORD wNumLines;
{
WORD i;
WORD wCurPix;
WORD wBufIndex = 0;
for( i=0; i<wNumLines; i++ )
{
wCurPix = (wWidth-1) * 3;
for(wBufIndex = 0; wBufIndex < wWidth*3; wBufIndex += 3 )
{
lpLineBuf[wBufIndex] = lpBits[wCurPix];
lpLineBuf[wBufIndex+1] = lpBits[wCurPix+1];
lpLineBuf[wBufIndex+2] = lpBits[wCurPix+2];
wCurPix -= 3;
}
UTmemcpy( lpBits, lpLineBuf, wLineSize );
lpBits += wLineSize;
}
}
WORD OIBCreateRotatedBmp( lpDisplay, hdc, lpTile, hChunkData )
POIB_DISPLAY lpDisplay;
DEVICE hdc;
POIBTILE lpTile;
HANDLE hChunkData;
{
HANDLE hNewData;
// NOTE:
// This code assumes that Image.wWidth and Image.wHeight, as well
// as the tile offsets and dimensions, have already been changed to
// reflect the rotation.
hNewData = OIBNPRotateChunk( hChunkData, lpTile, lpDisplay );
if( hNewData != NULL )
OIBNPCreateTileBitmap( lpDisplay, hdc, lpTile, hNewData );
else
lpTile->hBmp = NULL;
return 0;
}
VOID OIBRotate1BitData( pOrgData, pNewData, wOrgWidth, wOrgHeight, wOrgLineSize, wNewLineSize )
HPBYTE pOrgData;
HPBYTE pNewData;
WORD wOrgWidth;
WORD wOrgHeight;
WORD wOrgLineSize;
WORD wNewLineSize;
{
WORD x, y;
DWORD dwOrgOffset, dwNewOffset;
WORD twoNew, threeNew, fourNew, fiveNew, sixNew, sevenNew, eightNew;
WORD twoOrg, threeOrg, fourOrg, fiveOrg, sixOrg, sevenOrg;
WORD wExcess;
WORD mask;
BYTE NewByte;
WORD i, wNumPix;
// Let's only do these multiplications once.
twoNew = 2*wNewLineSize;
threeNew = 3*wNewLineSize;
fourNew = 4*wNewLineSize;
fiveNew = 5*wNewLineSize;
sixNew = 6*wNewLineSize;
sevenNew = 7*wNewLineSize;
eightNew = 8*wNewLineSize;
twoOrg = 2*wOrgLineSize;
threeOrg = 3*wOrgLineSize;
fourOrg = 4*wOrgLineSize;
fiveOrg = 5*wOrgLineSize;
sixOrg = 6*wOrgLineSize;
sevenOrg = 7*wOrgLineSize;
wExcess = wOrgHeight % 8;
if( wExcess )
{
// Let's set the last byte of each new scan line.
dwNewOffset = (DWORD)wNewLineSize * (wOrgWidth-1) + (wOrgHeight-1)/8;
dwOrgOffset = (DWORD)wOrgLineSize * (wOrgHeight-wExcess);
for( x=0; x < wOrgWidth; x+= 8 )
{
mask = 0x0080;
wNumPix = min( 8, wOrgWidth-x );
for( i=0; i<wNumPix; i++ )
{
NewByte = 0;
switch( wExcess )
{
case 7:
if( pOrgData[dwOrgOffset+sixOrg] & mask ) NewByte |= 0x02;
case 6:
if( pOrgData[dwOrgOffset+fiveOrg] & mask ) NewByte |= 0x04;
case 5:
if( pOrgData[dwOrgOffset+fourOrg] & mask ) NewByte |= 0x08;
case 4:
if( pOrgData[dwOrgOffset+threeOrg] & mask ) NewByte |= 0x10;
case 3:
if( pOrgData[dwOrgOffset+twoOrg] & mask ) NewByte |= 0x20;
case 2:
if( pOrgData[dwOrgOffset+wOrgLineSize] & mask ) NewByte |= 0x40;
case 1:
if( pOrgData[dwOrgOffset] & mask ) NewByte |= 0x80;
}
pNewData[dwNewOffset] = NewByte;
dwNewOffset -= wNewLineSize;
mask = mask >> 1;
}
dwOrgOffset++;
}
// Okay, now we're ready for the rest of the damn bitmap.
wOrgHeight -= wExcess;
}
for( y=0; y < wOrgHeight; y+=8 )
{
dwOrgOffset = (DWORD)y * wOrgLineSize;
dwNewOffset = (DWORD)wNewLineSize*(wOrgWidth-1) + y/8; // Remember, DIBs are bottom-to-top.
for( x=0; x < wOrgWidth; x+=8 )
{
wNumPix = min( 8, wOrgWidth-x);
switch( wNumPix )
{
case 8:
pNewData[ dwNewOffset - sevenNew ] =
(BYTE)((pOrgData[ dwOrgOffset] << 7) & 0x80) |
(BYTE)((pOrgData[ dwOrgOffset+wOrgLineSize] << 6) & 0x40) |
(BYTE)((pOrgData[ dwOrgOffset+twoOrg ] << 5) & 0x20) |
(BYTE)((pOrgData[ dwOrgOffset+threeOrg ] << 4) & 0x10) |
(BYTE)((pOrgData[ dwOrgOffset+fourOrg ] << 3) & 0x08) |
(BYTE)((pOrgData[ dwOrgOffset+fiveOrg ] << 2) & 0x04) |
(BYTE)((pOrgData[ dwOrgOffset+sixOrg ] << 1) & 0x02) |
(BYTE)((pOrgData[ dwOrgOffset+sevenOrg ] ) & 0x01);
case 7:
pNewData[ dwNewOffset - sixNew ] =
(BYTE)((pOrgData[ dwOrgOffset] << 6) & 0x80) |
(BYTE)((pOrgData[ dwOrgOffset+wOrgLineSize] << 5) & 0x40) |
(BYTE)((pOrgData[ dwOrgOffset+twoOrg ] << 4) & 0x20) |
(BYTE)((pOrgData[ dwOrgOffset+threeOrg ] << 3) & 0x10) |
(BYTE)((pOrgData[ dwOrgOffset+fourOrg ] << 2) & 0x08) |
(BYTE)((pOrgData[ dwOrgOffset+fiveOrg ] << 1) & 0x04) |
(BYTE)((pOrgData[ dwOrgOffset+sixOrg ] ) & 0x02) |
(BYTE)((pOrgData[ dwOrgOffset+sevenOrg ] >> 1) & 0x01);
case 6:
pNewData[ dwNewOffset - fiveNew ] =
(BYTE)((pOrgData[ dwOrgOffset] << 5) & 0x80) |
(BYTE)((pOrgData[ dwOrgOffset+wOrgLineSize] << 4) & 0x40) |
(BYTE)((pOrgData[ dwOrgOffset+twoOrg ] << 3) & 0x20) |
(BYTE)((pOrgData[ dwOrgOffset+threeOrg ] << 2) & 0x10) |
(BYTE)((pOrgData[ dwOrgOffset+fourOrg ] << 1) & 0x08) |
(BYTE)((pOrgData[ dwOrgOffset+fiveOrg ] ) & 0x04) |
(BYTE)((pOrgData[ dwOrgOffset+sixOrg ] >> 1) & 0x02) |
(BYTE)((pOrgData[ dwOrgOffset+sevenOrg ] >> 2) & 0x01);
case 5:
pNewData[ dwNewOffset - fourNew ] =
(BYTE)((pOrgData[ dwOrgOffset] << 4) & 0x80) |
(BYTE)((pOrgData[ dwOrgOffset+wOrgLineSize] << 3) & 0x40) |
(BYTE)((pOrgData[ dwOrgOffset+twoOrg ] << 2) & 0x20) |
(BYTE)((pOrgData[ dwOrgOffset+threeOrg ] << 1) & 0x10) |
(BYTE)((pOrgData[ dwOrgOffset+fourOrg ] ) & 0x08) |
(BYTE)((pOrgData[ dwOrgOffset+fiveOrg ] >> 1) & 0x04) |
(BYTE)((pOrgData[ dwOrgOffset+sixOrg ] >> 2) & 0x02) |
(BYTE)((pOrgData[ dwOrgOffset+sevenOrg ] >> 3) & 0x01);
case 4:
pNewData[ dwNewOffset - threeNew ] =
(BYTE)((pOrgData[ dwOrgOffset] << 3) & 0x80) |
(BYTE)((pOrgData[ dwOrgOffset+wOrgLineSize] << 2) & 0x40) |
(BYTE)((pOrgData[ dwOrgOffset+twoOrg ] << 1) & 0x20) |
(BYTE)((pOrgData[ dwOrgOffset+threeOrg ] ) & 0x10) |
(BYTE)((pOrgData[ dwOrgOffset+fourOrg ] >> 1) & 0x08) |
(BYTE)((pOrgData[ dwOrgOffset+fiveOrg ] >> 2) & 0x04) |
(BYTE)((pOrgData[ dwOrgOffset+sixOrg ] >> 3) & 0x02) |
(BYTE)((pOrgData[ dwOrgOffset+sevenOrg ] >> 4) & 0x01);
case 3:
pNewData[ dwNewOffset - twoNew ] =
(BYTE)((pOrgData[ dwOrgOffset] << 2) & 0x80) |
(BYTE)((pOrgData[ dwOrgOffset+wOrgLineSize] << 1) & 0x40) |
(BYTE)((pOrgData[ dwOrgOffset+twoOrg ] ) & 0x20) |
(BYTE)((pOrgData[ dwOrgOffset+threeOrg ] >> 1) & 0x10) |
(BYTE)((pOrgData[ dwOrgOffset+fourOrg ] >> 2) & 0x08) |
(BYTE)((pOrgData[ dwOrgOffset+fiveOrg ] >> 3) & 0x04) |
(BYTE)((pOrgData[ dwOrgOffset+sixOrg ] >> 4) & 0x02) |
(BYTE)((pOrgData[ dwOrgOffset+sevenOrg ] >> 5) & 0x01);
case 2:
pNewData[ dwNewOffset - wNewLineSize] =
(BYTE)((pOrgData[ dwOrgOffset] << 1) & 0x80) |
(BYTE)((pOrgData[ dwOrgOffset+wOrgLineSize] ) & 0x40) |
(BYTE)((pOrgData[ dwOrgOffset+twoOrg ] >> 1) & 0x20) |
(BYTE)((pOrgData[ dwOrgOffset+threeOrg ] >> 2) & 0x10) |
(BYTE)((pOrgData[ dwOrgOffset+fourOrg ] >> 3) & 0x08) |
(BYTE)((pOrgData[ dwOrgOffset+fiveOrg ] >> 4) & 0x04) |
(BYTE)((pOrgData[ dwOrgOffset+sixOrg ] >> 5) & 0x02) |
(BYTE)((pOrgData[ dwOrgOffset+sevenOrg ] >> 6) & 0x01);
case 1:
pNewData[dwNewOffset] =
(BYTE)(pOrgData[dwOrgOffset] & 0x80) |
(BYTE)((pOrgData[ dwOrgOffset+wOrgLineSize] >> 1) & 0x40) |
(BYTE)((pOrgData[ dwOrgOffset+twoOrg ] >> 2) & 0x20) |
(BYTE)((pOrgData[ dwOrgOffset+threeOrg] >> 3) & 0x10) |
(BYTE)((pOrgData[ dwOrgOffset+fourOrg] >> 4) & 0x08) |
(BYTE)((pOrgData[ dwOrgOffset+fiveOrg] >> 5) & 0x04) |
(BYTE)((pOrgData[ dwOrgOffset+sixOrg] >> 6) & 0x02) |
(BYTE)((pOrgData[ dwOrgOffset+sevenOrg] >> 7) & 0x01);
}
dwOrgOffset++;
dwNewOffset -= eightNew;
}
}
}
VOID OIBRotate4BitData( pOrgData, pNewData, wOrgWidth, wOrgHeight, wOrgLineSize, wNewLineSize )
HPBYTE pOrgData;
HPBYTE pNewData;
WORD wOrgWidth;
WORD wOrgHeight;
WORD wOrgLineSize;
WORD wNewLineSize;
{
WORD x, y;
DWORD dwOrgOffset, dwNewOffset;
// First off, let's handle the tricky boundary conditions.
// These are the areas in the DIB that contain only one
// pixel per byte, instead of the normal 2 per pixel.
// (When the width or height is an odd number.)
if( wOrgWidth & 0x01 )
{
// Let's make that last scan line.
dwNewOffset = (DWORD)wOrgHeight/2-1; // last byte in last scan line.
dwOrgOffset = (DWORD)(wOrgHeight-1) * wOrgLineSize + wOrgWidth/2;
y = wOrgHeight;
if( y & 0x01 ) // Odd height, too.
{
pNewData[dwNewOffset+1] = pOrgData[dwOrgOffset];
y--;
dwOrgOffset -= wOrgLineSize;
}
while( y )
{
pNewData[dwNewOffset] = (pOrgData[dwOrgOffset-wOrgLineSize] & 0xf0) | (BYTE)((pOrgData[dwOrgOffset] >> 4) & 0x0f);
y -= 2;
dwNewOffset--;
dwOrgOffset -= 2*wOrgLineSize;
}
wOrgWidth--;
pNewData += wNewLineSize;
}
if( wOrgHeight & 0x01 ) // Odd height
{
// Set the last pixel of each scan line to the pixels contained in the
// first scan line of the original DIB.
dwOrgOffset = (DWORD)wOrgLineSize * (wOrgHeight-1);
dwNewOffset = (DWORD)(wOrgWidth-1) * wNewLineSize + wOrgHeight/2;
for( x=0; x<wOrgWidth; x+=2 )
{
pNewData[dwNewOffset] = pOrgData[dwOrgOffset];
dwNewOffset -= wNewLineSize;
pNewData[dwNewOffset] = (BYTE)((pOrgData[dwOrgOffset] & 0x0F) << 4);
dwNewOffset -= wNewLineSize;
dwOrgOffset++;
}
wOrgHeight--;
}
// General case, speedy loop. (Even width, even height.)
for( y=0; y < wOrgHeight; y+=2 )
{
dwOrgOffset = (DWORD)y * wOrgLineSize;
dwNewOffset = (DWORD)wNewLineSize*(wOrgWidth-1) + y/2; // Remember, DIBs are bottom-to-top.
for( x=0; x < wOrgWidth; x+=2 )
{
pNewData[dwNewOffset] = (pOrgData[dwOrgOffset] & 0xf0) | (BYTE)((pOrgData[dwOrgOffset+wOrgLineSize] >> 4) & 0x0f);
pNewData[dwNewOffset - wNewLineSize] = (BYTE)((pOrgData[dwOrgOffset] << 4) & 0xf0) | (pOrgData[dwOrgOffset+wOrgLineSize] & 0x0f);
dwOrgOffset++;
dwNewOffset -= 2*wNewLineSize;
}
}
}
VOID OIBRotate8BitData( pOrgData, pNewData, wOrgWidth, wOrgHeight, wOrgLineSize, wNewLineSize )
HPBYTE pOrgData;
HPBYTE pNewData;
WORD wOrgWidth;
WORD wOrgHeight;
WORD wOrgLineSize;
WORD wNewLineSize;
{
WORD x, y;
DWORD dwOrgOffset, dwNewOffset;
for( y=0; y < wOrgHeight; y++ )
{
dwOrgOffset = (DWORD)y * (DWORD)wOrgLineSize;
dwNewOffset = (DWORD)wNewLineSize*(DWORD)(wOrgWidth-1) + y; // Remember, DIBs are bottom-to-top.
for( x=0; x < wOrgWidth; x++ )
{
pNewData[dwNewOffset] = pOrgData[dwOrgOffset];
dwOrgOffset++;
dwNewOffset -= wNewLineSize;
}
}
}
VOID OIBRotate24BitData( pOrgData, pNewData, wOrgWidth, wOrgHeight, wOrgLineSize, wNewLineSize )
HPBYTE pOrgData;
HPBYTE pNewData;
WORD wOrgWidth;
WORD wOrgHeight;
WORD wOrgLineSize;
WORD wNewLineSize;
{
WORD x, y;
DWORD dwOrgOffset, dwNewOffset;
for( y=0; y < wOrgHeight; y++ )
{
dwOrgOffset = (DWORD)y * (DWORD)wOrgLineSize;
dwNewOffset = (DWORD)wNewLineSize*(DWORD)(wOrgWidth-1) + (DWORD)y*3; // Remember, DIBs are bottom-to-top.
for( x=0; x < wOrgWidth; x++ )
{
pNewData[dwNewOffset] = pOrgData[dwOrgOffset++];
pNewData[dwNewOffset+1] = pOrgData[dwOrgOffset++];
pNewData[dwNewOffset+2] = pOrgData[dwOrgOffset++];
dwNewOffset -= wNewLineSize;
}
}
}
#endif //SCCFEATURE_ROTATION
VOID OIBGetOrgTileExtents( lpDisplay, pTile, pWidth, pHeight )
POIB_DISPLAY lpDisplay;
POIBTILE pTile;
LPWORD pWidth;
LPWORD pHeight;
{
#ifdef SCCFEATURE_ROTATION
if( lpDisplay->wRotation & OIB_ROTATE90 )
{
*pWidth = (WORD)pTile->Size.y;
*pHeight = (WORD)pTile->Size.x;
}
else
#endif
{
*pWidth = (WORD)pTile->Size.x;
*pHeight = (WORD)pTile->Size.y;
}
}
WORD OIBHandleReadAhead( lpDisplay )
POIB_DISPLAY lpDisplay;
{
WORD i;
CHSECTIONINFO SecInfo;
PCHUNK pChunkTable;
RECT rcUpdate;
BOOL bFirstRect = TRUE;
POIBTILE lpTile;
SecInfo = *(CHLockSectionInfo(lpDisplay->Gen.hFilter, lpDisplay->Gen.wSection));
CHUnlockSectionInfo(lpDisplay->Gen.hFilter, lpDisplay->Gen.wSection);
if( lpDisplay->Image.wNumTiles != SecInfo.wChunkTableSize )
{
if( lpDisplay->Image.hTiles == NULL )
{
lpDisplay->Image.hTiles = UTGlobalAlloc( SecInfo.wChunkTableSize * sizeof(OIBTILE) );
lpDisplay->Image.pBmpTiles = (POIBTILE) UTGlobalLock( lpDisplay->Image.hTiles );
}
pChunkTable = (PCHUNK) UTGlobalLock( SecInfo.hChunkTable );
OIBNPLockBmInfo( lpDisplay );
i = lpDisplay->Image.wNumTiles;
while( i < SecInfo.wCurTotalChunks )
{
lpTile = &(lpDisplay->Image.pBmpTiles[i]);
OIBInitTile( i, lpTile, &(pChunkTable[i]), lpDisplay );
lpDisplay->Image.wNumTiles++;
if( !(lpDisplay->wFlags & OIBF_RENDERIMAGEONLY) )
{
if( bFirstRect )
{
bFirstRect = FALSE;
rcUpdate.left = lpTile->Offset.x;
rcUpdate.right = rcUpdate.left + lpTile->Size.x;
rcUpdate.top = lpTile->Offset.y;
rcUpdate.bottom = rcUpdate.top + lpTile->Size.y;
}
else
{
if( lpTile->Offset.x < rcUpdate.left )
rcUpdate.left = lpTile->Offset.x;
else
rcUpdate.right = max( rcUpdate.right, lpTile->Offset.x + lpTile->Size.x );
if( lpTile->Offset.y < rcUpdate.top )
rcUpdate.top = lpTile->Offset.y;
else
rcUpdate.bottom = max( rcUpdate.bottom, lpTile->Offset.y + lpTile->Size.y );
}
}
i++;
}
UTGlobalUnlock( SecInfo.hChunkTable );
OIBNPUnlockBmInfo( lpDisplay );
if( !(lpDisplay->wFlags & OIBF_RENDERIMAGEONLY) )
{
#ifdef SCCFEATURE_FULLSCREEN
if( lpDisplay->wFlags & OIBF_FULLSCREEN )
{
rcUpdate.left += lpDisplay->ptFullScreenOffset.x;
rcUpdate.right += lpDisplay->ptFullScreenOffset.x;
rcUpdate.top += lpDisplay->ptFullScreenOffset.y;
rcUpdate.bottom += lpDisplay->ptFullScreenOffset.y;
DUInvalRect( lpDisplay, &rcUpdate );
}
else
#endif
{
#ifdef SCCFEATURE_SCALING
if( lpDisplay->wScaleTo != lpDisplay->wScaleFrom )
OIBNPScaleRect( NULL, &rcUpdate, lpDisplay );
#endif // SCCFEATURE_SCALING
rcUpdate.left += lpDisplay->ptWinOrg.x;
rcUpdate.right += lpDisplay->ptWinOrg.x;
rcUpdate.top += lpDisplay->ptWinOrg.y;
rcUpdate.bottom += lpDisplay->ptWinOrg.y;
#ifdef MAC
// Account for display offset, if necessary.
BUOffsetRect( &rcUpdate, lpDisplay->winRect.left, lpDisplay->winRect.top );
#endif
DUInvalRect( lpDisplay, &rcUpdate );
}
}
}
if( SecInfo.Flags & (CH_SECTIONFINISHED | CH_EMPTYSECTION) )
return TRUE;
else
return FALSE;
}
VOID OIBInitTile( wTile, pTile, pChunk, lpDisplay )
WORD wTile;
POIBTILE pTile;
PCHUNK pChunk;
POIB_DISPLAY lpDisplay;
{
OIBNPSetTileDimensions( pTile, pChunk, lpDisplay );
if( !lpDisplay->Image.TileCache.bCacheFull )
{
if( NULL == OIBCreateBitmap(lpDisplay, pTile, wTile) )
{
if( lpDisplay->Image.TileCache.wCount )
lpDisplay->Image.TileCache.bCacheFull = TRUE;
else // Not enough memory for image.
UTBailOut( SCCCHERR_OUTOFMEMORY );
}
else if( ++lpDisplay->Image.TileCache.wCount == lpDisplay->Image.TileCache.wSize )
lpDisplay->Image.TileCache.bCacheFull = TRUE;
}
else
pTile->hBmp = NULL;
}
WORD OIBLoadTile( lpDisplay, pTile, wTile )
POIB_DISPLAY lpDisplay;
POIBTILE pTile;
WORD wTile;
{
WORD i;
POIBTILE pTileList;
if( pTile->hBmp == NULL )
{
pTileList = lpDisplay->Image.pBmpTiles;
// Remove a tile from the cache.
// Try to get one that isn't visible.
for( i=0; i<lpDisplay->Image.wNumTiles; i++ )
{
if( pTileList->hBmp != NULL && !pTileList->bVisible )
{
BUDeleteDeviceBitmap(pTileList->hBmp, lpDisplay);
pTileList->hBmp = NULL;
break;
}
pTileList++;
}
if( i == lpDisplay->Image.wNumTiles )
{
// Couldn't find a non-visible tile to remove.
pTileList = lpDisplay->Image.pBmpTiles;
for( i=0; i<lpDisplay->Image.wNumTiles; i++ )
{
if( pTileList->hBmp != NULL )
{
BUDeleteDeviceBitmap(pTileList->hBmp, lpDisplay);
pTileList->hBmp = NULL;
break;
}
pTileList++;
}
}
if( NULL == OIBCreateBitmap(lpDisplay, pTile, wTile) )
return 1;
}
return 0;
}