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.
1985 lines
45 KiB
1985 lines
45 KiB
|
|
/******************************Module*Header*******************************\
|
|
* Module Name: textxl.c
|
|
*
|
|
* Draw glyphs to 1Bpp temporary buffer. This is the portable version
|
|
* of the x86 code from the VGA driver.
|
|
*
|
|
*
|
|
* Copyright (c) 1994-1999 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#include "engine.h"
|
|
|
|
#if !defined (_X86_)
|
|
|
|
|
|
typedef VOID (*PFN_GLYPHLOOP)(LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
typedef VOID (*PFN_GLYPHLOOPN)(LONG,LONG,LONG,PUCHAR,PUCHAR,LONG,LONG);
|
|
|
|
PFN_GLYPHLOOP pfnGlyphLoop;
|
|
|
|
//
|
|
// debug routine
|
|
//
|
|
|
|
VOID
|
|
exit_fast_text(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// or_all_1_wide_rotated_need_last::
|
|
// or_all_1_wide_rotated_no_last::
|
|
// or_first_1_wide_rotated_need_last
|
|
// or_first_1_wide_rotated_no_last::
|
|
//
|
|
|
|
VOID
|
|
or_all_1_wide_rotated_need_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + cyGlyph;
|
|
UCHAR c;
|
|
|
|
do {
|
|
c = *pGlyph++;
|
|
*pBuffer |= c >> RightRot;
|
|
pBuffer += ulBufDelta;
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
//
|
|
// mov_first_1_wide_rotated_need_last::
|
|
// mov_first_1_wide_rotated_no_last::
|
|
//
|
|
|
|
VOID
|
|
mov_first_1_wide_rotated_need_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + cyGlyph;
|
|
UCHAR c;
|
|
|
|
do {
|
|
c = *pGlyph++;
|
|
*pBuffer = c >> RightRot;
|
|
pBuffer += ulBufDelta;
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
//
|
|
// mov_first_1_wide_unrotated::
|
|
//
|
|
|
|
VOID
|
|
mov_first_1_wide_unrotated(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + cyGlyph;
|
|
do {
|
|
*pBuffer = *pGlyph++;
|
|
pBuffer += ulBufDelta;
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
|
|
//
|
|
//or_all_1_wide_unrotated::
|
|
//or_all_1_wide_unrotated_loop::
|
|
//
|
|
|
|
VOID
|
|
or_all_1_wide_unrotated(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + cyGlyph;
|
|
do {
|
|
*pBuffer |= *pGlyph++;
|
|
pBuffer += ulBufDelta;
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
//
|
|
// or_first_2_wide_rotated_need_last::
|
|
//
|
|
|
|
VOID
|
|
or_first_2_wide_rotated_need_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + 2*cyGlyph;
|
|
ULONG rl = 8-RightRot;
|
|
UCHAR c0,c1;
|
|
|
|
do {
|
|
c0 = *pGlyph;
|
|
c1 = *(pGlyph+1);
|
|
pGlyph+=2;
|
|
*pBuffer |= c0 >> RightRot;
|
|
*(pBuffer+1) = (c1 >> RightRot) | (c0 << rl);
|
|
pBuffer += ulBufDelta;
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
//
|
|
//or_all_2_wide_rotated_need_last::
|
|
//
|
|
|
|
VOID
|
|
or_all_2_wide_rotated_need_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + 2*cyGlyph;
|
|
ULONG rl = 8-RightRot;
|
|
USHORT usTmp;
|
|
UCHAR c0,c1;
|
|
|
|
|
|
|
|
do {
|
|
usTmp = *(PUSHORT)pGlyph;
|
|
pGlyph += 2;
|
|
c0 = (UCHAR)usTmp;
|
|
c1 = (UCHAR)(usTmp >> 8);
|
|
*pBuffer |= (UCHAR)(c0 >> RightRot);
|
|
*(pBuffer+1) |= (UCHAR)((c1 >> RightRot) | (c0 << rl));
|
|
pBuffer += ulBufDelta;
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
//
|
|
// mov_first_2_wide_rotated_need_last::
|
|
//
|
|
|
|
VOID
|
|
mov_first_2_wide_rotated_need_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + 2*cyGlyph;
|
|
ULONG rl = 8-RightRot;
|
|
USHORT us;
|
|
UCHAR c0;
|
|
UCHAR c1;
|
|
|
|
do {
|
|
us = *(PUSHORT)pGlyph;
|
|
c0 = (us & 0xff);
|
|
c1 = us >> 8;
|
|
pGlyph += 2;
|
|
*pBuffer = c0 >> RightRot;
|
|
*(pBuffer+1) = (c1 >> RightRot) | (c0 << rl);
|
|
pBuffer += ulBufDelta;
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
//
|
|
// or_first_2_wide_rotated_no_last
|
|
//
|
|
|
|
VOID
|
|
or_first_2_wide_rotated_no_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + cyGlyph;
|
|
ULONG rl = 8-RightRot;
|
|
UCHAR c0;
|
|
|
|
do {
|
|
c0 = *pGlyph++;
|
|
*pBuffer |= c0 >> RightRot;
|
|
*(pBuffer+1) = (c0 << rl);
|
|
pBuffer += ulBufDelta;
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
|
|
//
|
|
//or_all_2_wide_rotated_no_last::
|
|
//
|
|
|
|
VOID
|
|
or_all_2_wide_rotated_no_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + cyGlyph;
|
|
ULONG rl = 8-RightRot;
|
|
UCHAR c;
|
|
|
|
do {
|
|
c = *pGlyph;
|
|
pGlyph ++;
|
|
*pBuffer |= (UCHAR)(c >> RightRot);
|
|
*(pBuffer+1) |= (UCHAR)(c << rl);
|
|
pBuffer += ulBufDelta;
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
//
|
|
// or_all_2_wide_unrotated::
|
|
//
|
|
|
|
VOID
|
|
or_all_2_wide_unrotated(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + 2*cyGlyph;
|
|
|
|
//
|
|
// aligned?
|
|
//
|
|
|
|
if ((ULONG_PTR)pBuffer & 0x01) {
|
|
|
|
//
|
|
// not aligned
|
|
//
|
|
|
|
USHORT usTmp;
|
|
UCHAR c1,c0;
|
|
|
|
do {
|
|
usTmp = *(PUSHORT)pGlyph;
|
|
pGlyph +=2;
|
|
*pBuffer |= (UCHAR)usTmp;
|
|
*(pBuffer+1) |= (UCHAR)(usTmp >> 8);
|
|
pBuffer += ulBufDelta;
|
|
} while (pGlyph != pjEnd);
|
|
|
|
} else {
|
|
|
|
//
|
|
// aligned
|
|
//
|
|
|
|
USHORT usTmp;
|
|
|
|
do {
|
|
usTmp = *(PUSHORT)pGlyph;
|
|
pGlyph +=2;
|
|
*(PUSHORT)pBuffer |= usTmp;
|
|
pBuffer += ulBufDelta;
|
|
} while (pGlyph != pjEnd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// mov_first_2_wide_unrotated::
|
|
//
|
|
|
|
VOID
|
|
mov_first_2_wide_unrotated(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + 2*cyGlyph;
|
|
USHORT us;
|
|
|
|
do {
|
|
us = *(PUSHORT)pGlyph;
|
|
pGlyph +=2;
|
|
*pBuffer = us & 0xff;
|
|
*(pBuffer+1) = (UCHAR)(us >> 8);
|
|
pBuffer += ulBufDelta;
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
//
|
|
// mov_first_2_wide_rotated_no_last::
|
|
//
|
|
|
|
VOID
|
|
mov_first_2_wide_rotated_no_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + cyGlyph;
|
|
ULONG rl = 8-RightRot;
|
|
UCHAR c0;
|
|
UCHAR c1;
|
|
|
|
do {
|
|
c0 = *pGlyph++;
|
|
*pBuffer = c0 >> RightRot;
|
|
*(pBuffer+1) = c0 << rl;
|
|
pBuffer += ulBufDelta;
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
//
|
|
// or_first_3_wide_rotated_need_last::
|
|
//
|
|
|
|
VOID
|
|
or_first_3_wide_rotated_need_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + 3*cyGlyph;
|
|
ULONG ul;
|
|
UCHAR c0,c1,c2;
|
|
|
|
do {
|
|
c0 = *pGlyph;
|
|
c1 = *(pGlyph+1);
|
|
c2 = *(pGlyph+2);
|
|
|
|
//
|
|
// make into big-endian ulong and shift
|
|
//
|
|
|
|
ul = (c0 << 16) | (c1 << 8) | c2;
|
|
ul >>= RightRot;
|
|
|
|
*pBuffer |= (BYTE)(ul >> 16);
|
|
*(pBuffer+1) = (BYTE)(ul >> 8);
|
|
*(pBuffer+2) = (BYTE)(ul);
|
|
|
|
pGlyph += 3;
|
|
pBuffer += ulBufDelta;
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
|
|
//
|
|
// or_all_3_wide_rotated_need_last::
|
|
//
|
|
|
|
VOID
|
|
or_all_3_wide_rotated_need_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + 3*cyGlyph;
|
|
ULONG ul;
|
|
UCHAR c0,c1,c2;
|
|
do {
|
|
c0 = *pGlyph;
|
|
c1 = *(pGlyph+1);
|
|
c2 = *(pGlyph+2);
|
|
|
|
//
|
|
// make into big-endian ulong and shift
|
|
//
|
|
|
|
ul = (c0 << 16) | (c1 << 8) | c2;
|
|
ul >>= RightRot;
|
|
|
|
*pBuffer |= (BYTE)(ul >> 16);
|
|
*(pBuffer+1) |= (BYTE)(ul >> 8);
|
|
*(pBuffer+2) |= (BYTE)(ul);
|
|
|
|
pGlyph += 3;
|
|
pBuffer += ulBufDelta;
|
|
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
//
|
|
// or_all_3_wide_rotated_no_last::
|
|
//
|
|
|
|
VOID
|
|
or_all_3_wide_rotated_no_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + 2*cyGlyph;
|
|
ULONG ul;
|
|
UCHAR c0,c1;
|
|
|
|
do {
|
|
|
|
c0 = *pGlyph;
|
|
c1 = *(pGlyph+1);
|
|
|
|
//
|
|
// make big-endian and shift
|
|
//
|
|
|
|
ul = (c0 << 16) | (c1 << 8);
|
|
ul >>= RightRot;
|
|
|
|
//
|
|
// store result
|
|
//
|
|
|
|
*pBuffer |= (BYTE)(ul >> 16);
|
|
*(pBuffer+1) |= (BYTE)(ul >> 8);
|
|
*(pBuffer+2) |= (BYTE)ul;
|
|
|
|
|
|
pGlyph += 2;
|
|
pBuffer += ulBufDelta;
|
|
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
//
|
|
// or_first_3_wide_rotated_no_last::
|
|
//
|
|
|
|
VOID
|
|
or_first_3_wide_rotated_no_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + 2*cyGlyph;
|
|
ULONG ul;
|
|
UCHAR c0,c1;
|
|
|
|
do {
|
|
|
|
c0 = *pGlyph;
|
|
c1 = *(pGlyph+1);
|
|
|
|
//
|
|
// make big-endian and shift
|
|
//
|
|
|
|
ul = (c0 << 16) | (c1 << 8);
|
|
ul >>= RightRot;
|
|
|
|
//
|
|
// store result, only or in first byte
|
|
//
|
|
|
|
*pBuffer |= (BYTE)(ul >> 16);
|
|
*(pBuffer+1) = (BYTE)(ul >> 8);
|
|
*(pBuffer+2) = (BYTE)ul;
|
|
|
|
|
|
pGlyph += 2;
|
|
pBuffer += ulBufDelta;
|
|
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
//
|
|
// mov_first_3_wide_unrotated::
|
|
//
|
|
|
|
VOID
|
|
mov_first_3_wide_unrotated(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + 3*cyGlyph;
|
|
ULONG rl = 8-RightRot;
|
|
UCHAR c0,c1,c2;
|
|
|
|
do {
|
|
|
|
c0 = *pGlyph;
|
|
c1 = *(pGlyph+1);
|
|
c2 = *(pGlyph+2);
|
|
|
|
*pBuffer = c0;
|
|
*(pBuffer+1) = c1;
|
|
*(pBuffer+2) = c2;
|
|
|
|
pGlyph += 3;
|
|
pBuffer += ulBufDelta;
|
|
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
|
|
//
|
|
//or_all_3_wide_unrotated::
|
|
//
|
|
|
|
VOID
|
|
or_all_3_wide_unrotated(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + 3*cyGlyph;
|
|
ULONG rl = 8-RightRot;
|
|
UCHAR c0,c1,c2;
|
|
|
|
do {
|
|
c0 = *pGlyph;
|
|
c1 = *(pGlyph+1);
|
|
c2 = *(pGlyph+2);
|
|
|
|
*pBuffer |= c0;
|
|
*(pBuffer+1) |= c1;
|
|
*(pBuffer+2) |= c2;
|
|
|
|
pBuffer += ulBufDelta;
|
|
pGlyph += 3;
|
|
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
//
|
|
// or_first_4_wide_rotated_need_last::
|
|
//
|
|
|
|
VOID
|
|
or_first_4_wide_rotated_need_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + 4*cyGlyph;
|
|
ULONG ul;
|
|
ULONG t0,t1,t2;
|
|
|
|
do {
|
|
|
|
ul = *(PULONG)pGlyph;
|
|
|
|
//
|
|
// endian swap
|
|
//
|
|
|
|
t0 = ul << 24;
|
|
t1 = ul >> 24;
|
|
t2 = (ul >> 8) & (0xff << 8);
|
|
ul = (ul << 8) & (0xff << 16);
|
|
|
|
ul = ul | t0 | t1 | t2;
|
|
|
|
ul >>= RightRot;
|
|
|
|
*pBuffer |= (BYTE)(ul >> 24);
|
|
|
|
*(pBuffer+1) = (BYTE)(ul >> 16);
|
|
|
|
*(pBuffer+2) = (BYTE)(ul >> 8);
|
|
|
|
*(pBuffer+3) = (BYTE)(ul);
|
|
|
|
pGlyph += 4;
|
|
pBuffer += ulBufDelta;
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
//
|
|
// or_all_4_wide_rotated_need_last::
|
|
//
|
|
|
|
VOID
|
|
or_all_4_wide_rotated_need_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + 4*cyGlyph;
|
|
ULONG ul;
|
|
ULONG t0,t1,t2;
|
|
|
|
do {
|
|
|
|
ul = *(PULONG)pGlyph;
|
|
|
|
//
|
|
// endian swap
|
|
//
|
|
|
|
t0 = ul << 24;
|
|
t1 = ul >> 24;
|
|
t2 = (ul >> 8) & (0xff << 8);
|
|
ul = (ul << 8) & (0xff << 16);
|
|
|
|
ul = ul | t0 | t1 | t2;
|
|
|
|
ul >>= RightRot;
|
|
|
|
*pBuffer |= (BYTE)(ul >> 24);
|
|
|
|
*(pBuffer+1) |= (BYTE)(ul >> 16);
|
|
|
|
*(pBuffer+2) |= (BYTE)(ul >> 8);
|
|
|
|
*(pBuffer+3) |= (BYTE)(ul);
|
|
|
|
pGlyph += 4;
|
|
pBuffer += ulBufDelta;
|
|
|
|
} while (pGlyph != pjEnd);
|
|
}
|
|
|
|
//
|
|
// or_first_4_wide_rotated_no_last::
|
|
//
|
|
|
|
VOID
|
|
or_first_4_wide_rotated_no_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PBYTE pjEnd = pGlyph + 3*cyGlyph;
|
|
BYTE c0,c1,c2;
|
|
ULONG ul;
|
|
|
|
|
|
while (pGlyph != pjEnd) {
|
|
|
|
//
|
|
// load src
|
|
//
|
|
|
|
c0 = *pGlyph;
|
|
c1 = *(pGlyph+1);
|
|
c2 = *(pGlyph+2);
|
|
|
|
//
|
|
// or into big endian ULONG and shift
|
|
//
|
|
|
|
ul = (c0 << 24) | (c1 << 16) | (c2 << 8);
|
|
ul >>= RightRot;
|
|
|
|
//
|
|
// store result, ony or in fisrt byte
|
|
//
|
|
|
|
*pBuffer |= (BYTE)(ul >> 24);
|
|
|
|
*(pBuffer+1) = (BYTE)(ul >> 16);;
|
|
|
|
*(pBuffer+2) = (BYTE)(ul >> 8);
|
|
|
|
*(pBuffer+3) = (BYTE)(ul);
|
|
|
|
//
|
|
// inc scan line
|
|
//
|
|
|
|
pGlyph += 3;
|
|
pBuffer += ulBufDelta;
|
|
}
|
|
}
|
|
|
|
//
|
|
// or_all_4_wide_rotated_no_last::
|
|
//
|
|
|
|
VOID
|
|
or_all_4_wide_rotated_no_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PBYTE pjEnd = pGlyph + 3*cyGlyph;
|
|
BYTE c0,c1,c2;
|
|
ULONG ul;
|
|
|
|
|
|
while (pGlyph != pjEnd) {
|
|
|
|
//
|
|
// load src
|
|
//
|
|
|
|
c0 = *pGlyph;
|
|
c1 = *(pGlyph+1);
|
|
c2 = *(pGlyph+2);
|
|
|
|
//
|
|
// or into big endian ULONG and shift
|
|
//
|
|
|
|
ul = (c0 << 24) | (c1 << 16) | (c2 << 8);
|
|
ul >>= RightRot;
|
|
|
|
//
|
|
// store result
|
|
//
|
|
|
|
*pBuffer |= (BYTE)(ul >> 24);
|
|
|
|
*(pBuffer+1) |= (BYTE)(ul >> 16);;
|
|
|
|
*(pBuffer+2) |= (BYTE)(ul >> 8);
|
|
|
|
*(pBuffer+3) |= (BYTE)(ul);
|
|
|
|
//
|
|
// inc scan line
|
|
//
|
|
|
|
pGlyph += 3;
|
|
pBuffer += ulBufDelta;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
mov_first_4_wide_unrotated(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + 4*cyGlyph;
|
|
|
|
switch ((ULONG_PTR)pBuffer & 0x03 ) {
|
|
case 0:
|
|
|
|
while (pGlyph != pjEnd) {
|
|
*(PULONG)pBuffer = *(PULONG)pGlyph;
|
|
pGlyph += 4;
|
|
pBuffer += ulBufDelta;
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
case 3:
|
|
while (pGlyph != pjEnd) {
|
|
|
|
*pBuffer = *pGlyph;
|
|
*(pBuffer+1) = *(pGlyph+1);
|
|
*(pBuffer+2) = *(pGlyph+2);
|
|
*(pBuffer+3) = *(pGlyph+3);
|
|
|
|
pGlyph += 4;
|
|
pBuffer += ulBufDelta;
|
|
}
|
|
break;
|
|
case 2:
|
|
while (pGlyph != pjEnd) {
|
|
|
|
*(PUSHORT)(pBuffer) = *(PUSHORT)pGlyph;
|
|
*(PUSHORT)(pBuffer+2) = *(PUSHORT)(pGlyph+2);
|
|
|
|
pBuffer += ulBufDelta;
|
|
pGlyph += 4;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// or_all_4_wide_unrotated::
|
|
//
|
|
|
|
VOID
|
|
or_all_4_wide_unrotated(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph
|
|
)
|
|
{
|
|
PUCHAR pjEnd = pGlyph + 4*cyGlyph;
|
|
|
|
switch ((ULONG_PTR)pBuffer & 0x03 ) {
|
|
case 0:
|
|
|
|
while (pGlyph != pjEnd) {
|
|
|
|
*(PULONG)pBuffer |= *(PULONG)pGlyph;
|
|
|
|
pGlyph += 4;
|
|
pBuffer += ulBufDelta;
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
case 3:
|
|
|
|
while (pGlyph != pjEnd) {
|
|
|
|
*pBuffer |= *pGlyph;
|
|
*(pBuffer+1) |= *(pGlyph+1);
|
|
*(pBuffer+2) |= *(pGlyph+2);
|
|
*(pBuffer+3) |= *(pGlyph+3);
|
|
|
|
pGlyph += 4;
|
|
pBuffer += ulBufDelta;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
|
|
while (pGlyph != pjEnd) {
|
|
|
|
*(PUSHORT)pBuffer |= *(PUSHORT)pGlyph;
|
|
*(PUSHORT)(pBuffer+2) |= *(PUSHORT)(pGlyph+2);
|
|
|
|
pGlyph += 4;
|
|
pBuffer += ulBufDelta;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* Routine Name
|
|
*
|
|
* or_first_N_wide_rotated_need_last
|
|
*
|
|
*
|
|
* Routine Description:
|
|
*
|
|
* Draw arbitrarily wide glyphs to 1BPP temp buffer
|
|
*
|
|
*
|
|
* Arguments:
|
|
*
|
|
* cyGlyph - glyph height
|
|
* RightRot - alignment
|
|
* ulBufDelta - scan line stride of temp buffer
|
|
* pGlyph - pointer to glyph bitmap
|
|
* pBuffer - pointer to temp buffer
|
|
* cxGlyph - glyph width in pixels
|
|
* cxDst - Dest width in bytes
|
|
*
|
|
* Return Value:
|
|
*
|
|
* None
|
|
*
|
|
\**************************************************************************/
|
|
VOID
|
|
or_first_N_wide_rotated_need_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph,
|
|
LONG cxDst
|
|
)
|
|
{
|
|
PUCHAR pjDst = (PUCHAR)pBuffer;
|
|
PUCHAR pjDstEnd;
|
|
PUCHAR pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
|
|
LONG lStride = ulBufDelta - cxDst;
|
|
LONG rl = 8-RightRot;
|
|
|
|
//
|
|
// source doesn't advance after first byte, and
|
|
// we do the first byte outside the loop
|
|
//
|
|
|
|
do {
|
|
|
|
UCHAR c0 = *pGlyph++;
|
|
UCHAR c1;
|
|
pjDstEnd = pjDst + cxDst;
|
|
|
|
*pjDst |= c0 >> RightRot;
|
|
pjDst++;
|
|
c1 = c0 << rl;
|
|
|
|
//
|
|
// know cxDst is at least 4, use do-while
|
|
//
|
|
|
|
do {
|
|
c0 = *pGlyph;
|
|
*pjDst = (c0 >> RightRot) | c1;
|
|
c1 = c0 << rl;
|
|
pjDst++;
|
|
pGlyph++;
|
|
|
|
} while (pjDst != pjDstEnd);
|
|
|
|
pjDst += lStride;
|
|
|
|
} while (pjDst != pjDstEndy);
|
|
}
|
|
|
|
VOID
|
|
or_all_N_wide_rotated_need_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph,
|
|
LONG cxDst
|
|
)
|
|
{
|
|
PUCHAR pjDst = (PUCHAR)pBuffer;
|
|
PUCHAR pjDstEnd;
|
|
PUCHAR pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
|
|
LONG lStride = ulBufDelta - cxDst;
|
|
LONG rl = 8-RightRot;
|
|
|
|
//
|
|
// source doesn't advance after first byte, and
|
|
// we do the first byte outside the loop
|
|
//
|
|
|
|
do {
|
|
|
|
UCHAR c0 = *pGlyph++;
|
|
UCHAR c1;
|
|
pjDstEnd = pjDst + cxDst;
|
|
|
|
*pjDst |= c0 >> RightRot;
|
|
pjDst++;
|
|
c1 = c0 << rl;
|
|
|
|
//
|
|
// know cxDst is at least 4, use do-while
|
|
//
|
|
|
|
do {
|
|
c0 = *pGlyph;
|
|
*pjDst |= ((c0 >> RightRot) | c1);
|
|
c1 = c0 << rl;
|
|
pjDst++;
|
|
pGlyph++;
|
|
|
|
} while (pjDst != pjDstEnd);
|
|
|
|
pjDst += lStride;
|
|
|
|
} while (pjDst != pjDstEndy);
|
|
}
|
|
|
|
VOID
|
|
or_first_N_wide_rotated_no_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph,
|
|
LONG cxDst
|
|
)
|
|
{
|
|
PUCHAR pjDst = (PUCHAR)pBuffer;
|
|
PUCHAR pjDstEnd;
|
|
PUCHAR pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
|
|
LONG lStride = ulBufDelta - cxDst;
|
|
LONG rl = 8-RightRot;
|
|
|
|
//
|
|
// source doesn't advance after first byte, and
|
|
// we do the first byte outside the loop
|
|
//
|
|
|
|
do {
|
|
|
|
UCHAR c0;
|
|
UCHAR c1;
|
|
pjDstEnd = pjDst + cxDst - 1;
|
|
|
|
//
|
|
// do first dest byte outside loop for OR
|
|
//
|
|
|
|
c1 = 0;
|
|
c0 = *pGlyph;
|
|
*pjDst |= ((c0 >> RightRot) | c1);
|
|
pjDst++;
|
|
pGlyph++;
|
|
|
|
|
|
//
|
|
// know cxDst is at least 4, use do-while
|
|
//
|
|
|
|
do {
|
|
c0 = *pGlyph;
|
|
*pjDst = ((c0 >> RightRot) | c1);
|
|
c1 = c0 << rl;
|
|
pjDst++;
|
|
pGlyph++;
|
|
|
|
} while (pjDst != pjDstEnd);
|
|
|
|
//
|
|
// last dst byte outside loop, no new src needed
|
|
//
|
|
|
|
*pjDst = c1;
|
|
pjDst++;
|
|
|
|
pjDst += lStride;
|
|
|
|
} while (pjDst != pjDstEndy);
|
|
}
|
|
|
|
VOID
|
|
or_all_N_wide_rotated_no_last(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph,
|
|
LONG cxDst
|
|
)
|
|
{
|
|
PUCHAR pjDst = (PUCHAR)pBuffer;
|
|
PUCHAR pjDstEnd;
|
|
PUCHAR pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
|
|
LONG lStride = ulBufDelta - cxDst;
|
|
LONG rl = 8-RightRot;
|
|
|
|
//
|
|
// source doesn't advance after first byte, and
|
|
// we do the first byte outside the loop
|
|
//
|
|
|
|
do {
|
|
|
|
UCHAR c0;
|
|
UCHAR c1;
|
|
pjDstEnd = pjDst + cxDst - 1;
|
|
|
|
//
|
|
// do first dest byte outside loop for OR
|
|
//
|
|
|
|
c1 = 0;
|
|
|
|
//
|
|
// know cxDst is at least 4, use do-while
|
|
//
|
|
|
|
do {
|
|
c0 = *pGlyph;
|
|
*pjDst |= ((c0 >> RightRot) | c1);
|
|
c1 = c0 << rl;
|
|
pjDst++;
|
|
pGlyph++;
|
|
|
|
} while (pjDst != pjDstEnd);
|
|
|
|
//
|
|
// last dst byte outside loop, no new src needed
|
|
//
|
|
|
|
*pjDst |= c1;
|
|
pjDst++;
|
|
|
|
pjDst += lStride;
|
|
|
|
} while (pjDst != pjDstEndy);
|
|
}
|
|
|
|
//
|
|
// The following routines can be significantly sped up by
|
|
// breaking them out into DWORD alignment cases.
|
|
//
|
|
|
|
VOID
|
|
mov_first_N_wide_unrotated(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph,
|
|
LONG cxDst
|
|
)
|
|
{
|
|
PUCHAR pjDst = (PUCHAR)pBuffer;
|
|
PUCHAR pjDstEnd;
|
|
PUCHAR pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
|
|
LONG lStride = ulBufDelta - cxDst;
|
|
|
|
//
|
|
// byte aligned copy
|
|
//
|
|
|
|
|
|
do {
|
|
|
|
pjDstEnd = pjDst + cxDst;
|
|
|
|
//
|
|
// let compiler unroll inner loop
|
|
//
|
|
|
|
do {
|
|
|
|
*pjDst++ = *pGlyph++;
|
|
|
|
} while (pjDst != pjDstEnd );
|
|
|
|
pjDst += lStride;
|
|
|
|
} while (pjDst != pjDstEndy);
|
|
}
|
|
|
|
VOID
|
|
or_all_N_wide_unrotated(
|
|
LONG cyGlyph,
|
|
LONG RightRot,
|
|
LONG ulBufDelta,
|
|
PUCHAR pGlyph,
|
|
PUCHAR pBuffer,
|
|
LONG cxGlyph,
|
|
LONG cxDst
|
|
)
|
|
{
|
|
PUCHAR pjDst = (PUCHAR)pBuffer;
|
|
PUCHAR pjDstEnd;
|
|
PUCHAR pjDstEndy = pBuffer + ulBufDelta * cyGlyph;
|
|
LONG lStride = ulBufDelta - cxDst;
|
|
|
|
//
|
|
// byte aligned copy
|
|
//
|
|
|
|
|
|
do {
|
|
|
|
pjDstEnd = pjDst + cxDst;
|
|
|
|
//
|
|
// let compiler unroll inner loop
|
|
//
|
|
|
|
do {
|
|
|
|
*pjDst++ |= *pGlyph++;
|
|
|
|
} while (pjDst != pjDstEnd );
|
|
|
|
pjDst += lStride;
|
|
|
|
} while (pjDst != pjDstEndy);
|
|
}
|
|
|
|
|
|
|
|
VOID exit_fast_text(LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
VOID or_all_1_wide_rotated_need_last(LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
VOID or_all_1_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
VOID or_all_1_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
VOID or_all_2_wide_rotated_need_last(LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
VOID or_all_2_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
VOID or_all_2_wide_rotated_no_last (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
VOID or_all_2_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
VOID or_all_3_wide_rotated_need_last(LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
VOID or_all_3_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
VOID or_all_3_wide_rotated_no_last (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
VOID or_all_3_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
VOID or_all_4_wide_rotated_need_last(LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
VOID or_all_4_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
VOID or_all_4_wide_rotated_no_last (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
VOID or_all_4_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG);
|
|
VOID or_all_N_wide_rotated_need_last(LONG,LONG,LONG,PUCHAR,PUCHAR,LONG,LONG);
|
|
VOID or_all_N_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG,LONG);
|
|
VOID or_all_N_wide_rotated_no_last (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG,LONG);
|
|
VOID or_all_N_wide_unrotated (LONG,LONG,LONG,PUCHAR,PUCHAR,LONG,LONG);
|
|
|
|
|
|
PVOID OrAllTableNarrow[] = {
|
|
exit_fast_text,
|
|
exit_fast_text,
|
|
exit_fast_text,
|
|
exit_fast_text,
|
|
or_all_1_wide_rotated_need_last,
|
|
or_all_1_wide_unrotated,
|
|
or_all_1_wide_rotated_need_last,
|
|
or_all_1_wide_unrotated,
|
|
or_all_2_wide_rotated_need_last,
|
|
or_all_2_wide_unrotated,
|
|
or_all_2_wide_rotated_no_last,
|
|
or_all_2_wide_unrotated,
|
|
or_all_3_wide_rotated_need_last,
|
|
or_all_3_wide_unrotated,
|
|
or_all_3_wide_rotated_no_last,
|
|
or_all_3_wide_unrotated,
|
|
or_all_4_wide_rotated_need_last,
|
|
or_all_4_wide_unrotated,
|
|
or_all_4_wide_rotated_no_last,
|
|
or_all_4_wide_unrotated
|
|
};
|
|
|
|
|
|
PVOID OrInitialTableNarrow[] = {
|
|
exit_fast_text ,
|
|
exit_fast_text ,
|
|
exit_fast_text ,
|
|
exit_fast_text ,
|
|
|
|
or_all_1_wide_rotated_need_last ,
|
|
mov_first_1_wide_unrotated ,
|
|
or_all_1_wide_rotated_need_last ,
|
|
mov_first_1_wide_unrotated ,
|
|
|
|
or_first_2_wide_rotated_need_last ,
|
|
mov_first_2_wide_unrotated ,
|
|
or_first_2_wide_rotated_no_last ,
|
|
mov_first_2_wide_unrotated ,
|
|
|
|
or_first_3_wide_rotated_need_last ,
|
|
mov_first_3_wide_unrotated ,
|
|
or_first_3_wide_rotated_no_last ,
|
|
mov_first_3_wide_unrotated ,
|
|
or_first_4_wide_rotated_need_last ,
|
|
mov_first_4_wide_unrotated ,
|
|
or_first_4_wide_rotated_no_last ,
|
|
mov_first_4_wide_unrotated
|
|
};
|
|
|
|
//
|
|
// Handles arbitrarily wide glyph drawing, for case where initial byte should be
|
|
// ORed if it's not aligned (intended for use in drawing all but the first glyph
|
|
// in a string). Table format is:
|
|
// Bit 1 : 1 if don't need last source byte, 0 if do need last source byte
|
|
// Bit 0 : 1 if no rotation (aligned), 0 if rotation (non-aligned)
|
|
//
|
|
|
|
PVOID OrInitialTableWide[] = {
|
|
or_first_N_wide_rotated_need_last,
|
|
mov_first_N_wide_unrotated,
|
|
or_first_N_wide_rotated_no_last,
|
|
mov_first_N_wide_unrotated
|
|
};
|
|
|
|
//
|
|
// Handles arbitrarily wide glyph drawing, for case where all bytes should
|
|
// be ORed (intended for use in drawing potentially overlapping glyphs).
|
|
// Table format is:
|
|
// Bit 1 : 1 if don't need last source byte, 0 if do need last source byte
|
|
// Bit 0 : 1 if no rotation (aligned), 0 if rotation (non-aligned)
|
|
//
|
|
//
|
|
|
|
PVOID OrAllTableWide[] = {
|
|
or_all_N_wide_rotated_need_last,
|
|
or_all_N_wide_unrotated,
|
|
or_all_N_wide_rotated_no_last,
|
|
or_all_N_wide_unrotated
|
|
};
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* Routine Name
|
|
*
|
|
* draw_nf_ntb_o_to_temp_start
|
|
*
|
|
* Routine Description:
|
|
*
|
|
* Specialized glyph dispatch routine for non-fixed pitch, top and
|
|
* bottom not aligned glyphs that do overlap. This routine calculates
|
|
* the glyph's position on the temp buffer, then determines the correct
|
|
* highly specialized routine to be used to draw each glyph based on
|
|
* the glyph width, alignment and rotation
|
|
*
|
|
* Arguments:
|
|
*
|
|
* pGlyphPos - Pointer to first in list of GLYPHPOS structs
|
|
* cGlyph - Number of glyphs to draw
|
|
* pjTempBuffer - Pointer to temp 1Bpp buffer to draw into
|
|
* ulLeftEdge - left edge of TextRect & 0xFFFFFFF80
|
|
* TempBufDelta - Scan line Delta for TempBuffer (always pos)
|
|
*
|
|
* Return Value:
|
|
*
|
|
* None
|
|
*
|
|
\**************************************************************************/
|
|
VOID
|
|
draw_nf_ntb_o_to_temp_start(
|
|
PGLYPHPOS pGlyphPos,
|
|
ULONG cGlyphs,
|
|
PUCHAR pjTempBuffer,
|
|
ULONG ulLeftEdge,
|
|
ULONG TempBufDelta,
|
|
ULONG ulCharInc,
|
|
ULONG ulTempTop
|
|
)
|
|
{
|
|
|
|
LONG NumScans;
|
|
LONG RightRot;
|
|
PBYTE pGlyphData;
|
|
PBYTE pTempOutput;
|
|
GLYPHBITS *pGlyphBits;
|
|
LONG GlyphPosX;
|
|
LONG GlyphPixels;
|
|
LONG GlyphAlignment;
|
|
LONG SrcBytes;
|
|
LONG DstBytes;
|
|
ULONG ulDrawFlag;
|
|
PFN_GLYPHLOOPN pfnGlyphLoopN;
|
|
PFN_GLYPHLOOP pfnGlyphLoop;
|
|
ULONG iGlyph = 0;
|
|
LONG GlyphPosY;
|
|
|
|
//
|
|
// Draw non fixed pitch, tops and bottoms not aligned,overlap
|
|
//
|
|
|
|
while (cGlyphs--) {
|
|
|
|
pGlyphBits = pGlyphPos[iGlyph].pgdf->pgb;
|
|
|
|
//
|
|
// Glyph position in temp buffer = point.x + org.c - (TextRect.left & 0xffffffe0)
|
|
//
|
|
|
|
GlyphPosX = pGlyphPos[iGlyph].ptl.x + pGlyphPos[iGlyph].pgdf->pgb->ptlOrigin.x - ulLeftEdge;
|
|
GlyphPosY = pGlyphPos[iGlyph].ptl.y + pGlyphPos[iGlyph].pgdf->pgb->ptlOrigin.y - ulTempTop ;
|
|
GlyphAlignment = GlyphPosX & 0x07;
|
|
|
|
//
|
|
// calc byte offset
|
|
//
|
|
|
|
pTempOutput = pjTempBuffer + (GlyphPosX >> 3);
|
|
|
|
//
|
|
// glyph width
|
|
//
|
|
|
|
GlyphPixels = pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cx;
|
|
|
|
//
|
|
// source and dest bytes required
|
|
//
|
|
|
|
DstBytes = ((GlyphAlignment) + GlyphPixels + 7) >> 3;
|
|
SrcBytes = (GlyphPixels + 7) >> 3;
|
|
|
|
pTempOutput += (GlyphPosY * TempBufDelta);
|
|
|
|
if (DstBytes <= 4) {
|
|
|
|
//
|
|
// use narrow initial table
|
|
//
|
|
|
|
ulDrawFlag = (
|
|
(DstBytes << 2) |
|
|
((DstBytes > SrcBytes) << 1) |
|
|
((GlyphAlignment == 0))
|
|
);
|
|
|
|
|
|
pfnGlyphLoop = (PFN_GLYPHLOOP)OrAllTableNarrow[ulDrawFlag];
|
|
|
|
pfnGlyphLoop(
|
|
pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cy,
|
|
GlyphAlignment,
|
|
TempBufDelta,
|
|
pGlyphPos[iGlyph].pgdf->pgb->aj,
|
|
pTempOutput,
|
|
SrcBytes
|
|
);
|
|
|
|
} else {
|
|
|
|
//
|
|
// use wide glyph drawing
|
|
//
|
|
|
|
ulDrawFlag = (
|
|
((DstBytes > SrcBytes) << 1) |
|
|
((GlyphAlignment == 0))
|
|
);
|
|
|
|
|
|
pfnGlyphLoopN = (PFN_GLYPHLOOPN)OrAllTableWide[ulDrawFlag];
|
|
|
|
pfnGlyphLoopN(
|
|
pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cy,
|
|
GlyphAlignment,
|
|
TempBufDelta,
|
|
pGlyphPos[iGlyph].pgdf->pgb->aj,
|
|
pTempOutput,
|
|
SrcBytes,
|
|
DstBytes
|
|
);
|
|
|
|
|
|
}
|
|
|
|
iGlyph++;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* Routine Name
|
|
*
|
|
* draw_f_ntb_o_to_temp_start
|
|
*
|
|
* Routine Description:
|
|
*
|
|
* Specialized glyph dispatch routine for fixed pitch, top and
|
|
* bottom not aligned glyphs that do overlap. This routine calculates
|
|
* the glyph's position on the temp buffer, then determines the correct
|
|
* highly specialized routine to be used to draw each glyph based on
|
|
* the glyph width, alignment and rotation
|
|
*
|
|
* Arguments:
|
|
*
|
|
* pGlyphPos - Pointer to first in list of GLYPHPOS structs
|
|
* cGlyph - Number of glyphs to draw
|
|
* pjTempBuffer - Pointer to temp 1Bpp buffer to draw into
|
|
* ulLeftEdge - left edge of TextRect & 0xFFFFFFF80
|
|
* TempBufDelta - Scan line Delta for TempBuffer (always pos)
|
|
*
|
|
* Return Value:
|
|
*
|
|
* None
|
|
*
|
|
\**************************************************************************/
|
|
VOID
|
|
draw_f_ntb_o_to_temp_start(
|
|
PGLYPHPOS pGlyphPos,
|
|
ULONG cGlyphs,
|
|
PUCHAR pjTempBuffer,
|
|
ULONG ulLeftEdge,
|
|
ULONG TempBufDelta,
|
|
ULONG ulCharInc,
|
|
ULONG ulTempTop
|
|
)
|
|
{
|
|
LONG NumScans;
|
|
LONG RightRot;
|
|
PBYTE pGlyphData;
|
|
PBYTE pTempOutput;
|
|
GLYPHBITS *pGlyphBits;
|
|
LONG GlyphPosX;
|
|
LONG GlyphPixels;
|
|
LONG GlyphAlignment;
|
|
LONG SrcBytes;
|
|
LONG DstBytes;
|
|
ULONG ulDrawFlag;
|
|
PFN_GLYPHLOOP pfnGlyphLoop;
|
|
PFN_GLYPHLOOPN pfnGlyphLoopN;
|
|
ULONG iGlyph = 0;
|
|
LONG GlyphPitchX;
|
|
LONG GlyphPitchY;
|
|
LONG GlyphPosY;
|
|
|
|
//
|
|
// Draw fixed pitch, tops and bottoms not aligned,overlap
|
|
//
|
|
|
|
GlyphPitchX = pGlyphPos->ptl.x - ulLeftEdge;
|
|
GlyphPitchY = pGlyphPos->ptl.y - ulTempTop;
|
|
|
|
while (cGlyphs--) {
|
|
|
|
pGlyphBits = pGlyphPos[iGlyph].pgdf->pgb;
|
|
|
|
//
|
|
// Glyph position in temp buffer = point.x + org.c - (TextRect.left & 0xfffffff8)
|
|
//
|
|
|
|
GlyphPosX = GlyphPitchX + pGlyphPos[iGlyph].pgdf->pgb->ptlOrigin.x;
|
|
GlyphPosY = GlyphPitchY + pGlyphPos[iGlyph].pgdf->pgb->ptlOrigin.y;
|
|
|
|
GlyphAlignment = GlyphPosX & 0x07;
|
|
|
|
//
|
|
// calc byte offset
|
|
//
|
|
|
|
pTempOutput = pjTempBuffer + (GlyphPosX >> 3);
|
|
|
|
//
|
|
// glyph width
|
|
//
|
|
|
|
GlyphPixels = pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cx;
|
|
|
|
//
|
|
// source and dest bytes required
|
|
//
|
|
|
|
DstBytes = ((GlyphAlignment) + GlyphPixels + 7) >> 3;
|
|
SrcBytes = (GlyphPixels + 7) >> 3;
|
|
|
|
//
|
|
// calc glyph destination scan line
|
|
//
|
|
|
|
pTempOutput += (GlyphPosY * TempBufDelta);
|
|
|
|
if (DstBytes <= 4) {
|
|
|
|
//
|
|
// use narrow initial table
|
|
//
|
|
|
|
ulDrawFlag = (
|
|
(DstBytes << 2) |
|
|
((DstBytes > SrcBytes) << 1) |
|
|
((GlyphAlignment == 0))
|
|
);
|
|
|
|
|
|
pfnGlyphLoop = (PFN_GLYPHLOOP)OrAllTableNarrow[ulDrawFlag];
|
|
|
|
pfnGlyphLoop(
|
|
pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cy,
|
|
GlyphAlignment,
|
|
TempBufDelta,
|
|
pGlyphPos[iGlyph].pgdf->pgb->aj,
|
|
pTempOutput,
|
|
SrcBytes
|
|
);
|
|
|
|
} else {
|
|
|
|
//
|
|
// use wide glyph drawing
|
|
//
|
|
|
|
ulDrawFlag = (
|
|
((DstBytes > SrcBytes) << 1) |
|
|
((GlyphAlignment == 0))
|
|
);
|
|
|
|
|
|
pfnGlyphLoopN = (PFN_GLYPHLOOPN)OrAllTableWide[ulDrawFlag];
|
|
|
|
pfnGlyphLoopN(
|
|
pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cy,
|
|
GlyphAlignment,
|
|
TempBufDelta,
|
|
pGlyphPos[iGlyph].pgdf->pgb->aj,
|
|
pTempOutput,
|
|
SrcBytes,
|
|
DstBytes
|
|
);
|
|
|
|
|
|
}
|
|
|
|
GlyphPitchX += ulCharInc;
|
|
iGlyph++;
|
|
}
|
|
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* Routine Name
|
|
*
|
|
* draw_nf_tb_no_to_temp_start
|
|
*
|
|
* Routine Description:
|
|
*
|
|
* Specialized glyph dispatch routine for non-fixed pitch, top and
|
|
* bottom aligned glyphs that do not overlap. This routine calculates
|
|
* the glyph's position on the temp buffer, then determines the correct
|
|
* highly specialized routine to be used to draw each glyph based on
|
|
* the glyph width, alignment and rotation
|
|
*
|
|
* Arguments:
|
|
*
|
|
* pGlyphPos - Pointer to first in list of GLYPHPOS structs
|
|
* cGlyph - Number of glyphs to draw
|
|
* pjTempBuffer - Pointer to temp 1Bpp buffer to draw into
|
|
* ulLeftEdge - left edge of TextRect & 0xFFFFFFF80
|
|
* TempBufDelta - Scan line Delta for TempBuffer (always pos)
|
|
*
|
|
* Return Value:
|
|
*
|
|
* None
|
|
*
|
|
\**************************************************************************/
|
|
VOID
|
|
draw_nf_tb_no_to_temp_start(
|
|
PGLYPHPOS pGlyphPos,
|
|
ULONG cGlyphs,
|
|
PUCHAR pjTempBuffer,
|
|
ULONG ulLeftEdge,
|
|
ULONG TempBufDelta,
|
|
ULONG ulCharInc,
|
|
ULONG ulTempTop
|
|
)
|
|
{
|
|
|
|
LONG NumScans;
|
|
LONG RightRot;
|
|
PBYTE pGlyphData;
|
|
PBYTE pTempOutput;
|
|
GLYPHBITS *pGlyphBits;
|
|
LONG GlyphPosX;
|
|
LONG GlyphPixels;
|
|
LONG GlyphAlignment;
|
|
LONG SrcBytes;
|
|
LONG DstBytes;
|
|
ULONG ulDrawFlag;
|
|
PFN_GLYPHLOOP pfnGlyphLoop;
|
|
PFN_GLYPHLOOPN pfnGlyphLoopN;
|
|
ULONG iGlyph = 0;
|
|
|
|
//
|
|
// Draw non fixed pitch, tops and bottoms not aligned,overlap
|
|
//
|
|
|
|
while (cGlyphs--) {
|
|
|
|
pGlyphBits = pGlyphPos[iGlyph].pgdf->pgb;
|
|
|
|
//
|
|
// Glyph position in temp buffer = point.x + org.c - (TextRect.left & 0xfffffff8)
|
|
//
|
|
|
|
GlyphPosX = pGlyphPos[iGlyph].ptl.x + pGlyphPos[iGlyph].pgdf->pgb->ptlOrigin.x - ulLeftEdge;
|
|
GlyphAlignment = GlyphPosX & 0x07;
|
|
|
|
//
|
|
// calc byte offset
|
|
//
|
|
|
|
pTempOutput = pjTempBuffer + (GlyphPosX >> 3);
|
|
|
|
//
|
|
// glyph width
|
|
//
|
|
|
|
GlyphPixels = pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cx;
|
|
|
|
//
|
|
// source and dest bytes required
|
|
//
|
|
|
|
DstBytes = ((GlyphAlignment) + GlyphPixels + 7) >> 3;
|
|
SrcBytes = (GlyphPixels + 7) >> 3;
|
|
|
|
if (DstBytes <= 4) {
|
|
|
|
//
|
|
// use narrow initial table
|
|
//
|
|
|
|
ulDrawFlag = (
|
|
(DstBytes << 2) |
|
|
((DstBytes > SrcBytes) << 1) |
|
|
((GlyphAlignment == 0))
|
|
);
|
|
|
|
|
|
pfnGlyphLoop = (PFN_GLYPHLOOP)OrInitialTableNarrow[ulDrawFlag];
|
|
|
|
pfnGlyphLoop(
|
|
pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cy,
|
|
GlyphAlignment,
|
|
TempBufDelta,
|
|
pGlyphPos[iGlyph].pgdf->pgb->aj,
|
|
pTempOutput,
|
|
SrcBytes
|
|
);
|
|
|
|
} else {
|
|
|
|
//
|
|
// use wide glyph drawing
|
|
//
|
|
|
|
ulDrawFlag = (
|
|
((DstBytes > SrcBytes) << 1) |
|
|
((GlyphAlignment == 0))
|
|
);
|
|
|
|
|
|
pfnGlyphLoopN = (PFN_GLYPHLOOPN)OrAllTableWide[ulDrawFlag];
|
|
|
|
pfnGlyphLoopN(
|
|
pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cy,
|
|
GlyphAlignment,
|
|
TempBufDelta,
|
|
pGlyphPos[iGlyph].pgdf->pgb->aj,
|
|
pTempOutput,
|
|
SrcBytes,
|
|
DstBytes
|
|
);
|
|
|
|
|
|
}
|
|
|
|
iGlyph++;
|
|
}
|
|
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* Routine Name
|
|
*
|
|
* draw_f_tb_no_to_temp_start
|
|
*
|
|
* Routine Description:
|
|
*
|
|
* Specialized glyph dispatch routine for fixed pitch, top and
|
|
* bottom aligned glyphs that do not overlap. This routine calculates
|
|
* the glyph's position on the temp buffer, then determines the correct
|
|
* highly specialized routine to be used to draw each glyph based on
|
|
* the glyph width, alignment and rotation
|
|
*
|
|
* Arguments:
|
|
*
|
|
* pGlyphPos - Pointer to first in list of GLYPHPOS structs
|
|
* cGlyph - Number of glyphs to draw
|
|
* pjTempBuffer - Pointer to temp 1Bpp buffer to draw into
|
|
* ulLeftEdge - left edge of TextRect & 0xFFFFFFF80
|
|
* TempBufDelta - Scan line Delta for TempBuffer (always pos)
|
|
*
|
|
* Return Value:
|
|
*
|
|
* None
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID
|
|
draw_f_tb_no_to_temp_start(
|
|
PGLYPHPOS pGlyphPos,
|
|
ULONG cGlyphs,
|
|
PUCHAR pjTempBuffer,
|
|
ULONG ulLeftEdge,
|
|
ULONG TempBufDelta,
|
|
ULONG ulCharInc,
|
|
ULONG ulTempTop
|
|
)
|
|
{
|
|
|
|
LONG NumScans;
|
|
LONG RightRot;
|
|
PBYTE pGlyphData;
|
|
PBYTE pTempOutput;
|
|
GLYPHBITS *pGlyphBits;
|
|
LONG GlyphPosX;
|
|
LONG GlyphPixels;
|
|
LONG GlyphAlignment;
|
|
LONG SrcBytes;
|
|
LONG DstBytes;
|
|
ULONG ulDrawFlag;
|
|
PFN_GLYPHLOOPN pfnGlyphLoopN;
|
|
PFN_GLYPHLOOP pfnGlyphLoop;
|
|
ULONG iGlyph = 0;
|
|
LONG GlyphPitchX;
|
|
|
|
GlyphPitchX = pGlyphPos->ptl.x;
|
|
|
|
//
|
|
// Draw fixed pitch, tops and bottoms not aligned,overlap
|
|
//
|
|
|
|
while (cGlyphs--) {
|
|
|
|
pGlyphBits = pGlyphPos[iGlyph].pgdf->pgb;
|
|
|
|
//
|
|
// Glyph position in temp buffer = point.x + org.c - (TextRect.left & 0xfffffff8)
|
|
//
|
|
|
|
GlyphPosX = GlyphPitchX + pGlyphPos[iGlyph].pgdf->pgb->ptlOrigin.x - ulLeftEdge;
|
|
GlyphAlignment = GlyphPosX & 0x07;
|
|
|
|
//
|
|
// calc byte offset
|
|
//
|
|
|
|
pTempOutput = pjTempBuffer + (GlyphPosX >> 3);
|
|
|
|
//
|
|
// glyph width
|
|
//
|
|
|
|
GlyphPixels = pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cx;
|
|
|
|
//
|
|
// source and dest bytes required
|
|
//
|
|
|
|
DstBytes = ((GlyphAlignment) + GlyphPixels + 7) >> 3;
|
|
SrcBytes = (GlyphPixels + 7) >> 3;
|
|
|
|
if (DstBytes <= 4) {
|
|
|
|
//
|
|
// use narrow initial table
|
|
//
|
|
|
|
ulDrawFlag = (
|
|
(DstBytes << 2) |
|
|
((DstBytes > SrcBytes) << 1) |
|
|
(GlyphAlignment == 0)
|
|
);
|
|
|
|
|
|
pfnGlyphLoop = (PFN_GLYPHLOOP)OrInitialTableNarrow[ulDrawFlag];
|
|
|
|
pfnGlyphLoop(
|
|
pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cy,
|
|
GlyphAlignment,
|
|
TempBufDelta,
|
|
pGlyphPos[iGlyph].pgdf->pgb->aj,
|
|
pTempOutput,
|
|
SrcBytes
|
|
);
|
|
|
|
} else {
|
|
|
|
//
|
|
// use wide glyph drawing
|
|
//
|
|
|
|
ulDrawFlag = (
|
|
((DstBytes > SrcBytes) << 1) |
|
|
((GlyphAlignment == 0))
|
|
);
|
|
|
|
|
|
pfnGlyphLoopN = (PFN_GLYPHLOOPN)OrAllTableWide[ulDrawFlag];
|
|
|
|
pfnGlyphLoopN(
|
|
pGlyphPos[iGlyph].pgdf->pgb->sizlBitmap.cy,
|
|
GlyphAlignment,
|
|
TempBufDelta,
|
|
pGlyphPos[iGlyph].pgdf->pgb->aj,
|
|
pTempOutput,
|
|
SrcBytes,
|
|
DstBytes
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
iGlyph++;
|
|
GlyphPitchX += ulCharInc;
|
|
|
|
}
|
|
|
|
}
|
|
#endif
|