| Index: ui/gfx/geometry/scale.cc
|
| diff --git a/ui/gfx/geometry/scale.cc b/ui/gfx/geometry/scale.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..089344eead51617e9c2dccde9e3fe0a9d28ec1bf
|
| --- /dev/null
|
| +++ b/ui/gfx/geometry/scale.cc
|
| @@ -0,0 +1,84 @@
|
| +// Copyright (c) 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "ui/gfx/geometry/scale.h"
|
| +
|
| +#include "base/command_line.h"
|
| +#include "base/logging.h"
|
| +#include "base/numerics/safe_math.h"
|
| +#include "ui/gfx/switches.h"
|
| +
|
| +namespace {
|
| +const int kScalePrecision = 4;
|
| +
|
| +bool VerifyFixedPrecisionValue(float value) {
|
| + const base::CheckedNumeric<float> checked_factor = pow(10, kScalePrecision);
|
| + if (!checked_factor.IsValid())
|
| + return false;
|
| +
|
| + base::CheckedNumeric<float> checked_value = value;
|
| + checked_value *= checked_factor.ValueOrDie();
|
| + if (!checked_value.IsValid())
|
| + return false;
|
| +
|
| + checked_value = floor(checked_value.ValueOrDie());
|
| + checked_value /= checked_factor.ValueOrDie();
|
| + return checked_value.IsValid();
|
| +}
|
| +
|
| +float ComputeFixedPrecisionValue(float value) {
|
| + // Limiting precision 1 <= kScalePrecision <= 8, as floating point precision
|
| + // of >= 12 gives different values, 8 on a safer side.
|
| + DCHECK(kScalePrecision >= 1 && kScalePrecision <= 8);
|
| + DCHECK(VerifyFixedPrecisionValue(value));
|
| +
|
| + const float factor = pow(10, kScalePrecision);
|
| + value *= factor;
|
| + value = floor(value);
|
| + value /= factor;
|
| + return value;
|
| +}
|
| +
|
| +bool IsFixedPrecisionScaleEnabled() {
|
| + static bool fixed_precision_enabled =
|
| + base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kEnableFixedPrecisionScale);
|
| + return fixed_precision_enabled;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +namespace gfx {
|
| +
|
| +Scale::Scale(float value) : absolute_value_(value) {
|
| + // Scale < 0.0f is undefined.
|
| + DCHECK(absolute_value_ >= 0);
|
| + DCHECK_LT(absolute_value_, std::numeric_limits<float>::max());
|
| +
|
| + if (IsFixedPrecisionScaleEnabled())
|
| + value_ = ComputeFixedPrecisionValue(absolute_value_);
|
| + else
|
| + value_ = absolute_value_;
|
| +}
|
| +
|
| +Scale::Scale(const Scale& other) {
|
| + absolute_value_ = other.absolute_value_;
|
| + value_ = other.value_;
|
| +}
|
| +
|
| +Scale& Scale::operator=(const Scale& other) {
|
| + absolute_value_ = other.absolute_value_;
|
| + value_ = other.value_;
|
| + return *this;
|
| +}
|
| +
|
| +bool Scale::operator<(const Scale& other) const {
|
| + return this->Value() < other.Value();
|
| +}
|
| +
|
| +bool Scale::operator>(const Scale& other) const {
|
| + return this->Value() > other.Value();
|
| +}
|
| +
|
| +} // namespace gfx
|
|
|