Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 24 additions & 12 deletions core/src/display_object/edit_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,23 +791,32 @@ impl<'gc> EditText<'gc> {
/// coordinate space into this object's local space.
fn layout_to_local_matrix(self) -> Matrix {
let bounds = self.0.bounds.get();
Matrix::translate(
let matrix = Matrix::translate(
bounds.x_min + Self::GUTTER - Twips::from_pixels(self.0.hscroll.get()),
bounds.y_min + Self::GUTTER - self.0.vertical_scroll_offset(),
)
);

if self.font_type() == FontType::Device {
// Device text cannot be scaled independently in x/y.
// Here we have to make sure the independent x/y scale applied for
// the local coordinate space is reversed, leaving only y scale
// and keeping the original aspect ratio in x.
let m = self.local_to_global_matrix();
let device_font_scale_x = m.d / m.a;
matrix * Matrix::scale(device_font_scale_x, 1.0f32)
} else {
matrix
}
}

/// Returns the matrix for transforming from this object's
/// local space into its layout coordinate space.
fn local_to_layout_matrix(self) -> Matrix {
// layout_to_local contains only a translation,
// no need to inverse the matrix generically.
let Matrix { tx, ty, .. } = self.layout_to_local_matrix();
Matrix::translate(-tx, -ty)
fn local_to_layout_matrix(self) -> Option<Matrix> {
self.layout_to_local_matrix().inverse()
}

fn local_to_layout(self, local: Point<Twips>) -> Point<Twips> {
self.local_to_layout_matrix() * local
fn local_to_layout(self, local: Point<Twips>) -> Option<Point<Twips>> {
Some(self.local_to_layout_matrix()? * local)
}

pub fn replace_text(
Expand Down Expand Up @@ -969,6 +978,7 @@ impl<'gc> EditText<'gc> {
/// The returned tuple should be interpreted as width, then height.
pub fn measure_text(self, _context: &mut UpdateContext<'gc>) -> (Twips, Twips) {
let text_size = self.0.layout.borrow().text_size();
let text_size = self.layout_to_local_matrix() * text_size;
(text_size.width(), text_size.height())
}

Expand Down Expand Up @@ -1592,7 +1602,7 @@ impl<'gc> EditText<'gc> {
/// Characters are divided in half, the last line is extended, etc.
pub fn screen_position_to_index(self, position: Point<Twips>) -> Option<usize> {
let position = self.global_to_local(position)?;
let position = self.local_to_layout(position);
let position = self.local_to_layout(position)?;

// TODO We can use binary search for both y and x here

Expand Down Expand Up @@ -2261,13 +2271,15 @@ impl<'gc> EditText<'gc> {
let line = layout.lines().get(line)?;
let bounds = line.bounds();

// TODO What about internal bounds?
let bounds = self.layout_to_local_matrix() * bounds;
Some(LayoutMetrics {
ascent: line.ascent(),
descent: line.descent(),
leading: line.leading(),
width: bounds.width(),
height: bounds.height() + line.leading(),
x: bounds.offset_x() + Self::GUTTER,
x: bounds.offset_x(),
})
}

Expand Down Expand Up @@ -2302,7 +2314,7 @@ impl<'gc> EditText<'gc> {
return None;
}

let position = self.local_to_layout(position);
let position = self.local_to_layout(position)?;

Some(
self.0
Expand Down
38 changes: 38 additions & 0 deletions core/src/html/dimensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,34 @@ impl<T> From<Position<T>> for Size<T> {
}
}

impl From<swf::PointDelta<Twips>> for Size<Twips> {
fn from(size: swf::PointDelta<Twips>) -> Self {
Self {
width: size.dx,
height: size.dy,
}
}
}

impl From<Size<Twips>> for swf::PointDelta<Twips> {
fn from(size: Size<Twips>) -> Self {
Self {
dx: size.width,
dy: size.height,
}
}
}

impl std::ops::Mul<Size<Twips>> for ruffle_render::matrix::Matrix {
type Output = Size<Twips>;

fn mul(self, size: Size<Twips>) -> Size<Twips> {
// Size has the same semantics as PointDelta when applying a matrix
let size: swf::PointDelta<Twips> = size.into();
(self * size).into()
}
}

/// A type which represents the offset and size of a text box.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct BoxBounds<T> {
Expand Down Expand Up @@ -203,6 +231,16 @@ where
}
}

impl std::ops::Mul<BoxBounds<Twips>> for ruffle_render::matrix::Matrix {
type Output = BoxBounds<Twips>;

fn mul(self, bounds: BoxBounds<Twips>) -> BoxBounds<Twips> {
// BoxBounds have the same semantics as Rectangle when applying a matrix
let bounds: Rectangle<Twips> = bounds.into();
(self * bounds).into()
}
}

impl<T> BoxBounds<T>
where
T: Add<T, Output = T> + Sub<T, Output = T> + Copy,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package {
import flash.display.*;
import flash.text.*;
import flash.geom.*;

[SWF(width="200", height="200")]
public class Test extends Sprite {
[Embed(source="TestFont.ttf", fontName="TestFont", embedAsCFF="false", unicodeRange="U+0061-U+0064")]
private var TestFont:Class;

private var nextX:int = 0;
private var nextY:int = 0;

public function Test() {
stage.scaleMode = "noScale";

test(false);
test(false, 2);
test(false, 1, 2);
test(false, 2, 2);

nextX = 100;
nextY = 0;

test(true);
test(true, 2);
test(true, 1, 2);
test(true, 2, 2);
}

private function test(device: Boolean, scaleX: Number = 1, scaleY: Number = 1):TextField {
var text:TextField = new TextField();
text.x = nextX;
text.y = nextY;
text.border = true;
text.width = 40;
text.height = 20;
text.embedFonts = !device;
var tf:TextFormat = new TextFormat();
tf.font = "TestFont";
tf.size = 10;
text.defaultTextFormat = tf;

text.multiline = true;
text.text = "ab\n\n\n\n\n\n\n\n\n\n\nab";
text.scaleX = scaleX;
text.scaleY = scaleY;
addChild(text);

nextY += 50;

trace("" + device + " = " + text.getCharBoundaries(0) + "," + text.getCharBoundaries(1));
trace("" + device + " = " + metricsToString(text.getLineMetrics(0)));
trace("" + device + " = " + text.textWidth);

return text;
}

private function metricsToString(m:TextLineMetrics): String {
return "width=" + Math.round(m.width);
}
}
}
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10)
false = width=16
false = 16
false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10)
false = width=16
false = 16
false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10)
false = width=16
false = 16
false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10)
false = width=16
false = 16
true = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10)
true = width=16
true = 16
true = (x=2, y=2, w=4, h=10),(x=6, y=2, w=4, h=10)
true = width=8
true = 8
true = (x=2, y=2, w=16, h=10),(x=18, y=2, w=16, h=10)
true = width=32
true = 32
true = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10)
true = width=16
true = 16
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
num_ticks = 1

[[image_comparisons.output.checks]]
tolerance = 0
max_outliers = 90

[[image_comparisons.output.checks]]
tolerance = 128
max_outliers = 14

[player_options]
with_renderer = { optional = true, sample_count = 4 }

[fonts.test_font]
family = "TestFont"
path = "TestFont.ttf"
bold = false
italic = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package {
import flash.display.*;
import flash.text.*;
import flash.geom.*;

[SWF(width="200", height="200")]
public class Test extends Sprite {
[Embed(source="TestFont.ttf", fontName="TestFont", embedAsCFF="false", unicodeRange="U+0061-U+0064")]
private var TestFont:Class;

private var nextX:int = 0;
private var nextY:int = 0;

public function Test() {
stage.scaleMode = "noScale";

test(false);
test(false, 2);
test(false, 1, 2);
test(false, 2, 2);

nextX = 100;
nextY = 0;

test(true);
test(true, 2);
test(true, 1, 2);
test(true, 2, 2);
}

private function test(device: Boolean, scaleX: Number = 1, scaleY: Number = 1):TextField {
var text:TextField = new TextField();
text.x = nextX;
text.y = nextY;
text.border = true;
text.width = 40;
text.height = 20;
text.embedFonts = !device;
var tf:TextFormat = new TextFormat();
tf.font = "TestFont";
tf.size = 10;
text.defaultTextFormat = tf;

text.multiline = true;
text.text = "ab\n\n\n\n\n\n\n\n\n\n\nab";
text.scaleX = scaleX;
text.scaleY = scaleY;
addChild(text);

nextY += 50;

trace("" + device + " = " + text.getCharBoundaries(0) + "," + text.getCharBoundaries(1));
trace("" + device + " = " +
text.getCharIndexAtPoint(1, 5) + "," +
text.getCharIndexAtPoint(2, 5) + "," +
text.getCharIndexAtPoint(5, 5) + "," +
text.getCharIndexAtPoint(8, 5) + "," +
text.getCharIndexAtPoint(10, 5) + "," +
text.getCharIndexAtPoint(12, 5) + "," +
text.getCharIndexAtPoint(15, 5) + "," +
text.getCharIndexAtPoint(8, 1) + "," +
text.getCharIndexAtPoint(12, 1) + "," +
text.getCharIndexAtPoint(8, 12) + "," +
text.getCharIndexAtPoint(12, 12) + "," +
"");
trace("" + device + " = " + metricsToString(text.getLineMetrics(0)));
trace("" + device + " = " + text.textHeight);
trace("" + device + " = " + text.textWidth);

return text;
}

private function metricsToString(m:TextLineMetrics): String {
return "height=" + Math.round(m.height) +
",width=" + Math.round(m.width) +
",x=" + Math.round(m.x) +
",ascent=" + Math.round(m.ascent) +
",descent=" + Math.round(m.descent);
}
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10)
false = 0,0,0,0,1,1,1,-1,-1,-1,-1,
false = height=10,width=16,x=2,ascent=8,descent=2
false = 120
false = 16
false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10)
false = 0,0,0,0,1,1,1,-1,-1,-1,-1,
false = height=10,width=16,x=2,ascent=8,descent=2
false = 120
false = 16
false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10)
false = 0,0,0,0,1,1,1,-1,-1,-1,-1,
false = height=10,width=16,x=2,ascent=8,descent=2
false = 120
false = 16
false = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10)
false = 0,0,0,0,1,1,1,-1,-1,-1,-1,
false = height=10,width=16,x=2,ascent=8,descent=2
false = 120
false = 16
true = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10)
true = 0,0,0,0,1,1,1,-1,-1,-1,-1,
true = height=10,width=16,x=102,ascent=8,descent=2
true = 120
true = 16
true = (x=2, y=2, w=4, h=10),(x=6, y=2, w=4, h=10)
true = 0,0,0,1,-1,-1,-1,-1,-1,-1,-1,
true = height=5,width=8,x=52,ascent=4,descent=1
true = 60
true = 8
true = (x=2, y=2, w=16, h=10),(x=18, y=2, w=16, h=10)
true = 0,0,0,0,0,0,0,-1,-1,-1,-1,
true = height=20,width=32,x=102,ascent=16,descent=4
true = 240
true = 32
true = (x=2, y=2, w=8, h=10),(x=10, y=2, w=8, h=10)
true = 0,0,0,0,1,1,1,-1,-1,-1,-1,
true = height=10,width=16,x=52,ascent=8,descent=2
true = 120
true = 16
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
num_ticks = 1
known_failure = true

[fonts.test_font]
family = "TestFont"
path = "TestFont.ttf"
bold = false
italic = false
Loading
Loading