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.

CollapsingBorderModelEyeCatching.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*
  2. * Copyright 2005 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.table;
  18. import org.apache.fop.fo.Constants;
  19. import org.apache.fop.fo.flow.Table;
  20. import org.apache.fop.fo.flow.TableBody;
  21. import org.apache.fop.fo.flow.TableCell;
  22. import org.apache.fop.fo.flow.TableColumn;
  23. import org.apache.fop.fo.flow.TableRow;
  24. import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
  25. /**
  26. * Implements the normal "collapse" border model defined in 6.7.10 in XSL 1.0.
  27. *
  28. * TODO Column groups are not yet checked in this algorithm!
  29. */
  30. public class CollapsingBorderModelEyeCatching extends CollapsingBorderModel {
  31. public BorderInfo determineWinner(GridUnit currentGridUnit,
  32. GridUnit otherGridUnit, int side, int flags) {
  33. final boolean vertical = isVerticalRelation(side);
  34. final int otherSide = getOtherSide(side);
  35. //Get cells
  36. TableCell currentCell = currentGridUnit.getCell();
  37. TableCell otherCell = null;
  38. if (otherGridUnit != null) {
  39. otherCell = otherGridUnit.getCell();
  40. }
  41. //Get rows
  42. TableRow currentRow = currentGridUnit.getRow();
  43. TableRow otherRow = null;
  44. if (vertical && otherCell != null) {
  45. otherRow = otherGridUnit.getRow();
  46. }
  47. //get bodies
  48. TableBody currentBody = currentGridUnit.getBody();
  49. TableBody otherBody = null;
  50. if (otherRow != null) {
  51. otherBody = otherGridUnit.getBody();
  52. }
  53. //get columns
  54. TableColumn currentColumn = currentGridUnit.getColumn();
  55. TableColumn otherColumn = null;
  56. if (otherGridUnit != null) {
  57. otherColumn = otherGridUnit.getColumn();
  58. }
  59. //TODO get column groups
  60. //Get table
  61. Table table = currentGridUnit.getTable();
  62. //----------------------------------------------------------------------
  63. //We're creating two arrays containing the applicable BorderInfos for
  64. //each cell in question.
  65. //0 = cell, 1 = row, 2 = row group (body), 3 = column,
  66. //4 = col group (spanned column, see 6.7.3), 5 = table
  67. BorderInfo[] current = new BorderInfo[6];
  68. BorderInfo[] other = new BorderInfo[6];
  69. //cell
  70. current[0] = currentGridUnit.getOriginalBorderInfoForCell(side);
  71. if (otherGridUnit != null) {
  72. other[0] = otherGridUnit.getOriginalBorderInfoForCell(otherSide);
  73. }
  74. if ((currentRow != null)
  75. && (side == BEFORE
  76. || side == AFTER
  77. || (currentGridUnit.getFlag(GridUnit.IN_FIRST_COLUMN) && side == START)
  78. || (currentGridUnit.getFlag(GridUnit.IN_LAST_COLUMN) && side == END))) {
  79. //row
  80. current[1] = currentRow.getCommonBorderPaddingBackground().getBorderInfo(side);
  81. }
  82. if (otherRow != null) {
  83. //row
  84. other[1] = otherRow.getCommonBorderPaddingBackground().getBorderInfo(otherSide);
  85. }
  86. if ((side == BEFORE && currentGridUnit.getFlag(GridUnit.FIRST_IN_BODY))
  87. || (side == AFTER && currentGridUnit.getFlag(GridUnit.LAST_IN_BODY))
  88. || (currentGridUnit.getFlag(GridUnit.IN_FIRST_COLUMN) && side == START)
  89. || (currentGridUnit.getFlag(GridUnit.IN_LAST_COLUMN) && side == END)) {
  90. //row group (=body, table-header or table-footer)
  91. current[2] = currentBody.getCommonBorderPaddingBackground().getBorderInfo(side);
  92. }
  93. if (otherGridUnit != null
  94. && otherBody != null
  95. && ((otherSide == BEFORE && otherGridUnit.getFlag(GridUnit.FIRST_IN_BODY))
  96. || (otherSide == AFTER && otherGridUnit.getFlag(GridUnit.LAST_IN_BODY)))) {
  97. //row group (=body, table-header or table-footer)
  98. other[2] = otherBody.getCommonBorderPaddingBackground().getBorderInfo(otherSide);
  99. }
  100. if ((side == BEFORE && otherGridUnit == null)
  101. || (side == AFTER && otherGridUnit == null)
  102. || (side == START)
  103. || (side == END)) {
  104. //column
  105. current[3] = currentColumn.getCommonBorderPaddingBackground().getBorderInfo(side);
  106. }
  107. if (otherColumn != null) {
  108. //column
  109. other[3] = otherColumn.getCommonBorderPaddingBackground().getBorderInfo(otherSide);
  110. }
  111. //TODO current[4] and other[4] for column groups
  112. if (otherGridUnit == null
  113. && ((side == BEFORE && (flags & VERTICAL_START_END_OF_TABLE) > 0)
  114. || (side == AFTER && (flags & VERTICAL_START_END_OF_TABLE) > 0)
  115. || (side == START)
  116. || (side == END))) {
  117. //table
  118. current[5] = table.getCommonBorderPaddingBackground().getBorderInfo(side);
  119. }
  120. //other[6] is always null, since it's always the same table
  121. BorderInfo resolved = null;
  122. // *** Rule 1 ***
  123. resolved = doRule1(current, other);
  124. if (resolved != null) {
  125. return resolved;
  126. }
  127. // *** Rule 2 ***
  128. if (!doRule2(current, other)) {
  129. }
  130. // *** Rule 3 ***
  131. resolved = doRule3(current, other);
  132. if (resolved != null) {
  133. return resolved;
  134. }
  135. // *** Rule 4 ***
  136. resolved = doRule4(current, other);
  137. if (resolved != null) {
  138. return resolved;
  139. }
  140. // *** Rule 5 ***
  141. resolved = doRule5(current, other);
  142. if (resolved != null) {
  143. return resolved;
  144. }
  145. return null; //no winner, no border
  146. }
  147. private BorderInfo doRule1(BorderInfo[] current, BorderInfo[] other) {
  148. for (int i = 0; i < current.length; i++) {
  149. if ((current[i] != null) && (current[i].getStyle() == Constants.EN_HIDDEN)) {
  150. return current[i];
  151. }
  152. if ((other[i] != null) && (other[i].getStyle() == Constants.EN_HIDDEN)) {
  153. return other[i];
  154. }
  155. }
  156. return null;
  157. }
  158. private boolean doRule2(BorderInfo[] current, BorderInfo[] other) {
  159. boolean found = false;
  160. for (int i = 0; i < current.length; i++) {
  161. if ((current[i] != null) && (current[i].getStyle() != Constants.EN_NONE)) {
  162. found = true;
  163. break;
  164. }
  165. if ((other[i] != null) && (other[i].getStyle() != Constants.EN_NONE)) {
  166. found = true;
  167. break;
  168. }
  169. }
  170. return found;
  171. }
  172. private BorderInfo doRule3(BorderInfo[] current, BorderInfo[] other) {
  173. int width = 0;
  174. //Find max border width
  175. for (int i = 0; i < current.length; i++) {
  176. if ((current[i] != null) && (current[i].getRetainedWidth() > width)) {
  177. width = current[i].getRetainedWidth();
  178. }
  179. if ((other[i] != null) && (other[i].getRetainedWidth() > width)) {
  180. width = other[i].getRetainedWidth();
  181. }
  182. }
  183. BorderInfo widest = null;
  184. int count = 0;
  185. //See if there's only one with the widest border
  186. for (int i = 0; i < current.length; i++) {
  187. if ((current[i] != null) && (current[i].getRetainedWidth() == width)) {
  188. count++;
  189. if (widest == null) {
  190. widest = current[i];
  191. }
  192. } else {
  193. current[i] = null; //Discard the narrower ones
  194. }
  195. if ((other[i] != null) && (other[i].getRetainedWidth() == width)) {
  196. count++;
  197. if (widest == null) {
  198. widest = other[i];
  199. }
  200. } else {
  201. other[i] = null; //Discard the narrower ones
  202. }
  203. }
  204. if (count == 1) {
  205. return widest;
  206. } else {
  207. return null;
  208. }
  209. }
  210. private BorderInfo doRule4(BorderInfo[] current, BorderInfo[] other) {
  211. int pref = getPreferenceValue(Constants.EN_INSET); //Lowest preference
  212. //Find highest preference value
  213. for (int i = 0; i < current.length; i++) {
  214. if (current[i] != null) {
  215. int currPref = getPreferenceValue(current[i].getStyle());
  216. if (currPref > pref) {
  217. pref = currPref;
  218. }
  219. }
  220. if (other[i] != null) {
  221. int currPref = getPreferenceValue(other[i].getStyle());
  222. if (currPref > pref) {
  223. pref = currPref;
  224. }
  225. }
  226. }
  227. BorderInfo preferred = null;
  228. int count = 0;
  229. //See if there's only one with the preferred border style
  230. for (int i = 0; i < current.length; i++) {
  231. if (current[i] != null) {
  232. int currPref = getPreferenceValue(current[i].getStyle());
  233. if (currPref == pref) {
  234. count++;
  235. if (preferred == null) {
  236. preferred = current[i];
  237. }
  238. break;
  239. }
  240. } else {
  241. current[i] = null; //Discard the ones that are not preferred
  242. }
  243. if (other[i] != null) {
  244. int currPref = getPreferenceValue(other[i].getStyle());
  245. if (currPref == pref) {
  246. count++;
  247. if (preferred == null) {
  248. preferred = other[i];
  249. }
  250. break;
  251. }
  252. } else {
  253. other[i] = null; //Discard the ones that are not preferred
  254. }
  255. }
  256. if (count == 1) {
  257. return preferred;
  258. } else {
  259. return null;
  260. }
  261. }
  262. private BorderInfo doRule5(BorderInfo[] current, BorderInfo[] other) {
  263. for (int i = 0; i < current.length; i++) {
  264. if (current[i] != null) {
  265. return current[i];
  266. }
  267. if (other[i] != null) {
  268. return other[i];
  269. }
  270. }
  271. return null;
  272. }
  273. }