tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

DOMRect.cpp (5688B)


      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 "mozilla/dom/DOMRect.h"
      8 
      9 #include <cmath>
     10 
     11 #include "js/StructuredClone.h"
     12 #include "mozilla/AppUnits.h"
     13 #include "mozilla/Casting.h"
     14 #include "mozilla/dom/BindingDeclarations.h"
     15 #include "mozilla/dom/DOMRectBinding.h"
     16 #include "mozilla/dom/DOMRectListBinding.h"
     17 #include "nsIGlobalObject.h"
     18 #include "nsRect.h"
     19 
     20 using namespace mozilla;
     21 using namespace mozilla::dom;
     22 
     23 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMRectReadOnly, mParent)
     24 NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMRectReadOnly)
     25 NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMRectReadOnly)
     26 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMRectReadOnly)
     27  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
     28  NS_INTERFACE_MAP_ENTRY(nsISupports)
     29 NS_INTERFACE_MAP_END
     30 
     31 JSObject* DOMRectReadOnly::WrapObject(JSContext* aCx,
     32                                      JS::Handle<JSObject*> aGivenProto) {
     33  MOZ_ASSERT(mParent);
     34  return DOMRectReadOnly_Binding::Wrap(aCx, this, aGivenProto);
     35 }
     36 
     37 already_AddRefed<DOMRectReadOnly> DOMRectReadOnly::FromRect(
     38    const GlobalObject& aGlobal, const DOMRectInit& aInit) {
     39  RefPtr<DOMRectReadOnly> obj = new DOMRectReadOnly(
     40      aGlobal.GetAsSupports(), aInit.mX, aInit.mY, aInit.mWidth, aInit.mHeight);
     41  return obj.forget();
     42 }
     43 
     44 already_AddRefed<DOMRectReadOnly> DOMRectReadOnly::Constructor(
     45    const GlobalObject& aGlobal, double aX, double aY, double aWidth,
     46    double aHeight) {
     47  RefPtr<DOMRectReadOnly> obj =
     48      new DOMRectReadOnly(aGlobal.GetAsSupports(), aX, aY, aWidth, aHeight);
     49  return obj.forget();
     50 }
     51 
     52 // https://drafts.fxtf.org/geometry/#structured-serialization
     53 bool DOMRectReadOnly::WriteStructuredClone(
     54    JSContext* aCx, JSStructuredCloneWriter* aWriter) const {
     55 #define WriteDouble(d)                                                       \
     56  JS_WriteUint32Pair(aWriter, (BitwiseCast<uint64_t>(d) >> 32) & 0xffffffff, \
     57                     BitwiseCast<uint64_t>(d) & 0xffffffff)
     58 
     59  return WriteDouble(mX) && WriteDouble(mY) && WriteDouble(mWidth) &&
     60         WriteDouble(mHeight);
     61 
     62 #undef WriteDouble
     63 }
     64 
     65 // static
     66 already_AddRefed<DOMRectReadOnly> DOMRectReadOnly::ReadStructuredClone(
     67    JSContext* aCx, nsIGlobalObject* aGlobal,
     68    JSStructuredCloneReader* aReader) {
     69  RefPtr<DOMRectReadOnly> retval = new DOMRectReadOnly(aGlobal);
     70  if (!retval->ReadStructuredClone(aReader)) {
     71    return nullptr;
     72  }
     73  return retval.forget();
     74 }
     75 
     76 bool DOMRectReadOnly::ReadStructuredClone(JSStructuredCloneReader* aReader) {
     77  uint32_t high;
     78  uint32_t low;
     79 
     80 #define ReadDouble(d)                             \
     81  if (!JS_ReadUint32Pair(aReader, &high, &low)) { \
     82    return false;                                 \
     83  }                                               \
     84  (*(d) = BitwiseCast<double>(static_cast<uint64_t>(high) << 32 | low))
     85 
     86  ReadDouble(&mX);
     87  ReadDouble(&mY);
     88  ReadDouble(&mWidth);
     89  ReadDouble(&mHeight);
     90 
     91  return true;
     92 
     93 #undef ReadDouble
     94 }
     95 
     96 // -----------------------------------------------------------------------------
     97 
     98 JSObject* DOMRect::WrapObject(JSContext* aCx,
     99                              JS::Handle<JSObject*> aGivenProto) {
    100  MOZ_ASSERT(mParent);
    101  return DOMRect_Binding::Wrap(aCx, this, aGivenProto);
    102 }
    103 
    104 already_AddRefed<DOMRect> DOMRect::FromRect(const GlobalObject& aGlobal,
    105                                            const DOMRectInit& aInit) {
    106  RefPtr<DOMRect> obj = new DOMRect(aGlobal.GetAsSupports(), aInit.mX, aInit.mY,
    107                                    aInit.mWidth, aInit.mHeight);
    108  return obj.forget();
    109 }
    110 
    111 already_AddRefed<DOMRect> DOMRect::Constructor(const GlobalObject& aGlobal,
    112                                               double aX, double aY,
    113                                               double aWidth, double aHeight) {
    114  RefPtr<DOMRect> obj =
    115      new DOMRect(aGlobal.GetAsSupports(), aX, aY, aWidth, aHeight);
    116  return obj.forget();
    117 }
    118 
    119 // static
    120 already_AddRefed<DOMRect> DOMRect::ReadStructuredClone(
    121    JSContext* aCx, nsIGlobalObject* aGlobal,
    122    JSStructuredCloneReader* aReader) {
    123  RefPtr<DOMRect> retval = new DOMRect(aGlobal);
    124  if (!retval->ReadStructuredClone(aReader)) {
    125    return nullptr;
    126  }
    127  return retval.forget();
    128 }
    129 
    130 // -----------------------------------------------------------------------------
    131 
    132 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMRectList, mParent, mArray)
    133 
    134 NS_INTERFACE_TABLE_HEAD(DOMRectList)
    135  NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY
    136  NS_INTERFACE_TABLE0(DOMRectList)
    137  NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(DOMRectList)
    138 NS_INTERFACE_MAP_END
    139 
    140 NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMRectList)
    141 NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMRectList)
    142 
    143 JSObject* DOMRectList::WrapObject(JSContext* cx,
    144                                  JS::Handle<JSObject*> aGivenProto) {
    145  return mozilla::dom::DOMRectList_Binding::Wrap(cx, this, aGivenProto);
    146 }
    147 
    148 static double RoundFloat(double aValue) { return floor(aValue + 0.5); }
    149 
    150 void DOMRect::SetLayoutRect(const nsRect& aLayoutRect) {
    151  double scale = 65536.0;
    152  // Round to the nearest 1/scale units. We choose scale so it can be
    153  // represented exactly by machine floating point.
    154  double scaleInv = 1 / scale;
    155  double t2pScaled = scale / AppUnitsPerCSSPixel();
    156  double x = RoundFloat(aLayoutRect.x * t2pScaled) * scaleInv;
    157  double y = RoundFloat(aLayoutRect.y * t2pScaled) * scaleInv;
    158  SetRect(x, y, RoundFloat(aLayoutRect.XMost() * t2pScaled) * scaleInv - x,
    159          RoundFloat(aLayoutRect.YMost() * t2pScaled) * scaleInv - y);
    160 }