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.

TableFObj.java 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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.fo.flow.table;
  19. import org.apache.fop.apps.FOPException;
  20. import org.apache.fop.datatypes.Numeric;
  21. import org.apache.fop.datatypes.ValidationPercentBaseContext;
  22. import org.apache.fop.fo.Constants;
  23. import org.apache.fop.fo.FONode;
  24. import org.apache.fop.fo.FObj;
  25. import org.apache.fop.fo.PropertyList;
  26. import org.apache.fop.fo.expr.PropertyException;
  27. import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
  28. import org.apache.fop.fo.properties.NumberProperty;
  29. import org.apache.fop.fo.properties.Property;
  30. import org.apache.fop.layoutmgr.table.CollapsingBorderModel;
  31. /**
  32. * Common base class for table-related FOs
  33. */
  34. public abstract class TableFObj extends FObj {
  35. private Numeric borderAfterPrecedence;
  36. private Numeric borderBeforePrecedence;
  37. private Numeric borderEndPrecedence;
  38. private Numeric borderStartPrecedence;
  39. ConditionalBorder borderBefore;
  40. ConditionalBorder borderAfter;
  41. BorderSpecification borderStart;
  42. BorderSpecification borderEnd;
  43. CollapsingBorderModel collapsingBorderModel;
  44. /**
  45. * Main constructor
  46. *
  47. * @param parent the parent node
  48. */
  49. public TableFObj(FONode parent) {
  50. super(parent);
  51. }
  52. /** {@inheritDoc} */
  53. public void bind(PropertyList pList) throws FOPException {
  54. super.bind(pList);
  55. borderAfterPrecedence = pList.get(PR_BORDER_AFTER_PRECEDENCE).getNumeric();
  56. borderBeforePrecedence = pList.get(PR_BORDER_BEFORE_PRECEDENCE).getNumeric();
  57. borderEndPrecedence = pList.get(PR_BORDER_END_PRECEDENCE).getNumeric();
  58. borderStartPrecedence = pList.get(PR_BORDER_START_PRECEDENCE).getNumeric();
  59. if (getNameId() != FO_TABLE //Separate check for fo:table in Table.java
  60. && getNameId() != FO_TABLE_CELL
  61. && getCommonBorderPaddingBackground().hasPadding(
  62. ValidationPercentBaseContext.getPseudoContext())) {
  63. TableEventProducer eventProducer = TableEventProducer.Provider.get(
  64. getUserAgent().getEventBroadcaster());
  65. eventProducer.paddingNotApplicable(this, getName(), getLocator());
  66. }
  67. }
  68. /**
  69. *
  70. * @param side the side for which to return the border precedence
  71. * @return the "border-precedence" value for the given side
  72. */
  73. public Numeric getBorderPrecedence(int side) {
  74. switch (side) {
  75. case CommonBorderPaddingBackground.BEFORE:
  76. return borderBeforePrecedence;
  77. case CommonBorderPaddingBackground.AFTER:
  78. return borderAfterPrecedence;
  79. case CommonBorderPaddingBackground.START:
  80. return borderStartPrecedence;
  81. case CommonBorderPaddingBackground.END:
  82. return borderEndPrecedence;
  83. default:
  84. return null;
  85. }
  86. }
  87. /**
  88. * Convenience method to returns a reference
  89. * to the base Table instance
  90. *
  91. * @return the base table instance
  92. *
  93. */
  94. public Table getTable() {
  95. // Will be overridden in Table; for any other Table-node, recursive call to
  96. // parent.getTable()
  97. return ((TableFObj) parent).getTable();
  98. }
  99. /**
  100. * @return the Common Border, Padding, and Background Properties.
  101. */
  102. public abstract CommonBorderPaddingBackground getCommonBorderPaddingBackground();
  103. /**
  104. * PropertyMaker subclass for the column-number property
  105. *
  106. */
  107. public static class ColumnNumberPropertyMaker extends NumberProperty.Maker {
  108. /**
  109. * Constructor
  110. * @param propId the id of the property for which the maker should
  111. * be created
  112. */
  113. public ColumnNumberPropertyMaker(int propId) {
  114. super(propId);
  115. }
  116. /** {@inheritDoc} */
  117. public Property make(PropertyList propertyList)
  118. throws PropertyException {
  119. FObj fo = propertyList.getFObj();
  120. return NumberProperty.getInstance(((ColumnNumberManagerHolder) fo.getParent())
  121. .getColumnNumberManager().getCurrentColumnNumber());
  122. }
  123. /**
  124. * Check the value of the column-number property.
  125. * Return the parent's column index (initial value) in case
  126. * of a negative or zero value
  127. *
  128. * @see org.apache.fop.fo.properties.PropertyMaker#make(PropertyList, String, FObj)
  129. */
  130. public Property make(PropertyList propertyList, String value, FObj fo)
  131. throws PropertyException {
  132. Property p = super.make(propertyList, value, fo);
  133. ColumnNumberManagerHolder parent
  134. = (ColumnNumberManagerHolder) propertyList.getParentFObj();
  135. ColumnNumberManager columnIndexManager = parent.getColumnNumberManager();
  136. int columnIndex = p.getNumeric().getValue();
  137. if (columnIndex <= 0) {
  138. /* No warning necessary as the spec clearly defines how to handle these cases.
  139. log.warn("Specified negative or zero value for "
  140. + "column-number on " + fo.getName() + ": "
  141. + columnIndex + " forced to "
  142. + columnIndexManager.getCurrentColumnNumber());*/
  143. return NumberProperty.getInstance(columnIndexManager.getCurrentColumnNumber());
  144. } else {
  145. double tmpIndex = p.getNumeric().getNumericValue();
  146. if (tmpIndex - columnIndex > 0.0) {
  147. columnIndex = (int) Math.round(tmpIndex);
  148. /* No warning necessary as the spec clearly defines how to handle these cases.
  149. log.warn("Rounding specified column-number of "
  150. + tmpIndex + " to " + columnIndex);*/
  151. p = NumberProperty.getInstance(columnIndex);
  152. }
  153. }
  154. int colSpan = propertyList.get(Constants.PR_NUMBER_COLUMNS_SPANNED)
  155. .getNumeric().getValue();
  156. int i = -1;
  157. while (++i < colSpan) {
  158. if (columnIndexManager.isColumnNumberUsed(columnIndex + i)) {
  159. /* if column-number is already in use by another
  160. * cell/column => error!
  161. */
  162. TableEventProducer eventProducer = TableEventProducer.Provider.get(
  163. fo.getUserAgent().getEventBroadcaster());
  164. eventProducer.cellOverlap(this, fo.getName(), columnIndex + 1, fo.getLocator());
  165. }
  166. }
  167. return p;
  168. }
  169. }
  170. /** {@inheritDoc} */
  171. public void startOfNode() throws FOPException {
  172. super.startOfNode();
  173. Table table = getTable();
  174. if (!inMarker() && !table.isSeparateBorderModel()) {
  175. collapsingBorderModel = CollapsingBorderModel.getBorderModelFor(table
  176. .getBorderCollapse());
  177. setCollapsedBorders();
  178. }
  179. }
  180. /*
  181. * TODO made public so that RetrieveMarker can access it.
  182. */
  183. /** {@inheritDoc} */
  184. public void endOfNode() throws FOPException {
  185. super.endOfNode();
  186. }
  187. /**
  188. * Prepares the borders of this element if the collapsing-border model is in use.
  189. * Conflict resolution with parent elements is done where applicable.
  190. */
  191. protected abstract void setCollapsedBorders();
  192. /**
  193. * Creates a BorderSpecification from the border set on the given side. If no border
  194. * is set, a BorderSpecification with border-style none is created.
  195. *
  196. * @param side one of CommonBorderPaddingBackground.BEFORE|AFTER|START|END
  197. */
  198. protected void createBorder(int side) {
  199. BorderSpecification borderSpec = new BorderSpecification(
  200. getCommonBorderPaddingBackground().getBorderInfo(side), getNameId());
  201. switch (side) {
  202. case CommonBorderPaddingBackground.BEFORE:
  203. borderBefore = new ConditionalBorder(borderSpec, collapsingBorderModel);
  204. break;
  205. case CommonBorderPaddingBackground.AFTER:
  206. borderAfter = new ConditionalBorder(borderSpec, collapsingBorderModel);
  207. break;
  208. case CommonBorderPaddingBackground.START:
  209. borderStart = borderSpec;
  210. break;
  211. case CommonBorderPaddingBackground.END:
  212. borderEnd = borderSpec;
  213. break;
  214. default: assert false;
  215. }
  216. }
  217. /**
  218. * Creates a BorderSpecification from the border set on the given side, performing
  219. * conflict resolution with the same border on the given object.
  220. *
  221. * @param side one of CommonBorderPaddingBackground.BEFORE|AFTER|START|END
  222. * @param competitor a parent table element whose side coincides with the given side
  223. * on this element
  224. */
  225. protected void createBorder(int side, TableFObj competitor) {
  226. createBorder(side);
  227. switch (side) {
  228. case CommonBorderPaddingBackground.BEFORE:
  229. borderBefore.integrateSegment(competitor.borderBefore, true, true, true);
  230. break;
  231. case CommonBorderPaddingBackground.AFTER:
  232. borderAfter.integrateSegment(competitor.borderAfter, true, true, true);
  233. break;
  234. case CommonBorderPaddingBackground.START:
  235. borderStart = collapsingBorderModel.determineWinner(borderStart,
  236. competitor.borderStart);
  237. break;
  238. case CommonBorderPaddingBackground.END:
  239. borderEnd = collapsingBorderModel.determineWinner(borderEnd,
  240. competitor.borderEnd);
  241. break;
  242. default: assert false;
  243. }
  244. }
  245. }