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

📄 line.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Permedia3 Sample Display Driver
// line.c
//
// Copyright (c) 2000 Microsoft Corporation. All rights reserved.
//
// This file contains the GDI entry points for drawing lines, or unfilled
// shapes given as a set of edges. It currently does not hardware accelerate
// this operation, rather, it relies on the software graphics library's
// SoftwareLine routine.

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

// This is a dumb little helper macro.

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

// These constants are used as flags for storing line information.

#define FL_H_ROUND_DOWN         0x00000080     // .... .... 1... ....
#define FL_V_ROUND_DOWN         0x00008000     // 1... .... .... ....

#define FL_FLIP_D               0x00000005     // .... .... .... .1.1
#define FL_FLIP_V               0x00000008     // .... .... .... 1...
#define FL_FLIP_SLOPE_ONE       0x00000010     // .... .... ...1 ....
#define FL_FLIP_HALF            0x00000002     // .... .... .... ..1.
#define FL_FLIP_H               0x00000200     // .... ..1. .... ....

#define FL_ROUND_MASK           0x0000001C     // .... .... ...1 11..
#define FL_ROUND_SHIFT          2

#define FL_RECTLCLIP_MASK       0x0000000C     // .... .... .... 11..
#define FL_RECTLCLIP_SHIFT      2

#define FL_STRIP_MASK           0x00000003     // .... .... .... ..11
#define FL_STRIP_SHIFT          0

#define FL_SIMPLE_CLIP          0x00000020     // .... .... ..1. ....
#define FL_COMPLEX_CLIP         0x00000040     // .... .... .1.. ....
#define FL_CLIP                 (FL_SIMPLE_CLIP | FL_COMPLEX_CLIP)

#define FL_STYLED               0x00000400     // .... .1.. .... ....
#define FL_ALTERNATESTYLED      0x00001000     // ...1 .... .... ....

#define FL_STYLE_MASK           0x00000400
#define FL_STYLE_SHIFT          10

#define FL_LAST_PEL_INCLUSIVE   0x00002000     // ..1. .... .... ....

const ULONG RoundLookup[] = {
    FL_H_ROUND_DOWN | FL_V_ROUND_DOWN, // no flips
    FL_H_ROUND_DOWN | FL_V_ROUND_DOWN, // FL_FLIP_D
    FL_H_ROUND_DOWN,                   // FL_FLIP_V
    FL_V_ROUND_DOWN,                   // FL_FLIP_V | FL_FLIP_D
    FL_V_ROUND_DOWN,                   // FL_FLIP_SLOPE_ONE
    0xbaadf00d,                        // FL_FLIP_SLOPE_ONE | FL_FLIP_D
    FL_H_ROUND_DOWN,                   // FL_FLIP_SLOPE_ONE | FL_FLIP_V
    0xbaadf00d                         // FL_FLIP_SLOPE_ONE | FL_FLIP_V | FL_FLIP_D
};

BOOL
DrvStrokePath(
  SURFOBJ   * DestSurface,
  PATHOBJ   * Path,
  CLIPOBJ   * Clipper,
  XFORMOBJ  * Xform,
  BRUSHOBJ  * Brush,
  POINTL    * BrushOrigin,
  LINEATTRS * Attributes,
  MIX         Mix
  )
{
  // DrvStrokePath
  // This function is called by GDI when it needs to draw the outline of a
  // geometric shape, defined by a list of edges. ("Stroke a path" in GDI's
  // parlance.) 

  // Local variables.

  BOOL          FnRetVal = TRUE;
  LINE_PARAM    Parameters;
  PERM3_SURFACE Dest;
  LONG          DashNum;
  LONG          DashPixel;
  LONG          BitNum;
  LONG          BitVal;
  RECT        * ClipRect;
  BOOL          MoreClipRects;
  ENUMRECTS     ClipEnum;
  RECT          OreintedClipRect[8];
  RECT        * CurOreintedClipRect;
  BOOL          MorePathData;
  PATHDATA      PathData;
  ULONG         Point;
  ULONG         PointCount;
  POINTFIX      StartPoint;
  POINTFIX      LastPoint;
  POINTFIX    * PreviousPoint;
  POINTFIX    * CurrentPoint;
  ULONG         x, y;
  FIX           x1, y1, x2, y2;
  FIX           M1, M2;
  FIX           N1, N2;
  FIX           dN, dM;
  ULONG         Flags;
  LONG          Gamma;
  LONG          Beta;
  LONG          Left, Right, Top, Bottom;
  LONG          ErrorTerm;
  LONG          StylePixels;
  LONG          xStart, yStart;
  LONG          Direction;
  LONG          PixelCount;

  // Check parameters.

  // !TODO!

  Enter(L"DrvStrokePath");

  Assert(Brush->iSolidColor != 0xFFFFFFFF);

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

  // Fill in all of the line parameters that are constant along the path.

  Parameters.FillValue = Brush->iSolidColor;
  Parameters.Mix = (USHORT)Mix;
  
  SurfobjToPerm3Surface(&Dest,
                        DestSurface,
                        NULL,
                        FALSE);

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

  // Work out the line style. Windows CE only draws single pixel wide
  // lines, hence we do not worry about mitering, endcaps, and joining.

  Parameters.Style = 0;

  if (Attributes && (((Mix >> 8) & 0x00FF) != (Mix & 0x00FF))) {

    if (Attributes->fl & LA_ALTERNATE) {

      // Special case style, every other pixel on.

      Parameters.Style = 0xAAAAAAAA;
    }
    else if (Attributes->pstyle != NULL && 
             Attributes->cstyle != 0) {

      // Use the given style array to work out the style dword for the
      // software line rasterizer.

      for (DashNum = 0, BitNum = 0, BitVal = 0; 
           BitNum < 32;
           DashNum++) {

        DashNum %= Attributes->cstyle;

        for (DashPixel = 0;
             (DashPixel < Attributes->pstyle[DashNum].l) && (BitNum < 32);
             DashPixel++, BitNum++) {

          Parameters.Style |= (BitVal << BitNum);
        }

        BitVal ^= 1;

        if (DashNum == 64) {

          // All segments have 0 length

          Parameters.Style = 0;
          break;
        }
      }
    }
    if (Attributes->fl & LA_STARTGAP) {

      // First dash is actually a gap.

      Parameters.Style = ~Parameters.Style;
    }
  }

  // Deal with the line clipping.

  if ((Clipper == NULL) || (Clipper->iDComplexity == DC_TRIVIAL)) {

    ClipRect = NULL;
    MoreClipRects = FALSE;
  }
  else if (Clipper->iDComplexity == DC_RECT) {

    ClipRect = (RECT *)&(Clipper->rclBounds);
    MoreClipRects = FALSE;
  }
  else {

    MoreClipRects = TRUE;
  }

  // Iterate over the clip rectangles. (Just once if no list.)

  for (ClipEnum.c = 1 - (MoreClipRects ? 1 : 0);
       (ClipEnum.c != 0) || (MoreClipRects);
       ClipRect++, ClipEnum.c--) {

    if (ClipEnum.c == 0) {

      // Get the next rectangle from the clipper.

      MoreClipRects = CLIPOBJ_bEnum(Clipper,
                                    sizeof(ClipEnum),
                                    (ULONG *)&ClipEnum);
      ClipRect = (RECT *)ClipEnum.arcl;
      if (ClipEnum.c == 0) {
        continue;
      }
    }

    Parameters.StyleState = 0;

    // Now, fill out the OreintedClipRect array by precomputing all
    // possible flips and/or rotations.

    memcpy(&(OreintedClipRect[0]), ClipRect, sizeof(RECT));

    // FL_FLIP_D

    OreintedClipRect[1].top    = ClipRect->left;
    OreintedClipRect[1].left   = ClipRect->top;
    OreintedClipRect[1].bottom = ClipRect->right;
    OreintedClipRect[1].right  = ClipRect->bottom;

    // FL_FLIP_V

    OreintedClipRect[2].top    = -ClipRect->bottom + 1;
    OreintedClipRect[2].left   = ClipRect->left;
    OreintedClipRect[2].bottom = -ClipRect->top + 1;
    OreintedClipRect[2].right  = ClipRect->right;

    // FL_FLIP_V | FL_FLIP_D

    OreintedClipRect[3].top    =  ClipRect->left;
    OreintedClipRect[3].left   = -ClipRect->bottom + 1;
    OreintedClipRect[3].bottom =  ClipRect->right;
    OreintedClipRect[3].right  = -ClipRect->top + 1;

    // FL_FLIP_H

    OreintedClipRect[4].top    =  ClipRect->top;
    OreintedClipRect[4].left   =  -ClipRect->right + 1;
    OreintedClipRect[4].bottom =  ClipRect->bottom;
    OreintedClipRect[4].right  =  -ClipRect->left + 1;

    // FL_FLIP_H | FL_FLIP_D

    OreintedClipRect[5].top    =  -ClipRect->right + 1;
    OreintedClipRect[5].left   =  ClipRect->top;
    OreintedClipRect[5].bottom =  -ClipRect->left + 1;
    OreintedClipRect[5].right  =  ClipRect->bottom;

    // FL_FLIP_H | FL_FLIP_V

    OreintedClipRect[6].top    = -ClipRect->bottom + 1;
    OreintedClipRect[6].left   = -ClipRect->right + 1;
    OreintedClipRect[6].bottom = -ClipRect->top + 1;
    OreintedClipRect[6].right  = -ClipRect->left + 1;

    // FL_FLIP_H | FL_FLIP_V | FL_FLIP_D

    OreintedClipRect[7].top    =  -ClipRect->right + 1;
    OreintedClipRect[7].left   =  -ClipRect->bottom + 1;
    OreintedClipRect[7].bottom =  -ClipRect->left + 1;
    OreintedClipRect[7].right  =  -ClipRect->top + 1;

    // Loop through the line segments in the path.

    PATHOBJ_vEnumStart(Path);

    do {

      MorePathData = PATHOBJ_bEnum(Path, &PathData);

      PointCount = PathData.count;

      if (PointCount == 0) {
        break;
      }

      if (PathData.flags & PD_BEGINSUBPATH) {

        StartPoint = *PathData.pptfx;
        PreviousPoint = PathData.pptfx;
        CurrentPoint = PathData.pptfx + 1;

⌨️ 快捷键说明

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