tor-browser

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

SVGOrientSMILType.cpp (5643B)


      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 "SVGOrientSMILType.h"
      8 
      9 #include <math.h>
     10 
     11 #include "SVGAnimatedOrient.h"
     12 #include "mozilla/SMILValue.h"
     13 #include "mozilla/dom/SVGMarkerElement.h"
     14 #include "nsDebug.h"
     15 
     16 namespace mozilla {
     17 
     18 using namespace dom::SVGAngle_Binding;
     19 using namespace dom::SVGMarkerElement_Binding;
     20 
     21 /*static*/
     22 SVGOrientSMILType SVGOrientSMILType::sSingleton;
     23 
     24 void SVGOrientSMILType::InitValue(SMILValue& aValue) const {
     25  MOZ_ASSERT(aValue.IsNull(), "Unexpected value type");
     26 
     27  aValue.mU.mOrient.mAngle = 0.0f;
     28  aValue.mU.mOrient.mUnit = SVG_ANGLETYPE_UNSPECIFIED;
     29  aValue.mU.mOrient.mOrientType = SVG_MARKER_ORIENT_ANGLE;
     30  aValue.mType = this;
     31 }
     32 
     33 void SVGOrientSMILType::DestroyValue(SMILValue& aValue) const {
     34  MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value.");
     35  aValue.mU.mPtr = nullptr;
     36  aValue.mType = SMILNullType::Singleton();
     37 }
     38 
     39 nsresult SVGOrientSMILType::Assign(SMILValue& aDest,
     40                                   const SMILValue& aSrc) const {
     41  MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types.");
     42  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value.");
     43 
     44  aDest.mU.mOrient.mAngle = aSrc.mU.mOrient.mAngle;
     45  aDest.mU.mOrient.mUnit = aSrc.mU.mOrient.mUnit;
     46  aDest.mU.mOrient.mOrientType = aSrc.mU.mOrient.mOrientType;
     47  return NS_OK;
     48 }
     49 
     50 bool SVGOrientSMILType::IsEqual(const SMILValue& aLeft,
     51                                const SMILValue& aRight) const {
     52  MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
     53  MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
     54 
     55  return aLeft.mU.mOrient.mAngle == aRight.mU.mOrient.mAngle &&
     56         aLeft.mU.mOrient.mUnit == aRight.mU.mOrient.mUnit &&
     57         aLeft.mU.mOrient.mOrientType == aRight.mU.mOrient.mOrientType;
     58 }
     59 
     60 static float ValueInDegrees(const SMILValue& aValue) {
     61  MOZ_ASSERT(aValue.mU.mOrient.mOrientType == SVG_MARKER_ORIENT_ANGLE);
     62 
     63  return aValue.mU.mOrient.mAngle == 0.0f
     64             ? 0.0f
     65             : aValue.mU.mOrient.mAngle * SVGAnimatedOrient::GetDegreesPerUnit(
     66                                              aValue.mU.mOrient.mUnit);
     67 }
     68 
     69 nsresult SVGOrientSMILType::Add(SMILValue& aDest, const SMILValue& aValueToAdd,
     70                                uint32_t aCount) const {
     71  MOZ_ASSERT(aValueToAdd.mType == aDest.mType, "Trying to add invalid types");
     72  MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type");
     73 
     74  if (aDest.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE ||
     75      aValueToAdd.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE) {
     76    // TODO: it would be nice to be able to add to auto angles
     77    return NS_ERROR_FAILURE;
     78  }
     79 
     80  // We may be dealing with two different angle units, so we normalize to
     81  // degrees for the add:
     82  float currentAngle = ValueInDegrees(aDest);
     83  float angleToAdd = ValueInDegrees(aValueToAdd) * aCount;
     84 
     85  // And then we give the resulting animated value the same units as the value
     86  // that we're animating to/by (i.e. the same as aValueToAdd):
     87  aDest.mU.mOrient.mAngle =
     88      (currentAngle + angleToAdd) /
     89      SVGAnimatedOrient::GetDegreesPerUnit(aValueToAdd.mU.mOrient.mUnit);
     90  aDest.mU.mOrient.mUnit = aValueToAdd.mU.mOrient.mUnit;
     91 
     92  return NS_OK;
     93 }
     94 
     95 nsresult SVGOrientSMILType::ComputeDistance(const SMILValue& aFrom,
     96                                            const SMILValue& aTo,
     97                                            double& aDistance) const {
     98  MOZ_ASSERT(aFrom.mType == aTo.mType, "Trying to compare different types");
     99  MOZ_ASSERT(aFrom.mType == this, "Unexpected source type");
    100 
    101  if (aFrom.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE ||
    102      aTo.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE) {
    103    // TODO: it would be nice to be able to compute distance with auto angles
    104    return NS_ERROR_FAILURE;
    105  }
    106 
    107  // Normalize both to degrees in case they're different angle units:
    108  aDistance = fabs(ValueInDegrees(aTo) - ValueInDegrees(aFrom));
    109 
    110  return NS_OK;
    111 }
    112 
    113 nsresult SVGOrientSMILType::Interpolate(const SMILValue& aStartVal,
    114                                        const SMILValue& aEndVal,
    115                                        double aUnitDistance,
    116                                        SMILValue& aResult) const {
    117  MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
    118             "Trying to interpolate different types");
    119  MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation.");
    120  MOZ_ASSERT(aResult.mType == this, "Unexpected result type.");
    121 
    122  if (aStartVal.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE ||
    123      aEndVal.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE) {
    124    // TODO: it would be nice to be able to handle auto angles too.
    125    return NS_ERROR_FAILURE;
    126  }
    127 
    128  float start = ValueInDegrees(aStartVal);
    129  float end = ValueInDegrees(aEndVal);
    130  float result = (start + (end - start) * aUnitDistance);
    131 
    132  // we use the unit of the nearest value for the result:
    133  if (aUnitDistance > 0.5) {
    134    aResult.mU.mOrient.mAngle =
    135        result / SVGAnimatedOrient::GetDegreesPerUnit(aEndVal.mU.mOrient.mUnit);
    136    aResult.mU.mOrient.mUnit = aEndVal.mU.mOrient.mUnit;
    137  } else {
    138    aResult.mU.mOrient.mAngle = result / SVGAnimatedOrient::GetDegreesPerUnit(
    139                                             aStartVal.mU.mOrient.mUnit);
    140    aResult.mU.mOrient.mUnit = aStartVal.mU.mOrient.mUnit;
    141  }
    142 
    143  return NS_OK;
    144 }
    145 
    146 }  // namespace mozilla