From 0d18643331171b47c26d7d80abc0cbf67e4ca79a Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Tue, 2 Aug 2005 17:16:20 +0000 Subject: [PATCH] Font support from Yegor, from Bug #35972 git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353759 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/hslf/record/FontCollection.java | 92 ++++++++++++ .../poi/hslf/record/FontEntityAtom.java | 141 ++++++++++++++++++ .../poi/hslf/record/RecordContainer.java | 11 ++ .../apache/poi/hslf/record/RecordTypes.java | 4 +- 4 files changed, 246 insertions(+), 2 deletions(-) create mode 100644 src/scratchpad/src/org/apache/poi/hslf/record/FontCollection.java create mode 100644 src/scratchpad/src/org/apache/poi/hslf/record/FontEntityAtom.java diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/FontCollection.java b/src/scratchpad/src/org/apache/poi/hslf/record/FontCollection.java new file mode 100644 index 0000000000..97866de1f6 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/FontCollection.java @@ -0,0 +1,92 @@ +/* ==================================================================== + Copyright 2002-2004 Apache Software Foundation + + Licensed 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. +==================================================================== */ + + +package org.apache.poi.hslf.record; + +import org.apache.poi.util.LittleEndian; +import java.io.*; +import java.util.*; + +/** + * FontCollection ia a container that holds information + * about all the fonts in the presentation. + * + * @author Yegor Kozlov + */ + +public class FontCollection extends RecordContainer { + private List fonts; + private Record[] _children; + private byte[] _header; + + protected FontCollection(byte[] source, int start, int len) { + // Grab the header + _header = new byte[8]; + System.arraycopy(source,start,_header,0,8); + + _children = Record.findChildRecords(source,start+8,len-8); + // Save font names into List + fonts = new ArrayList(); + for (int i = 0; i < _children.length; i++){ + FontEntityAtom atom = (FontEntityAtom)_children[i]; + fonts.add(atom.getFontName()); + } + + } + + public long getRecordType() { + return RecordTypes.FontCollection.typeID; + } + + public Record[] getChildRecords() { + return _children; + } + + /** + * Write the contents of the record back, so it can be written + * to disk + */ + public void writeOut(OutputStream out) throws IOException { + writeOut(_header[0],_header[1],getRecordType(),_children,out); + } + + /** + * Add font with the specified name to the font collection. + * If the font is already present return its index. + * @param name of the font + * @return zero based index of the font in the collection + */ + public int addFont(String name) { + for (int i = 0; i < fonts.size(); i++) { + if(fonts.get(i).equals(name)){ + //if the font is already present return its index + return i; + } + } + + FontEntityAtom fnt = new FontEntityAtom(); + fnt.setFontIndex(fonts.size() << 4); + fnt.setFontName(name); + fonts.add(name); + + // append new child to the end + _children = appendChildRecord(fnt,_children); + + return fonts.size()-1; //the added font is the last in the list + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/FontEntityAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/FontEntityAtom.java new file mode 100644 index 0000000000..cff1a4e394 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/FontEntityAtom.java @@ -0,0 +1,141 @@ + +/* ==================================================================== + Copyright 2002-2004 Apache Software Foundation + + Licensed 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. +==================================================================== */ + + +package org.apache.poi.hslf.record; + +import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.StringUtil; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +/** + * This atom corresponds exactly to a Windows Logical Font (LOGFONT) structure. + * It keeps all the information needed to define the attributes of a font, + * such as height, width, etc. For more information, consult the + * Windows API Programmer's reference. + * + * @author Yegor Kozlov + */ + +public class FontEntityAtom extends RecordAtom { + /** + * record header + */ + private byte[] _header; + + /** + * record data + */ + private byte[] _recdata; + + /** + * Build an instance of FontEntityAtom from on-disk data + */ + protected FontEntityAtom(byte[] source, int start, int len) { + // Get the header + _header = new byte[8]; + System.arraycopy(source,start,_header,0,8); + + // Grab the record data + _recdata = new byte[len-8]; + System.arraycopy(source,start+8,_recdata,0,len-8); + } + + /** + * Create a new instance of FontEntityAtom + */ + protected FontEntityAtom() { + _recdata = new byte[68]; + + _header = new byte[8]; + LittleEndian.putShort(_header, 2, (short)getRecordType()); + LittleEndian.putInt(_header, 4, _recdata.length); + } + + public long getRecordType() { + return RecordTypes.FontEntityAtom.typeID; + } + + /** + * A null-terminated string that specifies the typeface name of the font. + * The length of this string must not exceed 32 characters + * including the null terminator. + * @return font name + */ + public String getFontName(){ + String name = null; + try { + int i = 0; + while(i < 64){ + //loop until find null-terminated end of the font name + if(_recdata[i] == 0 && _recdata[i + 1] == 0) { + name = new String(_recdata, 0, i, "UTF-16LE"); + break; + } + i += 2; + } + } catch (UnsupportedEncodingException e){ + throw new RuntimeException(e.getMessage(), e); + } + return name; + } + + /** + * Set the name of the font. + * The length of this string must not exceed 32 characters + * including the null terminator. + * Will be converted to null-terminated if not already + * @param name of the font + */ + public void setFontName(String name){ + // Add a null termination if required + if(! name.endsWith("\000")) { + name = name + "\000"; + } + + // Ensure it's not now too long + if(name.length() > 32) { + throw new RuntimeException("The length of the font name, including null termination, must not exceed 32 characters"); + } + + // Everything's happy, so save the name + try { + byte[] bytes = name.getBytes("UTF-16LE"); + System.arraycopy(bytes, 0, _recdata, 0, bytes.length); + } catch (UnsupportedEncodingException e){ + throw new RuntimeException(e.getMessage(), e); + } + } + + protected void setFontIndex(int idx){ + LittleEndian.putShort(_header, 0, (short)idx); + } + + protected int getFontIndex(){ + return LittleEndian.getShort(_header, 0); + } + + /** + * Write the contents of the record back, so it can be written to disk + */ + public void writeOut(OutputStream out) throws IOException { + out.write(_header); + out.write(_recdata); + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java b/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java index 6ecb770c0b..275e87441e 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/RecordContainer.java @@ -39,6 +39,17 @@ public abstract class RecordContainer extends Record */ public boolean isAnAtom() { return false; } + /** + * Add a new child record onto a record's list of children, and + * return the new list. + */ + public Record[] appendChildRecord(Record newChild, Record[] children) { + Record[] r = new Record[children.length + 1]; + System.arraycopy(children,0,r,0,children.length); + r[r.length-1] = newChild; + return r; + } + /** * Write out our header, and our children. * @param headerA the first byte of the header diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java b/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java index 45ffa0f23e..21846068be 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java @@ -67,7 +67,7 @@ public class RecordTypes { public static final Type NamedShowSlides = new Type(1042,null); public static final Type SheetProperties = new Type(1044,null); public static final Type List = new Type(2000,null); - public static final Type FontCollection = new Type(2005,null); + public static final Type FontCollection = new Type(2005,FontCollection.class); public static final Type BookmarkCollection = new Type(2019,null); public static final Type SoundCollAtom = new Type(2021,null); public static final Type Sound = new Type(2022,null); @@ -93,7 +93,7 @@ public class RecordTypes { public static final Type TxSIStyleAtom = new Type(4009,null); public static final Type TextSpecInfoAtom = new Type(4010,null); public static final Type DefaultRulerAtom = new Type(4011,null); - public static final Type FontEntityAtom = new Type(4023,null); + public static final Type FontEntityAtom = new Type(4023,FontEntityAtom.class); public static final Type FontEmbeddedData = new Type(4024,null); public static final Type CString = new Type(4026,null); public static final Type MetaFile = new Type(4033,null); -- 2.39.5