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

📄 blt.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 3 页
字号:
      yDMajor = yDMinor - 2 * yDMajor;
      yAccum = yShrink ? (2 * Height - SourceHeight) : (3 * SourceHeight - 2 * Height);
    }
  }

  // Clipping. We only clip against a single rectangle

  if (Parameters->ClipRect) {

    memcpy(&ClippedDestRect, DestRect, sizeof(RECT));

    if (ClippedDestRect.left < Parameters->ClipRect->left) {
      ClippedDestRect.left = Parameters->ClipRect->left;
    }
    if (ClippedDestRect.top < Parameters->ClipRect->top) {
      ClippedDestRect.top = Parameters->ClipRect->top;
    }
    if (ClippedDestRect.bottom > Parameters->ClipRect->bottom) {
      ClippedDestRect.bottom = Parameters->ClipRect->bottom;
    }
    if (ClippedDestRect.right > Parameters->ClipRect->right) {
      ClippedDestRect.right = Parameters->ClipRect->right;
    }

    if (ClippedDestRect.right <= ClippedDestRect.left ||
        ClippedDestRect.bottom <= ClippedDestRect.top) {

      // We've clipped our destination completely away. Consequently, we're
      // done.

      return TRUE;
    }

    DestXStartSkip = DestXPositive ? (ClippedDestRect.left - DestRect->left) : (DestRect->right - ClippedDestRect.right);
    DestYStartSkip = DestYPositive ? (ClippedDestRect.top - DestRect->top) : (DestRect->bottom - ClippedDestRect.bottom);

    Width = RectWidth(&ClippedDestRect);
    Height = RectHeight(&ClippedDestRect);
  }

  // Finish preparing the stretching parameters in light of the clipping
  // rectangle.

  if (Parameters->Source) {

    if (xShrink) {
			
      while (RowXAccum < 0) {
        RowXAccum += xDMinor;
        SourceXStartSkip++;
      }
      RowXAccum += xDMajor; 
    }
		
    for (SkipCount = DestXStartSkip; SkipCount != 0; SkipCount--) {

      if (xShrink) {

        while (RowXAccum < 0) {
          RowXAccum += xDMinor;
          SourceXStartSkip++;
        }

        // This is the Source Skip inherent with a Destination Skip.
        SourceXStartSkip++;	
        RowXAccum += xDMajor; 
      }
      else if (xStretch) {

        if (RowXAccum < 0) RowXAccum += xDMinor;
        else {
          RowXAccum += xDMajor;
          SourceXStartSkip++;
        }
      }
      else SourceXStartSkip++;
    }

    if (yShrink) {
      yAccum += DestYStartSkip * yDMajor;

      // This is the Source Skip inherent with a Destination Skip.
      SourceYStartSkip += DestYStartSkip;
    }
    else if (yStretch) {

      for (SkipCount = DestYStartSkip; SkipCount != 0; SkipCount--) {

        if (yAccum < 0) yAccum += yDMinor;
        else {
          yAccum += yDMajor;
          SourceYStartSkip++;
        }
      }
    }
    else SourceYStartSkip += DestYStartSkip;
  }

  if (Parameters->ColorKeyType == NoColorKey) {

    DoSourceColorKey = FALSE;
    DoDestColorKey = FALSE;
  }
  else {

    DoSourceColorKey = (BOOL)(Parameters->ColorKeyType == SourceColorKey ||
                              Parameters->ColorKeyType == SourceAndDestColorKey);

    DoDestColorKey = (BOOL)(Parameters->ColorKeyType == DestColorKey ||
                            Parameters->ColorKeyType == SourceAndDestColorKey);

    if (DoSourceColorKey) {

      if (Parameters->SourceColorKey->LowValue ==
          Parameters->SourceColorKey->HighValue) {

        SourceColorKeyValue = Parameters->SourceColorKey->LowValue;
      }
      else {

        // We only support a single key, not color spaces...

        return FALSE;
      }
    }

    if (DoDestColorKey) {

      if (Parameters->DestColorKey->LowValue ==
          Parameters->DestColorKey->HighValue) {

        DestColorKeyValue = Parameters->DestColorKey->LowValue;
      }
      else {

        // We only support a single key, not color spaces...

        return FALSE;
      }
    }
  }

  if (Parameters->Brush) {
		
    // Calculate an rclBrush so that the correct starting pixel is chosen
    // for the brush iterator.

    BrushTopIndent = (Parameters->BrushOrigin) ? (Parameters->Brush->Size.cy - Parameters->BrushOrigin->y) : 0;
    BrushLeftIndent = (Parameters->BrushOrigin) ? (Parameters->Brush->Size.cx - Parameters->BrushOrigin->x) : 0;

    BrushRect.left = (BrushLeftIndent + DestRect->left) % Parameters->Brush->Size.cx;
    BrushRect.right = (BrushRect.left + Parameters->Brush->Size.cx - 1) % Parameters->Brush->Size.cx;
    BrushRect.top = (BrushTopIndent + DestRect->top) % Parameters->Brush->Size.cy;
    BrushRect.bottom = (BrushRect.top + Parameters->Brush->Size.cy - 1 ) % Parameters->Brush->Size.cy;
  }

  Source.Ptr = Source.RowPtr = 
   Mask.Ptr = Mask.RowPtr = 
   Brush.Ptr = Brush.RowPtr = NULL;

  if (Parameters->Source) {
  
    InitPixelBuffer(&Source, 
                    Parameters->Source, 
                    Parameters->ScanXPositive,
                    Parameters->ScanYPositive,
                    Parameters->SourceRect,
                    SourceXStartSkip,
                    SourceYStartSkip);

    // Check for color conversion.

    DoColorConvert = !IsSameFormat(Parameters->Source->Format,
                                   Parameters->Destination->Format);

    if (DoColorConvert) {

      InitColorConverter(Parameters->Source->Format,
                         Parameters->Destination->Format);
    }
  }

  if (Parameters->Brush) {
  
    InitBrushPixelBuffer(&Brush, 
                         Parameters->Brush, 
                         Parameters->ScanXPositive,
                         Parameters->ScanYPositive,
                         &BrushRect);
  }

  if ((MaskedRop3 != UnmaskedRop3) && (Parameters->Mask == NULL)) {

    // ROP indicates we need a mask, but we don't have one.

    return FALSE;
  }

  if (Parameters->Mask) {

    InitPixelBuffer(&Mask, 
                    Parameters->Mask, 
                    Parameters->ScanXPositive,
                    Parameters->ScanYPositive,
                    Parameters->MaskRect,
                    SourceXStartSkip,
                    SourceYStartSkip);
  }
  else Mask.RowIncrement = 0;

  if ((Dest.Bpp = Parameters->Destination->Format->BitsPerPixel) >= 8) {
  
    QuickWrite = TRUE;

    if (!DestYPositive) {

      Dest.RowIncrement = -Parameters->Destination->Stride;
      Dest.RowPtr = (BYTE *)Parameters->Destination->Ptr + Parameters->Destination->Stride * (DestRect->bottom - 1 - DestYStartSkip);
    }
    else {
      Dest.RowIncrement = Parameters->Destination->Stride;
      Dest.RowPtr = (BYTE *)Parameters->Destination->Ptr + Parameters->Destination->Stride * (DestYStartSkip + DestRect->top);
    }
		
    if (!DestXPositive) {
      Dest.BytesPerAccess = -(LONG)(Dest.Bpp / 8);
      Dest.RowPtr -= Dest.BytesPerAccess * (DestRect->right - 1 - DestXStartSkip);
    }
    else {
      Dest.BytesPerAccess = Dest.Bpp / 8;
      Dest.RowPtr += Dest.BytesPerAccess * (DestXStartSkip + DestRect->left);
    }
		
    Dest.Mask = (2 << (Dest.Bpp - 1)) - 1;
    Dest.CacheState = 0;
  }
  else {
    InitPixelBuffer(&Dest, 
                    Parameters->Destination, 
                    DestXPositive, 
                    DestYPositive, 
                    DestRect,
                    DestXStartSkip, 
                    DestYStartSkip);
  }

  if (yShrinkStretch) {

    // Back up the source and mask row increments because they will be
    // altered dynamically.

    OriginalMaskRowInc = Mask.RowIncrement;
    OriginalSrcRowInc = Source.RowIncrement;
  }

  if (Parameters->Rop == 0x0000) {
    Source.Value = 0;
  }
  else if (Parameters->Rop == 0xffff) {
    Source.Value = Dest.Mask;
  }
  else {
    Source.Value = Parameters->FillValue & Dest.Mask;
    if ((MaskedRop3 != UnmaskedRop3) || 
        DoSourceColorKey ||
        DoDestColorKey ||
        xShrinkStretch ||
        (Rop3 != 0xCC && (Rop3 != 0xF0 || Parameters->Brush))) {

      ComplexBlt = TRUE;
    }
  }
	
  Brush.Value = Source.Value;

  while (Height--) {
		
    // Handle y Shrinking or stretching.
    
    if (yShrinkStretch) {
      if (yShrink) {

        // Skip source line(s) if shrinking.

        while (yAccum < 0) {
          Source.RowPtr += Source.RowIncrement;
          Mask.RowPtr += Mask.RowIncrement;
          yAccum += yDMinor;
        }
        yAccum += yDMajor;
      }
      else {
        if (yAccum < 0) {

          // Repeat source line if stretching.
          // yDMinor is a small +ve number.

          yAccum += yDMinor;
          if (yStretch) {
            Source.RowIncrement = 0;
            Mask.RowIncrement = 0;
          }
        }
        else {
          // Switch to next source line  (after this row)
          // yDMajor is a large -ve value (i.e. |yDMajor| > |yDMinor| )

          yAccum += yDMajor;
          Source.RowIncrement = OriginalSrcRowInc;
          Mask.RowIncrement = OriginalMaskRowInc;
        }
      }
    }

    // Move all buffers to next line.

    if (Source.RowPtr) {

      Source.Ptr = Source.RowPtr;
      Source.RowPtr += Source.RowIncrement;
      
      if (!Source.Is24Bit) {
        Source.Cache = *(ULONG *)Source.Ptr;
        Source.CacheState = Source.CacheStateNewRow;
      }
    }
		
    if (Mask.RowPtr) {

      Mask.Ptr = Mask.RowPtr;
      Mask.RowPtr += Mask.RowIncrement;
      Mask.Cache = *(UNALIGNED ULONG *)Mask.Ptr;
      Mask.CacheState = Mask.CacheStateNewRow;
    }

    if (Brush.RowPtr) {

      Brush.Ptr = Brush.RowPtr;
      Brush.LeftRowPtr = Brush.Ptr - (Brush.FirstRowPtr - (BYTE *)(Parameters->Brush->Ptr));
      if (--Brush.RowsRemaining) {

        Brush.RowPtr += Brush.RowIncrement;
      }
      else {

        Brush.RowPtr = Brush.FirstRowPtr;
        Brush.RowsRemaining = Brush.Rows;
      }
      Brush.Cache = *(ULONG *)Brush.Ptr;
      Brush.CacheState = Brush.CacheStateNewRow;
      Brush.PixelsRemaining = Brush.RowInitialPixelsRemaining;
    }

    Dest.Ptr = Dest.RowPtr;
    Dest.RowPtr += Dest.RowIncrement;

    if (!QuickWrite) {
      Dest.Cache = *(ULONG *)Dest.Ptr;
      Dest.CacheState = Dest.CacheStateNewRow;
    }

    if (xStretch) {
      PrevMaskPtr = Mask.Ptr;
      PrevMaskCache = Mask.Cache;
      PrevMaskCacheState = Mask.CacheState;

      PrevSrcPtr = Source.Ptr;
      PrevSrcCache = Source.Cache;
      PrevSrcCacheState = Source.CacheState;
    }

    xAccum = RowXAccum;

    for (x = 0; x < Width; x++) {

      if (Source.Ptr) {

        // Read the next pixel in and convert to same depth as destination.

        if (Source.Is24Bit) {
          // Since 24-bit packed pixels cross dword boundaries:

          Source.Value = (*(Source.Ptr + 2) << 16) + (*(Source.Ptr + 1) << 8) + *(Source.Ptr);
          Source.Ptr += Source.BytesPerAccess;
        }
        else {
          // Check bits remaining in src.Cache.

          if (!(Source.CacheState & 0x00ff00)) {
            Source.Ptr += Source.BytesPerAccess;
            Source.CacheState = Source.CacheStateNewDWord;
            Source.Cache = *(ULONG *)Source.Ptr;
          }
          Source.Value = Source.Cache >> ((Source.CacheState >> 16) ^ Source.MaskShiftXor);
          Source.CacheState += Source.CacheStateIncrement;		 
        }

        OriginalSrc = (Source.Value &= Source.Mask);

        if (DoColorConvert) {

          Source.Value = ColorConvert(Source.Value);
        }
      }
			
      if (ComplexBlt) { // Brush, masked, color key, unusual rop3, etc...

        if (Brush.Ptr) {

          // Note that the brush should have already been converted to the same
          // depth as the destination (if they weren't the same).

          // Check for wrapping off right edge of pattern

          if (!(Brush.PixelsRemaining--)) {

            Brush.Ptr = Brush.LeftRowPtr;
            Brush.PixelsRemaining = Brush.PixelsPerRow - 1;
            Brush.CacheState = Brush.CacheStateNewDWord;
            Brush.Cache = *(ULONG *)Brush.Ptr;
          }
          // Check bits remaining in brush.Cache
          else if (!(Brush.CacheState & 0x00ff00)) {

            Brush.Ptr += Brush.BytesPerAccess;
            Brush.CacheState = Brush.CacheStateNewDWord;
            Brush.Cache = *(ULONG *)Brush.Ptr;
          }
          Brush.Value = Brush.Cache >> ((Brush.CacheState >> 16) ^ Brush.MaskShiftXor);
          Brush.CacheState += Brush.CacheStateIncrement;
        }

        // Use the mask to select between two ROPs.

        if (Mask.Ptr) {

          // 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;
          }
	  
          Rop3 = (Mask.Cache & (1 << ((Mask.CacheState >> 16) ^ Mask.MaskShiftXor))) ? UnmaskedRop3 : MaskedRop3;
          Mask.CacheState += Mask.CacheStateIncrement;
        }

        if (xShrinkStretch) {

          // Handle x Stretching.
          if (xStretch) {
						
            if (xAccum < 0) {   // Repeat this pixel

              xAccum += xDMinor;

              Mask.Ptr = PrevMaskPtr;
              Mask.Cache = PrevMaskCache;
              Mask.CacheState = PrevMaskCacheState;

              Source.Ptr = PrevSrcPtr;
              Source.Cache = PrevSrcCache;
              Source.CacheState = PrevSrcCacheState;
	    }
	    else {  // OK to move to next source pixel after this

              xAccum += xDMajor;

              PrevMaskPtr = Mask.Ptr;
              PrevMaskCache = Mask.Cache;
              PrevMaskCacheState = Mask.CacheState;

              PrevSrcPtr = Source.Ptr;
              PrevSrcCache = Source.Cache;
              PrevSrcCacheState = Source.CacheState;
            }
          }
          else {  // xShrink

            while (xAccum < 0) {  // Skip pixel(s)

              // Move to next Source pixel.

	      if (Source.Is24Bit) {	

                // Since 24-bit packed pixels cross dword boundaries:

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

                // Check bits remaining in src.Cache.

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

                  Source.Ptr += Source.BytesPerAccess;
                  Source.CacheState = Source.CacheStateNewDWord;
                                    
                  if (x != Width - 1) { 
                    Source.Cache = *(ULONG *)Source.Ptr;
                  }
		}

                Source.CacheState += Source.CacheStateIncrement;

⌨️ 快捷键说明

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