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.

BlockArea.java 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /*
  2. * $Id$
  3. * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
  4. * For details on use and redistribution please refer to the
  5. * LICENSE file included with these sources.
  6. */
  7. package org.apache.fop.layout;
  8. // FOP
  9. import org.apache.fop.render.Renderer;
  10. import org.apache.fop.fo.flow.*;
  11. import org.apache.fop.fo.*;
  12. import org.apache.fop.apps.*;
  13. import org.apache.fop.fo.properties.*;
  14. // Java
  15. import java.util.Vector;
  16. import java.util.Enumeration;
  17. import org.apache.fop.messaging.MessageHandler;
  18. /**
  19. * This class represents a Block Area.
  20. * A block area is made up of a sequence of Line Areas.
  21. *
  22. * This class is used to organise the sequence of line areas as
  23. * inline areas are added to this block it creates and ands line areas
  24. * to hold the inline areas.
  25. * This uses the line-height and line-stacking-strategy to work
  26. * out how to stack the lines.
  27. */
  28. public class BlockArea extends Area {
  29. /* relative to area container */
  30. protected int startIndent;
  31. protected int endIndent;
  32. /* first line startIndent modifier */
  33. protected int textIndent;
  34. protected int lineHeight;
  35. protected int halfLeading;
  36. /* text-align of all but the last line */
  37. protected int align;
  38. /* text-align of the last line */
  39. protected int alignLastLine;
  40. protected LineArea currentLineArea;
  41. protected LinkSet currentLinkSet;
  42. /* have any line areas been used? */
  43. protected boolean hasLines = false;
  44. /* hyphenation */
  45. protected HyphenationProps hyphProps;
  46. protected Vector pendingFootnotes = null;
  47. public BlockArea(FontState fontState, int allocationWidth, int maxHeight,
  48. int startIndent, int endIndent, int textIndent,
  49. int align, int alignLastLine, int lineHeight) {
  50. super(fontState, allocationWidth, maxHeight);
  51. this.startIndent = startIndent;
  52. this.endIndent = endIndent;
  53. this.textIndent = textIndent;
  54. this.contentRectangleWidth = allocationWidth - startIndent
  55. - endIndent;
  56. this.align = align;
  57. this.alignLastLine = alignLastLine;
  58. this.lineHeight = lineHeight;
  59. if (fontState != null)
  60. this.halfLeading = (lineHeight - fontState.getFontSize()) / 2;
  61. }
  62. /**
  63. * Add a Line Area to this block area.
  64. * Used internally to add a completed line area to this block area
  65. * when either a new line area is created or this block area is
  66. * completed.
  67. *
  68. * @param la the LineArea to add
  69. */
  70. protected void addLineArea(LineArea la) {
  71. if (!la.isEmpty()) {
  72. la.verticalAlign();
  73. this.addDisplaySpace(this.halfLeading);
  74. int size = la.getHeight();
  75. this.addChild(la);
  76. this.increaseHeight(size);
  77. this.addDisplaySpace(this.halfLeading);
  78. }
  79. // add pending footnotes
  80. if (pendingFootnotes != null) {
  81. for (Enumeration e = pendingFootnotes.elements();
  82. e.hasMoreElements(); ) {
  83. FootnoteBody fb = (FootnoteBody)e.nextElement();
  84. Page page = getPage();
  85. if (!Footnote.layoutFootnote(page, fb, this)) {
  86. page.addPendingFootnote(fb);
  87. }
  88. }
  89. pendingFootnotes = null;
  90. }
  91. }
  92. /**
  93. * Get the current line area in this block area.
  94. * This is used to get the current line area for adding
  95. * inline objects to.
  96. * This will return null if there is not enough room left
  97. * in the block area to accomodate the line area.
  98. *
  99. * @return the line area to be used to add inlie objects
  100. */
  101. public LineArea getCurrentLineArea() {
  102. if (currentHeight + lineHeight > maxHeight) {
  103. return null;
  104. }
  105. this.currentLineArea.changeHyphenation(hyphProps);
  106. this.hasLines = true;
  107. return this.currentLineArea;
  108. }
  109. /**
  110. * Create a new line area to add inline objects.
  111. * This should be called after getting the current line area
  112. * and discovering that the inline object will not fit inside the current
  113. * line. This method will create a new line area to place the inline
  114. * object into.
  115. * This will return null if the new line cannot fit into the block area.
  116. *
  117. * @return the new current line area, which will be empty.
  118. */
  119. public LineArea createNextLineArea() {
  120. if (this.hasLines) {
  121. this.currentLineArea.align(this.align);
  122. this.addLineArea(this.currentLineArea);
  123. }
  124. this.currentLineArea = new LineArea(fontState, lineHeight,
  125. halfLeading, allocationWidth,
  126. startIndent, endIndent,
  127. currentLineArea);
  128. this.currentLineArea.changeHyphenation(hyphProps);
  129. if (currentHeight + lineHeight > maxHeight) {
  130. return null;
  131. }
  132. return this.currentLineArea;
  133. }
  134. public void setupLinkSet(LinkSet ls) {
  135. if (ls != null) {
  136. this.currentLinkSet = ls;
  137. ls.setYOffset(currentHeight);
  138. }
  139. }
  140. /**
  141. * Notify this block that the area has completed layout.
  142. * Indicates the the block has been fully laid out, this will
  143. * add (if any) the current line area.
  144. */
  145. public void end() {
  146. if (this.hasLines) {
  147. this.currentLineArea.addPending();
  148. this.currentLineArea.align(this.alignLastLine);
  149. this.addLineArea(this.currentLineArea);
  150. }
  151. }
  152. public void start() {
  153. currentLineArea = new LineArea(fontState, lineHeight, halfLeading,
  154. allocationWidth,
  155. startIndent + textIndent, endIndent,
  156. null);
  157. }
  158. public int getEndIndent() {
  159. return endIndent;
  160. }
  161. // KL: I think we should just return startIndent here!
  162. public int getStartIndent() {
  163. // return startIndent + paddingLeft + borderWidthLeft;
  164. return startIndent;
  165. }
  166. public void setIndents(int startIndent, int endIndent) {
  167. this.startIndent = startIndent;
  168. this.endIndent = endIndent;
  169. this.contentRectangleWidth = allocationWidth - startIndent
  170. - endIndent;
  171. }
  172. /**
  173. * Return the maximum space remaining for this area's content in
  174. * the block-progression-dimension.
  175. * Remove top and bottom padding and spacing since these reduce
  176. * available space for content and they are not yet accounted for
  177. * in the positioning of the object.
  178. */
  179. public int spaceLeft() {
  180. // return maxHeight - currentHeight ;
  181. return maxHeight - currentHeight -
  182. (getPaddingTop() + getPaddingBottom()
  183. + getBorderTopWidth() + getBorderBottomWidth());
  184. }
  185. public int getHalfLeading() {
  186. return halfLeading;
  187. }
  188. public void setHyphenation(HyphenationProps hyphProps) {
  189. this.hyphProps = hyphProps;
  190. }
  191. public void addFootnote(FootnoteBody fb) {
  192. if (pendingFootnotes == null) {
  193. pendingFootnotes = new Vector();
  194. }
  195. pendingFootnotes.addElement(fb);
  196. }
  197. }