Skip to content

Commit

Permalink
Version 0.2, more optimised rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
makuke1234 committed Jan 20, 2022
1 parent c758059 commit 2bcb332
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 12 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ The x86 (32-bit) Windows binaries can be downloaded [here](https://github.com/ma

# Changelog

* 0.2.0 (planned)
* 0.2.0
* Refactor codebase
* Upgrade PDFium version
* Tabulating using Ctrl+Tab & Ctrl+Shift+Tab
* Fix most bugs (hopefully)
* Revamped tab close buttons
* [ ] More optimised rendering
* More optimised rendering (buffered pages)

* 0.1.0
* Initial release
Expand Down
18 changes: 14 additions & 4 deletions src/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,28 @@ namespace pdfv
template<typename T>
struct GDI
{
T obj;
T obj{ nullptr };

GDI() = default;
constexpr GDI(const T & value) noexcept
: obj(value)
{
}
GDI(const GDI & other) = delete;
constexpr GDI(const GDI & other) noexcept
: obj(other.obj)
{
}
constexpr GDI(GDI && other) noexcept
: obj(other.obj)
{
other.obj = nullptr;
}
GDI & operator=(const GDI & other) = delete;
GDI & operator=(const GDI & other) noexcept
{
this->~GDI();
this->obj = other.obj;
return *this;
}
GDI & operator=(GDI && other) noexcept
{
this->~GDI();
Expand All @@ -120,6 +129,7 @@ namespace pdfv
{
auto temp{ this->obj };
this->obj = nullptr;
DEBUGPRINT("DeleteObject(%p)\n", static_cast<void *>(temp));
::DeleteObject(temp);
}
}
Expand All @@ -128,7 +138,7 @@ namespace pdfv
{
return this->obj;
}
[[nodiscard]] constexpr operator const T &() const noexcept
[[nodiscard]] constexpr operator const T & () const noexcept
{
return this->obj;
}
Expand Down
32 changes: 32 additions & 0 deletions src/hdcbuffer.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,33 @@
#include "hdcbuffer.hpp"

void pdfv::hdc::Renderer::clear() noexcept
{
this->bmBuffer.clear();
}

[[nodiscard]] bool pdfv::hdc::Renderer::hasPage(std::size_t pageIdx) const noexcept
{
return this->bmBuffer.find(pageIdx) != this->bmBuffer.end();
}
void pdfv::hdc::Renderer::putPage(std::size_t pageIdx, xy<int> pos, xy<int> size, std::function<Renderer::RenderT (void *)> render, void * renderArg)
{
bool reRender{ true };
if (auto it = this->bmBuffer.find(pageIdx); it != this->bmBuffer.end())
{
if (it->second.pos == pos && it->second.size == size)
{
reRender = false;
}
}

if (reRender)
{
this->bmBuffer[pageIdx] = RenderStats(render(renderArg), pos, size);
}
}

pdfv::hdc::Renderer::RenderT & pdfv::hdc::Renderer::getPage(std::size_t pageIdx)
{
return this->bmBuffer.at(pageIdx).hrender;
}

28 changes: 25 additions & 3 deletions src/hdcbuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,32 @@

#include "common.hpp"

#include <functional>
#include <unordered_map>

namespace pdfv::hdc
{
class renderer
class Renderer
{

public:
using RenderT = w::GDI<HBITMAP>;

struct RenderStats
{
RenderT hrender;
xy<int> pos, size;
};

private:
std::unordered_map<std::size_t, RenderStats> bmBuffer;

public:

void clear() noexcept;

[[nodiscard]] bool hasPage(std::size_t pageIdx) const noexcept;
void putPage(std::size_t pageIdx, xy<int> pos, xy<int> size, std::function<RenderT (void *)> render, void * renderArg);

RenderT & getPage(std::size_t pageIdx);
};
}
}
47 changes: 45 additions & 2 deletions src/lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ void pdfv::Pdfium::pageUnload() noexcept
}
}

pdfv::error::Errorcode pdfv::Pdfium::pageRender(HDC dc, pdfv::xy<int> pos, pdfv::xy<int> size) const noexcept
pdfv::error::Errorcode pdfv::Pdfium::pageRender(HDC dc, pdfv::xy<int> pos, pdfv::xy<int> size)
{
DEBUGPRINT("pdf::Pdfium::pageRender(%p, %p, %p)\n", static_cast<void *>(dc), static_cast<void *>(&pos), static_cast<void *>(&size));
assert(s_libInit == true);
Expand All @@ -222,7 +222,50 @@ pdfv::error::Errorcode pdfv::Pdfium::pageRender(HDC dc, pdfv::xy<int> pos, pdfv:
pos = size - newsize;
pos /= 2;

FPDF_RenderPage(dc, this->m_fpage, pos.x, pos.y, newsize.x, newsize.y, 0, 0);
void * args[] = { this, dc, &newsize };
this->m_optRenderer.putPage(
this->m_fpagenum,
pos,
newsize,
[](void * args) -> hdc::Renderer::RenderT
{
DEBUGPRINT("render!\n");
auto argv = reinterpret_cast<void **>(args);

auto self = static_cast<Pdfium *>(argv[0]);
auto dc = static_cast<HDC>(argv[1]);
auto size = static_cast<xy<int> *>(argv[2]);

auto memdc = ::CreateCompatibleDC(dc);
auto render = ::CreateCompatibleBitmap(dc, size->x, size->y);

auto hbmold = ::SelectObject(memdc, render);

RECT r{ .left = 0, .top = 0, .right = size->x, .bottom = size->y };
::FillRect(memdc, &r, reinterpret_cast<HBRUSH>(COLOR_WINDOW));

FPDF_RenderPage(memdc, self->m_fpage, 0, 0, size->x, size->y, 0, 0);

::SelectObject(memdc, hbmold);
::DeleteDC(memdc);

DEBUGPRINT("HBITMAP = %p (fresh)\n", static_cast<void *>(render));
return render;

},
args
);

const auto & render = this->m_optRenderer.getPage(this->m_fpagenum);

auto memdc = ::CreateCompatibleDC(dc);
DEBUGPRINT("HBITMAP = %p\n", static_cast<void *>(render.get()));
auto hbmold = ::SelectObject(memdc, render.get());

::BitBlt(dc, pos.x, pos.y, newsize.x, newsize.y, memdc, 0, 0, SRCCOPY);

::SelectObject(memdc, hbmold);
::DeleteDC(memdc);

return error::noerror;
}
Expand Down
6 changes: 5 additions & 1 deletion src/lib.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include "common.hpp"
#include "hdcbuffer.hpp"

#include <vector>

Expand All @@ -18,6 +20,8 @@ namespace pdfv

std::unique_ptr<std::uint8_t> m_buf{ nullptr };

hdc::Renderer m_optRenderer;

public:
Pdfium() noexcept;
Pdfium(const Pdfium & other) = delete;
Expand Down Expand Up @@ -74,7 +78,7 @@ namespace pdfv
// Renders the current page of the PDF document to the specified
// position on the device context with specified size
//
error::Errorcode pageRender(HDC dc, pdfv::xy<int> pos, pdfv::xy<int> size) const noexcept;
error::Errorcode pageRender(HDC dc, pdfv::xy<int> pos, pdfv::xy<int> size);

//
// Returns the page count of the currently opened PDF document
Expand Down

0 comments on commit 2bcb332

Please sign in to comment.