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

📄 brush.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
字号:
//
// Permedia3 Sample Display Driver
// brush.c
//
// Copyright (c) 2000 Microsoft Corporation. All rights reserved.
//
// This module includes the source code necessary to support GDI brushes.

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

BOOL
DrvRealizeBrush(
  BRUSHOBJ * Brush,
  SURFOBJ  * TargetSurface,
  SURFOBJ  * PatternSurface,
  SURFOBJ  * MaskSurface,
  XLATEOBJ * Xlate,
  ULONG      Hatch
  )
{
  // DrvRealizeBrush
  // GDI calls this function when it needs to convert a brush into a format
  // that the driver can use. 

  // Local variables.

  BOOL            FnRetVal = FALSE;
  PERM3_SURFACE   Target;
  PERM3_SURFACE   Pattern;
  PERM3_SURFACE * RBrush;
  LONG            RBrushStride;
  ULONG           BytesForRBrush;
  PERM3_BLT_PARAM Parameters;
  PERM3_FORMAT  * Format;
  ULONG         * Masks;
  RECT            DestRect;
  RECT            SourceRect;
  ULONG           SizeofMaskArray;

  // Check parameters.

  // !TODO! Finish parameter check.

  // Neither of these parameters is used by Windows CE.

  Assert(Xlate != NULL);
  Assert(MaskSurface == NULL);
  Assert(Hatch == 0);

  Enter(L"DrvRealizeBrush");

  SurfobjToPerm3Surface(&Target,
                        TargetSurface,
                        Xlate,
                        FALSE);

  SurfobjToPerm3Surface(&Pattern,
                        PatternSurface,
                        Xlate,
                        TRUE);

  // Our realized brush will use the dimensions from the "Pattern" surface and
  // same pixel format as the "Target" surface. As such, we must copy the
  // masks or palette from the "Target" surface. We know that all FORMAT *
  // actually point to PERM3_FORMAT *, so this cast is legal.

  SizeofMaskArray = GetSizeofPaletteMasks((const PERM3_FORMAT *)Target.Format);

  // We need to allocate the bits for the realized brush along with
  // the brush data structure becasue GDI does not call us when it
  // deallocate this. It is done automatically.

  RBrushStride = Pattern.Size.cx * Target.Format->BitsPerPixel / 8;

  // This can happen with very small 1 Bpp patterns. The blitting code that
  // we are about to call requires at least 4 bytes per scanline, as it does
  // ULONG fetchs on each line.

  if (RBrushStride < 4) {

    RBrushStride = 4;
  }

  BytesForRBrush = (RBrushStride * Pattern.Size.cy) + 4 +
                   sizeof(PERM3_FORMAT) +
                   sizeof(PERM3_SURFACE) +
                   SizeofMaskArray;

  // This call also associates this lump of memory with the given brush.
  // We need only initialize that memory correctly to be finished.

  RBrush = BRUSHOBJ_pvAllocRbrush(Brush, BytesForRBrush);

  memset(RBrush, 0, sizeof(PERM3_SURFACE));

  if (RBrush != NULL ) {

    // Setup the format and mask pointers. 

    Format = (PERM3_FORMAT *)(((BYTE *)RBrush) + sizeof(PERM3_SURFACE));
    Masks = (ULONG *)(((BYTE *)Format) + sizeof(PERM3_FORMAT));

    // Copy the relevant data in from the target surface.

    Format->BitsPerPixel = Target.Format->BitsPerPixel;
    Format->FourCC = Target.Format->FourCC;

    memcpy(Masks,
           Target.Format->Masks,
           SizeofMaskArray);

    // The PERM3_FORMAT and masks will be freed when all of the brush
    // memory is freed.

    Format->FreePaletteMasks = FALSE;
    Format->Masks = Masks;
      
    RBrush->FreeFormat = FALSE;
    RBrush->Format = (const FORMAT *)Format;
 
    memcpy(&RBrush->Size, &Pattern.Size, sizeof(SIZE));
    RBrush->Stride = RBrushStride;

    // Make sure the brush surface is 32 bit aligned.

    RBrush->Ptr = (LPVOID)((((DWORD)Format->Masks + SizeofMaskArray) & 0xFFFFFFFC) + 4);
    RBrush->BitmapHandle = 0;
    RBrush->Type = SystemMemory;

    // Use a SRCCOPY blit to copy the bits from the pattern to the
    // realized brush. This will color convert from the "Pattern"
    // pixel format to the "realized" "Target" format.

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

    Parameters.Rop = 0xCCCC;  // SRCCOPY

    Parameters.Destination = (const SURFACE *)RBrush;
    Parameters.Source = (const SURFACE *)&Pattern;

    DestRect.top = 0;
    DestRect.left = 0;
    DestRect.bottom = RBrush->Size.cy;
    DestRect.right = RBrush->Size.cx;

    Parameters.DestRect = &DestRect;

    SourceRect.top = 0;
    SourceRect.left = 0;
    SourceRect.bottom = Pattern.Size.cy;
    SourceRect.right = Pattern.Size.cx;

    Parameters.SourceRect = &SourceRect;

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

    FnRetVal = TryBothBlt(&Parameters);
  } 
  else {
 
    Error(L"BRUSHOBJ_pvAllocRbrush failed.\n");
  }

  FreeSurfobjDerivedPerm3Surface(&Target);
  FreeSurfobjDerivedPerm3Surface(&Pattern);

  Exit(L"DrvRealizeBrush");  
  
  return FnRetVal;
}

void
HwBrush(
  PERM3_BLT_PARAM * Parameters
  )
{
  // HwBrush
  // This function, loads pattern, or brush, as specified in the blit parameter
  // structure, into the hardware. This needs to be called in a DMA block of
  // appropriate size.

  // Local variables.

  ULONG   DataUlongCount;
  ULONG * BrushData;
  ULONG   i;

  // Check parameters.

  // !TODO!

  Enter(L"HwBrush");

  Assert(Parameters->Brush->Stride > 0);
  Assert(IsSameFormat(Parameters->Brush->Format, 
                      (const FORMAT *)GetDisplayModeFormat(GetCurrentMode())));

  // Some locals to help out in the actual loop that queues the data.

  BrushData = (ULONG *)Parameters->Brush->Ptr;

  // This cast is protected by the assertion above. We always realize brushes
  // with positive slopes.

  DataUlongCount = (ULONG)Parameters->Brush->Stride * 
                   Parameters->Brush->Size.cy / 4;

  // We don't allow brushes of any size but 8x8.

  Assert(Parameters->BrushOrigin->x < 8);
  Assert(Parameters->BrushOrigin->y < 8);

  // Enable the LUT, and set the pattern origin.

  WriteRegUlong(r_LUTMode,
                b_LUTMode_Enable                   |
                (1 << 8)                           |  // SpanOperation = SpanPattern
                (Parameters->BrushOrigin->x << 12) |
                (Parameters->BrushOrigin->y << 15) |
                b_LUTMode_SpanVCXAlignment);

  // If we did pattern caching, we might want to load a different index here.

  WriteRegUlong(r_LUTIndex, 0);

  // Move the data into the LUT in ulongs. This works because we know that
  // we will always be moving 8x8 surfaces: even if the surface is 8bpp, the
  // data is still some multiple of 32 bit values. We also know that
  // DrvRealizeBrush has converted the data to the same format as the screen.

  for (i = 0; i < DataUlongCount; i++) {
    WriteRegUlong(r_LUTData, *(BrushData + i));
  }

  Exit(L"HwBrush");
}

⌨️ 快捷键说明

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