Only show the "Text Effects" button when a monochrome SVG is loaded

This commit is contained in:
Patrick Walton 2019-03-06 19:35:57 -08:00
parent 40209b6fe8
commit b80ab2ad25
9 changed files with 80 additions and 73 deletions

View File

@ -90,6 +90,7 @@ pub struct DemoApp {
scale_factor: f32, scale_factor: f32,
scene_view_box: RectF32, scene_view_box: RectF32,
scene_is_monochrome: bool,
camera: Camera, camera: Camera,
frame_counter: u32, frame_counter: u32,
@ -147,8 +148,9 @@ impl DemoApp {
let built_svg = load_scene(&options.input_path); let built_svg = load_scene(&options.input_path);
let message = get_svg_building_message(&built_svg); let message = get_svg_building_message(&built_svg);
let scene_view_box = built_svg.scene.view_box; 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 renderer = Renderer::new(device, &resources, drawable_size);
let scene_thread_proxy = SceneThreadProxy::new(built_svg.scene, options.clone()); let scene_thread_proxy = SceneThreadProxy::new(built_svg.scene, options.clone());
update_drawable_size(&window, &scene_thread_proxy); update_drawable_size(&window, &scene_thread_proxy);
@ -186,6 +188,7 @@ impl DemoApp {
scale_factor: drawable_width as f32 / window_width as f32, scale_factor: drawable_width as f32 / window_width as f32,
scene_view_box, scene_view_box,
scene_is_monochrome,
camera, camera,
frame_counter: 0, frame_counter: 0,
@ -389,6 +392,7 @@ impl DemoApp {
self.renderer.debug_ui.ui.event = ui_event; self.renderer.debug_ui.ui.event = ui_event;
self.renderer.debug_ui.ui.mouse_position = get_mouse_position(&self.sdl_event_pump, self.renderer.debug_ui.ui.mouse_position = get_mouse_position(&self.sdl_event_pump,
self.scale_factor); self.scale_factor);
self.ui.show_text_effects = self.scene_is_monochrome;
let mut ui_action = UIAction::None; let mut ui_action = UIAction::None;
self.ui.update(&self.renderer.device, &mut self.renderer.debug_ui, &mut ui_action); 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.ui.message = get_svg_building_message(&built_svg);
self.scene_view_box = built_svg.scene.view_box; 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); update_drawable_size(&self.window, &self.scene_thread_proxy);
let drawable_size = current_drawable_size(&self.window); let drawable_size = current_drawable_size(&self.window);

View File

@ -28,7 +28,6 @@ const SLIDER_KNOB_HEIGHT: i32 = 48;
const EFFECTS_PANEL_WIDTH: i32 = 550; const EFFECTS_PANEL_WIDTH: i32 = 550;
const EFFECTS_PANEL_HEIGHT: i32 = BUTTON_HEIGHT * 3 + PADDING * 4; 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_WIDTH: i32 = SLIDER_WIDTH + PADDING * 2;
const ROTATE_PANEL_HEIGHT: i32 = PADDING * 2 + SLIDER_HEIGHT; const ROTATE_PANEL_HEIGHT: i32 = PADDING * 2 + SLIDER_HEIGHT;
@ -63,6 +62,7 @@ pub struct DemoUI<D> where D: Device {
pub subpixel_aa_effect_enabled: bool, pub subpixel_aa_effect_enabled: bool,
pub rotation: i32, pub rotation: i32,
pub message: String, pub message: String,
pub show_text_effects: bool,
} }
impl<D> DemoUI<D> where D: Device { impl<D> DemoUI<D> where D: Device {
@ -96,6 +96,7 @@ impl<D> DemoUI<D> where D: Device {
subpixel_aa_effect_enabled: false, subpixel_aa_effect_enabled: false,
rotation: SLIDER_WIDTH / 2, rotation: SLIDER_WIDTH / 2,
message: String::new(), message: String::new(),
show_text_effects: true,
} }
} }
@ -116,14 +117,18 @@ impl<D> DemoUI<D> where D: Device {
let button_size = Point2DI32::new(BUTTON_WIDTH, BUTTON_HEIGHT); let button_size = Point2DI32::new(BUTTON_WIDTH, BUTTON_HEIGHT);
let switch_size = Point2DI32::new(SWITCH_SIZE, BUTTON_HEIGHT); let switch_size = Point2DI32::new(SWITCH_SIZE, BUTTON_HEIGHT);
// Draw effects button. // Draw text effects button.
if debug_ui.ui.draw_button(device, position, &self.effects_texture) { if self.show_text_effects {
self.effects_panel_visible = !self.effects_panel_visible; 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. // Draw open button.
if debug_ui.ui.draw_button(device, position, &self.open_texture) { if debug_ui.ui.draw_button(device, position, &self.open_texture) {
@ -161,34 +166,34 @@ impl<D> DemoUI<D> where D: Device {
debug_ui.ui.draw_tooltip(device, "Background Color", RectI32::new(position, switch_size)); debug_ui.ui.draw_tooltip(device, "Background Color", RectI32::new(position, switch_size));
position += Point2DI32::new(SWITCH_SIZE + PADDING, 0); 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. // Draw effects panel, if necessary.
self.draw_effects_panel(device, debug_ui); self.draw_effects_panel(device, debug_ui);
// Draw rotate panel, if necessary. // Draw rotate and zoom buttons, if applicable.
self.draw_rotate_panel(device, debug_ui, action); 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<D>) { fn draw_message_text(&mut self, device: &D, debug_ui: &mut DebugUI<D>) {
@ -245,20 +250,24 @@ impl<D> DemoUI<D> where D: Device {
} }
fn draw_rotate_panel(&mut self, device: &D, debug_ui: &mut DebugUI<D>, action: &mut UIAction) { fn draw_rotate_panel(&mut self,
device: &D,
debug_ui: &mut DebugUI<D>,
rotate_panel_x: i32,
action: &mut UIAction) {
if !self.rotate_panel_visible { if !self.rotate_panel_visible {
return; return;
} }
let bottom = debug_ui.ui.framebuffer_size().y() - PADDING; let bottom = debug_ui.ui.framebuffer_size().y() - PADDING;
let rotate_panel_y = bottom - (BUTTON_HEIGHT + PADDING + ROTATE_PANEL_HEIGHT); 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); let rotate_panel_size = Point2DI32::new(ROTATE_PANEL_WIDTH, ROTATE_PANEL_HEIGHT);
debug_ui.ui.draw_solid_rounded_rect(device, debug_ui.ui.draw_solid_rounded_rect(device,
RectI32::new(rotate_panel_origin, rotate_panel_size), RectI32::new(rotate_panel_origin, rotate_panel_size),
WINDOW_COLOR); 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), let widget_rect = RectI32::new(Point2DI32::new(widget_x, widget_y),
Point2DI32::new(SLIDER_WIDTH, SLIDER_KNOB_HEIGHT)); Point2DI32::new(SLIDER_WIDTH, SLIDER_KNOB_HEIGHT));
if let Some(position) = debug_ui.ui if let Some(position) = debug_ui.ui

View File

@ -10,8 +10,8 @@
use crate::gpu::debug::DebugUI; use crate::gpu::debug::DebugUI;
use crate::gpu_data::{Batch, BuiltScene, SolidTileScenePrimitive}; use crate::gpu_data::{Batch, BuiltScene, SolidTileScenePrimitive};
use crate::paint::ObjectShader;
use crate::post::DefringingKernel; use crate::post::DefringingKernel;
use crate::scene::ObjectShader;
use crate::tiles::{TILE_HEIGHT, TILE_WIDTH}; use crate::tiles::{TILE_HEIGHT, TILE_WIDTH};
use pathfinder_geometry::basic::point::{Point2DI32, Point3DF32}; use pathfinder_geometry::basic::point::{Point2DI32, Point3DF32};
use pathfinder_geometry::color::ColorU; use pathfinder_geometry::color::ColorU;

View File

@ -10,7 +10,7 @@
//! Packed data ready to be sent to the GPU. //! 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 crate::tiles::{self, TILE_HEIGHT, TILE_WIDTH};
use fixedbitset::FixedBitSet; use fixedbitset::FixedBitSet;
use pathfinder_geometry::basic::line_segment::{LineSegmentF32, LineSegmentU4, LineSegmentU8}; use pathfinder_geometry::basic::line_segment::{LineSegmentF32, LineSegmentU4, LineSegmentU8};

View File

@ -13,7 +13,6 @@
pub mod builder; pub mod builder;
pub mod gpu; pub mod gpu;
pub mod gpu_data; pub mod gpu_data;
pub mod paint;
pub mod post; pub mod post;
pub mod scene; pub mod scene;
pub mod tiles; pub mod tiles;

View File

@ -1,29 +0,0 @@
// pathfinder/renderer/src/paint.rs
//
// Copyright © 2019 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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,
}

View File

@ -12,11 +12,11 @@
use crate::builder::{PreparedRenderOptions, PreparedRenderTransform}; use crate::builder::{PreparedRenderOptions, PreparedRenderTransform};
use crate::gpu_data::BuiltObject; use crate::gpu_data::BuiltObject;
use crate::paint::{ObjectShader, Paint, PaintId, ShaderId};
use crate::tiles::Tiler; use crate::tiles::Tiler;
use crate::z_buffer::ZBuffer; use crate::z_buffer::ZBuffer;
use hashbrown::HashMap; use hashbrown::HashMap;
use pathfinder_geometry::basic::rect::{RectF32, RectI32}; use pathfinder_geometry::basic::rect::{RectF32, RectI32};
use pathfinder_geometry::color::ColorU;
use pathfinder_geometry::outline::Outline; use pathfinder_geometry::outline::Outline;
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator}; use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
use std::fmt::{self, Debug, Formatter}; use std::fmt::{self, Debug, Formatter};
@ -139,6 +139,14 @@ impl Scene {
outline.prepare_for_tiling(self.view_box); outline.prepare_for_tiling(self.view_box);
outline 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 { 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? // TODO(pcwalton): Use a `Point2DI32` here?
#[inline] #[inline]
pub fn scene_tile_index(tile_x: i32, tile_y: i32, tile_rect: RectI32) -> u32 { pub fn scene_tile_index(tile_x: i32, tile_y: i32, tile_rect: RectI32) -> u32 {

View File

@ -9,7 +9,7 @@
// except according to those terms. // except according to those terms.
use crate::gpu_data::BuiltObject; use crate::gpu_data::BuiltObject;
use crate::paint::ShaderId; use crate::scene::ShaderId;
use crate::sorted_vector::SortedVector; use crate::sorted_vector::SortedVector;
use crate::z_buffer::ZBuffer; use crate::z_buffer::ZBuffer;
use pathfinder_geometry::basic::line_segment::LineSegmentF32; use pathfinder_geometry::basic::line_segment::LineSegmentF32;

View File

@ -21,8 +21,7 @@ use pathfinder_geometry::color::ColorU;
use pathfinder_geometry::outline::Outline; use pathfinder_geometry::outline::Outline;
use pathfinder_geometry::segment::{Segment, SegmentFlags}; use pathfinder_geometry::segment::{Segment, SegmentFlags};
use pathfinder_geometry::stroke::OutlineStrokeToFill; use pathfinder_geometry::stroke::OutlineStrokeToFill;
use pathfinder_renderer::paint::Paint; use pathfinder_renderer::scene::{Paint, PathObject, PathObjectKind, Scene};
use pathfinder_renderer::scene::{PathObject, PathObjectKind, Scene};
use std::fmt::{Display, Formatter, Result as FormatResult}; use std::fmt::{Display, Formatter, Result as FormatResult};
use std::mem; use std::mem;
use usvg::{Color as SvgColor, Node, NodeExt, NodeKind, Paint as UsvgPaint}; use usvg::{Color as SvgColor, Node, NodeExt, NodeKind, Paint as UsvgPaint};