行構造與間距演算法
字元叢集與換行位置
段落先取得 Unicode 提供的換行位置,但絕不拆開已完成字形處理的字元叢集(cluster)。同一字元叢集的字形會組成不可分割的排版單位。若各單位的字幅為 \(a_i\)、縮排為 \(h\),候選行寬是 \(W = h + \sum_i a_i\);加入下一個單位會超過 max_width 時,便回到最近的合法換行位置。
定位點與縮排
位置 \(x\) 的 Tab 字元會前進到第一個大於 \(x\) 的指定定位點。沒有可用定位點時,以預設間距 \(T\) 計算 \(\Delta x = T - (x \mod T)\)。首行與後續行分別使用 first_line_indent 與 hanging_indent。
對齊與左右齊行
可用寬度 \(M\)、行寬 \(W\) 時,起始、置中、末端的位移為 \(0,(M-W)/2,M-W\)。非末行的左右對齊把剩餘寬度平均分給 \(N_{\text{space}}\) 個可調空白:
\[
\delta=(M-W)/N_{\text{space}}.
\]
增加的是字幅,不會改動字形輪廓。
Paragraph(
spans,
max_width=None,
max_height=None,
align='start',
line_height=None,
first_line_indent=0.0,
hanging_indent=0.0,
paragraph_spacing=0.0,
tab_stops=(),
default_tab_width=None,
)
保存帶樣式的文字片段,以及演算法使用的寬高、縮排、對齊、定位點與行距限制。
LineLayout(
runs,
baseline,
advance,
logical_bounds,
ink_bounds,
horizontal_overflow=0.0,
source_range=None,
explicitly_terminated=False,
reading_order=(),
)
記錄一行的字形列、字幅、邏輯與墨跡範圍、基線、原文範圍及結束方式。
TextMeasurement(
advance,
logical_bounds,
ink_bounds,
baselines,
horizontal_overflow,
vertical_overflow,
)
彙整整個段落的範圍、基線、行數、閱讀順序與水平/垂直溢位。
垂直排版與溢位
有明確行高 \(H\) 時,相鄰基線相差 \(H\);否則 GlyphKit 依該行最大的文字樣式推導行高。max_height 限制可接受的行數,未容納的高度記入 vertical_overflow,不會改寫既有字形資料。