18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2004, 2006, 2007 Apple Inc.  All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2005 Nokia.  All rights reserved.
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FloatPoint.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "AffineTransform.h"
31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "TransformationMatrix.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FloatConversion.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "IntPoint.h"
342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include <limits>
355ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include <math.h>
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectFloatPoint::FloatPoint(const IntPoint& p) : m_x(p.x()), m_y(p.y())
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
435ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid FloatPoint::normalize()
445ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    float tempLength = length();
465ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (tempLength) {
485ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        m_x /= tempLength;
495ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        m_y /= tempLength;
505ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    }
515ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
525ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
535ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenfloat FloatPoint::length() const
545ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
555ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return sqrtf(lengthSquared());
565ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
575ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
588a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve BlockFloatPoint FloatPoint::matrixTransform(const AffineTransform& transform) const
598a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{
608a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    double newX, newY;
618a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    transform.map(static_cast<double>(m_x), static_cast<double>(m_y), newX, newY);
628a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    return narrowPrecision(newX, newY);
638a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
648a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
65635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectFloatPoint FloatPoint::matrixTransform(const TransformationMatrix& transform) const
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double newX, newY;
688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    transform.map(static_cast<double>(m_x), static_cast<double>(m_y), newX, newY);
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return narrowPrecision(newX, newY);
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectFloatPoint FloatPoint::narrowPrecision(double x, double y)
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return FloatPoint(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y));
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochfloat findSlope(const FloatPoint& p1, const FloatPoint& p2, float& c)
782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (p2.x() == p1.x())
802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return std::numeric_limits<float>::infinity();
812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // y = mx + c
832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    float slope = (p2.y() - p1.y()) / (p2.x() - p1.x());
842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    c = p1.y() - slope * p1.x();
852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return slope;
862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool findIntersection(const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& d1, const FloatPoint& d2, FloatPoint& intersection)
892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    float pOffset = 0;
912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    float pSlope = findSlope(p1, p2, pOffset);
922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    float dOffset = 0;
942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    float dSlope = findSlope(d1, d2, dOffset);
952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (dSlope == pSlope)
972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return false;
982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (pSlope == std::numeric_limits<float>::infinity()) {
1002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        intersection.setX(p1.x());
1012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        intersection.setY(dSlope * intersection.x() + dOffset);
1022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return true;
1032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
1042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (dSlope == std::numeric_limits<float>::infinity()) {
1052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        intersection.setX(d1.x());
1062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        intersection.setY(pSlope * intersection.x() + pOffset);
1072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return true;
1082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
1092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Find x at intersection, where ys overlap; x = (c' - c) / (m - m')
1112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    intersection.setX((dOffset - pOffset) / (pSlope - dSlope));
1122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    intersection.setY(pSlope * intersection.x() + pOffset);
1132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return true;
1142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
1152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
117