diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/servo/gfx/display_list.rs | 6 | ||||
-rw-r--r-- | src/servo/gfx/render_context.rs | 147 | ||||
-rw-r--r-- | src/servo/text/font.rs | 147 |
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); |