123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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 "mozilla/ArrayUtils.h"
- #include "SVGTransformListParser.h"
- #include "SVGContentUtils.h"
- #include "nsSVGTransform.h"
- #include "nsGkAtoms.h"
- #include "nsIAtom.h"
- using namespace mozilla;
- //----------------------------------------------------------------------
- // private methods
- bool
- SVGTransformListParser::Parse()
- {
- mTransforms.Clear();
- return ParseTransforms();
- }
- bool
- SVGTransformListParser::ParseTransforms()
- {
- if (!SkipWsp()) {
- return true;
- }
- if (!ParseTransform()) {
- return false;
- }
- while (SkipWsp()) {
- // The SVG BNF allows multiple comma-wsp between transforms
- while (*mIter == ',') {
- ++mIter;
- if (!SkipWsp()) {
- return false;
- }
- }
- if (!ParseTransform()) {
- return false;
- }
- }
- return true;
- }
- bool
- SVGTransformListParser::ParseTransform()
- {
- RangedPtr<const char16_t> start(mIter);
- while (IsAlpha(*mIter)) {
- ++mIter;
- if (mIter == mEnd) {
- return false;
- }
- }
- if (start == mIter) {
- // Didn't read anything
- return false;
- }
- const nsAString& transform = Substring(start.get(), mIter.get());
- nsIAtom* keyAtom = NS_GetStaticAtom(transform);
- if (!keyAtom || !SkipWsp()) {
- return false;
- }
- if (keyAtom == nsGkAtoms::translate) {
- return ParseTranslate();
- }
- if (keyAtom == nsGkAtoms::scale) {
- return ParseScale();
- }
- if (keyAtom == nsGkAtoms::rotate) {
- return ParseRotate();
- }
- if (keyAtom == nsGkAtoms::skewX) {
- return ParseSkewX();
- }
- if (keyAtom == nsGkAtoms::skewY) {
- return ParseSkewY();
- }
- if (keyAtom == nsGkAtoms::matrix) {
- return ParseMatrix();
- }
- return false;
- }
- bool
- SVGTransformListParser::ParseArguments(float* aResult,
- uint32_t aMaxCount,
- uint32_t* aParsedCount)
- {
- if (*mIter != '(') {
- return false;
- }
- ++mIter;
- if (!SkipWsp()) {
- return false;
- }
- if (!SVGContentUtils::ParseNumber(mIter, mEnd, aResult[0])) {
- return false;
- }
- *aParsedCount = 1;
- while (SkipWsp()) {
- if (*mIter == ')') {
- ++mIter;
- return true;
- }
- if (*aParsedCount == aMaxCount) {
- return false;
- }
- SkipCommaWsp();
- if (!SVGContentUtils::ParseNumber(mIter, mEnd, aResult[(*aParsedCount)++])) {
- return false;
- }
- }
- return false;
- }
- bool
- SVGTransformListParser::ParseTranslate()
- {
- float t[2];
- uint32_t count;
- if (!ParseArguments(t, ArrayLength(t), &count)) {
- return false;
- }
- switch (count) {
- case 1:
- t[1] = 0.f;
- MOZ_FALLTHROUGH;
- case 2:
- {
- nsSVGTransform* transform = mTransforms.AppendElement(fallible);
- if (!transform) {
- return false;
- }
- transform->SetTranslate(t[0], t[1]);
- return true;
- }
- }
- return false;
- }
- bool
- SVGTransformListParser::ParseScale()
- {
- float s[2];
- uint32_t count;
- if (!ParseArguments(s, ArrayLength(s), &count)) {
- return false;
- }
- switch (count) {
- case 1:
- s[1] = s[0];
- MOZ_FALLTHROUGH;
- case 2:
- {
- nsSVGTransform* transform = mTransforms.AppendElement(fallible);
- if (!transform) {
- return false;
- }
- transform->SetScale(s[0], s[1]);
- return true;
- }
- }
- return false;
- }
- bool
- SVGTransformListParser::ParseRotate()
- {
- float r[3];
- uint32_t count;
- if (!ParseArguments(r, ArrayLength(r), &count)) {
- return false;
- }
- switch (count) {
- case 1:
- r[1] = r[2] = 0.f;
- MOZ_FALLTHROUGH;
- case 3:
- {
- nsSVGTransform* transform = mTransforms.AppendElement(fallible);
- if (!transform) {
- return false;
- }
- transform->SetRotate(r[0], r[1], r[2]);
- return true;
- }
- }
- return false;
- }
- bool
- SVGTransformListParser::ParseSkewX()
- {
- float skew;
- uint32_t count;
- if (!ParseArguments(&skew, 1, &count) || count != 1) {
- return false;
- }
- nsSVGTransform* transform = mTransforms.AppendElement(fallible);
- if (!transform) {
- return false;
- }
- transform->SetSkewX(skew);
- return true;
- }
- bool
- SVGTransformListParser::ParseSkewY()
- {
- float skew;
- uint32_t count;
- if (!ParseArguments(&skew, 1, &count) || count != 1) {
- return false;
- }
- nsSVGTransform* transform = mTransforms.AppendElement(fallible);
- if (!transform) {
- return false;
- }
- transform->SetSkewY(skew);
- return true;
- }
- bool
- SVGTransformListParser::ParseMatrix()
- {
- float m[6];
- uint32_t count;
- if (!ParseArguments(m, ArrayLength(m), &count) || count != 6) {
- return false;
- }
- nsSVGTransform* transform = mTransforms.AppendElement(fallible);
- if (!transform) {
- return false;
- }
- transform->SetMatrix(gfxMatrix(m[0], m[1], m[2], m[3], m[4], m[5]));
- return true;
- }
|