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; 029 030import org.opencms.util.CmsStringUtil; 031 032/** 033 * Scale parameter data bean.<p> 034 * 035 * @since 8.0.0 036 */ 037public class CmsCroppingParamBean { 038 039 /** Format parameter name. */ 040 private static final String SCALE_FORMAT_NAME_PARAM = "format"; 041 042 /** The scale parameter colon. */ 043 private static final String SCALE_PARAM_COLON = ":"; 044 045 /** Scale parameter name. */ 046 private static final String SCALE_PARAM_CROP_HEIGHT = "ch"; 047 048 /** Scale parameter name. */ 049 private static final String SCALE_PARAM_CROP_WIDTH = "cw"; 050 051 /** Scale parameter name. */ 052 private static final String SCALE_PARAM_CROP_X = "cx"; 053 054 /** Scale parameter name. */ 055 private static final String SCALE_PARAM_CROP_Y = "cy"; 056 057 /** The scale parameter delimiter. */ 058 private static final String SCALE_PARAM_DELIMITER = ","; 059 060 /** The scale parameter equal. */ 061 private static final String SCALE_PARAM_EQ = "="; 062 063 /** Scale parameter name. */ 064 private static final String SCALE_PARAM_NAME = "__scale"; 065 066 /** Scale parameter name. */ 067 private static final String SCALE_PARAM_TARGETHEIGHT = "h"; 068 069 /** Scale parameter name. */ 070 private static final String SCALE_PARAM_TARGETWIDTH = "w"; 071 072 /** The cropping height parameter. */ 073 private int m_cropHeight = I_CmsFormatRestriction.DIMENSION_NOT_SET; 074 075 /** The cropping width parameter. */ 076 private int m_cropWidth = I_CmsFormatRestriction.DIMENSION_NOT_SET; 077 078 /** The cropping X parameter. */ 079 private int m_cropX = I_CmsFormatRestriction.DIMENSION_NOT_SET; 080 081 /** The cropping Y parameter. */ 082 private int m_cropY = I_CmsFormatRestriction.DIMENSION_NOT_SET; 083 084 /** The used format name. */ 085 private String m_formatName; 086 087 /** The original image height. */ 088 private int m_orgHeight = I_CmsFormatRestriction.DIMENSION_NOT_SET; 089 090 /** The original image width. */ 091 private int m_orgWidth = I_CmsFormatRestriction.DIMENSION_NOT_SET; 092 093 /** The target height. */ 094 private int m_targetHeight = I_CmsFormatRestriction.DIMENSION_NOT_SET; 095 096 /** The target width. */ 097 private int m_targetWidth = I_CmsFormatRestriction.DIMENSION_NOT_SET; 098 099 /** 100 * Constructor.<p> 101 */ 102 public CmsCroppingParamBean() { 103 104 // nothing to do here 105 } 106 107 /** 108 * Copy constructor.<p> 109 * 110 * @param copy the copy values to use 111 */ 112 public CmsCroppingParamBean(CmsCroppingParamBean copy) { 113 114 this(copy.getOrgHeight(), copy.getOrgWidth()); 115 m_cropHeight = copy.getCropHeight(); 116 m_cropWidth = copy.getCropWidth(); 117 m_cropX = copy.getCropX(); 118 m_cropY = copy.getCropY(); 119 m_targetHeight = copy.getTargetHeight(); 120 m_targetWidth = copy.getTargetWidth(); 121 } 122 123 /** 124 * Constructor.<p> 125 * 126 * @param orgHeight the original image height 127 * @param orgWidth the original image width 128 */ 129 public CmsCroppingParamBean(int orgHeight, int orgWidth) { 130 131 m_orgHeight = orgHeight; 132 m_orgWidth = orgWidth; 133 } 134 135 /** 136 * Parses an image scale parameter and returns the parsed data.<p> 137 * 138 * @param selectedPath the image path including the scale parameter 139 * 140 * @return the cropping data 141 */ 142 public static CmsCroppingParamBean parseImagePath(String selectedPath) { 143 144 CmsCroppingParamBean result = null; 145 int pos = selectedPath.indexOf(SCALE_PARAM_NAME + SCALE_PARAM_EQ); 146 if (pos > -1) { 147 // removing string part before the scaling parameter 148 String param = selectedPath.substring(pos + SCALE_PARAM_NAME.length() + SCALE_PARAM_EQ.length()); 149 150 // removing string part after the scaling parameter 151 pos = param.indexOf("&"); 152 if (pos > -1) { 153 param = param.substring(0, pos); 154 } 155 result = parseScaleParam(param); 156 } else { 157 result = new CmsCroppingParamBean(); 158 } 159 // look up format name if available 160 pos = selectedPath.indexOf(SCALE_FORMAT_NAME_PARAM + SCALE_PARAM_EQ); 161 if (pos > -1) { 162 String param = selectedPath.substring(pos + SCALE_FORMAT_NAME_PARAM.length() + SCALE_PARAM_EQ.length()); 163 164 // removing string part after the scaling parameter 165 pos = param.indexOf("&"); 166 if (pos > -1) { 167 param = param.substring(0, pos); 168 } 169 result.setFormatName(param); 170 } 171 return result; 172 } 173 174 /** 175 * Parses an image scale parameter and returns the parsed data.<p> 176 * 177 * @param param the image path including the scale parameter 178 * 179 * @return the cropping data 180 */ 181 public static CmsCroppingParamBean parseScaleParam(String param) { 182 183 CmsCroppingParamBean result = new CmsCroppingParamBean(); 184 if (CmsStringUtil.isEmptyOrWhitespaceOnly(param)) { 185 return result; 186 } 187 String[] parameters = param.split(SCALE_PARAM_DELIMITER); 188 for (int i = 0; i < parameters.length; i++) { 189 String scaleParam = parameters[i].trim(); 190 if (scaleParam.startsWith(SCALE_PARAM_TARGETHEIGHT + SCALE_PARAM_COLON)) { 191 result.setTargetHeight(parseValue(SCALE_PARAM_TARGETHEIGHT, scaleParam)); 192 continue; 193 } 194 if (scaleParam.startsWith(SCALE_PARAM_TARGETWIDTH + SCALE_PARAM_COLON)) { 195 result.setTargetWidth(parseValue(SCALE_PARAM_TARGETWIDTH, scaleParam)); 196 continue; 197 } 198 if (scaleParam.startsWith(SCALE_PARAM_CROP_X + SCALE_PARAM_COLON)) { 199 result.setCropX(parseValue(SCALE_PARAM_CROP_X, scaleParam)); 200 continue; 201 } 202 if (scaleParam.startsWith(SCALE_PARAM_CROP_Y + SCALE_PARAM_COLON)) { 203 result.setCropY(parseValue(SCALE_PARAM_CROP_Y, scaleParam)); 204 continue; 205 } 206 if (scaleParam.startsWith(SCALE_PARAM_CROP_HEIGHT + SCALE_PARAM_COLON)) { 207 result.setCropHeight(parseValue(SCALE_PARAM_CROP_HEIGHT, scaleParam)); 208 continue; 209 } 210 if (scaleParam.startsWith(SCALE_PARAM_CROP_WIDTH + SCALE_PARAM_COLON)) { 211 result.setCropWidth(parseValue(SCALE_PARAM_CROP_WIDTH, scaleParam)); 212 continue; 213 } 214 } 215 return result; 216 } 217 218 /** 219 * Parses a single scale value. Returning <code>-1</code> --> 220 * {@link I_CmsFormatRestriction#DIMENSION_NOT_SET} invalid parameters.<p> 221 * 222 * @param paramName the parameter name 223 * @param param the parameter 224 * 225 * @return the value 226 */ 227 private static native int parseValue(String paramName, String param)/*-{ 228 param = param.substr(paramName.length + 1); 229 var result = parseInt(param); 230 if (isNaN(result)) { 231 return I_CmsFormatRestriction.DIMENSION_NOT_SET; 232 } 233 return result; 234 }-*/; 235 236 /** 237 * Returns the cropping height parameter.<p> 238 * 239 * @return the cropping height parameter 240 */ 241 public int getCropHeight() { 242 243 return m_cropHeight; 244 } 245 246 /** 247 * Returns the cropping width parameter.<p> 248 * 249 * @return the cropping width parameter 250 */ 251 public int getCropWidth() { 252 253 return m_cropWidth; 254 } 255 256 /** 257 * Returns the cropping X parameter.<p> 258 * 259 * @return the cropping X parameter 260 */ 261 public int getCropX() { 262 263 return m_cropX; 264 } 265 266 /** 267 * Returns the cropping Y parameter.<p> 268 * 269 * @return the cropping Y parameter 270 */ 271 public int getCropY() { 272 273 return m_cropY; 274 } 275 276 /** 277 * Returns the used format name.<p> 278 * 279 * @return the used format name 280 */ 281 public String getFormatName() { 282 283 return m_formatName; 284 } 285 286 /** 287 * Returns the original image height.<p> 288 * 289 * @return the original image height 290 */ 291 public int getOrgHeight() { 292 293 return m_orgHeight; 294 } 295 296 /** 297 * Returns the original image width.<p> 298 * 299 * @return the original image width 300 */ 301 public int getOrgWidth() { 302 303 return m_orgWidth; 304 } 305 306 /** 307 * Returns the resulting image ratio.<p> 308 * 309 * @return the image ratio 310 */ 311 public double getRatio() { 312 313 double ratio = 1; 314 if ((getTargetWidth() == -1) || (getTargetHeight() == -1)) { 315 ratio = (double)getOrgWidth() / getOrgHeight(); 316 } else { 317 ratio = (double)getTargetWidth() / getTargetHeight(); 318 } 319 return ratio; 320 } 321 322 /** 323 * Returns a cropping bean with a restricted maximum target size.<p> 324 * 325 * @param maxHeight the max height 326 * @param maxWidth the max width 327 * 328 * @return the cropping bean 329 */ 330 public CmsCroppingParamBean getRestrictedSizeParam(int maxHeight, int maxWidth) { 331 332 CmsCroppingParamBean result = new CmsCroppingParamBean(this); 333 if ((getTargetHeight() <= maxHeight) && (getTargetWidth() <= maxWidth)) { 334 if ((getTargetHeight() == I_CmsFormatRestriction.DIMENSION_NOT_SET) && (getOrgHeight() > maxHeight)) { 335 result.setTargetHeight(maxHeight); 336 } 337 if ((getTargetWidth() == I_CmsFormatRestriction.DIMENSION_NOT_SET) && (getOrgWidth() > maxWidth)) { 338 result.setTargetWidth(maxWidth); 339 } 340 return result; 341 } 342 343 if (((1.00 * getTargetHeight()) / getTargetWidth()) > ((1.00 * maxHeight) / maxWidth)) { 344 result.setTargetHeight(maxHeight); 345 double width = (1.00 * getTargetWidth() * maxHeight) / getTargetHeight(); 346 result.setTargetWidth((int)Math.floor(width)); 347 return result; 348 } 349 double height = (1.00 * getTargetHeight() * maxWidth) / getTargetWidth(); 350 result.setTargetHeight((int)Math.floor(height)); 351 result.setTargetWidth(maxWidth); 352 return result; 353 } 354 355 /** 356 * Returns the scale parameter to this bean for a restricted maximum target size.<p> 357 * 358 * TODO: This does not work correctly if there isn't any cropping/scaling defined. 359 * 360 * @param maxHeight the max height 361 * @param maxWidth the max width 362 * 363 * @return the scale parameter 364 */ 365 public String getRestrictedSizeScaleParam(int maxHeight, int maxWidth) { 366 367 String result = toString(); 368 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(result)) { 369 370 return getRestrictedSizeParam(maxHeight, maxWidth).toString(); 371 } 372 if ((getOrgWidth() < maxWidth) && (getOrgHeight() < maxHeight)) { 373 return ""; 374 } 375 CmsCroppingParamBean restricted = new CmsCroppingParamBean(); 376 restricted.setTargetHeight(maxHeight); 377 restricted.setTargetWidth(maxWidth); 378 return restricted.toString(); 379 } 380 381 /** 382 * Returns the resulting height of the cropped image.<p> 383 * 384 * @return the height 385 */ 386 public int getResultingHeight() { 387 388 int height = getResultingTargetHeight(); 389 if (height == -1) { 390 if (isCropped()) { 391 height = m_cropHeight; 392 } else { 393 height = m_orgHeight; 394 } 395 } 396 return height; 397 } 398 399 /** 400 * Returns the resulting width of the cropped image.<p> 401 * 402 * @return the width 403 */ 404 public int getResultingWidth() { 405 406 int width = getResultingTargetWidth(); 407 if (width == -1) { 408 if (isCropped()) { 409 width = m_cropWidth; 410 } else { 411 width = m_orgWidth; 412 } 413 } 414 return width; 415 } 416 417 /** 418 * Returns the scale parameter.<p> 419 * 420 * @return the scale parameter 421 */ 422 public String getScaleParam() { 423 424 if (!isScaled() && !isCropped()) { 425 // the image is not cropped nor scaled, return an empty parameter 426 return ""; 427 } 428 StringBuffer result = new StringBuffer(); 429 if ((m_targetHeight > -1) || (m_targetWidth > -1)) { 430 result.append(SCALE_PARAM_TARGETHEIGHT).append(SCALE_PARAM_COLON).append(getResultingTargetHeight()).append( 431 SCALE_PARAM_DELIMITER); 432 result.append(SCALE_PARAM_TARGETWIDTH).append(SCALE_PARAM_COLON).append(getResultingTargetWidth()).append( 433 SCALE_PARAM_DELIMITER); 434 } 435 if (m_cropX > -1) { 436 result.append(SCALE_PARAM_CROP_X).append(SCALE_PARAM_COLON).append(m_cropX).append(SCALE_PARAM_DELIMITER); 437 } 438 if (m_cropY > -1) { 439 result.append(SCALE_PARAM_CROP_Y).append(SCALE_PARAM_COLON).append(m_cropY).append(SCALE_PARAM_DELIMITER); 440 } 441 if (m_cropHeight > -1) { 442 result.append(SCALE_PARAM_CROP_HEIGHT).append(SCALE_PARAM_COLON).append(m_cropHeight).append( 443 SCALE_PARAM_DELIMITER); 444 } 445 if (m_cropWidth > -1) { 446 result.append(SCALE_PARAM_CROP_WIDTH).append(SCALE_PARAM_COLON).append(m_cropWidth).append( 447 SCALE_PARAM_DELIMITER); 448 } 449 if (result.length() > 0) { 450 result.deleteCharAt(result.length() - 1); 451 } 452 return result.toString(); 453 } 454 455 /** 456 * Returns the target height.<p> 457 * 458 * @return the target height 459 */ 460 public int getTargetHeight() { 461 462 return m_targetHeight; 463 } 464 465 /** 466 * Returns the target width.<p> 467 * 468 * @return the target width 469 */ 470 public int getTargetWidth() { 471 472 return m_targetWidth; 473 } 474 475 /** 476 * Returns if contained parameters indicate a cropped image.<p> 477 * 478 * @return <code>true</code> if contained parameters indicate a cropped image 479 */ 480 public boolean isCropped() { 481 482 return m_cropX > I_CmsFormatRestriction.DIMENSION_NOT_SET; 483 } 484 485 /** 486 * Returns if the given cropping parameters would scale the image.<p> 487 * 488 * @return <code>true</code> if the image is scaled 489 */ 490 public boolean isScaled() { 491 492 return !(((m_targetHeight == m_orgHeight) || (m_targetHeight == -1)) 493 && ((m_targetWidth == m_orgWidth) || (m_targetWidth == -1))); 494 } 495 496 /** 497 * Resets the cropping parameters to no cropping.<p> 498 */ 499 public void reset() { 500 501 m_cropHeight = I_CmsFormatRestriction.DIMENSION_NOT_SET; 502 m_cropWidth = I_CmsFormatRestriction.DIMENSION_NOT_SET; 503 m_cropX = I_CmsFormatRestriction.DIMENSION_NOT_SET; 504 m_cropY = I_CmsFormatRestriction.DIMENSION_NOT_SET; 505 m_targetHeight = I_CmsFormatRestriction.DIMENSION_NOT_SET; 506 m_targetWidth = I_CmsFormatRestriction.DIMENSION_NOT_SET; 507 } 508 509 /** 510 * Sets the cropping height parameter.<p> 511 * 512 * @param cropHeight the cropping height parameter to set 513 */ 514 public void setCropHeight(int cropHeight) { 515 516 m_cropHeight = cropHeight; 517 } 518 519 /** 520 * Sets the cropping width parameter.<p> 521 * 522 * @param cropWidth the cropping width parameter to set 523 */ 524 public void setCropWidth(int cropWidth) { 525 526 m_cropWidth = cropWidth; 527 } 528 529 /** 530 * Sets the cropping X parameter.<p> 531 * 532 * @param cropX the cropping X parameter to set 533 */ 534 public void setCropX(int cropX) { 535 536 m_cropX = cropX; 537 } 538 539 /** 540 * Sets the cropping Y parameter.<p> 541 * 542 * @param cropY the cropping Y parameter to set 543 */ 544 public void setCropY(int cropY) { 545 546 m_cropY = cropY; 547 } 548 549 /** 550 * Sets the used format name.<p> 551 * 552 * @param formatName the used format name to set 553 */ 554 public void setFormatName(String formatName) { 555 556 m_formatName = formatName; 557 } 558 559 /** 560 * Sets the original image height.<p> 561 * 562 * @param orgHeight the original image height to set 563 */ 564 public void setOrgHeight(int orgHeight) { 565 566 m_orgHeight = orgHeight; 567 } 568 569 /** 570 * Sets the original image width.<p> 571 * 572 * @param orgWidth the original image width to set 573 */ 574 public void setOrgWidth(int orgWidth) { 575 576 m_orgWidth = orgWidth; 577 } 578 579 /** 580 * Sets the target height.<p> 581 * 582 * @param targetHeight the target height to set 583 */ 584 public void setTargetHeight(int targetHeight) { 585 586 m_targetHeight = targetHeight; 587 } 588 589 /** 590 * Sets the target width.<p> 591 * 592 * @param targetWidth the target width to set 593 */ 594 public void setTargetWidth(int targetWidth) { 595 596 m_targetWidth = targetWidth; 597 } 598 599 /** 600 * @see java.lang.Object#toString() 601 */ 602 @Override 603 public String toString() { 604 605 String result = getScaleParam(); 606 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(result)) { 607 result = SCALE_PARAM_NAME + SCALE_PARAM_EQ + result; 608 } 609 return result; 610 } 611 612 /** 613 * Returns the resulting target height if set, otherwise '-1'.<p> 614 * 615 * @return the height 616 */ 617 private int getResultingTargetHeight() { 618 619 int height = -1; 620 if ((m_targetHeight > -1) || (m_targetWidth > -1)) { 621 if (m_targetHeight > -1) { 622 height = m_targetHeight; 623 } else { 624 height = (int)Math.floor(((1.00 * m_orgHeight) / m_orgWidth) * m_targetWidth); 625 } 626 } 627 return height; 628 } 629 630 /** 631 * Returns the resulting target width if set, otherwise '-1'.<p> 632 * 633 * @return the width 634 */ 635 private int getResultingTargetWidth() { 636 637 int width = -1; 638 if ((m_targetHeight > -1) || (m_targetWidth > -1)) { 639 if (m_targetWidth > -1) { 640 width = m_targetWidth; 641 } else { 642 width = (int)Math.floor(((1.00 * m_orgWidth) / m_orgHeight) * m_targetHeight); 643 } 644 } 645 return width; 646 } 647 648}