| 757 | } |
| 758 | |
| 759 | void PDFExportContext::onDrawImageRect(std::shared_ptr<Image> image, const Rect& rect, |
| 760 | const SamplingOptions& sampling, const MCState& state, |
| 761 | const Fill& fill) { |
| 762 | if (!image) { |
| 763 | return; |
| 764 | } |
| 765 | |
| 766 | // First, figure out the src->dst transform and subset the image if needed. |
| 767 | auto bound = Rect::MakeWH(image->width(), image->height()); |
| 768 | float scaleX = rect.width() / bound.width(); |
| 769 | float scaleY = rect.height() / bound.height(); |
| 770 | float transX = rect.left - (bound.left * scaleX); |
| 771 | float transY = rect.top - (bound.top * scaleY); |
| 772 | auto transform = Matrix::I(); |
| 773 | transform.postScale(scaleX, scaleY); |
| 774 | transform.postTranslate(transX, transY); |
| 775 | |
| 776 | // Alpha-only images need to get their color from the shader, before applying the colorfilter. |
| 777 | auto modifiedFill = fill; |
| 778 | if (image->isAlphaOnly() && modifiedFill.colorFilter) { |
| 779 | // must blend alpha image and shader before applying colorfilter. |
| 780 | auto surface = Surface::Make(document->context(), image->width(), image->height()); |
| 781 | Canvas* canvas = surface->getCanvas(); |
| 782 | Paint tmpPaint; |
| 783 | // In the case of alpha images with shaders, the shader's coordinate system is the image's |
| 784 | // coordiantes. |
| 785 | tmpPaint.setShader(modifiedFill.shader); |
| 786 | tmpPaint.setColor(modifiedFill.color); |
| 787 | canvas->clear(); |
| 788 | canvas->drawImage(image, &tmpPaint); |
| 789 | if (modifiedFill.shader != nullptr) { |
| 790 | modifiedFill.shader = nullptr; |
| 791 | } |
| 792 | image = surface->makeImageSnapshot(); |
| 793 | DEBUG_ASSERT(!image->isAlphaOnly()); |
| 794 | } |
| 795 | |
| 796 | if (image->isAlphaOnly()) { |
| 797 | // The ColorFilter applies to the paint color/shader, not the alpha layer. |
| 798 | DEBUG_ASSERT(modifiedFill.colorFilter == nullptr); |
| 799 | |
| 800 | // PDF doesn't seem to allow masking vector graphics with an Image XObject. Must mask with a |
| 801 | // Form XObject. |
| 802 | auto maskContext = PDFExportContext(ISize::Make(image->width(), image->height()), document); |
| 803 | { |
| 804 | auto canvas = PDFDocumentImpl::MakeCanvas(&maskContext); |
| 805 | // This clip prevents the mask image shader from covering entire device if unnecessary. |
| 806 | canvas->clipRect(state.clip.getBounds()); |
| 807 | if (modifiedFill.maskFilter) { |
| 808 | Paint tmpPaint; |
| 809 | auto imageShader = |
| 810 | Shader::MakeImageShader(image, TileMode::Clamp, TileMode::Clamp, SamplingOptions()); |
| 811 | imageShader = imageShader->makeWithMatrix(transform); |
| 812 | tmpPaint.setShader(imageShader); |
| 813 | tmpPaint.setMaskFilter(modifiedFill.maskFilter); |
| 814 | canvas->drawRect(rect, tmpPaint); |
| 815 | } else { |
| 816 | canvas->concat(transform); |
nothing calls this directly
no test coverage detected