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.
 
 
 
 
 
 

1802 lines
72 KiB

/****************************************************************************
ANBITMAP.C
$Log: S:\products\msprods\oiwh\display\anbitmap.c_v $
*
* Rev 1.36 20 Jun 1996 16:01:20 RC
* Fixed resize of image and text marks
*
* Rev 1.35 16 Apr 1996 15:24:28 BEG06016
* Added #ifdef IN_PROG_CHANNEL_SAFARI.
*
* Rev 1.34 15 Apr 1996 11:03:38 RC
* Fixed freeing of the display dib every time in BitsTransparent
*
* Rev 1.33 11 Apr 1996 15:12:14 BEG06016
* Optimized named block access some.
*
* Rev 1.32 17 Jan 1996 13:58:58 RC
* Changed scalealgstruct.uimageflags to be assigned pimage->nrwdatatype
* from pimage->pimg->ntype (in PaintAnnotationBitmap)
*
* Rev 1.31 10 Jan 1996 11:53:54 RC
* Fixed a bad pointer in BitsTransparent
*
* Rev 1.30 02 Jan 1996 14:10:42 BLJ
* Fixed bug in BW_AVG_TO_BW scale algorithm.
*
* Rev 1.29 02 Jan 1996 09:56:18 BLJ
* Changed alot of UINTs to ints.
* Changed IMG structure to include the image data.
* Changed lp prefix to p.
*
* Rev 1.28 22 Dec 1995 11:15:02 RC
* Passed in palette to scalebits in ipscaling
*
* Rev 1.27 22 Dec 1995 11:10:44 BLJ
* Added a parameter for zero init'ing to some memory manager calls.
*
* Rev 1.26 29 Nov 1995 14:18:28 RC
* Passed in both horiz and vert scales into ipscaling
*
* Rev 1.25 08 Nov 1995 11:12:34 RC
* Took out PAINT_MODE_SELECTED flag as its function is now performed by
* PaintHandles
*
* Rev 1.24 18 Oct 1995 15:15:22 RC
* Changed image marks to be non scale to gray if they are not b&w, no matter
* what happens to the base image
*
* Rev 1.23 13 Oct 1995 12:27:12 RAR
* Use StretchDIBits() instead of Rectangle() for non-highlighted filled
* rectangles (only when printing). Work around for printer drivers (HPLJ4
* drivers) that ignore SetROP2() drawing mode.
****************************************************************************/
#include "privdisp.h"
/******************************************************************************
FUNCTION: IPScaling
PURPOSE: To scale the dib with IPpack scaling and then blt
it to the DC passed in
*********************************************************************************/
int WINAPI IPScaling(HDC hDC, PBITMAPINFOHEADER pDib, LRECT lrScaledRect,
int nHScale, int nVScale, PAN_NEW_ROTATE_STRUCT pAnRotation,
LRECT lrDestPt, PIMAGE pImage, BOOL transparent,
int mode, int nScaleAlgorithm,
PMARK pMark, PPSTR ppgray){
int nStatus = 0;
HBITMAP hBitmap = 0;
HBITMAP hOldBitmap = 0;
HDC hdcmem = 0;
PIMG pDestImg = 0;
PIMG pHidImage = 0;
RECT rRect;
LRECT lrRect;
PBITMAPINFOHEADER pNewDib = 0;
int nSize;
// to avoid divide by 0 errors
if (lrScaledRect.right == 0)
lrScaledRect.right = 1;
if (lrScaledRect.bottom == 0)
lrScaledRect.bottom = 1;
// convert dib to ippack image (pHidImage)
CheckError2(DibToIpNoPal(&pHidImage, pDib))
// modes 1 and 2 are for bitblting when the image is ready. All
// scale to gray and other stuff has already been done to the image
if ((mode == 1) || (mode == 2)){
pNewDib = pDib;
goto NoScaleToGray;
}
// convert the image to a displayable format at the right scale.
switch (nScaleAlgorithm){
case OI_SCALE_ALG_USE_DEFAULT:
case OI_SCALE_ALG_NORMAL:
case OI_SCALE_ALG_STAMP:
CheckError2(CreateAnyImgBuf(&pDestImg,
(lrScaledRect.right - lrScaledRect.left),
(lrScaledRect.bottom - lrScaledRect.top), pHidImage->nType))
break;
case OI_SCALE_ALG_AVERAGE_TO_GRAY4:
CheckError2(CreateAnyImgBuf(&pDestImg,
(lrScaledRect.right - lrScaledRect.left),
(lrScaledRect.bottom - lrScaledRect.top), ITYPE_GRAY4))
break;
case OI_SCALE_ALG_AVERAGE_TO_GRAY7:
CheckError2(CreateAnyImgBuf(&pDestImg,
(lrScaledRect.right - lrScaledRect.left),
(lrScaledRect.bottom - lrScaledRect.top), ITYPE_GRAY7))
break;
case OI_SCALE_ALG_AVERAGE_TO_GRAY8:
CheckError2(CreateAnyImgBuf(&pDestImg,
(lrScaledRect.right - lrScaledRect.left),
(lrScaledRect.bottom - lrScaledRect.top), ITYPE_GRAY8))
break;
case OI_SCALE_ALG_BW_MINORITY:
case OI_SCALE_ALG_BW_MAJORITY:
case OI_SCALE_ALG_BW_AVERAGE_TO_BW:
CheckError2(CreateAnyImgBuf(&pDestImg,
(lrScaledRect.right - lrScaledRect.left),
(lrScaledRect.bottom - lrScaledRect.top), ITYPE_BI_LEVEL))
break;
default:
nStatus = Error(DISPLAY_DATACORRUPTED);
goto Exit;
}
CopyRect(lrRect, lrScaledRect);
ConvertRect2(&lrRect, CONV_SCALED_TO_FULLSIZE, nHScale, nVScale, 0, 0);
CheckError2(ScaleBits(pHidImage, pDestImg, nScaleAlgorithm,
nHScale, nVScale, lrRect, lrScaledRect,
(LPRGBQUAD) ((PSTR) pDib + sizeof(BITMAPINFOHEADER))))
SetRect(&rRect, 0, 0, pDestImg->nWidth, pDestImg->nHeight);
// Convert scaled ippack image to a dib
CheckError2(IPtoDIB(pImage, pDestImg, &pNewDib, rRect))
// Copy palette info from old dib to new dib
if (pHidImage->nType == pDestImg->nType){
memcpy((PSTR) pNewDib + sizeof(BITMAPINFOHEADER),
(PSTR) pDib + sizeof(BITMAPINFOHEADER), ((int) pDib->biClrUsed*4));
}
NoScaleToGray:
if (mode != 4){ // if transparent blt, dont do
hBitmap = CreateCompatibleBitmap (hDC, (int) pNewDib->biWidth,
(int) pNewDib->biHeight);
hdcmem = CreateCompatibleDC (hDC);
if (!SetDIBits (hDC, hBitmap, 0, (int) pNewDib->biHeight,
(PSTR) pNewDib + sizeof(BITMAPINFOHEADER) + (pNewDib->biClrUsed*4),
(PBITMAPINFO) pNewDib, DIB_RGB_COLORS)){
nStatus = Error(DISPLAY_GETBITMAPBITSFAILED);
goto Exit;
}
hOldBitmap = SelectObject (hdcmem, hBitmap);
}
// Now blt the scaled dib to the DC
if (!transparent){
if (mode == 4){
*ppgray = (PSTR) pNewDib;
goto Exit;
}
if (!BitBlt (hDC, (int)lrDestPt.left, (int)lrDestPt.top,
(int) pNewDib->biWidth, (int) pNewDib->biHeight, hdcmem, 0, 0, SRCCOPY)){
nStatus = Error(DISPLAY_SETBITMAPBITSFAILED);
goto Exit;
}
if (mode == 3){
// Replace old szOiDIB with new pNewDib;
nSize = sizeof(BITMAPINFOHEADER) + (pNewDib->biClrUsed*4) + (pNewDib->biSizeImage);
CheckError2(AddAMarkNamedBlock(pMark, szOiDIB, (PPSTR) &pNewDib, nSize))
}
}else{ // transparent blt
// the modes are set by BitsTransparent to blt the mask and then
// the image
if (mode == 1){
if (!BitBlt (hDC, (int)lrDestPt.left, (int)lrDestPt.top,
(int) pNewDib->biWidth, (int) pNewDib->biHeight, hdcmem, 0, 0, SRCAND)){
nStatus = Error(DISPLAY_SETBITMAPBITSFAILED);
goto Exit;
}
}else if (mode == 2){
if (!BitBlt (hDC, (int)lrDestPt.left, (int)lrDestPt.top,
(int) pNewDib->biWidth, (int) pNewDib->biHeight, hdcmem, 0, 0, SRCPAINT)){
nStatus = Error(DISPLAY_SETBITMAPBITSFAILED);
goto Exit;
}
}
}
Exit:
if (nStatus || ((mode != 1) && (mode !=2) && (mode != 3) && (mode != 4))){
// Free temporary dib, if not the mode in which it is saved to the mark
FreeMemory((PPSTR) &pNewDib);
}
if (hOldBitmap){
SelectObject(hdcmem, hOldBitmap);
}
if (hBitmap){
DeleteObject(hBitmap);
}
if (hdcmem){
DeleteDC(hdcmem);
}
FreeImgBuf(&pHidImage);
FreeImgBuf(&pDestImg);
return (nStatus);
}
/*****************************************************************************
FUNCTION: BitsTransparent
PURPOSE: Makes RGB(255,255,255) portion of image transparent
******************************************************************************/
int WINAPI BitsTransparent(HDC hDC, PBITMAPINFOHEADER pDib,
LRECT lrScaledRect, PAN_NEW_ROTATE_STRUCT pAnRotation,
LRECT lrDestPt, int nMode, PIMAGE pImage,
int nHScale, int nVScale, int nScaleAlgorithm, PMARK pMark){
int nStatus = 0;
RGBQUAD FAR* pRGB;
RGBQUAD FAR* pRGB1 = 0;
int n;
ulong ByteColor;
BYTE huge* hpByte;
BYTE huge* hpRGB1 = 0;
BYTE huge* hpRGB;
int nRopCode;
int nOldROP;
HBRUSH hOldBrush;
HPEN hOldPen;
BOOL transparent;
int mode;
HDC hLocalDC = 0;// this is just a dummy dc
PSTR pgray=0;
PBITMAPINFOHEADER pNewDib ;
switch (nMode){
case PAINT_MODE_DRAG:
case PAINT_MODE_XOR:
nRopCode = R2_XORPEN;
break;
case PAINT_MODE_NORMAL:
nRopCode = R2_COPYPEN;
break;
}
nOldROP = SetROP2(hDC, nRopCode);
if ((nMode == PAINT_MODE_DRAG) || (nMode == PAINT_MODE_XOR)){
// if image is dragged, draw a rect the size of the image
// and then fall through (actual bit manipulation not needed)
hOldPen = SelectObject(hDC, GetStockObject(NULL_PEN));
hOldBrush = SelectObject(hDC, GetStockObject(GRAY_BRUSH));
Rectangle (hDC, (int)lrDestPt.left, (int)lrDestPt.top, (int)lrDestPt.left
+ (int)(lrScaledRect.right-lrScaledRect.left),
(int)lrDestPt.top + (int)(lrScaledRect.bottom-lrScaledRect.top));
SelectObject(hDC, hOldBrush);
SelectObject(hDC, hOldPen);
goto Exit;
}
if ((pDib->biClrUsed == 0) && (pDib->biBitCount != 24)){
nStatus = Error(DISPLAY_IMAGETYPENOTSUPPORTED);
goto Exit;
}
// this stuff does the scaling and we get the scaled dib back as pNewDib
// No blting to the dc is done in this ipscaling call
transparent = FALSE;
mode = 4;
CheckError2(IPScaling(hLocalDC, pDib, lrScaledRect, nHScale, nVScale,
pAnRotation, lrDestPt, pImage, transparent, mode,
nScaleAlgorithm, pMark, &pgray))
pNewDib = (PBITMAPINFOHEADER) pgray;
// if it is 24-bit color bitmap (1, 4 & 8bits will fail earlier)
if (pNewDib->biClrUsed == 0){
// for transparency, a copy of the original bits must be saved
CheckError2(AllocateMemory(pNewDib->biSizeImage, (PPSTR) &hpRGB1, ZERO_INIT))
// point to the bits in the dib passed in
hpByte = ((PSTR) pNewDib + pNewDib->biSize);
// copy bits from the dib passed in to the memory just allocated
memcpy (hpRGB1, hpByte, pNewDib->biSizeImage);
// the bits pointed to by hpRGB1, and now hpRGB are the original
// dib bits which must be restored to the dib when we are done.
// hpRGB1 will change, but hpRGB will always point to the top of
// memory which makes copying all the bits back to the dib easy.
hpRGB = hpRGB1;
// go through all the dib bits searching for RGB(255,255,255)
// ByteColor is incremented by 3 for the RGB triples
// hpByte points to the bits in the dib
// This process builds a mask by setting the RGB transparent
// color to white and all else to black
for (ByteColor = 0; (ByteColor < pNewDib->biSizeImage);
ByteColor = ByteColor + 3,hpByte++ ){
// if first byte in RGB triple is 255 carry on, else fail
if (*hpByte == (uchar)255){
hpByte++;
// if second byte is 255
if (*hpByte==(uchar)255){
hpByte++;
//if third byte is 255, RGB triple is (255,255,255)
if(*hpByte==(uchar)255){
//set color to white
*(hpByte-2) = (uchar)255;
*(hpByte-1) = (uchar)255;
*hpByte = (uchar)255;
}else{
// if it fails, dont search the remaining bytes
// in the RGB triple, increment hpByte and go on
// Also set the RGB triple to RGB(0,0,0)
*(hpByte-2) = 0;
*(hpByte-1) = 0;
*hpByte = 0;
}
}else{
hpByte++;
*(hpByte-2) = 0;
*(hpByte-1) = 0;
*hpByte = 0;
}
}else{
hpByte = hpByte + 2;
*(hpByte-2) = 0;
*(hpByte-1) = 0;
*hpByte = 0;
}
}
if (nMode == PAINT_MODE_NORMAL){
// prepare destination dc by blting the mask just prepared
transparent = TRUE;
mode = 1;
CheckError2(IPScaling(hDC, pNewDib, lrScaledRect, nHScale, nVScale, pAnRotation,
lrDestPt, pImage, transparent, mode,
nScaleAlgorithm, pMark, &pgray))
}
//hpByte now points to the changed bits in the dib
hpByte = ((PSTR) pNewDib + pNewDib->biSize);
// now for every color that is white (from above change)
// set color to black, else set it to its original color.
// hpRGB1 points to the original bits in the dib
for (ByteColor=0; (ByteColor < pNewDib->biSizeImage);
ByteColor=ByteColor + 3,hpByte++, hpRGB1++ ){
if (*hpByte == (uchar)255){
// make sure pointers to original bits and new bits are in sync
hpByte++;
hpRGB1++;
if (*hpByte==(uchar)255){
hpByte++;
hpRGB1++;
// if color is white, set to black
if(*hpByte==(uchar)255){
*(hpByte-2) = 0;
*(hpByte-1) = 0;
*hpByte = 0;
}else{
// else set to original color
*(hpByte-2) = *(hpRGB1-2);
*(hpByte-1) = *(hpRGB1-1);
*hpByte = *hpRGB1;
}
}else{
hpByte++;
hpRGB1++;
*(hpByte-2) = *(hpRGB1-2);
*(hpByte-1) = *(hpRGB1-1);
*hpByte = *hpRGB1;
}
}else{
hpByte = hpByte + 2;
hpRGB1 = hpRGB1 + 2;
*(hpByte-2) = *(hpRGB1-2);
*(hpByte-1) = *(hpRGB1-1);
*hpByte = *hpRGB1;
}
}
if (nMode == PAINT_MODE_NORMAL){
// now blt the source transparently
transparent = TRUE;
mode = 2;
CheckError2(IPScaling (hDC, pNewDib, lrScaledRect, nHScale, nVScale, pAnRotation,
lrDestPt, pImage, transparent, mode,
nScaleAlgorithm, pMark, &pgray))
}
// set dib bits back to the way they were passed in and free mem
hpByte = ((PSTR) pNewDib + pNewDib->biSize);
memcpy (hpByte, hpRGB, pNewDib->biSizeImage);
hpRGB1 = hpRGB;
goto Exit;
}
// for non 24-bit bitmaps
// In non 24-bit bitmaps the colors are stored in the palette
// section of the dib, versus actually in the bits themselves
// allocate memory to save the original palette
CheckError2(AllocateMemory(pNewDib->biClrUsed*4, (PPSTR) &pRGB1, ZERO_INIT))
pRGB = (RGBQUAD FAR*)((PSTR) pNewDib + pNewDib->biSize);
// pRGB points to the palette in the dib passed in, pRGB1
// saves the colors in the original palette
for (n=0; n<(int) pNewDib->biClrUsed; n++, pRGB++){
if ((pRGB->rgbRed == 255) && (pRGB->rgbGreen==255)
&& (pRGB->rgbBlue==255)){
// for every color, if color is transparent set it
// to white, else black (prepare the mask)
pRGB1[n].rgbRed = pRGB->rgbRed;
pRGB1[n].rgbGreen = pRGB->rgbGreen;
pRGB1[n].rgbBlue = pRGB->rgbBlue;
pRGB->rgbRed = 255;
pRGB->rgbGreen = 255;
pRGB->rgbBlue = 255;
}else{
pRGB1[n].rgbRed = pRGB->rgbRed;
pRGB1[n].rgbGreen = pRGB->rgbGreen;
pRGB1[n].rgbBlue = pRGB->rgbBlue;
pRGB->rgbRed = 0;
pRGB->rgbGreen = 0;
pRGB->rgbBlue = 0;
}
}
if (nMode == PAINT_MODE_NORMAL){
// prepare destination dc by blting the mask
transparent = TRUE;
mode = 1;
CheckError2(IPScaling (hDC, pNewDib, lrScaledRect, nHScale, nVScale, pAnRotation,
lrDestPt, pImage, transparent, mode,
nScaleAlgorithm, pMark, &pgray))
}
//now point to the changed palette
pRGB = (RGBQUAD FAR*)((PSTR) pNewDib + pNewDib->biSize);
for (n=0; n<(int) pNewDib->biClrUsed; n++, pRGB++){
// for every color, if color is white change to black
// else set color to its original state
if ((pRGB->rgbRed == 255) && (pRGB->rgbGreen==255)
&& (pRGB->rgbBlue==255)){
pRGB->rgbRed = 0;
pRGB->rgbGreen = 0;
pRGB->rgbBlue = 0;
}else{
pRGB->rgbRed = pRGB1[n].rgbRed;
pRGB->rgbGreen = pRGB1[n].rgbGreen;
pRGB->rgbBlue = pRGB1[n].rgbBlue;
}
}
if (nMode == PAINT_MODE_NORMAL){
// now do the transparent blt
transparent = TRUE;
mode = 2;
CheckError2(IPScaling (hDC, pNewDib, lrScaledRect, nHScale, nVScale, pAnRotation, lrDestPt,
pImage, transparent, mode, nScaleAlgorithm, pMark, &pgray))
}
// Restore the original color table
pRGB = (RGBQUAD FAR*)((PSTR) pNewDib + pNewDib->biSize);
for (n=0; n<(int) pNewDib->biClrUsed; n++, pRGB++){
pRGB->rgbRed = pRGB1[n].rgbRed;
pRGB->rgbGreen = pRGB1[n].rgbGreen;
pRGB->rgbBlue = pRGB1[n].rgbBlue;
}
Exit:
if (pgray){
FreeMemory ((PPSTR) &pgray);
}
FreeMemory((PPSTR) &hpRGB1);
FreeMemory((PPSTR) &pRGB1);
SetROP2(hDC, nOldROP);
return (nStatus);
}
/****************************************************************************
FUNCTION: StartOperationBitmap
PURPOSE: This routine contains the text code for OiStartOperation.
****************************************************************************/
int WINAPI StartOperationBitmap(HWND hWnd, PANO_IMAGE pAnoImage,
LPOIOP_START_OPERATION_STRUCT pStartStruct,
POINT ptPoint, WPARAM fwKeys, int nFlags,
PWINDOW pWindow, PIMAGE pImage,
PMARK pMark, HDC hDC, RECT rClientRect,
LRECT lrFullsizeClientRect, PBOOL pbDeleteMark,
PBOOL pbMarkComplete, PBOOL pbRepaint){
int nStatus = 0;
FIO_INFO_CGBW FioInfoCgbw;
FIO_INFORMATION FioInfo;
PAN_NAME_STRUCT pAnName;
PAN_NEW_ROTATE_STRUCT pAnRotation;
LRECT lrFSPoint;
int fid;
int localfile, error;
PSTR pFileName;
char FileName[256];
int nHMarkScale;
int nVMarkScale;
char szRealFilename[255];
PSTR pRealFilename = szRealFilename;
int nPage;
if ((int) pMark->Attributes.uType == OIOP_AN_FORM){
if (pAnoImage->pFormImage != 0){
nStatus = Error (DISPLAY_INVALID_OPTIONS);
goto Exit;
}
}
switch ((int) pMark->Attributes.uType){
case OIOP_AN_FORM:
case OIOP_AN_IMAGE:
case OIOP_AN_IMAGE_BY_REFERENCE:
if (!pStartStruct->szString[0]){
nStatus = Error(DISPLAY_INVALID_OPTIONS);
goto Exit;
}
pFileName = FileName;
GetFileName (pFileName, (PSTR) pStartStruct->szString);
GetPageNumandFileName (pRealFilename, &nPage, pFileName);
// see if file exists
if (fid = IMGFileBinaryOpen(hWnd, pRealFilename,
OF_EXIST, &localfile, &error)){
nStatus = Error(DISPLAY_IMAGE_MARK_NAME);
goto Exit;
}
// now allocate a block to save the name of the file
// (file name as passed in, not just created)
pAnName = 0;
CheckError2(AddAMarkNamedBlock(pMark, szOiFilNam,
(PPSTR) &pAnName, strlen(pStartStruct->szString) + 1))
strcpy(pAnName->name, pStartStruct->szString);
// get the size of the image so we can set the bounds
// attribute in pMark
memset(&FioInfoCgbw, 0, sizeof(FIO_INFO_CGBW));
memset(&FioInfo, 0, sizeof(FIO_INFORMATION));
FioInfo.filename = pRealFilename;
FioInfo.page_number = 1;
FioInfoCgbw.palette_entries = 0;
FioInfoCgbw.lppalette_table = NULL;
CheckError2(IMGFileGetInfo(NULL, hWnd, &FioInfo, &FioInfoCgbw, 0))
// if it is a form type then both base image and form mark must
// be b & w
if (((int) pMark->Attributes.uType == OIOP_AN_FORM) &&
((FioInfoCgbw.image_type != ITYPE_BI_LEVEL) ||
(pImage->pImg->nType != ITYPE_BI_LEVEL))){
nStatus = Error (DISPLAY_INVALID_OPTIONS);
goto Exit;
}
// Convert pt where image is to be placed to fullsize coords
lrFSPoint.left = ptPoint.x;
lrFSPoint.top = ptPoint.y;
lrFSPoint.right = 0;
lrFSPoint.bottom = 0;
ConvertRect(pWindow, &lrFSPoint, CONV_WINDOW_TO_FULLSIZE);
nHMarkScale = ((pImage->nHRes * 1000)/ FioInfo.horizontal_dpi);
nVMarkScale = ((pImage->nVRes * 1000)/ FioInfo.vertical_dpi);
// Set the dimensions of the image in fullsize
pMark->Attributes.lrBounds.left = lrFSPoint.left;
pMark->Attributes.lrBounds.top = lrFSPoint.top;
pMark->Attributes.lrBounds.right = lrFSPoint.left + (((ulong)FioInfo.horizontal_pixels
* nHMarkScale)/1000);
pMark->Attributes.lrBounds.bottom = lrFSPoint.top + (((ulong)FioInfo.vertical_pixels
* nVMarkScale)/1000);
// Create the block which will contain rotation info
// and resolution info
pAnRotation = 0;
CheckError2(AddAMarkNamedBlock(pMark, szOiAnoDat,
(PPSTR) &pAnRotation, sizeof (AN_NEW_ROTATE_STRUCT)))
// Default rotation info to the original image condition
pAnRotation->rotation = 1;
pAnRotation->scale = 1000;
pAnRotation->bFormMark = FALSE;
pAnRotation->bClipboardOp = FALSE;
// Resolution info
pAnRotation->nHRes = FioInfo.horizontal_dpi;
pAnRotation->nVRes = FioInfo.vertical_dpi;
pAnRotation->nOrigHRes = FioInfo.horizontal_dpi;
pAnRotation->nOrigVRes = FioInfo.vertical_dpi;
if ((int) pMark->Attributes.uType == OIOP_AN_FORM){
CheckError2(CacheFile (hWnd, pRealFilename, nPage, &pAnoImage->pFormImage))
pAnoImage->pFormImage->nLockCount++;
pAnoImage->pFormMark = pMark;
pAnoImage->nBPFValidLines = 0;
pAnoImage->pBasePlusFormImg = 0;
// *pbMarkComplete = TRUE;
// *pbRepaint = TRUE;
}
break;
default:
break;
}
Exit:
if (nStatus){
*pbDeleteMark = TRUE;
}
return(nStatus);
}
//
/****************************************************************************
FUNCTION: ContinueOperationBitmap
PURPOSE: This routine contains the text code for OIContinueOperation.
****************************************************************************/
int WINAPI ContinueOperationBitmap(HWND hWnd, POINT ptPoint, int nFlags,
PWINDOW pWindow, PIMAGE pImage, PMARK pMark,
HDC hDC, RECT rClientRect, LRECT lrFullsizeClientRect){
int nStatus = 0;
int hoffset, voffset;
LRECT lrFSptRect;
int nHScale;
int nVScale;
CheckError2(TranslateScale(pWindow->nScale, pImage->nHRes, pImage->nVRes,
&nHScale, &nVScale))
switch ((int) pMark->Attributes.uType){
case OIOP_AN_IMAGE:
case OIOP_AN_IMAGE_BY_REFERENCE:
case OIOP_AN_FORM:
// this xor will erase the present image rect
CheckError2(PaintAnnotation(hWnd, hDC, pWindow, pImage, pMark,
rClientRect, lrFullsizeClientRect, PAINT_MODE_DRAG, pWindow->nScale,
nHScale, nVScale, pWindow->lHOffset, pWindow->lVOffset, 0, DONT_USE_BI_LEVEL_DITHERING,
DONT_FORCE_OPAQUE_RECTANGLES))
SetLRect (lrFSptRect, ptPoint.x, ptPoint.y, 0, 0);
ConvertRect(pWindow, &lrFSptRect, CONV_WINDOW_TO_FULLSIZE);
// calculate image offset to new position being dragged to
hoffset = (int)(lrFSptRect.left - pMark->Attributes.lrBounds.left);
voffset = (int)(lrFSptRect.top - pMark->Attributes.lrBounds.top);
// npdate the bounds of the image to the new position
pMark->Attributes.lrBounds.left =
pMark->Attributes.lrBounds.left + hoffset;
pMark->Attributes.lrBounds.right =
pMark->Attributes.lrBounds.right + hoffset;
pMark->Attributes.lrBounds.top =
pMark->Attributes.lrBounds.top + voffset;
pMark->Attributes.lrBounds.bottom =
pMark->Attributes.lrBounds.bottom + voffset;
// this xor will draw the new rect at the new location
CheckError2(PaintAnnotation(hWnd, hDC, pWindow, pImage, pMark,
rClientRect, lrFullsizeClientRect, PAINT_MODE_DRAG, pWindow->nScale,
nHScale, nVScale, pWindow->lHOffset, pWindow->lVOffset, 0, DONT_USE_BI_LEVEL_DITHERING,
DONT_FORCE_OPAQUE_RECTANGLES))
break;
default:
break;
}
Exit:
return(nStatus);
}
//
/****************************************************************************
FUNCTION: EndOperationBitmap
PURPOSE: This routine contains the image code for OIEndOperation.
****************************************************************************/
int WINAPI EndOperationBitmap(HWND hWnd, PWINDOW pWindow,
PIMAGE pImage, PMARK pMark, HDC hDC,
RECT rClientRect, LRECT lrFullsizeClientRect,
PBOOL pbDeleteMark, PBOOL pbRepaint){
int nStatus = 0;
PAN_NEW_ROTATE_STRUCT pAnRotation = 0;
switch ((int) pMark->Attributes.uType){
case OIOP_AN_IMAGE:
case OIOP_AN_IMAGE_BY_REFERENCE:
case OIOP_AN_FORM:
CheckError2(GetAMarkNamedBlock(pMark, szOiAnoDat, (PPSTR) &pAnRotation))
// repaint entire window now that we know where the mark
// needs to be redrawn
*pbRepaint = TRUE;
break;
default:
break;
}
Exit:
return(nStatus);
}
//
/****************************************************************************
FUNCTION: RotateImage
PURPOSE: This routine contains the code for rotating the form image
****************************************************************************/
int WINAPI RotateImage (PMARK pMark, PIMAGE pFormImage, int nRotation){
int nStatus;
PAN_NEW_ROTATE_STRUCT pAnRotation;
int tempres;
PIMG pTempImg = 0;
pAnRotation = 0;
CheckError2(GetAMarkNamedBlock(pMark, szOiAnoDat, (PPSTR) &pAnRotation))
if (pAnRotation == 0){
nStatus = Error (DISPLAY_DATACORRUPTED);
goto Exit;
}
switch (nRotation){
// no rotation needed
case 1:
break;
//rotate right
case 2:
CheckError2(CreateAnyImgBuf(&pTempImg, pFormImage->nHeight,
pFormImage->nWidth, pFormImage->pImg->nType))
CheckError2(RotateRight90(pFormImage->pImg, pTempImg,
pFormImage->nWidth, pFormImage->nHeight))
FreeImgBuf(&pFormImage->pImg);
MoveImage(&pTempImg, &pFormImage->pImg);
// npdate resolution info
tempres = pAnRotation->nVRes;
pAnRotation->nVRes = pAnRotation->nHRes;
pAnRotation->nHRes = tempres;
tempres = pFormImage->nVRes;
pFormImage->nVRes = pFormImage->nHRes;
pFormImage->nHRes = tempres;
pFormImage->nWidth = pFormImage->pImg->nWidth;
pFormImage->nHeight = pFormImage->pImg->nHeight;
break;
// rotate 180
case 3: //OD_FLIP:
CheckError2(Flip(pFormImage->pImg, pFormImage->nWidth, pFormImage->nHeight))
break;
//rotate left
case 4:
CheckError2(CreateAnyImgBuf(&pTempImg, pFormImage->nHeight,
pFormImage->nWidth, pFormImage->pImg->nType))
CheckError2(RotateRight270(pFormImage->pImg, pTempImg,
pFormImage->nWidth, pFormImage->nHeight))
FreeImgBuf(&pFormImage->pImg);
MoveImage(&pTempImg, &pFormImage->pImg);
// npdate resolution info
tempres = pAnRotation->nVRes;
pAnRotation->nVRes = pAnRotation->nHRes;
pAnRotation->nHRes = tempres;
tempres = pFormImage->nVRes;
pFormImage->nVRes = pFormImage->nHRes;
pFormImage->nHRes = tempres;
pFormImage->nWidth = pFormImage->pImg->nWidth;
pFormImage->nHeight = pFormImage->pImg->nHeight;
break;
// vertical mirror
case 5:
CheckError2(VerticalMirror(pFormImage->pImg, pFormImage->nWidth, pFormImage->nHeight))
break;
// vertical mirror and rotate right
case 6:
CheckError2(VerticalMirror(pFormImage->pImg, pFormImage->nWidth, pFormImage->nHeight))
CheckError2(CreateAnyImgBuf(&pTempImg, pFormImage->nHeight,
pFormImage->nWidth, pFormImage->pImg->nType))
CheckError2(RotateRight90(pFormImage->pImg, pTempImg,
pFormImage->nWidth, pFormImage->nHeight))
FreeImgBuf(&pFormImage->pImg);
MoveImage(&pTempImg, &pFormImage->pImg);
// npdate resolution info
tempres = pAnRotation->nVRes;
pAnRotation->nVRes = pAnRotation->nHRes;
pAnRotation->nHRes = tempres;
tempres = pFormImage->nVRes;
pFormImage->nVRes = pFormImage->nHRes;
pFormImage->nHRes = tempres;
pFormImage->nWidth = pFormImage->pImg->nWidth;
pFormImage->nHeight = pFormImage->pImg->nHeight;
break;
//vertical mirror and rotate 180
case 7:
CheckError2(VerticalMirror(pFormImage->pImg, pFormImage->nWidth, pFormImage->nHeight))
CheckError2(Flip(pFormImage->pImg, pFormImage->nWidth, pFormImage->nHeight))
break;
//vertical mirror and rotate left
case 8:
CheckError2(VerticalMirror(pFormImage->pImg, pFormImage->nWidth, pFormImage->nHeight))
CheckError2(CreateAnyImgBuf(&pTempImg, pFormImage->nHeight,
pFormImage->nWidth, pFormImage->pImg->nType))
CheckError2(RotateRight270(pFormImage->pImg, pTempImg,
pFormImage->nWidth, pFormImage->nHeight))
FreeImgBuf(&pFormImage->pImg);
MoveImage(&pTempImg, &pFormImage->pImg);
// npdate resolution info
tempres = pAnRotation->nVRes;
pAnRotation->nVRes = pAnRotation->nHRes;
pAnRotation->nHRes = tempres;
tempres = pFormImage->nVRes;
pFormImage->nVRes = pFormImage->nHRes;
pFormImage->nHRes = tempres;
pFormImage->nWidth = pFormImage->pImg->nWidth;
pFormImage->nHeight = pFormImage->pImg->nHeight;
break;
default:
break;
}
Exit:
return(nStatus);
}
/******************************************************************************
FUNCTION: OiImageToDib
PURPOSE: Converts an Open/image image to a DIB. The filename of
the O/i image is passed in, and a handle to the DIB returned
*******************************************************************************/
int WINAPI OiImageToDib(HWND hWnd, PSTR pFilename, PBITMAPINFOHEADER *ppDib){
int nStatus;
PIMAGE pImage=0;
RECT rRect;
int nPage=1;
char szRealFilename[255];
PSTR pRealFilename = szRealFilename;
GetPageNumandFileName (pRealFilename, &nPage, pFilename);
CheckError2(CacheFile(hWnd, pRealFilename, nPage, &pImage))
CheckError2(CacheRead(hWnd, pImage, pImage->nHeight))
SetRect (&rRect, 0, 0, (int) pImage->nWidth, (int) pImage->nHeight);
CheckError2(IPtoDIB (pImage, pImage->pImg, ppDib, rRect))
Exit:
return (nStatus);
}
//
/****************************************************************************
FUNCTION: PaintAnnotationBitmap
PURPOSE: This routine Paints an annotation on an hDC.
This routine contains the text code for PaintAnnotation.
INPUTS: nMode - PAINT_MODE_XOR - Draw the mark XORed with white.
PAINT_MODE_DRAG - Draw the mark for dragging purposes.
PAINT_MODE_NORMAL - Draw the mark as it normally appears.
****************************************************************************/
int WINAPI PaintAnnotationBitmap(HWND hWnd, HDC hDC, PWINDOW pWindow,
PIMAGE pImage, PMARK pMark, RECT rRepaintRect,
LRECT lrFullsizeRepaintRect, int nMode, int nScale,
int nHScale, int nVScale, long lHOffset, long lVOffset,
int nFlags){
int nStatus = 0;
PDISPLAY pDisplay;
PBITMAPINFOHEADER pDib = 0;
PBITMAPINFOHEADER pDisplayDib;
LRECT lrScaledRect, lrDestPt, lrFSRect, lrWindowMark;
PAN_IMAGE_STRUCT pAnImage = 0;
PAN_IMAGE_STRUCT pDisplayAnImage = 0;
PAN_NAME_STRUCT pAnName = 0;
PSTR pFileName;
PAN_NEW_ROTATE_STRUCT pAnRotation = 0;
int nRopCode;
int nOldROP;
HBRUSH hOldBrush;
BOOL bBrushSelected = FALSE;
BOOL bPenSelected = FALSE;
HPEN hOldPen;
BOOL transparent;
int mode;
PPSTR ppgray=0;
int fid;
int localfile, error;
char FileName[256];
PARM_SCALE_ALGORITHM_STRUCT ScaleAlgStruct;
int nPage=1;
char szRealFilename[255];
PSTR pRealFilename = szRealFilename;
PSTR plrMarkBounds=0 ;
pDisplay = pWindow->pDisplay;
switch (nMode){
case PAINT_MODE_DRAG:
case PAINT_MODE_XOR:
nRopCode = R2_XORPEN;
break;
case PAINT_MODE_NORMAL:
nRopCode = R2_COPYPEN;
break;
}
nOldROP = SetROP2(hDC, nRopCode);
switch ((int) pMark->Attributes.uType){
case OIOP_AN_IMAGE:
case OIOP_AN_IMAGE_BY_REFERENCE:
case OIOP_AN_FORM:
pAnName = 0;
pAnImage = 0;
pAnRotation = 0;
CheckError2(GetAMarkNamedBlock(pMark, szOiFilNam, (PPSTR) &pAnName))
CheckError2(GetAMarkNamedBlock(pMark, szOiDIB, (PPSTR) &pAnImage))
CheckError2(GetAMarkNamedBlock(pMark, szOiAnoDat, (PPSTR) &pAnRotation))
CheckError2(GetAMarkNamedBlock(pMark, szOiZDpDIB, (PPSTR) &pDisplayAnImage))
CheckError2(GetAMarkNamedBlock(pMark, "MarkBnds", (PPSTR) &plrMarkBounds))
//save these bounds, if they change the next time around, it means the mark needs
// to be resized
if (!plrMarkBounds) {
CheckError2(AllocateMemory(sizeof(LRECT), &plrMarkBounds, ZERO_INIT))
((LRECT *)plrMarkBounds)->left = pMark->Attributes.lrBounds.left ;
((LRECT *)plrMarkBounds)->top = pMark->Attributes.lrBounds.top ;
((LRECT *)plrMarkBounds)->right = pMark->Attributes.lrBounds.right ;
((LRECT *)plrMarkBounds)->bottom = pMark->Attributes.lrBounds.bottom ;
CheckError2(AddAMarkNamedBlock(pMark, "MarkBnds",
(PPSTR) &plrMarkBounds, sizeof (LRECT)))
}
// if there is no image and no name, what can be done???
if ((!pAnImage) && (!pAnName) || (!pAnRotation)){
nStatus = Error (DISPLAY_DATACORRUPTED);
goto Exit;
}
// if there is a name but no image, create the dib
if (!pAnImage){
pFileName = FileName;
GetFileName (pFileName, (PSTR) pAnName->name);
GetPageNumandFileName (pRealFilename, &nPage, pFileName);
// see if file exists
if (fid = IMGFileBinaryOpen(hWnd, pRealFilename, OF_EXIST, &localfile, &error)){
nStatus = Error(DISPLAY_IMAGE_MARK_NAME);
goto Exit;
}
CheckError2(OiImageToDib (hWnd, pFileName, &pDib))
pAnImage = 0;
CheckError2(AddAMarkNamedBlock(pMark, szOiDIB,
(PPSTR) &pAnImage, sizeof(BITMAPINFOHEADER)
+ (pDib->biClrUsed*4) + (pDib->biSizeImage)))
memcpy (pAnImage->dibInfo, pDib,
sizeof(BITMAPINFOHEADER) + (pDib->biClrUsed*4) + (pDib->biSizeImage));
}
// now we must scale the coords obtained above, which were
// in fullsize
if ((int) pMark->Attributes.uType == OIOP_AN_IMAGE_BY_REFERENCE){
// for image by reference, the final scale must also
// include the initial scale for the image, saved in
// pAnRotation (ie, an image saved at 50% will have
// the scale info for the ref. image at 50%)
nScale = (pAnRotation->scale * nScale) / 1000;
// tempscale = (pAnRotation->scale * nScale) / 1000;
// nScale = tempscale;
}else if ((int) pMark->Attributes.uType == OIOP_AN_IMAGE){
// for embedded image no such problems, scale is
// whatever the display scale is
// nScale = nScale;
}
ScaleAlgStruct.uImageFlags = pImage->nRWDataType;
if ((((nScale * pImage->nHRes) / pAnRotation->nHRes) > 1000 ||
((nScale * pImage->nVRes) / pAnRotation->nVRes) > 1000) ||
(((PBITMAPINFOHEADER) pAnImage)->biBitCount != 1)){
ScaleAlgStruct.uScaleAlgorithm = OI_SCALE_ALG_NORMAL;
// }else if (nStatus = IMGGetParmsCgbw (hWnd, PARM_SCALE_ALGORITHM,
// &ScaleAlgStruct, PARM_IMAGE | PARM_NO_DEFAULT)){
// goto Exit;
// }
}else{
ScaleAlgStruct.uScaleAlgorithm = pDisplay->nCurrentScaleAlgorithm ;
}
if (ScaleAlgStruct.uScaleAlgorithm == OI_SCALE_ALG_AVERAGE_TO_GRAY8){
ScaleAlgStruct.uScaleAlgorithm = OI_SCALE_ALG_AVERAGE_TO_GRAY7;
}
// if the base image scale algorithm has changed then throw the display
// dib away
if (pDisplayAnImage && (pAnRotation->nReserved[0] != (int)ScaleAlgStruct.uScaleAlgorithm)){
CheckError2(DeleteAMarkNamedBlock (pMark, szOiZDpDIB))
pDisplayAnImage = 0;
}
if (pDisplayAnImage){
pDisplayDib = (PBITMAPINFOHEADER) pDisplayAnImage;
}
if ((!pDisplayAnImage || pAnRotation->nHRes != pImage->nHRes
|| pAnRotation->nVRes != pImage->nVRes
|| ((LRECT *)plrMarkBounds)->left != pMark->Attributes.lrBounds.left
|| ((LRECT *)plrMarkBounds)->top != pMark->Attributes.lrBounds.top
|| ((LRECT *)plrMarkBounds)->right != pMark->Attributes.lrBounds.right
|| ((LRECT *)plrMarkBounds)->bottom != pMark->Attributes.lrBounds.bottom)
&& (int) pMark->Attributes.uType != OIOP_AN_FORM){
CheckError2(ConvResolutionAnoBitmap(hWnd, pMark, pAnRotation->rotation,
ScaleAlgStruct.uScaleAlgorithm))
CheckError2(GetAMarkNamedBlock(pMark, szOiZDpDIB, (PPSTR) &pDisplayAnImage))
pDisplayDib = (PBITMAPINFOHEADER) pDisplayAnImage;
CheckError2(GetAMarkNamedBlock(pMark, szOiAnoDat, (PPSTR) &pAnRotation))
}
// save the base image scale algorithm so that if it changes, the display
// dib can be thrown away and regenerated
pAnRotation->nReserved[0] = (int)ScaleAlgStruct.uScaleAlgorithm;
// save the current image bounds
((LRECT *)plrMarkBounds)->left = pMark->Attributes.lrBounds.left ;
((LRECT *)plrMarkBounds)->top = pMark->Attributes.lrBounds.top ;
((LRECT *)plrMarkBounds)->right = pMark->Attributes.lrBounds.right ;
((LRECT *)plrMarkBounds)->bottom = pMark->Attributes.lrBounds.bottom ;
if (nFlags != OIAN_CLIPBOARD_OPERATION){
// clip the image to the repaint rect
if (pMark->Attributes.lrBounds.left <= lrFullsizeRepaintRect.left){
lrFSRect.left = lrFullsizeRepaintRect.left;
}else{
lrFSRect.left = pMark->Attributes.lrBounds.left;
}if (pMark->Attributes.lrBounds.right >= lrFullsizeRepaintRect.right){
lrFSRect.right = lrFullsizeRepaintRect.right;
}else{
lrFSRect.right = pMark->Attributes.lrBounds.right;
}if (pMark->Attributes.lrBounds.top <= lrFullsizeRepaintRect.top){
lrFSRect.top = lrFullsizeRepaintRect.top;
}else{
lrFSRect.top = pMark->Attributes.lrBounds.top;
}if (pMark->Attributes.lrBounds.bottom >=
lrFullsizeRepaintRect.bottom){
lrFSRect.bottom = lrFullsizeRepaintRect.bottom;
}else{
lrFSRect.bottom = pMark->Attributes.lrBounds.bottom;
}
// if repaint rect is outside base image bounds, then
// do nothing
if ((lrFSRect.top > pImage->nHeight) ||
(lrFSRect.left > pImage->nWidth)){
goto Exit;
}
// clip the image to the base image
if (lrFSRect.right > pImage->nWidth){
lrFSRect.right = pImage->nWidth;
}if (lrFSRect.bottom > pImage->nHeight){
lrFSRect.bottom = pImage->nHeight;
}
}else{
CopyRect (lrFSRect, pMark->Attributes.lrBounds);
}
// coords of the portion of the image to be displayed
// relative to the entire image mark. Needed by ippack
// to get a portion of the image
lrFSRect.bottom = lmax (0, lrFSRect.bottom - pMark->Attributes.lrBounds.top);
lrFSRect.right = lmax (0, lrFSRect.right - pMark->Attributes.lrBounds.left);
lrFSRect.left = lmax (0, lrFSRect.left - pMark->Attributes.lrBounds.left);
lrFSRect.top = lmax (0, lrFSRect.top - pMark->Attributes.lrBounds.top);
// scale the image rect
SetLRect (lrScaledRect, lrFSRect.left, lrFSRect.top, lrFSRect.right,
lrFSRect.bottom);
ConvertRect2(&lrScaledRect, CONV_FULLSIZE_TO_SCALED,
nHScale, nVScale, lHOffset, lVOffset);
// get the npper left corner of the image relative to
// the DC, needed by BitBlt as X and Y
SetLRect (lrWindowMark, pMark->Attributes.lrBounds.left,
pMark->Attributes.lrBounds.top, 0, 0);
ConvertRect2(&lrWindowMark, CONV_FULLSIZE_TO_WINDOW,
nHScale, nVScale, lHOffset, lVOffset);
lrDestPt.top = lmax (lrWindowMark.top, rRepaintRect.top);
lrDestPt.left = lmax (lrWindowMark.left, rRepaintRect.left);
if (!pMark->Attributes.bTransparent ||
((int) pMark->Attributes.uType == OIOP_AN_FORM)){
if ((nMode == PAINT_MODE_DRAG) || (nMode == PAINT_MODE_XOR)){
// draw a grey rect while image is being dragged
hOldPen = SelectObject(hDC, GetStockObject(NULL_PEN));
hOldBrush = SelectObject(hDC, GetStockObject(GRAY_BRUSH));
bBrushSelected = TRUE;
bPenSelected = TRUE;
Rectangle (hDC, (int)lrDestPt.left ,
(int)lrDestPt.top, (int)lrDestPt.left +
(int)(lrScaledRect.right-lrScaledRect.left),
(int)lrDestPt.top +
(int)(lrScaledRect.bottom-lrScaledRect.top));
}else if (nMode == PAINT_MODE_NORMAL){
transparent = FALSE;
mode = 0;
if ((int) pMark->Attributes.uType == OIOP_AN_FORM){
goto Exit;
}
// scale the dib and blt it to the DC
CheckError2(IPScaling (hDC, pDisplayDib, lrScaledRect,
nHScale, nVScale, pAnRotation,lrDestPt, pImage,
transparent, mode, ScaleAlgStruct.uScaleAlgorithm,
pMark, ppgray))
}
}else if (pMark->Attributes.bTransparent){
if ((int) pMark->Attributes.uType == OIOP_AN_FORM){
goto Exit;
}
// do the transparent for pure white stuff
CheckError2(BitsTransparent(hDC, pDisplayDib,
lrScaledRect, pAnRotation, lrDestPt, nMode, pImage,
nHScale, nVScale, ScaleAlgStruct.uScaleAlgorithm, pMark))
}
break;
default:
break;
}
Exit:
FreeMemory((PPSTR) &pDib);
if (bBrushSelected){
SelectObject(hDC, hOldBrush);
}
if (bPenSelected){
SelectObject (hDC, hOldPen);
}
SetROP2(hDC, nOldROP);
return(nStatus);
}
//
/****************************************************************************
FUNCTION: OrientAnnotationBitmap
PURPOSE: This routine orients the annotation.
This routine contains the text code for OrientAnnotations.
****************************************************************************/
int WINAPI OrientAnnotationBitmap(HWND hWnd, PWINDOW pWindow,
PIMAGE pImage, int nOrientation, PMARK pMark){
int nStatus = 0;
PAN_NEW_ROTATE_STRUCT pAnRotation;
long templeft, temptop, tempright;
pAnRotation = 0;
CheckError2(GetAMarkNamedBlock(pMark, szOiAnoDat, (PPSTR) &pAnRotation))
if (!pAnRotation){
nStatus = Error (DISPLAY_DATACORRUPTED);
goto Exit;
}
if ((int) pMark->Attributes.uType == OIOP_AN_IMAGE ||
(int) pMark->Attributes.uType == OIOP_AN_IMAGE_BY_REFERENCE ||
(int) pMark->Attributes.uType == OIOP_AN_FORM){
switch (nOrientation){// this saves the new rotation state of the
// image. A horizontal mirror is saved as
// a vertical mirror, then a rotate 180
// This info only needed for ref.images
//1=original, 2=rot.right, 3=flip, 4=rot.left, 5=vert.mirror
//6=vert.mirr,rot.right, 7=vert.mirror,flip, 8=vert.mirror,rot.left
case OD_ROTRIGHT:
switch (pAnRotation->rotation){
case 1: pAnRotation->rotation = 2; break;
case 2: pAnRotation->rotation = 3; break;
case 3: pAnRotation->rotation = 4; break;
case 4: pAnRotation->rotation = 1; break;
case 5: pAnRotation->rotation = 6; break;
case 6: pAnRotation->rotation = 7; break;
case 7: pAnRotation->rotation = 8; break;
case 8: pAnRotation->rotation = 5; break;
}
break;
case OD_ROTLEFT:
switch (pAnRotation->rotation){
case 1: pAnRotation->rotation = 4; break;
case 2: pAnRotation->rotation = 1; break;
case 3: pAnRotation->rotation = 2; break;
case 4: pAnRotation->rotation = 3; break;
case 5: pAnRotation->rotation = 8; break;
case 6: pAnRotation->rotation = 5; break;
case 7: pAnRotation->rotation = 6; break;
case 8: pAnRotation->rotation = 7; break;
}
break;
case OD_FLIP:
switch (pAnRotation->rotation){
case 1: pAnRotation->rotation = 3; break;
case 2: pAnRotation->rotation = 4; break;
case 3: pAnRotation->rotation = 1; break;
case 4: pAnRotation->rotation = 2; break;
case 5: pAnRotation->rotation = 7; break;
case 6: pAnRotation->rotation = 8; break;
case 7: pAnRotation->rotation = 5; break;
case 8: pAnRotation->rotation = 6; break;
}
break;
case OD_HMIRROR:
switch (pAnRotation->rotation){
case 1: pAnRotation->rotation = 7; break;
case 2: pAnRotation->rotation = 6; break;
case 3: pAnRotation->rotation = 5; break;
case 4: pAnRotation->rotation = 8; break;
case 5: pAnRotation->rotation = 3; break;
case 6: pAnRotation->rotation = 2; break;
case 7: pAnRotation->rotation = 1; break;
case 8: pAnRotation->rotation = 4; break;
}
break;
case OD_VMIRROR:
switch (pAnRotation->rotation){
case 1: pAnRotation->rotation = 5; break;
case 2: pAnRotation->rotation = 8; break;
case 3: pAnRotation->rotation = 7; break;
case 4: pAnRotation->rotation = 6; break;
case 5: pAnRotation->rotation = 1; break;
case 6: pAnRotation->rotation = 4; break;
case 7: pAnRotation->rotation = 3; break;
case 8: pAnRotation->rotation = 2; break;
}
}
}
if ((int) pMark->Attributes.uType == OIOP_AN_IMAGE
|| (int) pMark->Attributes.uType == OIOP_AN_IMAGE_BY_REFERENCE){
switch (nOrientation){
case OD_FLIP:
// npdate the bounds of the image in pMark
templeft = pMark->Attributes.lrBounds.left;
temptop = pMark->Attributes.lrBounds.top;
pMark->Attributes.lrBounds.left
= pImage->nWidth - pMark->Attributes.lrBounds.right;
pMark->Attributes.lrBounds.top
= pImage->nHeight - pMark->Attributes.lrBounds.bottom;
pMark->Attributes.lrBounds.right = pImage->nWidth - templeft;
pMark->Attributes.lrBounds.bottom = pImage->nHeight - temptop;
break;
case OD_HMIRROR:
templeft = pMark->Attributes.lrBounds.left;
temptop = pMark->Attributes.lrBounds.top;
pMark->Attributes.lrBounds.top
= pImage->nHeight - pMark->Attributes.lrBounds.bottom;
pMark->Attributes.lrBounds.bottom = pImage->nHeight - temptop;
break;
case OD_VMIRROR:
templeft = pMark->Attributes.lrBounds.left;
temptop = pMark->Attributes.lrBounds.top;
pMark->Attributes.lrBounds.left
= pImage->nWidth - pMark->Attributes.lrBounds.right;
pMark->Attributes.lrBounds.right = pImage->nWidth - templeft;
break;
case OD_ROTRIGHT:
case OD_ROTLEFT:
if (nOrientation == OD_ROTRIGHT){
tempright = pMark->Attributes.lrBounds.right;
temptop = pMark->Attributes.lrBounds.top;
templeft = pMark->Attributes.lrBounds.left;
pMark->Attributes.lrBounds.left
= pImage->nHeight - pMark->Attributes.lrBounds.bottom;
pMark->Attributes.lrBounds.top = templeft;
pMark->Attributes.lrBounds.right
= pImage->nHeight - temptop;
pMark->Attributes.lrBounds.bottom = tempright;
}else{ // OD_ROTLEFT
templeft = pMark->Attributes.lrBounds.left;
pMark->Attributes.lrBounds.left
= pMark->Attributes.lrBounds.top;
pMark->Attributes.lrBounds.top
= pImage->nWidth - pMark->Attributes.lrBounds.right;
pMark->Attributes.lrBounds.right
= pMark->Attributes.lrBounds.bottom;
pMark->Attributes.lrBounds.bottom = pImage->nWidth - templeft;
}
break;
}
}
CheckError2(DeleteAMarkNamedBlock (pMark, szOiZDpDIB))
Exit:
return(nStatus);
}
//
/****************************************************************************
FUNCTION: ScaleAnnotationImage
PURPOSE: This scales an annotation down to the size specified in the
pSaveEx structure.
****************************************************************************/
int WINAPI ScaleAnnotationImage(HWND hWnd, PMARK pMark, int nHScale, int nVScale,
int nScaleAlgorithm){
int nStatus = 0;
HDC hlocalDC;
PAN_IMAGE_STRUCT pAnImage=0;
PBITMAPINFOHEADER pDib;
LRECT lrDestPt;
PAN_NEW_ROTATE_STRUCT pAnRotation=0;
IMAGE Image;
PPSTR ppgray=0;
int temp;
ulong nScale;
LRECT lrDibBounds;
PAN_IMAGE_STRUCT pDisplayAnImage = 0;
CheckError2(GetAMarkNamedBlock(pMark, szOiAnoDat, (PPSTR) &pAnRotation))
if (!pAnRotation){
nStatus = Error (DISPLAY_DATACORRUPTED);
goto Exit;
}
CheckError2(GetAMarkNamedBlock(pMark, szOiZDpDIB, (PPSTR) &pDisplayAnImage))
// since this routine is called before a save, for image by ref. npdate
// the bounds but don't scale the dib since it will be thrown away
if ((int) pMark->Attributes.uType == OIOP_AN_IMAGE_BY_REFERENCE
|| (int) pMark->Attributes.uType == OIOP_AN_FORM){
nScale = (nHScale * pAnRotation->scale)/
1000;
pAnRotation->scale = nScale;
pMark->Attributes.lrBounds.left = ( pMark->Attributes.lrBounds.left
* nHScale) / 1000;
pMark->Attributes.lrBounds.right = ( pMark->Attributes.lrBounds.right
* nHScale) / 1000;
pMark->Attributes.lrBounds.top = ( pMark->Attributes.lrBounds.top
* nVScale) / 1000;
pMark->Attributes.lrBounds.bottom = ( pMark->Attributes.lrBounds.bottom
* nVScale) / 1000;
goto Exit;
}
if ((int) pMark->Attributes.uType != OIOP_AN_IMAGE)
goto Exit; // this routine should only be called for embedded images
// or image by reference
pAnImage = 0;
CheckError2(GetAMarkNamedBlock(pMark, szOiDIB, (PPSTR) &pAnImage))
if (!pAnImage){
nStatus = Error (DISPLAY_DATACORRUPTED);
goto Exit; // must have dib bits to scale
}
switch ((int) pMark->Attributes.uType){
case OIOP_AN_IMAGE:
pDib = (PBITMAPINFOHEADER) pAnImage;
pMark->Attributes.lrBounds.left = ( pMark->Attributes.lrBounds.left
* nHScale) / 1000;
pMark->Attributes.lrBounds.right = ( pMark->Attributes.lrBounds.right
* nHScale) / 1000;
pMark->Attributes.lrBounds.top = ( pMark->Attributes.lrBounds.top
* nVScale) / 1000;
pMark->Attributes.lrBounds.bottom = ( pMark->Attributes.lrBounds.bottom
* nVScale) / 1000;
if (!(hlocalDC = CreateCompatibleDC (NULL))){
nStatus = Error (DISPLAY_SETBITMAPBITSFAILED);
goto Exit;
}
SetLRect (lrDestPt, 0, 0, 0, 0);
// presently resolution of image is same vertically
// and horiz due to the way scaleImage works, so
// account for it
temp = pAnRotation->nVRes;
pAnRotation->nVRes = pAnRotation->nHRes;
// mode is set to 3, so new dib is saved to mark
SetLRect (lrDibBounds, 0, 0, (int) pDib->biWidth, (int) pDib->biHeight);
ConvertRect2(&lrDibBounds, CONV_FULLSIZE_TO_SCALED, nHScale,
nHScale, 0, 0);
CheckError2(IPScaling (hlocalDC, pDib, lrDibBounds,
nHScale, nHScale, pAnRotation, lrDestPt, &Image,
FALSE, 3, nScaleAlgorithm, pMark, ppgray))
pAnRotation->nVRes = temp;
DeleteDC (hlocalDC);
/* pMark->Attributes.uLineSize = (( pMark->Attributes.uLineSize
* pSaveEx->nScaleFactor) / 1000);
*/
break;
default:
break;
}
Exit:
if (pAnRotation){
// set resolution back to original, since display dib will be thrown away
pAnRotation->nHRes = pAnRotation->nOrigHRes;
pAnRotation->nVRes = pAnRotation->nOrigVRes;
}
return(nStatus);
}
//
/****************************************************************************
FUNCTION: CanMarkBeScaledImage
PURPOSE: This tests an annotation to see if it can be scaled to a
particular scale factor.
****************************************************************************/
int WINAPI CanMarkBeScaledImage(HWND hWnd, PMARK pMark, int nScale){
DWORD LocalScale;
int nStatus = 0;
PAN_NEW_ROTATE_STRUCT pAnRotation;
switch ((int) pMark->Attributes.uType){
case OIOP_AN_IMAGE:
if ((nScale >65000) || (nScale <20)){
nStatus = Error(DISPLAY_INVALIDSCALE);
goto Exit;
}
break;
case OIOP_AN_IMAGE_BY_REFERENCE:
case OIOP_AN_FORM:
CheckError2(GetAMarkNamedBlock(pMark, szOiAnoDat, (PPSTR) &pAnRotation))
// make sure for image by ref the final scale (initial image by
// ref.scale * nScale) is within bounds
if (!pAnRotation){
nStatus = Error(DISPLAY_INVALIDSCALE);
goto Exit;
}
LocalScale = (pAnRotation->scale * nScale)/ 1000;
if ((LocalScale >65000) || (LocalScale <20)){
nStatus = Error(DISPLAY_INVALIDSCALE);
goto Exit;
}
break;
default:
break;
}
Exit:
return (nStatus);
}
//
/****************************************************************************
FUNCTION: ConvResolutionAnoBitmap
PURPOSE: This is called whenever the resolution of the base image is
being changed. Its purpose is to change the resolution of this
mark.
****************************************************************************/
int WINAPI ConvResolutionAnoBitmap(HWND hWnd, PMARK pMark, int nRotation,
int nScaleAlgorithm){
int nStatus = 0;
PAN_NEW_ROTATE_STRUCT pAnRotation;
PBITMAPINFOHEADER pDib;
PBITMAPINFOHEADER pNewDib;
IMAGE MarkImage;
RECT rRect;
PWINDOW pWindow;
PANO_IMAGE pAnoImage;
PIMAGE pImage;
PAN_IMAGE_STRUCT pAnImage = 0;
PAN_IMAGE_STRUCT pDisplayAnImage = 0;
PIMG pTempImg = 0;
LRECT *plrMarkBounds=0 ;
CheckError2(Init(hWnd, &pWindow, &pAnoImage, FALSE, TRUE))
pImage = pAnoImage->pBaseImage;
CheckError2(GetAMarkNamedBlock(pMark, szOiAnoDat, (PPSTR) &pAnRotation))
CheckError2(GetAMarkNamedBlock(pMark, szOiDIB, (PPSTR) &pAnImage))
CheckError2(GetAMarkNamedBlock(pMark, szOiZDpDIB, (PPSTR) &pDisplayAnImage))
CheckError2(GetAMarkNamedBlock(pMark, "MarkBnds", (PPSTR) &plrMarkBounds))
if (!pAnImage){
Error (DISPLAY_DATACORRUPTED);
goto Exit;
}
pDib = (PBITMAPINFOHEADER) pAnImage;
CheckError2(DibToIpNoPal(&MarkImage.pImg, pDib))
MarkImage.nHeight = (int) (int) pDib->biHeight;
MarkImage.nWidth = (int) pDib->biWidth;
pAnRotation->nHRes = pAnRotation->nOrigHRes;
pAnRotation->nVRes = pAnRotation->nOrigVRes;
CheckError2(RotateImage (pMark, &MarkImage, nRotation))
SetRect(&rRect, 0, 0, MarkImage.pImg->nWidth, MarkImage.pImg->nHeight);
CheckError2(ScaleImage(MarkImage.pImg, &pTempImg,
(int)(((pMark->Attributes.lrBounds.right - pMark->Attributes.lrBounds.left) * 1000L) /
MarkImage.pImg->nWidth),
(int)(((pMark->Attributes.lrBounds.bottom - pMark->Attributes.lrBounds.top) * 1000L) /
MarkImage.pImg->nHeight),
rRect, nScaleAlgorithm,
(LP_FIO_RGBQUAD) ((PSTR) pDib + sizeof(BITMAPINFOHEADER)),
pDib->biClrUsed))
FreeImgBuf(&MarkImage.pImg);
MoveImage(&pTempImg, &MarkImage.pImg);
SetRect(&rRect, 0, 0, MarkImage.pImg->nWidth, MarkImage.pImg->nHeight);
CheckError2(IPtoDIB (pImage, MarkImage.pImg, &pNewDib, rRect))
// adjust the mark bounds to the new resolution of the image
pMark->Attributes.lrBounds.right = pMark->Attributes.lrBounds.left + pNewDib->biWidth;
pMark->Attributes.lrBounds.bottom = pMark->Attributes.lrBounds.top + pNewDib->biHeight;
// copy palette info from old dib to new dib
if ((nScaleAlgorithm != OI_SCALE_ALG_AVERAGE_TO_GRAY4)
&& (nScaleAlgorithm != OI_SCALE_ALG_AVERAGE_TO_GRAY8)){
memcpy ((PSTR) pNewDib + sizeof(BITMAPINFOHEADER),
(PSTR) pDib + sizeof(BITMAPINFOHEADER), ((int) pDib->biClrUsed * 4));
}
// delete the old display dib and replace it with new resolution
// adjusted dib
CheckError2(AddAMarkNamedBlock(pMark, szOiZDpDIB, (PPSTR) &pNewDib,
sizeof(BITMAPINFOHEADER) + (pNewDib->biClrUsed * 4) + (pNewDib->biSizeImage)))
pAnRotation->nHRes = pImage->nHRes;
pAnRotation->nVRes = pImage->nVRes;
FreeImgBuf(&MarkImage.pImg);
Exit:
DeInit(FALSE, TRUE);
return(nStatus);
}
//
/****************************************************************************
FUNCTION: MakeMarkFromDib
PURPOSE: This will make an annotation mark from a Dib.
****************************************************************************/
int WINAPI MakeMarkFromDib(PBITMAPINFOHEADER pDib, PMARK *ppMark,
int nHRes, int nVRes){
int nStatus = 0;
PAN_IMAGE_STRUCT pAnImage;
PAN_NEW_ROTATE_STRUCT pAnRotation;
if (!pDib->biClrUsed){
if (pDib->biBitCount == 1){
pDib->biClrUsed = 2;
}
if (pDib->biBitCount == 4){
pDib->biClrUsed = 16;
}
if (pDib->biBitCount == 8){
pDib->biClrUsed = 256;
}
}
pAnImage = 0;
CheckError2(AddAMarkNamedBlock(*ppMark, szOiDIB,
(PPSTR) &pAnImage, sizeof(BITMAPINFOHEADER)
+ (pDib->biClrUsed*4) + (pDib->biSizeImage)))
memcpy (pAnImage->dibInfo, pDib,
sizeof(BITMAPINFOHEADER) + (pDib->biClrUsed*4) + (pDib->biSizeImage));
pAnRotation = 0;
CheckError2(AddAMarkNamedBlock(*ppMark, szOiAnoDat,
(PPSTR) &pAnRotation, sizeof (AN_NEW_ROTATE_STRUCT)))
// Default rotation info to the original image condition
pAnRotation->rotation = 1;
pAnRotation->scale = 1000;
pAnRotation->bFormMark = FALSE;
pAnRotation->bClipboardOp = FALSE;
// Resolution info
pAnRotation->nHRes = nHRes;
pAnRotation->nVRes = nVRes;
pAnRotation->nOrigHRes = nHRes;
pAnRotation->nOrigVRes = nVRes;
(*ppMark)->Attributes.uType = OIOP_AN_IMAGE;
(*ppMark)->Attributes.bVisible = TRUE;
Exit:
return(nStatus);
}
//
/******************************************************************************
FUNCTION: GetFileName
PURPOSE: To do the stuff needed to get an image by reference filename
from the form x:filename where x is the path defined in win.ini
If it is already a filename then it just returns that string
*********************************************************************************/
void WINAPI GetFileName(PSTR pFileName, PCSTR pOrigName){
static char szatoistr[256];
char *npszatoistr;
char szSection[12];
char szEntry [12];
char szDefaultEntry[5];
char szReturnBuffer[256];
char szstr[3];
PSTR pszstr;
PSTR pszSection;
PSTR pszEntry;
PCSTR pszDefaultEntry;
PCSTR pszReturnBuffer;
strncpy(szatoistr, pOrigName, 255);
// set a near pointer to the filename string passed in
// to overcome the DS!=SS problem
npszatoistr = szatoistr;
// if filename passed in is of the form 'x:' where x = 1-9
// do special handling to get the actual file name
if ((isdigit (*npszatoistr)) && (atoi(npszatoistr) != 0)
&& ((*(npszatoistr + 1)) == ':')){
// must go to the win.ini O/i ImagePath section and look
// for path next to a number
pszSection = szSection;
LoadString (hInst, ID_OI_IMAGE_PATH, pszSection, 80);
pszstr = szstr;
// this gets the number in the file name which must be
// obtained to get the right path from win.ini
*pszstr = *pOrigName;
*(pszstr + 1) = '\0';
// pszstr now points to the number in the O/i ImagePath section
strcpy (szEntry, pszstr);
pszEntry = szEntry;
strcpy (szDefaultEntry, "c:\\");
pszDefaultEntry = szDefaultEntry;
pszReturnBuffer = szReturnBuffer;
// go to the woi.ini and get the path
GetProfileString(pszSection, pszEntry,
pszDefaultEntry, (PSTR) pszReturnBuffer, 256);
// point to the character after : in the filename passed in
pszstr = npszatoistr + 2;
// now create the valid path and file name by concating
// the filename passed in and the path gotten from the ini
strcat ((PSTR) pszReturnBuffer, pszstr);
strcpy (pFileName, pszReturnBuffer);
}else{ // if filename is already valid, just return it
strcpy (pFileName, pOrigName);
}
}
//
/******************************************************************************
FUNCTION: GetPageNumandFileName
PURPOSE: To get the page no. embedded in the filename. The format is
"filename|page"
*********************************************************************************/
void WINAPI GetPageNumandFileName(PSTR pRealFilename, PINT pnPage, PSTR pOrigName){
PSTR pTempPointer;
*pnPage = 1;
// this will search for filenames with embedded page no.s.
// The format is "filename|page"
strcpy (pRealFilename, pOrigName);
pTempPointer = pRealFilename;
while (*pTempPointer != '\0'){// search for end of string
if (*pTempPointer == '|'){
*pnPage = atoi(pTempPointer + 1);
*pTempPointer = '\0';
break;
}
pTempPointer++;
}
}
//
/******************************************************************************
FUNCTION: EmbedImageData
PURPOSE: Change reference marks, like image by reference and forms to
non reference marks like embedded images
*********************************************************************************/
int WINAPI EmbedImageData(HWND hWnd, PMARK pMark, PANO_IMAGE pAnoImage){
int nStatus = 0;
PAN_IMAGE_STRUCT pAnImage = 0;
PAN_NAME_STRUCT pAnName = 0;
PSTR pFileName;
char FileName[256];
IMAGE TempImage;
PAN_NEW_ROTATE_STRUCT pAnRotation;
PIMG pTempImg = 0;
RECT rRect;
PBITMAPINFOHEADER pDib;
PBITMAPINFOHEADER pNewDib;
PIMAGE pImage;
CheckError2(GetAMarkNamedBlock(pMark, szOiDIB, (PPSTR) &pAnImage))
if (!pAnImage){ // create the dib from the name
CheckError2(GetAMarkNamedBlock(pMark, szOiFilNam, (PPSTR) &pAnName))
if (!pAnName){
nStatus = Error(DISPLAY_DATACORRUPTED);
goto Exit;
}
pImage = pAnoImage->pBaseImage;
pFileName = FileName;
GetFileName (pFileName, (PSTR) pAnName->name);
CheckError2(OiImageToDib (hWnd, pFileName, &pDib))
CheckError2(DibToIpNoPal(&TempImage.pImg, pDib))
TempImage.nHeight = (int) (int) pDib->biHeight;
TempImage.nWidth = (int) pDib->biWidth;
CheckError2(GetAMarkNamedBlock(pMark, szOiAnoDat, (PPSTR) &pAnRotation))
if (nStatus = RotateImage (pMark, &TempImage, pAnRotation->rotation)){
goto Exit;
}
SetRect(&rRect, 0, 0, TempImage.pImg->nWidth, TempImage.pImg->nHeight);
CheckError2(ScaleImage(TempImage.pImg, &pTempImg, pAnRotation->scale,
pAnRotation->scale, rRect, 1,
(LP_FIO_RGBQUAD) ((PSTR) pDib + sizeof(BITMAPINFOHEADER)),
pDib->biClrUsed))
FreeImgBuf(&TempImage.pImg);
MoveImage(&pTempImg, &TempImage.pImg);
SetRect(&rRect, 0, 0, TempImage.pImg->nWidth, TempImage.pImg->nHeight);
CheckError2(IPtoDIB (pImage, TempImage.pImg, &pNewDib, rRect))
memcpy ((PSTR) pNewDib + sizeof(BITMAPINFOHEADER),
(PSTR) pDib + sizeof(BITMAPINFOHEADER), ((int) pDib->biClrUsed*4));
pAnImage = 0;
CheckError2(AddAMarkNamedBlock(pMark, szOiDIB,
(PPSTR) &pAnImage, sizeof(BITMAPINFOHEADER) +
(pNewDib->biClrUsed*4) + (pNewDib->biSizeImage)))
memcpy (pAnImage->dibInfo, pNewDib,
sizeof(BITMAPINFOHEADER) + (pNewDib->biClrUsed*4) + (pNewDib->biSizeImage));
FreeImgBuf(&TempImage.pImg);
FreeMemory((PPSTR) &pDib);
FreeMemory((PPSTR) &pNewDib);
}
if ((int) pMark->Attributes.uType == OIOP_AN_FORM){
pMark->Attributes.bTransparent = TRUE;
}
(int) pMark->Attributes.uType = OIOP_AN_IMAGE;
Exit:
return (nStatus);
}