forked from organicmaps/organicmaps
[graphics] Significantly removed memory pressure in StraightTextElement.
This commit is contained in:
parent
3b3c70a9b7
commit
6f28783996
8 changed files with 156 additions and 208 deletions
|
@ -7,23 +7,14 @@
|
|||
|
||||
namespace graphics
|
||||
{
|
||||
GlyphLayout::GlyphLayout()
|
||||
{}
|
||||
|
||||
GlyphLayout::GlyphLayout(GlyphCache * glyphCache,
|
||||
FontDesc const & fontDesc,
|
||||
m2::PointD const & pt,
|
||||
strings::UniString const & visText,
|
||||
graphics::EPosition pos)
|
||||
GlyphLayout::GlyphLayout(FontDesc const & font)
|
||||
: m_firstVisible(0),
|
||||
m_lastVisible(visText.size()),
|
||||
m_fontDesc(fontDesc),
|
||||
m_pivot(pt),
|
||||
m_lastVisible(0),
|
||||
m_fontDesc(font),
|
||||
m_pivot(0, 0),
|
||||
m_offset(0, 0),
|
||||
m_textLength(0),
|
||||
m_textOffset(0)
|
||||
m_textLength(0)
|
||||
{
|
||||
initStraigthText(glyphCache, fontDesc, pt, visText, pos, numeric_limits<unsigned>::max());
|
||||
}
|
||||
|
||||
GlyphLayout::GlyphLayout(GlyphCache * glyphCache,
|
||||
|
@ -37,27 +28,23 @@ namespace graphics
|
|||
m_fontDesc(fontDesc),
|
||||
m_pivot(pt),
|
||||
m_offset(0, 0),
|
||||
m_textLength(0),
|
||||
m_textOffset(0)
|
||||
m_textLength(0)
|
||||
{
|
||||
initStraigthText(glyphCache, fontDesc, pt, visText, pos, maxWidth);
|
||||
}
|
||||
|
||||
GlyphLayout::GlyphLayout(GlyphLayout const & src,
|
||||
math::Matrix<double, 3, 3> const & m)
|
||||
: m_firstVisible(0),
|
||||
m_lastVisible(0),
|
||||
GlyphLayoutPath::GlyphLayoutPath(GlyphLayoutPath const & src,
|
||||
math::Matrix<double, 3, 3> const & m)
|
||||
: GlyphLayout(src.m_fontDesc),
|
||||
m_path(src.m_path, m),
|
||||
m_visText(src.m_visText),
|
||||
m_fontDesc(src.m_fontDesc),
|
||||
m_metrics(src.m_metrics),
|
||||
m_pivot(0, 0),
|
||||
m_offset(0, 0),
|
||||
m_textLength(src.m_textLength)
|
||||
m_visText(src.m_visText)
|
||||
{
|
||||
if (!m_fontDesc.IsValid())
|
||||
return;
|
||||
|
||||
m_metrics = src.m_metrics;
|
||||
m_textLength = src.m_textLength;
|
||||
|
||||
m_boundRects.push_back(m2::AnyRectD(m2::RectD(0, 0, 0, 0)));
|
||||
|
||||
m_textOffset = (m2::PointD(0, src.m_textOffset) * m).Length(m2::PointD(0, 0) * m);
|
||||
|
@ -69,22 +56,17 @@ namespace graphics
|
|||
recalcAlongPath();
|
||||
}
|
||||
|
||||
GlyphLayout::GlyphLayout(GlyphCache * glyphCache,
|
||||
FontDesc const & fontDesc,
|
||||
m2::PointD const * pts,
|
||||
size_t ptsCount,
|
||||
strings::UniString const & visText,
|
||||
double fullLength,
|
||||
double pathOffset,
|
||||
double textOffset)
|
||||
: m_firstVisible(0),
|
||||
m_lastVisible(0),
|
||||
GlyphLayoutPath::GlyphLayoutPath(GlyphCache * glyphCache,
|
||||
FontDesc const & fontDesc,
|
||||
m2::PointD const * pts,
|
||||
size_t ptsCount,
|
||||
strings::UniString const & visText,
|
||||
double fullLength,
|
||||
double pathOffset,
|
||||
double textOffset)
|
||||
: GlyphLayout(fontDesc),
|
||||
m_path(pts, ptsCount, fullLength, pathOffset),
|
||||
m_visText(visText),
|
||||
m_fontDesc(fontDesc),
|
||||
m_pivot(0, 0),
|
||||
m_offset(0, 0),
|
||||
m_textLength(0),
|
||||
m_textOffset(textOffset)
|
||||
{
|
||||
if (!m_fontDesc.IsValid())
|
||||
|
@ -224,7 +206,7 @@ namespace graphics
|
|||
m_boundRects.push_back(m2::AnyRectD(boundRect));
|
||||
}
|
||||
|
||||
void GlyphLayout::recalcAlongPath()
|
||||
void GlyphLayoutPath::recalcAlongPath()
|
||||
{
|
||||
size_t const count = m_visText.size();
|
||||
if (count == 0 || m_path.fullLength() < m_textLength)
|
||||
|
@ -321,7 +303,7 @@ namespace graphics
|
|||
}
|
||||
|
||||
// storing glyph coordinates relative to pivot point.
|
||||
for (unsigned i = m_firstVisible; i < m_lastVisible; ++i)
|
||||
for (size_t i = m_firstVisible; i < m_lastVisible; ++i)
|
||||
m_entries[i].m_pt -= m_pivot;
|
||||
|
||||
computeBoundRects();
|
||||
|
@ -331,7 +313,7 @@ namespace graphics
|
|||
{
|
||||
map<double, m2::AnyRectD> rects;
|
||||
|
||||
for (unsigned i = m_firstVisible; i < m_lastVisible; ++i)
|
||||
for (size_t i = m_firstVisible; i < m_lastVisible; ++i)
|
||||
{
|
||||
if (m_metrics[i].m_width != 0)
|
||||
{
|
||||
|
@ -383,16 +365,6 @@ namespace graphics
|
|||
return m_lastVisible;
|
||||
}
|
||||
|
||||
buffer_vector<GlyphLayoutElem, 32> const & GlyphLayout::entries() const
|
||||
{
|
||||
return m_entries;
|
||||
}
|
||||
|
||||
buffer_vector<m2::AnyRectD, 16> const & GlyphLayout::boundRects() const
|
||||
{
|
||||
return m_boundRects;
|
||||
}
|
||||
|
||||
m2::PointD const & GlyphLayout::pivot() const
|
||||
{
|
||||
return m_pivot;
|
||||
|
@ -400,7 +372,7 @@ namespace graphics
|
|||
|
||||
void GlyphLayout::setPivot(m2::PointD const & pivot)
|
||||
{
|
||||
for (unsigned i = 0; i < m_boundRects.size(); ++i)
|
||||
for (size_t i = 0; i < m_boundRects.size(); ++i)
|
||||
m_boundRects[i].Offset(pivot - m_pivot);
|
||||
|
||||
m_pivot = pivot;
|
||||
|
@ -413,7 +385,7 @@ namespace graphics
|
|||
|
||||
void GlyphLayout::setOffset(m2::PointD const & offset)
|
||||
{
|
||||
for (unsigned i = 0; i < m_boundRects.size(); ++i)
|
||||
for (size_t i = 0; i < m_boundRects.size(); ++i)
|
||||
m_boundRects[i].Offset(offset - m_offset);
|
||||
|
||||
m_offset = offset;
|
||||
|
@ -432,4 +404,9 @@ namespace graphics
|
|||
|
||||
return -result;
|
||||
}
|
||||
|
||||
bool GlyphLayoutPath::IsFullVisible() const
|
||||
{
|
||||
return (m_firstVisible == 0 && m_lastVisible == m_visText.size());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,38 +28,29 @@ namespace graphics
|
|||
|
||||
class GlyphLayout
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
size_t m_firstVisible;
|
||||
size_t m_lastVisible;
|
||||
|
||||
TextPath m_path;
|
||||
|
||||
strings::UniString m_visText;
|
||||
|
||||
graphics::FontDesc m_fontDesc;
|
||||
|
||||
buffer_vector<GlyphMetrics, 32> m_metrics;
|
||||
buffer_vector<GlyphLayoutElem, 32> m_entries;
|
||||
buffer_vector<m2::AnyRectD, 16> m_boundRects;
|
||||
buffer_vector<GlyphMetrics, 8> m_metrics;
|
||||
buffer_vector<GlyphLayoutElem, 8> m_entries;
|
||||
buffer_vector<m2::AnyRectD, 1> m_boundRects;
|
||||
|
||||
m2::PointD m_pivot;
|
||||
m2::PointD m_offset;
|
||||
|
||||
double m_textLength;
|
||||
double m_textOffset;
|
||||
|
||||
void computeBoundRects();
|
||||
|
||||
void recalcPivot();
|
||||
void recalcAlongPath();
|
||||
|
||||
inline void addGlyph(GlyphCache * glyphCache,
|
||||
GlyphKey const & key,
|
||||
bool isFirst,
|
||||
strings::UniChar symbol,
|
||||
m2::RectD & boundRect,
|
||||
m2::PointD & curPt);
|
||||
void addGlyph(GlyphCache * glyphCache,
|
||||
GlyphKey const & key,
|
||||
bool isFirst,
|
||||
strings::UniChar symbol,
|
||||
m2::RectD & boundRect,
|
||||
m2::PointD & curPt);
|
||||
|
||||
void initStraigthText(GlyphCache * glyphCache,
|
||||
FontDesc const & font,
|
||||
|
@ -68,40 +59,27 @@ namespace graphics
|
|||
graphics::EPosition pos,
|
||||
unsigned maxWidth);
|
||||
|
||||
protected:
|
||||
GlyphLayout(FontDesc const & font);
|
||||
|
||||
public:
|
||||
|
||||
GlyphLayout();
|
||||
|
||||
GlyphLayout(GlyphLayout const & layout,
|
||||
math::Matrix<double, 3, 3> const & m);
|
||||
|
||||
GlyphLayout(GlyphCache * glyphCache,
|
||||
FontDesc const & font,
|
||||
m2::PointD const & pt,
|
||||
strings::UniString const & visText,
|
||||
graphics::EPosition pos);
|
||||
GlyphLayout() {}
|
||||
|
||||
GlyphLayout(GlyphCache * glyphCache,
|
||||
FontDesc const & font,
|
||||
m2::PointD const & pt,
|
||||
strings::UniString const & visText,
|
||||
graphics::EPosition pos,
|
||||
unsigned maxWidth);
|
||||
|
||||
GlyphLayout(GlyphCache * glyphCache,
|
||||
FontDesc const & font,
|
||||
m2::PointD const * pts,
|
||||
size_t ptsCount,
|
||||
strings::UniString const & visText,
|
||||
double fullLength,
|
||||
double pathOffset,
|
||||
double textOffset);
|
||||
unsigned maxWidth = numeric_limits<unsigned>::max());
|
||||
|
||||
size_t firstVisible() const;
|
||||
size_t lastVisible() const;
|
||||
|
||||
buffer_vector<GlyphLayoutElem, 32> const & entries() const;
|
||||
buffer_vector<m2::AnyRectD, 16> const & boundRects() const;
|
||||
buffer_vector<GlyphLayoutElem, 8> const & entries() const { return m_entries; }
|
||||
buffer_vector<m2::AnyRectD, 1> const & boundRects() const { return m_boundRects; }
|
||||
|
||||
/// @note! Used only in StraightTextElement.
|
||||
m2::RectD GetLastGlobalRect() const { return m_boundRects.back().GetGlobalRect(); }
|
||||
|
||||
graphics::FontDesc const & fontDesc() const;
|
||||
|
||||
|
@ -113,4 +91,31 @@ namespace graphics
|
|||
|
||||
int baseLineOffset();
|
||||
};
|
||||
|
||||
class GlyphLayoutPath : public GlyphLayout
|
||||
{
|
||||
TextPath m_path;
|
||||
strings::UniString m_visText;
|
||||
|
||||
double m_textOffset;
|
||||
|
||||
void recalcAlongPath();
|
||||
|
||||
public:
|
||||
GlyphLayoutPath() {}
|
||||
|
||||
GlyphLayoutPath(GlyphLayoutPath const & layout,
|
||||
math::Matrix<double, 3, 3> const & m);
|
||||
|
||||
GlyphLayoutPath(GlyphCache * glyphCache,
|
||||
FontDesc const & font,
|
||||
m2::PointD const * pts,
|
||||
size_t ptsCount,
|
||||
strings::UniString const & visText,
|
||||
double fullLength,
|
||||
double pathOffset,
|
||||
double textOffset);
|
||||
|
||||
bool IsFullVisible() const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -13,18 +13,18 @@ namespace graphics
|
|||
{}
|
||||
|
||||
PathTextElement::PathTextElement(Params const & p)
|
||||
: TextElement(p),
|
||||
m_glyphLayout(p.m_glyphCache,
|
||||
p.m_fontDesc,
|
||||
p.m_pts,
|
||||
p.m_ptsCount,
|
||||
visText(),
|
||||
p.m_fullLength,
|
||||
p.m_pathOffset,
|
||||
p.m_textOffset)
|
||||
: TextElement(p)
|
||||
{
|
||||
strings::UniString visText, auxVisText;
|
||||
(void) p.GetVisibleTexts(visText, auxVisText);
|
||||
|
||||
m_glyphLayout = GlyphLayoutPath(p.m_glyphCache, p.m_fontDesc,
|
||||
p.m_pts, p.m_ptsCount,
|
||||
visText, p.m_fullLength,
|
||||
p.m_pathOffset, p.m_textOffset);
|
||||
|
||||
setPivot(m_glyphLayout.pivot());
|
||||
setIsValid((m_glyphLayout.firstVisible() == 0) && (m_glyphLayout.lastVisible() == visText().size()));
|
||||
setIsValid(m_glyphLayout.IsFullVisible());
|
||||
}
|
||||
|
||||
vector<m2::AnyRectD> const & PathTextElement::boundRects() const
|
||||
|
@ -86,9 +86,9 @@ namespace graphics
|
|||
|
||||
void PathTextElement::setTransformation(const math::Matrix<double, 3, 3> & m)
|
||||
{
|
||||
m_glyphLayout = GlyphLayout(m_glyphLayout, getResetMatrix() * m);
|
||||
m_glyphLayout = GlyphLayoutPath(m_glyphLayout, getResetMatrix() * m);
|
||||
TextElement::setPivot(m_glyphLayout.pivot());
|
||||
setIsValid((m_glyphLayout.firstVisible() == 0) && (m_glyphLayout.lastVisible() == visText().size()));
|
||||
setIsValid(m_glyphLayout.IsFullVisible());
|
||||
TextElement::setTransformation(m);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace graphics
|
|||
{
|
||||
private:
|
||||
|
||||
GlyphLayout m_glyphLayout;
|
||||
GlyphLayoutPath m_glyphLayout;
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -80,51 +80,54 @@ namespace graphics
|
|||
double allElemWidth = 0;
|
||||
double allElemHeight = 0;
|
||||
|
||||
if (!visText().empty())
|
||||
strings::UniString visText, auxVisText;
|
||||
pair<bool, bool> const isBidi = p.GetVisibleTexts(visText, auxVisText);
|
||||
|
||||
if (!visText.empty())
|
||||
{
|
||||
buffer_vector<strings::UniString, 3> res;
|
||||
if (p.m_doForceSplit || (p.m_doSplit && !isBidi()))
|
||||
if (p.m_doForceSplit || (p.m_doSplit && !isBidi.first))
|
||||
{
|
||||
res.clear();
|
||||
if (!p.m_delimiters.empty())
|
||||
visSplit(visText(), res, p.m_delimiters.c_str(), p.m_useAllParts);
|
||||
visSplit(visText, res, p.m_delimiters.c_str(), p.m_useAllParts);
|
||||
else
|
||||
visSplit(visText(), res, " \n\t", p.m_useAllParts);
|
||||
visSplit(visText, res, " \n\t", p.m_useAllParts);
|
||||
}
|
||||
else
|
||||
res.push_back(visText());
|
||||
res.push_back(visText);
|
||||
|
||||
for (unsigned i = 0; i < res.size(); ++i)
|
||||
for (size_t i = 0; i < res.size(); ++i)
|
||||
{
|
||||
m_glyphLayouts.push_back(GlyphLayout(p.m_glyphCache, p.m_fontDesc, m2::PointD(0, 0), res[i], graphics::EPosCenter, p.m_maxPixelWidth));
|
||||
m2::RectD r = m_glyphLayouts.back().boundRects().back().GetGlobalRect();
|
||||
m2::RectD const r = m_glyphLayouts.back().GetLastGlobalRect();
|
||||
allElemWidth = max(r.SizeX(), allElemWidth);
|
||||
allElemHeight += r.SizeY();
|
||||
}
|
||||
}
|
||||
|
||||
if (p.m_auxFontDesc.IsValid() && !auxVisText().empty())
|
||||
if (p.m_auxFontDesc.IsValid() && !auxVisText.empty())
|
||||
{
|
||||
buffer_vector<strings::UniString, 3> auxRes;
|
||||
|
||||
GlyphLayout l(p.m_glyphCache, p.m_auxFontDesc, m2::PointD(0, 0), auxVisText(), graphics::EPosCenter);
|
||||
if (l.boundRects().back().GetGlobalRect().SizeX() > allElemWidth)
|
||||
GlyphLayout l(p.m_glyphCache, p.m_auxFontDesc, m2::PointD(0, 0), auxVisText, graphics::EPosCenter);
|
||||
if (l.GetLastGlobalRect().SizeX() > allElemWidth)
|
||||
{
|
||||
// should split
|
||||
if (p.m_doSplit && !isAuxBidi())
|
||||
if (p.m_doSplit && !isBidi.second)
|
||||
{
|
||||
if (!p.m_delimiters.empty())
|
||||
visSplit(auxVisText(), auxRes, p.m_delimiters.c_str(), p.m_useAllParts);
|
||||
visSplit(auxVisText, auxRes, p.m_delimiters.c_str(), p.m_useAllParts);
|
||||
else
|
||||
visSplit(auxVisText(), auxRes, " \n\t", p.m_useAllParts);
|
||||
visSplit(auxVisText, auxRes, " \n\t", p.m_useAllParts);
|
||||
}
|
||||
else
|
||||
auxRes.push_back(auxVisText());
|
||||
auxRes.push_back(auxVisText);
|
||||
}
|
||||
else
|
||||
auxRes.push_back(auxVisText());
|
||||
auxRes.push_back(auxVisText);
|
||||
|
||||
for (int i = 0; i < auxRes.size(); ++i)
|
||||
for (size_t i = 0; i < auxRes.size(); ++i)
|
||||
m_glyphLayouts.push_back(GlyphLayout(p.m_glyphCache, p.m_auxFontDesc, m2::PointD(0, 0), auxRes[i], graphics::EPosCenter));
|
||||
}
|
||||
|
||||
|
@ -133,32 +136,31 @@ namespace graphics
|
|||
|
||||
double curShift = allElemHeight / 2;
|
||||
|
||||
/// performing aligning of glyphLayouts as for the center position
|
||||
|
||||
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
// performing aligning of glyphLayouts as for the center position
|
||||
for (size_t i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
{
|
||||
double elemSize = m_glyphLayouts[i].boundRects().back().GetGlobalRect().SizeY();
|
||||
double const elemSize = m_glyphLayouts[i].GetLastGlobalRect().SizeY();
|
||||
m_glyphLayouts[i].setPivot(m_glyphLayouts[i].pivot() + m2::PointD(0, -curShift + elemSize / 2) + p.m_offset);
|
||||
curShift -= elemSize;
|
||||
}
|
||||
|
||||
if (position() & graphics::EPosLeft)
|
||||
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
for (size_t i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
m_glyphLayouts[i].setPivot(m_glyphLayouts[i].pivot() + m2::PointD(-allElemWidth / 2, 0));
|
||||
|
||||
if (position() & graphics::EPosRight)
|
||||
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
for (size_t i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
m_glyphLayouts[i].setPivot(m_glyphLayouts[i].pivot() + m2::PointD(allElemWidth / 2, 0));
|
||||
|
||||
if (position() & graphics::EPosAbove)
|
||||
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
for (size_t i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
m_glyphLayouts[i].setPivot(m_glyphLayouts[i].pivot() + m2::PointD(0, -allElemHeight / 2));
|
||||
|
||||
if (position() & graphics::EPosUnder)
|
||||
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
for (size_t i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
m_glyphLayouts[i].setPivot(m_glyphLayouts[i].pivot() + m2::PointD(0, allElemHeight / 2));
|
||||
|
||||
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
for (size_t i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
{
|
||||
m_offsets.push_back(m_glyphLayouts[i].pivot());
|
||||
m_glyphLayouts[i].setPivot(m_offsets[i] + pivot());
|
||||
|
@ -209,7 +211,7 @@ namespace graphics
|
|||
|
||||
doffs += 1;
|
||||
|
||||
for (unsigned i = 0 ; i < boundRects().size(); ++i)
|
||||
for (size_t i = 0 ; i < boundRects().size(); ++i)
|
||||
screen->drawRectangle(boundRects()[i], c, depth() + doffs);
|
||||
|
||||
doffs += 1;
|
||||
|
@ -218,7 +220,7 @@ namespace graphics
|
|||
if (!isNeedRedraw())
|
||||
return;
|
||||
|
||||
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
for (size_t i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
{
|
||||
if (m_glyphLayouts[i].fontDesc().m_isMasked)
|
||||
drawTextImpl(m_glyphLayouts[i], screen, m, true, true, m_glyphLayouts[i].fontDesc(), depth() + doffs);
|
||||
|
@ -226,7 +228,7 @@ namespace graphics
|
|||
|
||||
doffs += 1;
|
||||
|
||||
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
for (size_t i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
{
|
||||
graphics::FontDesc fontDesc = m_glyphLayouts[i].fontDesc();
|
||||
fontDesc.m_isMasked = false;
|
||||
|
@ -241,7 +243,7 @@ namespace graphics
|
|||
|
||||
TextElement::setPivot(pv);
|
||||
|
||||
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
for (size_t i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
m_glyphLayouts[i].setPivot(m_glyphLayouts[i].pivot() + offs);
|
||||
}
|
||||
|
||||
|
@ -249,7 +251,7 @@ namespace graphics
|
|||
{
|
||||
setPivot(pivot() * getResetMatrix() * m);
|
||||
|
||||
for (unsigned i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
for (size_t i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
{
|
||||
m_glyphLayouts[i].setPivot(pivot());
|
||||
m_glyphLayouts[i].setOffset(m_offsets[i]);
|
||||
|
|
|
@ -10,9 +10,10 @@ namespace graphics
|
|||
{
|
||||
private:
|
||||
|
||||
/// glyph layout of the text parts.
|
||||
vector<GlyphLayout> m_glyphLayouts;
|
||||
vector<m2::PointD> m_offsets;
|
||||
// Glyph layout of the text parts.
|
||||
// In 99% cases cantainers will hold 1 element.
|
||||
buffer_vector<GlyphLayout, 1> m_glyphLayouts;
|
||||
buffer_vector<m2::PointD, 1> m_offsets;
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -11,44 +11,30 @@ namespace graphics
|
|||
TextElement::TextElement(Params const & p)
|
||||
: OverlayElement(p),
|
||||
m_fontDesc(p.m_fontDesc),
|
||||
m_auxFontDesc(p.m_auxFontDesc),
|
||||
m_logText(p.m_logText),
|
||||
m_auxLogText(p.m_auxLogText),
|
||||
m_log2vis(p.m_log2vis)
|
||||
m_auxFontDesc(p.m_auxFontDesc)
|
||||
{
|
||||
}
|
||||
|
||||
pair<bool, bool> TextElement::Params::GetVisibleTexts(
|
||||
strings::UniString & visText, strings::UniString & auxVisText) const
|
||||
{
|
||||
if (m_log2vis)
|
||||
{
|
||||
m_visText = p.m_glyphCache->log2vis(m_logText);
|
||||
visText = m_glyphCache->log2vis(m_logText);
|
||||
if (!m_auxLogText.empty())
|
||||
m_auxVisText = p.m_glyphCache->log2vis(m_auxLogText);
|
||||
auxVisText = m_glyphCache->log2vis(m_auxLogText);
|
||||
|
||||
return make_pair(visText != m_logText, auxVisText != m_auxLogText);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_visText = m_logText;
|
||||
m_auxVisText = m_auxLogText;
|
||||
visText = m_logText;
|
||||
auxVisText = m_auxLogText;
|
||||
|
||||
return make_pair(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
strings::UniString const & TextElement::logText() const
|
||||
{
|
||||
return m_logText;
|
||||
}
|
||||
|
||||
strings::UniString const & TextElement::auxLogText() const
|
||||
{
|
||||
return m_auxLogText;
|
||||
}
|
||||
|
||||
strings::UniString const & TextElement::visText() const
|
||||
{
|
||||
return m_visText;
|
||||
}
|
||||
|
||||
strings::UniString const & TextElement::auxVisText() const
|
||||
{
|
||||
return m_auxVisText;
|
||||
}
|
||||
|
||||
FontDesc const & TextElement::fontDesc() const
|
||||
{
|
||||
return m_fontDesc;
|
||||
|
@ -59,16 +45,6 @@ namespace graphics
|
|||
return m_auxFontDesc;
|
||||
}
|
||||
|
||||
bool TextElement::isBidi() const
|
||||
{
|
||||
return m_logText != m_visText;
|
||||
}
|
||||
|
||||
bool TextElement::isAuxBidi() const
|
||||
{
|
||||
return m_auxLogText != m_auxVisText;
|
||||
}
|
||||
|
||||
void TextElement::drawTextImpl(GlyphLayout const & layout,
|
||||
OverlayRenderer * screen,
|
||||
math::Matrix<double, 3, 3> const & m,
|
||||
|
@ -96,17 +72,17 @@ namespace graphics
|
|||
deltaA = (ang::AngleD(0) * m).val();
|
||||
}
|
||||
|
||||
size_t cnt = layout.entries().size();
|
||||
size_t const cnt = layout.entries().size();
|
||||
|
||||
buffer_vector<Glyph::Info, 32> glyphInfos(cnt);
|
||||
buffer_vector<Resource::Info const *, 32> resInfos(cnt);
|
||||
buffer_vector<uint32_t, 32> glyphIDs(cnt);
|
||||
|
||||
unsigned firstVis = layout.firstVisible();
|
||||
unsigned lastVis = layout.lastVisible();
|
||||
size_t const firstVis = layout.firstVisible();
|
||||
size_t const lastVis = layout.lastVisible();
|
||||
|
||||
/// collecting all glyph infos in one array and packing them as a whole.
|
||||
for (unsigned i = firstVis; i < lastVis; ++i)
|
||||
for (size_t i = firstVis; i < lastVis; ++i)
|
||||
{
|
||||
GlyphKey glyphKey(layout.entries()[i].m_sym,
|
||||
fontDesc.m_size,
|
||||
|
@ -117,16 +93,16 @@ namespace graphics
|
|||
resInfos[i] = &glyphInfos[i];
|
||||
}
|
||||
|
||||
if ((firstVis != lastVis)
|
||||
&& !screen->mapInfo(&resInfos[firstVis],
|
||||
&glyphIDs[firstVis],
|
||||
lastVis - firstVis))
|
||||
if (firstVis != lastVis &&
|
||||
!screen->mapInfo(&resInfos[firstVis],
|
||||
&glyphIDs[firstVis],
|
||||
lastVis - firstVis))
|
||||
{
|
||||
LOG(LDEBUG, ("cannot render string", lastVis - firstVis, "characters long"));
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned i = firstVis; i < lastVis; ++i)
|
||||
for (size_t i = firstVis; i < lastVis; ++i)
|
||||
{
|
||||
GlyphLayoutElem const & elem = layout.entries()[i];
|
||||
Glyph const * glyph = static_cast<Glyph const *>(screen->fromID(glyphIDs[i]));
|
||||
|
|
|
@ -16,23 +16,10 @@ namespace graphics
|
|||
{
|
||||
protected:
|
||||
|
||||
/// text-element specific
|
||||
FontDesc m_fontDesc;
|
||||
FontDesc m_auxFontDesc;
|
||||
|
||||
strings::UniString m_logText; //< logical string
|
||||
strings::UniString m_auxLogText;
|
||||
|
||||
strings::UniString m_visText; //< visual string, BIDI processed
|
||||
strings::UniString m_auxVisText;
|
||||
|
||||
bool m_log2vis;
|
||||
FontDesc m_fontDesc, m_auxFontDesc;
|
||||
|
||||
mutable vector<m2::AnyRectD> m_boundRects;
|
||||
|
||||
bool isBidi() const;
|
||||
bool isAuxBidi() const;
|
||||
|
||||
public:
|
||||
|
||||
struct Params : OverlayElement::Params
|
||||
|
@ -45,6 +32,9 @@ namespace graphics
|
|||
|
||||
bool m_log2vis;
|
||||
GlyphCache * m_glyphCache;
|
||||
|
||||
pair<bool, bool> GetVisibleTexts(strings::UniString & visText,
|
||||
strings::UniString & auxVisText) const;
|
||||
};
|
||||
|
||||
TextElement(Params const & p);
|
||||
|
@ -56,10 +46,7 @@ namespace graphics
|
|||
bool doAlignPivot,
|
||||
FontDesc const & desc,
|
||||
double depth) const;
|
||||
strings::UniString const & logText() const;
|
||||
strings::UniString const & auxLogText() const;
|
||||
strings::UniString const & visText() const;
|
||||
strings::UniString const & auxVisText() const;
|
||||
|
||||
FontDesc const & fontDesc() const;
|
||||
FontDesc const & auxFontDesc() const;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue