Leaked source code of windows server 2003
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.
 
 
 
 
 
 

867 lines
22 KiB

/****************************************************************************
*
* 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);
}