DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (b6d82b1a6b02)

VCS Links

Line Code
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 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
/* -*- 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/. */

#pragma once

#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "mozilla/dom/SVGPointBinding.h"
#include "DOMSVGPointList.h"

// {d6b6c440-af8d-40ee-856b-02a317cab275}
#define MOZILLA_NSISVGPOINT_IID                      \
  {                                                  \
    0xd6b6c440, 0xaf8d, 0x40ee, {                    \
      0x85, 0x6b, 0x02, 0xa3, 0x17, 0xca, 0xb2, 0x75 \
    }                                                \
  }

#define MOZ_SVG_LIST_INDEX_BIT_COUNT 29

namespace mozilla {

namespace dom {
class SVGMatrix;
}  // namespace dom

/**
 * Class nsISVGPoint
 *
 * This class creates the DOM objects that wrap internal SVGPoint objects.
 * An nsISVGPoint can be either a DOMSVGPoint or a DOMSVGTranslatePoint
 */
class nsISVGPoint : public nsISupports, public nsWrapperCache {
 public:
  NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_NSISVGPOINT_IID)
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsISVGPoint)

  /**
   * Generic ctor for DOMSVGPoint objects that are created for an attribute.
   */
  explicit nsISVGPoint()
      : mList(nullptr),
        mListIndex(0),
        mIsReadonly(false),
        mIsAnimValItem(false),
        mIsTranslatePoint(false) {}

  explicit nsISVGPoint(SVGPoint* aPt, bool aIsTranslatePoint)
      : mList(nullptr),
        mListIndex(0),
        mIsReadonly(false),
        mIsAnimValItem(false),
        mIsTranslatePoint(aIsTranslatePoint) {
    mPt.mX = aPt->GetX();
    mPt.mY = aPt->GetY();
  }

 protected:
  virtual ~nsISVGPoint() {
    // Our mList's weak ref to us must be nulled out when we die. If GC has
    // unlinked us using the cycle collector code, then that has already
    // happened, and mList is null.
    if (mList) {
      mList->mItems[mListIndex] = nullptr;
    }
  }

 public:
  /**
   * Creates an unowned copy of this object's point as a DOMSVGPoint.
   */
  virtual DOMSVGPoint* Copy() = 0;

  SVGPoint ToSVGPoint() const {
    return HasOwner() ? const_cast<nsISVGPoint*>(this)->InternalItem() : mPt;
  }

  bool IsInList() const { return !!mList; }

  /**
   * In future, if this class is used for non-list points, this will be
   * different to IsInList(). "Owner" here means that the instance has an
   * internal counterpart from which it gets its values. (A better name may
   * be HasWrappee().)
   */
  bool HasOwner() const { return !!mList; }

  bool IsTranslatePoint() const { return mIsTranslatePoint; }

  /**
   * This method is called to notify this DOM object that it is being inserted
   * into a list, and give it the information it needs as a result.
   *
   * This object MUST NOT already belong to a list when this method is called.
   * That's not to say that script can't move these DOM objects between
   * lists - it can - it's just that the logic to handle that (and send out
   * the necessary notifications) is located elsewhere (in DOMSVGPointList).)
   */
  void InsertingIntoList(DOMSVGPointList* aList, uint32_t aListIndex,
                         bool aIsAnimValItem);

  static uint32_t MaxListIndex() {
    return (1U << MOZ_SVG_LIST_INDEX_BIT_COUNT) - 1;
  }

  /// This method is called to notify this object that its list index changed.
  void UpdateListIndex(uint32_t aListIndex) { mListIndex = aListIndex; }

  /**
   * This method is called to notify this DOM object that it is about to be
   * removed from its current DOM list so that it can first make a copy of its
   * internal counterpart's values. (If it didn't do this, then it would
   * "lose" its value on being removed.)
   */
  void RemovingFromList();

  bool IsReadonly() const { return mIsReadonly; }
  void SetReadonly(bool aReadonly) { mIsReadonly = aReadonly; }

  // WebIDL
  virtual float X() = 0;
  virtual void SetX(float aX, ErrorResult& rv) = 0;
  virtual float Y() = 0;
  virtual void SetY(float aY, ErrorResult& rv) = 0;
  virtual already_AddRefed<nsISVGPoint> MatrixTransform(
      dom::SVGMatrix& matrix) = 0;
  virtual JSObject* WrapObject(JSContext* cx,
                               JS::Handle<JSObject*> aGivenProto) override {
    return dom::SVGPoint_Binding::Wrap(cx, this, aGivenProto);
  }

  virtual nsISupports* GetParentObject() = 0;

 protected:
#ifdef DEBUG
  bool IndexIsValid();
#endif

  RefPtr<DOMSVGPointList> mList;

  // Bounds for the following are checked in the ctor, so be sure to update
  // that if you change the capacity of any of the following.

  uint32_t mListIndex : MOZ_SVG_LIST_INDEX_BIT_COUNT;
  uint32_t mIsReadonly : 1;     // These flags are uint32_t because MSVC won't
  uint32_t mIsAnimValItem : 1;  // pack otherwise.
  uint32_t mIsTranslatePoint : 1;

  /**
   * Get a reference to the internal SVGPoint list item that this DOM wrapper
   * object currently wraps.
   *
   * To simplify the code we just have this one method for obtaining both
   * baseVal and animVal internal items. This means that animVal items don't
   * get const protection, but then our setter methods guard against changing
   * animVal items.
   */
  SVGPoint& InternalItem();

  // The following member is only used when we're not in a list:
  SVGPoint mPt;
};

NS_DEFINE_STATIC_IID_ACCESSOR(nsISVGPoint, MOZILLA_NSISVGPOINT_IID)

}  // namespace mozilla

#undef MOZ_SVG_LIST_INDEX_BIT_COUNT