Categories:
Audio (13)
Biotech (29)
Bytecode (36)
Database (77)
Framework (7)
Game (7)
General (507)
Graphics (53)
I/O (35)
IDE (2)
JAR Tools (102)
JavaBeans (21)
JDBC (121)
JDK (426)
JSP (20)
Logging (108)
Mail (58)
Messaging (8)
Network (84)
PDF (97)
Report (7)
Scripting (84)
Security (32)
Server (121)
Servlet (26)
SOAP (24)
Testing (54)
Web (15)
XML (322)
Collections:
Other Resources:
JEuclid Core Source Code Files
JEuclid Source Code Files are provided
the
JEuclid GitHub Website.
You can browse JEuclid Source Code files below:
✍: FYIcenter
⏎ net/sourceforge/jeuclid/elements/support/text/CharacterMapping.java
/*
* Copyright 2002 - 2007 JEuclid, http://jeuclid.sf.net
*
* Licensed 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$ */
package net.sourceforge.jeuclid.elements.support.text;
import java.awt.Font;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.sourceforge.jeuclid.elements.support.attributes.FontFamily;
import net.sourceforge.jeuclid.elements.support.attributes.MathVariant;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlgraphics.fonts.Glyphs;
/**
* @version $Revision$
*/
public final class CharacterMapping implements Serializable {
private static final String LOAD_ERROR = "Error loading character mappings";
private static final int POS_CODESTR = 0;
private static final int POS_DESCRIPTION = 1;
private static final int POS_CATEGORY = 2;
private static final int POS_MAPS = 5;
private static final int HIGHPLANE_MATH_CHARS_START = 0x1D400;
private static final int HIGHPLANE_START = 0x10000;
/**
*
*/
private static final long serialVersionUID = 1L;
private static CharacterMapping instance;
/**
* Logger for this class.
*/
private static final Log LOGGER = LogFactory
.getLog(CharacterMapping.class);
private final Map<Integer, CodePointAndVariant> extractAttrs;
private final Set<Integer> forceSet;
private final Set<Integer> markSet;
private final Map<FontFamily, Map<Integer, Integer[]>> composeAttrs;
private transient Map<CodePointAndVariant, Reference<List<CodePointAndVariant>>> alternatives;
/**
* Default Constructor.
*/
private CharacterMapping() {
this.extractAttrs = new HashMap<Integer, CodePointAndVariant>();
this.forceSet = new HashSet<Integer>();
this.markSet = new HashSet<Integer>();
this.composeAttrs = new EnumMap<FontFamily, Map<Integer, Integer[]>>(
FontFamily.class);
this.readResolve();
this.loadUnicodeData();
}
private Object readResolve() {
this.alternatives = new HashMap<CodePointAndVariant, Reference<List<CodePointAndVariant>>>();
return this;
}
private void loadUnicodeData() {
final InputStream is = CharacterMapping.class
.getResourceAsStream("/net/sourceforge/jeuclid/UnicodeData.txt");
try {
final BufferedReader r = new BufferedReader(
new InputStreamReader(is));
try {
String s;
while ((s = r.readLine()) != null) {
final String[] c = s.split(";");
if (c.length > CharacterMapping.POS_MAPS) {
this.process(c[CharacterMapping.POS_CODESTR],
c[CharacterMapping.POS_DESCRIPTION],
c[CharacterMapping.POS_CATEGORY],
c[CharacterMapping.POS_MAPS]);
}
}
} catch (final IOException e) {
CharacterMapping.LOGGER.warn(CharacterMapping.LOAD_ERROR, e);
} finally {
try {
r.close();
} catch (final IOException e) {
CharacterMapping.LOGGER.warn(CharacterMapping.LOAD_ERROR,
e);
}
}
} catch (final NullPointerException e) {
CharacterMapping.LOGGER.warn(CharacterMapping.LOAD_ERROR, e);
}
}
private void process(final String codestr, final String descr,
final String category, final String mapsStr) {
try {
final int codepoint = Integer.parseInt(codestr, 16);
if (category.startsWith("M")) {
this.markSet.add(codepoint);
}
if (!mapsStr.startsWith("<font> ")) {
return;
}
final int mapsTo = Integer.parseInt(mapsStr.substring(7), 16);
final int awtStyle = this.parseAwtStyle(descr);
final FontFamily fam = this.parseFontFamily(descr);
if (fam == null) {
return;
}
final boolean force = (codepoint >= CharacterMapping.HIGHPLANE_MATH_CHARS_START)
&& ((FontFamily.SANSSERIF.equals(fam)) || (FontFamily.SERIF
.equals(fam)));
if (force) {
this.forceSet.add(codepoint);
}
final CodePointAndVariant cpav = new CodePointAndVariant(mapsTo,
new MathVariant(awtStyle, fam));
this.extractAttrs.put(codepoint, cpav);
final Map<Integer, Integer[]> ffmap = this.getFFMap(fam);
final Integer[] ia = this.getMapsTo(mapsTo, ffmap);
ia[awtStyle] = codepoint;
} catch (final NumberFormatException nfe) {
CharacterMapping.LOGGER.debug("Parse Error", nfe);
}
}
private Integer[] getMapsTo(final int mapsTo,
final Map<Integer, Integer[]> ffmap) {
Integer[] ia = ffmap.get(mapsTo);
if (ia == null) {
ia = new Integer[Font.BOLD + Font.ITALIC + 1];
ffmap.put(mapsTo, ia);
}
return ia;
}
private Map<Integer, Integer[]> getFFMap(final FontFamily fam) {
Map<Integer, Integer[]> ffmap = this.composeAttrs.get(fam);
if (ffmap == null) {
ffmap = new HashMap<Integer, Integer[]>();
this.composeAttrs.put(fam, ffmap);
}
return ffmap;
}
private int parseAwtStyle(final String descr) {
int awtStyle = Font.PLAIN;
if (descr.contains("BOLD")) {
awtStyle += Font.BOLD;
}
if (descr.contains("ITALIC")) {
awtStyle += Font.ITALIC;
}
return awtStyle;
}
private FontFamily parseFontFamily(final String descr) {
final FontFamily fam;
if (descr.contains("DOUBLE-STRUCK")) {
fam = FontFamily.DOUBLE_STRUCK;
} else if (descr.contains("SCRIPT")) {
fam = FontFamily.SCRIPT;
} else if (descr.contains("BLACK-LETTER")
|| descr.contains("FRAKTUR")) {
fam = FontFamily.FRAKTUR;
} else if (descr.contains("SANS-SERIF")) {
fam = FontFamily.SANSSERIF;
} else if (descr.contains("MONOSPACE")) {
fam = FontFamily.MONOSPACED;
} else if (descr.contains("MATHEMATICAL")) {
fam = FontFamily.SERIF;
} else {
fam = null;
}
return fam;
}
/**
* Get the singleton instance of this class.
*
* @return an instance of CharacterMapping.
*/
public static synchronized CharacterMapping getInstance() {
if (CharacterMapping.instance == null) {
CharacterMapping m;
try {
final InputStream is = CharacterMapping.class
.getResourceAsStream("/net/sourceforge/jeuclid/charmap.ser");
final ObjectInput oi = new ObjectInputStream(is);
m = (CharacterMapping) oi.readObject();
oi.close();
} catch (final ClassNotFoundException cnfe) {
m = null;
} catch (final IllegalArgumentException e) {
m = null;
} catch (final IOException e) {
m = null;
} catch (final NullPointerException e) {
m = null;
}
if (m == null) {
CharacterMapping.instance = new CharacterMapping();
} else {
CharacterMapping.instance = m;
}
}
return CharacterMapping.instance;
}
/**
* Compose a new SERIF Unicode char. This function tries to compose the
* given char into a SERIF char which shows the same characteristics at a
* particular Unicode codepoint.
*
* @param split
* the char which contains a coidepoint and variant.
* @param forbidHighplane
* if the high plane is broken (e.g. on OS X).
* @return a CodePointAndVariant representing the same char.
*/
public CodePointAndVariant composeUnicodeChar(
final CodePointAndVariant split, final boolean forbidHighplane) {
final MathVariant splitVariant = split.getVariant();
final Map<Integer, Integer[]> famList = this.composeAttrs
.get(splitVariant.getFontFamily());
if (famList == null) {
return split;
}
final Integer[] aList = famList.get(split.getCodePoint());
if (aList == null) {
return split;
}
final int splitStyle = splitVariant.getAwtStyle();
Integer to = aList[splitStyle];
if (to != null) {
if (forbidHighplane && to >= CharacterMapping.HIGHPLANE_START) {
return split;
}
return new CodePointAndVariant(to, MathVariant.NORMAL);
}
if (splitStyle != 0) {
to = aList[0];
}
if (to != null) {
if (forbidHighplane && to >= CharacterMapping.HIGHPLANE_START) {
return split;
}
return new CodePointAndVariant(to, new MathVariant(splitStyle,
FontFamily.SERIF));
}
return split;
}
/**
* Extract the given char into variant and codepoint.
*
* @param test
* the Unicode char to split up.
* @return A {@link CodePointAndVariant} representing the same character
* with explicit variant.
*/
public CodePointAndVariant extractUnicodeAttr(
final CodePointAndVariant test) {
final CodePointAndVariant mapsTo = this.extractAttrs.get(test
.getCodePoint());
if (mapsTo == null) {
return test;
}
final MathVariant testVariant = test.getVariant();
final int testStyle = testVariant.getAwtStyle();
final int mapsToCodepoint = mapsTo.getCodePoint();
final CodePointAndVariant retVal;
if ((testStyle == Font.PLAIN)
|| (this.forceSet.contains(mapsToCodepoint))) {
retVal = mapsTo;
} else {
final MathVariant mapsToVariant = mapsTo.getVariant();
retVal = new CodePointAndVariant(mapsToCodepoint,
new MathVariant(testStyle | mapsToVariant.getAwtStyle(),
mapsToVariant.getFontFamily()));
}
return retVal;
}
/**
* Get all alternatives codePoints for this codePoint. They can be used if
* the original code point and variant is not available.
*
* @param cpav
* original CodePointAndVariant
* @return A List of alternative code points to check.
*/
public List<CodePointAndVariant> getAllAlternatives(
final CodePointAndVariant cpav) {
final Reference<List<CodePointAndVariant>> ref = this.alternatives
.get(cpav);
List<CodePointAndVariant> result = null;
if (ref != null) {
result = ref.get();
}
if (result == null) {
result = this.reallyGetAllAternatives(cpav, true);
this.alternatives.put(cpav,
new SoftReference<List<CodePointAndVariant>>(result));
}
return result;
}
private List<CodePointAndVariant> reallyGetAllAternatives(
final CodePointAndVariant cpav, final boolean useGlyphMapping) {
final List<CodePointAndVariant> list = new ArrayList<CodePointAndVariant>(
3);
final CodePointAndVariant cpav2 = this.extractUnicodeAttr(cpav);
// High Plane is broken on OS X!
final CodePointAndVariant cpav3 = this.composeUnicodeChar(cpav2,
StringUtil.OSX);
this.addGlyphsAndTheirAlternatives(list, cpav2, useGlyphMapping);
this.addGlyphsAndTheirAlternatives(list, cpav3, useGlyphMapping);
this.addGlyphsAndTheirAlternatives(list, cpav, useGlyphMapping);
return list;
}
private void addGlyphsAndTheirAlternatives(
final List<CodePointAndVariant> list,
final CodePointAndVariant cpav, final boolean useGlyphMapping) {
if (!list.contains(cpav)) {
list.add(cpav);
if (useGlyphMapping) {
this.addAlternateGlyph(list, cpav);
}
}
}
private void addAlternateGlyph(final List<CodePointAndVariant> list,
final CodePointAndVariant cpav) {
final int codePoint = cpav.getCodePoint();
final String charAsString = new String(new int[] { codePoint }, 0, 1);
final String glyphName = Glyphs.stringToGlyph(charAsString);
final String[] alternateGlyphNames = Glyphs
.getCharNameAlternativesFor(glyphName);
if (alternateGlyphNames != null) {
for (final String altGlyph : alternateGlyphNames) {
final int altcp = Glyphs.getUnicodeSequenceForGlyphName(
altGlyph).codePointAt(0);
final List<CodePointAndVariant> alternateList = this
.reallyGetAllAternatives(new CodePointAndVariant(
altcp, cpav.getVariant()), false);
for (final CodePointAndVariant alternateCpav : alternateList) {
if (!list.contains(alternateCpav)) {
list.add(alternateCpav);
}
}
}
}
}
/**
* Checks if the given codepoint is a "marking" codepoint. Marking
* codepoints do not display by themself, but are usually combined with the
* previous character.
*
* @param codepoint
* codepoint to check.
* @return true if this codepoint reprensents a mark.
*/
public boolean isMark(int codepoint) {
return this.markSet.contains(codepoint);
}
}
⏎ net/sourceforge/jeuclid/elements/support/text/CharacterMapping.java
Or download all of them as a single archive file:
File name: jeuclid-core-3.1.14-fyi.zip File size: 325716 bytes Release date: 2019-02-24 Download
⇒ Using JEuclid 3.1.9 on macOS
⇐ Download and Install jeuclid-core-3.1.14.jar
2025-08-15, ≈38🔥, 0💬
Popular Posts:
What Is mail.jar of JavaMail 1.3? I got the JAR file from javamail-1_3.zip. mail.jar in javamail-1_3...
Jackson is "the Java JSON library" or "the best JSON parser for Java". Or simply as "JSON for Java"....
maven-compat-3.8.6.jar is the JAR file for Apache Maven 3.8.6 Compact module. The JAR file name may ...
JDK 11 java.xml.jmod is the JMOD file for JDK 11 XML (eXtensible Markup Language) module. JDK 11 XML...
How to display types defined in an XML Schema file with the xs\QueryXS.java provided in the Apache X...