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: RegionBody.java 1805173 2017-08-16 10:50:04Z ssteiner $ */
19 
20 package org.apache.fop.fo.pagination;
21 
22 // Java
23 import java.awt.Rectangle;
24 
25 import org.apache.fop.apps.FOPException;
26 import org.apache.fop.datatypes.FODimension;
27 import org.apache.fop.datatypes.Length;
28 import org.apache.fop.datatypes.LengthBase;
29 import org.apache.fop.datatypes.Numeric;
30 import org.apache.fop.datatypes.PercentBaseContext;
31 import org.apache.fop.fo.Constants;
32 import org.apache.fop.fo.FONode;
33 import org.apache.fop.fo.PropertyList;
34 import org.apache.fop.fo.properties.CommonMarginBlock;
35 
36 /**
37  * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_region-body">
38  * <code>fo:region-body</code></a> object.
39  */
40 public class RegionBody extends Region {
41     // The value of properties relevant for fo:region-body.
42     private CommonMarginBlock commonMarginBlock;
43     private Numeric columnCount;
44     private Length columnGap;
45     // End of property values
46 
47     /**
48      * Create a RegionBody instance that is a child of the
49      * given parent {@link FONode}.
50      * @param parent    the {@link FONode} that is to be the parent
51      */
RegionBody(FONode parent)52     public RegionBody(FONode parent) {
53         super(parent);
54     }
55 
56     /** {@inheritDoc} */
bind(PropertyList pList)57     public void bind(PropertyList pList) throws FOPException {
58         super.bind(pList);
59         commonMarginBlock = pList.getMarginBlockProps();
60         columnCount = pList.get(PR_COLUMN_COUNT).getNumeric();
61         columnGap = pList.get(PR_COLUMN_GAP).getLength();
62 
63         if ((getColumnCount() > 1) && (getOverflow() == EN_SCROLL)) {
64             /* This is an error (See XSL Rec, fo:region-body description).
65              * The Rec allows for acting as if "1" is chosen in
66              * these cases, but we will need to be able to change Numeric
67              * values in order to do this.
68              */
69             getFOValidationEventProducer().columnCountErrorOnRegionBodyOverflowScroll(this,
70                     getName(), getLocator());
71         }
72     }
73 
74     /**
75      * Return the {@link CommonMarginBlock} instance attached to
76      * this instance.
77      * @return the {@link CommonMarginBlock} instance
78      */
getCommonMarginBlock()79     public CommonMarginBlock getCommonMarginBlock() {
80         return commonMarginBlock;
81     }
82 
83     /**
84      * Return the value of the <code>column-count</code> property.
85      * @return the "column-count" property.
86      */
getColumnCount()87     public int getColumnCount() {
88         return columnCount.getValue();
89     }
90 
91     /**
92      * Return the value of the <code>column-gap</code> property.
93      * @return the "column-gap" property.
94      */
getColumnGap()95     public int getColumnGap() {
96         return columnGap.getValue();
97     }
98 
99     /** {@inheritDoc} */
getViewportRectangle(FODimension reldims)100     public Rectangle getViewportRectangle(FODimension reldims) {
101         /* Special rules apply to resolving margins in the page context.
102          * Contrary to normal margins in this case top and bottom margin
103          * are resolved relative to the height. In the property subsystem
104          * all margin properties are configured to using BLOCK_WIDTH.
105          * That's why we 'cheat' here and setup a context for the height but
106          * use the LengthBase.BLOCK_WIDTH.
107          * Also the values are resolved relative to the page size
108          * and reference orientation.
109          */
110         PercentBaseContext pageWidthContext
111             = getPageWidthContext(LengthBase.CONTAINING_BLOCK_WIDTH);
112         PercentBaseContext pageHeightContext
113             = getPageHeightContext(LengthBase.CONTAINING_BLOCK_WIDTH);
114 
115         int start;
116         int end;
117         // [TBD] WRITING MODE ALERT
118         switch (getWritingMode().getEnumValue()) {
119         case Constants.EN_RL_TB:
120             start = commonMarginBlock.marginRight.getValue(pageWidthContext);
121             end = commonMarginBlock.marginLeft.getValue(pageWidthContext);
122             break;
123         case Constants.EN_TB_LR:
124         case Constants.EN_TB_RL:
125             start = commonMarginBlock.marginTop.getValue(pageWidthContext);
126             end = commonMarginBlock.marginBottom.getValue(pageWidthContext);
127             break;
128         case Constants.EN_LR_TB:
129         default:
130             start = commonMarginBlock.marginLeft.getValue(pageWidthContext);
131             end = commonMarginBlock.marginRight.getValue(pageWidthContext);
132             break;
133         }
134         int before = commonMarginBlock.spaceBefore.getOptimum(pageHeightContext)
135                         .getLength().getValue(pageHeightContext);
136         int after = commonMarginBlock.spaceAfter.getOptimum(pageHeightContext)
137                         .getLength().getValue(pageHeightContext);
138         return new Rectangle(start, before,
139                     reldims.ipd - start - end,
140                     reldims.bpd - before - after);
141     }
142 
143     /** {@inheritDoc} */
getDefaultRegionName()144     public String getDefaultRegionName() {
145         return "xsl-region-body";
146     }
147 
148     /** {@inheritDoc} */
getLocalName()149     public String getLocalName() {
150         return "region-body";
151     }
152 
153     /**
154      * {@inheritDoc}
155      * @return {@link org.apache.fop.fo.Constants#FO_REGION_BODY}
156      */
getNameId()157     public int getNameId() {
158         return FO_REGION_BODY;
159     }
160 }
161