chromium/third_party/blink/renderer/platform/geometry/layout_unit.h

/*
 * Copyright (c) 2012, Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_LAYOUT_UNIT_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_LAYOUT_UNIT_H_

#include <climits>
#include <iosfwd>
#include <limits>
#include <optional>

#include "base/check_op.h"
#include "base/compiler_specific.h"
#include "base/dcheck_is_on.h"
#include "base/logging.h"
#include "base/numerics/clamped_math.h"
#include "base/numerics/safe_conversions.h"
#include "build/build_config.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/vector_traits.h"

namespace WTF {
class String;
}  // namespace WTF

namespace blink {

#if DCHECK_IS_ON()
#define REPORT_OVERFLOW(doesOverflow)
#else
#define REPORT_OVERFLOW
#endif

//
// `FixedPoint` is a fixed-point math class template, with the number of bits
// for the fractional part as a template parameter.
//
// `LayoutUnit` is an instantiated class of the `FixedPoint`, storing multiples
// of 1/64 of a pixel in an `int32_t` storage.
// See: https://trac.webkit.org/wiki/LayoutUnit
//
// `TextRunLayoutUnit` stores multiples of 1/65536 of a pixel in the same
// storage, so it has less integral part than `LayoutUnit` (16/16 bits vs 26/6
// bits). Suitable for a run of text, but not for the whole layout space.
//
// `InlineLayoutUnit` stores the same precision as `TextRunLayoutUnit` using an
// `int64_t` storage. It can provide the text precision, and represent the whole
// layout space (and more, 48 bits vs 26 bits), but it's double-sized.
//
// Note, non-member functions and operators for `TextRunLayoutUnit` and
// `InlineLayoutUnit` are implemented as needed.
//
template <unsigned fractional_bits, typename Storage>
class PLATFORM_EXPORT FixedPoint {};

LayoutUnit;
TextRunLayoutUnit;
InlineLayoutUnit;

// kIndefiniteSize is a special value used within layout code. It is typical
// within layout to have sizes which are only allowed to be non-negative or
// "indefinite". We use the value of "-1" to represent these indefinite values.
//
// It is common to clamp these indefinite values to zero.
// |LayoutUnit::ClampIndefiniteToZero| provides this functionality, and
// additionally DCHECKs that it isn't some other negative value.
inline constexpr LayoutUnit kIndefiniteSize(-1);

// TODO(kojii): Using three-way comparison (spaceship) operator for `int` makes
// too many cases ambiguous.
inline bool operator<=(const LayoutUnit& a, int b) {}

inline bool operator<=(const int a, const LayoutUnit& b) {}

inline bool operator>=(const LayoutUnit& a, int b) {}

inline bool operator>=(const int a, const LayoutUnit& b) {}

inline bool operator<(const LayoutUnit& a, int b) {}

inline bool operator<(const int a, const LayoutUnit& b) {}

inline bool operator>(const LayoutUnit& a, int b) {}

inline bool operator>(const int a, const LayoutUnit& b) {}

inline bool operator!=(const int a, const LayoutUnit& b) {}

inline bool operator!=(const LayoutUnit& a, int b) {}

inline bool operator==(const LayoutUnit& a, int b) {}

inline bool operator==(const int a, const LayoutUnit& b) {}

// For multiplication that's prone to overflow, this bounds it to
// `FixedPoint::Max()` and `FixedPoint::Min()`.
template <unsigned fractional_bits, typename RawValue>
  requires(std::is_same_v<RawValue, int32_t>)
inline FixedPoint<fractional_bits, RawValue> BoundedMultiply(
    const FixedPoint<fractional_bits, RawValue>& a,
    const FixedPoint<fractional_bits, RawValue>& b) {}

template <unsigned fractional_bits, typename RawValue>
  requires(std::is_same_v<RawValue, int32_t>)
inline FixedPoint<fractional_bits, RawValue> operator*(
    const FixedPoint<fractional_bits, RawValue>& a,
    const FixedPoint<fractional_bits, RawValue>& b) {}

inline double operator*(const LayoutUnit& a, double b) {}

inline float operator*(const LayoutUnit& a, float b) {}

template <unsigned fractional_bits, typename RawValue>
inline FixedPoint<fractional_bits, RawValue> operator*(
    const FixedPoint<fractional_bits, RawValue> a,
    std::integral auto b) {}

inline LayoutUnit operator*(std::integral auto a, const LayoutUnit& b) {
  return LayoutUnit(a) * b;
}

constexpr float operator*(const float a, const LayoutUnit& b) {}

constexpr double operator*(const double a, const LayoutUnit& b) {}

template <unsigned fractional_bits, typename RawValue>
  requires(std::is_same_v<RawValue, int32_t>)
inline FixedPoint<fractional_bits, RawValue> operator/(
    const FixedPoint<fractional_bits, RawValue>& a,
    const FixedPoint<fractional_bits, RawValue>& b) {}

template <unsigned fractional_bits, typename RawValue>
inline FixedPoint<fractional_bits, RawValue>
FixedPoint<fractional_bits, RawValue>::MulDiv(FixedPoint m,
                                              FixedPoint d) const {}

constexpr float operator/(const LayoutUnit& a, float b) {}

constexpr double operator/(const LayoutUnit& a, double b) {}

template <unsigned fractional_bits, typename RawValue>
inline FixedPoint<fractional_bits, RawValue> operator/(
    const FixedPoint<fractional_bits, RawValue>& a,
    std::integral auto b) {}

constexpr float operator/(const float a, const LayoutUnit& b) {}

constexpr double operator/(const double a, const LayoutUnit& b) {}

inline LayoutUnit operator/(std::integral auto a, const LayoutUnit& b) {
  return LayoutUnit(a) / b;
}

template <unsigned fractional_bits, typename RawValue>
ALWAYS_INLINE FixedPoint<fractional_bits, RawValue> operator+(
    const FixedPoint<fractional_bits, RawValue>& a,
    const FixedPoint<fractional_bits, RawValue>& b) {}

inline LayoutUnit operator+(const LayoutUnit& a, std::integral auto b) {
  return a + LayoutUnit(b);
}

template <unsigned fractional_bits, typename RawValue>
inline float operator+(const FixedPoint<fractional_bits, RawValue>& a,
                       float b) {}

inline double operator+(const LayoutUnit& a, double b) {}

inline LayoutUnit operator+(std::integral auto a, const LayoutUnit& b) {
  return LayoutUnit(a) + b;
}

constexpr float operator+(const float a, const LayoutUnit& b) {}

constexpr double operator+(const double a, const LayoutUnit& b) {}

ALWAYS_INLINE LayoutUnit operator-(const LayoutUnit& a, const LayoutUnit& b) {}

inline LayoutUnit operator-(const LayoutUnit& a, std::integral auto b) {
  return a - LayoutUnit(b);
}

constexpr float operator-(const LayoutUnit& a, float b) {}

constexpr double operator-(const LayoutUnit& a, double b) {}

inline LayoutUnit operator-(std::integral auto a, const LayoutUnit& b) {
  return LayoutUnit(a) - b;
}

constexpr float operator-(const float a, const LayoutUnit& b) {}

template <unsigned fractional_bits, typename RawValue>
inline FixedPoint<fractional_bits, RawValue> operator-(
    const FixedPoint<fractional_bits, RawValue>& a) {}

// Returns the remainder after a division with integer results.
// This calculates the modulo so that:
//   a = static_cast<int>(a / b) * b + IntMod(a, b).
inline LayoutUnit IntMod(const LayoutUnit& a, const LayoutUnit& b) {}

template <unsigned fractional_bits, typename RawValue, typename SourceStorage>
  requires(sizeof(SourceStorage) <= sizeof(RawValue))
inline FixedPoint<fractional_bits, RawValue>& operator+=(
    FixedPoint<fractional_bits, RawValue>& a,
    const FixedPoint<fractional_bits, SourceStorage>& b) {}

inline LayoutUnit& operator+=(LayoutUnit& a, std::integral auto b) {
  a = a + LayoutUnit(b);
  return a;
}

inline LayoutUnit& operator+=(LayoutUnit& a, float b) {}

inline float& operator+=(float& a, const LayoutUnit& b) {}

inline LayoutUnit& operator-=(LayoutUnit& a, std::integral auto b) {
  a = a - LayoutUnit(b);
  return a;
}

template <unsigned fractional_bits, typename RawValue>
inline FixedPoint<fractional_bits, RawValue>& operator-=(
    FixedPoint<fractional_bits, RawValue>& a,
    const FixedPoint<fractional_bits, RawValue>& b) {}

inline LayoutUnit& operator-=(LayoutUnit& a, float b) {}

inline float& operator-=(float& a, const LayoutUnit& b) {}

inline LayoutUnit& operator*=(LayoutUnit& a, const LayoutUnit& b) {}

inline LayoutUnit& operator*=(LayoutUnit& a, float b) {}

inline float& operator*=(float& a, const LayoutUnit& b) {}

inline LayoutUnit& operator/=(LayoutUnit& a, const LayoutUnit& b) {}

inline LayoutUnit& operator/=(LayoutUnit& a, float b) {}

inline float& operator/=(float& a, const LayoutUnit& b) {}

inline int SnapSizeToPixel(LayoutUnit size, LayoutUnit location) {}

inline int SnapSizeToPixelAllowingZero(LayoutUnit size, LayoutUnit location) {}

inline int RoundToInt(LayoutUnit value) {}

inline int FloorToInt(LayoutUnit value) {}

inline int CeilToInt(LayoutUnit value) {}

inline LayoutUnit AbsoluteValue(const LayoutUnit& value) {}

template <unsigned fractional_bits, typename RawValue>
inline std::optional<FixedPoint<fractional_bits, RawValue>>
FixedPoint<fractional_bits, RawValue>::NullOptIf(FixedPoint null_value) const {}

#if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS) && \
    defined(COMPILER_GCC) && !BUILDFLAG(IS_NACL) && __OPTIMIZE__
inline int GetMaxSaturatedSetResultForTesting() {
  // For ARM Asm version the set function maxes out to the biggest
  // possible integer part with the fractional part zero'd out.
  // e.g. 0x7fffffc0.
  return LayoutUnit::kRawValueMax & ~(LayoutUnit::kFixedPointDenominator - 1);
}

inline int GetMinSaturatedSetResultForTesting() {
  return LayoutUnit::kRawValueMin;
}
#else
ALWAYS_INLINE int GetMaxSaturatedSetResultForTesting() {}

ALWAYS_INLINE int GetMinSaturatedSetResultForTesting() {}
#endif  // CPU(ARM) && COMPILER(GCC)

template <unsigned fractional_bits, typename RawValue>
PLATFORM_EXPORT std::ostream& operator<<(
    std::ostream&,
    const FixedPoint<fractional_bits, RawValue>&);
template <unsigned fractional_bits, typename RawValue>
PLATFORM_EXPORT WTF::TextStream& operator<<(
    WTF::TextStream&,
    const FixedPoint<fractional_bits, RawValue>&);

}  // namespace blink

WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS()

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_LAYOUT_UNIT_H_