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 * Converts this bean to a scaling parameter string. 238 * 239 * @param highRes true if we want the high-resolution version 240 * @return the scaling parameter string 241 */ 242 public String convertToScalingParam(boolean highRes) { 243 244 String result = getScaleParam(highRes); 245 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(result)) { 246 result = SCALE_PARAM_NAME + SCALE_PARAM_EQ + result; 247 } 248 return result; 249 } 250 251 /** 252 * Returns the cropping height parameter.<p> 253 * 254 * @return the cropping height parameter 255 */ 256 public int getCropHeight() { 257 258 return m_cropHeight; 259 } 260 261 /** 262 * Returns the cropping width parameter.<p> 263 * 264 * @return the cropping width parameter 265 */ 266 public int getCropWidth() { 267 268 return m_cropWidth; 269 } 270 271 /** 272 * Returns the cropping X parameter.<p> 273 * 274 * @return the cropping X parameter 275 */ 276 public int getCropX() { 277 278 return m_cropX; 279 } 280 281 /** 282 * Returns the cropping Y parameter.<p> 283 * 284 * @return the cropping Y parameter 285 */ 286 public int getCropY() { 287 288 return m_cropY; 289 } 290 291 /** 292 * Returns the used format name.<p> 293 * 294 * @return the used format name 295 */ 296 public String getFormatName() { 297 298 return m_formatName; 299 } 300 301 /** 302 * Returns the original image height.<p> 303 * 304 * @return the original image height 305 */ 306 public int getOrgHeight() { 307 308 return m_orgHeight; 309 } 310 311 /** 312 * Returns the original image width.<p> 313 * 314 * @return the original image width 315 */ 316 public int getOrgWidth() { 317 318 return m_orgWidth; 319 } 320 321 /** 322 * Returns the resulting image ratio.<p> 323 * 324 * @return the image ratio 325 */ 326 public double getRatio() { 327 328 double ratio = 1; 329 if ((getTargetWidth() == -1) || (getTargetHeight() == -1)) { 330 ratio = (double)getOrgWidth() / getOrgHeight(); 331 } else { 332 ratio = (double)getTargetWidth() / getTargetHeight(); 333 } 334 return ratio; 335 } 336 337 /** 338 * Returns a cropping bean with a restricted maximum target size.<p> 339 * 340 * @param maxHeight the max height 341 * @param maxWidth the max width 342 * 343 * @return the cropping bean 344 */ 345 public CmsCroppingParamBean getRestrictedSizeParam(int maxHeight, int maxWidth) { 346 347 CmsCroppingParamBean result = new CmsCroppingParamBean(this); 348 if ((getTargetHeight() <= maxHeight) && (getTargetWidth() <= maxWidth)) { 349 if ((getTargetHeight() == I_CmsFormatRestriction.DIMENSION_NOT_SET) && (getOrgHeight() > maxHeight)) { 350 result.setTargetHeight(maxHeight); 351 } 352 if ((getTargetWidth() == I_CmsFormatRestriction.DIMENSION_NOT_SET) && (getOrgWidth() > maxWidth)) { 353 result.setTargetWidth(maxWidth); 354 } 355 return result; 356 } 357 358 if (((1.00 * getTargetHeight()) / getTargetWidth()) > ((1.00 * maxHeight) / maxWidth)) { 359 result.setTargetHeight(maxHeight); 360 double width = (1.00 * getTargetWidth() * maxHeight) / getTargetHeight(); 361 result.setTargetWidth((int)Math.floor(width)); 362 return result; 363 } 364 double height = (1.00 * getTargetHeight() * maxWidth) / getTargetWidth(); 365 result.setTargetHeight((int)Math.floor(height)); 366 result.setTargetWidth(maxWidth); 367 return result; 368 } 369 370 /** 371 * Returns the scale parameter to this bean for a restricted maximum target size.<p> 372 * 373 * TODO: This does not work correctly if there isn't any cropping/scaling defined. 374 * 375 * @param maxHeight the max height 376 * @param maxWidth the max width 377 * 378 * @return the scale parameter 379 */ 380 public String getRestrictedSizeScaleParam(int maxHeight, int maxWidth) { 381 382 String result = toString(); 383 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(result)) { 384 385 return getRestrictedSizeParam(maxHeight, maxWidth).toString(); 386 } 387 if ((getOrgWidth() < maxWidth) && (getOrgHeight() < maxHeight)) { 388 return ""; 389 } 390 CmsCroppingParamBean restricted = new CmsCroppingParamBean(); 391 restricted.setTargetHeight(maxHeight); 392 restricted.setTargetWidth(maxWidth); 393 return restricted.toString(); 394 } 395 396 /** 397 * Returns the resulting height of the cropped image.<p> 398 * 399 * @return the height 400 */ 401 public int getResultingHeight() { 402 403 int height = getResultingTargetHeight(); 404 if (height == -1) { 405 if (isCropped()) { 406 height = m_cropHeight; 407 } else { 408 height = m_orgHeight; 409 } 410 } 411 return height; 412 } 413 414 /** 415 * Returns the resulting width of the cropped image.<p> 416 * 417 * @return the width 418 */ 419 public int getResultingWidth() { 420 421 int width = getResultingTargetWidth(); 422 if (width == -1) { 423 if (isCropped()) { 424 width = m_cropWidth; 425 } else { 426 width = m_orgWidth; 427 } 428 } 429 return width; 430 } 431 432 /** 433 * Returns the scale parameter.<p> 434 * 435 * @param highres true if we want the high resolution version 436 * 437 * @return the scale parameter 438 */ 439 public String getScaleParam(boolean highres) { 440 441 int m = highres ? 2 : 1; 442 443 if (!isScaled() && !isCropped()) { 444 // the image is not cropped nor scaled, return an empty parameter 445 return ""; 446 } 447 StringBuffer result = new StringBuffer(); 448 if ((m_targetHeight > -1) || (m_targetWidth > -1)) { 449 result.append(SCALE_PARAM_TARGETHEIGHT).append(SCALE_PARAM_COLON).append( 450 m * getResultingTargetHeight()).append(SCALE_PARAM_DELIMITER); 451 result.append(SCALE_PARAM_TARGETWIDTH).append(SCALE_PARAM_COLON).append( 452 m * getResultingTargetWidth()).append(SCALE_PARAM_DELIMITER); 453 } 454 if (m_cropX > -1) { 455 result.append(SCALE_PARAM_CROP_X).append(SCALE_PARAM_COLON).append(m_cropX).append(SCALE_PARAM_DELIMITER); 456 } 457 if (m_cropY > -1) { 458 result.append(SCALE_PARAM_CROP_Y).append(SCALE_PARAM_COLON).append(m_cropY).append(SCALE_PARAM_DELIMITER); 459 } 460 if (m_cropHeight > -1) { 461 result.append(SCALE_PARAM_CROP_HEIGHT).append(SCALE_PARAM_COLON).append(m_cropHeight).append( 462 SCALE_PARAM_DELIMITER); 463 } 464 if (m_cropWidth > -1) { 465 result.append(SCALE_PARAM_CROP_WIDTH).append(SCALE_PARAM_COLON).append(m_cropWidth).append( 466 SCALE_PARAM_DELIMITER); 467 } 468 if (result.length() > 0) { 469 result.deleteCharAt(result.length() - 1); 470 } 471 return result.toString(); 472 } 473 474 /** 475 * Returns the target height.<p> 476 * 477 * @return the target height 478 */ 479 public int getTargetHeight() { 480 481 return m_targetHeight; 482 } 483 484 /** 485 * Returns the target width.<p> 486 * 487 * @return the target width 488 */ 489 public int getTargetWidth() { 490 491 return m_targetWidth; 492 } 493 494 /** 495 * Returns if contained parameters indicate a cropped image.<p> 496 * 497 * @return <code>true</code> if contained parameters indicate a cropped image 498 */ 499 public boolean isCropped() { 500 501 return m_cropX > I_CmsFormatRestriction.DIMENSION_NOT_SET; 502 } 503 504 /** 505 * Returns if the given cropping parameters would scale the image.<p> 506 * 507 * @return <code>true</code> if the image is scaled 508 */ 509 public boolean isScaled() { 510 511 return !(((m_targetHeight == m_orgHeight) || (m_targetHeight == -1)) 512 && ((m_targetWidth == m_orgWidth) || (m_targetWidth == -1))); 513 } 514 515 /** 516 * Resets the cropping parameters to no cropping.<p> 517 */ 518 public void reset() { 519 520 m_cropHeight = I_CmsFormatRestriction.DIMENSION_NOT_SET; 521 m_cropWidth = I_CmsFormatRestriction.DIMENSION_NOT_SET; 522 m_cropX = I_CmsFormatRestriction.DIMENSION_NOT_SET; 523 m_cropY = I_CmsFormatRestriction.DIMENSION_NOT_SET; 524 m_targetHeight = I_CmsFormatRestriction.DIMENSION_NOT_SET; 525 m_targetWidth = I_CmsFormatRestriction.DIMENSION_NOT_SET; 526 } 527 528 /** 529 * Sets the cropping height parameter.<p> 530 * 531 * @param cropHeight the cropping height parameter to set 532 */ 533 public void setCropHeight(int cropHeight) { 534 535 m_cropHeight = cropHeight; 536 } 537 538 /** 539 * Sets the cropping width parameter.<p> 540 * 541 * @param cropWidth the cropping width parameter to set 542 */ 543 public void setCropWidth(int cropWidth) { 544 545 m_cropWidth = cropWidth; 546 } 547 548 /** 549 * Sets the cropping X parameter.<p> 550 * 551 * @param cropX the cropping X parameter to set 552 */ 553 public void setCropX(int cropX) { 554 555 m_cropX = cropX; 556 } 557 558 /** 559 * Sets the cropping Y parameter.<p> 560 * 561 * @param cropY the cropping Y parameter to set 562 */ 563 public void setCropY(int cropY) { 564 565 m_cropY = cropY; 566 } 567 568 /** 569 * Sets the used format name.<p> 570 * 571 * @param formatName the used format name to set 572 */ 573 public void setFormatName(String formatName) { 574 575 m_formatName = formatName; 576 } 577 578 /** 579 * Sets the original image height.<p> 580 * 581 * @param orgHeight the original image height to set 582 */ 583 public void setOrgHeight(int orgHeight) { 584 585 m_orgHeight = orgHeight; 586 } 587 588 /** 589 * Sets the original image width.<p> 590 * 591 * @param orgWidth the original image width to set 592 */ 593 public void setOrgWidth(int orgWidth) { 594 595 m_orgWidth = orgWidth; 596 } 597 598 /** 599 * Sets the target height.<p> 600 * 601 * @param targetHeight the target height to set 602 */ 603 public void setTargetHeight(int targetHeight) { 604 605 m_targetHeight = targetHeight; 606 } 607 608 /** 609 * Sets the target width.<p> 610 * 611 * @param targetWidth the target width to set 612 */ 613 public void setTargetWidth(int targetWidth) { 614 615 m_targetWidth = targetWidth; 616 } 617 618 /** 619 * @see java.lang.Object#toString() 620 */ 621 @Override 622 public String toString() { 623 624 boolean highRes = false; 625 return convertToScalingParam(highRes); 626 } 627 628 /** 629 * Returns the resulting target height if set, otherwise '-1'.<p> 630 * 631 * @return the height 632 */ 633 private int getResultingTargetHeight() { 634 635 int height = -1; 636 if ((m_targetHeight > -1) || (m_targetWidth > -1)) { 637 if (m_targetHeight > -1) { 638 height = m_targetHeight; 639 } else { 640 height = (int)Math.floor(((1.00 * m_orgHeight) / m_orgWidth) * m_targetWidth); 641 } 642 } 643 return height; 644 } 645 646 /** 647 * Returns the resulting target width if set, otherwise '-1'.<p> 648 * 649 * @return the width 650 */ 651 private int getResultingTargetWidth() { 652 653 int width = -1; 654 if ((m_targetHeight > -1) || (m_targetWidth > -1)) { 655 if (m_targetWidth > -1) { 656 width = m_targetWidth; 657 } else { 658 width = (int)Math.floor(((1.00 * m_orgWidth) / m_orgHeight) * m_targetHeight); 659 } 660 } 661 return width; 662 } 663 664}