1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SVGViewBoxSMILType.h"
#include <math.h>
#include "SVGAnimatedViewBox.h"
#include "mozilla/SMILValue.h"
#include "nsDebug.h"
namespace mozilla {
/*static*/
SVGViewBoxSMILType SVGViewBoxSMILType::sSingleton;
void SVGViewBoxSMILType::InitValue(SMILValue& aValue) const {
MOZ_ASSERT(aValue.IsNull(), "Unexpected value type");
aValue.mU.mPtr = new SVGViewBox(0.0f, 0.0f, 0.0f, 0.0f);
aValue.mType = this;
}
void SVGViewBoxSMILType::DestroyValue(SMILValue& aValue) const {
MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
delete static_cast<SVGViewBox*>(aValue.mU.mPtr);
aValue.mU.mPtr = nullptr;
aValue.mType = SMILNullType::Singleton();
}
nsresult SVGViewBoxSMILType::Assign(SMILValue& aDest,
const SMILValue& aSrc) const {
MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
const SVGViewBox* src = static_cast<const SVGViewBox*>(aSrc.mU.mPtr);
SVGViewBox* dst = static_cast<SVGViewBox*>(aDest.mU.mPtr);
*dst = *src;
return NS_OK;
}
bool SVGViewBoxSMILType::IsEqual(const SMILValue& aLeft,
const SMILValue& aRight) const {
MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
const SVGViewBox* leftBox = static_cast<const SVGViewBox*>(aLeft.mU.mPtr);
const SVGViewBox* rightBox = static_cast<SVGViewBox*>(aRight.mU.mPtr);
return *leftBox == *rightBox;
}
nsresult SVGViewBoxSMILType::Add(SMILValue& aDest, const SMILValue& aValueToAdd,
uint32_t aCount) const {
MOZ_ASSERT(aValueToAdd.mType == aDest.mType, "Trying to add invalid types");
MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type");
auto* dest = static_cast<SVGViewBox*>(aDest.mU.mPtr);
const auto* valueToAdd = static_cast<const SVGViewBox*>(aValueToAdd.mU.mPtr);
if (dest->none || valueToAdd->none) {
return NS_ERROR_FAILURE;
}
dest->x += valueToAdd->x * aCount;
dest->y += valueToAdd->y * aCount;
dest->width += valueToAdd->width * aCount;
dest->height += valueToAdd->height * aCount;
return NS_OK;
}
nsresult SVGViewBoxSMILType::ComputeDistance(const SMILValue& aFrom,
const SMILValue& aTo,
double& aDistance) const {
MOZ_ASSERT(aFrom.mType == aTo.mType, "Trying to compare different types");
MOZ_ASSERT(aFrom.mType == this, "Unexpected source type");
const SVGViewBox* from = static_cast<const SVGViewBox*>(aFrom.mU.mPtr);
const SVGViewBox* to = static_cast<const SVGViewBox*>(aTo.mU.mPtr);
if (from->none || to->none) {
return NS_ERROR_FAILURE;
}
// We use the distances between the edges rather than the difference between
// the x, y, width and height for the "distance". This is necessary in
// order for the "distance" result that we calculate to be the same for a
// given change in the left side as it is for an equal change in the opposite
// side. See https://bugzilla.mozilla.org/show_bug.cgi?id=541884#c12
double dLeft = to->x - from->x;
double dTop = to->y - from->y;
double dRight = (to->x + to->width) - (from->x + from->width);
double dBottom = (to->y + to->height) - (from->y + from->height);
aDistance = std::sqrt(dLeft * dLeft + dTop * dTop + dRight * dRight +
dBottom * dBottom);
return NS_OK;
}
nsresult SVGViewBoxSMILType::Interpolate(const SMILValue& aStartVal,
const SMILValue& aEndVal,
double aUnitDistance,
SMILValue& aResult) const {
MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
"Trying to interpolate different types");
MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation");
MOZ_ASSERT(aResult.mType == this, "Unexpected result type");
const SVGViewBox* start = static_cast<const SVGViewBox*>(aStartVal.mU.mPtr);
const SVGViewBox* end = static_cast<const SVGViewBox*>(aEndVal.mU.mPtr);
if (start->none || end->none) {
return NS_ERROR_FAILURE;
}
SVGViewBox* current = static_cast<SVGViewBox*>(aResult.mU.mPtr);
float x = (start->x + (end->x - start->x) * aUnitDistance);
float y = (start->y + (end->y - start->y) * aUnitDistance);
float width = (start->width + (end->width - start->width) * aUnitDistance);
float height =
(start->height + (end->height - start->height) * aUnitDistance);
*current = SVGViewBox(x, y, width, height);
return NS_OK;
}
} // namespace mozilla
|