⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd0202.h

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 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 + -