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 de.intarsys.pdf.cds.CDSRectangle;
033: import de.intarsys.pdf.cos.COSArray;
034: import de.intarsys.pdf.cos.COSBasedObject;
035: import de.intarsys.pdf.cos.COSDictionary;
036: import de.intarsys.pdf.cos.COSInteger;
037: import de.intarsys.pdf.cos.COSName;
038: import de.intarsys.pdf.cos.COSObject;
039: import de.intarsys.pdf.cos.COSStream;
040: import de.intarsys.pdf.cos.COSString;
041: import de.intarsys.pdf.filter.Filter;
042: import de.intarsys.tools.collection.ByteArrayTools;
043:
044: /**
045: * The PDFontDescriptor that is used when an explicit font descriptor is
046: * available in the pdf file. This will happen most of the time, only the
047: * builtin fonts MAY discard this object.
048: */
049: public class PDFontDescriptorEmbedded extends PDFontDescriptor {
050: /**
051: * The meta class implementation
052: */
053: static public class MetaClass extends PDFontDescriptor.MetaClass {
054: protected MetaClass(Class instanceClass) {
055: super (instanceClass);
056: }
057:
058: protected COSBasedObject doCreateCOSBasedObject(COSObject object) {
059: return new PDFontDescriptorEmbedded(object);
060: }
061: }
062:
063: /** The meta class instance */
064: static public final MetaClass META = new MetaClass(MetaClass.class
065: .getDeclaringClass());
066:
067: //
068: static public final COSName DK_Descent = COSName
069: .constant("Descent");
070:
071: static public final COSName DK_CapHeight = COSName
072: .constant("CapHeight");
073:
074: static public final COSName DK_AvgWidth = COSName
075: .constant("AvgWidth");
076:
077: static public final COSName DK_Ascent = COSName.constant("Ascent");
078:
079: static public final COSName DK_XHeight = COSName
080: .constant("XHeight");
081:
082: static public final COSName DK_StemV = COSName.constant("StemV");
083:
084: static public final COSName DK_StemH = COSName.constant("StemH");
085:
086: static public final COSName DK_MissingWidth = COSName
087: .constant("MissingWidth");
088:
089: static public final COSName DK_MaxWidth = COSName
090: .constant("MaxWidth");
091:
092: static public final COSName DK_Leading = COSName
093: .constant("Leading");
094:
095: static public final COSName DK_ItalicAngle = COSName
096: .constant("ItalicAngle");
097:
098: static public final COSName DK_FontName = COSName
099: .constant("FontName");
100:
101: static public final COSName DK_FontBBox = COSName
102: .constant("FontBBox");
103:
104: static public final COSName DK_Flags = COSName.constant("Flags");
105:
106: static public final COSName DK_FontFile = COSName
107: .constant("FontFile");
108:
109: static public final COSName DK_FontFile2 = COSName
110: .constant("FontFile2");
111:
112: static public final COSName DK_FontFile3 = COSName
113: .constant("FontFile3");
114:
115: static public final COSName DK_Length1 = COSName
116: .constant("Length1");
117:
118: static public final COSName DK_Length2 = COSName
119: .constant("Length2");
120:
121: static public final COSName DK_Length3 = COSName
122: .constant("Length3");
123:
124: static public final COSName DK_FontFamily = COSName
125: .constant("FontFamily");
126:
127: /**
128: * Create the receiver class from an already defined {@link COSDictionary}.
129: * NEVER use the constructor directly.
130: *
131: * @param object
132: * the PDDocument containing the new object
133: */
134: protected PDFontDescriptorEmbedded(COSObject object) {
135: super (object);
136: }
137:
138: public void setAscent(int value) {
139: setFieldInt(DK_Ascent, value);
140: }
141:
142: /*
143: * (non-Javadoc)
144: *
145: * @see de.intarsys.pdf.font.PDFontDescriptor#getAscent()
146: */
147: public float getAscent() {
148: // TODO 3 wrong default, but this field is required
149: return getFieldFixed(DK_Ascent, 0);
150: }
151:
152: public void setAvgWidth(int value) {
153: setFieldInt(DK_AvgWidth, value);
154: }
155:
156: /*
157: * (non-Javadoc)
158: *
159: * @see de.intarsys.pdf.font.PDFontDescriptor#getAvgWidth()
160: */
161: public float getAvgWidth() {
162: return getFieldFixed(DK_AvgWidth, 0);
163: }
164:
165: public void setCapHeight(int value) {
166: setFieldInt(DK_CapHeight, value);
167: }
168:
169: /*
170: * (non-Javadoc)
171: *
172: * @see de.intarsys.pdf.font.PDFontDescriptor#getCapHeight()
173: */
174: public float getCapHeight() {
175: // TODO 3 wrong default, but this field is required
176: return getFieldFixed(DK_CapHeight, 0);
177: }
178:
179: public void setDescent(int value) {
180: setFieldInt(DK_Descent, value);
181: }
182:
183: /*
184: * (non-Javadoc)
185: *
186: * @see de.intarsys.pdf.font.PDFontDescriptor#getDescent()
187: */
188: public float getDescent() {
189: // TODO 3 wrong default, but this field is required
190: return getFieldFixed(DK_Descent, 0);
191: }
192:
193: public void setFlags(int value) {
194: setFieldInt(DK_Flags, value);
195: }
196:
197: /*
198: * (non-Javadoc)
199: *
200: * @see de.intarsys.pdf.font.PDFontDescriptor#getFlags()
201: */
202: public int getFlagsValue() {
203: // TODO 3 wrong default, but this field is required
204: return getFieldInt(DK_Flags, 0);
205: }
206:
207: /*
208: * (non-Javadoc)
209: *
210: * @see de.intarsys.pdf.font.PDFontDescriptor#setFlagsValue(int)
211: */
212: public void setFlagsValue(int value) {
213: setFieldInt(DK_Flags, value);
214: }
215:
216: public void setFontBB(CDSRectangle rect) {
217: setFieldObject(DK_FontBBox, rect);
218: }
219:
220: /*
221: * (non-Javadoc)
222: *
223: * @see de.intarsys.pdf.font.PDFontDescriptor#getRectangle()
224: */
225: public CDSRectangle getFontBB() {
226: COSArray array = cosGetField(DK_FontBBox).asArray();
227: if (array == null) {
228: return null;
229: }
230: return CDSRectangle.createFromCOS(array);
231: }
232:
233: public void setFontFamily(String value) {
234: // todo 3 name encoding
235: setFieldName(DK_FontFamily, value);
236: }
237:
238: /*
239: * (non-Javadoc)
240: *
241: * @see de.intarsys.pdf.font.PDFontDescriptor#getFontFamily()
242: */
243: public String getFontFamily() {
244: COSString ff = cosGetField(DK_FontFamily).asString();
245: return (ff == null) ? null : ff.stringValue();
246: }
247:
248: public byte[] getFontFile() {
249: COSStream stream = cosGetField(DK_FontFile).asStream();
250: if (stream == null) {
251: return null;
252: }
253: return stream.getDecodedBytes();
254: }
255:
256: /**
257: * This is the type 1 fontfile stream It will try to parse the input, which
258: * must be a pfb file. Upon parsing, the keys length1, length2 and length3
259: * will be determined. todo 2 Metadata key not supported
260: */
261: public void setFontFile(byte[] data) {
262: COSStream cosStream = COSStream.create(null);
263: setLengths(cosStream, data);
264: cosStream.setDecodedBytes(data);
265: cosStream.addFilter(Filter.CN_Filter_FlateDecode);
266: cosSetField(DK_FontFile, cosStream);
267: }
268:
269: /**
270: * Simple determination of required length fields.
271: *
272: * @param cosStream
273: * @param data
274: */
275: protected void setLengths(COSStream cosStream, byte[] data) {
276: byte[] pattern;
277: int length1 = 0;
278: int length2 = 0;
279: int length3 = 0;
280:
281: pattern = "currentfile eexec".getBytes();
282: int index1 = ByteArrayTools.indexOf(data, 0, data.length,
283: pattern, 0, pattern.length, 0);
284: if (index1 != -1) {
285: length1 = index1 + pattern.length;
286: }
287: // find 512 zero array
288: pattern = "0000000000000000000000000000000000000000000000000000000000000000"
289: .getBytes();
290: int index2 = ByteArrayTools.indexOf(data, 0, data.length,
291: pattern, 0, pattern.length, 0);
292: if (index2 == -1) {
293: length2 = data.length - length1;
294: } else {
295: length2 = index2 - length1;
296: length3 = data.length - index2;
297: }
298: cosStream.getDict().put(DK_Length1, COSInteger.create(length1));
299: cosStream.getDict().put(DK_Length2, COSInteger.create(length2));
300: cosStream.getDict().put(DK_Length3, COSInteger.create(length3));
301: }
302:
303: public void setFontFile2(byte[] data) {
304: COSStream cosStream = COSStream.create(null);
305: cosStream.getDict().put(DK_Length1,
306: COSInteger.create(data.length));
307: cosStream.addFilter(Filter.CN_Filter_FlateDecode);
308: cosStream.setDecodedBytes(data);
309: cosSetField(DK_FontFile2, cosStream);
310: }
311:
312: public byte[] getFontFile2() {
313: COSStream stream = cosGetField(DK_FontFile2).asStream();
314: if (stream == null) {
315: return null;
316: }
317: return stream.getDecodedBytes();
318: }
319:
320: public void setFontFile3(byte[] data) {
321: // todo 3 not supported
322: COSStream cosStream = COSStream.create(null);
323: cosStream.setDecodedBytes(data);
324: cosSetField(DK_FontFile3, cosStream);
325: }
326:
327: public byte[] getFontFile3() {
328: COSStream stream = cosGetField(DK_FontFile3).asStream();
329: if (stream == null) {
330: return null;
331: }
332: return stream.getDecodedBytes();
333: }
334:
335: public void setFontName(String value) {
336: // todo 3 name encoding
337: cosSetField(DK_FontName, COSName.create(value.getBytes()));
338: }
339:
340: /*
341: * (non-Javadoc)
342: *
343: * @see de.intarsys.pdf.font.PDFontDescriptor#getFontName()
344: */
345: public String getFontName() {
346: COSName fn = cosGetField(DK_FontName).asName();
347: return (fn == null) ? null : fn.stringValue();
348: }
349:
350: public void setItalicAngle(float value) {
351: setFieldFixed(DK_ItalicAngle, value);
352: }
353:
354: /*
355: * (non-Javadoc)
356: *
357: * @see de.intarsys.pdf.font.PDFontDescriptor#getItalicAngle()
358: */
359: public float getItalicAngle() {
360: // TODO 3 wrong default, but this field is required
361: return getFieldFixed(DK_ItalicAngle, 0);
362: }
363:
364: public void setLeading(int value) {
365: setFieldInt(DK_Leading, value);
366: }
367:
368: /*
369: * (non-Javadoc)
370: *
371: * @see de.intarsys.pdf.font.PDFontDescriptor#getLeading()
372: */
373: public int getLeading() {
374: return getFieldInt(DK_Leading, 0);
375: }
376:
377: public void setMaxWidth(int value) {
378: setFieldInt(DK_MaxWidth, value);
379: }
380:
381: /*
382: * (non-Javadoc)
383: *
384: * @see de.intarsys.pdf.font.PDFontDescriptor#getMaxWidth()
385: */
386: public int getMaxWidth() {
387: return getFieldInt(DK_MaxWidth, 0);
388: }
389:
390: public void setMissingWidth(int value) {
391: setFieldInt(DK_MissingWidth, value);
392: }
393:
394: /*
395: * (non-Javadoc)
396: *
397: * @see de.intarsys.pdf.font.PDFontDescriptor#getMissingWidth()
398: */
399: public int getMissingWidth() {
400: return getFieldInt(DK_MissingWidth, 0);
401: }
402:
403: public void setStemH(int value) {
404: setFieldInt(DK_StemH, value);
405: }
406:
407: /*
408: * (non-Javadoc)
409: *
410: * @see de.intarsys.pdf.font.PDFontDescriptor#getStemH()
411: */
412: public int getStemH() {
413: return getFieldInt(DK_StemH, 0);
414: }
415:
416: public void setStemV(int value) {
417: setFieldInt(DK_StemV, value);
418: }
419:
420: /*
421: * (non-Javadoc)
422: *
423: * @see de.intarsys.pdf.font.PDFontDescriptor#getStemV()
424: */
425: public int getStemV() {
426: // TODO 3 wrong default, but this field is required
427: return getFieldInt(DK_StemV, 0);
428: }
429:
430: public void setXHeight(int value) {
431: setFieldInt(DK_XHeight, value);
432: }
433:
434: /*
435: * (non-Javadoc)
436: *
437: * @see de.intarsys.pdf.font.PDFontDescriptor#getXHeight()
438: */
439: public float getXHeight() {
440: return getFieldInt(DK_XHeight, 0);
441: }
442:
443: public void removeFontFile2() {
444: cosGetDict().remove(DK_FontFile2);
445: }
446:
447: protected void initializeFromScratch() {
448: super.initializeFromScratch();
449: }
450: }
|