diff --git a/demo/common/src/lib.rs b/demo/common/src/lib.rs index 4c6b27c9..798103c9 100644 --- a/demo/common/src/lib.rs +++ b/demo/common/src/lib.rs @@ -90,6 +90,7 @@ pub struct DemoApp { scale_factor: f32, scene_view_box: RectF32, + scene_is_monochrome: bool, camera: Camera, frame_counter: u32, @@ -147,8 +148,9 @@ impl DemoApp { let built_svg = load_scene(&options.input_path); let message = get_svg_building_message(&built_svg); - let scene_view_box = built_svg.scene.view_box; + let scene_is_monochrome = built_svg.scene.is_monochrome(); + let renderer = Renderer::new(device, &resources, drawable_size); let scene_thread_proxy = SceneThreadProxy::new(built_svg.scene, options.clone()); update_drawable_size(&window, &scene_thread_proxy); @@ -186,6 +188,7 @@ impl DemoApp { scale_factor: drawable_width as f32 / window_width as f32, scene_view_box, + scene_is_monochrome, camera, frame_counter: 0, @@ -389,6 +392,7 @@ impl DemoApp { self.renderer.debug_ui.ui.event = ui_event; self.renderer.debug_ui.ui.mouse_position = get_mouse_position(&self.sdl_event_pump, self.scale_factor); + self.ui.show_text_effects = self.scene_is_monochrome; let mut ui_action = UIAction::None; self.ui.update(&self.renderer.device, &mut self.renderer.debug_ui, &mut ui_action); @@ -523,6 +527,7 @@ impl DemoApp { self.ui.message = get_svg_building_message(&built_svg); self.scene_view_box = built_svg.scene.view_box; + self.scene_is_monochrome = built_svg.scene.is_monochrome(); update_drawable_size(&self.window, &self.scene_thread_proxy); let drawable_size = current_drawable_size(&self.window); diff --git a/demo/common/src/ui.rs b/demo/common/src/ui.rs index f7eb3bbd..08e75e2b 100644 --- a/demo/common/src/ui.rs +++ b/demo/common/src/ui.rs @@ -28,7 +28,6 @@ const SLIDER_KNOB_HEIGHT: i32 = 48; const EFFECTS_PANEL_WIDTH: i32 = 550; const EFFECTS_PANEL_HEIGHT: i32 = BUTTON_HEIGHT * 3 + PADDING * 4; -const ROTATE_PANEL_X: i32 = PADDING + (BUTTON_WIDTH + PADDING) * 3 + (PADDING + SWITCH_SIZE) * 2; const ROTATE_PANEL_WIDTH: i32 = SLIDER_WIDTH + PADDING * 2; const ROTATE_PANEL_HEIGHT: i32 = PADDING * 2 + SLIDER_HEIGHT; @@ -63,6 +62,7 @@ pub struct DemoUI where D: Device { pub subpixel_aa_effect_enabled: bool, pub rotation: i32, pub message: String, + pub show_text_effects: bool, } impl DemoUI where D: Device { @@ -96,6 +96,7 @@ impl DemoUI where D: Device { subpixel_aa_effect_enabled: false, rotation: SLIDER_WIDTH / 2, message: String::new(), + show_text_effects: true, } } @@ -116,14 +117,18 @@ impl DemoUI where D: Device { let button_size = Point2DI32::new(BUTTON_WIDTH, BUTTON_HEIGHT); let switch_size = Point2DI32::new(SWITCH_SIZE, BUTTON_HEIGHT); - // Draw effects button. - if debug_ui.ui.draw_button(device, position, &self.effects_texture) { - self.effects_panel_visible = !self.effects_panel_visible; + // Draw text effects button. + if self.show_text_effects { + if debug_ui.ui.draw_button(device, position, &self.effects_texture) { + self.effects_panel_visible = !self.effects_panel_visible; + } + if !self.effects_panel_visible { + debug_ui.ui.draw_tooltip(device, + "Text Effects", + RectI32::new(position, button_size)); + } + position += Point2DI32::new(button_size.x() + PADDING, 0); } - if !self.effects_panel_visible { - debug_ui.ui.draw_tooltip(device, "Text Effects", RectI32::new(position, button_size)); - } - position += Point2DI32::new(button_size.x() + PADDING, 0); // Draw open button. if debug_ui.ui.draw_button(device, position, &self.open_texture) { @@ -161,34 +166,34 @@ impl DemoUI where D: Device { debug_ui.ui.draw_tooltip(device, "Background Color", RectI32::new(position, switch_size)); position += Point2DI32::new(SWITCH_SIZE + PADDING, 0); - // Draw rotate and zoom buttons, if applicable. - if !self.three_d_enabled { - if debug_ui.ui.draw_button(device, position, &self.rotate_texture) { - self.rotate_panel_visible = !self.rotate_panel_visible; - } - if !self.rotate_panel_visible { - debug_ui.ui.draw_tooltip(device, "Rotate", RectI32::new(position, button_size)); - } - position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0); - - if debug_ui.ui.draw_button(device, position, &self.zoom_in_texture) { - *action = UIAction::ZoomIn; - } - debug_ui.ui.draw_tooltip(device, "Zoom In", RectI32::new(position, button_size)); - position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0); - - if debug_ui.ui.draw_button(device, position, &self.zoom_out_texture) { - *action = UIAction::ZoomOut; - } - debug_ui.ui.draw_tooltip(device, "Zoom Out", RectI32::new(position, button_size)); - position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0); - } - // Draw effects panel, if necessary. self.draw_effects_panel(device, debug_ui); - // Draw rotate panel, if necessary. - self.draw_rotate_panel(device, debug_ui, action); + // Draw rotate and zoom buttons, if applicable. + if self.three_d_enabled { + return; + } + + if debug_ui.ui.draw_button(device, position, &self.rotate_texture) { + self.rotate_panel_visible = !self.rotate_panel_visible; + } + if !self.rotate_panel_visible { + debug_ui.ui.draw_tooltip(device, "Rotate", RectI32::new(position, button_size)); + } + self.draw_rotate_panel(device, debug_ui, position.x(), action); + position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0); + + if debug_ui.ui.draw_button(device, position, &self.zoom_in_texture) { + *action = UIAction::ZoomIn; + } + debug_ui.ui.draw_tooltip(device, "Zoom In", RectI32::new(position, button_size)); + position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0); + + if debug_ui.ui.draw_button(device, position, &self.zoom_out_texture) { + *action = UIAction::ZoomOut; + } + debug_ui.ui.draw_tooltip(device, "Zoom Out", RectI32::new(position, button_size)); + position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0); } fn draw_message_text(&mut self, device: &D, debug_ui: &mut DebugUI) { @@ -245,20 +250,24 @@ impl DemoUI where D: Device { } - fn draw_rotate_panel(&mut self, device: &D, debug_ui: &mut DebugUI, action: &mut UIAction) { + fn draw_rotate_panel(&mut self, + device: &D, + debug_ui: &mut DebugUI, + rotate_panel_x: i32, + action: &mut UIAction) { if !self.rotate_panel_visible { return; } let bottom = debug_ui.ui.framebuffer_size().y() - PADDING; let rotate_panel_y = bottom - (BUTTON_HEIGHT + PADDING + ROTATE_PANEL_HEIGHT); - let rotate_panel_origin = Point2DI32::new(ROTATE_PANEL_X, rotate_panel_y); + let rotate_panel_origin = Point2DI32::new(rotate_panel_x, rotate_panel_y); let rotate_panel_size = Point2DI32::new(ROTATE_PANEL_WIDTH, ROTATE_PANEL_HEIGHT); debug_ui.ui.draw_solid_rounded_rect(device, RectI32::new(rotate_panel_origin, rotate_panel_size), WINDOW_COLOR); - let (widget_x, widget_y) = (ROTATE_PANEL_X + PADDING, rotate_panel_y + PADDING); + let (widget_x, widget_y) = (rotate_panel_x + PADDING, rotate_panel_y + PADDING); let widget_rect = RectI32::new(Point2DI32::new(widget_x, widget_y), Point2DI32::new(SLIDER_WIDTH, SLIDER_KNOB_HEIGHT)); if let Some(position) = debug_ui.ui diff --git a/renderer/src/gpu/renderer.rs b/renderer/src/gpu/renderer.rs index 473537c9..af39a007 100644 --- a/renderer/src/gpu/renderer.rs +++ b/renderer/src/gpu/renderer.rs @@ -10,8 +10,8 @@ use crate::gpu::debug::DebugUI; use crate::gpu_data::{Batch, BuiltScene, SolidTileScenePrimitive}; -use crate::paint::ObjectShader; use crate::post::DefringingKernel; +use crate::scene::ObjectShader; use crate::tiles::{TILE_HEIGHT, TILE_WIDTH}; use pathfinder_geometry::basic::point::{Point2DI32, Point3DF32}; use pathfinder_geometry::color::ColorU; diff --git a/renderer/src/gpu_data.rs b/renderer/src/gpu_data.rs index f6867f2e..340565d5 100644 --- a/renderer/src/gpu_data.rs +++ b/renderer/src/gpu_data.rs @@ -10,7 +10,7 @@ //! Packed data ready to be sent to the GPU. -use crate::paint::{ObjectShader, ShaderId}; +use crate::scene::{ObjectShader, ShaderId}; use crate::tiles::{self, TILE_HEIGHT, TILE_WIDTH}; use fixedbitset::FixedBitSet; use pathfinder_geometry::basic::line_segment::{LineSegmentF32, LineSegmentU4, LineSegmentU8}; diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index 4159c57e..1dde6461 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -13,7 +13,6 @@ pub mod builder; pub mod gpu; pub mod gpu_data; -pub mod paint; pub mod post; pub mod scene; pub mod tiles; diff --git a/renderer/src/paint.rs b/renderer/src/paint.rs deleted file mode 100644 index 324201ec..00000000 --- a/renderer/src/paint.rs +++ /dev/null @@ -1,29 +0,0 @@ -// pathfinder/renderer/src/paint.rs -// -// Copyright © 2019 The Pathfinder Project Developers. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! How a path is to be filled. - -use pathfinder_geometry::color::ColorU; - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub struct Paint { - pub color: ColorU, -} - -#[derive(Clone, Copy, PartialEq, Debug)] -pub struct PaintId(pub u16); - -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct ShaderId(pub u16); - -#[derive(Clone, Copy, Debug, Default)] -pub struct ObjectShader { - pub fill_color: ColorU, -} diff --git a/renderer/src/scene.rs b/renderer/src/scene.rs index 6c932076..3deff388 100644 --- a/renderer/src/scene.rs +++ b/renderer/src/scene.rs @@ -12,11 +12,11 @@ use crate::builder::{PreparedRenderOptions, PreparedRenderTransform}; use crate::gpu_data::BuiltObject; -use crate::paint::{ObjectShader, Paint, PaintId, ShaderId}; use crate::tiles::Tiler; use crate::z_buffer::ZBuffer; use hashbrown::HashMap; use pathfinder_geometry::basic::rect::{RectF32, RectI32}; +use pathfinder_geometry::color::ColorU; use pathfinder_geometry::outline::Outline; use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator}; use std::fmt::{self, Debug, Formatter}; @@ -139,6 +139,14 @@ impl Scene { outline.prepare_for_tiling(self.view_box); outline } + + pub fn is_monochrome(&self) -> bool { + if self.objects.is_empty() { + return true; + } + let first_paint_id = self.objects[0].paint; + self.objects.iter().skip(1).all(|object| object.paint == first_paint_id) + } } impl Debug for Scene { @@ -194,6 +202,22 @@ impl PathObject { } } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct Paint { + pub color: ColorU, +} + +#[derive(Clone, Copy, PartialEq, Debug)] +pub struct PaintId(pub u16); + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct ShaderId(pub u16); + +#[derive(Clone, Copy, Debug, Default)] +pub struct ObjectShader { + pub fill_color: ColorU, +} + // TODO(pcwalton): Use a `Point2DI32` here? #[inline] pub fn scene_tile_index(tile_x: i32, tile_y: i32, tile_rect: RectI32) -> u32 { diff --git a/renderer/src/tiles.rs b/renderer/src/tiles.rs index 39ae0348..2f1185a1 100644 --- a/renderer/src/tiles.rs +++ b/renderer/src/tiles.rs @@ -9,7 +9,7 @@ // except according to those terms. use crate::gpu_data::BuiltObject; -use crate::paint::ShaderId; +use crate::scene::ShaderId; use crate::sorted_vector::SortedVector; use crate::z_buffer::ZBuffer; use pathfinder_geometry::basic::line_segment::LineSegmentF32; diff --git a/svg/src/lib.rs b/svg/src/lib.rs index 4c913944..31c7da94 100644 --- a/svg/src/lib.rs +++ b/svg/src/lib.rs @@ -21,8 +21,7 @@ use pathfinder_geometry::color::ColorU; use pathfinder_geometry::outline::Outline; use pathfinder_geometry::segment::{Segment, SegmentFlags}; use pathfinder_geometry::stroke::OutlineStrokeToFill; -use pathfinder_renderer::paint::Paint; -use pathfinder_renderer::scene::{PathObject, PathObjectKind, Scene}; +use pathfinder_renderer::scene::{Paint, PathObject, PathObjectKind, Scene}; use std::fmt::{Display, Formatter, Result as FormatResult}; use std::mem; use usvg::{Color as SvgColor, Node, NodeExt, NodeKind, Paint as UsvgPaint};