Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

PageSequence.java 29KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. /*
  2. * $Id$
  3. * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
  4. * For details on use and redistribution please refer to the
  5. * LICENSE file included with these sources.
  6. */
  7. /*
  8. Modified by Mark Lillywhite mark-fop@inomial.com. Does not add
  9. itself to the root any more. Does not hang onto currentPage
  10. pointer, which caused GC issues.
  11. */
  12. package org.apache.fop.fo.pagination;
  13. // FOP
  14. import org.apache.fop.fo.*;
  15. import org.apache.fop.fo.properties.*;
  16. import org.apache.fop.fo.flow.Flow;
  17. import org.apache.fop.fo.flow.StaticContent;
  18. import org.apache.fop.layout.PageMaster;
  19. import org.apache.fop.area.AreaTree;
  20. import org.apache.fop.area.PageViewport;
  21. import org.apache.fop.apps.FOPException;
  22. import org.apache.fop.layoutmgr.PageLayoutManager;
  23. // Java
  24. import java.util.HashMap;
  25. import org.xml.sax.Attributes;
  26. /**
  27. * This provides pagination of flows onto pages. Much of the
  28. * logic for paginating flows is contained in this class.
  29. * The main entry point is the format method.
  30. */
  31. public class PageSequence extends FObj {
  32. //
  33. // intial-page-number types
  34. //
  35. private static final int EXPLICIT = 0;
  36. private static final int AUTO = 1;
  37. private static final int AUTO_EVEN = 2;
  38. private static final int AUTO_ODD = 3;
  39. //
  40. // associations
  41. //
  42. /**
  43. * The parent root object
  44. */
  45. private Root root;
  46. /**
  47. * the set of layout masters (provided by the root object)
  48. */
  49. private LayoutMasterSet layoutMasterSet;
  50. // There doesn't seem to be anything in the spec requiring flows
  51. // to be in the order given, only that they map to the regions
  52. // defined in the page sequence, so all we need is this one hashmap
  53. // the set of flows includes StaticContent flows also
  54. /**
  55. * Map of flows to their flow name (flow-name, Flow)
  56. */
  57. private HashMap _flowMap;
  58. /**
  59. * the "master-reference" attribute
  60. */
  61. private String masterName;
  62. // according to communication from Paul Grosso (XSL-List,
  63. // 001228, Number 406), confusion in spec section 6.4.5 about
  64. // multiplicity of fo:flow in XSL 1.0 is cleared up - one (1)
  65. // fo:flow per fo:page-sequence only.
  66. private boolean isFlowSet = false;
  67. // for structure handler
  68. private boolean sequenceStarted = false;
  69. //
  70. // state attributes used during layout
  71. //
  72. private PageViewport currentPage;
  73. // page number and related formatting variables
  74. private String ipnValue;
  75. private int currentPageNumber = 0;
  76. private int explicitFirstNumber = 0; // explicitly specified
  77. private int firstPageNumber = 0; // actual
  78. private PageNumberGenerator pageNumberGenerator;
  79. private int forcePageCount = 0;
  80. private int pageCount = 0;
  81. private boolean isForcing = false;
  82. /**
  83. * specifies page numbering type (auto|auto-even|auto-odd|explicit)
  84. */
  85. private int pageNumberType;
  86. /**
  87. * used to determine whether to calculate auto, auto-even, auto-odd
  88. */
  89. private boolean thisIsFirstPage;
  90. /**
  91. * the current subsequence while formatting a given page sequence
  92. */
  93. private SubSequenceSpecifier currentSubsequence;
  94. /**
  95. * the current index in the subsequence list
  96. */
  97. private int currentSubsequenceNumber =
  98. -1; // starting case is -1 so that first getNext increments to 0
  99. /**
  100. * the name of the current page master
  101. */
  102. private String currentPageMasterName;
  103. /**
  104. * The main content flow for this page-sequence.
  105. */
  106. private Flow mainFlow=null;
  107. /**
  108. * The fo:title object for this page-sequence.
  109. */
  110. private Title titleFO;
  111. public PageSequence(FONode parent) {
  112. super(parent);
  113. }
  114. public void handleAttrs(Attributes attlist) throws FOPException {
  115. super.handleAttrs(attlist);
  116. if (parent.getName().equals("fo:root")) {
  117. this.root = (Root)parent;
  118. // this.root.addPageSequence(this);
  119. }
  120. else {
  121. throw new FOPException("page-sequence must be child of root, not "
  122. + parent.getName());
  123. }
  124. layoutMasterSet = root.getLayoutMasterSet();
  125. // best time to run some checks on LayoutMasterSet
  126. layoutMasterSet.checkRegionNames();
  127. _flowMap = new HashMap();
  128. thisIsFirstPage =
  129. true; // we are now on the first page of the page sequence
  130. ipnValue = this.properties.get("initial-page-number").getString();
  131. if (ipnValue.equals("auto")) {
  132. pageNumberType = AUTO;
  133. } else if (ipnValue.equals("auto-even")) {
  134. pageNumberType = AUTO_EVEN;
  135. } else if (ipnValue.equals("auto-odd")) {
  136. pageNumberType = AUTO_ODD;
  137. } else {
  138. pageNumberType = EXPLICIT;
  139. try {
  140. int pageStart = new Integer(ipnValue).intValue();
  141. this.explicitFirstNumber = (pageStart > 0) ? pageStart - 1 : 0;
  142. } catch (NumberFormatException nfe) {
  143. throw new FOPException("\"" + ipnValue
  144. + "\" is not a valid value for initial-page-number");
  145. }
  146. }
  147. masterName = this.properties.get("master-reference").getString();
  148. // TODO: Add code here to set a reference to the PageSequenceMaster
  149. // if the masterName names a page-sequence-master, else get a
  150. // reference to the SimplePageMaster. Throw an exception if neither?
  151. // get the 'format' properties
  152. this.pageNumberGenerator =
  153. new PageNumberGenerator(this.properties.get("format").getString(),
  154. this.properties.get("grouping-separator").getCharacter(),
  155. this.properties.get("grouping-size").getNumber().intValue(),
  156. this.properties.get("letter-value").getEnum());
  157. this.pageNumberGenerator.enableLogging(getLogger());
  158. this.forcePageCount =
  159. this.properties.get("force-page-count").getEnum();
  160. // this.properties.get("country");
  161. // this.properties.get("language");
  162. setupID();
  163. }
  164. /**
  165. * Add a flow or static content, mapped by its flow-name.
  166. * The flow-name is used to associate the flow with a region on a page,
  167. * based on the names given to the regions in the page-master used to
  168. * generate that page.
  169. */
  170. private void addFlow(Flow flow) throws FOPException {
  171. if (_flowMap.containsKey(flow.getFlowName())) {
  172. throw new FOPException("flow-names must be unique within an fo:page-sequence");
  173. }
  174. if (!this.layoutMasterSet.regionNameExists(flow.getFlowName())) {
  175. getLogger().error("region-name '"
  176. + flow.getFlowName()
  177. + "' doesn't exist in the layout-master-set.");
  178. }
  179. _flowMap.put(flow.getFlowName(), flow);
  180. //setIsFlowSet(true);
  181. }
  182. /**
  183. * Validate the child being added and initialize internal variables.
  184. * XSL content model for page-sequence:
  185. * <pre>(title?,static-content*,flow)</pre>
  186. * Note: title isn't currently implemented.
  187. * @param child The flow object child to be added to the PageSequence.
  188. */
  189. public void addChild(FONode child) {
  190. try {
  191. String childName = child.getName();
  192. if (childName.equals("fo:title")) {
  193. if (this._flowMap.size()>0) {
  194. getLogger().warn("fo:title should be first in page-sequence");
  195. } else {
  196. this.titleFO = (Title)child;
  197. structHandler.startPageSequence(this, titleFO, layoutMasterSet);
  198. sequenceStarted = true;
  199. }
  200. } else if (childName.equals("fo:flow")) {
  201. if (this.mainFlow != null) {
  202. throw new FOPException("Only a single fo:flow permitted"
  203. + " per fo:page-sequence");
  204. } else {
  205. if(!sequenceStarted) {
  206. structHandler.startPageSequence(this, titleFO, layoutMasterSet);
  207. sequenceStarted = true;
  208. }
  209. this.mainFlow = (Flow)child;
  210. addFlow(mainFlow);
  211. super.addChild(child); // For getChildren
  212. }
  213. } else if (childName.equals("fo:static-content")) {
  214. if (this.mainFlow != null) {
  215. throw new FOPException(childName +
  216. " must precede fo:flow; ignoring");
  217. } else {
  218. if(!sequenceStarted) {
  219. structHandler.startPageSequence(this, titleFO, layoutMasterSet);
  220. sequenceStarted = true;
  221. }
  222. addFlow((Flow)child);
  223. }
  224. } else {
  225. // Ignore it!
  226. getLogger().warn("FO '" + childName +
  227. "' not a legal page-sequence child.");
  228. return;
  229. }
  230. } catch (FOPException fopex) {
  231. getLogger().error("Error in PageSequence.addChild(): " +
  232. fopex.getMessage(), fopex);
  233. }
  234. }
  235. public void end() {
  236. try {
  237. this.structHandler.endPageSequence(this);
  238. } catch (FOPException fopex) {
  239. getLogger().error("Error in PageSequence.end(): " +
  240. fopex.getMessage(), fopex);
  241. }
  242. }
  243. // /**
  244. // * Return children for layout. Only the main flow is laid out directly.
  245. // */
  246. // public ListIterator getChildren() {
  247. // return new ListIterator() {
  248. // boolean bFirst=true;
  249. // public boolean hasNext() {
  250. // return (bFirst==true && mainFlow != null);
  251. // }
  252. // public Object next() {
  253. // if (bFirst==true && mainFlow != null) {
  254. // bFirst=false;
  255. // return mainFlow;
  256. // }
  257. // else throw new NoSuchElementException();
  258. // }
  259. // public void remove() {
  260. // throw new UnsupportedOperationException();
  261. // }
  262. // };
  263. // }
  264. /**
  265. * Runs the formatting of this page sequence into the given area tree
  266. */
  267. public void format(AreaTree areaTree) throws FOPException {
  268. // Make a new PageLayoutManager and a FlowLayoutManager
  269. // Run the PLM in a thread
  270. // Wait for them to finish.
  271. // If no main flow, nothing to layout!
  272. if (this.mainFlow == null) return;
  273. // Initialize if already used?
  274. this.layoutMasterSet.resetPageMasters();
  275. int firstAvailPageNumber = 0;
  276. // This will layout pages and add them to the area tree
  277. PageLayoutManager pageLM = new PageLayoutManager(areaTree, this);
  278. // For now, skip the threading and just call run directly.
  279. pageLM.run();
  280. // Thread layoutThread = new Thread(pageLM);
  281. // layoutThread.start();
  282. // log.debug("Layout thread started");
  283. // // wait on both managers
  284. // try {
  285. // layoutThread.join();
  286. // log.debug("Layout thread done");
  287. // } catch (InterruptedException ie) {
  288. // log.error("PageSequence.format() interrupted waiting on layout");
  289. // }
  290. // Tell the root the last page number we created.
  291. this.root.setRunningPageNumberCounter(this.currentPageNumber);
  292. }
  293. private void initPageNumber() {
  294. this.currentPageNumber = this.root.getRunningPageNumberCounter() + 1;
  295. if (this.pageNumberType == AUTO_ODD) {
  296. // Next page but force odd. May force empty page creation!
  297. // Whose master is used for this??? Assume no.
  298. // Use force-page-count=auto
  299. // on preceding page-sequence to make sure that there is no gap!
  300. if (currentPageNumber % 2 == 0) {
  301. this.currentPageNumber++;
  302. }
  303. } else if (pageNumberType == AUTO_EVEN) {
  304. if (currentPageNumber % 2 == 1) {
  305. this.currentPageNumber++;
  306. }
  307. }
  308. else if (pageNumberType == EXPLICIT) {
  309. this.currentPageNumber = this.explicitFirstNumber;
  310. }
  311. this.firstPageNumber = this.currentPageNumber;
  312. }
  313. /**
  314. * Called by PageLayoutManager when it needs a new page on which to
  315. * place content. The PageSequence manages the page number (odd/even),
  316. * but the PLM tells it if the page is blank or is the last page.
  317. * @param bIsBlank If true, use a master for a blank page.
  318. * @param bIsLast If true, use the master for the last page in the sequence.
  319. */
  320. public PageViewport createPage(boolean bIsBlank, boolean bIsLast)
  321. throws FOPException
  322. {
  323. // Set even/odd flag and first flag based on current state
  324. // Should do it this way, but fix it later....
  325. /*boolean bEvenPage = ((this.currentPageNumber %2)==0);
  326. currentPage = makePage(bEvenPage, */
  327. currentPage = makePage(this.currentPageNumber,
  328. this.currentPageNumber==this.firstPageNumber,
  329. bIsLast, bIsBlank);
  330. return currentPage;
  331. // The page will have a viewport/reference area pair defined
  332. // for each region in the master.
  333. // Set up the page itself
  334. // currentPage.setNumber(this.currentPageNumber);
  335. // SKIP ALL THIS FOR NOW!!!
  336. // String formattedPageNumber =
  337. // pageNumberGenerator.makeFormattedPageNumber(this.currentPageNumber);
  338. // currentPage.setFormattedNumber(formattedPageNumber);
  339. // this.currentPageNumber++;
  340. // //this.root.setRunningPageNumberCounter(this.currentPageNumber);
  341. // BodyAreaContainer bodyArea = currentPage.getBody();
  342. // bodyArea.setIDReferences(areaTree.getIDReferences());
  343. // // because of markers, do after fo:flow (likely also
  344. // // justifiable because of spec)
  345. // currentPage.setPageSequence(this);
  346. // formatStaticContent(areaTree);
  347. // //log.info("]");
  348. // areaTree.addPage(currentPage);
  349. // this.pageCount++; // used for 'force-page-count' calculations
  350. // handle the 'force-page-count'
  351. //forcePage(areaTree, firstAvailPageNumber);
  352. }
  353. /**
  354. * Creates a new page area for the given parameters
  355. * @param areaTree the area tree the page should be contained in
  356. * @param firstAvailPageNumber the page number for this page
  357. * @param isFirstPage true when this is the first page in the sequence
  358. * @param isEmptyPage true if this page will be empty
  359. * (e.g. forced even or odd break)
  360. * @return a Page layout object based on the page master selected
  361. * from the params
  362. * TODO: modify the other methods to use even/odd flag and bIsLast
  363. */
  364. private PageViewport makePage(int firstAvailPageNumber,
  365. boolean isFirstPage, boolean bIsLast,
  366. boolean isEmptyPage) throws FOPException {
  367. // layout this page sequence
  368. // while there is still stuff in the flow, ask the
  369. // layoutMasterSet for a new page
  370. // page number is 0-indexed
  371. PageMaster pageMaster = getNextPageMaster(masterName,
  372. firstAvailPageNumber,
  373. isFirstPage, isEmptyPage);
  374. // a legal alternative is to use the last sub-sequence
  375. // specification which should be handled in getNextSubsequence.
  376. // That's not done here.
  377. if (pageMaster == null) {
  378. throw new FOPException("page masters exhausted. Cannot recover.");
  379. }
  380. PageViewport p = pageMaster.makePage();
  381. // if (currentPage != null) {
  382. // Vector foots = currentPage.getPendingFootnotes();
  383. // p.setPendingFootnotes(foots);
  384. // }
  385. return p;
  386. }
  387. /**
  388. * Formats the static content of the current page
  389. */
  390. // private void formatStaticContent(AreaTree areaTree) throws FOPException {
  391. // SimplePageMaster simpleMaster = getCurrentSimplePageMaster();
  392. // if (simpleMaster.getRegion(Region.BODY) != null
  393. // && (currentPage.getBefore() != null)) {
  394. // Flow staticFlow =
  395. // (Flow)_flowMap.get(simpleMaster.getRegion(RegionBefore.REGION_CLASS).getRegionName());
  396. // if (staticFlow != null) {
  397. // AreaContainer beforeArea = currentPage.getBefore();
  398. // beforeArea.setIDReferences(areaTree.getIDReferences());
  399. // layoutStaticContent(staticFlow,
  400. // simpleMaster.getRegion(RegionBefore.REGION_CLASS),
  401. // beforeArea);
  402. // }
  403. // }
  404. // if (simpleMaster.getRegion(RegionAfter.REGION_CLASS) != null
  405. // && (currentPage.getAfter() != null)) {
  406. // Flow staticFlow =
  407. // (Flow)_flowMap.get(simpleMaster.getRegion(RegionAfter.REGION_CLASS).getRegionName());
  408. // if (staticFlow != null) {
  409. // AreaContainer afterArea = currentPage.getAfter();
  410. // afterArea.setIDReferences(areaTree.getIDReferences());
  411. // layoutStaticContent(staticFlow,
  412. // simpleMaster.getRegion(RegionAfter.REGION_CLASS),
  413. // afterArea);
  414. // }
  415. // }
  416. // if (simpleMaster.getRegion(RegionStart.REGION_CLASS) != null
  417. // && (currentPage.getStart() != null)) {
  418. // Flow staticFlow =
  419. // (Flow)_flowMap.get(simpleMaster.getRegion(RegionStart.REGION_CLASS).getRegionName());
  420. // if (staticFlow != null) {
  421. // AreaContainer startArea = currentPage.getStart();
  422. // startArea.setIDReferences(areaTree.getIDReferences());
  423. // layoutStaticContent(staticFlow,
  424. // simpleMaster.getRegion(RegionStart.REGION_CLASS),
  425. // startArea);
  426. // }
  427. // }
  428. // if (simpleMaster.getRegion(RegionEnd.REGION_CLASS) != null
  429. // && (currentPage.getEnd() != null)) {
  430. // Flow staticFlow =
  431. // (Flow)_flowMap.get(simpleMaster.getRegion(RegionEnd.REGION_CLASS).getRegionName());
  432. // if (staticFlow != null) {
  433. // AreaContainer endArea = currentPage.getEnd();
  434. // endArea.setIDReferences(areaTree.getIDReferences());
  435. // layoutStaticContent(staticFlow,
  436. // simpleMaster.getRegion(RegionEnd.REGION_CLASS),
  437. // endArea);
  438. // }
  439. // }
  440. // }
  441. //
  442. // private void layoutStaticContent(Flow flow, Region region,
  443. // AreaContainer area) throws FOPException {
  444. // if (flow instanceof StaticContent) {
  445. // AreaContainer beforeArea = currentPage.getBefore();
  446. // ((StaticContent)flow).layout(area, region);
  447. // } else {
  448. // log.error("" + region.getName()
  449. // + " only supports static-content flows currently. Cannot use flow named '"
  450. // + flow.getFlowName() + "'");
  451. // }
  452. // }
  453. /**
  454. * Returns the next SubSequenceSpecifier for the given page sequence master.
  455. * The result is bassed on the current state of this page sequence.
  456. */
  457. private SubSequenceSpecifier getNextSubsequence(PageSequenceMaster master) {
  458. if (master.getSubSequenceSpecifierCount()
  459. > currentSubsequenceNumber + 1) {
  460. currentSubsequence =
  461. master.getSubSequenceSpecifier(currentSubsequenceNumber + 1);
  462. currentSubsequenceNumber++;
  463. return currentSubsequence;
  464. } else {
  465. return null;
  466. }
  467. }
  468. /**
  469. * Returns the next simple page master for the given sequence master, page number and
  470. * other state information
  471. */
  472. private SimplePageMaster getNextSimplePageMaster(PageSequenceMaster sequenceMaster,
  473. int currentPageNumber, boolean thisIsFirstPage,
  474. boolean isEmptyPage) {
  475. // handle forcing
  476. if (isForcing) {
  477. String nextPageMaster = getNextPageMasterName(sequenceMaster,
  478. currentPageNumber, false, true);
  479. return this.layoutMasterSet.getSimplePageMaster(nextPageMaster);
  480. }
  481. String nextPageMaster = getNextPageMasterName(sequenceMaster,
  482. currentPageNumber, thisIsFirstPage, isEmptyPage);
  483. return this.layoutMasterSet.getSimplePageMaster(nextPageMaster);
  484. }
  485. /**
  486. * Get the next page master name.
  487. * This gets the name of the next page master. If the sequence
  488. * is exhausted then an error is indicated and the last page
  489. * master name is used.
  490. */
  491. private String getNextPageMasterName(PageSequenceMaster sequenceMaster,
  492. int currentPageNumber,
  493. boolean thisIsFirstPage,
  494. boolean isEmptyPage) {
  495. if (null == currentSubsequence) {
  496. currentSubsequence = getNextSubsequence(sequenceMaster);
  497. }
  498. String nextPageMaster =
  499. currentSubsequence.getNextPageMaster(currentPageNumber,
  500. thisIsFirstPage,
  501. isEmptyPage);
  502. if (null == nextPageMaster
  503. || isFlowForMasterNameDone(currentPageMasterName)) {
  504. SubSequenceSpecifier nextSubsequence =
  505. getNextSubsequence(sequenceMaster);
  506. if (nextSubsequence == null) {
  507. getLogger().error("Page subsequences exhausted. Using previous subsequence.");
  508. thisIsFirstPage =
  509. true; // this becomes the first page in the new (old really) page master
  510. currentSubsequence.reset();
  511. // we leave currentSubsequence alone
  512. }
  513. else {
  514. currentSubsequence = nextSubsequence;
  515. }
  516. nextPageMaster =
  517. currentSubsequence.getNextPageMaster(currentPageNumber,
  518. thisIsFirstPage,
  519. isEmptyPage);
  520. }
  521. currentPageMasterName = nextPageMaster;
  522. return nextPageMaster;
  523. }
  524. private SimplePageMaster getCurrentSimplePageMaster() {
  525. return this.layoutMasterSet.getSimplePageMaster(currentPageMasterName);
  526. }
  527. private String getCurrentPageMasterName() {
  528. return currentPageMasterName;
  529. }
  530. // refactored from LayoutMasterSet
  531. private PageMaster getNextPageMaster(String pageSequenceName,
  532. int currentPageNumber,
  533. boolean thisIsFirstPage,
  534. boolean isEmptyPage) throws FOPException {
  535. PageMaster pageMaster = null;
  536. // see if there is a page master sequence for this master name
  537. PageSequenceMaster sequenceMaster =
  538. this.layoutMasterSet.getPageSequenceMaster(pageSequenceName);
  539. if (sequenceMaster != null) {
  540. pageMaster = getNextSimplePageMaster(sequenceMaster,
  541. currentPageNumber,
  542. thisIsFirstPage,
  543. isEmptyPage).getPageMaster();
  544. } else { // otherwise see if there's a simple master by the given name
  545. SimplePageMaster simpleMaster =
  546. this.layoutMasterSet.getSimplePageMaster(pageSequenceName);
  547. if (simpleMaster == null) {
  548. throw new FOPException("'master-reference' for 'fo:page-sequence'"
  549. + "matches no 'simple-page-master' or 'page-sequence-master'");
  550. }
  551. currentPageMasterName = pageSequenceName;
  552. pageMaster = simpleMaster.getNextPageMaster();
  553. }
  554. return pageMaster;
  555. }
  556. // /**
  557. // * Returns true when there is more flow elements left to lay out.
  558. // */
  559. // private boolean flowsAreIncomplete() {
  560. // boolean isIncomplete = false;
  561. // for (Iterator e = _flowMap.values().iterator(); e.hasNext(); ) {
  562. // Flow flow = (Flow)e.next();
  563. // if (flow instanceof StaticContent) {
  564. // continue;
  565. // }
  566. // Status status = flow.getStatus();
  567. // isIncomplete |= status.isIncomplete();
  568. // }
  569. // return isIncomplete;
  570. // }
  571. // /**
  572. // * Returns the flow that maps to the given region class for the current
  573. // * page master.
  574. // */
  575. // private Flow getCurrentFlow(String regionClass) {
  576. // Region region = getCurrentSimplePageMaster().getRegion(regionClass);
  577. // if (region != null) {
  578. // Flow flow = (Flow)_flowMap.get(region.getRegionName());
  579. // return flow;
  580. // } else {
  581. // getLogger().error("flow is null. regionClass = '" + regionClass
  582. // + "' currentSPM = "
  583. // + getCurrentSimplePageMaster());
  584. // return null;
  585. // }
  586. // }
  587. private boolean isFlowForMasterNameDone(String masterName) {
  588. // parameter is master-name of PMR; we need to locate PM
  589. // referenced by this, and determine whether flow(s) are OK
  590. if (isForcing)
  591. return false;
  592. if (masterName != null) {
  593. SimplePageMaster spm =
  594. this.layoutMasterSet.getSimplePageMaster(masterName);
  595. Region region = spm.getRegion(Region.BODY);
  596. Flow flow = (Flow)_flowMap.get(region.getRegionName());
  597. /*if ((null == flow) || flow.getStatus().isIncomplete())
  598. return false;
  599. else
  600. return true;*/
  601. }
  602. return false;
  603. }
  604. public boolean isFlowSet() {
  605. return isFlowSet;
  606. }
  607. public void setIsFlowSet(boolean isFlowSet) {
  608. this.isFlowSet = isFlowSet;
  609. }
  610. public String getIpnValue() {
  611. return ipnValue;
  612. }
  613. public int getCurrentPageNumber() {
  614. return currentPageNumber;
  615. }
  616. // private void forcePage(AreaTree areaTree, int firstAvailPageNumber) {
  617. // boolean makePage = false;
  618. // if (this.forcePageCount == ForcePageCount.AUTO) {
  619. // PageSequence nextSequence =
  620. // this.root.getSucceedingPageSequence(this);
  621. // if (nextSequence != null) {
  622. // if (nextSequence.getIpnValue().equals("auto")) {
  623. // // do nothing special
  624. // }
  625. // else if (nextSequence.getIpnValue().equals("auto-odd")) {
  626. // if (firstAvailPageNumber % 2 == 0) {
  627. // makePage = true;
  628. // }
  629. // } else if (nextSequence.getIpnValue().equals("auto-even")) {
  630. // if (firstAvailPageNumber % 2 != 0) {
  631. // makePage = true;
  632. // }
  633. // } else {
  634. // int nextSequenceStartPageNumber =
  635. // nextSequence.getCurrentPageNumber();
  636. // if ((nextSequenceStartPageNumber % 2 == 0)
  637. // && (firstAvailPageNumber % 2 == 0)) {
  638. // makePage = true;
  639. // } else if ((nextSequenceStartPageNumber % 2 != 0)
  640. // && (firstAvailPageNumber % 2 != 0)) {
  641. // makePage = true;
  642. // }
  643. // }
  644. // }
  645. // } else if ((this.forcePageCount == ForcePageCount.EVEN)
  646. // && (this.pageCount % 2 != 0)) {
  647. // makePage = true;
  648. // } else if ((this.forcePageCount == ForcePageCount.ODD)
  649. // && (this.pageCount % 2 == 0)) {
  650. // makePage = true;
  651. // } else if ((this.forcePageCount == ForcePageCount.END_ON_EVEN)
  652. // && (firstAvailPageNumber % 2 == 0)) {
  653. // makePage = true;
  654. // } else if ((this.forcePageCount == ForcePageCount.END_ON_ODD)
  655. // && (firstAvailPageNumber % 2 != 0)) {
  656. // makePage = true;
  657. // } else if (this.forcePageCount == ForcePageCount.NO_FORCE) {
  658. // // do nothing
  659. // }
  660. // if (makePage) {
  661. // try {
  662. // this.isForcing = true;
  663. // this.currentPageNumber++;
  664. // firstAvailPageNumber = this.currentPageNumber;
  665. // currentPage = makePage(areaTree, firstAvailPageNumber, false,
  666. // true);
  667. // String formattedPageNumber =
  668. // pageNumberGenerator.makeFormattedPageNumber(this.currentPageNumber);
  669. // currentPage.setFormattedNumber(formattedPageNumber);
  670. // currentPage.setPageSequence(this);
  671. // formatStaticContent(areaTree);
  672. // log.debug("[forced-" + firstAvailPageNumber + "]");
  673. // areaTree.addPage(currentPage);
  674. // this.root.setRunningPageNumberCounter(this.currentPageNumber);
  675. // this.isForcing = false;
  676. // } catch (FOPException fopex) {
  677. // log.debug("'force-page-count' failure");
  678. // }
  679. // }
  680. // }
  681. }