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

📄 blt.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 3 页
字号:
              }

              // Move to next mask pixel.

              if (Parameters->Mask) {

                // Check bits remaining in mask cache.

                if (!(Mask.CacheState & 0x00ff00)) {

                  Mask.Ptr += Mask.BytesPerAccess;  //  == +/- 4
                  Mask.CacheState = Mask.CacheStateNewDWord;
                  Mask.Cache = *(UNALIGNED ULONG *)Mask.Ptr;
                }

                Mask.CacheState += Mask.CacheStateIncrement;
              }
	      
              xAccum += xDMinor;
            }

            xAccum += xDMajor;
          }
        }

        // Do we do destination pixel read-back?

        if (DestMatters) {

	  // We maintain dst.Cache valid at all times if not doing quickWrite.
					
          if (QuickWrite) {
						
            switch (Dest.Bpp) {
            case 8:
              *(BYTE *)&Dest.Value = *(BYTE *)Dest.Ptr;
              break;
            case 16:
              *(WORD *)&Dest.Value = *(WORD *)Dest.Ptr;
              break;
            case 32:
              *(ULONG *)&Dest.Value = *(ULONG *)Dest.Ptr;
              break;
            case 24:
              Dest.Value = (*(Dest.Ptr + 2) << 16) + (*(Dest.Ptr + 1) << 8) + *(Dest.Ptr);
              break;
            }
          }
          else {
            Dest.Value = Dest.Cache >> ((Dest.CacheState >> 16) ^ Dest.MaskShiftXor);
          }
        }

        switch (Rop3) {

        // The compiler sorts these and creates a binary search set of tests to
        // get to an entry quickly.  Branch "prediction" helps this a lot.
        // Remember that masked rop4s makes NOP and SRCCOPY more likely.

        case 0xCC: break; // SRCCOPY
        case 0xAA: Source.Value = Dest.Value; break;
        case 0x00: Source.Value = 0; break; // BLACKNESS
        case 0x22: Source.Value = (~Source.Value) & Dest.Value;	break;
        case 0xB8: Source.Value = (Brush.Value & ~Source.Value) | (Source.Value & Dest.Value); break;
        case 0x11: Source.Value = ~(Source.Value | Dest.Value);	break; // NOTSRCERASE
        case 0x33: Source.Value = ~Source.Value; break; // NOTSRCCOPY
        case 0x44: Source.Value &= ~Dest.Value;	break; // SRCERASE
        case 0x55: Source.Value = ~Dest.Value; break; // DSTINVERT
        case 0x5A: Source.Value = Brush.Value ^ Dest.Value; break; // PATINVERT
        case 0x66: Source.Value ^= Dest.Value; break; // SRCINVERT
        case 0x88: Source.Value &= Dest.Value; break; // SRCAND
        case 0xBB: Source.Value = ~Source.Value | Dest.Value; break; // MERGEPAINT
        case 0xC0: Source.Value &= Brush.Value; break; // MERGECOPY
        case 0xEE: Source.Value |= Dest.Value; break; // SRCPAINT
        case 0xF0: Source.Value = Brush.Value; break; // PATCOPY
        case 0xFB: Source.Value = Brush.Value | ~Source.Value | Dest.Value; break; // PATPAINT
        case 0xFF: Source.Value = 0xFFFFFFFF; break; // WHITENESS
        case 0xE2: Source.Value = (Dest.Value & ~Source.Value) | (Brush.Value & Source.Value); break;
        case 0xAC: Source.Value = ((Source.Value ^ Dest.Value) & Brush.Value) ^ Source.Value; break;
        default: 
          Source.Value = ProcessRop3(Dest.Value,
                                     Source.Value,
                                     Brush.Value,
                                     Rop3,
                                     (BYTE)Dest.Bpp);
          break;
	}

        Source.Value &= Dest.Mask;

        if ((DoSourceColorKey && OriginalSrc == SourceColorKeyValue) ||
            (DoDestColorKey && Dest.Value == DestColorKeyValue)) {

          // This pixel is being color-keyed out.

          if (QuickWrite) {

            Dest.Ptr += Dest.BytesPerAccess;
          }
          else {

            // Leave dirty flag as-is.

            Dest.CacheState += Dest.CacheStateIncrement;

            // Check bits remaining in Dest cache.

            if (!(Dest.CacheState & 0x00ff00)) {

              if (Dest.CacheState & 0x0000ff) {

                // Flush cache.

                *(ULONG *)Dest.Ptr = Dest.Cache;
              }

              // Clear dirty flag.

              Dest.CacheState = Dest.CacheStateNewDWord;
              Dest.Ptr += Dest.BytesPerAccess;	// +/- 4
              Dest.Cache = *(ULONG *)Dest.Ptr;
	    }
	  }
          continue;
	}
      }

      // Now, we are ready to write the value from Source.Value into the
      // destination pixel.

      if (QuickWrite) {
				
        switch (Dest.Bpp) {
        case 8:
          *(BYTE *)Dest.Ptr = (BYTE)Source.Value;
          break;
        case 16:
          *(WORD *)Dest.Ptr = (WORD)Source.Value;
          break;
        case 32:
          *(ULONG *)Dest.Ptr = (ULONG)Source.Value;
          break;
        case 24:
          *Dest.Ptr = (BYTE)(Source.Value);
          *(Dest.Ptr + 1) = (BYTE)(Source.Value >> 8);
          *(Dest.Ptr + 2) = (BYTE)(Source.Value >> 16);
          break;
        }
        Dest.Ptr += Dest.BytesPerAccess;
      }
      else {

        TempShift = (BYTE)((Dest.CacheState >> 16 ) ^ Dest.MaskShiftXor);
        Dest.Cache &= ~(Dest.Mask << TempShift);
        Dest.Cache |= Source.Value << TempShift;
        Dest.CacheState += Dest.CacheStateIncrementDirty;  // sets dirty flag

        // Check bits remaining in Dest cache.

        if (!(Dest.CacheState & 0x00ff00)) {

          // Flush cache (We know it was dirty.)

          *(ULONG *)Dest.Ptr = Dest.Cache;

          // Clear dirty flag.

          Dest.CacheState = Dest.CacheStateNewDWord;
          Dest.Ptr += Dest.BytesPerAccess;  // +/- 4

          if (x != Width - 1) Dest.Cache = *(ULONG *)Dest.Ptr;
        }
      }
    } // Next column

    // Flush out destination pixel cache for next row.

    if (Dest.CacheState & 0x0000ff) *(ULONG *)Dest.Ptr = Dest.Cache;

  } // Next row

  // Cleanup the color converter.

  if (DoColorConvert) {

    CleanupColorConverter();
  }

  return TRUE;
}

void 
InitPixelBuffer(
  PIXEL_BUFFER  * Buffer,
  const SURFACE * Surface,
  BOOL            xPositive,
  BOOL            yPositive,
  const RECT    * Rect,
  ULONG           xSkip,
  ULONG           ySkip
  )
{
  // InitPixelBuffer
  // This function fills out a PIXEL_BUFFER structure using the data provided
  // on the stack. Do not use this function for brushes.

  // Local variables.

  LONG StartX;
  LONG StartBit;

  // Check parameters.

  // !TODO!

  // Set pointer to start of first row to use
	
  Buffer->RowPtr = (BYTE *)Surface->Ptr;

  if (yPositive) {

    Buffer->RowIncrement = Surface->Stride;
    Buffer->RowPtr += Surface->Stride * (Rect->top + ySkip);
  }
  else {
    Buffer->RowIncrement = -Surface->Stride;
    Buffer->RowPtr += Surface->Stride * (Rect->bottom - 1 - ySkip);
  }

  Buffer->Bpp = Surface->Format->BitsPerPixel;

  Buffer->MaskShiftXor = (Buffer->Bpp < 8) ? (LONG)(8 - Buffer->Bpp) : 0;

  // Initally 32 / Bpp pixels in dword, 0 offset

  Buffer->CacheStateNewDWord = (32 / Buffer->Bpp) << 8;
	
  if (xPositive) {

    StartX = Rect->left + xSkip;
    Buffer->CacheStateIncrement = ((Buffer->Bpp << 8) - 1) << 8;
  }
  else {
    StartX = Rect->right - 1 - xSkip;
    Buffer->CacheStateIncrement = (((-(LONG)Buffer->Bpp) << 8) - 1) << 8;

    // Initial offset points to last pixel in dword

    Buffer->CacheStateNewDWord |= (32 - (LONG)Buffer->Bpp) << 16;
  }
  Buffer->CacheStateIncrementDirty = Buffer->CacheStateIncrement + 1;

  // Deliberate assignment.

  if (Buffer->Is24Bit = (Buffer->Bpp == 24)) {

    Buffer->RowPtr += 3 * StartX;
    Buffer->BytesPerAccess = 3;
  }
  else {
    StartBit = Buffer->Bpp * StartX;
    Buffer->RowPtr += (StartBit & ~31) >> 3;
		
    // Since the first pixel on row specified in Rect may not be on dword
    // alignment:
		
    Buffer->CacheStateNewRow = Buffer->CacheStateNewDWord;
    while (((Buffer->CacheStateNewRow >> 16) ^ StartBit) & 31) {
      Buffer->CacheStateNewRow += Buffer->CacheStateIncrement;
    }
    Buffer->BytesPerAccess = 4;
  }
	
  if (!xPositive) {
    Buffer->BytesPerAccess = -Buffer->BytesPerAccess;
  }
	
  Buffer->Mask = (2 << (Buffer->Bpp - 1)) - 1;
}

void
InitBrushPixelBuffer(
  BRUSH_PIXEL_BUFFER * Buffer,
  const SURFACE      * Surface,
  BOOL                 xPositive,
  BOOL                 yPositive,
  const RECT         * Rect
  )
{
  // InitBrushPixelBuffer
  // This function should be called to fill out one of the specialized
  // BRUSH_PIXEL_BUFFER structures. Obviously, this should only be used for
  // brushes.

  // Check parameters.

  // !TODO!

  // We can safely cast BRUSH_PIXEL_BUFFER to PIXEL_BUFFER because of the
  // embedded structure.

  InitPixelBuffer((PIXEL_BUFFER *)Buffer, 
                  Surface,
                  xPositive, 
                  yPositive, 
                  Rect,
                  0, 
                  0);
	
  Buffer->PixelsPerRow = Surface->Size.cx;
  Buffer->Rows = Surface->Size.cy;
	
  Buffer->RowInitialPixelsRemaining = xPositive ? Buffer->PixelsPerRow - Rect->left : Rect->right;
  Buffer->RowsRemaining = yPositive ? Buffer->Rows - Rect->top : Rect->bottom;
  Buffer->FirstRowPtr = Buffer->RowPtr - Buffer->RowIncrement * ( Buffer->Rows - Buffer->RowsRemaining);
}

ULONG
ProcessRop3(
  ULONG DestValue,
  ULONG SourceValue,
  ULONG BrushValue,
  BYTE  Rop3,
  BYTE  DestBitsPerPixel
  )
{
  // ProcessRop3
  // This function will use the given D, S, and B values to execute an
  // arbitrary ROP. It returns the value. This function may call itself
  // recursively.

  // Local variables.

  ULONG Result = 0;
  ULONG ResultBit = 1;

  // Check parameters.

  // !TODO!

  if (DestBitsPerPixel > 24) {
		
    // Recursively break into two halves, otherwise the brushValue <<= 2 below
    // will overflow.

    return (( ProcessRop3(DestValue, 
                          SourceValue, 
                          BrushValue, 
                          Rop3, 
                          16)) 
              |
	    ( ProcessRop3(DestValue >> 16,
                          SourceValue >> 16,
                          BrushValue >> 16,
                          Rop3,
                          (BYTE)(DestBitsPerPixel - 16)) << 16)
           );
  }

  BrushValue <<= 2;
  SourceValue <<= 1;

  while (DestBitsPerPixel--) {

    if ((1 << (BrushValue & 4 | SourceValue & 2 | DestValue & 1)) & Rop3) {
      Result |= ResultBit;
    }
    BrushValue >>= 1;
    SourceValue >>= 1;
    DestValue >>= 1;
    ResultBit <<= 1;
  }

  return Result;
}

LONG
RectWidth(
  const RECT * Rect
  )
{
  // RectWidth
  // This function returns the width of a rectangle. Inlined.
 
  // Check parameters

  // !TODO!

  return (Rect->right - Rect->left);
}

LONG
RectHeight(
  const RECT * Rect
  )
{
  // RectHeight
  // This function returns the height of a rectangle. Inlined.
 
  // Check parameters

  // !TODO!

  return (Rect->bottom - Rect->top);
}

void
SelectFill(
  ULONG    BitsPerPixel,
  BLT_FN   Fill2,
  BLT_FN   Fill8,
  BLT_FN   Fill16,
  BLT_FN   Fill32,
  BLT_FN * OutFill
  )
{
  // SelectFill
  // This function may be used to select a blitting function that has 2, 8, 16
  // and 32 bit destination variants. Currently, this is used for fill
  // functions. If the BitsPerPixel value is not 2, 8, 16 (15), or 32 (24),
  // then the output fill function pointer is not touched.

  // Check parameters.

  // !TODO!

  switch (BitsPerPixel) {

  case 2:  *OutFill = Fill2; break;
  case 8:  *OutFill = Fill8; break;
  case 15:
  case 16: *OutFill = Fill16; break;
  case 24:
  case 32: *OutFill = Fill32; break;
  }
}

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
  )
{
  // SelectSrcLogic
  // This function may be used to select a blitting function from a number of
  // different variants, depending on source and destination bits per pixel.
  // If no match is found, the output function pointer is not touched. This
  // function is currently used for the "source logic" ROPs. (SRCAND, SRCPAINT,
  // and SRCINVERT).

  // Check parameters.

  // !TODO!

  switch (DestBitsPerPixel) {

  case 2:

    if (SrcBitsPerPixel == 2) {

      *OutLogic = Logic0202;
    }
    break;

  case 8:

    switch (SrcBitsPerPixel) {

    case 1:  *OutLogic = Logic0108; break;
    case 8:  *OutLogic = Logic0808; break;
    }
    break;

  case 16:

    switch (SrcBitsPerPixel) {

    case 1:  *OutLogic = Logic0116; break;
    case 8:  *OutLogic = Logic0816; break;
    case 16: *OutLogic = Logic1616; break;
    }
    break;

  case 32:

    switch (SrcBitsPerPixel) {

    case 1:  *OutLogic = Logic0132; break;
    case 8:  *OutLogic = Logic0832; break;
    case 32: *OutLogic = Logic3232; break;
    }
    break;
  }
}

⌨️ 快捷键说明

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