avm2: Implement TextField.getLineIndexOfChar()
This commit is contained in:
parent
f2bbd241f9
commit
ee8c9e21fa
|
@ -170,10 +170,7 @@ package flash.text {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLineIndexOfChar(charIndex:int):int {
|
public native function getLineIndexOfChar(charIndex:int):int;
|
||||||
stub_method("flash.text.TextField", "getLineIndexOfChar");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getParagraphLength(charIndex:int):int {
|
public function getParagraphLength(charIndex:int):int {
|
||||||
stub_method("flash.text.TextField", "getParagraphLength");
|
stub_method("flash.text.TextField", "getParagraphLength");
|
||||||
|
|
|
@ -1444,3 +1444,28 @@ pub fn get_selected_text<'gc>(
|
||||||
}
|
}
|
||||||
Ok("".into())
|
Ok("".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_line_index_of_char<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let Some(this) = this
|
||||||
|
.as_display_object()
|
||||||
|
.and_then(|this| this.as_edit_text())
|
||||||
|
else {
|
||||||
|
return Ok(Value::Undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
let index = args.get_i32(activation, 0)?;
|
||||||
|
if index < 0 {
|
||||||
|
// Docs say "throw RangeError", reality says "return -1".
|
||||||
|
return Ok(Value::Number(-1f64));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(line) = this.line_index_of_char(index as usize) {
|
||||||
|
Ok(line.into())
|
||||||
|
} else {
|
||||||
|
Ok(Value::Number(-1f64))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1931,6 +1931,10 @@ impl<'gc> EditText<'gc> {
|
||||||
Some(first_box.start())
|
Some(first_box.start())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn line_index_of_char(self, index: usize) -> Option<usize> {
|
||||||
|
self.0.read().layout.find_line_index_by_position(index)
|
||||||
|
}
|
||||||
|
|
||||||
fn execute_avm1_asfunction(
|
fn execute_avm1_asfunction(
|
||||||
self,
|
self,
|
||||||
context: &mut UpdateContext<'_, 'gc>,
|
context: &mut UpdateContext<'_, 'gc>,
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::tag_utils::SwfMovie;
|
||||||
use crate::DefaultFont;
|
use crate::DefaultFont;
|
||||||
use gc_arena::Collect;
|
use gc_arena::Collect;
|
||||||
use ruffle_render::shape_utils::DrawCommand;
|
use ruffle_render::shape_utils::DrawCommand;
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min, Ordering};
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{Deref, Range};
|
use std::ops::{Deref, Range};
|
||||||
|
@ -773,6 +773,19 @@ impl<'gc> Layout<'gc> {
|
||||||
boxes_iter: None,
|
boxes_iter: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_line_index_by_position(&self, position: usize) -> Option<usize> {
|
||||||
|
let result = self.lines.binary_search_by(|probe| {
|
||||||
|
if probe.end <= position {
|
||||||
|
Ordering::Less
|
||||||
|
} else if position < probe.start {
|
||||||
|
Ordering::Greater
|
||||||
|
} else {
|
||||||
|
Ordering::Equal
|
||||||
|
}
|
||||||
|
});
|
||||||
|
result.ok()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A `LayoutLine` represents a single line of text.
|
/// A `LayoutLine` represents a single line of text.
|
||||||
|
|
Loading…
Reference in New Issue