View | Details | Raw Unified | Return to bug 55292
Collapse All | Expand All

(-)src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextParagraph.java (+490 lines)
Line 0 Link Here
1
/* ====================================================================
2
   Licensed to the Apache Software Foundation (ASF) under one or more
3
   contributor license agreements.  See the NOTICE file distributed with
4
   this work for additional information regarding copyright ownership.
5
   The ASF licenses this file to You under the Apache License, Version 2.0
6
   (the "License"); you may not use this file except in compliance with
7
   the License.  You may obtain a copy of the License at
8
9
       http://www.apache.org/licenses/LICENSE-2.0
10
11
   Unless required by applicable law or agreed to in writing, software
12
   distributed under the License is distributed on an "AS IS" BASIS,
13
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
   See the License for the specific language governing permissions and
15
   limitations under the License.
16
==================================================================== */
17
package org.apache.poi.xssf.usermodel;
18
19
import org.apache.poi.util.Beta;
20
import org.apache.poi.util.Internal;
21
import org.apache.poi.util.Units;
22
import org.apache.xmlbeans.XmlObject;
23
import org.openxmlformats.schemas.drawingml.x2006.main.*;
24
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape;
25
26
import java.awt.Color;
27
import java.awt.Graphics2D;
28
import java.awt.font.LineBreakMeasurer;
29
import java.awt.font.TextAttribute;
30
import java.awt.font.TextLayout;
31
import java.awt.geom.Rectangle2D;
32
import java.text.AttributedCharacterIterator;
33
import java.text.AttributedString;
34
import java.util.ArrayList;
35
import java.util.Iterator;
36
import java.util.List;
37
38
/**
39
 * Represents a paragraph of text within the containing text body.
40
 * The paragraph is the highest level text separation mechanism.
41
 */
42
public class XSSFTextParagraph implements Iterable<XSSFTextRun>{
43
    private final CTTextParagraph _p;
44
    private final CTShape _shape;
45
    private final List<XSSFTextRun> _runs;
46
47
    XSSFTextParagraph(CTTextParagraph p, CTShape ctShape){
48
        _p = p;
49
        _shape = ctShape;
50
        _runs = new ArrayList<XSSFTextRun>();
51
52
        for(XmlObject ch : _p.selectPath("*")){
53
            if(ch instanceof CTRegularTextRun){
54
                CTRegularTextRun r = (CTRegularTextRun)ch;
55
                _runs.add(new XSSFTextRun(r, this));
56
            } else if (ch instanceof CTTextLineBreak){
57
                CTTextLineBreak br = (CTTextLineBreak)ch;
58
                CTRegularTextRun r = CTRegularTextRun.Factory.newInstance();
59
                r.setRPr(br.getRPr());
60
                r.setT("\n");
61
                _runs.add(new XSSFTextRun(r, this));
62
            } else if (ch instanceof CTTextField){
63
                CTTextField f = (CTTextField)ch;
64
                CTRegularTextRun r = CTRegularTextRun.Factory.newInstance();
65
                r.setRPr(f.getRPr());
66
                r.setT(f.getT());
67
                _runs.add(new XSSFTextRun(r, this));
68
            }
69
        }
70
    }
71
72
    public String getText(){
73
        StringBuilder out = new StringBuilder();
74
        for (XSSFTextRun r : _runs) {
75
            out.append(r.getText());
76
        }
77
        return out.toString();
78
    }
79
80
    @Internal
81
    public CTTextParagraph getXmlObject(){
82
        return _p;
83
    }
84
    
85
    @Internal
86
    public CTShape getParentShape(){
87
        return _shape;
88
    }
89
90
    public List<XSSFTextRun> getTextRuns(){
91
        return _runs;
92
    }
93
94
    public Iterator<XSSFTextRun> iterator(){
95
        return _runs.iterator();
96
    }
97
98
    /**
99
     * Add a new run of text
100
     *
101
     * @return a new run of text
102
     */
103
    public XSSFTextRun addNewTextRun(){
104
        CTRegularTextRun r = _p.addNewR();
105
        CTTextCharacterProperties rPr = r.addNewRPr();
106
        rPr.setLang("en-US");
107
        XSSFTextRun run = new XSSFTextRun(r, this);
108
        _runs.add(run);
109
        return run;
110
    }
111
112
    /**
113
     * Insert a line break
114
     *
115
     * @return text run representing this line break ('\n')
116
     */
117
    public XSSFTextRun addLineBreak(){
118
        CTTextLineBreak br = _p.addNewBr();
119
        CTTextCharacterProperties brProps = br.addNewRPr();
120
        if(_runs.size() > 0){
121
            // by default line break has the font size of the last text run
122
            CTTextCharacterProperties prevRun = _runs.get(_runs.size() - 1).getRPr();
123
            brProps.set(prevRun);
124
        }
125
        CTRegularTextRun r = CTRegularTextRun.Factory.newInstance();
126
        r.setRPr(brProps);
127
        r.setT("\n");
128
        XSSFTextRun run = new XSSFLineBreak(r, this, brProps);
129
        _runs.add(run);
130
        return run;
131
    }
132
133
    /**
134
     * Returns the alignment that is applied to the paragraph.
135
     *
136
     * If this attribute is omitted, then a value of left is implied.
137
     * @return ??? alignment that is applied to the paragraph
138
     */
139
    public TextAlign getTextAlign(){
140
    	CTTextParagraphProperties pr = _p.getPPr();
141
    	if(pr != null) {
142
    		return pr.isSetAlgn() ? TextAlign.values()[pr.getAlgn().intValue() - 1] : TextAlign.LEFT;    	
143
    	}
144
        return TextAlign.LEFT;        
145
    }
146
147
    /**
148
     * Specifies the alignment that is to be applied to the paragraph.
149
     * Possible values for this include left, right, centered, justified and distributed,
150
     * see {@link org.apache.poi.xssf.usermodel.TextAlign}.
151
     *
152
     * @param align text align
153
     */
154
    public void setTextAlign(TextAlign align){
155
        CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
156
        if(align == null) {
157
            if(pr.isSetAlgn()) pr.unsetAlgn();
158
        } else {
159
            pr.setAlgn(STTextAlignType.Enum.forInt(align.ordinal() + 1));
160
        }
161
    }    
162
163
    /**
164
     * Returns the font alignment that is applied to the paragraph.
165
     *
166
     * If this attribute is omitted, then a value of baseline is implied.
167
     * @return ??? alignment that is applied to the paragraph
168
     */
169
    public TextFontAlign getTextFontAlign(){
170
    	CTTextParagraphProperties pr = _p.getPPr();
171
    	if(pr != null) {
172
    		return pr.isSetFontAlgn() ? TextFontAlign.values()[pr.getFontAlgn().intValue() - 1] : TextFontAlign.BASELINE;    	
173
    	}
174
        return TextFontAlign.BASELINE;
175
    }
176
    
177
    /**
178
     * Determines where vertically on a line of text the actual words are positioned. This deals
179
     * with vertical placement of the characters with respect to the baselines. For instance
180
     * having text anchored to the top baseline, anchored to the bottom baseline, centered in
181
     * between, etc.
182
     *
183
     * @param align text font align
184
     */
185
    public void setTextFontAlign(TextFontAlign align){
186
        CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
187
        if(align == null) {
188
            if(pr.isSetFontAlgn()) pr.unsetFontAlgn();
189
        } else {
190
            pr.setFontAlgn(STTextFontAlignType.Enum.forInt(align.ordinal() + 1));
191
        }
192
    }
193
    
194
195
196
    /**
197
     * Specifies the indent size that will be applied to the first line of text in the paragraph.
198
     *
199
     * @param value the indent in points. 
200
     */
201
    public void setIndent(double value){
202
        CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
203
        if(value == -1) {
204
            if(pr.isSetIndent()) pr.unsetIndent();
205
        } else {
206
            pr.setIndent(Units.toEMU(value));
207
        }
208
    }
209
210
    /**
211
     *
212
     * @return the indent applied to the first line of text in the paragraph.
213
     */
214
    public double getIndent(){
215
    	CTTextParagraphProperties pr = _p.getPPr();
216
        if(pr == null) return 0;
217
218
        return Units.toPoints(pr.getIndent());
219
    }
220
221
    
222
    
223
    /**
224
     * Specifies the left margin of the paragraph. This is specified in addition to the text body
225
     * inset and applies only to this text paragraph. That is the text body Inset and the LeftMargin
226
     * attributes are additive with respect to the text position.
227
     *
228
     * @param value the left margin of the paragraph
229
     */
230
    public void setLeftMargin(double value){
231
        CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
232
        if(value == -1) {
233
            if(pr.isSetMarL()) pr.unsetMarL();
234
        } else {
235
            pr.setMarL(Units.toEMU(value));
236
        }
237
238
    }
239
240
    /**
241
     *
242
     * @return the left margin of the paragraph
243
     */
244
    public double getLeftMargin(){
245
    	CTTextParagraphProperties pr = _p.getPPr();
246
    	if(pr != null && pr.isSetMarL()) {
247
    		return Units.toPoints(pr.getMarL());
248
    	}    	
249
    	return 347663;	// return the default which is 347663   	
250
    }
251
252
    /**
253
     * Specifies the right margin of the paragraph. This is specified in addition to the text body
254
     * inset and applies only to this text paragraph. That is the text body inset and the marR
255
     * attributes are additive with respect to the text position.
256
     *
257
     * @param value the right margin of the paragraph
258
     */
259
    public void setRightMargin(double value){
260
        CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
261
        if(value == -1) {
262
            if(pr.isSetMarR()) pr.unsetMarR();
263
        } else {
264
            pr.setMarR(Units.toEMU(value));
265
        }
266
267
    }
268
269
    /**
270
     *
271
     * @return the right margin of the paragraph
272
     */
273
    public double getRightMargin(){
274
    	CTTextParagraphProperties pr = _p.getPPr();
275
    	if(pr != null && pr.isSetMarR()) {
276
    		return Units.toPoints(pr.getMarR());
277
    	}    	
278
    	return 0;	// return the default which is 0    	
279
    }    
280
    
281
    /**
282
     * Add a single tab stop to be used on a line of text when there are one or more tab characters
283
     * present within the text. 
284
     * 
285
     * @param value the position of the tab stop relative to the left margin
286
     */
287
    public void addTabStop(double value){
288
        CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
289
        CTTextTabStopList tabStops = pr.isSetTabLst() ? pr.getTabLst() : pr.addNewTabLst();
290
        tabStops.addNewTab().setPos(Units.toEMU(value));
291
    }
292
293
    /**
294
     * This element specifies the vertical line spacing that is to be used within a paragraph.
295
     * This may be specified in two different ways, percentage spacing and font point spacing:
296
     * <p>
297
     * If linespacing >= 0, then linespacing is a percentage of normal line height
298
     * If linespacing < 0, the absolute value of linespacing is the spacing in points
299
     * </p>
300
     * Examples:
301
     * <pre><code>
302
     *      // spacing will be 120% of the size of the largest text on each line
303
     *      paragraph.setLineSpacing(120);
304
     *
305
     *      // spacing will be 200% of the size of the largest text on each line
306
     *      paragraph.setLineSpacing(200);
307
     *
308
     *      // spacing will be 48 points
309
     *      paragraph.setLineSpacing(-48.0);
310
     * </code></pre>
311
     * 
312
     * @param linespacing the vertical line spacing
313
     */
314
    public void setLineSpacing(double linespacing){
315
        CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
316
        CTTextSpacing spc = CTTextSpacing.Factory.newInstance();
317
        if(linespacing >= 0) spc.addNewSpcPct().setVal((int)(linespacing*1000));
318
        else spc.addNewSpcPts().setVal((int)(-linespacing*100));
319
        pr.setLnSpc(spc);
320
    }
321
322
    /**
323
     * Returns the vertical line spacing that is to be used within a paragraph.
324
     * This may be specified in two different ways, percentage spacing and font point spacing:
325
     * <p>
326
     * If linespacing >= 0, then linespacing is a percentage of normal line height.
327
     * If linespacing < 0, the absolute value of linespacing is the spacing in points
328
     * </p>
329
     *
330
     * @return the vertical line spacing.
331
     */
332
    public double getLineSpacing(){
333
    	CTTextParagraphProperties pr = _p.getPPr();
334
    	double lnSpc = 100;	// assume 100% default
335
    	if(pr != null) {
336
    		if(pr.isSetLnSpc()){
337
    			CTTextSpacing spc = pr.getLnSpc();
338
339
    			if(spc.isSetSpcPct()) 
340
    				lnSpc = spc.getSpcPct().getVal()*0.001;
341
                else if (spc.isSetSpcPts()) 
342
                	lnSpc = -spc.getSpcPts().getVal()*0.01;
343
    		}
344
    	}
345
    	
346
    	if(lnSpc > 0) {
347
            // check if the percentage value is scaled
348
            CTTextNormalAutofit normAutofit = getParentShape().getTxBody().getBodyPr().getNormAutofit();
349
            if(normAutofit != null) {
350
                double scale = 1 - (double)normAutofit.getLnSpcReduction() / 100000;
351
                lnSpc *= scale;
352
            }
353
        }
354
    	return lnSpc;
355
    }
356
357
    /**
358
     * Set the amount of vertical white space that will be present before the paragraph.
359
     * This space is specified in either percentage or points:
360
     * <p>
361
     * If spaceBefore >= 0, then space is a percentage of normal line height.
362
     * If spaceBefore < 0, the absolute value of linespacing is the spacing in points
363
     * </p>
364
     * Examples:
365
     * <pre><code>
366
     *      // The paragraph will be formatted to have a spacing before the paragraph text.
367
     *      // The spacing will be 200% of the size of the largest text on each line
368
     *      paragraph.setSpaceBefore(200);
369
     *
370
     *      // The spacing will be a size of 48 points
371
     *      paragraph.setSpaceBefore(-48.0);
372
     * </code></pre>
373
     *
374
     * @param spaceBefore the vertical white space before the paragraph.
375
     */
376
    public void setSpaceBefore(double spaceBefore){
377
        CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
378
        CTTextSpacing spc = CTTextSpacing.Factory.newInstance();
379
        if(spaceBefore >= 0) spc.addNewSpcPct().setVal((int)(spaceBefore*1000));
380
        else spc.addNewSpcPts().setVal((int)(-spaceBefore*100));
381
        pr.setSpcBef(spc);
382
    }
383
384
    /**
385
     * The amount of vertical white space before the paragraph
386
     * This may be specified in two different ways, percentage spacing and font point spacing:
387
     * <p>
388
     * If spaceBefore >= 0, then space is a percentage of normal line height.
389
     * If spaceBefore < 0, the absolute value of linespacing is the spacing in points
390
     * </p>
391
     *
392
     * @return the vertical white space before the paragraph
393
     */
394
    public double getSpaceBefore(){
395
    	CTTextParagraphProperties pr = _p.getPPr();
396
    	if(pr != null) {
397
    		if(pr.isSetSpcBef()) {
398
                CTTextSpacing spc = pr.getSpcBef();
399
400
                if(spc.isSetSpcPct()) 
401
                	return spc.getSpcPct().getVal()*0.001;
402
                else if (spc.isSetSpcPts()) 
403
                	return -spc.getSpcPts().getVal()*0.01;    			
404
    		}
405
    	}
406
    	return 0;
407
    }
408
409
    /**
410
     * Set the amount of vertical white space that will be present after the paragraph.
411
     * This space is specified in either percentage or points:
412
     * <p>
413
     * If spaceAfter >= 0, then space is a percentage of normal line height.
414
     * If spaceAfter < 0, the absolute value of linespacing is the spacing in points
415
     * </p>
416
     * Examples:
417
     * <pre><code>
418
     *      // The paragraph will be formatted to have a spacing after the paragraph text.
419
     *      // The spacing will be 200% of the size of the largest text on each line
420
     *      paragraph.setSpaceAfter(200);
421
     *
422
     *      // The spacing will be a size of 48 points
423
     *      paragraph.setSpaceAfter(-48.0);
424
     * </code></pre>
425
     *
426
     * @param spaceAfter the vertical white space after the paragraph.
427
     */
428
    public void setSpaceAfter(double spaceAfter){
429
        CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
430
        CTTextSpacing spc = CTTextSpacing.Factory.newInstance();
431
        if(spaceAfter >= 0) spc.addNewSpcPct().setVal((int)(spaceAfter*1000));
432
        else spc.addNewSpcPts().setVal((int)(-spaceAfter*100));
433
        pr.setSpcAft(spc);
434
    }
435
436
    /**
437
     * The amount of vertical white space after the paragraph
438
     * This may be specified in two different ways, percentage spacing and font point spacing:
439
     * <p>
440
     * If spaceBefore >= 0, then space is a percentage of normal line height.
441
     * If spaceBefore < 0, the absolute value of linespacing is the spacing in points
442
     * </p>
443
     *
444
     * @return the vertical white space after the paragraph
445
     */
446
    public double getSpaceAfter(){
447
    	CTTextParagraphProperties pr = _p.getPPr();
448
    	if(pr != null) {
449
    		if(pr.isSetSpcAft()) {
450
                CTTextSpacing spc = pr.getSpcAft();
451
452
                if(spc.isSetSpcPct()) 
453
                	return spc.getSpcPct().getVal()*0.001;
454
                else if (spc.isSetSpcPts()) 
455
                	return -spc.getSpcPts().getVal()*0.01;    			
456
    		}
457
    	}
458
    	return 0;
459
    }
460
461
    /**
462
     * Specifies the particular level text properties that this paragraph will follow.
463
     * The value for this attribute formats the text according to the corresponding level
464
     * paragraph properties defined in the SlideMaster.
465
     *
466
     * @param level the level (0 ... 4)
467
     */
468
    public void setLevel(int level){
469
        CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
470
471
        pr.setLvl(level);
472
    }
473
474
    /**
475
     *
476
     * @return the text level of this paragraph (0-based). Default is 0.
477
     */
478
    public int getLevel(){
479
        CTTextParagraphProperties pr = _p.getPPr();
480
        if(pr == null) return 0;
481
482
        return pr.getLvl();
483
484
    }
485
486
    @Override
487
    public String toString(){
488
        return "[" + getClass() + "]" + getText();
489
    }
490
}
(-)src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextRun.java (+360 lines)
Line 0 Link Here
1
/* ====================================================================
2
   Licensed to the Apache Software Foundation (ASF) under one or more
3
   contributor license agreements.  See the NOTICE file distributed with
4
   this work for additional information regarding copyright ownership.
5
   The ASF licenses this file to You under the Apache License, Version 2.0
6
   (the "License"); you may not use this file except in compliance with
7
   the License.  You may obtain a copy of the License at
8
9
       http://www.apache.org/licenses/LICENSE-2.0
10
11
   Unless required by applicable law or agreed to in writing, software
12
   distributed under the License is distributed on an "AS IS" BASIS,
13
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
   See the License for the specific language governing permissions and
15
   limitations under the License.
16
==================================================================== */
17
package org.apache.poi.xssf.usermodel;
18
19
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
20
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
21
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
22
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;
23
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
24
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
25
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont;
26
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit;
27
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
28
import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType;
29
import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;
30
import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;
31
32
import java.awt.Color;
33
34
/**
35
 * Represents a run of text within the containing text body. The run element is the
36
 * lowest level text separation mechanism within a text body.
37
 */
38
public class XSSFTextRun {
39
    private final CTRegularTextRun _r;
40
    private final XSSFTextParagraph _p;
41
42
    XSSFTextRun(CTRegularTextRun r, XSSFTextParagraph p){
43
        _r = r;
44
        _p = p;
45
    }
46
47
    XSSFTextParagraph getParentParagraph(){
48
        return _p;
49
    }
50
51
    public String getText(){
52
        return _r.getT();
53
    }
54
    
55
    public void setText(String text){
56
        _r.setT(text);
57
    }
58
59
    public CTRegularTextRun getXmlObject(){
60
        return _r;
61
    }
62
63
    public void setFontColor(Color color){
64
        CTTextCharacterProperties rPr = getRPr();
65
        CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill();
66
        CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : fill.addNewSrgbClr();
67
        clr.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()});
68
69
        if(fill.isSetHslClr()) fill.unsetHslClr();
70
        if(fill.isSetPrstClr()) fill.unsetPrstClr();
71
        if(fill.isSetSchemeClr()) fill.unsetSchemeClr();
72
        if(fill.isSetScrgbClr()) fill.unsetScrgbClr();
73
        if(fill.isSetSysClr()) fill.unsetSysClr();
74
75
    }
76
77
    public Color getFontColor(){
78
    	
79
        CTTextCharacterProperties rPr = getRPr();
80
        if(rPr.isSetSolidFill()){
81
        	CTSolidColorFillProperties fill = rPr.getSolidFill();
82
            
83
            if(fill.isSetSrgbClr()){
84
            	CTSRgbColor clr = fill.getSrgbClr();
85
            	byte[] rgb = clr.getVal();
86
            	return new Color(0xFF & rgb[0], 0xFF & rgb[1], 0xFF & rgb[2]);
87
            }	
88
        }
89
        
90
        return new Color(0, 0, 0);
91
    }
92
93
    /**
94
     *
95
     * @param fontSize  font size in points.
96
     * The value of <code>-1</code> unsets the Sz attribyte from the underlying xml bean
97
     */
98
    public void setFontSize(double fontSize){
99
        CTTextCharacterProperties rPr = getRPr();
100
        if(fontSize == -1.0) {
101
            if(rPr.isSetSz()) rPr.unsetSz();
102
        } else {
103
            if(fontSize < 1.0) {
104
                throw new IllegalArgumentException("Minimum font size is 1pt but was " + fontSize);
105
            }
106
107
            rPr.setSz((int)(100*fontSize));
108
        }
109
    }
110
111
    /**
112
     * @return font size in points or -1 if font size is not set.
113
     */
114
    public double getFontSize(){
115
        double scale = 1;
116
        double size = XSSFFont.DEFAULT_FONT_SIZE;	// default font size
117
        CTTextNormalAutofit afit = getParentParagraph().getParentShape().getTxBody().getBodyPr().getNormAutofit();
118
        if(afit != null) scale = (double)afit.getFontScale() / 100000;
119
120
        CTTextCharacterProperties rPr = getRPr();
121
        if(rPr.isSetSz()){
122
        	size = rPr.getSz()*0.01;        
123
        }
124
        
125
        return size * scale;
126
    }
127
128
    /**
129
     *
130
     * @return the spacing between characters within a text run,
131
     * If this attribute is omitted than a value of 0 or no adjustment is assumed.
132
     */
133
    public double getCharacterSpacing(){
134
    	CTTextCharacterProperties rPr = getRPr();
135
   		if(rPr.isSetSpc()){
136
   			return rPr.getSpc()*0.01;
137
   		}
138
    	return 0;
139
    }
140
141
    /**
142
     * Set the spacing between characters within a text run.
143
     * <p>
144
     * The spacing is specified in points. Positive values will cause the text to expand,
145
     * negative values to condense.
146
     * </p>
147
     *
148
     * @param spc  character spacing in points.
149
     */
150
    public void setCharacterSpacing(double spc){
151
        CTTextCharacterProperties rPr = getRPr();
152
        if(spc == 0.0) {
153
            if(rPr.isSetSpc()) rPr.unsetSpc();
154
        } else {
155
            rPr.setSpc((int)(100*spc));
156
        }
157
    }
158
159
    /**
160
     * Specifies the typeface, or name of the font that is to be used for this text run.
161
     *
162
     * @param typeface  the font to apply to this text run.
163
     * The value of <code>null</code> unsets the Typeface attrubute from the underlying xml.
164
     */
165
    public void setFont(String typeface){
166
        setFontFamily(typeface, (byte)-1, (byte)-1, false);
167
    }
168
169
    public void setFontFamily(String typeface, byte charset, byte pictAndFamily, boolean isSymbol){
170
        CTTextCharacterProperties rPr = getRPr();
171
172
        if(typeface == null){
173
            if(rPr.isSetLatin()) rPr.unsetLatin();
174
            if(rPr.isSetCs()) rPr.unsetCs();
175
            if(rPr.isSetSym()) rPr.unsetSym();
176
        } else {
177
            if(isSymbol){
178
                CTTextFont font = rPr.isSetSym() ? rPr.getSym() : rPr.addNewSym();
179
                font.setTypeface(typeface);
180
            } else {
181
                CTTextFont latin = rPr.isSetLatin() ? rPr.getLatin() : rPr.addNewLatin();
182
                latin.setTypeface(typeface);
183
                if(charset != -1) latin.setCharset(charset);
184
                if(pictAndFamily != -1) latin.setPitchFamily(pictAndFamily);
185
            }
186
        }
187
    }
188
189
    /**
190
     * @return  font family or null if not set
191
     */
192
    public String getFontFamily(){
193
    	CTTextCharacterProperties rPr = getRPr();
194
		CTTextFont font = rPr.getLatin();
195
		if(font != null){
196
		    return font.getTypeface();
197
		}
198
		return XSSFFont.DEFAULT_FONT_NAME;
199
	}
200
201
    public byte getPitchAndFamily(){
202
    	CTTextCharacterProperties rPr = getRPr();
203
		CTTextFont font = rPr.getLatin();
204
		if(font != null){
205
		    return font.getPitchFamily();
206
		}
207
		return 0;
208
    }
209
210
    /**
211
     * Specifies whether a run of text will be formatted as strikethrough text.
212
     *
213
     * @param strike whether a run of text will be formatted as strikethrough text.
214
     */
215
    public void setStrikethrough(boolean strike) {
216
        getRPr().setStrike(strike ? STTextStrikeType.SNG_STRIKE : STTextStrikeType.NO_STRIKE);
217
    }
218
219
    /**
220
     * @return whether a run of text will be formatted as strikethrough text. Default is false.
221
     */
222
    public boolean isStrikethrough() {
223
    	CTTextCharacterProperties rPr = getRPr();
224
    	if(rPr.isSetStrike()){
225
    		return rPr.getStrike() != STTextStrikeType.NO_STRIKE;
226
    	}
227
    	return false;
228
    }
229
230
    /**
231
     * @return whether a run of text will be formatted as a superscript text. Default is false.
232
     */
233
    public boolean isSuperscript() {
234
    	CTTextCharacterProperties rPr = getRPr();
235
    	if(rPr.isSetBaseline()){
236
    		return rPr.getBaseline() > 0;
237
    	}
238
    	return false;
239
    }
240
241
    /**
242
     *  Set the baseline for both the superscript and subscript fonts.
243
     *  <p>
244
     *     The size is specified using a percentage.
245
     *     Positive values indicate superscript, negative values indicate subscript.
246
     *  </p>
247
     *
248
     * @param baselineOffset
249
     */
250
    public void setBaselineOffset(double baselineOffset){
251
       getRPr().setBaseline((int) baselineOffset * 1000);
252
    }
253
254
    /**
255
     * Set whether the text in this run is formatted as superscript.
256
     * Default base line offset is 30%
257
     *
258
     * @see #setBaselineOffset(double)
259
     */
260
    public void setSuperscript(boolean flag){
261
        setBaselineOffset(flag ? 30. : 0.);
262
    }
263
264
    /**
265
     * Set whether the text in this run is formatted as subscript.
266
     * Default base line offset is -25%.
267
     *
268
     * @see #setBaselineOffset(double)
269
     */
270
    public void setSubscript(boolean flag){
271
        setBaselineOffset(flag ? -25.0 : 0.);
272
    }
273
274
    /**
275
     * @return whether a run of text will be formatted as a superscript text. Default is false.
276
     */
277
    public boolean isSubscript() {
278
    	CTTextCharacterProperties rPr = getRPr();
279
    	if(rPr.isSetBaseline()){
280
    		return rPr.getBaseline() < 0;
281
    	}
282
    	return false;
283
    }
284
285
    /**
286
     * @return whether a run of text will be formatted as a superscript text. Default is false.
287
     */
288
    public TextCap getTextCap() {    	
289
    	CTTextCharacterProperties rPr = getRPr();
290
    	if(rPr.isSetCap()){
291
    		return TextCap.values()[rPr.getCap().intValue() - 1];
292
    	}
293
    	return TextCap.NONE;
294
    }
295
296
    /**
297
     * Specifies whether this run of text will be formatted as bold text
298
     *
299
     * @param bold whether this run of text will be formatted as bold text
300
     */
301
    public void setBold(boolean bold){
302
        getRPr().setB(bold);
303
    }
304
305
    /**
306
     * @return whether this run of text is formatted as bold text
307
     */
308
    public boolean isBold(){
309
    	CTTextCharacterProperties rPr = getRPr();
310
    	if(rPr.isSetB()){
311
    		return rPr.getB();
312
    	}
313
    	return false;
314
    }
315
316
    /**
317
     * @param italic whether this run of text is formatted as italic text
318
     */
319
    public void setItalic(boolean italic){
320
        getRPr().setI(italic);
321
    }
322
323
    /**
324
     * @return whether this run of text is formatted as italic text
325
     */
326
    public boolean isItalic(){
327
    	CTTextCharacterProperties rPr = getRPr();
328
    	if(rPr.isSetI()){
329
    		return rPr.getI();
330
    	}
331
    	return false;
332
    }
333
334
    /**
335
     * @param underline whether this run of text is formatted as underlined text
336
     */
337
    public void setUnderline(boolean underline) {
338
        getRPr().setU(underline ? STTextUnderlineType.SNG : STTextUnderlineType.NONE);
339
    }
340
341
    /**
342
     * @return whether this run of text is formatted as underlined text
343
     */
344
    public boolean isUnderline(){
345
    	CTTextCharacterProperties rPr = getRPr();
346
    	if(rPr.isSetU()){
347
    		return rPr.getU() != STTextUnderlineType.NONE;
348
    	}
349
    	return false;
350
    }
351
352
    protected CTTextCharacterProperties getRPr(){
353
        return _r.isSetRPr() ? _r.getRPr() : _r.addNewRPr();
354
    }
355
356
    @Override
357
    public String toString(){
358
        return "[" + getClass() + "]" + getText();
359
    }
360
}
(-)src/ooxml/java/org/apache/poi/xssf/usermodel/TextDirection.java (+48 lines)
Line 0 Link Here
1
/*
2
 *  ====================================================================
3
 *    Licensed to the Apache Software Foundation (ASF) under one or more
4
 *    contributor license agreements.  See the NOTICE file distributed with
5
 *    this work for additional information regarding copyright ownership.
6
 *    The ASF licenses this file to You under the Apache License, Version 2.0
7
 *    (the "License"); you may not use this file except in compliance with
8
 *    the License.  You may obtain a copy of the License at
9
 *
10
 *        http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 *    Unless required by applicable law or agreed to in writing, software
13
 *    distributed under the License is distributed on an "AS IS" BASIS,
14
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 *    See the License for the specific language governing permissions and
16
 *    limitations under the License.
17
 * ====================================================================
18
 */
19
package org.apache.poi.xssf.usermodel;
20
21
/**
22
 * Vertical Text Types
23
 */
24
public enum TextDirection {
25
    /**
26
     * Horizontal text. This should be default.
27
     */
28
    HORIZONTAL,
29
    /**
30
     * Vertical orientation.
31
     * (each line is 90 degrees rotated clockwise, so it goes
32
     * from top to bottom; each next line is to the left from
33
     * the previous one).
34
     */
35
    VERTICAL,
36
    /**
37
     * Vertical orientation.
38
     * (each line is 270 degrees rotated clockwise, so it goes
39
     * from bottom to top; each next line is to the right from
40
     * the previous one).
41
     */
42
    VERTICAL_270,
43
    /**
44
     * Determines if all of the text is vertical
45
     * ("one letter on top of another").
46
     */
47
    STACKED;
48
}
(-)src/ooxml/java/org/apache/poi/xssf/usermodel/TextAlign.java (+48 lines)
Line 0 Link Here
1
/*
2
 *  ====================================================================
3
 *    Licensed to the Apache Software Foundation (ASF) under one or more
4
 *    contributor license agreements.  See the NOTICE file distributed with
5
 *    this work for additional information regarding copyright ownership.
6
 *    The ASF licenses this file to You under the Apache License, Version 2.0
7
 *    (the "License"); you may not use this file except in compliance with
8
 *    the License.  You may obtain a copy of the License at
9
 *
10
 *        http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 *    Unless required by applicable law or agreed to in writing, software
13
 *    distributed under the License is distributed on an "AS IS" BASIS,
14
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 *    See the License for the specific language governing permissions and
16
 *    limitations under the License.
17
 * ====================================================================
18
 */
19
package org.apache.poi.xssf.usermodel;
20
21
/**
22
 * Specified a list of text alignment types
23
 */
24
public enum TextAlign {
25
    /**
26
     * Align text to the left margin.
27
     */
28
    LEFT,
29
    /**
30
     * Align text in the center.
31
     */
32
    CENTER,
33
34
    /**
35
     * Align text to the right margin.
36
     */
37
    RIGHT,
38
39
    /**
40
     * Align text so that it is justified across the whole line. It
41
     * is smart in the sense that it will not justify sentences
42
     * which are short
43
     */
44
    JUSTIFY,
45
    JUSTIFY_LOW,
46
    DIST,
47
    THAI_DIST
48
}
(-)src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFLineBreak.java (+45 lines)
Line 0 Link Here
1
/*
2
 *  ====================================================================
3
 *    Licensed to the Apache Software Foundation (ASF) under one or more
4
 *    contributor license agreements.  See the NOTICE file distributed with
5
 *    this work for additional information regarding copyright ownership.
6
 *    The ASF licenses this file to You under the Apache License, Version 2.0
7
 *    (the "License"); you may not use this file except in compliance with
8
 *    the License.  You may obtain a copy of the License at
9
 *
10
 *        http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 *    Unless required by applicable law or agreed to in writing, software
13
 *    distributed under the License is distributed on an "AS IS" BASIS,
14
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 *    See the License for the specific language governing permissions and
16
 *    limitations under the License.
17
 * ====================================================================
18
 */
19
20
package org.apache.poi.xssf.usermodel;
21
22
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
23
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
24
25
/**
26
 * @author Darren Roberts
27
 */
28
class XSSFLineBreak extends XSSFTextRun {
29
    private final CTTextCharacterProperties _brProps;
30
31
    XSSFLineBreak(CTRegularTextRun r, XSSFTextParagraph p, CTTextCharacterProperties brProps){
32
        super(r, p);
33
        _brProps = brProps;
34
    }
35
36
    @Override
37
    protected CTTextCharacterProperties getRPr(){
38
        return _brProps;
39
    }
40
41
    public void setText(String text){
42
        throw new IllegalStateException("You cannot change text of a line break, it is always '\\n'");
43
    }
44
45
}
(-)src/ooxml/java/org/apache/poi/xssf/usermodel/TextVerticalOverflow.java (+41 lines)
Line 0 Link Here
1
/*
2
 *  ====================================================================
3
 *    Licensed to the Apache Software Foundation (ASF) under one or more
4
 *    contributor license agreements.  See the NOTICE file distributed with
5
 *    this work for additional information regarding copyright ownership.
6
 *    The ASF licenses this file to You under the Apache License, Version 2.0
7
 *    (the "License"); you may not use this file except in compliance with
8
 *    the License.  You may obtain a copy of the License at
9
 *
10
 *        http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 *    Unless required by applicable law or agreed to in writing, software
13
 *    distributed under the License is distributed on an "AS IS" BASIS,
14
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 *    See the License for the specific language governing permissions and
16
 *    limitations under the License.
17
 * ====================================================================
18
 */
19
package org.apache.poi.xssf.usermodel;
20
21
/**
22
 * Text Vertical Overflow
23
 */
24
public enum TextVerticalOverflow {
25
    /**
26
     * Overflow the text and pay no attention to top and bottom barriers.
27
     */
28
    OVERFLOW,
29
30
    /**
31
     * Pay attention to top and bottom barriers. Use an
32
     * ellipsis to denote that there is text which is not visible.     
33
     */
34
    ELLIPSIS,
35
36
    /**
37
     * Pay attention to top and bottom barriers. Provide no
38
     * indication that there is text which is not visible.
39
     */
40
    CLIP
41
}
(-)src/ooxml/java/org/apache/poi/xssf/usermodel/TextCap.java (+30 lines)
Line 0 Link Here
1
/*
2
 *  ====================================================================
3
 *    Licensed to the Apache Software Foundation (ASF) under one or more
4
 *    contributor license agreements.  See the NOTICE file distributed with
5
 *    this work for additional information regarding copyright ownership.
6
 *    The ASF licenses this file to You under the Apache License, Version 2.0
7
 *    (the "License"); you may not use this file except in compliance with
8
 *    the License.  You may obtain a copy of the License at
9
 *
10
 *        http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 *    Unless required by applicable law or agreed to in writing, software
13
 *    distributed under the License is distributed on an "AS IS" BASIS,
14
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 *    See the License for the specific language governing permissions and
16
 *    limitations under the License.
17
 * ====================================================================
18
 */
19
20
package org.apache.poi.xssf.usermodel;
21
22
/**
23
 * Text Capitalization that is to be applied to the text run. This is a render-only
24
 * modification and does not affect the actual characters stored in the text run.
25
 */
26
public enum TextCap {
27
    NONE,
28
    SMALL,
29
    ALL
30
}
(-)src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java (-41 / +463 lines)
Lines 17-22 Link Here
17
17
18
package org.apache.poi.xssf.usermodel;
18
package org.apache.poi.xssf.usermodel;
19
19
20
import java.util.ArrayList;
21
import java.util.Iterator;
22
import java.util.List;
23
20
import org.apache.poi.hssf.util.HSSFColor;
24
import org.apache.poi.hssf.util.HSSFColor;
21
import org.openxmlformats.schemas.drawingml.x2006.main.*;
25
import org.openxmlformats.schemas.drawingml.x2006.main.*;
22
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape;
26
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape;
Lines 24-38 Link Here
24
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRElt;
28
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRElt;
25
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRPrElt;
29
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRPrElt;
26
import org.apache.poi.util.Internal;
30
import org.apache.poi.util.Internal;
31
import org.apache.poi.util.Units;
32
import org.apache.poi.ss.usermodel.VerticalAlignment;
27
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnderlineValues;
33
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnderlineValues;
28
34
29
/**
35
/**
30
 * Represents a shape with a predefined geometry in a SpreadsheetML drawing.
36
 * Represents a shape with a predefined geometry in a SpreadsheetML drawing.
31
 * Possible shape types are defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}
37
 * Possible shape types are defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}
32
 *
33
 * @author Yegor Kozlov
34
 */
38
 */
35
public class XSSFSimpleShape extends XSSFShape { // TODO - instantiable superclass
39
public class XSSFSimpleShape extends XSSFShape implements Iterable<XSSFTextParagraph> { // TODO - instantiable superclass
40
	/**
41
	 * List of the paragraphs that make up the text in this shape
42
	 */
43
	private final List<XSSFTextParagraph> _paragraphs;
36
    /**
44
    /**
37
     * A default instance of CTShape used for creating new shapes.
45
     * A default instance of CTShape used for creating new shapes.
38
     */
46
     */
Lines 46-51 Link Here
46
    protected XSSFSimpleShape(XSSFDrawing drawing, CTShape ctShape) {
54
    protected XSSFSimpleShape(XSSFDrawing drawing, CTShape ctShape) {
47
        this.drawing = drawing;
55
        this.drawing = drawing;
48
        this.ctShape = ctShape;
56
        this.ctShape = ctShape;
57
        
58
        _paragraphs = new ArrayList<XSSFTextParagraph>();
59
        
60
        // initialize any existing paragraphs - this will be the default body paragraph in a new shape, 
61
        // or existing paragraphs that have been loaded from the file
62
        CTTextBody body = ctShape.getTxBody();
63
        for(int i = 0; i < body.sizeOfPArray(); i++) {
64
            _paragraphs.add(new XSSFTextParagraph(body.getPArray(i), ctShape));        	
65
        }
49
    }
66
    }
50
67
51
    /**
68
    /**
Lines 74-107 Link Here
74
            geom.setPrst(STShapeType.RECT);
91
            geom.setPrst(STShapeType.RECT);
75
            geom.addNewAvLst();
92
            geom.addNewAvLst();
76
93
77
            CTShapeStyle style = shape.addNewStyle();
78
            CTSchemeColor scheme = style.addNewLnRef().addNewSchemeClr();
79
            scheme.setVal(STSchemeColorVal.ACCENT_1);
80
            scheme.addNewShade().setVal(50000);
81
            style.getLnRef().setIdx(2);
82
83
            CTStyleMatrixReference fillref = style.addNewFillRef();
84
            fillref.setIdx(1);
85
            fillref.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);
86
87
            CTStyleMatrixReference effectRef = style.addNewEffectRef();
88
            effectRef.setIdx(0);
89
            effectRef.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);
90
91
            CTFontReference fontRef = style.addNewFontRef();
92
            fontRef.setIdx(STFontCollectionIndex.MINOR);
93
            fontRef.addNewSchemeClr().setVal(STSchemeColorVal.LT_1);
94
95
            CTTextBody body = shape.addNewTxBody();
94
            CTTextBody body = shape.addNewTxBody();
96
            CTTextBodyProperties bodypr = body.addNewBodyPr();
95
            CTTextBodyProperties bodypr = body.addNewBodyPr();
97
            bodypr.setAnchor(STTextAnchoringType.CTR);
96
            bodypr.setAnchor(STTextAnchoringType.T);
98
            bodypr.setRtlCol(false);
97
            bodypr.setRtlCol(false);
99
            CTTextParagraph p = body.addNewP();
98
            CTTextParagraph p = body.addNewP();
100
            p.addNewPPr().setAlgn(STTextAlignType.CTR);
99
            p.addNewPPr().setAlgn(STTextAlignType.L);
101
            CTTextCharacterProperties endPr = p.addNewEndParaRPr();
100
            CTTextCharacterProperties endPr = p.addNewEndParaRPr();
102
            endPr.setLang("en-US");
101
            endPr.setLang("en-US");
103
            endPr.setSz(1100);
102
            endPr.setSz(1100);   
104
103
            CTSolidColorFillProperties scfpr = endPr.addNewSolidFill();
104
            scfpr.addNewSrgbClr().setVal(new byte[] { 0, 0, 0 });
105
                        
105
            body.addNewLstStyle();
106
            body.addNewLstStyle();
106
107
107
            prototype = shape;
108
            prototype = shape;
Lines 114-143 Link Here
114
        return ctShape;
115
        return ctShape;
115
    }
116
    }
116
117
118
119
    public Iterator<XSSFTextParagraph> iterator(){
120
        return _paragraphs.iterator();
121
    }
122
117
    /**
123
    /**
118
     * Gets the shape type, one of the constants defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}.
124
     * Returns the text from all paragraphs in the shape. Paragraphs are separated by new lines.
119
     *
125
     * 
120
     * @return the shape type
126
     * @return  text contained within this shape or empty string
121
     * @see org.apache.poi.ss.usermodel.ShapeTypes
122
     */
127
     */
123
    public int getShapeType() {
128
    public String getText() {
124
        return ctShape.getSpPr().getPrstGeom().getPrst().intValue();
129
        StringBuilder out = new StringBuilder();
130
        for (XSSFTextParagraph p : _paragraphs) {
131
            if (out.length() > 0) out.append('\n');
132
            out.append(p.getText());
133
        }
134
        return out.toString();
125
    }
135
    }
126
136
127
    /**
137
    /**
128
     * Sets the shape types.
138
     * Clear all text from this shape
129
     *
130
     * @param type the shape type, one of the constants defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}.
131
     * @see org.apache.poi.ss.usermodel.ShapeTypes
132
     */
139
     */
133
    public void setShapeType(int type) {
140
    public void clearText(){
134
        ctShape.getSpPr().getPrstGeom().setPrst(STShapeType.Enum.forInt(type));
141
        _paragraphs.clear();
142
        CTTextBody txBody = ctShape.getTxBody();
143
        txBody.setPArray(null); // remove any existing paragraphs
135
    }
144
    }
145
    
146
    /**
147
     * Set a single paragraph of text on the shape. Note this will replace all existing paragraphs created on the shape.
148
     * @param text	string representing the paragraph text
149
     */
150
    public void setText(String text){
151
        clearText();
136
152
137
    protected CTShapeProperties getShapeProperties(){
153
        addNewTextParagraph().addNewTextRun().setText(text);
138
        return ctShape.getSpPr();
139
    }
154
    }
140
155
156
    /**
157
     * Set a single paragraph of text on the shape. Note this will replace all existing paragraphs created on the shape.
158
     * @param str	rich text string representing the paragraph text
159
     */
141
    public void setText(XSSFRichTextString str){
160
    public void setText(XSSFRichTextString str){
142
161
143
        XSSFWorkbook wb = (XSSFWorkbook)getDrawing().getParent().getParent();
162
        XSSFWorkbook wb = (XSSFWorkbook)getDrawing().getParent().getParent();
Lines 166-177 Link Here
166
                r.setT(lt.getT());
185
                r.setT(lt.getT());
167
            }
186
            }
168
        }
187
        }
188
        
189
        clearText();                
169
        ctShape.getTxBody().setPArray(new CTTextParagraph[]{p});
190
        ctShape.getTxBody().setPArray(new CTTextParagraph[]{p});
191
        _paragraphs.add(new XSSFTextParagraph(ctShape.getTxBody().getPArray(0), ctShape));
192
    }    
193
    
194
    /**
195
     * Returns a collection of the XSSFTextParagraphs that are attached to this shape
196
     * 
197
     * @return text paragraphs in this shape
198
     */
199
    public List<XSSFTextParagraph> getTextParagraphs() {
200
        return _paragraphs;
201
    }
170
202
203
    /**
204
     * Add a new paragraph run to this shape
205
     *
206
     * @return created paragraph run
207
     */
208
    public XSSFTextParagraph addNewTextParagraph() {
209
        CTTextBody txBody = ctShape.getTxBody();
210
        CTTextParagraph p = txBody.addNewP();
211
        XSSFTextParagraph paragraph = new XSSFTextParagraph(p, ctShape);
212
        _paragraphs.add(paragraph);
213
        return paragraph;
214
    }    
215
216
    /**
217
     * Add a new paragraph run to this shape, set to the provided rich text string 
218
     *
219
     * @return created paragraph run
220
     */
221
    public XSSFTextParagraph addNewTextParagraph(XSSFRichTextString str) {
222
        CTTextBody txBody = ctShape.getTxBody();
223
        CTTextParagraph p = txBody.addNewP();
224
       
225
        if(str.numFormattingRuns() == 0){
226
            CTRegularTextRun r = p.addNewR();
227
            CTTextCharacterProperties rPr = r.addNewRPr();
228
            rPr.setLang("en-US");
229
            rPr.setSz(1100);
230
            r.setT(str.getString());
231
232
        } else {
233
            for (int i = 0; i < str.getCTRst().sizeOfRArray(); i++) {
234
                CTRElt lt = str.getCTRst().getRArray(i);
235
                CTRPrElt ltPr = lt.getRPr();
236
                if(ltPr == null) ltPr = lt.addNewRPr();
237
238
                CTRegularTextRun r = p.addNewR();
239
                CTTextCharacterProperties rPr = r.addNewRPr();
240
                rPr.setLang("en-US");
241
242
                applyAttributes(ltPr, rPr);
243
244
                r.setT(lt.getT());
245
            }
246
        }
247
        
248
        // Note: the XSSFTextParagraph constructor will create its required XSSFTextRuns from the provided CTTextParagraph
249
        XSSFTextParagraph paragraph = new XSSFTextParagraph(p, ctShape);
250
        _paragraphs.add(paragraph);
251
        
252
        return paragraph;
171
    }
253
    }
172
254
173
    /**
255
    /**
256
     * Sets the type of horizontal overflow for the text.
174
     *
257
     *
258
     * @param overflow - the type of horizontal overflow.
259
     * A <code>null</code> values unsets this property.
260
     */
261
    public void setTextHorizontalOverflow(TextHorizontalOverflow overflow){
262
        CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
263
        if (bodyPr != null) {
264
             if(anchor == null) {
265
                if(bodyPr.isSetHorzOverflow()) bodyPr.unsetHorzOverflow();
266
            } else {
267
                bodyPr.setHorzOverflow(STTextHorzOverflowType.Enum.forInt(overflow.ordinal() + 1));
268
            }
269
        }
270
    }
271
272
    /**
273
     * Returns the type of horizontal overflow for the text.
274
     *
275
     * @return the type of horizontal overflow
276
     */
277
    public TextHorizontalOverflow getTextHorizontalOverflow(){
278
    	CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
279
    	if(bodyPr != null) {
280
    		if(bodyPr.isSetHorzOverflow()){
281
    			return TextHorizontalOverflow.values()[bodyPr.getVertOverflow().intValue() - 1];
282
    		}    			
283
    	}
284
    	return TextHorizontalOverflow.OVERFLOW;
285
    }    
286
    
287
    /**
288
     * Sets the type of vertical overflow for the text.
289
     *
290
     * @param overflow - the type of vertical overflow.
291
     * A <code>null</code> values unsets this property.
292
     */
293
    public void setTextVerticalOverflow(TextVerticalOverflow overflow){
294
        CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
295
        if (bodyPr != null) {
296
             if(anchor == null) {
297
                if(bodyPr.isSetVertOverflow()) bodyPr.unsetVertOverflow();
298
            } else {
299
                bodyPr.setVertOverflow(STTextVertOverflowType.Enum.forInt(overflow.ordinal() + 1));
300
            }
301
        }
302
    }
303
304
    /**
305
     * Returns the type of vertical overflow for the text.
306
     *
307
     * @return the type of vertical overflow
308
     */
309
    public TextVerticalOverflow getTextVerticalOverflow(){
310
    	CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
311
    	if(bodyPr != null) {
312
    		if(bodyPr.isSetVertOverflow()){
313
    			return TextVerticalOverflow.values()[bodyPr.getVertOverflow().intValue() - 1];
314
    		}    			
315
    	}
316
    	return TextVerticalOverflow.OVERFLOW;
317
    }   
318
    
319
    /**
320
     * Sets the type of vertical alignment for the text within the shape.
321
     *
322
     * @param anchor - the type of alignment.
323
     * A <code>null</code> values unsets this property.
324
     */
325
    public void setVerticalAlignment(VerticalAlignment anchor){
326
        CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
327
        if (bodyPr != null) {
328
             if(anchor == null) {
329
                if(bodyPr.isSetAnchor()) bodyPr.unsetAnchor();
330
            } else {
331
                bodyPr.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1));
332
            }
333
        }
334
    }
335
336
    /**
337
     * Returns the type of vertical alignment for the text within the shape.
338
     *
339
     * @return the type of vertical alignment
340
     */
341
    public VerticalAlignment getVerticalAlignment(){
342
    	CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
343
    	if(bodyPr != null) {
344
    		if(bodyPr.isSetAnchor()){
345
    			return VerticalAlignment.values()[bodyPr.getAnchor().intValue() - 1];
346
    		}    			
347
    	}
348
    	return VerticalAlignment.TOP;
349
    }
350
351
    /**
352
     * Sets the vertical orientation of the text
353
     * 
354
     * @param orientation vertical orientation of the text
355
     * A <code>null</code> values unsets this property.
356
     */
357
    public void setTextDirection(TextDirection orientation){
358
        CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
359
        if (bodyPr != null) {
360
            if(orientation == null) {
361
                if(bodyPr.isSetVert()) bodyPr.unsetVert();
362
            } else {
363
                bodyPr.setVert(STTextVerticalType.Enum.forInt(orientation.ordinal() + 1));
364
            }
365
        }
366
    }
367
368
    /**
369
     * Gets the vertical orientation of the text
370
     * 
371
     * @return vertical orientation of the text
372
     */
373
    public TextDirection getTextDirection(){
374
        CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
375
        if (bodyPr != null) {
376
            STTextVerticalType.Enum val = bodyPr.getVert();
377
            if(val != null){
378
                return TextDirection.values()[val.intValue() - 1];
379
            }
380
        }
381
        return TextDirection.HORIZONTAL;
382
    }
383
384
385
    /**
386
     * Returns the distance (in points) between the bottom of the text frame
387
     * and the bottom of the inscribed rectangle of the shape that contains the text.
388
     *
389
     * @return the bottom inset in points
390
     */
391
    public double getBottomInset(){
392
        CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
393
        if (bodyPr != null) {
394
        	if(bodyPr.isSetBIns()){
395
        		return Units.toPoints(bodyPr.getBIns());
396
        	}
397
        }
398
        // If this attribute is omitted, then a value of 0.05 inches is implied
399
        return 3.6;	
400
    }
401
402
    /**
403
     *  Returns the distance (in points) between the left edge of the text frame
404
     *  and the left edge of the inscribed rectangle of the shape that contains
405
     *  the text.
406
     *
407
     * @return the left inset in points
408
     */
409
    public double getLeftInset(){
410
        CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
411
        if (bodyPr != null) {
412
        	if(bodyPr.isSetLIns()){
413
        		return Units.toPoints(bodyPr.getLIns());
414
        	}
415
        }
416
        // If this attribute is omitted, then a value of 0.05 inches is implied
417
        return 3.6;
418
    }
419
420
    /**
421
     *  Returns the distance (in points) between the right edge of the
422
     *  text frame and the right edge of the inscribed rectangle of the shape
423
     *  that contains the text.
424
     *
425
     * @return the right inset in points
426
     */
427
    public double getRightInset(){
428
        CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
429
        if (bodyPr != null) {
430
        	if(bodyPr.isSetRIns()){
431
        		return Units.toPoints(bodyPr.getRIns());
432
        	}
433
        }
434
        // If this attribute is omitted, then a value of 0.05 inches is implied
435
        return 3.6;
436
    }
437
438
    /**
439
     *  Returns the distance (in points) between the top of the text frame
440
     *  and the top of the inscribed rectangle of the shape that contains the text.
441
     *
442
     * @return the top inset in points
443
     */
444
    public double getTopInset(){
445
        CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
446
        if (bodyPr != null) {
447
        	if(bodyPr.isSetTIns()){
448
        		return Units.toPoints(bodyPr.getTIns());
449
        	}
450
        }
451
        // If this attribute is omitted, then a value of 0.05 inches is implied
452
        return 3.6;    	
453
    }
454
455
    /**
456
     * Sets the bottom inset.
457
     * @see #getBottomInset()
458
     *
459
     * @param margin    the bottom margin
460
     */
461
    public void setBottomInset(double margin){
462
        CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
463
        if (bodyPr != null) {
464
            if(margin == -1) bodyPr.unsetBIns();
465
            else bodyPr.setBIns(Units.toEMU(margin));
466
        }
467
    }
468
469
    /**
470
     * Sets the left inset.
471
     * @see #getLeftInset()
472
     *
473
     * @param margin    the left margin
474
     */
475
    public void setLeftInset(double margin){
476
        CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
477
        if (bodyPr != null) {
478
            if(margin == -1) bodyPr.unsetLIns();
479
            else bodyPr.setLIns(Units.toEMU(margin));
480
        }
481
    }
482
483
    /**
484
     * Sets the right inset.
485
     * @see #getRightInset()
486
     *
487
     * @param margin    the right margin
488
     */
489
    public void setRightInset(double margin){
490
        CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
491
        if (bodyPr != null) {
492
            if(margin == -1) bodyPr.unsetRIns();
493
            else bodyPr.setRIns(Units.toEMU(margin));
494
        }
495
    }
496
497
    /**
498
     * Sets the top inset.
499
     * @see #getTopInset()
500
     *
501
     * @param margin    the top margin
502
     */
503
    public void setTopInset(double margin){
504
        CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
505
        if (bodyPr != null) {
506
            if(margin == -1) bodyPr.unsetTIns();
507
            else bodyPr.setTIns(Units.toEMU(margin));
508
        }
509
    }
510
511
512
    /**
513
     * @return whether to wrap words within the bounding rectangle
514
     */
515
    public boolean getWordWrap(){
516
    	CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
517
        if (bodyPr != null) {
518
        	if(bodyPr.isSetWrap()){
519
        		return bodyPr.getWrap() == STTextWrappingType.SQUARE;
520
        	}
521
        }
522
        return true;
523
    }
524
525
    /**
526
     *
527
     * @param wrap  whether to wrap words within the bounding rectangle
528
     */
529
    public void setWordWrap(boolean wrap){
530
        CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
531
        if (bodyPr != null) {
532
            bodyPr.setWrap(wrap ? STTextWrappingType.SQUARE : STTextWrappingType.NONE);
533
        }
534
    }
535
536
    /**
537
     *
538
     * Specifies that a shape should be auto-fit to fully contain the text described within it.
539
     * Auto-fitting is when text within a shape is scaled in order to contain all the text inside
540
     *
541
     * @param value type of autofit
542
     */
543
    public void setTextAutofit(TextAutofit value){
544
        CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
545
        if (bodyPr != null) {
546
            if(bodyPr.isSetSpAutoFit()) bodyPr.unsetSpAutoFit();
547
            if(bodyPr.isSetNoAutofit()) bodyPr.unsetNoAutofit();
548
            if(bodyPr.isSetNormAutofit()) bodyPr.unsetNormAutofit();
549
550
            switch(value){
551
                case NONE: bodyPr.addNewNoAutofit(); break;
552
                case NORMAL: bodyPr.addNewNormAutofit(); break;
553
                case SHAPE: bodyPr.addNewSpAutoFit(); break;
554
            }
555
        }
556
    }
557
558
    /**
559
     *
560
     * @return type of autofit
561
     */
562
    public TextAutofit getTextAutofit(){
563
        CTTextBodyProperties bodyPr = ctShape.getTxBody().getBodyPr();
564
        if (bodyPr != null) {
565
            if(bodyPr.isSetNoAutofit()) return TextAutofit.NONE;
566
            else if (bodyPr.isSetNormAutofit()) return TextAutofit.NORMAL;
567
            else if (bodyPr.isSetSpAutoFit()) return TextAutofit.SHAPE;
568
        }
569
        return TextAutofit.NORMAL;
570
    }
571
    
572
    /**
573
     * Gets the shape type, one of the constants defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}.
574
     *
575
     * @return the shape type
576
     * @see org.apache.poi.ss.usermodel.ShapeTypes
577
     */
578
    public int getShapeType() {
579
        return ctShape.getSpPr().getPrstGeom().getPrst().intValue();
580
    }
581
582
    /**
583
     * Sets the shape types.
584
     *
585
     * @param type the shape type, one of the constants defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}.
586
     * @see org.apache.poi.ss.usermodel.ShapeTypes
587
     */
588
    public void setShapeType(int type) {
589
        ctShape.getSpPr().getPrstGeom().setPrst(STShapeType.Enum.forInt(type));
590
    }
591
592
    protected CTShapeProperties getShapeProperties(){
593
        return ctShape.getSpPr();
594
    }
595
596
    /**
175
     * org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRPrElt to
597
     * org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRPrElt to
176
     * org.openxmlformats.schemas.drawingml.x2006.main.CTFont adapter
598
     * org.openxmlformats.schemas.drawingml.x2006.main.CTFont adapter
177
     */
599
     */
Lines 186-193 Link Here
186
        }
608
        }
187
        if(pr.sizeOfIArray() > 0) rPr.setI(pr.getIArray(0).getVal());
609
        if(pr.sizeOfIArray() > 0) rPr.setI(pr.getIArray(0).getVal());
188
610
189
        if(pr.sizeOfFamilyArray() > 0) {
611
        if(pr.sizeOfRFontArray() > 0) {
190
            CTTextFont rFont = rPr.addNewLatin();
612
            CTTextFont rFont = rPr.isSetLatin() ? rPr.getLatin() : rPr.addNewLatin();
191
            rFont.setTypeface(pr.getRFontArray(0).getVal());
613
            rFont.setTypeface(pr.getRFontArray(0).getVal());
192
        }
614
        }
193
615
(-)src/ooxml/java/org/apache/poi/xssf/usermodel/TextAutofit.java (+57 lines)
Line 0 Link Here
1
/*
2
 *  ====================================================================
3
 *    Licensed to the Apache Software Foundation (ASF) under one or more
4
 *    contributor license agreements.  See the NOTICE file distributed with
5
 *    this work for additional information regarding copyright ownership.
6
 *    The ASF licenses this file to You under the Apache License, Version 2.0
7
 *    (the "License"); you may not use this file except in compliance with
8
 *    the License.  You may obtain a copy of the License at
9
 *
10
 *        http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 *    Unless required by applicable law or agreed to in writing, software
13
 *    distributed under the License is distributed on an "AS IS" BASIS,
14
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 *    See the License for the specific language governing permissions and
16
 *    limitations under the License.
17
 * ====================================================================
18
 */
19
package org.apache.poi.xssf.usermodel;
20
21
/**
22
 * Specifies alist of auto-fit types.
23
 * <p>
24
 * Autofit specofies that a shape should be auto-fit to fully contain the text described within it.
25
 * Auto-fitting is when text within a shape is scaled in order to contain all the text inside
26
 * </p>
27
 */
28
public enum TextAutofit {
29
    /**
30
     * Specifies that text within the text body should not be auto-fit to the bounding box.
31
     * Auto-fitting is when text within a text box is scaled in order to remain inside
32
     * the text box.
33
     */
34
    NONE,
35
    /**
36
     * Specifies that text within the text body should be normally auto-fit to the bounding box.
37
     * Autofitting is when text within a text box is scaled in order to remain inside the text box.
38
     *
39
     * <p>
40
     * <em>Example:</em> Consider the situation where a user is building a diagram and needs
41
     * to have the text for each shape that they are using stay within the bounds of the shape.
42
     * An easy way this might be done is by using NORMAL autofit
43
     * </p>
44
     */
45
    NORMAL,
46
    /**
47
     * Specifies that a shape should be auto-fit to fully contain the text described within it.
48
     * Auto-fitting is when text within a shape is scaled in order to contain all the text inside.
49
     *
50
     * <p>
51
     * <em>Example:</em> Consider the situation where a user is building a diagram and needs to have
52
     * the text for each shape that they are using stay within the bounds of the shape.
53
     * An easy way this might be done is by using SHAPE autofit
54
     * </p>
55
     */
56
    SHAPE
57
}
(-)src/ooxml/java/org/apache/poi/xssf/usermodel/TextHorizontalOverflow.java (+36 lines)
Line 0 Link Here
1
/*
2
 *  ====================================================================
3
 *    Licensed to the Apache Software Foundation (ASF) under one or more
4
 *    contributor license agreements.  See the NOTICE file distributed with
5
 *    this work for additional information regarding copyright ownership.
6
 *    The ASF licenses this file to You under the Apache License, Version 2.0
7
 *    (the "License"); you may not use this file except in compliance with
8
 *    the License.  You may obtain a copy of the License at
9
 *
10
 *        http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 *    Unless required by applicable law or agreed to in writing, software
13
 *    distributed under the License is distributed on an "AS IS" BASIS,
14
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 *    See the License for the specific language governing permissions and
16
 *    limitations under the License.
17
 * ====================================================================
18
 */
19
package org.apache.poi.xssf.usermodel;
20
21
/**
22
 * Text Horizontal Overflow
23
 */
24
public enum TextHorizontalOverflow {
25
    /**
26
     * When a big character does not fit into a line, allow a
27
     * horizontal overflow.
28
     */
29
    OVERFLOW,
30
31
    /**
32
     * When a big character does not fit into a line, clip it at
33
     * the proper horizontal overflow.
34
     */
35
    CLIP
36
}
(-)src/ooxml/java/org/apache/poi/xssf/usermodel/TextFontAlign.java (+47 lines)
Line 0 Link Here
1
/*
2
 *  ====================================================================
3
 *    Licensed to the Apache Software Foundation (ASF) under one or more
4
 *    contributor license agreements.  See the NOTICE file distributed with
5
 *    this work for additional information regarding copyright ownership.
6
 *    The ASF licenses this file to You under the Apache License, Version 2.0
7
 *    (the "License"); you may not use this file except in compliance with
8
 *    the License.  You may obtain a copy of the License at
9
 *
10
 *        http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 *    Unless required by applicable law or agreed to in writing, software
13
 *    distributed under the License is distributed on an "AS IS" BASIS,
14
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 *    See the License for the specific language governing permissions and
16
 *    limitations under the License.
17
 * ====================================================================
18
 */
19
package org.apache.poi.xssf.usermodel;
20
21
/**
22
 * Specified a list of text font alignment types
23
 */
24
public enum TextFontAlign {
25
	/**
26
	 * Automatic alignment
27
	 */
28
	AUTO,
29
    /**
30
     * Align text to the top.
31
     */
32
    TOP,
33
    /**
34
     * Align text in the center.
35
     */
36
    CENTER,
37
38
    /**
39
     * Align text to the baseline.
40
     */
41
    BASELINE,
42
43
    /**
44
     * Align text to the bottom.
45
     */
46
    BOTTOM
47
}
(-)src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java (+290 lines)
Lines 243-246 Link Here
243
243
244
244
245
    }
245
    }
246
    
247
    /**
248
     * ensure that font and color rich text attributes defined in a XSSFRichTextString
249
     * are passed to XSSFSimpleShape.
250
     *
251
     * See Bugzilla 54969.
252
     */
253
    public void testRichTextFontAndColor() {
254
    	XSSFWorkbook wb = new XSSFWorkbook();
255
        XSSFSheet sheet = wb.createSheet();
256
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
257
258
        XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4));
259
        XSSFRichTextString rt = new XSSFRichTextString("Test String");
260
261
        XSSFFont font = wb.createFont();
262
        font.setColor(new XSSFColor(new Color(0, 128, 128)));
263
        font.setFontName("Arial");
264
        rt.applyFont(font);
265
266
        shape.setText(rt);
267
268
        CTTextParagraph pr = shape.getCTShape().getTxBody().getPArray(0);
269
        assertEquals(1, pr.sizeOfRArray());
270
271
        CTTextCharacterProperties rPr = pr.getRArray(0).getRPr();
272
        assertEquals("Arial", rPr.getLatin().getTypeface());
273
        assertTrue(Arrays.equals(
274
                new byte[]{0, (byte)128, (byte)128} ,
275
                rPr.getSolidFill().getSrgbClr().getVal()));
276
    	
277
    }
278
279
    /**
280
     * Test setText single paragraph to ensure backwards compatibility
281
     */
282
    public void testSetTextSingleParagraph() {
283
    
284
    	XSSFWorkbook wb = new XSSFWorkbook();
285
        XSSFSheet sheet = wb.createSheet();
286
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
287
288
        XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4));
289
        XSSFRichTextString rt = new XSSFRichTextString("Test String");
290
291
        XSSFFont font = wb.createFont();
292
        font.setColor(new XSSFColor(new Color(0, 255, 255)));
293
        font.setFontName("Arial");
294
        rt.applyFont(font);
295
296
        shape.setText(rt);
297
        
298
        List<XSSFTextParagraph> paras = shape.getTextParagraphs();
299
        assertEquals(1, paras.size());
300
        assertEquals("Test String", paras.get(0).getText());
301
        
302
        List<XSSFTextRun> runs = paras.get(0).getTextRuns();
303
        assertEquals(1, runs.size());
304
        assertEquals("Arial", runs.get(0).getFontFamily());
305
        
306
        Color clr = runs.get(0).getFontColor(); 
307
        assertTrue(Arrays.equals(
308
                new int[] { 0, 255, 255 } ,
309
                new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() }));
310
    }
311
    
312
    /**
313
     * Test addNewTextParagraph 
314
     */
315
    public void testAddNewTextParagraph() {
316
    
317
    	XSSFWorkbook wb = new XSSFWorkbook();
318
        XSSFSheet sheet = wb.createSheet();
319
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
320
321
        XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4));
322
        
323
        XSSFTextParagraph para = shape.addNewTextParagraph();
324
        para.addNewTextRun().setText("Line 1");
325
                
326
        List<XSSFTextParagraph> paras = shape.getTextParagraphs();
327
        assertEquals(2, paras.size());	// this should be 2 as XSSFSimpleShape creates a default paragraph (no text), and then we add a string to that.
328
        
329
        List<XSSFTextRun> runs = para.getTextRuns();
330
        assertEquals(1, runs.size());
331
        assertEquals("Line 1", runs.get(0).getText());
332
    }
333
334
    /**
335
     * Test addNewTextParagraph using RichTextString
336
     */
337
    public void testAddNewTextParagraphWithRTS() {
338
    
339
    	XSSFWorkbook wb = new XSSFWorkbook();
340
        XSSFSheet sheet = wb.createSheet();
341
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
342
343
        XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4));
344
        XSSFRichTextString rt = new XSSFRichTextString("Test Rich Text String");
345
346
        XSSFFont font = wb.createFont();        
347
        font.setColor(new XSSFColor(new Color(0, 255, 255)));
348
        font.setFontName("Arial");
349
        rt.applyFont(font);
350
        
351
        XSSFFont midfont = wb.createFont();
352
        midfont.setColor(new XSSFColor(new Color(0, 255, 0)));
353
        rt.applyFont(5, 14, midfont);	// set the text "Rich Text" to be green and the default font
354
        
355
        XSSFTextParagraph para = shape.addNewTextParagraph(rt);
356
        
357
        // Save and re-load it
358
        wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
359
        sheet = wb.getSheetAt(0);
360
361
        // Check
362
        drawing = sheet.createDrawingPatriarch();
363
        
364
        List<XSSFShape> shapes = drawing.getShapes();
365
        assertEquals(1, shapes.size());
366
        assertTrue(shapes.get(0) instanceof XSSFSimpleShape); 
367
        
368
        XSSFSimpleShape sshape = (XSSFSimpleShape) shapes.get(0);
369
        
370
        List<XSSFTextParagraph> paras = sshape.getTextParagraphs();
371
        assertEquals(2, paras.size());	// this should be 2 as XSSFSimpleShape creates a default paragraph (no text), and then we add a string to that.  
372
        
373
        List<XSSFTextRun> runs = para.getTextRuns();
374
        assertEquals(3, runs.size());
375
        
376
        // first run properties
377
        assertEquals("Test ", runs.get(0).getText());
378
        assertEquals("Arial", runs.get(0).getFontFamily());
379
380
        Color clr = runs.get(0).getFontColor(); 
381
        assertTrue(Arrays.equals(
382
                new int[] { 0, 255, 255 } ,
383
                new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() }));
384
385
        // second run properties        
386
        assertEquals("Rich Text", runs.get(1).getText());
387
        assertEquals(XSSFFont.DEFAULT_FONT_NAME, runs.get(1).getFontFamily());
388
389
        clr = runs.get(1).getFontColor(); 
390
        assertTrue(Arrays.equals(
391
                new int[] { 0, 255, 0 } ,
392
                new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() }));        
393
        
394
        // third run properties
395
        assertEquals(" String", runs.get(2).getText());
396
        assertEquals("Arial", runs.get(2).getFontFamily());
397
        clr = runs.get(2).getFontColor(); 
398
        assertTrue(Arrays.equals(
399
                new int[] { 0, 255, 255 } ,
400
                new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() }));
401
    }    
402
    
403
    /**
404
     * Test add multiple paragraphs and retrieve text
405
     */
406
    public void testAddMultipleParagraphs() {
407
    
408
    	XSSFWorkbook wb = new XSSFWorkbook();
409
        XSSFSheet sheet = wb.createSheet();
410
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
411
412
        XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4));
413
        
414
        XSSFTextParagraph para = shape.addNewTextParagraph();
415
        para.addNewTextRun().setText("Line 1");
416
                
417
        para = shape.addNewTextParagraph();
418
        para.addNewTextRun().setText("Line 2");
419
        
420
        para = shape.addNewTextParagraph();
421
        para.addNewTextRun().setText("Line 3");
422
        
423
        List<XSSFTextParagraph> paras = shape.getTextParagraphs();
424
        assertEquals(4, paras.size());	// this should be 4 as XSSFSimpleShape creates a default paragraph (no text), and then we added 3 paragraphs
425
        assertEquals("Line 1\nLine 2\nLine 3", shape.getText());           
426
    }
427
    
428
    /**
429
     * Test setting the text, then adding multiple paragraphs and retrieve text
430
     */
431
    public void testSetAddMultipleParagraphs() {
432
    
433
    	XSSFWorkbook wb = new XSSFWorkbook();
434
        XSSFSheet sheet = wb.createSheet();
435
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
436
437
        XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4));
438
        
439
        shape.setText("Line 1");
440
                
441
        XSSFTextParagraph para = shape.addNewTextParagraph();
442
        para.addNewTextRun().setText("Line 2");
443
        
444
        para = shape.addNewTextParagraph();
445
        para.addNewTextRun().setText("Line 3");
446
        
447
        List<XSSFTextParagraph> paras = shape.getTextParagraphs();
448
        assertEquals(3, paras.size());	// this should be 3 as we overwrote the default paragraph with setText, then added 2 new paragraphs
449
        assertEquals("Line 1\nLine 2\nLine 3", shape.getText());
450
    }
451
    
452
    /**
453
     * Test reading text from a textbox in an existing file
454
     */
455
    public void testReadTextBox(){
456
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithDrawing.xlsx");
457
        XSSFSheet sheet = wb.getSheetAt(0);
458
        //the sheet has one relationship and it is XSSFDrawing
459
        List<POIXMLDocumentPart> rels = sheet.getRelations();
460
        assertEquals(1, rels.size());
461
        assertTrue(rels.get(0) instanceof XSSFDrawing);
462
463
        XSSFDrawing drawing = (XSSFDrawing)rels.get(0);
464
        //sheet.createDrawingPatriarch() should return the same instance of XSSFDrawing
465
        assertSame(drawing, sheet.createDrawingPatriarch());
466
        String drawingId = drawing.getPackageRelationship().getId();
467
468
        //there should be a relation to this drawing in the worksheet
469
        assertTrue(sheet.getCTWorksheet().isSetDrawing());
470
        assertEquals(drawingId, sheet.getCTWorksheet().getDrawing().getId());
471
472
        List<XSSFShape> shapes = drawing.getShapes();
473
        assertEquals(6, shapes.size());
474
475
        assertTrue(shapes.get(4) instanceof XSSFSimpleShape);
476
477
        XSSFSimpleShape textbox = (XSSFSimpleShape) shapes.get(4); 
478
        assertEquals("Sheet with various pictures\n(jpeg, png, wmf, emf and pict)", textbox.getText());
479
    }
480
481
    /**
482
     * Test reading multiple paragraphs from a textbox in an existing file
483
     */
484
    public void testReadTextBoxParagraphs(){
485
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithTextBox.xlsx");
486
        XSSFSheet sheet = wb.getSheetAt(0);
487
        //the sheet has one relationship and it is XSSFDrawing
488
        List<POIXMLDocumentPart> rels = sheet.getRelations();
489
        assertEquals(1, rels.size());
490
        assertTrue(rels.get(0) instanceof XSSFDrawing);
491
492
        XSSFDrawing drawing = (XSSFDrawing)rels.get(0);
493
        //sheet.createDrawingPatriarch() should return the same instance of XSSFDrawing
494
        assertSame(drawing, sheet.createDrawingPatriarch());
495
        String drawingId = drawing.getPackageRelationship().getId();
496
497
        //there should be a relation to this drawing in the worksheet
498
        assertTrue(sheet.getCTWorksheet().isSetDrawing());
499
        assertEquals(drawingId, sheet.getCTWorksheet().getDrawing().getId());
500
501
        List<XSSFShape> shapes = drawing.getShapes();
502
        assertEquals(1, shapes.size());
503
504
        assertTrue(shapes.get(0) instanceof XSSFSimpleShape);
505
506
        XSSFSimpleShape textbox = (XSSFSimpleShape) shapes.get(0);
507
        
508
        List<XSSFTextParagraph> paras = textbox.getTextParagraphs();
509
        assertEquals(3, paras.size());
510
        
511
        assertEquals("Line 2", paras.get(1).getText());	// check content of second paragraph
512
513
        assertEquals("Line 1\nLine 2\nLine 3", textbox.getText());	// check content of entire textbox
514
        
515
        // check attributes of paragraphs
516
        assertEquals(TextAlign.LEFT, paras.get(0).getTextAlign());
517
        assertEquals(TextAlign.CENTER, paras.get(1).getTextAlign());
518
        assertEquals(TextAlign.RIGHT, paras.get(2).getTextAlign());
519
        
520
        Color clr = paras.get(0).getTextRuns().get(0).getFontColor(); 
521
        assertTrue(Arrays.equals(
522
                new int[] { 255, 0, 0 } ,
523
                new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() }));
524
        
525
        clr = paras.get(1).getTextRuns().get(0).getFontColor(); 
526
        assertTrue(Arrays.equals(
527
                new int[] { 0, 255, 0 } ,
528
                new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() }));
529
        
530
        clr = paras.get(2).getTextRuns().get(0).getFontColor(); 
531
        assertTrue(Arrays.equals(
532
                new int[] { 0, 0, 255 } ,
533
                new int[] { clr.getRed(), clr.getGreen(), clr.getBlue() }));
534
        
535
    }
246
}
536
}

Return to bug 55292