|
|
/****************************************************************************
* * Win16 Metafile emitter routines * * Date: 7/19/91 * Author: Jeffrey Newman (c-jeffn) * ***************************************************************************/
#include "precomp.h"
#pragma hdrstop
WORD GetSizeOfColorTable (LPBITMAPINFOHEADER lpDIBInfo);
/****************************************************************************
* bW16Emit0 - This is the base routine to emit a Win16 drawing order * with 0 parameters. ***************************************************************************/ BOOL bW16Emit0 ( PLOCALDC pLocalDC, WORD RecordID ) { BOOL b; METARECORD0 mr;
mr.rdSize = sizeof(mr) / sizeof(WORD); mr.rdFunction = RecordID;
b = bEmit(pLocalDC, &mr, sizeof(mr));
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return(b); }
/****************************************************************************
* bW16Emit1 - This is the base routine to emit a Win16 drawing order * with 1 parameter. ***************************************************************************/ BOOL bW16Emit1 ( PLOCALDC pLocalDC, WORD RecordID, WORD x1 ) { BOOL b; METARECORD1 mr;
mr.rdSize = sizeof(mr) / sizeof(WORD); mr.rdFunction = RecordID; mr.rdParm[0] = x1;
b = bEmit(pLocalDC, &mr, sizeof(mr));
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return(b); }
/****************************************************************************
* bW16Emit2 - This is the base routine to emit a Win16 drawing order * with 2 parameters. ***************************************************************************/ BOOL bW16Emit2 ( PLOCALDC pLocalDC, WORD RecordID, WORD x1, WORD x2 ) { BOOL b; METARECORD2 mr;
mr.rdSize = sizeof(mr) / sizeof(WORD); mr.rdFunction = RecordID; mr.rdParm[0] = x2; mr.rdParm[1] = x1;
b = bEmit(pLocalDC, &mr, sizeof(mr));
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return(b); }
/****************************************************************************
* bW16Emit4 - This is the base routine to emit a Win16 drawing order * with 4 parameters. ***************************************************************************/ BOOL bW16Emit4 ( PLOCALDC pLocalDC, WORD RecordID, WORD x1, WORD x2, WORD x3, WORD x4 ) { BOOL b; METARECORD4 mr;
mr.rdSize = sizeof(mr) / sizeof(WORD); mr.rdFunction = RecordID; mr.rdParm[0] = x4; mr.rdParm[1] = x3; mr.rdParm[2] = x2; mr.rdParm[3] = x1;
b = bEmit(pLocalDC, &mr, sizeof(mr));
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return(b); }
/****************************************************************************
* bW16Emit5 - This is the base routine to emit a Win16 drawing order * with 5 parameters. ***************************************************************************/ BOOL bW16Emit5 ( PLOCALDC pLocalDC, WORD RecordID, WORD x1, WORD x2, WORD x3, WORD x4, WORD x5 ) { BOOL b; METARECORD5 mr;
mr.rdSize = sizeof(mr) / sizeof(WORD); mr.rdFunction = RecordID; mr.rdParm[0] = x5; mr.rdParm[1] = x4; mr.rdParm[2] = x3; mr.rdParm[3] = x2; mr.rdParm[4] = x1;
b = bEmit(pLocalDC, &mr, sizeof(mr));
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return(b); }
/****************************************************************************
* bW16Emit6 - This is the base routine to emit a Win16 drawing order * with 6 parameters. ***************************************************************************/ BOOL bW16Emit6 ( PLOCALDC pLocalDC, WORD RecordID, WORD x1, WORD x2, WORD x3, WORD x4, WORD x5, WORD x6 ) { BOOL b; METARECORD6 mr;
mr.rdSize = sizeof(mr) / sizeof(WORD); mr.rdFunction = RecordID; mr.rdParm[0] = x6; mr.rdParm[1] = x5; mr.rdParm[2] = x4; mr.rdParm[3] = x3; mr.rdParm[4] = x2; mr.rdParm[5] = x1;
b = bEmit(pLocalDC, &mr, sizeof(mr));
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return(b); }
/****************************************************************************
* bW16Emit8 - This is the base routine to emit a Win16 drawing order * with 8 parameters. ***************************************************************************/ BOOL bW16Emit8 ( PLOCALDC pLocalDC, WORD RecordID, WORD x1, WORD x2, WORD x3, WORD x4, WORD x5, WORD x6, WORD x7, WORD x8 ) { BOOL b; METARECORD8 mr;
mr.rdSize = sizeof(mr) / sizeof(WORD); mr.rdFunction = RecordID; mr.rdParm[0] = x8; mr.rdParm[1] = x7; mr.rdParm[2] = x6; mr.rdParm[3] = x5; mr.rdParm[4] = x4; mr.rdParm[5] = x3; mr.rdParm[6] = x2; mr.rdParm[7] = x1;
b = bEmit(pLocalDC, &mr, sizeof(mr));
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return(b); }
/****************************************************************************
* bW16Emit9 - This is the base routine to emit a Win16 drawing order * with 9 parameters. ***************************************************************************/ BOOL bW16Emit9 ( PLOCALDC pLocalDC, WORD RecordID, WORD x1, WORD x2, WORD x3, WORD x4, WORD x5, WORD x6, WORD x7, WORD x8, WORD x9 ) { BOOL b; METARECORD9 mr;
mr.rdSize = sizeof(mr) / sizeof(WORD); mr.rdFunction = RecordID; mr.rdParm[0] = x9; mr.rdParm[1] = x8; mr.rdParm[2] = x7; mr.rdParm[3] = x6; mr.rdParm[4] = x5; mr.rdParm[5] = x4; mr.rdParm[6] = x3; mr.rdParm[7] = x2; mr.rdParm[8] = x1;
b = bEmit(pLocalDC, &mr, sizeof(mr));
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return(b); }
/****************************************************************************
* CreateFontIndirect - Win16 Metafile Emitter ***************************************************************************/ BOOL bEmitWin16CreateFontIndirect ( PLOCALDC pLocalDC, LPWIN16LOGFONT lpWin16LogFont ) { BOOL b; METARECORD_CREATEFONTINDIRECT mr;
mr.rdSize = sizeof(mr) / sizeof(WORD); mr.rdFunction = META_CREATEFONTINDIRECT; mr.lf16 = *lpWin16LogFont;
b = bEmit(pLocalDC, &mr, sizeof(mr));
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return(b); }
/****************************************************************************
* Polyline/Polygon - Win16 Metafile Emitter ***************************************************************************/ BOOL bEmitWin16Poly ( PLOCALDC pLocalDC, LPPOINTS ppt, SHORT cpt, WORD metaType ) { BOOL b ; WORD nSize ; METARECORD_POLY mr;
// Caculate the size of the points array
nSize = (WORD) (cpt * sizeof(POINTS));
// Build up the header of the Win16 poly record
mr.rdSize = (sizeof(mr) + nSize) / sizeof(WORD); mr.rdFunction = metaType; mr.cpt = cpt;
// Emit the Header, then if it succeds emit the points.
b = bEmit(pLocalDC, &mr, sizeof(mr)); if (b) { b = bEmit(pLocalDC, ppt, nSize); }
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return(b); }
/****************************************************************************
* PolyPolygon - Win16 Metafile Emitter ***************************************************************************/ BOOL bEmitWin16PolyPolygon ( PLOCALDC pLocalDC, PPOINTS ppt, PWORD pcpt, WORD cpt, WORD ccpt ) { BOOL b ; WORD nSize ; METARECORD_POLYPOLYGON mr;
nSize = cpt * sizeof(POINTS); nSize += ccpt * sizeof(WORD); nSize += sizeof(mr);
// Build up the header of the Win16 polyline record
mr.rdSize = nSize / sizeof(WORD); mr.rdFunction = META_POLYPOLYGON; mr.ccpt = ccpt;
// Emit the Header, then if it succeds emit the Point counts,
// then if it succeds emit the points.
b = bEmit(pLocalDC, &mr, sizeof(mr)); if (b) { b = bEmit(pLocalDC, pcpt, ccpt * sizeof(WORD)); if (b) { b = bEmit(pLocalDC, ppt, cpt * sizeof(POINTS)); }
}
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return(b); }
/****************************************************************************
* StretchBlt - Win16 Metafile Emitter ***************************************************************************/ BOOL bEmitWin16StretchBlt ( PLOCALDC pLocalDC, SHORT x, SHORT y, SHORT cx, SHORT cy, SHORT xSrc, SHORT ySrc, SHORT cxSrc, SHORT cySrc, DWORD rop, PBITMAPINFO lpbmi, DWORD cbbmi, PBYTE lpBits, DWORD cbBits ) { BOOL b ; DWORD nSize ; METARECORD_DIBSTRETCHBLT mr; DWORD clrUsed; WORD clrTableSize; WORD newClrTableSize; PBITMAPINFO lpnewbmi; DWORD newcbbmi;
// Need to make real sure the plane count is 1,
// otherwise this is not a DIB.
if (lpbmi->bmiHeader.biPlanes != 1) { RIPS("MF3216: bEmitWin16StretchBlt, Invalid biPlanes in DIB\n") ; return (FALSE) ; }
lpnewbmi = NULL; newcbbmi = 0; // Some programs don't work well with ClrUsed so always fill the palette
clrTableSize = GetSizeOfColorTable((LPBITMAPINFOHEADER)lpbmi); clrUsed = lpbmi->bmiHeader.biClrUsed; lpbmi->bmiHeader.biClrUsed = 0; newClrTableSize = GetSizeOfColorTable((LPBITMAPINFOHEADER)lpbmi); if (newClrTableSize != clrTableSize) { // It can happen that we are passed a color table bigger then we
// expect. So only copy the size of the new colortable
newcbbmi = lpbmi->bmiHeader.biSize + newClrTableSize; lpnewbmi = (PBITMAPINFO) LocalAlloc(LMEM_FIXED, newcbbmi); if (lpnewbmi != NULL) { // Copy the old header and fill the rest of the palette with 0
memcpy((void*) lpnewbmi, (void*)lpbmi, min(cbbmi, newcbbmi)); if (newcbbmi > cbbmi) { memset((void*) (((char*)lpnewbmi) + cbbmi), 0, newcbbmi - cbbmi); } lpbmi = lpnewbmi; cbbmi = newcbbmi; }
}
// Create the static portion of the
// Win 3.0 StretchBlt metafile record.
nSize = sizeof(mr) + cbbmi + cbBits;
mr.rdSize = nSize / sizeof(WORD); mr.rdFunction = META_DIBSTRETCHBLT; mr.rop = rop; mr.cySrc = cySrc; mr.cxSrc = cxSrc; mr.ySrc = ySrc; mr.xSrc = xSrc; mr.cy = cy; mr.cx = cx; mr.y = y; mr.x = x;
b = bEmit(pLocalDC, &mr, sizeof(mr)); if (b) { // Emit the bitmap info
b = bEmit(pLocalDC, lpbmi, cbbmi); if (b) { // Emit the actual bits, if any.
b = bEmit(pLocalDC, lpBits, cbBits); } }
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
if (lpnewbmi != NULL) { LocalFree((HLOCAL) lpnewbmi); }
return(b); }
/****************************************************************************
* ExtTextOut - Win16 Metafile Emitter ***************************************************************************/ BOOL bEmitWin16ExtTextOut ( PLOCALDC pLocalDC, SHORT x, SHORT y, WORD fwOpts, PRECTS prcts, PSTR ach, SHORT nCount, PWORD lpDx ) { BOOL b ; DWORD i, nBaseRecord ; WORD awRecord[11] ;
// Calculate the size of the record
i = ((WORD) nCount + 1) / 2 * 2; // i = size of string in bytes
if (lpDx) i += (WORD) nCount * sizeof(WORD); // add in size of Dx vector
i += sizeof(awRecord); // add in size of basic record
if (!(fwOpts & (ETO_OPAQUE | ETO_CLIPPED))) i -= sizeof(RECTS); // adjust for a rectangle being present
i /= sizeof(WORD) ; // change to word count
// Set the record size, type,
// x & y position, character count, and options.
awRecord[0] = LOWORD(i) ; awRecord[1] = HIWORD(i) ; awRecord[2] = META_EXTTEXTOUT ; awRecord[3] = y ; awRecord[4] = x ; awRecord[5] = nCount ; awRecord[6] = fwOpts ;
// Only if there is a opaque / clipping rectangle present
// do we copy it over, other wise it is nonexistent.
// We need to adjust the size of the Record emitted based upon
// the existence of the opaque / clipping rectangle.
nBaseRecord = 7 * sizeof(WORD) ; if (fwOpts & (ETO_OPAQUE | ETO_CLIPPED)) { awRecord[7] = prcts->left ; awRecord[8] = prcts->top ; awRecord[9] = prcts->right ; awRecord[10] = prcts->bottom ;
nBaseRecord += 4 * sizeof(WORD) ; }
// Emit the record.
b = bEmit(pLocalDC, awRecord, nBaseRecord) ; if (b) { // Emit the character string.
i = ((WORD) nCount + 1) / 2 * 2 ; b = bEmit(pLocalDC, ach, i) ; if (b) { if (lpDx) { // Emit the intercharacter spacing array
i = (WORD) (nCount * sizeof(WORD)) ; b = bEmit(pLocalDC, lpDx, i) ; } } }
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) awRecord) ;
return(b) ; }
/****************************************************************************
* Create Region - Win16 Metafile Emitter ***************************************************************************/ BOOL bEmitWin16CreateRegion ( PLOCALDC pLocalDC, DWORD cbRgn, PVOID pRgn ) { BOOL b; METARECORD0 mr;
mr.rdSize = (sizeof(mr) + cbRgn) / sizeof(WORD); mr.rdFunction = META_CREATEREGION;
// Emit the header.
b = bEmit(pLocalDC, &mr, sizeof(mr));
// Emit the region data.
b = bEmit(pLocalDC, pRgn, cbRgn);
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return(b); }
/****************************************************************************
* SetPaletteEntries - Win16 Metafile Emitter ***************************************************************************/ BOOL bEmitWin16SetPaletteEntries ( PLOCALDC pLocalDC, DWORD iStart, DWORD cEntries, LPPALETTEENTRY pPalEntries ) { BOOL b ; DWORD cbPalEntries ; METARECORD_SETPALENTRIES mr;
cbPalEntries = cEntries * sizeof(PALETTEENTRY);
mr.rdSize = (sizeof(mr) + cbPalEntries) / sizeof(WORD); mr.rdFunction = META_SETPALENTRIES; mr.iStart = (WORD) iStart; mr.cEntries = (WORD) cEntries;
// Emit the header.
b = bEmit(pLocalDC, &mr, sizeof(mr));
// Emit the actual palette entries.
b = bEmit(pLocalDC, pPalEntries, cbPalEntries) ;
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return(b); }
/****************************************************************************
* CreatePalette - Win16 Metafile Emitter ***************************************************************************/ BOOL bEmitWin16CreatePalette ( PLOCALDC pLocalDC, LPLOGPALETTE lpLogPal ) { BOOL b; DWORD cbLogPal; METARECORD0 mr;
cbLogPal = sizeof(LOGPALETTE) - sizeof(PALETTEENTRY) + lpLogPal->palNumEntries * sizeof(PALETTEENTRY) ;
mr.rdSize = (sizeof(mr) + cbLogPal) / sizeof(WORD); mr.rdFunction = META_CREATEPALETTE;
// Emit the header.
b = bEmit(pLocalDC, &mr, sizeof(mr));
// Emit the actual logpalette.
b = bEmit(pLocalDC, lpLogPal, cbLogPal);
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return (b) ; }
/****************************************************************************
* CreateBrushIndirect - Win16 Metafile Emitter ***************************************************************************/ BOOL bEmitWin16CreateBrushIndirect ( PLOCALDC pLocalDC, LPWIN16LOGBRUSH lpLogBrush16 ) { BOOL b; METARECORD_CREATEBRUSHINDIRECT mr;
mr.rdSize = sizeof(mr) / sizeof(WORD); mr.rdFunction = META_CREATEBRUSHINDIRECT; mr.lb16 = *lpLogBrush16;
b = bEmit(pLocalDC, &mr, sizeof(mr));
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return(b); }
/****************************************************************************
* CreateDIPatternBrush - Win16 Metafile Emitter ***************************************************************************/ BOOL bEmitWin16CreateDIBPatternBrush ( PLOCALDC pLocalDC, PBITMAPINFO pBitmapInfo, DWORD cbBitmapInfo, PBYTE pBits, DWORD cbBits, WORD iUsage, WORD iType ) { BOOL b ; METARECORD_DIBCREATEPATTERNBRUSH mr;
mr.rdSize = (sizeof(mr) + cbBitmapInfo + cbBits + 1) / sizeof(WORD); mr.rdFunction = META_DIBCREATEPATTERNBRUSH; mr.iType = iType; mr.iUsage = iUsage;
// On NT, the packed DIB is dword aligned. But on win3x, it is word aligned.
// Therefore, we emit the bitmap info followed by the bitmap bits in two
// separate stages.
ASSERTGDI(cbBitmapInfo % 2 == 0, "MF3216: bEmitWin16CreateDIBPatternBrush, bad bitmap info size");
// Emit the static portion of the record.
b = bEmit(pLocalDC, &mr, sizeof(mr)); if (b == FALSE) goto error_exit ;
// Emit the bitmap info.
b = bEmit(pLocalDC, pBitmapInfo, cbBitmapInfo) ; if (b == FALSE) goto error_exit ;
// Emit the bitmap bits.
b = bEmit(pLocalDC, pBits, (cbBits + 1) / sizeof(WORD) * sizeof(WORD)) ;
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
error_exit: return(b); }
/****************************************************************************
* CreatePen - Win16 Metafile Emitter ***************************************************************************/ BOOL bEmitWin16CreatePen ( PLOCALDC pLocalDC, WORD iPenStyle, PPOINTS pptsWidth, COLORREF crColor ) { BOOL b; METARECORD_CREATEPENINDIRECT mr;
mr.rdSize = sizeof(mr) / sizeof(WORD); mr.rdFunction = META_CREATEPENINDIRECT; mr.lopn16.lopnStyle = iPenStyle; mr.lopn16.lopnWidth = *pptsWidth; mr.lopn16.lopnColor = crColor;
b = bEmit(pLocalDC, &mr, sizeof(mr));
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return(b); }
//#if 0
/****************************************************************************
* Escape - Win16 Metafile Emitter ***************************************************************************/ BOOL bEmitWin16Escape ( PLOCALDC pLocalDC, SHORT wEscape, SHORT wCount, LPSTR lpInData, LPSTR lpOutData ) { BOOL b ; METARECORD_ESCAPE mr;
NOTUSED(lpOutData) ;
// Init the type & length field of the metafile record.
// Then emit the header of the escape record to the Win16 metafile.
mr.rdSize = (sizeof(mr) + (WORD) wCount) / sizeof(WORD); mr.rdFunction = META_ESCAPE; mr.wEscape = wEscape; mr.wCount = (WORD) wCount;
b = bEmit(pLocalDC, &mr, sizeof(mr)); if (b) { // Emit the actual data.
b = bEmit(pLocalDC, lpInData, (DWORD) (WORD) wCount) ; }
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) &mr);
return(b); } //#endif // 0
/****************************************************************************
* Escape - Win16 Metafile Emitter for enhanced metafile comment ***************************************************************************/ BOOL bEmitWin16EscapeEnhMetaFile ( PLOCALDC pLocalDC, PMETARECORD_ESCAPE pmfe, LPBYTE lpEmfData ) { BOOL b ; PMETA_ESCAPE_ENHANCED_METAFILE pmfeEnhMF = (PMETA_ESCAPE_ENHANCED_METAFILE) pmfe;
// Emit the header of the escape record to the Win16 metafile.
b = bEmit(pLocalDC, (PVOID) pmfeEnhMF, sizeof(META_ESCAPE_ENHANCED_METAFILE)); if (b) { // Emit the enhanced metafile data.
b = bEmit(pLocalDC, lpEmfData, pmfeEnhMF->cbCurrent); }
// Update the global max record size.
vUpdateMaxRecord(pLocalDC, (PMETARECORD) pmfeEnhMF);
return(b); }
|