Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions .github/workflows/build-windows-only.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: Build Windows Portable

on:
workflow_dispatch:

jobs:
build-windows:
runs-on: windows-latest

steps:
- uses: actions/checkout@v7
with:
submodules: 'recursive'

- name: Determine latest 1.26.x MuPDF tag
id: mupdf-tag
working-directory: mupdf
shell: bash
run: |
TAG=$(git ls-remote --tags origin '1.26.*' | grep -v '\^{}' | awk -F/ '{print $NF}' | sort -V | tail -n1)
echo "tag=$TAG" >> "$GITHUB_OUTPUT"

- name: Pin MuPDF to latest 1.26.x
working-directory: mupdf
run: |
git fetch --depth 1 origin tag ${{ steps.mupdf-tag.outputs.tag }}
git checkout ${{ steps.mupdf-tag.outputs.tag }}

- name: Determine latest 1.x zlib tag
id: zlib-tag
working-directory: zlib
shell: bash
run: |
TAG=$(git ls-remote --tags origin 'v1.*' | grep -v '\^{}' | awk -F/ '{print $NF}' | sort -V | tail -n1)
echo "tag=$TAG" >> "$GITHUB_OUTPUT"

- name: Pin zlib to latest 1.x
working-directory: zlib
run: |
git fetch --depth 1 origin tag ${{ steps.zlib-tag.outputs.tag }}
git checkout ${{ steps.zlib-tag.outputs.tag }}

- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: '6.11.*'
modules: 'all'
cache: true
aqtsource: 'git+https://github.com/miurahr/aqtinstall.git'

- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v3

- name: Add msvc-dev-cmd
uses: TheMrMilchmann/setup-msvc-dev@v4
with:
arch: x64

- name: Get Latest OpenSSL 3.x Version
id: get-openssl
shell: bash
run: |
VERSION=$(git ls-remote --tags https://github.com/openssl/openssl.git 'openssl-3.*' | grep -v '\^{}' | awk -F/ '{print $NF}' | sort -V | tail -n1)
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

- name: Cache OpenSSL
id: openssl-cache
uses: actions/cache@v6
with:
path: openssl_build
key: ${{ runner.os }}-openssl-${{ steps.get-openssl.outputs.version }}

- name: Build OpenSSL
if: steps.openssl-cache.outputs.cache-hit != 'true'
shell: cmd
run: |
curl -sLO https://github.com/openssl/openssl/releases/download/${{ steps.get-openssl.outputs.version }}/${{ steps.get-openssl.outputs.version }}.tar.gz
tar -xzf ${{ steps.get-openssl.outputs.version }}.tar.gz
cd ${{ steps.get-openssl.outputs.version }}
perl Configure VC-WIN64A no-asm --prefix=%GITHUB_WORKSPACE%\openssl_build
nmake
nmake install_sw

- name: Cache MuPDF build
uses: actions/cache@v6
with:
path: mupdf\platform\win32\x64
key: ${{ runner.os }}-mupdf-${{ steps.mupdf-tag.outputs.tag }}

- name: Update VC Runtime DLLs
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path "windows_runtime"
Copy-Item "C:\Windows\System32\vcruntime140.dll" -Destination "windows_runtime\vcruntime140.dll" -Force
Copy-Item "C:\Windows\System32\vcruntime140_1.dll" -Destination "windows_runtime\vcruntime140_1.dll" -Force

- name: Build Sioyek (portable)
working-directory: ${{env.GITHUB_WORKSPACE}}
run: .\build_windows.bat portable

- name: Upload Windows portable artifact
uses: actions/upload-artifact@v7
with:
path: sioyek-release-windows-portable.zip
archive: false
retention-days: 7
7 changes: 0 additions & 7 deletions .github/workflows/build_and_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@
name: Build Release

on:
push:
tags:
- "v*"
pull_request:
branches:
- "*"

workflow_dispatch:

jobs:
Expand Down
7 changes: 0 additions & 7 deletions .github/workflows/preview_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@
name: Preview Release

on:
push:
tags:
- "v*"
pull_request:
branches:
- "*"

workflow_dispatch:

jobs:
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.16)
project(sioyek VERSION 2.0.0 LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
Expand Down
51 changes: 38 additions & 13 deletions build_windows.bat
Original file line number Diff line number Diff line change
@@ -1,33 +1,58 @@
set BUILD_TYPE=Release
set BUILD_TYPELC=release
set PORTABLE=0

:: Parse command line arguments
for %%a in (%*) do (
if /i "%%a"=="debug" set BUILD_TYPE=Debug && set BUILD_TYPELC=debug
if /i "%%a"=="portable" set PORTABLE=1
)

:: Build MuPDF
cd mupdf\platform\win32\
msbuild -maxcpucount mupdf.sln /m /property:Configuration=Debug /property:MultiProcessorCompilation=true
msbuild -maxcpucount mupdf.sln /m /property:Configuration=Release /property:MultiProcessorCompilation=true
msbuild -maxcpucount mupdf.sln /m /property:Configuration=%BUILD_TYPE% /property:MultiProcessorCompilation=true
cd ..\..\..

:: Build Zlib
cd zlib
nmake -f win32/makefile.msc
cd ..

qmake -tp vc "DEFINES+=NON_PORTABLE" "CONFIG+=release" pdf_viewer_build_config.pro
:: Set portable preprocessor flag dynamically based on %PORTABLE%
set QMAKE_DEFINES="DEFINES+=NON_PORTABLE"
if "%PORTABLE%"=="1" set QMAKE_DEFINES=

:: Generate Visual Studio project via qmake
qmake -tp vc %QMAKE_DEFINES% "CONFIG+=%BUILD_TYPELC%" pdf_viewer_build_config.pro

:: Build Sioyek executable
msbuild -maxcpucount sioyek.vcxproj /m /property:Configuration=%BUILD_TYPE%

msbuild -maxcpucount sioyek.vcxproj /m /property:Configuration=Release
rm -r sioyek-release-windows 2> NUL
:: Clean and recreate output staging directory
if exist sioyek-release-windows rmdir /s /q sioyek-release-windows
mkdir sioyek-release-windows
cp release\sioyek.exe sioyek-release-windows\sioyek.exe

cp %BUILD_TYPELC%\sioyek.exe sioyek-release-windows\sioyek.exe
cp pdf_viewer\keys.config sioyek-release-windows\keys.config
cp pdf_viewer\prefs.config sioyek-release-windows\prefs.config
cp -r pdf_viewer\shaders sioyek-release-windows\shaders
cp tutorial.pdf sioyek-release-windows\tutorial.pdf
windeployqt --qmldir ./pdf_viewer/touchui --release sioyek-release-windows\sioyek.exe
REM windeployqt sioyek-release-windows\sioyek.exe
cp windows_runtime\vcruntime140_1.dll sioyek-release-windows\vcruntime140_1.dll
cp windows_runtime\libssl-1_1-x64.dll sioyek-release-windows\libssl-1_1-x64.dll
cp windows_runtime\libcrypto-1_1-x64.dll sioyek-release-windows\libcrypto-1_1-x64.dll

if %1 == portable (
:: Deploy Qt dependencies
windeployqt --qmldir ./pdf_viewer/touchui --%BUILD_TYPELC% sioyek-release-windows\sioyek.exe

:: Copy Runtime DLLs if present
if exist windows_runtime\vcruntime140.dll copy /y windows_runtime\vcruntime140.dll sioyek-release-windows\
if exist windows_runtime\vcruntime140_1.dll copy /y windows_runtime\vcruntime140_1.dll sioyek-release-windows\

:: Copy OpenSSL 3 DLLs if present
if exist openssl_build\bin\libssl-3-x64.dll copy /y openssl_build\bin\libssl-3-x64.dll sioyek-release-windows\
if exist openssl_build\bin\libcrypto-3-x64.dll copy /y openssl_build\bin\libcrypto-3-x64.dll sioyek-release-windows\

if "%PORTABLE%"=="1" (
cp pdf_viewer\keys_user.config sioyek-release-windows\keys_user.config
cp pdf_viewer\prefs_user.config sioyek-release-windows\prefs_user.config
7z a sioyek-release-windows-portable.zip sioyek-release-windows

) else (
7z a sioyek-release-windows.zip sioyek-release-windows
)
2 changes: 1 addition & 1 deletion pdf_viewer/document_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1586,9 +1586,9 @@ std::optional<AbsoluteRect> DocumentView::get_control_rect() {
std::optional<AbsoluteRect> DocumentView::shrink_selection(bool is_begin, bool word) {
if (selected_character_rects.size() > 1) {
if (word) {
int page;
int index = is_begin ? 0 : selected_character_rects.size() - 1;
DocumentRect page_rect = selected_character_rects[index].to_document(current_document);
int page = page_rect.page;
if (page >= 0) {
fz_stext_page* stext_page = current_document->get_stext_with_page_number(page);
std::optional<DocumentRect> new_rect_ = find_shrinking_rect_word(is_begin, stext_page, page_rect);
Expand Down
2 changes: 1 addition & 1 deletion pdf_viewer/main_widget.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// deduplicate database code
// deduplicate database code
// make sure jsons exported by previous sioyek versions can be imported
// maybe: use a better method to handle deletion of canceled download portals
// change find_closest_*_index and argminf to use the fact that the list is sorted and speed up the search (not important if there are not a ridiculous amount of highlight/bookmarks)
Expand Down
95 changes: 64 additions & 31 deletions pdf_viewer/pdf_view_opengl_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -932,9 +932,9 @@ void PdfViewOpenGLWidget::render_overview(OverviewState overview) {
draw_overview_background();


render_page(page, true, ColorPalette::None, false);
render_page(page-1, true, ColorPalette::None, false);
render_page(page+1, true, ColorPalette::None, false);
render_page(page, true, ColorPalette::None, true);
render_page(page-1, true, ColorPalette::None, true);
render_page(page+1, true, ColorPalette::None, true);

std::optional<SearchResult> highlighted_result = get_current_search_result();
// highlight the overview search result
Expand Down Expand Up @@ -1222,37 +1222,65 @@ void PdfViewOpenGLWidget::render_page(int page_number, bool in_overview, ColorPa
disable_stencil();
}

if ((get_current_color_mode() != Normal) && (PRESERVE_IMAGE_COLORS) && (!in_overview) && (forced_color_palette == ColorPalette::None) && (stencils_allowed)) {
if ((get_current_color_mode() != Normal) && (PRESERVE_IMAGE_COLORS) && (forced_color_palette == ColorPalette::None) && (stencils_allowed)) {
// render images in forced palette mode
fz_stext_page * stext_page = document_view->get_document()->get_stext_with_page_number(page_number);
fz_stext_page * stext_page = doc(in_overview)->get_stext_with_page_number(page_number);
std::vector<PagelessDocumentRect> image_rects;
for (fz_stext_block* blk = stext_page->first_block; blk != nullptr; blk = blk->next) {
if (blk->type == FZ_STEXT_BLOCK_IMAGE) {
float im_x = blk->u.i.transform.e;
float im_y = blk->u.i.transform.f;
float im_w = blk->u.i.transform.a;
float im_h = blk->u.i.transform.d;
PagelessDocumentRect image_rect;
image_rect.x0 = im_x;
image_rect.x1 = im_x + im_w;
image_rect.y0 = im_y;
image_rect.y1 = im_y + im_h;
image_rects.push_back(image_rect);
if (stext_page) {
for (fz_stext_block* blk = stext_page->first_block; blk != nullptr; blk = blk->next) {
if (blk->type == FZ_STEXT_BLOCK_IMAGE) {
float im_x = blk->u.i.transform.e;
float im_y = blk->u.i.transform.f;
float im_w = blk->u.i.transform.a;
float im_h = blk->u.i.transform.d;
PagelessDocumentRect image_rect;
image_rect.x0 = im_x;
image_rect.x1 = im_x + im_w;
image_rect.y0 = im_y;
image_rect.y1 = im_y + im_h;
image_rects.push_back(image_rect);
}
}
}

glClear(GL_STENCIL_BUFFER_BIT);
enable_stencil();
write_to_stencil();
draw_stencil_rects(page_number, image_rects);
use_stencil_to_write(true);
ColorPalette target_palette = ColorPalette::Normal;
if (color_mode == ColorPalette::Custom && INVERTED_PRESERVED_IMAGE_COLORS) {
target_palette = ColorPalette::Dark;
}
if (!image_rects.empty()) {
ColorPalette target_palette = ColorPalette::Normal;
if (color_mode == ColorPalette::Custom && INVERTED_PRESERVED_IMAGE_COLORS) {
target_palette = ColorPalette::Dark;
}

render_page(page_number, in_overview, target_palette, false);
disable_stencil();
if (in_overview) {
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glStencilFunc(GL_EQUAL, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
draw_stencil_rects(page_number, image_rects, true);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

glStencilFunc(GL_EQUAL, 2, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

render_page(page_number, in_overview, target_palette, false);

glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glStencilFunc(GL_EQUAL, 2, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
draw_stencil_rects(page_number, image_rects, true);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

glStencilFunc(GL_EQUAL, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
}
else {
glClear(GL_STENCIL_BUFFER_BIT);
enable_stencil();
write_to_stencil();
draw_stencil_rects(page_number, image_rects, false);
use_stencil_to_write(true);

render_page(page_number, in_overview, target_palette, false);
disable_stencil();
}
}
}

if (!document_view->is_presentation_mode() && (!in_overview) && (!document_view->is_two_page_mode())){
Expand Down Expand Up @@ -2492,10 +2520,15 @@ void PdfViewOpenGLWidget::draw_stencil_rects(const std::vector<NormalizedWindowR

}

void PdfViewOpenGLWidget::draw_stencil_rects(int page, const std::vector<PagelessDocumentRect>& rects) {
void PdfViewOpenGLWidget::draw_stencil_rects(int page, const std::vector<PagelessDocumentRect>& rects, bool in_overview) {
std::vector<NormalizedWindowRect> normalized_rects;
for (auto rect : rects) {
normalized_rects.push_back(DocumentRect(rect, page).to_window_normalized(document_view));
if (in_overview) {
normalized_rects.push_back(document_to_overview_rect(DocumentRect(rect, page)));
}
else {
normalized_rects.push_back(DocumentRect(rect, page).to_window_normalized(document_view));
}
}
draw_stencil_rects(normalized_rects);
}
Expand Down Expand Up @@ -3684,7 +3717,7 @@ void PdfViewOpenGLWidget::set_overview_highlights(const std::vector<DocumentRect
}

bool PdfViewOpenGLWidget::needs_stencil_buffer() {
return fastread_mode || selected_rectangle.has_value() || overview_page.has_value();
return fastread_mode || selected_rectangle.has_value() || overview_page.has_value() || (PRESERVE_IMAGE_COLORS && color_mode != ColorPalette::Normal);
}

void PdfViewOpenGLWidget::zoom_overview(float scale){
Expand Down
2 changes: 1 addition & 1 deletion pdf_viewer/pdf_view_opengl_widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ class PdfViewOpenGLWidget : public QOpenGLWidget, protected QOpenGLExtraFunction
void enable_stencil();
void write_to_stencil();
void draw_stencil_rects(const std::vector<NormalizedWindowRect>& window_rects);
void draw_stencil_rects(int page, const std::vector<PagelessDocumentRect>& rects);
void draw_stencil_rects(int page, const std::vector<PagelessDocumentRect>& rects, bool in_overview = false);
void use_stencil_to_write(bool eq);
void disable_stencil();

Expand Down
Loading