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
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;
|
|
}
|
|
}
|