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.

FontShorthandProperty.java 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * Copyright 2006 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /* $Id$ */
  17. package org.apache.fop.fo.properties;
  18. import org.apache.fop.fo.Constants;
  19. import org.apache.fop.fo.FObj;
  20. import org.apache.fop.fo.PropertyList;
  21. import org.apache.fop.fo.expr.PropertyException;
  22. /**
  23. * Property subclass for the font shorthand
  24. */
  25. public class FontShorthandProperty extends ListProperty {
  26. /**
  27. * Inner class for creating instances of FontShorthandProperty
  28. */
  29. public static class Maker extends PropertyMaker {
  30. private static final int[] PROP_IDS = {
  31. Constants.PR_FONT_SIZE, Constants.PR_FONT_FAMILY,
  32. Constants.PR_LINE_HEIGHT, Constants.PR_FONT_STYLE,
  33. Constants.PR_FONT_VARIANT, Constants.PR_FONT_WEIGHT
  34. };
  35. /**
  36. * @param propId ID of the property for which Maker should be created
  37. */
  38. public Maker(int propId) {
  39. super(propId);
  40. }
  41. /**
  42. * @see PropertyMaker#make(PropertyList, String, FObj)
  43. */
  44. public Property make(PropertyList propertyList,
  45. String value, FObj fo) throws PropertyException {
  46. FontShorthandProperty newProp = new FontShorthandProperty();
  47. newProp.setSpecifiedValue(value);
  48. String specVal = value;
  49. Property prop = null;
  50. if ("inherit".equals(specVal)) {
  51. for (int i = PROP_IDS.length; --i >= 0;) {
  52. prop = propertyList.getFromParent(PROP_IDS[i]);
  53. newProp.addProperty(prop, i);
  54. }
  55. } else {
  56. /* initialize list with nulls */
  57. for (int pos = 6; --pos >= 0;) {
  58. newProp.addProperty(null, pos);
  59. }
  60. prop = checkEnumValues(specVal);
  61. if (prop == null) {
  62. /* not an enum:
  63. * value should consist at least of font-size and font-family
  64. * separated by a space
  65. * mind the possible spaces from quoted font-family names
  66. */
  67. int spaceIndex = value.indexOf(' ');
  68. int quoteIndex = (value.indexOf('\'') == -1)
  69. ? value.indexOf('\"') : value.indexOf('\'');
  70. if (spaceIndex == -1
  71. || (quoteIndex != -1 && spaceIndex > quoteIndex)) {
  72. /* no spaces or first space appears after the first
  73. * single/double quote, so malformed value string
  74. */
  75. throw new PropertyException("Invalid property value: "
  76. + "font=\"" + value + "\"");
  77. }
  78. PropertyMaker m = null;
  79. int fromIndex = spaceIndex + 1;
  80. int toIndex = specVal.length();
  81. /* at least one space that appears before the first
  82. * single/double quote, so extract the individual properties
  83. */
  84. boolean fontFamilyParsed = false;
  85. int commaIndex = value.indexOf(',');
  86. while (!fontFamilyParsed) {
  87. /* value contains a (list of) possibly quoted
  88. * font-family name(s)
  89. */
  90. if (commaIndex == -1) {
  91. /* no list, just a single name
  92. * (or first name in the list)
  93. */
  94. if (quoteIndex != -1) {
  95. /* a single name, quoted
  96. */
  97. fromIndex = quoteIndex;
  98. }
  99. m = FObj.getPropertyMakerFor(PROP_IDS[1]);
  100. prop = m.make(propertyList, specVal.substring(fromIndex), fo);
  101. newProp.addProperty(prop, 1);
  102. fontFamilyParsed = true;
  103. } else {
  104. if (quoteIndex != -1 && quoteIndex < commaIndex) {
  105. /* a quoted font-family name as first name
  106. * in the comma-separated list
  107. * fromIndex = index of the first quote
  108. */
  109. fromIndex = quoteIndex;
  110. quoteIndex = -1;
  111. } else {
  112. fromIndex = value.lastIndexOf(' ', commaIndex) + 1;
  113. }
  114. commaIndex = -1;
  115. }
  116. }
  117. toIndex = fromIndex - 1;
  118. fromIndex = value.lastIndexOf(' ', toIndex - 1) + 1;
  119. value = specVal.substring(fromIndex, toIndex);
  120. int slashIndex = value.indexOf('/');
  121. String fontSize = value.substring(0,
  122. (slashIndex == -1) ? value.length() : slashIndex);
  123. m = FObj.getPropertyMakerFor(PROP_IDS[0]);
  124. prop = m.make(propertyList, fontSize, fo);
  125. /* need to make sure subsequent call to LineHeightPropertyMaker.make()
  126. * doesn't generate the default font-size property...
  127. */
  128. propertyList.putExplicit(PROP_IDS[0], prop);
  129. newProp.addProperty(prop, 0);
  130. if (slashIndex != -1) {
  131. /* line-height */
  132. String lineHeight = value.substring(slashIndex + 1);
  133. m = FObj.getPropertyMakerFor(PROP_IDS[2]);
  134. prop = m.make(propertyList, lineHeight, fo);
  135. newProp.addProperty(prop, 2);
  136. }
  137. if (fromIndex != 0) {
  138. toIndex = fromIndex - 1;
  139. value = specVal.substring(0, toIndex);
  140. fromIndex = 0;
  141. spaceIndex = value.indexOf(' ');
  142. do {
  143. toIndex = (spaceIndex == -1) ? value.length() : spaceIndex;
  144. String val = value.substring(fromIndex, toIndex);
  145. for (int i = 6; --i >= 3;) {
  146. if (newProp.list.get(i) == null) {
  147. /* not set */
  148. m = FObj.getPropertyMakerFor(PROP_IDS[i]);
  149. val = m.checkValueKeywords(val);
  150. prop = m.checkEnumValues(val);
  151. if (prop != null) {
  152. newProp.addProperty(prop, i);
  153. }
  154. }
  155. }
  156. fromIndex = toIndex + 1;
  157. spaceIndex = value.indexOf(' ', fromIndex);
  158. } while (toIndex != value.length());
  159. }
  160. } else {
  161. //TODO: implement enum values
  162. log.warn("Enum values other than \"inherit\""
  163. + " not yet supported for the font shorthand.");
  164. return null;
  165. }
  166. }
  167. if (newProp.list.get(0) == null || newProp.list.get(1) == null) {
  168. throw new PropertyException("Invalid property value: "
  169. + "font-size and font-family are required for the font shorthand"
  170. + "\nfont=" + value);
  171. }
  172. return newProp;
  173. }
  174. }
  175. private void addProperty(Property prop, int pos) {
  176. while (list.size() < (pos + 1)) {
  177. list.add(null);
  178. }
  179. list.set(pos, prop);
  180. }
  181. }