diff --git a/bin/darkwallet/Cargo.toml b/bin/darkwallet/Cargo.toml index fe3c966f1..4c02a6a24 100644 --- a/bin/darkwallet/Cargo.toml +++ b/bin/darkwallet/Cargo.toml @@ -9,7 +9,10 @@ edition = "2021" [dependencies] miniquad = { git = "https://github.com/not-fl3/miniquad" } -#harfbuzz = "0.6.0" +# Currently latest version links to freetype-sys 0.19 but we use 0.21 +#harfbuzz-sys = "0.6" +#harfbuzz-sys = { git = "https://github.com/servo/rust-harfbuzz" } +# Until we get cargo-quad ported, we are stuck with my shitty hack of unmaintained harfbuzz wrapper rather than the servo FFI harfbuzz_rs = { git = "https://github.com/narodnik/hbrs2.git", features = ["freetype"] } freetype-rs = { version = "0.37", features = ["bundled"] } image = "0.25.1" diff --git a/bin/darkwallet/Dockerfile b/bin/darkwallet/Dockerfile index 6228f653c..66fd138af 100644 --- a/bin/darkwallet/Dockerfile +++ b/bin/darkwallet/Dockerfile @@ -1,15 +1,19 @@ FROM archlinux RUN pacman -Syu --noconfirm -RUN pacman -S --noconfirm jdk8-openjdk unzip wget cmake rustup openssl pkgconf gcc git +RUN pacman -S --noconfirm jdk8-openjdk unzip wget cmake openssl pkgconf gcc git # github override HOME, so here we are ENV RUSTUP_HOME=/usr/local/rustup \ CARGO_HOME=/usr/local/cargo \ PATH=/usr/local/cargo/bin:$PATH -RUN rustup toolchain install nightly -RUN rustup default nightly +RUN curl -o rustup.sh --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs +RUN chmod +x rustup.sh +RUN ./rustup.sh -y --default-toolchain nightly + +#RUN rustup toolchain install nightly +#RUN rustup default nightly RUN rustc --version RUN rustup target add armv7-linux-androideabi @@ -42,6 +46,15 @@ ENV NDK_HOME /usr/local/android-ndk-r25 # Copy contents to container. Should only use this on a clean directory WORKDIR /root/ RUN git clone https://github.com/not-fl3/cargo-quad-apk cargo-apk +#RUN git clone https://github.com/narodnik/cargo-quad-apk cargo-apk + +# ArmV7a +#ENV CC ${NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi31-clang +#ENV CXX ${NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi31-clang++ +#ENV AR ${NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar +#ENV CXXSTDLIB c++ +# Arm64V8a +# X86 # Install binary RUN cargo install --path /root/cargo-apk diff --git a/bin/darkwallet/Makefile b/bin/darkwallet/Makefile index 18b038877..b79cce171 100644 --- a/bin/darkwallet/Makefile +++ b/bin/darkwallet/Makefile @@ -2,7 +2,7 @@ default: cargo lrun android: - docker run -v $(shell pwd):/root/dw -w /root/dw -t apk cargo quad-apk build + docker run -v $(shell pwd):/root/dw -v /tmp/cargo-quad-apk:/root/cargo-quad-apk -w /root/dw -t apk cargo quad-apk build adb uninstall darkfi.darkwallet adb install target/android-artifacts/debug/apk/darkwallet.apk reset diff --git a/bin/darkwallet/src/main.rs b/bin/darkwallet/src/main.rs index cc28901cd..1faead5f0 100644 --- a/bin/darkwallet/src/main.rs +++ b/bin/darkwallet/src/main.rs @@ -67,28 +67,6 @@ fn main() { simplelog::CombinedLogger::init(vec![term_logger]).expect("logger"); } - { - use freetype as ft; - - let ftlib = ft::Library::init().unwrap(); - let font_data = include_bytes!("../NotoColorEmoji.ttf") as &[u8]; - let face = ftlib.new_memory_face2(font_data, 0).unwrap(); - assert!(face.has_fixed_sizes()); - face.select_size(0).unwrap(); - - let mut flags = ft::face::LoadFlag::DEFAULT; - if face.has_color() { - flags |= ft::face::LoadFlag::COLOR; - } - - let glyph_id = 657; - // FIXME: glyph 884 hangs on android - // For now just avoid using emojis on android - debug!("load_glyph {}", glyph_id); - face.load_glyph(glyph_id, flags).unwrap(); - debug!("load_glyph {} [done]", glyph_id); - } - let ex = Arc::new(smol::Executor::new()); let sg = Arc::new(Mutex::new(SceneGraph::new())); diff --git a/bin/darkwallet/src/text2.rs b/bin/darkwallet/src/text2.rs index 7bd95d75d..1665af103 100644 --- a/bin/darkwallet/src/text2.rs +++ b/bin/darkwallet/src/text2.rs @@ -1,8 +1,18 @@ use async_lock::Mutex; use freetype as ft; +/* +use harfbuzz_sys::{ + freetype::hb_ft_font_create_referenced, hb_buffer_add_utf8, hb_buffer_create, + hb_buffer_destroy, hb_buffer_get_glyph_infos, hb_buffer_get_glyph_positions, + hb_buffer_guess_segment_properties, hb_buffer_set_cluster_level, hb_buffer_set_content_type, + hb_feature_t, hb_font_destroy, hb_glyph_info_t, hb_glyph_position_t, hb_shape, + HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS, HB_BUFFER_CONTENT_TYPE_UNICODE, +}; +*/ use miniquad::TextureId; use std::{ collections::HashMap, + os, sync::{Arc, Weak}, }; @@ -264,7 +274,7 @@ impl TextShaper { pub async fn shape(&self, text: String, font_size: f32) -> Vec { // Lock font faces // Freetype faces are not threadsafe - let faces = self.font_faces.lock().await; + let mut faces = self.font_faces.lock().await; let mut cache = self.cache.lock().await; let substrs = Self::split_into_substrs(&faces.0, text.clone()); @@ -294,10 +304,43 @@ impl TextShaper { let positions = output.get_glyph_positions(); let infos = output.get_glyph_infos(); + /* + let utf8_ptr = text.as_ptr() as *const _; + // https://harfbuzz.github.io/a-simple-shaping-example.html + let (hb_font, buf, glyph_infos, glyph_pos, glyph_infos_iter, glyph_pos_iter) = unsafe { + let ft_face_ptr: freetype::freetype_sys::FT_Face = face.raw_mut(); + let hb_font = hb_ft_font_create_referenced(ft_face_ptr); + let buf = hb_buffer_create(); + hb_buffer_set_content_type(buf, HB_BUFFER_CONTENT_TYPE_UNICODE); + hb_buffer_set_cluster_level(buf, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); + hb_buffer_add_utf8( + buf, + utf8_ptr, + text.len() as os::raw::c_int, + 0 as os::raw::c_uint, + text.len() as os::raw::c_int, + ); + hb_buffer_guess_segment_properties(buf); + hb_shape(hb_font, buf, std::ptr::null(), 0 as os::raw::c_uint); + + let mut length: u32 = 0; + let glyph_infos = hb_buffer_get_glyph_infos(buf, &mut length as *mut u32); + let glyph_infos_iter: &[hb_glyph_info_t] = + std::slice::from_raw_parts(glyph_infos as *const _, length as usize); + + let glyph_pos = hb_buffer_get_glyph_positions(buf, &mut length as *mut u32); + let glyph_pos_iter: &[hb_glyph_position_t] = + std::slice::from_raw_parts(glyph_pos as *const _, length as usize); + + (hb_font, buf, glyph_infos, glyph_pos, glyph_infos_iter, glyph_pos_iter) + }; + */ + let mut prev_cluster = 0; for (i, (position, info)) in positions.iter().zip(infos).enumerate() { - let glyph_id = info.codepoint; + //for (i, (position, info)) in glyph_pos_iter.iter().zip(glyph_infos_iter.iter()).enumerate() { + let glyph_id = info.codepoint as u32; // Index within this substr let curr_cluster = info.cluster as usize; @@ -352,11 +395,12 @@ impl TextShaper { flags |= ft::face::LoadFlag::COLOR; } - // FIXME: glyph 884 hangs on android - // For now just avoid using emojis on android - //debug!("load_glyph {}", gid); - face.load_glyph(glyph_id, flags).unwrap(); - //debug!("load_glyph {} [done]", gid); + //debug!("load_glyph {}", glyph_id); + if let Err(err) = face.load_glyph(glyph_id, flags) { + error!(target: "text", "error loading glyph: {}", glyph_id); + continue + } + //debug!("load_glyph {} [done]", glyph_id); // https://gist.github.com/jokertarot/7583938?permalink_comment_id=3327566#gistcomment-3327566 @@ -427,6 +471,13 @@ impl TextShaper { let substr = text[prev_cluster..].to_string(); glyphs.last_mut().unwrap().substr = substr; + + /* + unsafe { + hb_buffer_destroy(buf); + hb_font_destroy(hb_font); + } + */ } glyphs