Changeset - r23599:b4bf61c1f787
[Not reviewed]
master
0 6 0
Michael Lutz - 6 years ago 2019-04-02 19:31:10
michi@icosahedron.de
Codechange: Replace AutoDeleteSmallVector with direct std::vector use in text layout code.
6 files changed with 40 insertions and 39 deletions:
0 comments (0 inline, 0 general)
src/gfx.cpp
Show inline comments
 
@@ -337,18 +337,18 @@ static void SetColourRemap(TextColour co
 
 * @param underline Whether to underline what has been drawn or not.
 
 * @param truncation Whether to perform string truncation or not.
 
 *
 
 * @return In case of left or center alignment the right most pixel we have drawn to.
 
 *         In case of right alignment the left most pixel we have drawn to.
 
 */
 
static int DrawLayoutLine(const ParagraphLayouter::Line *line, int y, int left, int right, StringAlignment align, bool underline, bool truncation)
 
static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left, int right, StringAlignment align, bool underline, bool truncation)
 
{
 
	if (line->CountRuns() == 0) return 0;
 
	if (line.CountRuns() == 0) return 0;
 

	
 
	int w = line->GetWidth();
 
	int h = line->GetLeading();
 
	int w = line.GetWidth();
 
	int h = line.GetLeading();
 

	
 
	/*
 
	 * The following is needed for truncation.
 
	 * Depending on the text direction, we either remove bits at the rear
 
	 * or the front. For this we shift the entire area to draw so it fits
 
	 * within the left/right bounds and the side we do not truncate it on.
 
@@ -373,13 +373,13 @@ static int DrawLayoutLine(const Paragrap
 
		/*
 
		 * Assumption may be made that all fonts of a run are of the same size.
 
		 * In any case, we'll use these dots for the abbreviation, so even if
 
		 * another size would be chosen it won't have truncated too little for
 
		 * the truncation dots.
 
		 */
 
		FontCache *fc = ((const Font*)line->GetVisualRun(0).GetFont())->fc;
 
		FontCache *fc = ((const Font*)line.GetVisualRun(0).GetFont())->fc;
 
		GlyphID dot_glyph = fc->MapCharToGlyph('.');
 
		dot_width = fc->GetGlyphWidth(dot_glyph);
 
		dot_sprite = fc->GetGlyph(dot_glyph);
 

	
 
		if (_current_text_dir == TD_RTL) {
 
			min_x += 3 * dot_width;
 
@@ -418,14 +418,14 @@ static int DrawLayoutLine(const Paragrap
 
		default:
 
			NOT_REACHED();
 
	}
 

	
 
	TextColour colour = TC_BLACK;
 
	bool draw_shadow = false;
 
	for (int run_index = 0; run_index < line->CountRuns(); run_index++) {
 
		const ParagraphLayouter::VisualRun &run = line->GetVisualRun(run_index);
 
	for (int run_index = 0; run_index < line.CountRuns(); run_index++) {
 
		const ParagraphLayouter::VisualRun &run = line.GetVisualRun(run_index);
 
		const Font *f = (const Font*)run.GetFont();
 

	
 
		FontCache *fc = f->fc;
 
		colour = f->colour;
 
		SetColourRemap(colour);
 

	
 
@@ -509,13 +509,13 @@ int DrawString(int left, int right, int 
 
		return 0;
 
	}
 

	
 
	Layouter layout(str, INT32_MAX, colour, fontsize);
 
	if (layout.size() == 0) return 0;
 

	
 
	return DrawLayoutLine(layout.front(), top, left, right, align, underline, true);
 
	return DrawLayoutLine(*layout.front(), top, left, right, align, underline, true);
 
}
 

	
 
/**
 
 * Draw string, possibly truncated to make it fit in its allocated space
 
 *
 
 * @param left   The left most position to draw on.
 
@@ -645,20 +645,20 @@ int DrawStringMultiLine(int left, int ri
 
		default: NOT_REACHED();
 
	}
 

	
 
	int last_line = top;
 
	int first_line = bottom;
 

	
 
	for (const ParagraphLayouter::Line *line : layout) {
 
	for (const auto &line : layout) {
 

	
 
		int line_height = line->GetLeading();
 
		if (y >= top && y < bottom) {
 
			last_line = y + line_height;
 
			if (first_line > y) first_line = y;
 

	
 
			DrawLayoutLine(line, y, left, right, align, underline, false);
 
			DrawLayoutLine(*line, y, left, right, align, underline, false);
 
		}
 
		y += line_height;
 
	}
 

	
 
	return ((align & SA_VERT_MASK) == SA_BOTTOM) ? first_line : last_line;
 
}
src/gfx_layout.cpp
Show inline comments
 
@@ -121,13 +121,13 @@ le_bool Font::getGlyphPoint(LEGlyphID gl
 
	return FALSE;
 
}
 

	
 
/**
 
 * Wrapper for doing layouts with ICU.
 
 */
 
class ICUParagraphLayout : public AutoDeleteSmallVector<ParagraphLayouter::Line *>, public ParagraphLayouter {
 
class ICUParagraphLayout : public ParagraphLayouter {
 
	icu::ParagraphLayout *p; ///< The actual ICU paragraph layout.
 
public:
 
	/** Visual run contains data about the bit of text with the same font. */
 
	class ICUVisualRun : public ParagraphLayouter::VisualRun {
 
		const icu::ParagraphLayout::VisualRun *vr; ///< The actual ICU vr.
 

	
 
@@ -168,16 +168,16 @@ public:
 
	};
 

	
 
	ICUParagraphLayout(icu::ParagraphLayout *p) : p(p) { }
 
	~ICUParagraphLayout() override { delete p; }
 
	void Reflow() override  { p->reflow(); }
 

	
 
	ParagraphLayouter::Line *NextLine(int max_width) override
 
	std::unique_ptr<const Line> NextLine(int max_width) override
 
	{
 
		icu::ParagraphLayout::Line *l = p->nextLine(max_width);
 
		return l == NULL ? NULL : new ICULine(l);
 
		return std::unique_ptr<const Line>(l == NULL ? NULL : new ICULine(l));
 
	}
 
};
 

	
 
/**
 
 * Helper class to construct a new #ICUParagraphLayout.
 
 */
 
@@ -283,13 +283,13 @@ public:
 
	const WChar *buffer_begin; ///< Begin of the buffer.
 
	const WChar *buffer;       ///< The current location in the buffer.
 
	FontMap &runs;             ///< The fonts we have to use for this paragraph.
 

	
 
	FallbackParagraphLayout(WChar *buffer, int length, FontMap &runs);
 
	void Reflow() override;
 
	const ParagraphLayouter::Line *NextLine(int max_width) override;
 
	std::unique_ptr<const Line> NextLine(int max_width) override;
 
};
 

	
 
/**
 
 * Helper class to construct a new #FallbackParagraphLayout.
 
 */
 
class FallbackParagraphLayoutFactory {
 
@@ -495,27 +495,27 @@ void FallbackParagraphLayout::Reflow()
 

	
 
/**
 
 * Construct a new line with a maximum width.
 
 * @param max_width The maximum width of the string.
 
 * @return A Line, or NULL when at the end of the paragraph.
 
 */
 
const ParagraphLayouter::Line *FallbackParagraphLayout::NextLine(int max_width)
 
std::unique_ptr<const ParagraphLayouter::Line> FallbackParagraphLayout::NextLine(int max_width)
 
{
 
	/* Simple idea:
 
	 *  - split a line at a newline character, or at a space where we can break a line.
 
	 *  - split for a visual run whenever a new line happens, or the font changes.
 
	 */
 
	if (this->buffer == NULL) return NULL;
 

	
 
	FallbackLine *l = new FallbackLine();
 
	std::unique_ptr<FallbackLine> l(new FallbackLine());
 

	
 
	if (*this->buffer == '\0') {
 
		/* Only a newline. */
 
		this->buffer = NULL;
 
		l->emplace_back(this->runs.front().second, this->buffer, 0, 0);
 
		return l;
 
		return std::move(l); // Not supposed to be needed, but clang-3.8 barfs otherwise.
 
	}
 

	
 
	int offset = this->buffer - this->buffer_begin;
 
	FontMap::iterator iter = this->runs.data();
 
	while (iter->first <= offset) {
 
		iter++;
 
@@ -559,13 +559,13 @@ const ParagraphLayouter::Line *FallbackP
 
				/* The string is longer than maximum width so we need to decide
 
				 * what to do with it. */
 
				if (width == char_width) {
 
					/* The character is wider than allowed width; don't know
 
					 * what to do with this case... bail out! */
 
					this->buffer = NULL;
 
					return l;
 
					return std::move(l); // Not supposed to be needed, but clang-3.8 barfs otherwise.
 
				}
 

	
 
				if (last_space == NULL) {
 
					/* No space has been found. Just terminate at our current
 
					 * location. This usually happens for languages that do not
 
					 * require spaces in strings, like Chinese, Japanese and
 
@@ -586,13 +586,13 @@ const ParagraphLayouter::Line *FallbackP
 
	}
 

	
 
	if (l->size() == 0 || last_char - begin != 0) {
 
		int w = l->GetWidth();
 
		l->emplace_back(iter->second, begin, last_char - begin, w);
 
	}
 
	return l;
 
	return std::move(l); // Not supposed to be needed, but clang-3.8 barfs otherwise.
 
}
 

	
 
/**
 
 * Helper for getting a ParagraphLayouter of the given type.
 
 *
 
 * @note In case no ParagraphLayouter could be constructed, line.layout will be NULL.
 
@@ -727,29 +727,29 @@ Layouter::Layouter(const char *str, int 
 

	
 
			if (line.layout == NULL) {
 
				GetLayouter<FallbackParagraphLayoutFactory>(line, str, state);
 
			}
 
		}
 

	
 
		/* Copy all lines into a local cache so we can reuse them later on more easily. */
 
		const ParagraphLayouter::Line *l;
 
		while ((l = line.layout->NextLine(maxw)) != NULL) {
 
			this->push_back(l);
 
		/* Move all lines into a local cache so we can reuse them later on more easily. */
 
		for (;;) {
 
			auto l = line.layout->NextLine(maxw);
 
			if (l == NULL) break;
 
			this->push_back(std::move(l));
 
		}
 

	
 
	} while (c != '\0');
 
}
 

	
 
/**
 
 * Get the boundaries of this paragraph.
 
 * @return The boundaries.
 
 */
 
Dimension Layouter::GetBounds()
 
{
 
	Dimension d = { 0, 0 };
 
	for (const ParagraphLayouter::Line *l : *this) {
 
	for (const auto &l : *this) {
 
		d.width = max<uint>(d.width, l->GetWidth());
 
		d.height += l->GetLeading();
 
	}
 
	return d;
 
}
 

	
 
@@ -772,13 +772,13 @@ Point Layouter::GetCharPosition(const ch
 
		str += len;
 
		index += this->front()->GetInternalCharLength(c);
 
	}
 

	
 
	if (str == ch) {
 
		/* Valid character. */
 
		const ParagraphLayouter::Line *line = this->front();
 
		const auto &line = this->front();
 

	
 
		/* Pointer to the end-of-string/line marker? Return total line width. */
 
		if (*ch == '\0' || *ch == '\n') {
 
			Point p = { line->GetWidth(), 0 };
 
			return p;
 
		}
 
@@ -805,13 +805,13 @@ Point Layouter::GetCharPosition(const ch
 
 * Get the character that is at a position.
 
 * @param x Position in the string.
 
 * @return Pointer to the character at the position or NULL if no character is at the position.
 
 */
 
const char *Layouter::GetCharAtPosition(int x) const
 
{
 
	const ParagraphLayouter::Line *line = this->front();
 
	const auto &line = this->front();
 

	
 
	for (int run_index = 0; run_index < line->CountRuns(); run_index++) {
 
		const ParagraphLayouter::VisualRun &run = line->GetVisualRun(run_index);
 

	
 
		for (int i = 0; i < run.GetGlyphCount(); i++) {
 
			/* Not a valid glyph (empty). */
src/gfx_layout.h
Show inline comments
 
@@ -139,21 +139,21 @@ public:
 
		virtual int CountRuns() const = 0;
 
		virtual const VisualRun &GetVisualRun(int run) const = 0;
 
		virtual int GetInternalCharLength(WChar c) const = 0;
 
	};
 

	
 
	virtual void Reflow() = 0;
 
	virtual const Line *NextLine(int max_width) = 0;
 
	virtual std::unique_ptr<const Line> NextLine(int max_width) = 0;
 
};
 

	
 
/**
 
 * The layouter performs all the layout work.
 
 *
 
 * It also accounts for the memory allocations and frees.
 
 */
 
class Layouter : public AutoDeleteSmallVector<const ParagraphLayouter::Line *> {
 
class Layouter : public std::vector<std::unique_ptr<const ParagraphLayouter::Line>> {
 
	const char *string; ///< Pointer to the original string.
 

	
 
	/** Key into the linecache */
 
	struct LineCacheKey {
 
		FontState state_before;  ///< Font state at the beginning of the line.
 
		std::string str;         ///< Source string of the line (including colour and font size codes).
src/os/macosx/string_osx.cpp
Show inline comments
 
@@ -108,13 +108,13 @@ public:
 

	
 
	void Reflow() override
 
	{
 
		this->cur_offset = 0;
 
	}
 

	
 
	const Line *NextLine(int max_width) override;
 
	std::unique_ptr<const Line> NextLine(int max_width) override;
 
};
 

	
 

	
 
/** Get the width of an encoded sprite font character.  */
 
static CGFloat SpriteFontGetWidth(void *ref_con)
 
{
 
@@ -185,25 +185,25 @@ static CTRunDelegateCallbacks _sprite_fo
 
	CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedString(str);
 
	CFRelease(str);
 

	
 
	return typesetter != NULL ? new CoreTextParagraphLayout(typesetter, buff, length, fontMapping) : NULL;
 
}
 

	
 
/* virtual */ const CoreTextParagraphLayout::Line *CoreTextParagraphLayout::NextLine(int max_width)
 
/* virtual */ std::unique_ptr<const ParagraphLayouter::Line> CoreTextParagraphLayout::NextLine(int max_width)
 
{
 
	if (this->cur_offset >= this->length) return NULL;
 

	
 
	/* Get line break position, trying word breaking first and breaking somewhere if that doesn't work. */
 
	CFIndex len = CTTypesetterSuggestLineBreak(this->typesetter, this->cur_offset, max_width);
 
	if (len <= 0) len = CTTypesetterSuggestClusterBreak(this->typesetter, this->cur_offset, max_width);
 

	
 
	/* Create line. */
 
	CTLineRef line = CTTypesetterCreateLine(this->typesetter, CFRangeMake(this->cur_offset, len));
 
	this->cur_offset += len;
 

	
 
	return line != NULL ? new CoreTextLine(line, this->font_map, this->text_buffer) : NULL;
 
	return std::unique_ptr<const Line>(line != NULL ? new CoreTextLine(line, this->font_map, this->text_buffer) : NULL);
 
}
 

	
 
CoreTextParagraphLayout::CoreTextVisualRun::CoreTextVisualRun(CTRunRef run, Font *font, const CoreTextParagraphLayoutFactory::CharType *buff) : font(font)
 
{
 
	this->glyphs.resize(CTRunGetGlyphCount(run));
 

	
 
@@ -241,14 +241,14 @@ CoreTextParagraphLayout::CoreTextVisualR
 
 * Get the height of the line.
 
 * @return The maximum height of the line.
 
 */
 
int CoreTextParagraphLayout::CoreTextLine::GetLeading() const
 
{
 
	int leading = 0;
 
	for (const CoreTextVisualRun * const &run : *this) {
 
		leading = max(leading, run->GetLeading());
 
	for (const auto &run : *this) {
 
		leading = max(leading, run.GetLeading());
 
	}
 

	
 
	return leading;
 
}
 

	
 
/**
 
@@ -257,14 +257,14 @@ int CoreTextParagraphLayout::CoreTextLin
 
 */
 
int CoreTextParagraphLayout::CoreTextLine::GetWidth() const
 
{
 
	if (this->size() == 0) return 0;
 

	
 
	int total_width = 0;
 
	for (const CoreTextVisualRun * const &run : *this) {
 
		total_width += run->GetAdvance();
 
	for (const auto &run : *this) {
 
		total_width += run.GetAdvance();
 
	}
 

	
 
	return total_width;
 
}
 

	
 

	
src/os/windows/string_uniscribe.cpp
Show inline comments
 
@@ -131,13 +131,13 @@ public:
 
	void Reflow() override
 
	{
 
		this->cur_range = this->ranges.begin();
 
		this->cur_range_offset = 0;
 
	}
 

	
 
	const Line *NextLine(int max_width) override;
 
	std::unique_ptr<const Line> NextLine(int max_width) override;
 
};
 

	
 
void UniscribeResetScriptCache(FontSize size)
 
{
 
	if (_script_cache[size] != NULL) {
 
		ScriptFreeCache(&_script_cache[size]);
 
@@ -315,13 +315,13 @@ static std::vector<SCRIPT_ITEM> Uniscrib
 
		}
 
	}
 

	
 
	return new UniscribeParagraphLayout(ranges, buff);
 
}
 

	
 
/* virtual */ const ParagraphLayouter::Line *UniscribeParagraphLayout::NextLine(int max_width)
 
/* virtual */ std::unique_ptr<const ParagraphLayouter::Line> UniscribeParagraphLayout::NextLine(int max_width)
 
{
 
	std::vector<UniscribeRun>::iterator start_run = this->cur_range;
 
	std::vector<UniscribeRun>::iterator last_run = this->cur_range;
 

	
 
	if (start_run == this->ranges.end()) return NULL;
 

	
 
@@ -401,13 +401,13 @@ static std::vector<SCRIPT_ITEM> Uniscrib
 
		bidi_level.push_back(r->sa.s.uBidiLevel);
 
	}
 
	std::vector<INT> vis_to_log(bidi_level.size());
 
	if (FAILED(ScriptLayout((int)bidi_level.size(), &bidi_level[0], &vis_to_log[0], NULL))) return NULL;
 

	
 
	/* Create line. */
 
	UniscribeLine *line = new UniscribeLine();
 
	std::unique_ptr<UniscribeLine> line(new UniscribeLine());
 

	
 
	int cur_pos = 0;
 
	for (std::vector<INT>::iterator l = vis_to_log.begin(); l != vis_to_log.end(); l++) {
 
		std::vector<UniscribeRun>::iterator i_run = start_run + *l;
 
		UniscribeRun run = *i_run;
 

	
src/stdafx.h
Show inline comments
 
@@ -80,12 +80,13 @@
 
#include <cstdio>
 
#include <cstddef>
 
#include <cstring>
 
#include <cstdlib>
 
#include <climits>
 
#include <cassert>
 
#include <memory>
 

	
 
#ifndef SIZE_MAX
 
	#define SIZE_MAX ((size_t)-1)
 
#endif
 

	
 
#if defined(UNIX) || defined(__MINGW32__)
0 comments (0 inline, 0 general)