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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
/* -*- 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/. */
#ifndef DOM_SVG_SVGLENGTH_H_
#define DOM_SVG_SVGLENGTH_H_
#include "mozilla/dom/SVGAnimatedLength.h"
#include "mozilla/dom/SVGLengthBinding.h"
#include "nsDebug.h"
enum nsCSSUnit : uint32_t;
namespace mozilla {
namespace dom {
class SVGElement;
}
/**
* This SVGLength class is currently used for SVGLength *list* attributes only.
* The class that is currently used for <length> attributes is
* SVGAnimatedLength.
*
* The member mUnit should always be valid, but the member mValue may be
* numeric_limits<float>::quiet_NaN() under one circumstances (see the comment
* in SetValueAndUnit below). Even if mValue is valid, some methods may return
* numeric_limits<float>::quiet_NaN() if they involve a unit conversion that
* fails - see comments below.
*
* The DOM wrapper class for this class is DOMSVGLength.
*/
class SVGLength {
public:
SVGLength()
: mValue(0.0f), mUnit(dom::SVGLength_Binding::SVG_LENGTHTYPE_UNKNOWN) {}
SVGLength(float aValue, uint8_t aUnit) : mValue(aValue), mUnit(aUnit) {}
bool operator==(const SVGLength& rhs) const {
return mValue == rhs.mValue && mUnit == rhs.mUnit;
}
void GetValueAsString(nsAString& aValue) const;
/**
* This method returns true, unless there was a parse failure, in which
* case it returns false (and the length is left unchanged).
*/
bool SetValueFromString(const nsAString& aString);
/**
* This will usually return a valid, finite number. There is one exception
* though. If SVGLengthListSMILType has to convert between unit types and the
* unit conversion is undefined, it will end up passing in and setting
* numeric_limits<float>::quiet_NaN(). The painting code has to be
* able to handle NaN anyway, since conversion to user units may fail in
* general.
*/
float GetValueInCurrentUnits() const { return mValue; }
uint8_t GetUnit() const { return mUnit; }
void SetValueInCurrentUnits(float aValue) {
NS_ASSERTION(std::isfinite(aValue), "Set invalid SVGLength");
mValue = aValue;
}
void SetValueAndUnit(float aValue, uint8_t aUnit) {
mValue = aValue;
mUnit = aUnit;
}
/**
* If it's not possible to convert this length's value to pixels, then
* this method will return numeric_limits<float>::quiet_NaN().
*/
float GetValueInPixels(const dom::SVGElement* aElement, uint8_t aAxis) const {
return mValue * GetPixelsPerUnit(dom::SVGElementMetrics(aElement), aAxis);
}
float GetValueInPixelsWithZoom(const dom::SVGElement* aElement,
uint8_t aAxis) const {
return mValue *
GetPixelsPerUnitWithZoom(dom::SVGElementMetrics(aElement), aAxis);
}
/**
* Get this length's value in the units specified.
*
* This method returns numeric_limits<float>::quiet_NaN() if it is not
* possible to convert the value to the specified unit.
*/
float GetValueInSpecifiedUnit(uint8_t aUnit, const dom::SVGElement* aElement,
uint8_t aAxis) const;
bool IsPercentage() const { return IsPercentageUnit(mUnit); }
float GetPixelsPerUnitWithZoom(const dom::UserSpaceMetrics& aMetrics,
uint8_t aAxis) const {
return GetPixelsPerUnit(aMetrics, mUnit, aAxis, true);
}
float GetPixelsPerUnit(const dom::UserSpaceMetrics& aMetrics,
uint8_t aAxis) const {
return GetPixelsPerUnit(aMetrics, mUnit, aAxis, false);
}
static bool IsValidUnitType(uint16_t aUnitType) {
return aUnitType > dom::SVGLength_Binding::SVG_LENGTHTYPE_UNKNOWN &&
aUnitType <= dom::SVGLength_Binding::SVG_LENGTHTYPE_PC;
}
static bool IsPercentageUnit(uint8_t aUnit) {
return aUnit == dom::SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE;
}
static bool IsAbsoluteUnit(uint8_t aUnit);
static bool IsFontRelativeUnit(uint8_t aUnit);
static float GetAbsUnitsPerAbsUnit(uint8_t aUnits, uint8_t aPerUnit);
static nsCSSUnit SpecifiedUnitTypeToCSSUnit(uint8_t aSpecifiedUnit);
static void GetUnitString(nsAString& aUnit, uint16_t aUnitType);
static uint16_t GetUnitTypeForString(const nsAString& aUnit);
/**
* Returns the number of pixels per given unit.
*/
static float GetPixelsPerUnit(const dom::UserSpaceMetrics& aMetrics,
uint8_t aUnitType, uint8_t aAxis,
bool aApplyZoom);
static float GetPixelsPerCSSUnit(const dom::UserSpaceMetrics& aMetrics,
nsCSSUnit aCSSUnit, uint8_t aAxis,
bool aApplyZoom);
private:
float mValue;
uint8_t mUnit;
};
} // namespace mozilla
#endif // DOM_SVG_SVGLENGTH_H_
|