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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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.area;
  19. import java.util.List;
  20. import org.apache.fop.fo.Constants;
  21. import org.apache.fop.traits.WritingModeTraitsGetter;
  22. /**
  23. * The span-reference-area.
  24. * This is a block-area with 0 border and padding that is stacked
  25. * within the main-reference-area
  26. * This object holds one or more normal-flow-reference-area children
  27. * based on the column-count trait in effect for this span.
  28. * See fo:region-body definition in the XSL Rec for more information.
  29. */
  30. public class Span extends Area {
  31. private static final long serialVersionUID = -5551430053660081549L;
  32. // the list of flow reference areas in this span area
  33. private List<NormalFlow> flowAreas;
  34. private int colCount;
  35. private int colGap;
  36. private int colWidth; // width for each normal flow, calculated value
  37. private int curFlowIdx; // n-f-r-a currently being processed, zero-based
  38. /**
  39. * Create a span area with the number of columns for this span area.
  40. *
  41. * @param colCount the number of columns in the span
  42. * @param colGap the column gap between each column
  43. * @param ipd the total ipd of the span
  44. */
  45. public Span(int colCount, int colGap, int ipd) {
  46. addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
  47. this.colCount = colCount;
  48. this.colGap = colGap;
  49. this.ipd = ipd;
  50. curFlowIdx = 0;
  51. createNormalFlows();
  52. }
  53. /**
  54. * Create the normal flows for this Span
  55. */
  56. private void createNormalFlows() {
  57. flowAreas = new java.util.ArrayList<NormalFlow>(colCount);
  58. colWidth = (ipd - ((colCount - 1) * colGap)) / colCount;
  59. for (int i = 0; i < colCount; i++) {
  60. NormalFlow newFlow = new NormalFlow(colWidth);
  61. flowAreas.add(newFlow);
  62. }
  63. }
  64. /**
  65. * Get the column count for this span area.
  66. *
  67. * @return the number of columns defined for this span area
  68. */
  69. public int getColumnCount() {
  70. return colCount;
  71. }
  72. /**
  73. * Get the column gap for this span area.
  74. *
  75. * @return the column gap for this span area
  76. */
  77. public int getColumnGap() {
  78. return colGap;
  79. }
  80. /**
  81. * Get the width of a single column within this Span
  82. *
  83. * @return the width of a single column
  84. */
  85. public int getColumnWidth() {
  86. return colWidth;
  87. }
  88. /**
  89. * Get the height of this span area.
  90. *
  91. * @return the height of this span area
  92. */
  93. public int getHeight() {
  94. return getBPD();
  95. }
  96. /**
  97. * Get the normal flow area for a particular column.
  98. *
  99. * @param colRequested the zero-based column number of the flow
  100. * @return the flow area for the requested column
  101. */
  102. public NormalFlow getNormalFlow(int colRequested) {
  103. if (colRequested >= 0 && colRequested < colCount) {
  104. return flowAreas.get(colRequested);
  105. } else { // internal error
  106. throw new IllegalArgumentException("Invalid column number "
  107. + colRequested + " requested; only 0-" + (colCount - 1)
  108. + " available.");
  109. }
  110. }
  111. /**
  112. * Get the NormalFlow area currently being processed
  113. *
  114. * @return the current NormalFlow
  115. */
  116. public NormalFlow getCurrentFlow() {
  117. return getNormalFlow(curFlowIdx);
  118. }
  119. /** @return the index of the current normal flow */
  120. public int getCurrentFlowIndex() {
  121. return curFlowIdx;
  122. }
  123. /**
  124. * Indicate to the Span that the next column is being
  125. * processed.
  126. *
  127. * @return the new NormalFlow (in the next column)
  128. */
  129. public NormalFlow moveToNextFlow() {
  130. if (hasMoreFlows()) {
  131. curFlowIdx++;
  132. return getNormalFlow(curFlowIdx);
  133. } else {
  134. throw new IllegalStateException("(Internal error.) No more flows left in span.");
  135. }
  136. }
  137. /**
  138. * Indicates if the Span has unprocessed flows.
  139. *
  140. * @return true if Span can increment to the next flow,
  141. * false otherwise.
  142. */
  143. public boolean hasMoreFlows() {
  144. return (curFlowIdx < colCount - 1);
  145. }
  146. /**
  147. * Called to notify the span that all its flows have been fully generated so it can update
  148. * its own BPD extent.
  149. */
  150. public void notifyFlowsFinished() {
  151. int maxFlowBPD = Integer.MIN_VALUE;
  152. for (int i = 0; i < colCount; i++) {
  153. maxFlowBPD = Math.max(maxFlowBPD, getNormalFlow(i).getAllocBPD());
  154. }
  155. bpd = maxFlowBPD;
  156. }
  157. /**
  158. * Indicates whether any child areas have been added to this span area.
  159. *
  160. * This is achieved by looping through each flow.
  161. * @return true if no child areas have been added yet.
  162. */
  163. public boolean isEmpty() {
  164. int areaCount = 0;
  165. for (int i = 0; i < getColumnCount(); i++) {
  166. NormalFlow flow = getNormalFlow(i);
  167. if (flow != null) {
  168. if (flow.getChildAreas() != null) {
  169. areaCount += flow.getChildAreas().size();
  170. }
  171. }
  172. }
  173. return (areaCount == 0);
  174. }
  175. /**
  176. * Sets the writing mode traits for the main reference area of
  177. * this span area.
  178. * @param wmtg a WM traits getter
  179. */
  180. public void setWritingModeTraits(WritingModeTraitsGetter wmtg) {
  181. switch (wmtg.getColumnProgressionDirection().getEnumValue()) {
  182. case Constants.EN_RL:
  183. setBidiLevel(1);
  184. for (NormalFlow flowArea1 : flowAreas) {
  185. flowArea1.setBidiLevel(1);
  186. }
  187. break;
  188. default:
  189. resetBidiLevel();
  190. for (NormalFlow flowArea : flowAreas) {
  191. flowArea.resetBidiLevel();
  192. }
  193. break;
  194. }
  195. addTrait(Trait.INLINE_PROGRESSION_DIRECTION, wmtg.getInlineProgressionDirection());
  196. addTrait(Trait.BLOCK_PROGRESSION_DIRECTION, wmtg.getBlockProgressionDirection());
  197. }
  198. /** {@inheritDoc} */
  199. @Override
  200. public String toString() {
  201. StringBuffer sb = new StringBuffer(super.toString());
  202. if (colCount > 1) {
  203. sb.append(" {colCount=").append(colCount);
  204. sb.append(", colWidth=").append(colWidth);
  205. sb.append(", curFlowIdx=").append(this.curFlowIdx);
  206. sb.append("}");
  207. }
  208. return sb.toString();
  209. }
  210. }