tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SVGFEConvolveMatrixElement.cpp (9899B)


      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 #include "mozilla/dom/SVGFEConvolveMatrixElement.h"
      8 
      9 #include <numeric>
     10 
     11 #include "DOMSVGAnimatedNumberList.h"
     12 #include "mozilla/SVGFilterInstance.h"
     13 #include "mozilla/SVGUtils.h"
     14 #include "mozilla/dom/BindContext.h"
     15 #include "mozilla/dom/Document.h"
     16 #include "mozilla/dom/SVGFEConvolveMatrixElementBinding.h"
     17 
     18 NS_IMPL_NS_NEW_SVG_ELEMENT(FEConvolveMatrix)
     19 
     20 using namespace mozilla::gfx;
     21 
     22 namespace mozilla::dom {
     23 
     24 JSObject* SVGFEConvolveMatrixElement::WrapNode(
     25    JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
     26  return SVGFEConvolveMatrixElement_Binding::Wrap(aCx, this, aGivenProto);
     27 }
     28 
     29 SVGElement::NumberInfo SVGFEConvolveMatrixElement::sNumberInfo[2] = {
     30    {nsGkAtoms::divisor, 1}, {nsGkAtoms::bias, 0}};
     31 
     32 SVGElement::NumberPairInfo SVGFEConvolveMatrixElement::sNumberPairInfo[1] = {
     33    {nsGkAtoms::kernelUnitLength, 0, 0}};
     34 
     35 SVGElement::IntegerInfo SVGFEConvolveMatrixElement::sIntegerInfo[2] = {
     36    {nsGkAtoms::targetX, 0}, {nsGkAtoms::targetY, 0}};
     37 
     38 SVGElement::IntegerPairInfo SVGFEConvolveMatrixElement::sIntegerPairInfo[1] = {
     39    {nsGkAtoms::order, 3, 3}};
     40 
     41 SVGElement::BooleanInfo SVGFEConvolveMatrixElement::sBooleanInfo[1] = {
     42    {nsGkAtoms::preserveAlpha, false}};
     43 
     44 SVGEnumMapping SVGFEConvolveMatrixElement::sEdgeModeMap[] = {
     45    {nsGkAtoms::duplicate, SVG_EDGEMODE_DUPLICATE},
     46    {nsGkAtoms::wrap, SVG_EDGEMODE_WRAP},
     47    {nsGkAtoms::none, SVG_EDGEMODE_NONE},
     48    {nullptr, 0}};
     49 
     50 SVGElement::EnumInfo SVGFEConvolveMatrixElement::sEnumInfo[1] = {
     51    {nsGkAtoms::edgeMode, sEdgeModeMap, SVG_EDGEMODE_DUPLICATE}};
     52 
     53 SVGElement::StringInfo SVGFEConvolveMatrixElement::sStringInfo[2] = {
     54    {nsGkAtoms::result, kNameSpaceID_None, true},
     55    {nsGkAtoms::in, kNameSpaceID_None, true}};
     56 
     57 SVGElement::NumberListInfo SVGFEConvolveMatrixElement::sNumberListInfo[1] = {
     58    {nsGkAtoms::kernelMatrix}};
     59 
     60 //----------------------------------------------------------------------
     61 // nsINode methods
     62 
     63 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEConvolveMatrixElement)
     64 
     65 //----------------------------------------------------------------------
     66 
     67 already_AddRefed<DOMSVGAnimatedString> SVGFEConvolveMatrixElement::In1() {
     68  return mStringAttributes[IN1].ToDOMAnimatedString(this);
     69 }
     70 
     71 already_AddRefed<DOMSVGAnimatedInteger> SVGFEConvolveMatrixElement::OrderX() {
     72  return mIntegerPairAttributes[ORDER].ToDOMAnimatedInteger(
     73      SVGAnimatedIntegerPair::eFirst, this);
     74 }
     75 
     76 already_AddRefed<DOMSVGAnimatedInteger> SVGFEConvolveMatrixElement::OrderY() {
     77  return mIntegerPairAttributes[ORDER].ToDOMAnimatedInteger(
     78      SVGAnimatedIntegerPair::eSecond, this);
     79 }
     80 
     81 already_AddRefed<DOMSVGAnimatedNumberList>
     82 SVGFEConvolveMatrixElement::KernelMatrix() {
     83  return DOMSVGAnimatedNumberList::GetDOMWrapper(
     84      &mNumberListAttributes[KERNELMATRIX], this, KERNELMATRIX);
     85 }
     86 
     87 already_AddRefed<DOMSVGAnimatedInteger> SVGFEConvolveMatrixElement::TargetX() {
     88  return mIntegerAttributes[TARGET_X].ToDOMAnimatedInteger(this);
     89 }
     90 
     91 already_AddRefed<DOMSVGAnimatedInteger> SVGFEConvolveMatrixElement::TargetY() {
     92  return mIntegerAttributes[TARGET_Y].ToDOMAnimatedInteger(this);
     93 }
     94 
     95 already_AddRefed<DOMSVGAnimatedEnumeration>
     96 SVGFEConvolveMatrixElement::EdgeMode() {
     97  return mEnumAttributes[EDGEMODE].ToDOMAnimatedEnum(this);
     98 }
     99 
    100 already_AddRefed<DOMSVGAnimatedBoolean>
    101 SVGFEConvolveMatrixElement::PreserveAlpha() {
    102  return mBooleanAttributes[PRESERVEALPHA].ToDOMAnimatedBoolean(this);
    103 }
    104 
    105 already_AddRefed<DOMSVGAnimatedNumber> SVGFEConvolveMatrixElement::Divisor() {
    106  return mNumberAttributes[DIVISOR].ToDOMAnimatedNumber(this);
    107 }
    108 
    109 already_AddRefed<DOMSVGAnimatedNumber> SVGFEConvolveMatrixElement::Bias() {
    110  return mNumberAttributes[BIAS].ToDOMAnimatedNumber(this);
    111 }
    112 
    113 already_AddRefed<DOMSVGAnimatedNumber>
    114 SVGFEConvolveMatrixElement::KernelUnitLengthX() {
    115  return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(
    116      SVGAnimatedNumberPair::eFirst, this);
    117 }
    118 
    119 already_AddRefed<DOMSVGAnimatedNumber>
    120 SVGFEConvolveMatrixElement::KernelUnitLengthY() {
    121  return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(
    122      SVGAnimatedNumberPair::eSecond, this);
    123 }
    124 
    125 void SVGFEConvolveMatrixElement::GetSourceImageNames(
    126    nsTArray<SVGStringInfo>& aSources) {
    127  aSources.AppendElement(SVGStringInfo(&mStringAttributes[IN1], this));
    128 }
    129 
    130 FilterPrimitiveDescription SVGFEConvolveMatrixElement::GetPrimitiveDescription(
    131    SVGFilterInstance* aInstance, const IntRect& aFilterSubregion,
    132    const nsTArray<bool>& aInputsAreTainted,
    133    nsTArray<RefPtr<SourceSurface>>& aInputImages) {
    134  FilterPrimitiveDescription failureDescription;
    135 
    136  const SVGNumberList& kernelMatrix =
    137      mNumberListAttributes[KERNELMATRIX].GetAnimValue();
    138  uint32_t kmLength = kernelMatrix.Length();
    139 
    140  int32_t orderX = mIntegerPairAttributes[ORDER].GetAnimValue(
    141      SVGAnimatedIntegerPair::eFirst);
    142  int32_t orderY = mIntegerPairAttributes[ORDER].GetAnimValue(
    143      SVGAnimatedIntegerPair::eSecond);
    144 
    145  if (orderX <= 0 || orderY <= 0 ||
    146      static_cast<uint32_t>(orderX * orderY) != kmLength) {
    147    return failureDescription;
    148  }
    149 
    150  int32_t targetX, targetY;
    151  GetAnimatedIntegerValues(&targetX, &targetY, nullptr);
    152 
    153  if (mIntegerAttributes[TARGET_X].IsExplicitlySet()) {
    154    if (targetX < 0 || targetX >= orderX) return failureDescription;
    155  } else {
    156    targetX = orderX / 2;
    157  }
    158  if (mIntegerAttributes[TARGET_Y].IsExplicitlySet()) {
    159    if (targetY < 0 || targetY >= orderY) return failureDescription;
    160  } else {
    161    targetY = orderY / 2;
    162  }
    163 
    164  if (orderX > kReasonableSurfaceSize || orderY > kReasonableSurfaceSize)
    165    return failureDescription;
    166 
    167  float divisor;
    168  if (mNumberAttributes[DIVISOR].IsExplicitlySet()) {
    169    divisor = mNumberAttributes[DIVISOR].GetAnimValue();
    170  }
    171  if (!mNumberAttributes[DIVISOR].IsExplicitlySet() || divisor == 0) {
    172    divisor = std::accumulate(kernelMatrix.begin(), kernelMatrix.end(), 0.0f);
    173    if (divisor == 0) {
    174      divisor = 1;
    175    }
    176  }
    177 
    178  uint32_t edgeMode = mEnumAttributes[EDGEMODE].GetAnimValue();
    179  bool preserveAlpha = mBooleanAttributes[PRESERVEALPHA].GetAnimValue();
    180  float bias = mNumberAttributes[BIAS].GetAnimValue();
    181 
    182  Size kernelUnitLength = GetKernelUnitLength(
    183      aInstance, &mNumberPairAttributes[KERNEL_UNIT_LENGTH]);
    184 
    185  MOZ_ASSERT(kernelUnitLength.width > 0.0f && kernelUnitLength.height > 0.0f,
    186             "Expecting positive kernelUnitLength values");
    187 
    188  ConvolveMatrixAttributes atts;
    189  atts.mKernelSize = IntSize(orderX, orderY);
    190  atts.mKernelMatrix.AppendElements(&kernelMatrix[0], kmLength);
    191  atts.mDivisor = divisor;
    192  atts.mBias = bias;
    193  atts.mTarget = IntPoint(targetX, targetY);
    194  atts.mEdgeMode = edgeMode;
    195  atts.mKernelUnitLength = kernelUnitLength;
    196  atts.mPreserveAlpha = preserveAlpha;
    197 
    198  return FilterPrimitiveDescription(AsVariant(std::move(atts)));
    199 }
    200 
    201 bool SVGFEConvolveMatrixElement::AttributeAffectsRendering(
    202    int32_t aNameSpaceID, nsAtom* aAttribute) const {
    203  return SVGFEConvolveMatrixElementBase::AttributeAffectsRendering(
    204             aNameSpaceID, aAttribute) ||
    205         (aNameSpaceID == kNameSpaceID_None &&
    206          (aAttribute == nsGkAtoms::in || aAttribute == nsGkAtoms::divisor ||
    207           aAttribute == nsGkAtoms::bias ||
    208           aAttribute == nsGkAtoms::kernelUnitLength ||
    209           aAttribute == nsGkAtoms::targetX ||
    210           aAttribute == nsGkAtoms::targetY || aAttribute == nsGkAtoms::order ||
    211           aAttribute == nsGkAtoms::preserveAlpha ||
    212           aAttribute == nsGkAtoms::edgeMode ||
    213           aAttribute == nsGkAtoms::kernelMatrix));
    214 }
    215 
    216 nsresult SVGFEConvolveMatrixElement::BindToTree(BindContext& aCtx,
    217                                                nsINode& aParent) {
    218  if (aCtx.InComposedDoc()) {
    219    aCtx.OwnerDoc().SetUseCounter(eUseCounter_custom_feConvolveMatrix);
    220  }
    221 
    222  return SVGFEConvolveMatrixElementBase::BindToTree(aCtx, aParent);
    223 }
    224 
    225 //----------------------------------------------------------------------
    226 // SVGElement methods
    227 
    228 SVGElement::NumberAttributesInfo SVGFEConvolveMatrixElement::GetNumberInfo() {
    229  return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
    230                              std::size(sNumberInfo));
    231 }
    232 
    233 SVGElement::NumberPairAttributesInfo
    234 SVGFEConvolveMatrixElement::GetNumberPairInfo() {
    235  return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
    236                                  std::size(sNumberPairInfo));
    237 }
    238 
    239 SVGElement::IntegerAttributesInfo SVGFEConvolveMatrixElement::GetIntegerInfo() {
    240  return IntegerAttributesInfo(mIntegerAttributes, sIntegerInfo,
    241                               std::size(sIntegerInfo));
    242 }
    243 
    244 SVGElement::IntegerPairAttributesInfo
    245 SVGFEConvolveMatrixElement::GetIntegerPairInfo() {
    246  return IntegerPairAttributesInfo(mIntegerPairAttributes, sIntegerPairInfo,
    247                                   std::size(sIntegerPairInfo));
    248 }
    249 
    250 SVGElement::BooleanAttributesInfo SVGFEConvolveMatrixElement::GetBooleanInfo() {
    251  return BooleanAttributesInfo(mBooleanAttributes, sBooleanInfo,
    252                               std::size(sBooleanInfo));
    253 }
    254 
    255 SVGElement::EnumAttributesInfo SVGFEConvolveMatrixElement::GetEnumInfo() {
    256  return EnumAttributesInfo(mEnumAttributes, sEnumInfo, std::size(sEnumInfo));
    257 }
    258 
    259 SVGElement::StringAttributesInfo SVGFEConvolveMatrixElement::GetStringInfo() {
    260  return StringAttributesInfo(mStringAttributes, sStringInfo,
    261                              std::size(sStringInfo));
    262 }
    263 
    264 SVGElement::NumberListAttributesInfo
    265 SVGFEConvolveMatrixElement::GetNumberListInfo() {
    266  return NumberListAttributesInfo(mNumberListAttributes, sNumberListInfo,
    267                                  std::size(sNumberListInfo));
    268 }
    269 
    270 }  // namespace mozilla::dom