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.

SVGUtilities.java 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  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.svg;
  19. import java.awt.font.FontRenderContext;
  20. import java.awt.geom.AffineTransform;
  21. import java.awt.geom.Rectangle2D;
  22. import java.util.StringTokenizer;
  23. import org.w3c.dom.DOMImplementation;
  24. import org.w3c.dom.Document;
  25. import org.w3c.dom.Element;
  26. import org.apache.batik.anim.dom.SVGDOMImplementation;
  27. import org.apache.batik.constants.XMLConstants;
  28. /**
  29. * Some utilities for creating svg DOM documents and elements.
  30. */
  31. public final class SVGUtilities {
  32. private SVGUtilities() {
  33. }
  34. private static final String SVG_NS = SVGDOMImplementation.SVG_NAMESPACE_URI;
  35. /**
  36. * Create a new svg document with batik.
  37. * @param width the width of the root svg element
  38. * @param height the height of the root svg element
  39. * @return a new SVG Document
  40. */
  41. public static Document createSVGDocument(float width,
  42. float height) {
  43. DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
  44. Document doc = impl.createDocument(SVG_NS, "svg", null);
  45. Element svgRoot = doc.getDocumentElement();
  46. svgRoot.setAttributeNS(null, "width", "" + width);
  47. svgRoot.setAttributeNS(null, "height", "" + height);
  48. return doc;
  49. }
  50. /**
  51. * Get the string width for a particular string given the font.
  52. * @param str the string
  53. * @param font the font
  54. * @return the width of the string in the given font
  55. */
  56. public static float getStringWidth(String str, java.awt.Font font) {
  57. Rectangle2D rect
  58. = font.getStringBounds(str, 0, str.length(),
  59. new FontRenderContext(new AffineTransform(),
  60. true, true));
  61. return (float)rect.getWidth();
  62. }
  63. /**
  64. * Get the string height for a particular string given the font.
  65. * @param str the string
  66. * @param font the font
  67. * @return the height of the string in the given font
  68. */
  69. public static float getStringHeight(String str,
  70. java.awt.Font font) {
  71. Rectangle2D rect
  72. = font.getStringBounds(str, 0, str.length(),
  73. new FontRenderContext(new AffineTransform(),
  74. true, true));
  75. return (float)rect.getHeight();
  76. }
  77. /**
  78. * Get the string bounds for a particular string given the font.
  79. * @param str the string
  80. * @param font the font
  81. * @return the bounds of the string
  82. */
  83. public static Rectangle2D getStringBounds(String str,
  84. java.awt.Font font) {
  85. return font.getStringBounds(str, 0, str.length(),
  86. new FontRenderContext(new AffineTransform(),
  87. true, true));
  88. }
  89. /**
  90. * Create an SVG Line
  91. * @param doc the document to create the element
  92. * @param x the start x position
  93. * @param y the start y position
  94. * @param x2 the end x position
  95. * @param y2 the end y position
  96. * @return the new line element
  97. */
  98. public static Element createLine(Document doc, float x, float y,
  99. float x2, float y2) {
  100. Element ellipse = doc.createElementNS(SVG_NS, "line");
  101. ellipse.setAttributeNS(null, "x1", "" + x);
  102. ellipse.setAttributeNS(null, "x2", "" + x2);
  103. ellipse.setAttributeNS(null, "y1", "" + y);
  104. ellipse.setAttributeNS(null, "y2", "" + y2);
  105. return ellipse;
  106. }
  107. /**
  108. * Create an SVG Ellipse
  109. * @param doc the document to create the element
  110. * @param cx the centre x position
  111. * @param cy the centre y position
  112. * @param rx the x axis radius
  113. * @param ry the y axis radius
  114. * @return the new ellipse element
  115. */
  116. public static Element createEllipse(Document doc, float cx,
  117. float cy, float rx, float ry) {
  118. Element ellipse = doc.createElementNS(SVG_NS, "ellipse");
  119. ellipse.setAttributeNS(null, "cx", "" + cx);
  120. ellipse.setAttributeNS(null, "rx", "" + rx);
  121. ellipse.setAttributeNS(null, "cy", "" + cy);
  122. ellipse.setAttributeNS(null, "ry", "" + ry);
  123. return ellipse;
  124. }
  125. /**
  126. * Create an SVG Path.
  127. * @param doc the document to create the element
  128. * @param str the string for the d attribute on the path
  129. * @return the new path element
  130. */
  131. public static Element createPath(Document doc, String str) {
  132. Element path = doc.createElementNS(SVG_NS, "path");
  133. path.setAttributeNS(null, "d", str);
  134. return path;
  135. }
  136. /**
  137. * Create an SVG Text object.
  138. * @param doc the document to create the element
  139. * @param x the start x position
  140. * @param y the start y position
  141. * @param str the string
  142. * @return the new text element
  143. */
  144. public static Element createText(Document doc, float x, float y,
  145. String str) {
  146. Element textGraph = doc.createElementNS(SVG_NS, "text");
  147. textGraph.setAttributeNS(null, "x", "" + x);
  148. textGraph.setAttributeNS(null, "y", "" + y);
  149. org.w3c.dom.Text text = doc.createTextNode(str);
  150. textGraph.appendChild(text);
  151. return textGraph;
  152. }
  153. /**
  154. * Create an SVG Rectangle.
  155. * @param doc the document to create the element
  156. * @param x the start x position
  157. * @param y the start y position
  158. * @param width the width of the rectangle
  159. * @param height the height of the rectangle
  160. * @return the new rectangle element
  161. */
  162. public static Element createRect(Document doc, float x, float y,
  163. float width, float height) {
  164. Element border = doc.createElementNS(SVG_NS, "rect");
  165. border.setAttributeNS(null, "x", "" + x);
  166. border.setAttributeNS(null, "y", "" + y);
  167. border.setAttributeNS(null, "width", "" + width);
  168. border.setAttributeNS(null, "height", "" + height);
  169. return border;
  170. }
  171. /**
  172. * Create an SVG G.
  173. * @param doc the document to create the element
  174. * @return the new g element
  175. */
  176. public static Element createG(Document doc) {
  177. Element border = doc.createElementNS(SVG_NS, "g");
  178. return border;
  179. }
  180. /**
  181. * Create an SVG Clip.
  182. * @param doc the document to create the element
  183. * @param els the child elements that make the clip
  184. * @param id the id of the clipping path
  185. * @return the new clip element
  186. */
  187. public static Element createClip(Document doc, Element els,
  188. String id) {
  189. Element border = doc.createElementNS(SVG_NS, "clipPath");
  190. border.setAttributeNS(null, "id", id);
  191. border.appendChild(els);
  192. return border;
  193. }
  194. /**
  195. * Create and svg image element.
  196. * @param doc the document to create the element
  197. * @param ref the href link to the image
  198. * @param width the width to set on the image
  199. * @param height the height to set on the image
  200. * @return a new image element
  201. */
  202. public static Element createImage(Document doc, String ref,
  203. float width, float height) {
  204. Element border = doc.createElementNS(SVG_NS, "image");
  205. border.setAttributeNS(XMLConstants.XLINK_NAMESPACE_URI, "href",
  206. ref);
  207. border.setAttributeNS(null, "width", "" + width);
  208. border.setAttributeNS(null, "height", "" + height);
  209. return border;
  210. }
  211. /**
  212. * Create some SVG text that is wrapped into a specified width.
  213. * @param doc the document to create the elements
  214. * @param str the string to wrap
  215. * @param font the font
  216. * @param width the width to wrap
  217. * @return the new element containing the wrapped text
  218. */
  219. public static Element wrapText(Document doc, String str,
  220. java.awt.Font font, float width) {
  221. Element g = createG(doc);
  222. Element text;
  223. StringTokenizer st = new StringTokenizer(str, " \t\r\n");
  224. float totalWidth = 0;
  225. String totalStr = "";
  226. int line = 0;
  227. float height = getStringHeight(str, font);
  228. while (st.hasMoreTokens()) {
  229. String token = st.nextToken();
  230. float strwidth = getStringWidth(token, font);
  231. totalWidth += strwidth;
  232. if (totalWidth > width) {
  233. if (totalStr.equals("")) {
  234. totalStr = token;
  235. token = "";
  236. strwidth = 0;
  237. }
  238. text = createText(doc, 0, line * (height + 5), totalStr);
  239. g.appendChild(text);
  240. totalStr = token;
  241. totalWidth = strwidth;
  242. line++;
  243. } else {
  244. totalStr = totalStr + " " + token;
  245. }
  246. }
  247. return g;
  248. }
  249. }