
com.adobe.fontengine.inlineformatting.infontformatting.HanKanaFormatter Maven / Gradle / Ivy
/*
* File: HanFormatter.java
*
* ADOBE CONFIDENTIAL
* ___________________
*
* Copyright 2004-2005 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains the property of
* Adobe Systems Incorporated and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe Systems
* Incorporated and its suppliers and may be covered by U.S. and Foreign
* Patents, patents in process, and are protected by trade secret or
* copyright law. Dissemination of this information or reproduction of this
* material is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
*
*/
package com.adobe.fontengine.inlineformatting.infontformatting;
import com.adobe.agl.lang.UCharacter;
import com.adobe.agl.util.ULocale;
import com.adobe.fontengine.CharUtil;
import com.adobe.fontengine.font.Font;
import com.adobe.fontengine.font.FontData;
import com.adobe.fontengine.font.FontImpl;
import com.adobe.fontengine.font.FontLoadingException;
import com.adobe.fontengine.font.InvalidFontException;
import com.adobe.fontengine.font.UnsupportedFontException;
import com.adobe.fontengine.font.opentype.OTSelector;
import com.adobe.fontengine.font.opentype.OTSelectors;
import com.adobe.fontengine.font.opentype.OpenTypeFont;
import com.adobe.fontengine.font.opentype.Tag;
import com.adobe.fontengine.font.type1.Type1Font;
import com.adobe.fontengine.inlineformatting.AttributedRun;
import com.adobe.fontengine.inlineformatting.ElementAttribute;
import com.adobe.fontengine.inlineformatting.FontStyle;
import com.adobe.fontengine.inlineformatting.InterElementAttribute;
import com.adobe.fontengine.inlineformatting.LigatureLevel;
final class HanKanaFormatter extends BaseFormatter {
protected int setGlyphs (AttributedRun run, int start, int limit)
throws InvalidFontException, UnsupportedFontException, FontLoadingException {
Font font = (Font) run.getElementStyle (start, ElementAttribute.font);
FontData fontData = ((FontImpl) font).getFontData ();
while (start < limit) {
if (run. getElementStyle (start, ElementAttribute.isGlyph) == Boolean.TRUE) {
start++;
continue; }
int usv = run.elementAt (start);
if (usv == 0x200D /* ZWJ */) {
run.remove (start);
limit--;
run.setInterElementStyleBefore (start,
InterElementAttribute.ligatureLevel,
LigatureLevel.COMMON);
continue; }
if (usv == 0x200C /* ZWNJ */) {
run.remove (start);
limit--;
run.setInterElementStyleBefore (start,
InterElementAttribute.ligatureLevel,
LigatureLevel.NONE);
continue; }
if (CharUtil.isControl (usv)) {
run.remove (start);
limit--;
continue; }
if (((Integer)run.getElementStyle (start, ElementAttribute.bidiLevel)).intValue () % 2 == 1) {
usv = UCharacter.getMirror (usv); }
if ( ! CharUtil.isBase (usv)
|| start + 1 == limit
|| run.getElementStyle (start + 1, ElementAttribute.isGlyph) == Boolean.TRUE
|| ! CharUtil.isCombining (run.elementAt (start + 1))) {
// common case: a single character
int gid = fontData.getGlyphForChar (usv);
run.replace (start, gid);
run.setElementStyle (start, ElementAttribute.isGlyph, Boolean.TRUE);
start++;
continue; }
{ int graphemeLimit = start + 1;
while ( graphemeLimit < limit
&& run.getElementStyle (graphemeLimit, ElementAttribute.isGlyph) != Boolean.TRUE
&& CharUtil.isCombining (run.elementAt (graphemeLimit))) {
graphemeLimit++; }
boolean directMappingHasNotdef = false;
int[] usvs = new int [graphemeLimit - start];
int[] gids = new int [graphemeLimit - start];
for (int i = start; i < graphemeLimit; i++) {
usvs [i - start] = run.elementAt (i);
int gid = fontData.getGlyphForChar (usvs [i - start]);
if (gid == 0) {
directMappingHasNotdef = true; }
gids [i - start] = gid; }
if (directMappingHasNotdef) {
int usvc = CharUtil.compose (usvs, 0, graphemeLimit - start);
if (usvc != -1) {
int gid = fontData.getGlyphForChar (usvc);
if (gid != 0) {
run.replace (start, graphemeLimit, gid);
run.setElementStyle (start, ElementAttribute.isGlyph, Boolean.TRUE);
limit -= (graphemeLimit - start - 1);
start++;
continue; }}}
for (int i = start; i < graphemeLimit; i++) {
run.replace (i, gids [i - start]);
run.setElementStyle (start, ElementAttribute.isGlyph, Boolean.TRUE); }
start = graphemeLimit; }}
return limit;
}
//---------------------------------------------------------- OT formatting ---
protected boolean canFormatOT() {
return true;
}
protected int formatOT (OpenTypeFont otFont, AttributedRun run, int start, int limit, boolean shouldKern)
throws InvalidFontException, UnsupportedFontException, FontLoadingException {
// PRE: r.font [first, last] = one font
// r.direction [first, last] = one direction
// charRun is not defective, i.e. does not start in the
// middle of a default grapheme cluster
Integer bidiLevel = (Integer) run.getElementStyle (start, ElementAttribute.bidiLevel);
int scriptTag = getOTScriptTag ((Integer) run.getElementStyle (start, InFontFormatter.scriptAttribute));
int langTag = getOTLanguageTag ((ULocale) run.getElementStyle (start, ElementAttribute.locale));
// Map characters to glyphs; simply skip existing glyphs
limit = setGlyphs (run, start, limit);
// Adjust the glyphs by GSUB
if (otFont.gsub != null) {
int[][] gsubLookups = LookupsCache.resolveFeatureTag (otFont.gsub, scriptTag, langTag, gsubFeatures);
limit = otFont.gsub.applyLookups (gsubLookups [0], run, start, limit, OTSelectors.everywhere, otFont.gdef); //ccmp
limit = otFont.gsub.applyLookups (gsubLookups [1], run, start, limit, OTSelectors.everywhere, otFont.gdef); //locl
if (bidiLevel.intValue () % 2 == 1) {
limit = otFont.gsub.applyLookups (gsubLookups [2], run, start, limit, OTSelectors.everywhere, otFont.gdef); } //rtla
limit = otFont.gsub.applyLookups (gsubLookups [6], run, start, limit, italSelector, otFont.gdef); // ital
limit = otFont.gsub.applyLookups (gsubLookups [3], run, start, limit, OTSelectors.minimumLigatures, otFont.gdef); // rlig
limit = otFont.gsub.applyLookups (gsubLookups [4], run, start, limit, OTSelectors.commonLigatures, otFont.gdef); // liga
limit = otFont.gsub.applyLookups (gsubLookups [5], run, start, limit, OTSelectors.commonLigatures, otFont.gdef); // clig
limit = otFont.gsub.applyLookups (gsubLookups [7], run, start, limit, OTSelectors.uncommonLigatures, otFont.gdef); // dlig
limit = otFont.gsub.applyLookups (gsubLookups [8], run, start, limit, OTSelectors.exoticLigatures, otFont.gdef); } // hlig
// Position the glyphs by advance
posFromAdvanceWidth (run, otFont, start, limit);
// Adjust the positions by GPOS
if (otFont.gpos != null) {
int[][] gposLookups = LookupsCache.resolveFeatureTag (otFont.gpos, scriptTag, langTag, gposFeatures);
limit = otFont.gpos.applyLookups (gposLookups [0], run, start, limit, OTSelectors.everywhere, otFont.gdef); // mark
limit = otFont.gpos.applyLookups (gposLookups [1], run, start, limit, OTSelectors.everywhere, otFont.gdef); // mkmk
}
else if (shouldKern && otFont.kern != null)
{
applyKernTable(otFont, run, start, limit);
}
return limit;
}
private static final int[] gsubFeatures = {
Tag.feature_ccmp, // 0
Tag.feature_locl, // 1
Tag.feature_rtla, // 2
Tag.feature_rlig, // 3
Tag.feature_liga, // 4
Tag.feature_clig, // 5
Tag.feature_ital, // 6
Tag.feature_dlig, // 7
Tag.feature_hlig, // 8
};
private static final int[] gposFeatures = {
Tag.feature_mark, // 0
Tag.feature_mkmk, // 1
};
private static final OTSelector italSelector = new OTSelector () {
public boolean isApplied (AttributedRun run, int position) {
Object v = run.getElementStyle (position, ElementAttribute.fontStyle);
return (v == FontStyle.ITALIC || v == FontStyle.OBLIQUE);
}
};
//---------------------------------------------------------- TT formatting ---
protected boolean canFormatTT() {
return true;
}
protected int formatTT (OpenTypeFont otFont, AttributedRun run, int start, int limit, boolean shouldKern)
throws InvalidFontException, UnsupportedFontException, FontLoadingException {
// Map characters to glyphs; simply skip existing glyphs
limit = setGlyphs (run, start, limit);
// Position the glyphs by advance
posFromAdvanceWidth (run, otFont, start, limit);
return limit;
}
//---------------------------------------------------------- T1 formatting ---
protected boolean canFormatT1() {
return true;
}
protected int formatT1 (Type1Font t1Font, AttributedRun run, int start, int limit, boolean shouldKern)
throws InvalidFontException, UnsupportedFontException, FontLoadingException {
limit = setGlyphs (run, start, limit);
posFromAdvanceWidth (run, t1Font, start, limit);
return limit;
}
//----------------------------------------------------- Generic formatting ---
protected boolean canFormatGeneric() {
return true;
}
protected int formatGeneric (FontData fontData, AttributedRun run, int start, int limit, boolean shouldKern)
throws InvalidFontException, UnsupportedFontException, FontLoadingException {
limit = setGlyphs (run, start, limit);
posFromAdvanceWidth (run, fontData, start, limit);
return limit;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy