mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:37:35 +00:00
Painter: Add text elision support (only right-hand side supported.)
Some window titles didn't fit on the taskbar buttons, so I needed a way to collapse the remaining part of the text into "..."
This commit is contained in:
parent
ce7341be87
commit
4533539e8a
5 changed files with 56 additions and 15 deletions
|
@ -160,15 +160,20 @@ bool Font::write_to_file(const String& path)
|
||||||
|
|
||||||
int Font::width(const String& string) const
|
int Font::width(const String& string) const
|
||||||
{
|
{
|
||||||
if (string.is_empty())
|
return width(string.characters(), string.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
int Font::width(const char* characters, int length) const
|
||||||
|
{
|
||||||
|
if (!length)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (m_fixed_width)
|
if (m_fixed_width)
|
||||||
return string.length() * m_glyph_width;
|
return length * m_glyph_width;
|
||||||
|
|
||||||
int width = 0;
|
int width = 0;
|
||||||
for (int i = 0; i < string.length(); ++i)
|
for (int i = 0; i < length; ++i)
|
||||||
width += glyph_width(string[i]) + 1;
|
width += glyph_width(characters[i]) + 1;
|
||||||
|
|
||||||
return width - 1;
|
return width - 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ public:
|
||||||
byte max_glyph_width() const { return m_max_glyph_width; }
|
byte max_glyph_width() const { return m_max_glyph_width; }
|
||||||
byte glyph_spacing() const { return m_fixed_width ? 0 : 1; }
|
byte glyph_spacing() const { return m_fixed_width ? 0 : 1; }
|
||||||
int width(const String& string) const;
|
int width(const String& string) const;
|
||||||
|
int width(const char*, int) const;
|
||||||
|
|
||||||
String name() const { return m_name; }
|
String name() const { return m_name; }
|
||||||
void set_name(const String& name) { m_name = name; }
|
void set_name(const String& name) { m_name = name; }
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <SharedGraphics/CharacterBitmap.h>
|
#include <SharedGraphics/CharacterBitmap.h>
|
||||||
#include <AK/Assertions.h>
|
#include <AK/Assertions.h>
|
||||||
#include <AK/StdLibExtras.h>
|
#include <AK/StdLibExtras.h>
|
||||||
|
#include <AK/StringBuilder.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
Painter::Painter(GraphicsBitmap& bitmap)
|
Painter::Painter(GraphicsBitmap& bitmap)
|
||||||
|
@ -343,8 +344,34 @@ void Painter::draw_scaled_bitmap(const Rect& a_dst_rect, const GraphicsBitmap& s
|
||||||
draw_bitmap(point, font.glyph_bitmap(ch), color);
|
draw_bitmap(point, font.glyph_bitmap(ch), color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::draw_text(const Rect& rect, const char* text, int length, const Font& font, TextAlignment alignment, Color color)
|
void Painter::draw_text(const Rect& rect, const char* text, int length, const Font& font, TextAlignment alignment, Color color, TextElision elision)
|
||||||
{
|
{
|
||||||
|
String elided_text;
|
||||||
|
if (elision == TextElision::Right) {
|
||||||
|
if (font.width(text, length) > rect.width()) {
|
||||||
|
int glyph_spacing = font.glyph_spacing();
|
||||||
|
int new_length = 0;
|
||||||
|
int new_width = font.width("...");
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
int glyph_width = font.glyph_width(text[i]);
|
||||||
|
// NOTE: Glyph spacing should not be added after the last glyph on the line,
|
||||||
|
// but since we are here because the last glyph does not actually fit on the line,
|
||||||
|
// we don't have to worry about spacing.
|
||||||
|
int width_with_this_glyph_included = new_width + glyph_width + glyph_spacing;
|
||||||
|
if (width_with_this_glyph_included > rect.width())
|
||||||
|
break;
|
||||||
|
++new_length;
|
||||||
|
new_width += glyph_width + glyph_spacing;
|
||||||
|
}
|
||||||
|
StringBuilder builder;
|
||||||
|
builder.append(text, new_length);
|
||||||
|
builder.append("...");
|
||||||
|
elided_text = builder.to_string();
|
||||||
|
text = elided_text.characters();
|
||||||
|
length = elided_text.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Point point;
|
Point point;
|
||||||
|
|
||||||
if (alignment == TextAlignment::TopLeft) {
|
if (alignment == TextAlignment::TopLeft) {
|
||||||
|
@ -374,19 +401,19 @@ void Painter::draw_text(const Rect& rect, const char* text, int length, const Fo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::draw_text(const Rect& rect, const String& text, TextAlignment alignment, Color color)
|
void Painter::draw_text(const Rect& rect, const String& text, TextAlignment alignment, Color color, TextElision elision)
|
||||||
{
|
{
|
||||||
draw_text(rect, text.characters(), text.length(), alignment, color);
|
draw_text(rect, text.characters(), text.length(), alignment, color, elision);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::draw_text(const Rect& rect, const String& text, const Font& font, TextAlignment alignment, Color color)
|
void Painter::draw_text(const Rect& rect, const String& text, const Font& font, TextAlignment alignment, Color color, TextElision elision)
|
||||||
{
|
{
|
||||||
draw_text(rect, text.characters(), text.length(), font, alignment, color);
|
draw_text(rect, text.characters(), text.length(), font, alignment, color, elision);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::draw_text(const Rect& rect, const char* text, int length, TextAlignment alignment, Color color)
|
void Painter::draw_text(const Rect& rect, const char* text, int length, TextAlignment alignment, Color color, TextElision elision)
|
||||||
{
|
{
|
||||||
draw_text(rect, text, length, font(), alignment, color);
|
draw_text(rect, text, length, font(), alignment, color, elision);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::set_pixel(const Point& p, Color color)
|
void Painter::set_pixel(const Point& p, Color color)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "Rect.h"
|
#include "Rect.h"
|
||||||
#include "Size.h"
|
#include "Size.h"
|
||||||
#include <SharedGraphics/TextAlignment.h>
|
#include <SharedGraphics/TextAlignment.h>
|
||||||
|
#include <SharedGraphics/TextElision.h>
|
||||||
#include <AK/AKString.h>
|
#include <AK/AKString.h>
|
||||||
|
|
||||||
class CharacterBitmap;
|
class CharacterBitmap;
|
||||||
|
@ -28,10 +29,10 @@ public:
|
||||||
void blit(const Point&, const GraphicsBitmap&, const Rect& src_rect);
|
void blit(const Point&, const GraphicsBitmap&, const Rect& src_rect);
|
||||||
void blit_with_opacity(const Point&, const GraphicsBitmap&, const Rect& src_rect, float opacity);
|
void blit_with_opacity(const Point&, const GraphicsBitmap&, const Rect& src_rect, float opacity);
|
||||||
|
|
||||||
void draw_text(const Rect&, const char* text, int length, const Font&, TextAlignment = TextAlignment::TopLeft, Color = Color::Black);
|
void draw_text(const Rect&, const char* text, int length, const Font&, TextAlignment = TextAlignment::TopLeft, Color = Color::Black, TextElision = TextElision::None);
|
||||||
void draw_text(const Rect&, const char* text, int length, TextAlignment = TextAlignment::TopLeft, Color = Color::Black);
|
void draw_text(const Rect&, const char* text, int length, TextAlignment = TextAlignment::TopLeft, Color = Color::Black, TextElision = TextElision::None);
|
||||||
void draw_text(const Rect&, const String&, const Font&, TextAlignment = TextAlignment::TopLeft, Color = Color::Black);
|
void draw_text(const Rect&, const String&, const Font&, TextAlignment = TextAlignment::TopLeft, Color = Color::Black, TextElision = TextElision::None);
|
||||||
void draw_text(const Rect&, const String&, TextAlignment = TextAlignment::TopLeft, Color = Color::Black);
|
void draw_text(const Rect&, const String&, TextAlignment = TextAlignment::TopLeft, Color = Color::Black, TextElision = TextElision::None);
|
||||||
void draw_glyph(const Point&, char, Color);
|
void draw_glyph(const Point&, char, Color);
|
||||||
void draw_glyph(const Point&, char, const Font&, Color);
|
void draw_glyph(const Point&, char, const Font&, Color);
|
||||||
|
|
||||||
|
|
7
SharedGraphics/TextElision.h
Normal file
7
SharedGraphics/TextElision.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
enum class TextElision {
|
||||||
|
None,
|
||||||
|
Right,
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue