📄 sd0202.h
字号:
//
// Windows CE Software Graphics Library
// sd0202.h
//
// Copyright (c) 2000 Microsoft Corporation. All rights reserved.
//
// This header file contains the function template for special case blit
// routines with 2 bit source and 2 bit destination surfaces. This code
// does not stretch, colorkey, mask, clip, blend, or do color conversions.
//
// This file MUST be included after the deceleration of the fill mask
// arrays and the blt temporary buffer helper within the source file.
#if !defined(FUNCTION)
#error Must define FUNCTION
#endif
#if !defined(BYTE_OP)
#error Must define BYTE_OP
#endif
#if !defined(BLOCK_OP) && !defined(DWORD_OP)
#error Must define either BLOCK_OP or DWORD_OP
#endif
#if defined(BLOCK_OP) && defined(DWORD_OP)
#error Cannot define both BLOCK_OP and DWORD_OP
#endif
BOOL
FUNCTION(
BLT_PARAM * Parameters
)
{
// Local variables.
// Source-related info.
const RECT * SrcRect = Parameters->SourceRect;
LONG SrcScanStride = Parameters->Source->Stride;
ULONG SrcBitOffset = (SrcRect->left & 0x03) * 2;
BYTE * SrcScanLine = (BYTE *)Parameters->Source->Ptr +
SrcRect->top * SrcScanStride +
(SrcRect->left >> 2);
// Destination-related info.
const RECT * DstRect = Parameters->DestRect;
LONG DstScanStride = Parameters->Destination->Stride;
ULONG DstBitOffset = (DstRect->left & 0x03) * 2;
BYTE * DstScanLine = (BYTE *)Parameters->Destination->Ptr +
DstRect->top * DstScanStride +
(DstRect->left >> 2);
ULONG Rows = RectHeight(DstRect);
ULONG Cols = RectWidth(DstRect);
ULONG Row;
LONG RightBitOffset = ((DstRect->right - 1) & 0x03) * 2;
// Masks for left and right non-byte-aligned pixels.
BYTE RightMask, LeftMask;
// Bytes to copy from source to working buffer.
LONG MoveSrcCount = ((SrcRect->left + Cols - 1) >> 2) - (SrcRect->left >> 2) + 1;
// Buffer will be bit-shifted up to here.
BYTE * BufShiftLim;
// Calculate number of bytes that can be memcpy'ed out of the working
// buffer to the frame buffer. This does not include partial bytes.
LONG TotalBytes = ((DstRect->right - 1) >> 2) - (DstRect->left >> 2) + 1;
// We copy to this temp buffer to bit-align the source.
BYTE * Buffer;
// Calculate how far we'll have to left-shift the working buffer
// to bring bits into alignment with dest
const LONG BufferShiftLeft = (SrcBitOffset > DstBitOffset) ?
(SrcBitOffset - DstBitOffset) :
(8 - DstBitOffset + SrcBitOffset);
const LONG BufferShiftRight = 8 - BufferShiftLeft;
BYTE * BufferCopy;
register BYTE * Destination;
register BYTE * Source;
LONG Num;
BYTE * Shift;
#ifdef DWORD_OP
BYTE * TempSource;
LONG TempNum;
LONG LeftBytes;
LONG MiddleDwords;
LONG RightBytes;
BYTE * LeftLim;
BYTE * MiddleLim;
BYTE * RightLim;
#endif
// Calculate byte masks for leftmost and rightmost pixels (when the whole
// byte is unneeded).
LeftMask = LeftFillMask[DstRect->left & 0x03];
RightMask = RightFillMask[DstRect->right & 0x03];
if (TotalBytes == 1) {
LeftMask &= RightMask;
}
// Get a buffer large enough for one scanline (plus a little
// extra to handle dst-aligning the src bits).
if ((Buffer = GetBltBuffer((Cols >> 2) + 8)) == NULL) {
return FALSE;
}
// Need to align Buffer with DstScanLine so we can eventually
// do DWORD copies from one to the other.
Buffer += ((DWORD)DstScanLine) & 0x03;
// Make sure to copy source before overwriting. Since we use
// a temporary buffer to do our composing, we don't need to worry
// about overlapping src/dst in the X direction, just Y.
if (!Parameters->ScanYPositive) {
// Scan from end of memory, and negate stride
SrcScanLine += SrcScanStride * (Rows - 1);
DstScanLine += DstScanStride * (Rows - 1);
SrcScanStride = -SrcScanStride;
DstScanStride = -DstScanStride;
}
#ifdef DWORD_OP
// Since our source starts at the same address (Buffer) every time, we
// can calculate the end addresses for the byte/dword/byte loops below.
// Need to be careful to account for all of the adjustments to TempSource
// and TempNum that would happen by the time we actually use the lims.
TempSource = Buffer;
TempNum = TotalBytes;
// Skip leading partial byte.
if (DstBitOffset) {
TempSource++;
TempNum--;
}
// Don't fill partial last byte.
if (RightBitOffset != 6 && TempNum > 0) {
TempNum--;
}
// Calculate number of full bytes on left, dwords in middle,
// and bytes on the right
LeftBytes = min(4 - ((DWORD)TempSource & 0x03), (DWORD)TempNum) & 0x03;
MiddleDwords = (TempNum - LeftBytes) & ~0x03;
RightBytes = TempNum - LeftBytes - MiddleDwords;
LeftLim = TempSource + LeftBytes;
MiddleLim = LeftLim + MiddleDwords;
RightLim = MiddleLim + RightBytes;
#endif
// When we fill the buffer with the source, we memcpy so that the src
// bits end up aligned with or just to the left of their eventual
// destination.
BufferCopy = (SrcBitOffset >= DstBitOffset) ? Buffer : Buffer + 1;
// If the bit offsets are equal, no need to bit-shift buffer.
if (SrcBitOffset == DstBitOffset) {
BufShiftLim = Buffer;
}
else {
BufShiftLim = Buffer + MoveSrcCount + 1;
}
for (Row = 0; Row < Rows; Row++) {
// For each row, we use these variables to read and write pixels. Notice
// the use of the workign buffer we allocated as the source.
Destination = DstScanLine;
Source = Buffer;
Num = TotalBytes;
// Fill the buffer with the source.
memcpy(BufferCopy, SrcScanLine, MoveSrcCount);
// Now do a left shift on the entire buffer, bringing the source bits
// into alignment with the destination.
for (Shift = Buffer; Shift < BufShiftLim; Shift++) {
*Shift = (*Shift << BufferShiftLeft) | (*(Shift + 1) >> BufferShiftRight);
}
// Left pixels (non-byte aligned).
if (DstBitOffset) {
*Destination = (*Destination & ~LeftMask) |
(BYTE_OP(*Destination, *Source) & LeftMask);
Destination++;
Source++;
Num--;
}
// Right pixels (non-byte aligned).
if (RightBitOffset != 6 && Num > 0) {
BYTE * TempDestination = Destination + Num - 1;
BYTE * TempSource = Source + Num - 1;
*TempDestination = (*TempDestination & ~RightMask) |
(BYTE_OP(*TempDestination, *TempSource) & RightMask);
Num--;
}
#ifdef DWORD_OP
// We calculated LeftLim, MiddleLim and RightLim outside
// the loop -- use them here
while (Source < LeftLim) {
*Destination = BYTE_OP(*Destination, *Source);
Destination++;
Source++;
}
#if defined(PPC821) || defined(PPC403)
while (Source < MiddleLim) {
*Destination = BYTE_OP(*Destination, *Source);
Destination++;
Source++;
}
#else
while (Source < MiddleLim) {
*(DWORD *)Destination = DWORD_OP(*(DWORD *)Destination, *(DWORD *)Source);
Destination += 4;
Source += 4;
}
#endif
while (Source < RightLim) {
*Destination = BYTE_OP(*Destination, *Source);
Destination++;
Source++;
}
#endif
#ifdef BLOCK_OP
// Do the whole middle section at once
if (Num > 0) {
BLOCK_OP(Destination, Source, Num);
}
#endif
// Next line.
SrcScanLine += SrcScanStride;
DstScanLine += DstScanStride;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -