Completed
Push — development ( 29b82e...e01cc9 )
by Ashutosh
10:05
created

Text::render()   F

Complexity

Conditions 21
Paths 1921

Size

Total Lines 118
Code Lines 68

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 68
dl 0
loc 118
rs 0
c 0
b 0
f 0
cc 21
nc 1921
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @package dompdf
4
 * @link    http://dompdf.github.com/
5
 * @author  Benj Carson <[email protected]>
6
 * @author  Helmut Tischer <[email protected]>
7
 * @author  Fabien Ménager <[email protected]>
8
 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
9
 */
10
namespace Dompdf\Renderer;
11
12
use Dompdf\Adapter\CPDF;
13
use Dompdf\Frame;
14
15
/**
16
 * Renders text frames
17
 *
18
 * @package dompdf
19
 */
20
class Text extends AbstractRenderer
21
{
22
    /** Thickness of underline. Screen: 0.08, print: better less, e.g. 0.04 */
23
    const DECO_THICKNESS = 0.02;
24
25
    //Tweaking if $base and $descent are not accurate.
26
    //Check method_exists( $this->_canvas, "get_cpdf" )
27
    //- For cpdf these can and must stay 0, because font metrics are used directly.
28
    //- For other renderers, if different values are wanted, separate the parameter sets.
29
    //  But $size and $size-$height seem to be accurate enough
30
31
    /** Relative to bottom of text, as fraction of height */
32
    const UNDERLINE_OFFSET = 0.0;
33
34
    /** Relative to top of text */
35
    const OVERLINE_OFFSET = 0.0;
36
37
    /** Relative to centre of text. */
38
    const LINETHROUGH_OFFSET = 0.0;
39
40
    /** How far to extend lines past either end, in pt */
41
    const DECO_EXTENSION = 0.0;
42
43
    /**
44
     * @param \Dompdf\FrameDecorator\Text $frame
45
     */
46
    function render(Frame $frame)
47
    {
48
        $text = $frame->get_text();
49
        if (trim($text) === "") {
50
            return;
51
        }
52
53
        $style = $frame->get_style();
54
        list($x, $y) = $frame->get_position();
55
        $cb = $frame->get_containing_block();
56
57
        if (($ml = $style->margin_left) === "auto" || $ml === "none") {
58
            $ml = 0;
59
        }
60
61
        if (($pl = $style->padding_left) === "auto" || $pl === "none") {
62
            $pl = 0;
63
        }
64
65
        if (($bl = $style->border_left_width) === "auto" || $bl === "none") {
66
            $bl = 0;
67
        }
68
69
        $x += (float)$style->length_in_pt(array($ml, $pl, $bl), $cb["w"]);
70
71
        $font = $style->font_family;
72
        $size = $frame_font_size = $style->font_size;
73
        $word_spacing = $frame->get_text_spacing() + (float)$style->length_in_pt($style->word_spacing);
74
        $char_spacing = (float)$style->length_in_pt($style->letter_spacing);
75
        $width = $style->width;
76
77
        /*$text = str_replace(
78
          array("{PAGE_NUM}"),
79
          array($this->_canvas->get_page_number()),
80
          $text
81
        );*/
82
83
        $this->_canvas->text($x, $y, $text,
84
            $font, $size,
85
            $style->color, $word_spacing, $char_spacing);
86
87
        $line = $frame->get_containing_line();
88
89
        // FIXME Instead of using the tallest frame to position,
90
        // the decoration, the text should be well placed
91
        if (false && $line->tallest_frame) {
92
            $base_frame = $line->tallest_frame;
93
            $style = $base_frame->get_style();
94
            $size = $style->font_size;
95
        }
96
97
        $line_thickness = $size * self::DECO_THICKNESS;
98
        $underline_offset = $size * self::UNDERLINE_OFFSET;
99
        $overline_offset = $size * self::OVERLINE_OFFSET;
100
        $linethrough_offset = $size * self::LINETHROUGH_OFFSET;
101
        $underline_position = -0.08;
102
103
        if ($this->_canvas instanceof CPDF) {
104
            $cpdf_font = $this->_canvas->get_cpdf()->fonts[$style->font_family];
105
106
            if (isset($cpdf_font["UnderlinePosition"])) {
107
                $underline_position = $cpdf_font["UnderlinePosition"] / 1000;
108
            }
109
110
            if (isset($cpdf_font["UnderlineThickness"])) {
111
                $line_thickness = $size * ($cpdf_font["UnderlineThickness"] / 1000);
112
            }
113
        }
114
115
        $descent = $size * $underline_position;
116
        $base = $size;
117
118
        // Handle text decoration:
119
        // http://www.w3.org/TR/CSS21/text.html#propdef-text-decoration
120
121
        // Draw all applicable text-decorations.  Start with the root and work our way down.
122
        $p = $frame;
123
        $stack = array();
124
        while ($p = $p->get_parent()) {
125
            $stack[] = $p;
126
        }
127
128
        while (isset($stack[0])) {
129
            $f = array_pop($stack);
130
131
            if (($text_deco = $f->get_style()->text_decoration) === "none") {
132
                continue;
133
            }
134
135
            $deco_y = $y; //$line->y;
136
            $color = $f->get_style()->color;
137
138
            switch ($text_deco) {
139
                default:
140
                    continue;
141
142
                case "underline":
143
                    $deco_y += $base - $descent + $underline_offset + $line_thickness / 2;
144
                    break;
145
146
                case "overline":
147
                    $deco_y += $overline_offset + $line_thickness / 2;
148
                    break;
149
150
                case "line-through":
151
                    $deco_y += $base * 0.7 + $linethrough_offset;
152
                    break;
153
            }
154
155
            $dx = 0;
156
            $x1 = $x - self::DECO_EXTENSION;
157
            $x2 = $x + $width + $dx + self::DECO_EXTENSION;
158
            $this->_canvas->line($x1, $deco_y, $x2, $deco_y, $color, $line_thickness);
159
        }
160
161
        if ($this->_dompdf->getOptions()->getDebugLayout() && $this->_dompdf->getOptions()->getDebugLayoutLines()) {
162
            $text_width = $this->_dompdf->getFontMetrics()->getTextWidth($text, $font, $frame_font_size);
163
            $this->_debug_layout(array($x, $y, $text_width + ($line->wc - 1) * $word_spacing, $frame_font_size), "orange", array(0.5, 0.5));
164
        }
165
    }
166
}
167