drawImage method
void
drawImage(
- PdfImageRequest request
)
Implementation
@override
void drawImage(PdfImageRequest request) {
final image = images[pdfImageKey(request)];
if (image == null) return; // not decodable (yet): skip silently
final softMask = pdfGpuSoftMaskOf(image);
// antialiased edges leave hairline seams between abutting image slices
// (PowerPoint and scanners split large images into strips)
final paint = Paint()
..filterQuality = FilterQuality.medium
..isAntiAlias = false
..blendMode = softMask == null ? _fillElementBlend : BlendMode.srcOver;
if (request.isStencil) {
// stencil masks paint the fill color through the mask's alpha
paint.colorFilter = ColorFilter.mode(
_toColor(request.stencilColor, request.alpha), BlendMode.srcIn);
} else {
paint.color = Color.from(alpha: request.alpha, red: 0, green: 0, blue: 0);
}
canvas.save();
canvas.transform(_toFloat64(request.transform));
// image space: unit square, y-up; image pixels: y-down from the top
canvas.translate(0, 1);
canvas.scale(1, -1);
if (softMask != null) {
// Isolate the base + mask so the PDF blend mode applies to the finished
// composite, not to the base against a transparent temporary surface.
// The mask JPEG is grayscale, so its red sample is the specified alpha.
canvas.saveLayer(
const Rect.fromLTWH(0, 0, 1, 1),
Paint()..blendMode = _fillElementBlend,
);
}
canvas.drawImageRect(
image,
Rect.fromLTWH(0, 0, image.width.toDouble(), image.height.toDouble()),
const Rect.fromLTWH(0, 0, 1, 1),
paint,
);
if (softMask != null) {
// The dstIn and the red->alpha filter go on a *layer* paint, not on the
// mask's own draw paint. Impeller ignores a draw paint's blend mode when
// that same paint also carries a colour filter: the mask then composites
// srcOver, painting its filtered samples (opaque black where the mask is
// white) over the base instead of cutting the base's alpha - every
// /SMask'd JPEG on the page turns into a black rectangle (#675). Skia
// honours both on one paint, and both engines honour this shape.
canvas.saveLayer(
const Rect.fromLTWH(0, 0, 1, 1),
Paint()
..blendMode = BlendMode.dstIn
..colorFilter = const ColorFilter.matrix(_redToAlpha),
);
canvas.drawImageRect(
softMask,
Rect.fromLTWH(
0,
0,
softMask.width.toDouble(),
softMask.height.toDouble(),
),
const Rect.fromLTWH(0, 0, 1, 1),
Paint()
..filterQuality = FilterQuality.medium
..isAntiAlias = false,
);
canvas.restore();
canvas.restore();
}
canvas.restore();
}