Restore newline functionality (mostly...)
This commit is contained in:
parent
9f60567f66
commit
5fcaa52687
|
@ -174,24 +174,26 @@ impl<'gc> Font<'gc> {
|
|||
size
|
||||
}
|
||||
|
||||
/// Given a line of text, split it into the shortest number of lines that
|
||||
/// are shorter than `width`.
|
||||
/// Given a line of text, find the first breakpoint within the text.
|
||||
///
|
||||
/// This function assumes only `" "` is valid whitespace to split words on,
|
||||
/// and will not attempt to break words that are longer than `width`.
|
||||
/// and will not attempt to break words that are longer than `width`, nor
|
||||
/// will it break at newlines.
|
||||
///
|
||||
/// The given `offset` determines the start of the initial line.
|
||||
/// The given `offset` determines the start of the initial line, while the
|
||||
/// `width` indicates how long the line is supposed to be.
|
||||
///
|
||||
/// This function yields `None` if the line is not broken.
|
||||
///
|
||||
/// TODO: This function and, more generally, this entire file will need to
|
||||
/// be internationalized to implement AS3 `flash.text.engine`.
|
||||
pub fn split_wrapped_lines(
|
||||
pub fn wrap_line(
|
||||
self,
|
||||
text: &str,
|
||||
font_size: Twips,
|
||||
width: Twips,
|
||||
offset: Twips,
|
||||
) -> Vec<usize> {
|
||||
let mut result = vec![];
|
||||
) -> Option<usize> {
|
||||
let mut current_width = width
|
||||
.checked_sub(offset)
|
||||
.unwrap_or_else(|| Twips::from_pixels(0.0));
|
||||
|
@ -200,29 +202,19 @@ impl<'gc> Font<'gc> {
|
|||
for word in text.split(' ') {
|
||||
let measure = self.measure(word, font_size);
|
||||
let line_start = current_word.as_ptr() as usize - text.as_ptr() as usize;
|
||||
let line_end = if (line_start + current_word.len() + 1) < text.len() {
|
||||
line_start + current_word.len() + 1
|
||||
} else {
|
||||
line_start + current_word.len()
|
||||
};
|
||||
let line_end = line_start + current_word.len();
|
||||
let word_start = word.as_ptr() as usize - text.as_ptr() as usize;
|
||||
let word_end = if (word_start + word.len() + 1) < text.len() {
|
||||
word_start + word.len() + 1
|
||||
} else {
|
||||
word_start + word.len()
|
||||
};
|
||||
let word_end = word_start + word.len();
|
||||
|
||||
if measure.0 > current_width && measure.0 > width {
|
||||
//Failsafe for if we get a word wider than the field.
|
||||
if !current_word.is_empty() {
|
||||
result.push(line_end);
|
||||
return Some(line_end);
|
||||
}
|
||||
result.push(word_end);
|
||||
current_word = &text[word_end..word_end];
|
||||
current_width = width;
|
||||
return Some(word_end);
|
||||
} else if measure.0 > current_width {
|
||||
if !current_word.is_empty() {
|
||||
result.push(line_end);
|
||||
return Some(line_end);
|
||||
}
|
||||
|
||||
current_word = &text[word_start..word_end];
|
||||
|
@ -233,7 +225,7 @@ impl<'gc> Font<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
result
|
||||
None
|
||||
}
|
||||
|
||||
pub fn descriptor(self) -> FontDescriptor {
|
||||
|
|
|
@ -44,6 +44,12 @@ impl<'gc> LayoutContext<'gc> {
|
|||
&mut self.cursor
|
||||
}
|
||||
|
||||
/// Adjust the text layout cursor down to the next line.
|
||||
fn newline(&mut self, font_size: Twips) {
|
||||
self.cursor.set_x(Twips::from_pixels(0.0));
|
||||
self.cursor += (Twips::from_pixels(0.0), font_size).into();
|
||||
}
|
||||
|
||||
fn font(&self) -> Option<Font<'gc>> {
|
||||
self.font
|
||||
}
|
||||
|
@ -217,36 +223,48 @@ impl<'gc> LayoutBox<'gc> {
|
|||
for (start, _end, text, span) in fs.iter_spans() {
|
||||
if let Some(font) = layout_context.resolve_font(context, movie.clone(), &span) {
|
||||
let font_size = Twips::from_pixels(span.size);
|
||||
let breakpoint_list =
|
||||
font.split_wrapped_lines(&text, font_size, bounds, layout_context.cursor().x());
|
||||
|
||||
let end = text.len();
|
||||
|
||||
let mut last_breakpoint = 0;
|
||||
|
||||
for breakpoint in breakpoint_list {
|
||||
if last_breakpoint != breakpoint {
|
||||
Self::append_text_fragment(
|
||||
context.gc_context,
|
||||
&mut layout_context,
|
||||
&text[last_breakpoint..breakpoint],
|
||||
start + last_breakpoint,
|
||||
start + breakpoint,
|
||||
span,
|
||||
);
|
||||
while let Some(breakpoint) = font.wrap_line(
|
||||
&text[last_breakpoint..],
|
||||
font_size,
|
||||
bounds,
|
||||
layout_context.cursor().x(),
|
||||
) {
|
||||
if breakpoint == last_breakpoint {
|
||||
last_breakpoint += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
Self::append_text_fragment(
|
||||
context.gc_context,
|
||||
&mut layout_context,
|
||||
&text[last_breakpoint..breakpoint],
|
||||
start + last_breakpoint,
|
||||
start + breakpoint,
|
||||
span,
|
||||
);
|
||||
|
||||
last_breakpoint = breakpoint;
|
||||
if last_breakpoint >= text.len() {
|
||||
break;
|
||||
}
|
||||
|
||||
layout_context.newline(font_size);
|
||||
}
|
||||
|
||||
Self::append_text_fragment(
|
||||
context.gc_context,
|
||||
&mut layout_context,
|
||||
&text[last_breakpoint..end],
|
||||
start + last_breakpoint,
|
||||
start + end,
|
||||
span,
|
||||
);
|
||||
let span_end = text.len();
|
||||
|
||||
if last_breakpoint < span_end {
|
||||
Self::append_text_fragment(
|
||||
context.gc_context,
|
||||
&mut layout_context,
|
||||
&text[last_breakpoint..span_end],
|
||||
start + last_breakpoint,
|
||||
start + span_end,
|
||||
span,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue