Skip to content

Commit

Permalink
WIP: Proper DPI handling
Browse files Browse the repository at this point in the history
  • Loading branch information
fschutt committed Jan 14, 2019
1 parent 5098ab3 commit f732dc7
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 11 deletions.
14 changes: 11 additions & 3 deletions azul/src/display_list.rs
Expand Up @@ -275,6 +275,7 @@ impl<'a, T: Layout + 'a> DisplayList<'a, T> {
push_rectangles_into_displaylist(
&laid_out_rectangles,
window.internal.epoch,
window.state.size.hidpi_factor,
rects_in_rendering_order,
&mut scrollable_nodes,
&mut window.scroll_states,
Expand Down Expand Up @@ -679,6 +680,7 @@ fn test_overflow_parsing() {
fn push_rectangles_into_displaylist<'a, 'b, 'c, 'd, 'e, 'f, T: Layout>(
solved_rects: &NodeDataContainer<LayoutRect>,
epoch: Epoch,
hidpi_factor: f64,
content_grouped_rectangles: ContentGroupOrder,
scrollable_nodes: &mut ScrolledNodes,
scroll_states: &mut ScrollStates,
Expand All @@ -698,6 +700,7 @@ fn push_rectangles_into_displaylist<'a, 'b, 'c, 'd, 'e, 'f, T: Layout>(
item: RenderableNodeId,
solved_rects_data: &NodeDataContainer<LayoutRect>,
epoch: Epoch,
hidpi_factor: f64,
scrollable_nodes: &mut ScrolledNodes,
referenced_content: &DisplayListParametersRef<'a,'b,'c,'d,'e, T>,
referenced_mutable_content: &mut DisplayListParametersMut<'f, T>,
Expand All @@ -709,6 +712,7 @@ fn push_rectangles_into_displaylist<'a, 'b, 'c, 'd, 'e, 'f, T: Layout>(
epoch,
rect_idx: item.node_id,
html_node: &html_node.node_type,
hidpi_factor,
};

displaylist_handle_rect(solved_rect, scrollable_nodes, rectangle, referenced_content, referenced_mutable_content);
Expand All @@ -734,6 +738,7 @@ fn push_rectangles_into_displaylist<'a, 'b, 'c, 'd, 'e, 'f, T: Layout>(
push_rect(content_group.root,
solved_rects,
epoch,
hidpi_factor,
scrollable_nodes,
referenced_content,
referenced_mutable_content,
Expand All @@ -743,6 +748,7 @@ fn push_rectangles_into_displaylist<'a, 'b, 'c, 'd, 'e, 'f, T: Layout>(
push_rect(item,
solved_rects,
epoch,
hidpi_factor,
scrollable_nodes,
referenced_content,
referenced_mutable_content,
Expand Down Expand Up @@ -832,6 +838,7 @@ pub(crate) struct DisplayListRectParams<'a, T: 'a + Layout> {
pub epoch: Epoch,
pub rect_idx: NodeId,
pub html_node: &'a NodeType<T>,
hidpi_factor: f64,
}

fn get_clip_region<'a>(bounds: LayoutRect, rect: &DisplayRectangle<'a>) -> Option<ComplexClipRegion> {
Expand Down Expand Up @@ -864,7 +871,7 @@ fn displaylist_handle_rect<'a,'b,'c,'d,'e,'f,'g, T: Layout>(
} = referenced_content;

let DisplayListRectParams {
epoch, rect_idx, html_node,
epoch, rect_idx, html_node, hidpi_factor,
} = rectangle;

let rect = &display_rectangle_arena[rect_idx];
Expand Down Expand Up @@ -1051,7 +1058,7 @@ fn push_opengl_texture<'a,'b,'c,'d,'e,'f,'g, T: Layout>(
use compositor::{ActiveTexture, ACTIVE_GL_TEXTURES};
use gleam::gl;

let bounds = HidpiAdjustedBounds::from_bounds(&referenced_mutable_content.fake_window, info.rect);
let bounds = HidpiAdjustedBounds::from_bounds(info.rect, rectangle.hidpi_factor);

let texture;

Expand Down Expand Up @@ -1115,7 +1122,7 @@ fn push_iframe<'a,'b,'c,'d,'e,'f,'g, T: Layout>(
{
use glium::glutin::dpi::{LogicalPosition, LogicalSize};

let bounds = HidpiAdjustedBounds::from_bounds(&referenced_mutable_content.fake_window, info.rect);
let bounds = HidpiAdjustedBounds::from_bounds(info.rect, rectangle.hidpi_factor);

let new_dom;

Expand Down Expand Up @@ -1175,6 +1182,7 @@ fn push_iframe<'a,'b,'c,'d,'e,'f,'g, T: Layout>(
push_rectangles_into_displaylist(
&laid_out_rectangles,
rectangle.epoch,
rectangle.hidpi_factor,
rects_in_rendering_order,
&mut scrollable_nodes,
&mut ScrollStates::new(),
Expand Down
98 changes: 90 additions & 8 deletions azul/src/window.rs
Expand Up @@ -133,7 +133,7 @@ impl Facade for ReadOnlyWindow {
}

impl ReadOnlyWindow {

/*
pub fn get_physical_size(&self) -> (u32, u32) {
let hidpi = self.get_hidpi_factor();
self.inner.gl_window().get_inner_size().unwrap().to_physical(hidpi).into()
Expand All @@ -143,7 +143,7 @@ impl ReadOnlyWindow {
pub fn get_hidpi_factor(&self) -> f64 {
self.inner.gl_window().get_hidpi_factor()
}

*/
// Since webrender is asynchronous, we can't let the user draw
// directly onto the frame or the texture since that has to be timed
// with webrender
Expand Down Expand Up @@ -678,7 +678,13 @@ impl<'a, T: Layout> Window<T> {
WindowMonitorTarget::Custom(ref id) => id.clone(),
};

let hidpi_factor = monitor.get_hidpi_factor();
let winit_hidpi_factor = monitor.get_hidpi_factor();

#[cfg(target_os = "linux")]
let hidpi_factor = linux_get_hidpi_factor(&monitor, &events_loop);
#[cfg(not(target_os = "linux"))]
let hidpi_factor = winit_hidpi_factor;

options.state.size.hidpi_factor = hidpi_factor;

let mut window = WindowBuilder::new()
Expand Down Expand Up @@ -768,15 +774,20 @@ impl<'a, T: Layout> Window<T> {
if options.state.is_maximized && !options.state.is_fullscreen {
gl_window.window().set_maximized(true);
} else if !options.state.is_fullscreen {
gl_window.window().set_inner_size(options.state.size.dimensions);
let inner_size = LogicalSize::new(
options.state.size.dimensions.width / winit_hidpi_factor * hidpi_factor,
options.state.size.dimensions.height / winit_hidpi_factor * hidpi_factor
);
println!("setting inner size to: {:?}", inner_size);
gl_window.window().set_inner_size(inner_size);
}

/*#[cfg(debug_assertions)]
let display = Display::with_debug(gl_window, DebugCallbackBehavior::DebugMessageOnError)?;
#[cfg(not(debug_assertions))]*/
let display = Display::with_debug(gl_window, DebugCallbackBehavior::Ignore)?;

let device_pixel_ratio = display.gl_window().get_hidpi_factor();
let device_pixel_ratio = options.state.size.hidpi_factor;

// pre-caching shaders means to compile all shaders on startup
// this can take significant time and should be only used for testing the shaders
Expand Down Expand Up @@ -968,7 +979,12 @@ impl<'a, T: Layout> Window<T> {
}

if let Some(dpi) = frame_event_info.new_dpi_factor {
self.state.size.hidpi_factor = dpi;
#[cfg(target_os = "linux")] {
self.state.size.hidpi_factor = linux_get_hidpi_factor(&self.display.gl_window().window().get_current_monitor(), &self.events_loop);
}
#[cfg(not(target_os = "linux"))] {
self.state.size.hidpi_factor = dpi;
}
frame_event_info.should_redraw_window = true;
}
}
Expand Down Expand Up @@ -1010,8 +1026,7 @@ pub struct HidpiAdjustedBounds {
}

impl HidpiAdjustedBounds {
pub fn from_bounds<T: Layout>(fake_window: &FakeWindow<T>, bounds: LayoutRect) -> Self {
let hidpi_factor = fake_window.read_only_window().get_hidpi_factor();
pub fn from_bounds(bounds: LayoutRect, hidpi_factor: f64) -> Self {
let logical_size = LogicalSize::new(bounds.size.width as f64, bounds.size.height as f64);
let physical_size = logical_size.to_physical(hidpi_factor);

Expand Down Expand Up @@ -1068,3 +1083,70 @@ fn set_webrender_debug_flags(r: &mut Renderer, old_flags: &DebugState, new_flags
r.set_debug_flag(DebugFlags::GPU_CACHE_DBG, new_flags.gpu_cache_dbg);
}
}

#[cfg(target_os = "linux")]
fn get_xft_dpi() -> Option<f64>{
// TODO!
/*
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xresource.h>
double _glfwPlatformGetMonitorDPI(_GLFWmonitor* monitor)
{
char *resourceString = XResourceManagerString(_glfw.x11.display);
XrmDatabase db;
XrmValue value;
char *type = NULL;
double dpi = 0.0;
XrmInitialize(); /* Need to initialize the DB before calling Xrm* functions */
db = XrmGetStringDatabase(resourceString);
if (resourceString) {
printf("Entire DB:\n%s\n", resourceString);
if (XrmGetResource(db, "Xft.dpi", "String", &type, &value) == True) {
if (value.addr) {
dpi = atof(value.addr);
}
}
}
printf("DPI: %f\n", dpi);
return dpi;
}
*/
None
}

/// Return the DPI on X11 systems
#[cfg(target_os = "linux")]
fn linux_get_hidpi_factor(monitor: &MonitorId, events_loop: &EventsLoop) -> f64 {

use std::env;
use std::process::Command;
use glium::glutin::os::unix::EventsLoopExt;

let winit_dpi = monitor.get_hidpi_factor();
let winit_hidpi_factor = env::var("WINIT_HIDPI_FACTOR").ok().and_then(|hidpi_factor| hidpi_factor.parse::<f64>().ok());
let qt_font_dpi = env::var("QT_FONT_DPI").ok().and_then(|font_dpi| font_dpi.parse::<f64>().ok());

// Execute "gsettings get org.gnome.desktop.interface text-scaling-factor" and parse the output
let gsettings_dpi_factor =
Command::new("gsettings")
.arg("get")
.arg("org.gnome.desktop.interface")
.arg("text-scaling-factor")
.output().ok()
.map(|output| output.stdout)
.and_then(|stdout_bytes| String::from_utf8(stdout_bytes).ok())
.map(|stdout_string| stdout_string.lines().collect::<String>())
.and_then(|gsettings_output| gsettings_output.parse::<f64>().ok());

// Wayland: Ignore Xft.dpi
let xft_dpi = if events_loop.is_x11() { get_xft_dpi() } else { None };

let options = [winit_hidpi_factor, qt_font_dpi, gsettings_dpi_factor, xft_dpi];
options.into_iter().filter_map(|x| *x).next().unwrap_or(winit_dpi)
}

0 comments on commit f732dc7

Please sign in to comment.