Listing 1: Implementing ODF dashed lines on the Macintosh
void MacDrawDashLineTo(short h, short v, SDashInfo* dashInfo)
{
PenState ps;
GetPenState(&ps);
// Compute line's horizontal and vertical deltas
short dh = h - ps.pnLoc.h;
short dv = v - ps.pnLoc.v;
// We will need this many steps along the line
short steps = FW_Maximum(FW_Absolute(dh), FW_Absolute(dv));
// Each step will move us this much along the line
FW_CFixed fxHStep = FW_IntToFixed(dh) / FW_IntToFixed(steps);
FW_CFixed fxVStep = FW_IntToFixed(dv) / FW_IntToFixed(steps);
// Compute the distance along the line
FW_CFixed fxLength;
if (dh == 0)
fxLength = FW_IntToFixed(FW_Absolute(dv));
else if (dv == 0)
fxLength = FW_IntToFixed(FW_Absolute(dh));
else
{
// Fixed point square root
ODWide w;
w.lo = 0;
w.hi = dh * dh + dv * dv;
fxLength = FW_ODFixedToFixed(ODWideSquareRoot(&w));
}
// Each iteration will move this much aloing the line
FW_CFixed fxStep = fxLength / FW_IntToFixed(steps);
FW_CFixed fxDist = FW_kFixed0;
FW_CFixed fxHCur = FW_IntToFixed(ps.pnLoc.h);
FW_CFixed fxVCur = FW_IntToFixed(ps.pnLoc.v);
FW_Boolean drawCurSeg = TRUE; // first segment will be a dash
short curSegN = 0;
FW_Fixed fxCurSeg = FW_IntToFixed(dashInfo->fDashes[curSegN]);
// Now go through the line and draw the dashes
while (steps -- > 0)
{
fxHCur += fxHStep;
fxVCur += fxVStep;
fxDist += fxStep;
if (fxDist >= fxCurSeg)
{
// At the end of current segment: draw the dash
if (drawCurSeg)
LineTo(fxHCur.AsInt(),fxVCur.AsInt());
else
MoveTo(fxHCur.AsInt(),fxVCur.AsInt());
// Move on to the next segment
drawCurSeg = !drawCurSeg;
fxDist = 0;
curSegN = (curSegN + 1) % dashInfo->fDashCount;
fxCurSeg = FW_IntToFixed(dashInfo->fDashes[fCurSegN]);
}
}
// Draw the last dash, if any
if (drawCurSeg)
LineTo(fxHCur.AsInt(),fxVCur.AsInt());
}