oxwm

https://git.tonybtw.com/oxwm.git git://git.tonybtw.com/oxwm.git
3,804 bytes raw
1
use std::ffi::CString;
2
use x11::xft::{XftColor, XftDraw, XftDrawStringUtf8, XftFont, XftFontOpenName};
3
use x11::xlib::{Colormap, Display, Drawable, Visual};
4
use x11::xrender::XRenderColor;
5
6
use crate::errors::X11Error;
7
8
pub struct Font {
9
    xft_font: *mut XftFont,
10
    display: *mut Display,
11
}
12
13
impl Font {
14
    pub fn new(display: *mut Display, screen: i32, font_name: &str) -> Result<Self, X11Error> {
15
        let font_name_cstr =
16
            CString::new(font_name).map_err(|_| X11Error::FontLoadFailed(font_name.to_string()))?;
17
18
        let xft_font = unsafe { XftFontOpenName(display, screen, font_name_cstr.as_ptr()) };
19
20
        if xft_font.is_null() {
21
            return Err(X11Error::FontLoadFailed(font_name.to_string()));
22
        }
23
24
        Ok(Font { xft_font, display })
25
    }
26
27
    pub fn height(&self) -> u16 {
28
        unsafe {
29
            let font = &*self.xft_font;
30
            font.height as u16
31
        }
32
    }
33
34
    pub fn ascent(&self) -> i16 {
35
        unsafe {
36
            let font = &*self.xft_font;
37
            font.ascent as i16
38
        }
39
    }
40
41
    pub fn text_width(&self, text: &str) -> u16 {
42
        unsafe {
43
            let mut extents = std::mem::zeroed();
44
            x11::xft::XftTextExtentsUtf8(
45
                self.display,
46
                self.xft_font,
47
                text.as_ptr(),
48
                text.len() as i32,
49
                &mut extents,
50
            );
51
            extents.width
52
        }
53
    }
54
}
55
56
impl Drop for Font {
57
    fn drop(&mut self) {
58
        unsafe {
59
            if !self.xft_font.is_null() {
60
                x11::xft::XftFontClose(self.display, self.xft_font);
61
            }
62
        }
63
    }
64
}
65
66
pub struct FontDraw {
67
    xft_draw: *mut XftDraw,
68
}
69
70
impl FontDraw {
71
    pub fn new(
72
        display: *mut Display,
73
        drawable: Drawable,
74
        visual: *mut Visual,
75
        colormap: Colormap,
76
    ) -> Result<Self, X11Error> {
77
        let xft_draw = unsafe { x11::xft::XftDrawCreate(display, drawable, visual, colormap) };
78
79
        if xft_draw.is_null() {
80
            return Err(X11Error::DrawCreateFailed);
81
        }
82
83
        Ok(FontDraw { xft_draw })
84
    }
85
86
    pub fn draw_text(&self, font: &Font, color: u32, x: i16, y: i16, text: &str) {
87
        let red = ((color >> 16) & 0xFF) as u16;
88
        let green = ((color >> 8) & 0xFF) as u16;
89
        let blue = (color & 0xFF) as u16;
90
91
        let render_color = XRenderColor {
92
            red: red << 8 | red,
93
            green: green << 8 | green,
94
            blue: blue << 8 | blue,
95
            alpha: 0xFFFF,
96
        };
97
98
        let mut xft_color: XftColor = unsafe { std::mem::zeroed() };
99
100
        unsafe {
101
            x11::xft::XftColorAllocValue(
102
                x11::xft::XftDrawDisplay(self.xft_draw),
103
                x11::xft::XftDrawVisual(self.xft_draw),
104
                x11::xft::XftDrawColormap(self.xft_draw),
105
                &render_color,
106
                &mut xft_color,
107
            );
108
109
            XftDrawStringUtf8(
110
                self.xft_draw,
111
                &xft_color,
112
                font.xft_font,
113
                x as i32,
114
                y as i32,
115
                text.as_ptr(),
116
                text.len() as i32,
117
            );
118
119
            x11::xft::XftColorFree(
120
                x11::xft::XftDrawDisplay(self.xft_draw),
121
                x11::xft::XftDrawVisual(self.xft_draw),
122
                x11::xft::XftDrawColormap(self.xft_draw),
123
                &mut xft_color,
124
            );
125
        }
126
    }
127
128
    pub fn flush(&self) {
129
        unsafe {
130
            let display = x11::xft::XftDrawDisplay(self.xft_draw);
131
            x11::xlib::XFlush(display);
132
        }
133
    }
134
}
135
136
impl Drop for FontDraw {
137
    fn drop(&mut self) {
138
        unsafe {
139
            if !self.xft_draw.is_null() {
140
                x11::xft::XftDrawDestroy(self.xft_draw);
141
            }
142
        }
143
    }
144
}