SkPictureImageFilter.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*
  2. * Copyright 2013 The Android Open Source Project
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "include/effects/SkPictureImageFilter.h"
  8. #include "include/core/SkCanvas.h"
  9. #include "include/effects/SkImageSource.h"
  10. #include "src/core/SkPicturePriv.h"
  11. #include "src/core/SkReadBuffer.h"
  12. #include "src/core/SkSpecialImage.h"
  13. #include "src/core/SkSpecialSurface.h"
  14. #include "src/core/SkValidationUtils.h"
  15. #include "src/core/SkWriteBuffer.h"
  16. sk_sp<SkImageFilter> SkPictureImageFilter::Make(sk_sp<SkPicture> picture) {
  17. return sk_sp<SkImageFilter>(new SkPictureImageFilter(std::move(picture)));
  18. }
  19. sk_sp<SkImageFilter> SkPictureImageFilter::Make(sk_sp<SkPicture> picture,
  20. const SkRect& cropRect) {
  21. return sk_sp<SkImageFilter>(new SkPictureImageFilter(std::move(picture), cropRect));
  22. }
  23. SkPictureImageFilter::SkPictureImageFilter(sk_sp<SkPicture> picture)
  24. : INHERITED(nullptr, 0, nullptr)
  25. , fPicture(std::move(picture))
  26. , fCropRect(fPicture ? fPicture->cullRect() : SkRect::MakeEmpty()) {
  27. }
  28. SkPictureImageFilter::SkPictureImageFilter(sk_sp<SkPicture> picture, const SkRect& cropRect)
  29. : INHERITED(nullptr, 0, nullptr)
  30. , fPicture(std::move(picture))
  31. , fCropRect(cropRect) {
  32. }
  33. enum PictureResolution {
  34. kDeviceSpace_PictureResolution,
  35. kLocalSpace_PictureResolution
  36. };
  37. static sk_sp<SkImageFilter> make_localspace_filter(sk_sp<SkPicture> pic, const SkRect& cropRect,
  38. SkFilterQuality fq) {
  39. SkISize dim = { SkScalarRoundToInt(cropRect.width()), SkScalarRoundToInt(cropRect.height()) };
  40. auto img = SkImage::MakeFromPicture(std::move(pic), dim, nullptr, nullptr,
  41. SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB());
  42. return SkImageSource::Make(img, cropRect, cropRect, fq);
  43. }
  44. sk_sp<SkFlattenable> SkPictureImageFilter::CreateProc(SkReadBuffer& buffer) {
  45. sk_sp<SkPicture> picture;
  46. SkRect cropRect;
  47. if (buffer.readBool()) {
  48. picture = SkPicturePriv::MakeFromBuffer(buffer);
  49. }
  50. buffer.readRect(&cropRect);
  51. if (buffer.isVersionLT(SkReadBuffer::kRemovePictureImageFilterLocalSpace)) {
  52. PictureResolution pictureResolution = buffer.checkRange<PictureResolution>(
  53. kDeviceSpace_PictureResolution, kLocalSpace_PictureResolution);
  54. if (kLocalSpace_PictureResolution == pictureResolution) {
  55. return make_localspace_filter(std::move(picture), cropRect,
  56. buffer.checkFilterQuality());
  57. }
  58. }
  59. return sk_sp<SkImageFilter>(new SkPictureImageFilter(picture, cropRect));
  60. }
  61. void SkPictureImageFilter::flatten(SkWriteBuffer& buffer) const {
  62. bool hasPicture = (fPicture != nullptr);
  63. buffer.writeBool(hasPicture);
  64. if (hasPicture) {
  65. SkPicturePriv::Flatten(fPicture, buffer);
  66. }
  67. buffer.writeRect(fCropRect);
  68. }
  69. sk_sp<SkSpecialImage> SkPictureImageFilter::onFilterImage(SkSpecialImage* source,
  70. const Context& ctx,
  71. SkIPoint* offset) const {
  72. if (!fPicture) {
  73. return nullptr;
  74. }
  75. SkRect floatBounds;
  76. ctx.ctm().mapRect(&floatBounds, fCropRect);
  77. SkIRect bounds = floatBounds.roundOut();
  78. if (!bounds.intersect(ctx.clipBounds())) {
  79. return nullptr;
  80. }
  81. SkASSERT(!bounds.isEmpty());
  82. // Given the standard usage of the picture image filter (i.e., to render content at a fixed
  83. // resolution that, most likely, differs from the screen's) disable LCD text.
  84. SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
  85. sk_sp<SkSpecialSurface> surf(source->makeSurface(ctx.outputProperties(), bounds.size(),
  86. kPremul_SkAlphaType, &props));
  87. if (!surf) {
  88. return nullptr;
  89. }
  90. SkASSERT(kUnknown_SkPixelGeometry == surf->props().pixelGeometry());
  91. SkCanvas* canvas = surf->getCanvas();
  92. SkASSERT(canvas);
  93. canvas->clear(0x0);
  94. canvas->translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop));
  95. canvas->concat(ctx.ctm());
  96. canvas->drawPicture(fPicture);
  97. offset->fX = bounds.fLeft;
  98. offset->fY = bounds.fTop;
  99. return surf->makeImageSnapshot();
  100. }