Вход Регистрация
Файл: vendor/intervention/image/src/Drivers/AbstractFontProcessor.php
Строк: 326
<?php

declare(strict_types=1);

namespace 
InterventionImageDrivers;

use 
InterventionImageExceptionsFontException;
use 
InterventionImageGeometryPoint;
use 
InterventionImageGeometryRectangle;
use 
InterventionImageInterfacesFontInterface;
use 
InterventionImageInterfacesFontProcessorInterface;
use 
InterventionImageInterfacesPointInterface;
use 
InterventionImageTypographyLine;
use 
InterventionImageTypographyTextBlock;

abstract class 
AbstractFontProcessor implements FontProcessorInterface
{
    
/**
     * {@inheritdoc}
     *
     * @see FontProcessorInterface::textBlock()
     */
    
public function textBlock(string $textFontInterface $fontPointInterface $position): TextBlock
    
{
        
$lines $this->wrapTextBlock(new TextBlock($text), $font);
        
$pivot $this->buildPivot($lines$font$position);

        
$leading $this->leading($font);
        
$blockWidth $this->boxSize((string) $lines->longestLine(), $font)->width();

        
$x $pivot->x();
        
$y $font->hasFilename() ? $pivot->y() + $this->capHeight($font) : $pivot->y();
        
$xAdjustment 0;

        
// adjust line positions according to alignment
        
foreach ($lines as $line) {
            
$lineBoxSize $this->boxSize((string) $line$font);
            
$lineWidth $lineBoxSize->width() + $lineBoxSize->pivot()->x();
            
$xAdjustment $font->alignment() === 'left' $blockWidth $lineWidth;
            
$xAdjustment $font->alignment() === 'right' intval(round($xAdjustment)) : $xAdjustment;
            
$xAdjustment $font->alignment() === 'center' intval(round($xAdjustment 2)) : $xAdjustment;
            
$position = new Point($x $xAdjustment$y);
            
$position->rotate($font->angle(), $pivot);
            
$line->setPosition($position);
            
$y += $leading;
        }

        return 
$lines;
    }

    
/**
     * {@inheritdoc}
     *
     * @see FontProcessorInterface::nativeFontSize()
     */
    
public function nativeFontSize(FontInterface $font): float
    
{
        return 
$font->size();
    }

    
/**
     * {@inheritdoc}
     *
     * @see FontProcessorInterface::typographicalSize()
     */
    
public function typographicalSize(FontInterface $font): int
    
{
        return 
$this->boxSize('Hy'$font)->height();
    }

    
/**
     * {@inheritdoc}
     *
     * @see FontProcessorInterface::capHeight()
     */
    
public function capHeight(FontInterface $font): int
    
{
        return 
$this->boxSize('T'$font)->height();
    }

    
/**
     * {@inheritdoc}
     *
     * @see FontProcessorInterface::leading()
     */
    
public function leading(FontInterface $font): int
    
{
        return 
intval(round($this->typographicalSize($font) * $font->lineHeight()));
    }

    
/**
     * Reformat a text block by wrapping each line before the given maximum width
     *
     * @param TextBlock $block
     * @param FontInterface $font
     * @throws FontException
     * @return TextBlock
     */
    
protected function wrapTextBlock(TextBlock $blockFontInterface $font): TextBlock
    
{
        
$newLines = [];
        foreach (
$block as $line) {
            foreach (
$this->wrapLine($line$font) as $newLine) {
                
$newLines[] = $newLine;
            }
        }

        return 
$block->setLines($newLines);
    }

    
/**
     * Check if a line exceeds the given maximum width and wrap it if necessary.
     * The output will be an array of formatted lines that are all within the
     * maximum width.
     *
     * @param Line $line
     * @param FontInterface $font
     * @throws FontException
     * @return array<Line>
     */
    
protected function wrapLine(Line $lineFontInterface $font): array
    {
        
// no wrap width - no wrapping
        
if (is_null($font->wrapWidth())) {
            return [
$line];
        }

        
$wrapped = [];
        
$formattedLine = new Line();

        foreach (
$line as $word) {
            
// calculate width of newly formatted line
            
$lineWidth $this->boxSize(match ($formattedLine->count()) {
                
=> $word,
                default => 
$formattedLine ' ' $word,
            }, 
$font)->width();

            
// decide if word fits on current line or a new line must be created
            
if ($line->count() === || $lineWidth <= $font->wrapWidth()) {
                
$formattedLine->add($word);
            } else {
                if (
$formattedLine->count() !== 0) {
                    
$wrapped[] = $formattedLine;
                }
                
$formattedLine = new Line($word);
            }
        }

        
$wrapped[] = $formattedLine;

        return 
$wrapped;
    }

    
/**
     * Build pivot point of textblock according to the font settings and based on given position
     *
     * @param TextBlock $block
     * @param FontInterface $font
     * @param PointInterface $position
     * @throws FontException
     * @return PointInterface
     */
    
protected function buildPivot(TextBlock $blockFontInterface $fontPointInterface $position): PointInterface
    
{
        
// bounding box
        
$box = new Rectangle(
            
$this->boxSize((string) $block->longestLine(), $font)->width(),
            
$this->leading($font) * ($block->count() - 1) + $this->capHeight($font)
        );

        
// set position
        
$box->setPivot($position);

        
// alignment
        
$box->align($font->alignment());
        
$box->valign($font->valignment());
        
$box->rotate($font->angle());

        return 
$box->last();
    }
}
Онлайн: 2
Реклама