Commit | Line | Data |
---|---|---|
7f254ad8 AE |
1 | <?php |
2 | /** | |
3 | * @package dompdf | |
4 | * @link http://dompdf.github.com/ | |
5 | * @author Benj Carson <benjcarson@digitaljunkies.ca> | |
6 | * @author Brian Sweeney <eclecticgeek@gmail.com> | |
7 | * @author Fabien Ménager <fabien.menager@gmail.com> | |
8 | * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License | |
9 | */ | |
10 | namespace Dompdf\FrameDecorator; | |
11 | ||
12 | use Dompdf\Dompdf; | |
13 | use Dompdf\Frame; | |
14 | use Dompdf\Exception; | |
15 | use DOMText; | |
16 | use Dompdf\FontMetrics; | |
17 | ||
18 | /** | |
19 | * Decorates Frame objects for text layout | |
20 | * | |
21 | * @access private | |
22 | * @package dompdf | |
23 | */ | |
24 | class Text extends AbstractFrameDecorator | |
25 | { | |
26 | ||
27 | // protected members | |
28 | protected $_text_spacing; | |
29 | ||
30 | function __construct(Frame $frame, Dompdf $dompdf) | |
31 | { | |
32 | if (!$frame->is_text_node()) { | |
33 | throw new Exception("Text_Decorator can only be applied to #text nodes."); | |
34 | } | |
35 | ||
36 | parent::__construct($frame, $dompdf); | |
37 | $this->_text_spacing = null; | |
38 | } | |
39 | ||
40 | //........................................................................ | |
41 | ||
42 | function reset() | |
43 | { | |
44 | parent::reset(); | |
45 | $this->_text_spacing = null; | |
46 | } | |
47 | ||
48 | //........................................................................ | |
49 | ||
50 | // Accessor methods | |
51 | function get_text_spacing() | |
52 | { | |
53 | return $this->_text_spacing; | |
54 | } | |
55 | ||
56 | function get_text() | |
57 | { | |
58 | // FIXME: this should be in a child class (and is incorrect) | |
59 | // if ( $this->_frame->get_style()->content !== "normal" ) { | |
60 | // $this->_frame->get_node()->data = $this->_frame->get_style()->content; | |
61 | // $this->_frame->get_style()->content = "normal"; | |
62 | // } | |
63 | ||
64 | // Helpers::pre_r("---"); | |
65 | // $style = $this->_frame->get_style(); | |
66 | // var_dump($text = $this->_frame->get_node()->data); | |
67 | // var_dump($asc = utf8_decode($text)); | |
68 | // for ($i = 0; $i < strlen($asc); $i++) | |
69 | // Helpers::pre_r("$i: " . $asc[$i] . " - " . ord($asc[$i])); | |
70 | // Helpers::pre_r("width: " . $this->_dompdf->getFontMetrics()->getTextWidth($text, $style->font_family, $style->font_size)); | |
71 | ||
72 | return $this->_frame->get_node()->data; | |
73 | } | |
74 | ||
75 | //........................................................................ | |
76 | ||
77 | // Vertical margins & padding do not apply to text frames | |
78 | ||
79 | // http://www.w3.org/TR/CSS21/visudet.html#inline-non-replaced: | |
80 | // | |
81 | // The vertical padding, border and margin of an inline, non-replaced box | |
82 | // start at the top and bottom of the content area, not the | |
83 | // 'line-height'. But only the 'line-height' is used to calculate the | |
84 | // height of the line box. | |
85 | function get_margin_height() | |
86 | { | |
87 | // This function is called in add_frame_to_line() and is used to | |
88 | // determine the line height, so we actually want to return the | |
89 | // 'line-height' property, not the actual margin box | |
90 | $style = $this->get_parent()->get_style(); | |
91 | $font = $style->font_family; | |
92 | $size = $style->font_size; | |
93 | ||
94 | /* | |
95 | Helpers::pre_r('-----'); | |
96 | Helpers::pre_r($style->line_height); | |
97 | Helpers::pre_r($style->font_size); | |
98 | Helpers::pre_r($this->_dompdf->getFontMetrics()->getFontHeight($font, $size)); | |
99 | Helpers::pre_r(($style->line_height / $size) * $this->_dompdf->getFontMetrics()->getFontHeight($font, $size)); | |
100 | */ | |
101 | ||
102 | return ($style->line_height / ($size > 0 ? $size : 1)) * $this->_dompdf->getFontMetrics()->getFontHeight($font, $size); | |
103 | ||
104 | } | |
105 | ||
106 | function get_padding_box() | |
107 | { | |
108 | $pb = $this->_frame->get_padding_box(); | |
109 | $pb[3] = $pb["h"] = $this->_frame->get_style()->height; | |
110 | ||
111 | return $pb; | |
112 | } | |
113 | //........................................................................ | |
114 | ||
115 | // Set method | |
116 | function set_text_spacing($spacing) | |
117 | { | |
118 | $style = $this->_frame->get_style(); | |
119 | ||
120 | $this->_text_spacing = $spacing; | |
121 | $char_spacing = $style->length_in_pt($style->letter_spacing); | |
122 | ||
123 | // Re-adjust our width to account for the change in spacing | |
124 | $style->width = $this->_dompdf->getFontMetrics()->getTextWidth($this->get_text(), $style->font_family, $style->font_size, $spacing, $char_spacing); | |
125 | } | |
126 | ||
127 | //........................................................................ | |
128 | ||
129 | // Recalculate the text width | |
130 | function recalculate_width() | |
131 | { | |
132 | $style = $this->get_style(); | |
133 | $text = $this->get_text(); | |
134 | $size = $style->font_size; | |
135 | $font = $style->font_family; | |
136 | $word_spacing = $style->length_in_pt($style->word_spacing); | |
137 | $char_spacing = $style->length_in_pt($style->letter_spacing); | |
138 | ||
139 | return $style->width = $this->_dompdf->getFontMetrics()->getTextWidth($text, $font, $size, $word_spacing, $char_spacing); | |
140 | } | |
141 | ||
142 | //........................................................................ | |
143 | ||
144 | // Text manipulation methods | |
145 | ||
146 | // split the text in this frame at the offset specified. The remaining | |
147 | // text is added a sibling frame following this one and is returned. | |
148 | function split_text($offset) | |
149 | { | |
150 | if ($offset == 0) { | |
151 | return null; | |
152 | } | |
153 | ||
154 | $split = $this->_frame->get_node()->splitText($offset); | |
155 | ||
156 | $deco = $this->copy($split); | |
157 | ||
158 | $p = $this->get_parent(); | |
159 | $p->insert_child_after($deco, $this, false); | |
160 | ||
161 | if ($p instanceof Inline) { | |
162 | $p->split($deco); | |
163 | } | |
164 | ||
165 | return $deco; | |
166 | } | |
167 | ||
168 | //........................................................................ | |
169 | ||
170 | function delete_text($offset, $count) | |
171 | { | |
172 | $this->_frame->get_node()->deleteData($offset, $count); | |
173 | } | |
174 | ||
175 | //........................................................................ | |
176 | ||
177 | function set_text($text) | |
178 | { | |
179 | $this->_frame->get_node()->data = $text; | |
180 | } | |
181 | ||
182 | } |