mirror of https://github.com/lianthony/NT4.0
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.
2329 lines
52 KiB
2329 lines
52 KiB
/*++
|
|
|
|
Copyright (c) 1990-1991 Microsoft Corporation
|
|
|
|
|
|
Module Name:
|
|
|
|
htsetbmp.c
|
|
|
|
|
|
Abstract:
|
|
|
|
This module is used to provide set of functions to set the bits into the
|
|
final destination bitmap, the input to these function are data structures
|
|
(PRIMMONO_COUNT, PRIMCOLOR_COUNT and other pre-calculated data values).
|
|
|
|
|
|
Author:
|
|
28-Mar-1992 Sat 20:59:29 updated -by- Daniel Chou (danielc)
|
|
Add Support for VGA16, and also make output only 1 destinaiton pointer
|
|
for 3 planer.
|
|
|
|
|
|
03-Apr-1991 Wed 10:28:50 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
[Environment:]
|
|
|
|
Printer Driver.
|
|
|
|
|
|
[Notes:]
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
|
|
--*/
|
|
|
|
|
|
|
|
#define HAS_80x86_EQUIVALENT_CODES
|
|
|
|
|
|
#include "htp.h"
|
|
#include "htmapclr.h"
|
|
#include "htrender.h"
|
|
#include "htpat.h"
|
|
|
|
#include "htdebug.h"
|
|
#include "htsetbmp.h"
|
|
|
|
|
|
#ifndef HT_OK_GEN_80x86_CODES
|
|
|
|
|
|
#define MASK_PDEST(pD,m,d) *(pD)=(BYTE)((*(pD)&(m)) | (d))
|
|
#define MASK_PDEST_INC(pD,m,d) *((pD)++)=(BYTE)((*(pD)&(m))| (d))
|
|
|
|
#define MASKDEST_PDEST(pD,md,x) MASK_PDEST(pD,md.b[0],md.b[x])
|
|
#define MASKDEST_PDEST_INC(pD,md,x) MASK_PDEST_INC(pD,md.b[0],md.b[x])
|
|
|
|
|
|
BYTE VGA16ColorIndex[] = {
|
|
|
|
0x00, 0x77, 0x77, 0x88, 0x88, 0xff, // MONO
|
|
|
|
0x00, 0x00, 0x00, 0x11, 0x33, 0x77, // RY 0
|
|
0x00, 0x00, 0x11, 0x33, 0x77, 0x88, // RY 6
|
|
0x00, 0x00, 0x11, 0x33, 0x88, 0xff, // RY 18
|
|
|
|
0x00, 0x11, 0x33, 0x99, 0xbb, 0x77, // RY 24
|
|
0x11, 0x33, 0x99, 0xbb, 0x77, 0x88, // RY 30
|
|
0x11, 0x33, 0x99, 0xbb, 0x88, 0xff, // RY 36
|
|
|
|
0x00, 0x00, 0x00, 0x11, 0x55, 0x77, // RM 42
|
|
0x00, 0x00, 0x11, 0x55, 0x77, 0x88, // RM 48
|
|
0x00, 0x00, 0x11, 0x55, 0x88, 0xff, // RM 54
|
|
|
|
0x00, 0x11, 0x55, 0x99, 0xdd, 0x77, // RM 60
|
|
0x11, 0x55, 0x99, 0xdd, 0x77, 0x88, // RM 66
|
|
0x11, 0x55, 0x99, 0xdd, 0x88, 0xff, // RM 72
|
|
|
|
0x00, 0x00, 0x00, 0x22, 0x33, 0x77, // GY 78
|
|
0x00, 0x00, 0x22, 0x33, 0x77, 0x88, // GY 84
|
|
0x00, 0x00, 0x22, 0x33, 0x88, 0xff, // GY 90
|
|
|
|
0x00, 0x22, 0x33, 0xaa, 0xbb, 0x77, // GY 96
|
|
0x22, 0x33, 0xaa, 0xbb, 0x77, 0x88, // GY 102
|
|
0x22, 0x33, 0xaa, 0xbb, 0x88, 0xff, // GY 108
|
|
|
|
0x00, 0x00, 0x00, 0x22, 0x66, 0x77, // GC 114
|
|
0x00, 0x00, 0x22, 0x66, 0x77, 0x88, // GC 120
|
|
0x00, 0x00, 0x22, 0x66, 0x88, 0xff, // GC 126
|
|
|
|
0x00, 0x22, 0x66, 0xaa, 0xee, 0x77, // GC 132
|
|
0x22, 0x66, 0xaa, 0xee, 0x77, 0x88, // GC 138
|
|
0x22, 0x66, 0xaa, 0xee, 0x88, 0xff, // GC 144
|
|
|
|
0x00, 0x00, 0x00, 0x44, 0x55, 0x77, // BM 150
|
|
0x00, 0x00, 0x44, 0x55, 0x77, 0x88, // BM 156
|
|
0x00, 0x00, 0x44, 0x55, 0x88, 0xff, // BM
|
|
|
|
0x00, 0x44, 0x55, 0xcc, 0xdd, 0x77, // BM 162
|
|
0x44, 0x55, 0xcc, 0xdd, 0x77, 0x88, // BM 168
|
|
0x44, 0x55, 0xcc, 0xdd, 0x88, 0xff, // BM 174
|
|
|
|
0x00, 0x00, 0x00, 0x44, 0x66, 0x77, // BC 180
|
|
0x00, 0x00, 0x44, 0x66, 0x77, 0x88, // BC 186
|
|
0x00, 0x00, 0x44, 0x66, 0x88, 0xff, // BC 192
|
|
|
|
0x00, 0x44, 0x66, 0xcc, 0xee, 0x77, // BC 198
|
|
0x44, 0x66, 0xcc, 0xee, 0x77, 0x88, // BC 204
|
|
0x44, 0x66, 0xcc, 0xee, 0x88, 0xff // BC 210
|
|
};
|
|
|
|
|
|
#define VGA16_CLR_END_INDEX(pc) pc.Prim1
|
|
#define VGA16_CLR_1(pc) pc.Prim2
|
|
#define VGA16_CLR_2(pc) pc.Prim3
|
|
#define VGA16_CLR_3(pc) pc.Prim4
|
|
#define VGA16_CLR_4(pc) pc.w2b.bPrim[0]
|
|
#define VGA16_CLR_5(pc) pc.w2b.bPrim[1]
|
|
|
|
|
|
#define GET_VGA16_CLR_IDX(Index, PrimColor, Pattern) \
|
|
{ \
|
|
\
|
|
Index = (UINT)VGA16_CLR_END_INDEX(PrimColor); \
|
|
\
|
|
if (VGA16_CLR_3(PrimColor) < Pattern) { \
|
|
\
|
|
if (VGA16_CLR_4(PrimColor) < Pattern) { \
|
|
\
|
|
Index -= 4; \
|
|
\
|
|
if (VGA16_CLR_5(PrimColor) < Pattern) { \
|
|
\
|
|
--Index; \
|
|
} \
|
|
\
|
|
} else { \
|
|
\
|
|
Index -= 3; \
|
|
} \
|
|
\
|
|
} else { \
|
|
\
|
|
if (VGA16_CLR_1(PrimColor) < Pattern) { \
|
|
\
|
|
Index -= (VGA16_CLR_2(PrimColor) < Pattern) ? 2 : 1; \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
|
|
#define MASK_INDEX(c,p,m) (((UINT)(p) - (UINT)(c)) & (UINT)(m))
|
|
|
|
#define VGA256_R_IDX(PC,p) MASK_INDEX(PC.Prim3,p,VGA256_R_CUBE_INC << 8)
|
|
#define VGA256_G_IDX(PC,p) MASK_INDEX(PC.Prim2,p,VGA256_G_CUBE_INC << 8)
|
|
#define VGA256_B_IDX(PC,p) MASK_INDEX(PC.Prim1,p,VGA256_B_CUBE_INC << 8)
|
|
#define VGA256_RGB_IDX(PC,p) ((VGA256_R_IDX(PC,p) + VGA256_G_IDX(PC,p) + \
|
|
VGA256_B_IDX(PC,p)) >> 8)
|
|
|
|
#define RGB555_R_IDX(PC,p) MASK_INDEX(PC.Prim1,p,RGB555_R_CUBE_INC )
|
|
#define RGB555_G_IDX(PC,p) MASK_INDEX(PC.Prim2,p,RGB555_G_CUBE_INC << 8)
|
|
#define RGB555_B_IDX(PC,p) MASK_INDEX(PC.Prim3,p,RGB555_B_CUBE_INC << 8)
|
|
#define RGB555_RGB_IDX(PC,p) (RGB555_R_IDX(PC,p) + \
|
|
((RGB555_G_IDX(PC,p)+RGB555_B_IDX(PC,p))>>8))
|
|
|
|
#define SET_VGA256_PAT(p) (UINT)((p) - 1)
|
|
#define SET_RGB555_PAT(p) (UINT)((p) - 1)
|
|
#define GET_VGA256_INDEX(PC,p) (BYTE)(VGA256_RGB_IDX(PC,p) + PC.Prim4)
|
|
#define GET_RGB555_INDEX(PC,p) (WORD)(RGB555_RGB_IDX(PC,p) + PC.w2b.wPrim)
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
SingleCountOutputTo1BPP(
|
|
PPRIMMONO_COUNT pPrimMonoCount,
|
|
LPBYTE pDest,
|
|
LPBYTE pPattern,
|
|
OUTFUNCINFO OutFuncInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_1BPP destination surface from
|
|
PRIMMONO_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimMonoCount - Pointer to the PRIMMONO_COUNT data structure array.
|
|
|
|
pDest - Pointer to first modified destination byte
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LPBYTE pCurPat;
|
|
LPBYTE pEndPat;
|
|
PRIMMONO PM;
|
|
W2B MaskDest;
|
|
UINT SkipCount;
|
|
|
|
|
|
//
|
|
// The PatWidthBytes must multiple of 8
|
|
//
|
|
|
|
pEndPat = pCurPat = (pPattern + OutFuncInfo.PatWidthBytes); // goto end
|
|
|
|
MaskDest.w = 0;
|
|
|
|
if (SkipCount = (UINT)(pPrimMonoCount++)->Count) {
|
|
|
|
MaskDest.b[0] = (BYTE)~(0xff << SkipCount);
|
|
pCurPat -= SkipCount;
|
|
}
|
|
|
|
SkipCount = 8 - SkipCount;
|
|
|
|
|
|
while (TRUE) {
|
|
|
|
while (SkipCount--) {
|
|
|
|
MaskDest.w <<= 1;
|
|
PM = (pPrimMonoCount++)->Mono;
|
|
|
|
if (PM.Prim1 >= *(--pCurPat)) {
|
|
|
|
if (PM.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
if (PM.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
WORD LastCount;
|
|
|
|
if (LastCount = ((--pPrimMonoCount)->Count)) {
|
|
|
|
//
|
|
// We already shift once
|
|
//
|
|
|
|
MaskDest.w <<= (LastCount - 1);
|
|
|
|
if ((MaskDest.b[0] |= (BYTE)~(0xff << LastCount))
|
|
!= (BYTE)0xff) {
|
|
|
|
MASKDEST_PDEST(pDest, MaskDest, 1);
|
|
}
|
|
}
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
++MaskDest.b[0];
|
|
}
|
|
|
|
} else {
|
|
|
|
++MaskDest.b[1];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (MaskDest.b[0]) {
|
|
|
|
if (MaskDest.b[0] == (BYTE)0xff) {
|
|
|
|
++pDest;
|
|
|
|
} else {
|
|
|
|
MASK_PDEST_INC(pDest, MaskDest.b[0], MaskDest.b[1]);
|
|
}
|
|
|
|
} else {
|
|
|
|
*pDest++ = MaskDest.b[1];
|
|
}
|
|
|
|
MaskDest.w = 0;
|
|
SkipCount = 8;
|
|
|
|
if (pCurPat <= pPattern) {
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
VarCountOutputTo1BPP(
|
|
PPRIMMONO_COUNT pPrimMonoCount,
|
|
LPBYTE pDest,
|
|
LPBYTE pPattern,
|
|
OUTFUNCINFO OutFuncInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_1BPP destination surface from
|
|
PRIMMONO_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimMonoCount - Pointer to the PRIMMONO_COUNT data structure array.
|
|
|
|
pDest - Pointer to first modified destination byte
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LPBYTE pCurPat;
|
|
LPBYTE pEndPat;
|
|
PRIMMONO_COUNT PMC;
|
|
W2B MaskDest;
|
|
UINT SkipCount;
|
|
|
|
|
|
//
|
|
// The PatWidthBytes must multiple of 8
|
|
//
|
|
|
|
pEndPat = pCurPat = (pPattern + OutFuncInfo.PatWidthBytes); // goto end
|
|
|
|
PMC = *pPrimMonoCount++;
|
|
++PMC.Count;
|
|
|
|
while (TRUE) { // do until we return;
|
|
|
|
MaskDest.w = 0; // clear destination/mask
|
|
|
|
if (pCurPat <= pPattern) { // wrap around first, if so
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
|
|
if ((PMC.Count > 1) && // the count is not reduced yet!!
|
|
(PMC.Mono.Prim1 == PRIM_INVALID_DENSITY)) {
|
|
|
|
SkipCount = PMC.Count - 1;
|
|
PMC.Count = 1; // next one load
|
|
|
|
while (SkipCount >= 8) {
|
|
|
|
SkipCount -= 8; // skip 8 count
|
|
++pDest; // skip one destination
|
|
|
|
if ((pCurPat -= 8) <= pPattern) { // lazy way!!
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
}
|
|
|
|
if (SkipCount) {
|
|
|
|
MaskDest.b[0] = (BYTE)~(0xff << SkipCount);
|
|
pCurPat -= SkipCount;
|
|
SkipCount = (UINT)(8 - SkipCount);
|
|
|
|
} else {
|
|
|
|
SkipCount = 8; // exactly byte skip
|
|
}
|
|
|
|
} else {
|
|
|
|
SkipCount = 8;
|
|
}
|
|
|
|
while (SkipCount--) {
|
|
|
|
if (!(--PMC.Count)) {
|
|
|
|
PMC = *pPrimMonoCount++;
|
|
}
|
|
|
|
MaskDest.w <<= 1;
|
|
|
|
if (PMC.Mono.Prim1 >= *(--pCurPat)) {
|
|
|
|
if (PMC.Mono.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
if (PMC.Mono.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
WORD LastCount;
|
|
|
|
if (LastCount = ((--pPrimMonoCount)->Count)) {
|
|
|
|
//
|
|
// We already shift once
|
|
//
|
|
|
|
MaskDest.w <<= (LastCount - 1);
|
|
|
|
if ((MaskDest.b[0] |= (BYTE)~(0xff << LastCount))
|
|
!= (BYTE)0xff) {
|
|
|
|
MASKDEST_PDEST(pDest, MaskDest, 1);
|
|
}
|
|
}
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
++MaskDest.b[0];
|
|
}
|
|
|
|
} else {
|
|
|
|
++MaskDest.b[1];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (MaskDest.b[0]) {
|
|
|
|
if (MaskDest.b[0] == (BYTE)0xff) {
|
|
|
|
++pDest;
|
|
|
|
} else {
|
|
|
|
MASK_PDEST_INC(pDest, MaskDest.b[0], MaskDest.b[1]);
|
|
}
|
|
|
|
} else {
|
|
|
|
*pDest++ = MaskDest.b[1];
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
SingleCountOutputTo3Planes(
|
|
PPRIMCOLOR_COUNT pPrimColorCount,
|
|
LPBYTE pDest,
|
|
LPBYTE pPattern,
|
|
OUTFUNCINFO OutFuncInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_1BPP_3PLANES destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
pDest - Pointer to the first plane of the destination, the
|
|
size in bytes of each plane is indicate in OUTFUNCINFO
|
|
data structure, the pPlane1/2/3 are only offset different.
|
|
|
|
The bit location relationship with PRIMCOLOR is
|
|
|
|
Prim1 -> pPlane3 <---- Highest bit
|
|
Prim2 -> pPlane2
|
|
Prim3 -> pPlane1 <---- Lowest bit
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LPBYTE pCurPat;
|
|
LPBYTE pEndPat;
|
|
LPBYTE pPlane1;
|
|
LPBYTE pPlane2;
|
|
LPBYTE pPlane3;
|
|
PRIMCOLOR PC;
|
|
DW2W4B MaskDest;
|
|
UINT SkipCount;
|
|
BYTE PatternByte;
|
|
|
|
|
|
//
|
|
// The PatWidthBytes must multiple of 8
|
|
//
|
|
|
|
pPlane3 = (pPlane2 = (pPlane1 = pDest) +
|
|
OutFuncInfo.BytesPerPlane) +
|
|
OutFuncInfo.BytesPerPlane;
|
|
|
|
pEndPat = pCurPat = (pPattern + OutFuncInfo.PatWidthBytes); // goto end
|
|
|
|
MaskDest.dw = (DWORD)0;
|
|
|
|
if (SkipCount = (UINT)(pPrimColorCount++)->Count) {
|
|
|
|
MaskDest.b[0] = (BYTE)~(0xff << SkipCount);
|
|
pCurPat -= SkipCount;
|
|
}
|
|
|
|
SkipCount = 8 - SkipCount;
|
|
|
|
while (TRUE) {
|
|
|
|
while (SkipCount--) {
|
|
|
|
MaskDest.dw <<= 1;
|
|
PC = (pPrimColorCount++)->Color;
|
|
|
|
if (PC.Prim1 >= (PatternByte = *(--pCurPat))) {
|
|
|
|
if (PC.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
if (PC.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
WORD LastCount;
|
|
|
|
if (LastCount = ((--pPrimColorCount)->Count)) {
|
|
|
|
//
|
|
// We already shift once
|
|
//
|
|
|
|
MaskDest.dw <<= (LastCount - 1);
|
|
|
|
if ((MaskDest.b[0] |= (BYTE)~(0xff << LastCount))
|
|
!= (BYTE)0xff) {
|
|
|
|
MASKDEST_PDEST(pPlane1, MaskDest, 3);
|
|
MASKDEST_PDEST(pPlane2, MaskDest, 2);
|
|
MASKDEST_PDEST(pPlane3, MaskDest, 1);
|
|
}
|
|
}
|
|
|
|
return; // all done
|
|
|
|
} else {
|
|
|
|
++MaskDest.b[0]; // mask it
|
|
continue; // already masked
|
|
}
|
|
|
|
} else {
|
|
|
|
++MaskDest.b[1];
|
|
}
|
|
}
|
|
|
|
if (PC.Prim2 >= PatternByte) {
|
|
|
|
++MaskDest.b[2];
|
|
}
|
|
|
|
if (PC.Prim3 >= PatternByte) {
|
|
|
|
++MaskDest.b[3];
|
|
}
|
|
}
|
|
|
|
if (MaskDest.b[0]) {
|
|
|
|
if (MaskDest.b[0] != (BYTE)0xff) {
|
|
|
|
MASKDEST_PDEST_INC(pPlane1, MaskDest, 3);
|
|
MASKDEST_PDEST_INC(pPlane2, MaskDest, 2);
|
|
MASKDEST_PDEST_INC(pPlane3, MaskDest, 1);
|
|
|
|
} else {
|
|
|
|
++pPlane1;
|
|
++pPlane2;
|
|
++pPlane3;
|
|
}
|
|
|
|
} else {
|
|
|
|
*pPlane1++ = MaskDest.b[3];
|
|
*pPlane2++ = MaskDest.b[2];
|
|
*pPlane3++ = MaskDest.b[1];
|
|
}
|
|
|
|
MaskDest.dw = 0;
|
|
SkipCount = 8;
|
|
|
|
if (pCurPat <= pPattern) {
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
VarCountOutputTo3Planes(
|
|
PPRIMCOLOR_COUNT pPrimColorCount,
|
|
LPBYTE pDest,
|
|
LPBYTE pPattern,
|
|
OUTFUNCINFO OutFuncInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_1BPP_3PLANES destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
pDest - Pointer to the first plane of the destination, the
|
|
size in bytes of each plane is indicate in OUTFUNCINFO
|
|
data structure, the pPlane1/2/3 are only offset different.
|
|
|
|
The bit location relationship with PRIMCOLOR is
|
|
|
|
Prim1 -> pPlane3 <---- Highest bit
|
|
Prim2 -> pPlane2
|
|
Prim3 -> pPlane1 <---- Lowest bit
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LPBYTE pCurPat;
|
|
LPBYTE pEndPat;
|
|
LPBYTE pPlane1;
|
|
LPBYTE pPlane2;
|
|
LPBYTE pPlane3;
|
|
PRIMCOLOR_COUNT PCC;
|
|
DW2W4B MaskDest;
|
|
UINT SkipCount;
|
|
BYTE PatternByte;
|
|
|
|
|
|
|
|
//
|
|
// The PatWidthBytes must multiple of 8
|
|
//
|
|
|
|
pPlane3 = (pPlane2 = (pPlane1 = pDest) +
|
|
OutFuncInfo.BytesPerPlane) +
|
|
OutFuncInfo.BytesPerPlane;
|
|
|
|
pEndPat = pCurPat = (pPattern + OutFuncInfo.PatWidthBytes); // goto end
|
|
|
|
//
|
|
// First we set the PRIM_INVALID_DENSITY, so if count != 0, then we
|
|
// will skip the pel in the next while loop, also we add one to the
|
|
// Count, so Count = 1 if need to load next Prims, else it must be skipped
|
|
// Pels Count.
|
|
//
|
|
|
|
PCC.Color.Prim1 = PRIM_INVALID_DENSITY; // possible skipped
|
|
PCC.Count = (WORD)(*(LPWORD)&((pPrimColorCount++)->Count) + 1);
|
|
|
|
while (TRUE) { // do until we return
|
|
|
|
MaskDest.dw = 0; // clear destination/mask
|
|
|
|
if (pCurPat <= pPattern) { // wrap around first, if so
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
|
|
if ((PCC.Count > 1) && // the count is not reduced yet!!
|
|
(PCC.Color.Prim1 == PRIM_INVALID_DENSITY)) {
|
|
|
|
SkipCount = PCC.Count - 1;
|
|
PCC.Count = 0;
|
|
|
|
while (SkipCount >= 8) {
|
|
|
|
SkipCount -= 8; // skip 8 count
|
|
++PCC.Count; // how many bytes
|
|
|
|
if ((pCurPat -= 8) <= pPattern) { // lazy way!!
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
}
|
|
|
|
if (PCC.Count) { // if we do skipped
|
|
|
|
pPlane1 += PCC.Count; // skip Destination
|
|
pPlane2 += PCC.Count;
|
|
pPlane3 += PCC.Count;
|
|
}
|
|
|
|
if (SkipCount) {
|
|
|
|
MaskDest.b[0] = (BYTE)~(0xff << SkipCount);
|
|
pCurPat -= SkipCount;
|
|
SkipCount = (UINT)(8 - SkipCount);
|
|
|
|
} else {
|
|
|
|
SkipCount = 8; // exactly byte skip
|
|
}
|
|
|
|
PCC.Count = 1; // next one load
|
|
|
|
} else {
|
|
|
|
SkipCount = 8;
|
|
}
|
|
|
|
while (SkipCount--) {
|
|
|
|
if (!(--PCC.Count)) {
|
|
|
|
PCC = *pPrimColorCount++;
|
|
}
|
|
|
|
MaskDest.dw <<= 1;
|
|
|
|
if (PCC.Color.Prim1 >= (PatternByte = *(--pCurPat))) {
|
|
|
|
if (PCC.Color.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
if (PCC.Color.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
WORD LastCount;
|
|
|
|
if (LastCount = ((--pPrimColorCount)->Count)) {
|
|
|
|
//
|
|
// We already shift once
|
|
//
|
|
|
|
MaskDest.dw <<= (LastCount - 1);
|
|
|
|
if ((MaskDest.b[0] |= (BYTE)~(0xff << LastCount))
|
|
!= (BYTE)0xff) {
|
|
|
|
MASKDEST_PDEST(pPlane1, MaskDest, 3);
|
|
MASKDEST_PDEST(pPlane2, MaskDest, 2);
|
|
MASKDEST_PDEST(pPlane3, MaskDest, 1);
|
|
}
|
|
}
|
|
|
|
return; // all done
|
|
|
|
} else {
|
|
|
|
++MaskDest.b[0]; // mask it
|
|
continue; // already masked
|
|
}
|
|
|
|
} else {
|
|
|
|
++MaskDest.b[1];
|
|
}
|
|
}
|
|
|
|
if (PCC.Color.Prim2 >= PatternByte) {
|
|
|
|
++MaskDest.b[2];
|
|
}
|
|
|
|
if (PCC.Color.Prim3 >= PatternByte) {
|
|
|
|
++MaskDest.b[3];
|
|
}
|
|
}
|
|
|
|
if (MaskDest.b[0]) {
|
|
|
|
if (MaskDest.b[0] != (BYTE)0xff) {
|
|
|
|
MASKDEST_PDEST_INC(pPlane1, MaskDest, 3);
|
|
MASKDEST_PDEST_INC(pPlane2, MaskDest, 2);
|
|
MASKDEST_PDEST_INC(pPlane3, MaskDest, 1);
|
|
|
|
} else {
|
|
|
|
++pPlane1;
|
|
++pPlane2;
|
|
++pPlane3;
|
|
}
|
|
|
|
} else {
|
|
|
|
*pPlane1++ = MaskDest.b[3];
|
|
*pPlane2++ = MaskDest.b[2];
|
|
*pPlane3++ = MaskDest.b[1];
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
SingleCountOutputTo4BPP(
|
|
PPRIMCOLOR_COUNT pPrimColorCount,
|
|
LPBYTE pDest,
|
|
LPBYTE pPattern,
|
|
OUTFUNCINFO OutFuncInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_4BPP destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
pDest - Pointer to the destination planes pointers.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LPWORD pCurPat;
|
|
LPWORD pEndPat;
|
|
PRIMCOLOR PC;
|
|
W2B Pattern;
|
|
BYTE Dest;
|
|
|
|
|
|
//
|
|
// The PatWidthBytes must multiple of 8
|
|
//
|
|
|
|
pEndPat =
|
|
pCurPat = (LPWORD)(pPattern + OutFuncInfo.PatWidthBytes);
|
|
|
|
//
|
|
// Always load the first one
|
|
//
|
|
|
|
if ((pPrimColorCount++)->Count) {
|
|
|
|
PC.Prim1 = PRIM_INVALID_DENSITY;
|
|
PC.Prim2 = 0;
|
|
|
|
} else {
|
|
|
|
PC = (pPrimColorCount++)->Color;
|
|
}
|
|
|
|
while (TRUE) {
|
|
|
|
Pattern.w = *(--pCurPat);
|
|
|
|
if (pCurPat <= (LPWORD)pPattern) {
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
|
|
if (PC.Prim1 >= Pattern.b[1]) {
|
|
|
|
if (PC.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
if (PC.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
break; // EOF
|
|
}
|
|
|
|
PC = (pPrimColorCount++)->Color;
|
|
|
|
if (PC.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
if (PC.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
break; // EOF
|
|
}
|
|
|
|
++pDest;
|
|
PC = (pPrimColorCount++)->Color;
|
|
continue;
|
|
}
|
|
|
|
Dest = (BYTE)(*pDest & 0xf0);
|
|
|
|
} else {
|
|
|
|
Dest = (BYTE)(((PC.Prim2 >= Pattern.b[1]) ? 0x60 : 0x40) |
|
|
((PC.Prim3 >= Pattern.b[1]) ? 0x10 : 0x00));
|
|
|
|
PC = (pPrimColorCount++)->Color;
|
|
}
|
|
|
|
} else {
|
|
|
|
Dest = (BYTE)(((PC.Prim2 >= Pattern.b[1]) ? 0x20 : 0x00) |
|
|
((PC.Prim3 >= Pattern.b[1]) ? 0x10 : 0x00));
|
|
|
|
PC = (pPrimColorCount++)->Color;
|
|
}
|
|
|
|
|
|
if (PC.Prim1 >= Pattern.b[0]) {
|
|
|
|
if (PC.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
MASK_PDEST(pDest, 0x0f, Dest);
|
|
|
|
if (PC.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
break; // EOF
|
|
|
|
} else {
|
|
|
|
++pDest;
|
|
PC = (pPrimColorCount++)->Color;
|
|
continue;
|
|
}
|
|
|
|
} else {
|
|
|
|
Dest |= 0x04;
|
|
}
|
|
}
|
|
|
|
*pDest++ = (BYTE)(Dest |
|
|
((PC.Prim2 >= Pattern.b[0]) ? 0x02 : 0x00) |
|
|
((PC.Prim3 >= Pattern.b[0]) ? 0x01 : 0x00));
|
|
|
|
PC = (pPrimColorCount++)->Color;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
VarCountOutputTo4BPP(
|
|
PPRIMCOLOR_COUNT pPrimColorCount,
|
|
LPBYTE pDest,
|
|
LPBYTE pPattern,
|
|
OUTFUNCINFO OutFuncInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_4BPP destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
ppDest - Pointer to the destination planes pointers.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
LPWORD pCurPat;
|
|
LPWORD pEndPat;
|
|
PRIMCOLOR_COUNT PCC;
|
|
W2B Pattern;
|
|
UINT PatSkipWords;
|
|
UINT AvaiPatWords;
|
|
BYTE Dest;
|
|
|
|
|
|
|
|
//
|
|
// The PatWidthBytes must multiple of 8
|
|
//
|
|
|
|
pEndPat =
|
|
pCurPat = (LPWORD)pPattern + (OutFuncInfo.PatWidthBytes >>= 1);
|
|
|
|
if (PCC.Count = (UINT)((pPrimColorCount++)->Count)) {
|
|
|
|
PCC.Color.Prim1 = PRIM_INVALID_DENSITY;
|
|
PCC.Color.Prim2 = 0;
|
|
}
|
|
|
|
while (TRUE) {
|
|
|
|
Pattern.w = *(--pCurPat);
|
|
|
|
if (pCurPat <= (LPWORD)pPattern) {
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
|
|
if (!PCC.Count--) {
|
|
|
|
PCC = *pPrimColorCount++;
|
|
--PCC.Count;
|
|
}
|
|
|
|
if (PCC.Color.Prim1 >= Pattern.b[1]) {
|
|
|
|
if (PCC.Color.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
if (PCC.Color.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
break; // EOF
|
|
}
|
|
|
|
if (PCC.Count) {
|
|
|
|
pDest += (PatSkipWords = (UINT)(++PCC.Count >> 1));
|
|
AvaiPatWords = (UINT)(((LPBYTE)pCurPat -
|
|
(LPBYTE)pPattern) >> 1);
|
|
|
|
//
|
|
// The reason for --PatSkipWords is that current pattern
|
|
// word is part of the PCC.Count
|
|
//
|
|
|
|
if (--PatSkipWords >= AvaiPatWords) {
|
|
|
|
if ((PatSkipWords -= AvaiPatWords) >=
|
|
(UINT)OutFuncInfo.PatWidthBytes) {
|
|
|
|
PatSkipWords %= (UINT)OutFuncInfo.PatWidthBytes;
|
|
}
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
|
|
pCurPat -= PatSkipWords;
|
|
PCC.Count &= 0x01;
|
|
|
|
//
|
|
// PCC.Count = 1: we need to skip next left nibble
|
|
// PCC.Count = 0: we need to start from new byte (RELOAD)
|
|
//
|
|
|
|
continue;
|
|
}
|
|
|
|
Dest = (BYTE)(*pDest & 0xf0);
|
|
|
|
} else {
|
|
|
|
Dest = 0x40;
|
|
|
|
if (PCC.Color.Prim2 >= Pattern.b[1]) {
|
|
|
|
Dest |= 0x20;
|
|
}
|
|
|
|
if (PCC.Color.Prim3 >= Pattern.b[1]) {
|
|
|
|
Dest |= 0x10;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
Dest = 0x0;
|
|
|
|
if (PCC.Color.Prim2 >= Pattern.b[1]) {
|
|
|
|
Dest |= 0x20;
|
|
}
|
|
|
|
if (PCC.Color.Prim3 >= Pattern.b[1]) {
|
|
|
|
Dest |= 0x10;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Doing low nibble
|
|
//
|
|
|
|
if (!PCC.Count--) {
|
|
|
|
PCC = *pPrimColorCount++;
|
|
--PCC.Count;
|
|
}
|
|
|
|
if (PCC.Color.Prim1 >= Pattern.b[0]) {
|
|
|
|
if (PCC.Color.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
MASK_PDEST(pDest, 0x0f, Dest);
|
|
|
|
if (PCC.Color.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
break; // EOF
|
|
|
|
} else {
|
|
|
|
++pDest;
|
|
continue;
|
|
}
|
|
|
|
} else {
|
|
|
|
Dest |= 0x04;
|
|
}
|
|
}
|
|
|
|
if (PCC.Color.Prim2 >= Pattern.b[0]) {
|
|
|
|
Dest |= 0x02;
|
|
}
|
|
|
|
if (PCC.Color.Prim3 >= Pattern.b[0]) {
|
|
|
|
Dest |= 0x01;
|
|
}
|
|
|
|
*pDest++ = Dest;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
SingleCountOutputToVGA16(
|
|
PPRIMCOLOR_COUNT pPrimColorCount,
|
|
LPBYTE pDest,
|
|
LPBYTE pPattern,
|
|
OUTFUNCINFO OutFuncInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_4BPP destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
pDest - Pointer to the destination planes pointers.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LPWORD pCurPat;
|
|
LPWORD pEndPat;
|
|
PRIMCOLOR PC;
|
|
UINT Index;
|
|
W2B Pattern;
|
|
BYTE Dest;
|
|
|
|
|
|
//
|
|
// The PatWidthBytes must multiple of 8
|
|
//
|
|
|
|
pEndPat =
|
|
pCurPat = (LPWORD)(pPattern + OutFuncInfo.PatWidthBytes);
|
|
|
|
//
|
|
// Always load the first one
|
|
//
|
|
|
|
if ((pPrimColorCount++)->Count) {
|
|
|
|
PC.Prim1 = PRIM_INVALID_DENSITY;
|
|
PC.Prim2 = 0;
|
|
|
|
} else {
|
|
|
|
PC = (pPrimColorCount++)->Color;
|
|
}
|
|
|
|
while (TRUE) {
|
|
|
|
Pattern.w = *(--pCurPat);
|
|
|
|
if (pCurPat <= (LPWORD)pPattern) {
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
|
|
if (PC.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
if (PC.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
break; // EOF
|
|
}
|
|
|
|
PC = (pPrimColorCount++)->Color;
|
|
|
|
if (PC.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
if (PC.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
break; // EOF
|
|
}
|
|
|
|
++pDest;
|
|
|
|
PC = (pPrimColorCount++)->Color;
|
|
|
|
continue;
|
|
}
|
|
|
|
Dest = (BYTE)(*pDest & 0xf0);
|
|
|
|
} else {
|
|
|
|
GET_VGA16_CLR_IDX(Index, PC, Pattern.b[1]);
|
|
|
|
Dest = (BYTE)(VGA16ColorIndex[Index] & 0xf0);
|
|
PC = (pPrimColorCount++)->Color;
|
|
}
|
|
|
|
//
|
|
// Doing low nibble
|
|
//
|
|
|
|
if (PC.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
MASK_PDEST(pDest, 0x0f, Dest);
|
|
|
|
if (PC.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
break; // EOF
|
|
}
|
|
|
|
} else {
|
|
|
|
GET_VGA16_CLR_IDX(Index, PC, Pattern.b[0]);
|
|
|
|
*pDest = (BYTE)(Dest | (VGA16ColorIndex[Index] & 0x0f));
|
|
}
|
|
|
|
++pDest;
|
|
PC = (pPrimColorCount++)->Color;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
VarCountOutputToVGA16(
|
|
PPRIMCOLOR_COUNT pPrimColorCount,
|
|
LPBYTE pDest,
|
|
LPBYTE pPattern,
|
|
OUTFUNCINFO OutFuncInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_4BPP destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
ppDest - Pointer to the destination planes pointers.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
LPWORD pCurPat;
|
|
LPWORD pEndPat;
|
|
PRIMCOLOR_COUNT PCC;
|
|
W2B Pattern;
|
|
UINT Index;
|
|
UINT PatSkipWords;
|
|
UINT AvaiPatWords;
|
|
BYTE Dest;
|
|
|
|
|
|
//
|
|
// The PatWidthBytes must multiple of 8
|
|
//
|
|
|
|
pEndPat =
|
|
pCurPat = (LPWORD)pPattern + (OutFuncInfo.PatWidthBytes >>= 1);
|
|
|
|
if (PCC.Count = (UINT)((pPrimColorCount++)->Count)) {
|
|
|
|
PCC.Color.Prim1 = PRIM_INVALID_DENSITY;
|
|
PCC.Color.Prim2 = 0;
|
|
}
|
|
|
|
while (TRUE) {
|
|
|
|
Pattern.w = *(--pCurPat);
|
|
|
|
if (pCurPat <= (LPWORD)pPattern) {
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
|
|
if (!PCC.Count--) {
|
|
|
|
PCC = *pPrimColorCount++;
|
|
--PCC.Count;
|
|
}
|
|
|
|
if (PCC.Color.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
if (PCC.Color.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
break; // EOF
|
|
}
|
|
|
|
if (PCC.Count) {
|
|
|
|
pDest += (PatSkipWords = (UINT)(++PCC.Count >> 1));
|
|
AvaiPatWords = (UINT)(((LPBYTE)pCurPat -
|
|
(LPBYTE)pPattern) >> 1);
|
|
|
|
//
|
|
// The reason for --PatSkipWords is that current pattern
|
|
// word is part of the Count
|
|
//
|
|
|
|
if (--PatSkipWords >= AvaiPatWords) {
|
|
|
|
if ((PatSkipWords -= AvaiPatWords) >=
|
|
(UINT)OutFuncInfo.PatWidthBytes) {
|
|
|
|
PatSkipWords %= (UINT)OutFuncInfo.PatWidthBytes;
|
|
}
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
|
|
pCurPat -= PatSkipWords;
|
|
PCC.Count &= 0x01;
|
|
|
|
//
|
|
// PCC.Count = 1: we need to skip next left nibble
|
|
// PCC.Count = 0: we need to start from new byte (RELOAD)
|
|
//
|
|
|
|
continue;
|
|
|
|
|
|
} else {
|
|
|
|
Dest = (BYTE)(*pDest & 0xf0);
|
|
}
|
|
|
|
} else {
|
|
|
|
GET_VGA16_CLR_IDX(Index, PCC.Color, Pattern.b[1]);
|
|
|
|
Dest = (BYTE)(VGA16ColorIndex[Index] & 0xf0);
|
|
}
|
|
|
|
//
|
|
// Doing low nibble
|
|
//
|
|
|
|
if (!PCC.Count--) {
|
|
|
|
PCC = *pPrimColorCount++;
|
|
--PCC.Count;
|
|
}
|
|
|
|
if (PCC.Color.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
MASK_PDEST(pDest, 0x0f, Dest);
|
|
|
|
if (PCC.Color.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
break;
|
|
}
|
|
|
|
} else {
|
|
|
|
GET_VGA16_CLR_IDX(Index, PCC.Color, Pattern.b[0]);
|
|
|
|
*pDest = (BYTE)(Dest | (VGA16ColorIndex[Index] & 0x0f));
|
|
}
|
|
|
|
++pDest;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
SingleCountOutputToVGA256(
|
|
PPRIMCOLOR_COUNT pPrimColorCount,
|
|
LPBYTE pDest,
|
|
LPBYTE pPattern,
|
|
OUTFUNCINFO OutFuncInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_4BPP destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
pDest - Pointer to the destination planes pointers.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
01-Jun-1992 Mon 15:32:00 updated -by- Daniel Chou (danielc)
|
|
1. Fixed the first 'Dest = Prim1234.b[4]' to 'Dest = Prim1234.b[3]'
|
|
mistake.
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LPBYTE pCurPat;
|
|
LPBYTE pEndPat;
|
|
LPBYTE pXlate;
|
|
PRIMCOLOR PC;
|
|
UINT uiPat;
|
|
|
|
|
|
//
|
|
// The PatWidthBytes must multiple of 8
|
|
//
|
|
|
|
pEndPat =
|
|
pCurPat = (LPBYTE)(pPattern + OutFuncInfo.PatWidthBytes);
|
|
|
|
//
|
|
// Since we are in byte boundary, we should never get the first one is
|
|
// invalid
|
|
//
|
|
|
|
if (pXlate = (LPBYTE)OutFuncInfo.BytesPerPlane) {
|
|
|
|
while (TRUE) {
|
|
|
|
PC = (++pPrimColorCount)->Color;
|
|
|
|
if (PC.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
if (PC.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
break; // EOF
|
|
}
|
|
|
|
} else {
|
|
|
|
uiPat = SET_VGA256_PAT((UINT)*(--pCurPat));
|
|
*pDest = *(pXlate + GET_VGA256_INDEX(PC, uiPat));
|
|
}
|
|
|
|
++pDest;
|
|
|
|
if (pCurPat <= pPattern) {
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
while (TRUE) {
|
|
|
|
PC = (++pPrimColorCount)->Color;
|
|
|
|
if (PC.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
if (PC.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
break; // EOF
|
|
}
|
|
|
|
} else {
|
|
|
|
uiPat = SET_VGA256_PAT((UINT)*(--pCurPat));
|
|
*pDest = GET_VGA256_INDEX(PC, uiPat);
|
|
}
|
|
|
|
++pDest;
|
|
|
|
if (pCurPat <= pPattern) {
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
VarCountOutputToVGA256(
|
|
PPRIMCOLOR_COUNT pPrimColorCount,
|
|
LPBYTE pDest,
|
|
LPBYTE pPattern,
|
|
OUTFUNCINFO OutFuncInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_4BPP destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
ppDest - Pointer to the destination planes pointers.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
LPBYTE pCurPat;
|
|
LPBYTE pEndPat;
|
|
LPBYTE pXlate;
|
|
PRIMCOLOR_COUNT PCC;
|
|
UINT AvaiPat;
|
|
UINT uiPat;
|
|
|
|
|
|
//
|
|
// The PatWidthBytes must multiple of 8
|
|
//
|
|
|
|
pEndPat =
|
|
pCurPat = (LPBYTE)(pPattern + OutFuncInfo.PatWidthBytes);
|
|
|
|
//
|
|
// Since we are in byte boundary, we should never get the first one is
|
|
// invalid
|
|
//
|
|
|
|
if (pXlate = (LPBYTE)OutFuncInfo.BytesPerPlane) {
|
|
|
|
while (TRUE) {
|
|
|
|
PCC = *(++pPrimColorCount);
|
|
|
|
if (PCC.Color.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
if (PCC.Color.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
break; // EOF
|
|
}
|
|
|
|
pDest += PCC.Count; // advance destination
|
|
|
|
if (PCC.Count >= (AvaiPat = (UINT)(pCurPat - pPattern))) {
|
|
|
|
PCC.Count -= AvaiPat;
|
|
|
|
if (PCC.Count >= OutFuncInfo.PatWidthBytes) {
|
|
|
|
PCC.Count %= OutFuncInfo.PatWidthBytes; // WRAP it
|
|
}
|
|
|
|
pCurPat = pEndPat; // at end now
|
|
}
|
|
|
|
pCurPat -= PCC.Count;
|
|
|
|
} else {
|
|
|
|
while (PCC.Count--) {
|
|
|
|
uiPat = SET_VGA256_PAT((UINT)*(--pCurPat));
|
|
*pDest++ = *(pXlate + GET_VGA256_INDEX(PCC.Color, uiPat));
|
|
|
|
if (pCurPat <= pPattern) {
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
while (TRUE) {
|
|
|
|
PCC = *(++pPrimColorCount);
|
|
|
|
if (PCC.Color.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
if (PCC.Color.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
break; // EOF
|
|
}
|
|
|
|
pDest += PCC.Count; // advance destination
|
|
|
|
if (PCC.Count >= (AvaiPat = (UINT)(pCurPat - pPattern))) {
|
|
|
|
PCC.Count -= AvaiPat;
|
|
|
|
if (PCC.Count >= OutFuncInfo.PatWidthBytes) {
|
|
|
|
PCC.Count %= OutFuncInfo.PatWidthBytes; // WRAP it
|
|
}
|
|
|
|
pCurPat = pEndPat; // at end now
|
|
}
|
|
|
|
pCurPat -= PCC.Count;
|
|
|
|
} else {
|
|
|
|
while (PCC.Count--) {
|
|
|
|
uiPat = SET_VGA256_PAT((UINT)*(--pCurPat));
|
|
*pDest++ = GET_VGA256_INDEX(PCC.Color, uiPat);
|
|
|
|
if (pCurPat <= pPattern) {
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
SingleCountOutputTo16BPP_555(
|
|
PPRIMCOLOR_COUNT pPrimColorCount,
|
|
LPWORD pDest,
|
|
LPBYTE pPattern,
|
|
OUTFUNCINFO OutFuncInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_4BPP destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
pDest - Pointer to the destination planes pointers.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
01-Jun-1992 Mon 15:32:00 updated -by- Daniel Chou (danielc)
|
|
1. Fixed the first 'Dest = Prim1234.b[4]' to 'Dest = Prim1234.b[3]'
|
|
mistake.
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LPBYTE pCurPat;
|
|
LPBYTE pEndPat;
|
|
PRIMCOLOR PC;
|
|
UINT uiPat;
|
|
|
|
|
|
//
|
|
// The PatWidthBytes must multiple of 8
|
|
//
|
|
|
|
pEndPat =
|
|
pCurPat = (LPBYTE)(pPattern + OutFuncInfo.PatWidthBytes);
|
|
|
|
//
|
|
// Since we are in byte boundary, we should never get the first one is
|
|
// invalid
|
|
//
|
|
|
|
while (TRUE) {
|
|
|
|
PC = (++pPrimColorCount)->Color;
|
|
|
|
if (PC.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
if (PC.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
break; // EOF
|
|
}
|
|
|
|
} else {
|
|
|
|
uiPat = SET_RGB555_PAT((UINT)*(--pCurPat));
|
|
*pDest = GET_RGB555_INDEX(PC, uiPat);
|
|
}
|
|
|
|
++pDest;
|
|
|
|
if (pCurPat <= pPattern) {
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
VarCountOutputTo16BPP_555(
|
|
PPRIMCOLOR_COUNT pPrimColorCount,
|
|
LPWORD pDest,
|
|
LPBYTE pPattern,
|
|
OUTFUNCINFO OutFuncInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_4BPP destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
ppDest - Pointer to the destination planes pointers.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
LPBYTE pCurPat;
|
|
LPBYTE pEndPat;
|
|
PRIMCOLOR_COUNT PCC;
|
|
UINT AvaiPat;
|
|
UINT uiPat;
|
|
|
|
|
|
|
|
//
|
|
// The PatWidthBytes must multiple of 8
|
|
//
|
|
|
|
pEndPat =
|
|
pCurPat = (LPBYTE)(pPattern + OutFuncInfo.PatWidthBytes);
|
|
|
|
//
|
|
// Since we are in byte boundary, we should never get the first one is
|
|
// invalid
|
|
//
|
|
|
|
while (TRUE) {
|
|
|
|
PCC = *(++pPrimColorCount);
|
|
|
|
if (PCC.Color.Prim1 == PRIM_INVALID_DENSITY) {
|
|
|
|
if (PCC.Color.Prim2 == PRIM_INVALID_DENSITY) {
|
|
|
|
break; // EOF
|
|
}
|
|
|
|
pDest += PCC.Count; // advance destination
|
|
|
|
if (PCC.Count >= (AvaiPat = (UINT)(pCurPat - pPattern))) {
|
|
|
|
PCC.Count -= AvaiPat;
|
|
|
|
if (PCC.Count >= OutFuncInfo.PatWidthBytes) {
|
|
|
|
PCC.Count %= OutFuncInfo.PatWidthBytes; // WRAP it
|
|
}
|
|
|
|
pCurPat = pEndPat; // at end now
|
|
}
|
|
|
|
pCurPat -= PCC.Count;
|
|
|
|
} else {
|
|
|
|
while (PCC.Count--) {
|
|
|
|
uiPat = SET_RGB555_PAT((UINT)*(--pCurPat));
|
|
*pDest++ = GET_RGB555_INDEX(PCC.Color, uiPat);
|
|
|
|
if (pCurPat <= pPattern) {
|
|
|
|
pCurPat = pEndPat;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
HTENTRY
|
|
MakeHalftoneBrush(
|
|
LPBYTE pThresholds,
|
|
LPBYTE pOutputBuffer,
|
|
PRIMCOLOR_COUNT PCC,
|
|
HTBRUSHDATA HTBrushData
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is the alternate way to halftone a single color with width/height
|
|
equal to the HTCell.Widht/Height.
|
|
|
|
Arguments:
|
|
|
|
pThresholds - Pointer to a Halftone pattern threshold values array.
|
|
|
|
pOutputBuffer - Pointer to the output buffer
|
|
|
|
PC - PRIMCOLOR data structure
|
|
|
|
HTBrushData - HTBRUSHDATA data structure
|
|
|
|
Note: The returned brush always aligned at pattern origin (0,0)
|
|
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
22-Jan-1991 Tue 10:02:25 created -by- Daniel Chou (danielc)
|
|
|
|
13-Apr-1992 Mon 18:39:26 updated -by- Daniel Chou (danielc)
|
|
Rewrite to make it faster and correct the last bugs
|
|
the x86 assembly codes version also created
|
|
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
LPBYTE pbBuf;
|
|
LPBYTE pbBuf2;
|
|
LPBYTE pbBuf3;
|
|
LPWORD pwBuf;
|
|
UINT XLoop;
|
|
UINT uiDest;
|
|
INT LeftShifts;
|
|
DW2W4B dwDest;
|
|
BYTE Threshold;
|
|
BYTE bDest;
|
|
BYTE bMask;
|
|
|
|
|
|
pwBuf = (LPWORD)(pbBuf = pOutputBuffer);
|
|
|
|
switch (HTBrushData.SurfaceFormat) {
|
|
|
|
case BMF_1BPP_3PLANES:
|
|
|
|
while (HTBrushData.cyHTCell--) {
|
|
|
|
pbBuf = pOutputBuffer;
|
|
pbBuf2 = pbBuf + HTBrushData.SizePerPlane;
|
|
pbBuf3 = pbBuf2 + HTBrushData.SizePerPlane;
|
|
pOutputBuffer += HTBrushData.ScanLinePadBytes;
|
|
XLoop = (UINT)(HTBrushData.cxHTCell);
|
|
dwDest.dw = 0;
|
|
LeftShifts = 8;
|
|
|
|
while (XLoop--) {
|
|
|
|
dwDest.dw <<= 1;
|
|
|
|
if (PCC.Color.Prim1 >= (Threshold = *pThresholds++)) {
|
|
|
|
++dwDest.b[1];
|
|
}
|
|
|
|
if (PCC.Color.Prim2 >= Threshold) {
|
|
|
|
++dwDest.b[2];
|
|
}
|
|
|
|
if (PCC.Color.Prim3 >= Threshold) {
|
|
|
|
++dwDest.b[3];
|
|
}
|
|
|
|
if (!(--LeftShifts)) {
|
|
|
|
//
|
|
// The Plane3 is mapped from Prim1
|
|
// The Plane2 is mapped from Prim2
|
|
// The Plane1 is mapped from Prim3
|
|
//
|
|
|
|
*pbBuf++ = dwDest.b[3];
|
|
*pbBuf2++ = dwDest.b[2];
|
|
*pbBuf3++ = dwDest.b[1];
|
|
dwDest.dw = 0;
|
|
LeftShifts = 8;
|
|
}
|
|
}
|
|
|
|
if (LeftShifts < 8) {
|
|
|
|
dwDest.dw = (DWORD)(dwDest.dw << LeftShifts);
|
|
*pbBuf = dwDest.b[3];
|
|
*pbBuf2 = dwDest.b[2];
|
|
*pbBuf3 = dwDest.b[1];
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case BMF_1BPP:
|
|
|
|
while (HTBrushData.cyHTCell--) {
|
|
|
|
XLoop = (UINT)HTBrushData.cxHTCell;
|
|
bDest = 0x0;
|
|
bMask = 0x80;
|
|
|
|
while (XLoop--) {
|
|
|
|
if (PCC.Color.Prim1 >= *pThresholds++) {
|
|
|
|
bDest |= bMask;
|
|
}
|
|
|
|
if (!(bMask >>= 1)) {
|
|
|
|
*pbBuf++ = bDest;
|
|
bDest = 0x0;
|
|
bMask = 0x80;
|
|
}
|
|
}
|
|
|
|
if (bMask != 0x80) {
|
|
|
|
*pbBuf++ = bDest;
|
|
}
|
|
|
|
pbBuf += HTBrushData.ScanLinePadBytes;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case BMF_4BPP:
|
|
|
|
//
|
|
// Bit 2 = Prim1
|
|
// Bit 1 = Prim2
|
|
// Bit 0 = Prim3
|
|
//
|
|
|
|
while (HTBrushData.cyHTCell--) {
|
|
|
|
XLoop = (UINT)HTBrushData.cxHTCell;
|
|
|
|
while (XLoop) {
|
|
|
|
//
|
|
// Do High nibble first
|
|
//
|
|
|
|
if (PCC.Color.Prim1 >= (Threshold = *pThresholds++)) {
|
|
|
|
bDest = 0x40;
|
|
|
|
} else {
|
|
|
|
bDest = 0x00;
|
|
}
|
|
|
|
if (PCC.Color.Prim2 >= Threshold) {
|
|
|
|
bDest |= 0x20;
|
|
}
|
|
|
|
if (PCC.Color.Prim3 >= Threshold) {
|
|
|
|
bDest |= 0x10;
|
|
}
|
|
|
|
if (--XLoop) {
|
|
|
|
if (PCC.Color.Prim1 >= (Threshold = *pThresholds++)) {
|
|
|
|
bDest |= 0x04;
|
|
}
|
|
|
|
if (PCC.Color.Prim2 >= Threshold) {
|
|
|
|
bDest |= 0x02;
|
|
}
|
|
|
|
if (PCC.Color.Prim3 >= Threshold) {
|
|
|
|
bDest |= 0x01;
|
|
}
|
|
|
|
--XLoop;
|
|
}
|
|
|
|
*pbBuf++ = bDest;
|
|
}
|
|
|
|
pbBuf += HTBrushData.ScanLinePadBytes;
|
|
}
|
|
|
|
break;
|
|
|
|
case BMF_4BPP_VGA16:
|
|
|
|
while (HTBrushData.cyHTCell--) {
|
|
|
|
XLoop = (UINT)HTBrushData.cxHTCell;
|
|
|
|
while (XLoop) {
|
|
|
|
Threshold = *pThresholds++;
|
|
|
|
GET_VGA16_CLR_IDX(uiDest, PCC.Color, Threshold);
|
|
|
|
bDest = (BYTE)(VGA16ColorIndex[uiDest] & 0xf0);
|
|
|
|
if (--XLoop) {
|
|
|
|
Threshold = *pThresholds++;
|
|
|
|
GET_VGA16_CLR_IDX(uiDest, PCC.Color, Threshold);
|
|
|
|
bDest |= (BYTE)(VGA16ColorIndex[uiDest] & 0x0f);
|
|
|
|
--XLoop;
|
|
}
|
|
|
|
*pbBuf++ = bDest;
|
|
}
|
|
|
|
pbBuf += HTBrushData.ScanLinePadBytes;
|
|
}
|
|
|
|
break;
|
|
|
|
case BMF_8BPP_VGA256:
|
|
|
|
while (HTBrushData.cyHTCell--) {
|
|
|
|
XLoop = (UINT)HTBrushData.cxHTCell;
|
|
|
|
while (XLoop--) {
|
|
|
|
uiDest = SET_VGA256_PAT((UINT)*pThresholds++);
|
|
*pbBuf++ = GET_VGA256_INDEX(PCC.Color, uiDest);
|
|
}
|
|
|
|
pbBuf += HTBrushData.ScanLinePadBytes;
|
|
}
|
|
|
|
break;
|
|
|
|
case BMF_16BPP_555:
|
|
|
|
while (HTBrushData.cyHTCell--) {
|
|
|
|
XLoop = (UINT)HTBrushData.cxHTCell;
|
|
|
|
while (XLoop--) {
|
|
|
|
//
|
|
// PC.Prim1/Prim2/Prim3 = Composed 5:5:5 pattern index
|
|
// PC.w2b.wPrim = Initial color index
|
|
//
|
|
|
|
uiDest = SET_RGB555_PAT((UINT)*pThresholds++);
|
|
*pwBuf++ = GET_RGB555_INDEX(PCC.Color, uiDest);
|
|
}
|
|
|
|
(LPBYTE)pwBuf += HTBrushData.ScanLinePadBytes;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
#endif // if do not generate 80x86 codes
|