📄 line.c
字号:
PointCount--;
}
else {
PreviousPoint = &LastPoint;
CurrentPoint = PathData.pptfx;
}
for (Point = 0; Point <= PointCount; Point++) {
if (Point < PointCount) {
x1 = PreviousPoint->x;
y1 = PreviousPoint->y;
x2 = CurrentPoint->x;
y2 = CurrentPoint->y;
PreviousPoint = CurrentPoint++;
}
else {
LastPoint = PathData.pptfx[PathData.count - 1];
if (!(PathData.flags & PD_CLOSEFIGURE)) {
break;
}
x1 = LastPoint.x;
y1 = LastPoint.y;
x2 = StartPoint.x;
y2 = StartPoint.y;
}
// Use our rotations and flips to orient the line segment into octant
// 0.
Flags = 0;
if (x2 < x1) {
// Reflect across the x axis to make dx > 0.
x1 = -x1;
x2 = -x2;
Flags |= FL_FLIP_H;
}
if (y2 < y1) {
// Reflect across the y axis to make dy > 0.
y1 = -y1;
y2 = -y2;
Flags |= FL_FLIP_V;
}
if ((y2 - y1) > (x2 - x1)) {
// Reflect across y = x to make dx >= dy.
Swap(x1, y1);
Swap(x2, y2);
Flags |= FL_FLIP_D;
}
dM = x2 - x1;
dN = y2 - y1;
if (dM == dN) {
// Flag this line for slope == 1.
Flags |= FL_FLIP_SLOPE_ONE;
}
// Based on how we flipped the line, determine the rounding.
Flags |= RoundLookup[(Flags & FL_ROUND_MASK) >> FL_ROUND_SHIFT];
x = x1 >> 4;
y = y1 >> 4;
M1 = x1 & 0x0000000F;
N1 = y1 & 0x0000000F;
// Calculate remainder term.
Gamma = (dM * (N1 + 8) - dN * M1 - ((Flags & FL_V_ROUND_DOWN) ? 1 : 0)) >> 4;
Beta = ~Gamma;
// N1,M1 are 0..15 so this is ok if dM,dN < about 8 million pixels.
// Calculate N2,M2 - the fractional part of the line ends.
M2 = (M1 + dM) & 0x0000000F;
N2 = (N1 + dN) & 0x0000000F;
// x1,y1..x2,y2 are the integer parts of the line ends where the origin
// of the line is at 0.M1,0.N1.
// Thus x1 and y1 start off as 0 but may become 1 or 2 based on the
// exact starting point of the line to be rendered (and whether the
// last point is excluded)
x2 = ((M1 + dM) >> 4) - 1;
if (M2 > 0) {
if (N2 == 0) {
if (M2 > ((Flags & FL_H_ROUND_DOWN) ? 8 : 7 )) {
x2++;
}
}
else if (((N2 < 8) ? (8 - N2) : (N2 - 8)) <= M2) {
x2++;
}
}
x1 = 0;
if ((Flags & (FL_FLIP_SLOPE_ONE | FL_H_ROUND_DOWN)) == (FL_FLIP_SLOPE_ONE | FL_H_ROUND_DOWN)) {
if ((M2 > 0) && (N2 == M2 + 8)) {
x2--;
}
if ((M1 > 0) && (N1 == M1+8)) {
goto LeftToRightCompute_y1;
}
}
if (M1 > 0) {
if (N1 == 0) {
if (M1 > ((Flags & FL_H_ROUND_DOWN) ? 8 : 7)) {
x1 = 1;
}
}
else if (((N1 < 8) ? (8 - N1) : (N1 - 8)) <= M1) {
x1 = 1;
}
}
LeftToRightCompute_y1:
if (Gamma >= (LONG)(dM - (dN & (-(LONG)x1)))) {
ErrorTerm = Gamma + (dN & ~(x1 - 1)) - 2 * dM;
y1 = 1;
}
else {
ErrorTerm = Gamma + (dN & ~(x1 - 1)) - dM;
y1 = 0;
}
Gamma = ErrorTerm;
Beta = ~Gamma;
// Calculate length of unclipped line in pixels for style tracking.
StylePixels = x2 - x1 + 1;
if (StylePixels <= 0) {
// This line segment was too short to be visible!
continue;
}
// Normalize cliprect to origin.
CurOreintedClipRect = &OreintedClipRect[(Flags & FL_RECTLCLIP_MASK) >> FL_RECTLCLIP_SHIFT];
if (Flags & FL_FLIP_H) {
CurOreintedClipRect += 4;
}
Right = CurOreintedClipRect->right - x;
Left = CurOreintedClipRect->left - x;
Top = CurOreintedClipRect->top - y;
Bottom = CurOreintedClipRect->bottom - y;
if ((LONG)y1 >= Bottom ||
(LONG)x1 >= Right ||
(LONG)x2 < Left) {
// Totally clipped. (Note, we don't know y1 yet)
continue;
}
if ((LONG)x2 >= Right) {
x2 = Right - 1;
}
if (dM == 0 || dN == 0) {
if ((LONG)x1 < Left) {
x1 = (ULONG)Left;
}
if ((LONG)y1 < Top) {
continue;
}
y2 = y1;
}
else {
if ((LONG)x1 < Left) {
y1 = y1 + (ULONG)((Left - (LONG)x1) * dN + Gamma + dM) / dM;
x1 = (ULONG)Left;
if ((LONG)y1 >= Bottom) {
continue;
}
}
if ((LONG)y1 < Top) {
x1 = 1 + x1 + (ULONG)((Top - (LONG)y1 - 1) * dM - Gamma - 1) / dN;
y1 = (ULONG)Top;
if ((LONG)x1 >= Right) {
continue;
}
}
y2 = y1 + (ULONG)(((LONG)((x2 - x1) * dN) + Gamma + dM) / dM);
if ((LONG)y2 < Top) {
continue;
}
if ((LONG)y2 >= Bottom) {
y2 = (ULONG)(Bottom - 1);
x1 = (ULONG)(x1 + ((LONG)(y2 - y1) * dM - Gamma - 1) / dN);
if ((LONG)x2 < Left) {
continue;
}
}
}
// Unflip the endpoint coordinates
xStart = x + x1;
yStart = y + y1;
if (Flags & FL_FLIP_D) {
Swap (xStart, yStart);
}
if (Flags & FL_FLIP_V) {
yStart = -yStart;
}
if (Flags & FL_FLIP_H) {
xStart = -xStart;
}
Direction = ((Flags & FL_FLIP_V) ? 7 : 0) ^
((Flags & FL_FLIP_D) ? 1 : 0) ^
((Flags & FL_FLIP_H) ? 3 : 0);
PixelCount = x2 - x1 + 1;
if (PixelCount <= 0) {
// This can happen if line just touches cliprect.
continue;
}
Parameters.X = xStart;
Parameters.Y = yStart;
Parameters.PixelCount = PixelCount;
Parameters.dM = dM;
Parameters.dN = dN;
Parameters.Gamma = ErrorTerm;
Parameters.Direction = Direction;
FnRetVal = SoftwareLine(&Parameters);
if (!FnRetVal) {
MorePathData = FALSE;
break;
}
Parameters.StyleState = (Parameters.StyleState + StylePixels) & 31;
}
} while (MorePathData);
}
FreeSurfobjDerivedPerm3Surface(&Dest);
Exit(L"DrvStrokePath");
return FnRetVal;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -