refactor(pdf): rename crate to pdf_viewer and enforce repo conventions

This commit is contained in:
Kushagra Kumar committed 2026-09-02 21:31:12 +05:30
1 parent 93ed1b74c1
commit 23e07e06f4
21 files changed
+114 -214

No files matched your search

Generated
+16 -16
View File
@@ -8760,10 +8760,10 @@ dependencies = [
"fs",
"gpui",
"image",
"kkpdf-zed",
"language",
"log",
"menu",
"pdf_viewer",
"project",
"settings",
"theme",
@@ -9446,20 +9446,6 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]]
name = "kkpdf-zed"
version = "0.1.0"
dependencies = [
"anyhow",
"image",
"log",
"parking_lot",
"pdfium-render",
"serde",
"serde_json",
"tempfile",
]
[[package]]
name = "kqueue"
version = "1.2.0"
@@ -12740,6 +12726,20 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0008e816fcdaf229cdd540e9b6ca2dc4a10d65c31624abb546c6420a02846e61"
[[package]]
name = "pdf_viewer"
version = "0.1.0"
dependencies = [
"anyhow",
"image",
"log",
"parking_lot",
"pdfium-render",
"serde",
"serde_json",
"tempfile",
]
[[package]]
name = "pdfium-render"
version = "0.8.37"
@@ -13959,7 +13959,6 @@ dependencies = [
"image",
"indexmap 2.14.0",
"itertools 0.14.0",
"kkpdf-zed",
"language",
"log",
"lsp",
@@ -13968,6 +13967,7 @@ dependencies = [
"parking_lot",
"path",
"paths",
"pdf_viewer",
"percent-encoding",
"postage",
"prettier",
+2 -2
View File
@@ -114,7 +114,6 @@ members = [
"crates/journal",
"crates/json_schema_store",
"crates/keymap_editor",
"crates/kkpdf_zed",
"crates/language",
"crates/language_core",
"crates/language_detection",
@@ -159,6 +158,7 @@ members = [
"crates/panel",
"crates/path",
"crates/paths",
"crates/pdf_viewer",
"crates/picker",
"crates/picker_preview",
"crates/platform_title_bar",
@@ -377,7 +377,6 @@ http_client_tls = { path = "crates/http_client_tls" }
http_proxy = { path = "crates/http_proxy" }
icons = { path = "crates/icons" }
image_viewer = { path = "crates/image_viewer" }
kkpdf-zed = { path = "crates/kkpdf_zed" }
input_latency_ui = { path = "crates/input_latency_ui" }
inspector_ui = { path = "crates/inspector_ui" }
install_cli = { path = "crates/install_cli" }
@@ -428,6 +427,7 @@ outline_panel = { path = "crates/outline_panel" }
panel = { path = "crates/panel" }
path = { path = "crates/path" }
paths = { path = "crates/paths" }
pdf_viewer = { path = "crates/pdf_viewer" }
perf = { path = "tooling/perf" }
picker = { path = "crates/picker" }
picker_preview = { path = "crates/picker_preview" }
+3
View File
@@ -1,3 +1,6 @@
> [!IMPORTANT]
> Remove this line to confirm you've reviewed this PR before submitting.
# Zed
[![Zed](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/zed-industries/zed/main/assets/badge/v0.json)](https://zed.dev)
+1 -1
View File
@@ -22,10 +22,10 @@ editor.workspace = true
file_icons.workspace = true
gpui.workspace = true
image.workspace = true
kkpdf-zed.workspace = true
language.workspace = true
log.workspace = true
menu.workspace = true
pdf_viewer.workspace = true
project.workspace = true
settings.workspace = true
theme_settings.workspace = true
+5 -5
View File
@@ -23,7 +23,7 @@ use project::{
ImageItem, Project, ProjectPath, git_store::GitStoreEvent,
image_store::{ImageItemEvent, PdfPageEntry, PdfPageInfo},
};
use kkpdf_zed::{
use pdf_viewer::{
cache::{CacheKey, CacheablePage, PageLruCache, DEFAULT_MEMORY_BUDGET_BYTES},
rasterizer::RasterizerOptions,
PdfiumEngine,
@@ -492,7 +492,7 @@ impl ImageView {
}
fn find_segment_at(
segments: &[kkpdf_zed::PdfTextSegment],
segments: &[pdf_viewer::PdfTextSegment],
norm_x: f32,
norm_y: f32,
) -> Option<usize> {
@@ -1774,7 +1774,7 @@ impl Render for ImageView {
.custom_scrollbars(
Scrollbars::new(ScrollAxes::Vertical)
.id("pdf-scrollbar")
.style(ScrollbarStyle::Thick)
.style(ScrollbarStyle::Editor)
.tracked_scroll_handle(&self.pdf_scroll_handle)
.notify_content(),
window,
@@ -2508,7 +2508,7 @@ mod tests {
#[test]
fn test_pdf_collect_selection_text_multi_page() {
use kkpdf_zed::PdfTextSegment;
use pdf_viewer::PdfTextSegment;
let dummy_img = Arc::new(gpui::RenderImage::new(Vec::new()));
@@ -2615,7 +2615,7 @@ mod tests {
#[test]
fn test_find_segment_at_whitespace_rejection() {
let segments = vec![
kkpdf_zed::PdfTextSegment {
pdf_viewer::PdfTextSegment {
text: "Hello".to_string(),
x: 0.2,
y: 0.2,
-5
View File
@@ -1,5 +0,0 @@
//! User interface components for PDF viewing.
pub mod toolbar;
pub use toolbar::{PdfToolbarAction, PdfToolbarState};
@@ -1,5 +1,5 @@
[package]
name = "kkpdf-zed"
name = "pdf_viewer"
version = "0.1.0"
edition.workspace = true
publish.workspace = true
@@ -8,6 +8,10 @@ license = "GPL-3.0-or-later"
[lints]
workspace = true
[lib]
path = "src/pdf_viewer.rs"
doctest = false
[dependencies]
anyhow.workspace = true
image.workspace = true
@@ -1,15 +1,13 @@
# `kkpdf-zed`: Native PDF Viewer for Zed Editor
# `pdf_viewer`: Native PDF Viewer for Zed
A native, high-performance PDF viewing engine and GPUI workspace item engineered for the [Zed Editor](https://zed.dev).
A native, high performance PDF viewing engine and GPUI workspace item engineered for Zed.
---
## 0. Architectural Identity & Delivery Model
> **Important**: This is a **native workspace crate**, not an installable WASM extension.
> As of current Zed versions, Zed's WebAssembly extension API (`zed_extension_api`) contains no custom UI or file preview surfaces. `kkpdf-zed` is designed as a native crate to be registered within the Zed workspace (`crates/kkpdf_viewer` or integrated upstream into `zed-industries/zed`).
`extension.toml` in this repository is a **documentation stub** preserving metadata identity for a potential future extension surface or upstream contribution.
> As of current Zed versions, Zed's WebAssembly extension API (`zed_extension_api`) contains no custom UI or file preview surfaces. `pdf_viewer` is designed as a native crate registered within the Zed workspace (`crates/pdf_viewer`).
---
@@ -17,26 +15,26 @@ A native, high-performance PDF viewing engine and GPUI workspace item engineered
```
┌──────────────────────────────────────────────────────────────────────────────────┐
│ KKPDF-ZED CORE PIPELINE │
│ PDF_VIEWER CORE PIPELINE │
└──────────────────────────────────────────────────────────────────────────────────┘
│
[PDF Document on Disk / Memory Buffer]
│
▼
[Thread-Safe Document Handle (`document.rs`)]
[Thread Safe Document Handle (`document.rs`)]
│
▼
[Async Background Worker Pool (`gpui::Task` / Threads)]
│
(Zero UI-Thread Blocking Rasterization)
(Zero UI Thread Blocking Rasterization)
│
▼
[Memory-Budgeted LRU Cache (`cache.rs`)]
[Memory Budgeted LRU Cache (`cache.rs`)]
│
(Visible Viewport + 1-Page Margin)
(Visible Viewport + 1 Page Margin)
│
▼
[Luminosity Tone-Mapping Engine (`ui/page.rs`)]
[Luminosity Tone Mapping Engine (`ui.rs`)]
│
(Inverts White/Black; Preserves Images)
│
@@ -44,28 +42,26 @@ A native, high-performance PDF viewing engine and GPUI workspace item engineered
[Native GPUI Canvas / Bitmap Painter (`view.rs`)]
```
1. **Zero UI-Thread Blocking (120 FPS Target)**: PDF parsing and rasterization never execute on GPUI's main render loop. Work is dispatched to background tasks that stream RGBA framebuffers into memory.
2. **Viewport Virtualization & LRU Caching**: Pages are rasterized on-demand for the visible viewport plus a 1-page prefetch margin. Stale or passed-by in-flight render requests are cancelled during fast scrolls to prevent thread pool starvation.
3. **Luminosity-Threshold Dark Mode**: Unlike simple blanket RGB inversion (which turns photos and charts into negative ghosts), `kkpdf-zed` implements selective tone mapping—remapping near-white canvas backgrounds to editor background tones and near-black text to theme light text, while preserving saturated color images.
1. **Zero UI Thread Blocking**: PDF parsing and rasterization never execute on GPUI's main render loop. Work is dispatched to background tasks that stream RGBA framebuffers into memory.
2. **Viewport Virtualization & LRU Caching**: Pages are rasterized on demand for the visible viewport plus a 1 page prefetch margin. Stale or passed by in flight render requests are cancelled during fast scrolls to prevent thread pool starvation.
3. **Luminosity Threshold Dark Mode**: Unlike simple blanket RGB inversion (which turns photos and charts into negative ghosts), `pdf_viewer` implements selective tone mapping, remapping near white canvas backgrounds to editor background tones and near black text to theme light text, while preserving saturated color images.
4. **Scroll & Zoom Preserving Live Reload**: Watches the underlying PDF on disk (via file system notifications) and reloads seamlessly without resetting the user's scroll percentage or zoom level.
---
## 2. Scope Boundaries (v1)
## 2. Scope Boundaries
- **Bitmap-Rendered Continuous Scroll**: Version 1 is engineered strictly as a high-fidelity, high-frame-rate read-only document viewer.
- **Excluded from v1**:
- Text selection and copying.
- In-document text search (`Ctrl+F`).
- **Continuous Scroll & Text Selection**: Supports fluid high frame rate document browsing and visual text selection.
- **Excluded from initial scope**:
- Interactive PDF form field editing.
- *Rationale*: Delivering an ultra-fast, stutter-free viewing experience with zero UI locks takes precedence. Text extraction and selection layer synchronization will be introduced in subsequent milestones.
- *Rationale*: Delivering an ultra fast, stutter free viewing experience with zero UI locks takes precedence.
---
## 3. Security Posture & Threat Model
- **In-Process Parsing**: PDF rasterization is performed via Google's native C++ [Pdfium](https://pdfium.googlesource.com/pdfium/) engine linked in-process with the editor.
- **Accepted Risk in v1**: Because Pdfium runs in-process without sandboxing (e.g., without separate process IPC or WebAssembly memory isolation), malformed or malicious PDFs could theoretically trigger memory vulnerabilities in the underlying C++ library.
- **In Process Parsing**: PDF rasterization is performed via Google's native C++ [Pdfium](https://pdfium.googlesource.com/pdfium/) engine linked in process with the editor.
- **Accepted Risk**: Because Pdfium runs in process without sandboxing (for example, without separate process IPC or WebAssembly memory isolation), malformed or malicious PDFs could theoretically trigger memory vulnerabilities in the underlying C++ library.
- **Mitigation & Future Hardening**: Memory budgets are strictly capped, document handles are isolated behind thread boundaries, and a future sandboxed worker process model is planned for untrusted file browsing.
---
@@ -73,20 +69,21 @@ A native, high-performance PDF viewing engine and GPUI workspace item engineered
## 4. Repository Layout
```
kkpdf-zed/
crates/pdf_viewer/
├── Cargo.toml # Native crate manifest
├── extension.toml # Documentation stub
├── README.md # Architecture & operational guide
├── tests/
│ └── integration_tests.rs # End to end integration tests
└── src/
├── lib.rs # Crate entrypoint & exports
├── document.rs # Thread-safe PdfDocument handle
├── pdf_viewer.rs # Crate entrypoint & exports
├── cache.rs # Memory budgeted generic PageLruCache
├── document.rs # Thread safe PdfDocument handle
├── pdfium.rs # Pdfium engine binding & coordinate normalization
├── rasterizer.rs # Async background rendering pipeline
├── cache.rs # Memory-budgeted LRU cache with eviction
├── watcher.rs # Live-reload file watcher & scroll state
├── settings.rs # PDF viewer configuration options
├── ui.rs # Toolbar state & action models
├── view.rs # GPUI Render & Workspace Item implementation
└── ui/
├── page.rs # Bitmap painting & luminosity recolor
└── toolbar.rs # Zoom, fit-width & page jump controls
└── watcher.rs # Live reload file watcher & scroll state
```
---
@@ -95,6 +92,4 @@ kkpdf-zed/
Run unit and integration tests across the caching and rasterization engines:
```bash
cargo test
```
cargo test -p pdf_viewer
File renamed without changes.
File renamed without changes.
@@ -1,12 +1,12 @@
//! # `kkpdf-zed`
//! # `pdf_viewer`
//!
//! High-performance native PDF viewing engine and GPUI workspace item for Zed Editor.
//! High performance native PDF viewing engine and GPUI workspace item for Zed Editor.
//!
//! Features:
//! - Sub-millisecond viewport rendering via bounded LRU memory caching
//! - Smart luminosity-threshold dark mode tone mapping preserving saturated colors
//! - Continuous multi-page scroll, single-page, and two-page spread layouts
//! - Precision focal-point zoom (10% to 2000%) with mouse and gesture support
//! - High performance viewport rendering via bounded LRU memory caching
//! - Smart luminosity threshold dark mode tone mapping preserving saturated colors
//! - Continuous multi page scroll, single page, and two page spread layouts
//! - Precision focal point zoom (10% to 2000%) with mouse and gesture support
//! - Debounced disk change watcher preserving exact scroll percentages and zoom levels
//! - Native Pdfium C++ engine bindings with robust fallback support
@@ -496,6 +496,25 @@ pub struct PdfDocumentRenderResult {
pub pages: Vec<PdfPageRenderResult>,
}
#[inline]
fn normalize_coordinates(
left: f32,
right: f32,
bottom: f32,
top: f32,
page_w: f32,
page_h: f32,
) -> (f32, f32, f32, f32) {
if page_w <= 0.0 || page_h <= 0.0 {
return (0.0, 0.0, 0.0, 0.0);
}
let norm_x = (left / page_w).clamp(0.0, 1.0);
let norm_y = ((page_h - top) / page_h).clamp(0.0, 1.0);
let norm_w = ((right - left) / page_w).clamp(0.0, 1.0);
let norm_h = ((top - bottom) / page_h).clamp(0.0, 1.0);
(norm_x, norm_y, norm_w, norm_h)
}
fn extract_page_text_and_links(
page: &pdfium_render::prelude::PdfPage,
idx: usize,
@@ -534,26 +553,8 @@ fn extract_page_text_and_links(
let bottom = bounds.bottom().value.min(bounds.top().value);
let top = bounds.bottom().value.max(bounds.top().value);
let norm_x = if page_w > 0.0 {
(left / page_w).clamp(0.0, 1.0)
} else {
0.0
};
let norm_y = if page_h > 0.0 {
((page_h - top) / page_h).clamp(0.0, 1.0)
} else {
0.0
};
let norm_w = if page_w > 0.0 {
((right - left) / page_w).clamp(0.0, 1.0)
} else {
0.0
};
let norm_h = if page_h > 0.0 {
((top - bottom) / page_h).clamp(0.0, 1.0)
} else {
0.0
};
let (norm_x, norm_y, norm_w, norm_h) =
normalize_coordinates(left, right, bottom, top, page_w, page_h);
if norm_w > 0.0 && norm_h > 0.0 {
segments.push(PdfTextSegment {
@@ -581,26 +582,9 @@ fn extract_page_text_and_links(
if is_ws {
if has_word_char && !word_text.is_empty() {
let norm_x = if page_w > 0.0 {
(min_left / page_w).clamp(0.0, 1.0)
} else {
0.0
};
let norm_y = if page_h > 0.0 {
((page_h - max_top) / page_h).clamp(0.0, 1.0)
} else {
0.0
};
let norm_w = if page_w > 0.0 {
((max_right - min_left) / page_w).clamp(0.0, 1.0)
} else {
0.0
};
let norm_h = if page_h > 0.0 {
((max_top - min_bottom) / page_h).clamp(0.0, 1.0)
} else {
0.0
};
let (norm_x, norm_y, norm_w, norm_h) = normalize_coordinates(
min_left, max_right, min_bottom, max_top, page_w, page_h,
);
if norm_w > 0.0 && norm_h > 0.0 {
segments.push(PdfTextSegment {
@@ -636,26 +620,9 @@ fn extract_page_text_and_links(
}
if has_word_char && !word_text.is_empty() {
let norm_x = if page_w > 0.0 {
(min_left / page_w).clamp(0.0, 1.0)
} else {
0.0
};
let norm_y = if page_h > 0.0 {
((page_h - max_top) / page_h).clamp(0.0, 1.0)
} else {
0.0
};
let norm_w = if page_w > 0.0 {
((max_right - min_left) / page_w).clamp(0.0, 1.0)
} else {
0.0
};
let norm_h = if page_h > 0.0 {
((max_top - min_bottom) / page_h).clamp(0.0, 1.0)
} else {
0.0
};
let (norm_x, norm_y, norm_w, norm_h) = normalize_coordinates(
min_left, max_right, min_bottom, max_top, page_w, page_h,
);
if norm_w > 0.0 && norm_h > 0.0 {
segments.push(PdfTextSegment {
@@ -674,26 +641,8 @@ fn extract_page_text_and_links(
let bottom = bounds.bottom().value.min(bounds.top().value);
let top = bounds.bottom().value.max(bounds.top().value);
let norm_x = if page_w > 0.0 {
(left / page_w).clamp(0.0, 1.0)
} else {
0.0
};
let norm_y = if page_h > 0.0 {
((page_h - top) / page_h).clamp(0.0, 1.0)
} else {
0.0
};
let norm_w = if page_w > 0.0 {
((right - left) / page_w).clamp(0.0, 1.0)
} else {
0.0
};
let norm_h = if page_h > 0.0 {
((top - bottom) / page_h).clamp(0.0, 1.0)
} else {
0.0
};
let (norm_x, norm_y, norm_w, norm_h) =
normalize_coordinates(left, right, bottom, top, page_w, page_h);
segments.push(PdfTextSegment {
text: seg_trimmed.to_string(),
@@ -718,26 +667,8 @@ fn extract_page_text_and_links(
let bottom = rect.bottom().value.min(rect.top().value);
let top = rect.bottom().value.max(rect.top().value);
let norm_x = if page_w > 0.0 {
(left / page_w).clamp(0.0, 1.0)
} else {
0.0
};
let norm_y = if page_h > 0.0 {
((page_h - top) / page_h).clamp(0.0, 1.0)
} else {
0.0
};
let norm_w = if page_w > 0.0 {
((right - left) / page_w).clamp(0.0, 1.0)
} else {
0.0
};
let norm_h = if page_h > 0.0 {
((top - bottom) / page_h).clamp(0.0, 1.0)
} else {
0.0
};
let (norm_x, norm_y, norm_w, norm_h) =
normalize_coordinates(left, right, bottom, top, page_w, page_h);
links.push(PdfLinkAnnotation {
url: url_clean,
@@ -766,26 +697,8 @@ fn extract_page_text_and_links(
let bottom = rect.bottom().value.min(rect.top().value);
let top = rect.bottom().value.max(rect.top().value);
let norm_x = if page_w > 0.0 {
(left / page_w).clamp(0.0, 1.0)
} else {
0.0
};
let norm_y = if page_h > 0.0 {
((page_h - top) / page_h).clamp(0.0, 1.0)
} else {
0.0
};
let norm_w = if page_w > 0.0 {
((right - left) / page_w).clamp(0.0, 1.0)
} else {
0.0
};
let norm_h = if page_h > 0.0 {
((top - bottom) / page_h).clamp(0.0, 1.0)
} else {
0.0
};
let (norm_x, norm_y, norm_w, norm_h) =
normalize_coordinates(left, right, bottom, top, page_w, page_h);
let exists = links.iter().any(|l| {
l.url == url_clean
File renamed without changes.
File renamed without changes.
@@ -1,4 +1,4 @@
//! PDF viewer toolbar control models and layout definitions.
//! User interface components and toolbar state models for PDF viewing.
//!
//! Provides navigation, zoom presets, page jump controls, and dark mode toggles.
File renamed without changes.
File renamed without changes.
@@ -1,4 +1,4 @@
use kkpdf_zed::{PageLayoutMode, PdfToolbarState, PdfView, PdfViewerSettings};
use pdf_viewer::{PageLayoutMode, PdfToolbarState, PdfView, PdfViewerSettings};
use std::time::Duration;
const MINIMAL_PDF: &[u8] = b"%PDF-1.7\n1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n2 0 obj\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\nendobj\n3 0 obj\n<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] >>\nendobj\nxref\n0 4\n0000000000 65535 f \n0000000010 00000 n \n0000000060 00000 n \n0000000117 00000 n \ntrailer\n<< /Size 4 /Root 1 0 R >>\nstartxref\n185\n%%EOF\n";
+1 -1
View File
@@ -61,7 +61,6 @@ globset.workspace = true
gpui.workspace = true
http_client = { workspace = true, features = ["github-download"] }
image.workspace = true
kkpdf-zed.workspace = true
indexmap.workspace = true
itertools.workspace = true
language.workspace = true
@@ -72,6 +71,7 @@ node_runtime.workspace = true
parking_lot.workspace = true
path.workspace = true
paths.workspace = true
pdf_viewer.workspace = true
percent-encoding.workspace = true
postage.workspace = true
prettier.workspace = true
+8 -16
View File
@@ -122,8 +122,8 @@ pub struct PdfPageEntry {
pub width: u32,
pub height: u32,
pub image: Option<Arc<gpui::RenderImage>>,
pub links: Vec<kkpdf_zed::PdfLinkAnnotation>,
pub text_segments: Vec<kkpdf_zed::PdfTextSegment>,
pub links: Vec<pdf_viewer::PdfLinkAnnotation>,
pub text_segments: Vec<pdf_viewer::PdfTextSegment>,
pub page_text: String,
}
@@ -178,9 +178,9 @@ pub fn project_image_source(project: WeakEntity<Project>, path: ProjectPath) ->
impl ImageItem {
pub fn compute_metadata_from_bytes(image_bytes: &[u8]) -> Result<ImageMetadata> {
if image_bytes.starts_with(b"%PDF-") {
let engine = kkpdf_zed::pdfium::PdfiumEngine::new();
let engine = pdf_viewer::pdfium::PdfiumEngine::new();
let doc = engine.load_document_from_bytes(image_bytes, None)?;
let dim = doc.page_size(0).unwrap_or(kkpdf_zed::PageDimensions::new(612.0, 792.0));
let dim = doc.page_size(0).unwrap_or(pdf_viewer::PageDimensions::new(612.0, 792.0));
let (width, height) = dim.to_pixel_size(1.0, 144.0);
return Ok(ImageMetadata {
width,
@@ -278,7 +278,7 @@ impl ImageItem {
if let Some(ref text) = info.full_text {
Some(text.clone())
} else {
kkpdf_zed::PdfiumEngine::new().extract_text_from_bytes(&info.pdf_bytes, None).ok()
pdf_viewer::PdfiumEngine::new().extract_text_from_bytes(&info.pdf_bytes, None).ok()
}
}
@@ -1122,7 +1122,7 @@ impl LocalImageStore {
pub fn create_gpui_images_from_pdf(
pdf_bytes: &[u8],
) -> anyhow::Result<(Vec<PdfPageEntry>, Option<String>)> {
let engine = kkpdf_zed::PdfiumEngine::new();
let engine = pdf_viewer::PdfiumEngine::new();
let details = engine.extract_document_details(pdf_bytes)?;
let mut pages = Vec::with_capacity(details.pages.len());
@@ -1138,16 +1138,8 @@ pub fn create_gpui_images_from_pdf(
});
}
if pages.is_empty() && pdf_bytes.starts_with(b"%PDF-") {
pages.push(PdfPageEntry {
page_index: 0,
width: 612,
height: 792,
image: None,
links: Vec::new(),
text_segments: Vec::new(),
page_text: String::new(),
});
if pages.is_empty() {
anyhow::bail!("Failed to parse PDF document: no pages found or Pdfium engine unavailable");
}
let full_text = if !details.full_text.is_empty() {
+3 -5
View File
@@ -351,7 +351,6 @@ pub enum ScrollbarStyle {
#[default]
Regular,
Editor,
Thick,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
@@ -375,7 +374,6 @@ impl ScrollbarStyle {
match self {
ScrollbarStyle::Regular => px(6.),
ScrollbarStyle::Editor => px(15.),
ScrollbarStyle::Thick => px(14.),
}
}
}
@@ -1242,7 +1240,7 @@ impl<T: ScrollableHandle> Element for ScrollbarElement<T> {
bounds.size.apply_along(axis.invert(), |_| {
width
+ match state.style {
ScrollbarStyle::Regular | ScrollbarStyle::Thick => 2 * SCROLLBAR_PADDING,
ScrollbarStyle::Regular => 2 * SCROLLBAR_PADDING,
ScrollbarStyle::Editor => Pixels::ZERO,
}
}),
@@ -1254,7 +1252,7 @@ impl<T: ScrollableHandle> Element for ScrollbarElement<T> {
// Rounded style needs a bit of padding, whereas for editor scrollbars,
// we want the full length of the track
let thumb_container_bounds = match state.style {
ScrollbarStyle::Regular | ScrollbarStyle::Thick => {
ScrollbarStyle::Regular => {
scroll_track_bounds.dilate(-SCROLLBAR_PADDING)
}
ScrollbarStyle::Editor if has_border => scroll_track_bounds
@@ -1490,7 +1488,7 @@ impl<T: ScrollableHandle> Element for ScrollbarElement<T> {
window.paint_quad(quad(
*thumb_bounds,
match style {
ScrollbarStyle::Regular | ScrollbarStyle::Thick => Corners::all(Pixels::MAX)
ScrollbarStyle::Regular => Corners::all(Pixels::MAX)
.clamp_radii_for_quad_size(thumb_bounds.size),
ScrollbarStyle::Editor => Corners::default(),
},