b:
REF MaskRep.bitmap =>
TRUSTED {
sMask: Mask ← mask.InlineShift[-dest.sMin, -dest.fMin];
sMin: NAT ← MAX[sMask.sMin, 0];
sMax: NAT ← MIN[dest.sSize, b.lines, sMask.sMin + sMask.sSize];
fMin: NAT ← MAX[sMask.fMin, 0];
fMax: NAT ← MIN[dest.fSize, b.rast*Environment.bitsPerWord, sMask.fMin + sMask.fSize];
nextPixel: ImagerBasic.Pair ← ImagerTransform.InverseTransformVec[[0, 1], transformation];
nextLine: ImagerBasic.Pair ← ImagerTransform.InverseTransformVec[[1, 0], transformation];
start: ImagerBasic.Pair ← ImagerTransform.InverseTransform[[0.5+sMin+dest.sMin, 0.5+fMin+dest.fMin], transformation];
xStart: Scaled.Value ← ScaledFromReal[start.x];
yStart: Scaled.Value ← ScaledFromReal[start.y];
xDeltaPixel: Scaled.Value ← ScaledFromReal[nextPixel.x];
yDeltaPixel: Scaled.Value ← ScaledFromReal[nextPixel.y];
xDeltaLine: Scaled.Value ← ScaledFromReal[nextLine.x];
yDeltaLine: Scaled.Value ← ScaledFromReal[nextLine.y];
lineBits: NAT ← fMax - fMin;
buffer: PixelBuffer ← NEW[ImagerBasic.PixelBufferRep[lineBits]];
linePointer: LONG POINTER ← b.pointer + Inline.LongMult[sMin, b.rast];
sPeriod: CARDINAL ← deviceBrick.sPeriod;
fPeriod: CARDINAL ← deviceBrick.fPeriod;
sDivPeriod, sModPeriod: CARDINAL;
fBrick: NAT;
sMinBrick: INT ← sMin-(INT[deviceBrick.sMin]-(dest.sMin MOD sPeriod));
fMinBrick: INT ← fMin-(INT[deviceBrick.fMin]-(dest.fMin MOD fPeriod));
WHILE sMinBrick < 0 DO sMinBrick ← sMinBrick + sPeriod ENDLOOP;
WHILE fMinBrick < 0 DO fMinBrick ← fMinBrick + fPeriod ENDLOOP;
[quotient: sDivPeriod, remainder: sModPeriod] ← Inline.LongDivMod[sMinBrick, sPeriod];
fBrick ← Inline.LongDivMod[Inline.LongMult[sDivPeriod, deviceBrick.phase] + fMinBrick, fPeriod].remainder;
IF sMask.refRep =
NIL
THEN {
bitAddress: Environment.BitAddress ← [word: linePointer + fMin/16, bit: fMin MOD 16];
FOR s:
CARDINAL
IN [sMin..sMax)
DO
brickRow: PixelBuffer ← deviceBrick[sModPeriod];
brickPtr: LONG POINTER ← @(brickRow[fBrick]);
brickRem: INTEGER ← brickRow.maxLength - 15 - fBrick;
source.get[source, buffer, lineBits, 0, xStart, yStart, xDeltaPixel, yDeltaPixel];
DoLine[dst: bitAddress, count: lineBits, sourcePtr: @(buffer[0]), brickPtr: brickPtr, brickRem: brickRem, brickPeriod: fPeriod];
bitAddress.word ← bitAddress.word + b.rast;
xStart ← xStart.PLUS[xDeltaLine];
yStart ← yStart.PLUS[yDeltaLine];
sModPeriod ← sModPeriod + 1;
IF sModPeriod = sPeriod
THEN {
sModPeriod ← 0;
sDivPeriod ← sDivPeriod + 1;
fBrick ← fBrick + deviceBrick.phase;
WHILE fBrick >= fPeriod DO fBrick ← fBrick - fPeriod ENDLOOP;
};
ENDLOOP;
}
ELSE {
sMaskReader: ImagerMasksPrivate.Reader;
ImagerMasksPrivate.SetReader[@sMaskReader, sMask];
ImagerMasksPrivate.SkipTo[@sMaskReader, sMin];
FOR s:
NAT
IN [sMin..sMax)
DO
brickRow: PixelBuffer ← deviceBrick[sModPeriod];
brickPtr: LONG POINTER ← @(brickRow[fBrick]);
brickRem: INTEGER ← brickRow.maxLength - 15 - fBrick;
source.get[source, buffer, lineBits, 0, xStart, yStart, xDeltaPixel, yDeltaPixel];
WHILE sMaskReader.s = s
DO
fStart: NAT ← sMaskReader.fMin-fMin;
DoLine[dst: [word: linePointer + sMaskReader.fMin/16, bit: sMaskReader.fMin MOD 16], count: sMaskReader.fMax-sMaskReader.fMin, sourcePtr: @(buffer[fStart]), brickPtr: brickPtr+fStart, brickRem: brickRem-fStart, brickPeriod: fPeriod];
ImagerMasksPrivate.Advance[@sMaskReader];
ENDLOOP;
linePointer ← linePointer + b.rast;
xStart ← xStart.PLUS[xDeltaLine];
yStart ← yStart.PLUS[yDeltaLine];
sModPeriod ← sModPeriod + 1;
IF sModPeriod = sPeriod
THEN {
sModPeriod ← 0;
sDivPeriod ← sDivPeriod + 1;
fBrick ← fBrick + deviceBrick.phase;
WHILE fBrick >= fPeriod DO fBrick ← fBrick - fPeriod ENDLOOP;
};
ENDLOOP;
};
};