소스 검색

#61169 - Text with Japanese characters overflows textbox

- add resize methods with Graphics argument

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1801329 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_3_17_FINAL
Andreas Beeker 6 년 전
부모
커밋
c82aa1a4bb

+ 1
- 1
src/java/org/apache/poi/sl/draw/DrawTextShape.java 파일 보기

* @param oldGraphics the graphics context, which properties are to be copied, may be null * @param oldGraphics the graphics context, which properties are to be copied, may be null
* @return the height in points * @return the height in points
*/ */
protected double getTextHeight(Graphics2D oldGraphics) {
public double getTextHeight(Graphics2D oldGraphics) {
// dry-run in a 1x1 image and return the vertical advance // dry-run in a 1x1 image and return the vertical advance
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics(); Graphics2D graphics = img.createGraphics();

+ 36
- 0
src/java/org/apache/poi/sl/usermodel/TextShape.java 파일 보기



package org.apache.poi.sl.usermodel; package org.apache.poi.sl.usermodel;


import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.util.List; import java.util.List;


public interface TextShape< public interface TextShape<


/** /**
* Compute the cumulative height occupied by the text * Compute the cumulative height occupied by the text
*
* @return the cumulative height occupied by the text
*/ */
double getTextHeight(); double getTextHeight();

/**
* Compute the cumulative height occupied by the text
*
* @param graphics a customized graphics context, e.g. which contains font mappings
*
* @return the cumulative height occupied by the text
*
* @since POI 3.17-beta2
*/
double getTextHeight(Graphics2D graphics);
/** /**
* Returns the type of vertical alignment for the text. * Returns the type of vertical alignment for the text.
* @return the text placeholder * @return the text placeholder
*/ */
TextPlaceholder getTextPlaceholder(); TextPlaceholder getTextPlaceholder();
/**
* Adjust the size of the shape so it encompasses the text inside it.
*
* @return a {@code Rectangle2D} that is the bounds of this shape.
*
* @since POI 3.17-beta2
*/
Rectangle2D resizeToFitText();

/**
* Adjust the size of the shape so it encompasses the text inside it.
*
* @param graphics a customized graphics context, e.g. which contains font mappings
*
* @return a {@code Rectangle2D} that is the bounds of this shape.
*
* @since POI 3.17-beta2
*/
Rectangle2D resizeToFitText(Graphics2D graphics);

} }

+ 52
- 12
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java 파일 보기

return _p; return _p;
} }


@Override
public String getRawText(){ public String getRawText(){
if (_r instanceof CTTextField) { if (_r instanceof CTTextField) {
return ((CTTextField)_r).getT(); return ((CTTextField)_r).getT();
return buf.toString(); return buf.toString();
} }


@Override
public void setText(String text){ public void setText(String text){
if (_r instanceof CTTextField) { if (_r instanceof CTTextField) {
((CTTextField)_r).setT(text); ((CTTextField)_r).setT(text);
public PaintStyle getFontColor(){ public PaintStyle getFontColor(){
final boolean hasPlaceholder = getParentParagraph().getParentShape().getPlaceholder() != null; final boolean hasPlaceholder = getParentParagraph().getParentShape().getPlaceholder() != null;
CharacterPropertyFetcher<PaintStyle> fetcher = new CharacterPropertyFetcher<PaintStyle>(_p.getIndentLevel()){ CharacterPropertyFetcher<PaintStyle> fetcher = new CharacterPropertyFetcher<PaintStyle>(_p.getIndentLevel()){
@Override
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
if (props == null) { if (props == null) {
return false; return false;
public void setFontSize(Double fontSize){ public void setFontSize(Double fontSize){
CTTextCharacterProperties rPr = getRPr(true); CTTextCharacterProperties rPr = getRPr(true);
if(fontSize == null) { if(fontSize == null) {
if (rPr.isSetSz()) rPr.unsetSz();
if (rPr.isSetSz()) {
rPr.unsetSz();
}
} else { } else {
if (fontSize < 1.0) { if (fontSize < 1.0) {
throw new IllegalArgumentException("Minimum font size is 1pt but was " + fontSize); throw new IllegalArgumentException("Minimum font size is 1pt but was " + fontSize);
public Double getFontSize(){ public Double getFontSize(){
double scale = 1; double scale = 1;
CTTextNormalAutofit afit = getParentParagraph().getParentShape().getTextBodyPr().getNormAutofit(); CTTextNormalAutofit afit = getParentParagraph().getParentShape().getTextBodyPr().getNormAutofit();
if(afit != null) scale = (double)afit.getFontScale() / 100000;
if(afit != null) {
scale = (double)afit.getFontScale() / 100000;
}


CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getIndentLevel()){ CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getIndentLevel()){
@Override
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
if (props != null && props.isSetSz()) { if (props != null && props.isSetSz()) {
setValue(props.getSz()*0.01); setValue(props.getSz()*0.01);
public double getCharacterSpacing(){ public double getCharacterSpacing(){


CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getIndentLevel()){ CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getIndentLevel()){
@Override
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
if (props != null && props.isSetSpc()) { if (props != null && props.isSetSpc()) {
setValue(props.getSpc()*0.01); setValue(props.getSpc()*0.01);
public void setCharacterSpacing(double spc){ public void setCharacterSpacing(double spc){
CTTextCharacterProperties rPr = getRPr(true); CTTextCharacterProperties rPr = getRPr(true);
if(spc == 0.0) { if(spc == 0.0) {
if(rPr.isSetSpc()) rPr.unsetSpc();
if(rPr.isSetSpc()) {
rPr.unsetSpc();
}
} else { } else {
rPr.setSpc((int)(100*spc)); rPr.setSpc((int)(100*spc));
} }
CTTextCharacterProperties rPr = getRPr(true); CTTextCharacterProperties rPr = getRPr(true);


if(typeface == null){ if(typeface == null){
if(rPr.isSetLatin()) rPr.unsetLatin();
if(rPr.isSetCs()) rPr.unsetCs();
if(rPr.isSetSym()) rPr.unsetSym();
if(rPr.isSetLatin()) {
rPr.unsetLatin();
}
if(rPr.isSetCs()) {
rPr.unsetCs();
}
if(rPr.isSetSym()) {
rPr.unsetSym();
}
} else { } else {
if(isSymbol){ if(isSymbol){
CTTextFont font = rPr.isSetSym() ? rPr.getSym() : rPr.addNewSym(); CTTextFont font = rPr.isSetSym() ? rPr.getSym() : rPr.addNewSym();
} else { } else {
CTTextFont latin = rPr.isSetLatin() ? rPr.getLatin() : rPr.addNewLatin(); CTTextFont latin = rPr.isSetLatin() ? rPr.getLatin() : rPr.addNewLatin();
latin.setTypeface(typeface); latin.setTypeface(typeface);
if(charset != -1) latin.setCharset(charset);
if(pictAndFamily != -1) latin.setPitchFamily(pictAndFamily);
if(charset != -1) {
latin.setCharset(charset);
}
if(pictAndFamily != -1) {
latin.setPitchFamily(pictAndFamily);
}
} }
} }
} }
final XSLFTheme theme = _p.getParentShape().getSheet().getTheme(); final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();


CharacterPropertyFetcher<String> visitor = new CharacterPropertyFetcher<String>(_p.getIndentLevel()){ CharacterPropertyFetcher<String> visitor = new CharacterPropertyFetcher<String>(_p.getIndentLevel()){
@Override
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
if (props != null) { if (props != null) {
CTTextFont font = props.getLatin(); CTTextFont font = props.getLatin();
return visitor.getValue(); return visitor.getValue();
} }


@Override
public byte getPitchAndFamily(){ public byte getPitchAndFamily(){
// final XSLFTheme theme = _p.getParentShape().getSheet().getTheme(); // final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();


CharacterPropertyFetcher<Byte> visitor = new CharacterPropertyFetcher<Byte>(_p.getIndentLevel()){ CharacterPropertyFetcher<Byte> visitor = new CharacterPropertyFetcher<Byte>(_p.getIndentLevel()){
@Override
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
if (props != null) { if (props != null) {
CTTextFont font = props.getLatin(); CTTextFont font = props.getLatin();
@Override @Override
public boolean isStrikethrough() { public boolean isStrikethrough() {
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){ CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
@Override
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
if(props != null && props.isSetStrike()) { if(props != null && props.isSetStrike()) {
setValue(props.getStrike() != STTextStrikeType.NO_STRIKE); setValue(props.getStrike() != STTextStrikeType.NO_STRIKE);
@Override @Override
public boolean isSuperscript() { public boolean isSuperscript() {
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){ CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
@Override
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
if (props != null && props.isSetBaseline()) { if (props != null && props.isSetBaseline()) {
setValue(props.getBaseline() > 0); setValue(props.getBaseline() > 0);
@Override @Override
public boolean isSubscript() { public boolean isSubscript() {
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){ CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
@Override
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
if (props != null && props.isSetBaseline()) { if (props != null && props.isSetBaseline()) {
setValue(props.getBaseline() < 0); setValue(props.getBaseline() < 0);
/** /**
* @return whether a run of text will be formatted as a superscript text. Default is false. * @return whether a run of text will be formatted as a superscript text. Default is false.
*/ */
@Override
public TextCap getTextCap() { public TextCap getTextCap() {
CharacterPropertyFetcher<TextCap> fetcher = new CharacterPropertyFetcher<TextCap>(_p.getIndentLevel()){ CharacterPropertyFetcher<TextCap> fetcher = new CharacterPropertyFetcher<TextCap>(_p.getIndentLevel()){
@Override
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
if (props != null && props.isSetCap()) { if (props != null && props.isSetCap()) {
int idx = props.getCap().intValue() - 1; int idx = props.getCap().intValue() - 1;
@Override @Override
public boolean isBold(){ public boolean isBold(){
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){ CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
@Override
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
if (props != null && props.isSetB()) { if (props != null && props.isSetB()) {
setValue(props.getB()); setValue(props.getB());
@Override @Override
public boolean isItalic(){ public boolean isItalic(){
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){ CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
@Override
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
if (props != null && props.isSetI()) { if (props != null && props.isSetI()) {
setValue(props.getI()); setValue(props.getI());
@Override @Override
public boolean isUnderlined(){ public boolean isUnderlined(){
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){ CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
@Override
public boolean fetch(CTTextCharacterProperties props){ public boolean fetch(CTTextCharacterProperties props){
if (props != null && props.isSetU()) { if (props != null && props.isSetU()) {
setValue(props.getU() != STTextUnderlineType.NONE); setValue(props.getU() != STTextUnderlineType.NONE);
} }


boolean bold = r.isBold(); boolean bold = r.isBold();
if(bold != isBold()) setBold(bold);
if(bold != isBold()) {
setBold(bold);
}


boolean italic = r.isItalic(); boolean italic = r.isItalic();
if(italic != isItalic()) setItalic(italic);
if(italic != isItalic()) {
setItalic(italic);
}


boolean underline = r.isUnderlined(); boolean underline = r.isUnderlined();
if(underline != isUnderlined()) setUnderlined(underline);
if(underline != isUnderlined()) {
setUnderlined(underline);
}


boolean strike = r.isStrikethrough(); boolean strike = r.isStrikethrough();
if(strike != isStrikethrough()) setStrikethrough(strike);
if(strike != isStrikethrough()) {
setStrikethrough(strike);
}
} }

+ 15
- 8
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java 파일 보기



package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;


import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;


@Override @Override
public double getTextHeight(){ public double getTextHeight(){
DrawFactory drawFact = DrawFactory.getInstance(null);
return getTextHeight(null);
}
@Override
public double getTextHeight(Graphics2D graphics){
DrawFactory drawFact = DrawFactory.getInstance(graphics);
DrawTextShape dts = drawFact.getDrawable(this); DrawTextShape dts = drawFact.getDrawable(this);
return dts.getTextHeight();
return dts.getTextHeight(graphics);
} }


/**
* Adjust the size of the shape so it encompasses the text inside it.
*
* @return a <code>Rectangle2D</code> that is the bounds of this shape.
*/
@Override
public Rectangle2D resizeToFitText(){ public Rectangle2D resizeToFitText(){
return resizeToFitText(null);
}
@Override
public Rectangle2D resizeToFitText(Graphics2D graphics) {
Rectangle2D anchor = getAnchor(); Rectangle2D anchor = getAnchor();


if(anchor.getWidth() == 0.) { if(anchor.getWidth() == 0.) {
throw new POIXMLException("Anchor of the shape was not set."); throw new POIXMLException("Anchor of the shape was not set.");
} }
double height = getTextHeight();
double height = getTextHeight(graphics);
height += 1; // add a pixel to compensate rounding errors height += 1; // add a pixel to compensate rounding errors


Insets2D insets = getInsets(); Insets2D insets = getInsets();

+ 59
- 0
src/ooxml/testcases/org/apache/poi/sl/SLCommonUtils.java 파일 보기

/*
* ====================================================================
* 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.sl;

import java.io.IOException;
import java.io.InputStream;

import org.apache.poi.POIDataSamples;
import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.SlideShowFactory;

public class SLCommonUtils {
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
/** a generic way to open a sample slideshow document **/
public static SlideShow<?,?> openSampleSlideshow(String sampleName) throws IOException {
InputStream is = _slTests.openResourceAsStream(sampleName);
try {
return SlideShowFactory.create(is);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
is.close();
}
}

/**
* Tests, if the scratchpad classes are on the classpath
*
* @return true, if only xslf is on the classpath, and false, if both classpaths
* (XSLF and HSLF) can be used/referenced
*/
public static boolean xslfOnly() {
try {
Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow");
return false;
} catch (Exception e) {
return true;
}
}

}

+ 158
- 0
src/ooxml/testcases/org/apache/poi/sl/TestFonts.java 파일 보기

/* ====================================================================
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.sl;

import static org.apache.poi.sl.SLCommonUtils.xslfOnly;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeFalse;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.poi.POIDataSamples;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.Drawable;
import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.sl.usermodel.TextBox;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextRun;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFTextRun;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;


/**
* Test rendering - specific to font handling
*/
public class TestFonts {
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();

private static final String JPTEXT =
"\u3061\u3087\u3063\u3068\u65E9\u3044\u3051\u3069T\u30B7\u30E3\u30C4\u304C\u7740\u305F\u304F\u306A" +
"\u308B\u5B63\u7BC0\u2661\u304A\u6BCD\u3055\u3093\u306E\u5F71\u97FF\u304B\u3001\u975E\u5E38\u306B" +
"\u6050\u7ADC\u304C\u5927\u597D\u304D\u3067\u3059\u3002\u3082\u3046\u98FC\u3044\u305F\u3044\u304F" +
"\u3089\u3044\u5927\u597D\u304D\u3067\u3059\u3002#\u30B8\u30E5\u30E9\u30B7\u30C3\u30AF\u30EF\u30FC" +
"\u30EB\u30C9 \u306E\u30E9\u30D7\u30C8\u30EB4\u59C9\u59B9\u3068\u304B\u6FC0\u7684\u306B\u53EF\u611B" +
"\u304F\u3066\u53EF\u611B\u304F\u3066\u53EF\u611B\u304F\u3066\u53EF\u611B\u3044\u3067\u3059\u3002" +
"\u3081\u308D\u3081\u308D\u3001\u5927\u597D\u304D\u2661\u304A\u6BCD\u3055\u3093\u3082\u6050\u7ADC" +
"\u304C\u597D\u304D\u3067\u3001\u5C0F\u3055\u3044\u9803\u3001\u53E4\u4EE3\u751F\u7269\u306E\u56F3" +
"\u9451\u3092\u4E00\u7DD2\u306B\u898B\u3066\u305F\u306E\u601D\u3044\u51FA\u3059\u301C\u3068\u3044";

private static final String INIT_FONTS[] = { "mona.ttf" };
@BeforeClass
public static void initGE() throws FontFormatException, IOException {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
for (String s : INIT_FONTS) {
Font font = Font.createFont(Font.TRUETYPE_FONT, _slTests.getFile(s));
ge.registerFont(font);
}
}
@Test
public void resizeToFitTextHSLF() throws IOException {
assumeFalse(xslfOnly());
SlideShow<?,?> ppt = new HSLFSlideShow();
TextBox<?,?> tb = resizeToFitText(ppt);
Rectangle2D anc = tb.getAnchor();
// ignore font metrics differences on windows / linux (... hopefully ...)
assertEquals(anc.getHeight(), 312d, 5);
// setFont(tb, "Mona");
// FileOutputStream fos = new FileOutputStream("bla-hslf.ppt");
// ppt.write(fos);
// fos.close();
ppt.close();
}

@Test
public void resizeToFitTextXSLF() throws IOException {
SlideShow<?,?> ppt = new XMLSlideShow();
TextBox<?,?> tb = resizeToFitText(ppt);
Rectangle2D anc = tb.getAnchor();
// ignore font metrics differences on windows / linux (... hopefully ...)
assertEquals(anc.getHeight(), 312d, 5);
// setFont(tb, "Mona");
// FileOutputStream fos = new FileOutputStream("bla-xslf.ppt");
// ppt.write(fos);
// fos.close();
ppt.close();
}

private TextBox<?,?> resizeToFitText(SlideShow<?,?> slideshow) throws IOException {
Slide<?,?> sld = slideshow.createSlide();
TextBox<?,?> tb = sld.createTextBox();
tb.setAnchor(new Rectangle(50, 50, 200, 50));
tb.setStrokeStyle(Color.black, LineDash.SOLID, 3);
tb.setText(JPTEXT);
setFont(tb, "NoSuchFont");

Dimension pgsize = slideshow.getPageSize();
int width = (int)pgsize.getWidth();
int height = (int)pgsize.getHeight();
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = img.createGraphics();

Map<String,String> fallbackMap = new HashMap<String,String>();
fallbackMap.put("NoSuchFont", "Mona");
graphics.setRenderingHint(Drawable.FONT_FALLBACK, fallbackMap);
graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
DrawFactory.getInstance(graphics).fixFonts(graphics);
tb.resizeToFitText(graphics);
graphics.dispose();
return tb;
}
private void setFont(TextBox<?,?> tb, String fontFamily) {
// TODO: set east asian font family - MS Office uses "MS Mincho" or "MS Gothic" as a fallback
// see https://stackoverflow.com/questions/26063828 for good explanation about the font metrics
// differences on different environments
for (TextParagraph<?,?,? extends TextRun> p : tb.getTextParagraphs()) {
for (TextRun r : p.getTextRuns()) {
r.setFontFamily(fontFamily);
if (r instanceof XSLFTextRun) {
// TODO: provide API for HSLF
XSLFTextRun xr = (XSLFTextRun)r;
CTRegularTextRun tr = (CTRegularTextRun)xr.getXmlObject();
tr.getRPr().addNewEa().setTypeface(fontFamily);
}
}
}
}
}

+ 4
- 16
src/ooxml/testcases/org/apache/poi/sl/TestHeadersFooters.java 파일 보기



package org.apache.poi.sl; package org.apache.poi.sl;


import static org.apache.poi.sl.TestTable.openSampleSlideshow;
import static org.apache.poi.sl.SLCommonUtils.openSampleSlideshow;
import static org.apache.poi.sl.SLCommonUtils.xslfOnly;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import org.apache.poi.sl.usermodel.SlideShow; import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.TextParagraph; import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextShape; import org.apache.poi.sl.usermodel.TextShape;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;


public class TestHeadersFooters { public class TestHeadersFooters {
private static boolean xslfOnly = false;

@BeforeClass
public static void checkHslf() {
try {
Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow");
} catch (Exception e) {
xslfOnly = true;
}
}

@Test @Test
public void bug58144a() throws IOException { public void bug58144a() throws IOException {
assumeFalse(xslfOnly);
assumeFalse(xslfOnly());
SlideShow<?,?> ppt = openSampleSlideshow("bug58144-headers-footers-2003.ppt"); SlideShow<?,?> ppt = openSampleSlideshow("bug58144-headers-footers-2003.ppt");
HSLFSlide sl = (HSLFSlide)ppt.getSlides().get(0); HSLFSlide sl = (HSLFSlide)ppt.getSlides().get(0);
HeadersFooters hfs = sl.getHeadersFooters(); HeadersFooters hfs = sl.getHeadersFooters();
@Test @Test
public void bug58144b() throws IOException { public void bug58144b() throws IOException {
assumeFalse(xslfOnly);
assumeFalse(xslfOnly());
SlideShow<?,?> ppt = openSampleSlideshow("bug58144-headers-footers-2007.ppt"); SlideShow<?,?> ppt = openSampleSlideshow("bug58144-headers-footers-2007.ppt");
Slide<?,?> sl = ppt.getSlides().get(0); Slide<?,?> sl = ppt.getSlides().get(0);
HeadersFooters hfs2 = ((HSLFSlide)sl).getHeadersFooters(); HeadersFooters hfs2 = ((HSLFSlide)sl).getHeadersFooters();

+ 5
- 29
src/ooxml/testcases/org/apache/poi/sl/TestTable.java 파일 보기



package org.apache.poi.sl; package org.apache.poi.sl;


import static org.apache.poi.sl.SLCommonUtils.openSampleSlideshow;
import static org.apache.poi.sl.SLCommonUtils.xslfOnly;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;


import org.apache.poi.POIDataSamples;
import org.apache.poi.hslf.usermodel.HSLFSlideShow; import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.sl.usermodel.Slide; import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.sl.usermodel.SlideShow; import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.TableShape; import org.apache.poi.sl.usermodel.TableShape;
import org.apache.poi.sl.usermodel.TextShape.TextDirection; import org.apache.poi.sl.usermodel.TextShape.TextDirection;
import org.apache.poi.xslf.usermodel.XMLSlideShow; import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;


public class TestTable { public class TestTable {
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
private static boolean xslfOnly = false;

@BeforeClass
public static void checkHslf() {
try {
Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow");
} catch (Exception e) {
xslfOnly = true;
}
}
/** a generic way to open a sample slideshow document **/
public static SlideShow<?,?> openSampleSlideshow(String sampleName) throws IOException {
InputStream is = _slTests.openResourceAsStream(sampleName);
try {
return SlideShowFactory.create(is);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
is.close();
}
}
@Test @Test
public void colWidthRowHeight() throws IOException { public void colWidthRowHeight() throws IOException {
assumeFalse(xslfOnly);
assumeFalse(xslfOnly());


// Test of table dimensions of same slideshow saved as ppt/x // Test of table dimensions of same slideshow saved as ppt/x
// to check if both return similar (points) value // to check if both return similar (points) value


@Test @Test
public void directionHSLF() throws IOException { public void directionHSLF() throws IOException {
assumeFalse(xslfOnly);
assumeFalse(xslfOnly());
SlideShow<?,?> ppt1 = new HSLFSlideShow(); SlideShow<?,?> ppt1 = new HSLFSlideShow();
testTextDirection(ppt1); testTextDirection(ppt1);
ppt1.close(); ppt1.close();
@Test @Test
public void tableSpan() throws IOException { public void tableSpan() throws IOException {
String files[] = (xslfOnly) ? new String[]{ "bug60993.pptx" } : new String[]{ "bug60993.pptx", "bug60993.ppt" };
String files[] = (xslfOnly()) ? new String[]{ "bug60993.pptx" } : new String[]{ "bug60993.pptx", "bug60993.ppt" };
for (String f : files) { for (String f : files) {
SlideShow<?,?> ppt = openSampleSlideshow(f); SlideShow<?,?> ppt = openSampleSlideshow(f);
Slide<?,?> slide = ppt.getSlides().get(0); Slide<?,?> slide = ppt.getSlides().get(0);

+ 16
- 11
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java 파일 보기

import static org.apache.poi.hslf.record.RecordTypes.OEPlaceholderAtom; import static org.apache.poi.hslf.record.RecordTypes.OEPlaceholderAtom;
import static org.apache.poi.hslf.record.RecordTypes.RoundTripHFPlaceholder12; import static org.apache.poi.hslf.record.RecordTypes.RoundTripHFPlaceholder12;


import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
} }
} }



@Override
public Rectangle2D resizeToFitText() {
return resizeToFitText(null);
}
/**
* Adjust the size of the shape so it encompasses the text inside it.
*
* @return a <code>Rectangle2D</code> that is the bounds of this shape.
*/
public Rectangle2D resizeToFitText(){
@Override
public Rectangle2D resizeToFitText(Graphics2D graphics) {
Rectangle2D anchor = getAnchor(); Rectangle2D anchor = getAnchor();
if(anchor.getWidth() == 0.) { if(anchor.getWidth() == 0.) {
LOG.log(POILogger.WARN, "Width of shape wasn't set. Defaulting to 200px"); LOG.log(POILogger.WARN, "Width of shape wasn't set. Defaulting to 200px");
anchor.setRect(anchor.getX(), anchor.getY(), 200., anchor.getHeight()); anchor.setRect(anchor.getX(), anchor.getY(), 200., anchor.getHeight());
setAnchor(anchor); setAnchor(anchor);
} }
double height = getTextHeight();
double height = getTextHeight(graphics);
height += 1; // add a pixel to compensate rounding errors height += 1; // add a pixel to compensate rounding errors


Insets2D insets = getInsets(); Insets2D insets = getInsets();
} }


@Override @Override
public double getTextHeight(){
DrawFactory drawFact = DrawFactory.getInstance(null);
public double getTextHeight() {
return getTextHeight(null);
}
@Override
public double getTextHeight(Graphics2D graphics) {
DrawFactory drawFact = DrawFactory.getInstance(graphics);
DrawTextShape dts = drawFact.getDrawable(this); DrawTextShape dts = drawFact.getDrawable(this);
return dts.getTextHeight();
return dts.getTextHeight(graphics);
} }


@Override @Override

BIN
test-data/slideshow/mona.ttf 파일 보기


Loading…
취소
저장