Correct wxHTML IMG ALIGN=CENTER placement

Capture the current text metrics when parsing image cells and use them to
position ALIGN=CENTER images relative to the surrounding text center and
not to the total cell height.

Add a parser regression test for the image and adjacent word vertical
centers.

Fixes #2976.

Closes #26669.
This commit is contained in:
Richard
2026-07-20 20:06:14 +02:00
committed by Vadim Zeitlin
parent 6c85b39586
commit cb77a4e904
2 changed files with 45 additions and 2 deletions
+13 -2
View File
@@ -3,6 +3,7 @@
// Purpose: wxHtml module for displaying images
// Author: Vaclav Slavik
// Copyright: (c) 1999 Vaclav Slavik, Joel Lucsy
// (c) 2026 wxWidgets development team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
@@ -291,6 +292,7 @@ public:
int w = wxDefaultCoord, bool wpercent = false,
int h = wxDefaultCoord, bool hpresent = false,
double scale = 1.0, int align = wxHTML_ALIGN_BOTTOM,
int textHeight = 0, int textDescent = 0,
const wxString& mapname = wxEmptyString);
virtual ~wxHtmlImageCell();
void Draw(wxDC& dc, int x, int y, int view_y1, int view_y2,
@@ -318,6 +320,7 @@ public:
private:
wxBitmap *m_bitmap;
int m_align;
int m_textHeight, m_textDescent;
int m_bmpW, m_bmpH;
bool m_bmpWpercent:1;
bool m_bmpHpresent:1;
@@ -364,6 +367,7 @@ wxHtmlImageCell::wxHtmlImageCell(const wxHtmlTag& tag,
wxHtmlWindowInterface *windowIface,
wxFSFile *input, double scaleHDPI,
int w, bool wpercent, int h, bool hpresent, double scale, int align,
int textHeight, int textDescent,
const wxString& mapname) : wxHtmlCell(tag)
, m_mapName(mapname)
{
@@ -374,6 +378,8 @@ wxHtmlImageCell::wxHtmlImageCell(const wxHtmlTag& tag,
m_bmpW = w;
m_bmpH = h;
m_align = align;
m_textHeight = textHeight;
m_textDescent = textDescent;
m_bmpWpercent = wpercent;
m_bmpHpresent = hpresent;
m_imageMap = nullptr;
@@ -564,7 +570,9 @@ void wxHtmlImageCell::Layout(int w)
m_Descent = m_Height;
break;
case wxHTML_ALIGN_CENTER :
m_Descent = m_Height / 2;
// Center the image vertically with respect to the text and not the
// total cell height.
m_Descent = (m_Height - m_textHeight) / 2 + m_textDescent;
break;
case wxHTML_ALIGN_BOTTOM :
default :
@@ -748,12 +756,15 @@ TAG_HANDLER_BEGIN(IMG, "IMG,MAP,AREA")
mn = mn.Mid( 1 );
}
}
m_WParser->CreateCurrentFont();
const wxFontMetrics fm = m_WParser->GetDC()->GetFontMetrics();
wxHtmlImageCell *cel = new wxHtmlImageCell(
tag,
m_WParser->GetWindowInterface(),
str, scaleHDPI, w, wpercent, h, hpresent,
m_WParser->GetPixelScale(),
al, mn);
al, fm.height, fm.descent, mn);
m_WParser->ApplyStateToCell(cel);
m_WParser->StopCollapsingSpaces();
cel->SetAlt(tag.GetParam(wxT("alt")));
+32
View File
@@ -4,6 +4,7 @@
// Author: Vadim Zeitlin
// Created: 2011-01-13
// Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
// (c) 2026 wxWidgets development team
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
@@ -17,6 +18,7 @@
#ifndef WX_PRECOMP
#include "wx/dcmemory.h"
#include "wx/log.h"
#endif // WX_PRECOMP
#include "wx/html/winpars.h"
@@ -42,6 +44,36 @@ TEST_CASE("wxHtmlParser::ParseInvalid", "[html][parser][error]")
delete p.Parse("<!---");
}
TEST_CASE("wxHtmlParser::ImageAlignCenter", "[html][parser]")
{
wxBitmap bmp(200, 200);
wxMemoryDC dc(bmp);
wxHtmlWinParser p;
p.SetDC(&dc);
wxLogNull noLog;
std::unique_ptr<wxHtmlContainerCell> const cells(
static_cast<wxHtmlContainerCell*>(p.Parse(
R"(<img id="img" width="100" height="100" align="center" src="dummy"/>Text)"
))
);
REQUIRE( cells );
cells->Layout(200);
const wxString id("img");
const wxHtmlCell* const image = cells->Find(wxHTML_COND_ISANCHOR, &id);
REQUIRE( image );
const wxHtmlCell* const word = image->GetNext();
REQUIRE( word );
REQUIRE_FALSE( word->IsFormattingCell() );
CHECK( word->GetPosY() + word->GetHeight() / 2 ==
image->GetPosY() + image->GetHeight() / 2 );
}
TEST_CASE("wxHtmlCell::Detach", "[html][cell]")
{
wxMemoryDC dc;