You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by ga...@apache.org on 2012/02/26 03:29:29 UTC
svn commit: r1293736 [6/38] - in /xmlgraphics/fop/trunk: ./
src/codegen/java/org/apache/fop/tools/
src/codegen/unicode/java/org/apache/fop/complexscripts/
src/codegen/unicode/java/org/apache/fop/complexscripts/bidi/
src/documentation/content/xdocs/trun...
Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphCoverageMapping.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphCoverageMapping.java?rev=1293736&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphCoverageMapping.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphCoverageMapping.java Sun Feb 26 02:29:01 2012
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.fop.complexscripts.fonts;
+
+// CSOFF: LineLengthCheck
+
+/**
+ * The <code>GlyphCoverageMapping</code> interface provides glyph identifier to coverage
+ * index mapping support.
+ * @author Glenn Adams
+ */
+public interface GlyphCoverageMapping {
+
+ /**
+ * Obtain size of coverage table, i.e., ciMax + 1, where ciMax is the maximum
+ * coverage index.
+ * @return size of coverage table
+ */
+ int getCoverageSize();
+
+ /**
+ * Map glyph identifier (code) to coverge index. Returns -1 if glyph identifier is not in the domain of
+ * the coverage table.
+ * @param gid glyph identifier (code)
+ * @return non-negative glyph coverage index or -1 if glyph identifiers is not mapped by table
+ */
+ int getCoverageIndex ( int gid );
+
+}
Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphCoverageTable.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphCoverageTable.java?rev=1293736&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphCoverageTable.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphCoverageTable.java Sun Feb 26 02:29:01 2012
@@ -0,0 +1,233 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.fop.complexscripts.fonts;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Iterator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+// CSOFF: LineLengthCheck
+// CSOFF: InnerAssignmentCheck
+// CSOFF: NoWhitespaceAfterCheck
+
+/**
+ * Base class implementation of glyph coverage table.
+ * @author Glenn Adams
+ */
+public final class GlyphCoverageTable extends GlyphMappingTable implements GlyphCoverageMapping {
+
+ /* logging instance */
+ private static final Log log = LogFactory.getLog(GlyphCoverageTable.class); // CSOK: ConstantNameCheck
+
+ /** empty mapping table */
+ public static final int GLYPH_COVERAGE_TYPE_EMPTY = GLYPH_MAPPING_TYPE_EMPTY;
+
+ /** mapped mapping table */
+ public static final int GLYPH_COVERAGE_TYPE_MAPPED = GLYPH_MAPPING_TYPE_MAPPED;
+
+ /** range based mapping table */
+ public static final int GLYPH_COVERAGE_TYPE_RANGE = GLYPH_MAPPING_TYPE_RANGE;
+
+ private GlyphCoverageMapping cm;
+
+ private GlyphCoverageTable ( GlyphCoverageMapping cm ) {
+ assert cm != null;
+ assert cm instanceof GlyphMappingTable;
+ this.cm = cm;
+ }
+
+ /** {@inheritDoc} */
+ public int getType() {
+ return ( (GlyphMappingTable) cm ) .getType();
+ }
+
+ /** {@inheritDoc} */
+ public List getEntries() {
+ return ( (GlyphMappingTable) cm ) .getEntries();
+ }
+
+ /** {@inheritDoc} */
+ public int getCoverageSize() {
+ return cm.getCoverageSize();
+ }
+
+ /** {@inheritDoc} */
+ public int getCoverageIndex ( int gid ) {
+ return cm.getCoverageIndex ( gid );
+ }
+
+ /**
+ * Create glyph coverage table.
+ * @param entries list of mapped or ranged coverage entries, or null or empty list
+ * @return a new covera table instance
+ */
+ public static GlyphCoverageTable createCoverageTable ( List entries ) {
+ GlyphCoverageMapping cm;
+ if ( ( entries == null ) || ( entries.size() == 0 ) ) {
+ cm = new EmptyCoverageTable ( entries );
+ } else if ( isMappedCoverage ( entries ) ) {
+ cm = new MappedCoverageTable ( entries );
+ } else if ( isRangeCoverage ( entries ) ) {
+ cm = new RangeCoverageTable ( entries );
+ } else {
+ cm = null;
+ }
+ assert cm != null : "unknown coverage type";
+ return new GlyphCoverageTable ( cm );
+ }
+
+ private static boolean isMappedCoverage ( List entries ) {
+ if ( ( entries == null ) || ( entries.size() == 0 ) ) {
+ return false;
+ } else {
+ for ( Iterator it = entries.iterator(); it.hasNext();) {
+ Object o = it.next();
+ if ( ! ( o instanceof Integer ) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ private static boolean isRangeCoverage ( List entries ) {
+ if ( ( entries == null ) || ( entries.size() == 0 ) ) {
+ return false;
+ } else {
+ for ( Iterator it = entries.iterator(); it.hasNext();) {
+ Object o = it.next();
+ if ( ! ( o instanceof MappingRange ) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ private static class EmptyCoverageTable extends GlyphMappingTable.EmptyMappingTable implements GlyphCoverageMapping {
+ public EmptyCoverageTable ( List entries ) {
+ super ( entries );
+ }
+ /** {@inheritDoc} */
+ public int getCoverageSize() {
+ return 0;
+ }
+ /** {@inheritDoc} */
+ public int getCoverageIndex ( int gid ) {
+ return -1;
+ }
+ }
+
+ private static class MappedCoverageTable extends GlyphMappingTable.MappedMappingTable implements GlyphCoverageMapping {
+ private int[] map;
+ public MappedCoverageTable ( List entries ) {
+ populate ( entries );
+ }
+ /** {@inheritDoc} */
+ public List getEntries() {
+ List entries = new java.util.ArrayList();
+ if ( map != null ) {
+ for ( int i = 0, n = map.length; i < n; i++ ) {
+ entries.add ( Integer.valueOf ( map [ i ] ) );
+ }
+ }
+ return entries;
+ }
+ /** {@inheritDoc} */
+ public int getMappingSize() {
+ return ( map != null ) ? map.length : 0;
+ }
+ public int getMappedIndex ( int gid ) {
+ int i;
+ if ( ( i = Arrays.binarySearch ( map, gid ) ) >= 0 ) {
+ return i;
+ } else {
+ return -1;
+ }
+ }
+ /** {@inheritDoc} */
+ public int getCoverageSize() {
+ return getMappingSize();
+ }
+ /** {@inheritDoc} */
+ public int getCoverageIndex ( int gid ) {
+ return getMappedIndex ( gid );
+ }
+ private void populate ( List entries ) {
+ int i = 0, n = entries.size(), gidMax = -1;
+ int[] map = new int [ n ];
+ for ( Iterator it = entries.iterator(); it.hasNext();) {
+ Object o = it.next();
+ if ( o instanceof Integer ) {
+ int gid = ( (Integer) o ) . intValue();
+ if ( ( gid >= 0 ) && ( gid < 65536 ) ) {
+ if ( gid > gidMax ) {
+ map [ i++ ] = gidMax = gid;
+ } else {
+ log.info ( "ignoring out of order or duplicate glyph index: " + gid );
+ }
+ } else {
+ throw new AdvancedTypographicTableFormatException ( "illegal glyph index: " + gid );
+ }
+ } else {
+ throw new AdvancedTypographicTableFormatException ( "illegal coverage entry, must be Integer: " + o );
+ }
+ }
+ assert i == n;
+ assert this.map == null;
+ this.map = map;
+ }
+ /** {@inheritDoc} */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append('{');
+ for ( int i = 0, n = map.length; i < n; i++ ) {
+ if ( i > 0 ) {
+ sb.append(',');
+ }
+ sb.append ( Integer.toString ( map [ i ] ) );
+ }
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+
+ private static class RangeCoverageTable extends GlyphMappingTable.RangeMappingTable implements GlyphCoverageMapping {
+ public RangeCoverageTable ( List entries ) {
+ super ( entries );
+ }
+ /** {@inheritDoc} */
+ public int getMappedIndex ( int gid, int s, int m ) {
+ return m + gid - s;
+ }
+ /** {@inheritDoc} */
+ public int getCoverageSize() {
+ return getMappingSize();
+ }
+ /** {@inheritDoc} */
+ public int getCoverageIndex ( int gid ) {
+ return getMappedIndex ( gid );
+ }
+ }
+
+}
Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphDefinition.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphDefinition.java?rev=1293736&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphDefinition.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphDefinition.java Sun Feb 26 02:29:01 2012
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.fop.complexscripts.fonts;
+
+// CSOFF: LineLengthCheck
+
+/**
+ * The <code>GlyphDefinition</code> interface is a marker interface implemented by a glyph definition
+ * subtable.
+ * @author Glenn Adams
+ */
+public interface GlyphDefinition {
+
+ /**
+ * Determine if some definition is available for a specific glyph.
+ * @param gi a glyph index
+ * @return true if some (unspecified) definition is available for the specified glyph
+ */
+ boolean hasDefinition ( int gi );
+
+}
Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphDefinitionSubtable.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphDefinitionSubtable.java?rev=1293736&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphDefinitionSubtable.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphDefinitionSubtable.java Sun Feb 26 02:29:01 2012
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.fop.complexscripts.fonts;
+
+// CSOFF: LineLengthCheck
+// CSOFF: InnerAssignmentCheck
+
+/**
+ * The <code>GlyphDefinitionSubtable</code> implements an abstract base of a glyph definition subtable,
+ * providing a default implementation of the <code>GlyphDefinition</code> interface.
+ * @author Glenn Adams
+ */
+public abstract class GlyphDefinitionSubtable extends GlyphSubtable implements GlyphDefinition {
+
+ /**
+ * Instantiate a <code>GlyphDefinitionSubtable</code>.
+ * @param id subtable identifier
+ * @param sequence subtable sequence
+ * @param flags subtable flags
+ * @param format subtable format
+ * @param mapping subtable coverage table
+ */
+ protected GlyphDefinitionSubtable ( String id, int sequence, int flags, int format, GlyphMappingTable mapping ) {
+ super ( id, sequence, flags, format, mapping );
+ }
+
+ /** {@inheritDoc} */
+ public int getTableType() {
+ return GlyphTable.GLYPH_TABLE_TYPE_DEFINITION;
+ }
+
+ /** {@inheritDoc} */
+ public String getTypeName() {
+ return GlyphDefinitionTable.getLookupTypeName ( getType() );
+ }
+
+ /** {@inheritDoc} */
+ public boolean usesReverseScan() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ public boolean hasDefinition ( int gi ) {
+ GlyphCoverageMapping cvm;
+ if ( ( cvm = getCoverage() ) != null ) {
+ if ( cvm.getCoverageIndex ( gi ) >= 0 ) {
+ return true;
+ }
+ }
+ GlyphClassMapping clm;
+ if ( ( clm = getClasses() ) != null ) {
+ if ( clm.getClassIndex ( gi, 0 ) >= 0 ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphDefinitionTable.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphDefinitionTable.java?rev=1293736&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphDefinitionTable.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphDefinitionTable.java Sun Feb 26 02:29:01 2012
@@ -0,0 +1,451 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.fop.complexscripts.fonts;
+
+import java.nio.CharBuffer;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.complexscripts.scripts.ScriptProcessor;
+import org.apache.fop.complexscripts.util.GlyphSequence;
+
+// CSOFF: InnerAssignmentCheck
+// CSOFF: LineLengthCheck
+
+/**
+ * The <code>GlyphDefinitionTable</code> class is a glyph table that implements
+ * glyph definition functionality according to the OpenType GDEF table.
+ * @author Glenn Adams
+ */
+public class GlyphDefinitionTable extends GlyphTable {
+
+ /** logging instance */
+ private static final Log log = LogFactory.getLog(GlyphDefinitionTable.class); // CSOK: ConstantNameCheck
+
+ /** glyph class subtable type */
+ public static final int GDEF_LOOKUP_TYPE_GLYPH_CLASS = 1;
+ /** attachment point subtable type */
+ public static final int GDEF_LOOKUP_TYPE_ATTACHMENT_POINT = 2;
+ /** ligature caret subtable type */
+ public static final int GDEF_LOOKUP_TYPE_LIGATURE_CARET = 3;
+ /** mark attachment subtable type */
+ public static final int GDEF_LOOKUP_TYPE_MARK_ATTACHMENT = 4;
+
+ /** pre-defined glyph class - base glyph */
+ public static final int GLYPH_CLASS_BASE = 1;
+ /** pre-defined glyph class - ligature glyph */
+ public static final int GLYPH_CLASS_LIGATURE = 2;
+ /** pre-defined glyph class - mark glyph */
+ public static final int GLYPH_CLASS_MARK = 3;
+ /** pre-defined glyph class - component glyph */
+ public static final int GLYPH_CLASS_COMPONENT = 4;
+
+ /** singleton glyph class table */
+ private GlyphClassSubtable gct;
+ /** singleton attachment point table */
+ // private AttachmentPointSubtable apt; // NOT YET USED
+ /** singleton ligature caret table */
+ // private LigatureCaretSubtable lct; // NOT YET USED
+ /** singleton mark attachment table */
+ private MarkAttachmentSubtable mat;
+
+ /**
+ * Instantiate a <code>GlyphDefinitionTable</code> object using the specified subtables.
+ * @param subtables a list of identified subtables
+ */
+ public GlyphDefinitionTable ( List subtables ) {
+ super ( null, new HashMap(0) );
+ if ( ( subtables == null ) || ( subtables.size() == 0 ) ) {
+ throw new AdvancedTypographicTableFormatException ( "subtables must be non-empty" );
+ } else {
+ for ( Iterator it = subtables.iterator(); it.hasNext();) {
+ Object o = it.next();
+ if ( o instanceof GlyphDefinitionSubtable ) {
+ addSubtable ( (GlyphSubtable) o );
+ } else {
+ throw new AdvancedTypographicTableFormatException ( "subtable must be a glyph definition subtable" );
+ }
+ }
+ freezeSubtables();
+ }
+ }
+
+ /**
+ * Reorder combining marks in glyph sequence so that they precede (within the sequence) the base
+ * character to which they are applied. N.B. In the case of LTR segments, marks are not reordered by this,
+ * method since when the segment is reversed by BIDI processing, marks are automatically reordered to precede
+ * their base glyph.
+ * @param gs an input glyph sequence
+ * @param gpa associated glyph position adjustments (also reordered)
+ * @param script a script identifier
+ * @param language a language identifier
+ * @return the reordered (output) glyph sequence
+ */
+ public GlyphSequence reorderCombiningMarks ( GlyphSequence gs, int[][] gpa, String script, String language ) {
+ ScriptProcessor sp = ScriptProcessor.getInstance ( script );
+ return sp.reorderCombiningMarks ( this, gs, gpa, script, language );
+ }
+
+ /** {@inheritDoc} */
+ protected void addSubtable ( GlyphSubtable subtable ) {
+ if ( subtable instanceof GlyphClassSubtable ) {
+ this.gct = (GlyphClassSubtable) subtable;
+ } else if ( subtable instanceof AttachmentPointSubtable ) {
+ // TODO - not yet used
+ // this.apt = (AttachmentPointSubtable) subtable;
+ } else if ( subtable instanceof LigatureCaretSubtable ) {
+ // TODO - not yet used
+ // this.lct = (LigatureCaretSubtable) subtable;
+ } else if ( subtable instanceof MarkAttachmentSubtable ) {
+ this.mat = (MarkAttachmentSubtable) subtable;
+ } else {
+ throw new UnsupportedOperationException ( "unsupported glyph definition subtable type: " + subtable );
+ }
+ }
+
+ /**
+ * Determine if glyph belongs to pre-defined glyph class.
+ * @param gid a glyph identifier (index)
+ * @param gc a pre-defined glyph class (GLYPH_CLASS_BASE|GLYPH_CLASS_LIGATURE|GLYPH_CLASS_MARK|GLYPH_CLASS_COMPONENT).
+ * @return true if glyph belongs to specified glyph class
+ */
+ public boolean isGlyphClass ( int gid, int gc ) {
+ if ( gct != null ) {
+ return gct.isGlyphClass ( gid, gc );
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Determine glyph class.
+ * @param gid a glyph identifier (index)
+ * @return a pre-defined glyph class (GLYPH_CLASS_BASE|GLYPH_CLASS_LIGATURE|GLYPH_CLASS_MARK|GLYPH_CLASS_COMPONENT).
+ */
+ public int getGlyphClass ( int gid ) {
+ if ( gct != null ) {
+ return gct.getGlyphClass ( gid );
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * Determine if glyph belongs to (font specific) mark attachment class.
+ * @param gid a glyph identifier (index)
+ * @param mac a (font specific) mark attachment class
+ * @return true if glyph belongs to specified mark attachment class
+ */
+ public boolean isMarkAttachClass ( int gid, int mac ) {
+ if ( mat != null ) {
+ return mat.isMarkAttachClass ( gid, mac );
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Determine mark attachment class.
+ * @param gid a glyph identifier (index)
+ * @return a non-negative mark attachment class, or -1 if no class defined
+ */
+ public int getMarkAttachClass ( int gid ) {
+ if ( mat != null ) {
+ return mat.getMarkAttachClass ( gid );
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * Map a lookup type name to its constant (integer) value.
+ * @param name lookup type name
+ * @return lookup type
+ */
+ public static int getLookupTypeFromName ( String name ) {
+ int t;
+ String s = name.toLowerCase();
+ if ( "glyphclass".equals ( s ) ) {
+ t = GDEF_LOOKUP_TYPE_GLYPH_CLASS;
+ } else if ( "attachmentpoint".equals ( s ) ) {
+ t = GDEF_LOOKUP_TYPE_ATTACHMENT_POINT;
+ } else if ( "ligaturecaret".equals ( s ) ) {
+ t = GDEF_LOOKUP_TYPE_LIGATURE_CARET;
+ } else if ( "markattachment".equals ( s ) ) {
+ t = GDEF_LOOKUP_TYPE_MARK_ATTACHMENT;
+ } else {
+ t = -1;
+ }
+ return t;
+ }
+
+ /**
+ * Map a lookup type constant (integer) value to its name.
+ * @param type lookup type
+ * @return lookup type name
+ */
+ public static String getLookupTypeName ( int type ) {
+ String tn = null;
+ switch ( type ) {
+ case GDEF_LOOKUP_TYPE_GLYPH_CLASS:
+ tn = "glyphclass";
+ break;
+ case GDEF_LOOKUP_TYPE_ATTACHMENT_POINT:
+ tn = "attachmentpoint";
+ break;
+ case GDEF_LOOKUP_TYPE_LIGATURE_CARET:
+ tn = "ligaturecaret";
+ break;
+ case GDEF_LOOKUP_TYPE_MARK_ATTACHMENT:
+ tn = "markattachment";
+ break;
+ default:
+ tn = "unknown";
+ break;
+ }
+ return tn;
+ }
+
+ /**
+ * Create a definition subtable according to the specified arguments.
+ * @param type subtable type
+ * @param id subtable identifier
+ * @param sequence subtable sequence
+ * @param flags subtable flags (must be zero)
+ * @param format subtable format
+ * @param mapping subtable mapping table
+ * @param entries subtable entries
+ * @return a glyph subtable instance
+ */
+ public static GlyphSubtable createSubtable ( int type, String id, int sequence, int flags, int format, GlyphMappingTable mapping, List entries ) {
+ GlyphSubtable st = null;
+ switch ( type ) {
+ case GDEF_LOOKUP_TYPE_GLYPH_CLASS:
+ st = GlyphClassSubtable.create ( id, sequence, flags, format, mapping, entries );
+ break;
+ case GDEF_LOOKUP_TYPE_ATTACHMENT_POINT:
+ st = AttachmentPointSubtable.create ( id, sequence, flags, format, mapping, entries );
+ break;
+ case GDEF_LOOKUP_TYPE_LIGATURE_CARET:
+ st = LigatureCaretSubtable.create ( id, sequence, flags, format, mapping, entries );
+ break;
+ case GDEF_LOOKUP_TYPE_MARK_ATTACHMENT:
+ st = MarkAttachmentSubtable.create ( id, sequence, flags, format, mapping, entries );
+ break;
+ default:
+ break;
+ }
+ return st;
+ }
+
+ private abstract static class GlyphClassSubtable extends GlyphDefinitionSubtable {
+ GlyphClassSubtable ( String id, int sequence, int flags, int format, GlyphMappingTable mapping, List entries ) {
+ super ( id, sequence, flags, format, mapping );
+ }
+ /** {@inheritDoc} */
+ public int getType() {
+ return GDEF_LOOKUP_TYPE_GLYPH_CLASS;
+ }
+ /**
+ * Determine if glyph belongs to pre-defined glyph class.
+ * @param gid a glyph identifier (index)
+ * @param gc a pre-defined glyph class (GLYPH_CLASS_BASE|GLYPH_CLASS_LIGATURE|GLYPH_CLASS_MARK|GLYPH_CLASS_COMPONENT).
+ * @return true if glyph belongs to specified glyph class
+ */
+ public abstract boolean isGlyphClass ( int gid, int gc );
+ /**
+ * Determine glyph class.
+ * @param gid a glyph identifier (index)
+ * @return a pre-defined glyph class (GLYPH_CLASS_BASE|GLYPH_CLASS_LIGATURE|GLYPH_CLASS_MARK|GLYPH_CLASS_COMPONENT).
+ */
+ public abstract int getGlyphClass ( int gid );
+ static GlyphDefinitionSubtable create ( String id, int sequence, int flags, int format, GlyphMappingTable mapping, List entries ) {
+ if ( format == 1 ) {
+ return new GlyphClassSubtableFormat1 ( id, sequence, flags, format, mapping, entries );
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+
+ private static class GlyphClassSubtableFormat1 extends GlyphClassSubtable {
+ GlyphClassSubtableFormat1 ( String id, int sequence, int flags, int format, GlyphMappingTable mapping, List entries ) {
+ super ( id, sequence, flags, format, mapping, entries );
+ }
+ /** {@inheritDoc} */
+ public List getEntries() {
+ return null;
+ }
+ /** {@inheritDoc} */
+ public boolean isCompatible ( GlyphSubtable subtable ) {
+ return subtable instanceof GlyphClassSubtable;
+ }
+ /** {@inheritDoc} */
+ public boolean isGlyphClass ( int gid, int gc ) {
+ GlyphClassMapping cm = getClasses();
+ if ( cm != null ) {
+ return cm.getClassIndex ( gid, 0 ) == gc;
+ } else {
+ return false;
+ }
+ }
+ /** {@inheritDoc} */
+ public int getGlyphClass ( int gid ) {
+ GlyphClassMapping cm = getClasses();
+ if ( cm != null ) {
+ return cm.getClassIndex ( gid, 0 );
+ } else {
+ return -1;
+ }
+ }
+ }
+
+ private abstract static class AttachmentPointSubtable extends GlyphDefinitionSubtable {
+ AttachmentPointSubtable ( String id, int sequence, int flags, int format, GlyphMappingTable mapping, List entries ) {
+ super ( id, sequence, flags, format, mapping );
+ }
+ /** {@inheritDoc} */
+ public int getType() {
+ return GDEF_LOOKUP_TYPE_ATTACHMENT_POINT;
+ }
+ static GlyphDefinitionSubtable create ( String id, int sequence, int flags, int format, GlyphMappingTable mapping, List entries ) {
+ if ( format == 1 ) {
+ return new AttachmentPointSubtableFormat1 ( id, sequence, flags, format, mapping, entries );
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+
+ private static class AttachmentPointSubtableFormat1 extends AttachmentPointSubtable {
+ AttachmentPointSubtableFormat1 ( String id, int sequence, int flags, int format, GlyphMappingTable mapping, List entries ) {
+ super ( id, sequence, flags, format, mapping, entries );
+ }
+ /** {@inheritDoc} */
+ public List getEntries() {
+ return null;
+ }
+ /** {@inheritDoc} */
+ public boolean isCompatible ( GlyphSubtable subtable ) {
+ return subtable instanceof AttachmentPointSubtable;
+ }
+ }
+
+ private abstract static class LigatureCaretSubtable extends GlyphDefinitionSubtable {
+ LigatureCaretSubtable ( String id, int sequence, int flags, int format, GlyphMappingTable mapping, List entries ) {
+ super ( id, sequence, flags, format, mapping );
+ }
+ /** {@inheritDoc} */
+ public int getType() {
+ return GDEF_LOOKUP_TYPE_LIGATURE_CARET;
+ }
+ static GlyphDefinitionSubtable create ( String id, int sequence, int flags, int format, GlyphMappingTable mapping, List entries ) {
+ if ( format == 1 ) {
+ return new LigatureCaretSubtableFormat1 ( id, sequence, flags, format, mapping, entries );
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+
+ private static class LigatureCaretSubtableFormat1 extends LigatureCaretSubtable {
+ LigatureCaretSubtableFormat1 ( String id, int sequence, int flags, int format, GlyphMappingTable mapping, List entries ) {
+ super ( id, sequence, flags, format, mapping, entries );
+ }
+ /** {@inheritDoc} */
+ public List getEntries() {
+ return null;
+ }
+ /** {@inheritDoc} */
+ public boolean isCompatible ( GlyphSubtable subtable ) {
+ return subtable instanceof LigatureCaretSubtable;
+ }
+ }
+
+ private abstract static class MarkAttachmentSubtable extends GlyphDefinitionSubtable {
+ MarkAttachmentSubtable ( String id, int sequence, int flags, int format, GlyphMappingTable mapping, List entries ) {
+ super ( id, sequence, flags, format, mapping );
+ }
+ /** {@inheritDoc} */
+ public int getType() {
+ return GDEF_LOOKUP_TYPE_MARK_ATTACHMENT;
+ }
+ /**
+ * Determine if glyph belongs to (font specific) mark attachment class.
+ * @param gid a glyph identifier (index)
+ * @param mac a (font specific) mark attachment class
+ * @return true if glyph belongs to specified mark attachment class
+ */
+ public abstract boolean isMarkAttachClass ( int gid, int mac );
+ /**
+ * Determine mark attachment class.
+ * @param gid a glyph identifier (index)
+ * @return a non-negative mark attachment class, or -1 if no class defined
+ */
+ public abstract int getMarkAttachClass ( int gid );
+ static GlyphDefinitionSubtable create ( String id, int sequence, int flags, int format, GlyphMappingTable mapping, List entries ) {
+ if ( format == 1 ) {
+ return new MarkAttachmentSubtableFormat1 ( id, sequence, flags, format, mapping, entries );
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+
+ private static class MarkAttachmentSubtableFormat1 extends MarkAttachmentSubtable {
+ MarkAttachmentSubtableFormat1 ( String id, int sequence, int flags, int format, GlyphMappingTable mapping, List entries ) {
+ super ( id, sequence, flags, format, mapping, entries );
+ }
+ /** {@inheritDoc} */
+ public List getEntries() {
+ return null;
+ }
+ /** {@inheritDoc} */
+ public boolean isCompatible ( GlyphSubtable subtable ) {
+ return subtable instanceof MarkAttachmentSubtable;
+ }
+ /** {@inheritDoc} */
+ public boolean isMarkAttachClass ( int gid, int mac ) {
+ GlyphClassMapping cm = getClasses();
+ if ( cm != null ) {
+ return cm.getClassIndex ( gid, 0 ) == mac;
+ } else {
+ return false;
+ }
+ }
+ /** {@inheritDoc} */
+ public int getMarkAttachClass ( int gid ) {
+ GlyphClassMapping cm = getClasses();
+ if ( cm != null ) {
+ return cm.getClassIndex ( gid, 0 );
+ } else {
+ return -1;
+ }
+ }
+ }
+
+}
Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphMappingTable.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphMappingTable.java?rev=1293736&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphMappingTable.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphMappingTable.java Sun Feb 26 02:29:01 2012
@@ -0,0 +1,322 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.fop.complexscripts.fonts;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Iterator;
+
+// CSOFF: NoWhitespaceAfterCheck
+// CSOFF: InnerAssignmentCheck
+// CSOFF: LineLengthCheck
+
+/**
+ * Base class implementation of glyph mapping table. This base
+ * class maps glyph indices to arbitrary integers (mappping indices), and
+ * is used to implement both glyph coverage and glyph class maps.
+ * @author Glenn Adams
+ */
+public class GlyphMappingTable {
+
+ /** empty mapping table */
+ public static final int GLYPH_MAPPING_TYPE_EMPTY = 0;
+
+ /** mapped mapping table */
+ public static final int GLYPH_MAPPING_TYPE_MAPPED = 1;
+
+ /** range based mapping table */
+ public static final int GLYPH_MAPPING_TYPE_RANGE = 2;
+
+ /**
+ * Obtain mapping type.
+ * @return mapping format type
+ */
+ public int getType() {
+ return -1;
+ }
+
+ /**
+ * Obtain mapping entries.
+ * @return list of mapping entries
+ */
+ public List getEntries() {
+ return null;
+ }
+
+ /**
+ * Obtain size of mapping table, i.e., ciMax + 1, where ciMax is the maximum
+ * mapping index.
+ * @return size of mapping table
+ */
+ public int getMappingSize() {
+ return 0;
+ }
+
+ /**
+ * Map glyph identifier (code) to coverge index. Returns -1 if glyph identifier is not in the domain of
+ * the mapping table.
+ * @param gid glyph identifier (code)
+ * @return non-negative glyph mapping index or -1 if glyph identifiers is not mapped by table
+ */
+ public int getMappedIndex ( int gid ) {
+ return -1;
+ }
+
+ /** empty mapping table base class */
+ protected static class EmptyMappingTable extends GlyphMappingTable {
+ /**
+ * Construct empty mapping table.
+ */
+ public EmptyMappingTable() {
+ this ( (List) null );
+ }
+ /**
+ * Construct empty mapping table with entries (ignored).
+ * @param entries list of entries (ignored)
+ */
+ public EmptyMappingTable ( List entries ) {
+ }
+ /** {@inheritDoc} */
+ public int getType() {
+ return GLYPH_MAPPING_TYPE_EMPTY;
+ }
+ /** {@inheritDoc} */
+ public List getEntries() {
+ return new java.util.ArrayList();
+ }
+ /** {@inheritDoc} */
+ public int getMappingSize() {
+ return 0;
+ }
+ /** {@inheritDoc} */
+ public int getMappedIndex ( int gid ) {
+ return -1;
+ }
+ }
+
+ /** mapped mapping table base class */
+ protected static class MappedMappingTable extends GlyphMappingTable {
+ /**
+ * Construct mapped mapping table.
+ */
+ public MappedMappingTable() {
+ }
+ /** {@inheritDoc} */
+ public int getType() {
+ return GLYPH_MAPPING_TYPE_MAPPED;
+ }
+ }
+
+ /** range mapping table base class */
+ protected abstract static class RangeMappingTable extends GlyphMappingTable {
+ private int[] sa = null; // array of range (inclusive) starts
+ private int[] ea = null; // array of range (inclusive) ends
+ private int[] ma = null; // array of range mapped values
+ private int miMax = -1;
+ /**
+ * Construct range mapping table.
+ * @param entries of mapping ranges
+ */
+ public RangeMappingTable ( List entries ) {
+ populate ( entries );
+ }
+ /** {@inheritDoc} */
+ public int getType() {
+ return GLYPH_MAPPING_TYPE_RANGE;
+ }
+ /** {@inheritDoc} */
+ public List getEntries() {
+ List entries = new java.util.ArrayList();
+ if ( sa != null ) {
+ for ( int i = 0, n = sa.length; i < n; i++ ) {
+ entries.add ( new MappingRange ( sa [ i ], ea [ i ], ma [ i ] ) );
+ }
+ }
+ return entries;
+ }
+ /** {@inheritDoc} */
+ public int getMappingSize() {
+ return miMax + 1;
+ }
+ /** {@inheritDoc} */
+ public int getMappedIndex ( int gid ) {
+ int i, mi;
+ if ( ( i = Arrays.binarySearch ( sa, gid ) ) >= 0 ) {
+ mi = getMappedIndex ( gid, sa [ i ], ma [ i ] ); // matches start of (some) range
+ } else if ( ( i = - ( i + 1 ) ) == 0 ) {
+ mi = -1; // precedes first range
+ } else if ( gid > ea [ --i ] ) {
+ mi = -1; // follows preceding (or last) range
+ } else {
+ mi = getMappedIndex ( gid, sa [ i ], ma [ i ] ); // intersects (some) range
+ }
+ return mi;
+ }
+ /**
+ * Map glyph identifier (code) to coverge index. Returns -1 if glyph identifier is not in the domain of
+ * the mapping table.
+ * @param gid glyph identifier (code)
+ * @param s start of range
+ * @param m mapping value
+ * @return non-negative glyph mapping index or -1 if glyph identifiers is not mapped by table
+ */
+ public abstract int getMappedIndex ( int gid, int s, int m );
+ private void populate ( List entries ) {
+ int i = 0, n = entries.size(), gidMax = -1, miMax = -1;
+ int[] sa = new int [ n ];
+ int[] ea = new int [ n ];
+ int[] ma = new int [ n ];
+ for ( Iterator it = entries.iterator(); it.hasNext();) {
+ Object o = it.next();
+ if ( o instanceof MappingRange ) {
+ MappingRange r = (MappingRange) o;
+ int gs = r.getStart();
+ int ge = r.getEnd();
+ int mi = r.getIndex();
+ if ( ( gs < 0 ) || ( gs > 65535 ) ) {
+ throw new AdvancedTypographicTableFormatException ( "illegal glyph range: [" + gs + "," + ge + "]: bad start index" );
+ } else if ( ( ge < 0 ) || ( ge > 65535 ) ) {
+ throw new AdvancedTypographicTableFormatException ( "illegal glyph range: [" + gs + "," + ge + "]: bad end index" );
+ } else if ( gs > ge ) {
+ throw new AdvancedTypographicTableFormatException ( "illegal glyph range: [" + gs + "," + ge + "]: start index exceeds end index" );
+ } else if ( gs < gidMax ) {
+ throw new AdvancedTypographicTableFormatException ( "out of order glyph range: [" + gs + "," + ge + "]" );
+ } else if ( mi < 0 ) {
+ throw new AdvancedTypographicTableFormatException ( "illegal mapping index: " + mi );
+ } else {
+ int miLast;
+ sa [ i ] = gs;
+ ea [ i ] = gidMax = ge;
+ ma [ i ] = mi;
+ if ( ( miLast = mi + ( ge - gs ) ) > miMax ) {
+ miMax = miLast;
+ }
+ i++;
+ }
+ } else {
+ throw new AdvancedTypographicTableFormatException ( "illegal mapping entry, must be Integer: " + o );
+ }
+ }
+ assert i == n;
+ assert this.sa == null;
+ assert this.ea == null;
+ assert this.ma == null;
+ this.sa = sa;
+ this.ea = ea;
+ this.ma = ma;
+ this.miMax = miMax;
+ }
+ /** {@inheritDoc} */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append('{');
+ for ( int i = 0, n = sa.length; i < n; i++ ) {
+ if ( i > 0 ) {
+ sb.append(',');
+ }
+ sb.append ( '[' );
+ sb.append ( Integer.toString ( sa [ i ] ) );
+ sb.append ( Integer.toString ( ea [ i ] ) );
+ sb.append ( "]:" );
+ sb.append ( Integer.toString ( ma [ i ] ) );
+ }
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+
+ /**
+ * The <code>MappingRange</code> class encapsulates a glyph [start,end] range and
+ * a mapping index.
+ */
+ public static class MappingRange {
+
+ private final int gidStart; // first glyph in range (inclusive)
+ private final int gidEnd; // last glyph in range (inclusive)
+ private final int index; // mapping index;
+
+ /**
+ * Instantiate a mapping range.
+ */
+ public MappingRange() {
+ this ( 0, 0, 0 );
+ }
+
+ /**
+ * Instantiate a specific mapping range.
+ * @param gidStart start of range
+ * @param gidEnd end of range
+ * @param index mapping index
+ */
+ public MappingRange ( int gidStart, int gidEnd, int index ) {
+ if ( ( gidStart < 0 ) || ( gidEnd < 0 ) || ( index < 0 ) ) {
+ throw new AdvancedTypographicTableFormatException();
+ } else if ( gidStart > gidEnd ) {
+ throw new AdvancedTypographicTableFormatException();
+ } else {
+ this.gidStart = gidStart;
+ this.gidEnd = gidEnd;
+ this.index = index;
+ }
+ }
+
+ /** @return start of range */
+ public int getStart() {
+ return gidStart;
+ }
+
+ /** @return end of range */
+ public int getEnd() {
+ return gidEnd;
+ }
+
+ /** @return mapping index */
+ public int getIndex() {
+ return index;
+ }
+
+ /** @return interval as a pair of integers */
+ public int[] getInterval() {
+ return new int[] { gidStart, gidEnd };
+ }
+
+ /**
+ * Obtain interval, filled into first two elements of specified array, or returning new array.
+ * @param interval an array of length two or greater or null
+ * @return interval as a pair of integers, filled into specified array
+ */
+ public int[] getInterval ( int[] interval ) {
+ if ( ( interval == null ) || ( interval.length != 2 ) ) {
+ throw new IllegalArgumentException();
+ } else {
+ interval[0] = gidStart;
+ interval[1] = gidEnd;
+ }
+ return interval;
+ }
+
+ /** @return length of interval */
+ public int getLength() {
+ return gidStart - gidEnd;
+ }
+
+ }
+
+}
Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioning.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioning.java?rev=1293736&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioning.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioning.java Sun Feb 26 02:29:01 2012
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.fop.complexscripts.fonts;
+
+// CSOFF: LineLengthCheck
+
+/**
+ * The <code>GlyphPositioning</code> interface is implemented by a glyph positioning subtable
+ * that supports the determination of glyph positioning information based on script and
+ * language of the corresponding character content.
+ * @author Glenn Adams
+ */
+public interface GlyphPositioning {
+
+ /**
+ * Perform glyph positioning at the current index, mutating the positioning state object as required.
+ * Only the context associated with the current index is processed.
+ * @param ps glyph positioning state object
+ * @return true if the glyph subtable applies, meaning that the current context matches the
+ * associated input context glyph coverage table; note that returning true does not mean any position
+ * adjustment occurred; it only means that no further glyph subtables for the current lookup table
+ * should be applied.
+ */
+ boolean position ( GlyphPositioningState ps );
+
+}
Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningState.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningState.java?rev=1293736&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningState.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningState.java Sun Feb 26 02:29:01 2012
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.fop.complexscripts.fonts;
+
+import org.apache.fop.complexscripts.util.GlyphSequence;
+import org.apache.fop.complexscripts.util.ScriptContextTester;
+
+// CSOFF: LineLengthCheck
+// CSOFF: ParameterNumberCheck
+
+/**
+ * The <code>GlyphPositioningState</code> implements an state object used during glyph positioning
+ * processing.
+ * @author Glenn Adams
+ */
+
+public class GlyphPositioningState extends GlyphProcessingState {
+
+ /** font size */
+ private int fontSize;
+ /** default advancements */
+ private int[] widths;
+ /** current adjustments */
+ private int[][] adjustments;
+ /** if true, then some adjustment was applied */
+ private boolean adjusted;
+
+ /**
+ * Construct glyph positioning state.
+ * @param gs input glyph sequence
+ * @param script script identifier
+ * @param language language identifier
+ * @param feature feature identifier
+ * @param fontSize font size (in micropoints)
+ * @param widths array of design advancements (in glyph index order)
+ * @param adjustments positioning adjustments to which positioning is applied
+ * @param sct script context tester (or null)
+ */
+ public GlyphPositioningState ( GlyphSequence gs, String script, String language, String feature, int fontSize, int[] widths, int[][] adjustments, ScriptContextTester sct ) {
+ super ( gs, script, language, feature, sct );
+ this.fontSize = fontSize;
+ this.widths = widths;
+ this.adjustments = adjustments;
+ }
+
+ /**
+ * Construct glyph positioning state using an existing state object using shallow copy
+ * except as follows: input glyph sequence is copied deep except for its characters array.
+ * @param ps existing positioning state to copy from
+ */
+ public GlyphPositioningState ( GlyphPositioningState ps ) {
+ super ( ps );
+ this.fontSize = ps.fontSize;
+ this.widths = ps.widths;
+ this.adjustments = ps.adjustments;
+ }
+
+ /**
+ * Obtain design advancement (width) of glyph at specified index.
+ * @param gi glyph index
+ * @return design advancement, or zero if glyph index is not present
+ */
+ public int getWidth ( int gi ) {
+ if ( ( widths != null ) && ( gi < widths.length ) ) {
+ return widths [ gi ];
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Perform adjustments at current position index.
+ * @param v value containing adjustments
+ * @return true if a non-zero adjustment was made
+ */
+ public boolean adjust ( GlyphPositioningTable.Value v ) {
+ return adjust ( v, 0 );
+ }
+
+ /**
+ * Perform adjustments at specified offset from current position index.
+ * @param v value containing adjustments
+ * @param offset from current position index
+ * @return true if a non-zero adjustment was made
+ */
+ public boolean adjust ( GlyphPositioningTable.Value v, int offset ) {
+ assert v != null;
+ if ( ( index + offset ) < indexLast ) {
+ return v.adjust ( adjustments [ index + offset ], fontSize );
+ } else {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /**
+ * Obtain current adjustments at current position index.
+ * @return array of adjustments (int[4]) at current position
+ */
+ public int[] getAdjustment() {
+ return getAdjustment ( 0 );
+ }
+
+ /**
+ * Obtain current adjustments at specified offset from current position index.
+ * @param offset from current position index
+ * @return array of adjustments (int[4]) at specified offset
+ * @throws IndexOutOfBoundsException if offset is invalid
+ */
+ public int[] getAdjustment ( int offset ) throws IndexOutOfBoundsException {
+ if ( ( index + offset ) < indexLast ) {
+ return adjustments [ index + offset ];
+ } else {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /**
+ * Apply positioning subtable to current state at current position (only),
+ * resulting in the consumption of zero or more input glyphs.
+ * @param st the glyph positioning subtable to apply
+ * @return true if subtable applied, or false if it did not (e.g., its
+ * input coverage table did not match current input context)
+ */
+ public boolean apply ( GlyphPositioningSubtable st ) {
+ assert st != null;
+ updateSubtableState ( st );
+ boolean applied = st.position ( this );
+ resetSubtableState();
+ return applied;
+ }
+
+ /**
+ * Apply a sequence of matched rule lookups to the <code>nig</code> input glyphs
+ * starting at the current position. If lookups are non-null and non-empty, then
+ * all input glyphs specified by <code>nig</code> are consumed irregardless of
+ * whether any specified lookup applied.
+ * @param lookups array of matched lookups (or null)
+ * @param nig number of glyphs in input sequence, starting at current position, to which
+ * the lookups are to apply, and to be consumed once the application has finished
+ * @return true if lookups are non-null and non-empty; otherwise, false
+ */
+ public boolean apply ( GlyphTable.RuleLookup[] lookups, int nig ) {
+ if ( ( lookups != null ) && ( lookups.length > 0 ) ) {
+ // apply each rule lookup to extracted input glyph array
+ for ( int i = 0, n = lookups.length; i < n; i++ ) {
+ GlyphTable.RuleLookup l = lookups [ i ];
+ if ( l != null ) {
+ GlyphTable.LookupTable lt = l.getLookup();
+ if ( lt != null ) {
+ // perform positioning on a copy of previous state
+ GlyphPositioningState ps = new GlyphPositioningState ( this );
+ // apply lookup table positioning
+ if ( lt.position ( ps, l.getSequenceIndex() ) ) {
+ setAdjusted ( true );
+ }
+ }
+ }
+ }
+ consume ( nig );
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Apply default application semantices; namely, consume one input glyph.
+ */
+ public void applyDefault() {
+ super.applyDefault();
+ }
+
+ /**
+ * Set adjusted state, used to record effect of non-zero adjustment.
+ * @param adjusted true if to set adjusted state, otherwise false to
+ * clear adjusted state
+ */
+ public void setAdjusted ( boolean adjusted ) {
+ this.adjusted = adjusted;
+ }
+
+ /**
+ * Get adjusted state.
+ * @return adjusted true if some non-zero adjustment occurred and
+ * was recorded by {@link #setAdjusted}; otherwise, false.
+ */
+ public boolean getAdjusted() {
+ return adjusted;
+ }
+
+}
Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningSubtable.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningSubtable.java?rev=1293736&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningSubtable.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningSubtable.java Sun Feb 26 02:29:01 2012
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.fop.complexscripts.fonts;
+
+import java.util.List;
+
+import org.apache.fop.complexscripts.util.GlyphSequence;
+import org.apache.fop.complexscripts.util.ScriptContextTester;
+
+// CSOFF: LineLengthCheck
+// CSOFF: NoWhitespaceAfterCheck
+// CSOFF: ParameterNumberCheck
+
+/**
+ * The <code>GlyphPositioningSubtable</code> implements an abstract base of a glyph subtable,
+ * providing a default implementation of the <code>GlyphPositioning</code> interface.
+ * @author Glenn Adams
+ */
+public abstract class GlyphPositioningSubtable extends GlyphSubtable implements GlyphPositioning {
+
+ /**
+ * Instantiate a <code>GlyphPositioningSubtable</code>.
+ * @param id subtable identifier
+ * @param sequence subtable sequence
+ * @param flags subtable flags
+ * @param format subtable format
+ * @param coverage subtable coverage table
+ */
+ protected GlyphPositioningSubtable ( String id, int sequence, int flags, int format, GlyphCoverageTable coverage ) {
+ super ( id, sequence, flags, format, coverage );
+ }
+
+ /** {@inheritDoc} */
+ public int getTableType() {
+ return GlyphTable.GLYPH_TABLE_TYPE_POSITIONING;
+ }
+
+ /** {@inheritDoc} */
+ public String getTypeName() {
+ return GlyphPositioningTable.getLookupTypeName ( getType() );
+ }
+
+ /** {@inheritDoc} */
+ public boolean isCompatible ( GlyphSubtable subtable ) {
+ return subtable instanceof GlyphPositioningSubtable;
+ }
+
+ /** {@inheritDoc} */
+ public boolean usesReverseScan() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ public boolean position ( GlyphPositioningState ps ) {
+ return false;
+ }
+
+ /**
+ * Apply positioning using specified state and subtable array. For each position in input sequence,
+ * apply subtables in order until some subtable applies or none remain. If no subtable applied or no
+ * input was consumed for a given position, then apply default action (no adjustments and advance).
+ * If <code>sequenceIndex</code> is non-negative, then apply subtables only when current position
+ * matches <code>sequenceIndex</code> in relation to the starting position. Furthermore, upon
+ * successful application at <code>sequenceIndex</code>, then discontinue processing the remaining
+ * @param ps positioning state
+ * @param sta array of subtables to apply
+ * @param sequenceIndex if non negative, then apply subtables only at specified sequence index
+ * @return true if a non-zero adjustment occurred
+ */
+ public static final boolean position ( GlyphPositioningState ps, GlyphPositioningSubtable[] sta, int sequenceIndex ) {
+ int sequenceStart = ps.getPosition();
+ boolean appliedOneShot = false;
+ while ( ps.hasNext() ) {
+ boolean applied = false;
+ if ( ! appliedOneShot && ps.maybeApplicable() ) {
+ for ( int i = 0, n = sta.length; ! applied && ( i < n ); i++ ) {
+ if ( sequenceIndex < 0 ) {
+ applied = ps.apply ( sta [ i ] );
+ } else if ( ps.getPosition() == ( sequenceStart + sequenceIndex ) ) {
+ applied = ps.apply ( sta [ i ] );
+ if ( applied ) {
+ appliedOneShot = true;
+ }
+ }
+ }
+ }
+ if ( ! applied || ! ps.didConsume() ) {
+ ps.applyDefault();
+ }
+ ps.next();
+ }
+ return ps.getAdjusted();
+ }
+
+ /**
+ * Apply positioning.
+ * @param gs input glyph sequence
+ * @param script tag
+ * @param language tag
+ * @param feature tag
+ * @param fontSize the font size
+ * @param sta subtable array
+ * @param widths array
+ * @param adjustments array (receives output adjustments)
+ * @param sct script context tester
+ * @return true if a non-zero adjustment occurred
+ */
+ public static final boolean position ( GlyphSequence gs, String script, String language, String feature, int fontSize, GlyphPositioningSubtable[] sta, int[] widths, int[][] adjustments, ScriptContextTester sct ) {
+ return position ( new GlyphPositioningState ( gs, script, language, feature, fontSize, widths, adjustments, sct ), sta, -1 );
+ }
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org