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 18 /* $Id: CharacterSetOrientation.java 1805177 2017-08-16 11:02:44Z ssteiner $ */ 19 20 package org.apache.fop.afp.fonts; 21 22 import java.awt.Rectangle; 23 24 /** 25 * The IBM Font Object Content Architecture (FOCA) supports presentation 26 * of character shapes by defining their characteristics, which include 27 * Font-Description information for identifying the characters, Font-Metric 28 * information for positioning the characters, and Character-Shape 29 * information for presenting the character images.<br> 30 * 31 * Presenting a graphic character on a presentation surface requires 32 * that you communicate this information clearly to rotate and position 33 * characters correctly on the physical or logical page.<br> 34 * 35 * This class provides font metric information for a particular font 36 * as by the orientation.<br> 37 * 38 * This information is obtained directly from the AFP font files which must 39 * be installed in the classpath under in the location specified by the path 40 * attribute in the afp-font.xml file. 41 */ 42 public class CharacterSetOrientation { 43 44 /** 45 * The ascender height for the character set 46 */ 47 private int ascender; 48 49 /** 50 * The descender depth for the character set 51 */ 52 private int descender; 53 54 /** 55 * The height of capital letters 56 */ 57 private int capHeight; 58 59 /** 60 * The character widths in the character set (indexed using Unicode codepoints) 61 */ 62 private IntegerKeyStore<CharacterMetrics> characterMetrics; 63 64 /** 65 * The height of lowercase letters 66 */ 67 private int xHeight; 68 69 /** The character set orientation */ 70 private final int orientation; 71 /** space increment */ 72 private final int spaceIncrement; 73 /** em space increment */ 74 private final int emSpaceIncrement; 75 /** Nominal Character Increment */ 76 private final int nomCharIncrement; 77 78 private int underscoreWidth; 79 80 private int underscorePosition; 81 82 /** 83 * Constructor for the CharacterSetOrientation, the orientation is 84 * expressed as the degrees rotation (i.e 0, 90, 180, 270) 85 * 86 * @param orientation the character set orientation 87 * @param spaceIncrement the space increment 88 * @param emSpaceIncrement the em space increment 89 * @param nomCharIncrement the nominal character increment 90 */ CharacterSetOrientation(int orientation, int spaceIncrement, int emSpaceIncrement, int nomCharIncrement)91 public CharacterSetOrientation(int orientation, int spaceIncrement, int emSpaceIncrement, 92 int nomCharIncrement) { 93 this.orientation = orientation; 94 this.spaceIncrement = spaceIncrement; 95 this.emSpaceIncrement = emSpaceIncrement; 96 this.nomCharIncrement = nomCharIncrement; 97 this.characterMetrics = new IntegerKeyStore<CharacterMetrics>(); 98 } 99 100 /** 101 * Ascender height is the distance from the character baseline to the 102 * top of the character box. A negative ascender height signifies that 103 * all of the graphic character is below the character baseline. For 104 * a character rotation other than 0, ascender height loses its 105 * meaning when the character is lying on its side or is upside down 106 * with respect to normal viewing orientation. For the general case, 107 * Ascender Height is the character's most positive y-axis value. 108 * For bounded character boxes, for a given character having an 109 * ascender, ascender height and baseline offset are equal. 110 * @return the ascender value in millipoints 111 */ getAscender()112 public int getAscender() { 113 return ascender; 114 } 115 116 /** 117 * Cap height is the average height of the uppercase characters in 118 * a font. This value is specified by the designer of a font and is 119 * usually the height of the uppercase M. 120 * @return the cap height value in millipoints 121 */ getCapHeight()122 public int getCapHeight() { 123 return capHeight; 124 } 125 126 /** 127 * Descender depth is the distance from the character baseline to 128 * the bottom of a character box. A negative descender depth signifies 129 * that all of the graphic character is above the character baseline. 130 * @return the descender value in millipoints 131 */ getDescender()132 public int getDescender() { 133 return descender; 134 } 135 136 /** 137 * 138 * @return the underscore width 139 */ getUnderscoreWidth()140 public int getUnderscoreWidth() { 141 return underscoreWidth; 142 } 143 144 /** 145 * 146 * @return the underscore position 147 */ getUnderscorePosition()148 public int getUnderscorePosition() { 149 return underscorePosition; 150 } 151 152 /** 153 * The orientation for these metrics in the character set 154 * @return the orientation 155 */ getOrientation()156 public int getOrientation() { 157 return orientation; 158 } 159 160 /** 161 * XHeight refers to the height of the lower case letters above 162 * the baseline. 163 * @return heightX the typical height of characters 164 */ getXHeight()165 public int getXHeight() { 166 return xHeight; 167 } 168 169 /** 170 * Get the width (in 1/1000ths of a point size) of the character 171 * identified by the parameter passed. 172 * @param character the Unicode character to evaluate 173 * @param size the font size 174 * @return the widths of the character 175 */ getWidth(char character, int size)176 public int getWidth(char character, int size) { 177 CharacterMetrics cm = getCharacterMetrics(character); 178 return cm == null ? -1 : size * cm.width; 179 } 180 getCharacterMetrics(char character)181 private CharacterMetrics getCharacterMetrics(char character) { 182 return characterMetrics.get((int) character); 183 } 184 185 /** 186 * Get the character box (rectangle with dimensions in 1/1000ths of a point size) of the character 187 * identified by the parameter passed. 188 * @param character the Unicode character to evaluate 189 * @param size the font size 190 * @return the character box 191 */ getCharacterBox(char character, int size)192 public Rectangle getCharacterBox(char character, int size) { 193 CharacterMetrics cm = getCharacterMetrics(character); 194 return scale(cm == null ? getFallbackCharacterBox() : cm.characterBox, size); 195 } 196 scale(Rectangle rectangle, int size)197 private static Rectangle scale(Rectangle rectangle, int size) { 198 if (rectangle == null) { 199 return null; 200 } else { 201 return new Rectangle((int) (size * rectangle.getX()), (int) (size * rectangle.getY()), 202 (int) (size * rectangle.getWidth()), (int) (size * rectangle.getHeight())); 203 } 204 } 205 getFallbackCharacterBox()206 private Rectangle getFallbackCharacterBox() { 207 // TODO replace with something sensible 208 return new Rectangle(0, 0, 0, 0); 209 } 210 211 /** 212 * Ascender height is the distance from the character baseline to the 213 * top of the character box. A negative ascender height signifies that 214 * all of the graphic character is below the character baseline. For 215 * a character rotation other than 0, ascender height loses its 216 * meaning when the character is lying on its side or is upside down 217 * with respect to normal viewing orientation. For the general case, 218 * Ascender Height is the character's most positive y-axis value. 219 * For bounded character boxes, for a given character having an 220 * ascender, ascender height and baseline offset are equal. 221 * @param ascender the ascender to set 222 */ setAscender(int ascender)223 public void setAscender(int ascender) { 224 this.ascender = ascender; 225 } 226 227 /** 228 * Cap height is the average height of the uppercase characters in 229 * a font. This value is specified by the designer of a font and is 230 * usually the height of the uppercase M. 231 * @param capHeight the cap height to set 232 */ setCapHeight(int capHeight)233 public void setCapHeight(int capHeight) { 234 this.capHeight = capHeight; 235 } 236 237 /** 238 * Descender depth is the distance from the character baseline to 239 * the bottom of a character box. A negative descender depth signifies 240 * that all of the graphic character is above the character baseline. 241 * @param descender the descender value in millipoints 242 */ setDescender(int descender)243 public void setDescender(int descender) { 244 this.descender = descender; 245 } 246 247 /** 248 * TODO 249 * @param underscoreWidth the underscore width value in millipoints 250 */ setUnderscoreWidth(int underscoreWidth)251 public void setUnderscoreWidth(int underscoreWidth) { 252 this.underscoreWidth = underscoreWidth; 253 } 254 255 /** 256 * TODO 257 * @param underscorePosition the underscore position value in millipoints 258 */ setUnderscorePosition(int underscorePosition)259 public void setUnderscorePosition(int underscorePosition) { 260 this.underscorePosition = underscorePosition; 261 } 262 263 /** 264 * Set the width (in 1/1000ths of a point size) of the character 265 * identified by the parameter passed. 266 * @param character the Unicode character for which the width is being set 267 * @param width the widths of the character 268 * @param characterBox the character box 269 */ setCharacterMetrics(char character, int width, Rectangle characterBox)270 public void setCharacterMetrics(char character, int width, Rectangle characterBox) { 271 characterMetrics.put((int) character, new CharacterMetrics(width, characterBox)); 272 } 273 274 /** 275 * XHeight refers to the height of the lower case letters above 276 * the baseline. 277 * @param xHeight the typical height of characters 278 */ setXHeight(int xHeight)279 public void setXHeight(int xHeight) { 280 this.xHeight = xHeight; 281 } 282 283 /** 284 * Returns the space increment. 285 * @return the space increment 286 */ getSpaceIncrement()287 public int getSpaceIncrement() { 288 return this.spaceIncrement; 289 } 290 291 /** 292 * Returns the em space increment. 293 * @return the em space increment 294 */ getEmSpaceIncrement()295 public int getEmSpaceIncrement() { 296 return this.emSpaceIncrement; 297 } 298 299 /** 300 * Returns the nominal character increment. 301 * @return the nominal character increment 302 */ getNominalCharIncrement()303 public int getNominalCharIncrement() { 304 return this.nomCharIncrement; 305 } 306 307 private static class CharacterMetrics { 308 309 public final int width; 310 311 public final Rectangle characterBox; 312 CharacterMetrics(int width, Rectangle characterBox)313 public CharacterMetrics(int width, Rectangle characterBox) { 314 this.width = width; 315 this.characterBox = characterBox; 316 } 317 } 318 } 319