| 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 |
| 11 * notice, this list of conditions and the following disclaimer in the | 11 * notice, this list of conditions and the following disclaimer in the |
| 12 * documentation and/or other materials provided with the distribution. | 12 * documentation and/or other materials provided with the distribution. |
| 13 * | 13 * |
| 14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' | 14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
| 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS | 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
| 18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| 24 * THE POSSIBILITY OF SUCH DAMAGE. | 24 * THE POSSIBILITY OF SUCH DAMAGE. |
| 25 */ | 25 */ |
| 26 | 26 |
| 27 #include "config.h" | 27 #include "config.h" |
| 28 #include "core/platform/graphics/GraphicsContext.h" | 28 #include "core/platform/graphics/GraphicsContext.h" |
| 29 | 29 |
| 30 #include "core/platform/chromium/TraceEvent.h" |
| 30 #include "core/platform/graphics/BitmapImage.h" | 31 #include "core/platform/graphics/BitmapImage.h" |
| 32 #include "core/platform/graphics/Font.h" |
| 31 #include "core/platform/graphics/Gradient.h" | 33 #include "core/platform/graphics/Gradient.h" |
| 34 #include "core/platform/graphics/GraphicsContextAnnotation.h" |
| 32 #include "core/platform/graphics/ImageBuffer.h" | 35 #include "core/platform/graphics/ImageBuffer.h" |
| 33 #include "core/platform/graphics/IntRect.h" | 36 #include "core/platform/graphics/IntRect.h" |
| 37 #include "core/platform/graphics/Path.h" |
| 38 #include "core/platform/graphics/Pattern.h" |
| 34 #include "core/platform/graphics/RoundedRect.h" | 39 #include "core/platform/graphics/RoundedRect.h" |
| 40 #include "core/platform/graphics/TextRun.h" |
| 35 #include "core/platform/graphics/TextRunIterator.h" | 41 #include "core/platform/graphics/TextRunIterator.h" |
| 36 #include "core/platform/graphics/skia/SkiaUtils.h" | 42 #include "core/platform/graphics/skia/SkiaUtils.h" |
| 37 #include "core/platform/text/BidiResolver.h" | 43 #include "core/platform/text/BidiResolver.h" |
| 38 #include "third_party/skia/include/core/SkAnnotation.h" | 44 #include "third_party/skia/include/core/SkAnnotation.h" |
| 39 #include "third_party/skia/include/core/SkColorFilter.h" | 45 #include "third_party/skia/include/core/SkColorFilter.h" |
| 46 #include "third_party/skia/include/core/SkColorPriv.h" |
| 40 #include "third_party/skia/include/core/SkData.h" | 47 #include "third_party/skia/include/core/SkData.h" |
| 41 #include "third_party/skia/include/core/SkDevice.h" | 48 #include "third_party/skia/include/core/SkDevice.h" |
| 42 #include "third_party/skia/include/core/SkRRect.h" | 49 #include "third_party/skia/include/core/SkRRect.h" |
| 43 #include "third_party/skia/include/core/SkRefCnt.h" | 50 #include "third_party/skia/include/core/SkRefCnt.h" |
| 44 #include "third_party/skia/include/effects/SkBlurMaskFilter.h" | 51 #include "third_party/skia/include/effects/SkBlurMaskFilter.h" |
| 45 #include "third_party/skia/include/effects/SkCornerPathEffect.h" | 52 #include "third_party/skia/include/effects/SkCornerPathEffect.h" |
| 46 #include "weborigin/KURL.h" | 53 #include "weborigin/KURL.h" |
| 47 #include "wtf/Assertions.h" | 54 #include "wtf/Assertions.h" |
| 48 #include "wtf/MathExtras.h" | 55 #include "wtf/MathExtras.h" |
| 49 | 56 |
| 50 #if OS(DARWIN) | 57 #if OS(DARWIN) |
| 51 #include <ApplicationServices/ApplicationServices.h> | 58 #include <ApplicationServices/ApplicationServices.h> |
| 52 #endif | 59 #endif |
| 53 | 60 |
| 54 using namespace std; | 61 using namespace std; |
| 55 | 62 |
| 56 namespace WebCore { | 63 namespace WebCore { |
| 57 | 64 |
| 65 // Helper function for applying the state's alpha value to the given input |
| 66 // color to produce a new output color. |
| 67 static SkColor applyAlpha(SkColor c, float alpha) |
| 68 { |
| 69 int s = roundf(alpha * 256); |
| 70 if (s >= 256) |
| 71 return c; |
| 72 if (s < 0) |
| 73 return 0; |
| 74 |
| 75 int a = SkAlphaMul(SkColorGetA(c), s); |
| 76 return (c & 0x00FFFFFF) | (a << 24); |
| 77 } |
| 78 |
| 58 struct GraphicsContext::DeferredSaveState { | 79 struct GraphicsContext::DeferredSaveState { |
| 59 DeferredSaveState(unsigned mask, int count) : m_flags(mask), m_restoreCount(
count) { } | 80 DeferredSaveState(unsigned mask, int count) : m_flags(mask), m_restoreCount(
count) { } |
| 60 | 81 |
| 61 unsigned m_flags; | 82 unsigned m_flags; |
| 62 int m_restoreCount; | 83 int m_restoreCount; |
| 63 }; | 84 }; |
| 64 | 85 |
| 65 GraphicsContext::GraphicsContext(SkCanvas* canvas) | 86 GraphicsContext::GraphicsContext(SkCanvas* canvas) |
| 66 : m_canvas(canvas) | 87 : m_canvas(canvas) |
| 67 , m_deferredSaveFlags(0) | 88 , m_deferredSaveFlags(0) |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 return; | 214 return; |
| 194 | 215 |
| 195 canvas()->endCommentGroup(); | 216 canvas()->endCommentGroup(); |
| 196 | 217 |
| 197 ASSERT(m_annotationCount > 0); | 218 ASSERT(m_annotationCount > 0); |
| 198 #if !ASSERT_DISABLED | 219 #if !ASSERT_DISABLED |
| 199 --m_annotationCount; | 220 --m_annotationCount; |
| 200 #endif | 221 #endif |
| 201 } | 222 } |
| 202 | 223 |
| 203 void GraphicsContext::setStrokeColor(const Color& color) | 224 SkColor GraphicsContext::effectiveStrokeColor() const |
| 204 { | 225 { |
| 205 m_state->m_strokeData.setColor(color); | 226 return applyAlpha(m_state->m_strokeData.color().rgb(), m_state->m_alpha); |
| 206 m_state->m_strokeData.clearGradient(); | |
| 207 m_state->m_strokeData.clearPattern(); | |
| 208 } | 227 } |
| 209 | 228 |
| 210 void GraphicsContext::setStrokePattern(PassRefPtr<Pattern> pattern) | 229 void GraphicsContext::setStrokePattern(PassRefPtr<Pattern> pattern) |
| 211 { | 230 { |
| 212 if (paintingDisabled()) | 231 if (paintingDisabled()) |
| 213 return; | 232 return; |
| 214 | 233 |
| 215 ASSERT(pattern); | 234 ASSERT(pattern); |
| 216 if (!pattern) { | 235 if (!pattern) { |
| 217 setStrokeColor(Color::black); | 236 setStrokeColor(Color::black); |
| 218 return; | 237 return; |
| 219 } | 238 } |
| 220 m_state->m_strokeData.clearGradient(); | |
| 221 m_state->m_strokeData.setPattern(pattern); | 239 m_state->m_strokeData.setPattern(pattern); |
| 222 } | 240 } |
| 223 | 241 |
| 224 void GraphicsContext::setStrokeGradient(PassRefPtr<Gradient> gradient) | 242 void GraphicsContext::setStrokeGradient(PassRefPtr<Gradient> gradient) |
| 225 { | 243 { |
| 226 if (paintingDisabled()) | 244 if (paintingDisabled()) |
| 227 return; | 245 return; |
| 228 | 246 |
| 229 ASSERT(gradient); | 247 ASSERT(gradient); |
| 230 if (!gradient) { | 248 if (!gradient) { |
| 231 setStrokeColor(Color::black); | 249 setStrokeColor(Color::black); |
| 232 return; | 250 return; |
| 233 } | 251 } |
| 234 m_state->m_strokeData.setGradient(gradient); | 252 m_state->m_strokeData.setGradient(gradient); |
| 235 m_state->m_strokeData.clearPattern(); | |
| 236 } | 253 } |
| 237 | 254 |
| 238 void GraphicsContext::setFillColor(const Color& color) | 255 void GraphicsContext::setFillColor(const Color& color) |
| 239 { | 256 { |
| 240 m_state->m_fillColor = color; | 257 m_state->m_fillColor = color; |
| 241 m_state->m_fillGradient.clear(); | 258 m_state->m_fillGradient.clear(); |
| 242 m_state->m_fillPattern.clear(); | 259 m_state->m_fillPattern.clear(); |
| 243 } | 260 } |
| 244 | 261 |
| 262 SkColor GraphicsContext::effectiveFillColor() const |
| 263 { |
| 264 return applyAlpha(m_state->m_fillColor.rgb(), m_state->m_alpha); |
| 265 } |
| 266 |
| 245 void GraphicsContext::setFillPattern(PassRefPtr<Pattern> pattern) | 267 void GraphicsContext::setFillPattern(PassRefPtr<Pattern> pattern) |
| 246 { | 268 { |
| 247 if (paintingDisabled()) | 269 if (paintingDisabled()) |
| 248 return; | 270 return; |
| 249 | 271 |
| 250 ASSERT(pattern); | 272 ASSERT(pattern); |
| 251 if (!pattern) { | 273 if (!pattern) { |
| 252 setFillColor(Color::black); | 274 setFillColor(Color::black); |
| 253 return; | 275 return; |
| 254 } | 276 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 } | 393 } |
| 372 | 394 |
| 373 bool GraphicsContext::readPixels(SkBitmap* bitmap, int x, int y, SkCanvas::Confi
g8888 config8888) | 395 bool GraphicsContext::readPixels(SkBitmap* bitmap, int x, int y, SkCanvas::Confi
g8888 config8888) |
| 374 { | 396 { |
| 375 if (paintingDisabled()) | 397 if (paintingDisabled()) |
| 376 return false; | 398 return false; |
| 377 | 399 |
| 378 return m_canvas->readPixels(bitmap, x, y, config8888); | 400 return m_canvas->readPixels(bitmap, x, y, config8888); |
| 379 } | 401 } |
| 380 | 402 |
| 381 void GraphicsContext::setMatrix(const SkMatrix& matrix) | 403 void GraphicsContext::setCTM(const AffineTransform& transform) |
| 382 { | 404 { |
| 383 if (paintingDisabled()) | 405 if (paintingDisabled()) |
| 384 return; | 406 return; |
| 385 | 407 |
| 386 realizeSave(SkCanvas::kMatrix_SaveFlag); | 408 realizeSave(SkCanvas::kMatrix_SaveFlag); |
| 387 | 409 m_canvas->setMatrix(transform); |
| 388 m_canvas->setMatrix(matrix); | |
| 389 } | 410 } |
| 390 | 411 |
| 391 bool GraphicsContext::concat(const SkMatrix& matrix) | 412 void GraphicsContext::concatCTM(const AffineTransform& transform) |
| 392 { | 413 { |
| 393 if (paintingDisabled()) | 414 if (paintingDisabled()) |
| 394 return false; | 415 return; |
| 395 | 416 |
| 396 realizeSave(SkCanvas::kMatrix_SaveFlag); | 417 realizeSave(SkCanvas::kMatrix_SaveFlag); |
| 397 | 418 m_canvas->concat(transform); |
| 398 return m_canvas->concat(matrix); | |
| 399 } | 419 } |
| 400 | 420 |
| 401 void GraphicsContext::beginTransparencyLayer(float opacity) | 421 void GraphicsContext::beginTransparencyLayer(float opacity) |
| 402 { | 422 { |
| 403 if (paintingDisabled()) | 423 if (paintingDisabled()) |
| 404 return; | 424 return; |
| 405 | 425 |
| 406 // We need the "alpha" layer flag here because the base layer is opaque | 426 // We need the "alpha" layer flag here because the base layer is opaque |
| 407 // (the surface of the page) but layers on top may have transparent parts. | 427 // (the surface of the page) but layers on top may have transparent parts. |
| 408 // Without explicitly setting the alpha flag, the layer will inherit the | 428 // Without explicitly setting the alpha flag, the layer will inherit the |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 } | 934 } |
| 915 | 935 |
| 916 void GraphicsContext::drawEmphasisMarks(const Font& font, const TextRunPaintInfo
& runInfo, const AtomicString& mark, const FloatPoint& point) | 936 void GraphicsContext::drawEmphasisMarks(const Font& font, const TextRunPaintInfo
& runInfo, const AtomicString& mark, const FloatPoint& point) |
| 917 { | 937 { |
| 918 if (paintingDisabled()) | 938 if (paintingDisabled()) |
| 919 return; | 939 return; |
| 920 | 940 |
| 921 font.drawEmphasisMarks(this, runInfo, mark, point); | 941 font.drawEmphasisMarks(this, runInfo, mark, point); |
| 922 } | 942 } |
| 923 | 943 |
| 924 void GraphicsContext::drawBidiText(const Font& font, const TextRunPaintInfo& run
Info, const FloatPoint& point, Font::CustomFontNotReadyAction customFontNotReady
Action) | 944 void GraphicsContext::drawBidiText(const Font& font, const TextRunPaintInfo& run
Info, const FloatPoint& point, CustomFontNotReadyAction customFontNotReadyAction
) |
| 925 { | 945 { |
| 926 if (paintingDisabled()) | 946 if (paintingDisabled()) |
| 927 return; | 947 return; |
| 928 | 948 |
| 929 // sub-run painting is not supported for Bidi text. | 949 // sub-run painting is not supported for Bidi text. |
| 930 const TextRun& run = runInfo.run; | 950 const TextRun& run = runInfo.run; |
| 931 ASSERT((runInfo.from == 0) && (runInfo.to == run.length())); | 951 ASSERT((runInfo.from == 0) && (runInfo.to == run.length())); |
| 932 BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver; | 952 BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver; |
| 933 bidiResolver.setStatus(BidiStatus(run.direction(), run.directionalOverride()
)); | 953 bidiResolver.setStatus(BidiStatus(run.direction(), run.directionalOverride()
)); |
| 934 bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&run, 0)); | 954 bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&run, 0)); |
| (...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1865 | 1885 |
| 1866 if (grad) { | 1886 if (grad) { |
| 1867 shader = grad->shader(); | 1887 shader = grad->shader(); |
| 1868 color = SK_ColorBLACK; | 1888 color = SK_ColorBLACK; |
| 1869 } else if (pat) { | 1889 } else if (pat) { |
| 1870 shader = pat->shader(); | 1890 shader = pat->shader(); |
| 1871 color = SK_ColorBLACK; | 1891 color = SK_ColorBLACK; |
| 1872 paint->setFilterBitmap(imageInterpolationQuality() != InterpolationNone)
; | 1892 paint->setFilterBitmap(imageInterpolationQuality() != InterpolationNone)
; |
| 1873 } | 1893 } |
| 1874 | 1894 |
| 1875 paint->setColor(m_state->applyAlpha(color)); | 1895 paint->setColor(applyAlpha(color, m_state->m_alpha)); |
| 1876 paint->setShader(shader); | 1896 paint->setShader(shader); |
| 1877 } | 1897 } |
| 1878 | 1898 |
| 1879 | 1899 |
| 1880 void GraphicsContext::applyClipFromImage(const SkRect& rect, const SkBitmap& ima
geBuffer) | 1900 void GraphicsContext::applyClipFromImage(const SkRect& rect, const SkBitmap& ima
geBuffer) |
| 1881 { | 1901 { |
| 1882 if (paintingDisabled()) | 1902 if (paintingDisabled()) |
| 1883 return; | 1903 return; |
| 1884 | 1904 |
| 1885 // NOTE: this assumes the image mask contains opaque black for the portions
that are to be shown, as such we | 1905 // NOTE: this assumes the image mask contains opaque black for the portions
that are to be shown, as such we |
| 1886 // only look at the alpha when compositing. I'm not 100% sure this is what W
ebKit expects for image clipping. | 1906 // only look at the alpha when compositing. I'm not 100% sure this is what W
ebKit expects for image clipping. |
| 1887 SkPaint paint; | 1907 SkPaint paint; |
| 1888 paint.setXfermodeMode(SkXfermode::kDstIn_Mode); | 1908 paint.setXfermodeMode(SkXfermode::kDstIn_Mode); |
| 1889 realizeSave(SkCanvas::kMatrixClip_SaveFlag); | 1909 realizeSave(SkCanvas::kMatrixClip_SaveFlag); |
| 1890 m_canvas->save(SkCanvas::kMatrix_SaveFlag); | 1910 m_canvas->save(SkCanvas::kMatrix_SaveFlag); |
| 1891 m_canvas->resetMatrix(); | 1911 m_canvas->resetMatrix(); |
| 1892 m_canvas->drawBitmapRect(imageBuffer, 0, rect, &paint); | 1912 m_canvas->drawBitmapRect(imageBuffer, 0, rect, &paint); |
| 1893 m_canvas->restore(); | 1913 m_canvas->restore(); |
| 1894 } | 1914 } |
| 1895 | 1915 |
| 1896 void GraphicsContext::didDrawTextInRect(const SkRect& textRect) | 1916 void GraphicsContext::didDrawTextInRect(const SkRect& textRect) |
| 1897 { | 1917 { |
| 1898 if (m_trackTextRegion) { | 1918 if (m_trackTextRegion) { |
| 1899 TRACE_EVENT0("skia", "PlatformContextSkia::trackTextRegion"); | 1919 TRACE_EVENT0("skia", "PlatformContextSkia::trackTextRegion"); |
| 1900 m_textRegion.join(textRect); | 1920 m_textRegion.join(textRect); |
| 1901 } | 1921 } |
| 1902 } | 1922 } |
| 1903 | 1923 |
| 1904 } | 1924 } |
| OLD | NEW |