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.

Leader.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /*
  2. * $Id$
  3. * ============================================================================
  4. * The Apache Software License, Version 1.1
  5. * ============================================================================
  6. *
  7. * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without modifica-
  10. * tion, are permitted provided that the following conditions are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright notice,
  13. * this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if any, must
  20. * include the following acknowledgment: "This product includes software
  21. * developed by the Apache Software Foundation (http://www.apache.org/)."
  22. * Alternately, this acknowledgment may appear in the software itself, if
  23. * and wherever such third-party acknowledgments normally appear.
  24. *
  25. * 4. The names "FOP" and "Apache Software Foundation" must not be used to
  26. * endorse or promote products derived from this software without prior
  27. * written permission. For written permission, please contact
  28. * apache@apache.org.
  29. *
  30. * 5. Products derived from this software may not be called "Apache", nor may
  31. * "Apache" appear in their name, without prior written permission of the
  32. * Apache Software Foundation.
  33. *
  34. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  35. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  36. * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  37. * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  38. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
  39. * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  40. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  43. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44. * ============================================================================
  45. *
  46. * This software consists of voluntary contributions made by many individuals
  47. * on behalf of the Apache Software Foundation and was originally created by
  48. * James Tauber <jtauber@jtauber.com>. For more information on the Apache
  49. * Software Foundation, please see <http://www.apache.org/>.
  50. */
  51. package org.apache.fop.fo.flow;
  52. // FOP
  53. import org.apache.fop.fo.FObjMixed;
  54. import org.apache.fop.fo.FObj;
  55. import org.apache.fop.fo.PropertyList;
  56. import org.apache.fop.fo.Status;
  57. import org.apache.fop.datatypes.ColorType;
  58. import org.apache.fop.datatypes.Length;
  59. import org.apache.fop.datatypes.PercentLength;
  60. import org.apache.fop.layout.Area;
  61. import org.apache.fop.layout.AccessibilityProps;
  62. import org.apache.fop.layout.AuralProps;
  63. import org.apache.fop.layout.BorderAndPadding;
  64. import org.apache.fop.layout.BackgroundProps;
  65. import org.apache.fop.layout.MarginInlineProps;
  66. import org.apache.fop.layout.RelativePositionProps;
  67. import org.apache.fop.layout.BlockArea;
  68. import org.apache.fop.layout.LineArea;
  69. import org.apache.fop.layout.FontState;
  70. import org.apache.fop.apps.FOPException;
  71. /**
  72. * Implements fo:leader; main property of leader leader-pattern.
  73. * The following patterns are treated: rule, space, dots.
  74. * The pattern use-content is ignored, i.e. it still must be implemented.
  75. */
  76. public class Leader extends FObjMixed {
  77. public static class Maker extends FObj.Maker {
  78. public FObj make(FObj parent, PropertyList propertyList,
  79. String systemId, int line, int column)
  80. throws FOPException {
  81. return new Leader(parent, propertyList, systemId, line, column);
  82. }
  83. }
  84. public static FObj.Maker maker() {
  85. return new Leader.Maker();
  86. }
  87. public Leader(FObj parent, PropertyList propertyList,
  88. String systemId, int line, int column)
  89. throws FOPException {
  90. super(parent, propertyList, systemId, line, column);
  91. }
  92. public String getName() {
  93. return "fo:leader";
  94. }
  95. public int layout(Area area) throws FOPException {
  96. BlockArea blockArea;
  97. // restriction in this version
  98. if (!(area instanceof BlockArea)) {
  99. log.warn("in this version of Fop fo:leader must be a direct child of fo:block ");
  100. return Status.OK;
  101. } else {
  102. blockArea = (BlockArea)area;
  103. }
  104. // Common Accessibility Properties
  105. AccessibilityProps mAccProps = propMgr.getAccessibilityProps();
  106. // Common Aural Properties
  107. AuralProps mAurProps = propMgr.getAuralProps();
  108. // Common Border, Padding, and Background Properties
  109. BorderAndPadding bap = propMgr.getBorderAndPadding();
  110. BackgroundProps bProps = propMgr.getBackgroundProps();
  111. // Common Font Properties
  112. //this.fontState = propMgr.getFontState(area.getFontInfo());
  113. // Common Margin Properties-Inline
  114. MarginInlineProps mProps = propMgr.getMarginInlineProps();
  115. // Common Relative Position Properties
  116. RelativePositionProps mRelProps = propMgr.getRelativePositionProps();
  117. // this.properties.get("alignment-adjust");
  118. // this.properties.get("alignment-baseline");
  119. // this.properties.get("baseline-shift");
  120. // this.properties.get("color");
  121. // this.properties.get("dominant-baseline");
  122. // this.properties.get("text-depth");
  123. // this.properties.get("text-altitude");
  124. // this.properties.get("id");
  125. // this.properties.get("leader-alignment");
  126. // this.properties.get("leader-length");
  127. // this.properties.get("leader-pattern");
  128. // this.properties.get("leader-pattern-width");
  129. // this.properties.get("rule-style");
  130. // this.properties.get("rule-thickness");
  131. // this.properties.get("letter-spacing");
  132. // this.properties.get("line-height");
  133. // this.properties.get("line-height-shift-adjustment");
  134. // this.properties.get("text-shadow");
  135. // this.properties.get("visibility");
  136. // this.properties.get("word-spacing");
  137. // this.properties.get("z-index");
  138. // color properties
  139. ColorType c = this.properties.get("color").getColorType();
  140. float red = c.red();
  141. float green = c.green();
  142. float blue = c.blue();
  143. // fo:leader specific properties
  144. // determines the pattern of leader; allowed values: space, rule,dots, use-content
  145. int leaderPattern = this.properties.get("leader-pattern").getEnum();
  146. // length of the leader
  147. Length length = this.properties.get("leader-length.minimum").getLength();
  148. int leaderLengthMinimum;
  149. if (length instanceof PercentLength) {
  150. leaderLengthMinimum = (int)(((PercentLength)length).value()
  151. * area.getAllocationWidth());
  152. } else {
  153. leaderLengthMinimum = length.mvalue();
  154. }
  155. length = this.properties.get("leader-length.optimum").getLength();
  156. int leaderLengthOptimum;
  157. if (length instanceof PercentLength) {
  158. leaderLengthOptimum = (int)(((PercentLength)length).value()
  159. * area.getAllocationWidth());
  160. } else {
  161. leaderLengthOptimum = length.mvalue();
  162. }
  163. length = this.properties.get("leader-length.maximum").getLength();
  164. int leaderLengthMaximum;
  165. if (length instanceof PercentLength) {
  166. leaderLengthMaximum = (int)(((PercentLength)length).value()
  167. * area.getAllocationWidth());
  168. } else {
  169. leaderLengthMaximum = length.mvalue();
  170. }
  171. // the following properties only apply for leader-pattern = "rule"
  172. int ruleThickness =
  173. this.properties.get("rule-thickness").getLength().mvalue();
  174. int ruleStyle = this.properties.get("rule-style").getEnum();
  175. // if leaderPatternWidth = 0 = default = use-font-metric
  176. int leaderPatternWidth =
  177. this.properties.get("leader-pattern-width").getLength().mvalue();
  178. int leaderAlignment =
  179. this.properties.get("leader-alignment").getEnum();
  180. // initialize id
  181. String id = this.properties.get("id").getString();
  182. try {
  183. blockArea.getIDReferences().initializeID(id, blockArea);
  184. }
  185. catch(FOPException e) {
  186. if (!e.isLocationSet()) {
  187. e.setLocation(systemId, line, column);
  188. }
  189. throw e;
  190. }
  191. // adds leader to blockarea, there the leaderArea is generated
  192. int succeeded = addLeader(blockArea,
  193. propMgr.getFontState(area.getFontInfo()),
  194. red, green, blue, leaderPattern,
  195. leaderLengthMinimum, leaderLengthOptimum,
  196. leaderLengthMaximum, ruleThickness,
  197. ruleStyle, leaderPatternWidth,
  198. leaderAlignment);
  199. if (succeeded == 1) {
  200. return Status.OK;
  201. } else {
  202. // not sure that this is the correct Status here
  203. return Status.AREA_FULL_SOME;
  204. }
  205. }
  206. /**
  207. * adds a leader to current line area of containing block area
  208. * the actual leader area is created in the line area
  209. *
  210. * @return int +1 for success and -1 for none
  211. */
  212. public int addLeader(BlockArea ba, FontState fontState, float red,
  213. float green, float blue, int leaderPattern,
  214. int leaderLengthMinimum, int leaderLengthOptimum,
  215. int leaderLengthMaximum, int ruleThickness,
  216. int ruleStyle, int leaderPatternWidth,
  217. int leaderAlignment) {
  218. LineArea la = ba.getCurrentLineArea();
  219. // this should start a new page
  220. if (la == null) {
  221. return -1;
  222. }
  223. la.changeFont(fontState);
  224. la.changeColor(red, green, blue);
  225. // check whether leader fits into the (rest of the) line
  226. // using length.optimum to determine where to break the line as defined
  227. // in the xsl:fo spec: "User agents may choose to use the value of 'leader-length.optimum'
  228. // to determine where to break the line" (7.20.4)
  229. // if leader is longer then create a new LineArea and put leader there
  230. if (leaderLengthOptimum <= la.getRemainingWidth()) {
  231. la.addLeader(leaderPattern, leaderLengthMinimum,
  232. leaderLengthOptimum, leaderLengthMaximum, ruleStyle,
  233. ruleThickness, leaderPatternWidth, leaderAlignment);
  234. } else {
  235. la = ba.createNextLineArea();
  236. if (la == null) {
  237. // not enough room
  238. return -1;
  239. }
  240. la.changeFont(fontState);
  241. la.changeColor(red, green, blue);
  242. // check whether leader fits into LineArea at all, otherwise
  243. // clip it (should honor the clip option of containing area)
  244. if (leaderLengthMinimum <= la.getContentWidth()) {
  245. la.addLeader(leaderPattern, leaderLengthMinimum,
  246. leaderLengthOptimum, leaderLengthMaximum,
  247. ruleStyle, ruleThickness, leaderPatternWidth,
  248. leaderAlignment);
  249. } else {
  250. log.error("Leader doesn't fit into line, it will be clipped to fit.");
  251. la.addLeader(leaderPattern, la.getRemainingWidth(),
  252. la.getRemainingWidth(), la.getRemainingWidth(),
  253. ruleStyle, ruleThickness, leaderPatternWidth,
  254. leaderAlignment);
  255. }
  256. }
  257. return 1;
  258. }
  259. }