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.
 
 
 
 
 
 

2062 lines
46 KiB

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
pclxl.cpp
Abstract:
PCL-XL command output high level function implementation
Environment:
Windows Whistler
Revision History:
08/23/99
Created initial framework.
--*/
#include "xlpdev.h"
#include "pclxlcmd.h"
#include "pclxle.h"
#include "xldebug.h"
#include "xlgstate.h"
#include "xloutput.h"
#include "xlbmpcvt.h"
//
// Hatch brush raster pattern
//
const BYTE gubSizeOfHatchBrush = 32 * 32 / 8;
const USHORT gusWidthOfHatchBrush = 32;
const USHORT gusHeightOfHatchBrush = 32;
const BYTE gubHatchBrush[6][gubSizeOfHatchBrush] =
{ {0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01},
{0x80, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00,
0x00, 0x40, 0x00, 0x00,
0x00, 0x20, 0x00, 0x00,
0x00, 0x10, 0x00, 0x00,
0x00, 0x08, 0x00, 0x00,
0x00, 0x04, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x80, 0x00,
0x00, 0x00, 0x40, 0x00,
0x00, 0x00, 0x20, 0x00,
0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0x08, 0x00,
0x00, 0x00, 0x04, 0x00,
0x00, 0x00, 0x02, 0x00,
0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x80,
0x00, 0x00, 0x00, 0x40,
0x00, 0x00, 0x00, 0x20,
0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x01},
{
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x00, 0x20,
0x00, 0x00, 0x00, 0x40,
0x00, 0x00, 0x00, 0x80,
0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x02, 0x00,
0x00, 0x00, 0x04, 0x00,
0x00, 0x00, 0x08, 0x00,
0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0x20, 0x00,
0x00, 0x00, 0x40, 0x00,
0x00, 0x00, 0x80, 0x00,
0x00, 0x01, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00,
0x00, 0x04, 0x00, 0x00,
0x00, 0x08, 0x00, 0x00,
0x00, 0x10, 0x00, 0x00,
0x00, 0x20, 0x00, 0x00,
0x00, 0x40, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00},
{0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01},
{0x80, 0x00, 0x00, 0x01,
0x40, 0x00, 0x00, 0x02,
0x20, 0x00, 0x00, 0x04,
0x10, 0x00, 0x00, 0x08,
0x08, 0x00, 0x00, 0x10,
0x04, 0x00, 0x00, 0x20,
0x02, 0x00, 0x00, 0x40,
0x01, 0x00, 0x00, 0x80,
0x00, 0x80, 0x01, 0x00,
0x00, 0x40, 0x02, 0x00,
0x00, 0x20, 0x04, 0x00,
0x00, 0x10, 0x08, 0x00,
0x00, 0x08, 0x10, 0x00,
0x00, 0x04, 0x20, 0x00,
0x00, 0x02, 0x40, 0x00,
0x00, 0x01, 0x80, 0x00,
0x00, 0x01, 0x80, 0x00,
0x00, 0x02, 0x40, 0x00,
0x00, 0x04, 0x20, 0x00,
0x00, 0x08, 0x10, 0x00,
0x00, 0x10, 0x08, 0x00,
0x00, 0x20, 0x04, 0x00,
0x00, 0x40, 0x02, 0x00,
0x00, 0x80, 0x01, 0x00,
0x01, 0x00, 0x00, 0x80,
0x02, 0x00, 0x00, 0x40,
0x04, 0x00, 0x00, 0x20,
0x08, 0x00, 0x00, 0x10,
0x10, 0x00, 0x00, 0x08,
0x20, 0x00, 0x00, 0x04,
0x40, 0x00, 0x00, 0x02,
0x80, 0x00, 0x00, 0x01}
};
//
// High level output functions
//
HRESULT
XLOutput::
BeginImage(
ColorMapping CMapping,
ULONG ulOutputBPP,
ULONG ulSrcWidth,
ULONG ulSrcHeight,
ULONG ulDestWidth,
ULONG ulDestHeight)
/*++
Routine Description:
Sends BeginImage operator.
Arguments:
Return Value:
Note:
--*/
{
DWORD dwI = 0;
XL_VERBOSE(("XLOutput::BeginImage:SrcW=%d, SrcH=%d, DstH=%d, DstW=%d\n",
ulSrcWidth, ulSrcHeight, ulDestHeight, ulDestWidth));
SetOutputBPP(CMapping, ulOutputBPP);
SetSourceWidth((uint16)ulSrcWidth);
SetSourceHeight((uint16)ulSrcHeight);
SetDestinationSize((uint16)ulDestWidth, (uint16)ulDestHeight);
Send_cmd(eBeginImage);
return S_OK;
}
HRESULT
XLOutput::
SetOutputBPP(
ColorMapping CMapping,
ULONG ulOutputBPP)
/*++
Routine Description:
Sends Color mapping and output depth.
Arguments:
Return Value:
Note:
--*/
{
switch (CMapping)
{
case eDirectPixel:
SetColorMapping(eDirectPixel);
break;
case eIndexedPixel:
SetColorMapping(eIndexedPixel);
break;
default:
SetColorMapping(eDirectPixel);
}
switch (ulOutputBPP)
{
case 1:
SetColorDepth(e1Bit);
break;
case 4:
SetColorDepth(e4Bit);
break;
case 8:
case 24:
SetColorDepth(e8Bit);
break;
default:
XL_ERR(("ulOutputBPP = %d is not supported\n", ulOutputBPP));
//
// Send color depth anyway to avoid XL error.
//
SetColorDepth(e8Bit);
}
return S_OK;
}
HRESULT
XLOutput::
SetPalette(
ULONG ulOutputBPP,
DWORD dwCEntries,
DWORD *pdwColor)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
HRESULT hResult;
if (dwCEntries != 0 && pdwColor != NULL)
{
SetPaletteDepth(e8Bit);
SetPaletteData(m_DeviceColorDepth, dwCEntries, pdwColor);
hResult = S_OK;
}
else
{
XL_ERR(("XLOutput::SetPalette pxlo = NULL\n"));
hResult = S_FALSE;
}
return hResult;
}
HRESULT
XLOutput::
SetClip(
CLIPOBJ *pco)
/*++
Routine Description:
Sends clip object.
Arguments:
Return Value:
Note:
--*/
{
PATHOBJ *ppo;
XLGState *pGState = this;
HRESULT hResult;
if (S_OK == pGState->CheckClip(pco))
return S_OK;
if ( NULL == pco )
{
XL_VERBOSE(("XLOutput::SetClip pco = NULL.\n"));
Send_cmd(eSetClipToPage);
pGState->ClearClip();
return S_OK;
}
XL_VERBOSE(("XLOutput::SetClip: pco->iDComplexity=%d\n", pco->iDComplexity));
switch(pco->iDComplexity)
{
case DC_RECT:
SetClipMode(eClipEvenOdd);
Send_cmd(eNewPath);
RectanglePath(&(pco->rclBounds));
SetClipRegion(eInterior);
Send_cmd(eSetClipReplace);
pGState->SetClip(pco);
hResult = S_OK;
break;
case DC_COMPLEX:
ppo = CLIPOBJ_ppoGetPath(pco);
if (NULL == ppo)
{
XL_ERR(("XLOutput::SetClip ppo = NULL.\n"));
Send_cmd(eSetClipToPage);
pGState->ClearClip();
hResult = S_FALSE;
break;
}
SetClipMode(eClipEvenOdd);
Path(ppo);
SetClipRegion(eInterior);
Send_cmd(eSetClipReplace);
pGState->SetClip(pco);
hResult = S_OK;
break;
case DC_TRIVIAL:
default:
Send_cmd(eSetClipToPage);
pGState->ClearClip();
hResult = S_OK;
break;
}
return hResult;
}
HRESULT
XLOutput::
RoundRectanglePath(
RECTL *prclBounds)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
RECTL Rectl;
if ( NULL == prclBounds )
{
XL_ERR(("XLOutput::RoundRectangle prclBounds = NULL.\n"));
return E_UNEXPECTED;
}
XL_VERBOSE(("XLOutput::RoundRectanglePath:left=%d, top=%d, right=%d, bottom=%d\n",
prclBounds->left,
prclBounds->top,
prclBounds->right,
prclBounds->bottom));
//
// BoundingBox can handle only positive numbers.
//
Rectl = *prclBounds;
if (Rectl.left < 0)
{
Rectl.left = 0;
}
if (Rectl.top < 0)
{
Rectl.top = 0;
}
if (Rectl.right < 0)
{
Rectl.right = 0;
}
if (Rectl.bottom < 0)
{
Rectl.bottom = 0;
}
//
// DCR: Round value needs to be sent!
//
if (S_OK == SetBoundingBox((uint16)Rectl.left,
(uint16)Rectl.top,
(uint16)Rectl.right,
(uint16)Rectl.bottom) &&
S_OK == Send_uint16_xy(0, 0) &&
S_OK == Send_attr_ubyte(eEllipseDimension) &&
S_OK == Send_cmd(eRoundRectanglePath))
return S_OK;
else
return S_FALSE;
}
HRESULT
XLOutput::
SetCursor(
LONG lX,
LONG lY)
/*++
Routine Description:
Set cursor.
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("XLOutput::SetCursor:X=%d, Y=%d\n", lX, lY));
Send_sint16_xy((sint16)lX, (sint16)lY);
Send_attr_ubyte(ePoint);
Send_cmd(eSetCursor);
m_lX = lX;
m_lY = lY;
return S_OK;
}
HRESULT
XLOutput::
GetCursorPos(
PLONG plX,
PLONG plY)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("XLOutput::GetCursor:X=%d, Y=%d\n", *plX, *plY));
if (plX == NULL || plY == NULL)
return E_UNEXPECTED;
*plX = m_lX;
*plY = m_lY;
return S_OK;
}
HRESULT
XLOutput::
ReadImage(
DWORD dwBlockHeight,
CompressMode CMode)
/*++
Routine Description:
Sends ReadImage operator
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("XLOutput::ReadImage:dwBlockHeight=%d\n", dwBlockHeight));
Send_uint16((uint16)0);
Send_attr_ubyte(eStartLine);
Send_uint16((uint16)dwBlockHeight);
Send_attr_ubyte(eBlockHeight);
//
// DCR: Need to support JPEG
//
SetCompressMode(CMode);
Send_cmd(eReadImage);
return S_OK;
}
HRESULT
XLOutput::
ReadImage(
DWORD dwStart,
DWORD dwBlockHeight,
CompressMode CMode)
/*++
Routine Description:
Sends ReadImage operator
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("XLOutput::ReadImage:dwBlockHeight=%d\n", dwBlockHeight));
Send_uint16((uint16)dwStart);
Send_attr_ubyte(eStartLine);
Send_uint16((uint16)dwBlockHeight);
Send_attr_ubyte(eBlockHeight);
//
// DCR: Need to support JPEG
//
SetCompressMode(CMode);
Send_cmd(eReadImage);
return S_OK;
}
HRESULT
XLOutput::
ReadRasterPattern(
DWORD dwBlockHeight,
CompressMode CMode)
/*++
Routine Description:
Sends ReadRasterPattern operator.
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("XLOutput::ReadRasterPattern:dwBlockHeight=%d\n", dwBlockHeight));
Send_uint16((uint16)0);
Send_attr_ubyte(eStartLine);
Send_uint16((uint16)dwBlockHeight);
Send_attr_ubyte(eBlockHeight);
//
// DCR: Need to support JPEG
//
SetCompressMode(CMode);
Send_cmd(eReadRastPattern);
return S_OK;
}
HRESULT
XLOutput::
SetRGBColor(
uint32 uint32_RGB)
/*++
Routine Description:
Sends SetGrayLevel attribute.
Arguments:
Return Value:
Note:
--*/
{
//
// RGB color 3 bytes
//
Send_ubyte_array_header(3);
WriteByte(RED(uint32_RGB));
WriteByte(GREEN(uint32_RGB));
WriteByte(BLUE(uint32_RGB));
Send_attr_ubyte(eRGBColor);
return S_OK;
}
HRESULT
XLOutput::
SetGrayLevel(
ubyte ubyte_gray)
/*++
Routine Description:
Sends SetGrayLevel attribute.
Arguments:
Return Value:
Note:
--*/
{
Send_ubyte(ubyte_gray);
Send_attr_ubyte(eGrayLevel);
return S_OK;
}
HRESULT
XLOutput::
RectanglePath(
RECTL *prclRect)
/*++
Routine Description:
Sends Rectangle Path
Arguments:
Return Value:
Note:
--*/
{
RECTL Rectl;
if (NULL == prclRect)
{
XL_ERR(("XLOutput::RectanglePath: prclRect == NULL\n"));
return E_UNEXPECTED;
}
XL_VERBOSE(("XLOutput::RectanglePath:left=%d, top=%d, right=%d, bottom=%d\n",
prclRect->left,
prclRect->top,
prclRect->right,
prclRect->bottom));
Rectl = *prclRect;
if (prclRect->left < 0)
{
Rectl.left = 0;
}
if (prclRect->top < 0)
{
Rectl.top = 0;
}
if (prclRect->right < 0)
{
Rectl.right = 0;
}
if (prclRect->bottom < 0)
{
Rectl.bottom = 0;
}
if (S_OK == SetBoundingBox((uint16)Rectl.left,
(uint16)Rectl.top,
(uint16)Rectl.right,
(uint16)Rectl.bottom) &&
S_OK == Send_cmd(eRectanglePath) )
return S_OK;
else
return S_FALSE;
}
HRESULT
XLOutput::
Path(
PATHOBJ *ppo)
/*++
Routine Description:
Sends path.
Arguments:
Return Value:
Note:
--*/
{
POINTFIX* pptfx;
PATHDATA PathData;
LONG lPoints;
HRESULT hResult;
BOOL bMore;
XL_VERBOSE(("XLOutput::Path\n"));
if (ppo == NULL)
{
XL_ERR(("XLOutput::Path ppo = NULL.\n"));
return E_UNEXPECTED;
}
//
// Emit newpath operator
// Don't do it if we're between path escapes
//
hResult = Send_cmd(eNewPath);
//
// Path object case
//
PATHOBJ_vEnumStart(ppo);
do
{
bMore = PATHOBJ_bEnum(ppo, &PathData);
pptfx = PathData.pptfx;
if ( 0 == (lPoints = PathData.count))
{
XL_VERBOSE(("XLOutput::Path PathData.Count == 0\n"));
hResult = S_FALSE;
continue;
}
//
// Begin new sub path
//
if (PathData.flags & PD_BEGINSUBPATH)
{
//
// start new path
//
if (hResult == S_OK)
hResult = SetCursor(FXTOL(pptfx->x), FXTOL(pptfx->y));;
pptfx++;
lPoints--;
}
if (lPoints > 0)
{
if (PathData.flags & PD_BEZIERS)
{
//
// Output a Bezier curve segment
//
ASSERTMSG((lPoints % 3) == 0,
("Incorrect number of points for a Bezier curve: %d\n", lPoints));
if (hResult == S_OK)
hResult = BezierPath(pptfx, lPoints);
}
else
{
//
// Draw straight line segment
//
if (hResult == S_OK)
hResult = LinePath(pptfx, lPoints);
}
}
//
// Close subpath
//
if (PathData.flags & PD_CLOSEFIGURE)
{
if (hResult == S_OK)
hResult = Send_cmd(eCloseSubPath);
}
}
while (bMore);
return hResult;
}
HRESULT
XLOutput::
BezierPath(
POINTFIX* pptfx,
LONG lPoints)
/*++
Routine Description:
Sends bezier path
Arguments:
Return Value:
Note:
--*/
{
LONG lValue, lI;
DWORD dwDataLength;
if (NULL == pptfx)
{
XL_ERR(("XLOutput::BezierPath: pptfx == NULL\n"));
return E_UNEXPECTED;
}
XL_VERBOSE(("XLOutput::BezierPath(lPoints=%d)\n",lPoints));
Send_uint16((uint16)lPoints);
Send_attr_ubyte(eNumberOfPoints);
Send_ubyte(eSint16);
Send_attr_ubyte(ePointType);
Send_cmd(eBezierPath);
dwDataLength = lPoints * 2 * sizeof(sint16);
if (dwDataLength > 0xff)
{
WriteByte(PCLXL_dataLength);
Write((PBYTE)&dwDataLength, sizeof(DWORD));
}
else
{
WriteByte(PCLXL_dataLengthByte);
WriteByte((ubyte)dwDataLength);
}
for (lI = 0; lI < lPoints; lI++)
{
lValue = FXTOL(pptfx->x);
Write((PBYTE)&lValue, sizeof(sint16));
lValue = FXTOL(pptfx->y);
Write((PBYTE)&lValue, sizeof(sint16));
pptfx++;
}
//
// Update the last coordinate.
// Make sure that there are some points.
if (lPoints > 0)
{
pptfx--;
m_lX = FXTOL(pptfx->x);
m_lY = FXTOL(pptfx->y);
}
else
{
m_lX = 0;
m_lY = 0;
}
return S_OK;
}
HRESULT
XLOutput::
LinePath(
POINTFIX* pptfx,
LONG lPoints)
/*++
Routine Description:
Sends line path.
Arguments:
Return Value:
Note:
--*/
{
LONG lValueX, lValueY, lI, lJ;
LONG lx, ly;
DWORD dwDataLength;
if (NULL == pptfx)
{
XL_ERR(("XLOutput::LinePath: pptfx == NULL\n"));
return E_UNEXPECTED;
}
XL_VERBOSE(("XLOutput::LinePath(lPoints=%d)\n", lPoints));
//
// Optimization. Use byte relpath to minimize the output size
// First, check if the difference from the previous position is in a byte.
//
BOOL bModeChange;
enum { eMode_SByte, eMode_SInt, eMode_None} Mode;
LONG lStart, lEnd, lNumOfSByte;
LONG lStartX, lStartY;
POINTFIX *pptfx_tmp = pptfx;
//
// Get current cursor position
//
lStartX = lx = m_lX;
lStartY = ly = m_lY;
//
// Reset
//
lStart = 0;
Mode = eMode_None;
bModeChange = FALSE;
lNumOfSByte = 0;
for (lI = 0; lI < lPoints; )
{
XL_VERBOSE(("XLOutput::LinePath: (%d)=(%d,%d)\n",lI, lx, ly));
lValueX = FXTOL(pptfx_tmp->x) - (LONG)lx;
lValueY = FXTOL(pptfx_tmp->y) - (LONG)ly;
//
// Mode needs to be in SByte or SInt?
//
if ( -128 <= lValueX && lValueX <= 127
&& -128 <= lValueY && lValueY <= 127 )
{
if (Mode == eMode_SInt)
{
//
// Optimization
//
// To switch mode between SInt and SByte, it needs 7 bytes.
//
// uint16 XX NumberOfPoints
// ubyte eSByte PointType
// LineRelPath
//
// 4 points with SInt consumes 2 x 4 = 8 bytes extra data.
// 3 points with SInt consumes 2 x 3 = 6 bytes extra data.
//
// 4 points is the threshold to swith mode to SInt.
//
// Number of points: lEnd - lStart + 1
// if (lI - 1 - lStartSByte + 1 >= 4)
//
// If SByte continues more than 4 points, switch mode from
// SByte to SInt.
//
if (lNumOfSByte >= 4)
{
bModeChange = TRUE;
lI -= lNumOfSByte;
pptfx_tmp -= lNumOfSByte;
lEnd = (lI - 1);
lNumOfSByte = 0;
}
//
// Reset starting point of SByte
//
lNumOfSByte ++;
}
else
{
Mode = eMode_SByte;
}
XL_VERBOSE(("XLOutput::LinePath: (SByte) lx1=%d, lx2=%d\n", lx, FXTOL(pptfx_tmp->x)));
}
else
{
if (Mode == eMode_SByte)
{
bModeChange = TRUE;
lEnd = lI - 1;
}
else
{
Mode = eMode_SInt;
lNumOfSByte = 0;
}
XL_VERBOSE(("XLOutput::LinePath: (SInt) lx1=%d, lx2=%d\n", lx, FXTOL(pptfx_tmp->x)));
}
if (!bModeChange && lI + 1 == lPoints)
{
bModeChange = TRUE;
lEnd = lI;
lI ++;
}
if (bModeChange)
{
XL_VERBOSE(("XLOutput::LinePath: Draw\n"));
//
// Get start cursor position
//
lx = lStartX;
ly = lStartY;
if (Mode == eMode_SByte)
{
//
// SByte
//
Send_uint16((uint16)(lEnd - lStart + 1));
Send_attr_ubyte(eNumberOfPoints);
Send_ubyte(eSByte);
Send_attr_ubyte(ePointType);
Send_cmd(eLineRelPath);
dwDataLength = (lEnd - lStart + 1) * 2 * sizeof(ubyte);
if (dwDataLength <= 0xFF)
{
WriteByte(PCLXL_dataLengthByte);
WriteByte((ubyte)dwDataLength);
}
else
{
WriteByte(PCLXL_dataLength);
Write((PBYTE)&dwDataLength, sizeof(DWORD));
}
for (lJ = 0; lJ <= (lEnd - lStart); lJ++)
{
lValueX = FXTOL(pptfx->x) - (LONG)lx;
lValueY = FXTOL(pptfx->y) - (LONG)ly;
Write((PBYTE)&lValueX, sizeof(ubyte));
Write((PBYTE)&lValueY, sizeof(ubyte));
lx = FXTOL(pptfx->x);
ly = FXTOL(pptfx->y);
pptfx++;
}
Mode = eMode_SInt;
}
else if (Mode == eMode_SInt)
{
//
// SInt16
//
Send_uint16((uint16)(lEnd - lStart + 1));
Send_attr_ubyte(eNumberOfPoints);
Send_ubyte(eSint16);
Send_attr_ubyte(ePointType);
Send_cmd(eLineRelPath);
dwDataLength = (lEnd - lStart + 1) * 2 * sizeof(uint16);
if (dwDataLength <= 0xFF)
{
WriteByte(PCLXL_dataLengthByte);
WriteByte((ubyte)dwDataLength);
}
else
{
WriteByte(PCLXL_dataLength);
Write((PBYTE)&dwDataLength, sizeof(DWORD));
}
for (lJ = 0; lJ <= (lEnd - lStart); lJ++)
{
lValueX = FXTOL(pptfx->x) - (LONG)lx;
lValueY = FXTOL(pptfx->y) - (LONG)ly;
Write((PBYTE)&lValueX, sizeof(sint16));
Write((PBYTE)&lValueY, sizeof(sint16));
lx = FXTOL(pptfx->x);
ly = FXTOL(pptfx->y);
pptfx++;
}
Mode = eMode_SByte;
}
bModeChange = FALSE;
lStartX = lx = FXTOL((pptfx_tmp-1)->x);
lStartY = ly = FXTOL((pptfx_tmp-1)->y);
lStart = lI;
}
else
{
lx = FXTOL((pptfx_tmp)->x);
ly = FXTOL((pptfx_tmp)->y);
pptfx_tmp ++;
lI ++;
}
}
//
// Update cursor position
//
m_lX = FXTOL((pptfx_tmp)->x);
m_lY = FXTOL((pptfx_tmp)->y);
return S_OK;
}
inline
VOID
XLOutput::
SetupBrush(
BRUSHOBJ *pbo,
POINTL *pptlBrushOrg,
CMNBRUSH *pcmnbrush)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
DWORD dwHatchID;
XLBRUSH *pBrush;
if (NULL == pcmnbrush)
{
//
// Make sure that pcmnbrush is valid.
//
XL_ERR(("SetupBrush:pcmnbrush is invalid.\n"));
return;
}
//
// Initialize CMNBRUSH
//
pcmnbrush->dwSig = BRUSH_SIGNATURE;
pcmnbrush->BrushType = kNoBrush;
pcmnbrush->ulHatch = 0XFFFFFFFF;
pcmnbrush->dwColor = 0x00FFFFFF;
pcmnbrush->dwCEntries = 0;
pcmnbrush->dwPatternBrushID = 0xFFFFFFFF;
XL_VERBOSE(("XLOutput::SetupBrush\n"));
if (NULL == pbo)
{
XL_VERBOSE(("XLOutput::SetupBrush: pbo == NULL, set NULL brush\n"));
}
else
{
#ifndef WINNT_40
if ( !(pbo->flColorType & BR_CMYKCOLOR) &&
(pbo->iSolidColor == NOT_SOLID_COLOR) )
#else
if (pbo->iSolidColor == NOT_SOLID_COLOR)
#endif
{
pcmnbrush->ulSolidColor = BRUSHOBJ_ulGetBrushColor(pbo);
pBrush = (XLBRUSH*)BRUSHOBJ_pvGetRbrush(pbo);
if (NULL == pBrush)
{
XL_ERR(("SetupBrush:BRUSHOBJ_pvGetRbrush failed.\n"));
dwHatchID = HS_DDI_MAX;
}
else
{
dwHatchID = pBrush->dwHatch;
}
}
else
{
dwHatchID = HS_DDI_MAX;
pcmnbrush->ulSolidColor = pbo->iSolidColor;
pBrush = NULL;
}
pcmnbrush->ulHatch = dwHatchID;
switch (dwHatchID)
{
case HS_HORIZONTAL:
case HS_VERTICAL:
case HS_BDIAGONAL:
case HS_FDIAGONAL:
case HS_CROSS:
case HS_DIAGCROSS:
XL_VERBOSE(("XLOutput::SetupBrush(uiSolidColor=%d,dwHatchID=%d)\n",
pbo->iSolidColor,
dwHatchID));
pcmnbrush->BrushType = kBrushTypeHatch;
pcmnbrush->dwPatternBrushID = dwHatchID;
if (pBrush)
{
pcmnbrush->dwColor = pBrush->dwColor;
}
if (GetDeviceColorDepth() == e24Bit)
{
SetColorSpace(eRGB);
}
else
{
SetColorSpace(eGray);
}
SetPaletteDepth(e8Bit);
if (pBrush->dwCEntries)
{
SetPaletteData(m_DeviceColorDepth, pBrush->dwCEntries, pBrush->adwColor);
}
else
{
DWORD dwColorTableTmp[2] = {0x00ffffff, 0x00ffffff};
dwColorTableTmp[1] = pBrush->dwColor;
SetPaletteData(m_DeviceColorDepth, 2, dwColorTableTmp);
}
Send_cmd(eSetColorSpace);
if (!(m_dwHatchBrushAvailability & (HORIZONTAL_AVAILABLE << dwHatchID)))
{
SetColorMapping(eIndexedPixel);
SetColorDepth(e1Bit);
SetSourceWidth((uint16)gusWidthOfHatchBrush);
SetSourceHeight((uint16)gusHeightOfHatchBrush);
//
// Pattern scaling factor
// 160 is an experimentally introduced number.
//
WORD wScale = (WORD)(160 * m_dwResolution / 1200);
SetDestinationSize((uint16)wScale, (uint16)wScale);
SetPatternPersistence(eSessionPattern);
SetPatternDefineID((sint16)dwHatchID);
Send_cmd(eBeginRastPattern);
Send_uint16((uint16)0);
Send_attr_ubyte(eStartLine);
Send_uint16((uint16)gusHeightOfHatchBrush);
Send_attr_ubyte(eBlockHeight);
SetCompressMode(eNoCompression);
Send_cmd(eReadRastPattern);
WriteByte(PCLXL_dataLengthByte);
WriteByte(gubSizeOfHatchBrush);
Write((PBYTE)gubHatchBrush[dwHatchID], gubSizeOfHatchBrush);
Send_cmd(eEndRastPattern);
m_dwHatchBrushAvailability |= HORIZONTAL_AVAILABLE << dwHatchID;
}
//
//SendPatternSelectID();
//
Send_sint16((sint16)dwHatchID);
Send_attr_ubyte(ePatternSelectID);
break;
case HS_DDI_MAX:
pcmnbrush->BrushType = kBrushTypeSolid;
//pcmnbrush->dwColor = BRUSHOBJ_ulGetBrushColor(pbo);
pcmnbrush->dwColor = pcmnbrush->ulSolidColor;
XL_VERBOSE(("XLOutput::SetupBrush(RGB=0x%x)\n", pcmnbrush->dwColor));
if (e24Bit == GetDeviceColorDepth())
{
SetRGBColor(pcmnbrush->dwColor);
}
else
{
ubyte ubyte_gray = (ubyte) DWORD2GRAY(pcmnbrush->dwColor);
SetGrayLevel(ubyte_gray);
}
break;
default:
if (NULL == pBrush)
{
XL_ERR(("XLOutput:SetupBrush: invalid pBrush\n"));
return;
}
XL_VERBOSE(("XLOutput::SetupBrush(PatternID=%d)\n", pBrush->dwPatternID));
pcmnbrush->dwColor = pBrush->dwColor;
pcmnbrush->dwPatternBrushID = pBrush->dwPatternID;
pcmnbrush->BrushType = kBrushTypePattern;
if (e24Bit == GetDeviceColorDepth())
{
SetColorSpace(eRGB);
}
else
{
SetColorSpace(eGray);
}
if (pBrush->dwCEntries)
{
SetPaletteDepth(e8Bit);
SetPaletteData(m_DeviceColorDepth, pBrush->dwCEntries, pBrush->adwColor);
}
Send_cmd(eSetColorSpace);
//SendPatternSelectID();
Send_sint16((sint16)pBrush->dwPatternID);
Send_attr_ubyte(ePatternSelectID);
}
}
return;
}
HRESULT
XLOutput::
SetPenColor(
BRUSHOBJ *pbo,
POINTL *pptlBrushOrg)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("XLOutput::SetPenColor\n"));
XLPen *pPen = this;
CMNBRUSH cmnbrush;
if (S_OK == pPen->CheckCurrentBrush(pbo))
return S_OK;
if (NULL == pbo)
{
Send_ubyte(0);
Send_attr_ubyte(eNullPen);
}
SetupBrush(pbo, pptlBrushOrg, &cmnbrush);
Send_cmd(eSetPenSource);
pPen->SetBrush(&cmnbrush);
return S_OK;
}
HRESULT
XLOutput::
SetPen(
LINEATTRS *plineattrs,
XFORMOBJ *pxo)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
LineCap linecap;
XLLineEndCap xllinecap;
LineJoin linejoin;
XLLineJoin xllinejoin;
FLOATOBJ fLineWidth;
uint16 uint16_linewidth;
XL_VERBOSE(("XLOutput::SetPen\n"));
if (NULL == plineattrs)
{
XL_ERR(("XLOutput:SetPen: invalid parameters\n"));
return E_UNEXPECTED;
}
XLGState *pGState = this;
DWORD dwLine = pGState->GetDifferentAttribute(plineattrs);
//
// DCR: need to check each attribute.
//
if (XLLINE_NONE == dwLine)
return S_OK;
if (plineattrs->fl & LA_GEOMETRIC)
{
//
// Line joint
//
switch(plineattrs->iJoin)
{
case JOIN_ROUND:
linejoin = eRoundJoin;
xllinejoin = kXLLineJoin_Round;
break;
case JOIN_BEVEL:
linejoin = eBevelJoin;
xllinejoin = kXLLineJoin_Bevel;
break;
case JOIN_MITER:
linejoin = eMiterJoin;
xllinejoin = kXLLineJoin_Miter;
break;
default:
linejoin = eRoundJoin;
xllinejoin = kXLLineJoin_Round;
break;
}
//
// Line endcap
//
switch(plineattrs->iEndCap)
{
case ENDCAP_ROUND:
linecap = eRoundCap;
xllinecap = kXLLineEndCapRound;
break;
case ENDCAP_SQUARE:
linecap = eSquareCap;
xllinecap = kXLLineEndCapSquare;
break;
case ENDCAP_BUTT:
linecap = eButtCap;
xllinecap = kXLLineEndCapButt;
break;
default:
linecap = eRoundCap;
xllinecap = kXLLineEndCapRound;
break;
}
//
// Line width
//
fLineWidth = plineattrs->elWidth.e;
}
else
{
linejoin = eRoundJoin;
linecap = eRoundCap;
FLOATOBJ_SetLong(&fLineWidth, plineattrs->elWidth.l);
}
if (dwLine & XLLINE_WIDTH)
{
uint16_linewidth = (uint16)FLOATOBJ_GetLong(&fLineWidth);
SetPenWidth(uint16_linewidth);
pGState->SetLineWidth(plineattrs->elWidth);
}
if (dwLine & XLLINE_ENDCAP)
{
SetLineCap(linecap);
pGState->SetLineEndCap(xllinecap);
}
if (dwLine & XLLINE_JOIN)
{
SetLineJoin(linejoin);
pGState->SetLineJoin(xllinejoin);
}
//
// Line style
//
if (dwLine & XLLINE_STYLE)
{
if (plineattrs->cstyle == 0)
{
Send_ubyte((ubyte)0);
Send_attr_ubyte(eSolidLine);
Send_cmd(eSetLineDash);
}
else
{
DWORD dwI, dwSegCount;
PFLOAT_LONG plSize;
FLOAT_LONG lSize[2];
FLOATOBJ fSize;
uint16 uint16_linesize;
if (plineattrs->fl & LA_ALTERNATE)
{
if (plineattrs->fl & LA_GEOMETRIC)
{
FLOATOBJ_SetLong(&lSize[0].e, 1);
FLOATOBJ_SetLong(&lSize[1].e, 1);
}
else
{
lSize[0].l = 1;
lSize[1].l = 1;
}
dwSegCount = 2;
plSize = lSize;
}
else
{
dwSegCount = plineattrs->cstyle;
plSize = plineattrs->pstyle;
}
if (plSize)
{
Send_uint16_array_header(dwSegCount);
for (dwI = 0; dwI < dwSegCount; dwI ++, plSize ++)
{
if (plineattrs->fl & LA_GEOMETRIC)
{
fSize = plSize->e;
}
else
{
FLOATOBJ_SetLong(&fSize, plSize->l);
//
// It is necessary to scale the line pattern. The number
// 24 on 1200 dpi was introduced experimentally.
// Here is an assumption. Resolution could be 300, 600,
// or 1200.
//
if (m_dwResolution > 50)
{
FLOATOBJ_MulLong(&fSize, m_dwResolution / 50);
}
}
uint16_linesize = (uint16)FLOATOBJ_GetLong(&fSize);
Write((PBYTE)&uint16_linesize, sizeof(uint16_linesize));
}
Send_attr_ubyte(eLineDashStyle);
Send_cmd(eSetLineDash);
}
}
pGState->SetLineStyle(plineattrs->cstyle,
plineattrs->pstyle,
plineattrs->elStyleState);
}
if (dwLine & XLLINE_MITERLIMIT)
{
FLOATOBJ fMiter;
FLOATOBJ_SetFloat(&fMiter, plineattrs->eMiterLimit);
uint16 uint16_miter = (uint16)FLOATOBJ_GetLong(&fMiter);
//
// PCLXL interpreter doesn't accept miterlimiter less than 1.
// If it is less than 1, it replaces the value with 10.
// We'd better set 1 instead.
//
// Actuall less than 1 means 0 here, though.
//
if (uint16_miter < 1)
{
uint16_miter = 1;
}
SetMiterLimit(uint16_miter);
pGState->SetMiterLimit(plineattrs->eMiterLimit);
}
pGState->SetLineType((XLLineType)plineattrs->fl);
return S_OK;
}
HRESULT
XLOutput::
SetBrush(
BRUSHOBJ *pbo,
POINTL *pptlBrushOrg)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("XLOutput::SetBrush\n"));
XLBrush *pBrush = this;
CMNBRUSH cmnbrush;
if (S_OK == pBrush->CheckCurrentBrush(pbo))
return S_OK;
if (NULL == pbo)
{
Send_ubyte(0);
Send_attr_ubyte(eNullBrush);
}
SetupBrush(pbo, pptlBrushOrg, &cmnbrush);
Send_cmd(eSetBrushSource);
pBrush->SetBrush(&cmnbrush);
return S_OK;
}
HRESULT
XLOutput::
Paint(
VOID)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("XLOutput::Paint\n"));
return Send_cmd(ePaintPath);
}
HRESULT
XLOutput::
SetPaletteData(
ColorDepth value,
DWORD dwPaletteNum,
DWORD *pdwColorTable)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
DWORD dwI;
if (NULL == pdwColorTable)
{
XL_ERR(("XLOutput::SetPaletteData pdwColorTable == NULL\n"));
return E_UNEXPECTED;
}
switch (value)
{
case e8Bit:
WriteByte(PCLXL_ubyte_array);
Send_uint16((uint16)dwPaletteNum);
for (dwI = 0; dwI < dwPaletteNum; dwI ++)
WriteByte((ubyte)DWORD2GRAY(*(pdwColorTable+dwI)));
Send_attr_ubyte(ePaletteData);
break;
case e24Bit:
WriteByte(PCLXL_ubyte_array);
Send_uint16((uint16)dwPaletteNum * 3);
for (dwI = 0; dwI < dwPaletteNum; dwI ++)
{
Write((PBYTE)(pdwColorTable+dwI), 3);
}
Send_attr_ubyte(ePaletteData);
break;
default:
//
// DCR: only supports 8bits gray scale
//
XL_ERR(("XLOutput::SetPaletteData: unsupported ColorDepth:%d\n", value));
}
return S_OK;
}
HRESULT
XLOutput::
SetFont(
FontType fonttype,
PBYTE pFontName,
DWORD dwFontHeight,
DWORD dwFontWidth,
DWORD dwSymbolSet,
DWORD dwFontSimulation)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
FLOATOBJ fSize;
LONG lvalue;
if (NULL == pFontName)
{
XL_ERR(("XLOutput::SetFont: Invalie pFontName parameter\n"));
return E_UNEXPECTED;
}
XLGState *pGState = this;
if (S_OK == pGState->CheckCurrentFont(fonttype,
pFontName,
dwFontHeight,
dwFontWidth,
dwSymbolSet,
dwFontSimulation))
return S_OK;
FLOATOBJ_SetLong(&fSize, dwFontHeight);
lvalue = FLOATOBJ_GetFloat(&fSize);
//
// Select font
//
Send_ubyte_array_header(PCLXL_FONTNAME_SIZE);
Write(pFontName, PCLXL_FONTNAME_SIZE);
Send_attr_ubyte(eFontName);
Send_real32(lvalue);
Send_attr_ubyte(eCharSize);
Send_uint16((uint16)dwSymbolSet);
Send_attr_ubyte(eSymbolSet);
Send_cmd(eSetFont);
//
// TrueType font outline or device font
// Font Scale
// Font bold/italic simulaiton
//
if (fonttype == kFontTypeTTOutline ||
fonttype == kFontTypeDevice )
{
if (dwFontWidth != pGState->GetFontWidth() ||
dwFontHeight != pGState->GetFontHeight() )
{
//
// Scale X and Y
//
if (dwFontWidth != 0 && dwFontHeight != dwFontWidth)
{
FLOATOBJ fTemp;
FLOATOBJ_SetLong(&fTemp, dwFontWidth);
FLOATOBJ_DivFloat(&fTemp, fSize);
lvalue = FLOATOBJ_GetFloat(&fTemp);
Send_real32_xy((real32)lvalue, (real32)real32_IEEE_1_0F);
Send_attr_ubyte(eCharScale);
Send_cmd(eSetCharScale);
}
else
{
Send_real32_xy((real32)real32_IEEE_1_0F, (real32)real32_IEEE_1_0F);
Send_attr_ubyte(eCharScale);
Send_cmd(eSetCharScale);
}
}
DWORD dwCurrentFontSim = pGState->GetFontSimulation();
//
// Bold simulation
//
if ((dwFontSimulation & XLOUTPUT_FONTSIM_BOLD) !=
(dwCurrentFontSim& XLOUTPUT_FONTSIM_BOLD))
{
if (dwFontSimulation & XLOUTPUT_FONTSIM_BOLD)
{
//
// Hardcoded bold value 0.01500
//
#define XL_BOLD_VALUE 0x3c75c28f
Send_real32((real32)XL_BOLD_VALUE);
}
else
Send_real32((real32)0);
Send_attr_ubyte(eCharBoldValue);
Send_cmd(eSetCharBoldValue);
}
//
// Italic simulation
//
if ((dwFontSimulation & XLOUTPUT_FONTSIM_ITALIC) !=
(dwCurrentFontSim & XLOUTPUT_FONTSIM_ITALIC))
{
if (dwFontSimulation & XLOUTPUT_FONTSIM_ITALIC)
{
//
// Hardcoded italic value 0.316200
//
#define XL_ITALIC_VALUE 0x3ea1e4f7
Send_real32_xy((real32)XL_ITALIC_VALUE, (real32)0);
}
else
Send_real32_xy((real32)0, (real32)0);
Send_attr_ubyte(eCharShear);
Send_cmd(eSetCharShear);
}
//
// Vertical font simulation
//
if ((dwFontSimulation & XLOUTPUT_FONTSIM_VERTICAL) !=
(dwCurrentFontSim & XLOUTPUT_FONTSIM_VERTICAL))
{
if (dwFontSimulation & XLOUTPUT_FONTSIM_VERTICAL)
{
Send_ubyte(eVertical);
}
else
{
Send_ubyte(eHorizontal);
}
Send_attr_ubyte(eWritingMode);
Send_cmd(eSetCharAttributes);
}
}
else
{
if (kFontTypeTTBitmap != pGState->GetFontType())
{
//
// Bitmap font can't be scaled x and y. Need to set 1 : 1.
//
Send_real32_xy((real32)real32_IEEE_1_0F, (real32)real32_IEEE_1_0F);
Send_attr_ubyte(eCharScale);
Send_cmd(eSetCharScale);
}
}
//
// Change GState to set current selected font.
//
pGState->SetFont(fonttype,
pFontName,
dwFontHeight,
dwFontWidth,
dwSymbolSet,
dwFontSimulation);
return S_OK;
}
HRESULT
XLOutput::
SetSourceTxMode(
TxMode SrcTxMode)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
XLGState *pGState = this;
if (SrcTxMode == pGState->GetSourceTxMode())
{
return S_OK;
}
if (S_OK == SetTxMode(SrcTxMode) &&
S_OK == Send_cmd(eSetSourceTxMode))
{
pGState->SetSourceTxMode(SrcTxMode);
return S_OK;
}
else
{
return S_FALSE;
}
}
HRESULT
XLOutput::
SetPaintTxMode(
TxMode PaintTxMode)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
XLGState *pGState = this;
if (PaintTxMode == pGState->GetPaintTxMode())
{
return S_OK;
}
if (S_OK == SetTxMode(PaintTxMode) &&
S_OK == Send_cmd(eSetPatternTxMode))
{
pGState->SetPaintTxMode(PaintTxMode);
return S_OK;
}
else
{
return S_FALSE;
}
}