Skip to content

Commit

Permalink
Use proper method to shrink text in bubble widget to fix #3432
Browse files Browse the repository at this point in the history
  • Loading branch information
CodingJellyfish committed May 1, 2024
1 parent c9d4473 commit ff18633
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 41 deletions.
80 changes: 56 additions & 24 deletions src/font/font_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,64 @@ namespace LineBreakingRules
// like using "。"instead of a ".", you can add more characters if needed.
// For full list please visit:
// http://webapp.docx4java.org/OnlineDemo/ecma376/WordML/kinsoku.html
bool endSentence(char32_t c)
{
switch (c)
{
case '!':
return true;
case ',':
return true;
case '.':
return true;
case '?':
return true;
case ':':
return true;
case ';':
return true;
// ،
case 1548:
return true;
// ؛
case 1563:
return true;
// ؟
case 1567:
return true;
//
case 65281:
return true;
//
case 65311:
return true;
//
case 65292:
return true;
//
case 65306:
return true;
//
case 65307:
return true;
//
case 65294:
return true;
//
case 12290:
return true;
//
case 12289:
return true;
default:
return false;
}
} // endSentence
//-------------------------------------------------------------------------
bool noStartingLine(char32_t c)
{
if (endSentence(c))
return true;
switch (c)
{
//
Expand Down Expand Up @@ -152,36 +208,12 @@ namespace LineBreakingRules
//
case 12311:
return true;
//
case 65281:
return true;
//
case 65285:
return true;
//
case 65311:
return true;
//
case 65344:
return true;
//
case 65292:
return true;
//
case 65306:
return true;
//
case 65307:
return true;
//
case 65294:
return true;
//
case 12290:
return true;
//
case 12289:
return true;
default:
return false;
}
Expand Down
5 changes: 5 additions & 0 deletions src/font/font_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,5 +153,10 @@ class FontManager : public NoCopy

extern FontManager *font_manager;

namespace LineBreakingRules
{
bool endSentence(char32_t c);
}

#endif
/* EOF */
72 changes: 55 additions & 17 deletions src/guiengine/widgets/bubble_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#include "font/font_manager.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/widgets/bubble_widget.hpp"
#include "online/link_helper.hpp"
#include <algorithm>

#include <GlyphLayout.h>
#include <IGUIStaticText.h>
#include <IGUIElement.h>
#include <IGUIEnvironment.h>
#include <IGUIFont.h>

using namespace irr::core;
using namespace irr::gui;
Expand Down Expand Up @@ -77,8 +80,6 @@ void BubbleWidget::add()

m_element->setTabOrder(m_id);
m_element->setTabStop(true);

m_element->setNotClipped(true);
}

void BubbleWidget::resize()
Expand All @@ -93,9 +94,47 @@ void BubbleWidget::updateForNewSize()
{
IGUIStaticText* irrwidget = static_cast<IGUIStaticText*>(m_element);
// find expanded bubble size
stringw message = getText();
irrwidget->setText(message);
int text_height = irrwidget->getTextHeight();
m_shrinked_text = getText();
irrwidget->setText(m_shrinked_text);

start:
IGUIFont* font = irrwidget->getActiveFont();
int text_height = font->getHeightPerLine();
int max_cluster = -1;
bool has_newline = false;
auto& glyph_layouts = irrwidget->getGlyphLayouts();
for (unsigned i = 0; i < glyph_layouts.size(); i++)
{
const GlyphLayout& glyph = glyph_layouts[i];
if ((glyph.flags & GLF_NEWLINE) != 0)
{
has_newline = true;
text_height += font->getHeightPerLine();
if (text_height > m_shrinked_size.getHeight())
{
if (max_cluster != -1)
continue;
for (unsigned idx = 0; idx < i; idx++)
{
const GlyphLayout& gl = glyph_layouts[idx];
for (int c : gl.cluster)
{
if (c > max_cluster)
max_cluster = c;
}
}
while (max_cluster > 0 && LineBreakingRules::endSentence(
m_shrinked_text[max_cluster - 1]))
max_cluster--;
m_shrinked_text = m_shrinked_text.subString(0, max_cluster) +
L"\u2026";
irrwidget->setText(m_shrinked_text);
}
}
}

irrwidget->setText(getText());
text_height = irrwidget->getTextHeight();

m_expanded_size = m_shrinked_size;
const int additionalNeededSize = std::max(0, text_height - m_shrinked_size.getHeight());
Expand All @@ -104,24 +143,19 @@ void BubbleWidget::updateForNewSize()
{
m_expanded_size.UpperLeftCorner.Y -= additionalNeededSize/2 + 10;
m_expanded_size.LowerRightCorner.Y += additionalNeededSize/2 + 10;

// reduce text to fit in the available space if it's too long
// FIXME : this loop is ugly
while (text_height > m_shrinked_size.getHeight() && message.size() > 10)
{
message = message.subString(0, message.size() - 10) + "...";
irrwidget->setText(message);
text_height = irrwidget->getTextHeight();
}
}
m_shrinked_text = message;
irrwidget->setText(m_shrinked_text);
text_height = irrwidget->getTextHeight();
if (has_newline && text_height > m_shrinked_size.getHeight())
goto start;
}

void BubbleWidget::replaceText()
{
IGUIStaticText* irrwidget = (IGUIStaticText*) m_element;
// Take border into account for line breaking (happens in setText)
irrwidget->setDrawBorder(true);
irrwidget->setNotClipped(true);

EGUI_ALIGNMENT align = EGUIA_UPPERLEFT;
if (m_properties[PROP_TEXT_ALIGN] == "center") align = EGUIA_CENTER;
Expand All @@ -147,6 +181,9 @@ void BubbleWidget::setText(const irr::core::stringw &s)

void BubbleWidget::updateSize()
{
stringw real_text = getText();
if (m_shrinked_text == real_text)
return;
core::rect<s32> currsize = m_shrinked_size;

const int y1_top = m_shrinked_size.UpperLeftCorner.Y;
Expand All @@ -161,10 +198,11 @@ void BubbleWidget::updateSize()

m_element->setRelativePosition(currsize);

IGUIStaticText* irrwidget = static_cast<IGUIStaticText*>(m_element);
if (m_zoom > 0.5f)
getIrrlichtElement<IGUIStaticText>()->setText(getText().c_str());
irrwidget->setText(real_text);
else
getIrrlichtElement<IGUIStaticText>()->setText(m_shrinked_text.c_str());
irrwidget->setText(m_shrinked_text);
}

// ----------------------------------------------------------------------------
Expand Down

0 comments on commit ff18633

Please sign in to comment.