You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SimplePageMaster.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  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. /* $Id$ */
  18. package org.apache.fop.fo.pagination;
  19. // Java
  20. import java.util.HashMap;
  21. import java.util.Iterator;
  22. import java.util.Map;
  23. import org.xml.sax.Locator;
  24. import org.apache.fop.apps.FOPException;
  25. import org.apache.fop.datatypes.Length;
  26. import org.apache.fop.datatypes.Numeric;
  27. import org.apache.fop.datatypes.SimplePercentBaseContext;
  28. import org.apache.fop.datatypes.PercentBaseContext;
  29. import org.apache.fop.fo.FONode;
  30. import org.apache.fop.fo.FObj;
  31. import org.apache.fop.fo.PropertyList;
  32. import org.apache.fop.fo.ValidationException;
  33. import org.apache.fop.fo.properties.CommonMarginBlock;
  34. /**
  35. * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_simple-page-master">
  36. * <code>fo:simple-page-master</code></a> object.
  37. * This creates a simple page from the specified regions
  38. * and attributes.
  39. */
  40. public class SimplePageMaster extends FObj {
  41. // The value of properties relevant for fo:simple-page-master.
  42. private CommonMarginBlock commonMarginBlock;
  43. private String masterName;
  44. private Length pageHeight;
  45. private Length pageWidth;
  46. private Numeric referenceOrientation;
  47. private int writingMode;
  48. // End of property values
  49. /**
  50. * Page regions (regionClass, Region)
  51. */
  52. private Map<String, Region> regions;
  53. // used for node validation
  54. private boolean hasRegionBody = false;
  55. private boolean hasRegionBefore = false;
  56. private boolean hasRegionAfter = false;
  57. private boolean hasRegionStart = false;
  58. private boolean hasRegionEnd = false;
  59. /**
  60. * Base constructor
  61. *
  62. * @param parent {@link FONode} that is the parent of this object
  63. */
  64. public SimplePageMaster(FONode parent) {
  65. super(parent);
  66. }
  67. /** {@inheritDoc} */
  68. public void bind(PropertyList pList) throws FOPException {
  69. commonMarginBlock = pList.getMarginBlockProps();
  70. masterName = pList.get(PR_MASTER_NAME).getString();
  71. pageHeight = pList.get(PR_PAGE_HEIGHT).getLength();
  72. pageWidth = pList.get(PR_PAGE_WIDTH).getLength();
  73. referenceOrientation = pList.get(PR_REFERENCE_ORIENTATION).getNumeric();
  74. writingMode = pList.getWritingMode();
  75. if (masterName == null || masterName.equals("")) {
  76. missingPropertyError("master-name");
  77. }
  78. }
  79. /** {@inheritDoc} */
  80. protected void startOfNode() throws FOPException {
  81. LayoutMasterSet layoutMasterSet = (LayoutMasterSet) parent;
  82. if (masterName == null) {
  83. missingPropertyError("master-name");
  84. } else {
  85. layoutMasterSet.addSimplePageMaster(this);
  86. }
  87. //Well, there are only 5 regions so we can save a bit of memory here
  88. regions = new HashMap<String, Region>(5);
  89. }
  90. /** {@inheritDoc} */
  91. protected void endOfNode() throws FOPException {
  92. if (!hasRegionBody) {
  93. missingChildElementError(
  94. "(region-body, region-before?, region-after?, region-start?, region-end?)");
  95. }
  96. }
  97. /**
  98. * {@inheritDoc}
  99. * <br>XSL Content Model: (region-body,region-before?,region-after?,region-start?,region-end?)
  100. */
  101. protected void validateChildNode(Locator loc, String nsURI, String localName)
  102. throws ValidationException {
  103. if (FO_URI.equals(nsURI)) {
  104. if (localName.equals("region-body")) {
  105. if (hasRegionBody) {
  106. tooManyNodesError(loc, "fo:region-body");
  107. } else {
  108. hasRegionBody = true;
  109. }
  110. } else if (localName.equals("region-before")) {
  111. if (!hasRegionBody) {
  112. nodesOutOfOrderError(loc, "fo:region-body", "fo:region-before");
  113. } else if (hasRegionBefore) {
  114. tooManyNodesError(loc, "fo:region-before");
  115. } else if (hasRegionAfter) {
  116. nodesOutOfOrderError(loc, "fo:region-before", "fo:region-after");
  117. } else if (hasRegionStart) {
  118. nodesOutOfOrderError(loc, "fo:region-before", "fo:region-start");
  119. } else if (hasRegionEnd) {
  120. nodesOutOfOrderError(loc, "fo:region-before", "fo:region-end");
  121. } else {
  122. hasRegionBefore = true;
  123. }
  124. } else if (localName.equals("region-after")) {
  125. if (!hasRegionBody) {
  126. nodesOutOfOrderError(loc, "fo:region-body", "fo:region-after");
  127. } else if (hasRegionAfter) {
  128. tooManyNodesError(loc, "fo:region-after");
  129. } else if (hasRegionStart) {
  130. nodesOutOfOrderError(loc, "fo:region-after", "fo:region-start");
  131. } else if (hasRegionEnd) {
  132. nodesOutOfOrderError(loc, "fo:region-after", "fo:region-end");
  133. } else {
  134. hasRegionAfter = true;
  135. }
  136. } else if (localName.equals("region-start")) {
  137. if (!hasRegionBody) {
  138. nodesOutOfOrderError(loc, "fo:region-body", "fo:region-start");
  139. } else if (hasRegionStart) {
  140. tooManyNodesError(loc, "fo:region-start");
  141. } else if (hasRegionEnd) {
  142. nodesOutOfOrderError(loc, "fo:region-start", "fo:region-end");
  143. } else {
  144. hasRegionStart = true;
  145. }
  146. } else if (localName.equals("region-end")) {
  147. if (!hasRegionBody) {
  148. nodesOutOfOrderError(loc, "fo:region-body", "fo:region-end");
  149. } else if (hasRegionEnd) {
  150. tooManyNodesError(loc, "fo:region-end");
  151. } else {
  152. hasRegionEnd = true;
  153. }
  154. } else {
  155. invalidChildError(loc, nsURI, localName);
  156. }
  157. }
  158. }
  159. /** {@inheritDoc} */
  160. public boolean generatesReferenceAreas() {
  161. return true;
  162. }
  163. /** {@inheritDoc} */
  164. protected void addChildNode(FONode child) throws FOPException {
  165. if (child instanceof Region) {
  166. addRegion((Region)child);
  167. } else {
  168. super.addChildNode(child);
  169. }
  170. }
  171. /**
  172. * Adds a region to this simple-page-master.
  173. * @param region region to add
  174. */
  175. protected void addRegion(Region region) {
  176. regions.put(String.valueOf(region.getNameId()), region);
  177. }
  178. /**
  179. * Gets the context for the width of the page-reference-area,
  180. * taking into account the reference-orientation.
  181. *
  182. * @param lengthBase the lengthBase to use to resolve percentages
  183. * @return context for the width of the page-reference-area
  184. */
  185. protected final PercentBaseContext getPageWidthContext(int lengthBase) {
  186. return (this.referenceOrientation.getValue() % 180 == 0)
  187. ? new SimplePercentBaseContext(
  188. null,
  189. lengthBase,
  190. this.getPageWidth().getValue())
  191. : new SimplePercentBaseContext(
  192. null,
  193. lengthBase,
  194. this.getPageHeight().getValue());
  195. }
  196. /**
  197. * Gets the context for the height of the page-reference-area,
  198. * taking into account the reference-orientation.
  199. *
  200. * @param lengthBase the lengthBase to use to resolve percentages
  201. * @return the context for the height of the page-reference-area
  202. */
  203. protected final PercentBaseContext getPageHeightContext(int lengthBase) {
  204. return (this.referenceOrientation.getValue() % 180 == 0)
  205. ? new SimplePercentBaseContext(
  206. null,
  207. lengthBase,
  208. this.getPageHeight().getValue())
  209. : new SimplePercentBaseContext(
  210. null,
  211. lengthBase,
  212. this.getPageWidth().getValue());
  213. }
  214. /**
  215. * Returns the region for a given region class.
  216. * @param regionId Constants ID of the FO representing the region
  217. * @return the region, null if it doesn't exist
  218. */
  219. public Region getRegion(int regionId) {
  220. return regions.get(String.valueOf(regionId));
  221. }
  222. /**
  223. * Returns a Map of regions associated with this simple-page-master
  224. * @return the regions
  225. */
  226. public Map<String, Region> getRegions() {
  227. return regions;
  228. }
  229. /**
  230. * Indicates if a region with a given name exists in this
  231. * simple-page-master.
  232. * @param regionName name of the region to lookup
  233. * @return True if a region with this name exists
  234. */
  235. protected boolean regionNameExists(String regionName) {
  236. for (Region r : regions.values()) {
  237. if (r.getRegionName().equals(regionName)) {
  238. return true;
  239. }
  240. }
  241. return false;
  242. }
  243. /** @return the Common Margin Properties-Block. */
  244. public CommonMarginBlock getCommonMarginBlock() {
  245. return commonMarginBlock;
  246. }
  247. /** @return "master-name" property. */
  248. public String getMasterName() {
  249. return masterName;
  250. }
  251. /** @return the "page-width" property. */
  252. public Length getPageWidth() {
  253. return pageWidth;
  254. }
  255. /** @return the "page-height" property. */
  256. public Length getPageHeight() {
  257. return pageHeight;
  258. }
  259. /** @return the "writing-mode" property. */
  260. public int getWritingMode() {
  261. return writingMode;
  262. }
  263. /** @return the "reference-orientation" property. */
  264. public int getReferenceOrientation() {
  265. return referenceOrientation.getValue();
  266. }
  267. /** {@inheritDoc} */
  268. public String getLocalName() {
  269. return "simple-page-master";
  270. }
  271. /**
  272. * {@inheritDoc}
  273. * @return {@link org.apache.fop.fo.Constants#FO_SIMPLE_PAGE_MASTER}
  274. */
  275. public int getNameId() {
  276. return FO_SIMPLE_PAGE_MASTER;
  277. }
  278. }