1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 /* $Id: Trait.java 1790795 2017-04-10 10:03:35Z cbowditch $ */ 19 20 package org.apache.fop.area; 21 22 import java.awt.Color; 23 import java.io.Serializable; 24 25 import org.apache.xmlgraphics.image.loader.ImageInfo; 26 27 import org.apache.fop.fonts.FontTriplet; 28 import org.apache.fop.traits.BorderProps; 29 import org.apache.fop.traits.Direction; 30 import org.apache.fop.traits.Visibility; 31 import org.apache.fop.traits.WritingMode; 32 import org.apache.fop.util.ColorUtil; 33 34 import static org.apache.fop.fo.Constants.EN_NOREPEAT; 35 import static org.apache.fop.fo.Constants.EN_REPEAT; 36 import static org.apache.fop.fo.Constants.EN_REPEATX; 37 import static org.apache.fop.fo.Constants.EN_REPEATY; 38 39 // properties should be serialized by the holder 40 /** 41 * Area traits used for rendering. 42 * This class represents an area trait that specifies a value for rendering. 43 */ 44 public final class Trait implements Serializable { 45 46 private static final long serialVersionUID = 3234280285391611437L; 47 Trait()48 private Trait() { 49 } 50 51 /** Id reference line, not resolved. (not sure if this is needed.) */ 52 //public static final Integer ID_LINK = Integer.valueOf(0); 53 54 /** 55 * Internal link trait. 56 * Contains the PageViewport key and the PROD_ID of the target area 57 */ 58 public static final Integer INTERNAL_LINK = 1; 59 60 /** * External link. A URL link to an external resource. */ 61 public static final Integer EXTERNAL_LINK = 2; 62 63 /** The font triplet for the current font. */ 64 public static final Integer FONT = 3; 65 66 /** Font size for the current font. */ 67 public static final Integer FONT_SIZE = 4; 68 69 /** The current color. */ 70 public static final Integer COLOR = 7; 71 72 /** The ID of the FO that produced an area. */ 73 public static final Integer PROD_ID = 8; 74 75 /** Background trait for an area. */ 76 public static final Integer BACKGROUND = 9; 77 78 /** Underline trait used when rendering inline parent. */ 79 public static final Integer UNDERLINE = 10; 80 81 /** Overline trait used when rendering inline parent. */ 82 public static final Integer OVERLINE = 11; 83 84 /** Linethrough trait used when rendering inline parent. */ 85 public static final Integer LINETHROUGH = 12; 86 87 /** Shadow offset. */ 88 //public static final Integer OFFSET = Integer.valueOf(13); 89 90 /** The shadow for text. */ 91 //public static final Integer SHADOW = Integer.valueOf(14); 92 93 /** The border start. */ 94 public static final Integer BORDER_START = 15; 95 96 /** The border end. */ 97 public static final Integer BORDER_END = 16; 98 99 /** The border before. */ 100 public static final Integer BORDER_BEFORE = 17; 101 102 /** The border after. */ 103 public static final Integer BORDER_AFTER = 18; 104 105 /** The padding start. */ 106 public static final Integer PADDING_START = 19; 107 108 /** The padding end. */ 109 public static final Integer PADDING_END = 20; 110 111 /** The padding before. */ 112 public static final Integer PADDING_BEFORE = 21; 113 114 /** The padding after. */ 115 public static final Integer PADDING_AFTER = 22; 116 117 /** The space start. */ 118 public static final Integer SPACE_START = 23; 119 120 /** The space end. */ 121 public static final Integer SPACE_END = 24; 122 123 /** break before */ 124 //public static final Integer BREAK_BEFORE = Integer.valueOf(25); 125 126 /** break after */ 127 //public static final Integer BREAK_AFTER = Integer.valueOf(26); 128 129 /** The start-indent trait. */ 130 public static final Integer START_INDENT = 27; 131 132 /** The end-indent trait. */ 133 public static final Integer END_INDENT = 28; 134 135 /** The space-before trait. */ 136 public static final Integer SPACE_BEFORE = 29; 137 138 /** The space-after trait. */ 139 public static final Integer SPACE_AFTER = 30; 140 141 /** The is-reference-area trait. */ 142 public static final Integer IS_REFERENCE_AREA = 31; 143 144 /** The is-viewport-area trait. */ 145 public static final Integer IS_VIEWPORT_AREA = 32; 146 147 /** Blinking trait used when rendering inline parent. */ 148 public static final Integer BLINK = 33; 149 150 /** Trait for color of underline decorations when rendering inline parent. */ 151 public static final Integer UNDERLINE_COLOR = 34; 152 153 /** Trait for color of overline decorations when rendering inline parent. */ 154 public static final Integer OVERLINE_COLOR = 35; 155 156 /** Trait for color of linethrough decorations when rendering inline parent. */ 157 public static final Integer LINETHROUGH_COLOR = 36; 158 159 /** For navigation in the document structure. */ 160 public static final Integer STRUCTURE_TREE_ELEMENT = 37; 161 162 /** writing mode trait */ 163 public static final Integer WRITING_MODE = 38; 164 /** inline progression direction trait */ 165 public static final Integer INLINE_PROGRESSION_DIRECTION = 39; 166 /** block progression direction trait */ 167 public static final Integer BLOCK_PROGRESSION_DIRECTION = 40; 168 /** column progression direction trait */ 169 public static final Integer COLUMN_PROGRESSION_DIRECTION = 41; 170 /** shift direction trait */ 171 public static final Integer SHIFT_DIRECTION = 42; 172 173 /** For optional content groups. */ 174 public static final Integer LAYER = 43; 175 176 /** Used to disable the rendering of a Block http://www.w3.org/TR/xsl/#rend-vis */ 177 public static final Integer VISIBILITY = 44; 178 179 /** Maximum value used by trait keys */ 180 public static final int MAX_TRAIT_KEY = 44; 181 182 private static final TraitInfo[] TRAIT_INFO = new TraitInfo[MAX_TRAIT_KEY + 1]; 183 184 private static class TraitInfo { 185 private String name; 186 private Class clazz; // Class of trait data 187 TraitInfo(String name, Class clazz)188 public TraitInfo(String name, Class clazz) { 189 this.name = name; 190 this.clazz = clazz; 191 } 192 getName()193 public String getName() { 194 return this.name; 195 } 196 getClazz()197 public Class getClazz() { 198 return this.clazz; 199 } 200 } 201 put(Integer key, TraitInfo info)202 private static void put(Integer key, TraitInfo info) { 203 TRAIT_INFO[key] = info; 204 } 205 206 static { 207 // Create a hashmap mapping trait code to name for external representation 208 //put(ID_LINK, new TraitInfo("id-link", String.class)); put(STRUCTURE_TREE_ELEMENT, new TraitInfo(R, String.class))209 put(STRUCTURE_TREE_ELEMENT, new TraitInfo("structure-tree-element", String.class)); put(INTERNAL_LINK, new TraitInfo(R, InternalLink.class))210 put(INTERNAL_LINK, new TraitInfo("internal-link", InternalLink.class)); put(EXTERNAL_LINK, new TraitInfo(R, ExternalLink.class))211 put(EXTERNAL_LINK, new TraitInfo("external-link", ExternalLink.class)); put(FONT, new TraitInfo(R, FontTriplet.class))212 put(FONT, new TraitInfo("font", FontTriplet.class)); put(FONT_SIZE, new TraitInfo(R, Integer.class))213 put(FONT_SIZE, new TraitInfo("font-size", Integer.class)); put(COLOR, new TraitInfo(R, Color.class))214 put(COLOR, new TraitInfo("color", Color.class)); put(PROD_ID, new TraitInfo(R, String.class))215 put(PROD_ID, new TraitInfo("prod-id", String.class)); put(BACKGROUND, new TraitInfo(R, Background.class))216 put(BACKGROUND, new TraitInfo("background", Background.class)); put(UNDERLINE, new TraitInfo(R, Boolean.class))217 put(UNDERLINE, new TraitInfo("underline-score", Boolean.class)); put(UNDERLINE_COLOR, new TraitInfo(R, Color.class))218 put(UNDERLINE_COLOR, new TraitInfo("underline-score-color", Color.class)); put(OVERLINE, new TraitInfo(R, Boolean.class))219 put(OVERLINE, new TraitInfo("overline-score", Boolean.class)); put(OVERLINE_COLOR, new TraitInfo(R, Color.class))220 put(OVERLINE_COLOR, new TraitInfo("overline-score-color", Color.class)); put(LINETHROUGH, new TraitInfo(R, Boolean.class))221 put(LINETHROUGH, new TraitInfo("through-score", Boolean.class)); put(LINETHROUGH_COLOR, new TraitInfo(R, Color.class))222 put(LINETHROUGH_COLOR, new TraitInfo("through-score-color", Color.class)); put(BLINK, new TraitInfo(R, Boolean.class))223 put(BLINK, new TraitInfo("blink", Boolean.class)); 224 //put(OFFSET, new TraitInfo("offset", Integer.class)); 225 //put(SHADOW, new TraitInfo("shadow", Integer.class)); put(BORDER_START, new TraitInfo(R, BorderProps.class))226 put(BORDER_START, new TraitInfo("border-start", BorderProps.class)); put(BORDER_END, new TraitInfo(R, BorderProps.class))227 put(BORDER_END, new TraitInfo("border-end", BorderProps.class)); put(BORDER_BEFORE, new TraitInfo(R, BorderProps.class))228 put(BORDER_BEFORE, new TraitInfo("border-before", BorderProps.class)); put(BORDER_AFTER, new TraitInfo(R, BorderProps.class))229 put(BORDER_AFTER, new TraitInfo("border-after", BorderProps.class)); put(PADDING_START, new TraitInfo(R, Integer.class))230 put(PADDING_START, new TraitInfo("padding-start", Integer.class)); put(PADDING_END, new TraitInfo(R, Integer.class))231 put(PADDING_END, new TraitInfo("padding-end", Integer.class)); put(PADDING_BEFORE, new TraitInfo(R, Integer.class))232 put(PADDING_BEFORE, new TraitInfo("padding-before", Integer.class)); put(PADDING_AFTER, new TraitInfo(R, Integer.class))233 put(PADDING_AFTER, new TraitInfo("padding-after", Integer.class)); put(SPACE_START, new TraitInfo(R, Integer.class))234 put(SPACE_START, new TraitInfo("space-start", Integer.class)); put(SPACE_END, new TraitInfo(R, Integer.class))235 put(SPACE_END, new TraitInfo("space-end", Integer.class)); 236 //put(BREAK_BEFORE, new TraitInfo("break-before", Integer.class)); 237 //put(BREAK_AFTER, new TraitInfo("break-after", Integer.class)); put(START_INDENT, new TraitInfo(R, Integer.class))238 put(START_INDENT, new TraitInfo("start-indent", Integer.class)); put(END_INDENT, new TraitInfo(R, Integer.class))239 put(END_INDENT, new TraitInfo("end-indent", Integer.class)); put(SPACE_BEFORE, new TraitInfo(R, Integer.class))240 put(SPACE_BEFORE, new TraitInfo("space-before", Integer.class)); put(SPACE_AFTER, new TraitInfo(R, Integer.class))241 put(SPACE_AFTER, new TraitInfo("space-after", Integer.class)); put(IS_REFERENCE_AREA, new TraitInfo(R, Boolean.class))242 put(IS_REFERENCE_AREA, new TraitInfo("is-reference-area", Boolean.class)); put(IS_VIEWPORT_AREA, new TraitInfo(R, Boolean.class))243 put(IS_VIEWPORT_AREA, new TraitInfo("is-viewport-area", Boolean.class)); put(WRITING_MODE, new TraitInfo(R, WritingMode.class))244 put(WRITING_MODE, 245 new TraitInfo("writing-mode", WritingMode.class)); put(INLINE_PROGRESSION_DIRECTION, new TraitInfo(R, Direction.class))246 put(INLINE_PROGRESSION_DIRECTION, 247 new TraitInfo("inline-progression-direction", Direction.class)); put(BLOCK_PROGRESSION_DIRECTION, new TraitInfo(R, Direction.class))248 put(BLOCK_PROGRESSION_DIRECTION, 249 new TraitInfo("block-progression-direction", Direction.class)); put(SHIFT_DIRECTION, new TraitInfo(R, Direction.class))250 put(SHIFT_DIRECTION, 251 new TraitInfo("shift-direction", Direction.class)); put(LAYER, new TraitInfo(R, String.class))252 put(LAYER, new TraitInfo("layer", String.class)); put(VISIBILITY, new TraitInfo(R, Visibility.class))253 put(VISIBILITY, new TraitInfo("visibility", Visibility.class)); 254 } 255 256 /** 257 * Get the trait name for a trait code. 258 * 259 * @param traitCode the trait code to get the name for 260 * @return the trait name 261 */ getTraitName(Object traitCode)262 public static String getTraitName(Object traitCode) { 263 return TRAIT_INFO[(Integer)traitCode].getName(); 264 } 265 266 /** 267 * Get the data storage class for the trait. 268 * 269 * @param traitCode the trait code to lookup 270 * @return the class type for the trait 271 */ getTraitClass(Object traitCode)272 public static Class getTraitClass(Object traitCode) { 273 return TRAIT_INFO[(Integer)traitCode].getClazz(); 274 } 275 276 /** 277 * Class for internal link traits. 278 * Stores PageViewport key and producer ID 279 */ 280 public static class InternalLink implements Serializable { 281 282 private static final long serialVersionUID = -8993505060996723039L; 283 284 /** The unique key of the PageViewport. */ 285 private String pvKey; 286 287 /** The PROD_ID of the link target */ 288 private String idRef; 289 290 /** 291 * Create an InternalLink to the given PageViewport and target ID 292 * 293 * @param pvKey the PageViewport key 294 * @param idRef the target ID 295 */ InternalLink(String pvKey, String idRef)296 public InternalLink(String pvKey, String idRef) { 297 setPVKey(pvKey); 298 setIDRef(idRef); 299 } 300 301 /** 302 * Create an InternalLink based on the given XML attribute value. 303 * This is typically called when data are read from an XML area tree. 304 * 305 * @param attrValue attribute value to be parsed by InternalLink.parseXMLAttribute 306 */ InternalLink(String attrValue)307 public InternalLink(String attrValue) { 308 String[] values = parseXMLAttribute(attrValue); 309 setPVKey(values[0]); 310 setIDRef(values[1]); 311 } 312 313 /** 314 * Sets the key of the targeted PageViewport. 315 * 316 * @param pvKey the PageViewport key 317 */ setPVKey(String pvKey)318 public void setPVKey(String pvKey) { 319 this.pvKey = pvKey; 320 } 321 322 /** 323 * Returns the key of the targeted PageViewport. 324 * 325 * @return the PageViewport key 326 */ getPVKey()327 public String getPVKey() { 328 return pvKey; 329 } 330 331 /** 332 * Sets the target ID. 333 * 334 * @param idRef the target ID 335 */ setIDRef(String idRef)336 public void setIDRef(String idRef) { 337 this.idRef = idRef; 338 } 339 340 /** 341 * Returns the target ID. 342 * 343 * @return the target ID 344 */ getIDRef()345 public String getIDRef() { 346 return idRef; 347 } 348 349 /** 350 * Returns the attribute value for this object as 351 * used in the area tree XML. 352 * 353 * @return a string of the type "(thisPVKey,thisIDRef)" 354 */ xmlAttribute()355 public String xmlAttribute() { 356 return makeXMLAttribute(pvKey, idRef); 357 } 358 359 /** 360 * Returns the XML attribute value for the given PV key and ID ref. 361 * This value is used in the area tree XML. 362 * 363 * @param pvKey the PageViewport key of the link target 364 * @param idRef the ID of the link target 365 * @return a string of the type "(thisPVKey,thisIDRef)" 366 */ makeXMLAttribute(String pvKey, String idRef)367 public static String makeXMLAttribute(String pvKey, String idRef) { 368 return "(" + (pvKey == null ? "" : pvKey) + "," 369 + (idRef == null ? "" : idRef) + ")"; 370 } 371 372 /** 373 * Parses XML attribute value from the area tree into 374 * PageViewport key + IDRef strings. If the attribute value is 375 * formatted like "(s1,s2)", then s1 and s2 are considered to be 376 * the PV key and the IDRef, respectively. 377 * Otherwise, the entire string is the PV key and the IDRef is null. 378 * 379 * @param attrValue the atribute value (PV key and possibly IDRef) 380 * @return a 2-String array containing the PV key and the IDRef. 381 * Both may be null. 382 */ parseXMLAttribute(String attrValue)383 public static String[] parseXMLAttribute(String attrValue) { 384 String[] result = {null, null}; 385 if (attrValue != null) { 386 int len = attrValue.length(); 387 if (len >= 2 && attrValue.charAt(0) == '(' && attrValue.charAt(len - 1) == ')' 388 && attrValue.indexOf(',') != -1) { 389 String value = attrValue.substring(1, len - 1); // remove brackets 390 int delimIndex = value.indexOf(','); 391 result[0] = value.substring(0, delimIndex).trim(); // PV key 392 result[1] = value.substring(delimIndex + 1, value.length()).trim(); // IDRef 393 } else { 394 // PV key only, e.g. from old area tree XML: 395 result[0] = attrValue; 396 } 397 } 398 return result; 399 } 400 401 /** 402 * Return the human-friendly string for debugging. 403 * {@inheritDoc} 404 */ 405 @Override toString()406 public String toString() { 407 StringBuffer sb = new StringBuffer(); 408 sb.append("pvKey=").append(pvKey); 409 sb.append(",idRef=").append(idRef); 410 return sb.toString(); 411 } 412 } 413 414 /** 415 * External Link trait structure 416 */ 417 public static class ExternalLink implements Serializable { 418 419 private static final long serialVersionUID = -3720707599232620946L; 420 421 private String destination; 422 private boolean newWindow; 423 424 /** 425 * Constructs an ExternalLink object with the given destination 426 * 427 * @param destination target of the link 428 * @param newWindow true if the target should be opened in a new window 429 */ ExternalLink(String destination, boolean newWindow)430 public ExternalLink(String destination, boolean newWindow) { 431 this.destination = destination; 432 this.newWindow = newWindow; 433 } 434 435 /** 436 * Create an <code>ExternalLink</code> from a trait value/attribute value in the 437 * area tree 438 * @param traitValue the value to use (should match the result of {@link #toString()} 439 * @return an <code>ExternalLink</code> instance corresponding to the given value 440 */ makeFromTraitValue(String traitValue)441 protected static ExternalLink makeFromTraitValue(String traitValue) { 442 String dest = null; 443 boolean newWindow = false; 444 String[] values = traitValue.split(","); 445 for (String v : values) { 446 if (v.startsWith("dest=")) { 447 dest = v.substring(5); 448 } else if (v.startsWith("newWindow=")) { 449 newWindow = Boolean.valueOf(v.substring(10)); 450 } else { 451 throw new IllegalArgumentException( 452 "Malformed trait value for Trait.ExternalLink: " + traitValue); 453 } 454 } 455 return new ExternalLink(dest, newWindow); 456 } 457 458 /** 459 * Get the target/destination of the link 460 * @return the destination of the link 461 */ getDestination()462 public String getDestination() { 463 return this.destination; 464 } 465 466 /** 467 * Check if the target has to be displayed in a new window 468 * @return <code>true</code> if the target has to be displayed in a new window 469 */ newWindow()470 public boolean newWindow() { 471 return this.newWindow; 472 } 473 474 /** 475 * Return a String representation of the object. 476 * @return a <code>String</code> of the form 477 * "org.apache.fop.area.Trait.ExternalLink[dest=someURL,newWindow=false]" 478 */ 479 @Override toString()480 public String toString() { 481 StringBuffer sb = new StringBuffer(64); 482 sb.append("newWindow=").append(newWindow); 483 sb.append(",dest=").append(this.destination); 484 return sb.toString(); 485 } 486 } 487 488 /** 489 * Background trait structure. 490 * Used for storing back trait information which are related. 491 */ 492 public static class Background implements Serializable { 493 494 private static final long serialVersionUID = 8452078676273242870L; 495 496 /** The background color if any. */ 497 private Color color; 498 499 /** The background image url if any. */ 500 private String url; 501 502 /** The background image if any. */ 503 private ImageInfo imageInfo; 504 505 /** Background repeat enum for images. */ 506 private int repeat; 507 508 /** Background horizontal offset for images. */ 509 private int horiz; 510 511 /** Background vertical offset for images. */ 512 private int vertical; 513 514 private int imageTargetWidth; 515 516 private int imageTargetHeight; 517 518 /** 519 * Returns the background color. 520 * @return background color, null if n/a 521 */ getColor()522 public Color getColor() { 523 return color; 524 } 525 526 /** 527 * Returns the horizontal offset for images. 528 * @return the horizontal offset 529 */ getHoriz()530 public int getHoriz() { 531 return horiz; 532 } 533 534 /** 535 * Returns the image repetition behaviour for images. 536 * @return the image repetition behaviour 537 */ getRepeat()538 public int getRepeat() { 539 return repeat; 540 } 541 542 /** 543 * Returns the URL to the background image 544 * @return URL to the background image, null if n/a 545 */ getURL()546 public String getURL() { 547 return url; 548 } 549 550 /** 551 * Returns the ImageInfo object representing the background image 552 * @return the background image, null if n/a 553 */ getImageInfo()554 public ImageInfo getImageInfo() { 555 return imageInfo; 556 } 557 558 /** 559 * Returns the vertical offset for images. 560 * @return the vertical offset 561 */ getVertical()562 public int getVertical() { 563 return vertical; 564 } 565 566 /** 567 * Sets the color. 568 * @param color The color to set 569 */ setColor(Color color)570 public void setColor(Color color) { 571 this.color = color; 572 } 573 574 /** 575 * Sets the horizontal offset. 576 * @param horiz The horizontal offset to set 577 */ setHoriz(int horiz)578 public void setHoriz(int horiz) { 579 this.horiz = horiz; 580 } 581 582 /** 583 * Sets the image repetition behaviour for images. 584 * @param repeat The image repetition behaviour to set 585 */ setRepeat(int repeat)586 public void setRepeat(int repeat) { 587 this.repeat = repeat; 588 } 589 590 /** 591 * Sets the image repetition behaviour for images. 592 * @param repeat The image repetition behaviour to set 593 */ setRepeat(String repeat)594 public void setRepeat(String repeat) { 595 setRepeat(getConstantForRepeat(repeat)); 596 } 597 598 /** 599 * Sets the URL to the background image. 600 * @param url The URL to set 601 */ setURL(String url)602 public void setURL(String url) { 603 this.url = url; 604 } 605 606 /** 607 * Sets the ImageInfo of the image to use as the background image. 608 * @param info The background image's info object 609 */ setImageInfo(ImageInfo info)610 public void setImageInfo(ImageInfo info) { 611 this.imageInfo = info; 612 } 613 614 /** 615 * Sets the vertical offset for images. 616 * @param vertical The vertical offset to set 617 */ setVertical(int vertical)618 public void setVertical(int vertical) { 619 this.vertical = vertical; 620 } 621 getRepeatString()622 private String getRepeatString() { 623 switch (getRepeat()) { 624 case EN_REPEAT: return "repeat"; 625 case EN_REPEATX: return "repeat-x"; 626 case EN_REPEATY: return "repeat-y"; 627 case EN_NOREPEAT: return "no-repeat"; 628 default: throw new IllegalStateException("Illegal repeat style: " + getRepeat()); 629 } 630 } 631 getConstantForRepeat(String repeat)632 private static int getConstantForRepeat(String repeat) { 633 if ("repeat".equalsIgnoreCase(repeat)) { 634 return EN_REPEAT; 635 } else if ("repeat-x".equalsIgnoreCase(repeat)) { 636 return EN_REPEATX; 637 } else if ("repeat-y".equalsIgnoreCase(repeat)) { 638 return EN_REPEATY; 639 } else if ("no-repeat".equalsIgnoreCase(repeat)) { 640 return EN_NOREPEAT; 641 } else { 642 throw new IllegalStateException("Illegal repeat style: " + repeat); 643 } 644 } 645 646 /** 647 * Return the string for debugging. 648 * {@inheritDoc} 649 */ 650 @Override toString()651 public String toString() { 652 StringBuffer sb = new StringBuffer(); 653 if (color != null) { 654 sb.append("color=").append(ColorUtil.colorToString(color)); 655 } 656 if (url != null) { 657 if (color != null) { 658 sb.append(","); 659 } 660 sb.append("url=").append(url); 661 sb.append(",repeat=").append(getRepeatString()); 662 sb.append(",horiz=").append(horiz); 663 sb.append(",vertical=").append(vertical); 664 } 665 if (imageTargetWidth != 0) { 666 sb.append(",target-width=").append(Integer.toString(imageTargetWidth)); 667 } 668 if (imageTargetHeight != 0) { 669 sb.append(",target-height=").append(Integer.toString(imageTargetHeight)); 670 } 671 return sb.toString(); 672 } 673 setImageTargetWidth(int value)674 public void setImageTargetWidth(int value) { 675 imageTargetWidth = value; 676 } 677 getImageTargetWidth()678 public int getImageTargetWidth() { 679 return imageTargetWidth; 680 } 681 setImageTargetHeight(int value)682 public void setImageTargetHeight(int value) { 683 imageTargetHeight = value; 684 } 685 getImageTargetHeight()686 public int getImageTargetHeight() { 687 return imageTargetHeight; 688 } 689 690 } 691 } 692 693