$NetBSD: patch-src_assistant_qlitehtml_src_container__qpainter.cpp,v 1.1 2024/02/10 11:03:39 wiz Exp $ From 7071977bd53c0e5f0bc5efba55505bb898ce8136 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 19 May 2023 14:53:21 +0200 Subject: [PATCH] Update litehtml to v0.9 - lots of smaller changes needed to be adapted to, like std::string instead of litehtml::tstring, std::list for child elements, and other mostly mechanical changes - element::is_visible vanished, and we don't get to the render items, so replaced that with our own version. render_item::is_visible would also take m_skip into account, so this might be wrong for some elements. (only relevant for the search index) - element::get_element_by_point was removed, replace by own depth-first iteration deepest_child_at_point. That takes a lot less properties into consideration compared to get_element_by_point, like z-order, no fixed position elements, etc Task-number: QTCREATORBUG-29169 Task-number: QTBUG-118990 Fixes: QTBUG-121861 Change-Id: I7264a8407f123f44ba47e47cecc57fbf31a85a3d Reviewed-by: Jarek Kobus Reviewed-by: Kai Köhne --- --- src/assistant/qlitehtml/src/container_qpainter.cpp.orig 2023-11-20 11:56:10.000000000 +0000 +++ src/assistant/qlitehtml/src/container_qpainter.cpp @@ -48,9 +48,16 @@ static QRect toQRect(litehtml::position return {position.x, position.y, position.width, position.height}; } -static litehtml::elements_vector path(const litehtml::element::ptr &element) +static bool isVisible(const litehtml::element::ptr &element) { - litehtml::elements_vector result; + // TODO render_item::is_visible() would also take m_skip into account, so this might be wrong + return element->css().get_display() != litehtml::display_none + && element->css().get_visibility() == litehtml::visibility_visible; +} + +static litehtml::elements_list path(const litehtml::element::ptr &element) +{ + litehtml::elements_list result; litehtml::element::ptr current = element; while (current) { result.push_back(current); @@ -60,17 +67,23 @@ static litehtml::elements_vector path(co return result; } -static std::pair getCommonParent(const litehtml::elements_vector &a, - const litehtml::elements_vector &b) +// +static std::tuple +getCommonParent(const litehtml::elements_list &a, const litehtml::elements_list &b) { litehtml::element::ptr parent; - const size_t minSize = std::min(a.size(), b.size()); - for (size_t i = 0; i < minSize; ++i) { - if (a.at(i) != b.at(i)) - return {parent, i}; - parent = a.at(i); - } - return {parent, minSize}; + auto ait = a.cbegin(); + auto bit = b.cbegin(); + while (ait != a.cend() && bit != b.cend()) { + if (*ait != *bit) + return {parent, *ait, *bit}; + parent = *ait; + ++ait; + ++bit; + } + return {parent, + (ait != a.cend() ? *ait : litehtml::element::ptr()), + (bit != b.cend() ? *bit : litehtml::element::ptr())}; } static std::pair getStartAndEnd(const Selection::Element &a, @@ -81,11 +94,12 @@ static std::pairget_children_count()); ++i) { - const litehtml::element::ptr child = commonParent->get_child(i); + for (const litehtml::element::ptr &child : commonParent->children()) { if (child == aBranch) return {a, b}; if (child == bBranch) @@ -108,14 +119,6 @@ static std::pairget_children_count()); ++i) - if (parent->get_child(i) == child) - return i; - return -1; -} - // 1) stops right away if element == stop, otherwise stops whenever stop element is encountered // 2) moves down the first children from element until there is none anymore static litehtml::element::ptr firstLeaf(const litehtml::element::ptr &element, @@ -124,8 +127,8 @@ static litehtml::element::ptr firstLeaf( if (element == stop) return element; litehtml::element::ptr current = element; - while (current != stop && current->get_children_count() > 0) - current = current->get_child(0); + while (current != stop && !current->children().empty()) + current = current->children().front(); return current; } @@ -138,17 +141,23 @@ static litehtml::element::ptr nextLeaf(c if (element == stop) return element; litehtml::element::ptr current = element; - if (current->have_parent()) { + if (!current->is_root()) { // find next sibling const litehtml::element::ptr parent = current->parent(); - const int childIndex = findChild(current, parent); - if (childIndex < 0) { + const litehtml::elements_list &children = parent->children(); + auto childIt = std::find_if(children.cbegin(), + children.cend(), + [¤t](const litehtml::element::ptr &e) { + return e == current; + }); + if (childIt == children.cend()) { qWarning() << "internal error: filed to find litehtml child element in parent"; return stop; } - if (childIndex + 1 >= int(parent->get_children_count())) // no sibling, move up + ++childIt; + if (childIt == children.cend()) // no sibling, move up return nextLeaf(parent, stop); - current = parent->get_child(childIndex + 1); + current = *childIt; } return firstLeaf(current, stop); } @@ -158,9 +167,9 @@ static Selection::Element selectionDetai const QPoint &pos) { // shortcut, which _might_ not really be correct - if (element->get_children_count() > 0) + if (!element->children().empty()) return {element, -1, -1}; // everything selected - const QFont &font = toQFont(element->get_font()); + const QFont &font = toQFont(element->css().get_font()); const QFontMetrics fm(font); int previous = 0; for (int i = 0; i < text.size(); ++i) { @@ -172,48 +181,63 @@ static Selection::Element selectionDetai return {element, int(text.size()), previous}; } -static Selection::Element deepest_child_at_point(const litehtml::document::ptr &document, - const QPoint &pos, - const QPoint &viewportPos, - Selection::Mode mode) +// Returns whether the intended child was found and stop. +// Does a depth-first iteration over elements that "pos" is inside, and executes +// \a action with them. If \a action returns \c true, the iteration is stopped. +static bool deepest_child_at_point(const litehtml::element::ptr &element, + const QPoint &pos, + const QPoint &viewportPos, + const std::function &action, + int level = 0) { - if (!document) - return {}; - - // the following does not find the "smallest" element, it often consists of children - // with individual words as text... - const litehtml::element::ptr element = document->root()->get_element_by_point(pos.x(), - pos.y(), - viewportPos.x(), - viewportPos.y()); - // ...so try to find a better match - const std::function recursion = - [&recursion, pos, mode](const litehtml::element::ptr &element, - const QRect &placement) -> Selection::Element { - if (!element) - return {}; - Selection::Element result; - for (int i = 0; i < int(element->get_children_count()); ++i) { - const litehtml::element::ptr child = element->get_child(i); - result = recursion(child, - toQRect(child->get_position()).translated(placement.topLeft())); - if (result.element) - return result; - } - if (placement.contains(pos)) { - litehtml::tstring text; - element->get_text(text); - if (!text.empty()) { - return mode == Selection::Mode::Free - ? selectionDetails(element, - QString::fromStdString(text), - pos - placement.topLeft()) - : Selection::Element({element, -1, -1}); - } - } - return {}; - }; - return recursion(element, element ? toQRect(element->get_placement()) : QRect()); + // TODO are there elements for which we should take viewportPos into account instead? + // E.g. fixed position elements? + if (!element) + return false /*continue iterating*/; + const QRect placement = toQRect(element->get_placement()); + // Do not continue down elements that do not cover the position. Exceptions: + // - elements with 0 size (includes anchors and other weird elements) + // - html and body, which for some reason have size == viewport size + if (!placement.size().isEmpty() && element->tag() != litehtml::_html_ + && element->tag() != litehtml::_body_ && !placement.contains(pos)) { + return false /*continue iterating*/; + } + // qDebug() << qPrintable(QString(level * 2, ' ')) << element->dump_get_name() << placement << pos; + + const litehtml::elements_list &children = element->children(); + for (auto it = children.cbegin(); it != children.cend(); ++it) { + if (deepest_child_at_point(*it, pos, viewportPos, action, level + 1)) + return true; + } + if (placement.contains(pos)) + return action(element); + return false /*continue iterating*/; +} + +static Selection::Element selection_element_at_point(const litehtml::element::ptr &element, + const QPoint &pos, + const QPoint &viewportPos, + Selection::Mode mode) +{ + Selection::Element result; + deepest_child_at_point(element, + pos, + viewportPos, + [mode, &result, &pos](const litehtml::element::ptr &element) { + const QRect placement = toQRect(element->get_placement()); + std::string text; + element->get_text(text); + if (!text.empty()) { + result = mode == Selection::Mode::Free + ? selectionDetails(element, + QString::fromStdString(text), + pos - placement.topLeft()) + : Selection::Element({element, -1, -1}); + return true; + } + return false; /*continue*/ + }); + return result; } // CSS: 400 == normal, 700 == bold. @@ -235,9 +259,9 @@ static QFont::Weight cssWeightToQtWeight static QFont::Style toQFontStyle(litehtml::font_style style) { switch (style) { - case litehtml::fontStyleNormal: + case litehtml::font_style_normal: return QFont::StyleNormal; - case litehtml::fontStyleItalic: + case litehtml::font_style_italic: return QFont::StyleItalic; } // should not happen @@ -355,7 +379,7 @@ void Selection::update() { const auto addElement = [this](const Selection::Element &element, const Selection::Element &end = {}) { - litehtml::tstring elemText; + std::string elemText; element.element->get_text(elemText); const QString textStr = QString::fromStdString(elemText); if (!textStr.isEmpty()) { @@ -429,7 +453,7 @@ DocumentContainer::DocumentContainer() DocumentContainer::~DocumentContainer() = default; -litehtml::uint_ptr DocumentContainerPrivate::create_font(const litehtml::tchar_t *faceName, +litehtml::uint_ptr DocumentContainerPrivate::create_font(const char *faceName, int size, int weight, litehtml::font_style italic, @@ -485,14 +509,14 @@ void DocumentContainerPrivate::delete_fo delete font; } -int DocumentContainerPrivate::text_width(const litehtml::tchar_t *text, litehtml::uint_ptr hFont) +int DocumentContainerPrivate::text_width(const char *text, litehtml::uint_ptr hFont) { const QFontMetrics fm(toQFont(hFont)); return fm.horizontalAdvance(QString::fromUtf8(text)); } void DocumentContainerPrivate::draw_text(litehtml::uint_ptr hdc, - const litehtml::tchar_t *text, + const char *text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position &pos) @@ -514,7 +538,7 @@ int DocumentContainerPrivate::get_defaul return m_defaultFont.pointSize(); } -const litehtml::tchar_t *DocumentContainerPrivate::get_default_font_name() const +const char *DocumentContainerPrivate::get_default_font_name() const { return m_defaultFontFamilyName.constData(); } @@ -551,9 +575,7 @@ void DocumentContainerPrivate::draw_list } } -void DocumentContainerPrivate::load_image(const litehtml::tchar_t *src, - const litehtml::tchar_t *baseurl, - bool redraw_on_ready) +void DocumentContainerPrivate::load_image(const char *src, const char *baseurl, bool redraw_on_ready) { const auto qtSrc = QString::fromUtf8(src); const auto qtBaseUrl = QString::fromUtf8(baseurl); @@ -569,8 +591,8 @@ void DocumentContainerPrivate::load_imag m_pixmaps.insert(url, pixmap); } -void DocumentContainerPrivate::get_image_size(const litehtml::tchar_t *src, - const litehtml::tchar_t *baseurl, +void DocumentContainerPrivate::get_image_size(const char *src, + const char *baseurl, litehtml::size &sz) { const auto qtSrc = QString::fromUtf8(src); @@ -617,8 +639,8 @@ void DocumentContainerPrivate::buildInde m_index.elementToIndex.insert({current, index}); if (!inBody) inBody = tagName(current).toLower() == "body"; - if (inBody && current->is_visible()) { - litehtml::tstring text; + if (inBody && isVisible(current)) { + std::string text; current->get_text(text); if (!text.empty()) { m_index.indexToElement.push_back({index, current}); @@ -657,84 +679,89 @@ void DocumentContainerPrivate::clearSele } void DocumentContainerPrivate::draw_background(litehtml::uint_ptr hdc, - const litehtml::background_paint &bg) + const std::vector &bgs) { auto painter = toQPainter(hdc); - if (bg.is_root) { - // TODO ? - return; - } painter->save(); - painter->setClipRect(toQRect(bg.clip_box)); - const QRegion horizontalMiddle( - QRect(bg.border_box.x, - bg.border_box.y + bg.border_radius.top_left_y, - bg.border_box.width, - bg.border_box.height - bg.border_radius.top_left_y - bg.border_radius.bottom_left_y)); - const QRegion horizontalTop( - QRect(bg.border_box.x + bg.border_radius.top_left_x, - bg.border_box.y, - bg.border_box.width - bg.border_radius.top_left_x - bg.border_radius.top_right_x, - bg.border_radius.top_left_y)); - const QRegion horizontalBottom(QRect(bg.border_box.x + bg.border_radius.bottom_left_x, - bg.border_box.bottom() - bg.border_radius.bottom_left_y, - bg.border_box.width - bg.border_radius.bottom_left_x - - bg.border_radius.bottom_right_x, - bg.border_radius.bottom_left_y)); - const QRegion topLeft(QRect(bg.border_box.left(), - bg.border_box.top(), - 2 * bg.border_radius.top_left_x, - 2 * bg.border_radius.top_left_y), - QRegion::Ellipse); - const QRegion topRight(QRect(bg.border_box.right() - 2 * bg.border_radius.top_right_x, - bg.border_box.top(), - 2 * bg.border_radius.top_right_x, - 2 * bg.border_radius.top_right_y), - QRegion::Ellipse); - const QRegion bottomLeft(QRect(bg.border_box.left(), - bg.border_box.bottom() - 2 * bg.border_radius.bottom_left_y, - 2 * bg.border_radius.bottom_left_x, - 2 * bg.border_radius.bottom_left_y), - QRegion::Ellipse); - const QRegion bottomRight(QRect(bg.border_box.right() - 2 * bg.border_radius.bottom_right_x, - bg.border_box.bottom() - 2 * bg.border_radius.bottom_right_y, - 2 * bg.border_radius.bottom_right_x, - 2 * bg.border_radius.bottom_right_y), + for (const litehtml::background_paint &bg : bgs) { + if (bg.is_root) { + // TODO ? + break; + } + painter->setClipRect(toQRect(bg.clip_box)); + const QRegion horizontalMiddle(QRect(bg.border_box.x, + bg.border_box.y + bg.border_radius.top_left_y, + bg.border_box.width, + bg.border_box.height - bg.border_radius.top_left_y + - bg.border_radius.bottom_left_y)); + const QRegion horizontalTop( + QRect(bg.border_box.x + bg.border_radius.top_left_x, + bg.border_box.y, + bg.border_box.width - bg.border_radius.top_left_x - bg.border_radius.top_right_x, + bg.border_radius.top_left_y)); + const QRegion horizontalBottom(QRect(bg.border_box.x + bg.border_radius.bottom_left_x, + bg.border_box.bottom() - bg.border_radius.bottom_left_y, + bg.border_box.width - bg.border_radius.bottom_left_x + - bg.border_radius.bottom_right_x, + bg.border_radius.bottom_left_y)); + const QRegion topLeft(QRect(bg.border_box.left(), + bg.border_box.top(), + 2 * bg.border_radius.top_left_x, + 2 * bg.border_radius.top_left_y), QRegion::Ellipse); - const QRegion clipRegion = horizontalMiddle.united(horizontalTop) - .united(horizontalBottom) - .united(topLeft) - .united(topRight) - .united(bottomLeft) - .united(bottomRight); - painter->setClipRegion(clipRegion, Qt::IntersectClip); - painter->setPen(Qt::NoPen); - painter->setBrush(toQColor(bg.color)); - painter->drawRect(bg.border_box.x, bg.border_box.y, bg.border_box.width, bg.border_box.height); - drawSelection(painter, toQRect(bg.border_box)); - if (!bg.image.empty()) { - const QPixmap pixmap = getPixmap(QString::fromStdString(bg.image), - QString::fromStdString(bg.baseurl)); - if (bg.repeat == litehtml::background_repeat_no_repeat) { - painter->drawPixmap(QRect(bg.position_x, - bg.position_y, - bg.image_size.width, - bg.image_size.height), - pixmap); - } else if (bg.repeat == litehtml::background_repeat_repeat_x) { - if (bg.image_size.width > 0) { - int x = bg.border_box.left(); - while (x <= bg.border_box.right()) { - painter->drawPixmap(QRect(x, - bg.border_box.top(), - bg.image_size.width, - bg.image_size.height), - pixmap); - x += bg.image_size.width; + const QRegion topRight(QRect(bg.border_box.right() - 2 * bg.border_radius.top_right_x, + bg.border_box.top(), + 2 * bg.border_radius.top_right_x, + 2 * bg.border_radius.top_right_y), + QRegion::Ellipse); + const QRegion bottomLeft(QRect(bg.border_box.left(), + bg.border_box.bottom() - 2 * bg.border_radius.bottom_left_y, + 2 * bg.border_radius.bottom_left_x, + 2 * bg.border_radius.bottom_left_y), + QRegion::Ellipse); + const QRegion bottomRight(QRect(bg.border_box.right() - 2 * bg.border_radius.bottom_right_x, + bg.border_box.bottom() - 2 * bg.border_radius.bottom_right_y, + 2 * bg.border_radius.bottom_right_x, + 2 * bg.border_radius.bottom_right_y), + QRegion::Ellipse); + const QRegion clipRegion = horizontalMiddle.united(horizontalTop) + .united(horizontalBottom) + .united(topLeft) + .united(topRight) + .united(bottomLeft) + .united(bottomRight); + painter->setClipRegion(clipRegion, Qt::IntersectClip); + painter->setPen(Qt::NoPen); + painter->setBrush(toQColor(bg.color)); + painter->drawRect(bg.border_box.x, + bg.border_box.y, + bg.border_box.width, + bg.border_box.height); + drawSelection(painter, toQRect(bg.border_box)); + if (!bg.image.empty()) { + const QPixmap pixmap = getPixmap(QString::fromStdString(bg.image), + QString::fromStdString(bg.baseurl)); + if (bg.repeat == litehtml::background_repeat_no_repeat) { + painter->drawPixmap(QRect(bg.position_x, + bg.position_y, + bg.image_size.width, + bg.image_size.height), + pixmap); + } else if (bg.repeat == litehtml::background_repeat_repeat_x) { + if (bg.image_size.width > 0) { + int x = bg.border_box.left(); + while (x <= bg.border_box.right()) { + painter->drawPixmap(QRect(x, + bg.border_box.top(), + bg.image_size.width, + bg.image_size.height), + pixmap); + x += bg.image_size.width; + } } + } else { + qWarning(log) << "unsupported background repeat" << bg.repeat; } - } else { - qWarning(log) << "unsupported background repeat" << bg.repeat; } } painter->restore(); @@ -806,12 +833,12 @@ void DocumentContainerPrivate::draw_bord } } -void DocumentContainerPrivate::set_caption(const litehtml::tchar_t *caption) +void DocumentContainerPrivate::set_caption(const char *caption) { m_caption = QString::fromUtf8(caption); } -void DocumentContainerPrivate::set_base_url(const litehtml::tchar_t *base_url) +void DocumentContainerPrivate::set_base_url(const char *base_url) { m_baseUrl = QString::fromUtf8(base_url); } @@ -825,20 +852,19 @@ void DocumentContainerPrivate::link(cons Q_UNUSED(el) } -void DocumentContainerPrivate::on_anchor_click(const litehtml::tchar_t *url, - const litehtml::element::ptr &el) +void DocumentContainerPrivate::on_anchor_click(const char *url, const litehtml::element::ptr &el) { Q_UNUSED(el) if (!m_blockLinks) m_linkCallback(resolveUrl(QString::fromUtf8(url), m_baseUrl)); } -void DocumentContainerPrivate::set_cursor(const litehtml::tchar_t *cursor) +void DocumentContainerPrivate::set_cursor(const char *cursor) { m_cursorCallback(toQCursor(QString::fromUtf8(cursor))); } -void DocumentContainerPrivate::transform_text(litehtml::tstring &text, litehtml::text_transform tt) +void DocumentContainerPrivate::transform_text(std::string &text, litehtml::text_transform tt) { // TODO qDebug(log) << "transform_text"; @@ -846,9 +872,9 @@ void DocumentContainerPrivate::transform Q_UNUSED(tt) } -void DocumentContainerPrivate::import_css(litehtml::tstring &text, - const litehtml::tstring &url, - litehtml::tstring &baseurl) +void DocumentContainerPrivate::import_css(std::string &text, + const std::string &url, + std::string &baseurl) { const QUrl actualUrl = resolveUrl(QString::fromStdString(url), QString::fromStdString(baseurl)); const QString urlString = actualUrl.toString(QUrl::None); @@ -858,16 +884,12 @@ void DocumentContainerPrivate::import_cs } void DocumentContainerPrivate::set_clip(const litehtml::position &pos, - const litehtml::border_radiuses &bdr_radius, - bool valid_x, - bool valid_y) + const litehtml::border_radiuses &bdr_radius) { // TODO qDebug(log) << "set_clip"; Q_UNUSED(pos) Q_UNUSED(bdr_radius) - Q_UNUSED(valid_x) - Q_UNUSED(valid_y) } void DocumentContainerPrivate::del_clip() @@ -882,7 +904,7 @@ void DocumentContainerPrivate::get_clien } std::shared_ptr DocumentContainerPrivate::create_element( - const litehtml::tchar_t *tag_name, + const char *tag_name, const litehtml::string_map &attributes, const std::shared_ptr &doc) { @@ -900,7 +922,7 @@ void DocumentContainerPrivate::get_media qDebug(log) << "get_media_features"; } -void DocumentContainerPrivate::get_language(litehtml::tstring &language, litehtml::tstring &culture) const +void DocumentContainerPrivate::get_language(std::string &language, std::string &culture) const { // TODO qDebug(log) << "get_language"; @@ -922,7 +944,9 @@ void DocumentContainer::setDocument(cons { d->m_pixmaps.clear(); d->clearSelection(); - d->m_document = litehtml::document::createFromUTF8(data.constData(), d.get(), &context->d->context); + d->m_document = litehtml::document::createFromString(data.constData(), + d.get(), + context->d->masterCss.toUtf8().constData()); d->buildIndex(); } @@ -987,10 +1011,10 @@ QVector DocumentContainer::mouseP redrawRects.append(d->m_selection.boundingRect()); d->clearSelection(); d->m_selection.selectionStartDocumentPos = documentPos; - d->m_selection.startElem = deepest_child_at_point(d->m_document, - documentPos, - viewportPos, - d->m_selection.mode); + d->m_selection.startElem = selection_element_at_point(d->m_document->root(), + documentPos, + viewportPos, + d->m_selection.mode); // post to litehtml litehtml::position::vector redrawBoxes; if (d->m_document->on_lbutton_down( @@ -1012,10 +1036,10 @@ QVector DocumentContainer::mouseM || (!d->m_selection.selectionStartDocumentPos.isNull() && (d->m_selection.selectionStartDocumentPos - documentPos).manhattanLength() >= kDragDistance && d->m_selection.startElem.element)) { - const Selection::Element element = deepest_child_at_point(d->m_document, - documentPos, - viewportPos, - d->m_selection.mode); + const Selection::Element element = selection_element_at_point(d->m_document->root(), + documentPos, + viewportPos, + d->m_selection.mode); if (element.element) { redrawRects.append( d->m_selection.boundingRect() /*.adjusted(-1, -1, +1, +1)*/); // redraw old selection area @@ -1067,10 +1091,10 @@ QVector DocumentContainer::mouseD QVector redrawRects; d->clearSelection(); d->m_selection.mode = Selection::Mode::Word; - const Selection::Element element = deepest_child_at_point(d->m_document, - documentPos, - viewportPos, - d->m_selection.mode); + const Selection::Element element = selection_element_at_point(d->m_document->root(), + documentPos, + viewportPos, + d->m_selection.mode); if (element.element) { d->m_selection.startElem = element; d->m_selection.endElem = d->m_selection.startElem; @@ -1104,11 +1128,19 @@ QUrl DocumentContainer::linkAt(const QPo { if (!d->m_document) return {}; - const litehtml::element::ptr element = d->m_document->root()->get_element_by_point( - documentPos.x(), documentPos.y(), viewportPos.x(), viewportPos.y()); - if (!element) - return {}; - const char *href = element->get_attr("href"); + const char *href = nullptr; + deepest_child_at_point(d->m_document->root(), + documentPos, + viewportPos, + [&href](const litehtml::element::ptr &e) { + const litehtml::element::ptr parent = e->parent(); + if (parent && parent->tag() == litehtml::_a_) { + href = parent->get_attr("href"); + if (href) + return true; + } + return false; /*continue*/ + }); if (href) return d->resolveUrl(QString::fromUtf8(href), d->m_baseUrl); return {}; @@ -1171,10 +1203,10 @@ void DocumentContainer::findText(const Q } const auto fillXPos = [](const Selection::Element &e) { - litehtml::tstring ttext; + std::string ttext; e.element->get_text(ttext); const QString text = QString::fromStdString(ttext); - const QFont &font = toQFont(e.element->get_font()); + const QFont &font = toQFont(e.element->css().get_font()); const QFontMetrics fm(font); return Selection::Element{e.element, e.index, fm.size(0, text.left(e.index)).width()}; }; @@ -1226,7 +1258,7 @@ void DocumentContainer::setDefaultFont(c // we need to trigger the reparse of this info. if (d->m_document && d->m_document->root()) { d->m_document->root()->refresh_styles(); - d->m_document->root()->parse_styles(); + d->m_document->root()->compute_styles(); } } @@ -1260,27 +1292,26 @@ void DocumentContainer::setClipboardCall d->m_clipboardCallback = callback; } +static litehtml::element::ptr elementForY(int y, const litehtml::element::ptr &element) +{ + if (!element) + return {}; + if (element->get_placement().y >= y) + return element; + for (const litehtml::element::ptr &child : element->children()) { + litehtml::element::ptr result = elementForY(y, child); + if (result) + return result; + } + return {}; +} + static litehtml::element::ptr elementForY(int y, const litehtml::document::ptr &document) { if (!document) return {}; - const std::function recursion = - [&recursion](int y, const litehtml::element::ptr &element) { - litehtml::element::ptr result; - const int subY = y - element->get_position().y; - if (subY <= 0) - return element; - for (int i = 0; i < int(element->get_children_count()); ++i) { - const litehtml::element::ptr child = element->get_child(i); - result = recursion(subY, child); - if (result) - return result; - } - return result; - }; - - return recursion(y, document->root()); + return elementForY(y, document->root()); } int DocumentContainer::withFixedElementPosition(int y, const std::function &action) @@ -1368,5 +1399,5 @@ DocumentContainerContext::~DocumentConta void DocumentContainerContext::setMasterStyleSheet(const QString &css) { - d->context.load_master_stylesheet(css.toUtf8().constData()); + d->masterCss = css; }