start improving handling of resources in HSLF. PPFont object represents a font in a presenatation.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@648203 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2008-04-15 10:05:22 +00:00
parent 149e87cda0
commit 0d790c922c
6 changed files with 464 additions and 13 deletions

View File

@ -0,0 +1,243 @@
/* ====================================================================
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.
==================================================================== */
package org.apache.poi.hslf.model;
import org.apache.poi.hslf.record.FontEntityAtom;
/**
* Represents a Font used in a presenation.
* <p>
* In PowerPoint Font is a shared resource and can be shared among text object in the presentation.
* </p>
* Some commonly used fonts are predefined in static constants.
*
* @author Yegor Kozlov
*/
public class PPFont {
/**
* ANSI character set
*/
public final static byte ANSI_CHARSET = 0;
/**
* Default character set.
*/
public final static byte DEFAULT_CHARSET = 1;
/**
* Symbol character set
*/
public final static byte SYMBOL_CHARSET = 2;
/**
* Constants for the pitch and family of the font.
* The two low-order bits specify the pitch of the font and can be one of the following values
*/
public final static byte DEFAULT_PITCH = 0;
public final static byte FIXED_PITCH = 1;
public final static byte VARIABLE_PITCH = 2;
/**
* Don't care or don't know.
*/
public final static byte FF_DONTCARE = 0;
/**
* Fonts with variable stroke width (proportional) and with serifs. Times New Roman is an example.
*/
public final static byte FF_ROMAN = 16;
/**
* Fonts with variable stroke width (proportional) and without serifs. Arial is an example.
*/
public final static byte FF_SWISS = 32;
/**
* Fonts designed to look like handwriting. Script and Cursive are examples.
*/
public final static byte FF_SCRIPT = 64;
/**
* Fonts with constant stroke width (monospace), with or without serifs.
* Monospace fonts are usually modern. CourierNew is an example
*/
public final static byte FF_MODERN = 48;
/**
* Novelty fonts. Old English is an example
*/
public final static byte FF_DECORATIVE = 80;
protected int charset;
protected int type;
protected int flags;
protected int pitch;
protected String name;
/**
* Creates a new instance of PPFont
*/
public PPFont(){
}
/**
* Creates a new instance of PPFont and initialize it from the supplied font atom
*/
public PPFont(FontEntityAtom fontAtom){
name = fontAtom.getFontName();
charset = fontAtom.getCharSet();
type = fontAtom.getFontType();
flags = fontAtom.getFontFlags();
pitch = fontAtom.getPitchAndFamily();
}
/**
* set the name for the font (i.e. Arial)
*
* @param val String representing the name of the font to use
*/
public void setFontName(String val){
name = val;
}
/**
* get the name for the font (i.e. Arial)
*
* @return String representing the name of the font to use
*/
public String getFontName(){
return name;
}
/**
* set the character set
*
* @param val - characterset
*/
public void setCharSet(int val){
charset = val;
}
/**
* get the character set
*
* @return charset - characterset
*/
public int getCharSet(){
return charset;
}
/**
* set the font flags
* Bit 1: If set, font is subsetted
*
* @param val - the font flags
*/
public void setFontFlags(int val){
flags = val;
}
/**
* get the character set
* Bit 1: If set, font is subsetted
*
* @return the font flags
*/
public int getFontFlags(){
return flags;
}
/**
* set the font type
* <p>
* Bit 1: Raster Font
* Bit 2: Device Font
* Bit 3: TrueType Font
* </p>
*
* @param val - the font type
*/
public void setFontType(int val){
type = val;
}
/**
* get the font type
* <p>
* Bit 1: Raster Font
* Bit 2: Device Font
* Bit 3: TrueType Font
* </p>
*
* @return the font type
*/
public int getFontType(){
return type;
}
/**
* set lfPitchAndFamily
*
*
* @param val - Corresponds to the lfPitchAndFamily field of the Win32 API LOGFONT structure
*/
public void setPitchAndFamily(int val){
pitch = val;
}
/**
* get lfPitchAndFamily
*
* @return corresponds to the lfPitchAndFamily field of the Win32 API LOGFONT structure
*/
public int getPitchAndFamily(){
return pitch;
}
public static final PPFont ARIAL;
public static final PPFont TIMES_NEW_ROMAN ;
public static final PPFont COURIER_NEW;
public static final PPFont WINGDINGS;
static {
ARIAL = new PPFont();
ARIAL.setFontName("Arial");
ARIAL.setCharSet(ANSI_CHARSET);
ARIAL.setFontType(4);
ARIAL.setFontFlags(0);
ARIAL.setPitchAndFamily(VARIABLE_PITCH | FF_SWISS);
TIMES_NEW_ROMAN = new PPFont();
TIMES_NEW_ROMAN.setFontName("Times New Roman");
TIMES_NEW_ROMAN.setCharSet(ANSI_CHARSET);
TIMES_NEW_ROMAN.setFontType(4);
TIMES_NEW_ROMAN.setFontFlags(0);
TIMES_NEW_ROMAN.setPitchAndFamily(VARIABLE_PITCH | FF_ROMAN);
COURIER_NEW = new PPFont();
COURIER_NEW.setFontName("Courier New");
COURIER_NEW.setCharSet(ANSI_CHARSET);
COURIER_NEW.setFontType(4);
COURIER_NEW.setFontFlags(0);
COURIER_NEW.setPitchAndFamily(FIXED_PITCH | FF_MODERN);
WINGDINGS = new PPFont();
WINGDINGS.setFontName("Wingdings");
WINGDINGS.setCharSet(SYMBOL_CHARSET);
WINGDINGS.setFontType(4);
WINGDINGS.setFontFlags(0);
WINGDINGS.setPitchAndFamily(VARIABLE_PITCH | FF_DONTCARE);
}
}

View File

@ -75,16 +75,20 @@ public class FontCollection extends RecordContainer {
* @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;
}
}
int idx = getFontIndex(name);
if(idx != -1) return idx;
return addFont(name, 0, 0, 4, 34);
}
public int addFont(String name, int charset, int flags, int type, int pitch) {
FontEntityAtom fnt = new FontEntityAtom();
fnt.setFontIndex(fonts.size() << 4);
fnt.setFontName(name);
fnt.setCharSet(charset);
fnt.setFontFlags(flags);
fnt.setFontType(type);
fnt.setPitchAndFamily(pitch);
fonts.add(name);
// Append new child to the end
@ -92,8 +96,25 @@ public class FontCollection extends RecordContainer {
return fonts.size()-1; //the added font is the last in the list
}
/**
/**
* @return zero based index of the font in the collection or -1 if not found
*/
public int getFontIndex(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;
}
}
return -1;
}
public int getNumberOfFonts() {
return fonts.size();
}
/**
* Get the name of the font at the given ID, or null if there is
* no font at that ID.
* @param id

View File

@ -61,7 +61,7 @@ public class FontEntityAtom extends RecordAtom {
/**
* Create a new instance of <code>FontEntityAtom</code>
*/
protected FontEntityAtom() {
public FontEntityAtom() {
_recdata = new byte[68];
_header = new byte[8];
@ -124,15 +124,100 @@ public class FontEntityAtom extends RecordAtom {
}
}
protected void setFontIndex(int idx){
public void setFontIndex(int idx){
LittleEndian.putShort(_header, 0, (short)idx);
}
protected int getFontIndex(){
return LittleEndian.getShort(_header, 0);
public int getFontIndex(){
return LittleEndian.getShort(_header, 0) >> 4;
}
/**
/**
* set the character set
*
* @param charset - characterset
*/
public void setCharSet(int charset){
_recdata[64] = (byte)charset;
}
/**
* get the character set
*
* @return charset - characterset
*/
public int getCharSet(){
return _recdata[64];
}
/**
* set the font flags
* Bit 1: If set, font is subsetted
*
* @param flags - the font flags
*/
public void setFontFlags(int flags){
_recdata[65] = (byte)flags;
}
/**
* get the character set
* Bit 1: If set, font is subsetted
*
* @return the font flags
*/
public int getFontFlags(){
return _recdata[65];
}
/**
* set the font type
* <p>
* Bit 1: Raster Font
* Bit 2: Device Font
* Bit 3: TrueType Font
* </p>
*
* @param type - the font type
*/
public void setFontType(int type){
_recdata[66] = (byte)type;
}
/**
* get the font type
* <p>
* Bit 1: Raster Font
* Bit 2: Device Font
* Bit 3: TrueType Font
* </p>
*
* @return the font type
*/
public int getFontType(){
return _recdata[66];
}
/**
* set lfPitchAndFamily
*
*
* @param val - Corresponds to the lfPitchAndFamily field of the Win32 API LOGFONT structure
*/
public void setPitchAndFamily(int val){
_recdata[67] = (byte)val;
}
/**
* get lfPitchAndFamily
*
* @return corresponds to the lfPitchAndFamily field of the Win32 API LOGFONT structure
*/
public int getPitchAndFamily(){
return _recdata[67];
}
/**
* Write the contents of the record back, so it can be written to disk
*/
public void writeOut(OutputStream out) throws IOException {

View File

@ -757,4 +757,50 @@ public class SlideShow
}
return addPicture(data, format);
}
/**
* Add a font in this presentation
*
* @param font the font to add
* @return 0-based index of the font
*/
public int addFont(PPFont font) {
FontCollection fonts = getDocumentRecord().getEnvironment().getFontCollection();
int idx = fonts.getFontIndex(font.getFontName());
if(idx == -1){
idx = fonts.addFont(font.getFontName(), font.getCharSet(), font.getFontFlags(), font.getFontType(), font.getPitchAndFamily());
}
return idx;
}
/**
* Get a font by index
*
* @param idx 0-based index of the font
* @return of an instance of <code>PPFont</code> or <code>null</code> if not found
*/
public PPFont getFont(int idx) {
PPFont font = null;
FontCollection fonts = getDocumentRecord().getEnvironment().getFontCollection();
Record[] ch = fonts.getChildRecords();
for (int i = 0; i < ch.length; i++) {
if(ch[i] instanceof FontEntityAtom) {
FontEntityAtom atom = (FontEntityAtom)ch[i];
if(atom.getFontIndex() == idx){
font = new PPFont(atom);
break;
}
}
}
return font;
}
/**
* get the number of fonts in the presentation
*
* @return number of fonts
*/
public int getNumberOfFonts() {
return getDocumentRecord().getEnvironment().getFontCollection().getNumberOfFonts();
}
}

View File

@ -0,0 +1,56 @@
/* ====================================================================
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.
==================================================================== */
package org.apache.poi.hslf.model;
import junit.framework.TestCase;
import org.apache.poi.hslf.usermodel.SlideShow;
import java.io.IOException;
/**
* Test adding fonts to the presenataion resources
*
* @author Yegor Kozlov
*/
public class TestPPFont extends TestCase{
public void testCreate() throws IOException {
SlideShow ppt = new SlideShow();
assertEquals(1, ppt.getNumberOfFonts());
assertEquals("Arial", ppt.getFont(0).getFontName());
//adding the same font twice
assertEquals(0, ppt.addFont(PPFont.ARIAL));
assertEquals(1, ppt.getNumberOfFonts());
assertEquals(1, ppt.addFont(PPFont.TIMES_NEW_ROMAN));
assertEquals(2, ppt.addFont(PPFont.COURIER_NEW));
assertEquals(3, ppt.addFont(PPFont.WINGDINGS));
assertEquals(4, ppt.getNumberOfFonts());
assertEquals(PPFont.TIMES_NEW_ROMAN.getFontName(), ppt.getFont(1).getFontName());
assertEquals(PPFont.COURIER_NEW.getFontName(), ppt.getFont(2).getFontName());
PPFont font3 = ppt.getFont(3);
assertEquals(PPFont.WINGDINGS.getFontName(), font3.getFontName());
assertEquals(PPFont.SYMBOL_CHARSET, font3.getCharSet());
assertEquals(PPFont.VARIABLE_PITCH, font3.getPitchAndFamily());
}
}