OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 The Android Open Source Project | 2 * Copyright 2013 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkPictureImageFilter.h" | 8 #include "SkPictureImageFilter.h" |
9 #include "SkDevice.h" | 9 |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
11 #include "SkReadBuffer.h" | 11 #include "SkReadBuffer.h" |
12 #include "SkSurfaceProps.h" | 12 #include "SkSpecialImage.h" |
| 13 #include "SkSpecialSurface.h" |
13 #include "SkWriteBuffer.h" | 14 #include "SkWriteBuffer.h" |
14 #include "SkValidationUtils.h" | 15 #include "SkValidationUtils.h" |
15 | 16 |
16 SkPictureImageFilter::SkPictureImageFilter(sk_sp<SkPicture> picture) | 17 SkPictureImageFilter::SkPictureImageFilter(sk_sp<SkPicture> picture) |
17 : INHERITED(nullptr, 0, nullptr) | 18 : INHERITED(nullptr, 0, nullptr) |
18 , fPicture(std::move(picture)) | 19 , fPicture(std::move(picture)) |
19 , fCropRect(fPicture ? fPicture->cullRect() : SkRect::MakeEmpty()) | 20 , fCropRect(fPicture ? fPicture->cullRect() : SkRect::MakeEmpty()) |
20 , fPictureResolution(kDeviceSpace_PictureResolution) | 21 , fPictureResolution(kDeviceSpace_PictureResolution) |
21 , fFilterQuality(kLow_SkFilterQuality) { | 22 , fFilterQuality(kLow_SkFilterQuality) { |
22 } | 23 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 fPicture->flatten(buffer); | 74 fPicture->flatten(buffer); |
74 } | 75 } |
75 } | 76 } |
76 buffer.writeRect(fCropRect); | 77 buffer.writeRect(fCropRect); |
77 buffer.writeInt(fPictureResolution); | 78 buffer.writeInt(fPictureResolution); |
78 if (kLocalSpace_PictureResolution == fPictureResolution) { | 79 if (kLocalSpace_PictureResolution == fPictureResolution) { |
79 buffer.writeInt(fFilterQuality); | 80 buffer.writeInt(fFilterQuality); |
80 } | 81 } |
81 } | 82 } |
82 | 83 |
83 bool SkPictureImageFilter::onFilterImageDeprecated(Proxy* proxy, const SkBitmap&
, | 84 sk_sp<SkSpecialImage> SkPictureImageFilter::onFilterImage(SkSpecialImage* source
, |
84 const Context& ctx, | 85 const Context& ctx, |
85 SkBitmap* result, SkIPoint* o
ffset) const { | 86 SkIPoint* offset) cons
t { |
86 if (!fPicture) { | 87 if (!fPicture) { |
87 offset->fX = offset->fY = 0; | 88 return nullptr; |
88 return true; | |
89 } | 89 } |
90 | 90 |
91 SkRect floatBounds; | 91 SkRect floatBounds; |
92 ctx.ctm().mapRect(&floatBounds, fCropRect); | 92 ctx.ctm().mapRect(&floatBounds, fCropRect); |
93 SkIRect bounds = floatBounds.roundOut(); | 93 SkIRect bounds = floatBounds.roundOut(); |
94 if (!bounds.intersect(ctx.clipBounds())) { | 94 if (!bounds.intersect(ctx.clipBounds())) { |
95 return false; | 95 return nullptr; |
96 } | 96 } |
97 | 97 |
98 if (bounds.isEmpty()) { | 98 SkASSERT(!bounds.isEmpty()); |
99 offset->fX = offset->fY = 0; | 99 |
100 return true; | 100 SkImageInfo info = SkImageInfo::MakeN32(bounds.width(), bounds.height(), kPr
emul_SkAlphaType); |
| 101 sk_sp<SkSpecialSurface> surf(source->makeSurface(info)); |
| 102 if (!surf) { |
| 103 return nullptr; |
101 } | 104 } |
102 | 105 |
103 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds
.height())); | 106 SkCanvas* canvas = surf->getCanvas(); |
104 if (nullptr == device.get()) { | 107 SkASSERT(canvas); |
105 return false; | 108 |
| 109 canvas->clear(0x0); |
| 110 |
| 111 if (kDeviceSpace_PictureResolution == fPictureResolution || |
| 112 0 == (ctx.ctm().getType() & ~SkMatrix::kTranslate_Mask)) { |
| 113 this->drawPictureAtDeviceResolution(canvas, bounds, ctx); |
| 114 } else { |
| 115 this->drawPictureAtLocalResolution(source, canvas, bounds, ctx); |
106 } | 116 } |
107 | 117 |
108 if (kDeviceSpace_PictureResolution == fPictureResolution || | |
109 0 == (ctx.ctm().getType() & ~SkMatrix::kTranslate_Mask)) { | |
110 this->drawPictureAtDeviceResolution(device.get(), bounds, ctx); | |
111 } else { | |
112 this->drawPictureAtLocalResolution(proxy, device.get(), bounds, ctx); | |
113 } | |
114 | |
115 *result = device.get()->accessBitmap(false); | |
116 offset->fX = bounds.fLeft; | 118 offset->fX = bounds.fLeft; |
117 offset->fY = bounds.fTop; | 119 offset->fY = bounds.fTop; |
118 return true; | 120 return surf->makeImageSnapshot(); |
119 } | 121 } |
120 | 122 |
121 void SkPictureImageFilter::drawPictureAtDeviceResolution(SkBaseDevice* device, | 123 void SkPictureImageFilter::drawPictureAtDeviceResolution(SkCanvas* canvas, |
122 const SkIRect& deviceBo
unds, | 124 const SkIRect& deviceBo
unds, |
123 const Context& ctx) con
st { | 125 const Context& ctx) con
st { |
124 SkCanvas canvas(device); | 126 canvas->translate(-SkIntToScalar(deviceBounds.fLeft), -SkIntToScalar(deviceB
ounds.fTop)); |
125 | 127 canvas->concat(ctx.ctm()); |
126 canvas.translate(-SkIntToScalar(deviceBounds.fLeft), -SkIntToScalar(deviceBo
unds.fTop)); | 128 canvas->drawPicture(fPicture); |
127 canvas.concat(ctx.ctm()); | |
128 canvas.drawPicture(fPicture); | |
129 } | 129 } |
130 | 130 |
131 void SkPictureImageFilter::drawPictureAtLocalResolution(Proxy* proxy, SkBaseDevi
ce* device, | 131 void SkPictureImageFilter::drawPictureAtLocalResolution(SkSpecialImage* source, |
| 132 SkCanvas* canvas, |
132 const SkIRect& deviceBou
nds, | 133 const SkIRect& deviceBou
nds, |
133 const Context& ctx) cons
t { | 134 const Context& ctx) cons
t { |
134 SkMatrix inverseCtm; | 135 SkMatrix inverseCtm; |
135 if (!ctx.ctm().invert(&inverseCtm)) { | 136 if (!ctx.ctm().invert(&inverseCtm)) { |
136 return; | 137 return; |
137 } | 138 } |
138 | 139 |
139 SkRect localBounds = SkRect::Make(ctx.clipBounds()); | 140 SkRect localBounds = SkRect::Make(ctx.clipBounds()); |
140 inverseCtm.mapRect(&localBounds); | 141 inverseCtm.mapRect(&localBounds); |
141 if (!localBounds.intersect(fCropRect)) { | 142 if (!localBounds.intersect(fCropRect)) { |
142 return; | 143 return; |
143 } | 144 } |
144 SkIRect localIBounds = localBounds.roundOut(); | 145 SkIRect localIBounds = localBounds.roundOut(); |
145 SkAutoTUnref<SkBaseDevice> localDevice(proxy->createDevice(localIBounds.widt
h(), localIBounds.height())); | |
146 | 146 |
147 SkCanvas localCanvas(localDevice); | 147 sk_sp<SkSpecialImage> localImg; |
148 localCanvas.translate(-SkIntToScalar(localIBounds.fLeft), -SkIntToScalar(loc
alIBounds.fTop)); | 148 { |
149 localCanvas.drawPicture(fPicture); | 149 const SkImageInfo info = SkImageInfo::MakeN32(localIBounds.width(), loca
lIBounds.height(), |
| 150 kPremul_SkAlphaType); |
150 | 151 |
151 SkCanvas canvas(device); | 152 sk_sp<SkSpecialSurface> localSurface(source->makeSurface(info)); |
| 153 if (!localSurface) { |
| 154 return; |
| 155 } |
152 | 156 |
153 canvas.translate(-SkIntToScalar(deviceBounds.fLeft), -SkIntToScalar(deviceBo
unds.fTop)); | 157 SkCanvas* localCanvas = localSurface->getCanvas(); |
154 canvas.concat(ctx.ctm()); | 158 SkASSERT(localCanvas); |
155 SkPaint paint; | 159 |
156 paint.setFilterQuality(fFilterQuality); | 160 localCanvas->translate(-SkIntToScalar(localIBounds.fLeft), |
157 canvas.drawBitmap(localDevice.get()->accessBitmap(false), SkIntToScalar(loca
lIBounds.fLeft), | 161 -SkIntToScalar(localIBounds.fTop)); |
158 SkIntToScalar(localIBounds.fTop), &paint); | 162 localCanvas->drawPicture(fPicture); |
| 163 |
| 164 localImg = localSurface->makeImageSnapshot(); |
| 165 SkASSERT(localImg); |
| 166 } |
| 167 |
| 168 { |
| 169 canvas->translate(-SkIntToScalar(deviceBounds.fLeft), -SkIntToScalar(dev
iceBounds.fTop)); |
| 170 canvas->concat(ctx.ctm()); |
| 171 SkPaint paint; |
| 172 paint.setFilterQuality(fFilterQuality); |
| 173 |
| 174 localImg->draw(canvas, |
| 175 SkIntToScalar(localIBounds.fLeft), |
| 176 SkIntToScalar(localIBounds.fTop), |
| 177 &paint); |
| 178 } |
159 } | 179 } |
160 | 180 |
161 #ifndef SK_IGNORE_TO_STRING | 181 #ifndef SK_IGNORE_TO_STRING |
162 void SkPictureImageFilter::toString(SkString* str) const { | 182 void SkPictureImageFilter::toString(SkString* str) const { |
163 str->appendf("SkPictureImageFilter: ("); | 183 str->appendf("SkPictureImageFilter: ("); |
164 str->appendf("crop: (%f,%f,%f,%f) ", | 184 str->appendf("crop: (%f,%f,%f,%f) ", |
165 fCropRect.fLeft, fCropRect.fTop, fCropRect.fRight, fCropRect.fB
ottom); | 185 fCropRect.fLeft, fCropRect.fTop, fCropRect.fRight, fCropRect.fB
ottom); |
166 if (fPicture) { | 186 if (fPicture) { |
167 str->appendf("picture: (%f,%f,%f,%f)", | 187 str->appendf("picture: (%f,%f,%f,%f)", |
168 fPicture->cullRect().fLeft, fPicture->cullRect().fTop, | 188 fPicture->cullRect().fLeft, fPicture->cullRect().fTop, |
169 fPicture->cullRect().fRight, fPicture->cullRect().fBottom); | 189 fPicture->cullRect().fRight, fPicture->cullRect().fBottom); |
170 } | 190 } |
171 str->append(")"); | 191 str->append(")"); |
172 } | 192 } |
173 #endif | 193 #endif |
OLD | NEW |