aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian J. Burg <burg@cs.washington.edu>2012-10-24 17:29:41 -0700
committerBrian J. Burg <burg@cs.washington.edu>2012-10-24 18:16:51 -0700
commita06b573e74e2493e181330f1bd554bf207f575e7 (patch)
treedfe060133c3ad19ff3f157b512cf6819b6bc3cba
parent416ffeaca6870e94ea3c579673f4d38bec7d0ef0 (diff)
downloadservo-a06b573e74e2493e181330f1bd554bf207f575e7.tar.gz
servo-a06b573e74e2493e181330f1bd554bf207f575e7.zip
Move RenderContext::draw_text() to Font::draw_text_into_context(). Fixes #156.
-rw-r--r--src/servo/gfx/display_list.rs6
-rw-r--r--src/servo/gfx/render_context.rs147
-rw-r--r--src/servo/text/font.rs147
3 files changed, 153 insertions, 147 deletions
diff --git a/src/servo/gfx/display_list.rs b/src/servo/gfx/display_list.rs
index 3e1b9361708..93c233c3113 100644
--- a/src/servo/gfx/display_list.rs
+++ b/src/servo/gfx/display_list.rs
@@ -2,6 +2,7 @@ use azure::azure_hl::DrawTarget;
use au = gfx::geometry;
use au::Au;
use geom::rect::Rect;
+use geom::point::Point2D;
use image::base::Image;
use render_context::RenderContext;
use servo_text::text_run;
@@ -49,7 +50,10 @@ impl DisplayItem {
SolidColor(_, r,g,b) => ctx.draw_solid_color(&self.d().bounds, r, g, b),
Text(_, run, range) => {
let new_run = @run.deserialize(ctx.font_cache);
- ctx.draw_text(self.d().bounds, new_run, range)
+ let font = new_run.font;
+ 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);
},
Image(_, ref img) => ctx.draw_image(self.d().bounds, clone_arc(img)),
Border(_, width, r, g, b) => ctx.draw_border(&self.d().bounds, width, r, g, b),
diff --git a/src/servo/gfx/render_context.rs b/src/servo/gfx/render_context.rs
index 62f9948d4e8..03d175ffbf3 100644
--- a/src/servo/gfx/render_context.rs
+++ b/src/servo/gfx/render_context.rs
@@ -15,10 +15,8 @@ use std::arc::ARC;
use geom::size::Size2D;
use geom::point::Point2D;
use geom::rect::Rect;
-use azure::bindgen::AzDrawTargetFillGlyphs;
-use azure::cairo::{cairo_font_face_t, cairo_scaled_font_t};
use azure::cairo_hl::ImageSurface;
-use azure::{AzDrawOptions, AzFloat, AzGlyph, AzGlyphBuffer};
+use azure::{AzDrawOptions, AzFloat};
use azure::azure_hl::{AsAzureRect, B8G8R8A8, Color, ColorPattern, DrawOptions, DrawSurfaceOptions, StrokeOptions};
use azure::azure_hl::{DrawTarget, Linear};
@@ -28,6 +26,10 @@ struct RenderContext {
}
impl RenderContext {
+ pub fn get_draw_target(&self) -> &self/DrawTarget {
+ &self.canvas.draw_target
+ }
+
pub fn draw_solid_color(&self, bounds: &Rect<Au>, r: u8, g: u8, b: u8) {
let color = Color(r.to_float() as AzFloat,
g.to_float() as AzFloat,
@@ -74,85 +76,6 @@ impl RenderContext {
draw_surface_options, draw_options);
}
- // TODO: azure takes the origin as the left or right baseline. We
- // should be passing in a bunch of glyphs and the baseline
- // point. The baseline point should be computed somewhere else,
- // like Font::draw_to_context() or TextRun::draw_to_context().
- pub fn draw_text(&self, bounds: Rect<Au>, run: &TextRun, range: Range) {
- use ptr::{null};
- use vec::raw::to_ptr;
- use libc::types::common::c99::{uint16_t, uint32_t};
- use geom::point::Point2D;
- use text::font_cache::FontCache;
- use text::font::Font;
- use azure::{AzNativeFont, AzFloat, AZ_NATIVE_FONT_CAIRO_FONT_FACE};
- use azure::bindgen::{AzCreateScaledFontWithCairo,
- AzReleaseScaledFont,
- AzCreateColorPattern,
- AzReleaseColorPattern};
- use azure::cairo::bindgen::cairo_scaled_font_destroy;
-
- let font = run.font;
- // See the TODO above.
- let y_adjust = font.metrics.descent;
- let nfont: AzNativeFont = {
- mType: AZ_NATIVE_FONT_CAIRO_FONT_FACE,
- mFont: null()
- };
-
- let cfont = get_cairo_font(font);
- let azfont = AzCreateScaledFontWithCairo(to_unsafe_ptr(&nfont), 1f as AzFloat, cfont);
- assert azfont.is_not_null();
- cairo_scaled_font_destroy(cfont);
-
- let color = {
- r: 0f as AzFloat,
- g: 0f as AzFloat,
- b: 0f as AzFloat,
- a: 1f as AzFloat
- };
- let pattern = AzCreateColorPattern(to_unsafe_ptr(&color));
- assert pattern.is_not_null();
-
- let options: AzDrawOptions = {
- mAlpha: 1f as AzFloat,
- fields: 0 as uint16_t
- };
-
- let mut origin = Point2D(bounds.origin.x, bounds.origin.y.add(&bounds.size.height) - y_adjust);
- let azglyphs = DVec();
- azglyphs.reserve(range.length());
-
- do run.glyphs.iter_glyphs_for_range(range) |_i, glyph| {
- let glyph_advance = glyph.advance();
- let glyph_offset = glyph.offset().get_default(au::zero_point());
-
- let azglyph: AzGlyph = {
- mIndex: glyph.index() as uint32_t,
- mPosition: {
- x: au::to_px(origin.x + glyph_offset.x) as AzFloat,
- y: au::to_px(origin.y + glyph_offset.y) as AzFloat
- }
- };
- origin = Point2D(origin.x + glyph_advance, origin.y);
- azglyphs.push(move azglyph)
- };
-
- let azglyph_buf_len = azglyphs.len();
- let azglyph_buf = dvec::unwrap(move azglyphs);
- let glyphbuf: AzGlyphBuffer = unsafe {{
- mGlyphs: to_ptr(azglyph_buf),
- mNumGlyphs: azglyph_buf_len as uint32_t
- }};
-
- // TODO: this call needs to move into azure_hl.rs
- AzDrawTargetFillGlyphs(self.canvas.draw_target.azure_draw_target, azfont,
- to_unsafe_ptr(&glyphbuf), pattern, to_unsafe_ptr(&options), null());
-
- AzReleaseColorPattern(pattern);
- AzReleaseScaledFont(azfont);
- }
-
fn clear(&self) {
let pattern = ColorPattern(Color(1f as AzFloat, 1f as AzFloat, 1f as AzFloat, 1f as AzFloat));
let rect = Rect(Point2D(0 as AzFloat, 0 as AzFloat),
@@ -187,63 +110,3 @@ impl Rect<Au> : ToAzureRect {
Size2D(au::to_px(self.size.width) as AzFloat, au::to_px(self.size.height) as AzFloat))
}
}
-
-#[cfg(target_os = "linux")]
-fn get_cairo_face(font: &Font) -> *cairo_font_face_t {
-
- use libc::c_int;
- use azure::cairo_ft::bindgen::{cairo_ft_font_face_create_for_ft_face};
-
- let ftface = font.native_font.face;
- let cface = cairo_ft_font_face_create_for_ft_face(ftface, 0 as c_int);
- // FIXME: error handling
- return cface;
-}
-
-#[cfg(target_os = "macos")]
-fn get_cairo_face(font: &Font) -> *cairo_font_face_t {
- use azure::cairo_quartz::bindgen::cairo_quartz_font_face_create_for_cgfont;
-
- let cgfont = font.native_font.cgfont;
- let face = cairo_quartz_font_face_create_for_cgfont(cgfont);
- // FIXME: error handling
- return face;
-}
-
-fn get_cairo_font(font: &Font) -> *cairo_scaled_font_t {
-
- use libc::c_double;
- use azure::cairo;
- use cairo::cairo_matrix_t;
- use cairo::bindgen::{cairo_matrix_init_identity,
- cairo_matrix_scale,
- cairo_font_options_create,
- cairo_scaled_font_create,
- cairo_font_options_destroy,
- cairo_font_face_destroy};
-
- // FIXME: error handling
-
- let face = get_cairo_face(font);
-
- let idmatrix: cairo_matrix_t = {
- xx: 0 as c_double,
- yx: 0 as c_double,
- xy: 0 as c_double,
- yy: 0 as c_double,
- x0: 0 as c_double,
- y0: 0 as c_double
- };
- cairo_matrix_init_identity(to_unsafe_ptr(&idmatrix));
-
- let fontmatrix = idmatrix;
- cairo_matrix_scale(to_unsafe_ptr(&fontmatrix), 21f as c_double, 21f as c_double);
- let options = cairo_font_options_create();
- let cfont = cairo_scaled_font_create(face, to_unsafe_ptr(&fontmatrix),
- to_unsafe_ptr(&idmatrix), options);
- cairo_font_options_destroy(options);
- cairo_font_face_destroy(face);
-
- return cfont;
-}
-
diff --git a/src/servo/text/font.rs b/src/servo/text/font.rs
index 8d6a7aacec9..ce5a4d122b5 100644
--- a/src/servo/text/font.rs
+++ b/src/servo/text/font.rs
@@ -2,16 +2,15 @@ pub use font_cache::FontCache;
use au = gfx::geometry;
use au::Au;
+use core::dvec::DVec;
+use gfx::render_context::RenderContext;
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use glyph::GlyphIndex;
-use libc::{ c_int, c_double, c_ulong };
use native_font::NativeFont;
-use ptr::{null, addr_of};
-use text::text_run::TextRun;
-use vec_to_ptr = vec::raw::to_ptr;
use servo_util::range::Range;
+use text::text_run::TextRun;
// Used to abstract over the shaper's choice of fixed int representation.
type FractionalPixel = float;
@@ -42,6 +41,7 @@ struct RunMetrics {
// Public API
pub trait FontMethods {
+ fn draw_text_into_context(rctx: &RenderContext, run: &TextRun, range: Range, baseline_origin: Point2D<Au>);
fn measure_text(&TextRun, Range) -> RunMetrics;
fn buf(&self) -> @~[u8];
@@ -52,6 +52,145 @@ pub trait FontMethods {
}
pub impl Font : FontMethods {
+ fn draw_text_into_context(rctx: &RenderContext, run: &TextRun, range: Range, baseline_origin: Point2D<Au>) {
+ use libc::types::common::c99::{uint16_t, uint32_t};
+ use azure::{AzDrawOptions,
+ AzFloat,
+ AzGlyph,
+ AzGlyphBuffer,
+ AzNativeFont,
+ AZ_NATIVE_FONT_CAIRO_FONT_FACE};
+ use azure::bindgen::{AzCreateColorPattern,
+ AzCreateScaledFontWithCairo,
+ AzDrawTargetFillGlyphs,
+ AzReleaseScaledFont,
+ AzReleaseColorPattern};
+ use azure::cairo::{cairo_font_face_t, cairo_scaled_font_t};
+ use azure::cairo::bindgen::cairo_scaled_font_destroy;
+
+ let target = rctx.get_draw_target();
+ // TODO(Issue #83): these should be cached on this Font, not created anew
+ let nfont: AzNativeFont = {
+ mType: AZ_NATIVE_FONT_CAIRO_FONT_FACE,
+ mFont: ptr::null()
+ };
+
+ // TODO(Issue #64): we should be able to remove cairo stepping
+ // stones and manual memory management, and put them inside of
+ // azure_hl.rs and elsewhere instead.
+ let cfont = get_cairo_font(&self);
+ let azfont = AzCreateScaledFontWithCairo(ptr::to_unsafe_ptr(&nfont), 1f as AzFloat, cfont);
+ assert azfont.is_not_null();
+ cairo_scaled_font_destroy(cfont);
+
+ let color = {
+ r: 0f as AzFloat,
+ g: 0f as AzFloat,
+ b: 0f as AzFloat,
+ a: 1f as AzFloat
+ };
+ let pattern = AzCreateColorPattern(ptr::to_unsafe_ptr(&color));
+ assert pattern.is_not_null();
+
+ let options: AzDrawOptions = {
+ mAlpha: 1f as AzFloat,
+ fields: 0 as uint16_t
+ };
+
+ let mut origin = copy baseline_origin;
+ let azglyphs = DVec();
+ azglyphs.reserve(range.length());
+
+ do run.glyphs.iter_glyphs_for_range(range) |_i, glyph| {
+ let glyph_advance = glyph.advance();
+ let glyph_offset = glyph.offset().get_default(au::zero_point());
+
+ let azglyph: AzGlyph = {
+ mIndex: glyph.index() as uint32_t,
+ mPosition: {
+ x: au::to_px(origin.x + glyph_offset.x) as AzFloat,
+ y: au::to_px(origin.y + glyph_offset.y) as AzFloat
+ }
+ };
+ origin = Point2D(origin.x + glyph_advance, origin.y);
+ azglyphs.push(move azglyph)
+ };
+
+ let azglyph_buf_len = azglyphs.len();
+ let azglyph_buf = dvec::unwrap(move azglyphs);
+ let glyphbuf: AzGlyphBuffer = unsafe {{
+ mGlyphs: vec::raw::to_ptr(azglyph_buf),
+ mNumGlyphs: azglyph_buf_len as uint32_t
+ }};
+
+ // TODO: this call needs to move into azure_hl.rs
+ AzDrawTargetFillGlyphs(target.azure_draw_target, azfont,
+ ptr::to_unsafe_ptr(&glyphbuf), pattern, ptr::to_unsafe_ptr(&options), ptr::null());
+
+ AzReleaseColorPattern(pattern);
+ AzReleaseScaledFont(azfont);
+
+ // TODO: these should be private instance methods
+ #[cfg(target_os = "linux")]
+ fn get_cairo_face(font: &Font) -> *cairo_font_face_t {
+
+ use libc::c_int;
+ use azure::cairo_ft::bindgen::{cairo_ft_font_face_create_for_ft_face};
+
+ let ftface = font.native_font.face;
+ let cface = cairo_ft_font_face_create_for_ft_face(ftface, 0 as c_int);
+ // FIXME: error handling
+ return cface;
+ }
+
+ #[cfg(target_os = "macos")]
+ fn get_cairo_face(font: &Font) -> *cairo_font_face_t {
+ use azure::cairo_quartz::bindgen::cairo_quartz_font_face_create_for_cgfont;
+
+ let cgfont = font.native_font.cgfont;
+ let face = cairo_quartz_font_face_create_for_cgfont(cgfont);
+ // FIXME: error handling
+ return face;
+ }
+
+ fn get_cairo_font(font: &Font) -> *cairo_scaled_font_t {
+
+ use libc::c_double;
+ use azure::cairo;
+ use cairo::cairo_matrix_t;
+ use cairo::bindgen::{cairo_matrix_init_identity,
+ cairo_matrix_scale,
+ cairo_font_options_create,
+ cairo_scaled_font_create,
+ cairo_font_options_destroy,
+ cairo_font_face_destroy};
+
+ // FIXME: error handling
+
+ let face = get_cairo_face(font);
+
+ let idmatrix: cairo_matrix_t = {
+ xx: 0 as c_double,
+ yx: 0 as c_double,
+ xy: 0 as c_double,
+ yy: 0 as c_double,
+ x0: 0 as c_double,
+ y0: 0 as c_double
+ };
+ cairo_matrix_init_identity(ptr::to_unsafe_ptr(&idmatrix));
+
+ let fontmatrix = idmatrix;
+ cairo_matrix_scale(ptr::to_unsafe_ptr(&fontmatrix), 21f as c_double, 21f as c_double);
+ let options = cairo_font_options_create();
+ let cfont = cairo_scaled_font_create(face, ptr::to_unsafe_ptr(&fontmatrix),
+ ptr::to_unsafe_ptr(&idmatrix), options);
+ cairo_font_options_destroy(options);
+ cairo_font_face_destroy(face);
+
+ return cfont;
+ }
+ }
+
fn measure_text(run: &TextRun, range: Range) -> RunMetrics {
assert range.is_valid_for_string(run.text);