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.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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. m = FObj.getPropertyMakerFor(PROP_IDS[1]);
  95. prop = m.make(propertyList, specVal.substring(fromIndex), fo);
  96. newProp.addProperty(prop, 1);
  97. fontFamilyParsed = true;
  98. } else {
  99. if (quoteIndex != -1 && quoteIndex < commaIndex) {
  100. /* a quoted font-family name as first name
  101. * in the comma-separated list
  102. * fromIndex = index of the first quote
  103. */
  104. fromIndex = quoteIndex;
  105. } else {
  106. fromIndex = value.lastIndexOf(' ', commaIndex) + 1;
  107. }
  108. commaIndex = -1;
  109. }
  110. }
  111. toIndex = fromIndex - 1;
  112. fromIndex = value.lastIndexOf(' ', toIndex - 1) + 1;
  113. value = specVal.substring(fromIndex, toIndex);
  114. int slashIndex = value.indexOf('/');
  115. String fontSize = value.substring(0,
  116. (slashIndex == -1) ? value.length() : slashIndex);
  117. m = FObj.getPropertyMakerFor(PROP_IDS[0]);
  118. prop = m.make(propertyList, fontSize, fo);
  119. /* need to make sure subsequent call to LineHeightPropertyMaker.make()
  120. * doesn't generate the default font-size property...
  121. */
  122. propertyList.putExplicit(PROP_IDS[0], prop);
  123. newProp.addProperty(prop, 0);
  124. if (slashIndex != -1) {
  125. /* line-height */
  126. String lineHeight = value.substring(slashIndex + 1);
  127. m = FObj.getPropertyMakerFor(PROP_IDS[2]);
  128. prop = m.make(propertyList, lineHeight, fo);
  129. newProp.addProperty(prop, 2);
  130. }
  131. if (fromIndex != 0) {
  132. toIndex = fromIndex - 1;
  133. value = specVal.substring(0, toIndex);
  134. fromIndex = 0;
  135. spaceIndex = value.indexOf(' ');
  136. do {
  137. toIndex = (spaceIndex == -1) ? value.length() : spaceIndex;
  138. String val = value.substring(fromIndex, toIndex);
  139. for (int i = 6; --i >= 3;) {
  140. if (newProp.list.get(i) == null) {
  141. /* not set */
  142. m = FObj.getPropertyMakerFor(PROP_IDS[i]);
  143. val = m.checkValueKeywords(val);
  144. prop = m.checkEnumValues(val);
  145. if (prop != null) {
  146. newProp.addProperty(prop, i);
  147. }
  148. }
  149. }
  150. fromIndex = toIndex + 1;
  151. spaceIndex = value.indexOf(' ', fromIndex);
  152. } while (toIndex != value.length());
  153. }
  154. } else {
  155. //TODO: implement enum values
  156. log.warn("Enum values other than \"inherit\""
  157. + " not yet supported for the font shorthand.");
  158. return null;
  159. }
  160. }
  161. if (newProp.list.get(0) == null || newProp.list.get(1) == null) {
  162. throw new PropertyException("Invalid property value: "
  163. + "font-size and font-family are required for the font shorthand"
  164. + "\nfont=" + value);
  165. }
  166. return newProp;
  167. }
  168. }
  169. private void addProperty(Property prop, int pos) {
  170. while (list.size() < (pos + 1)) {
  171. list.add(null);
  172. }
  173. list.set(pos, prop);
  174. }
  175. }