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.

InlineLayoutManager.java 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  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.inline;
  19. import java.util.LinkedList;
  20. import java.util.List;
  21. import java.util.ListIterator;
  22. import org.apache.commons.logging.Log;
  23. import org.apache.commons.logging.LogFactory;
  24. import org.apache.fop.area.Area;
  25. import org.apache.fop.area.inline.InlineArea;
  26. import org.apache.fop.area.inline.InlineBlockParent;
  27. import org.apache.fop.area.inline.InlineParent;
  28. import org.apache.fop.datatypes.Length;
  29. import org.apache.fop.fo.flow.Inline;
  30. import org.apache.fop.fo.flow.InlineLevel;
  31. import org.apache.fop.fo.flow.Leader;
  32. import org.apache.fop.fo.pagination.Title;
  33. import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
  34. import org.apache.fop.fo.properties.CommonFont;
  35. import org.apache.fop.fo.properties.CommonMarginInline;
  36. import org.apache.fop.fo.properties.SpaceProperty;
  37. import org.apache.fop.fonts.Font;
  38. import org.apache.fop.fonts.FontInfo;
  39. import org.apache.fop.fonts.FontTriplet;
  40. import org.apache.fop.layoutmgr.BlockKnuthSequence;
  41. import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
  42. import org.apache.fop.layoutmgr.BreakElement;
  43. import org.apache.fop.layoutmgr.InlineKnuthSequence;
  44. import org.apache.fop.layoutmgr.KnuthBox;
  45. import org.apache.fop.layoutmgr.KnuthSequence;
  46. import org.apache.fop.layoutmgr.LayoutContext;
  47. import org.apache.fop.layoutmgr.LayoutManager;
  48. import org.apache.fop.layoutmgr.NonLeafPosition;
  49. import org.apache.fop.layoutmgr.Position;
  50. import org.apache.fop.layoutmgr.PositionIterator;
  51. import org.apache.fop.layoutmgr.SpaceSpecifier;
  52. import org.apache.fop.layoutmgr.TraitSetter;
  53. import org.apache.fop.traits.MinOptMax;
  54. import org.apache.fop.traits.SpaceVal;
  55. import org.apache.fop.util.ListUtil;
  56. /**
  57. * LayoutManager for objects which stack children in the inline direction,
  58. * such as Inline or Line
  59. */
  60. public class InlineLayoutManager extends InlineStackingLayoutManager {
  61. /**
  62. * logging instance
  63. */
  64. private static Log log = LogFactory.getLog(InlineLayoutManager.class);
  65. private CommonMarginInline inlineProps = null;
  66. private CommonBorderPaddingBackground borderProps = null;
  67. private boolean areaCreated = false;
  68. private LayoutManager lastChildLM = null; // Set when return last breakposs;
  69. private Position auxiliaryPosition;
  70. private Font font;
  71. /** The alignment adjust property */
  72. protected Length alignmentAdjust;
  73. /** The alignment baseline property */
  74. protected int alignmentBaseline = EN_BASELINE;
  75. /** The baseline shift property */
  76. protected Length baselineShift;
  77. /** The dominant baseline property */
  78. protected int dominantBaseline;
  79. /** The line height property */
  80. protected SpaceProperty lineHeight;
  81. /** The keep-together property */
  82. //private KeepProperty keepTogether;
  83. private AlignmentContext alignmentContext = null;
  84. /**
  85. * Create an inline layout manager.
  86. * This is used for fo's that create areas that
  87. * contain inline areas.
  88. *
  89. * @param node the formatting object that creates the area
  90. */
  91. // The node should be FObjMixed
  92. public InlineLayoutManager(InlineLevel node) {
  93. super(node);
  94. }
  95. private Inline getInlineFO() {
  96. return (Inline) fobj;
  97. }
  98. /** {@inheritDoc} */
  99. public void initialize() {
  100. InlineLevel fobj = (InlineLevel) this.fobj;
  101. int padding = 0;
  102. FontInfo fi = fobj.getFOEventHandler().getFontInfo();
  103. CommonFont commonFont = fobj.getCommonFont();
  104. FontTriplet[] fontkeys = commonFont.getFontState(fi);
  105. font = fi.getFontInstance(fontkeys[0], commonFont.fontSize.getValue(this));
  106. lineHeight = fobj.getLineHeight();
  107. borderProps = fobj.getCommonBorderPaddingBackground();
  108. inlineProps = fobj.getCommonMarginInline();
  109. if (fobj instanceof Inline) {
  110. alignmentAdjust = ((Inline)fobj).getAlignmentAdjust();
  111. alignmentBaseline = ((Inline)fobj).getAlignmentBaseline();
  112. baselineShift = ((Inline)fobj).getBaselineShift();
  113. dominantBaseline = ((Inline)fobj).getDominantBaseline();
  114. } else if (fobj instanceof Leader) {
  115. alignmentAdjust = ((Leader)fobj).getAlignmentAdjust();
  116. alignmentBaseline = ((Leader)fobj).getAlignmentBaseline();
  117. baselineShift = ((Leader)fobj).getBaselineShift();
  118. dominantBaseline = ((Leader)fobj).getDominantBaseline();
  119. }
  120. if (borderProps != null) {
  121. padding = borderProps.getPadding(CommonBorderPaddingBackground.BEFORE, false, this);
  122. padding += borderProps.getBorderWidth(CommonBorderPaddingBackground.BEFORE,
  123. false);
  124. padding += borderProps.getPadding(CommonBorderPaddingBackground.AFTER, false, this);
  125. padding += borderProps.getBorderWidth(CommonBorderPaddingBackground.AFTER, false);
  126. }
  127. extraBPD = new MinOptMax(padding);
  128. }
  129. /** {@inheritDoc} */
  130. protected MinOptMax getExtraIPD(boolean isNotFirst, boolean isNotLast) {
  131. int borderAndPadding = 0;
  132. if (borderProps != null) {
  133. borderAndPadding
  134. = borderProps.getPadding(CommonBorderPaddingBackground.START, isNotFirst, this);
  135. borderAndPadding
  136. += borderProps.getBorderWidth(CommonBorderPaddingBackground.START, isNotFirst);
  137. borderAndPadding
  138. += borderProps.getPadding(CommonBorderPaddingBackground.END, isNotLast, this);
  139. borderAndPadding
  140. += borderProps.getBorderWidth(CommonBorderPaddingBackground.END, isNotLast);
  141. }
  142. return new MinOptMax(borderAndPadding);
  143. }
  144. /** {@inheritDoc} */
  145. protected boolean hasLeadingFence(boolean isNotFirst) {
  146. return borderProps != null
  147. && (borderProps.getPadding(CommonBorderPaddingBackground.START, isNotFirst, this) > 0
  148. || borderProps.getBorderWidth(CommonBorderPaddingBackground.START, isNotFirst) > 0
  149. );
  150. }
  151. /** {@inheritDoc} */
  152. protected boolean hasTrailingFence(boolean isNotLast) {
  153. return borderProps != null
  154. && (borderProps.getPadding(CommonBorderPaddingBackground.END, isNotLast, this) > 0
  155. || borderProps.getBorderWidth(CommonBorderPaddingBackground.END, isNotLast) > 0
  156. );
  157. }
  158. /** {@inheritDoc} */
  159. protected SpaceProperty getSpaceStart() {
  160. return inlineProps != null ? inlineProps.spaceStart : null;
  161. }
  162. /** {@inheritDoc} */
  163. protected SpaceProperty getSpaceEnd() {
  164. return inlineProps != null ? inlineProps.spaceEnd : null;
  165. }
  166. /**
  167. * Create and initialize an <code>InlineArea</code>
  168. *
  169. * @param hasInlineParent true if the parent is an inline
  170. * @return the area
  171. */
  172. protected InlineArea createArea(boolean hasInlineParent) {
  173. InlineArea area;
  174. if (hasInlineParent) {
  175. area = new InlineParent();
  176. area.setOffset(0);
  177. } else {
  178. area = new InlineBlockParent();
  179. }
  180. if (fobj instanceof Inline) {
  181. TraitSetter.setProducerID(area, getInlineFO().getId());
  182. }
  183. return area;
  184. }
  185. /** {@inheritDoc} */
  186. protected void setTraits(boolean isNotFirst, boolean isNotLast) {
  187. if (borderProps != null) {
  188. // Add border and padding to current area and set flags (FIRST, LAST ...)
  189. TraitSetter.setBorderPaddingTraits(getCurrentArea(),
  190. borderProps, isNotFirst, isNotLast, this);
  191. TraitSetter.addBackground(getCurrentArea(), borderProps, this);
  192. }
  193. }
  194. /**
  195. * @return true if this element must be kept together
  196. */
  197. public boolean mustKeepTogether() {
  198. return mustKeepTogether(this.getParent());
  199. }
  200. private boolean mustKeepTogether(LayoutManager lm) {
  201. if (lm instanceof BlockLevelLayoutManager) {
  202. return ((BlockLevelLayoutManager) lm).mustKeepTogether();
  203. } else if (lm instanceof InlineLayoutManager) {
  204. return ((InlineLayoutManager) lm).mustKeepTogether();
  205. } else {
  206. return mustKeepTogether(lm.getParent());
  207. }
  208. }
  209. /** {@inheritDoc} */
  210. public List getNextKnuthElements(LayoutContext context, int alignment) {
  211. LayoutManager curLM;
  212. // the list returned by child LM
  213. List returnedList;
  214. // the list which will be returned to the parent LM
  215. List returnList = new LinkedList();
  216. KnuthSequence lastSequence = null;
  217. if (fobj instanceof Title) {
  218. alignmentContext = new AlignmentContext(font,
  219. lineHeight.getOptimum(this).getLength().getValue(this),
  220. context.getWritingMode());
  221. } else {
  222. alignmentContext = new AlignmentContext(font
  223. , lineHeight.getOptimum(this).getLength().getValue(this)
  224. , alignmentAdjust
  225. , alignmentBaseline
  226. , baselineShift
  227. , dominantBaseline
  228. , context.getAlignmentContext());
  229. }
  230. childLC = new LayoutContext(context);
  231. childLC.setAlignmentContext(alignmentContext);
  232. if (context.startsNewArea()) {
  233. // First call to this LM in new parent "area", but this may
  234. // not be the first area created by this inline
  235. if (getSpaceStart() != null) {
  236. context.getLeadingSpace().addSpace(new SpaceVal(getSpaceStart(), this));
  237. }
  238. }
  239. StringBuffer trace = new StringBuffer("InlineLM:");
  240. // We'll add the border to the first inline sequence created.
  241. // This flag makes sure we do it only once.
  242. boolean borderAdded = false;
  243. if (borderProps != null) {
  244. childLC.setLineStartBorderAndPaddingWidth(context.getLineStartBorderAndPaddingWidth()
  245. + borderProps.getPaddingStart(true, this)
  246. + borderProps.getBorderStartWidth(true)
  247. );
  248. childLC.setLineEndBorderAndPaddingWidth(context.getLineEndBorderAndPaddingWidth()
  249. + borderProps.getPaddingEnd(true, this)
  250. + borderProps.getBorderEndWidth(true)
  251. );
  252. }
  253. while ((curLM = getChildLM()) != null) {
  254. if (!(curLM instanceof InlineLevelLayoutManager)) {
  255. // A block LM
  256. // Leave room for start/end border and padding
  257. if (borderProps != null) {
  258. childLC.setRefIPD(childLC.getRefIPD()
  259. - borderProps.getPaddingStart(lastChildLM != null, this)
  260. - borderProps.getBorderStartWidth(lastChildLM != null)
  261. - borderProps.getPaddingEnd(hasNextChildLM(), this)
  262. - borderProps.getBorderEndWidth(hasNextChildLM()));
  263. }
  264. }
  265. // get KnuthElements from curLM
  266. returnedList = curLM.getNextKnuthElements(childLC, alignment);
  267. if (returnList.isEmpty() && childLC.isKeepWithPreviousPending()) {
  268. childLC.clearKeepWithPreviousPending();
  269. }
  270. if (returnedList == null
  271. || returnedList.isEmpty()) {
  272. // curLM returned null or an empty list, because it finished;
  273. // just iterate once more to see if there is another child
  274. continue;
  275. }
  276. if (curLM instanceof InlineLevelLayoutManager) {
  277. context.clearKeepWithNextPending();
  278. // "wrap" the Position stored in each element of returnedList
  279. ListIterator seqIter = returnedList.listIterator();
  280. while (seqIter.hasNext()) {
  281. KnuthSequence sequence = (KnuthSequence) seqIter.next();
  282. sequence.wrapPositions(this);
  283. }
  284. if (lastSequence != null && lastSequence.appendSequenceOrClose
  285. ((KnuthSequence) returnedList.get(0))) {
  286. returnedList.remove(0);
  287. }
  288. // add border and padding to the first complete sequence of this LM
  289. if (!borderAdded && !returnedList.isEmpty()) {
  290. addKnuthElementsForBorderPaddingStart((KnuthSequence) returnedList.get(0));
  291. borderAdded = true;
  292. }
  293. returnList.addAll(returnedList);
  294. } else { // A block LM
  295. BlockKnuthSequence sequence = new BlockKnuthSequence(returnedList);
  296. sequence.wrapPositions(this);
  297. boolean appended = false;
  298. if (lastSequence != null) {
  299. if (lastSequence.canAppendSequence(sequence)) {
  300. BreakElement bk = new BreakElement(new Position(this), 0, context);
  301. boolean keepTogether = (mustKeepTogether()
  302. || context.isKeepWithNextPending()
  303. || childLC.isKeepWithPreviousPending());
  304. appended = lastSequence.appendSequenceOrClose(sequence, keepTogether, bk);
  305. } else {
  306. lastSequence.endSequence();
  307. }
  308. }
  309. if (!appended) {
  310. // add border and padding to the first complete sequence of this LM
  311. if (!borderAdded) {
  312. addKnuthElementsForBorderPaddingStart(sequence);
  313. borderAdded = true;
  314. }
  315. returnList.add(sequence);
  316. }
  317. // propagate and clear
  318. context.updateKeepWithNextPending(childLC.getKeepWithNextPending());
  319. childLC.clearKeepsPending();
  320. }
  321. lastSequence = (KnuthSequence) ListUtil.getLast(returnList);
  322. lastChildLM = curLM;
  323. }
  324. if (lastSequence != null) {
  325. addKnuthElementsForBorderPaddingEnd(lastSequence);
  326. }
  327. setFinished(true);
  328. log.trace(trace);
  329. if (returnList.isEmpty()) {
  330. /*
  331. * if the FO itself is empty, but has an id specified
  332. * or associated fo:markers, then we still need a dummy
  333. * sequence to register its position in the area tree
  334. */
  335. if (fobj.hasId() || fobj.hasMarkers()) {
  336. InlineKnuthSequence emptySeq = new InlineKnuthSequence();
  337. emptySeq.add(new KnuthInlineBox(
  338. 0,
  339. alignmentContext,
  340. notifyPos(getAuxiliaryPosition()),
  341. true));
  342. returnList.add(emptySeq);
  343. }
  344. }
  345. return returnList.isEmpty() ? null : returnList;
  346. }
  347. /**
  348. * Generate and add areas to parent area.
  349. * Set size of each area. This should only create and return one
  350. * inline area for any inline parent area.
  351. *
  352. * @param parentIter Iterator over Position information returned
  353. * by this LayoutManager.
  354. * @param context layout context.
  355. */
  356. public void addAreas(PositionIterator parentIter,
  357. LayoutContext context) {
  358. addId();
  359. setChildContext(new LayoutContext(context)); // Store current value
  360. // If this LM has fence, make a new leading space specifier.
  361. if (hasLeadingFence(areaCreated)) {
  362. getContext().setLeadingSpace(new SpaceSpecifier(false));
  363. getContext().setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true);
  364. } else {
  365. getContext().setFlags(LayoutContext.RESOLVE_LEADING_SPACE, false);
  366. }
  367. if (getSpaceStart() != null) {
  368. context.getLeadingSpace().addSpace(new SpaceVal(getSpaceStart(), this));
  369. }
  370. // "Unwrap" the NonLeafPositions stored in parentIter and put
  371. // them in a new list. Set lastLM to be the LayoutManager
  372. // which created the last Position: if the LAST_AREA flag is
  373. // set in the layout context, it must be also set in the
  374. // layout context given to lastLM, but must be cleared in the
  375. // layout context given to the other LMs.
  376. List positionList = new LinkedList();
  377. NonLeafPosition pos;
  378. LayoutManager lastLM = null;// last child LM in this iterator
  379. Position lastPos = null;
  380. while (parentIter.hasNext()) {
  381. pos = (NonLeafPosition) parentIter.next();
  382. if (pos != null && pos.getPosition() != null) {
  383. positionList.add(pos.getPosition());
  384. lastLM = pos.getPosition().getLM();
  385. lastPos = pos;
  386. }
  387. }
  388. /*if (pos != null) {
  389. lastLM = pos.getPosition().getLM();
  390. }*/
  391. addMarkersToPage(
  392. true,
  393. !areaCreated,
  394. lastPos == null || isLast(lastPos));
  395. InlineArea parent = createArea(lastLM == null
  396. || lastLM instanceof InlineLevelLayoutManager);
  397. parent.setBPD(alignmentContext.getHeight());
  398. if (parent instanceof InlineParent) {
  399. parent.setOffset(alignmentContext.getOffset());
  400. } else if (parent instanceof InlineBlockParent) {
  401. // All inline elements are positioned by the renderers relative to
  402. // the before edge of their content rectangle
  403. if (borderProps != null) {
  404. parent.setOffset(borderProps.getPaddingBefore(false, this)
  405. + borderProps.getBorderBeforeWidth(false));
  406. }
  407. }
  408. setCurrentArea(parent);
  409. StackingIter childPosIter
  410. = new StackingIter(positionList.listIterator());
  411. LayoutManager prevLM = null;
  412. LayoutManager childLM;
  413. while ((childLM = childPosIter.getNextChildLM()) != null) {
  414. getContext().setFlags(LayoutContext.LAST_AREA,
  415. context.isLastArea() && childLM == lastLM);
  416. childLM.addAreas(childPosIter, getContext());
  417. getContext().setLeadingSpace(getContext().getTrailingSpace());
  418. getContext().setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true);
  419. prevLM = childLM;
  420. }
  421. /* If this LM has a trailing fence, resolve trailing space
  422. * specs from descendants. Otherwise, propagate any trailing
  423. * space specs to the parent LM via the layout context. If
  424. * the last child LM called returns LAST_AREA in the layout
  425. * context and it is the last child LM for this LM, then this
  426. * must be the last area for the current LM too.
  427. */
  428. boolean isLast = (getContext().isLastArea() && prevLM == lastChildLM);
  429. if (hasTrailingFence(isLast)) {
  430. addSpace(getCurrentArea(),
  431. getContext().getTrailingSpace().resolve(false),
  432. getContext().getSpaceAdjust());
  433. context.setTrailingSpace(new SpaceSpecifier(false));
  434. } else {
  435. // Propagate trailing space-spec sequence to parent LM in context.
  436. context.setTrailingSpace(getContext().getTrailingSpace());
  437. }
  438. // Add own trailing space to parent context (or set on area?)
  439. if (context.getTrailingSpace() != null && getSpaceEnd() != null) {
  440. context.getTrailingSpace().addSpace(new SpaceVal(getSpaceEnd(), this));
  441. }
  442. // Not sure if lastPos can legally be null or if that masks a different problem.
  443. // But it seems to fix bug 38053.
  444. setTraits(areaCreated, lastPos == null || !isLast(lastPos));
  445. parentLM.addChildArea(getCurrentArea());
  446. addMarkersToPage(
  447. false,
  448. !areaCreated,
  449. lastPos == null || isLast(lastPos));
  450. context.setFlags(LayoutContext.LAST_AREA, isLast);
  451. areaCreated = true;
  452. checkEndOfLayout(lastPos);
  453. }
  454. /** {@inheritDoc} */
  455. public void addChildArea(Area childArea) {
  456. Area parent = getCurrentArea();
  457. if (getContext().resolveLeadingSpace()) {
  458. addSpace(parent,
  459. getContext().getLeadingSpace().resolve(false),
  460. getContext().getSpaceAdjust());
  461. }
  462. parent.addChildArea(childArea);
  463. }
  464. /** {@inheritDoc} */
  465. public List getChangedKnuthElements(List oldList, int alignment) {
  466. List returnedList = new LinkedList();
  467. addKnuthElementsForBorderPaddingStart(returnedList);
  468. returnedList.addAll(super.getChangedKnuthElements(oldList, alignment));
  469. addKnuthElementsForBorderPaddingEnd(returnedList);
  470. return returnedList;
  471. }
  472. /**
  473. * Creates Knuth elements for start border padding and adds them to the return list.
  474. * @param returnList return list to add the additional elements to
  475. */
  476. protected void addKnuthElementsForBorderPaddingStart(List returnList) {
  477. //Border and Padding (start)
  478. /**
  479. * If the returnlist is a BlockKnuthSequence, the border and padding should be added
  480. * to the first paragraph inside it, but it is too late to do that now.
  481. * At least, avoid adding it to the bpd sequence.
  482. */
  483. if (returnList instanceof BlockKnuthSequence) {
  484. return;
  485. }
  486. CommonBorderPaddingBackground borderAndPadding =
  487. ((InlineLevel)fobj).getCommonBorderPaddingBackground();
  488. if (borderAndPadding != null) {
  489. int ipStart = borderAndPadding.getBorderStartWidth(false)
  490. + borderAndPadding.getPaddingStart(false, this);
  491. if (ipStart > 0) {
  492. returnList.add(0,new KnuthBox(ipStart, getAuxiliaryPosition(), true));
  493. }
  494. }
  495. }
  496. /**
  497. * Creates Knuth elements for end border padding and adds them to the return list.
  498. * @param returnList return list to add the additional elements to
  499. */
  500. protected void addKnuthElementsForBorderPaddingEnd(List returnList) {
  501. //Border and Padding (after)
  502. /**
  503. * If the returnlist is a BlockKnuthSequence, the border and padding should be added
  504. * to the last paragraph inside it, but it is too late to do that now.
  505. * At least, avoid adding it to the bpd sequence.
  506. */
  507. if (returnList instanceof BlockKnuthSequence) {
  508. return;
  509. }
  510. CommonBorderPaddingBackground borderAndPadding =
  511. ((InlineLevel)fobj).getCommonBorderPaddingBackground();
  512. if (borderAndPadding != null) {
  513. int ipEnd = borderAndPadding.getBorderEndWidth(false)
  514. + borderAndPadding.getPaddingEnd(false, this);
  515. if (ipEnd > 0) {
  516. returnList.add(new KnuthBox(ipEnd, getAuxiliaryPosition(), true));
  517. }
  518. }
  519. }
  520. /** @return a cached auxiliary Position instance used for things like spaces. */
  521. protected Position getAuxiliaryPosition() {
  522. //if (this.auxiliaryPosition == null) {
  523. //this.auxiliaryPosition = new NonLeafPosition(this, new LeafPosition(this, -1));
  524. this.auxiliaryPosition = new NonLeafPosition(this, null);
  525. //}
  526. return this.auxiliaryPosition;
  527. }
  528. }