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

📄 blt.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Permedia3 Sample Display Driver
// blt.c
//
// Copyright (c) 2000 Microsoft Corporation. All rights reserved.
//
// This code contains the various GDI and DirectDraw entry points for blitting,
// as well as our hardware accelerated blitting functions.

#include "pch.h"  // Precompiled header support.
#include "debug.h"
#include "struct.h"
#include "proto.h"
#include "register.h"

// Used to report that no Permedia3 logicop is appropriate for the given
// Rop3.

#define NO_APPROPRIATE_OP 16

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

static USHORT
LookupLogicop(
  BYTE Rop3
  );

static void
UploadBitMask(
  const PERM3_SURFACE * Mask,
  const RECT          * Rect
  );

BOOL
DrvBitBlt(
  SURFOBJ  * DestSurface,
  SURFOBJ  * SourceSurface,
  SURFOBJ  * MaskSurface,
  CLIPOBJ  * Clipper,
  XLATEOBJ * Xlate,
  RECTL    * DestRect,
  POINTL   * SourceTopLeft,
  POINTL   * MaskTopLeft,
  BRUSHOBJ * Brush,
  POINTL   * BrushOrigin,
  ROP4       Rop
  )
{
  // DrvBitBlt
  // This function peforms a GDI BitBlt. It is capable of all ROPs, including
  // masked blits. It can express color conversion blits, blits with clipping,
  // and blits with brushes, and text out through a special ROP code.
  // This is implemented in terms of DrvAnyBlt.

  // Stretch blits, color keying and alpha blending are not expressable.

  // Local variables.

  RECT SourceRect;
  BOOL FnRetVal;  // Return value for this function.

  // Check parameters.

  Assert(sizeof(RECT) == sizeof(RECTL));

  // !TODO! Finish parameter check.

  Enter(L"DrvBitBlt");

  // Put together the source rectangle.

  if (SourceTopLeft) {
    SourceRect.left = SourceTopLeft->x;
    SourceRect.top = SourceTopLeft->y;
  }
  else {
    SourceRect.left = 0;
    SourceRect.top = 0;
  }

  // Rely on the fact that a RECT is rely the same as a RECTL. This is
  // asserted above.

  SourceRect.right = SourceRect.left + RectWidth((RECT *)DestRect);
  SourceRect.bottom = SourceRect.top + RectHeight((RECT *)DestRect);

  // Do the blit.

  FnRetVal = DrvAnyBlt(DestSurface,
                       SourceSurface,
                       MaskSurface,
                       Clipper,
                       Xlate,
                       NULL,  // No OrginTopLeft...
                       DestRect,
                       (RECTL *)&SourceRect,
                       MaskTopLeft,
                       Brush,
                       BrushOrigin,
                       Rop,
                       0,  // No Mode...
                       0);  // No Flags

  Exit(L"DrvBitBlt");

  return FnRetVal;
}

BOOL 
DrvAnyBlt(
  SURFOBJ  * DestSurface,
  SURFOBJ  * SourceSurface,
  SURFOBJ  * MaskSurface,
  CLIPOBJ  * Clipper,
  XLATEOBJ * Xlate,
  POINTL   * OriginTopLeft,
  RECTL    * DestRect,
  RECTL    * SourceRect,
  POINTL   * MaskTopLeft,
  BRUSHOBJ * Brush,
  POINTL   * BrushOrigin,
  ROP4       Rop,
  ULONG      Mode,
  ULONG	     Flags
  )
{
  // DrvAnyBlt
  // This function peforms a GDI Blit. It is capable of all ROPs, including
  // masked blits. It can express color conversion blits, blits with clipping,
  // and blits with brushes, text out through a special ROP code, and stretch
  // blits.

  // Color keying and alpha blending are not expressable.

  // Local variables.

  PERM3_BLT_PARAM Parameters;
  PERM3_SURFACE   Dest;
  RECT            LocalDestRect;
  PERM3_SURFACE   Source;
  RECT            LocalSourceRect;
  PERM3_SURFACE * BrushSurface;
  RECT            BrushRect;
  POINT           LocalBrushOrigin;
  RECT            MaskRect;
  PERM3_SURFACE   Mask;
  BOOL            FnRetVal;  // This is the return value from the function.
  XLATEOBJ      * FixedXlate;
  ENUMRECTS     * ClipperRects = NULL;
  ULONG           SizeofClipperRects;
  ULONG           ClipperSortDirection = CD_ANY;

  // Check parameters.

  Assert(sizeof(SIZE) == sizeof(SIZEL));
  Assert(sizeof(RECT) == sizeof(RECTL));
  Assert(sizeof(POINT) == sizeof(POINTL));

  // !TODO! Change this once we return something real from DrvEnablePDEV.

  Assert((ULONG)DestSurface->dhpdev == 123);

  // !TODO! Finish parameter check.

  Enter(L"DrvAnyBlt");

  memset(&Parameters, 0, sizeof(PERM3_BLT_PARAM));

  // GDI, in all of it's magnificent stupidity, will pass us a bogus XLATEOBJ
  // when we don't need it, as opposed to NULL. Work around this by detecting
  // the conditions where bogusness might occur.

  FixedXlate = (SourceSurface != NULL) ? Xlate : NULL;

  // Fill in Parameters.

  Parameters.Rop = Rop;

  SurfobjToPerm3Surface(&Dest,
                        DestSurface,
                        FixedXlate,
                        FALSE);

  Parameters.Destination = (const SURFACE *)&Dest;

  if (DestRect != NULL) {

    // We know that RECT and RECL are really the same thing. The assert above
    // protects this.

    Parameters.DestRect = (RECT *)DestRect;
  }
  else {

    LocalDestRect.left = 0;
    LocalDestRect.top = 0;
    LocalDestRect.right = Dest.Size.cx;
    LocalDestRect.bottom = Dest.Size.cy;
    Parameters.DestRect = &LocalDestRect;
  }

  // Reject blits that have no height or width.

  if (Parameters.DestRect->top == Parameters.DestRect->bottom ||
      Parameters.DestRect->left == Parameters.DestRect->right) {

    return TRUE;
  }

  // Default to left-down blitting.

  Parameters.ScanXPositive = TRUE;
  Parameters.ScanYPositive = TRUE;

  // Source surface details.

  if (SourceSurface != NULL) {

    SurfobjToPerm3Surface(&Source,
                          SourceSurface,
                          FixedXlate,
                          TRUE);

    Parameters.Source = (const SURFACE *)&Source;

    if (SourceRect != NULL) {

      // We know that RECT and RECL are really the same thing. The assert above
      // protects this.

      Parameters.SourceRect = (RECT *)SourceRect;
    }
    else {

      LocalSourceRect.left = 0;
      LocalSourceRect.top = 0;
      LocalSourceRect.right = Source.Size.cx;
      LocalSourceRect.bottom = Source.Size.cy;
      Parameters.SourceRect = &LocalSourceRect;
    }

    // Check for an overlap, and set the blitting direction appropriately.

    if (Source.Ptr == Dest.Ptr) {

      if (Parameters.SourceRect->bottom > Parameters.DestRect->top &&
          Parameters.SourceRect->top < Parameters.DestRect->bottom &&
          Parameters.SourceRect->right > Parameters.DestRect->left &&
          Parameters.SourceRect->left < Parameters.DestRect->right) {

        if (Parameters.SourceRect->top == Parameters.DestRect->top) {

          // Horizontal blt, just set ScanXPositive appropriately.

          Parameters.ScanXPositive = (BOOL)(Parameters.SourceRect->left >= Parameters.DestRect->left);
        }
        else {

          // Non horizontal blts, just set ScanYPositive appropriately.

          Parameters.ScanYPositive = (BOOL)(Parameters.SourceRect->top >= Parameters.DestRect->top);
        }

        // Might need particular clipping rectangles sort order.

        if (Clipper) {

          if (Parameters.SourceRect->top > Parameters.DestRect->top) {

            ClipperSortDirection = (Parameters.SourceRect->left > Parameters.DestRect->left) ? CD_RIGHTDOWN : CD_LEFTDOWN;
          }
          else {
          
            ClipperSortDirection = (Parameters.SourceRect->left > Parameters.DestRect->left) ? CD_RIGHTUP : CD_LEFTUP;
          }
        }

      }
    }
  }
  else {

    // It's possible there is no source surface. We know that the memset above
    // has set all pertanent parameters to 0, NULL, so we're good to go.
  }

  // Handle the brush for pattern blits.

  if (Brush) {

    if (Brush->iSolidColor == 0xFFFFFFFF) {    

      Parameters.PatternType = BitmapPattern;

      // Get the brush surface and transfer the appropriate details into
      // the parameters structure.

      if (Brush->pvRbrush == NULL) {

        BrushSurface = (PERM3_SURFACE *)(BRUSHOBJ_pvGetRbrush(Brush));
        // !TODO! Check return code?
      }
      else {

        BrushSurface = (PERM3_SURFACE *)(Brush->pvRbrush);
      }

      Parameters.Brush = (const SURFACE *)BrushSurface;

      BrushRect.left = 0;
      BrushRect.top = 0;

      BrushRect.right  = Parameters.Brush->Size.cx;
      BrushRect.bottom = Parameters.Brush->Size.cy;

      Parameters.BrushRect = &BrushRect;

      if (BrushOrigin) {

        Parameters.BrushOrigin = (POINT *)BrushOrigin;
      }
      else {

        LocalBrushOrigin.x = 0;
        LocalBrushOrigin.y = 0;

        Parameters.BrushOrigin = &LocalBrushOrigin;
      } 
    }
    else {

      Parameters.PatternType = SolidPattern;
      Parameters.FillValue = Brush->iSolidColor;
    }
  }

  if (MaskSurface) {

    // We only support 1bpp masks.

    Assert(MaskSurface->iBitmapFormat == BMF_1BPP);

    SurfobjToPerm3Surface(&Mask,
                          MaskSurface,
                          NULL,
                          FALSE);

    Parameters.Mask = (const SURFACE *)&Mask;

    // Sometimes, mask surfaces are given to us with a size of (0,0) This
    // might trip up our blitting code later, so in such a case, we will
    // replace with the height and width of the destination rectnagle.

    if (Mask.Size.cx == 0 || Mask.Size.cy == 0) {

      // Rely on the fact that a RECT is rely the same as a RECTL. This is
      // asserted above.

      Mask.Size.cx = RectWidth((RECT *)DestRect);
      Mask.Size.cy = RectHeight((RECT *)DestRect);
    }

    // Build the rectangle of the mask to be used in the blit from the size
    // and the given top-left.

    if (MaskTopLeft) {
      MaskRect.left = MaskTopLeft->x;
      MaskRect.top = MaskTopLeft->y;
    }
    else {
      MaskRect.left = 0;
      MaskRect.top = 0;
    }

    MaskRect.right = MaskRect.left + Mask.Size.cx;
    MaskRect.bottom = MaskRect.top + Mask.Size.cy;

    Parameters.MaskRect = &MaskRect;
  }

  if (Clipper && Clipper->iDComplexity != DC_TRIVIAL) {

    if (Clipper->iDComplexity == DC_RECT) {

      // Sometimes GDI wants us to clip to the dimensions of the destination
      // surface: which is implicit, and should not be specified as a clip
      // rectangle.

      if (!(Clipper->rclBounds.left == 0 &&
            Clipper->rclBounds.top == 0 &&
            Clipper->rclBounds.right == Parameters.Destination->Size.cx &&
            Clipper->rclBounds.bottom == Parameters.Destination->Size.cy)) {
 
        Parameters.ClipRectCount = 1;
        Parameters.ClipRect = (const RECT *)&(Clipper->rclBounds);
      }
    }
    else if (Clipper->iDComplexity == DC_COMPLEX) {

      // Extract all of the rectangles from GDI.

      Parameters.ClipRectCount = CLIPOBJ_cEnumStart(Clipper,
                                                    TRUE,
                                                    CT_RECTANGLES,
                                                    ClipperSortDirection,
                                                    0);

      // The ENUMRECTS strcuture already contains space for 1 rectangle.

      SizeofClipperRects = sizeof(ENUMRECTS) +
                           sizeof(RECT) * (Parameters.ClipRectCount - 1);
      ClipperRects = SystemAlloc(SizeofClipperRects);
      if (ClipperRects) {

        CLIPOBJ_bEnum(Clipper,
                      SizeofClipperRects,
                      (ULONG *)ClipperRects);

        Assert(ClipperRects->c == Parameters.ClipRectCount);

        Parameters.ClipRect = (const RECT *)ClipperRects->arcl;
      }
      else {

        Error(L"System memory allocation failure.\n");
      }
    }
    else {
      Error(L"Unknown clipping complexity.\n");
    }
  }

  // Call the Blt with our newly constructed parameter block.

  FnRetVal = TryBothBlt(&Parameters);

  FreeSurfobjDerivedPerm3Surface(&Dest);

  if (SourceSurface) {
    FreeSurfobjDerivedPerm3Surface(&Source);
  }

  if (MaskSurface) {
    FreeSurfobjDerivedPerm3Surface(&Mask);
  }

  if (ClipperRects) {
    SystemFree(ClipperRects);
  }

  Exit(L"DrvAnyBlt");

  return FnRetVal;
}

BOOL 
DrvTransparentBlt(
  SURFOBJ  * DestSurface,
  SURFOBJ  * SourceSurface,
  CLIPOBJ  * Clipper,
  XLATEOBJ * Xlate,
  RECTL    * DestRect,
  RECTL    * SourceRect,
  ULONG      TransColor
  )
{

⌨️ 快捷键说明

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