Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#113: Fix text measurement #115

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion oxygine/src/DebugActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ namespace oxygine
_text->setText(s.str());


setHeight(_text->getTextRect().size.y + _text->getY() + 3);
setHeight(_text->getTextRect(1.0f).size.y + _text->getY() + 3);
_bg->setSize(getSize());


Expand Down
16 changes: 11 additions & 5 deletions oxygine/src/Font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@

namespace oxygine
{
Font::Font() : _size(0), _baselineDistance(0), _scale(1.0f), _sdf(false), _ignoreOptions(true)
Font::Font() : _size(0), _lineHeight(0), _lineGap(0), _scale(1.0f), _sdf(false), _ignoreOptions(true)
{
}

Font::~Font()
{
}

void Font::init(const char* name, int realSize, int baselineDistance, int lineHeight, bool sdf)
void Font::init(const char* name, int realSize, int lineHeight, int lineGap, bool sdf)
{
setName(name);
_sdf = sdf;
_size = realSize;
_baselineDistance = baselineDistance;
_lineHeight = lineHeight;
_lineGap = lineGap;
}

void Font::addGlyph(const glyph& gl)
Expand Down Expand Up @@ -66,9 +67,14 @@ namespace oxygine
return g;
}

int Font::getBaselineDistance() const
int Font::getLineHeight() const
{
return _baselineDistance;
return _lineHeight;
}

int Font::getLineGap() const
{
return _lineGap;
}

int Font::getSize() const
Expand Down
9 changes: 5 additions & 4 deletions oxygine/src/Font.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,16 @@ namespace oxygine
Font();
~Font();

void init(const char* name, int size, int baselineDistance, int lineHeight, bool sdf = false);
void init(const char* name, int size, int lineHeight, int lineGap, bool sdf = false);

void addGlyph(const glyph& g);
void sortGlyphs() {}

void setScale(float scale) { _scale = scale; }
void setBaselineDistance(int d) { _baselineDistance = d; }

const glyph* getGlyph(int code, const glyphOptions& opt) const;
int getBaselineDistance() const;
int getLineHeight() const;
int getLineGap() const;
int getSize() const;
float getScale() const;
bool isSDF() const;
Expand All @@ -80,6 +80,7 @@ namespace oxygine
bool _sdf;

int _size;
int _baselineDistance;
int _lineHeight;
int _lineGap;
};
}
13 changes: 7 additions & 6 deletions oxygine/src/TextField.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "Serialize.h"

#include "Material.h"
#include "Stage.h"

namespace oxygine
{
Expand Down Expand Up @@ -56,7 +57,7 @@ namespace oxygine

bool TextField::isOn(const Vector2& localPosition, float localScale)
{
Rect r = getTextRect(localScale);
RectF r = getTextRect(localScale);
r.expand(Point(_extendedIsOn, _extendedIsOn), Point(_extendedIsOn, _extendedIsOn));
return r.pointIn(Point((int)localPosition.x, (int)localPosition.y));
}
Expand Down Expand Up @@ -288,15 +289,15 @@ namespace oxygine
return const_cast<TextField*>(this)->getRootNode(_rtscale)->getSymbol(pos);
}

const Rect& TextField::getTextRect(float localScale) const
const RectF& TextField::getTextRect(float localScale) const
{
const_cast<TextField*>(this)->getRootNode(localScale);
return _textRect;
}

bool TextField::getBounds(RectF& r) const
{
r = getTextRect().cast<RectF>();
r = getTextRect(Stage::instance->getScaleX());
return true;
}

Expand All @@ -306,7 +307,6 @@ namespace oxygine
if (!_style.font)
return _root;


float scale = 1.0f;
const Font* font = _style.font->getClosestFont(globalScale, _style.fontSize, scale);

Expand Down Expand Up @@ -334,7 +334,7 @@ namespace oxygine
rd.end();

_root->finalPass(rd);
rd.bounds = (rd.bounds.cast<RectF>() / rd.getScale()).cast<Rect>();
rd.bounds = rd.bounds / rd.getScale();

_textRect = rd.bounds;
}
Expand Down Expand Up @@ -426,7 +426,8 @@ namespace oxygine
stream << " htmlMode";
}

Rect r = const_cast<TextField*>(this)->getTextRect();
RectF r;
const_cast<TextField*>(this)->getBounds(r);
stream << " textRect=(" << r.pos.x << ", " << r.pos.y << ", " << r.size.x << ", " << r.size.y << ")";

stream << "\n" << Actor::dump(options);
Expand Down
4 changes: 2 additions & 2 deletions oxygine/src/TextField.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace oxygine
/**Returns current text style*/
const TextStyle& getStyle() const {return _style;}
/**Returns text bounds*/
const Rect& getTextRect(float localScale = 1.0f) const;
const RectF& getTextRect(float localScale) const;
/**Returns current text*/
const std::string& getText() const { return _text; }
const ResFont* getFont() const;
Expand Down Expand Up @@ -115,7 +115,7 @@ namespace oxygine
TextStyle _style;

text::Node* _root;
Rect _textRect;
RectF _textRect;
float _rtscale;
int _realFontSize;

Expand Down
4 changes: 2 additions & 2 deletions oxygine/src/dev_tools/TexturesInspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ namespace oxygine

text->setBreakLongWords(true);

rect->setSize(text->getTextRect().size.cast<Vector2>() + Vector2(2, 2));
rect->setSize(text->getTextRect(1.0f).size.cast<Vector2>() + Vector2(2, 2));
rect->setY((itemSize.y - rect->getHeight()) / 2.0f);
}

Expand Down Expand Up @@ -97,7 +97,7 @@ namespace oxygine
);


offsetY += text->getTextRect().getBottom() + 5;
offsetY += text->getTextRect(1.0f).getBottom() + 5;

spActor content = new Actor;
content->setX(2);
Expand Down
2 changes: 1 addition & 1 deletion oxygine/src/dev_tools/TreeInspectorLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ namespace oxygine
std::string desc = item->dump(0);

tb->setHtmlText(desc);
Vector2 ts = tb->getTextRect().size.cast<Vector2>();
Vector2 ts = tb->getTextRect(1.0f).size.cast<Vector2>();
if (ts.x < minWidth)
ts.x = minWidth;

Expand Down
2 changes: 1 addition & 1 deletion oxygine/src/res/ResFontBM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ namespace oxygine
gl.sw = width / downsample;
gl.sh = height / downsample;
gl.offset_x = xoffset / downsample;
gl.offset_y = yoffset / downsample - base;
gl.offset_y = yoffset / downsample - lineHeight;
gl.advance_x = xadvance / downsample;
gl.advance_y = 0;

Expand Down
79 changes: 31 additions & 48 deletions oxygine/src/text_utils/Aligner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ namespace oxygine
{
namespace text
{
#define GSCALE 1

Aligner::Aligner(const TextStyle& Style, const Font* font, float gscale, const Vector2& size): width((int)size.x), height((int)size.y), _x(0), _y(0), _lineWidth(0), bounds(0, 0, 0, 0), style(Style), _scale(gscale), _font(font)
Aligner::Aligner(const TextStyle& Style, const Font* font, float scale, const Vector2& size): width((int)size.x), height((int)size.y), _x(0), _y(0), _lineWidth(0), bounds(0, 0, 0, 0), style(Style), _scale(scale), _font(font)
{
//log::messageln("gscale %f, adjScale %f globscale %f, %d %f", gscale, _globalScale, _fontSize, fs);
_line.reserve(50);
_lineSkip = (int)(_font->getBaselineDistance() * style.baselineScale) + style.linesOffset;
_lineSkip = _font->getLineHeight() * style.baselineScale + style.linesOffset;
options = Style.options;
}

Expand All @@ -21,9 +19,9 @@ namespace oxygine

}

int Aligner::_alignX(int rx)
float Aligner::_alignX(float rx)
{
int tx = 0;
float tx = 0;
switch (getStyle().hAlign)
{
case TextStyle::HALIGN_LEFT:
Expand All @@ -40,9 +38,9 @@ namespace oxygine
return tx;
}

int Aligner::_alignY(int ry)
float Aligner::_alignY(float ry)
{
int ty = 0;
float ty = 0;

switch (getStyle().vAlign)
{
Expand All @@ -66,40 +64,29 @@ namespace oxygine
void Aligner::begin()
{
_x = 0;
_y = 0;

width = int(width * _scale);
height = int(height * _scale);
_y = getLineSkip();
_lineWidth = 0;

bounds = Rect(_alignX(0), _alignY(0), 0, 0);
nextLine();
width = width * _scale;
height = height * _scale;

bounds = RectF(_alignX(0), _alignY(0), 0, 0);
}

void Aligner::end()
{
int ry = _y;

if (getStyle().multiline)
{
nextLine();
_y -= getLineSkip();
}
else
{
_alignLine(_line);
}
_alignLine(_line);

bounds.setY(_alignY(ry));
bounds.setHeight(ry);
bounds.setY(_alignY(_y));
bounds.setHeight(_y);
}

int Aligner::getLineWidth() const
float Aligner::getLineWidth() const
{
return _lineWidth;
}

int Aligner::getLineSkip() const
float Aligner::getLineSkip() const
{
return _lineSkip;
}
Expand All @@ -109,14 +96,14 @@ namespace oxygine
if (!ln.empty())
{
//calculate real text width
int rx = 0;
float rx = 0;
for (size_t i = 0; i < ln.size(); ++i)
{
Symbol& s = *ln[i];
rx = std::max(s.x + s.gl.advance_x, rx);
rx = std::fmaxf(s.x + s.gl.advance_x, rx);
}

int tx = _alignX(rx);
float tx = _alignX(rx);

for (size_t i = 0; i < ln.size(); ++i)
{
Expand All @@ -126,16 +113,15 @@ namespace oxygine

_lineWidth = rx;

bounds.setX(std::min(tx, bounds.getX()));
bounds.setWidth(std::max(_lineWidth, bounds.getWidth()));
bounds.setX(std::fminf(tx, bounds.getX()));
bounds.setWidth(std::fmaxf(_lineWidth, bounds.getWidth()));
}
}

void Aligner::_nextLine(line& ln)
{
_y += getLineSkip();
_alignLine(ln);

_y += getLineSkip();

_lineWidth = 0;

Expand All @@ -144,7 +130,7 @@ namespace oxygine

void Aligner::nextLine()
{
//assert(multiline == true); commented, becase even if multiline is false - there are breakLine markers, they could be used anyway
assert(getStyle().multiline);

_nextLine(_line);
_line.clear();
Expand All @@ -170,15 +156,14 @@ namespace oxygine
s.y = _y + s.gl.offset_y;
_x += s.gl.advance_x + getStyle().kerning;

int rx = s.x + s.gl.advance_x;
float rx = s.x + s.gl.advance_x;


_lineWidth = std::max(rx, _lineWidth);
_lineWidth = std::fmaxf(rx, _lineWidth);

//
if (_lineWidth > width && getStyle().multiline && (width > 0) && _line.size() > 1)
if (_lineWidth > width && getStyle().multiline && width > 0 && _line.size() > 1)
{
int lastWordPos = (int)_line.size() - 1;
size_t lastWordPos = _line.size() - 1;
for (; lastWordPos > 0; --lastWordPos)
{
if (_line[lastWordPos]->code == ' ' && _line[lastWordPos - 1]->code != ' ')
Expand All @@ -188,20 +173,18 @@ namespace oxygine
if (!lastWordPos)
{
if (style.breakLongWords)
lastWordPos = (int)_line.size() - 1;
lastWordPos = _line.size() - 1;
else
return 0;
}


int delta = (int)_line.size() - lastWordPos;
size_t delta = _line.size() - lastWordPos;
line leftPart;
leftPart.resize(delta + 1);
leftPart.assign(_line.begin() + lastWordPos, _line.end());
_line.resize(lastWordPos);
nextLine();

//line = leftPart;
nextLine();

for (size_t i = 0; i < leftPart.size(); ++i)
{
Expand All @@ -216,4 +199,4 @@ namespace oxygine
return 0;
}
}
}
}
Loading