avm2: Implement TextField.getLineIndexOfChar()
This commit is contained in:
parent
f2bbd241f9
commit
ee8c9e21fa
|
@ -170,10 +170,7 @@ package flash.text {
|
|||
return 0;
|
||||
}
|
||||
|
||||
public function getLineIndexOfChar(charIndex:int):int {
|
||||
stub_method("flash.text.TextField", "getLineIndexOfChar");
|
||||
return 0;
|
||||
}
|
||||
public native function getLineIndexOfChar(charIndex:int):int;
|
||||
|
||||
public function getParagraphLength(charIndex:int):int {
|
||||
stub_method("flash.text.TextField", "getParagraphLength");
|
||||
|
|
|
@ -1444,3 +1444,28 @@ pub fn get_selected_text<'gc>(
|
|||
}
|
||||
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())
|
||||
}
|
||||
|
||||
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(
|
||||
self,
|
||||
context: &mut UpdateContext<'_, 'gc>,
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::tag_utils::SwfMovie;
|
|||
use crate::DefaultFont;
|
||||
use gc_arena::Collect;
|
||||
use ruffle_render::shape_utils::DrawCommand;
|
||||
use std::cmp::{max, min};
|
||||
use std::cmp::{max, min, Ordering};
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::mem;
|
||||
use std::ops::{Deref, Range};
|
||||
|
@ -773,6 +773,19 @@ impl<'gc> Layout<'gc> {
|
|||
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.
|
||||
|
|
Loading…
Reference in New Issue