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}