Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
96 / 96 |
|
100.00% |
1 / 1 |
CRAP | |
100.00% |
1 / 1 |
Paragraph | |
100.00% |
96 / 96 |
|
100.00% |
1 / 1 |
31 | |
100.00% |
1 / 1 |
write | |
100.00% |
96 / 96 |
|
100.00% |
1 / 1 |
31 |
1 | <?php |
2 | |
3 | /** |
4 | * This file is part of PHPWord - A pure PHP library for reading and writing |
5 | * word processing documents. |
6 | * |
7 | * PHPWord is free software distributed under the terms of the GNU Lesser |
8 | * General Public License version 3 as published by the Free Software Foundation. |
9 | * |
10 | * For the full copyright and license information, please read the LICENSE |
11 | * file that was distributed with this source code. For the full list of |
12 | * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. |
13 | * |
14 | * @see https://github.com/PHPOffice/PHPWord |
15 | * |
16 | * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 |
17 | */ |
18 | |
19 | namespace PhpOffice\PhpWord\Writer\ODText\Style; |
20 | |
21 | use PhpOffice\PhpWord\Settings; |
22 | use PhpOffice\PhpWord\Shared\Converter; |
23 | use PhpOffice\PhpWord\SimpleType\Jc; |
24 | use PhpOffice\PhpWord\Style; |
25 | |
26 | /** |
27 | * Font style writer. |
28 | * |
29 | * @since 0.10.0 |
30 | */ |
31 | class Paragraph extends AbstractStyle |
32 | { |
33 | private const BIDI_MAP = [ |
34 | Jc::END => Jc::LEFT, |
35 | Jc::START => Jc::RIGHT, |
36 | ]; |
37 | |
38 | private const NON_BIDI_MAP = [ |
39 | Jc::START => Jc::LEFT, |
40 | Jc::END => Jc::RIGHT, |
41 | ]; |
42 | |
43 | /** |
44 | * Write style. |
45 | */ |
46 | public function write(): void |
47 | { |
48 | $style = $this->getStyle(); |
49 | if (!$style instanceof Style\Paragraph) { |
50 | return; |
51 | } |
52 | $xmlWriter = $this->getXmlWriter(); |
53 | |
54 | $marginTop = $style->getSpaceBefore(); |
55 | $marginBottom = $style->getSpaceAfter(); |
56 | |
57 | $xmlWriter->startElement('style:style'); |
58 | |
59 | $styleName = (string) $style->getStyleName(); |
60 | $styleAuto = false; |
61 | $mpm = ''; |
62 | $psm = ''; |
63 | $pagestart = -1; |
64 | $breakafter = $breakbefore = $breakauto = false; |
65 | if ($style->isAuto()) { |
66 | if (substr($styleName, 0, 2) === 'PB') { |
67 | $styleAuto = true; |
68 | $breakafter = true; |
69 | } elseif (substr($styleName, 0, 2) === 'SB') { |
70 | $styleAuto = true; |
71 | $mpm = 'Standard' . substr($styleName, 2); |
72 | $psn = $style->getNumLevel(); |
73 | $pagestart = $psn; |
74 | } elseif (substr($styleName, 0, 2) === 'HD') { |
75 | $styleAuto = true; |
76 | $psm = 'Heading_' . substr($styleName, 2); |
77 | $stylep = Style::getStyle($psm); |
78 | if ($stylep instanceof Style\Font) { |
79 | if (method_exists($stylep, 'getParagraph')) { |
80 | $stylep = $stylep->getParagraph(); |
81 | } |
82 | } |
83 | if ($stylep instanceof Style\Paragraph) { |
84 | if ($stylep->hasPageBreakBefore()) { |
85 | $breakbefore = true; |
86 | } |
87 | } |
88 | } elseif (substr($styleName, 0, 2) === 'HE') { |
89 | $styleAuto = true; |
90 | $psm = 'Heading_' . substr($styleName, 2); |
91 | $breakauto = true; |
92 | } else { |
93 | $styleAuto = true; |
94 | $psm = 'Normal'; |
95 | if (preg_match('/^P\\d+_(\\w+)$/', $styleName, $matches)) { |
96 | $psm = $matches[1]; |
97 | } |
98 | } |
99 | } |
100 | |
101 | $xmlWriter->writeAttribute('style:name', $style->getStyleName()); |
102 | $xmlWriter->writeAttribute('style:family', 'paragraph'); |
103 | if ($styleAuto) { |
104 | $xmlWriter->writeAttributeIf($psm !== '', 'style:parent-style-name', $psm); |
105 | $xmlWriter->writeAttributeIf($mpm !== '', 'style:master-page-name', $mpm); |
106 | } |
107 | |
108 | $xmlWriter->startElement('style:paragraph-properties'); |
109 | if ($styleAuto) { |
110 | if ($breakafter) { |
111 | $xmlWriter->writeAttribute('fo:break-after', 'page'); |
112 | $xmlWriter->writeAttribute('fo:margin-top', '0cm'); |
113 | $xmlWriter->writeAttribute('fo:margin-bottom', '0cm'); |
114 | } elseif ($breakbefore) { |
115 | $xmlWriter->writeAttribute('fo:break-before', 'page'); |
116 | } elseif ($breakauto) { |
117 | $xmlWriter->writeAttribute('fo:break-before', 'auto'); |
118 | } |
119 | if ($pagestart > 0) { |
120 | $xmlWriter->writeAttribute('style:page-number', $pagestart); |
121 | } |
122 | } |
123 | if (!$breakafter && !$breakbefore && !$breakauto) { |
124 | $twipToPoint = Converter::INCH_TO_TWIP / Converter::INCH_TO_POINT; // 20 |
125 | $xmlWriter->writeAttributeIf($marginTop !== null, 'fo:margin-top', ($marginTop / $twipToPoint) . 'pt'); |
126 | $xmlWriter->writeAttributeIf($marginBottom !== null, 'fo:margin-bottom', ($marginBottom / $twipToPoint) . 'pt'); |
127 | } |
128 | $alignment = $style->getAlignment(); |
129 | $bidi = $style->isBidi(); |
130 | $defaultRtl = Settings::isDefaultRtl(); |
131 | if ($alignment === '' && $bidi !== null) { |
132 | $alignment = Jc::START; |
133 | } |
134 | if ($bidi) { |
135 | $alignment = self::BIDI_MAP[$alignment] ?? $alignment; |
136 | } elseif ($defaultRtl !== null) { |
137 | $alignment = self::NON_BIDI_MAP[$alignment] ?? $alignment; |
138 | } |
139 | $xmlWriter->writeAttributeIf($alignment !== '', 'fo:text-align', $alignment); |
140 | $temp = $style->getLineHeight(); |
141 | $xmlWriter->writeAttributeIf($temp !== null, 'fo:line-height', ((string) ($temp * 100) . '%')); |
142 | $xmlWriter->writeAttributeIf($style->hasPageBreakBefore() === true, 'fo:break-before', 'page'); |
143 | |
144 | $tabs = $style->getTabs(); |
145 | if ($tabs !== null && count($tabs) > 0) { |
146 | $xmlWriter->startElement('style:tab-stops'); |
147 | foreach ($tabs as $tab) { |
148 | $xmlWriter->startElement('style:tab-stop'); |
149 | $xmlWriter->writeAttribute('style:type', $tab->getType()); |
150 | $xmlWriter->writeAttribute('style:position', (string) ($tab->getPosition() / Converter::INCH_TO_TWIP) . 'in'); |
151 | $xmlWriter->endElement(); |
152 | } |
153 | $xmlWriter->endElement(); |
154 | } |
155 | |
156 | //Right to left |
157 | $xmlWriter->writeAttributeIf($style->isBidi(), 'style:writing-mode', 'rl-tb'); |
158 | |
159 | //Indentation |
160 | $indent = $style->getIndentation(); |
161 | //if ($indent instanceof \PhpOffice\PhpWord\Style\Indentation) { |
162 | if (!empty($indent)) { |
163 | $marg = $indent->getLeft(); |
164 | $xmlWriter->writeAttributeIf($marg !== null, 'fo:margin-left', (string) ($marg / Converter::INCH_TO_TWIP) . 'in'); |
165 | $marg = $indent->getRight(); |
166 | $xmlWriter->writeAttributeIf($marg !== null, 'fo:margin-right', (string) ($marg / Converter::INCH_TO_TWIP) . 'in'); |
167 | } |
168 | |
169 | $xmlWriter->endElement(); //style:paragraph-properties |
170 | |
171 | if ($styleAuto && substr($styleName, 0, 2) === 'SB') { |
172 | $xmlWriter->startElement('style:text-properties'); |
173 | $xmlWriter->writeAttribute('text:display', 'none'); |
174 | $xmlWriter->endElement(); |
175 | } |
176 | |
177 | $xmlWriter->endElement(); //style:style |
178 | } |
179 | } |