File indexing completed on 2025-01-26 05:29:14
0001 <?php 0002 0003 namespace Intervention\Image\Gd; 0004 0005 use Intervention\Image\Image; 0006 0007 class Font extends \Intervention\Image\AbstractFont 0008 { 0009 /** 0010 * Get font size in points 0011 * 0012 * @return int 0013 */ 0014 protected function getPointSize() 0015 { 0016 return intval(ceil($this->size * 0.75)); 0017 } 0018 0019 /** 0020 * Filter function to access internal integer font values 0021 * 0022 * @return int 0023 */ 0024 private function getInternalFont() 0025 { 0026 $internalfont = is_null($this->file) ? 1 : $this->file; 0027 $internalfont = is_numeric($internalfont) ? $internalfont : false; 0028 0029 if ( ! in_array($internalfont, [1, 2, 3, 4, 5])) { 0030 throw new \Intervention\Image\Exception\NotSupportedException( 0031 sprintf('Internal GD font (%s) not available. Use only 1-5.', $internalfont) 0032 ); 0033 } 0034 0035 return intval($internalfont); 0036 } 0037 0038 /** 0039 * Get width of an internal font character 0040 * 0041 * @return int 0042 */ 0043 private function getInternalFontWidth() 0044 { 0045 return $this->getInternalFont() + 4; 0046 } 0047 0048 /** 0049 * Get height of an internal font character 0050 * 0051 * @return int 0052 */ 0053 private function getInternalFontHeight() 0054 { 0055 switch ($this->getInternalFont()) { 0056 case 1: 0057 return 8; 0058 0059 case 2: 0060 return 14; 0061 0062 case 3: 0063 return 14; 0064 0065 case 4: 0066 return 16; 0067 0068 case 5: 0069 return 16; 0070 } 0071 } 0072 0073 /** 0074 * Calculates bounding box of current font setting 0075 * 0076 * @return Array 0077 */ 0078 public function getBoxSize() 0079 { 0080 $box = []; 0081 0082 if ($this->hasApplicableFontFile()) { 0083 0084 // get bounding box with angle 0 0085 $box = imagettfbbox($this->getPointSize(), 0, $this->file, $this->text); 0086 0087 // rotate points manually 0088 if ($this->angle != 0) { 0089 0090 $angle = pi() * 2 - $this->angle * pi() * 2 / 360; 0091 0092 for ($i=0; $i<4; $i++) { 0093 $x = $box[$i * 2]; 0094 $y = $box[$i * 2 + 1]; 0095 $box[$i * 2] = cos($angle) * $x - sin($angle) * $y; 0096 $box[$i * 2 + 1] = sin($angle) * $x + cos($angle) * $y; 0097 } 0098 } 0099 0100 $box['width'] = intval(abs($box[4] - $box[0])); 0101 $box['height'] = intval(abs($box[5] - $box[1])); 0102 0103 } else { 0104 0105 // get current internal font size 0106 $width = $this->getInternalFontWidth(); 0107 $height = $this->getInternalFontHeight(); 0108 0109 if (strlen($this->text) == 0) { 0110 // no text -> no boxsize 0111 $box['width'] = 0; 0112 $box['height'] = 0; 0113 } else { 0114 // calculate boxsize 0115 $box['width'] = strlen($this->text) * $width; 0116 $box['height'] = $height; 0117 } 0118 } 0119 0120 return $box; 0121 } 0122 0123 /** 0124 * Draws font to given image at given position 0125 * 0126 * @param Image $image 0127 * @param int $posx 0128 * @param int $posy 0129 * @return void 0130 */ 0131 public function applyToImage(Image $image, $posx = 0, $posy = 0) 0132 { 0133 // parse text color 0134 $color = new Color($this->color); 0135 0136 if ($this->hasApplicableFontFile()) { 0137 0138 if ($this->angle != 0 || is_string($this->align) || is_string($this->valign)) { 0139 0140 $box = $this->getBoxSize(); 0141 0142 $align = is_null($this->align) ? 'left' : strtolower($this->align); 0143 $valign = is_null($this->valign) ? 'bottom' : strtolower($this->valign); 0144 0145 // correction on position depending on v/h alignment 0146 switch ($align.'-'.$valign) { 0147 0148 case 'center-top': 0149 $posx = $posx - round(($box[6]+$box[4])/2); 0150 $posy = $posy - round(($box[7]+$box[5])/2); 0151 break; 0152 0153 case 'right-top': 0154 $posx = $posx - $box[4]; 0155 $posy = $posy - $box[5]; 0156 break; 0157 0158 case 'left-top': 0159 $posx = $posx - $box[6]; 0160 $posy = $posy - $box[7]; 0161 break; 0162 0163 case 'center-center': 0164 case 'center-middle': 0165 $posx = $posx - round(($box[0]+$box[4])/2); 0166 $posy = $posy - round(($box[1]+$box[5])/2); 0167 break; 0168 0169 case 'right-center': 0170 case 'right-middle': 0171 $posx = $posx - round(($box[2]+$box[4])/2); 0172 $posy = $posy - round(($box[3]+$box[5])/2); 0173 break; 0174 0175 case 'left-center': 0176 case 'left-middle': 0177 $posx = $posx - round(($box[0]+$box[6])/2); 0178 $posy = $posy - round(($box[1]+$box[7])/2); 0179 break; 0180 0181 case 'center-bottom': 0182 $posx = $posx - round(($box[0]+$box[2])/2); 0183 $posy = $posy - round(($box[1]+$box[3])/2); 0184 break; 0185 0186 case 'right-bottom': 0187 $posx = $posx - $box[2]; 0188 $posy = $posy - $box[3]; 0189 break; 0190 0191 case 'left-bottom': 0192 $posx = $posx - $box[0]; 0193 $posy = $posy - $box[1]; 0194 break; 0195 } 0196 } 0197 0198 // enable alphablending for imagettftext 0199 imagealphablending($image->getCore(), true); 0200 0201 // draw ttf text 0202 imagettftext($image->getCore(), $this->getPointSize(), $this->angle, $posx, $posy, $color->getInt(), $this->file, $this->text); 0203 0204 } else { 0205 0206 // get box size 0207 $box = $this->getBoxSize(); 0208 $width = $box['width']; 0209 $height = $box['height']; 0210 0211 // internal font specific position corrections 0212 if ($this->getInternalFont() == 1) { 0213 $top_correction = 1; 0214 $bottom_correction = 2; 0215 } elseif ($this->getInternalFont() == 3) { 0216 $top_correction = 2; 0217 $bottom_correction = 4; 0218 } else { 0219 $top_correction = 3; 0220 $bottom_correction = 4; 0221 } 0222 0223 // x-position corrections for horizontal alignment 0224 switch (strtolower($this->align)) { 0225 case 'center': 0226 $posx = ceil($posx - ($width / 2)); 0227 break; 0228 0229 case 'right': 0230 $posx = ceil($posx - $width) + 1; 0231 break; 0232 } 0233 0234 // y-position corrections for vertical alignment 0235 switch (strtolower($this->valign)) { 0236 case 'center': 0237 case 'middle': 0238 $posy = ceil($posy - ($height / 2)); 0239 break; 0240 0241 case 'top': 0242 $posy = ceil($posy - $top_correction); 0243 break; 0244 0245 default: 0246 case 'bottom': 0247 $posy = round($posy - $height + $bottom_correction); 0248 break; 0249 } 0250 0251 // draw text 0252 imagestring($image->getCore(), $this->getInternalFont(), $posx, $posy, $this->text, $color->getInt()); 0253 } 0254 } 0255 }