You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TraitSetter.java 28KB

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