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.

LeafNodeLayoutManager.java 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*
  2. * Copyright 1999-2004 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /* $Id$ */
  17. package org.apache.fop.layoutmgr;
  18. import org.apache.fop.area.Area;
  19. import org.apache.fop.area.inline.InlineArea;
  20. import org.apache.fop.traits.MinOptMax;
  21. /**
  22. * Base LayoutManager for leaf-node FObj, ie: ones which have no children.
  23. * These are all inline objects. Most of them cannot be split (Text is
  24. * an exception to this rule.)
  25. * This class can be extended to handle the creation and adding of the
  26. * inline area.
  27. */
  28. public class LeafNodeLayoutManager extends AbstractLayoutManager {
  29. /**
  30. * The inline area that this leafnode will add.
  31. */
  32. protected InlineArea curArea = null;
  33. private int alignment;
  34. private int lead;
  35. private MinOptMax ipd;
  36. /**
  37. * Create a Leaf node layout mananger.
  38. */
  39. public LeafNodeLayoutManager() {
  40. }
  41. /**
  42. * get the inline area.
  43. * @param context the context used to create the area
  44. * @return the current inline area for this layout manager
  45. */
  46. public InlineArea get(LayoutContext context) {
  47. return curArea;
  48. }
  49. /**
  50. * Check if this generates inline areas.
  51. * @return true always since this is an inline area manager
  52. */
  53. public boolean generatesInlineAreas() {
  54. return true;
  55. }
  56. /**
  57. * Check if this inline area is resolved due to changes in
  58. * page or ipd.
  59. * Currently not used.
  60. * @return true if the area is resolved when adding
  61. */
  62. public boolean resolved() {
  63. return false;
  64. }
  65. /**
  66. * Set the current inline area.
  67. * @param ia the inline area to set for this layout manager
  68. */
  69. public void setCurrentArea(InlineArea ia) {
  70. curArea = ia;
  71. }
  72. /**
  73. * Set the alignment of the inline area.
  74. * @param al the vertical alignment positioning
  75. */
  76. public void setAlignment(int al) {
  77. alignment = al;
  78. }
  79. /**
  80. * Set the lead for this inline area.
  81. * The lead is the distance from the top of the object
  82. * to the baseline.
  83. * Currently not used.
  84. * @param l the lead value
  85. */
  86. public void setLead(int l) {
  87. lead = l;
  88. }
  89. /**
  90. * This is a leaf-node, so this method is never called.
  91. * @param childArea the childArea to add
  92. */
  93. public void addChild(Area childArea) {
  94. }
  95. /**
  96. * This is a leaf-node, so this method is never called.
  97. * @param childArea the childArea to get the parent for
  98. * @return the parent area
  99. */
  100. public Area getParentArea(Area childArea) {
  101. return null;
  102. }
  103. /**
  104. * Get the next break position.
  105. * Since this holds an inline area it will return a single
  106. * break position.
  107. * @param context the layout context for this inline area
  108. * @return the break poisition for adding this inline area
  109. */
  110. public BreakPoss getNextBreakPoss(LayoutContext context) {
  111. curArea = get(context);
  112. if (curArea == null) {
  113. setFinished(true);
  114. return null;
  115. }
  116. BreakPoss bp = new BreakPoss(new LeafPosition(this, 0),
  117. BreakPoss.CAN_BREAK_AFTER
  118. | BreakPoss.CAN_BREAK_BEFORE | BreakPoss.ISFIRST
  119. | BreakPoss.ISLAST);
  120. ipd = getAllocationIPD(context.getRefIPD());
  121. bp.setStackingSize(ipd);
  122. bp.setNonStackingSize(new MinOptMax(curArea.getHeight()));
  123. bp.setTrailingSpace(new SpaceSpecifier(false));
  124. int bpd = curArea.getHeight();
  125. switch (alignment) {
  126. case VerticalAlign.MIDDLE:
  127. bp.setMiddle(bpd / 2 /* - fontLead/2 */);
  128. bp.setLead(bpd / 2 /* + fontLead/2 */);
  129. break;
  130. case VerticalAlign.TOP:
  131. bp.setTotal(bpd);
  132. break;
  133. case VerticalAlign.BOTTOM:
  134. bp.setTotal(bpd);
  135. break;
  136. case VerticalAlign.BASELINE:
  137. default:
  138. bp.setLead(bpd);
  139. break;
  140. }
  141. setFinished(true);
  142. return bp;
  143. }
  144. /**
  145. * Get the allocation ipd of the inline area.
  146. * This method may be overridden to handle percentage values.
  147. * @param refIPD the ipd of the parent reference area
  148. * @return the min/opt/max ipd of the inline area
  149. */
  150. protected MinOptMax getAllocationIPD(int refIPD) {
  151. return new MinOptMax(curArea.getIPD());
  152. }
  153. /**
  154. * Reset the position.
  155. * If the reset position is null then this inline area should be
  156. * restarted.
  157. * @param resetPos the position to reset.
  158. */
  159. public void resetPosition(Position resetPos) {
  160. // only reset if setting null, start again
  161. if (resetPos == null) {
  162. setFinished(false);
  163. }
  164. }
  165. /**
  166. * Add the area for this layout manager.
  167. * This adds the single inline area to the parent.
  168. * @param posIter the position iterator
  169. * @param context the layout context for adding the area
  170. */
  171. public void addAreas(PositionIterator posIter, LayoutContext context) {
  172. parentLM.addChild(curArea);
  173. addID();
  174. offsetArea(context);
  175. widthAdjustArea(context);
  176. while (posIter.hasNext()) {
  177. posIter.next();
  178. }
  179. }
  180. /**
  181. * Offset this area.
  182. * Offset the inline area in the bpd direction when adding the
  183. * inline area.
  184. * This is used for vertical alignment.
  185. * Subclasses should override this if necessary.
  186. * @param context the layout context used for adding the area
  187. */
  188. protected void offsetArea(LayoutContext context) {
  189. int bpd = curArea.getHeight();
  190. switch (alignment) {
  191. case VerticalAlign.MIDDLE:
  192. curArea.setOffset(context.getBaseline() - bpd / 2 /* - fontLead/2 */);
  193. break;
  194. case VerticalAlign.TOP:
  195. //curArea.setOffset(0);
  196. break;
  197. case VerticalAlign.BOTTOM:
  198. curArea.setOffset(context.getLineHeight() - bpd);
  199. break;
  200. case VerticalAlign.BASELINE:
  201. default:
  202. curArea.setOffset(context.getBaseline() - bpd);
  203. break;
  204. }
  205. }
  206. /**
  207. * Adjust the width of the area when adding.
  208. * This uses the min/opt/max values to adjust the with
  209. * of the inline area by a percentage.
  210. * @param context the layout context for adding this area
  211. */
  212. protected void widthAdjustArea(LayoutContext context) {
  213. double dAdjust = context.getIPDAdjust();
  214. int width = ipd.opt;
  215. if (dAdjust < 0) {
  216. width = (int)(width + dAdjust * (ipd.opt - ipd.min));
  217. } else if (dAdjust > 0) {
  218. width = (int)(width + dAdjust * (ipd.max - ipd.opt));
  219. }
  220. curArea.setWidth(width);
  221. }
  222. /**
  223. * Check if can break before this area.
  224. * @param context the layout context to check for the break
  225. * @return true if can break before this area in the context
  226. */
  227. public boolean canBreakBefore(LayoutContext context) {
  228. return true;
  229. }
  230. }