Skip to content

Commit e74863b

Browse files
committed
Add configurable tab width
1 parent e7d32cd commit e74863b

File tree

8 files changed

+56
-1
lines changed

8 files changed

+56
-1
lines changed

piet-cairo/src/text.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::rc::Rc;
77

88
use glib::translate::{from_glib_full, ToGlibPtr};
99

10-
use pango::{AttrList, FontMapExt};
10+
use pango::{AttrList, FontMapExt, TabAlign, TabArray};
1111
use pango_sys::pango_attr_insert_hyphens_new;
1212
use pangocairo::FontMap;
1313

@@ -49,9 +49,12 @@ pub struct CairoTextLayout {
4949

5050
pub struct CairoTextLayoutBuilder {
5151
text: Rc<dyn TextStorage>,
52+
5253
defaults: util::LayoutDefaults,
5354
attributes: Vec<AttributeWithRange>,
5455
last_range_start_pos: usize,
56+
57+
tab_width: Option<f64>,
5558
width_constraint: f64,
5659
pango_layout: PangoLayout,
5760
}
@@ -193,6 +196,7 @@ impl Text for CairoText {
193196
defaults: util::LayoutDefaults::default(),
194197
attributes: Vec::new(),
195198
last_range_start_pos: 0,
199+
tab_width: None,
196200
width_constraint: f64::INFINITY,
197201
pango_layout,
198202
}
@@ -213,6 +217,11 @@ impl TextLayoutBuilder for CairoTextLayoutBuilder {
213217
self
214218
}
215219

220+
fn tab_width(mut self, width: f64) -> Self {
221+
self.tab_width = Some(width);
222+
self
223+
}
224+
216225
fn alignment(self, alignment: TextAlignment) -> Self {
217226
/*
218227
* NOTE: Pango has `auto_dir` enabled by default. This means that
@@ -277,6 +286,13 @@ impl TextLayoutBuilder for CairoTextLayoutBuilder {
277286
}
278287

279288
fn build(self) -> Result<Self::Out, Error> {
289+
if let Some(tab_width) = self.tab_width {
290+
let tab_width = (tab_width * PANGO_SCALE) as i32;
291+
let mut array = TabArray::new(1, false);
292+
array.set_tab(0, TabAlign::Left, tab_width);
293+
self.pango_layout.set_tabs(Some(&array));
294+
}
295+
280296
let pango_attributes = AttrList::new();
281297
let add_attribute = |attribute| {
282298
if let Some(attribute) = attribute {

piet-coregraphics/src/text.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,10 @@ impl TextLayoutBuilder for CoreGraphicsTextLayoutBuilder {
514514
self
515515
}
516516

517+
fn tab_width(mut self, _width: f64) -> Self {
518+
self
519+
}
520+
517521
fn alignment(mut self, alignment: piet::TextAlignment) -> Self {
518522
self.alignment = alignment;
519523
self

piet-direct2d/src/dwrite.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,12 @@ impl TextLayout {
341341
}
342342
}
343343

344+
pub(crate) fn set_incremental_tab_stop(&self, distance: f32) {
345+
unsafe {
346+
self.0.SetIncrementalTabStop(distance);
347+
}
348+
}
349+
344350
/// Set the weight for a range of this layout. `start` and `len` are in utf16.
345351
pub(crate) fn set_weight(&mut self, range: Utf16Range, weight: FontWeight) {
346352
let weight = weight.to_raw() as DWRITE_FONT_WEIGHT;

piet-direct2d/src/text.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ pub struct D2DTextLayout {
8484
pub struct D2DTextLayoutBuilder {
8585
text: Rc<dyn TextStorage>,
8686
layout: Result<dwrite::TextLayout, Error>,
87+
tab_width: Option<f32>,
8788
len_utf16: usize,
8889
loaded_fonts: D2DLoadedFonts,
8990
default_font: FontFamily,
@@ -161,6 +162,7 @@ impl Text for D2DText {
161162
D2DTextLayoutBuilder {
162163
layout,
163164
text,
165+
tab_width: None,
164166
len_utf16: wide_str.len(),
165167
colors: Vec::new(),
166168
loaded_fonts: self.loaded_fonts.clone(),
@@ -186,6 +188,11 @@ impl TextLayoutBuilder for D2DTextLayoutBuilder {
186188
self
187189
}
188190

191+
fn tab_width(mut self, width: f64) -> Self {
192+
self.tab_width = Some(width as f32);
193+
self
194+
}
195+
189196
fn alignment(mut self, alignment: TextAlignment) -> Self {
190197
if let Ok(layout) = self.layout.as_mut() {
191198
layout.set_alignment(alignment);
@@ -229,6 +236,10 @@ impl TextLayoutBuilder for D2DTextLayoutBuilder {
229236
let (default_line_height, default_baseline) = self.get_default_line_height_and_baseline();
230237
let layout = self.layout?;
231238

239+
if let Some(tab_width) = self.tab_width {
240+
layout.set_incremental_tab_stop(tab_width);
241+
}
242+
232243
let mut layout = D2DTextLayout {
233244
text: self.text,
234245
colors: self.colors.into(),

piet-svg/src/text.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ impl piet::TextLayoutBuilder for TextLayoutBuilder {
4747
self
4848
}
4949

50+
fn tab_width(self, _width: f64) -> Self {
51+
self
52+
}
53+
5054
fn alignment(self, _alignment: piet::TextAlignment) -> Self {
5155
self
5256
}

piet-web/src/text.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ impl TextLayoutBuilder for WebTextLayoutBuilder {
144144
self
145145
}
146146

147+
fn tab_width(self, _width: f64) -> Self {
148+
self
149+
}
150+
147151
fn alignment(self, _alignment: piet::TextAlignment) -> Self {
148152
web_sys::console::log_1(&"TextLayout alignment unsupported on web".into());
149153
self

piet/src/null_renderer.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ impl TextLayoutBuilder for NullTextLayoutBuilder {
157157
self
158158
}
159159

160+
fn tab_width(self, _width: f64) -> Self {
161+
self
162+
}
163+
160164
fn alignment(self, _alignment: crate::TextAlignment) -> Self {
161165
self
162166
}

piet/src/text.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,12 @@ pub trait TextLayoutBuilder: Sized {
175175
/// default behaviour.
176176
fn max_width(self, width: f64) -> Self;
177177

178+
/// Set the base tabulator width.
179+
///
180+
/// The width specified here controls the max width for tab characters
181+
/// in the final layout.
182+
fn tab_width(self, width: f64) -> Self;
183+
178184
/// Set the [`TextAlignment`] to be used for this layout.
179185
///
180186
/// [`TextAlignment`]: enum.TextAlignment.html

0 commit comments

Comments
 (0)