Skip to content

Commit

Permalink
fix DjVu rotation (fixes #1593)
Browse files Browse the repository at this point in the history
must process the file before setting rotation
  • Loading branch information
kjk committed Jul 12, 2021
1 parent c2d5c27 commit 0105b8b
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 27 deletions.
13 changes: 0 additions & 13 deletions src/DisplayModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,6 @@ static int ColumnsFromDisplayMode(DisplayMode displayMode) {
return 1;
}

int NormalizeRotation(int rotation) {
CrashIf((rotation % 90) != 0);
rotation = rotation % 360;
if (rotation < 0) {
rotation += 360;
}
if (rotation < 0 || rotation >= 360 || (rotation % 90) != 0) {
CrashIf(true);
return 0;
}
return rotation;
}

ScrollState::ScrollState(int page, double x, double y) : page(page), x(x), y(y) {
}

Expand Down
2 changes: 0 additions & 2 deletions src/DisplayModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,5 +246,3 @@ struct DisplayModel : public Controller {
resp. number of Back history entries */
size_t navHistoryIdx{0};
};

int NormalizeRotation(int rotation);
35 changes: 26 additions & 9 deletions src/EngineDjVu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ RenderedBitmap* EngineDjVu::RenderPage(RenderPageArgs& args) {
auto pageRect = args.pageRect;
auto zoom = args.zoom;
auto pageNo = args.pageNo;
auto rotation = args.rotation;
auto rotation = NormalizeRotation(args.rotation);
RectF pageRc = pageRect ? *pageRect : PageMediabox(pageNo);
Rect screen = Transform(pageRc, pageNo, zoom, rotation).Round();
Rect full = Transform(PageMediabox(pageNo), pageNo, zoom, rotation).Round();
Expand All @@ -563,16 +563,35 @@ RenderedBitmap* EngineDjVu::RenderPage(RenderPageArgs& args) {
if (!page) {
return nullptr;
}
int rotation4 = (((-rotation / 90) % 4) + 4) % 4;
ddjvu_page_set_rotation(page, (ddjvu_page_rotation_t)rotation4);

while (!ddjvu_page_decoding_done(page)) {
gDjVuContext->SpinMessageLoop();
}
if (ddjvu_page_decoding_error(page)) {
return nullptr;
}

ddjvu_page_rotation_t rot = DDJVU_ROTATE_0;
switch (rotation) {
case 0:
rot = DDJVU_ROTATE_0;
break;
// for whatever reason, 90 and 270 are reverased compared to what I expect
// maybe I'm doing other parts of the code wrong
case 90:
rot = DDJVU_ROTATE_270;
break;
case 180:
rot = DDJVU_ROTATE_180;
break;
case 270:
rot = DDJVU_ROTATE_90;
break;
default:
CrashIf("invalid rotation");
break;
}
ddjvu_page_set_rotation(page, rot);

bool isBitonal = DDJVU_PAGETYPE_BITONAL == ddjvu_page_get_type(page);
ddjvu_format_style_t style = isBitonal ? DDJVU_FORMAT_GREY8 : DDJVU_FORMAT_BGR24;
ddjvu_format_t* fmt = ddjvu_format_create(style, 0, nullptr);
Expand Down Expand Up @@ -618,14 +637,14 @@ RectF EngineDjVu::PageContentBox(int pageNo, [[maybe_unused]] RenderTarget targe
if (!page) {
return pageRc;
}
ddjvu_page_set_rotation(page, DDJVU_ROTATE_0);

while (!ddjvu_page_decoding_done(page)) {
gDjVuContext->SpinMessageLoop();
}
if (ddjvu_page_decoding_error(page)) {
return pageRc;
}
ddjvu_page_set_rotation(page, DDJVU_ROTATE_0);

// render the page in 8-bit grayscale up to 250x250 px in size
ddjvu_format_t* fmt = ddjvu_format_create(DDJVU_FORMAT_GREY8, 0, nullptr);
Expand Down Expand Up @@ -710,10 +729,8 @@ PointF EngineDjVu::TransformPoint(PointF pt, int pageNo, float zoom, int rotatio
zoom = 1.0f / zoom;
}

rotation = rotation % 360;
while (rotation < 0) {
rotation += 360;
}
rotation = NormalizeRotation(rotation);

PointF res = pt; // for rotation == 0
if (90 == rotation) {
res = PointF(page.dy - pt.y, pt.x);
Expand Down
27 changes: 26 additions & 1 deletion src/log.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
A daily log of changes and commentary. An experiment of sorts.

=======
2021-07-06 Tue

don't ask to save unsaved annotations in stress testing

sign when building locally

make 3.3 release

update mupdf

update harfbuzz

update lcms2

update openjpeg

simplify cmd-line arg parsing

rename CClassFactory => FilterClassFactory / PreviewClassFactory

fix DjVu rotation (fixes #1593)
must process the file before setting rotation
https://github.com/sumatrapdfreader/sumatrapdf/issues/1593

2021-06-29 Tue

simplify GetPaperFormat()
Expand Down Expand Up @@ -53,7 +78,7 @@ in annotations editor, add explicit button for saving to a new PDF instead of ct

make default annotation color yellow (0xffffff00) so it matches value in gColorsValues

add context menu�Select annotation�when cursor over annotation and edit annotation window is visible (replaces�Edit annotations�menu) (for #1992)
add context menu�Select annotation�when cursor over annotation and edit annotation window is visible (replaces�Edit annotations�menu) (for #1992)
https://github.com/sumatrapdfreader/sumatrapdf/issues/1992

fix DefaultAppearanceTextColor() (for #1974)
Expand Down
4 changes: 2 additions & 2 deletions src/utils/FileUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -499,8 +499,8 @@ std::span<u8> ReadFileWithAllocator(const char* filePath, Allocator* allocator)
if (nRead != size) {
int err = ferror(fp);
int isEof = feof(fp);
logf("ReadFileWithAllocator: fread() failed, path: '%s', size: %d, nRead: %d, err: %d, isEof: %d\n", filePath, (int)size, (int)nRead,
err, isEof);
logf("ReadFileWithAllocator: fread() failed, path: '%s', size: %d, nRead: %d, err: %d, isEof: %d\n", filePath,
(int)size, (int)nRead, err, isEof);
// we should either get eof or err
// either way shouldn't happen because we're reading the exact size of file
// I've seen this in crash reports so maybe the files are over-written
Expand Down
14 changes: 14 additions & 0 deletions src/utils/GeomUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,3 +444,17 @@ Gdiplus::Rect ToGdipRect(const RectF r) {
Gdiplus::RectF ToGdipRectF(const RectF r) {
return Gdiplus::RectF(r.x, r.y, r.dx, r.dy);
}

int NormalizeRotation(int rotation) {
while (rotation < 0) {
rotation += 360;
}
while (rotation >= 360) {
rotation -= 360;
}
if ((rotation % 90) != 0) {
CrashIf(true);
return 0;
}
return rotation;
}
2 changes: 2 additions & 0 deletions src/utils/GeomUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,5 @@ RECT ToRECT(const RectF r);
Rect ToRect(const RectF r);
Gdiplus::Rect ToGdipRect(const RectF r);
Gdiplus::RectF ToGdipRectF(const RectF r);

int NormalizeRotation(int rotation);

0 comments on commit 0105b8b

Please sign in to comment.