001: /*
002: * Copyright (c) 2007, intarsys consulting GmbH
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * - Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * - Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * - Neither the name of intarsys nor the names of its contributors may be used
015: * to endorse or promote products derived from this software without specific
016: * prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
028: * POSSIBILITY OF SUCH DAMAGE.
029: */
030: package de.intarsys.pdf.font;
031:
032: import java.util.ArrayList;
033: import java.util.Iterator;
034: import java.util.List;
035: import de.intarsys.pdf.content.CSContent;
036: import de.intarsys.pdf.content.CSOperation;
037: import de.intarsys.pdf.cos.COSArray;
038: import de.intarsys.pdf.cos.COSInteger;
039: import de.intarsys.pdf.cos.COSName;
040: import de.intarsys.pdf.cos.COSObject;
041: import de.intarsys.pdf.cos.COSString;
042:
043: /**
044: *
045: */
046: public class StreamBasedCMap extends CMap {
047: /**
048: * The meta class implementation
049: */
050: public static class MetaClass extends CMap.MetaClass {
051: protected MetaClass(Class instanceClass) {
052: super (instanceClass);
053: }
054: }
055:
056: /** The meta class instance */
057: public static final MetaClass META = new MetaClass(MetaClass.class
058: .getDeclaringClass());
059:
060: public static final COSName DK_CMapName = COSName
061: .constant("CMapName");
062:
063: public static final COSName DK_CIDSystemInfo = COSName
064: .constant("CIDSystemInfo");
065:
066: public static final COSName DK_WMode = COSName.constant("WMode");
067:
068: public static final COSName DK_UseCMap = COSName
069: .constant("UseCMap");
070:
071: /**
072: * @param object
073: */
074: protected StreamBasedCMap(COSObject object) {
075: super (object);
076: }
077:
078: /**
079: * The maps from bytes to CID's
080: */
081: private List maps = new ArrayList();
082:
083: /**
084: * The notdef maps
085: */
086: private List notdefs = new ArrayList();
087:
088: /**
089: * The codespace ranges
090: */
091: private List ranges = new ArrayList();
092:
093: protected void addMap(CMapMap map) {
094: maps.add(map);
095: }
096:
097: protected void addNotdef(CMapMap notdef) {
098: notdefs.add(notdef);
099: }
100:
101: protected void addRange(CMapRange range) {
102: ranges.add(range);
103: }
104:
105: protected void do_beginbfchar(CSOperation operation) {
106: // no op, ignore size
107: }
108:
109: protected void do_beginbfrange(CSOperation operation) {
110: // no op, ignore size
111: }
112:
113: protected void do_begincidchar(CSOperation operation) {
114: // no op, ignore size
115: }
116:
117: protected void do_begincidrange(CSOperation operation) {
118: // no op, ignore size
119: }
120:
121: /**
122: *
123: */
124: protected void do_begincmap(CSOperation operation) {
125: // this is a no op
126: }
127:
128: /**
129: *
130: */
131: protected void do_begincodespacerange(CSOperation operation) {
132: // no op, ignore size
133: }
134:
135: /**
136: *
137: */
138: protected void do_beginnotdefchar(CSOperation operation) {
139: // no op, ignore size
140: }
141:
142: /**
143: *
144: */
145: protected void do_beginnotdefrange(CSOperation operation) {
146: // no op, ignore size
147: }
148:
149: /**
150: *
151: */
152: protected void do_endbfchar(CSOperation operation) {
153: Iterator it = operation.getOperands();
154: while (it.hasNext()) {
155: COSString start = (COSString) it.next();
156: COSObject destination = (COSObject) it.next();
157: CMapCharMap map;
158: if (destination instanceof COSString) {
159: map = new CMapBFCharCodeMap(start.byteValue(),
160: ((COSString) destination).byteValue());
161: } else {
162: map = new CMapBFCharNameMap(start.byteValue(),
163: (COSName) destination);
164: }
165: addMap(map);
166: }
167: }
168:
169: /**
170: *
171: */
172: protected void do_endbfrange(CSOperation operation) {
173: Iterator it = operation.getOperands();
174: while (it.hasNext()) {
175: COSString start = (COSString) it.next();
176: COSString end = (COSString) it.next();
177: COSObject destination = (COSObject) it.next();
178: CMapRangeMap map;
179: if (destination instanceof COSString) {
180: map = new CMapBFRangeCodeMap(start.byteValue(), end
181: .byteValue(), ((COSString) destination)
182: .byteValue());
183: } else {
184: map = new CMapBFRangeNameMap(start.byteValue(), end
185: .byteValue(), (COSArray) destination);
186: }
187: addMap(map);
188: }
189: }
190:
191: /**
192: *
193: */
194: protected void do_endcidchar(CSOperation operation) {
195: Iterator it = operation.getOperands();
196: while (it.hasNext()) {
197: COSString start = (COSString) it.next();
198: COSInteger destination = (COSInteger) it.next();
199: CMapCharMap map = new CMapCIDCharCodeMap(start.byteValue(),
200: destination.intValue());
201: addMap(map);
202: }
203: }
204:
205: /**
206: *
207: */
208: protected void do_endcidrange(CSOperation operation) {
209: Iterator it = operation.getOperands();
210: while (it.hasNext()) {
211: COSString start = (COSString) it.next();
212: COSString end = (COSString) it.next();
213: COSInteger destination = (COSInteger) it.next();
214: CMapRangeMap map = new CMapCIDRangeCodeMap(start
215: .byteValue(), end.byteValue(), destination
216: .intValue());
217: addMap(map);
218: }
219: }
220:
221: /**
222: *
223: */
224: protected void do_endcmap(CSOperation operation) {
225: // this is a no op
226: }
227:
228: /**
229: *
230: */
231: protected void do_endcodespacerange(CSOperation operation) {
232: Iterator it = operation.getOperands();
233: while (it.hasNext()) {
234: COSString startString = (COSString) it.next();
235: COSString endString = (COSString) it.next();
236: CMapRange range = new CMapRange(startString.byteValue(),
237: endString.byteValue());
238: addRange(range);
239: }
240: }
241:
242: /**
243: *
244: */
245: protected void do_endnotdefchar(CSOperation operation) {
246: Iterator it = operation.getOperands();
247: while (it.hasNext()) {
248: COSString start = (COSString) it.next();
249: COSInteger destination = (COSInteger) it.next();
250: CMapCharMap map = new CMapCIDCharCodeMap(start.byteValue(),
251: destination.intValue());
252: addNotdef(map);
253: }
254: }
255:
256: /**
257: *
258: */
259: protected void do_endnotdefrange(CSOperation operation) {
260: Iterator it = operation.getOperands();
261: while (it.hasNext()) {
262: COSString start = (COSString) it.next();
263: COSString end = (COSString) it.next();
264: COSInteger destination = (COSInteger) it.next();
265: CMapRangeMap map = new CMapCIDRangeNotdefMap(start
266: .byteValue(), end.byteValue(), destination
267: .intValue());
268: addNotdef(map);
269: }
270: }
271:
272: /**
273: *
274: */
275: protected void do_usecmap(CSOperation operation) {
276: // todo 2 cmap not yet supported
277: }
278:
279: /**
280: *
281: */
282: protected void do_usefont(CSOperation operation) {
283: // not needed and not yet supported
284: }
285:
286: public CID lookup(byte[] value) {
287: // todo 1 cmap byte range check ??
288: for (Iterator it = maps.iterator(); it.hasNext();) {
289: CMapMap map = (CMapMap) it.next();
290: CID result = map.map(value);
291: if (result != null) {
292: return result;
293: }
294: }
295:
296: // todo 1 cmap notdefs
297: return CID.Notdef;
298: }
299:
300: /*
301: * (non-Javadoc)
302: *
303: * @see de.intarsys.pdf.content.IContentStreamVisitor#visitFromContentStream(de.intarsys.pdf.content.CSContent)
304: */
305: protected void initializeFromContent(CSContent content) {
306: int len = content.size();
307: for (int i = 0; i < len; i++) {
308: CSOperation operation = content.getOperation(i);
309: initializeFromOperation(operation);
310: }
311: }
312:
313: protected void initializeFromOperation(CSOperation operation) {
314: if (operation.matchesOperator(CMapOperator.CMO_beginbfchar)) {
315: do_beginbfchar(operation);
316: } else if (operation
317: .matchesOperator(CMapOperator.CMO_beginbfrange)) {
318: do_beginbfrange(operation);
319: } else if (operation
320: .matchesOperator(CMapOperator.CMO_begincidchar)) {
321: do_begincidchar(operation);
322: } else if (operation
323: .matchesOperator(CMapOperator.CMO_begincidrange)) {
324: do_begincidrange(operation);
325: } else if (operation
326: .matchesOperator(CMapOperator.CMO_begincmap)) {
327: do_begincmap(operation);
328: } else if (operation
329: .matchesOperator(CMapOperator.CMO_begincodespacerange)) {
330: do_begincodespacerange(operation);
331: } else if (operation
332: .matchesOperator(CMapOperator.CMO_beginnotdefchar)) {
333: do_beginnotdefchar(operation);
334: } else if (operation
335: .matchesOperator(CMapOperator.CMO_beginnotdefrange)) {
336: do_beginnotdefrange(operation);
337: } else if (operation
338: .matchesOperator(CMapOperator.CMO_endbfchar)) {
339: do_endbfchar(operation);
340: } else if (operation
341: .matchesOperator(CMapOperator.CMO_endbfrange)) {
342: do_endbfrange(operation);
343: } else if (operation
344: .matchesOperator(CMapOperator.CMO_endcidchar)) {
345: do_endcidchar(operation);
346: } else if (operation
347: .matchesOperator(CMapOperator.CMO_endcidrange)) {
348: do_endcidrange(operation);
349: } else if (operation.matchesOperator(CMapOperator.CMO_endcmap)) {
350: do_endcmap(operation);
351: } else if (operation
352: .matchesOperator(CMapOperator.CMO_endcodespacerange)) {
353: do_endcodespacerange(operation);
354: } else if (operation
355: .matchesOperator(CMapOperator.CMO_endnotdefchar)) {
356: do_endnotdefchar(operation);
357: } else if (operation
358: .matchesOperator(CMapOperator.CMO_endnotdefrange)) {
359: do_endnotdefrange(operation);
360: } else if (operation.matchesOperator(CMapOperator.CMO_usecmap)) {
361: do_usecmap(operation);
362: } else if (operation.matchesOperator(CMapOperator.CMO_usefont)) {
363: do_usefont(operation);
364: } else {
365: // unknown operator
366: }
367: }
368:
369: /*
370: * (non-Javadoc)
371: *
372: * @see de.intarsys.pdf.cos.COSBasedObject#initializeFromCos()
373: */
374: protected void initializeFromCos() {
375: super .initializeFromCos();
376: CSContent result = CSContent.createFromCos(cosGetStream());
377: initializeFromContent(result);
378: }
379:
380: public CID getNextCID(byte[] bytes, int offset) {
381: // todo 1 cmap this is wrong coding...
382: return new CIDSelectorCID(bytes, offset, 2);
383: }
384: }
|