fix build

This commit is contained in:
Martin Rotter 2022-03-29 14:08:18 +02:00
parent 982a3dc004
commit ac86a34c1f
2 changed files with 273 additions and 460 deletions

View File

@ -31,15 +31,16 @@
#include "container_qpainter.h" #include "container_qpainter.h"
#include <QDebug> #include <QDebug>
#include <QPaintEvent>
#include <QPainter> #include <QPainter>
#include <QPaintEvent>
#include <QScrollBar> #include <QScrollBar>
#include <QStyle> #include <QStyle>
const int kScrollBarStep = 40; const int kScrollBarStep = 40;
// TODO copied from litehtml/include/master.css // TODO copied from litehtml/include/master.css
const char mastercss[] = R"RAW( const char mastercss[] =
R"RAW(
html { html {
display: block; display: block;
height:100%; height:100%;
@ -84,74 +85,16 @@ display:block;
margin-bottom:1em; margin-bottom:1em;
} }
b, strong {
display:inline;
font-weight:bold;
}
i, em {
display:inline;
font-style:italic;
}
center center
{ {
text-align:center; text-align:center;
display:block; display:block;
} }
a:link
{
text-decoration: underline;
color: #00f;
cursor: pointer;
}
h1, h2, h3, h4, h5, h6, div { h1, h2, h3, h4, h5, h6, div {
display:block; display:block;
} }
h1 {
font-weight:bold;
margin-top:0.67em;
margin-bottom:0.67em;
font-size: 2em;
}
h2 {
font-weight:bold;
margin-top:0.83em;
margin-bottom:0.83em;
font-size: 1.5em;
}
h3 {
font-weight:bold;
margin-top:1em;
margin-bottom:1em;
font-size:1.17em;
}
h4 {
font-weight:bold;
margin-top:1.33em;
margin-bottom:1.33em
}
h5 {
font-weight:bold;
margin-top:1.67em;
margin-bottom:1.67em;
font-size:.83em;
}
h6 {
font-weight:bold;
margin-top:2.33em;
margin-bottom:2.33em;
font-size:.67em;
}
br { br {
display:inline-block; display:inline-block;
} }
@ -171,14 +114,6 @@ br[clear="right"]
clear:right; clear:right;
} }
span {
display:inline
}
img {
display: inline-block;
}
img[align="right"] img[align="right"]
{ {
float: right; float: right;
@ -188,188 +123,11 @@ img[align="left"]
{ {
float: left; float: left;
} }
hr {
display: block;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: auto;
margin-right: auto;
border-style: inset;
border-width: 1px
}
/***************** TABLES ********************/
table {
display: table;
border-collapse: separate;
border-spacing: 2px;
border-top-color:gray;
border-left-color:gray;
border-bottom-color:black;
border-right-color:black;
}
tbody, tfoot, thead {
display:table-row-group;
vertical-align:middle;
}
tr {
display: table-row;
vertical-align: inherit;
border-color: inherit;
}
td, th {
display: table-cell;
vertical-align: inherit;
border-width:1px;
padding:1px;
}
th {
font-weight: bold;
}
table[border] {
border-style:solid;
}
table[border|=0] {
border-style:none;
}
table[border] td, table[border] th {
border-style:solid;
border-top-color:black;
border-left-color:black;
border-bottom-color:gray;
border-right-color:gray;
}
table[border|=0] td, table[border|=0] th {
border-style:none;
}
caption {
display: table-caption;
}
td[nowrap], th[nowrap] {
white-space:nowrap;
}
tt, code, kbd, samp {
font-family: monospace
}
pre, xmp, plaintext, listing {
display: block;
font-family: monospace;
white-space: pre;
margin: 1em 0
}
/***************** LISTS ********************/
ul, menu, dir {
display: block;
list-style-type: disc;
margin-top: 1em;
margin-bottom: 1em;
margin-left: 0;
margin-right: 0;
padding-left: 40px
}
ol {
display: block;
list-style-type: decimal;
margin-top: 1em;
margin-bottom: 1em;
margin-left: 0;
margin-right: 0;
padding-left: 40px
}
li {
display: list-item;
}
ul ul, ol ul {
list-style-type: circle;
}
ol ol ul, ol ul ul, ul ol ul, ul ul ul {
list-style-type: square;
}
dd {
display: block;
margin-left: 40px;
}
dl {
display: block;
margin-top: 1em;
margin-bottom: 1em;
margin-left: 0;
margin-right: 0;
}
dt {
display: block;
}
ol ul, ul ol, ul ul, ol ol {
margin-top: 0;
margin-bottom: 0
}
blockquote {
display: block;
margin-top: 1em;
margin-bottom: 1em;
margin-left: 40px;
margin-left: 40px;
}
/*********** FORM ELEMENTS ************/
form {
display: block;
margin-top: 0em;
}
option {
display: none;
}
input, textarea, keygen, select, button, isindex {
margin: 0em;
color: initial;
line-height: normal;
text-transform: none;
text-indent: 0;
text-shadow: none;
display: inline-block;
}
input[type="hidden"] {
display: none;
}
article, aside, footer, header, hgroup, nav, section
{
display: block;
}
)RAW"; )RAW";
class QLiteHtmlWidgetPrivate class QLiteHtmlWidgetPrivate
{ {
public: public:
QString html; QString html;
DocumentContainerContext context; DocumentContainerContext context;
QUrl url; QUrl url;
@ -378,338 +136,393 @@ public:
QUrl lastHighlightedLink; QUrl lastHighlightedLink;
}; };
QLiteHtmlWidget::QLiteHtmlWidget(QWidget *parent) QLiteHtmlWidget::QLiteHtmlWidget(QWidget* parent)
: QAbstractScrollArea(parent) : QAbstractScrollArea(parent)
, d(new QLiteHtmlWidgetPrivate) , d(new QLiteHtmlWidgetPrivate)
{ {
setMouseTracking(true); setMouseTracking(true);
horizontalScrollBar()->setSingleStep(kScrollBarStep); horizontalScrollBar()->setSingleStep(kScrollBarStep);
verticalScrollBar()->setSingleStep(kScrollBarStep); verticalScrollBar()->setSingleStep(kScrollBarStep);
d->documentContainer.setCursorCallback([this](const QCursor &c) { viewport()->setCursor(c); }); d->documentContainer.setCursorCallback([this](const QCursor& c) {
d->documentContainer.setPaletteCallback([this] { return palette(); }); viewport()->setCursor(c);
d->documentContainer.setLinkCallback([this](const QUrl &url) { });
QUrl fullUrl = url; d->documentContainer.setPaletteCallback([this] {
if (url.isRelative() && url.path(QUrl::FullyEncoded).isEmpty()) { // fragment/anchor only return palette();
fullUrl = d->url; });
fullUrl.setFragment(url.fragment(QUrl::FullyEncoded)); d->documentContainer.setLinkCallback([this](const QUrl& url) {
} QUrl fullUrl = url;
// delay because document may not be changed directly during this callback if (url.isRelative() && url.path(QUrl::FullyEncoded).isEmpty()) { // fragment/anchor only
QMetaObject::invokeMethod(this, [this, fullUrl] { emit linkClicked(fullUrl); }, fullUrl = d->url;
Qt::QueuedConnection); fullUrl.setFragment(url.fragment(QUrl::FullyEncoded));
}); }
d->documentContainer.setClipboardCallback([this](bool yes) { emit copyAvailable(yes); });
// TODO adapt mastercss to palette (default text & background color) // delay because document may not be changed directly during this callback
d->context.setMasterStyleSheet(mastercss); QMetaObject::invokeMethod(this, [this, fullUrl] {
emit linkClicked(fullUrl);
},
Qt::QueuedConnection);
});
d->documentContainer.setClipboardCallback([this](bool yes) {
emit copyAvailable(yes);
});
// TODO adapt mastercss to palette (default text & background color)
d->context.setMasterStyleSheet(mastercss);
} }
QLiteHtmlWidget::~QLiteHtmlWidget() QLiteHtmlWidget::~QLiteHtmlWidget()
{ {
delete d; delete d;
} }
void QLiteHtmlWidget::setUrl(const QUrl &url) void QLiteHtmlWidget::setUrl(const QUrl& url)
{ {
d->url = url; d->url = url;
QUrl baseUrl = url; QUrl baseUrl = url;
baseUrl.setFragment({});
const QString path = baseUrl.path(QUrl::FullyEncoded); baseUrl.setFragment({});
const int lastSlash = path.lastIndexOf('/'); const QString path = baseUrl.path(QUrl::FullyEncoded);
const QString basePath = lastSlash >= 0 ? path.left(lastSlash) : QString(); const int lastSlash = path.lastIndexOf('/');
baseUrl.setPath(basePath); const QString basePath = lastSlash >= 0 ? path.left(lastSlash) : QString();
d->documentContainer.setBaseUrl(baseUrl.toString(QUrl::FullyEncoded));
QMetaObject::invokeMethod(this, [this] { updateHightlightedLink(); }, baseUrl.setPath(basePath);
Qt::QueuedConnection); d->documentContainer.setBaseUrl(baseUrl.toString(QUrl::FullyEncoded));
QMetaObject::invokeMethod(this, [this] {
updateHightlightedLink();
},
Qt::QueuedConnection);
} }
QUrl QLiteHtmlWidget::url() const QUrl QLiteHtmlWidget::url() const
{ {
return d->url; return d->url;
} }
void QLiteHtmlWidget::setHtml(const QString &content) void QLiteHtmlWidget::setHtml(const QString& content)
{ {
d->html = content; d->html = content;
d->documentContainer.setPaintDevice(viewport()); d->documentContainer.setPaintDevice(viewport());
d->documentContainer.setDocument(content.toUtf8(), &d->context); d->documentContainer.setDocument(content.toUtf8(), &d->context);
verticalScrollBar()->setValue(0); verticalScrollBar()->setValue(0);
horizontalScrollBar()->setValue(0); horizontalScrollBar()->setValue(0);
render(); render();
QMetaObject::invokeMethod(this, [this] { updateHightlightedLink(); }, QMetaObject::invokeMethod(this, [this] {
Qt::QueuedConnection); updateHightlightedLink();
},
Qt::QueuedConnection);
} }
QString QLiteHtmlWidget::html() const QString QLiteHtmlWidget::html() const
{ {
return d->html; return d->html;
} }
QString QLiteHtmlWidget::title() const QString QLiteHtmlWidget::title() const
{ {
return d->documentContainer.caption(); return d->documentContainer.caption();
} }
void QLiteHtmlWidget::setZoomFactor(qreal scale) void QLiteHtmlWidget::setZoomFactor(qreal scale)
{ {
Q_ASSERT(scale != 0); Q_ASSERT(scale != 0);
d->zoomFactor = scale; d->zoomFactor = scale;
withFixedTextPosition([this] { render(); }); withFixedTextPosition([this] {
render();
});
} }
qreal QLiteHtmlWidget::zoomFactor() const qreal QLiteHtmlWidget::zoomFactor() const
{ {
return d->zoomFactor; return d->zoomFactor;
} }
bool QLiteHtmlWidget::findText(const QString &text, bool QLiteHtmlWidget::findText(const QString& text,
QTextDocument::FindFlags flags, QTextDocument::FindFlags flags,
bool incremental, bool incremental,
bool *wrapped) bool* wrapped)
{ {
bool success = false; bool success = false;
QVector<QRect> oldSelection; QVector<QRect> oldSelection;
QVector<QRect> newSelection; QVector<QRect> newSelection;
d->documentContainer
.findText(text, flags, incremental, wrapped, &success, &oldSelection, &newSelection); d->documentContainer
// scroll to search result position and/or redraw as necessary .findText(text, flags, incremental, wrapped, &success, &oldSelection, &newSelection);
QRect newSelectionCombined;
for (const QRect &r : qAsConst(newSelection)) // scroll to search result position and/or redraw as necessary
newSelectionCombined = newSelectionCombined.united(r); QRect newSelectionCombined;
QScrollBar *vBar = verticalScrollBar();
const int top = newSelectionCombined.top(); for (const QRect& r : qAsConst(newSelection))
const int bottom = newSelectionCombined.bottom() - toVirtual(viewport()->size()).height(); newSelectionCombined = newSelectionCombined.united(r);
if (success && top < vBar->value() && vBar->minimum() <= top) {
vBar->setValue(top); QScrollBar* vBar = verticalScrollBar();
} else if (success && vBar->value() < bottom && bottom <= vBar->maximum()) { const int top = newSelectionCombined.top();
vBar->setValue(bottom); const int bottom = newSelectionCombined.bottom() - toVirtual(viewport()->size()).height();
} else {
viewport()->update(fromVirtual(newSelectionCombined.translated(-scrollPosition()))); if (success && top < vBar->value() && vBar->minimum() <= top) {
for (const QRect &r : qAsConst(oldSelection)) vBar->setValue(top);
viewport()->update(fromVirtual(r.translated(-scrollPosition()))); }
} else if (success && vBar->value() < bottom && bottom <= vBar->maximum()) {
return success; vBar->setValue(bottom);
}
else {
viewport()->update(fromVirtual(newSelectionCombined.translated(-scrollPosition())));
for (const QRect& r : qAsConst(oldSelection))
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
}
return success;
} }
void QLiteHtmlWidget::setDefaultFont(const QFont &font) void QLiteHtmlWidget::setDefaultFont(const QFont& font)
{ {
withFixedTextPosition([this, &font] { withFixedTextPosition([this, &font] {
d->documentContainer.setDefaultFont(font); d->documentContainer.setDefaultFont(font);
render(); render();
}); });
} }
QFont QLiteHtmlWidget::defaultFont() const QFont QLiteHtmlWidget::defaultFont() const
{ {
return d->documentContainer.defaultFont(); return d->documentContainer.defaultFont();
} }
void QLiteHtmlWidget::scrollToAnchor(const QString &name) void QLiteHtmlWidget::scrollToAnchor(const QString& name)
{ {
if (!d->documentContainer.hasDocument()) if (!d->documentContainer.hasDocument())
return; return;
horizontalScrollBar()->setValue(0);
if (name.isEmpty()) { horizontalScrollBar()->setValue(0);
verticalScrollBar()->setValue(0); if (name.isEmpty()) {
return; verticalScrollBar()->setValue(0);
} return;
const int y = d->documentContainer.anchorY(name); }
if (y >= 0)
verticalScrollBar()->setValue(std::min(y, verticalScrollBar()->maximum())); const int y = d->documentContainer.anchorY(name);
if (y >= 0)
verticalScrollBar()->setValue(std::min(y, verticalScrollBar()->maximum()));
} }
void QLiteHtmlWidget::setResourceHandler(const QLiteHtmlWidget::ResourceHandler &handler) void QLiteHtmlWidget::setResourceHandler(const QLiteHtmlWidget::ResourceHandler& handler)
{ {
d->documentContainer.setDataCallback(handler); d->documentContainer.setDataCallback(handler);
} }
QString QLiteHtmlWidget::selectedText() const QString QLiteHtmlWidget::selectedText() const
{ {
return d->documentContainer.selectedText(); return d->documentContainer.selectedText();
} }
void QLiteHtmlWidget::paintEvent(QPaintEvent *event) void QLiteHtmlWidget::paintEvent(QPaintEvent* event)
{ {
if (!d->documentContainer.hasDocument()) if (!d->documentContainer.hasDocument())
return; return;
d->documentContainer.setScrollPosition(scrollPosition());
QPainter p(viewport()); d->documentContainer.setScrollPosition(scrollPosition());
p.setWorldTransform(QTransform().scale(d->zoomFactor, d->zoomFactor)); QPainter p(viewport());
p.setRenderHint(QPainter::SmoothPixmapTransform, true);
p.setRenderHint(QPainter::Antialiasing, true); p.setWorldTransform(QTransform().scale(d->zoomFactor, d->zoomFactor));
d->documentContainer.draw(&p, toVirtual(event->rect())); p.setRenderHint(QPainter::SmoothPixmapTransform, true);
p.setRenderHint(QPainter::Antialiasing, true);
d->documentContainer.draw(&p, toVirtual(event->rect()));
} }
void QLiteHtmlWidget::resizeEvent(QResizeEvent *event) void QLiteHtmlWidget::resizeEvent(QResizeEvent* event)
{ {
withFixedTextPosition([this, event] { withFixedTextPosition([this, event] {
QAbstractScrollArea::resizeEvent(event); QAbstractScrollArea::resizeEvent(event);
render(); render();
}); });
} }
void QLiteHtmlWidget::mouseMoveEvent(QMouseEvent *event) void QLiteHtmlWidget::mouseMoveEvent(QMouseEvent* event)
{ {
QPoint viewportPos; QPoint viewportPos;
QPoint pos; QPoint pos;
htmlPos(event->pos(), &viewportPos, &pos);
const QVector<QRect> areas = d->documentContainer.mouseMoveEvent(pos, viewportPos);
for (const QRect &r : areas)
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
updateHightlightedLink(); htmlPos(event->pos(), &viewportPos, &pos);
const QVector<QRect> areas = d->documentContainer.mouseMoveEvent(pos, viewportPos);
for (const QRect& r : areas)
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
updateHightlightedLink();
} }
void QLiteHtmlWidget::mousePressEvent(QMouseEvent *event) void QLiteHtmlWidget::mousePressEvent(QMouseEvent* event)
{ {
QPoint viewportPos; QPoint viewportPos;
QPoint pos; QPoint pos;
htmlPos(event->pos(), &viewportPos, &pos);
const QVector<QRect> areas = d->documentContainer.mousePressEvent(pos, viewportPos, event->button()); htmlPos(event->pos(), &viewportPos, &pos);
for (const QRect &r : areas) const QVector<QRect> areas = d->documentContainer.mousePressEvent(pos, viewportPos, event->button());
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
for (const QRect& r : areas)
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
} }
void QLiteHtmlWidget::mouseReleaseEvent(QMouseEvent *event) void QLiteHtmlWidget::mouseReleaseEvent(QMouseEvent* event)
{ {
QPoint viewportPos; QPoint viewportPos;
QPoint pos; QPoint pos;
htmlPos(event->pos(), &viewportPos, &pos);
const QVector<QRect> areas = d->documentContainer.mouseReleaseEvent(pos, viewportPos, event->button()); htmlPos(event->pos(), &viewportPos, &pos);
for (const QRect &r : areas) const QVector<QRect> areas = d->documentContainer.mouseReleaseEvent(pos, viewportPos, event->button());
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
for (const QRect& r : areas)
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
} }
void QLiteHtmlWidget::mouseDoubleClickEvent(QMouseEvent *event) void QLiteHtmlWidget::mouseDoubleClickEvent(QMouseEvent* event)
{ {
QPoint viewportPos; QPoint viewportPos;
QPoint pos; QPoint pos;
htmlPos(event->pos(), &viewportPos, &pos);
const QVector<QRect> areas = d->documentContainer.mouseDoubleClickEvent(pos, viewportPos, event->button()); htmlPos(event->pos(), &viewportPos, &pos);
for (const QRect &r : areas) { const QVector<QRect> areas = d->documentContainer.mouseDoubleClickEvent(pos, viewportPos, event->button());
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
} for (const QRect& r : areas) {
viewport()->update(fromVirtual(r.translated(-scrollPosition())));
}
} }
void QLiteHtmlWidget::leaveEvent(QEvent *event) void QLiteHtmlWidget::leaveEvent(QEvent* event)
{ {
Q_UNUSED(event) Q_UNUSED(event)
const QVector<QRect> areas = d->documentContainer.leaveEvent(); const QVector<QRect> areas = d->documentContainer.leaveEvent();
for (const QRect &r : areas)
viewport()->update(fromVirtual(r.translated(-scrollPosition()))); for (const QRect& r : areas)
setHightlightedLink(QUrl()); viewport()->update(fromVirtual(r.translated(-scrollPosition())));
setHightlightedLink(QUrl());
} }
void QLiteHtmlWidget::contextMenuEvent(QContextMenuEvent *event) void QLiteHtmlWidget::contextMenuEvent(QContextMenuEvent* event)
{ {
QPoint viewportPos; QPoint viewportPos;
QPoint pos; QPoint pos;
htmlPos(event->pos(), &viewportPos, &pos);
emit contextMenuRequested(event->pos(), d->documentContainer.linkAt(pos, viewportPos)); htmlPos(event->pos(), &viewportPos, &pos);
emit contextMenuRequested(event->pos(), d->documentContainer.linkAt(pos, viewportPos));
} }
static QAbstractSlider::SliderAction getSliderAction(int key) static QAbstractSlider::SliderAction getSliderAction(int key)
{ {
if (key == Qt::Key_Home) if (key == Qt::Key_Home)
return QAbstractSlider::SliderToMinimum; return QAbstractSlider::SliderToMinimum;
if (key == Qt::Key_End)
return QAbstractSlider::SliderToMaximum; if (key == Qt::Key_End)
if (key == Qt::Key_PageUp) return QAbstractSlider::SliderToMaximum;
return QAbstractSlider::SliderPageStepSub;
if (key == Qt::Key_PageDown) if (key == Qt::Key_PageUp)
return QAbstractSlider::SliderPageStepAdd; return QAbstractSlider::SliderPageStepSub;
return QAbstractSlider::SliderNoAction;
if (key == Qt::Key_PageDown)
return QAbstractSlider::SliderPageStepAdd;
return QAbstractSlider::SliderNoAction;
} }
void QLiteHtmlWidget::keyPressEvent(QKeyEvent *event) void QLiteHtmlWidget::keyPressEvent(QKeyEvent* event)
{ {
if (event->modifiers() == Qt::NoModifier || event->modifiers() == Qt::KeypadModifier) { if (event->modifiers() == Qt::NoModifier || event->modifiers() == Qt::KeypadModifier) {
const QAbstractSlider::SliderAction sliderAction = getSliderAction(event->key()); const QAbstractSlider::SliderAction sliderAction = getSliderAction(event->key());
if (sliderAction != QAbstractSlider::SliderNoAction) {
verticalScrollBar()->triggerAction(sliderAction);
event->accept();
}
}
QAbstractScrollArea::keyPressEvent(event); if (sliderAction != QAbstractSlider::SliderNoAction) {
verticalScrollBar()->triggerAction(sliderAction);
event->accept();
}
}
QAbstractScrollArea::keyPressEvent(event);
} }
void QLiteHtmlWidget::updateHightlightedLink() void QLiteHtmlWidget::updateHightlightedLink()
{ {
QPoint viewportPos; QPoint viewportPos;
QPoint pos; QPoint pos;
htmlPos(mapFromGlobal(QCursor::pos()), &viewportPos, &pos);
setHightlightedLink(d->documentContainer.linkAt(pos, viewportPos)); htmlPos(mapFromGlobal(QCursor::pos()), &viewportPos, &pos);
setHightlightedLink(d->documentContainer.linkAt(pos, viewportPos));
} }
void QLiteHtmlWidget::setHightlightedLink(const QUrl &url) void QLiteHtmlWidget::setHightlightedLink(const QUrl& url)
{ {
if (d->lastHighlightedLink == url) if (d->lastHighlightedLink == url)
return; return;
d->lastHighlightedLink = url;
emit linkHighlighted(d->lastHighlightedLink); d->lastHighlightedLink = url;
emit linkHighlighted(d->lastHighlightedLink);
} }
void QLiteHtmlWidget::withFixedTextPosition(const std::function<void()> &action) void QLiteHtmlWidget::withFixedTextPosition(const std::function<void()>& action)
{ {
// remember element to which to scroll after re-rendering // remember element to which to scroll after re-rendering
QPoint viewportPos; QPoint viewportPos;
QPoint pos; QPoint pos;
htmlPos({}, &viewportPos, &pos); // top-left
const int y = d->documentContainer.withFixedElementPosition(pos.y(), action); htmlPos({}, &viewportPos, &pos); // top-left
if (y >= 0) const int y = d->documentContainer.withFixedElementPosition(pos.y(), action);
verticalScrollBar()->setValue(std::min(y, verticalScrollBar()->maximum()));
if (y >= 0)
verticalScrollBar()->setValue(std::min(y, verticalScrollBar()->maximum()));
} }
void QLiteHtmlWidget::render() void QLiteHtmlWidget::render()
{ {
if (!d->documentContainer.hasDocument()) if (!d->documentContainer.hasDocument())
return; return;
const int fullWidth = width() / d->zoomFactor;
const QSize vViewportSize = toVirtual(viewport()->size()); const int fullWidth = width() / d->zoomFactor;
const int scrollbarWidth = style()->pixelMetric(QStyle::PM_ScrollBarExtent, nullptr, this); const QSize vViewportSize = toVirtual(viewport()->size());
const int w = fullWidth - scrollbarWidth - 2; const int scrollbarWidth = style()->pixelMetric(QStyle::PM_ScrollBarExtent, nullptr, this);
d->documentContainer.render(w, vViewportSize.height()); const int w = fullWidth - scrollbarWidth - 2;
// scroll bars reflect virtual/scaled size of html document
horizontalScrollBar()->setPageStep(vViewportSize.width()); d->documentContainer.render(w, vViewportSize.height());
horizontalScrollBar()->setRange(0, std::max(0, d->documentContainer.documentWidth() - w));
verticalScrollBar()->setPageStep(vViewportSize.height()); // scroll bars reflect virtual/scaled size of html document
verticalScrollBar() horizontalScrollBar()->setPageStep(vViewportSize.width());
->setRange(0, std::max(0, d->documentContainer.documentHeight() - vViewportSize.height())); horizontalScrollBar()->setRange(0, std::max(0, d->documentContainer.documentWidth() - w));
viewport()->update(); verticalScrollBar()->setPageStep(vViewportSize.height());
verticalScrollBar()
->setRange(0, std::max(0, d->documentContainer.documentHeight() - vViewportSize.height()));
viewport()->update();
} }
QPoint QLiteHtmlWidget::scrollPosition() const QPoint QLiteHtmlWidget::scrollPosition() const
{ {
return {horizontalScrollBar()->value(), verticalScrollBar()->value()}; return { horizontalScrollBar()->value(), verticalScrollBar()->value() };
} }
void QLiteHtmlWidget::htmlPos(const QPoint &pos, QPoint *viewportPos, QPoint *htmlPos) const void QLiteHtmlWidget::htmlPos(const QPoint& pos, QPoint* viewportPos, QPoint* htmlPos) const
{ {
*viewportPos = toVirtual(viewport()->mapFromParent(pos)); *viewportPos = toVirtual(viewport()->mapFromParent(pos));
*htmlPos = *viewportPos + scrollPosition(); *htmlPos = *viewportPos + scrollPosition();
} }
QPoint QLiteHtmlWidget::toVirtual(const QPoint &p) const QPoint QLiteHtmlWidget::toVirtual(const QPoint& p) const
{ {
return {int(p.x() / d->zoomFactor), int(p.y() / d->zoomFactor)}; return { int(p.x() / d->zoomFactor), int(p.y() / d->zoomFactor) };
} }
QSize QLiteHtmlWidget::toVirtual(const QSize &s) const QSize QLiteHtmlWidget::toVirtual(const QSize& s) const
{ {
return {int(s.width() / d->zoomFactor), int(s.height() / d->zoomFactor)}; return { int(s.width() / d->zoomFactor), int(s.height() / d->zoomFactor) };
} }
QRect QLiteHtmlWidget::toVirtual(const QRect &r) const QRect QLiteHtmlWidget::toVirtual(const QRect& r) const
{ {
return {toVirtual(r.topLeft()), toVirtual(r.size())}; return { toVirtual(r.topLeft()), toVirtual(r.size()) };
} }
QRect QLiteHtmlWidget::fromVirtual(const QRect &r) const QRect QLiteHtmlWidget::fromVirtual(const QRect& r) const
{ {
const QPoint tl{int(r.x() * d->zoomFactor), int(r.y() * d->zoomFactor)}; const QPoint tl{ int(r.x() * d->zoomFactor), int(r.y() * d->zoomFactor) };
// round size up, and add one since the topleft point was rounded down
const QSize s{int(r.width() * d->zoomFactor + 0.5) + 1, // round size up, and add one since the topleft point was rounded down
int(r.height() * d->zoomFactor + 0.5) + 1}; const QSize s{ int(r.width() * d->zoomFactor + 0.5) + 1,
return {tl, s}; int(r.height() * d->zoomFactor + 0.5) + 1 };
return { tl, s };
} }

View File

@ -44,7 +44,7 @@ WebBrowser::WebBrowser(WebViewer* viewer, QWidget* parent) : TabContent(parent),
this)) { this)) {
if (m_webView == nullptr) { if (m_webView == nullptr) {
#if !defined(USE_WEBENGINE) #if !defined(USE_WEBENGINE)
m_webView = new LiteHtmlViewer(this), m_webView = new LiteHtmlViewer(this);
#else #else
if (qApp->forcedNoWebEngine()) { if (qApp->forcedNoWebEngine()) {
m_webView = new LiteHtmlViewer(this); m_webView = new LiteHtmlViewer(this);