Replace the existing default format on `EditText` with our brand-new `FormatSpans`.
This also includes code to automatically populate the default format with data from the SWF tag.
This commit is contained in:
parent
efdecdea64
commit
4eca2d4bdd
|
@ -4,7 +4,7 @@ use crate::avm1::{Avm1, Object, StageObject, Value};
|
|||
use crate::context::{RenderContext, UpdateContext};
|
||||
use crate::display_object::{DisplayObjectBase, TDisplayObject};
|
||||
use crate::font::{Font, Glyph};
|
||||
use crate::html::TextFormat;
|
||||
use crate::html::{FormatSpans, TextFormat};
|
||||
use crate::library::Library;
|
||||
use crate::prelude::*;
|
||||
use crate::tag_utils::SwfMovie;
|
||||
|
@ -42,10 +42,22 @@ pub struct EditTextData<'gc> {
|
|||
text: String,
|
||||
|
||||
/// The current HTML document displayed by this `EditText`.
|
||||
///
|
||||
/// The HTML representation of this `EditText` is lowered into an
|
||||
/// appropriate set of format spans, which is used for actual rendering.
|
||||
/// The HTML is only retained if there is also a stylesheet already defined
|
||||
/// on the `EditText`, else it is discarded during the lowering process.
|
||||
document: XMLDocument<'gc>,
|
||||
|
||||
/// The text formatting for newly inserted text spans.
|
||||
new_format: TextFormat,
|
||||
/// The underlying text format spans of the `EditText`.
|
||||
///
|
||||
/// This is generated from HTML (with optional CSS) or set directly, and
|
||||
/// can be directly manipulated by ActionScript. It can also be raised to
|
||||
/// an equivalent HTML representation, as long as no stylesheet is present.
|
||||
///
|
||||
/// It is lowered further into layout boxes, which are used for actual
|
||||
/// rendering.
|
||||
text_spans: FormatSpans,
|
||||
|
||||
/// If the text is in multi-line mode or single-line mode.
|
||||
is_multiline: bool,
|
||||
|
@ -71,6 +83,7 @@ impl<'gc> EditText<'gc> {
|
|||
let is_word_wrap = swf_tag.is_word_wrap;
|
||||
let document = XMLDocument::new(context.gc_context);
|
||||
let text = swf_tag.initial_text.clone().unwrap_or_default();
|
||||
let default_format = TextFormat::from_swf_tag(swf_tag.clone(), swf_movie.clone(), context);
|
||||
|
||||
if swf_tag.is_html {
|
||||
document
|
||||
|
@ -91,7 +104,7 @@ impl<'gc> EditText<'gc> {
|
|||
base: Default::default(),
|
||||
text,
|
||||
document,
|
||||
new_format: TextFormat::default(),
|
||||
text_spans: FormatSpans::from_str_and_format("", default_format),
|
||||
static_data: gc_arena::Gc::allocate(
|
||||
context.gc_context,
|
||||
EditTextStatic {
|
||||
|
@ -192,12 +205,12 @@ impl<'gc> EditText<'gc> {
|
|||
}
|
||||
|
||||
pub fn new_text_format(self) -> TextFormat {
|
||||
self.0.read().new_format.clone()
|
||||
self.0.read().text_spans.default_format().clone()
|
||||
}
|
||||
|
||||
pub fn set_new_text_format(self, tf: TextFormat, gc_context: MutationContext<'gc, '_>) {
|
||||
self.0.write(gc_context).cached_break_points = None;
|
||||
self.0.write(gc_context).new_format = tf;
|
||||
self.0.write(gc_context).text_spans.set_default_format(tf);
|
||||
}
|
||||
|
||||
pub fn is_multiline(self) -> bool {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
mod dimensions;
|
||||
mod text_format;
|
||||
|
||||
pub use text_format::TextFormat;
|
||||
pub use text_format::{FormatSpans, TextFormat};
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
//! Classes that store formatting options
|
||||
use crate::avm1::{Avm1, Object, ScriptObject, TObject, Value};
|
||||
use crate::context::UpdateContext;
|
||||
use crate::tag_utils::SwfMovie;
|
||||
use gc_arena::Collect;
|
||||
use std::cmp::{min, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
/// A set of text formatting options to be applied to some part, or the whole
|
||||
/// of, a given text field.
|
||||
|
@ -101,6 +103,50 @@ fn getbool_from_avm1_object<'gc>(
|
|||
}
|
||||
|
||||
impl TextFormat {
|
||||
/// Construct a `TextFormat` from an `EditText`'s SWF tag.
|
||||
///
|
||||
/// This requires an `UpdateContext` as we will need to retrieve some font
|
||||
/// information from the actually-referenced font.
|
||||
pub fn from_swf_tag<'gc>(
|
||||
et: swf::EditText,
|
||||
swf_movie: Arc<SwfMovie>,
|
||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
) -> Self {
|
||||
let movie_library = context.library.library_for_movie_mut(swf_movie);
|
||||
|
||||
//TODO: How do we represent fonts referenced by character rather than
|
||||
//by linkage name?
|
||||
let font = et.font_class_name;
|
||||
let align = et.layout.clone().map(|l| l.align);
|
||||
let left_margin = et.layout.clone().map(|l| l.left_margin.to_pixels());
|
||||
let right_margin = et.layout.clone().map(|l| l.right_margin.to_pixels());
|
||||
let indent = et.layout.clone().map(|l| l.indent.to_pixels());
|
||||
let leading = et.layout.map(|l| l.leading.to_pixels());
|
||||
|
||||
Self {
|
||||
font,
|
||||
size: et.height.map(|h| h.to_pixels()),
|
||||
color: et.color,
|
||||
align,
|
||||
bold: None, // TODO: Resolve a font and pull this from that font
|
||||
italic: None, // TODO: Resolve a font and pull this from that font
|
||||
underline: None, // TODO: Resolve a font and pull this from that font
|
||||
left_margin,
|
||||
right_margin,
|
||||
indent,
|
||||
block_indent: Some(0.0), // TODO: This isn't specified by the tag itself
|
||||
kerning: Some(true), // TODO: this isn't specified by the tag itself
|
||||
leading,
|
||||
letter_spacing: Some(0.0), // TODO: This isn't specified by the tag itself
|
||||
tab_stops: Some(vec![]), // TODO: Are there default tab stops?
|
||||
bullet: Some(false), // TODO: Default tab stops?
|
||||
|
||||
// TODO: These are probably empty strings by default
|
||||
url: Some("".to_string()),
|
||||
target: Some("".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a `TextFormat` from an object that is
|
||||
pub fn from_avm1_object<'gc>(
|
||||
object1: Object<'gc>,
|
||||
|
@ -643,6 +689,14 @@ impl FormatSpans {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn default_format(&self) -> &TextFormat {
|
||||
&self.default_format
|
||||
}
|
||||
|
||||
pub fn set_default_format(&mut self, tf: TextFormat) {
|
||||
self.default_format = tf;
|
||||
}
|
||||
|
||||
/// Find the index of the span that covers a given search position.
|
||||
///
|
||||
/// This function returns both the index of the span which covers the
|
||||
|
|
Loading…
Reference in New Issue