001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.ade.galleries.client.preview.util;
029
030import org.opencms.ade.galleries.shared.CmsPoint;
031
032/**
033 * A coordinate system transform for translating between coordinates relative to a rectangle and the coordinates relative to a second
034 * rectangle with the first rectangle fit into the second one, either by just centering if possible or by centering and scaling it.
035 */
036public class CmsBoxFit implements I_CmsTransform {
037
038    /**
039     * Scale mode.<p>
040     */
041    public enum Mode {
042        /** Always scale. */
043        scaleAlways,
044
045        /** Only scale if the rectangle in the target coordinate system does not fit in the source coordinate system. */
046        scaleOnlyIfNecessary;
047    }
048
049    /** Name for debugging. */
050    private String m_name;
051
052    /** The horizontal offset. */
053    private double m_offsetLeft;
054
055    /** The vertical offset. */
056    private double m_offsetTop;
057
058    /** The scaling factor. */
059    private double m_scale;
060
061    /**
062     * Creates a new instance.<p>
063     *
064     * @param mode the scale mode
065     * @param width the width of the first rectangle
066     * @param height the height of the first rectangle
067     * @param naturalWidth the width of the second rectangle
068     * @param naturalHeight the height of the second rectangle
069     */
070    public CmsBoxFit(Mode mode, double width, double height, double naturalWidth, double naturalHeight) {
071
072        m_name = "[CmsBoxFit " + mode + " " + width + " " + height + " " + naturalWidth + " " + naturalHeight + "]";
073        if ((mode == Mode.scaleOnlyIfNecessary) && (naturalWidth <= width) && (naturalHeight <= height)) {
074            // just fit the rectangle in the middle, no scaling
075            m_offsetLeft = (width - naturalWidth) / 2.0;
076            m_offsetTop = (height - naturalHeight) / 2.0;
077            m_scale = 1;
078        } else {
079            // Use minimum so that the second rectangle, when scaled, completely fits in the first one
080            m_scale = Math.min(width / naturalWidth, height / naturalHeight);
081            m_offsetLeft = (width - (naturalWidth * m_scale)) / 2.0;
082            m_offsetTop = (height - (naturalHeight * m_scale)) / 2.0;
083        }
084
085    }
086
087    /**
088     * @see java.lang.Object#toString()
089     */
090    @Override
091    public String toString() {
092
093        return m_name;
094    }
095
096    /**
097     * @see org.opencms.ade.galleries.client.preview.util.I_CmsTransform#transformBack(org.opencms.ade.galleries.shared.CmsPoint)
098     */
099    public CmsPoint transformBack(CmsPoint point) {
100
101        double rx = (m_scale * point.getX()) + m_offsetLeft;
102        double ry = (m_scale * point.getY()) + m_offsetTop;
103        return new CmsPoint(rx, ry);
104    }
105
106    /**
107     * @see org.opencms.ade.galleries.client.preview.util.I_CmsTransform#transformForward(org.opencms.ade.galleries.shared.CmsPoint)
108     */
109    public CmsPoint transformForward(CmsPoint point) {
110
111        double rx = (point.getX() - m_offsetLeft) / m_scale;
112        double ry = (point.getY() - m_offsetTop) / m_scale;
113        return new CmsPoint(rx, ry);
114
115    }
116
117}