|
Java example source code file (GlyphLayout.java)
The GlyphLayout.java Java example source code
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
/*
*
* (C) Copyright IBM Corp. 1999-2003 - All Rights Reserved
*
* The original version of this source code and documentation is
* copyrighted and owned by IBM. These materials are provided
* under terms of a License Agreement between IBM and Sun.
* This technology is protected by multiple US and International
* patents. This notice and attribution to IBM may not be removed.
*/
/*
* GlyphLayout is used to process a run of text into a run of run of
* glyphs, optionally with position and char mapping info.
*
* The text has already been processed for numeric shaping and bidi.
* The run of text that layout works on has a single bidi level. It
* also has a single font/style. Some operations need context to work
* on (shaping, script resolution) so context for the text run text is
* provided. It is assumed that the text array contains sufficient
* context, and the offset and count delimit the portion of the text
* that needs to actually be processed.
*
* The font might be a composite font. Layout generally requires
* tables from a single physical font to operate, and so it must
* resolve the 'single' font run into runs of physical fonts.
*
* Some characters are supported by several fonts of a composite, and
* in order to properly emulate the glyph substitution behavior of a
* single physical font, these characters might need to be mapped to
* different physical fonts. The script code that is assigned
* characters normally considered 'common script' can be used to
* resolve which physical font to use for these characters. The input
* to the char to glyph mapper (which assigns physical fonts as it
* processes the glyphs) should include the script code, and the
* mapper should operate on runs of a single script.
*
* To perform layout, call get() to get a new (or reuse an old)
* GlyphLayout, call layout on it, then call done(GlyphLayout) when
* finished. There's no particular problem if you don't call done,
* but it assists in reuse of the GlyphLayout.
*/
package sun.font;
import java.lang.ref.SoftReference;
import java.awt.Font;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import static java.lang.Character.*;
public final class GlyphLayout {
// data for glyph vector
private GVData _gvdata;
// cached glyph layout data for reuse
private static volatile GlyphLayout cache; // reusable
private LayoutEngineFactory _lef; // set when get is called, unset when done is called
private TextRecord _textRecord; // the text we're working on, used by iterators
private ScriptRun _scriptRuns; // iterator over script runs
private FontRunIterator _fontRuns; // iterator over physical fonts in a composite
private int _ercount;
private ArrayList _erecords;
private Point2D.Float _pt;
private FontStrikeDesc _sd;
private float[] _mat;
private int _typo_flags;
private int _offset;
public static final class LayoutEngineKey {
private Font2D font;
private int script;
private int lang;
LayoutEngineKey() {
}
LayoutEngineKey(Font2D font, int script, int lang) {
init(font, script, lang);
}
void init(Font2D font, int script, int lang) {
this.font = font;
this.script = script;
this.lang = lang;
}
LayoutEngineKey copy() {
return new LayoutEngineKey(font, script, lang);
}
Font2D font() {
return font;
}
int script() {
return script;
}
int lang() {
return lang;
}
public boolean equals(Object rhs) {
if (this == rhs) return true;
if (rhs == null) return false;
try {
LayoutEngineKey that = (LayoutEngineKey)rhs;
return this.script == that.script &&
this.lang == that.lang &&
this.font.equals(that.font);
}
catch (ClassCastException e) {
return false;
}
}
public int hashCode() {
return script ^ lang ^ font.hashCode();
}
}
public static interface LayoutEngineFactory {
/**
* Given a font, script, and language, determine a layout engine to use.
*/
public LayoutEngine getEngine(Font2D font, int script, int lang);
/**
* Given a key, determine a layout engine to use.
*/
public LayoutEngine getEngine(LayoutEngineKey key);
}
public static interface LayoutEngine {
/**
* Given a strike descriptor, text, rtl flag, and starting point, append information about
* glyphs, positions, and character indices to the glyphvector data, and advance the point.
*
* If the GVData does not have room for the glyphs, throws an IndexOutOfBoundsException and
* leave pt and the gvdata unchanged.
*/
public void layout(FontStrikeDesc sd, float[] mat, int gmask,
int baseIndex, TextRecord text, int typo_flags, Point2D.Float pt, GVData data);
}
/**
* Return a new instance of GlyphLayout, using the provided layout engine factory.
* If null, the system layout engine factory will be used.
*/
public static GlyphLayout get(LayoutEngineFactory lef) {
if (lef == null) {
lef = SunLayoutEngine.instance();
}
GlyphLayout result = null;
synchronized(GlyphLayout.class) {
if (cache != null) {
result = cache;
cache = null;
}
}
if (result == null) {
result = new GlyphLayout();
}
result._lef = lef;
return result;
}
/**
* Return the old instance of GlyphLayout when you are done. This enables reuse
* of GlyphLayout objects.
*/
public static void done(GlyphLayout gl) {
gl._lef = null;
cache = gl; // object reference assignment is thread safe, it says here...
}
private static final class SDCache {
public Font key_font;
public FontRenderContext key_frc;
public AffineTransform dtx;
public AffineTransform invdtx;
public AffineTransform gtx;
public Point2D.Float delta;
public FontStrikeDesc sd;
private SDCache(Font font, FontRenderContext frc) {
key_font = font;
key_frc = frc;
// !!! add getVectorTransform and hasVectorTransform to frc? then
// we could just skip this work...
dtx = frc.getTransform();
dtx.setTransform(dtx.getScaleX(), dtx.getShearY(),
dtx.getShearX(), dtx.getScaleY(),
0, 0);
if (!dtx.isIdentity()) {
try {
invdtx = dtx.createInverse();
}
catch (NoninvertibleTransformException e) {
throw new InternalError(e);
}
}
float ptSize = font.getSize2D();
if (font.isTransformed()) {
gtx = font.getTransform();
gtx.scale(ptSize, ptSize);
delta = new Point2D.Float((float)gtx.getTranslateX(),
(float)gtx.getTranslateY());
gtx.setTransform(gtx.getScaleX(), gtx.getShearY(),
gtx.getShearX(), gtx.getScaleY(),
0, 0);
gtx.preConcatenate(dtx);
} else {
delta = ZERO_DELTA;
gtx = new AffineTransform(dtx);
gtx.scale(ptSize, ptSize);
}
/* Similar logic to that used in SunGraphics2D.checkFontInfo().
* Whether a grey (AA) strike is needed is size dependent if
* AA mode is 'gasp'.
*/
int aa =
FontStrikeDesc.getAAHintIntVal(frc.getAntiAliasingHint(),
FontUtilities.getFont2D(font),
(int)Math.abs(ptSize));
int fm = FontStrikeDesc.getFMHintIntVal
(frc.getFractionalMetricsHint());
sd = new FontStrikeDesc(dtx, gtx, font.getStyle(), aa, fm);
}
private static final Point2D.Float ZERO_DELTA = new Point2D.Float();
private static
SoftReference<ConcurrentHashMap
Other Java examples (source code examples)Here is a short list of links related to this Java GlyphLayout.java source code file: |
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.