Index: src/documentation/content/xdocs/status.xml =================================================================== --- src/documentation/content/xdocs/status.xml (revision 1561435) +++ src/documentation/content/xdocs/status.xml (working copy) @@ -36,6 +36,7 @@ + 55802 - Special Letters not exported correct 51585 - WorkbookFactory.create() hangs when creating a workbook Index: src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java =================================================================== --- src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java (revision 1554121) +++ src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java (working copy) @@ -45,6 +45,8 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; +import org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture; +import org.openxmlformats.schemas.drawingml.x2006.picture.CTPictureNonVisual; import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor; import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr; @@ -69,8 +71,6 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalAlignRun; import org.w3c.dom.NodeList; import org.w3c.dom.Text; -import org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture; -import org.openxmlformats.schemas.drawingml.x2006.picture.CTPictureNonVisual; /** * XWPFRun object defines a region of text with a common set of properties @@ -82,6 +82,16 @@ private List pictures; /** + * @see [MS-OI29500] Run Fonts + */ + public static enum FontCharRange { + ascii /* char 0-127 */, + cs /* complex symbol */, + eastAsia /* east asia */, + hAnsi /* high ansi */ + }; + + /** * @param r the CTR bean which holds the run attributes * @param p the parent paragraph */ @@ -481,29 +491,97 @@ } /** - * Specifies the fonts which shall be used to display the text contents of + * Gets the fonts which shall be used to display the text contents of * this run. Specifies a font which shall be used to format all characters * in the ASCII range (0 - 127) within the parent run * * @return a string representing the font family */ public String getFontFamily() { - CTRPr pr = run.getRPr(); - return (pr != null && pr.isSetRFonts()) ? pr.getRFonts().getAscii() - : null; + return getFontFamily(null); } /** + * Gets the font family for the specified font char range. + * If fcr is null, the font char range "ascii" is used + * + * @param fcr the font char range, defaults to "ansi" + * @return a string representing the font famil + */ + public String getFontFamily(FontCharRange fcr) { + CTRPr pr = run.getRPr(); + if (pr == null || !pr.isSetRFonts()) return null; + + CTFonts fonts = pr.getRFonts(); + switch (fcr == null ? FontCharRange.ascii : fcr) { + default: + case ascii: + return fonts.getAscii(); + case cs: + return fonts.getCs(); + case eastAsia: + return fonts.getEastAsia(); + case hAnsi: + return fonts.getHAnsi(); + } + } + + + /** * Specifies the fonts which shall be used to display the text contents of * this run. Specifies a font which shall be used to format all characters - * in the ASCII range (0 - 127) within the parent run + * in the ASCII range (0 - 127) within the parent run. + * + * Also sets the other font ranges, if they haven't been set before * * @param fontFamily + * + * @see FontCharRange */ public void setFontFamily(String fontFamily) { + setFontFamily(fontFamily, null); + } + + /** + * Specifies the fonts which shall be used to display the text contents of + * this run. The default handling for fcr == null is to overwrite the + * ascii font char range with the given font family and also set all not + * specified font ranges + * + * @param fontFamily + * @param fcr FontCharRange or null for default handling + */ + public void setFontFamily(String fontFamily, FontCharRange fcr) { CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr(); CTFonts fonts = pr.isSetRFonts() ? pr.getRFonts() : pr.addNewRFonts(); - fonts.setAscii(fontFamily); + + if (fcr == null) { + fonts.setAscii(fontFamily); + if (!fonts.isSetHAnsi()) { + fonts.setHAnsi(fontFamily); + } + if (!fonts.isSetCs()) { + fonts.setCs(fontFamily); + } + if (!fonts.isSetEastAsia()) { + fonts.setEastAsia(fontFamily); + } + } else { + switch (fcr) { + case ascii: + fonts.setAscii(fontFamily); + break; + case cs: + fonts.setCs(fontFamily); + break; + case eastAsia: + fonts.setEastAsia(fontFamily); + break; + case hAnsi: + fonts.setHAnsi(fontFamily); + break; + } + } } /** Index: src/ooxml/testcases/org/apache/poi/xwpf/AllXWPFTests.java =================================================================== --- src/ooxml/testcases/org/apache/poi/xwpf/AllXWPFTests.java (revision 1554121) +++ src/ooxml/testcases/org/apache/poi/xwpf/AllXWPFTests.java (working copy) @@ -37,6 +37,7 @@ @RunWith(Suite.class) @Suite.SuiteClasses({ TestXWPFBugs.class, + org.apache.poi.xwpf.usermodel.TestXWPFBugs.class, TestXWPFDocument.class, TestXWPFWordExtractor.class, TestXWPFHeaderFooterPolicy.class, Index: src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFBugs.java =================================================================== --- src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFBugs.java (revision 0) +++ src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFBugs.java (working copy) @@ -0,0 +1,51 @@ +/* ==================================================================== + 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.xwpf.usermodel; + +import static org.junit.Assert.assertEquals; + +import org.apache.poi.xwpf.usermodel.XWPFRun.FontCharRange; +import org.junit.Test; + +public class TestXWPFBugs { + @Test + public void bug55802() throws Exception { + String blabla = + "Bir, iki, \u00fc\u00e7, d\u00f6rt, be\u015f,\n"+ + "\nalt\u0131, yedi, sekiz, dokuz, on.\n"+ + "\nK\u0131rm\u0131z\u0131 don,\n"+ + "\ngel bizim bah\u00e7eye kon,\n"+ + "\nsar\u0131 limon"; + XWPFDocument doc = new XWPFDocument(); + XWPFRun run = doc.createParagraph().createRun(); + + for (String str : blabla.split("\n")) { + run.setText(str); + run.addBreak(); + } + + run.setFontFamily("Times New Roman"); + run.setFontSize(20); + assertEquals(run.getFontFamily(), "Times New Roman"); + assertEquals(run.getFontFamily(FontCharRange.cs), "Times New Roman"); + assertEquals(run.getFontFamily(FontCharRange.eastAsia), "Times New Roman"); + assertEquals(run.getFontFamily(FontCharRange.hAnsi), "Times New Roman"); + run.setFontFamily("Arial", FontCharRange.hAnsi); + assertEquals(run.getFontFamily(FontCharRange.hAnsi), "Arial"); + } + +}