Source code of Windows XP (NT5)
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.

128 lines
3.0 KiB

  1. /*************************************************************************\
  2. * Module Name: intline.c
  3. *
  4. * Copyright (c) 1993-1994 Microsoft Corporation
  5. * Copyright (c) 1992 Digital Equipment Corporation
  6. \**************************************************************************/
  7. #include "precomp.h"
  8. /******************************************************************************
  9. * bIntegerLine
  10. *
  11. * This routine attempts to draw a line segment between two points. It
  12. * will only draw if both end points are whole integers: it does not support
  13. * fractional endpoints.
  14. *
  15. * Returns:
  16. * TRUE if the line segment is drawn
  17. * FALSE otherwise
  18. *****************************************************************************/
  19. BOOL
  20. bIntegerLine (
  21. PDEV* ppdev,
  22. ULONG x1,
  23. ULONG y1,
  24. ULONG x2,
  25. ULONG y2
  26. )
  27. {
  28. BYTE* pjBase = ppdev->pjBase;
  29. LONG cBpp = ppdev->cBpp;
  30. LONG lDelta = ppdev->lDelta;
  31. LONG xyOffset = ppdev->xyOffset;
  32. ULONG ulDst;
  33. LONG dx;
  34. LONG dy;
  35. LONG fudge;
  36. BYTE jLineDrawCmd = (LINE_DRAW | LINE_USE_ERROR_TERM);
  37. LONG ErrorTerm;
  38. //
  39. // This code assumes that CP_PEL_DEPTH()
  40. // has been set to ((cBpp - 1) << 4)
  41. //
  42. // This is done in stroke.c before this routine is called.
  43. //
  44. // Unfortunately, I can't verify it with an ASSERT because values
  45. // in the queue cannot be read back.
  46. //
  47. x1 >>= 4;
  48. y1 >>= 4;
  49. x2 >>= 4;
  50. y2 >>= 4;
  51. dx = x2 - x1;
  52. dy = y2 - y1;
  53. if ((dx == 0) && (dy == 0))
  54. {
  55. goto ReturnTrue;
  56. }
  57. ulDst = (y1 * lDelta) + (cBpp * x1);
  58. ulDst += xyOffset;
  59. //
  60. // If dx and dy have different signs and the line is Y Major then
  61. // we'll have to adjust the Error Term by 1.
  62. //
  63. fudge = ((dx ^ dy) < 0)? 1:0;
  64. if (dx < 0)
  65. {
  66. ulDst += (cBpp-1);
  67. CP_PAT_ADDR(ppdev, pjBase, (ppdev->ulSolidColorOffset + cBpp -1));
  68. jLineDrawCmd |= LINE_X_NEG;
  69. dx = -dx;
  70. }
  71. if (dy < 0)
  72. {
  73. fudge = -fudge;
  74. jLineDrawCmd |= LINE_Y_NEG;
  75. dy = -dy;
  76. }
  77. WAIT_FOR_EMPTY_ACL_QUEUE(ppdev, pjBase);
  78. CP_DST_Y_OFFSET(ppdev, pjBase, (lDelta - 1));
  79. if (dx > dy)
  80. {
  81. // x major
  82. jLineDrawCmd |= LINE_X_MAJOR;
  83. ErrorTerm = dx;
  84. CP_XCNT(ppdev, pjBase, ((dx - 1) * cBpp));
  85. CP_YCNT(ppdev, pjBase, 0xfff);
  86. CP_DELTA_MINOR(ppdev, pjBase, dy);
  87. CP_DELTA_MAJOR(ppdev, pjBase, dx);
  88. }
  89. else
  90. {
  91. // y major
  92. ErrorTerm = dy - fudge;
  93. CP_XCNT(ppdev, pjBase, 0xfff);
  94. CP_YCNT(ppdev, pjBase, (dy - 1));
  95. CP_DELTA_MINOR(ppdev, pjBase, dx);
  96. CP_DELTA_MAJOR(ppdev, pjBase, dy);
  97. }
  98. CP_XY_DIR(ppdev, pjBase, jLineDrawCmd);
  99. CP_ERR_TERM(ppdev, pjBase, ErrorTerm);
  100. CP_DST_ADDR(ppdev, pjBase, ulDst);
  101. WAIT_FOR_EMPTY_ACL_QUEUE(ppdev, pjBase);
  102. CP_XY_DIR(ppdev, pjBase, 0);
  103. CP_PAT_ADDR(ppdev, pjBase, (ppdev->ulSolidColorOffset));
  104. ReturnTrue:
  105. return TRUE;
  106. }