All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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