OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. |
3 * Copyright (C) 2013 Google Inc. All rights reserved. | 3 * Copyright (C) 2013 Google Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 24 matching lines...) Expand all Loading... |
35 #include "platform/graphics/ImageBuffer.h" | 35 #include "platform/graphics/ImageBuffer.h" |
36 #include "platform/weborigin/KURL.h" | 36 #include "platform/weborigin/KURL.h" |
37 #include "third_party/skia/include/core/SkAnnotation.h" | 37 #include "third_party/skia/include/core/SkAnnotation.h" |
38 #include "third_party/skia/include/core/SkColorFilter.h" | 38 #include "third_party/skia/include/core/SkColorFilter.h" |
39 #include "third_party/skia/include/core/SkData.h" | 39 #include "third_party/skia/include/core/SkData.h" |
40 #include "third_party/skia/include/core/SkPicture.h" | 40 #include "third_party/skia/include/core/SkPicture.h" |
41 #include "third_party/skia/include/core/SkPictureRecorder.h" | 41 #include "third_party/skia/include/core/SkPictureRecorder.h" |
42 #include "third_party/skia/include/core/SkRRect.h" | 42 #include "third_party/skia/include/core/SkRRect.h" |
43 #include "third_party/skia/include/core/SkRefCnt.h" | 43 #include "third_party/skia/include/core/SkRefCnt.h" |
44 #include "third_party/skia/include/effects/SkCornerPathEffect.h" | 44 #include "third_party/skia/include/effects/SkCornerPathEffect.h" |
45 #include "third_party/skia/include/effects/SkDropShadowImageFilter.h" | |
46 #include "third_party/skia/include/effects/SkLumaColorFilter.h" | 45 #include "third_party/skia/include/effects/SkLumaColorFilter.h" |
47 #include "third_party/skia/include/effects/SkPictureImageFilter.h" | 46 #include "third_party/skia/include/effects/SkPictureImageFilter.h" |
48 #include "third_party/skia/include/utils/SkNullCanvas.h" | 47 #include "third_party/skia/include/utils/SkNullCanvas.h" |
49 #include "wtf/Assertions.h" | 48 #include "wtf/Assertions.h" |
50 #include "wtf/MathExtras.h" | 49 #include "wtf/MathExtras.h" |
51 | 50 |
52 namespace blink { | 51 namespace blink { |
53 | 52 |
54 class GraphicsContext::RecordingState { | 53 class GraphicsContext::RecordingState { |
55 WTF_MAKE_FAST_ALLOCATED(GraphicsContext::RecordingState); | 54 WTF_MAKE_FAST_ALLOCATED(GraphicsContext::RecordingState); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 , m_paintStateIndex(0) | 96 , m_paintStateIndex(0) |
98 #if ENABLE(ASSERT) | 97 #if ENABLE(ASSERT) |
99 , m_layerCount(0) | 98 , m_layerCount(0) |
100 , m_disableDestructionChecks(false) | 99 , m_disableDestructionChecks(false) |
101 , m_inDrawingRecorder(false) | 100 , m_inDrawingRecorder(false) |
102 #endif | 101 #endif |
103 , m_disabledState(disableContextOrPainting) | 102 , m_disabledState(disableContextOrPainting) |
104 , m_deviceScaleFactor(1.0f) | 103 , m_deviceScaleFactor(1.0f) |
105 , m_accelerated(false) | 104 , m_accelerated(false) |
106 , m_printing(false) | 105 , m_printing(false) |
107 , m_antialiasHairlineImages(false) | |
108 { | 106 { |
109 // FIXME: Do some tests to determine how many states are typically used, and
allocate | 107 // FIXME: Do some tests to determine how many states are typically used, and
allocate |
110 // several here. | 108 // several here. |
111 m_paintStateStack.append(GraphicsContextState::create()); | 109 m_paintStateStack.append(GraphicsContextState::create()); |
112 m_paintState = m_paintStateStack.last().get(); | 110 m_paintState = m_paintStateStack.last().get(); |
113 | 111 |
114 if (contextDisabled()) { | 112 if (contextDisabled()) { |
115 DEFINE_STATIC_LOCAL(RefPtr<SkCanvas>, nullCanvas, (adoptRef(SkCreateNull
Canvas()))); | 113 DEFINE_STATIC_LOCAL(RefPtr<SkCanvas>, nullCanvas, (adoptRef(SkCreateNull
Canvas()))); |
116 m_canvas = nullCanvas.get(); | 114 m_canvas = nullCanvas.get(); |
117 } | 115 } |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 if (contextDisabled()) | 270 if (contextDisabled()) |
273 return; | 271 return; |
274 | 272 |
275 OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create(); | 273 OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create(); |
276 if (!color.alpha()) { | 274 if (!color.alpha()) { |
277 if (shadowMode == DrawShadowOnly) { | 275 if (shadowMode == DrawShadowOnly) { |
278 // shadow only, but there is no shadow: use an empty draw looper to
disable rendering of the source primitive | 276 // shadow only, but there is no shadow: use an empty draw looper to
disable rendering of the source primitive |
279 setDrawLooper(drawLooperBuilder.release()); | 277 setDrawLooper(drawLooperBuilder.release()); |
280 return; | 278 return; |
281 } | 279 } |
282 clearShadow(); | 280 clearDrawLooper(); |
283 return; | 281 return; |
284 } | 282 } |
285 | 283 |
286 drawLooperBuilder->addShadow(offset, blur, color, shadowTransformMode, shado
wAlphaMode); | 284 drawLooperBuilder->addShadow(offset, blur, color, shadowTransformMode, shado
wAlphaMode); |
287 if (shadowMode == DrawShadowAndForeground) { | 285 if (shadowMode == DrawShadowAndForeground) { |
288 drawLooperBuilder->addUnmodifiedContent(); | 286 drawLooperBuilder->addUnmodifiedContent(); |
289 } | 287 } |
290 setDrawLooper(drawLooperBuilder.release()); | 288 setDrawLooper(drawLooperBuilder.release()); |
291 | |
292 if (shadowTransformMode == DrawLooperBuilder::ShadowIgnoresTransforms | |
293 && shadowAlphaMode == DrawLooperBuilder::ShadowRespectsAlpha) { | |
294 // This image filter will be used in place of the drawLooper created abo
ve but only for drawing non-opaque bitmaps; | |
295 // see preparePaintForDrawRectToRect(). | |
296 SkColor skColor = color.rgb(); | |
297 // These constants are from RadiusToSigma() from DrawLooperBuilder.cpp. | |
298 const SkScalar sigma = 0.288675f * blur + 0.5f; | |
299 SkDropShadowImageFilter::ShadowMode dropShadowMode = shadowMode == DrawS
hadowAndForeground ? SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMod
e : SkDropShadowImageFilter::kDrawShadowOnly_ShadowMode; | |
300 RefPtr<SkImageFilter> filter = adoptRef(SkDropShadowImageFilter::Create(
offset.width(), offset.height(), sigma, sigma, skColor, dropShadowMode)); | |
301 setDropShadowImageFilter(filter); | |
302 } | |
303 } | 289 } |
304 | 290 |
305 void GraphicsContext::setDrawLooper(PassOwnPtr<DrawLooperBuilder> drawLooperBuil
der) | 291 void GraphicsContext::setDrawLooper(PassOwnPtr<DrawLooperBuilder> drawLooperBuil
der) |
306 { | 292 { |
307 if (contextDisabled()) | 293 if (contextDisabled()) |
308 return; | 294 return; |
309 | 295 |
310 mutableState()->setDrawLooper(drawLooperBuilder->detachDrawLooper()); | 296 mutableState()->setDrawLooper(drawLooperBuilder->detachDrawLooper()); |
311 } | 297 } |
312 | 298 |
313 void GraphicsContext::clearDrawLooper() | 299 void GraphicsContext::clearDrawLooper() |
314 { | 300 { |
315 if (contextDisabled()) | 301 if (contextDisabled()) |
316 return; | 302 return; |
317 | 303 |
318 mutableState()->clearDrawLooper(); | 304 mutableState()->clearDrawLooper(); |
319 } | 305 } |
320 | 306 |
321 void GraphicsContext::setDropShadowImageFilter(PassRefPtr<SkImageFilter> imageFi
lter) | |
322 { | |
323 if (contextDisabled()) | |
324 return; | |
325 | |
326 mutableState()->setDropShadowImageFilter(imageFilter); | |
327 } | |
328 | |
329 void GraphicsContext::clearDropShadowImageFilter() | |
330 { | |
331 if (contextDisabled()) | |
332 return; | |
333 | |
334 mutableState()->clearDropShadowImageFilter(); | |
335 } | |
336 | |
337 SkMatrix GraphicsContext::getTotalMatrix() const | 307 SkMatrix GraphicsContext::getTotalMatrix() const |
338 { | 308 { |
339 // FIXME: this is a hack to avoid changing all call sites of getTotalMatrix(
) to not use this method. | 309 // FIXME: this is a hack to avoid changing all call sites of getTotalMatrix(
) to not use this method. |
340 // The code needs to be cleand up after Slimming Paint is launched. | 310 // The code needs to be cleand up after Slimming Paint is launched. |
341 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) | 311 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) |
342 return SkMatrix::I(); | 312 return SkMatrix::I(); |
343 | 313 |
344 if (contextDisabled() || !m_canvas) | 314 if (contextDisabled() || !m_canvas) |
345 return SkMatrix::I(); | 315 return SkMatrix::I(); |
346 | 316 |
347 ASSERT(m_canvas); | 317 ASSERT(m_canvas); |
348 | 318 |
349 if (!isRecording()) | 319 if (!isRecording()) |
350 return m_canvas->getTotalMatrix(); | 320 return m_canvas->getTotalMatrix(); |
351 | 321 |
352 SkMatrix totalMatrix = m_recordingStateStack.last()->matrix(); | 322 SkMatrix totalMatrix = m_recordingStateStack.last()->matrix(); |
353 totalMatrix.preConcat(m_canvas->getTotalMatrix()); | 323 totalMatrix.preConcat(m_canvas->getTotalMatrix()); |
354 | 324 |
355 return totalMatrix; | 325 return totalMatrix; |
356 } | 326 } |
357 | 327 |
358 void GraphicsContext::setCompositeOperation(SkXfermode::Mode xferMode) | |
359 { | |
360 if (contextDisabled()) | |
361 return; | |
362 mutableState()->setCompositeOperation(xferMode); | |
363 } | |
364 | |
365 SkXfermode::Mode GraphicsContext::compositeOperation() const | |
366 { | |
367 return immutableState()->compositeOperation(); | |
368 } | |
369 | |
370 SkColorFilter* GraphicsContext::colorFilter() const | 328 SkColorFilter* GraphicsContext::colorFilter() const |
371 { | 329 { |
372 return immutableState()->colorFilter(); | 330 return immutableState()->colorFilter(); |
373 } | 331 } |
374 | 332 |
375 void GraphicsContext::setColorFilter(ColorFilter colorFilter) | 333 void GraphicsContext::setColorFilter(ColorFilter colorFilter) |
376 { | 334 { |
377 GraphicsContextState* stateToSet = mutableState(); | 335 GraphicsContextState* stateToSet = mutableState(); |
378 | 336 |
379 // We only support one active color filter at the moment. If (when) this bec
omes a problem, | 337 // We only support one active color filter at the moment. If (when) this bec
omes a problem, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 SkPaint layerPaint; | 371 SkPaint layerPaint; |
414 layerPaint.setAlpha(static_cast<unsigned char>(opacity * 255)); | 372 layerPaint.setAlpha(static_cast<unsigned char>(opacity * 255)); |
415 layerPaint.setXfermodeMode(xfermode); | 373 layerPaint.setXfermodeMode(xfermode); |
416 layerPaint.setColorFilter(WebCoreColorFilterToSkiaColorFilter(colorFilter).g
et()); | 374 layerPaint.setColorFilter(WebCoreColorFilterToSkiaColorFilter(colorFilter).g
et()); |
417 layerPaint.setImageFilter(imageFilter); | 375 layerPaint.setImageFilter(imageFilter); |
418 | 376 |
419 if (bounds) { | 377 if (bounds) { |
420 SkRect skBounds = WebCoreFloatRectToSKRect(*bounds); | 378 SkRect skBounds = WebCoreFloatRectToSKRect(*bounds); |
421 saveLayer(&skBounds, &layerPaint); | 379 saveLayer(&skBounds, &layerPaint); |
422 } else { | 380 } else { |
423 saveLayer(0, &layerPaint); | 381 saveLayer(nullptr, &layerPaint); |
424 } | 382 } |
425 | 383 |
426 #if ENABLE(ASSERT) | 384 #if ENABLE(ASSERT) |
427 ++m_layerCount; | 385 ++m_layerCount; |
428 #endif | 386 #endif |
429 } | 387 } |
430 | 388 |
431 void GraphicsContext::endLayer() | 389 void GraphicsContext::endLayer() |
432 { | 390 { |
433 if (contextDisabled()) | 391 if (contextDisabled()) |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 SkPath path; | 483 SkPath path; |
526 setPathFromPoints(&path, numPoints, points); | 484 setPathFromPoints(&path, numPoints, points); |
527 | 485 |
528 SkPaint paint(immutableState()->fillPaint()); | 486 SkPaint paint(immutableState()->fillPaint()); |
529 paint.setAntiAlias(shouldAntialias); | 487 paint.setAntiAlias(shouldAntialias); |
530 paint.setColor(color.rgb()); | 488 paint.setColor(color.rgb()); |
531 | 489 |
532 drawPath(path, paint); | 490 drawPath(path, paint); |
533 } | 491 } |
534 | 492 |
535 float GraphicsContext::prepareFocusRingPaint(SkPaint& paint, const Color& color,
int width) const | |
536 { | |
537 paint.setAntiAlias(true); | |
538 paint.setStyle(SkPaint::kStroke_Style); | |
539 paint.setColor(color.rgb()); | |
540 paint.setStrokeWidth(focusRingWidth(width)); | |
541 | |
542 #if OS(MACOSX) | |
543 paint.setAlpha(64); | |
544 return (width - 1) * 0.5f; | |
545 #else | |
546 return 1; | |
547 #endif | |
548 } | |
549 | |
550 void GraphicsContext::drawFocusRingPath(const SkPath& path, const Color& color,
int width) | 493 void GraphicsContext::drawFocusRingPath(const SkPath& path, const Color& color,
int width) |
551 { | 494 { |
552 SkPaint paint; | 495 drawPlatformFocusRing( |
553 float cornerRadius = prepareFocusRingPaint(paint, color, width); | 496 [this, path](SkPaint& paint, float cornerRadius) |
554 | 497 { |
555 paint.setPathEffect(SkCornerPathEffect::Create(SkFloatToScalar(cornerRadius)
))->unref(); | 498 paint.setPathEffect(SkCornerPathEffect::Create(SkFloatToScalar(corne
rRadius)))->unref(); |
556 | 499 m_canvas->drawPath(path, paint); |
557 // Outer path | 500 } , color.rgb(), width); |
558 drawPath(path, paint); | |
559 | |
560 #if OS(MACOSX) | |
561 // Inner path | |
562 paint.setAlpha(128); | |
563 paint.setStrokeWidth(paint.getStrokeWidth() * 0.5f); | |
564 drawPath(path, paint); | |
565 #endif | |
566 } | 501 } |
567 | 502 |
568 void GraphicsContext::drawFocusRingRect(const SkRect& rect, const Color& color,
int width) | 503 void GraphicsContext::drawFocusRingRect(const SkRect& rect, const Color& color,
int width) |
569 { | 504 { |
570 SkPaint paint; | 505 drawPlatformFocusRing( |
571 float cornerRadius = prepareFocusRingPaint(paint, color, width); | 506 [this, rect](const SkPaint& paint, float cornerRadius) |
572 | 507 { |
573 SkRRect rrect; | 508 SkRRect rrect; |
574 rrect.setRectXY(rect, SkFloatToScalar(cornerRadius), SkFloatToScalar(cornerR
adius)); | 509 rrect.setRectXY(rect, SkFloatToScalar(cornerRadius), SkFloatToScalar
(cornerRadius)); |
575 | 510 m_canvas->drawRRect(rrect, paint); |
576 // Outer rect | 511 }, color.rgb(), width); |
577 drawRRect(rrect, paint); | |
578 | |
579 #if OS(MACOSX) | |
580 // Inner rect | |
581 paint.setAlpha(128); | |
582 paint.setStrokeWidth(paint.getStrokeWidth() * 0.5f); | |
583 drawRRect(rrect, paint); | |
584 #endif | |
585 } | 512 } |
586 | 513 |
587 void GraphicsContext::drawFocusRing(const Path& focusRingPath, int width, int of
fset, const Color& color) | 514 void GraphicsContext::drawFocusRing(const Path& focusRingPath, int width, int of
fset, const Color& color) |
588 { | 515 { |
589 // FIXME: Implement support for offset. | 516 // FIXME: Implement support for offset. |
590 if (contextDisabled()) | 517 if (contextDisabled()) |
591 return; | 518 return; |
592 | 519 |
593 drawFocusRingPath(focusRingPath.skPath(), color, width); | 520 drawFocusRingPath(focusRingPath.skPath(), color, width); |
594 } | 521 } |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 int thickness = SkMax32(static_cast<int>(strokeThickness()), 1); | 806 int thickness = SkMax32(static_cast<int>(strokeThickness()), 1); |
880 SkRect r; | 807 SkRect r; |
881 r.fLeft = WebCoreFloatToSkScalar(pt.x()); | 808 r.fLeft = WebCoreFloatToSkScalar(pt.x()); |
882 // Avoid anti-aliasing lines. Currently, these are always horizontal. | 809 // Avoid anti-aliasing lines. Currently, these are always horizontal. |
883 // Round to nearest pixel to match text and other content. | 810 // Round to nearest pixel to match text and other content. |
884 r.fTop = WebCoreFloatToSkScalar(floorf(pt.y() + 0.5f)); | 811 r.fTop = WebCoreFloatToSkScalar(floorf(pt.y() + 0.5f)); |
885 r.fRight = r.fLeft + WebCoreFloatToSkScalar(width); | 812 r.fRight = r.fLeft + WebCoreFloatToSkScalar(width); |
886 r.fBottom = r.fTop + SkIntToScalar(thickness); | 813 r.fBottom = r.fTop + SkIntToScalar(thickness); |
887 paint = immutableState()->fillPaint(); | 814 paint = immutableState()->fillPaint(); |
888 // Text lines are drawn using the stroke color. | 815 // Text lines are drawn using the stroke color. |
889 paint.setColor(effectiveStrokeColor()); | 816 paint.setColor(strokeColor().rgb()); |
890 drawRect(r, paint); | 817 drawRect(r, paint); |
891 return; | 818 return; |
892 } | 819 } |
893 case DottedStroke: | 820 case DottedStroke: |
894 case DashedStroke: { | 821 case DashedStroke: { |
895 int y = floorf(pt.y() + std::max<float>(strokeThickness() / 2.0f, 0.5f))
; | 822 int y = floorf(pt.y() + std::max<float>(strokeThickness() / 2.0f, 0.5f))
; |
896 drawLine(IntPoint(pt.x(), y), IntPoint(pt.x() + width, y)); | 823 drawLine(IntPoint(pt.x(), y), IntPoint(pt.x() + width, y)); |
897 return; | 824 return; |
898 } | 825 } |
899 } | 826 } |
(...skipping 13 matching lines...) Expand all Loading... |
913 | 840 |
914 SkRect skRect = rect; | 841 SkRect skRect = rect; |
915 int fillcolorNotTransparent = immutableState()->fillColor().rgb() & 0xFF0000
00; | 842 int fillcolorNotTransparent = immutableState()->fillColor().rgb() & 0xFF0000
00; |
916 if (fillcolorNotTransparent) | 843 if (fillcolorNotTransparent) |
917 drawRect(skRect, immutableState()->fillPaint()); | 844 drawRect(skRect, immutableState()->fillPaint()); |
918 | 845 |
919 if (immutableState()->strokeData().style() != NoStroke | 846 if (immutableState()->strokeData().style() != NoStroke |
920 && immutableState()->strokeColor().alpha()) { | 847 && immutableState()->strokeColor().alpha()) { |
921 // Stroke a width: 1 inset border | 848 // Stroke a width: 1 inset border |
922 SkPaint paint(immutableState()->fillPaint()); | 849 SkPaint paint(immutableState()->fillPaint()); |
923 paint.setColor(effectiveStrokeColor()); | 850 paint.setColor(strokeColor().rgb()); |
924 paint.setStyle(SkPaint::kStroke_Style); | 851 paint.setStyle(SkPaint::kStroke_Style); |
925 paint.setStrokeWidth(1); | 852 paint.setStrokeWidth(1); |
926 | 853 |
927 skRect.inset(0.5f, 0.5f); | 854 skRect.inset(0.5f, 0.5f); |
928 drawRect(skRect, paint); | 855 drawRect(skRect, paint); |
929 } | 856 } |
930 } | 857 } |
931 | 858 |
932 void GraphicsContext::drawText(const Font& font, const TextRunPaintInfo& runInfo
, const FloatPoint& point, const SkPaint& paint) | 859 void GraphicsContext::drawText(const Font& font, const TextRunPaintInfo& runInfo
, const FloatPoint& point, const SkPaint& paint) |
933 { | 860 { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1004 { | 931 { |
1005 if (!image) | 932 if (!image) |
1006 return; | 933 return; |
1007 drawImage(image, FloatRect(r), FloatRect(FloatPoint(), FloatSize(image->size
())), op, shouldRespectImageOrientation); | 934 drawImage(image, FloatRect(r), FloatRect(FloatPoint(), FloatSize(image->size
())), op, shouldRespectImageOrientation); |
1008 } | 935 } |
1009 | 936 |
1010 void GraphicsContext::drawImage(Image* image, const FloatRect& dest, const Float
Rect& src, SkXfermode::Mode op, RespectImageOrientationEnum shouldRespectImageOr
ientation) | 937 void GraphicsContext::drawImage(Image* image, const FloatRect& dest, const Float
Rect& src, SkXfermode::Mode op, RespectImageOrientationEnum shouldRespectImageOr
ientation) |
1011 { | 938 { |
1012 if (contextDisabled() || !image) | 939 if (contextDisabled() || !image) |
1013 return; | 940 return; |
1014 image->draw(this, dest, src, op, shouldRespectImageOrientation); | 941 |
| 942 SkPaint imagePaint = immutableState()->fillPaint(); |
| 943 imagePaint.setXfermodeMode(op); |
| 944 imagePaint.setColor(SK_ColorBLACK); |
| 945 imagePaint.setFilterQuality(computeFilterQuality(image, dest, src)); |
| 946 // Disable anti-aliasing if we're not rotated or skewed. |
| 947 // TODO(junov): crbug.com/492187 This code will disable antialiasing |
| 948 // regardless of whether content is pixel aligned. Is this correct? |
| 949 // For now, just preserving legacy behavior. |
| 950 imagePaint.setAntiAlias(shouldAntialiasImages()); |
| 951 bool shouldClampToSourceRect = true; |
| 952 image->draw(m_canvas, imagePaint, dest, src, shouldRespectImageOrientation,
shouldClampToSourceRect); |
| 953 } |
| 954 |
| 955 SkFilterQuality GraphicsContext::computeFilterQuality(Image* image, const FloatR
ect& dest, const FloatRect& src) const |
| 956 { |
| 957 InterpolationQuality resampling; |
| 958 if (printing()) { |
| 959 resampling = InterpolationNone; |
| 960 } else if (image->isLazyDecodedBitmap()) { |
| 961 resampling = InterpolationHigh; |
| 962 } else { |
| 963 // Take into account scale applied to the canvas when computing sampling
mode (e.g. CSS scale or page scale). |
| 964 // FIXME: In slimming paint, we create GCs on the fly when entering a ne
w DisplayItemList |
| 965 // scope, so relying on getTotalMatrix here is not sound. |
| 966 SkRect destRectTarget = dest; |
| 967 SkMatrix totalMatrix = getTotalMatrix(); |
| 968 if (!(totalMatrix.getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPersp
ective_Mask))) |
| 969 totalMatrix.mapRect(&destRectTarget, dest); |
| 970 |
| 971 resampling = computeInterpolationQuality(totalMatrix, |
| 972 SkScalarToFloat(src.width()), SkScalarToFloat(src.height()), |
| 973 SkScalarToFloat(destRectTarget.width()), SkScalarToFloat(destRectTar
get.height()), |
| 974 image->isImmutableBitmap()); |
| 975 } |
| 976 |
| 977 if (resampling == InterpolationNone) { |
| 978 // FIXME: This is to not break tests (it results in the filter bitmap fl
ag |
| 979 // being set to true). We need to decide if we respect InterpolationNone |
| 980 // being returned from computeInterpolationQuality. |
| 981 resampling = InterpolationLow; |
| 982 } |
| 983 return static_cast<SkFilterQuality>(limitInterpolationQuality(this, resampli
ng)); |
1015 } | 984 } |
1016 | 985 |
1017 void GraphicsContext::drawTiledImage(Image* image, const IntRect& destRect, cons
t IntPoint& srcPoint, const IntSize& tileSize, SkXfermode::Mode op, const IntSiz
e& repeatSpacing) | 986 void GraphicsContext::drawTiledImage(Image* image, const IntRect& destRect, cons
t IntPoint& srcPoint, const IntSize& tileSize, SkXfermode::Mode op, const IntSiz
e& repeatSpacing) |
1018 { | 987 { |
1019 if (contextDisabled() || !image) | 988 if (contextDisabled() || !image) |
1020 return; | 989 return; |
1021 image->drawTiled(this, destRect, srcPoint, tileSize, op, repeatSpacing); | 990 image->drawTiled(this, destRect, srcPoint, tileSize, op, repeatSpacing); |
1022 } | 991 } |
1023 | 992 |
1024 void GraphicsContext::drawTiledImage(Image* image, const IntRect& dest, const In
tRect& srcRect, | 993 void GraphicsContext::drawTiledImage(Image* image, const IntRect& dest, const In
tRect& srcRect, |
(...skipping 22 matching lines...) Expand all Loading... |
1047 | 1016 |
1048 void GraphicsContext::writePixels(const SkImageInfo& info, const void* pixels, s
ize_t rowBytes, int x, int y) | 1017 void GraphicsContext::writePixels(const SkImageInfo& info, const void* pixels, s
ize_t rowBytes, int x, int y) |
1049 { | 1018 { |
1050 if (contextDisabled()) | 1019 if (contextDisabled()) |
1051 return; | 1020 return; |
1052 ASSERT(m_canvas); | 1021 ASSERT(m_canvas); |
1053 | 1022 |
1054 m_canvas->writePixels(info, pixels, rowBytes, x, y); | 1023 m_canvas->writePixels(info, pixels, rowBytes, x, y); |
1055 } | 1024 } |
1056 | 1025 |
1057 void GraphicsContext::drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, | |
1058 const SkRect& dst, const SkPaint* paint) | |
1059 { | |
1060 // Textures are bound to the blink main-thread GrContext, which can not be | |
1061 // used on the compositor raster thread. | |
1062 // FIXME: Mailbox support would make this possible in the GPU-raster case. | |
1063 // If we're printing it is safe to access the texture because we are always | |
1064 // on main thread, even if the other conditions are not met. | |
1065 ASSERT(!isRecording() || !bitmap.getTexture() || printing()); | |
1066 if (contextDisabled()) | |
1067 return; | |
1068 | |
1069 SkCanvas::DrawBitmapRectFlags flags = | |
1070 immutableState()->shouldClampToSourceRect() ? SkCanvas::kNone_DrawBitmap
RectFlag : SkCanvas::kBleed_DrawBitmapRectFlag; | |
1071 | |
1072 ASSERT(m_canvas); | |
1073 m_canvas->drawBitmapRectToRect(bitmap, src, dst, paint, flags); | |
1074 } | |
1075 | |
1076 void GraphicsContext::drawOval(const SkRect& oval, const SkPaint& paint) | 1026 void GraphicsContext::drawOval(const SkRect& oval, const SkPaint& paint) |
1077 { | 1027 { |
1078 if (contextDisabled()) | 1028 if (contextDisabled()) |
1079 return; | 1029 return; |
1080 ASSERT(m_canvas); | 1030 ASSERT(m_canvas); |
1081 | 1031 |
1082 m_canvas->drawOval(oval, paint); | 1032 m_canvas->drawOval(oval, paint); |
1083 } | 1033 } |
1084 | 1034 |
1085 void GraphicsContext::drawPath(const SkPath& path, const SkPaint& paint) | 1035 void GraphicsContext::drawPath(const SkPath& path, const SkPaint& paint) |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1132 return; | 1082 return; |
1133 | 1083 |
1134 drawRect(rect, immutableState()->fillPaint()); | 1084 drawRect(rect, immutableState()->fillPaint()); |
1135 } | 1085 } |
1136 | 1086 |
1137 void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, SkXfer
mode::Mode xferMode) | 1087 void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, SkXfer
mode::Mode xferMode) |
1138 { | 1088 { |
1139 if (contextDisabled()) | 1089 if (contextDisabled()) |
1140 return; | 1090 return; |
1141 | 1091 |
1142 if (color == fillColor() && xferMode == compositeOperation()) { | |
1143 drawRect(rect, immutableState()->fillPaint()); | |
1144 return; | |
1145 } | |
1146 | |
1147 SkPaint paint = immutableState()->fillPaint(); | 1092 SkPaint paint = immutableState()->fillPaint(); |
1148 paint.setColor(color.rgb()); | 1093 paint.setColor(color.rgb()); |
1149 paint.setXfermodeMode(xferMode); | 1094 paint.setXfermodeMode(xferMode); |
1150 | 1095 |
1151 drawRect(rect, paint); | 1096 drawRect(rect, paint); |
1152 } | 1097 } |
1153 | 1098 |
1154 void GraphicsContext::fillRoundedRect(const FloatRoundedRect& rrect, const Color
& color) | 1099 void GraphicsContext::fillRoundedRect(const FloatRoundedRect& rrect, const Color
& color) |
1155 { | 1100 { |
1156 if (contextDisabled()) | 1101 if (contextDisabled()) |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1641 { | 1586 { |
1642 static const SkPMColor colors[] = { | 1587 static const SkPMColor colors[] = { |
1643 SkPreMultiplyARGB(0x60, 0xFF, 0x00, 0x00), // More transparent red | 1588 SkPreMultiplyARGB(0x60, 0xFF, 0x00, 0x00), // More transparent red |
1644 SkPreMultiplyARGB(0x60, 0xC0, 0xC0, 0xC0) // More transparent gray | 1589 SkPreMultiplyARGB(0x60, 0xC0, 0xC0, 0xC0) // More transparent gray |
1645 }; | 1590 }; |
1646 | 1591 |
1647 return colors[index]; | 1592 return colors[index]; |
1648 } | 1593 } |
1649 #endif | 1594 #endif |
1650 | 1595 |
1651 int GraphicsContext::preparePaintForDrawRectToRect( | |
1652 SkPaint* paint, | |
1653 const SkRect& srcRect, | |
1654 const SkRect& destRect, | |
1655 SkXfermode::Mode compositeOp, | |
1656 bool isBitmapWithAlpha, | |
1657 bool isLazyDecoded, | |
1658 bool isDataComplete) const | |
1659 { | |
1660 int initialSaveCount = m_canvas->getSaveCount(); | |
1661 | |
1662 paint->setColorFilter(this->colorFilter()); | |
1663 paint->setAlpha(this->getNormalizedAlpha()); | |
1664 bool usingImageFilter = false; | |
1665 if (dropShadowImageFilter() && isBitmapWithAlpha) { | |
1666 SkMatrix ctm = getTotalMatrix(); | |
1667 SkMatrix invCtm; | |
1668 if (ctm.invert(&invCtm)) { | |
1669 usingImageFilter = true; | |
1670 // The image filter is meant to ignore tranforms with respect to | |
1671 // the shadow parameters. The matrix tweaks below ensures that the i
mage | |
1672 // filter is applied in post-transform space. We use concat() instea
d of | |
1673 // setMatrix() in case this goes into a recording canvas which may n
eed to | |
1674 // respect a parent transform at playback time. | |
1675 m_canvas->save(); | |
1676 m_canvas->concat(invCtm); | |
1677 SkRect bounds = destRect; | |
1678 ctm.mapRect(&bounds); | |
1679 SkRect filteredBounds; | |
1680 dropShadowImageFilter()->computeFastBounds(bounds, &filteredBounds); | |
1681 SkPaint layerPaint; | |
1682 layerPaint.setXfermodeMode(compositeOp); | |
1683 layerPaint.setImageFilter(dropShadowImageFilter()); | |
1684 m_canvas->saveLayer(&filteredBounds, &layerPaint); | |
1685 m_canvas->concat(ctm); | |
1686 } | |
1687 } | |
1688 | |
1689 if (!usingImageFilter) { | |
1690 paint->setXfermodeMode(compositeOp); | |
1691 paint->setLooper(this->drawLooper()); | |
1692 } | |
1693 | |
1694 paint->setAntiAlias(shouldDrawAntiAliased(this, destRect)); | |
1695 | |
1696 InterpolationQuality resampling; | |
1697 if (this->isAccelerated()) { | |
1698 resampling = InterpolationLow; | |
1699 } else if (this->printing()) { | |
1700 resampling = InterpolationNone; | |
1701 } else if (isLazyDecoded) { | |
1702 resampling = InterpolationHigh; | |
1703 } else { | |
1704 // Take into account scale applied to the canvas when computing sampling
mode (e.g. CSS scale or page scale). | |
1705 SkRect destRectTarget = destRect; | |
1706 SkMatrix totalMatrix = this->getTotalMatrix(); | |
1707 if (!(totalMatrix.getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPersp
ective_Mask))) | |
1708 totalMatrix.mapRect(&destRectTarget, destRect); | |
1709 | |
1710 resampling = computeInterpolationQuality(totalMatrix, | |
1711 SkScalarToFloat(srcRect.width()), SkScalarToFloat(srcRect.height()), | |
1712 SkScalarToFloat(destRectTarget.width()), SkScalarToFloat(destRectTar
get.height()), | |
1713 isDataComplete); | |
1714 } | |
1715 | |
1716 if (resampling == InterpolationNone) { | |
1717 // FIXME: This is to not break tests (it results in the filter bitmap fl
ag | |
1718 // being set to true). We need to decide if we respect InterpolationNone | |
1719 // being returned from computeInterpolationQuality. | |
1720 resampling = InterpolationLow; | |
1721 } | |
1722 resampling = limitInterpolationQuality(this, resampling); | |
1723 paint->setFilterQuality(static_cast<SkFilterQuality>(resampling)); | |
1724 | |
1725 return initialSaveCount; | |
1726 } | |
1727 | |
1728 } // namespace blink | 1596 } // namespace blink |
OLD | NEW |