Skip to content

Commit

Permalink
Add support for Libra Colour and Clara Colour
Browse files Browse the repository at this point in the history
Fixes #364.
  • Loading branch information
baskerville committed Nov 25, 2024
1 parent 8aa30f1 commit 6506454
Show file tree
Hide file tree
Showing 36 changed files with 440 additions and 347 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ Any 4.*X*.*Y* firmware, with *X* ≥ 6, will do.

## Supported devices

- *Clara BW*
- *Libra Colour*.
- *Clara Colour*.
- *Clara BW*.
- *Elipsa 2E*.
- *Clara 2E*.
- *Libra 2*.
Expand Down
2 changes: 1 addition & 1 deletion contrib/Settings-sample.toml
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ notify-success = true
size = 2
# The current pen color.
# Possible values: 0 … 255.
color = 0
color = { gray = 0 }
# Vary the diameter according to the pen's velocity.
dynamic = true
# The amplitude of the diameter variation when `dynamic` is set.
Expand Down
12 changes: 7 additions & 5 deletions contrib/plato.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ if [ -e "$KOBO_TAG" ] ; then
# This is a combination of the information given in `FBInk/fbink_device_id.c`
# and `calibre/src/calibre/devices/kobo/driver.py`.
case "$MODEL_NUMBER" in
310|320) PRODUCT_ID=0x4163 ;; # Touch A/B, Touch C
3[12]0) PRODUCT_ID=0x4163 ;; # Touch A/B, Touch C
330) PRODUCT_ID=0x4173 ;; # Glo
340) PRODUCT_ID=0x4183 ;; # Mini
350) PRODUCT_ID=0x4193 ;; # Aura HD
Expand All @@ -77,7 +77,9 @@ if [ -e "$KOBO_TAG" ] ; then
388) PRODUCT_ID=0x4234 ;; # Libra 2
386) PRODUCT_ID=0x4235 ;; # Clara 2E
389) PRODUCT_ID=0x4236 ;; # Elipsa 2E
391) PRODUCT_ID=0x4237 ;; # Clara BW
390) PRODUCT_ID=0x4237 ;; # Libra Colour
393) PRODUCT_ID=0x4238 ;; # Clara Colour
391) PRODUCT_ID=0x4239 ;; # Clara BW
*) PRODUCT_ID=0x6666 ;;
esac

Expand All @@ -92,11 +94,11 @@ export LD_LIBRARY_PATH="libs:${LD_LIBRARY_PATH}"

if [ "$PLATO_SET_FRAMEBUFFER_DEPTH" ] ; then
case "${PRODUCT}:${MODEL_NUMBER}" in
spaBW:*|condor:*|goldfinch:*|io:*|cadmus:*|europa:*|storm:*|frost:*|nova:*|snow:378|star:379)
unset ORIG_BPP
kraken:*|pixie:*|dragon:*|phoenix:*|dahlia:*|alyssum:*|pika:*|daylight:*|star:375|snow:374)
ORIG_BPP=$(./bin/utils/fbdepth -g)
;;
*)
ORIG_BPP=$(./bin/utils/fbdepth -g)
unset ORIG_BPP
;;
esac
fi
Expand Down
154 changes: 117 additions & 37 deletions crates/core/src/color.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,119 @@
#![allow(unused)]

pub const GRAY00: u8 = 0x00;
pub const GRAY01: u8 = 0x11;
pub const GRAY02: u8 = 0x22;
pub const GRAY03: u8 = 0x33;
pub const GRAY04: u8 = 0x44;
pub const GRAY05: u8 = 0x55;
pub const GRAY06: u8 = 0x66;
pub const GRAY07: u8 = 0x77;
pub const GRAY08: u8 = 0x88;
pub const GRAY09: u8 = 0x99;
pub const GRAY10: u8 = 0xAA;
pub const GRAY11: u8 = 0xBB;
pub const GRAY12: u8 = 0xCC;
pub const GRAY13: u8 = 0xDD;
pub const GRAY14: u8 = 0xEE;
pub const GRAY15: u8 = 0xFF;

pub const BLACK: u8 = GRAY00;
pub const WHITE: u8 = GRAY15;

pub const TEXT_NORMAL: [u8; 3] = [WHITE, BLACK, GRAY08];
pub const TEXT_BUMP_SMALL: [u8; 3] = [GRAY14, BLACK, GRAY07];
pub const TEXT_BUMP_LARGE: [u8; 3] = [GRAY11, BLACK, BLACK];

pub const TEXT_INVERTED_SOFT: [u8; 3] = [GRAY05, WHITE, WHITE];
pub const TEXT_INVERTED_HARD: [u8; 3] = [BLACK, WHITE, GRAY06];

pub const SEPARATOR_NORMAL: u8 = GRAY10;
pub const SEPARATOR_STRONG: u8 = GRAY07;

pub const KEYBOARD_BG: u8 = GRAY12;
pub const BATTERY_FILL: u8 = GRAY12;
pub const READING_PROGRESS: u8 = GRAY07;

pub const PROGRESS_FULL: u8 = GRAY05;
pub const PROGRESS_EMPTY: u8 = GRAY13;
pub const PROGRESS_VALUE: u8 = GRAY06;
use serde::{Serialize, Deserialize};
use crate::geom::lerp;

#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum Color {
Gray(u8),
Rgb(u8, u8, u8),
}

impl Color {
pub fn gray(&self) -> u8 {
match *self {
Color::Gray(level) => level,
Color::Rgb(red, green, blue) => {
(red as f32 * 0.2126 + green as f32 * 0.7152 + blue as f32 * 0.0722) as u8
},
}
}

pub fn rgb(&self) -> [u8; 3] {
match *self {
Color::Gray(level) => [level; 3],
Color::Rgb(red, green, blue) => [red, green, blue],
}
}

pub fn from_rgb(rgb: &[u8]) -> Color {
Color::Rgb(rgb[0], rgb[1], rgb[2])
}

pub fn apply<F>(&self, f: F) -> Color where F: Fn(u8) -> u8 {
match *self {
Color::Gray(level) => Color::Gray(f(level)),
Color::Rgb(red, green, blue) => Color::Rgb(f(red), f(green), f(blue)),
}
}

pub fn lerp(&self, color: Color, alpha: f32) -> Color {
match (*self, color) {
(Color::Gray(l1), Color::Gray(l2)) => Color::Gray(lerp(l1 as f32, l2 as f32, alpha) as u8),
(Color::Rgb(red, green, blue), Color::Gray(level)) => Color::Rgb(lerp(red as f32, level as f32, alpha) as u8,
lerp(green as f32, level as f32, alpha) as u8,
lerp(blue as f32, level as f32, alpha) as u8),
(Color::Gray(level), Color::Rgb(red, green, blue)) => Color::Rgb(lerp(level as f32, red as f32, alpha) as u8,
lerp(level as f32, green as f32, alpha) as u8,
lerp(level as f32, blue as f32, alpha) as u8),
(Color::Rgb(r1, g1, b1), Color::Rgb(r2, g2, b2)) => Color::Rgb(lerp(r1 as f32, r2 as f32, alpha) as u8,
lerp(g1 as f32, g2 as f32, alpha) as u8,
lerp(b1 as f32, b2 as f32, alpha) as u8),
}
}

pub fn invert(&mut self) {
match self {
Color::Gray(level) => *level = 255 - *level,
Color::Rgb(red, green, blue) => {
*red = 255 - *red;
*green = 255 - *green;
*blue = 255 - *blue;
},
}
}

pub fn shift(&mut self, drift: u8) {
match self {
Color::Gray(level) => *level = level.saturating_sub(drift),
Color::Rgb(red, green, blue) => {
*red = red.saturating_sub(drift);
*green = green.saturating_sub(drift);
*blue = blue.saturating_sub(drift);
},
}
}
}

macro_rules! gray {
($a:expr) => ($crate::color::Color::Gray($a));
}

pub const GRAY00: Color = gray!(0x00);
pub const GRAY01: Color = gray!(0x11);
pub const GRAY02: Color = gray!(0x22);
pub const GRAY03: Color = gray!(0x33);
pub const GRAY04: Color = gray!(0x44);
pub const GRAY05: Color = gray!(0x55);
pub const GRAY06: Color = gray!(0x66);
pub const GRAY07: Color = gray!(0x77);
pub const GRAY08: Color = gray!(0x88);
pub const GRAY09: Color = gray!(0x99);
pub const GRAY10: Color = gray!(0xAA);
pub const GRAY11: Color = gray!(0xBB);
pub const GRAY12: Color = gray!(0xCC);
pub const GRAY13: Color = gray!(0xDD);
pub const GRAY14: Color = gray!(0xEE);
pub const GRAY15: Color = gray!(0xFF);

pub const BLACK: Color = GRAY00;
pub const WHITE: Color = GRAY15;

pub const TEXT_NORMAL: [Color; 3] = [WHITE, BLACK, GRAY08];
pub const TEXT_BUMP_SMALL: [Color; 3] = [GRAY14, BLACK, GRAY07];
pub const TEXT_BUMP_LARGE: [Color; 3] = [GRAY11, BLACK, BLACK];

pub const TEXT_INVERTED_SOFT: [Color; 3] = [GRAY05, WHITE, WHITE];
pub const TEXT_INVERTED_HARD: [Color; 3] = [BLACK, WHITE, GRAY06];

pub const SEPARATOR_NORMAL: Color = GRAY10;
pub const SEPARATOR_STRONG: Color = GRAY07;

pub const KEYBOARD_BG: Color = GRAY12;
pub const BATTERY_FILL: Color = GRAY12;
pub const READING_PROGRESS: Color = GRAY07;

pub const PROGRESS_FULL: Color = GRAY05;
pub const PROGRESS_EMPTY: Color = GRAY13;
pub const PROGRESS_VALUE: Color = GRAY06;
51 changes: 40 additions & 11 deletions crates/core/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use crate::input::TouchProto;

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Model {
LibraColour,
ClaraColour,
ClaraBW,
Elipsa2E,
Clara2E,
Expand Down Expand Up @@ -42,6 +44,8 @@ pub enum Orientation {
impl fmt::Display for Model {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Model::LibraColour => write!(f, "Libra Colour"),
Model::ClaraColour => write!(f, "Clara Colour"),
Model::ClaraBW => write!(f, "Clara BW"),
Model::Elipsa2E => write!(f, "Elipsa 2E"),
Model::Clara2E => write!(f, "Clara 2E"),
Expand Down Expand Up @@ -210,6 +214,18 @@ impl Device {
dims: (1072, 1448),
dpi: 300,
},
"spaColour" => Device {
model: Model::ClaraColour,
proto: TouchProto::MultiB,
dims: (1072, 1448),
dpi: 300,
},
"monza" => Device {
model: Model::LibraColour,
proto: TouchProto::MultiB,
dims: (1264, 1680),
dpi: 300,
},
_ => Device {
model: if model_number == "320" { Model::TouchC } else { Model::TouchAB },
proto: TouchProto::Single,
Expand All @@ -219,12 +235,15 @@ impl Device {
}
}

pub fn color_samples(&self) -> usize {
match self.model {
Model::ClaraColour | Model::LibraColour => 3,
_ => 1,
}
}

pub fn frontlight_kind(&self) -> FrontlightKind {
match self.model {
Model::AuraONE |
Model::AuraONELimEd |
Model::AuraH2OEd2V1 |
Model::AuraH2OEd2V2 => FrontlightKind::Natural,
Model::ClaraHD |
Model::Forma |
Model::Forma32GB |
Expand All @@ -233,7 +252,13 @@ impl Device {
Model::Libra2 |
Model::Clara2E |
Model::Elipsa2E |
Model::ClaraBW => FrontlightKind::Premixed,
Model::ClaraBW |
Model::ClaraColour |
Model::LibraColour => FrontlightKind::Premixed,
Model::AuraONE |
Model::AuraONELimEd |
Model::AuraH2OEd2V1 |
Model::AuraH2OEd2V2 => FrontlightKind::Natural,
_ => FrontlightKind::Standard,
}
}
Expand All @@ -249,14 +274,14 @@ impl Device {

pub fn has_gyroscope(&self) -> bool {
matches!(self.model,
Model::Forma | Model::Forma32GB | Model::LibraH2O |
Model::Elipsa | Model::Sage | Model::Libra2 | Model::Elipsa2E)
Model::Forma | Model::Forma32GB | Model::LibraH2O | Model::Elipsa |
Model::Sage | Model::Libra2 | Model::Elipsa2E | Model::LibraColour)
}

pub fn has_page_turn_buttons(&self) -> bool {
matches!(self.model,
Model::Forma | Model::Forma32GB | Model::LibraH2O |
Model::Sage | Model::Libra2)
Model::Sage | Model::Libra2 | Model::LibraColour)
}

pub fn has_power_cover(&self) -> bool {
Expand Down Expand Up @@ -286,7 +311,9 @@ impl Device {

pub fn mark(&self) -> u8 {
match self.model {
Model::ClaraBW => 12,
Model::LibraColour => 13,
Model::ClaraBW |
Model::ClaraColour => 12,
Model::Elipsa2E => 11,
Model::Clara2E => 10,
Model::Libra2 => 9,
Expand Down Expand Up @@ -355,7 +382,8 @@ impl Device {
Model::LibraH2O => 0,
Model::AuraH2OEd2V1 |
Model::Forma | Model::Forma32GB |
Model::Sage | Model::Libra2 | Model::Elipsa2E => 1,
Model::Sage | Model::Libra2 | Model::Elipsa2E |
Model::LibraColour => 1,
_ => 3,
}
}
Expand Down Expand Up @@ -390,7 +418,8 @@ impl Device {
Model::LibraH2O => n ^ 1,
Model::Libra2 |
Model::Sage |
Model::Elipsa2E => (6 - n) % 4,
Model::Elipsa2E |
Model::LibraColour => (6 - n) % 4,
Model::Elipsa => (4 - n) % 4,
_ => n,
}
Expand Down
19 changes: 13 additions & 6 deletions crates/core/src/document/djvu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ impl Document for DjvuDocument {
unsafe { ddjvu_document_get_pagenum(self.doc) as usize }
}

fn pixmap(&mut self, loc: Location, scale: f32) -> Option<(Pixmap, usize)> {
fn pixmap(&mut self, loc: Location, scale: f32, samples: usize) -> Option<(Pixmap, usize)> {
let index = self.resolve_location(loc)? as usize;
self.page(index).and_then(|page| page.pixmap(scale)).map(|pixmap| (pixmap, index))
self.page(index).and_then(|page| page.pixmap(scale, samples)).map(|pixmap| (pixmap, index))
}

fn toc(&mut self) -> Option<Vec<TocEntry>> {
Expand Down Expand Up @@ -388,7 +388,7 @@ impl DjvuDocument {
}

impl<'a> DjvuPage<'a> {
pub fn pixmap(&self, scale: f32) -> Option<Pixmap> {
pub fn pixmap(&self, scale: f32, samples: usize) -> Option<Pixmap> {
unsafe {
let (width, height) = self.dims();
let rect = DjvuRect {
Expand All @@ -398,7 +398,12 @@ impl<'a> DjvuPage<'a> {
h: (scale * height as f32) as libc::c_uint,
};

let fmt = ddjvu_format_create(DDJVU_FORMAT_GREY8, 0, ptr::null());
let style = if samples == 1 {
DDJVU_FORMAT_GREY8
} else {
DDJVU_FORMAT_RGB24
};
let fmt = ddjvu_format_create(style, 0, ptr::null());

if fmt.is_null() {
return None;
Expand All @@ -407,17 +412,18 @@ impl<'a> DjvuPage<'a> {
ddjvu_format_set_row_order(fmt, 1);
ddjvu_format_set_y_direction(fmt, 1);

let len = (rect.w * rect.h) as usize;
let len = samples * (rect.w * rect.h) as usize;
let mut data = Vec::new();
if data.try_reserve_exact(len).is_err() {
ddjvu_format_release(fmt);
return None;
}
data.resize(len, 0xff);

let row_size = (samples * rect.w as usize) as libc::c_ulong;
ddjvu_page_render(self.page, DDJVU_RENDER_COLOR,
&rect, &rect, fmt,
rect.w as libc::c_ulong, data.as_mut_ptr());
row_size, data.as_mut_ptr());

let job = ddjvu_page_job(self.page);

Expand All @@ -433,6 +439,7 @@ impl<'a> DjvuPage<'a> {

Some(Pixmap { width: rect.w as u32,
height: rect.h as u32,
samples,
data })
}
}
Expand Down
Loading

0 comments on commit 6506454

Please sign in to comment.