blob: 98d7fd5bccca989ec621c9b986a48cfbb8db1f47 [file] [log] [blame]
/*
* 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 ((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;
}
}