Line data Source code
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 "SVGViewBoxSMILType.h"
8 : #include "nsSMILValue.h"
9 : #include "nsSVGViewBox.h"
10 : #include "nsDebug.h"
11 : #include <math.h>
12 :
13 : namespace mozilla {
14 :
15 : /*static*/ SVGViewBoxSMILType SVGViewBoxSMILType::sSingleton;
16 :
17 : void
18 0 : SVGViewBoxSMILType::Init(nsSMILValue& aValue) const
19 : {
20 0 : MOZ_ASSERT(aValue.IsNull(), "Unexpected value type");
21 :
22 0 : aValue.mU.mPtr = new nsSVGViewBoxRect();
23 0 : aValue.mType = this;
24 0 : }
25 :
26 : void
27 0 : SVGViewBoxSMILType::Destroy(nsSMILValue& aValue) const
28 : {
29 0 : NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
30 0 : delete static_cast<nsSVGViewBoxRect*>(aValue.mU.mPtr);
31 0 : aValue.mU.mPtr = nullptr;
32 0 : aValue.mType = nsSMILNullType::Singleton();
33 0 : }
34 :
35 : nsresult
36 0 : SVGViewBoxSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const
37 : {
38 0 : NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
39 0 : NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value");
40 :
41 0 : const nsSVGViewBoxRect* src = static_cast<const nsSVGViewBoxRect*>(aSrc.mU.mPtr);
42 0 : nsSVGViewBoxRect* dst = static_cast<nsSVGViewBoxRect*>(aDest.mU.mPtr);
43 0 : *dst = *src;
44 0 : return NS_OK;
45 : }
46 :
47 : bool
48 0 : SVGViewBoxSMILType::IsEqual(const nsSMILValue& aLeft,
49 : const nsSMILValue& aRight) const
50 : {
51 0 : NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
52 0 : NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
53 :
54 : const nsSVGViewBoxRect* leftBox =
55 0 : static_cast<const nsSVGViewBoxRect*>(aLeft.mU.mPtr);
56 : const nsSVGViewBoxRect* rightBox =
57 0 : static_cast<nsSVGViewBoxRect*>(aRight.mU.mPtr);
58 0 : return *leftBox == *rightBox;
59 : }
60 :
61 : nsresult
62 0 : SVGViewBoxSMILType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
63 : uint32_t aCount) const
64 : {
65 0 : NS_PRECONDITION(aValueToAdd.mType == aDest.mType,
66 : "Trying to add invalid types");
67 0 : NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type");
68 :
69 : // See https://bugzilla.mozilla.org/show_bug.cgi?id=541884#c3 and the two
70 : // comments that follow that one for arguments for and against allowing
71 : // viewBox to be additive.
72 :
73 0 : return NS_ERROR_FAILURE;
74 : }
75 :
76 : nsresult
77 0 : SVGViewBoxSMILType::ComputeDistance(const nsSMILValue& aFrom,
78 : const nsSMILValue& aTo,
79 : double& aDistance) const
80 : {
81 0 : NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
82 0 : NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
83 :
84 0 : const nsSVGViewBoxRect* from = static_cast<const nsSVGViewBoxRect*>(aFrom.mU.mPtr);
85 0 : const nsSVGViewBoxRect* to = static_cast<const nsSVGViewBoxRect*>(aTo.mU.mPtr);
86 :
87 0 : if (from->none || to->none) {
88 0 : return NS_ERROR_FAILURE;
89 : }
90 :
91 : // We use the distances between the edges rather than the difference between
92 : // the x, y, width and height for the "distance". This is necessary in
93 : // order for the "distance" result that we calculate to be the same for a
94 : // given change in the left side as it is for an equal change in the opposite
95 : // side. See https://bugzilla.mozilla.org/show_bug.cgi?id=541884#c12
96 :
97 0 : float dLeft = to->x - from->x;
98 0 : float dTop = to->y - from->y;
99 0 : float dRight = ( to->x + to->width ) - ( from->x + from->width );
100 0 : float dBottom = ( to->y + to->height ) - ( from->y + from->height );
101 :
102 0 : aDistance = sqrt(dLeft*dLeft + dTop*dTop + dRight*dRight + dBottom*dBottom);
103 :
104 0 : return NS_OK;
105 : }
106 :
107 : nsresult
108 0 : SVGViewBoxSMILType::Interpolate(const nsSMILValue& aStartVal,
109 : const nsSMILValue& aEndVal,
110 : double aUnitDistance,
111 : nsSMILValue& aResult) const
112 : {
113 0 : NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
114 : "Trying to interpolate different types");
115 0 : NS_PRECONDITION(aStartVal.mType == this,
116 : "Unexpected types for interpolation");
117 0 : NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
118 :
119 0 : const nsSVGViewBoxRect* start = static_cast<const nsSVGViewBoxRect*>(aStartVal.mU.mPtr);
120 0 : const nsSVGViewBoxRect* end = static_cast<const nsSVGViewBoxRect*>(aEndVal.mU.mPtr);
121 :
122 0 : if (start->none || end->none) {
123 0 : return NS_ERROR_FAILURE;
124 : }
125 :
126 0 : nsSVGViewBoxRect* current = static_cast<nsSVGViewBoxRect*>(aResult.mU.mPtr);
127 :
128 0 : float x = (start->x + (end->x - start->x) * aUnitDistance);
129 0 : float y = (start->y + (end->y - start->y) * aUnitDistance);
130 0 : float width = (start->width + (end->width - start->width) * aUnitDistance);
131 0 : float height = (start->height + (end->height - start->height) * aUnitDistance);
132 :
133 0 : *current = nsSVGViewBoxRect(x, y, width, height);
134 :
135 0 : return NS_OK;
136 : }
137 :
138 : } // namespace mozilla
|