Commit eb00e7e0 authored by pkasting's avatar pkasting Committed by Commit bot

Type conversion fixes, ui/gfx/ edition.

This is mostly to fix MSVC warnings about possible value truncation.

BUG=81439
TEST=none

Review URL: https://codereview.chromium.org/649203003

Cr-Commit-Position: refs/heads/master@{#302687}
parent cc81e830
......@@ -48,7 +48,7 @@ double LinearAnimation::GetCurrentValue() const {
void LinearAnimation::SetCurrentValue(double new_value) {
new_value = std::max(0.0, std::min(1.0, new_value));
base::TimeDelta time_delta = base::TimeDelta::FromMicroseconds(
duration_.InMicroseconds() * (new_value - state_));
static_cast<int64>(duration_.InMicroseconds() * (new_value - state_)));
SetStartTime(start_time() - time_delta);
state_ = new_value;
}
......
......@@ -14,6 +14,7 @@
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "ui/gfx/geometry/cubic_bezier.h"
#include "ui/gfx/safe_integer_conversions.h"
......@@ -71,7 +72,7 @@ double Tween::CalculateValue(Tween::Type type, double state) {
namespace {
uint8 FloatToColorByte(float f) {
return std::min(std::max(ToRoundedInt(f * 255.f), 0), 255);
return base::saturated_cast<uint8>(ToRoundedInt(f * 255.f));
}
uint8 BlendColorComponents(uint8 start,
......@@ -149,7 +150,8 @@ int Tween::IntValueBetween(double value, int start, int target) {
//static
int Tween::LinearIntValueBetween(double value, int start, int target) {
return std::floor(0.5 + DoubleValueBetween(value, start, target));
// NOTE: Do not use ToRoundedInt()! See comments on function declaration.
return ToFlooredInt(0.5 + DoubleValueBetween(value, start, target));
}
// static
......
......@@ -40,26 +40,26 @@ class KMeanCluster {
}
void Reset() {
centroid[0] = centroid[1] = centroid[2] = 0;
aggregate[0] = aggregate[1] = aggregate[2] = 0;
counter = 0;
weight = 0;
centroid_[0] = centroid_[1] = centroid_[2] = 0;
aggregate_[0] = aggregate_[1] = aggregate_[2] = 0;
counter_ = 0;
weight_ = 0;
}
inline void SetCentroid(uint8_t r, uint8_t g, uint8_t b) {
centroid[0] = r;
centroid[1] = g;
centroid[2] = b;
centroid_[0] = r;
centroid_[1] = g;
centroid_[2] = b;
}
inline void GetCentroid(uint8_t* r, uint8_t* g, uint8_t* b) {
*r = centroid[0];
*g = centroid[1];
*b = centroid[2];
*r = centroid_[0];
*g = centroid_[1];
*b = centroid_[2];
}
inline bool IsAtCentroid(uint8_t r, uint8_t g, uint8_t b) {
return r == centroid[0] && g == centroid[1] && b == centroid[2];
return r == centroid_[0] && g == centroid_[1] && b == centroid_[2];
}
// Recomputes the centroid of the cluster based on the aggregate data. The
......@@ -67,30 +67,30 @@ class KMeanCluster {
// purposes. The aggregate and counter are then cleared to be ready for the
// next iteration.
inline void RecomputeCentroid() {
if (counter > 0) {
centroid[0] = aggregate[0] / counter;
centroid[1] = aggregate[1] / counter;
centroid[2] = aggregate[2] / counter;
aggregate[0] = aggregate[1] = aggregate[2] = 0;
weight = counter;
counter = 0;
if (counter_ > 0) {
centroid_[0] = static_cast<uint8_t>(aggregate_[0] / counter_);
centroid_[1] = static_cast<uint8_t>(aggregate_[1] / counter_);
centroid_[2] = static_cast<uint8_t>(aggregate_[2] / counter_);
aggregate_[0] = aggregate_[1] = aggregate_[2] = 0;
weight_ = counter_;
counter_ = 0;
}
}
inline void AddPoint(uint8_t r, uint8_t g, uint8_t b) {
aggregate[0] += r;
aggregate[1] += g;
aggregate[2] += b;
++counter;
aggregate_[0] += r;
aggregate_[1] += g;
aggregate_[2] += b;
++counter_;
}
// Just returns the distance^2. Since we are comparing relative distances
// there is no need to perform the expensive sqrt() operation.
inline uint32_t GetDistanceSqr(uint8_t r, uint8_t g, uint8_t b) {
return (r - centroid[0]) * (r - centroid[0]) +
(g - centroid[1]) * (g - centroid[1]) +
(b - centroid[2]) * (b - centroid[2]);
return (r - centroid_[0]) * (r - centroid_[0]) +
(g - centroid_[1]) * (g - centroid_[1]) +
(b - centroid_[2]) * (b - centroid_[2]);
}
// In order to determine if we have hit convergence or not we need to see
......@@ -98,18 +98,18 @@ class KMeanCluster {
// not the centroid is the same as the aggregate sum of points that will be
// used to generate the next centroid.
inline bool CompareCentroidWithAggregate() {
if (counter == 0)
if (counter_ == 0)
return false;
return aggregate[0] / counter == centroid[0] &&
aggregate[1] / counter == centroid[1] &&
aggregate[2] / counter == centroid[2];
return aggregate_[0] / counter_ == centroid_[0] &&
aggregate_[1] / counter_ == centroid_[1] &&
aggregate_[2] / counter_ == centroid_[2];
}
// Returns the previous counter, which is used to determine the weight
// of the cluster for sorting.
inline uint32_t GetWeight() const {
return weight;
return weight_;
}
static bool SortKMeanClusterByWeight(const KMeanCluster& a,
......@@ -118,16 +118,16 @@ class KMeanCluster {
}
private:
uint8_t centroid[3];
uint8_t centroid_[3];
// Holds the sum of all the points that make up this cluster. Used to
// generate the next centroid as well as to check for convergence.
uint32_t aggregate[3];
uint32_t counter;
uint32_t aggregate_[3];
uint32_t counter_;
// The weight of the cluster, determined by how many points were used
// to generate the previous centroid.
uint32_t weight;
uint32_t weight_;
};
// Un-premultiplies each pixel in |bitmap| into an output |buffer|.
......@@ -468,24 +468,33 @@ gfx::Matrix3F ComputeColorCovariance(const SkBitmap& bitmap) {
// of R, G and B channels with (R, G, B)
int pixel_n = bitmap.width() * bitmap.height();
covariance.set(
(static_cast<double>(rr_sum) / pixel_n -
static_cast<double>(r_sum * r_sum) / pixel_n / pixel_n),
(static_cast<double>(rg_sum) / pixel_n -
static_cast<double>(r_sum * g_sum) / pixel_n / pixel_n),
(static_cast<double>(rb_sum) / pixel_n -
static_cast<double>(r_sum * b_sum) / pixel_n / pixel_n),
(static_cast<double>(rg_sum) / pixel_n -
static_cast<double>(r_sum * g_sum) / pixel_n / pixel_n),
(static_cast<double>(gg_sum) / pixel_n -
static_cast<double>(g_sum * g_sum) / pixel_n / pixel_n),
(static_cast<double>(gb_sum) / pixel_n -
static_cast<double>(g_sum * b_sum) / pixel_n / pixel_n),
(static_cast<double>(rb_sum) / pixel_n -
static_cast<double>(r_sum * b_sum) / pixel_n / pixel_n),
(static_cast<double>(gb_sum) / pixel_n -
static_cast<double>(g_sum * b_sum) / pixel_n / pixel_n),
(static_cast<double>(bb_sum) / pixel_n -
static_cast<double>(b_sum * b_sum) / pixel_n / pixel_n));
static_cast<float>(
static_cast<double>(rr_sum) / pixel_n -
static_cast<double>(r_sum * r_sum) / pixel_n / pixel_n),
static_cast<float>(
static_cast<double>(rg_sum) / pixel_n -
static_cast<double>(r_sum * g_sum) / pixel_n / pixel_n),
static_cast<float>(
static_cast<double>(rb_sum) / pixel_n -
static_cast<double>(r_sum * b_sum) / pixel_n / pixel_n),
static_cast<float>(
static_cast<double>(rg_sum) / pixel_n -
static_cast<double>(r_sum * g_sum) / pixel_n / pixel_n),
static_cast<float>(
static_cast<double>(gg_sum) / pixel_n -
static_cast<double>(g_sum * g_sum) / pixel_n / pixel_n),
static_cast<float>(
static_cast<double>(gb_sum) / pixel_n -
static_cast<double>(g_sum * b_sum) / pixel_n / pixel_n),
static_cast<float>(
static_cast<double>(rb_sum) / pixel_n -
static_cast<double>(r_sum * b_sum) / pixel_n / pixel_n),
static_cast<float>(
static_cast<double>(gb_sum) / pixel_n -
static_cast<double>(g_sum * b_sum) / pixel_n / pixel_n),
static_cast<float>(
static_cast<double>(bb_sum) / pixel_n -
static_cast<double>(b_sum * b_sum) / pixel_n / pixel_n));
return covariance;
}
......@@ -529,9 +538,9 @@ bool ApplyColorReduction(const SkBitmap& source_bitmap,
else
c = source_color_row[x];
float r = SkColorGetR(c);
float g = SkColorGetG(c);
float b = SkColorGetB(c);
uint8_t r = SkColorGetR(c);
uint8_t g = SkColorGetG(c);
uint8_t b = SkColorGetB(c);
float gray_level = tr * r + tg * g + tb * b;
max_val = std::max(max_val, gray_level);
min_val = std::min(min_val, gray_level);
......@@ -542,7 +551,7 @@ bool ApplyColorReduction(const SkBitmap& source_bitmap,
float scale = 0.0;
t0 = -min_val;
if (max_val > min_val)
scale = 255.0 / (max_val - min_val);
scale = 255.0f / (max_val - min_val);
t0 *= scale;
tr *= scale;
tg *= scale;
......@@ -561,9 +570,9 @@ bool ApplyColorReduction(const SkBitmap& source_bitmap,
else
c = source_color_row[x];
float r = SkColorGetR(c);
float g = SkColorGetG(c);
float b = SkColorGetB(c);
uint8_t r = SkColorGetR(c);
uint8_t g = SkColorGetG(c);
uint8_t b = SkColorGetB(c);
float gl = t0 + tr * r + tg * g + tb * b;
if (gl < 0)
......
......@@ -13,6 +13,7 @@
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "build/build_config.h"
#if defined(OS_WIN)
#include "skia/ext/skia_utils_win.h"
......@@ -77,10 +78,10 @@ double ContrastRatio(double foreground_luminance, double background_luminance) {
// ----------------------------------------------------------------------------
unsigned char GetLuminanceForColor(SkColor color) {
int luma = static_cast<int>((0.3 * SkColorGetR(color)) +
(0.59 * SkColorGetG(color)) +
(0.11 * SkColorGetB(color)));
return std::max(std::min(luma, 255), 0);
return base::saturated_cast<unsigned char>(
(0.3 * SkColorGetR(color)) +
(0.59 * SkColorGetG(color)) +
(0.11 * SkColorGetB(color)));
}
double RelativeLuminance(SkColor color) {
......@@ -136,7 +137,7 @@ SkColor HSLToSkColor(const HSL& hsl, SkAlpha alpha) {
else if (lightness >= 1.0)
light = 255;
else
light = SkDoubleToFixed(lightness) >> 8;
light = static_cast<uint8>(SkDoubleToFixed(lightness) >> 8);
return SkColorSetARGB(alpha, light, light, light);
}
......@@ -198,7 +199,7 @@ bool IsWithinHSLRange(const HSL& hsl,
SkColor HSLShift(SkColor color, const HSL& shift) {
HSL hsl;
int alpha = SkColorGetA(color);
SkAlpha alpha = SkColorGetA(color);
SkColorToHSL(color, &hsl);
// Replace the hue with the tint's hue.
......
......@@ -153,7 +153,7 @@ void Display::SetSize(const gfx::Size& size_in_pixel) {
#if defined(USE_AURA)
gfx::PointF origin_f = origin;
origin_f.Scale(device_scale_factor_);
origin.SetPoint(origin_f.x(), origin_f.y());
origin = gfx::ToFlooredPoint(origin_f);
#endif
SetScaleAndBounds(device_scale_factor_, gfx::Rect(origin, size_in_pixel));
}
......
......@@ -34,7 +34,8 @@ class GFX_EXPORT Insets : public InsetsBase<Insets, int> {
}
operator InsetsF() const {
return InsetsF(top(), left(), bottom(), right());
return InsetsF(static_cast<float>(top()), static_cast<float>(left()),
static_cast<float>(bottom()), static_cast<float>(right()));
}
// Returns a string representation of the insets.
......
......@@ -105,15 +105,24 @@ Matrix3F Matrix3F::Inverse() const {
return inverse; // Singular matrix. Return Zeros().
inverse.set(
(data_[M11] * data_[M22] - data_[M12] * data_[M21]) / determinant,
(data_[M02] * data_[M21] - data_[M01] * data_[M22]) / determinant,
(data_[M01] * data_[M12] - data_[M02] * data_[M11]) / determinant,
(data_[M12] * data_[M20] - data_[M10] * data_[M22]) / determinant,
(data_[M00] * data_[M22] - data_[M02] * data_[M20]) / determinant,
(data_[M02] * data_[M10] - data_[M00] * data_[M12]) / determinant,
(data_[M10] * data_[M21] - data_[M11] * data_[M20]) / determinant,
(data_[M01] * data_[M20] - data_[M00] * data_[M21]) / determinant,
(data_[M00] * data_[M11] - data_[M01] * data_[M10]) / determinant);
static_cast<float>((data_[M11] * data_[M22] - data_[M12] * data_[M21]) /
determinant),
static_cast<float>((data_[M02] * data_[M21] - data_[M01] * data_[M22]) /
determinant),
static_cast<float>((data_[M01] * data_[M12] - data_[M02] * data_[M11]) /
determinant),
static_cast<float>((data_[M12] * data_[M20] - data_[M10] * data_[M22]) /
determinant),
static_cast<float>((data_[M00] * data_[M22] - data_[M02] * data_[M20]) /
determinant),
static_cast<float>((data_[M02] * data_[M10] - data_[M00] * data_[M12]) /
determinant),
static_cast<float>((data_[M10] * data_[M21] - data_[M11] * data_[M20]) /
determinant),
static_cast<float>((data_[M01] * data_[M20] - data_[M00] * data_[M21]) /
determinant),
static_cast<float>((data_[M00] * data_[M11] - data_[M01] * data_[M10]) /
determinant));
return inverse;
}
......
......@@ -90,7 +90,7 @@ class GFX_EXPORT Point {
}
operator PointF() const {
return PointF(x(), y());
return PointF(static_cast<float>(x()), static_cast<float>(y()));
}
// Returns a string representation of point.
......
......@@ -16,6 +16,7 @@
#include <iosfwd>
#include <string>
#include "base/numerics/safe_conversions.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h"
......@@ -59,7 +60,8 @@ class GFX_EXPORT Rect {
#endif
operator RectF() const {
return RectF(origin().x(), origin().y(), size().width(), size().height());
return RectF(static_cast<float>(x()), static_cast<float>(y()),
static_cast<float>(width()), static_cast<float>(height()));
}
int x() const { return origin_.x(); }
......@@ -220,10 +222,24 @@ GFX_EXPORT Rect BoundingRect(const Point& p1, const Point& p2);
inline Rect ScaleToEnclosingRect(const Rect& rect,
float x_scale,
float y_scale) {
int x = std::floor(rect.x() * x_scale);
int y = std::floor(rect.y() * y_scale);
int r = rect.width() == 0 ? x : std::ceil(rect.right() * x_scale);
int b = rect.height() == 0 ? y : std::ceil(rect.bottom() * y_scale);
// These next functions cast instead of using e.g. ToFlooredInt() because we
// haven't checked to ensure that the clamping behavior of the helper
// functions doesn't degrade performance, and callers shouldn't be passing
// values that cause overflow anyway.
DCHECK(base::IsValueInRangeForNumericType<int>(
std::floor(rect.x() * x_scale)));
DCHECK(base::IsValueInRangeForNumericType<int>(
std::floor(rect.y() * y_scale)));
DCHECK(base::IsValueInRangeForNumericType<int>(
std::ceil(rect.right() * x_scale)));
DCHECK(base::IsValueInRangeForNumericType<int>(
std::ceil(rect.bottom() * y_scale)));
int x = static_cast<int>(std::floor(rect.x() * x_scale));
int y = static_cast<int>(std::floor(rect.y() * y_scale));
int r = rect.width() == 0 ?
x : static_cast<int>(std::ceil(rect.right() * x_scale));
int b = rect.height() == 0 ?
y : static_cast<int>(std::ceil(rect.bottom() * y_scale));
return Rect(x, y, r - x, b - y);
}
......@@ -234,10 +250,20 @@ inline Rect ScaleToEnclosingRect(const Rect& rect, float scale) {
inline Rect ScaleToEnclosedRect(const Rect& rect,
float x_scale,
float y_scale) {
int x = std::ceil(rect.x() * x_scale);
int y = std::ceil(rect.y() * y_scale);
int r = rect.width() == 0 ? x : std::floor(rect.right() * x_scale);
int b = rect.height() == 0 ? y : std::floor(rect.bottom() * y_scale);
DCHECK(base::IsValueInRangeForNumericType<int>(
std::ceil(rect.x() * x_scale)));
DCHECK(base::IsValueInRangeForNumericType<int>(
std::ceil(rect.y() * y_scale)));
DCHECK(base::IsValueInRangeForNumericType<int>(
std::floor(rect.right() * x_scale)));
DCHECK(base::IsValueInRangeForNumericType<int>(
std::floor(rect.bottom() * y_scale)));
int x = static_cast<int>(std::ceil(rect.x() * x_scale));
int y = static_cast<int>(std::ceil(rect.y() * y_scale));
int r = rect.width() == 0 ?
x : static_cast<int>(std::floor(rect.right() * x_scale));
int b = rect.height() == 0 ?
y : static_cast<int>(std::floor(rect.bottom() * y_scale));
return Rect(x, y, r - x, b - y);
}
......
......@@ -47,6 +47,15 @@ inline int ToRoundedInt(float value) {
return ClampToInt(rounded);
}
inline int ToRoundedInt(double value) {
double rounded;
if (value >= 0.0)
rounded = std::floor(value + 0.5);
else
rounded = std::ceil(value - 0.5);
return ClampToInt(rounded);
}
inline bool IsExpressibleAsInt(float value) {
if (value != value)
return false; // no int NaN.
......
......@@ -96,7 +96,7 @@ TEST(SafeIntegerConversions, ToRoundedInt) {
EXPECT_EQ(-100, ToRoundedInt(-100.1f));
EXPECT_EQ(-101, ToRoundedInt(-100.5f));
EXPECT_EQ(-101, ToRoundedInt(-100.9f));
EXPECT_EQ(0, ToRoundedInt(0));
EXPECT_EQ(0, ToRoundedInt(0.f));
EXPECT_EQ(100, ToRoundedInt(100.1f));
EXPECT_EQ(101, ToRoundedInt(100.5f));
EXPECT_EQ(101, ToRoundedInt(100.9f));
......
......@@ -67,7 +67,7 @@ class GFX_EXPORT Size {
bool IsEmpty() const { return !width() || !height(); }
operator SizeF() const {
return SizeF(width(), height());
return SizeF(static_cast<float>(width()), static_cast<float>(height()));
}
std::string ToString() const;
......
......@@ -60,7 +60,9 @@ class GFX_EXPORT Vector2d {
std::string ToString() const;
operator Vector2dF() const { return Vector2dF(x_, y_); }
operator Vector2dF() const {
return Vector2dF(static_cast<float>(x()), static_cast<float>(y()));
}
private:
int x_;
......
......@@ -331,8 +331,8 @@ void InterpolatedTransformAboutPivot::Init(const gfx::Point& pivot,
InterpolatedTransform* xform) {
gfx::Transform to_pivot;
gfx::Transform from_pivot;
to_pivot.Translate(-pivot.x(), -pivot.y());
from_pivot.Translate(pivot.x(), pivot.y());
to_pivot.Translate(SkIntToMScalar(-pivot.x()), SkIntToMScalar(-pivot.y()));
from_pivot.Translate(SkIntToMScalar(pivot.x()), SkIntToMScalar(pivot.y()));
scoped_ptr<InterpolatedTransform> pre_transform(
new InterpolatedConstantTransform(to_pivot));
......
......@@ -174,7 +174,7 @@ void ConvertSkiaToRGBA(const unsigned char* skia,
const uint32_t pixel_in = *reinterpret_cast<const uint32_t*>(&skia[i]);
// Pack the components here.
int alpha = SkGetPackedA32(pixel_in);
SkAlpha alpha = SkGetPackedA32(pixel_in);
if (alpha != 0 && alpha != 255) {
SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel_in);
rgba[i + 0] = SkColorGetR(unmultiplied);
......
......@@ -153,13 +153,13 @@ void Transform::RotateAbout(const Vector3dF& axis, double degrees) {
matrix_.setRotateDegreesAbout(SkFloatToMScalar(axis.x()),
SkFloatToMScalar(axis.y()),
SkFloatToMScalar(axis.z()),
degrees);
SkDoubleToMScalar(degrees));
} else {
SkMatrix44 rot(SkMatrix44::kUninitialized_Constructor);
rot.setRotateDegreesAbout(SkFloatToMScalar(axis.x()),
SkFloatToMScalar(axis.y()),
SkFloatToMScalar(axis.z()),
degrees);
SkDoubleToMScalar(degrees));
matrix_.preConcat(rot);
}
}
......@@ -179,9 +179,9 @@ void Transform::Translate3d(SkMScalar x, SkMScalar y, SkMScalar z) {
}
void Transform::SkewX(double angle_x) {
if (matrix_.isIdentity())
if (matrix_.isIdentity()) {
matrix_.set(0, 1, TanDegrees(angle_x));
else {
} else {
SkMatrix44 skew(SkMatrix44::kIdentity_Constructor);
skew.set(0, 1, TanDegrees(angle_x));
matrix_.preConcat(skew);
......@@ -189,9 +189,9 @@ void Transform::SkewX(double angle_x) {
}
void Transform::SkewY(double angle_y) {
if (matrix_.isIdentity())
if (matrix_.isIdentity()) {
matrix_.set(1, 0, TanDegrees(angle_y));
else {
} else {
SkMatrix44 skew(SkMatrix44::kIdentity_Constructor);
skew.set(1, 0, TanDegrees(angle_y));
matrix_.preConcat(skew);
......@@ -201,11 +201,11 @@ void Transform::SkewY(double angle_y) {
void Transform::ApplyPerspectiveDepth(SkMScalar depth) {
if (depth == 0)
return;
if (matrix_.isIdentity())
matrix_.set(3, 2, -1.0 / depth);
else {
if (matrix_.isIdentity()) {
matrix_.set(3, 2, -SK_MScalar1 / depth);
} else {
SkMatrix44 m(SkMatrix44::kIdentity_Constructor);
m.set(3, 2, -1.0 / depth);
m.set(3, 2, -SK_MScalar1 / depth);
matrix_.preConcat(m);
}
}
......@@ -516,7 +516,7 @@ void Transform::TransformPointInternal(const SkMatrix44& xform,
if (xform.isIdentity())
return;
SkMScalar p[4] = {SkFloatToMScalar(point->x()), SkFloatToMScalar(point->y()),
SkMScalar p[4] = {SkIntToMScalar(point->x()), SkIntToMScalar(point->y()),
0, 1};
xform.mapMScalars(p);
......
......@@ -102,7 +102,7 @@ bool Normalize(SkMatrix44& m) {
// Cannot normalize.
return false;
SkMScalar scale = 1.0 / m.get(3, 3);
SkMScalar scale = SK_MScalar1 / m.get(3, 3);
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
m.set(i, j, m.get(i, j) * scale);
......@@ -143,15 +143,15 @@ SkMatrix44 BuildRotationMatrix(const DecomposedTransform& decomp) {
SkMatrix44 matrix(SkMatrix44::kUninitialized_Constructor);
// Implicitly calls matrix.setIdentity()
matrix.set3x3(1.0 - 2.0 * (y * y + z * z),
2.0 * (x * y + z * w),
2.0 * (x * z - y * w),
2.0 * (x * y - z * w),
1.0 - 2.0 * (x * x + z * z),
2.0 * (y * z + x * w),
2.0 * (x * z + y * w),
2.0 * (y * z - x * w),
1.0 - 2.0 * (x * x + y * y));
matrix.set3x3(SkDoubleToMScalar(1.0 - 2.0 * (y * y + z * z)),
SkDoubleToMScalar(2.0 * (x * y + z * w)),
SkDoubleToMScalar(2.0 * (x * z - y * w)),
SkDoubleToMScalar(2.0 * (x * y - z * w)),
SkDoubleToMScalar(1.0 - 2.0 * (x * x + z * z)),
SkDoubleToMScalar(2.0 * (y * z + x * w)),
SkDoubleToMScalar(2.0 * (x * z + y * w)),
SkDoubleToMScalar(2.0 * (y * z - x * w)),
SkDoubleToMScalar(1.0 - 2.0 * (x * x + y * y)));
return matrix;
}
......@@ -417,14 +417,17 @@ bool DecomposeTransform(DecomposedTransform* decomp,
}
}
decomp->quaternion[0] =
0.5 * std::sqrt(std::max(1.0 + row[0][0] - row[1][1] - row[2][2], 0.0));
decomp->quaternion[1] =
0.5 * std::sqrt(std::max(1.0 - row[0][0] + row[1][1] - row[2][2], 0.0));
decomp->quaternion[2] =
0.5 * std::sqrt(std::max(1.0 - row[0][0] - row[1][1] + row[2][2], 0.0));
decomp->quaternion[3] =
0.5 * std::sqrt(std::max(1.0 + row[0][0] + row[1][1] + row[2][2], 0.0));
double row00 = SkMScalarToDouble(row[0][0]);
double row11 = SkMScalarToDouble(row[1][1]);
double row22 = SkMScalarToDouble(row[2][2]);
decomp->quaternion[0] = SkDoubleToMScalar(
0.5 * std::sqrt(std::max(1.0 + row00 - row11 - row22, 0.0)));
decomp->quaternion[1] = SkDoubleToMScalar(
0.5 * std::sqrt(std::max(1.0 - row00 + row11 - row22, 0.0)));
decomp->quaternion[2] = SkDoubleToMScalar(
0.5 * std::sqrt(std::max(1.0 - row00 - row11 + row22, 0.0)));
decomp->quaternion[3] = SkDoubleToMScalar(
0.5 * std::sqrt(std::max(1.0 + row00 + row11 + row22, 0.0)));
if (row[2][1] > row[1][2])
decomp->quaternion[0] = -decomp->quaternion[0];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment