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: TraitSetter.java 1790795 2017-04-10 10:03:35Z cbowditch $ */ 19 20 package org.apache.fop.layoutmgr; 21 22 import org.apache.commons.logging.Log; 23 import org.apache.commons.logging.LogFactory; 24 25 import org.apache.fop.accessibility.StructureTreeElement; 26 import org.apache.fop.area.Area; 27 import org.apache.fop.area.Trait; 28 import org.apache.fop.datatypes.LengthBase; 29 import org.apache.fop.datatypes.PercentBaseContext; 30 import org.apache.fop.datatypes.SimplePercentBaseContext; 31 import org.apache.fop.fo.Constants; 32 import org.apache.fop.fo.properties.CommonBorderPaddingBackground; 33 import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo; 34 import org.apache.fop.fo.properties.CommonMarginBlock; 35 import org.apache.fop.fo.properties.CommonTextDecoration; 36 import org.apache.fop.fonts.Font; 37 import org.apache.fop.traits.BorderProps; 38 import org.apache.fop.traits.MinOptMax; 39 import org.apache.fop.traits.Visibility; 40 41 /** 42 * This is a helper class used for setting common traits on areas. 43 */ 44 public final class TraitSetter { 45 TraitSetter()46 private TraitSetter() { 47 } 48 49 /** logger */ 50 private static final Log LOG = LogFactory.getLog(TraitSetter.class); 51 52 /** 53 * Sets border and padding traits on areas. 54 * 55 * @param area area to set the traits on 56 * @param bpProps border and padding properties 57 * @param isNotFirst True if the area is not the first area 58 * @param isNotLast True if the area is not the last area 59 * @param context Property evaluation context 60 */ setBorderPaddingTraits(Area area, CommonBorderPaddingBackground bpProps, boolean isNotFirst, boolean isNotLast, PercentBaseContext context)61 public static void setBorderPaddingTraits(Area area, 62 CommonBorderPaddingBackground bpProps, boolean isNotFirst, boolean isNotLast, 63 PercentBaseContext context) { 64 int padding; 65 padding = bpProps.getPadding(CommonBorderPaddingBackground.START, isNotFirst, context); 66 if (padding > 0) { 67 area.addTrait(Trait.PADDING_START, padding); 68 } 69 padding = bpProps.getPadding(CommonBorderPaddingBackground.END, isNotLast, context); 70 if (padding > 0) { 71 area.addTrait(Trait.PADDING_END, padding); 72 } 73 padding = bpProps.getPadding(CommonBorderPaddingBackground.BEFORE, false, context); 74 if (padding > 0) { 75 area.addTrait(Trait.PADDING_BEFORE, padding); 76 } 77 padding = bpProps.getPadding(CommonBorderPaddingBackground.AFTER, false, context); 78 if (padding > 0) { 79 area.addTrait(Trait.PADDING_AFTER, padding); 80 } 81 82 addBorderTrait(area, bpProps, isNotFirst, 83 CommonBorderPaddingBackground.START, 84 BorderProps.Mode.SEPARATE, Trait.BORDER_START, context); 85 86 addBorderTrait(area, bpProps, isNotLast, 87 CommonBorderPaddingBackground.END, 88 BorderProps.Mode.SEPARATE, Trait.BORDER_END, context); 89 90 addBorderTrait(area, bpProps, false, 91 CommonBorderPaddingBackground.BEFORE, 92 BorderProps.Mode.SEPARATE, Trait.BORDER_BEFORE, context); 93 94 addBorderTrait(area, bpProps, false, 95 CommonBorderPaddingBackground.AFTER, 96 BorderProps.Mode.SEPARATE, Trait.BORDER_AFTER, context); 97 } 98 99 /* 100 * Sets border traits on an area. 101 * 102 * @param area area to set the traits on 103 * @param bpProps border and padding properties 104 * @param mode the border paint mode (see BorderProps) 105 */ addBorderTrait(Area area, CommonBorderPaddingBackground bpProps, boolean discard, int side, BorderProps.Mode mode, Integer traitCode, PercentBaseContext context)106 private static void addBorderTrait(Area area, 107 CommonBorderPaddingBackground bpProps, 108 109 boolean discard, int side, BorderProps.Mode mode, 110 Integer traitCode, PercentBaseContext context) { 111 int width = bpProps.getBorderWidth(side, discard); 112 int radiusStart = bpProps.getBorderRadiusStart(side, discard, context); 113 int radiusEnd = bpProps.getBorderRadiusEnd(side, discard, context); 114 if (width > 0 || radiusStart > 0 || radiusEnd > 0) { 115 area.addTrait(traitCode, new BorderProps(bpProps.getBorderStyle(side), width, radiusStart, 116 radiusEnd, bpProps.getBorderColor(side), mode)); 117 } 118 } 119 120 /** 121 * Add borders to an area. Note: this method also adds unconditional padding. Don't use! 122 * Layout managers that create areas with borders can use this to 123 * add the borders to the area. 124 * @param area the area to set the traits on. 125 * @param borderProps border properties 126 * @param context Property evaluation context 127 * @deprecated Call the other addBorders() method and addPadding separately. 128 */ addBorders(Area area, CommonBorderPaddingBackground borderProps, PercentBaseContext context)129 public static void addBorders(Area area, CommonBorderPaddingBackground borderProps, 130 PercentBaseContext context) { 131 BorderProps bps = getBorderProps(borderProps, CommonBorderPaddingBackground.BEFORE, context); 132 if (bps != null) { 133 area.addTrait(Trait.BORDER_BEFORE, bps); 134 } 135 bps = getBorderProps(borderProps, CommonBorderPaddingBackground.AFTER, context); 136 if (bps != null) { 137 area.addTrait(Trait.BORDER_AFTER, bps); 138 } 139 bps = getBorderProps(borderProps, CommonBorderPaddingBackground.START, context); 140 if (bps != null) { 141 area.addTrait(Trait.BORDER_START, bps); 142 } 143 bps = getBorderProps(borderProps, CommonBorderPaddingBackground.END, context); 144 if (bps != null) { 145 area.addTrait(Trait.BORDER_END, bps); 146 } 147 148 addPadding(area, borderProps, context); 149 } 150 151 /** 152 * Add borders to an area. 153 * Layout managers that create areas with borders can use this to 154 * add the borders to the area. 155 * @param area the area to set the traits on. 156 * @param borderProps border properties 157 * @param discardBefore true if the before border should be discarded 158 * @param discardAfter true if the after border should be discarded 159 * @param discardStart true if the start border should be discarded 160 * @param discardEnd true if the end border should be discarded 161 * @param context Property evaluation context 162 */ 163 //TODO: remove evaluation context; unused, since border-widths are always absolute lengths addBorders(Area area, CommonBorderPaddingBackground borderProps, boolean discardBefore, boolean discardAfter, boolean discardStart, boolean discardEnd, PercentBaseContext context)164 public static void addBorders(Area area, CommonBorderPaddingBackground borderProps, 165 boolean discardBefore, boolean discardAfter, 166 boolean discardStart, boolean discardEnd, 167 PercentBaseContext context) { 168 BorderProps bps = getBorderProps(borderProps, CommonBorderPaddingBackground.BEFORE, context); 169 if (bps != null && !discardBefore) { 170 area.addTrait(Trait.BORDER_BEFORE, bps); 171 } 172 bps = getBorderProps(borderProps, CommonBorderPaddingBackground.AFTER, context); 173 if (bps != null && !discardAfter) { 174 area.addTrait(Trait.BORDER_AFTER, bps); 175 } 176 bps = getBorderProps(borderProps, CommonBorderPaddingBackground.START, context); 177 if (bps != null && !discardStart) { 178 area.addTrait(Trait.BORDER_START, bps); 179 } 180 bps = getBorderProps(borderProps, CommonBorderPaddingBackground.END, context); 181 if (bps != null && !discardEnd) { 182 area.addTrait(Trait.BORDER_END, bps); 183 } 184 185 } 186 187 /** 188 * Add borders to an area for the collapsing border model in tables. 189 * Layout managers that create areas with borders can use this to 190 * add the borders to the area. 191 * @param area the area to set the traits on. 192 * @param borderBefore the resolved before border 193 * @param borderAfter the resolved after border 194 * @param borderStart the resolved start border 195 * @param borderEnd the resolved end border 196 * @param outer 4 boolean values indicating if the side represents the 197 * table's outer border. Order: before, after, start, end 198 */ addCollapsingBorders(Area area, BorderInfo borderBefore, BorderInfo borderAfter, BorderInfo borderStart, BorderInfo borderEnd, boolean[] outer)199 public static void addCollapsingBorders(Area area, 200 BorderInfo borderBefore, BorderInfo borderAfter, 201 BorderInfo borderStart, BorderInfo borderEnd, 202 boolean[] outer) { 203 BorderProps bps = getCollapsingBorderProps(borderBefore, outer[0]); 204 if (bps != null) { 205 area.addTrait(Trait.BORDER_BEFORE, bps); 206 } 207 bps = getCollapsingBorderProps(borderAfter, outer[1]); 208 if (bps != null) { 209 area.addTrait(Trait.BORDER_AFTER, bps); 210 } 211 bps = getCollapsingBorderProps(borderStart, outer[2]); 212 if (bps != null) { 213 area.addTrait(Trait.BORDER_START, bps); 214 } 215 bps = getCollapsingBorderProps(borderEnd, outer[3]); 216 if (bps != null) { 217 area.addTrait(Trait.BORDER_END, bps); 218 } 219 } 220 addPadding(Area area, CommonBorderPaddingBackground bordProps, PercentBaseContext context)221 private static void addPadding(Area area, CommonBorderPaddingBackground bordProps, 222 PercentBaseContext context) { 223 addPadding(area, bordProps, false, false, false, false, context); 224 } 225 226 /** 227 * Add padding to an area. 228 * Layout managers that create areas with padding can use this to 229 * add the borders to the area. 230 * @param area the area to set the traits on. 231 * @param bordProps border and padding properties 232 * @param discardBefore true if the before padding should be discarded 233 * @param discardAfter true if the after padding should be discarded 234 * @param discardStart true if the start padding should be discarded 235 * @param discardEnd true if the end padding should be discarded 236 * @param context Property evaluation context 237 */ addPadding(Area area, CommonBorderPaddingBackground bordProps, boolean discardBefore, boolean discardAfter, boolean discardStart, boolean discardEnd, PercentBaseContext context)238 public static void addPadding(Area area, CommonBorderPaddingBackground bordProps, 239 boolean discardBefore, boolean discardAfter, 240 boolean discardStart, boolean discardEnd, 241 PercentBaseContext context) { 242 int padding = bordProps.getPadding(CommonBorderPaddingBackground.BEFORE, 243 discardBefore, context); 244 if (padding != 0) { 245 area.addTrait(Trait.PADDING_BEFORE, padding); 246 } 247 248 padding = bordProps.getPadding(CommonBorderPaddingBackground.AFTER, 249 discardAfter, context); 250 if (padding != 0) { 251 area.addTrait(Trait.PADDING_AFTER, padding); 252 } 253 254 padding = bordProps.getPadding(CommonBorderPaddingBackground.START, 255 discardStart, context); 256 if (padding != 0) { 257 area.addTrait(Trait.PADDING_START, padding); 258 } 259 260 padding = bordProps.getPadding(CommonBorderPaddingBackground.END, 261 discardEnd, context); 262 if (padding != 0) { 263 area.addTrait(Trait.PADDING_END, padding); 264 } 265 266 } 267 getBorderProps(CommonBorderPaddingBackground bordProps, int side, PercentBaseContext context)268 private static BorderProps getBorderProps(CommonBorderPaddingBackground bordProps, 269 int side, PercentBaseContext context) { 270 int width = bordProps.getBorderWidth(side, false); 271 int radiusStart = bordProps.getBorderRadiusStart(side, false, context); 272 int radiusEnd = bordProps.getBorderRadiusEnd(side, false, context); 273 if (width != 0 || radiusStart != 0 || radiusEnd != 0) { 274 return new BorderProps(bordProps.getBorderStyle(side), width, radiusStart, radiusEnd, 275 bordProps.getBorderColor(side), BorderProps.Mode.SEPARATE); 276 } else { 277 return null; 278 } 279 } 280 getCollapsingBorderProps(BorderInfo borderInfo, boolean outer)281 private static BorderProps getCollapsingBorderProps(BorderInfo borderInfo, boolean outer) { 282 assert borderInfo != null; 283 int width = borderInfo.getRetainedWidth(); 284 if (width != 0) { 285 return BorderProps.makeRectangular(borderInfo.getStyle(), width, borderInfo.getColor(), 286 (outer ? BorderProps.Mode.COLLAPSE_OUTER : BorderProps.Mode.COLLAPSE_INNER)); 287 } else { 288 return null; 289 } 290 } 291 292 293 /** 294 * Add background to an area. This method is mainly used by table-related layout 295 * managers to add background for column, body or row. Since the area corresponding to 296 * border-separation must be filled with the table's background, for every cell an 297 * additional area with the same dimensions is created to hold the background for the 298 * corresponding column/body/row. An additional shift must then be added to 299 * background-position-horizontal/vertical to ensure the background images are 300 * correctly placed. Indeed the placement of images must be made WRT the 301 * column/body/row and not the cell. 302 * 303 * <p>Note: The area's IPD and BPD must be set before calling this method.</p> 304 * 305 * <p>TODO the regular 306 * {@link #addBackground(Area, CommonBorderPaddingBackground, PercentBaseContext)} 307 * method should be used instead, and a means to retrieve the original area's 308 * dimensions must be found.</p> 309 * 310 * <p>TODO the placement of images in the x- or y-direction will be incorrect if 311 * background-repeat is set for that direction.</p> 312 * 313 * @param area the area to set the traits on 314 * @param backProps the background properties 315 * @param context Property evaluation context 316 * @param ipdShift horizontal shift to affect to the background, in addition to the 317 * value of the background-position-horizontal property 318 * @param bpdShift vertical shift to affect to the background, in addition to the 319 * value of the background-position-vertical property 320 * @param referenceIPD value to use as a reference for percentage calculation 321 * @param referenceBPD value to use as a reference for percentage calculation 322 */ addBackground(Area area, CommonBorderPaddingBackground backProps, PercentBaseContext context, int ipdShift, int bpdShift, int referenceIPD, int referenceBPD)323 public static void addBackground(Area area, 324 CommonBorderPaddingBackground backProps, 325 PercentBaseContext context, 326 int ipdShift, int bpdShift, int referenceIPD, int referenceBPD) { 327 if (!backProps.hasBackground()) { 328 return; 329 } 330 Trait.Background back = new Trait.Background(); 331 back.setColor(backProps.backgroundColor); 332 333 if (backProps.getImageInfo() != null) { 334 back.setURL(backProps.backgroundImage); 335 back.setImageInfo(backProps.getImageInfo()); 336 back.setRepeat(backProps.backgroundRepeat); 337 if (backProps.backgroundPositionHorizontal != null) { 338 if (back.getRepeat() == Constants.EN_NOREPEAT 339 || back.getRepeat() == Constants.EN_REPEATY) { 340 if (area.getIPD() > 0) { 341 PercentBaseContext refContext = new SimplePercentBaseContext(context, 342 LengthBase.IMAGE_BACKGROUND_POSITION_HORIZONTAL, 343 (referenceIPD - back.getImageInfo().getSize().getWidthMpt())); 344 345 back.setHoriz(ipdShift 346 + backProps.backgroundPositionHorizontal.getValue(refContext)); 347 } else { 348 // TODO Area IPD has to be set for this to work 349 LOG.warn("Horizontal background image positioning ignored" 350 + " because the IPD was not set on the area." 351 + " (Yes, it's a bug in FOP)"); 352 } 353 } 354 } 355 if (backProps.backgroundPositionVertical != null) { 356 if (back.getRepeat() == Constants.EN_NOREPEAT 357 || back.getRepeat() == Constants.EN_REPEATX) { 358 if (area.getBPD() > 0) { 359 PercentBaseContext refContext = new SimplePercentBaseContext(context, 360 LengthBase.IMAGE_BACKGROUND_POSITION_VERTICAL, 361 (referenceBPD - back.getImageInfo().getSize().getHeightMpt())); 362 back.setVertical(bpdShift 363 + backProps.backgroundPositionVertical.getValue(refContext)); 364 } else { 365 // TODO Area BPD has to be set for this to work 366 LOG.warn("Vertical background image positioning ignored" 367 + " because the BPD was not set on the area." 368 + " (Yes, it's a bug in FOP)"); 369 } 370 } 371 } 372 } 373 374 area.addTrait(Trait.BACKGROUND, back); 375 } 376 377 /** 378 * Add background to an area. 379 * Layout managers that create areas with a background can use this to 380 * add the background to the area. 381 * Note: The area's IPD and BPD must be set before calling this method. 382 * @param area the area to set the traits on 383 * @param backProps the background properties 384 * @param context Property evaluation context 385 */ addBackground(Area area, CommonBorderPaddingBackground backProps, PercentBaseContext context)386 public static void addBackground(Area area, 387 CommonBorderPaddingBackground backProps, 388 PercentBaseContext context) { 389 if (!backProps.hasBackground()) { 390 return; 391 } 392 Trait.Background back = new Trait.Background(); 393 back.setColor(backProps.backgroundColor); 394 395 if (backProps.getImageInfo() != null) { 396 back.setURL(backProps.backgroundImage); 397 back.setImageInfo(backProps.getImageInfo()); 398 back.setRepeat(backProps.backgroundRepeat); 399 if (backProps.backgroundPositionHorizontal != null) { 400 if (back.getRepeat() == Constants.EN_NOREPEAT 401 || back.getRepeat() == Constants.EN_REPEATY) { 402 if (area.getIPD() > 0) { 403 int width = area.getIPD(); 404 width += backProps.getPaddingStart(false, context); 405 width += backProps.getPaddingEnd(false, context); 406 int imageWidthMpt = back.getImageInfo().getSize().getWidthMpt(); 407 int lengthBaseValue = width - imageWidthMpt; 408 SimplePercentBaseContext simplePercentBaseContext 409 = new SimplePercentBaseContext(context, 410 LengthBase.IMAGE_BACKGROUND_POSITION_HORIZONTAL, 411 lengthBaseValue); 412 int horizontal = backProps.backgroundPositionHorizontal.getValue( 413 simplePercentBaseContext); 414 back.setHoriz(horizontal); 415 } else { 416 //TODO Area IPD has to be set for this to work 417 LOG.warn("Horizontal background image positioning ignored" 418 + " because the IPD was not set on the area." 419 + " (Yes, it's a bug in FOP)"); 420 } 421 } 422 } 423 if (backProps.backgroundPositionVertical != null) { 424 if (back.getRepeat() == Constants.EN_NOREPEAT 425 || back.getRepeat() == Constants.EN_REPEATX) { 426 if (area.getBPD() > 0) { 427 int height = area.getBPD(); 428 height += backProps.getPaddingBefore(false, context); 429 height += backProps.getPaddingAfter(false, context); 430 int imageHeightMpt = back.getImageInfo().getSize().getHeightMpt(); 431 int lengthBaseValue = height - imageHeightMpt; 432 SimplePercentBaseContext simplePercentBaseContext 433 = new SimplePercentBaseContext(context, 434 LengthBase.IMAGE_BACKGROUND_POSITION_VERTICAL, 435 lengthBaseValue); 436 int vertical = backProps.backgroundPositionVertical.getValue( 437 simplePercentBaseContext); 438 back.setVertical(vertical); 439 } else { 440 //TODO Area BPD has to be set for this to work 441 LOG.warn("Vertical background image positioning ignored" 442 + " because the BPD was not set on the area." 443 + " (Yes, it's a bug in FOP)"); 444 } 445 } 446 } 447 if (backProps.backgroungImageTargetWidth.getValue() != 0) { 448 back.setImageTargetWidth(backProps.backgroungImageTargetWidth.getValue()); 449 } 450 if (backProps.backgroungImageTargetHeight.getValue() != 0) { 451 back.setImageTargetHeight(backProps.backgroungImageTargetHeight.getValue()); 452 } 453 } 454 455 area.addTrait(Trait.BACKGROUND, back); 456 } 457 458 /** 459 * Add space to a block area. 460 * Layout managers that create block areas can use this to add space 461 * outside of the border rectangle to the area. 462 * @param area the area to set the traits on. 463 * @param bpProps the border, padding and background properties 464 * @param startIndent the effective start-indent value 465 * @param endIndent the effective end-indent value 466 * @param context the context for evaluation of percentages 467 */ addMargins(Area area, CommonBorderPaddingBackground bpProps, int startIndent, int endIndent, PercentBaseContext context)468 public static void addMargins(Area area, 469 CommonBorderPaddingBackground bpProps, 470 int startIndent, int endIndent, 471 PercentBaseContext context) { 472 if (startIndent != 0) { 473 area.addTrait(Trait.START_INDENT, startIndent); 474 } 475 476 int spaceStart = startIndent 477 - bpProps.getBorderStartWidth(false) 478 - bpProps.getPaddingStart(false, context); 479 if (spaceStart != 0) { 480 area.addTrait(Trait.SPACE_START, spaceStart); 481 } 482 483 if (endIndent != 0) { 484 area.addTrait(Trait.END_INDENT, endIndent); 485 } 486 int spaceEnd = endIndent 487 - bpProps.getBorderEndWidth(false) 488 - bpProps.getPaddingEnd(false, context); 489 if (spaceEnd != 0) { 490 area.addTrait(Trait.SPACE_END, spaceEnd); 491 } 492 } 493 494 /** 495 * Add space to a block area. 496 * Layout managers that create block areas can use this to add space 497 * outside of the border rectangle to the area. 498 * @param area the area to set the traits on. 499 * @param bpProps the border, padding and background properties 500 * @param marginProps the margin properties. 501 * @param context the context for evaluation of percentages 502 */ addMargins(Area area, CommonBorderPaddingBackground bpProps, CommonMarginBlock marginProps, PercentBaseContext context)503 public static void addMargins(Area area, 504 CommonBorderPaddingBackground bpProps, 505 CommonMarginBlock marginProps, 506 PercentBaseContext context) { 507 int startIndent = marginProps.startIndent.getValue(context); 508 int endIndent = marginProps.endIndent.getValue(context); 509 addMargins(area, bpProps, startIndent, endIndent, context); 510 } 511 512 /** 513 * Returns the effective space length of a resolved space specifier based on the adjustment 514 * value. 515 * @param adjust the adjustment value 516 * @param space the space specifier 517 * @return the effective space length 518 */ getEffectiveSpace(double adjust, MinOptMax space)519 public static int getEffectiveSpace(double adjust, MinOptMax space) { 520 if (space == null) { 521 return 0; 522 } else { 523 int spaceOpt = space.getOpt(); 524 if (adjust > 0) { 525 spaceOpt += (int) (adjust * space.getStretch()); 526 } else { 527 spaceOpt += (int) (adjust * space.getShrink()); 528 } 529 return spaceOpt; 530 } 531 } 532 533 /** 534 * Adds traits for space-before and space-after to an area. 535 * @param area the target area 536 * @param adjust the adjustment value 537 * @param spaceBefore the space-before space specifier 538 * @param spaceAfter the space-after space specifier 539 */ addSpaceBeforeAfter(Area area, double adjust, MinOptMax spaceBefore, MinOptMax spaceAfter)540 public static void addSpaceBeforeAfter(Area area, double adjust, MinOptMax spaceBefore, 541 MinOptMax spaceAfter) { 542 addSpaceTrait(area, Trait.SPACE_BEFORE, spaceBefore, adjust); 543 addSpaceTrait(area, Trait.SPACE_AFTER, spaceAfter, adjust); 544 } 545 addSpaceTrait(Area area, Integer spaceTrait, MinOptMax space, double adjust)546 private static void addSpaceTrait(Area area, Integer spaceTrait, 547 MinOptMax space, double adjust) { 548 int effectiveSpace = getEffectiveSpace(adjust, space); 549 if (effectiveSpace != 0) { 550 area.addTrait(spaceTrait, effectiveSpace); 551 } 552 } 553 554 /** 555 * Sets the traits for breaks on an area. 556 * @param area the area to set the traits on. 557 * @param breakBefore the value for break-before 558 * @param breakAfter the value for break-after 559 */ addBreaks(Area area, int breakBefore, int breakAfter)560 public static void addBreaks(Area area, int breakBefore, int breakAfter) { 561 /* Currently disabled as these traits are never used by the renderers 562 area.addTrait(Trait.BREAK_AFTER, Integer.valueOf(breakAfter)); 563 area.addTrait(Trait.BREAK_BEFORE, Integer.valueOf(breakBefore)); 564 */ 565 } 566 567 /** 568 * Adds font traits to an area 569 * @param area the target are 570 * @param font the font to use 571 */ addFontTraits(Area area, Font font)572 public static void addFontTraits(Area area, Font font) { 573 area.addTrait(Trait.FONT, font.getFontTriplet()); 574 area.addTrait(Trait.FONT_SIZE, font.getFontSize()); 575 } 576 577 /** 578 * Adds the text-decoration traits to the area. 579 * @param area the area to set the traits on 580 * @param deco the text decorations 581 */ addTextDecoration(Area area, CommonTextDecoration deco)582 public static void addTextDecoration(Area area, CommonTextDecoration deco) { 583 //TODO Finish text-decoration 584 if (deco != null) { 585 if (deco.hasUnderline()) { 586 area.addTrait(Trait.UNDERLINE, Boolean.TRUE); 587 area.addTrait(Trait.UNDERLINE_COLOR, deco.getUnderlineColor()); 588 } 589 if (deco.hasOverline()) { 590 area.addTrait(Trait.OVERLINE, Boolean.TRUE); 591 area.addTrait(Trait.OVERLINE_COLOR, deco.getOverlineColor()); 592 } 593 if (deco.hasLineThrough()) { 594 area.addTrait(Trait.LINETHROUGH, Boolean.TRUE); 595 area.addTrait(Trait.LINETHROUGH_COLOR, deco.getLineThroughColor()); 596 } 597 if (deco.isBlinking()) { 598 area.addTrait(Trait.BLINK, Boolean.TRUE); 599 } 600 } 601 } 602 setVisibility(Area area, int visibility)603 public static void setVisibility(Area area, int visibility) { 604 Visibility v; 605 switch (visibility) { 606 case Constants.EN_COLLAPSE: 607 v = Visibility.COLLAPSE; 608 break; 609 case Constants.EN_HIDDEN: 610 v = Visibility.HIDDEN; 611 break; 612 default: 613 v = Visibility.VISIBLE; 614 } 615 area.addTrait(Trait.VISIBILITY, v); 616 } 617 618 /** 619 * Sets the structure tree element associated to the given area. 620 * 621 * @param area the area to set the traits on 622 * @param structureTreeElement the element the area is associated to in the document structure 623 */ addStructureTreeElement(Area area, StructureTreeElement structureTreeElement)624 public static void addStructureTreeElement(Area area, 625 StructureTreeElement structureTreeElement) { 626 if (structureTreeElement != null) { 627 area.addTrait(Trait.STRUCTURE_TREE_ELEMENT, structureTreeElement); 628 } 629 } 630 631 /** 632 * Sets the producer's ID as a trait on the area. This can be used to track back the 633 * generating FO node. 634 * @param area the area to set the traits on 635 * @param id the ID to set 636 */ setProducerID(Area area, String id)637 public static void setProducerID(Area area, String id) { 638 if (id != null && id.length() > 0) { 639 area.addTrait(Trait.PROD_ID, id); 640 } 641 } 642 643 /** 644 * Sets the optional content group layer as a trait on the area. 645 * @param area the area to set the traits on 646 * @param layer the layer ID to set 647 */ setLayer(Area area, String layer)648 public static void setLayer(Area area, String layer) { 649 if (layer != null && layer.length() > 0) { 650 area.addTrait(Trait.LAYER, layer); 651 } 652 } 653 } 654