tor-browser

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

SVGTransform.cpp (6251B)


      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 "SVGTransform.h"
      8 
      9 #include "nsContentUtils.h"  // for NS_ENSURE_FINITE
     10 #include "nsError.h"
     11 #include "nsTextFormatter.h"
     12 
     13 namespace {
     14 const double kRadPerDegree = 2.0 * M_PI / 360.0;
     15 }  // namespace
     16 
     17 namespace mozilla {
     18 
     19 using namespace dom::SVGTransform_Binding;
     20 
     21 void SVGTransform::GetValueAsString(nsAString& aValue) const {
     22  switch (mType) {
     23    case SVG_TRANSFORM_TRANSLATE:
     24      // The spec say that if Y is not provided, it is assumed to be zero.
     25      if (mMatrix._32 != 0)
     26        nsTextFormatter::ssprintf(aValue, u"translate(%g, %g)", mMatrix._31,
     27                                  mMatrix._32);
     28      else
     29        nsTextFormatter::ssprintf(aValue, u"translate(%g)", mMatrix._31);
     30      break;
     31    case SVG_TRANSFORM_ROTATE:
     32      if (mOriginX != 0.0f || mOriginY != 0.0f)
     33        nsTextFormatter::ssprintf(aValue, u"rotate(%g, %g, %g)", mAngle,
     34                                  mOriginX, mOriginY);
     35      else
     36        nsTextFormatter::ssprintf(aValue, u"rotate(%g)", mAngle);
     37      break;
     38    case SVG_TRANSFORM_SCALE:
     39      if (mMatrix._11 != mMatrix._22)
     40        nsTextFormatter::ssprintf(aValue, u"scale(%g, %g)", mMatrix._11,
     41                                  mMatrix._22);
     42      else
     43        nsTextFormatter::ssprintf(aValue, u"scale(%g)", mMatrix._11);
     44      break;
     45    case SVG_TRANSFORM_SKEWX:
     46      nsTextFormatter::ssprintf(aValue, u"skewX(%g)", mAngle);
     47      break;
     48    case SVG_TRANSFORM_SKEWY:
     49      nsTextFormatter::ssprintf(aValue, u"skewY(%g)", mAngle);
     50      break;
     51    case SVG_TRANSFORM_MATRIX:
     52      nsTextFormatter::ssprintf(aValue, u"matrix(%g, %g, %g, %g, %g, %g)",
     53                                mMatrix._11, mMatrix._12, mMatrix._21,
     54                                mMatrix._22, mMatrix._31, mMatrix._32);
     55      break;
     56    default:
     57      aValue.Truncate();
     58      NS_ERROR("unknown transformation type");
     59      break;
     60  }
     61 }
     62 
     63 void SVGTransform::SetMatrix(const gfxMatrix& aMatrix) {
     64  mType = SVG_TRANSFORM_MATRIX;
     65  mMatrix = aMatrix;
     66  // We set the other members here too, since operator== requires it and
     67  // the DOM requires it for mAngle.
     68  mAngle = 0.f;
     69  mOriginX = 0.f;
     70  mOriginY = 0.f;
     71 }
     72 
     73 void SVGTransform::SetTranslate(float aTx, float aTy) {
     74  mType = SVG_TRANSFORM_TRANSLATE;
     75  mMatrix = gfxMatrix::Translation(aTx, aTy);
     76  mAngle = 0.f;
     77  mOriginX = 0.f;
     78  mOriginY = 0.f;
     79 }
     80 
     81 void SVGTransform::SetScale(float aSx, float aSy) {
     82  mType = SVG_TRANSFORM_SCALE;
     83  mMatrix = gfxMatrix::Scaling(aSx, aSy);
     84  mAngle = 0.f;
     85  mOriginX = 0.f;
     86  mOriginY = 0.f;
     87 }
     88 
     89 void SVGTransform::SetRotate(float aAngle, float aCx, float aCy) {
     90  mType = SVG_TRANSFORM_ROTATE;
     91  mMatrix = gfxMatrix::Translation(aCx, aCy)
     92                .PreRotate(aAngle * kRadPerDegree)
     93                .PreTranslate(-aCx, -aCy);
     94  mAngle = aAngle;
     95  mOriginX = aCx;
     96  mOriginY = aCy;
     97 }
     98 
     99 nsresult SVGTransform::SetSkewX(float aAngle) {
    100  double ta = tan(aAngle * kRadPerDegree);
    101  // No one actually cares about the exact error return type here.
    102  NS_ENSURE_FINITE(ta, NS_ERROR_INVALID_ARG);
    103 
    104  mType = SVG_TRANSFORM_SKEWX;
    105  mMatrix = gfxMatrix();
    106  mMatrix._21 = ta;
    107  mAngle = aAngle;
    108  mOriginX = 0.f;
    109  mOriginY = 0.f;
    110  return NS_OK;
    111 }
    112 
    113 nsresult SVGTransform::SetSkewY(float aAngle) {
    114  double ta = tan(aAngle * kRadPerDegree);
    115  // No one actually cares about the exact error return type here.
    116  NS_ENSURE_FINITE(ta, NS_ERROR_INVALID_ARG);
    117 
    118  mType = SVG_TRANSFORM_SKEWY;
    119  mMatrix = gfxMatrix();
    120  mMatrix._12 = ta;
    121  mAngle = aAngle;
    122  mOriginX = 0.f;
    123  mOriginY = 0.f;
    124  return NS_OK;
    125 }
    126 
    127 SVGTransformSMILData::SVGTransformSMILData(const SVGTransform& aTransform)
    128    : mTransformType(aTransform.Type()) {
    129  MOZ_ASSERT(mTransformType >= SVG_TRANSFORM_MATRIX &&
    130                 mTransformType <= SVG_TRANSFORM_SKEWY,
    131             "Unexpected transform type");
    132 
    133  for (uint32_t i = 0; i < NUM_STORED_PARAMS; ++i) {
    134    mParams[i] = 0.f;
    135  }
    136 
    137  switch (mTransformType) {
    138    case SVG_TRANSFORM_MATRIX: {
    139      const gfxMatrix& mx = aTransform.GetMatrix();
    140      mParams[0] = static_cast<float>(mx._11);
    141      mParams[1] = static_cast<float>(mx._12);
    142      mParams[2] = static_cast<float>(mx._21);
    143      mParams[3] = static_cast<float>(mx._22);
    144      mParams[4] = static_cast<float>(mx._31);
    145      mParams[5] = static_cast<float>(mx._32);
    146      break;
    147    }
    148    case SVG_TRANSFORM_TRANSLATE: {
    149      const gfxMatrix& mx = aTransform.GetMatrix();
    150      mParams[0] = static_cast<float>(mx._31);
    151      mParams[1] = static_cast<float>(mx._32);
    152      break;
    153    }
    154    case SVG_TRANSFORM_SCALE: {
    155      const gfxMatrix& mx = aTransform.GetMatrix();
    156      mParams[0] = static_cast<float>(mx._11);
    157      mParams[1] = static_cast<float>(mx._22);
    158      break;
    159    }
    160    case SVG_TRANSFORM_ROTATE:
    161      mParams[0] = aTransform.Angle();
    162      aTransform.GetRotationOrigin(mParams[1], mParams[2]);
    163      break;
    164 
    165    case SVG_TRANSFORM_SKEWX:
    166    case SVG_TRANSFORM_SKEWY:
    167      mParams[0] = aTransform.Angle();
    168      break;
    169 
    170    default:
    171      MOZ_ASSERT_UNREACHABLE("Unexpected transform type");
    172      break;
    173  }
    174 }
    175 
    176 SVGTransform SVGTransformSMILData::ToSVGTransform() const {
    177  SVGTransform result;
    178 
    179  switch (mTransformType) {
    180    case SVG_TRANSFORM_MATRIX:
    181      result.SetMatrix(gfxMatrix(mParams[0], mParams[1], mParams[2], mParams[3],
    182                                 mParams[4], mParams[5]));
    183      break;
    184 
    185    case SVG_TRANSFORM_TRANSLATE:
    186      result.SetTranslate(mParams[0], mParams[1]);
    187      break;
    188 
    189    case SVG_TRANSFORM_SCALE:
    190      result.SetScale(mParams[0], mParams[1]);
    191      break;
    192 
    193    case SVG_TRANSFORM_ROTATE:
    194      result.SetRotate(mParams[0], mParams[1], mParams[2]);
    195      break;
    196 
    197    case SVG_TRANSFORM_SKEWX:
    198      result.SetSkewX(mParams[0]);
    199      break;
    200 
    201    case SVG_TRANSFORM_SKEWY:
    202      result.SetSkewY(mParams[0]);
    203      break;
    204 
    205    default:
    206      MOZ_ASSERT_UNREACHABLE("Unexpected transform type");
    207      break;
    208  }
    209  return result;
    210 }
    211 
    212 }  // namespace mozilla