Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Underline layout and rendering #480

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -9,7 +9,7 @@ use text::SendableTextRun;

use clone_arc = std::arc::clone;
use geom::Rect;
use geom::Point2D;
use geom::{Point2D, Size2D};
use std::arc::ARC;
use servo_net::image::base::Image;
use servo_util::range::Range;
@@ -56,6 +56,16 @@ pub impl<'self> DisplayItem {
let origin = self.d().bounds.origin;
let baseline_origin = Point2D(origin.x, origin.y + font.metrics.ascent);
font.draw_text_into_context(ctx, new_run, range, baseline_origin, color);
if(new_run.underline){
//TODO: Use the font metrics to properly position the underline bar
let width = self.d().bounds.size.width;
let u_size = font.metrics.underline_size;
let u_bounds = Rect(
Point2D(baseline_origin.x, baseline_origin.y),
Size2D(width, u_size)
);
ctx.draw_solid_color(&u_bounds, color);
}
},
&Image(_, ref img) => {
debug!("drawing image at %?", self.d().bounds);
@@ -181,11 +181,11 @@ pub impl FontGroup {
self.fonts = ~[];
}

fn create_textrun(&self, text: ~str) -> TextRun {
fn create_textrun(&self, text: ~str, underline: bool) -> TextRun {
assert!(self.fonts.len() > 0);

// TODO(Issue #177): Actually fall back through the FontGroup when a font is unsuitable.
return TextRun::new(self.fonts[0], text);
return TextRun::new(self.fonts[0], text, underline);
}
}

@@ -12,13 +12,15 @@ use servo_util::range::Range;
pub struct TextRun {
text: ~str,
font: @mut Font,
underline: bool,
glyphs: GlyphStore,
}

/// This is a hack until TextRuns are normally sendable, or we instead use ARC<TextRun> everywhere.
pub struct SendableTextRun {
text: ~str,
font: FontDescriptor,
underline: bool,
priv glyphs: GlyphStore,
}

@@ -32,20 +34,22 @@ impl SendableTextRun {
TextRun {
text: copy self.text,
font: font,
underline: copy self.underline,
glyphs: copy self.glyphs
}
}
}

pub impl<'self> TextRun {
fn new(font: @mut Font, text: ~str) -> TextRun {
fn new(font: @mut Font, text: ~str, underline: bool) -> TextRun {
let mut glyph_store = GlyphStore::new(str::char_len(text));
TextRun::compute_potential_breaks(text, &mut glyph_store);
font.shape_text(text, &mut glyph_store);

let run = TextRun {
text: text,
font: font,
underline: underline,
glyphs: glyph_store,
};
return run;
@@ -101,6 +105,7 @@ pub impl<'self> TextRun {
SendableTextRun {
text: copy self.text,
font: self.font.get_descriptor(),
underline: copy self.underline,
glyphs: copy self.glyphs,
}
}
@@ -26,7 +26,7 @@ use newcss::units::{Cursive, Em, Fantasy, Length, Monospace, Pt, Px, SansSerif,
use newcss::values::{CSSBorderWidthLength, CSSBorderWidthMedium};
use newcss::values::{CSSFontFamilyFamilyName, CSSFontFamilyGenericFamily};
use newcss::values::{CSSFontSizeLength, CSSFontStyleItalic, CSSFontStyleNormal};
use newcss::values::{CSSFontStyleOblique, CSSTextAlign};
use newcss::values::{CSSFontStyleOblique, CSSTextAlign, CSSTextDecoration};
use servo_net::image::holder::ImageHolder;
use servo_net::local_image_cache::LocalImageCache;
use servo_util::range::*;
@@ -759,6 +759,11 @@ pub impl RenderBox {
fn text_align(&self) -> CSSTextAlign {
self.nearest_ancestor_element().style().text_align()
}

/// Returns the text decoration of the computed style of the nearest `Element` node
fn text_decoration(&self) -> CSSTextDecoration {
self.nearest_ancestor_element().style().text_decoration()
}
}

impl DebugMethods for RenderBox {
@@ -21,6 +21,8 @@ use gfx::text::text_run::TextRun;
use gfx::text::util::*;
use newcss::values::{CSSTextAlignCenter, CSSTextAlignJustify, CSSTextAlignLeft};
use newcss::values::{CSSTextAlignRight};
use newcss::values::CSSTextDecorationUnderline;
use newcss::values::CSSTextDecoration;
use servo_util::range::Range;
use std::deque::Deque;

@@ -243,6 +245,13 @@ impl TextRunScanner {
let inline = &mut *flow.inline();
let in_boxes = &inline.boxes;

fn hasUnderline(decoration: CSSTextDecoration) -> bool{
match decoration {
CSSTextDecorationUnderline => true,
_ => false
}
}

assert!(self.clump.length() > 0);

debug!("TextRunScanner: flushing boxes in range=%?", self.clump);
@@ -264,6 +273,7 @@ impl TextRunScanner {
let old_box = in_boxes[self.clump.begin()];
let text = old_box.raw_text();
let font_style = old_box.font_style();
let underline = hasUnderline(old_box.text_decoration());

// TODO(#115): Use the actual CSS `white-space` property of the relevant style.
let compression = CompressWhitespaceNewline;
@@ -274,7 +284,7 @@ impl TextRunScanner {
// font group fonts. This is probably achieved by creating the font group above
// and then letting `FontGroup` decide which `Font` to stick into the text run.
let fontgroup = ctx.font_ctx.get_resolved_font_for_style(&font_style);
let run = @fontgroup.create_textrun(transformed_text);
let run = @fontgroup.create_textrun(transformed_text, underline);

debug!("TextRunScanner: pushing single text box in range: %?", self.clump);
let new_box = do old_box.with_imm_base |old_box_base| {
@@ -316,12 +326,13 @@ impl TextRunScanner {
// and then letting `FontGroup` decide which `Font` to stick into the text run.
let font_style = in_boxes[self.clump.begin()].font_style();
let fontgroup = ctx.font_ctx.get_resolved_font_for_style(&font_style);
let underline = hasUnderline(in_boxes[self.clump.begin()].text_decoration());

// TextRuns contain a cycle which is usually resolved by the teardown
// sequence. If no clump takes ownership, however, it will leak.
let clump = self.clump;
let run = if clump.length() != 0 {
Some(@TextRun::new(fontgroup.fonts[0], run_str))
Some(@TextRun::new(fontgroup.fonts[0], run_str, underline))
} else {
None
};
@@ -0,0 +1,55 @@
<!DOCTYPE html>
<html>
<head>
<title>The Book of Mozilla, 11:9</title>
<style type="text/css">
html {
background: maroon;
color: white;
font-style: italic;
}

#moztext {
margin-top: 15%;
font-size: 1.1em;
font-family: serif;
text-align: center;
line-height: 1.5;
}

#from {
font-size: 1.95em;
font-family: serif;
text-align: right;
}

em {
font-size: 1.3em;
line-height: 0;
font-style: oblique;
}

a {
text-decoration: none;
color: white;
}
</style>
</head>
<body>

<p id="moztext">
Mammon slept. And the <em>beast reborn</em> spread over the earth and its numbers
grew legion. And they proclaimed the times and <em>sacrificed</em> crops unto the
fire, with the <em>cunning of foxes</em>. And they built a new world in their own
image as promised by the <em><a href="http://www.mozilla.org/about/mozilla-manifesto.html">
sacred words</a></em>, and <em><a href="http://wiki.mozilla.org/About:mozilla">spoke
</a></em> of the beast with their children. Mammon awoke, and lo! it was
<em>naught</em> but a follower.
</p>

<p id="from">
from <strong>The Book of Mozilla,</strong> 11:9<br/><small>(10th Edition)</small>
</p>

</body>
</html>
@@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<title>The Book of Mozilla, 11:9</title>
<style type="text/css">
html {
background: maroon;
color: white;
font-style: italic;
}

#moztext {
margin-top: 15%;
font-size: 1.1em;
font-family: serif;
text-align: center;
line-height: 1.5;
text-decoration: underline;
}


#from {
font-size: 1.95em;
font-family: serif;
text-align: right;
}

em {
font-size: 1.3em;
line-height: 0;
}

a {
text-decoration: none;
color: white;
}
</style>
</head>
<body>

<p id="moztext">
Mammon slept. And the <em>beast reborn</em> spread over the earth and its numbers
grew legion. And they proclaimed the times and <em>sacrificed</em> crops unto the
fire, with the <em>cunning of foxes</em>. And they built a new world in their own
image as promised by the <em><a href="http://www.mozilla.org/about/mozilla-manifesto.html">
sacred words</a></em>, and <em><a href="http://wiki.mozilla.org/About:mozilla">spoke
</a></em> of the beast with their children. Mammon awoke, and lo! it was
<em>naught</em> but a follower.
</p>

<p id="from">
from <strong>The Book of Mozilla,</strong> 11:9<br/><small>(10th Edition)</small>
</p>

</body>
</html>
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.