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

📄 blt.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Windows CE Software Graphics Library
// blt.c
//
// Copyright (c) 2000 Microsoft Corporation. All rights reserved.
//
// This source file contains the implementation of the software blit routine.

#include "pch.h"
#include "swg.h"
#include "specialcase.h"

// This is a dumb little helper macro.

#define Swap(a,b)  \
{                  \
  (a) = (a) ^ (b); \
  (b) = (a) ^ (b); \
  (a) = (a) ^ (b); \
}

// The pixel buffer structure is used to store all of the details concerning
// the source, destination and mask surfaces.

typedef struct t_PIXEL_BUFFER {

  BYTE * RowPtr;
  LONG   RowIncrement;
  ULONG  CacheStateNewDWord;
  ULONG  CacheStateNewRow;
  ULONG  CacheStateIncrement;
  ULONG  CacheStateIncrementDirty;
  BOOL   Is24Bit;
  ULONG  Mask;
  LONG   BytesPerAccess;
  ULONG  Bpp;
  BYTE * Ptr;
  ULONG  Cache;
  ULONG  Value;
  ULONG  CacheState;
  BYTE   MaskShiftXor;

} PIXEL_BUFFER;

// This is a special variant of the PIXEL_BUFFER structure with extra members
// for brushs.

typedef struct t_BRUSH_PIXEL_BUFFER {

  // Note the use of the "anonymous structure" Microsoft C extension.

  PIXEL_BUFFER;

  // Pixels still available this row of brush including cache.

  LONG PixelsRemaining;

  // Width of source surface.

  LONG PixelsPerRow;

  // PixelsRemaining at start of each destination row.

  LONG RowInitialPixelsRemaining;

  // Rows (including this one) left in pattern.

  LONG RowsRemaining;

  // Total rows in pattern.

  LONG Rows;

  // Pointer to first ulong to use in top/bottom row.

  BYTE * FirstRowPtr;

  // Pointer to *left* of pattern of current row.

  BYTE * LeftRowPtr;

} BRUSH_PIXEL_BUFFER;

// This is a function pointer to a blitting function.

typedef BOOL (*BLT_FN)(BLT_PARAM *);

// Internal prototypes. These functions are not exposed outside this module.

static void 
InitPixelBuffer(
  PIXEL_BUFFER  * Buffer,
  const SURFACE * Surface,
  BOOL            xPositive,
  BOOL            yPositive,
  const RECT    * Rect,
  ULONG           xSkip,
  ULONG           ySkip
  );

static void
InitBrushPixelBuffer(
  BRUSH_PIXEL_BUFFER * Buffer,
  const SURFACE      * Surface,
  BOOL                 xPositive,
  BOOL                 yPositive,
  const RECT         * Rect
  );

static ULONG
ProcessRop3(
  ULONG DestValue,
  ULONG SourceValue,
  ULONG BrushValue,
  BYTE  Rop3,
  BYTE  DestBitsPerPixel
  );

static BOOL
AnyBlt(
  BLT_PARAM * Parameters
  );

static void
SelectFill(
  ULONG    BitsPerPixel,
  BLT_FN   Fill2,
  BLT_FN   Fill8,
  BLT_FN   Fill16,
  BLT_FN   Fill32,
  BLT_FN * OutFill
  );

static void
SelectSrcLogic(
  ULONG    DestBitsPerPixel,
  ULONG    SrcBitsPerPixel,
  BLT_FN   Logic0202,
  BLT_FN   Logic0108,
  BLT_FN   Logic0808,
  BLT_FN   Logic0116,
  BLT_FN   Logic0816,
  BLT_FN   Logic1616,
  BLT_FN   Logic0132,
  BLT_FN   Logic0832,
  BLT_FN   Logic3232,
  BLT_FN * OutLogic
  );

BOOL
SoftwareBlt(
  BLT_PARAM * Parameters
  )
{
  // SoftwareBlt
  // This routine will examine the blit's parameters and determine if any
  // special case software blitting routines are appropriate to do the job.
  // If so, the special case is called, if not, we use the AnyBlt routine to
  // handle the blit.

  // Local variables.

  BLT_FN BltFn;
  BOOL   Stretching;

  // Check parameters.

  // !TODO!

  // Default to the blit routine that can handle anything.

  BltFn = AnyBlt;

  // Are we stretching?

  Stretching = FALSE;

  if (Parameters->Source) {

    if (RectWidth(Parameters->SourceRect) != RectWidth(Parameters->DestRect) ||
        RectHeight(Parameters->SourceRect) != RectHeight(Parameters->DestRect)) {
      Stretching = TRUE;
    }
  }

  // !TODO! Add checking for color conversion.

  // None of the optimized software routines color key or handle stretching.

  if (Parameters->ColorKeyType == NoColorKey && 
      !Stretching &&
      Parameters->ClipRectCount == 0) {

    switch (Parameters->Rop) {

    case 0x0000: // BLACKNESS

      Parameters->PatternType = SolidPattern;
      Parameters->FillValue = 0x00000000;

      SelectFill(Parameters->Destination->Format->BitsPerPixel,
                 SolidFill02,
                 SolidFill08,
                 SolidFill16,
                 SolidFill32,
                 &BltFn);
      break;

    case 0xFFFF: // WHITENESS

      Parameters->PatternType = SolidPattern;
      Parameters->FillValue = 0xFFFFFFFF;

      SelectFill(Parameters->Destination->Format->BitsPerPixel,
                 SolidFill02,
                 SolidFill08,
                 SolidFill16,
                 SolidFill32,
                 &BltFn);
      break;

    case 0xAAF0: // Masked fill : usually text.

      // !TODO!

    case 0xF0F0: // PATCOPY

      if (Parameters->PatternType == SolidPattern) {

        SelectFill(Parameters->Destination->Format->BitsPerPixel,
                   SolidFill02,
                   SolidFill08,
                   SolidFill16,
                   SolidFill32,
                   &BltFn);
      }
      break;

    case 0xCCCC: 

      switch (Parameters->Destination->Format->BitsPerPixel) {

      case 2:

        if (Parameters->Source->Format->BitsPerPixel == 2) {

          BltFn = SrcCopy0202;
	}
        break;

      case 8:

        switch (Parameters->Source->Format->BitsPerPixel) {

        case 1: BltFn = SrcCopy0108; break;
        case 4: BltFn = SrcCopy0408; break;
        case 8: BltFn = SrcCopy0808; break;
        }
        break;

      case 15:
      case 16:

        switch (Parameters->Source->Format->BitsPerPixel) {

        case 1:  BltFn = SrcCopy0116; break;
        case 4:  BltFn = SrcCopy0416; break;
        case 8:  BltFn = SrcCopy0816; break;
        case 16: BltFn = SrcCopy1616; break;
        }
        break;

      case 24:
      case 32:

        switch (Parameters->Source->Format->BitsPerPixel) {

        case 1:  BltFn = SrcCopy0132; break;
        case 4:  BltFn = SrcCopy0432; break;
        case 8:  BltFn = SrcCopy0832; break;
        case 32: BltFn = SrcCopy3232; break;
        }
        break;
      }
      break;

    case 0x8888: // SRCAND

      SelectSrcLogic(Parameters->Destination->Format->BitsPerPixel,
                     Parameters->Source->Format->BitsPerPixel,
                     SrcAnd0202,
                     SrcAnd0108,
                     SrcAnd0808,
                     SrcAnd0116,
                     SrcAnd0816,
                     SrcAnd1616,
                     SrcAnd0132,
                     SrcAnd0832,
                     SrcAnd3232,
                     &BltFn);
      break;

    case 0xEEEE: // SRCPAINT

      SelectSrcLogic(Parameters->Destination->Format->BitsPerPixel,
                     Parameters->Source->Format->BitsPerPixel,
                     SrcPaint0202,
                     SrcPaint0108,
                     SrcPaint0808,
                     SrcPaint0116,
                     SrcPaint0816,
                     SrcPaint1616,
                     SrcPaint0132,
                     SrcPaint0832,
                     SrcPaint3232,
                     &BltFn);
      break;

    case 0x6666: // SRCINVERT

      SelectSrcLogic(Parameters->Destination->Format->BitsPerPixel,
                     Parameters->Source->Format->BitsPerPixel,
                     SrcInvert0202,
                     SrcInvert0108,
                     SrcInvert0808,
                     SrcInvert0116,
                     SrcInvert0816,
                     SrcInvert1616,
                     SrcInvert0132,
                     SrcInvert0832,
                     SrcInvert3232,
                     &BltFn);
      break;

    }
  }

  // Call the blitter.

  return (BltFn(Parameters));
}

BOOL
AnyBlt(
  BLT_PARAM * Parameters
  )
{
  // AnyBlt
  // This is the fully-featured software blitting routine. It can be called to
  // perform blits that the hardware cannot do. It supports the following
  // features:
  //
  // - Arbitrary ROP
  // - Source and destination color key (single color only)
  // - Shrink and Scale
  // - Color format conversion
  //
  // Note: this function assume that all surfaces are locked and that if we
  // are rendering to the primary, that the graphics pipe is flushed and
  // stalled.

  // Local variables.

  BYTE Rop3 = (BYTE)Parameters->Rop;
  BYTE MaskedRop3 = (BYTE)(Parameters->Rop >> 8);
  BYTE UnmaskedRop3 = Rop3;

  BYTE TempShift;

  BOOL ComplexBlt = 0;
  BOOL QuickWrite = 0;

  LONG Width = RectWidth(Parameters->DestRect);
  LONG Height = RectHeight(Parameters->DestRect);

  LONG x;

  BOOL DestMatters = (((Parameters->Rop >> 1) ^ Parameters->Rop) & 0x5555) != 0;

  BOOL DestXPositive = Parameters->ScanXPositive;
  BOOL DestYPositive = Parameters->ScanYPositive;

  const RECT * DestRect = Parameters->DestRect;
  RECT TempDestRect;
  RECT ClippedDestRect;

  BOOL xShrinkStretch = FALSE;
  BOOL xShrink        = FALSE;
  BOOL xStretch       = FALSE;
  BOOL yShrinkStretch = FALSE;
  BOOL yShrink        = FALSE;
  BOOL yStretch       = FALSE;

  LONG SourceWidth;
  LONG SourceHeight;

  LONG RowXAccum, xAccum, xDMajor, xDMinor;    // only valid if xShrinkStretch
  LONG yAccum, yDMajor, yDMinor;               // only valid if yShrinkStretch
  LONG OriginalMaskRowInc, OriginalSrcRowInc;  // only valid if yShrinkStretch

  BYTE * PrevMaskPtr, * PrevSrcPtr;

  ULONG PrevMaskCache, PrevSrcCache;
  ULONG PrevMaskCacheState, PrevSrcCacheState;

  ULONG OriginalSrc;

  RECT  BrushRect;
  LONG  BrushTopIndent;
  LONG  BrushLeftIndent;

  // Number of dst pixels to not write (left if dstXPositive else right)

  LONG DestXStartSkip = 0;
  LONG SourceXStartSkip = 0;

  // Number of rows to ignore (top if dstYPositive)
  	
  LONG DestYStartSkip = 0;
  LONG SourceYStartSkip = 0;

  LONG SkipCount;

  BOOL DoSourceColorKey;
  ULONG SourceColorKeyValue;

  BOOL DoDestColorKey;
  ULONG DestColorKeyValue;

  PIXEL_BUFFER Source, Dest, Mask;
  BRUSH_PIXEL_BUFFER Brush;

  BOOL DoColorConvert;

  // Check parameters.

  // !TODO!

  // Handle improperly ordered prclDst resulting from stretch Blt
  // Note that only prclDst is ever improperly ordered
	
  if (Width < 0 || Height < 0) {

    memcpy(&TempDestRect, DestRect, sizeof(RECT));	
    DestRect = &TempDestRect;

    if (Width < 0) {
      Swap(TempDestRect.left, TempDestRect.right);
      Width = -Width;
      DestXPositive = !DestXPositive;
    }

    if (Height < 0) {
      Swap(TempDestRect.top, TempDestRect.bottom);
      Height = -Height;
      DestYPositive = !DestYPositive;
    }
  }
  // DestRect is now properly ordered.

  // Check for stretching and/or shrinking.

  if (Parameters->Source) {
		
    SourceWidth = RectWidth(Parameters->SourceRect);
    SourceHeight = RectHeight(Parameters->SourceRect);

    if (Width > SourceWidth) {
      xStretch = TRUE;
      xDMajor = Width;
      xDMinor = SourceWidth;
    }
    else if (Width < SourceWidth) {
      xShrink = TRUE;
      xDMajor = SourceWidth;
      xDMinor = Width;
    }

    if (xStretch || xShrink) {
      xShrinkStretch = TRUE;
			
      // Convert to Bresenham parameters.

      xDMinor *= 2;
      xDMajor = xDMinor - 2 * xDMajor;
      RowXAccum = xShrink ? (2 * Width - SourceWidth) : (3 * SourceWidth -  2 * Width);
      // Loaded into xAccum at start of each row.
    }
		
    if (Height > SourceHeight) {
      yStretch = TRUE;
      yDMajor = Height;
      yDMinor = SourceHeight;
    }
    if (Height < SourceHeight) {
      yShrink = TRUE;
      yDMajor = SourceHeight;
      yDMinor = Height;
    }

    if (yStretch || yShrink) {
      yShrinkStretch = TRUE;
			
      // Convert to Bresenham parameters.

      yDMinor *= 2;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -