Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $Id: RasterFont.java 1761019 2016-09-16 10:43:45Z ssteiner $ */
package org.apache.fop.afp.fonts;
import java.awt.Rectangle;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* A font where each character is stored as an array of pixels (a bitmap). Such
* fonts are not easily scalable, in contrast to vectored fonts. With this type
* of font, the font metrics information is held in character set files (one for
* each size and style).
*/
public class RasterFont extends AFPFont {
/** Static logging instance */
protected static final Log LOG = LogFactory.getLog("org.apache.fop.afp.fonts");
private final SortedMap charSets = new TreeMap();
private Map substitutionCharSets;
private CharacterSet charSet;
/**
* Constructor for the raster font requires the name, weight and style
* attribute to be available as this forms the key to the font.
*
* @param name the name of the font
* @param embeddable {@code true} if the font is embeddable
*/
public RasterFont(String name, boolean embeddable) {
super(name, embeddable);
}
/**
* Adds the character set for the given point size
* @param size point size (in mpt)
* @param characterSet character set
*/
public void addCharacterSet(int size, CharacterSet characterSet) {
//TODO: replace with Integer.valueOf() once we switch to Java 5
this.charSets.put(size, characterSet);
this.charSet = characterSet;
}
/**
* Get the character set metrics for the specified point size.
*
* @param sizeInMpt the point size (in mpt)
* @return the character set metrics
*/
public CharacterSet getCharacterSet(int sizeInMpt) {
Integer requestedSize = sizeInMpt;
CharacterSet csm = charSets.get(requestedSize);
double sizeInPt = sizeInMpt / 1000.0;
if (csm != null) {
return csm;
}
if (substitutionCharSets != null) {
//Check first if a substitution has already been added
csm = substitutionCharSets.get(requestedSize);
}
if (csm == null && !charSets.isEmpty()) {
// No match or substitution found, but there exist entries
// for other sizes
// Get char set with nearest, smallest font size
SortedMap smallerSizes = charSets.headMap(requestedSize);
SortedMap largerSizes = charSets.tailMap(requestedSize);
int smallerSize = smallerSizes.isEmpty() ? 0
: smallerSizes.lastKey();
int largerSize = largerSizes.isEmpty() ? Integer.MAX_VALUE
: largerSizes.firstKey();
Integer fontSize;
if (!smallerSizes.isEmpty()
&& (sizeInMpt - smallerSize) <= (largerSize - sizeInMpt)) {
fontSize = smallerSize;
} else {
fontSize = largerSize;
}
csm = charSets.get(fontSize);
if (csm != null) {
// Add the substitute mapping, so subsequent calls will
// find it immediately
if (substitutionCharSets == null) {
substitutionCharSets = new HashMap();
}
substitutionCharSets.put(requestedSize, csm);
// do not output the warning if the font size is closer to an integer less than 0.1
if (!(Math.abs(fontSize / 1000.0 - sizeInPt) < 0.1)) {
String msg = "No " + sizeInPt + "pt font " + getFontName()
+ " found, substituted with " + fontSize / 1000f + "pt font";
LOG.warn(msg);
}
}
}
if (csm == null) {
// Still no match -> error
String msg = "No font found for font " + getFontName() + " with point size " + sizeInPt;
LOG.error(msg);
throw new FontRuntimeException(msg);
}
return csm;
}
private int metricsToAbsoluteSize(CharacterSet cs, int value, int givenSize) {
int nominalVerticalSize = cs.getNominalVerticalSize();
if (nominalVerticalSize != 0) {
return value * nominalVerticalSize;
} else {
return value * givenSize;
}
}
private int metricsToAbsoluteSize(CharacterSet cs, double value, int givenSize) {
int nominalVerticalSize = cs.getNominalVerticalSize();
if (nominalVerticalSize != 0) {
return (int) (value * nominalVerticalSize);
} else {
return (int) (value * givenSize);
}
}
/**
* The ascender is the part of a lowercase letter that extends above the
* "x-height" (the height of the letter "x"), such as "d", "t", or "h". Also
* used to denote the part of the letter extending above the x-height.
*
* @param size the font size (in mpt)
* @return the ascender for the given point size
*/
public int getAscender(int size) {
CharacterSet cs = getCharacterSet(size);
return metricsToAbsoluteSize(cs, cs.getAscender(), size);
}
/** {@inheritDoc} */
public int getUnderlinePosition(int size) {
CharacterSet cs = getCharacterSet(size);
return metricsToAbsoluteSize(cs, cs.getUnderscorePosition(), size);
}
@Override
public int getUnderlineThickness(int size) {
CharacterSet cs = getCharacterSet(size);
int underscoreWidth = cs.getUnderscoreWidth();
return underscoreWidth == 0 ? super.getUnderlineThickness(size)
: metricsToAbsoluteSize(cs, underscoreWidth, size);
}
/**
* Obtains the height of capital letters for the specified point size.
*
* @param size the font size (in mpt)
* @return the cap height for the specified point size
*/
public int getCapHeight(int size) {
CharacterSet cs = getCharacterSet(size);
return metricsToAbsoluteSize(cs, cs.getCapHeight(), size);
}
/**
* The descender is the part of a lowercase letter that extends below the
* base line, such as "g", "j", or "p". Also used to denote the part of the
* letter extending below the base line.
*
* @param size the font size (in mpt)
* @return the descender for the specified point size
*/
public int getDescender(int size) {
CharacterSet cs = getCharacterSet(size);
return metricsToAbsoluteSize(cs, cs.getDescender(), size);
}
/**
* The "x-height" (the height of the letter "x").
*
* @param size the font size (in mpt)
* @return the x height for the given point size
*/
public int getXHeight(int size) {
CharacterSet cs = getCharacterSet(size);
return metricsToAbsoluteSize(cs, cs.getXHeight(), size);
}
/**
* Obtain the width of the character for the specified point size.
* @param character the character
* @param size the font size (in mpt)
* @return the width for the given point size
*/
public int getWidth(int character, int size) {
CharacterSet cs = getCharacterSet(size);
return metricsToAbsoluteSize(cs, cs.getWidth(toUnicodeCodepoint(character), 1), size);
}
/**
* TODO
*/
public Rectangle getBoundingBox(int character, int size) {
CharacterSet cs = getCharacterSet(size);
Rectangle characterBox = cs.getCharacterBox(toUnicodeCodepoint(character), 1);
int x = metricsToAbsoluteSize(cs, characterBox.getX(), size);
int y = metricsToAbsoluteSize(cs, characterBox.getY(), size);
int w = metricsToAbsoluteSize(cs, characterBox.getWidth(), size);
int h = metricsToAbsoluteSize(cs, characterBox.getHeight(), size);
return new Rectangle(x, y, w, h);
}
/** {@inheritDoc} */
public boolean hasChar(char c) {
return charSet.hasChar(c);
}
/**
* Map a Unicode character to a code point in the font.
* @param c character to map
* @return the mapped character
*/
public char mapChar(char c) {
return charSet.mapChar(c);
}
/** {@inheritDoc} */
public String getEncodingName() {
return charSet.getEncoding();
}
}