Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

348 lines
11 KiB

/******************************************************************************\
*
* $Workfile: lineto.c $
*
* Contents:
* This file contains the DrvLineTo function and line drawing code for the
* CL-GD546x chips.
*
* Copyright (c) 1996 Cirrus Logic, Inc.
*
* $Log: X:/log/laguna/nt35/displays/cl546x/lineto.c $
*
* Rev 1.19 Mar 04 1998 15:27:54 frido
* Added new shadow macros.
*
* Rev 1.18 Feb 27 1998 15:43:14 frido
* Roll back of 1.16.
* Removed sloped lines.
*
* Rev 1.17 Feb 26 1998 17:16:32 frido
* Removed diagonal line drawing.
* Optimized horizontal and vertical line drawing.
*
* Rev 1.16 Jan 26 1998 09:59:12 frido
* A complete rewrite. Ported most code from Alpine NT driver (I already did
* most of the work for that driver) and fixed all bugs in it.
*
* Rev 1.15 Nov 03 1997 15:46:04 frido
* Added REQUIRE macros.
*
* Rev 1.14 08 Apr 1997 12:25:36 einkauf
*
* add SYNC_W_3D to coordinat MCD/2D hw access
*
*
* Rev 1.13 21 Mar 1997 11:43:20 noelv
*
* Combined 'do_flag' and 'sw_test_flag' together into 'pointer_switch'
*
* Rev 1.12 04 Feb 1997 10:38:34 SueS
* Added another ifdef to the punt condition, because there's a hardware
* bug in the 2D clip engine.
*
* Rev 1.11 27 Jan 1997 13:08:36 noelv
* Don't compile hardware clipping for 5464 chip.
*
* Rev 1.10 27 Jan 1997 07:58:06 SueS
* Punt for the 5462/64. There was a problem with clipping on the 62.
*
* Rev 1.9 23 Jan 1997 15:25:34 SueS
* Added support for hardware clipping in the 5465. For all 546x family,
* punt on complex clipping.
*
* Rev 1.8 10 Jan 1997 17:23:48 SueS
* Reenabled DrvLineTo. Modified clipping function. Added boundary
* condition tests.
*
* Rev 1.7 08 Jan 1997 14:40:48 SueS
* Temporarily punt on all DrvLineTo calls.
*
* Rev 1.6 08 Jan 1997 09:33:24 SueS
* Punt in DrvLineTo for complex clipping.
*
* Rev 1.5 06 Jan 1997 10:32:06 SueS
* Modified line drawing functions so that clipping is applied properly, and
* so that pixels for lines with y as the driving axis drawn from top to
* bottom will now be calculated correctly. Changed debug statements to hex.
*
* Rev 1.4 26 Nov 1996 10:43:02 noelv
* Changed debug level.
*
* Rev 1.3 26 Nov 1996 10:01:22 noelv
*
* Changed Debug prints.
*
* Rev 1.2 06 Sep 1996 15:16:26 noelv
* Updated NULL driver for 4.0
*
* Rev 1.1 28 Aug 1996 17:25:04 noelv
* Added #IFDEF to prevent this file from being compiled into 3.51 driver.
*
* Rev 1.0 20 Aug 1996 11:38:46 noelv
* Initial revision.
*
* Rev 1.0 18 Aug 1996 22:52:18 frido
* Ported from CL-GD5446 code.
*
\******************************************************************************/
#include "PreComp.h"
#define LINETO_DBG_LEVEL 1
#define LEFT 0x01
#define RIGHT 0x02
#define TOP 0x04
#define BOTTOM 0x08
extern BYTE Rop2ToRop3[];
extern USHORT mixToBLTDEF[];
//
// This file isn't used in NT 3.51
//
#ifndef WINNT_VER35
/******************************************************************************\
*
* Function: DrvLineTo
*
* This function draws a line between any two points. This function only draws
* lines in solid colors and are just 1 pixel wide. The end-point is not drawn.
*
* Parameters: pso Pointer to surface.
* pco Pointer to CLIPOBJ.
* pbo Pointer to BRUSHOBJ.
* x1 Starting x-coordinate.
* y1 Starting y-coordinate.
* x2 Ending x-coordinate.
* y2 Ending y-coordinate.
* prclBounds Pointer to an unclipped bounding rectangle.
* mix Mix to perform on the destination.
*
* Returns: TRUE if the line has been drawn, FALSE otherwise.
*
\******************************************************************************/
BOOL DrvLineTo(
SURFOBJ* pso,
CLIPOBJ* pco,
BRUSHOBJ* pbo,
LONG x1,
LONG y1,
LONG x2,
LONG y2,
RECTL* prclBounds,
MIX mix)
{
PDEV* ppdev;
ULONG ulColor;
BYTE iDComplexity;
LONG dx, dy;
BYTE bCode1 = 0, bCode2 = 0;
RECTL rclClip1, rclClip2;
#if NULL_LINETO
{
if (pointer_switch)
{
return(TRUE);
}
}
#endif
DISPDBG((LINETO_DBG_LEVEL, "DrvLineTo: %x,%x - %x,%x\n", x1, y1, x2, y2));
ppdev = (PDEV*) pso->dhpdev;
SYNC_W_3D(ppdev);
if (pso->iType == STYPE_DEVBITMAP)
{
DSURF* pdsurf = (DSURF*) pso->dhsurf;
// If the device bitmap is located in memory, try copying it back to
// off-screen.
if ( pdsurf->pso && !bCreateScreenFromDib(ppdev, pdsurf) )
{
return(EngLineTo(pdsurf->pso, pco, pbo, x1, y1, x2, y2, prclBounds,
mix));
}
ppdev->ptlOffset = pdsurf->ptl;
}
else
{
ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0;
}
// Punt complex clipping.
iDComplexity = (pco == NULL) ? DC_TRIVIAL : pco->iDComplexity;
if (iDComplexity == DC_COMPLEX)
{
DISPDBG((LINETO_DBG_LEVEL, " Complex clipping: punt\n"));
return(FALSE);
}
// Set line deltas.
dx = x2 - x1;
dy = y2 - y1;
// We only handle horizontal and vertical lines.
if ( (dx != 0) && (dy != 0) )
{
return(FALSE);
}
// Test for zero deltas.
if ( (dx == 0) && (dy == 0) )
{
return(TRUE);
}
// Clip the coordinates.
if (iDComplexity == DC_RECT)
{
// Set clipping rectangles.
rclClip1.left = pco->rclBounds.left;
rclClip1.top = pco->rclBounds.top;
rclClip1.right = pco->rclBounds.right - 1;
rclClip1.bottom = pco->rclBounds.bottom - 1;
rclClip2.left = pco->rclBounds.left - 1;
rclClip2.top = pco->rclBounds.top - 1;
rclClip2.right = pco->rclBounds.right;
rclClip2.bottom = pco->rclBounds.bottom;
// Set line flags.
if (x1 < rclClip1.left) bCode1 |= LEFT;
if (y1 < rclClip1.top) bCode1 |= TOP;
if (x1 > rclClip1.right) bCode1 |= RIGHT;
if (y1 > rclClip1.bottom) bCode1 |= BOTTOM;
if (x2 < rclClip2.left) bCode2 |= LEFT;
if (y2 < rclClip2.top) bCode2 |= TOP;
if (x2 > rclClip2.right) bCode2 |= RIGHT;
if (y2 > rclClip2.bottom) bCode2 |= BOTTOM;
if ((bCode1 & bCode2) != 0)
{
// The line is completely clipped.
return(TRUE);
}
// Vertical line.
if (dx == 0)
{
if (bCode1 & TOP)
{
y1 = rclClip1.top;
}
else if (bCode1 & BOTTOM)
{
y1 = rclClip1.bottom;
}
if (bCode2 & TOP)
{
y2 = rclClip2.top;
}
else if (bCode2 & BOTTOM)
{
y2 = rclClip2.bottom;
}
}
// Horizontal line.
else
{
if (bCode1 & LEFT)
{
x1 = rclClip1.left;
}
else if (bCode1 & RIGHT)
{
x1 = rclClip1.right;
}
if (bCode2 & LEFT)
{
x2 = rclClip2.left;
}
else if (bCode2 & RIGHT)
{
x2 = rclClip2.right;
}
}
if (bCode1 | bCode2)
{
// Recalculate line deltas.
dx = x2 - x1;
dy = y2 - y1;
}
}
// Get the color from the brush.
ASSERTMSG(pbo, "Null brush in DrvLineTo!\n");
ulColor = pbo->iSolidColor;
REQUIRE(9);
// If we have a color here we need to setup the hardware.
if (ulColor != 0xFFFFFFFF)
{
// Expand the color.
switch (ppdev->ulBitCount)
{
case 8:
ulColor |= ulColor << 8;
case 16:
ulColor |= ulColor << 16;
}
LL_BGCOLOR(ulColor, 2);
// Convert mix to ternary ROP.
ppdev->uRop = Rop2ToRop3[mix & 0xF];
ppdev->uBLTDEF = mixToBLTDEF[mix & 0xF];
}
LL_DRAWBLTDEF((ppdev->uBLTDEF << 16) | ppdev->uRop, 2);
// Horizontal line.
if (dy == 0)
{
if (dx > 0)
{
// From left to right.
//above REQUIRE(5);
LL_OP0(x1 + ppdev->ptlOffset.x, y1 + ppdev->ptlOffset.y);
LL_BLTEXT(dx, 1);
}
else
{
// From right to left.
//above REQUIRE(5);
LL_OP0(x2 + 1 + ppdev->ptlOffset.x, y2 + ppdev->ptlOffset.y);
LL_BLTEXT(-dx, 1);
}
}
// Vertical line.
else
{
if (dy > 0)
{
// From top to bottom.
//above REQUIRE(5);
LL_OP0(x1 + ppdev->ptlOffset.x, y1 + ppdev->ptlOffset.y);
LL_BLTEXT(1, dy);
}
else
{
// From bottom to top.
//above REQUIRE(5);
LL_OP0(x2 + ppdev->ptlOffset.x, y2 + 1 + ppdev->ptlOffset.y);
LL_BLTEXT(1, -dy);
}
}
return(TRUE);
}
#endif // !WINNT_VER35