/* * Copyright 2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id$ */ package org.apache.fop.layoutmgr.table; import org.apache.fop.fo.Constants; import org.apache.fop.fo.flow.Table; import org.apache.fop.fo.flow.TableBody; import org.apache.fop.fo.flow.TableCell; import org.apache.fop.fo.flow.TableColumn; import org.apache.fop.fo.flow.TableRow; import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo; /** * Implements the normal "collapse" border model defined in 6.7.10 in XSL 1.0. * * TODO Column groups are not yet checked in this algorithm! */ public class CollapsingBorderModelEyeCatching extends CollapsingBorderModel { public BorderInfo determineWinner(GridUnit currentGridUnit, GridUnit otherGridUnit, int side, int flags) { final boolean vertical = isVerticalRelation(side); final int otherSide = getOtherSide(side); //Get cells TableCell currentCell = currentGridUnit.getCell(); TableCell otherCell = null; if (otherGridUnit != null) { otherCell = otherGridUnit.getCell(); } //Get rows TableRow currentRow = currentGridUnit.getRow(); TableRow otherRow = null; if (vertical && otherCell != null) { otherRow = otherGridUnit.getRow(); } //get bodies TableBody currentBody = currentGridUnit.getBody(); TableBody otherBody = null; if (otherRow != null) { otherBody = otherGridUnit.getBody(); } //get columns TableColumn currentColumn = currentGridUnit.getColumn(); TableColumn otherColumn = null; if (otherGridUnit != null) { otherColumn = otherGridUnit.getColumn(); } //TODO get column groups //Get table Table table = currentGridUnit.getTable(); //---------------------------------------------------------------------- //We're creating two arrays containing the applicable BorderInfos for //each cell in question. //0 = cell, 1 = row, 2 = row group (body), 3 = column, //4 = col group (spanned column, see 6.7.3), 5 = table BorderInfo[] current = new BorderInfo[6]; BorderInfo[] other = new BorderInfo[6]; //cell current[0] = currentGridUnit.getOriginalBorderInfoForCell(side); if (otherGridUnit != null) { other[0] = otherGridUnit.getOriginalBorderInfoForCell(otherSide); } if ((currentRow != null) && (side == BEFORE || side == AFTER || (currentGridUnit.getFlag(GridUnit.IN_FIRST_COLUMN) && side == START) || (currentGridUnit.getFlag(GridUnit.IN_LAST_COLUMN) && side == END))) { //row current[1] = currentRow.getCommonBorderPaddingBackground().getBorderInfo(side); } if (otherRow != null) { //row other[1] = otherRow.getCommonBorderPaddingBackground().getBorderInfo(otherSide); } if (currentBody != null && ((side == BEFORE && currentGridUnit.getFlag(GridUnit.FIRST_IN_BODY)) || (side == AFTER && currentGridUnit.getFlag(GridUnit.LAST_IN_BODY)) || (currentGridUnit.getFlag(GridUnit.IN_FIRST_COLUMN) && side == START) || (currentGridUnit.getFlag(GridUnit.IN_LAST_COLUMN) && side == END))) { //row group (=body, table-header or table-footer) current[2] = currentBody.getCommonBorderPaddingBackground().getBorderInfo(side); } if (otherGridUnit != null && otherBody != null && ((otherSide == BEFORE && otherGridUnit.getFlag(GridUnit.FIRST_IN_BODY)) || (otherSide == AFTER && otherGridUnit.getFlag(GridUnit.LAST_IN_BODY)))) { //row group (=body, table-header or table-footer) other[2] = otherBody.getCommonBorderPaddingBackground().getBorderInfo(otherSide); } if ((side == BEFORE && otherGridUnit == null) || (side == AFTER && otherGridUnit == null) || (side == START) || (side == END)) { //column current[3] = currentColumn.getCommonBorderPaddingBackground().getBorderInfo(side); } if (otherColumn != null) { //column other[3] = otherColumn.getCommonBorderPaddingBackground().getBorderInfo(otherSide); } //TODO current[4] and other[4] for column groups if (otherGridUnit == null && ((side == BEFORE && (flags & VERTICAL_START_END_OF_TABLE) > 0) || (side == AFTER && (flags & VERTICAL_START_END_OF_TABLE) > 0) || (side == START) || (side == END))) { //table current[5] = table.getCommonBorderPaddingBackground().getBorderInfo(side); } //other[6] is always null, since it's always the same table BorderInfo resolved = null; // *** Rule 1 *** resolved = doRule1(current, other); if (resolved != null) { return resolved; } // *** Rule 2 *** if (!doRule2(current, other)) { } // *** Rule 3 *** resolved = doRule3(current, other); if (resolved != null) { return resolved; } // *** Rule 4 *** resolved = doRule4(current, other); if (resolved != null) { return resolved; } // *** Rule 5 *** resolved = doRule5(current, other); if (resolved != null) { return resolved; } return null; //no winner, no border } private BorderInfo doRule1(BorderInfo[] current, BorderInfo[] other) { for (int i = 0; i < current.length; i++) { if ((current[i] != null) && (current[i].getStyle() == Constants.EN_HIDDEN)) { return current[i]; } if ((other[i] != null) && (other[i].getStyle() == Constants.EN_HIDDEN)) { return other[i]; } } return null; } private boolean doRule2(BorderInfo[] current, BorderInfo[] other) { boolean found = false; for (int i = 0; i < current.length; i++) { if ((current[i] != null) && (current[i].getStyle() != Constants.EN_NONE)) { found = true; break; } if ((other[i] != null) && (other[i].getStyle() != Constants.EN_NONE)) { found = true; break; } } return found; } private BorderInfo doRule3(BorderInfo[] current, BorderInfo[] other) { int width = 0; //Find max border width for (int i = 0; i < current.length; i++) { if ((current[i] != null) && (current[i].getRetainedWidth() > width)) { width = current[i].getRetainedWidth(); } if ((other[i] != null) && (other[i].getRetainedWidth() > width)) { width = other[i].getRetainedWidth(); } } BorderInfo widest = null; int count = 0; //See if there's only one with the widest border for (int i = 0; i < current.length; i++) { if ((current[i] != null) && (current[i].getRetainedWidth() == width)) { count++; if (widest == null) { widest = current[i]; } } else { current[i] = null; //Discard the narrower ones } if ((other[i] != null) && (other[i].getRetainedWidth() == width)) { count++; if (widest == null) { widest = other[i]; } } else { other[i] = null; //Discard the narrower ones } } if (count == 1) { return widest; } else { return null; } } private BorderInfo doRule4(BorderInfo[] current, BorderInfo[] other) { int pref = getPreferenceValue(Constants.EN_INSET); //Lowest preference //Find highest preference value for (int i = 0; i < current.length; i++) { if (current[i] != null) { int currPref = getPreferenceValue(current[i].getStyle()); if (currPref > pref) { pref = currPref; } } if (other[i] != null) { int currPref = getPreferenceValue(other[i].getStyle()); if (currPref > pref) { pref = currPref; } } } BorderInfo preferred = null; int count = 0; //See if there's only one with the preferred border style for (int i = 0; i < current.length; i++) { if (current[i] != null) { int currPref = getPreferenceValue(current[i].getStyle()); if (currPref == pref) { count++; if (preferred == null) { preferred = current[i]; } break; } } else { current[i] = null; //Discard the ones that are not preferred } if (other[i] != null) { int currPref = getPreferenceValue(other[i].getStyle()); if (currPref == pref) { count++; if (preferred == null) { preferred = other[i]; } break; } } else { other[i] = null; //Discard the ones that are not preferred } } if (count == 1) { return preferred; } else { return null; } } private BorderInfo doRule5(BorderInfo[] current, BorderInfo[] other) { for (int i = 0; i < current.length; i++) { if (current[i] != null) { return current[i]; } if (other[i] != null) { return other[i]; } } return null; } }