/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* Remind: need to enhance to extend component list with a fallback
* list, which is not used in metrics or queries on the composite, but
* is used in drawing primitives and queries which supply an actual string.
* ie for a codepoint that is only in a fallback, font-wide queries such
* as FontMetrics.getHeight() will not take it into account.
* But getStringBounds(..) would take it into account.
* Its fuzzier for queries such as "canDisplay". If this does not include
* the fallback, then we probably want to add "canDisplayFallback()"
* But its probably OK to include it so long as only composites include
* fallbacks. If physicals do then it would be really confusing ..
*/
private boolean[] deferredInitialisation;
/* because components can be lazily initialised the components field is
* private, to ensure all clients call getSlotFont()
*/
int numSlots;
int numMetricsSlots;
int[] exclusionRanges;
int[] maxIndices;
boolean isStdComposite = true;
int[] exclRanges, int[] maxIndexes,
handle = new Font2DHandle(this);
} else {
}
/* Only the first "numMetricsSlots" slots are used for font metrics.
* the rest are considered "fallback" slots".
*/
/*
* See if this is a windows locale which has a system EUDC font.
* If so add it as the final fallback component of the composite.
* The caller could be responsible for this, but for now it seems
* better that it is handled internally to the CompositeFont class.
*/
numSlots++;
if (componentNames != null) {
}
if (componentFileNames != null) {
}
deferredInitialisation = new boolean[numSlots];
if (defer) {
deferredInitialisation[i] = true;
}
}
} else {
deferredInitialisation = new boolean[numSlots];
if (defer) {
for (int i=0; i<numSlots; i++) {
deferredInitialisation[i] = true;
}
}
}
if (index>0) {
/* composites don't call setStyle() as parsing the style
* takes place at the same time as parsing the family name.
* Do I really have to parse the style from the name?
* Need to look into having the caller provide this. */
}
}
} else {
}
}
/* This method is currently intended to be called only from
* FontManager.getCompositeFontUIResource(Font)
* It creates a new CompositeFont with the contents of the Physical
* one pre-pended as slot 0.
*/
isStdComposite = false;
handle = new Font2DHandle(this);
/* Ugly though it is, we synchronize here on the FontManager class
* because it is the lock used to do deferred initialisation.
* We need to ensure that the arrays have consistent information.
* But it may be possible to dispense with the synchronisation if
* it is harmless that we do not know a slot is already initialised
* and just need to discover that and mark it so.
*/
synchronized (FontManagerFactory.getInstance()) {
}
}
deferredInitialisation = new boolean[numSlots];
deferredInitialisation[0] = false;
}
}
/* This is used for deferred initialisation, so that the components of
* a logical font are initialised only when the font is used.
* This can have a positive impact on start-up of most UI applications.
* Note that this technique cannot be used with a TTC font as it
* doesn't know which font in the collection is needed. The solution to
* this is that the initialisation checks if the returned font is
* really the one it wants by comparing the name against the name that
* was passed in (if none was passed in then you aren't using a TTC
* as you would have to specify the name in such a case).
* Assuming there's only two or three fonts in a collection then it
* may be sufficient to verify the returned name is the expected one.
* But half the time it won't be. However since initialisation of the
* TTC will initialise all its components then just do a findFont2D call
* to locate the right one.
* This code allows for initialisation of each slot on demand.
* There are two issues with this.
* 1) All metrics slots probably may be initialised anyway as many
* apps will query the overall font metrics. However this is not an
* absolute requirement
* 2) Some font configuration files on Solaris reference two versions
* of a TT font: a Latin-1 version, then a Pan-European version.
* a euro_fonts directory which is symlinked from numerous locations.
* This is difficult to avoid because the two do not share XLFDs so
* both will be consequently mapped by separate XLFDs needed by AWT.
* The difficulty this presents for lazy initialisation is that if
* all the components are not mapped at once, the smaller version may
* have been used only to be replaced later, and what is the consequence
* for a client that displayed the contents of this font already.
* After some thought I think this will not be a problem because when
* client tries to display a glyph only in the Euro font, the composite
* will ask all components of this font for that glyph and will get
* the euro one. Subsequent uses will all come from the 100% compatible
* euro one.
*/
if (deferredInitialisation[slot] == false) {
return;
}
/* Synchronize on FontManager so that is the global lock
* to update its static set of deferred fonts.
* This global lock is rarely likely to be an issue as there
* are only going to be a few calls into this code.
*/
synchronized (fm) {
if (componentNames == null) {
}
/* Warning: it is possible that the returned component is
* not derived from the file name argument, this can happen if:
* - the file can't be found
* - the file has a bad font
* - the font in the file is superseded by a more complete one
* This should not be a problem for composite font as it will
* make no further use of this file, but code debuggers/
* maintainers need to be conscious of this possibility.
*/
if (componentFileNames != null &&
components[slot] =
}
}
components[slot] =
}
}
deferredInitialisation[slot] = false;
}
}
/* To called only by FontManager.replaceFont */
if (components == null) {
return;
}
if (componentNames != null) {
}
}
}
}
slot >= numMetricsSlots) {
return false;
}
int minIndex = 0;
if (slot > 0) {
}
return true; // excluded
}
curIndex += 2;
}
return false;
}
} else {
}
}
public int getNumSlots() {
return numSlots;
}
/* This is essentially the runtime overhead for deferred font
* initialisation: a boolean test on obtaining a slot font,
* which will happen per slot, on initialisation of a strike
* (as that is the only frequent call site of this method.
*/
if (deferredInitialisation[slot]) {
}
try {
try {
} catch (ClassCastException cce) {
}
}
return font;
} catch (Exception e) {
return fm.getDefaultPhysicalFont();
}
}
return new CompositeStrike(this, desc);
}
/* This is set false when the composite is created using a specified
* physical font as the first slot and called by code which
* selects composites by locale preferences to know that this
* isn't a font which should be adjusted.
*/
public boolean isStdComposite() {
return isStdComposite;
}
/* This isn't very efficient but its infrequently used.
* StandardGlyphVector uses it when the client assigns the glyph codes.
* These may not be valid. This validates them substituting the missing
* glyph elsewhere.
*/
return getMapper().getMissingGlyphCode();
}
return getMapper().getMissingGlyphCode();
} else {
return glyphCode;
}
}
mapper = new CompositeGlyphMapper(this);
}
return mapper;
}
public boolean hasSupplementaryChars() {
for (int i=0; i<numSlots; i++) {
if (getSlotFont(i).hasSupplementaryChars()) {
return true;
}
}
return false;
}
public int getNumGlyphs() {
if (numGlyphs == 0) {
}
return numGlyphs;
}
public int getMissingGlyphCode() {
return getMapper().getMissingGlyphCode();
}
public boolean canDisplay(char c) {
return getMapper().canDisplay(c);
}
/* Find the first slot that supports the default encoding and use
* that to decide the "gasp" behaviour of the composite font.
* REMIND "default encoding" isn't applicable to a Unicode locale
* and we need to replace this with a better mechanism for deciding
* if a font "supports" the user's language. See TrueTypeFont.java
*/
if (localeSlot == -1) {
/* Ordinarily check numMetricsSlots, but non-standard composites
* set that to "1" whilst not necessarily supporting the default
* encoding with that first slot. In such a case check all slots.
*/
int numCoreSlots = numMetricsSlots;
}
localeSlot = slot;
break;
}
}
if (localeSlot == -1) {
localeSlot = 0;
}
}
}
for (int i=0; i<numSlots; i++) {
}
return "** Composite Font: Family=" + familyName +
}
}