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 18 /* $Id: CollapsingBorderModel.java 1617052 2014-08-10 06:55:01Z gadams $ */ 19 20 package org.apache.fop.layoutmgr.table; 21 22 import org.apache.fop.fo.Constants; 23 import org.apache.fop.fo.flow.table.BorderSpecification; 24 import org.apache.fop.fo.properties.CommonBorderPaddingBackground; 25 26 /** 27 * This class is a superclass for the two collapsing border models defined 28 * in the XSL 1.0 specification. 29 */ 30 public abstract class CollapsingBorderModel { 31 32 /** before side */ 33 protected static final int BEFORE = CommonBorderPaddingBackground.BEFORE; 34 /** after side */ 35 protected static final int AFTER = CommonBorderPaddingBackground.AFTER; 36 /** start side */ 37 protected static final int START = CommonBorderPaddingBackground.START; 38 /** end side */ 39 protected static final int END = CommonBorderPaddingBackground.END; 40 41 /** Indicates that the cell is/starts in the first row being painted on a particular page */ 42 //public static final int FIRST_ROW_IN_TABLE_PART = 1; 43 /** Indicates that the cell is/ends in the last row being painted on a particular page */ 44 //public static final int LAST_ROW_IN_TABLE_PART = 2; 45 /** Indicates that the cell is/starts in the first row of a body/table-header/table-footer */ 46 //public static final int FIRST_ROW_IN_GROUP = 4; 47 /** Indicates that the cell is/end in the last row of a body/table-header/table-footer */ 48 //public static final int LAST_ROW_IN_GROUP = 8; 49 50 private static CollapsingBorderModel collapse = new CollapsingBorderModelEyeCatching(); 51 // private static CollapsingBorderModel collapseWithPrecedence = null; 52 53 /** 54 * @param borderCollapse border collapse control 55 * @return the border model for the cell 56 */ getBorderModelFor(int borderCollapse)57 public static CollapsingBorderModel getBorderModelFor(int borderCollapse) { 58 switch (borderCollapse) { 59 case Constants.EN_COLLAPSE: 60 return collapse; 61 case Constants.EN_COLLAPSE_WITH_PRECEDENCE: 62 throw new UnsupportedOperationException("collapse-with-precedence not yet supported"); 63 default: 64 throw new IllegalArgumentException("Illegal border-collapse mode."); 65 } 66 } 67 68 /** 69 * @param side the side on the current cell 70 * @return the adjacent side on the neighbouring cell 71 */ getOtherSide(int side)72 public/*TODO*/ static int getOtherSide(int side) { 73 switch (side) { 74 case CommonBorderPaddingBackground.BEFORE: 75 return CommonBorderPaddingBackground.AFTER; 76 case CommonBorderPaddingBackground.AFTER: 77 return CommonBorderPaddingBackground.BEFORE; 78 case CommonBorderPaddingBackground.START: 79 return CommonBorderPaddingBackground.END; 80 case CommonBorderPaddingBackground.END: 81 return CommonBorderPaddingBackground.START; 82 default: 83 throw new IllegalArgumentException("Illegal parameter: side"); 84 } 85 } 86 87 /** 88 * @param side the side to investigate 89 * @return true if the adjacent cell is before or after 90 */ isVerticalRelation(int side)91 protected boolean isVerticalRelation(int side) { 92 return (side == CommonBorderPaddingBackground.BEFORE 93 || side == CommonBorderPaddingBackground.AFTER); 94 } 95 compareInt(int value1, int value2)96 private static int compareInt(int value1, int value2) { 97 if (value1 < value2) { 98 return -1; 99 } else if (value1 == value2) { 100 return 0; 101 } else { 102 return 1; 103 } 104 } 105 106 /** 107 * See rule 4 in 6.7.10 for the collapsing border model. 108 * @param style the border style to get the preference value for 109 * @return the preference value of the style 110 */ getStylePreferenceValue(int style)111 private static int getStylePreferenceValue(int style) { 112 switch (style) { 113 case Constants.EN_DOUBLE: return 0; 114 case Constants.EN_SOLID: return -1; 115 case Constants.EN_DASHED: return -2; 116 case Constants.EN_DOTTED: return -3; 117 case Constants.EN_RIDGE: return -4; 118 case Constants.EN_OUTSET: return -5; 119 case Constants.EN_GROOVE: return -6; 120 case Constants.EN_INSET: return -7; 121 default: throw new IllegalStateException("Illegal border style: " + style); 122 } 123 } 124 125 /** 126 * Compares the two given styles (see {@link Constants}). 127 * 128 * @param style1 a style constant 129 * @param style2 another style constant 130 * @return a value < 0 if style1 has less priority than style2, 0 if both are 131 * equal, a value > 0 if style1 has more priority than style2 132 */ compareStyles(int style1, int style2)133 static int compareStyles(int style1, int style2) { 134 int value1 = getStylePreferenceValue(style1); 135 int value2 = getStylePreferenceValue(style2); 136 return compareInt(value1, value2); 137 } 138 getHolderPreferenceValue(int id)139 private static int getHolderPreferenceValue(int id) { 140 switch (id) { 141 case Constants.FO_TABLE_CELL: return 0; 142 case Constants.FO_TABLE_ROW: return -1; 143 case Constants.FO_TABLE_HEADER: 144 case Constants.FO_TABLE_FOOTER: 145 case Constants.FO_TABLE_BODY: 146 return -2; 147 case Constants.FO_TABLE_COLUMN: return -3; 148 // TODO colgroup 149 case Constants.FO_TABLE: return -4; 150 default: throw new IllegalStateException(); 151 } 152 } 153 154 /** 155 * Compares the two given FO ids ({@link Constants}.FO*) in terms of border 156 * declaration. 157 * 158 * @param id1 a FO id ({@link Constants#FO_TABLE}, {@link Constants#FO_TABLE_BODY}, 159 * etc.) 160 * @param id2 another FO id 161 * @return a value < 0 if id1 has less priority than id2, 0 if both are equal, a 162 * value > 0 if id1 has more priority than id2 163 */ compareFOs(int id1, int id2)164 static int compareFOs(int id1, int id2) { 165 int p1 = getHolderPreferenceValue(id1); 166 int p2 = getHolderPreferenceValue(id2); 167 return compareInt(p1, p2); 168 } 169 170 /** 171 * Returns the border which wins the border conflict resolution. In case the two 172 * borders are equivalent (identical, or only the color is different), null is 173 * returned. 174 * 175 * @param border1 a border specification 176 * @param border2 another border specification 177 * @param discard true if the .conditionality component of the border width must be 178 * taken into account 179 * @return the winning border, null if the two borders are equivalent 180 */ determineWinner(BorderSpecification border1, BorderSpecification border2, boolean discard)181 public abstract BorderSpecification determineWinner(BorderSpecification border1, 182 BorderSpecification border2, boolean discard); 183 184 /** 185 * Returns the border which wins the border conflict resolution. Same as 186 * {@link #determineWinner(BorderSpecification, BorderSpecification, boolean) 187 * determineWinner(border1, border2, false)}. 188 * 189 * @param border1 a border specification 190 * @param border2 another border specification 191 * @return the winning border, null if the two borders are equivalent 192 * @see #determineWinner(BorderSpecification,BorderSpecification,boolean) 193 */ determineWinner(BorderSpecification border1, BorderSpecification border2)194 public abstract BorderSpecification determineWinner(BorderSpecification border1, 195 BorderSpecification border2); 196 197 } 198