SVGImageContext.cpp (4680B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 // Main header first: 8 #include "SVGImageContext.h" 9 10 // Keep others in (case-insensitive) order: 11 #include "gfxUtils.h" 12 #include "mozilla/LookAndFeel.h" 13 #include "mozilla/ServoCSSParser.h" 14 #include "mozilla/StaticPrefs_svg.h" 15 #include "mozilla/dom/Document.h" 16 #include "nsIFrame.h" 17 #include "nsISVGPaintContext.h" 18 #include "nsPresContext.h" 19 #include "nsStyleStruct.h" 20 21 namespace mozilla { 22 23 /* static */ 24 void SVGImageContext::MaybeStoreContextPaint(SVGImageContext& aContext, 25 nsIFrame* aFromFrame, 26 imgIContainer* aImgContainer) { 27 return MaybeStoreContextPaint(aContext, *aFromFrame->PresContext(), 28 *aFromFrame->Style(), aImgContainer); 29 } 30 31 /* static */ 32 void SVGImageContext::MaybeStoreContextPaint(SVGImageContext& aContext, 33 const nsPresContext& aPresContext, 34 const ComputedStyle& aStyle, 35 imgIContainer* aImgContainer) { 36 if (aImgContainer->GetType() != imgIContainer::TYPE_VECTOR) { 37 // Avoid this overhead for raster images. 38 return; 39 } 40 41 { 42 auto scheme = LookAndFeel::ColorSchemeForStyle( 43 *aPresContext.Document(), aStyle.StyleUI()->mColorScheme.bits, 44 ColorSchemeMode::Preferred); 45 aContext.SetColorScheme(Some(scheme)); 46 } 47 48 const nsStyleSVG* style = aStyle.StyleSVG(); 49 if (!style->ExposesContextProperties()) { 50 // Content must have '-moz-context-properties' set to the names of the 51 // properties it wants to expose to images it links to. 52 return; 53 } 54 55 bool haveContextPaint = false; 56 57 auto contextPaint = MakeRefPtr<SVGEmbeddingContextPaint>(); 58 59 if ((style->mMozContextProperties.bits & StyleContextPropertyBits::FILL) && 60 style->mFill.kind.IsColor()) { 61 haveContextPaint = true; 62 contextPaint->SetFill(style->mFill.kind.AsColor().CalcColor(aStyle)); 63 } 64 if ((style->mMozContextProperties.bits & StyleContextPropertyBits::STROKE) && 65 style->mStroke.kind.IsColor()) { 66 haveContextPaint = true; 67 contextPaint->SetStroke(style->mStroke.kind.AsColor().CalcColor(aStyle)); 68 } 69 if (style->mMozContextProperties.bits & 70 StyleContextPropertyBits::FILL_OPACITY) { 71 haveContextPaint = true; 72 contextPaint->SetFillOpacity(style->mFillOpacity.IsOpacity() 73 ? style->mFillOpacity.AsOpacity() 74 : 1.0f); 75 } 76 if (style->mMozContextProperties.bits & 77 StyleContextPropertyBits::STROKE_OPACITY) { 78 haveContextPaint = true; 79 contextPaint->SetStrokeOpacity(style->mStrokeOpacity.IsOpacity() 80 ? style->mStrokeOpacity.AsOpacity() 81 : 1.0f); 82 } 83 84 if (haveContextPaint) { 85 aContext.mContextPaint = std::move(contextPaint); 86 } 87 } 88 89 /* static */ 90 void SVGImageContext::MaybeStoreContextPaint(SVGImageContext& aContext, 91 nsISVGPaintContext* aPaintContext, 92 imgIContainer* aImgContainer) { 93 if (aImgContainer->GetType() != imgIContainer::TYPE_VECTOR || 94 !aPaintContext) { 95 // Avoid this overhead for raster images. 96 return; 97 } 98 99 bool haveContextPaint = false; 100 auto contextPaint = MakeRefPtr<SVGEmbeddingContextPaint>(); 101 nsCString value; 102 float opacity; 103 104 if (NS_SUCCEEDED(aPaintContext->GetStrokeColor(value)) && !value.IsEmpty()) { 105 nscolor color; 106 if (ServoCSSParser::ComputeColor(nullptr, NS_RGB(0, 0, 0), value, &color)) { 107 haveContextPaint = true; 108 contextPaint->SetStroke(color); 109 } 110 } 111 112 if (NS_SUCCEEDED(aPaintContext->GetFillColor(value)) && !value.IsEmpty()) { 113 nscolor color; 114 if (ServoCSSParser::ComputeColor(nullptr, NS_RGB(0, 0, 0), value, &color)) { 115 haveContextPaint = true; 116 contextPaint->SetFill(color); 117 } 118 } 119 120 if (NS_SUCCEEDED(aPaintContext->GetStrokeOpacity(&opacity))) { 121 haveContextPaint = true; 122 contextPaint->SetStrokeOpacity(opacity); 123 } 124 125 if (NS_SUCCEEDED(aPaintContext->GetFillOpacity(&opacity))) { 126 haveContextPaint = true; 127 contextPaint->SetFillOpacity(opacity); 128 } 129 130 if (haveContextPaint) { 131 aContext.mContextPaint = std::move(contextPaint); 132 } 133 } 134 135 } // namespace mozilla