Skip to content

Commit

Permalink
libgui|Font: Rich format colors are acquired from an external object
Browse files Browse the repository at this point in the history
Any object that implements RichFormat::IStyle can determine which
colors to use for the format.
  • Loading branch information
skyjake committed May 23, 2013
1 parent ecf8cee commit 940a044
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 31 deletions.
47 changes: 37 additions & 10 deletions doomsday/libgui/include/de/gui/font.h
Expand Up @@ -39,7 +39,7 @@ namespace de {
*/
class LIBGUI_PUBLIC Font
{
public:
public:
/**
* Rich formatting instructions for a string of text.
*
Expand All @@ -59,10 +59,35 @@ class LIBGUI_PUBLIC Font
*/
class RichFormat
{
public:
/**
* Interface for an object providing style information: fonts and
* colors.
*/
class IStyle
{
public:
typedef Vector4ub Color;

virtual ~IStyle() {}

/**
* Returns a color from the style's palette.
* @param index Color index (see RichFormat::Color).
* @return Color values (RGBA 0...255).
*/
virtual Color richStyleColor(int index) const = 0;
};

public:
RichFormat();
RichFormat(IStyle const &style);
RichFormat(RichFormat const &other);

bool haveStyle() const;
void setStyle(IStyle const &style);
IStyle const &style() const;

/**
* Constructs a RichFormat that specifies no formatting instructions.
*
Expand All @@ -85,17 +110,16 @@ class LIBGUI_PUBLIC Font

enum Weight {
OriginalWeight = -1,
Normal = 0,
Light = 1,
Bold = 2
Normal = 0,
Light = 1,
Bold = 2
};
enum Style {
OriginalStyle = -1,
Regular = 0,
Italic = 1
OriginalStyle = -1,
Regular = 0,
Italic = 1
};
enum Color
{
enum Color {
OriginalColor = -1,
NormalColor = 0,
HighlightColor = 1,
Expand Down Expand Up @@ -133,11 +157,14 @@ class LIBGUI_PUBLIC Font
float sizeFactor() const;
Weight weight() const;
Style style() const;
int color() const;
int colorIndex() const;
IStyle::Color color() const;
bool markIndent() const;
};

private:
IStyle const *_style;

struct FormatRange
{
Rangei range;
Expand Down
81 changes: 60 additions & 21 deletions doomsday/libgui/src/font.cpp
Expand Up @@ -25,13 +25,31 @@

namespace de {

Font::RichFormat::RichFormat()
Font::RichFormat::RichFormat() : _style(0)
{}

Font::RichFormat::RichFormat(IStyle const &style) : _style(&style)
{}

Font::RichFormat::RichFormat(RichFormat const &other)
: _ranges(other._ranges)
: _style(other._style), _ranges(other._ranges)
{}

void Font::RichFormat::setStyle(IStyle const &style)
{
_style = &style;
}

bool Font::RichFormat::haveStyle() const
{
return _style != 0;
}

Font::RichFormat::IStyle const &Font::RichFormat::style() const
{
return *_style;
}

Font::RichFormat Font::RichFormat::fromPlainText(String const &plainText)
{
FormatRange all;
Expand Down Expand Up @@ -174,21 +192,21 @@ String Font::RichFormat::initFromStyledText(String const &styledText)

case '5': // Log section style
format->sizeFactor = 1.f;
format->weight = OriginalWeight;
format->weight = Light;
format->style = Italic;
format->colorIndex = DimmedColor;
format->colorIndex = AccentColor;
break;

case '8': // Bad message style
format->sizeFactor = 1.f;
format->weight = Bold;
format->style = Regular;
format->colorIndex = AccentColor;
format->colorIndex = HighlightColor;
break;

case '9': // Debug message style
format->sizeFactor = .8f;
format->weight = Light;
format->weight = Normal;
format->style = Regular;
format->colorIndex = DimmedColor;
break;
Expand Down Expand Up @@ -272,10 +290,10 @@ void Font::RichFormat::Iterator::next()

bool Font::RichFormat::Iterator::isOriginal() const
{
return (fequal(sizeFactor(), 1.f) &&
weight() == OriginalWeight &&
style() == OriginalStyle &&
color() == OriginalColor);
return (fequal(sizeFactor(), 1.f) &&
weight() == OriginalWeight &&
style() == OriginalStyle &&
colorIndex() == OriginalColor);
}

Rangei Font::RichFormat::Iterator::range() const
Expand All @@ -298,11 +316,21 @@ Font::RichFormat::Style Font::RichFormat::Iterator::style() const
return format._ranges[index].style;
}

int Font::RichFormat::Iterator::color() const
int Font::RichFormat::Iterator::colorIndex() const
{
return format._ranges[index].colorIndex;
}

Font::RichFormat::IStyle::Color Font::RichFormat::Iterator::color() const
{
if(format._style)
{
return format._style->richStyleColor(colorIndex());
}
// Fall back to white.
return Vector4ub(255, 255, 255, 255);
}

bool Font::RichFormat::Iterator::markIndent() const
{
return format._ranges[index].markIndent;
Expand Down Expand Up @@ -415,6 +443,13 @@ Rectanglei Font::measure(String const &textLine, RichFormat const &format) const
String const part = textLine.substr(iter.range());
Rectanglei rect = Rectanglei::fromQRect(metrics.boundingRect(part));

if(rect.height() == 0)
{
// It seems measuring the bounds of a Tab character produce
// strange results (position 100000?).
rect = Rectanglei(0, 0, rect.width(), 0);
}

// Combine to the total bounds.
rect.moveTopLeft(Vector2i(advance, rect.top()));
bounds |= rect;
Expand Down Expand Up @@ -467,39 +502,43 @@ QImage Font::rasterize(String const &textLine,
QColor bgColor(background.x, background.y, background.z, background.w);

QImage img(QSize(bounds.width(),
de::max(duint(d->metrics->height()), bounds.height()) + 1), QImage::Format_ARGB32);
de::max(duint(d->metrics->height()), bounds.height()) + 1),
QImage::Format_ARGB32);
img.fill(bgColor.rgba());

QPainter painter(&img);
painter.setBrush(bgColor);
QPainter painter(&img);
painter.setCompositionMode(QPainter::CompositionMode_Source);

int advance = 0;
RichFormat::Iterator iter(format);
while(iter.hasNext())
{
iter.next();
//painter.drawText(img.rect(), Qt::TextDontClip | Qt::TextSingleLine, textLine);

QFont font = d->font;

if(iter.isOriginal())
{
painter.setPen(fgColor);
painter.setBrush(bgColor);
}
else
{
font = d->alteredFont(iter);

QColor color = fgColor;
if(iter.color() == RichFormat::DimmedColor)
if(iter.colorIndex() != RichFormat::OriginalColor)
{
color.setAlpha(color.alpha() * 2 / 3);
RichFormat::IStyle::Color styleColor = iter.color();
QColor const fg(styleColor.x, styleColor.y, styleColor.z, styleColor.w);
QColor const bg(styleColor.x, styleColor.y, styleColor.z, 0);
painter.setPen(fg);
painter.setBrush(bg);
}
else if(iter.color() != RichFormat::OriginalColor)
else
{
// where to get the color palette?
painter.setPen(fgColor);
painter.setBrush(bgColor);
}
painter.setPen(color);
}
painter.setFont(font);

Expand Down

0 comments on commit 940a044

Please sign in to comment.