123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.fo.flow.table;
-
- import org.apache.fop.layoutmgr.table.CollapsingBorderModel;
-
- /**
- * A class that holds the three possible values for a border-before/after on a table-cell,
- * in the collapsing model. These three values are (for border-before, similar for
- * border-after):
- * <ul>
- * <li>normal: common case, when a cell follows the cell before on a same page;</li>
- * <li>leading: when the table is broken and the cell appears at the top of a page, in
- * which case its border must be resolved with the header (or the top of the table)
- * instead of with the previous cell;</li>
- * <li>rest: when a cell is broken over several pages; same as leading but with
- * conditionality taken into account.</li>
- * </ul>
- */
- public class ConditionalBorder {
-
- /** normal border */
- public static final int NORMAL = 0;
-
- /** leading and trailing border */
- public static final int LEADING_TRAILING = 1;
-
- /** all the rest */
- public static final int REST = 2;
-
- /** Normal case, no break. */
- BorderSpecification normal; // CSOK: VisibilityModifier
-
- /** Special case: the cell is at the top or the bottom of the page. */
- BorderSpecification leadingTrailing; // CSOK: VisibilityModifier
-
- /** Special case: break inside the cell. */
- BorderSpecification rest; // CSOK: VisibilityModifier
-
- /** The model used to resolve borders. */
- private CollapsingBorderModel collapsingBorderModel;
-
- private ConditionalBorder(BorderSpecification normal,
- BorderSpecification leadingTrailing, BorderSpecification rest,
- CollapsingBorderModel collapsingBorderModel) {
- assert collapsingBorderModel != null;
- this.normal = normal;
- this.leadingTrailing = leadingTrailing;
- this.rest = rest;
- this.collapsingBorderModel = collapsingBorderModel;
- }
-
- /**
- * Creates a new conditional border.
- *
- * @param borderSpecification the border specification to take as a basis
- * @param collapsingBorderModel the model that will be used to resolved borders
- */
- ConditionalBorder(BorderSpecification borderSpecification,
- CollapsingBorderModel collapsingBorderModel) {
- this ( borderSpecification, borderSpecification,
- borderSpecification.getBorderInfo().getWidth().isDiscard()
- ? BorderSpecification.getDefaultBorder() : borderSpecification,
- collapsingBorderModel );
- }
-
- /**
- * Resolves and updates the relevant parts of this border as well as the given one.
- *
- * @param competitor
- * @param withNormal
- * @param withLeadingTrailing
- * @param withRest
- */
- void resolve(ConditionalBorder competitor, boolean withNormal,
- boolean withLeadingTrailing, boolean withRest) {
- if (withNormal) {
- BorderSpecification resolvedBorder = collapsingBorderModel.determineWinner(
- normal, competitor.normal);
- if (resolvedBorder != null) {
- normal = resolvedBorder;
- competitor.normal = resolvedBorder;
- }
- }
- if (withLeadingTrailing) {
- BorderSpecification resolvedBorder = collapsingBorderModel.determineWinner(
- leadingTrailing, competitor.leadingTrailing);
- if (resolvedBorder != null) {
- leadingTrailing = resolvedBorder;
- competitor.leadingTrailing = resolvedBorder;
- }
- }
- if (withRest) {
- BorderSpecification resolvedBorder = collapsingBorderModel.determineWinner(rest,
- competitor.rest);
- if (resolvedBorder != null) {
- rest = resolvedBorder;
- competitor.rest = resolvedBorder;
- }
- }
- }
-
- /**
- * Integrates the given segment in this border. Unlike for
- * {@link #integrateSegment(ConditionalBorder, boolean, boolean, boolean)}, this
- * method nicely handles the case where the CollapsingBorderModel returns null, by
- * keeping the components to their old values.
- *
- * @param competitor
- * @param withNormal
- * @param withLeadingTrailing
- * @param withRest
- */
- void integrateCompetingSegment(ConditionalBorder competitor, boolean withNormal,
- boolean withLeadingTrailing, boolean withRest) {
- if (withNormal) {
- BorderSpecification resolvedBorder = collapsingBorderModel.determineWinner(
- normal, competitor.normal);
- if (resolvedBorder != null) {
- normal = resolvedBorder;
- }
- }
- if (withLeadingTrailing) {
- BorderSpecification resolvedBorder = collapsingBorderModel.determineWinner(
- leadingTrailing, competitor.leadingTrailing);
- if (resolvedBorder != null) {
- leadingTrailing = resolvedBorder;
- }
- }
- if (withRest) {
- BorderSpecification resolvedBorder = collapsingBorderModel.determineWinner(rest,
- competitor.rest);
- if (resolvedBorder != null) {
- rest = resolvedBorder;
- }
- }
- }
-
- /**
- * Updates this border after taking into account the given segment. The
- * CollapsingBorderModel is not expected to return null.
- *
- * @param segment
- * @param withNormal
- * @param withLeadingTrailing
- * @param withRest
- */
- void integrateSegment(ConditionalBorder segment, boolean withNormal,
- boolean withLeadingTrailing, boolean withRest) {
- if (withNormal) {
- normal = collapsingBorderModel.determineWinner(normal, segment.normal);
- assert normal != null;
- }
- if (withLeadingTrailing) {
- leadingTrailing = collapsingBorderModel.determineWinner(leadingTrailing,
- segment.leadingTrailing);
- assert leadingTrailing != null;
- }
- if (withRest) {
- rest = collapsingBorderModel.determineWinner(rest, segment.rest);
- assert rest != null;
- }
- }
-
- /**
- * Returns a shallow copy of this border.
- *
- * @return a copy of this border
- */
- ConditionalBorder copy() {
- return new ConditionalBorder(normal, leadingTrailing, rest, collapsingBorderModel);
- }
-
- /** {@inheritDoc} */
- public String toString() {
- return "{normal: " + normal + ", leading: " + leadingTrailing + ", rest: " + rest + "}";
- }
-
- /**
- * Returns a default border specification.
- *
- * @param collapsingBorderModel the model that will be used to resolve borders
- * @return a border with style 'none' for all of the three components
- */
- static ConditionalBorder getDefaultBorder(CollapsingBorderModel collapsingBorderModel) {
- BorderSpecification defaultBorderSpec = BorderSpecification.getDefaultBorder();
- return new ConditionalBorder(defaultBorderSpec, defaultBorderSpec, defaultBorderSpec,
- collapsingBorderModel);
- }
- }
|