Improve the fidelity of the NanoVG demo some more
This commit is contained in:
parent
0fec0061e6
commit
83c05e9f77
|
@ -326,8 +326,8 @@ impl LayoutExt for Layout {
|
||||||
|
|
||||||
let glyph_id = last_glyph.glyph_id;
|
let glyph_id = last_glyph.glyph_id;
|
||||||
let font_metrics = last_glyph.font.font.metrics();
|
let font_metrics = last_glyph.font.font.metrics();
|
||||||
let glyph_rect = last_glyph.font.font.typographic_bounds(glyph_id).unwrap();
|
|
||||||
let scale_factor = self.size / font_metrics.units_per_em as f32;
|
let scale_factor = self.size / font_metrics.units_per_em as f32;
|
||||||
|
let glyph_rect = last_glyph.font.font.typographic_bounds(glyph_id).unwrap();
|
||||||
last_glyph.offset.x() + glyph_rect.max_x() * scale_factor
|
last_glyph.offset.x() + glyph_rect.max_x() * scale_factor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,14 +338,16 @@ impl LayoutExt for Layout {
|
||||||
};
|
};
|
||||||
|
|
||||||
let glyph_id = first_glyph.glyph_id;
|
let glyph_id = first_glyph.glyph_id;
|
||||||
|
let font_metrics = first_glyph.font.font.metrics();
|
||||||
|
let scale_factor = self.size / font_metrics.units_per_em as f32;
|
||||||
let glyph_rect = first_glyph.font
|
let glyph_rect = first_glyph.font
|
||||||
.font
|
.font
|
||||||
.raster_bounds(glyph_id,
|
.raster_bounds(glyph_id,
|
||||||
self.size,
|
font_metrics.units_per_em as f32,
|
||||||
Transform2F::default(),
|
Transform2F::default(),
|
||||||
HintingOptions::None,
|
HintingOptions::None,
|
||||||
RasterizationOptions::GrayscaleAa).unwrap();
|
RasterizationOptions::GrayscaleAa).unwrap();
|
||||||
first_glyph.offset.x() + glyph_rect.min_x() as f32
|
first_glyph.offset.x() + glyph_rect.min_x() as f32 * scale_factor
|
||||||
}
|
}
|
||||||
|
|
||||||
fn actual_bounding_box_right(&self) -> f32 {
|
fn actual_bounding_box_right(&self) -> f32 {
|
||||||
|
@ -355,14 +357,16 @@ impl LayoutExt for Layout {
|
||||||
};
|
};
|
||||||
|
|
||||||
let glyph_id = last_glyph.glyph_id;
|
let glyph_id = last_glyph.glyph_id;
|
||||||
|
let font_metrics = last_glyph.font.font.metrics();
|
||||||
|
let scale_factor = self.size / font_metrics.units_per_em as f32;
|
||||||
let glyph_rect = last_glyph.font
|
let glyph_rect = last_glyph.font
|
||||||
.font
|
.font
|
||||||
.raster_bounds(glyph_id,
|
.raster_bounds(glyph_id,
|
||||||
self.size,
|
font_metrics.units_per_em as f32,
|
||||||
Transform2F::default(),
|
Transform2F::default(),
|
||||||
HintingOptions::None,
|
HintingOptions::None,
|
||||||
RasterizationOptions::GrayscaleAa).unwrap();
|
RasterizationOptions::GrayscaleAa).unwrap();
|
||||||
last_glyph.offset.x() + glyph_rect.max_x() as f32
|
last_glyph.offset.x() + glyph_rect.max_x() as f32 * scale_factor
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hanging_baseline(&self) -> f32 {
|
fn hanging_baseline(&self) -> f32 {
|
||||||
|
|
|
@ -276,19 +276,24 @@ fn draw_paragraph(context: &mut CanvasRenderingContext2D,
|
||||||
|
|
||||||
let line_bounds = main_text.lines[text_location.line_index as usize].bounds();
|
let line_bounds = main_text.lines[text_location.line_index as usize].bounds();
|
||||||
let gutter_origin = line_bounds.origin() + vec2f(-10.0, MAIN_LINE_HEIGHT * 0.5);
|
let gutter_origin = line_bounds.origin() + vec2f(-10.0, MAIN_LINE_HEIGHT * 0.5);
|
||||||
|
|
||||||
context.set_font_size(12.0);
|
context.set_font_size(12.0);
|
||||||
|
|
||||||
let gutter_text = format!("{}", text_location.line_index + 1);
|
|
||||||
let gutter_text_width = context.measure_text(&gutter_text).width;
|
|
||||||
|
|
||||||
context.set_text_align(TextAlign::Right);
|
context.set_text_align(TextAlign::Right);
|
||||||
context.set_text_baseline(TextBaseline::Middle);
|
context.set_text_baseline(TextBaseline::Middle);
|
||||||
context.set_fill_style(rgbau(255, 192, 0, 255));
|
context.set_fill_style(rgbau(255, 192, 0, 255));
|
||||||
let gutter_text_bounds = RectF::new(gutter_origin - vec2f(gutter_text_width, 6.0),
|
|
||||||
vec2f(gutter_text_width, 12.0));
|
let gutter_text = format!("{}", text_location.line_index + 1);
|
||||||
|
let gutter_text_metrics = context.measure_text(&gutter_text);
|
||||||
|
|
||||||
|
let gutter_text_bounds =
|
||||||
|
RectF::from_points(vec2f(gutter_text_metrics.actual_bounding_box_left,
|
||||||
|
-gutter_text_metrics.font_bounding_box_ascent),
|
||||||
|
vec2f(gutter_text_metrics.actual_bounding_box_right,
|
||||||
|
-gutter_text_metrics.font_bounding_box_descent));
|
||||||
let gutter_path_bounds = gutter_text_bounds.dilate(vec2f(4.0, 2.0));
|
let gutter_path_bounds = gutter_text_bounds.dilate(vec2f(4.0, 2.0));
|
||||||
let gutter_path_radius = gutter_path_bounds.width() * 0.5 - 1.0;
|
let gutter_path_radius = gutter_path_bounds.width() * 0.5 - 1.0;
|
||||||
let path = create_rounded_rect_path(gutter_path_bounds, gutter_path_radius);
|
let path = create_rounded_rect_path(gutter_path_bounds + gutter_origin,
|
||||||
|
gutter_path_radius);
|
||||||
context.fill_path(path, FillRule::Winding);
|
context.fill_path(path, FillRule::Winding);
|
||||||
|
|
||||||
context.set_fill_style(rgbau(32, 32, 32, 255));
|
context.set_fill_style(rgbau(32, 32, 32, 255));
|
||||||
|
@ -866,13 +871,17 @@ fn draw_search_box(context: &mut CanvasRenderingContext2D,
|
||||||
let corner_radius = rect.height() * 0.5 - 1.0;
|
let corner_radius = rect.height() * 0.5 - 1.0;
|
||||||
|
|
||||||
let path = create_rounded_rect_path(rect, corner_radius);
|
let path = create_rounded_rect_path(rect, corner_radius);
|
||||||
context.save();
|
|
||||||
context.clip_path(path.clone(), FillRule::Winding);
|
|
||||||
context.set_shadow_offset(vec2f(0.0, 1.5));
|
|
||||||
context.set_shadow_blur(5.0 * hidpi_factor);
|
|
||||||
context.set_shadow_color(rgbau(0, 0, 0, 92));
|
|
||||||
context.set_fill_style(rgbau(0, 0, 0, 16));
|
context.set_fill_style(rgbau(0, 0, 0, 16));
|
||||||
context.fill_path(path, FillRule::Winding);
|
context.fill_path(path.clone(), FillRule::Winding);
|
||||||
|
context.save();
|
||||||
|
context.clip_path(path, FillRule::Winding);
|
||||||
|
let shadow_path = create_rounded_rect_path(rect + vec2f(0.0, 1.5), corner_radius);
|
||||||
|
context.set_shadow_blur(5.0 * hidpi_factor);
|
||||||
|
context.set_shadow_offset(vec2f(0.0, 0.0));
|
||||||
|
context.set_shadow_color(rgbau(0, 0, 0, 92));
|
||||||
|
context.set_stroke_style(rgbau(0, 0, 0, 92));
|
||||||
|
context.set_line_width(1.0);
|
||||||
|
context.stroke_path(shadow_path);
|
||||||
context.restore();
|
context.restore();
|
||||||
|
|
||||||
context.set_font_size(rect.height() * 0.5);
|
context.set_font_size(rect.height() * 0.5);
|
||||||
|
@ -884,7 +893,7 @@ fn draw_search_box(context: &mut CanvasRenderingContext2D,
|
||||||
|
|
||||||
context.set_font(FONT_NAME_REGULAR);
|
context.set_font(FONT_NAME_REGULAR);
|
||||||
context.set_font_size(17.0);
|
context.set_font_size(17.0);
|
||||||
context.set_fill_style(rgbau(255, 255, 255, 64));
|
context.set_fill_style(rgbau(255, 255, 255, 32));
|
||||||
context.set_text_align(TextAlign::Left);
|
context.set_text_align(TextAlign::Left);
|
||||||
context.set_text_baseline(TextBaseline::Middle);
|
context.set_text_baseline(TextBaseline::Middle);
|
||||||
context.fill_text(text, rect.origin() + vec2f(1.05, 0.5) * rect.height());
|
context.fill_text(text, rect.origin() + vec2f(1.05, 0.5) * rect.height());
|
||||||
|
@ -947,11 +956,15 @@ fn draw_edit_box(context: &mut CanvasRenderingContext2D, rect: RectF, hidpi_fact
|
||||||
|
|
||||||
context.save();
|
context.save();
|
||||||
let path = create_rounded_rect_path(rect.contract(1.0), CORNER_RADIUS - 1.0);
|
let path = create_rounded_rect_path(rect.contract(1.0), CORNER_RADIUS - 1.0);
|
||||||
context.set_shadow_color(rgbau(255, 255, 255, 32));
|
context.set_fill_style(rgbau(255, 255, 255, 32));
|
||||||
context.set_shadow_offset(vec2f(0.0, 1.5));
|
context.fill_path(path.clone(), FillRule::Winding);
|
||||||
context.set_shadow_blur(4.0 * hidpi_factor);
|
context.clip_path(path.clone(), FillRule::Winding);
|
||||||
context.set_fill_style(rgbau(32, 32, 32, 32));
|
context.set_line_width(1.0);
|
||||||
context.fill_path(path, FillRule::Winding);
|
context.set_shadow_blur(2.0 * hidpi_factor);
|
||||||
|
context.set_shadow_color(rgbau(32, 32, 32, 92));
|
||||||
|
context.set_shadow_offset(vec2f(0.0, 1.0));
|
||||||
|
context.set_stroke_style(rgbau(32, 32, 32, 92));
|
||||||
|
context.stroke_path(path);
|
||||||
context.restore();
|
context.restore();
|
||||||
|
|
||||||
context.set_stroke_style(rgbau(0, 0, 0, 48));
|
context.set_stroke_style(rgbau(0, 0, 0, 48));
|
||||||
|
@ -1009,23 +1022,27 @@ fn draw_check_box(context: &mut CanvasRenderingContext2D,
|
||||||
context.set_text_baseline(TextBaseline::Middle);
|
context.set_text_baseline(TextBaseline::Middle);
|
||||||
context.fill_text(text, rect.origin() + vec2f(28.0, rect.height() * 0.5));
|
context.fill_text(text, rect.origin() + vec2f(28.0, rect.height() * 0.5));
|
||||||
|
|
||||||
|
context.save();
|
||||||
let check_box_rect = RectF::new(vec2f(rect.origin_x(), rect.center().y().floor() - 9.0),
|
let check_box_rect = RectF::new(vec2f(rect.origin_x(), rect.center().y().floor() - 9.0),
|
||||||
vec2f(20.0, 20.0)).contract(1.0);
|
vec2f(20.0, 20.0)).contract(1.0);
|
||||||
let check_box_path = create_rounded_rect_path(check_box_rect, CORNER_RADIUS);
|
let check_box_path = create_rounded_rect_path(check_box_rect, CORNER_RADIUS);
|
||||||
context.save();
|
context.set_fill_style(rgbau(0, 0, 0, 32));
|
||||||
context.clip_path(check_box_path.clone(), FillRule::Winding);
|
context.fill_path(check_box_path.clone(), FillRule::Winding);
|
||||||
context.set_shadow_offset(vec2f(0.0, 1.0));
|
context.clip_path(check_box_path, FillRule::Winding);
|
||||||
context.set_shadow_blur(3.0 * hidpi_factor);
|
context.set_line_width(1.0);
|
||||||
context.set_shadow_color(rgbau(0, 0, 0, 32));
|
context.set_stroke_style(rgbau(0, 0, 0, 92));
|
||||||
context.set_fill_style(rgbau(0, 0, 0, 92));
|
context.set_shadow_color(rgbau(0, 0, 0, 92));
|
||||||
context.fill_path(check_box_path, FillRule::Winding);
|
context.set_shadow_blur(1.5 * hidpi_factor);
|
||||||
|
context.set_shadow_offset(vec2f(0.0, 0.0));
|
||||||
|
let shadow_path = create_rounded_rect_path(check_box_rect + vec2f(0.0, 1.0), CORNER_RADIUS);
|
||||||
|
context.stroke_path(shadow_path);
|
||||||
context.restore();
|
context.restore();
|
||||||
|
|
||||||
context.set_font(FONT_NAME_EMOJI);
|
context.set_font(FONT_NAME_EMOJI);
|
||||||
context.set_font_size(17.0);
|
context.set_font_size(17.0);
|
||||||
context.set_fill_style(rgbau(255, 255, 255, 128));
|
context.set_fill_style(rgbau(255, 255, 255, 128));
|
||||||
context.set_text_align(TextAlign::Center);
|
context.set_text_align(TextAlign::Center);
|
||||||
context.fill_text("✔︎", rect.origin() + vec2f(11.0, rect.height() * 0.5));
|
context.fill_text("✔︎", check_box_rect.center());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_button(context: &mut CanvasRenderingContext2D,
|
fn draw_button(context: &mut CanvasRenderingContext2D,
|
||||||
|
@ -1102,20 +1119,8 @@ fn draw_slider(context: &mut CanvasRenderingContext2D,
|
||||||
context.fill_path(track_path, FillRule::Winding);
|
context.fill_path(track_path, FillRule::Winding);
|
||||||
context.restore();
|
context.restore();
|
||||||
|
|
||||||
// Draw knob shadow.
|
|
||||||
let knob_position = vec2f(rect.origin_x() + (value * rect.width()).floor(), center_y);
|
|
||||||
let mut background_gradient =
|
|
||||||
Gradient::radial(LineSegment2F::new(knob_position, knob_position) + vec2f(0.0, 1.0),
|
|
||||||
F32x2::splat(knob_radius) * F32x2::new(-3.0, 3.0));
|
|
||||||
background_gradient.add_color_stop(rgbau(0, 0, 0, 64), 0.0);
|
|
||||||
background_gradient.add_color_stop(rgbau(0, 0, 0, 0), 1.0);
|
|
||||||
context.set_fill_style(background_gradient);
|
|
||||||
let mut path = Path2D::new();
|
|
||||||
path.rect(RectF::new(knob_position, Vector2F::zero()).dilate(knob_radius + 5.0));
|
|
||||||
path.ellipse(knob_position, knob_radius, 0.0, 0.0, PI_2);
|
|
||||||
context.fill_path(path, FillRule::EvenOdd);
|
|
||||||
|
|
||||||
// Fill knob.
|
// Fill knob.
|
||||||
|
let knob_position = vec2f(rect.origin_x() + (value * rect.width()).floor(), center_y);
|
||||||
let mut background_gradient =
|
let mut background_gradient =
|
||||||
Gradient::linear_from_points(knob_position - vec2f(0.0, knob_radius),
|
Gradient::linear_from_points(knob_position - vec2f(0.0, knob_radius),
|
||||||
knob_position + vec2f(0.0, knob_radius));
|
knob_position + vec2f(0.0, knob_radius));
|
||||||
|
@ -1124,7 +1129,11 @@ fn draw_slider(context: &mut CanvasRenderingContext2D,
|
||||||
let mut path = Path2D::new();
|
let mut path = Path2D::new();
|
||||||
path.ellipse(knob_position, knob_radius - 1.0, 0.0, 0.0, PI_2);
|
path.ellipse(knob_position, knob_radius - 1.0, 0.0, 0.0, PI_2);
|
||||||
context.set_fill_style(rgbu(40, 43, 48));
|
context.set_fill_style(rgbu(40, 43, 48));
|
||||||
|
context.set_shadow_blur(6.0 * hidpi_factor);
|
||||||
|
context.set_shadow_color(rgbau(0, 0, 0, 128));
|
||||||
|
context.set_shadow_offset(vec2f(0.0, 1.0));
|
||||||
context.fill_path(path.clone(), FillRule::Winding);
|
context.fill_path(path.clone(), FillRule::Winding);
|
||||||
|
context.set_shadow_color(rgbau(0, 0, 0, 0));
|
||||||
context.set_fill_style(background_gradient);
|
context.set_fill_style(background_gradient);
|
||||||
context.fill_path(path, FillRule::Winding);
|
context.fill_path(path, FillRule::Winding);
|
||||||
|
|
||||||
|
@ -1156,22 +1165,17 @@ fn draw_thumbnails(context: &mut CanvasRenderingContext2D,
|
||||||
|
|
||||||
context.save();
|
context.save();
|
||||||
|
|
||||||
// Draw drop shadow.
|
|
||||||
let shadow_path = create_rounded_rect_path(rect, CORNER_RADIUS * 2.0);
|
|
||||||
context.set_fill_style(rgbau(0, 0, 0, 0));
|
|
||||||
context.set_shadow_blur(20.0 * hidpi_factor);
|
|
||||||
context.set_shadow_color(rgbau(0, 0, 0, 128));
|
|
||||||
context.set_shadow_offset(vec2f(0.0, 4.0));
|
|
||||||
context.fill_path(shadow_path, FillRule::Winding);
|
|
||||||
context.set_shadow_color(rgbau(0, 0, 0, 0));
|
|
||||||
|
|
||||||
// Draw window.
|
// Draw window.
|
||||||
let mut path = create_rounded_rect_path(rect, CORNER_RADIUS);
|
let mut path = create_rounded_rect_path(rect, CORNER_RADIUS);
|
||||||
path.move_to(rect.origin() + vec2f(-10.0, ARROW_Y_POSITION));
|
path.move_to(rect.origin() + vec2f(-10.0, ARROW_Y_POSITION));
|
||||||
path.line_to(rect.origin() + vec2f(1.0, ARROW_Y_POSITION - 11.0));
|
path.line_to(rect.origin() + vec2f(1.0, ARROW_Y_POSITION - 11.0));
|
||||||
path.line_to(rect.origin() + vec2f(1.0, ARROW_Y_POSITION + 11.0));
|
path.line_to(rect.origin() + vec2f(1.0, ARROW_Y_POSITION + 11.0));
|
||||||
context.set_fill_style(rgbu(200, 200, 200));
|
context.set_fill_style(rgbu(200, 200, 200));
|
||||||
|
context.set_shadow_blur(20.0 * hidpi_factor);
|
||||||
|
context.set_shadow_offset(vec2f(0.0, 4.0));
|
||||||
|
context.set_shadow_color(rgbau(0, 0, 0, 64));
|
||||||
context.fill_path(path, FillRule::Winding);
|
context.fill_path(path, FillRule::Winding);
|
||||||
|
context.set_shadow_color(rgbau(0, 0, 0, 0));
|
||||||
|
|
||||||
// Draw images.
|
// Draw images.
|
||||||
|
|
||||||
|
@ -1240,30 +1244,36 @@ fn draw_thumbnails(context: &mut CanvasRenderingContext2D,
|
||||||
|
|
||||||
// Draw scroll bar.
|
// Draw scroll bar.
|
||||||
|
|
||||||
|
context.save();
|
||||||
let scroll_bar_rect = RectF::new(rect.upper_right() + vec2f(-12.0, 4.0),
|
let scroll_bar_rect = RectF::new(rect.upper_right() + vec2f(-12.0, 4.0),
|
||||||
vec2f(8.0, rect.height() - 8.0));
|
vec2f(8.0, rect.height() - 8.0));
|
||||||
context.save();
|
let path = create_rounded_rect_path(scroll_bar_rect, CORNER_RADIUS);
|
||||||
context.set_shadow_blur(4.0 * hidpi_factor);
|
context.set_fill_style(rgbau(0, 0, 0, 32));
|
||||||
|
context.fill_path(path.clone(), FillRule::Winding);
|
||||||
|
context.clip_path(path, FillRule::Winding);
|
||||||
|
context.set_stroke_style(rgbau(0, 0, 0, 92));
|
||||||
context.set_shadow_offset(vec2f(0.0, 0.0));
|
context.set_shadow_offset(vec2f(0.0, 0.0));
|
||||||
context.set_shadow_color(rgbau(0, 0, 0, 92));
|
context.set_shadow_color(rgbau(0, 0, 0, 92));
|
||||||
context.set_fill_style(rgbau(0, 0, 0, 32));
|
context.set_shadow_blur(4.0 * hidpi_factor);
|
||||||
let clip_path = create_rounded_rect_path(scroll_bar_rect, CORNER_RADIUS);
|
let shadow_path = create_rounded_rect_path(scroll_bar_rect + vec2f(0.0, 1.0), CORNER_RADIUS);
|
||||||
context.clip_path(clip_path, FillRule::Winding);
|
context.stroke_path(shadow_path);
|
||||||
let path = create_rounded_rect_path(scroll_bar_rect + vec2f(0.0, 1.0), CORNER_RADIUS);
|
context.set_shadow_color(rgbau(0, 0, 0, 0));
|
||||||
context.fill_path(path, FillRule::Winding);
|
|
||||||
context.restore();
|
context.restore();
|
||||||
|
|
||||||
let knob_rect = RectF::new(
|
let knob_rect = RectF::new(
|
||||||
rect.upper_right() + vec2f(-11.0, 5.0 + (rect.height() - 8.0 - scroll_height) * scroll_y),
|
scroll_bar_rect.origin() + vec2f(0.0, (rect.height() - 8.0 - scroll_height) * scroll_y),
|
||||||
vec2f(6.0, scroll_height - 2.0));
|
vec2f(8.0, scroll_height));
|
||||||
context.set_shadow_blur(4.0 * hidpi_factor);
|
context.set_fill_style(rgbu(220, 220, 220));
|
||||||
context.set_shadow_offset(vec2f(0.0, 1.0));
|
let path = create_rounded_rect_path(knob_rect.contract(1.0), 3.0);
|
||||||
context.set_shadow_color(rgbu(220, 220, 220));
|
context.fill_path(path.clone(), FillRule::Winding);
|
||||||
context.set_fill_style(rgbau(0, 0, 0, 32));
|
context.clip_path(path, FillRule::Winding);
|
||||||
let clip_path = create_rounded_rect_path(knob_rect, 2.0);
|
context.set_stroke_style(rgbu(128, 128, 128));
|
||||||
context.clip_path(clip_path, FillRule::Winding);
|
context.set_line_width(1.0);
|
||||||
let path = create_rounded_rect_path(knob_rect.dilate(2.0) + vec2f(0.0, 1.0), 3.0);
|
let shadow_path = create_rounded_rect_path(knob_rect, 3.0);
|
||||||
context.fill_path(path, FillRule::Winding);
|
context.set_shadow_blur(2.0 * hidpi_factor);
|
||||||
|
context.set_shadow_color(rgbu(128, 128, 128));
|
||||||
|
context.set_shadow_offset(vec2f(0.0, 0.0));
|
||||||
|
context.stroke_path(shadow_path);
|
||||||
|
|
||||||
context.restore();
|
context.restore();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue