OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
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 "SkColorPriv.h" | 8 #include "SkColorPriv.h" |
9 #include "SkDeflateWStream.h" | 9 #include "SkDeflateWStream.h" |
10 #include "SkPDFBitmap.h" | 10 #include "SkPDFBitmap.h" |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 if (fSMask) { | 240 if (fSMask) { |
241 pdfDict.insert("SMask", new SkPDFObjRef(fSMask))->unref(); | 241 pdfDict.insert("SMask", new SkPDFObjRef(fSMask))->unref(); |
242 } | 242 } |
243 if (deflate) { | 243 if (deflate) { |
244 pdfDict.insertName("Filter", "FlateDecode"); | 244 pdfDict.insertName("Filter", "FlateDecode"); |
245 } | 245 } |
246 pdfDict.insertInt("Length", length); | 246 pdfDict.insertInt("Length", length); |
247 pdfDict.emitObject(stream, catalog); | 247 pdfDict.emitObject(stream, catalog); |
248 } | 248 } |
249 | 249 |
250 SkPDFBitmap::SkPDFBitmap(const SkBitmap& bm, SkPDFObject* smask) | 250 SkPDFBitmap::SkPDFBitmap(SkPDFCanon* canon, |
251 : fBitmap(bm), fSMask(smask) {} | 251 const SkBitmap& bm, |
| 252 SkPDFObject* smask) |
| 253 : fCanon(canon), fBitmap(bm), fSMask(smask) {} |
252 | 254 |
253 SkPDFBitmap::~SkPDFBitmap() { | 255 SkPDFBitmap::~SkPDFBitmap() { fCanon->removeBitmap(this); } |
254 SkAutoMutexAcquire autoMutexAcquire(SkPDFCanon::GetBitmapMutex()); | |
255 SkPDFCanon::GetCanon().removeBitmap(this); | |
256 } | |
257 | 256 |
258 //////////////////////////////////////////////////////////////////////////////// | 257 //////////////////////////////////////////////////////////////////////////////// |
259 static bool is_transparent(const SkBitmap& bm) { | 258 static bool is_transparent(const SkBitmap& bm) { |
260 SkAutoLockPixels autoLockPixels(bm); | 259 SkAutoLockPixels autoLockPixels(bm); |
261 if (NULL == bm.getPixels()) { | 260 if (NULL == bm.getPixels()) { |
262 return true; | 261 return true; |
263 } | 262 } |
264 SkASSERT(kN32_SkColorType == bm.colorType()); | 263 SkASSERT(kN32_SkColorType == bm.colorType()); |
265 for (int y = 0; y < bm.height(); ++y) { | 264 for (int y = 0; y < bm.height(); ++y) { |
266 U8CPU alpha = 0; | 265 U8CPU alpha = 0; |
267 const SkPMColor* src = bm.getAddr32(0, y); | 266 const SkPMColor* src = bm.getAddr32(0, y); |
268 for (int x = 0; x < bm.width(); ++x) { | 267 for (int x = 0; x < bm.width(); ++x) { |
269 alpha |= SkGetPackedA32(*src++); | 268 alpha |= SkGetPackedA32(*src++); |
270 } | 269 } |
271 if (alpha) { | 270 if (alpha) { |
272 return false; | 271 return false; |
273 } | 272 } |
274 } | 273 } |
275 return true; | 274 return true; |
276 } | 275 } |
277 | 276 |
278 // TODO(halcanary): SkPDFBitmap::Create should take a SkPDFCanon* parameter. | 277 SkPDFBitmap* SkPDFBitmap::Create(SkPDFCanon* canon, |
279 SkPDFBitmap* SkPDFBitmap::Create(const SkBitmap& bitmap, | 278 const SkBitmap& bitmap, |
280 const SkIRect& subset) { | 279 const SkIRect& subset) { |
| 280 SkASSERT(canon); |
281 if (kN32_SkColorType != bitmap.colorType()) { | 281 if (kN32_SkColorType != bitmap.colorType()) { |
282 // TODO(halcanary): support other colortypes. | 282 // TODO(halcanary): support other colortypes. |
283 return NULL; | 283 return NULL; |
284 } | 284 } |
285 SkBitmap bm; | 285 SkBitmap bm; |
286 // Should extractSubset be done by the SkPDFDevice? | 286 // Should extractSubset be done by the SkPDFDevice? |
287 if (!bitmap.extractSubset(&bm, subset)) { | 287 if (!bitmap.extractSubset(&bm, subset)) { |
288 return NULL; | 288 return NULL; |
289 } | 289 } |
290 if (bm.drawsNothing()) { | 290 if (bm.drawsNothing()) { |
291 return NULL; | 291 return NULL; |
292 } | 292 } |
293 if (!bm.isImmutable()) { | 293 if (!bm.isImmutable()) { |
294 SkBitmap copy; | 294 SkBitmap copy; |
295 if (!bm.copyTo(©)) { | 295 if (!bm.copyTo(©)) { |
296 return NULL; | 296 return NULL; |
297 } | 297 } |
298 copy.setImmutable(); | 298 copy.setImmutable(); |
299 bm = copy; | 299 bm = copy; |
300 } | 300 } |
301 | 301 |
302 SkAutoMutexAcquire autoMutexAcquire(SkPDFCanon::GetBitmapMutex()); | 302 SkPDFBitmap* pdfBitmap = canon->findBitmap(bm); |
303 SkPDFCanon& canon = SkPDFCanon::GetCanon(); | |
304 SkPDFBitmap* pdfBitmap = canon.findBitmap(bm); | |
305 if (pdfBitmap) { | 303 if (pdfBitmap) { |
306 return SkRef(pdfBitmap); | 304 return SkRef(pdfBitmap); |
307 } | 305 } |
308 SkPDFObject* smask = NULL; | 306 SkPDFObject* smask = NULL; |
309 if (!bm.isOpaque() && !SkBitmap::ComputeIsOpaque(bm)) { | 307 if (!bm.isOpaque() && !SkBitmap::ComputeIsOpaque(bm)) { |
310 if (is_transparent(bm)) { | 308 if (is_transparent(bm)) { |
311 return NULL; | 309 return NULL; |
312 } | 310 } |
313 // PDFAlphaBitmaps do not get directly canonicalized (they | 311 // PDFAlphaBitmaps do not get directly canonicalized (they |
314 // are refed by the SkPDFBitmap). | 312 // are refed by the SkPDFBitmap). |
315 smask = SkNEW_ARGS(PDFAlphaBitmap, (bm)); | 313 smask = SkNEW_ARGS(PDFAlphaBitmap, (bm)); |
316 } | 314 } |
317 pdfBitmap = SkNEW_ARGS(SkPDFBitmap, (bm, smask)); | 315 pdfBitmap = SkNEW_ARGS(SkPDFBitmap, (canon, bm, smask)); |
318 canon.addBitmap(pdfBitmap); | 316 canon->addBitmap(pdfBitmap); |
319 return pdfBitmap; | 317 return pdfBitmap; |
320 } | 318 } |
OLD | NEW |