WindowsXP-SP1/windows/advcore/gdiplus/engine/render/scandib.hpp
2020-09-30 16:53:49 +02:00

280 lines
6.8 KiB
C++

/**************************************************************************\
*
* Copyright (c) 1998-2000 Microsoft Corporation
*
* Abstract:
*
* Internal output banding class for use with printing.
*
* This class supports two major forms of DIB banding. Both are useful
* when printing.
*
* 1. Output at a 'capped DPI' either 32bpp or 24bpp.
* 2. Output at a 'device DPI' only the alpha channel.
*
* Revision History:
*
* 07/26/1999 ericvan
* Created it.
*
\**************************************************************************/
#ifndef __SCANDIB_HPP
#define __SCANDIB_HPP
// Internally generate a bottom up DIB
#define PRINT_BOTTOM_UP 1
enum ScanDIBOptions
{
ScanCappedBounds = 0x00000001, // allocate 24bpp buffer at capped size
ScanDeviceBounds = 0x00000002, // allocate 1bpp mask at device size
ScanCapped32bpp = 0x00000004, // otherwise the default is 24bpp
ScanCapped32bppOver = 0x00000008, // otherwise the default is 24bpp
ScanCappedOver = 0x00000010, // do whiteness source over on 24bpp
ScanDeviceZeroOut = 0x00000020, // zero out 0's in capped buffer when
// generating 0's in alpha mask buffer
// !! ONLY if dev/cap is integer.
ScanDeviceAlpha = 0x00000040, // generate alpha vs. opaque 1bpp mask
ScanBleedOut = 0x00000080, // bleed color data
ScanDeviceFlags = ScanDeviceAlpha | ScanDeviceZeroOut | ScanDeviceBounds,
ScanCappedFlags = ScanCappedBounds | ScanCapped32bpp | ScanCappedOver |
ScanCapped32bppOver
};
class EpScanDIB : public EpScan
{
private:
GpRect CappedBounds; // bounds at capped DPI (24bpp)
GpRect DeviceBounds; // bounds at device DPI (1bpp)
INT CappedStride;
GpPoint MinBound;
GpPoint MaxBound;
INT ScaleX;
INT ScaleY;
// Last output scan operation
INT OutputX, OutputY, OutputWidth, OutputBleed, OutputLastY;
// 32bpp/24bpp DIB section
BYTE* BufStart;
ARGB* Buf32bpp;
ARGB* CurBuffer;
struct {
BITMAPINFO BMI;
RGBQUAD rgbQuad[4];
} Buf;
// Transparency mask
BYTE* MaskStart;
INT MaskStride; // # of bytes in one stride
struct {
BITMAPINFO BMI;
RGBQUAD rgbQuad[4];
} Mask;
// pointer to 32bpp scanline which we halftone FROM into the 1bpp mask above
ARGB* AlphaStart;
// array for keeping count for zeroing out scans of capped image
BYTE* ZeroStart;
NEXTBUFFERFUNCTION NextBuffer;
DWORD ScanOptions;
BOOL RenderAlpha;
BOOL Rasterizing;
// padding of pixels that we don't zeroout.
INT ZeroOutPad;
private:
// output at capped dpi at 32bpp
VOID *NextBufferFunc32bpp(
INT x,
INT y,
INT newWidth,
INT updateWidth,
INT blenderNum
);
// output at capped dpi at 32bpp
VOID *NextBufferFunc32bppOver(
INT x,
INT y,
INT newWidth,
INT updateWidth,
INT blenderNum
);
// output at capped dpi at 24bpp
VOID *NextBufferFunc24bpp(
INT x,
INT y,
INT newWidth,
INT updateWidth,
INT blenderNum
);
// output at capped dpi at 24bpp
VOID *NextBufferFunc24bppBleed(
INT x,
INT y,
INT newWidth,
INT updateWidth,
INT blenderNum
);
// output at capped dpi at 24bpp, does implicit alpha blend on white
// surface
VOID *NextBufferFunc24bppOver(
INT x,
INT y,
INT newWidth,
INT updateWidth,
INT blenderNum
);
// output alpha mask at device dpi at 1bpp
VOID *NextBufferFuncAlpha(
INT x,
INT y,
INT newWidth,
INT updateWidth,
INT blenderNum
);
// output opaque mask at device dpi at 1bpp
VOID *NextBufferFuncOpaque(
INT x,
INT y,
INT newWidth,
INT updateWidth,
INT blenderNum
);
// doesn't output a mask, but zero's out clipped portions of 24bpp DIB
VOID *NextBufferFuncZeroOut(
INT x,
INT y,
INT newWidth,
INT updateWidth,
INT blenderNum
);
public:
EpScanDIB();
~EpScanDIB() {}
virtual BOOL Start(
DpDriver *driver,
DpContext *context,
DpBitmap *surface,
NEXTBUFFERFUNCTION *nextBuffer,
EpScanType scanType,
PixelFormatID pixFmtGeneral,
PixelFormatID pixFmtOpaque,
ARGB solidColor
);
VOID End(INT updateWidth);
VOID Flush();
// ARGB buffer
BYTE *GetStartBuffer()
{
return BufStart;
}
BITMAPINFO *GetBufferBITMAPINFO()
{
return &Buf.BMI;
}
DWORD GetBufferStride()
{
return CappedStride;
}
// Mask Buffer
BYTE *GetMaskBuffer()
{
return MaskStart;
}
DWORD GetMaskStride()
{
return MaskStride;
}
BITMAPINFO *GetMaskBITMAPINFO()
{
return &Mask.BMI;
}
VOID *GetCurrentBuffer()
{
return CurBuffer;
}
virtual BYTE* GetCurrentCTBuffer()
{
// Since this class is meant for printers, higher-level
// code should prevent us from getting here.
// GpGraphics::GetTextRenderingHintInternal() guards against this.
ASSERT(FALSE);
return NULL;
}
DWORD GetOptions()
{
return ScanOptions;
}
BOOL GetActualBounds(GpRect *rect);
VOID SetRenderMode(BOOL RenderAlpha, GpRect* newBounds);
// Allocate DIB and monochrome DIB memory
GpStatus CreateBufferDIB(const GpRect* boundsCap,
const GpRect* boundsDev,
DWORD scanDIBOptions,
INT scaleX,
INT scaleY);
VOID DestroyBufferDIB();
INT GetZeroOutPad()
{
return ZeroOutPad;
}
VOID SetZeroOutPad(INT pad)
{
ASSERT(pad >= 0);
ZeroOutPad = pad;
}
VOID ResetZeroOutPad()
{
ZeroOutPad = 2;
}
#if 0
// create 1bpp monochrome mask of DIB
GpStatus CreateAlphaMask();
// create simple opaque monochrome mask of DIB (alpha>0 => opaque)
GpStatus CreateOpaqueMask(); // not used
#endif
};
#endif