♻️ Refactor and rename ParagraphBuilder instantiating from TextContent

This commit is contained in:
Belén Albeza
2025-09-02 15:22:05 +02:00
parent 50b9e8c6e6
commit d40b68c004
6 changed files with 332 additions and 301 deletions

View File

@@ -24,6 +24,7 @@ pub use surfaces::{SurfaceId, Surfaces};
use crate::performance;
use crate::shapes::{Blur, BlurType, Corners, Fill, Shape, StructureEntry, Type};
use crate::state::ShapesPool;
use crate::textlayout::{paragraph_builders_from_text, stroke_paragraph_builders_from_text};
use crate::tiles::{self, PendingTiles, TileRect};
use crate::uuid::Uuid;
use crate::view::Viewbox;
@@ -541,13 +542,18 @@ impl RenderState {
let inner_shadows = shape.inner_shadow_paints();
let blur_filter = shape.image_filter(1.);
let blur_mask = shape.mask_filter(1.);
let mut paragraphs =
text_content.to_paragraphs(blur_filter.as_ref(), blur_mask.as_ref(), None);
let mut paragraphs = paragraph_builders_from_text(
&text_content,
blur_filter.as_ref(),
blur_mask.as_ref(),
None,
);
// Render all drop shadows if there are no visible strokes
if !shape.has_visible_strokes() && !drop_shadows.is_empty() {
for drop_shadow in &drop_shadows {
let mut paragraphs_with_drop_shadows = text_content.to_paragraphs(
let mut paragraphs_with_drop_shadows = paragraph_builders_from_text(
&text_content,
blur_filter.as_ref(),
blur_mask.as_ref(),
Some(drop_shadow),
@@ -564,8 +570,9 @@ impl RenderState {
text::render(self, &shape, &mut paragraphs, None);
for stroke in shape.visible_strokes().rev() {
for drop_shadow in &drop_shadows {
let mut stroke_paragraphs_with_drop_shadows = text_content
.to_stroke_paragraphs(
let mut stroke_paragraphs_with_drop_shadows =
stroke_paragraph_builders_from_text(
&text_content,
stroke,
&shape.selrect(),
blur_filter.as_ref(),
@@ -580,7 +587,8 @@ impl RenderState {
);
}
let mut stroke_paragraphs = text_content.to_stroke_paragraphs(
let mut stroke_paragraphs = stroke_paragraph_builders_from_text(
&text_content,
stroke,
&shape.selrect(),
blur_filter.as_ref(),
@@ -600,8 +608,9 @@ impl RenderState {
);
for inner_shadow in &inner_shadows {
let mut stroke_paragraphs_with_inner_shadows = text_content
.to_stroke_paragraphs(
let mut stroke_paragraphs_with_inner_shadows =
stroke_paragraph_builders_from_text(
&text_content,
stroke,
&shape.selrect(),
blur_filter.as_ref(),
@@ -618,7 +627,8 @@ impl RenderState {
}
for inner_shadow in &inner_shadows {
let mut paragraphs_with_inner_shadows = text_content.to_paragraphs(
let mut paragraphs_with_inner_shadows = paragraph_builders_from_text(
&text_content,
blur_filter.as_ref(),
blur_mask.as_ref(),
Some(inner_shadow),

View File

@@ -14,7 +14,7 @@ use crate::shapes::{
TransformEntry, Type,
};
use crate::state::{ShapesPool, State};
use crate::textlayout::auto_height;
use crate::textlayout::{auto_height, paragraph_builders_from_text};
use crate::uuid::Uuid;
#[allow(clippy::too_many_arguments)]
@@ -200,7 +200,7 @@ fn propagate_transform(
match content.grow_type() {
GrowType::AutoHeight => {
let paragraph_width = shape_bounds_after.width();
let mut paragraphs = content.to_paragraphs(None, None, None);
let mut paragraphs = paragraph_builders_from_text(content, None, None, None);
let height = auto_height(&mut paragraphs, paragraph_width);
let resize_transform = math::resize_matrix(
&shape_bounds_after,
@@ -213,7 +213,7 @@ fn propagate_transform(
}
GrowType::AutoWidth => {
let paragraph_width = content.width();
let mut paragraphs = content.to_paragraphs(None, None, None);
let mut paragraphs = paragraph_builders_from_text(content, None, None, None);
let height = auto_height(&mut paragraphs, paragraph_width);
let resize_transform = math::resize_matrix(
&shape_bounds_after,

View File

@@ -1,20 +1,16 @@
use crate::{
math::{Matrix, Rect},
render::{default_font, filters::compose_filters, DEFAULT_EMOJI_FONT},
render::{default_font, DEFAULT_EMOJI_FONT},
textlayout::paragraph_builders_from_text,
};
use skia_safe::{
self as skia,
paint::Paint,
textlayout::{ParagraphBuilder, ParagraphStyle},
ImageFilter, MaskFilter,
};
use skia_safe::{self as skia, paint::Paint, textlayout::ParagraphStyle, ImageFilter, MaskFilter};
use std::collections::HashSet;
use super::FontFamily;
use crate::shapes::{self, merge_fills, set_paint_fill, Stroke, StrokeKind};
use crate::shapes::{self, merge_fills};
use crate::textlayout::{auto_height, auto_width};
use crate::utils::{get_fallback_fonts, get_font_collection, uuid_from_u32};
use crate::utils::uuid_from_u32;
use crate::wasm::fills::parse_fills_from_bytes;
use crate::Uuid;
@@ -62,6 +58,10 @@ impl TextContent {
}
}
pub fn bounds(&self) -> Rect {
self.bounds
}
pub fn set_xywh(&mut self, x: f32, y: f32, w: f32, h: f32) {
self.bounds = Rect::from_xywh(x, y, w, h);
}
@@ -80,102 +80,13 @@ impl TextContent {
self.paragraphs.push(paragraph);
}
pub fn to_paragraphs(
&self,
blur: Option<&ImageFilter>,
blur_mask: Option<&MaskFilter>,
shadow: Option<&Paint>,
) -> Vec<Vec<ParagraphBuilder>> {
let fonts = get_font_collection();
let fallback_fonts = get_fallback_fonts();
let mut paragraph_group = Vec::new();
for paragraph in &self.paragraphs {
let paragraph_style = paragraph.paragraph_to_style();
let mut builder = ParagraphBuilder::new(&paragraph_style, fonts);
for leaf in &paragraph.children {
let text_style =
leaf.to_style(&self.bounds, fallback_fonts, blur, blur_mask, shadow);
let text = leaf.apply_text_transform();
builder.push_style(&text_style);
builder.add_text(&text);
}
paragraph_group.push(vec![builder]);
}
paragraph_group
}
pub fn to_stroke_paragraphs(
&self,
stroke: &Stroke,
bounds: &Rect,
blur: Option<&ImageFilter>,
blur_mask: Option<&MaskFilter>,
shadow: Option<&Paint>,
count_inner_strokes: usize,
) -> Vec<Vec<ParagraphBuilder>> {
let fallback_fonts = get_fallback_fonts();
let fonts = get_font_collection();
let mut paragraph_group = Vec::new();
for paragraph in &self.paragraphs {
let mut stroke_paragraphs_map: std::collections::HashMap<usize, ParagraphBuilder> =
std::collections::HashMap::new();
for leaf in paragraph.children.iter() {
let mut text_paint = merge_fills(&leaf.fills, *bounds);
if let Some(blur_mask) = blur_mask {
text_paint.set_mask_filter(blur_mask.clone());
}
let stroke_paints = if shadow.is_some() {
get_text_stroke_paints_with_shadows(
stroke,
blur,
blur_mask,
shadow,
leaf.is_transparent(),
)
} else {
get_text_stroke_paints(
stroke,
bounds,
&text_paint,
blur,
blur_mask,
count_inner_strokes,
)
};
let text: String = leaf.apply_text_transform();
for (paint_idx, stroke_paint) in stroke_paints.iter().enumerate() {
let builder = stroke_paragraphs_map.entry(paint_idx).or_insert_with(|| {
let paragraph_style = paragraph.paragraph_to_style();
ParagraphBuilder::new(&paragraph_style, fonts)
});
let stroke_paint = stroke_paint.clone();
let stroke_style =
leaf.to_stroke_style(&stroke_paint, fallback_fonts, blur, blur_mask, None);
builder.push_style(&stroke_style);
builder.add_text(&text);
}
}
let stroke_paragraphs: Vec<ParagraphBuilder> = (0..stroke_paragraphs_map.len())
.map(|i| stroke_paragraphs_map.remove(&i).unwrap())
.collect();
paragraph_group.push(stroke_paragraphs);
}
paragraph_group
pub fn paragraphs(&self) -> &Vec<Paragraph> {
&self.paragraphs
}
pub fn width(&self) -> f32 {
if self.grow_type() == GrowType::AutoWidth {
let temp_paragraphs = self.to_paragraphs(None, None, None);
let temp_paragraphs = paragraph_builders_from_text(self, None, None, None);
let mut temp_paragraphs = temp_paragraphs;
auto_width(&mut temp_paragraphs, f32::MAX).ceil()
} else {
@@ -193,7 +104,7 @@ impl TextContent {
pub fn visual_bounds(&self) -> (f32, f32) {
let paragraph_width = self.width();
let mut paragraphs = self.to_paragraphs(None, None, None);
let mut paragraphs = paragraph_builders_from_text(self, None, None, None);
let paragraph_height = auto_height(&mut paragraphs, paragraph_width);
(paragraph_width, paragraph_height)
}
@@ -390,6 +301,10 @@ impl TextLeaf {
}
}
pub fn fills(&self) -> &[shapes::Fill] {
&self.fills
}
pub fn to_style(
&self,
content_bounds: &Rect,
@@ -713,183 +628,3 @@ impl From<&Vec<u8>> for RawTextData {
Self { paragraph }
}
}
fn get_text_stroke_paints_with_shadows(
stroke: &Stroke,
blur: Option<&ImageFilter>,
blur_mask: Option<&MaskFilter>,
shadow: Option<&Paint>,
is_transparent: bool,
) -> Vec<Paint> {
let mut paints = Vec::new();
match stroke.kind {
StrokeKind::Inner => {
let mut paint = skia_safe::Paint::default();
paint.set_style(skia::PaintStyle::Fill);
paint.set_anti_alias(true);
if let Some(blur) = blur {
paint.set_image_filter(blur.clone());
}
if let Some(shadow) = shadow {
paint.set_image_filter(shadow.image_filter());
}
paints.push(paint.clone());
if is_transparent {
let image_filter = skia_safe::image_filters::erode(
(stroke.width, stroke.width),
paint.image_filter(),
None,
);
paint.set_image_filter(image_filter);
paint.set_blend_mode(skia::BlendMode::DstOut);
paints.push(paint.clone());
}
}
StrokeKind::Center => {
let mut paint = skia_safe::Paint::default();
paint.set_anti_alias(true);
paint.set_stroke_width(stroke.width);
if let Some(blur) = blur {
paint.set_image_filter(blur.clone());
}
if let Some(shadow) = shadow {
paint.set_image_filter(shadow.image_filter());
}
if is_transparent {
paint.set_style(skia::PaintStyle::Stroke);
} else {
paint.set_style(skia::PaintStyle::StrokeAndFill);
}
paints.push(paint);
}
StrokeKind::Outer => {
let mut paint = skia_safe::Paint::default();
paint.set_style(skia::PaintStyle::StrokeAndFill);
paint.set_anti_alias(true);
paint.set_stroke_width(stroke.width * 2.0);
if let Some(blur_mask) = blur_mask {
paint.set_mask_filter(blur_mask.clone());
}
if let Some(shadow) = shadow {
paint.set_image_filter(shadow.image_filter());
}
paints.push(paint.clone());
if is_transparent {
let image_filter = skia_safe::image_filters::erode(
(stroke.width, stroke.width),
paint.image_filter(),
None,
);
paint.set_image_filter(image_filter);
paint.set_blend_mode(skia::BlendMode::DstOut);
paints.push(paint.clone());
}
}
}
paints
}
fn get_text_stroke_paints(
stroke: &Stroke,
bounds: &Rect,
text_paint: &Paint,
blur: Option<&ImageFilter>,
blur_mask: Option<&MaskFilter>,
count_inner_strokes: usize,
) -> Vec<Paint> {
let mut paints = Vec::new();
match stroke.kind {
StrokeKind::Inner => {
let shader = text_paint.shader();
let mut is_opaque = true;
if shader.is_some() {
is_opaque = shader.unwrap().is_opaque();
}
if is_opaque && count_inner_strokes == 1 {
let mut paint = text_paint.clone();
paint.set_style(skia::PaintStyle::Fill);
paint.set_anti_alias(true);
if let Some(blur) = blur {
paint.set_image_filter(blur.clone());
}
paints.push(paint);
let mut paint = skia::Paint::default();
paint.set_style(skia::PaintStyle::Stroke);
paint.set_blend_mode(skia::BlendMode::SrcIn);
paint.set_anti_alias(true);
paint.set_stroke_width(stroke.width * 2.0);
set_paint_fill(&mut paint, &stroke.fill, bounds);
if let Some(blur) = blur {
paint.set_image_filter(blur.clone());
}
paints.push(paint);
} else {
let mut paint = text_paint.clone();
paint.set_style(skia::PaintStyle::Fill);
paint.set_anti_alias(false);
set_paint_fill(&mut paint, &stroke.fill, bounds);
paints.push(paint);
let mut paint = skia::Paint::default();
let image_filter =
skia_safe::image_filters::erode((stroke.width, stroke.width), None, None);
let filter = compose_filters(blur, image_filter.as_ref());
paint.set_image_filter(filter);
paint.set_anti_alias(false);
paint.set_blend_mode(skia::BlendMode::DstOut);
paints.push(paint);
}
}
StrokeKind::Center => {
let mut paint = skia::Paint::default();
paint.set_style(skia::PaintStyle::Stroke);
paint.set_anti_alias(true);
paint.set_stroke_width(stroke.width);
set_paint_fill(&mut paint, &stroke.fill, bounds);
if let Some(blur) = blur {
paint.set_image_filter(blur.clone());
}
paints.push(paint);
}
StrokeKind::Outer => {
let mut paint = skia::Paint::default();
paint.set_style(skia::PaintStyle::Stroke);
paint.set_blend_mode(skia::BlendMode::DstOver);
paint.set_anti_alias(true);
paint.set_stroke_width(stroke.width * 2.0);
set_paint_fill(&mut paint, &stroke.fill, bounds);
if let Some(blur_mask) = blur_mask {
paint.set_mask_filter(blur_mask.clone());
}
paints.push(paint);
let mut paint = skia::Paint::default();
paint.set_style(skia::PaintStyle::Fill);
paint.set_blend_mode(skia::BlendMode::Clear);
paint.set_color(skia::Color::TRANSPARENT);
paint.set_anti_alias(true);
paints.push(paint);
}
}
paints
}

View File

@@ -1,4 +1,4 @@
use crate::shapes::text::TextContent;
use crate::{shapes::text::TextContent, textlayout::paragraph_builders_from_text};
use skia_safe::{
self as skia, textlayout::Paragraph as SkiaParagraph, FontMetrics, Point, Rect, TextBlob,
};
@@ -20,7 +20,7 @@ impl TextPaths {
let mut paths = Vec::new();
let mut offset_y = self.bounds.y();
let mut paragraphs = self.to_paragraphs(None, None, None);
let mut paragraphs = paragraph_builders_from_text(&self.0, None, None, None);
for paragraphs in paragraphs.iter_mut() {
for paragraph_builder in paragraphs.iter_mut() {

View File

@@ -1,4 +1,10 @@
use skia_safe::textlayout::ParagraphBuilder;
use skia_safe::{self as skia, textlayout::ParagraphBuilder, ImageFilter, MaskFilter, Paint, Rect};
use crate::{
render::filters::compose_filters,
shapes::{merge_fills, set_paint_fill, Stroke, StrokeKind, TextContent},
utils::{get_fallback_fonts, get_font_collection},
};
pub fn auto_width(paragraphs: &mut [Vec<ParagraphBuilder>], width: f32) -> f32 {
let built_paragraphs = get_built_paragraphs(paragraphs, width);
@@ -45,9 +51,287 @@ pub fn build_paragraphs_with_width(
.collect()
}
pub fn paragraph_builders_from_text(
text_content: &TextContent,
blur: Option<&ImageFilter>,
blur_mask: Option<&MaskFilter>,
shadow: Option<&Paint>,
) -> Vec<Vec<ParagraphBuilder>> {
let fonts = get_font_collection();
let fallback_fonts = get_fallback_fonts();
let mut paragraph_group = Vec::new();
for paragraph in text_content.paragraphs() {
let paragraph_style = paragraph.paragraph_to_style();
let mut builder = ParagraphBuilder::new(&paragraph_style, fonts);
for leaf in paragraph.get_children() {
let text_style = leaf.to_style(
&text_content.bounds(),
fallback_fonts,
blur,
blur_mask,
shadow,
);
let text = leaf.apply_text_transform();
builder.push_style(&text_style);
builder.add_text(&text);
}
paragraph_group.push(vec![builder]);
}
paragraph_group
}
pub fn stroke_paragraph_builders_from_text(
text_content: &TextContent,
stroke: &Stroke,
bounds: &Rect,
blur: Option<&ImageFilter>,
blur_mask: Option<&MaskFilter>,
shadow: Option<&Paint>,
count_inner_strokes: usize,
) -> Vec<Vec<ParagraphBuilder>> {
let fallback_fonts = get_fallback_fonts();
let fonts = get_font_collection();
let mut paragraph_group = Vec::new();
for paragraph in text_content.paragraphs() {
let mut stroke_paragraphs_map: std::collections::HashMap<usize, ParagraphBuilder> =
std::collections::HashMap::new();
for leaf in paragraph.get_children().iter() {
let mut text_paint = merge_fills(leaf.fills(), *bounds);
if let Some(blur_mask) = blur_mask {
text_paint.set_mask_filter(blur_mask.clone());
}
let stroke_paints = if shadow.is_some() {
get_text_stroke_paints_with_shadows(
stroke,
blur,
blur_mask,
shadow,
leaf.is_transparent(),
)
} else {
get_text_stroke_paints(
stroke,
bounds,
&text_paint,
blur,
blur_mask,
count_inner_strokes,
)
};
let text: String = leaf.apply_text_transform();
for (paint_idx, stroke_paint) in stroke_paints.iter().enumerate() {
let builder = stroke_paragraphs_map.entry(paint_idx).or_insert_with(|| {
let paragraph_style = paragraph.paragraph_to_style();
ParagraphBuilder::new(&paragraph_style, fonts)
});
let stroke_paint = stroke_paint.clone();
let stroke_style =
leaf.to_stroke_style(&stroke_paint, fallback_fonts, blur, blur_mask, None);
builder.push_style(&stroke_style);
builder.add_text(&text);
}
}
let stroke_paragraphs: Vec<ParagraphBuilder> = (0..stroke_paragraphs_map.len())
.map(|i| stroke_paragraphs_map.remove(&i).unwrap())
.collect();
paragraph_group.push(stroke_paragraphs);
}
paragraph_group
}
fn get_built_paragraphs(
paragraphs: &mut [Vec<ParagraphBuilder>],
width: f32,
) -> Vec<Vec<skia_safe::textlayout::Paragraph>> {
build_paragraphs_with_width(paragraphs, width)
}
fn get_text_stroke_paints_with_shadows(
stroke: &Stroke,
blur: Option<&ImageFilter>,
blur_mask: Option<&MaskFilter>,
shadow: Option<&Paint>,
is_transparent: bool,
) -> Vec<Paint> {
let mut paints = Vec::new();
match stroke.kind {
StrokeKind::Inner => {
let mut paint = Paint::default();
paint.set_style(skia::PaintStyle::Fill);
paint.set_anti_alias(true);
if let Some(blur) = blur {
paint.set_image_filter(blur.clone());
}
if let Some(shadow) = shadow {
paint.set_image_filter(shadow.image_filter());
}
paints.push(paint.clone());
if is_transparent {
let image_filter = skia_safe::image_filters::erode(
(stroke.width, stroke.width),
paint.image_filter(),
None,
);
paint.set_image_filter(image_filter);
paint.set_blend_mode(skia::BlendMode::DstOut);
paints.push(paint.clone());
}
}
StrokeKind::Center => {
let mut paint = skia_safe::Paint::default();
paint.set_anti_alias(true);
paint.set_stroke_width(stroke.width);
if let Some(blur) = blur {
paint.set_image_filter(blur.clone());
}
if let Some(shadow) = shadow {
paint.set_image_filter(shadow.image_filter());
}
if is_transparent {
paint.set_style(skia::PaintStyle::Stroke);
} else {
paint.set_style(skia::PaintStyle::StrokeAndFill);
}
paints.push(paint);
}
StrokeKind::Outer => {
let mut paint = skia_safe::Paint::default();
paint.set_style(skia::PaintStyle::StrokeAndFill);
paint.set_anti_alias(true);
paint.set_stroke_width(stroke.width * 2.0);
if let Some(blur_mask) = blur_mask {
paint.set_mask_filter(blur_mask.clone());
}
if let Some(shadow) = shadow {
paint.set_image_filter(shadow.image_filter());
}
paints.push(paint.clone());
if is_transparent {
let image_filter = skia_safe::image_filters::erode(
(stroke.width, stroke.width),
paint.image_filter(),
None,
);
paint.set_image_filter(image_filter);
paint.set_blend_mode(skia::BlendMode::DstOut);
paints.push(paint.clone());
}
}
}
paints
}
fn get_text_stroke_paints(
stroke: &Stroke,
bounds: &Rect,
text_paint: &Paint,
blur: Option<&ImageFilter>,
blur_mask: Option<&MaskFilter>,
count_inner_strokes: usize,
) -> Vec<Paint> {
let mut paints = Vec::new();
match stroke.kind {
StrokeKind::Inner => {
let shader = text_paint.shader();
let mut is_opaque = true;
if shader.is_some() {
is_opaque = shader.unwrap().is_opaque();
}
if is_opaque && count_inner_strokes == 1 {
let mut paint = text_paint.clone();
paint.set_style(skia::PaintStyle::Fill);
paint.set_anti_alias(true);
if let Some(blur) = blur {
paint.set_image_filter(blur.clone());
}
paints.push(paint);
let mut paint = skia::Paint::default();
paint.set_style(skia::PaintStyle::Stroke);
paint.set_blend_mode(skia::BlendMode::SrcIn);
paint.set_anti_alias(true);
paint.set_stroke_width(stroke.width * 2.0);
set_paint_fill(&mut paint, &stroke.fill, bounds);
if let Some(blur) = blur {
paint.set_image_filter(blur.clone());
}
paints.push(paint);
} else {
let mut paint = text_paint.clone();
paint.set_style(skia::PaintStyle::Fill);
paint.set_anti_alias(false);
set_paint_fill(&mut paint, &stroke.fill, bounds);
paints.push(paint);
let mut paint = skia::Paint::default();
let image_filter =
skia_safe::image_filters::erode((stroke.width, stroke.width), None, None);
let filter = compose_filters(blur, image_filter.as_ref());
paint.set_image_filter(filter);
paint.set_anti_alias(false);
paint.set_blend_mode(skia::BlendMode::DstOut);
paints.push(paint);
}
}
StrokeKind::Center => {
let mut paint = skia::Paint::default();
paint.set_style(skia::PaintStyle::Stroke);
paint.set_anti_alias(true);
paint.set_stroke_width(stroke.width);
set_paint_fill(&mut paint, &stroke.fill, bounds);
if let Some(blur) = blur {
paint.set_image_filter(blur.clone());
}
paints.push(paint);
}
StrokeKind::Outer => {
let mut paint = skia::Paint::default();
paint.set_style(skia::PaintStyle::Stroke);
paint.set_blend_mode(skia::BlendMode::DstOver);
paint.set_anti_alias(true);
paint.set_stroke_width(stroke.width * 2.0);
set_paint_fill(&mut paint, &stroke.fill, bounds);
if let Some(blur_mask) = blur_mask {
paint.set_mask_filter(blur_mask.clone());
}
paints.push(paint);
let mut paint = skia::Paint::default();
paint.set_style(skia::PaintStyle::Fill);
paint.set_blend_mode(skia::BlendMode::Clear);
paint.set_color(skia::Color::TRANSPARENT);
paint.set_anti_alias(true);
paints.push(paint);
}
}
paints
}

View File

@@ -1,6 +1,6 @@
use crate::mem;
use crate::shapes::{GrowType, RawTextData, Type};
use crate::textlayout::{auto_height, build_paragraphs_with_width};
use crate::textlayout::{auto_height, build_paragraphs_with_width, paragraph_builders_from_text};
use crate::{with_current_shape, with_current_shape_mut, STATE};
#[no_mangle]
@@ -44,7 +44,7 @@ pub extern "C" fn get_text_dimensions() -> *mut u8 {
if let Type::Text(content) = &shape.shape_type {
// 1. Reset Paragraphs
let paragraph_width = content.width();
let mut paragraphs = content.to_paragraphs(None, None, None);
let mut paragraphs = paragraph_builders_from_text(content, None, None, None);
let built_paragraphs = build_paragraphs_with_width(&mut paragraphs, paragraph_width);
// 2. Max Width Calculation
@@ -56,12 +56,14 @@ pub extern "C" fn get_text_dimensions() -> *mut u8 {
// 3. Width and Height Calculation
match content.grow_type() {
GrowType::AutoHeight => {
let mut paragraph_height = content.to_paragraphs(None, None, None);
let mut paragraph_height =
paragraph_builders_from_text(content, None, None, None);
height = auto_height(&mut paragraph_height, paragraph_width).ceil();
}
GrowType::AutoWidth => {
width = paragraph_width;
let mut paragraph_height = content.to_paragraphs(None, None, None);
let mut paragraph_height =
paragraph_builders_from_text(content, None, None, None);
height = auto_height(&mut paragraph_height, paragraph_width).ceil();
}
GrowType::Fixed => {}