fix: rotated pages (missing commits) (#219)

Signed-off-by: Peter Staar <taa@zurich.ibm.com>
This commit is contained in:
Peter W. J. Staar
2026-02-17 16:50:28 +01:00
committed by GitHub
parent aeca2496c9
commit 6d984796a9
27 changed files with 447 additions and 59 deletions
+11 -5
View File
@@ -111,8 +111,9 @@ jobs:
echo "Building cp: ${{ env.python_cp_version }}"
echo "Building cache_tag: ${PY_CACHE_TAG}"
echo "Building platform_id: ${{ matrix.os.platform_id }}"
echo "Building with BUILD_THREADS: ${BUILD_THREADS:-not set}"
uv run python --version
uv run python --version | grep ${{ matrix.python-version }}
uv run python --version | grep ${{ matrix.python-version }}
cat ./pyproject.toml
uv pip install --group build
rm -rf ./build || true
@@ -163,8 +164,9 @@ jobs:
echo "Building cp: ${{ env.python_cp_version }}"
echo "Building cache_tag: ${PY_CACHE_TAG}"
echo "Building platform_id: ${{ matrix.os.platform_id }}"
echo "Building with BUILD_THREADS: ${BUILD_THREADS:-not set}"
uv run python --version
uv run python --version | grep ${{ matrix.python-version }}
uv run python --version | grep ${{ matrix.python-version }}
cat ./pyproject.toml
uv pip install --group build
rm -rf ./build || true
@@ -204,14 +206,18 @@ jobs:
CIBW_SKIP: "pp* *musllinux_* *_i686* *_s390* *pypy*"
CIBW_PROJECT_REQUIRES_PYTHON: "~=${{ matrix.python-version }}.0"
CIBW_BUILD_VERBOSITY: 3
BUILD_THREADS: "8"
# Multi-threading: pass BUILD_THREADS into the cibuildwheel Docker container.
# Comment out the next line to disable parallel builds.
CIBW_ENVIRONMENT_PASS_LINUX: "BUILD_THREADS"
BUILD_THREADS: "4"
run: |
PY_CACHE_TAG=$(uv run python -c 'import sys;print(sys.implementation.cache_tag)')
echo "Building cp: ${{ env.python_cp_version }}"
echo "Building cache_tag: ${PY_CACHE_TAG}"
echo "Building platform_id: ${{ matrix.os.platform_id }}"
echo "Building with BUILD_THREADS: ${BUILD_THREADS:-not set}"
uv run python --version
uv run python --version | grep ${{ matrix.python-version }}
uv run python --version | grep ${{ matrix.python-version }}
cat ./pyproject.toml
uv pip install --group build
rm -rf ./build || true
@@ -275,7 +281,7 @@ jobs:
CMAKE_LIBRARY_PATH: "C:/msys64/mingw64/lib;C:/mingw64/lib;C:/windows-libs/external-libs/lib-mingw64"
CMAKE_INCLUDE_PATH: "C:/msys64/mingw64/include;C:/mingw64/include;C:/windows-libs/external-libs/include"
CMAKE_GENERATOR: "MSYS Makefiles"
BUILD_THREADS: 1
BUILD_THREADS: 4
ASM_NASM: "C:/nasm/nasm.exe"
shell: pwsh
run: |
+1
View File
@@ -70,4 +70,5 @@ def build_local(num_threads: int):
if "__main__" == __name__:
num_threads = int(os.getenv("BUILD_THREADS", "4"))
print(f"Building with {num_threads} threads (BUILD_THREADS={os.getenv('BUILD_THREADS', 'not set, defaulting to 4')})")
build_local(num_threads=num_threads)
+1
View File
@@ -14,6 +14,7 @@
#include <regex>
#include <fstream>
#include <iostream>
#include <cmath>
#ifdef _WIN32
#include <share.h> // to define _SH_DENYNO for loguru
+36 -49
View File
@@ -111,94 +111,80 @@ namespace pdflib
std::pair<double, double> page_item<PAGE_DIMENSION>::rotate(int my_angle)
{
angle -= my_angle;
LOG_S(INFO) << "my_angle: " << my_angle;
utils::values::rotate_inplace(my_angle, media_bbox);
// normalize the angle (after rotation, it should be zero)
angle -= my_angle;
LOG_S(INFO) << "media: "
LOG_S(INFO) << "media (before): "
<< media_bbox[0] << ", "
<< media_bbox[1] << ", "
<< media_bbox[2] << ", "
<< media_bbox[3];
utils::values::rotate_inplace(my_angle, crop_bbox);
LOG_S(INFO) << "crop: "
LOG_S(INFO) << "crop (before): "
<< crop_bbox[0] << ", "
<< crop_bbox[1] << ", "
<< crop_bbox[2] << ", "
<< crop_bbox[3];
utils::values::rotate_inplace(my_angle, bleed_bbox);
utils::values::rotate_inplace(my_angle, trim_bbox);
utils::values::rotate_inplace(my_angle, art_bbox);
utils::values::rotate_inplace(my_angle, bbox);
std::pair<double, double> delta = {0.0, 0.0};
// std::pair<double, double> delta = {0.0, std::abs(media_bbox[3])};
std::pair<double, double> delta = {0.0, 0.0}; //std::abs(media_bbox[3])};
switch(my_angle)
{
case 0:
{}
{
delta = {0.0, 0.0};
}
break;
case 90:
{
delta = {0.0, std::abs(media_bbox[3])};
media_bbox[3] += 2*delta.second;
crop_bbox[3] += 2*delta.second;
bleed_bbox[3] += 2*delta.second;
trim_bbox[3] += 2*delta.second;
art_bbox[3] += 2*delta.second;
bbox[3] += 2*delta.second;
delta = {
0.0,
std::abs(media_bbox[2])
};
}
break;
case 180:
{
delta = {std::abs(media_bbox[2]), std::abs(media_bbox[3])};
media_bbox[2] += 2*delta.first;
media_bbox[3] += 2*delta.second;
crop_bbox[2] += 2*delta.first;
crop_bbox[3] += 2*delta.second;
bleed_bbox[2] += 2*delta.first;
bleed_bbox[3] += 2*delta.second;
trim_bbox[2] += 2*delta.first;
trim_bbox[3] += 2*delta.second;
art_bbox[2] += 2*delta.first;
art_bbox[3] += 2*delta.second;
bbox[2] += 2*delta.first;
bbox[3] += 2*delta.second;
delta = {
std::abs(media_bbox[2]),
std::abs(media_bbox[3])
};
}
break;
case 270:
{
delta = {
std::abs(media_bbox[3]),
0.0
};
}
break;
default:
{
LOG_S(WARNING) << "might be unsupported rotation angle: " << my_angle;
}
}
LOG_S(INFO) << "crop: "
utils::values::transform_bottomleft_bbox_inplace(my_angle, delta, crop_bbox);
utils::values::transform_bottomleft_bbox_inplace(my_angle, delta, media_bbox);
utils::values::transform_bottomleft_bbox_inplace(my_angle, delta, trim_bbox);
utils::values::transform_bottomleft_bbox_inplace(my_angle, delta, bleed_bbox);
utils::values::transform_bottomleft_bbox_inplace(my_angle, delta, art_bbox);
utils::values::transform_bottomleft_bbox_inplace(my_angle, delta, bbox);
LOG_S(INFO) << "crop (after): "
<< crop_bbox[0] << ", "
<< crop_bbox[1] << ", "
<< crop_bbox[2] << ", "
<< crop_bbox[3];
LOG_S(INFO) << "bbox: "
LOG_S(INFO) << "bbox (after): "
<< bbox[0] << ", "
<< bbox[1] << ", "
<< bbox[2] << ", "
@@ -206,7 +192,8 @@ namespace pdflib
return delta;
}
std::array<double, 4> page_item<PAGE_DIMENSION>::normalize_page_boundaries(std::array<double, 4> bbox, std::string name)
{
LOG_S(INFO) << __FUNCTION__;
+2 -2
View File
@@ -132,7 +132,7 @@ namespace pdflib
void page_item<PAGE_IMAGE>::rotate(int angle, std::pair<double, double> delta)
{
LOG_S(INFO) << "rotate & translate image: (x0: " << x0 << ", y0: " << y0 << ", x1: " << x1 << ", y1: " << y1 << ")";
// LOG_S(INFO) << "rotate & translate image: (x0: " << x0 << ", y0: " << y0 << ", x1: " << x1 << ", y1: " << y1 << ")";
utils::values::rotate_inplace(angle, x0, y0);
utils::values::rotate_inplace(angle, x1, y1);
@@ -140,7 +140,7 @@ namespace pdflib
utils::values::translate_inplace(delta, x0, y0);
utils::values::translate_inplace(delta, x1, y1);
LOG_S(INFO) << "into (x0: " << x0 << ", y0: " << y0 << ", x1: " << x1 << ", y1: " << y1 << ")";
// LOG_S(INFO) << "into (x0: " << x0 << ", y0: " << y0 << ", x1: " << x1 << ", y1: " << y1 << ")";
// The bounding box always needs to have x0<x1 and y0<y1. If you want
// to keep the orientation of the image, we will need to add the rectangle
+43 -1
View File
@@ -76,7 +76,8 @@ namespace utils
void rotate_inplace(int angle, double& x0, double& y0)
{
double phi = -3.141592*angle/180.0;
//double phi = -3.141592*angle/180.0;
double phi = -M_PI*angle/180.0;
double x1 = x0, y1 = y0;
@@ -102,6 +103,47 @@ namespace utils
bbox[2] = std::cos(phi)*tmp[2] - std::sin(phi)*tmp[3];
bbox[3] = std::sin(phi)*tmp[2] + std::cos(phi)*tmp[3];
}
void transform_bottomleft_bbox_inplace(const int& angle,
const std::pair<double, double>& delta,
std::array<double, 4>& bbox)
{
// LOG_S(INFO) << "delta-x1: " << delta.first << ", delta-y1: " << delta.second;
double& x0 = bbox.at(0);
double& y0 = bbox.at(1);
double& x1 = bbox.at(2);
double& y1 = bbox.at(3);
// LOG_S(INFO) << "before x1: " << x1 << ", y1: " << y1;
utils::values::rotate_inplace(angle, x0, y0);
utils::values::rotate_inplace(angle, x1, y1);
// LOG_S(INFO) << "rotate x1: " << x1 << ", y1: " << y1;
utils::values::translate_inplace(delta, x0, y0);
utils::values::translate_inplace(delta, x1, y1);
// LOG_S(INFO) << "translate x1: " << x1 << ", y1: " << y1;
// The bounding box always needs to have x0<x1 and y0<y1. If you want
// to keep the orientation of the image, we will need to add the rectangle
// as demonstrated in the page_cell.
double x_min = std::min(x0, x1);
double x_max = std::max(x0, x1);
double y_min = std::min(y0, y1);
double y_max = std::max(y0, y1);
x0 = x_min;
x1 = x_max;
y0 = y_min;
y1 = y_max;
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -2
View File
@@ -418,10 +418,9 @@ def test_reference_documents_from_filenames():
_fname = fname + f".{unit}.txt"
lines = []
with open(_fname, "r") as fr:
content = fr.read()
lines = content.split(SPECIAL_SEPERATOR)
lines = content.split(SPECIAL_SEPERATOR) if content else []
assert len(lines) == len(
_lines