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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use ffi;
use std::ops;
#[derive(Debug, Copy, Clone)]
pub struct Flags<T: CacheFlag = AllowCache>(pub u32, T);
impl Flags {
pub const NO_CACHE: Flags<DisallowCache> = Flags(ffi::FLAGS_NOCACHE, DisallowCache);
pub const NO_OPTIMIZE: Flags = Flags(ffi::FLAGS_NOOPTIMIZE, AllowCache);
pub const NULL_TRANSFORM: Flags = Flags(ffi::FLAGS_NULLTRANSFORM, AllowCache);
pub const GAMUT_CHECK: Flags = Flags(ffi::FLAGS_GAMUTCHECK, AllowCache);
pub const SOFT_PROOFING: Flags = Flags(ffi::FLAGS_SOFTPROOFING, AllowCache);
pub const BLACKPOINT_COMPENSATION: Flags = Flags(ffi::FLAGS_BLACKPOINTCOMPENSATION, AllowCache);
pub const NO_WHITE_ON_WHITE_FIXUP: Flags = Flags(ffi::FLAGS_NOWHITEONWHITEFIXUP, AllowCache);
pub const HIGHRES_PRECALC: Flags = Flags(ffi::FLAGS_HIGHRESPRECALC, AllowCache);
pub const LOWRES_PRECALC: Flags = Flags(ffi::FLAGS_LOWRESPRECALC, AllowCache);
pub const DEVICELINK_8BITS: Flags = Flags(ffi::FLAGS_8BITS_DEVICELINK, AllowCache);
pub const GUESS_DEVICE_CLASS: Flags = Flags(ffi::FLAGS_GUESSDEVICECLASS, AllowCache);
pub const KEEP_SEQUENCE: Flags = Flags(ffi::FLAGS_KEEP_SEQUENCE, AllowCache);
pub const FORCE_CLUT: Flags = Flags(ffi::FLAGS_FORCE_CLUT, AllowCache);
pub const CLUT_POST_LINEARIZATION: Flags = Flags(ffi::FLAGS_CLUT_POST_LINEARIZATION, AllowCache);
pub const CLUT_PRE_LINEARIZATION: Flags = Flags(ffi::FLAGS_CLUT_PRE_LINEARIZATION, AllowCache);
pub const NO_NEGATIVES: Flags = Flags(ffi::FLAGS_NONEGATIVES, AllowCache);
pub const COPY_ALPHA: Flags = Flags(ffi::FLAGS_COPY_ALPHA, AllowCache);
pub const NO_DEFAULT_RESOURCE_DEF: Flags = Flags(ffi::FLAGS_NODEFAULTRESOURCEDEF, AllowCache);
}
impl<T: CacheFlag> ops::BitOr<Flags<T>> for Flags<DisallowCache> {
type Output = Flags<DisallowCache>;
fn bitor(self, other: Flags<T>) -> Flags<DisallowCache> {
Flags(self.0 | other.0, DisallowCache)
}
}
impl<T: CacheFlag> ops::BitOr<Flags<T>> for Flags<AllowCache> {
type Output = Flags<T>;
fn bitor(self, other: Flags<T>) -> Flags<T> {
Flags(self.0 | other.0, other.1)
}
}
impl<T: CacheFlag> Flags<T> {
pub(crate) fn bits(&self) -> u32 {
self.0
}
pub(crate) fn allow_cache(&self) -> Flags {
Flags(self.0, AllowCache)
}
pub fn has<F: CacheFlag>(&mut self, flag: Flags<F>) -> bool {
0 != (self.0 & flag.0)
}
}
impl Default for Flags {
fn default() -> Self {
Flags(0, AllowCache)
}
}
#[derive(Copy, Clone, Debug)]
pub struct DisallowCache;
#[derive(Copy, Clone, Debug)]
pub struct AllowCache;
pub trait CacheFlag: Sized {}
impl CacheFlag for AllowCache {}
impl CacheFlag for DisallowCache {}
#[test]
fn flags() {
let _ = Flags::default();
let mut t = Flags::COPY_ALPHA | Flags::NO_OPTIMIZE;
t = t | Flags::CLUT_PRE_LINEARIZATION;
assert!(t.has(Flags::CLUT_PRE_LINEARIZATION));
assert!(t.has(Flags::COPY_ALPHA));
assert!(t.has(Flags::NO_OPTIMIZE));
assert!(!t.has(Flags::DEVICELINK_8BITS));
assert!(!t.has(Flags::GAMUT_CHECK));
let _ = Flags::default() | Flags::NO_CACHE;
let _ = Flags::NO_CACHE | Flags::CLUT_PRE_LINEARIZATION;
}