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:
parent
149e87cda0
commit
0d790c922c
243
src/scratchpad/src/org/apache/poi/hslf/model/PPFont.java
Executable file
243
src/scratchpad/src/org/apache/poi/hslf/model/PPFont.java
Executable 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);
|
||||||
|
}
|
||||||
|
}
|
@ -75,16 +75,20 @@ public class FontCollection extends RecordContainer {
|
|||||||
* @return zero based index of the font in the collection
|
* @return zero based index of the font in the collection
|
||||||
*/
|
*/
|
||||||
public int addFont(String name) {
|
public int addFont(String name) {
|
||||||
for (int i = 0; i < fonts.size(); i++) {
|
int idx = getFontIndex(name);
|
||||||
if(fonts.get(i).equals(name)){
|
if(idx != -1) return idx;
|
||||||
//if the font is already present return its index
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return addFont(name, 0, 0, 4, 34);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int addFont(String name, int charset, int flags, int type, int pitch) {
|
||||||
FontEntityAtom fnt = new FontEntityAtom();
|
FontEntityAtom fnt = new FontEntityAtom();
|
||||||
fnt.setFontIndex(fonts.size() << 4);
|
fnt.setFontIndex(fonts.size() << 4);
|
||||||
fnt.setFontName(name);
|
fnt.setFontName(name);
|
||||||
|
fnt.setCharSet(charset);
|
||||||
|
fnt.setFontFlags(flags);
|
||||||
|
fnt.setFontType(type);
|
||||||
|
fnt.setPitchAndFamily(pitch);
|
||||||
fonts.add(name);
|
fonts.add(name);
|
||||||
|
|
||||||
// Append new child to the end
|
// Append new child to the end
|
||||||
@ -93,7 +97,24 @@ public class FontCollection extends RecordContainer {
|
|||||||
return fonts.size()-1; //the added font is the last in the list
|
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
|
* Get the name of the font at the given ID, or null if there is
|
||||||
* no font at that ID.
|
* no font at that ID.
|
||||||
* @param id
|
* @param id
|
||||||
|
@ -61,7 +61,7 @@ public class FontEntityAtom extends RecordAtom {
|
|||||||
/**
|
/**
|
||||||
* Create a new instance of <code>FontEntityAtom</code>
|
* Create a new instance of <code>FontEntityAtom</code>
|
||||||
*/
|
*/
|
||||||
protected FontEntityAtom() {
|
public FontEntityAtom() {
|
||||||
_recdata = new byte[68];
|
_recdata = new byte[68];
|
||||||
|
|
||||||
_header = new byte[8];
|
_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);
|
LittleEndian.putShort(_header, 0, (short)idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getFontIndex(){
|
public int getFontIndex(){
|
||||||
return LittleEndian.getShort(_header, 0);
|
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
|
* Write the contents of the record back, so it can be written to disk
|
||||||
*/
|
*/
|
||||||
public void writeOut(OutputStream out) throws IOException {
|
public void writeOut(OutputStream out) throws IOException {
|
||||||
|
@ -757,4 +757,50 @@ public class SlideShow
|
|||||||
}
|
}
|
||||||
return addPicture(data, format);
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
56
src/scratchpad/testcases/org/apache/poi/hslf/model/TestPPFont.java
Executable file
56
src/scratchpad/testcases/org/apache/poi/hslf/model/TestPPFont.java
Executable 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());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user