Fix #4978: Area Type Options › Text Flow by rows or by columns

This commit is contained in:
bflatastic
2026-11-01 06:11:11 +07:00
parent 8704c15c6d
commit 7d8f1d4e06
41 changed files with 248 additions and 16 deletions
+2 -1
View File
@@ -109,7 +109,8 @@ pub use style_libs::StyleLibrary;
pub use text::{
AreaFit, AreaOptions, Burasagari, CharAlign, CharPosition, CharStyle, Composer, Digits, FirstBaseline, HyphenationOptions, InlineArt,
JustificationOptions, Justify, Kinsoku, LeadingModel, Mojikumi, ParaDirection, ParaStyle, PathAlign, PathEffect, RubyAlign, RubyPosition,
RubySpan, ScriptMetrics, SingleWordJustify, TabAlign, TabStop, TextKind, TextObject, TextRun, TextStyleDef, TextWrap, VerticalAlign, WrapShape,
RubySpan, ScriptMetrics, SingleWordJustify, TabAlign, TabStop, TextFlow, TextKind, TextObject, TextRun, TextStyleDef, TextWrap, VerticalAlign,
WrapShape,
};
pub use trace::TraceView;
pub use variables::{DataSet, DataValue, Variable, VariableKind, Variables};
+1 -1
View File
@@ -13,7 +13,7 @@ mod para_style;
mod runs;
mod tabs_lists;
pub use area::{AreaFit, AreaOptions, PathAlign, PathEffect, TextWrap, VerticalAlign, WrapShape};
pub use area::{AreaFit, AreaOptions, PathAlign, PathEffect, TextFlow, TextWrap, VerticalAlign, WrapShape};
use char_style::yes;
pub use char_style::{CharAlign, CharPosition, CharStyle, Digits, ScriptMetrics};
pub use para_style::{
+17
View File
@@ -29,6 +29,19 @@ impl VerticalAlign {
}
}
/// Area Type Options › Text Flow: the order text fills the cells of area type with several rows
/// and columns.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum TextFlow {
/// Down each column's rows, then on to the next column (the default, and what a document
/// from before the option reads as).
#[default]
Columns,
/// Across each row's columns, then on to the next row.
Rows,
}
/// Text Wrap Options of a wrap object (Object → Text Wrap).
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
#[serde(default)]
@@ -135,6 +148,9 @@ pub struct AreaOptions {
pub first_baseline_min: f64,
/// Vertical alignment of the lines in each row/column.
pub vertical_align: VerticalAlign,
/// Text Flow: by columns (the default, left out when saved) or by rows.
#[serde(skip_serializing_if = "crate::skip::is_default")]
pub flow: TextFlow,
/// How the frame and its text fit each other (Auto Size, Shrink Text to Fit).
#[serde(skip_serializing_if = "crate::skip::is_default")]
pub fit: AreaFit,
@@ -150,6 +166,7 @@ impl Default for AreaOptions {
first_baseline: FirstBaseline::Ascent,
first_baseline_min: 0.0,
vertical_align: VerticalAlign::Top,
flow: TextFlow::Columns,
fit: AreaFit::None,
}
}
+13
View File
@@ -293,6 +293,19 @@ fn paragraph_styles_split_merge_and_normalize() {
assert_eq!(back.para_at(3).space_before, 4.0);
}
/// Text Flow is saved only when by rows: area type by columns (the default) saves as it did before
/// the option, and files from before it read by columns; other values don't read.
#[test]
fn text_flow_is_saved_only_when_by_rows() {
let by_columns = serde_json::to_value(AreaOptions::default()).unwrap();
assert!(by_columns.get("flow").is_none());
assert_eq!(serde_json::from_value::<AreaOptions>(by_columns).unwrap().flow, TextFlow::Columns);
let by_rows = serde_json::to_value(AreaOptions { flow: TextFlow::Rows, ..AreaOptions::default() }).unwrap();
assert_eq!(by_rows["flow"], "rows");
assert_eq!(serde_json::from_value::<AreaOptions>(by_rows).unwrap().flow, TextFlow::Rows);
assert!(serde_json::from_value::<AreaOptions>(serde_json::json!({"flow": "diagonal"})).is_err());
}
/// 120 × 40 area type at (40, 40), its text drawn at twice its size.
fn area_type() -> TextObject {
let mut t = TextObject::point(Point::ZERO, "Some text", CharStyle::default());