summaryrefslogtreecommitdiff
path: root/librsvg-c/src/c_api/dpi.rs
blob: b2e15eef78a0304f15a3314957e692a4eb82ce34 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//! Legacy C API for setting a default DPI (dots per inch = DPI).
//!
//! There are two deprecated functions, `rsvg_set_default_dpi` and
//! `rsvg_set_default_dpi_x_y`, which set global values for the default DPI to be used
//! with `RsvgHandle`.  In turn, `RsvgHandle` assumes that when its own DPI value is set
//! to `0.0` (which is in fact its default), it will fall back to the global DPI.
//!
//! This is clearly not thread-safe, but it is the legacy behavior.
//!
//! This module encapsulates that behavior so that the `rsvg_internals` crate
//! can always have immutable DPI values as intended.

// This is configurable at runtime
const DEFAULT_DPI_X: f64 = 90.0;
const DEFAULT_DPI_Y: f64 = 90.0;

static mut DPI_X: f64 = DEFAULT_DPI_X;
static mut DPI_Y: f64 = DEFAULT_DPI_Y;

#[derive(Debug, Copy, Clone, Default)]
pub(crate) struct Dpi {
    x: f64,
    y: f64,
}

impl Dpi {
    pub(crate) fn new(x: f64, y: f64) -> Dpi {
        Dpi { x, y }
    }

    pub(crate) fn x(&self) -> f64 {
        if self.x <= 0.0 {
            unsafe { DPI_X }
        } else {
            self.x
        }
    }

    pub(crate) fn y(&self) -> f64 {
        if self.y <= 0.0 {
            unsafe { DPI_Y }
        } else {
            self.y
        }
    }
}

#[no_mangle]
pub unsafe extern "C" fn rsvg_set_default_dpi_x_y(dpi_x: libc::c_double, dpi_y: libc::c_double) {
    if dpi_x <= 0.0 {
        DPI_X = DEFAULT_DPI_X;
    } else {
        DPI_X = dpi_x;
    }

    if dpi_y <= 0.0 {
        DPI_Y = DEFAULT_DPI_Y;
    } else {
        DPI_Y = dpi_y;
    }
}

#[no_mangle]
pub unsafe extern "C" fn rsvg_set_default_dpi(dpi: libc::c_double) {
    rsvg_set_default_dpi_x_y(dpi, dpi);
}