diff options
author | PJ Fanning <fanningpj@apache.org> | 2022-12-12 15:18:35 +0000 |
---|---|---|
committer | PJ Fanning <fanningpj@apache.org> | 2022-12-12 15:18:35 +0000 |
commit | 624f83431065e1a7613f1f044f1820c27e504266 (patch) | |
tree | 0941baadbb36c365b58899211f50789a550c11db | |
parent | e9aa298e1eea7be331128057d3d16c0849347916 (diff) | |
download | poi-624f83431065e1a7613f1f044f1820c27e504266.tar.gz poi-624f83431065e1a7613f1f044f1820c27e504266.zip |
[github-404] issue with text runs and styling relating to table cells. Thanks to gffloodg. This closes #404
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1905933 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java | 49 | ||||
-rw-r--r-- | poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java | 2 | ||||
-rw-r--r-- | poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFTableCell.java | 231 | ||||
-rw-r--r-- | test-data/slideshow/table-with-no-theme.pptx | bin | 0 -> 34362 bytes | |||
-rw-r--r-- | test-data/slideshow/table-with-theme.pptx | bin | 0 -> 35189 bytes |
5 files changed, 269 insertions, 13 deletions
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java index d30bfa5521..f84c37d08e 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java @@ -735,27 +735,44 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, public PaintStyle getFontColor() { CTTableStyleTextStyle txStyle = getTextStyle(); if (txStyle == null) { + // No table styling, so just use the text run output return super.getFontColor(); + } else { + final CTTextCharacterProperties props = this.getRPr(false); + final XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props); + if (fp != null && (fp.isSetSolidFill() || fp.isSetGradFill() || fp.isSetPattFill())) { + // If this run has style set locally, then it overrides table cell style. + return super.getFontColor(); + } else { + // Otherwise just use the properties from the table cell style. + CTSchemeColor phClr = null; + CTFontReference fontRef = txStyle.getFontRef(); + if (fontRef != null) { + phClr = fontRef.getSchemeClr(); + } + + XSLFTheme theme = getSheet().getTheme(); + final XSLFColor c = new XSLFColor(txStyle, theme, phClr, getSheet()); + return DrawPaint.createSolidPaint(c.getColorStyle()); + } } - - CTSchemeColor phClr = null; - CTFontReference fontRef = txStyle.getFontRef(); - if (fontRef != null) { - phClr = fontRef.getSchemeClr(); - } - - XSLFTheme theme = getSheet().getTheme(); - final XSLFColor c = new XSLFColor(txStyle, theme, phClr, getSheet()); - return DrawPaint.createSolidPaint(c.getColorStyle()); } @Override public boolean isBold() { CTTableStyleTextStyle txStyle = getTextStyle(); if (txStyle == null) { + // No table styling, so just use the text run output return super.isBold(); } else { - return txStyle.isSetB() && txStyle.getB().intValue() == STOnOffStyleType.INT_ON; + final CTTextCharacterProperties rPr = super.getRPr(false); + if (rPr.isSetB()) { + // If this run has bold set locally, then it overrides table cell style. + return rPr.getB(); + } else { + // Otherwise just use the properties from the table cell style. + return txStyle.isSetB() && txStyle.getB().intValue() == STOnOffStyleType.INT_ON; + } } } @@ -763,9 +780,17 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, public boolean isItalic() { CTTableStyleTextStyle txStyle = getTextStyle(); if (txStyle == null) { + // No table styling, so just use the text run output return super.isItalic(); } else { - return txStyle.isSetI() && txStyle.getI().intValue() == STOnOffStyleType.INT_ON; + final CTTextCharacterProperties rPr = super.getRPr(false); + if (rPr.isSetI()) { + // If this run has italic set locally, then it overrides table cell style. + return rPr.getI(); + } else { + // Otherwise just use the properties from the table cell style. + return txStyle.isSetI() && txStyle.getI().intValue() == STOnOffStyleType.INT_ON; + } } } diff --git a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java index d8bcd25f1d..60b648244b 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java @@ -75,7 +75,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr if (r instanceof CTTextLineBreak) { _runs.add(new XSLFLineBreak((CTTextLineBreak)r, this)); } else if (r instanceof CTRegularTextRun || r instanceof CTTextField) { - _runs.add(new XSLFTextRun(r, this)); + _runs.add(this.newTextRun(r)); } } while (c.toNextSibling()); } diff --git a/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFTableCell.java b/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFTableCell.java new file mode 100644 index 0000000000..f7df4ed611 --- /dev/null +++ b/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFTableCell.java @@ -0,0 +1,231 @@ +/* ==================================================================== + 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.xslf.usermodel; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.awt.Color; +import java.io.IOException; +import java.util.List; + +import org.apache.poi.sl.usermodel.PaintStyle; +import org.apache.poi.xslf.XSLFTestDataSamples; +import org.junit.jupiter.api.Test; + +class TestXSLFTableCell +{ + + @Test + void testCorrectlyReadsTextRunStylingForCellsWithNoTheme() throws IOException { + XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("table-with-no-theme.pptx"); + + XSLFSlide slide = ppt.getSlides().get(0); + List<XSLFShape> shapes = slide.getShapes(); + assertEquals(1, shapes.size()); + assertTrue(shapes.get(0) instanceof XSLFTable); + XSLFTable tbl = (XSLFTable)shapes.get(0); + assertEquals(1, tbl.getNumberOfColumns()); + assertEquals(2, tbl.getNumberOfRows()); + + List<XSLFTableRow> rows = tbl.getRows(); + assertEquals(2, rows.size()); + + // First row has 1 col and 1 runs + XSLFTableRow row0 = rows.get(0); + List<XSLFTableCell> cells0 = row0.getCells(); + assertEquals(1, cells0.size()); + + List<XSLFTextParagraph> paras0 = cells0.get(0).getTextParagraphs(); + assertEquals(1, paras0.size()); + + List<XSLFTextRun> runs0 = paras0.get(0).getTextRuns(); + assertEquals(1, runs0.size()); + + // IMPORTANT -> this should not be a normal text run (was a bug previously) + XSLFTextRun run00 = runs0.get(0); + assertEquals("XSLFCellTextRun", run00.getClass().getSimpleName()); + assertFalse(run00.isBold()); + assertFalse(run00.isItalic()); + assertNotNull(run00.getFontColor()); + assertTrue(run00.getFontColor() instanceof PaintStyle.SolidPaint); + assertEquals(Color.black, ((PaintStyle.SolidPaint)run00.getFontColor()).getSolidColor().getColor()); + + // Second row has 1 col and 3 runs + XSLFTableRow row1 = rows.get(1); + List<XSLFTableCell> cells1 = row1.getCells(); + assertEquals(1, cells1.size()); + + List<XSLFTextParagraph> paras1 = cells1.get(0).getTextParagraphs(); + assertEquals(1, paras1.size()); + + List<XSLFTextRun> runs1 = paras1.get(0).getTextRuns(); + assertEquals(3, runs1.size()); + + // IMPORTANT -> this should not be a normal text run (was a bug previously) + XSLFTextRun run10 = runs1.get(0); + assertEquals("XSLFCellTextRun", run10.getClass().getSimpleName()); + assertTrue(run10.isBold()); + assertFalse(run10.isItalic()); + assertNotNull(run10.getFontColor()); + assertTrue(run10.getFontColor() instanceof PaintStyle.SolidPaint); + assertEquals(Color.black, ((PaintStyle.SolidPaint)run10.getFontColor()).getSolidColor().getColor()); + + XSLFTextRun run11 = runs1.get(1); + assertEquals("XSLFCellTextRun", run11.getClass().getSimpleName()); + assertFalse(run11.isBold()); + assertFalse(run11.isItalic()); + assertNotNull(run11.getFontColor()); + assertTrue(run11.getFontColor() instanceof PaintStyle.SolidPaint); + assertEquals(Color.black, ((PaintStyle.SolidPaint)run11.getFontColor()).getSolidColor().getColor()); + + XSLFTextRun run12 = runs1.get(2); + assertEquals("XSLFCellTextRun", run12.getClass().getSimpleName()); + assertFalse(run12.isBold()); + assertTrue(run12.isItalic()); + assertNotNull(run12.getFontColor()); + assertTrue(run12.getFontColor() instanceof PaintStyle.SolidPaint); + assertEquals(Color.black, ((PaintStyle.SolidPaint)run12.getFontColor()).getSolidColor().getColor()); + + ppt.close(); + } + + @Test + void testCorrectlyReadsTextRunStylingForCellsWithTheme() throws IOException { + XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("table-with-theme.pptx"); + + XSLFSlide slide = ppt.getSlides().get(0); + List<XSLFShape> shapes = slide.getShapes(); + assertEquals(1, shapes.size()); + assertTrue(shapes.get(0) instanceof XSLFTable); + XSLFTable tbl = (XSLFTable)shapes.get(0); + assertEquals(1, tbl.getNumberOfColumns()); + assertEquals(2, tbl.getNumberOfRows()); + + List<XSLFTableRow> rows = tbl.getRows(); + assertEquals(2, rows.size()); + + // First row has 1 col and 3 runs + XSLFTableRow row0 = rows.get(0); + List<XSLFTableCell> cells0 = row0.getCells(); + assertEquals(1, cells0.size()); + + List<XSLFTextParagraph> paras0 = cells0.get(0).getTextParagraphs(); + assertEquals(1, paras0.size()); + + List<XSLFTextRun> runs0 = paras0.get(0).getTextRuns(); + assertEquals(3, runs0.size()); + + // IMPORTANT -> this should not be a normal text run (was a bug previously) + XSLFTextRun run00 = runs0.get(0); + assertEquals("XSLFCellTextRun", run00.getClass().getSimpleName()); + assertTrue(run00.isBold()); + assertFalse(run00.isItalic()); + assertNotNull(run00.getFontColor()); + assertTrue(run00.getFontColor() instanceof PaintStyle.SolidPaint); + assertEquals(Color.white, ((PaintStyle.SolidPaint)run00.getFontColor()).getSolidColor().getColor()); + + XSLFTextRun run01 = runs0.get(1); + assertEquals("XSLFCellTextRun", run01.getClass().getSimpleName()); + assertTrue(run01.isBold()); + assertFalse(run01.isItalic()); + assertNotNull(run01.getFontColor()); + assertTrue(run01.getFontColor() instanceof PaintStyle.SolidPaint); + assertEquals(Color.white, ((PaintStyle.SolidPaint)run01.getFontColor()).getSolidColor().getColor()); + + XSLFTextRun run02 = runs0.get(2); + assertEquals("XSLFCellTextRun", run02.getClass().getSimpleName()); + assertFalse(run02.isBold()); + assertFalse(run02.isItalic()); + assertNotNull(run02.getFontColor()); + assertTrue(run02.getFontColor() instanceof PaintStyle.SolidPaint); + assertEquals(Color.red, ((PaintStyle.SolidPaint)run02.getFontColor()).getSolidColor().getColor()); + + // Second row has 1 col and 7 runs + XSLFTableRow row1 = rows.get(1); + List<XSLFTableCell> cells1 = row1.getCells(); + assertEquals(1, cells1.size()); + + List<XSLFTextParagraph> paras1 = cells1.get(0).getTextParagraphs(); + assertEquals(1, paras1.size()); + + List<XSLFTextRun> runs1 = paras1.get(0).getTextRuns(); + assertEquals(7, runs1.size()); + + // IMPORTANT -> this should not be a normal text run (was a bug previously) + XSLFTextRun run10 = runs1.get(0); + assertEquals("XSLFCellTextRun", run10.getClass().getSimpleName()); + assertTrue(run10.isBold()); + assertFalse(run10.isItalic()); + assertNotNull(run10.getFontColor()); + assertTrue(run10.getFontColor() instanceof PaintStyle.SolidPaint); + assertEquals(Color.black, ((PaintStyle.SolidPaint)run10.getFontColor()).getSolidColor().getColor()); + + XSLFTextRun run11 = runs1.get(1); + assertEquals("XSLFCellTextRun", run11.getClass().getSimpleName()); + assertFalse(run11.isBold()); + assertFalse(run11.isItalic()); + assertNotNull(run11.getFontColor()); + assertTrue(run11.getFontColor() instanceof PaintStyle.SolidPaint); + assertEquals(Color.black, ((PaintStyle.SolidPaint)run11.getFontColor()).getSolidColor().getColor()); + + XSLFTextRun run12 = runs1.get(2); + assertEquals("XSLFCellTextRun", run12.getClass().getSimpleName()); + assertFalse(run12.isBold()); + assertTrue(run12.isItalic()); + assertNotNull(run12.getFontColor()); + assertTrue(run12.getFontColor() instanceof PaintStyle.SolidPaint); + assertEquals(Color.black, ((PaintStyle.SolidPaint)run12.getFontColor()).getSolidColor().getColor()); + + XSLFTextRun run13 = runs1.get(3); + assertEquals("XSLFCellTextRun", run13.getClass().getSimpleName()); + assertFalse(run13.isBold()); + assertFalse(run13.isItalic()); + assertNotNull(run13.getFontColor()); + assertTrue(run13.getFontColor() instanceof PaintStyle.SolidPaint); + assertEquals(Color.black, ((PaintStyle.SolidPaint)run13.getFontColor()).getSolidColor().getColor()); + + XSLFTextRun run14 = runs1.get(4); + assertEquals("XSLFCellTextRun", run14.getClass().getSimpleName()); + assertFalse(run14.isBold()); + assertFalse(run14.isItalic()); + assertNotNull(run14.getFontColor()); + assertTrue(run14.getFontColor() instanceof PaintStyle.SolidPaint); + assertEquals(Color.yellow, ((PaintStyle.SolidPaint)run14.getFontColor()).getSolidColor().getColor()); + + XSLFTextRun run15 = runs1.get(5); + assertEquals("XSLFCellTextRun", run15.getClass().getSimpleName()); + assertFalse(run15.isBold()); + assertFalse(run15.isItalic()); + assertNotNull(run15.getFontColor()); + assertTrue(run15.getFontColor() instanceof PaintStyle.SolidPaint); + assertEquals(Color.black, ((PaintStyle.SolidPaint)run15.getFontColor()).getSolidColor().getColor()); + + XSLFTextRun run16 = runs1.get(6); + assertEquals("XSLFCellTextRun", run16.getClass().getSimpleName()); + assertFalse(run16.isBold()); + assertFalse(run16.isItalic()); + assertNotNull(run16.getFontColor()); + assertTrue(run16.getFontColor() instanceof PaintStyle.SolidPaint); + assertEquals(Color.black, ((PaintStyle.SolidPaint)run16.getFontColor()).getSolidColor().getColor()); + + ppt.close(); + } + +} diff --git a/test-data/slideshow/table-with-no-theme.pptx b/test-data/slideshow/table-with-no-theme.pptx Binary files differnew file mode 100644 index 0000000000..6fc99e5ee9 --- /dev/null +++ b/test-data/slideshow/table-with-no-theme.pptx diff --git a/test-data/slideshow/table-with-theme.pptx b/test-data/slideshow/table-with-theme.pptx Binary files differnew file mode 100644 index 0000000000..d0a8ead6dc --- /dev/null +++ b/test-data/slideshow/table-with-theme.pptx |