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.

FoUnitsConverter.java 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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.render.rtf;
  19. import java.util.HashMap;
  20. import java.util.Map;
  21. import org.apache.fop.apps.FOPException;
  22. import org.apache.fop.fo.properties.FixedLength;
  23. /** Converts XSL-FO units to RTF units
  24. *
  25. * @author Bertrand Delacretaz <bdelacretaz@codeconsult.ch>
  26. * @author putzi
  27. * @author Peter Herweg <pherweg@web.de>
  28. *
  29. * This class was originally developed by Bertrand Delacretaz bdelacretaz@codeconsult.ch
  30. * for the JFOR project and is now integrated into FOP.
  31. */
  32. final class FoUnitsConverter {
  33. private static final FoUnitsConverter INSTANCE = new FoUnitsConverter();
  34. /** points to twips: 1 twip is 1/20 of a point */
  35. public static final float POINT_TO_TWIPS = 20f;
  36. /** millimeters and centimeters to twips: , one point is 1/72 of an inch, one inch is 25.4 mm */
  37. public static final float IN_TO_TWIPS = 72f * POINT_TO_TWIPS;
  38. public static final float MM_TO_TWIPS = IN_TO_TWIPS / 25.4f;
  39. public static final float CM_TO_TWIPS = 10 * MM_TO_TWIPS;
  40. /** conversion factors keyed by xsl:fo units names */
  41. private static final Map TWIP_FACTORS = new HashMap();
  42. static {
  43. TWIP_FACTORS.put(FixedLength.MM, new Float(MM_TO_TWIPS));
  44. TWIP_FACTORS.put(FixedLength.CM, new Float(CM_TO_TWIPS));
  45. TWIP_FACTORS.put(FixedLength.POINT, new Float(POINT_TO_TWIPS));
  46. TWIP_FACTORS.put(FixedLength.INCH, new Float(IN_TO_TWIPS));
  47. }
  48. /** singleton pattern */
  49. private FoUnitsConverter() {
  50. }
  51. /** singleton pattern */
  52. static FoUnitsConverter getInstance() {
  53. return INSTANCE;
  54. }
  55. /** convert given value to RTF units
  56. * @param foValue a value like "12mm"
  57. * TODO: tested with "mm" units only, needs work to comply with FO spec
  58. * Why does it search for period instead of simply breaking last two
  59. * Characters into another units string? - Chris
  60. */
  61. float convertToTwips(String foValue)
  62. throws FOPException {
  63. foValue = foValue.trim();
  64. // break value into number and units
  65. final StringBuffer number = new StringBuffer();
  66. final StringBuffer units = new StringBuffer();
  67. for (int i = 0; i < foValue.length(); i++) {
  68. final char c = foValue.charAt(i);
  69. if (Character.isDigit(c) || c == '.') {
  70. number.append(c);
  71. } else {
  72. // found the end of the digits
  73. units.append(foValue.substring(i).trim());
  74. break;
  75. }
  76. }
  77. return numberToTwips(number.toString(), units.toString());
  78. }
  79. /** convert given value to twips according to given units */
  80. private float numberToTwips(String number, String units)
  81. throws FOPException {
  82. float result = 0;
  83. // convert number to integer
  84. try {
  85. if (number != null && number.trim().length() > 0) {
  86. result = Float.valueOf(number).floatValue();
  87. }
  88. } catch (Exception e) {
  89. throw new FOPException("number format error: cannot convert '"
  90. + number + "' to float value");
  91. }
  92. // find conversion factor
  93. if (units != null && units.trim().length() > 0) {
  94. final Float factor = (Float)TWIP_FACTORS.get(units.toLowerCase());
  95. if (factor == null) {
  96. throw new FOPException("conversion factor not found for '" + units + "' units");
  97. }
  98. result *= factor.floatValue();
  99. }
  100. return result;
  101. }
  102. /** convert a font size given in points like "12pt" */
  103. int convertFontSize(String size) throws FOPException {
  104. size = size.trim();
  105. final String sFONTSUFFIX = FixedLength.POINT;
  106. if (!size.endsWith(sFONTSUFFIX)) {
  107. throw new FOPException("Invalid font size '" + size + "', must end with '"
  108. + sFONTSUFFIX + "'");
  109. }
  110. float result = 0;
  111. size = size.substring(0, size.length() - sFONTSUFFIX.length());
  112. try {
  113. result = (Float.valueOf(size).floatValue());
  114. } catch (Exception e) {
  115. throw new FOPException("Invalid font size value '" + size + "'");
  116. }
  117. // RTF font size units are in half-points
  118. return (int)(result * 2.0);
  119. }
  120. public float convertMptToTwips(int width) {
  121. return width * POINT_TO_TWIPS / 1000;
  122. }
  123. }