All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ofdrw.layout.element.TxtLineBlock Maven / Gradle / Ivy

The newest version!
package org.ofdrw.layout.element;

import org.ofdrw.layout.Rectangle;

import java.util.LinkedList;
import java.util.List;

/**
 * 行内文字
 *
 * @author 权观宇
 * @since 2020-03-13 01:03:54
 */
public class TxtLineBlock {
    /**
     * 行内字体浮动方向
     * 

* 默认:左浮动 */ private TextAlign textAlign; /** * 行内所在元素 */ private List inlineSpans; /** * 最高的文字高度 */ private Double maxSpanHeight = 0d; /** * 行宽度 */ private Double width = 0d; /** * 行间距 */ private Double lineSpace; /** * 行最大宽度 */ private double lineMaxAvailableWidth; private TxtLineBlock() { } /** * 创建行块 * * @param lineMaxAvailableWidth 行内运行最大宽度 * @param lineSpace 行间距 */ public TxtLineBlock(double lineMaxAvailableWidth, Double lineSpace) { this(lineMaxAvailableWidth, lineSpace, TextAlign.left); } /** * 创建行块 * * @param lineMaxAvailableWidth 行内运行最大宽度 * @param lineSpace 行间距 * @param textAlign 行内字体浮动方式 */ public TxtLineBlock(double lineMaxAvailableWidth, Double lineSpace, TextAlign textAlign) { this.lineMaxAvailableWidth = lineMaxAvailableWidth; this.lineSpace = lineSpace; if (textAlign == null) { textAlign = TextAlign.left; } this.textAlign = textAlign; this.inlineSpans = new LinkedList<>(); } /** * 尝试向行中加入文字单元 * * @param span 文字单元 * @return true - 足够容纳可以加入;false - 无法容纳无法加入 */ public boolean tryAdd(Span span) { Rectangle rec = span.blockSize(); if (rec.getWidth() + width > lineMaxAvailableWidth) { // 空间不足不足以容纳元素 return false; } width += rec.getWidth(); if (rec.getHeight() > maxSpanHeight) { // 判断行高 maxSpanHeight = rec.getHeight(); } inlineSpans.add(span); return true; } /** * 尝试通过切分文字单元的方式加入行内 *

* 如果文字单元能够被切分,那么会返回切分后剩余部分文字单元 *

* 如果切分之后也无法加入行中,那么返回空。 * * @param span 待切分文字单元 * @return null 表示行的空间耗尽,无法加入新的文字;切分后的剩余的文字单元 */ public Span trySplitAdd(Span span) { if (span.isIntegrity()) { throw new IllegalStateException("文字单元(Span)不可拆分"); } // 获取剩余宽度 double remainWidth = lineMaxAvailableWidth - width; // 文字单元切分点 int splitIndex = 0; // 行中的剩余空间不足且Span可以被换行等分割 List txtGlyphs = span.glyphList(); for (int i = 0; i < txtGlyphs.size(); i++) { TxtGlyph txt = txtGlyphs.get(i); if (txt.getW() <= remainWidth) { remainWidth -= txt.getW(); continue; } if (i == 0) { // 一个字符都无法加入到行内,说明行空间基本耗尽,需要换行 return null; } // 找到前一个字符 splitIndex = i; break; } // 切分文字单元 Span[] split = span.split(splitIndex); // 前半段放入行中 tryAdd(split[0]); // 后半段返回,准备加入下一段 return split[1]; } public boolean isEmpty() { return inlineSpans.isEmpty(); } /** * 获取行内所有文字单元 * * @return 行内所有文字单元 */ public List getInlineSpans() { return inlineSpans; } /** * 获取行所占据的区域大小 * * @return 行占据区域 */ public Rectangle size() { return new Rectangle(width, maxSpanHeight + lineSpace); } /** * 获取整个行占据的高度(文字高度 + 行间距) * * @return 行占据的高度 */ public double getHeight() { return maxSpanHeight + lineSpace; } /** * 获取行间距 * * @return 行间距 */ public Double getLineSpace() { return lineSpace; } /** * 行内最高元素高度 * * @return 行内最高元素高度 */ public Double getMaxSpanHeight() { return maxSpanHeight; } /** * 行内容元素宽度 * * @return 行宽度 */ public Double getWidth() { return width; } /** * 获取文字在行内的浮动方式 *

* 默认:左浮动 * * @return 浮动方式 */ public TextAlign getTextAlign() { return textAlign; } /** * 获取 行内可用最大宽度 * * @return 行内可用最大宽度 */ public double getLineMaxAvailableWidth() { return lineMaxAvailableWidth; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy