001: /*
002:
003: Licensed to the Apache Software Foundation (ASF) under one or more
004: contributor license agreements. See the NOTICE file distributed with
005: this work for additional information regarding copyright ownership.
006: The ASF licenses this file to You under the Apache License, Version 2.0
007: (the "License"); you may not use this file except in compliance with
008: the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing, software
013: distributed under the License is distributed on an "AS IS" BASIS,
014: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: See the License for the specific language governing permissions and
016: limitations under the License.
017:
018: */
019: package org.apache.batik.svggen.font.table;
020:
021: import java.io.ByteArrayInputStream;
022: import java.util.ArrayList;
023: import java.util.Iterator;
024: import java.util.List;
025:
026: /**
027: * Glyph description for composite glyphs. Composite glyphs are made up of one
028: * or more simple glyphs, usually with some sort of transformation applied to
029: * each.
030: *
031: * @version $Id: GlyfCompositeDescript.java 475477 2006-11-15 22:44:28Z cam $
032: * @author <a href="mailto:david@steadystate.co.uk">David Schweinsberg</a>
033: */
034: public class GlyfCompositeDescript extends GlyfDescript {
035:
036: private List components = new ArrayList();
037:
038: protected boolean beingResolved = false;
039: protected boolean resolved = false;
040:
041: public GlyfCompositeDescript(GlyfTable parentTable,
042: ByteArrayInputStream bais) {
043: super (parentTable, (short) -1, bais);
044:
045: // Get all of the composite components
046: GlyfCompositeComp comp;
047: do {
048: comp = new GlyfCompositeComp(bais);
049: components.add(comp);
050: } while ((comp.getFlags() & GlyfCompositeComp.MORE_COMPONENTS) != 0);
051:
052: // Are there hinting intructions to read?
053: if ((comp.getFlags() & GlyfCompositeComp.WE_HAVE_INSTRUCTIONS) != 0) {
054: readInstructions(bais, (bais.read() << 8 | bais.read()));
055: }
056: }
057:
058: public void resolve() {
059: if (resolved)
060: return;
061: if (beingResolved) {
062: System.err
063: .println("Circular reference in GlyfCompositeDesc");
064: return;
065: }
066: beingResolved = true;
067:
068: int firstIndex = 0;
069: int firstContour = 0;
070:
071: Iterator i = components.iterator();
072: while (i.hasNext()) {
073: GlyfCompositeComp comp = (GlyfCompositeComp) i.next();
074: comp.setFirstIndex(firstIndex);
075: comp.setFirstContour(firstContour);
076:
077: GlyfDescript desc;
078: desc = parentTable.getDescription(comp.getGlyphIndex());
079: if (desc != null) {
080: desc.resolve();
081: firstIndex += desc.getPointCount();
082: firstContour += desc.getContourCount();
083: }
084: }
085: resolved = true;
086: beingResolved = false;
087: }
088:
089: public int getEndPtOfContours(int i) {
090: GlyfCompositeComp c = getCompositeCompEndPt(i);
091: if (c != null) {
092: GlyphDescription gd = parentTable.getDescription(c
093: .getGlyphIndex());
094: return gd.getEndPtOfContours(i - c.getFirstContour())
095: + c.getFirstIndex();
096: }
097: return 0;
098: }
099:
100: public byte getFlags(int i) {
101: GlyfCompositeComp c = getCompositeComp(i);
102: if (c != null) {
103: GlyphDescription gd = parentTable.getDescription(c
104: .getGlyphIndex());
105: return gd.getFlags(i - c.getFirstIndex());
106: }
107: return 0;
108: }
109:
110: public short getXCoordinate(int i) {
111: GlyfCompositeComp c = getCompositeComp(i);
112: if (c != null) {
113: GlyphDescription gd = parentTable.getDescription(c
114: .getGlyphIndex());
115: int n = i - c.getFirstIndex();
116: int x = gd.getXCoordinate(n);
117: int y = gd.getYCoordinate(n);
118: short x1 = (short) c.scaleX(x, y);
119: x1 += c.getXTranslate();
120: return x1;
121: }
122: return 0;
123: }
124:
125: public short getYCoordinate(int i) {
126: GlyfCompositeComp c = getCompositeComp(i);
127: if (c != null) {
128: GlyphDescription gd = parentTable.getDescription(c
129: .getGlyphIndex());
130: int n = i - c.getFirstIndex();
131: int x = gd.getXCoordinate(n);
132: int y = gd.getYCoordinate(n);
133: short y1 = (short) c.scaleY(x, y);
134: y1 += c.getYTranslate();
135: return y1;
136: }
137: return 0;
138: }
139:
140: public boolean isComposite() {
141: return true;
142: }
143:
144: public int getPointCount() {
145: if (!resolved)
146: System.err
147: .println("getPointCount called on unresolved GlyfCompositeDescript");
148:
149: GlyfCompositeComp c = (GlyfCompositeComp) components
150: .get(components.size() - 1);
151: // System.err.println("C: " + c + " Idx: " + c.getGlyphIndex());
152: // System.err.println("Ptbl: " + parentTable);
153: return c.getFirstIndex()
154: + parentTable.getDescription(c.getGlyphIndex())
155: .getPointCount();
156: }
157:
158: public int getContourCount() {
159: if (!resolved)
160: System.err
161: .println("getContourCount called on unresolved GlyfCompositeDescript");
162:
163: GlyfCompositeComp c = (GlyfCompositeComp) components
164: .get(components.size() - 1);
165: return c.getFirstContour()
166: + parentTable.getDescription(c.getGlyphIndex())
167: .getContourCount();
168: }
169:
170: public int getComponentIndex(int i) {
171: return ((GlyfCompositeComp) components.get(i)).getFirstIndex();
172: }
173:
174: public int getComponentCount() {
175: return components.size();
176: }
177:
178: protected GlyfCompositeComp getCompositeComp(int i) {
179: GlyfCompositeComp c;
180: for (int n = 0; n < components.size(); n++) {
181: c = (GlyfCompositeComp) components.get(n);
182: GlyphDescription gd = parentTable.getDescription(c
183: .getGlyphIndex());
184: if (c.getFirstIndex() <= i
185: && i < (c.getFirstIndex() + gd.getPointCount())) {
186: return c;
187: }
188: }
189: return null;
190: }
191:
192: protected GlyfCompositeComp getCompositeCompEndPt(int i) {
193: GlyfCompositeComp c;
194: for (int j = 0; j < components.size(); j++) {
195: c = (GlyfCompositeComp) components.get(j);
196: GlyphDescription gd = parentTable.getDescription(c
197: .getGlyphIndex());
198: if (c.getFirstContour() <= i
199: && i < (c.getFirstContour() + gd.getContourCount())) {
200: return c;
201: }
202: }
203: return null;
204: }
205: }
|