LCOV - code coverage report
Current view: top level - layout/svg - nsCSSFilterInstance.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 214 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 19 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : // Main header first:
       7             : #include "nsCSSFilterInstance.h"
       8             : 
       9             : // Keep others in (case-insensitive) order:
      10             : #include "gfx2DGlue.h"
      11             : #include "gfxUtils.h"
      12             : #include "nsIFrame.h"
      13             : #include "nsStyleStruct.h"
      14             : #include "nsTArray.h"
      15             : 
      16             : using namespace mozilla;
      17             : using namespace mozilla::gfx;
      18             : 
      19           0 : static float ClampFactor(float aFactor)
      20             : {
      21           0 :   if (aFactor > 1) {
      22           0 :     return 1;
      23           0 :   } else if (aFactor < 0) {
      24           0 :     NS_NOTREACHED("A negative value should not have been parsed.");
      25           0 :     return 0;
      26             :   }
      27             : 
      28           0 :   return aFactor;
      29             : }
      30             : 
      31           0 : nsCSSFilterInstance::nsCSSFilterInstance(const nsStyleFilter& aFilter,
      32             :                                          nscolor aShadowFallbackColor,
      33             :                                          const nsIntRect& aTargetBoundsInFilterSpace,
      34           0 :                                          const gfxMatrix& aFrameSpaceInCSSPxToFilterSpaceTransform)
      35             :   : mFilter(aFilter)
      36             :   , mShadowFallbackColor(aShadowFallbackColor)
      37             :   , mTargetBoundsInFilterSpace(aTargetBoundsInFilterSpace)
      38           0 :   , mFrameSpaceInCSSPxToFilterSpaceTransform(aFrameSpaceInCSSPxToFilterSpaceTransform)
      39             : {
      40           0 : }
      41             : 
      42             : nsresult
      43           0 : nsCSSFilterInstance::BuildPrimitives(nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
      44             :                                      bool aInputIsTainted)
      45             : {
      46           0 :   FilterPrimitiveDescription descr;
      47             :   nsresult result;
      48             : 
      49           0 :   switch(mFilter.GetType()) {
      50             :     case NS_STYLE_FILTER_BLUR:
      51           0 :       descr = CreatePrimitiveDescription(PrimitiveType::GaussianBlur,
      52             :                                          aPrimitiveDescrs,
      53           0 :                                          aInputIsTainted);
      54           0 :       result = SetAttributesForBlur(descr);
      55           0 :       break;
      56             :     case NS_STYLE_FILTER_BRIGHTNESS:
      57           0 :       descr = CreatePrimitiveDescription(PrimitiveType::ComponentTransfer,
      58             :                                          aPrimitiveDescrs,
      59           0 :                                          aInputIsTainted);
      60           0 :       result = SetAttributesForBrightness(descr);
      61           0 :       break;
      62             :     case NS_STYLE_FILTER_CONTRAST:
      63           0 :       descr = CreatePrimitiveDescription(PrimitiveType::ComponentTransfer,
      64             :                                          aPrimitiveDescrs,
      65           0 :                                          aInputIsTainted);
      66           0 :       result = SetAttributesForContrast(descr);
      67           0 :       break;
      68             :     case NS_STYLE_FILTER_DROP_SHADOW:
      69           0 :       descr = CreatePrimitiveDescription(PrimitiveType::DropShadow,
      70             :                                          aPrimitiveDescrs,
      71           0 :                                          aInputIsTainted);
      72           0 :       result = SetAttributesForDropShadow(descr);
      73           0 :       break;
      74             :     case NS_STYLE_FILTER_GRAYSCALE:
      75           0 :       descr = CreatePrimitiveDescription(PrimitiveType::ColorMatrix,
      76             :                                          aPrimitiveDescrs,
      77           0 :                                          aInputIsTainted);
      78           0 :       result = SetAttributesForGrayscale(descr);
      79           0 :       break;
      80             :     case NS_STYLE_FILTER_HUE_ROTATE:
      81           0 :       descr = CreatePrimitiveDescription(PrimitiveType::ColorMatrix,
      82             :                                          aPrimitiveDescrs,
      83           0 :                                          aInputIsTainted);
      84           0 :       result = SetAttributesForHueRotate(descr);
      85           0 :       break;
      86             :     case NS_STYLE_FILTER_INVERT:
      87           0 :       descr = CreatePrimitiveDescription(PrimitiveType::ComponentTransfer,
      88             :                                          aPrimitiveDescrs,
      89           0 :                                          aInputIsTainted);
      90           0 :       result = SetAttributesForInvert(descr);
      91           0 :       break;
      92             :     case NS_STYLE_FILTER_OPACITY:
      93           0 :       descr = CreatePrimitiveDescription(PrimitiveType::ComponentTransfer,
      94             :                                          aPrimitiveDescrs,
      95           0 :                                          aInputIsTainted);
      96           0 :       result = SetAttributesForOpacity(descr);
      97           0 :       break;
      98             :     case NS_STYLE_FILTER_SATURATE:
      99           0 :       descr = CreatePrimitiveDescription(PrimitiveType::ColorMatrix,
     100             :                                          aPrimitiveDescrs,
     101           0 :                                          aInputIsTainted);
     102           0 :       result = SetAttributesForSaturate(descr);
     103           0 :       break;
     104             :     case NS_STYLE_FILTER_SEPIA:
     105           0 :       descr = CreatePrimitiveDescription(PrimitiveType::ColorMatrix,
     106             :                                          aPrimitiveDescrs,
     107           0 :                                          aInputIsTainted);
     108           0 :       result = SetAttributesForSepia(descr);
     109           0 :       break;
     110             :     default:
     111           0 :       NS_NOTREACHED("not a valid CSS filter type");
     112           0 :       return NS_ERROR_FAILURE;
     113             :   }
     114             : 
     115           0 :   if (NS_FAILED(result)) {
     116           0 :     return result;
     117             :   }
     118             : 
     119             :   // Compute the primitive's bounds now that we've determined its attributes.
     120             :   // Some attributes like blur radius can influence the bounds.
     121           0 :   SetBounds(descr, aPrimitiveDescrs);
     122             : 
     123             :   // Add this primitive to the filter chain.
     124           0 :   aPrimitiveDescrs.AppendElement(descr);
     125           0 :   return NS_OK;
     126             : }
     127             : 
     128             : FilterPrimitiveDescription
     129           0 : nsCSSFilterInstance::CreatePrimitiveDescription(PrimitiveType aType,
     130             :                                                 const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
     131             :                                                 bool aInputIsTainted) {
     132           0 :   FilterPrimitiveDescription descr(aType);
     133           0 :   int32_t inputIndex = GetLastResultIndex(aPrimitiveDescrs);
     134           0 :   descr.SetInputPrimitive(0, inputIndex);
     135           0 :   descr.SetIsTainted(inputIndex < 0 ? aInputIsTainted : aPrimitiveDescrs[inputIndex].IsTainted());
     136           0 :   descr.SetInputColorSpace(0, ColorSpace::SRGB);
     137           0 :   descr.SetOutputColorSpace(ColorSpace::SRGB);
     138           0 :   return descr;
     139             : }
     140             : 
     141             : nsresult
     142           0 : nsCSSFilterInstance::SetAttributesForBlur(FilterPrimitiveDescription& aDescr)
     143             : {
     144           0 :   const nsStyleCoord& radiusInFrameSpace = mFilter.GetFilterParameter();
     145           0 :   if (radiusInFrameSpace.GetUnit() != eStyleUnit_Coord) {
     146           0 :     NS_NOTREACHED("unexpected unit");
     147           0 :     return NS_ERROR_FAILURE;
     148             :   }
     149             : 
     150           0 :   Size radiusInFilterSpace = BlurRadiusToFilterSpace(radiusInFrameSpace.GetCoordValue());
     151           0 :   aDescr.Attributes().Set(eGaussianBlurStdDeviation, radiusInFilterSpace);
     152           0 :   return NS_OK;
     153             : }
     154             : 
     155             : nsresult
     156           0 : nsCSSFilterInstance::SetAttributesForBrightness(FilterPrimitiveDescription& aDescr)
     157             : {
     158           0 :   const nsStyleCoord& styleValue = mFilter.GetFilterParameter();
     159           0 :   float value = styleValue.GetFactorOrPercentValue();
     160             : 
     161             :   // Set transfer functions for RGB.
     162           0 :   AttributeMap brightnessAttrs;
     163             :   brightnessAttrs.Set(eComponentTransferFunctionType,
     164           0 :                       (uint32_t)SVG_FECOMPONENTTRANSFER_TYPE_LINEAR);
     165           0 :   brightnessAttrs.Set(eComponentTransferFunctionSlope, value);
     166           0 :   brightnessAttrs.Set(eComponentTransferFunctionIntercept, 0.0f);
     167           0 :   aDescr.Attributes().Set(eComponentTransferFunctionR, brightnessAttrs);
     168           0 :   aDescr.Attributes().Set(eComponentTransferFunctionG, brightnessAttrs);
     169           0 :   aDescr.Attributes().Set(eComponentTransferFunctionB, brightnessAttrs);
     170             : 
     171             :   // Set identity transfer function for A.
     172           0 :   AttributeMap identityAttrs;
     173             :   identityAttrs.Set(eComponentTransferFunctionType,
     174           0 :                     (uint32_t)SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY);
     175           0 :   aDescr.Attributes().Set(eComponentTransferFunctionA, identityAttrs);
     176             : 
     177           0 :   return NS_OK;
     178             : }
     179             : 
     180             : nsresult
     181           0 : nsCSSFilterInstance::SetAttributesForContrast(FilterPrimitiveDescription& aDescr)
     182             : {
     183           0 :   const nsStyleCoord& styleValue = mFilter.GetFilterParameter();
     184           0 :   float value = styleValue.GetFactorOrPercentValue();
     185           0 :   float intercept = -(0.5 * value) + 0.5;
     186             : 
     187             :   // Set transfer functions for RGB.
     188           0 :   AttributeMap contrastAttrs;
     189             :   contrastAttrs.Set(eComponentTransferFunctionType,
     190           0 :                     (uint32_t)SVG_FECOMPONENTTRANSFER_TYPE_LINEAR);
     191           0 :   contrastAttrs.Set(eComponentTransferFunctionSlope, value);
     192           0 :   contrastAttrs.Set(eComponentTransferFunctionIntercept, intercept);
     193           0 :   aDescr.Attributes().Set(eComponentTransferFunctionR, contrastAttrs);
     194           0 :   aDescr.Attributes().Set(eComponentTransferFunctionG, contrastAttrs);
     195           0 :   aDescr.Attributes().Set(eComponentTransferFunctionB, contrastAttrs);
     196             : 
     197             :   // Set identity transfer function for A.
     198           0 :   AttributeMap identityAttrs;
     199             :   identityAttrs.Set(eComponentTransferFunctionType,
     200           0 :                     (uint32_t)SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY);
     201           0 :   aDescr.Attributes().Set(eComponentTransferFunctionA, identityAttrs);
     202             : 
     203           0 :   return NS_OK;
     204             : }
     205             : 
     206             : nsresult
     207           0 : nsCSSFilterInstance::SetAttributesForDropShadow(FilterPrimitiveDescription& aDescr)
     208             : {
     209           0 :   nsCSSShadowArray* shadows = mFilter.GetDropShadow();
     210           0 :   if (!shadows || shadows->Length() != 1) {
     211           0 :     NS_NOTREACHED("Exactly one drop shadow should have been parsed.");
     212           0 :     return NS_ERROR_FAILURE;
     213             :   }
     214             : 
     215           0 :   nsCSSShadowItem* shadow = shadows->ShadowAt(0);
     216             : 
     217             :   // Set drop shadow blur radius.
     218           0 :   Size radiusInFilterSpace = BlurRadiusToFilterSpace(shadow->mRadius);
     219           0 :   aDescr.Attributes().Set(eDropShadowStdDeviation, radiusInFilterSpace);
     220             : 
     221             :   // Set offset.
     222           0 :   IntPoint offsetInFilterSpace = OffsetToFilterSpace(shadow->mXOffset, shadow->mYOffset);
     223           0 :   aDescr.Attributes().Set(eDropShadowOffset, offsetInFilterSpace);
     224             : 
     225             :   // Set color. If unspecified, use the CSS color property.
     226           0 :   nscolor shadowColor = shadow->mHasColor ? shadow->mColor : mShadowFallbackColor;
     227           0 :   aDescr.Attributes().Set(eDropShadowColor, ToAttributeColor(shadowColor));
     228             : 
     229           0 :   return NS_OK;
     230             : }
     231             : 
     232             : nsresult
     233           0 : nsCSSFilterInstance::SetAttributesForGrayscale(FilterPrimitiveDescription& aDescr)
     234             : {
     235             :   // Set color matrix type.
     236           0 :   aDescr.Attributes().Set(eColorMatrixType, (uint32_t)SVG_FECOLORMATRIX_TYPE_SATURATE);
     237             : 
     238             :   // Set color matrix values.
     239           0 :   const nsStyleCoord& styleValue = mFilter.GetFilterParameter();
     240           0 :   float value = 1 - ClampFactor(styleValue.GetFactorOrPercentValue());
     241           0 :   aDescr.Attributes().Set(eColorMatrixValues, &value, 1);
     242             : 
     243           0 :   return NS_OK;
     244             : }
     245             : 
     246             : nsresult
     247           0 : nsCSSFilterInstance::SetAttributesForHueRotate(FilterPrimitiveDescription& aDescr)
     248             : {
     249             :   // Set color matrix type.
     250           0 :   aDescr.Attributes().Set(eColorMatrixType, (uint32_t)SVG_FECOLORMATRIX_TYPE_HUE_ROTATE);
     251             : 
     252             :   // Set color matrix values.
     253           0 :   const nsStyleCoord& styleValue = mFilter.GetFilterParameter();
     254           0 :   float value = styleValue.GetAngleValueInDegrees();
     255           0 :   aDescr.Attributes().Set(eColorMatrixValues, &value, 1);
     256             : 
     257           0 :   return NS_OK;
     258             : }
     259             : 
     260             : nsresult
     261           0 : nsCSSFilterInstance::SetAttributesForInvert(FilterPrimitiveDescription& aDescr)
     262             : {
     263           0 :   const nsStyleCoord& styleValue = mFilter.GetFilterParameter();
     264           0 :   float value = ClampFactor(styleValue.GetFactorOrPercentValue());
     265             : 
     266             :   // Set transfer functions for RGB.
     267           0 :   AttributeMap invertAttrs;
     268             :   float invertTableValues[2];
     269           0 :   invertTableValues[0] = value;
     270           0 :   invertTableValues[1] = 1 - value;
     271             :   invertAttrs.Set(eComponentTransferFunctionType,
     272           0 :                   (uint32_t)SVG_FECOMPONENTTRANSFER_TYPE_TABLE);
     273           0 :   invertAttrs.Set(eComponentTransferFunctionTableValues, invertTableValues, 2);
     274           0 :   aDescr.Attributes().Set(eComponentTransferFunctionR, invertAttrs);
     275           0 :   aDescr.Attributes().Set(eComponentTransferFunctionG, invertAttrs);
     276           0 :   aDescr.Attributes().Set(eComponentTransferFunctionB, invertAttrs);
     277             : 
     278             :   // Set identity transfer function for A.
     279           0 :   AttributeMap identityAttrs;
     280             :   identityAttrs.Set(eComponentTransferFunctionType,
     281           0 :                     (uint32_t)SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY);
     282           0 :   aDescr.Attributes().Set(eComponentTransferFunctionA, identityAttrs);
     283             : 
     284           0 :   return NS_OK;
     285             : }
     286             : 
     287             : nsresult
     288           0 : nsCSSFilterInstance::SetAttributesForOpacity(FilterPrimitiveDescription& aDescr)
     289             : {
     290           0 :   const nsStyleCoord& styleValue = mFilter.GetFilterParameter();
     291           0 :   float value = ClampFactor(styleValue.GetFactorOrPercentValue());
     292             : 
     293             :   // Set identity transfer functions for RGB.
     294           0 :   AttributeMap identityAttrs;
     295             :   identityAttrs.Set(eComponentTransferFunctionType,
     296           0 :                     (uint32_t)SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY);
     297           0 :   aDescr.Attributes().Set(eComponentTransferFunctionR, identityAttrs);
     298           0 :   aDescr.Attributes().Set(eComponentTransferFunctionG, identityAttrs);
     299           0 :   aDescr.Attributes().Set(eComponentTransferFunctionB, identityAttrs);
     300             : 
     301             :   // Set transfer function for A.
     302           0 :   AttributeMap opacityAttrs;
     303             :   float opacityTableValues[2];
     304           0 :   opacityTableValues[0] = 0;
     305           0 :   opacityTableValues[1] = value;
     306             :   opacityAttrs.Set(eComponentTransferFunctionType,
     307           0 :                   (uint32_t)SVG_FECOMPONENTTRANSFER_TYPE_TABLE);
     308           0 :   opacityAttrs.Set(eComponentTransferFunctionTableValues, opacityTableValues, 2);
     309           0 :   aDescr.Attributes().Set(eComponentTransferFunctionA, opacityAttrs);
     310             : 
     311           0 :   return NS_OK;
     312             : }
     313             : 
     314             : nsresult
     315           0 : nsCSSFilterInstance::SetAttributesForSaturate(FilterPrimitiveDescription& aDescr)
     316             : {
     317             :   // Set color matrix type.
     318           0 :   aDescr.Attributes().Set(eColorMatrixType, (uint32_t)SVG_FECOLORMATRIX_TYPE_SATURATE);
     319             : 
     320             :   // Set color matrix values.
     321           0 :   const nsStyleCoord& styleValue = mFilter.GetFilterParameter();
     322           0 :   float value = styleValue.GetFactorOrPercentValue();
     323           0 :   aDescr.Attributes().Set(eColorMatrixValues, &value, 1);
     324             : 
     325           0 :   return NS_OK;
     326             : }
     327             : 
     328             : nsresult
     329           0 : nsCSSFilterInstance::SetAttributesForSepia(FilterPrimitiveDescription& aDescr)
     330             : {
     331             :   // Set color matrix type.
     332           0 :   aDescr.Attributes().Set(eColorMatrixType, (uint32_t)SVG_FECOLORMATRIX_TYPE_SEPIA);
     333             : 
     334             :   // Set color matrix values.
     335           0 :   const nsStyleCoord& styleValue = mFilter.GetFilterParameter();
     336           0 :   float value = ClampFactor(styleValue.GetFactorOrPercentValue());
     337           0 :   aDescr.Attributes().Set(eColorMatrixValues, &value, 1);
     338             : 
     339           0 :   return NS_OK;
     340             : }
     341             : 
     342             : Size
     343           0 : nsCSSFilterInstance::BlurRadiusToFilterSpace(nscoord aRadiusInFrameSpace)
     344             : {
     345             :   float radiusInFrameSpaceInCSSPx =
     346           0 :     nsPresContext::AppUnitsToFloatCSSPixels(aRadiusInFrameSpace);
     347             : 
     348             :   // Convert the radius to filter space.
     349             :   Size radiusInFilterSpace(radiusInFrameSpaceInCSSPx,
     350           0 :                            radiusInFrameSpaceInCSSPx);
     351             :   gfxSize frameSpaceInCSSPxToFilterSpaceScale =
     352           0 :     mFrameSpaceInCSSPxToFilterSpaceTransform.ScaleFactors(true);
     353           0 :   radiusInFilterSpace.Scale(frameSpaceInCSSPxToFilterSpaceScale.width,
     354           0 :                             frameSpaceInCSSPxToFilterSpaceScale.height);
     355             : 
     356             :   // Check the radius limits.
     357           0 :   if (radiusInFilterSpace.width < 0 || radiusInFilterSpace.height < 0) {
     358           0 :     NS_NOTREACHED("we shouldn't have parsed a negative radius in the style");
     359           0 :     return Size();
     360             :   }
     361           0 :   Float maxStdDeviation = (Float)kMaxStdDeviation;
     362           0 :   radiusInFilterSpace.width = std::min(radiusInFilterSpace.width, maxStdDeviation);
     363           0 :   radiusInFilterSpace.height = std::min(radiusInFilterSpace.height, maxStdDeviation);
     364             : 
     365           0 :   return radiusInFilterSpace;
     366             : }
     367             : 
     368             : IntPoint
     369           0 : nsCSSFilterInstance::OffsetToFilterSpace(nscoord aXOffsetInFrameSpace,
     370             :                                          nscoord aYOffsetInFrameSpace)
     371             : {
     372           0 :   gfxPoint offsetInFilterSpace(nsPresContext::AppUnitsToFloatCSSPixels(aXOffsetInFrameSpace),
     373           0 :                                nsPresContext::AppUnitsToFloatCSSPixels(aYOffsetInFrameSpace));
     374             : 
     375             :   // Convert the radius to filter space.
     376             :   gfxSize frameSpaceInCSSPxToFilterSpaceScale =
     377           0 :     mFrameSpaceInCSSPxToFilterSpaceTransform.ScaleFactors(true);
     378           0 :   offsetInFilterSpace.x *= frameSpaceInCSSPxToFilterSpaceScale.width;
     379           0 :   offsetInFilterSpace.y *= frameSpaceInCSSPxToFilterSpaceScale.height;
     380             : 
     381           0 :   return IntPoint(int32_t(offsetInFilterSpace.x), int32_t(offsetInFilterSpace.y));
     382             : }
     383             : 
     384             : Color
     385           0 : nsCSSFilterInstance::ToAttributeColor(nscolor aColor)
     386             : {
     387           0 :   return Color(
     388           0 :     NS_GET_R(aColor) / 255.0,
     389           0 :     NS_GET_G(aColor) / 255.0,
     390           0 :     NS_GET_B(aColor) / 255.0,
     391           0 :     NS_GET_A(aColor) / 255.0
     392           0 :   );
     393             : }
     394             : 
     395             : int32_t
     396           0 : nsCSSFilterInstance::GetLastResultIndex(const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs)
     397             : {
     398           0 :   uint32_t numPrimitiveDescrs = aPrimitiveDescrs.Length();
     399           0 :   return !numPrimitiveDescrs ?
     400             :     FilterPrimitiveDescription::kPrimitiveIndexSourceGraphic :
     401           0 :     numPrimitiveDescrs - 1;
     402             : }
     403             : 
     404             : void
     405           0 : nsCSSFilterInstance::SetBounds(FilterPrimitiveDescription& aDescr,
     406             :                                const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs)
     407             : {
     408           0 :   int32_t inputIndex = GetLastResultIndex(aPrimitiveDescrs);
     409             :   nsIntRect inputBounds = (inputIndex < 0) ?
     410           0 :     mTargetBoundsInFilterSpace : aPrimitiveDescrs[inputIndex].PrimitiveSubregion();
     411             : 
     412           0 :   nsTArray<nsIntRegion> inputExtents;
     413           0 :   inputExtents.AppendElement(inputBounds);
     414             : 
     415             :   nsIntRegion outputExtents =
     416           0 :     FilterSupport::PostFilterExtentsForPrimitive(aDescr, inputExtents);
     417           0 :   IntRect outputBounds = outputExtents.GetBounds();
     418             : 
     419           0 :   aDescr.SetPrimitiveSubregion(outputBounds);
     420           0 :   aDescr.SetFilterSpaceBounds(outputBounds);
     421           0 : }

Generated by: LCOV version 1.13