Changeset - r22896:063f71e2d5c3
[Not reviewed]
master
0 1 0
Michael Lutz - 6 years ago 2018-04-29 14:43:30
michi@icosahedron.de
Codechange: Move ParagraphLayouter-specific functions into factory classes instead of relying on overloads.
1 file changed with 85 insertions and 74 deletions:
0 comments (0 inline, 0 general)
src/gfx_layout.cpp
Show inline comments
 
@@ -113,26 +113,12 @@ le_bool Font::getGlyphPoint(LEGlyphID gl
 
	return FALSE;
 
}
 

	
 
static size_t AppendToBuffer(UChar *buff, const UChar *buffer_last, WChar c)
 
{
 
	/* Transform from UTF-32 to internal ICU format of UTF-16. */
 
	int32 length = 0;
 
	UErrorCode err = U_ZERO_ERROR;
 
	u_strFromUTF32(buff, buffer_last - buff, &length, (UChar32*)&c, 1, &err);
 
	return length;
 
}
 

	
 
/**
 
 * Wrapper for doing layouts with ICU.
 
 */
 
class ICUParagraphLayout : public AutoDeleteSmallVector<ParagraphLayouter::Line *, 4>, public ParagraphLayouter {
 
	ParagraphLayout *p; ///< The actual ICU paragraph layout.
 
public:
 
	/** Helper for GetLayouter, to get the right type. */
 
	typedef UChar CharType;
 
	/** Helper for GetLayouter, to get whether the layouter supports RTL. */
 
	static const bool SUPPORTS_RTL = true;
 

	
 
	/** Visual run contains data about the bit of text with the same font. */
 
	class ICUVisualRun : public ParagraphLayouter::VisualRun {
 
		const ParagraphLayout::VisualRun *vr; ///< The actual ICU vr.
 
@@ -184,35 +170,54 @@ public:
 
	}
 
};
 

	
 
static ParagraphLayouter *GetParagraphLayout(UChar *buff, UChar *buff_end, FontMap &fontMapping)
 
{
 
	int32 length = buff_end - buff;
 
/**
 
 * Helper class to construct a new #ICUParagraphLayout.
 
 */
 
class ICUParagraphLayoutFactory {
 
public:
 
	/** Helper for GetLayouter, to get the right type. */
 
	typedef UChar CharType;
 
	/** Helper for GetLayouter, to get whether the layouter supports RTL. */
 
	static const bool SUPPORTS_RTL = true;
 

	
 
	static ParagraphLayouter *GetParagraphLayout(UChar *buff, UChar *buff_end, FontMap &fontMapping)
 
	{
 
		int32 length = buff_end - buff;
 

	
 
	if (length == 0) {
 
		/* ICU's ParagraphLayout cannot handle empty strings, so fake one. */
 
		buff[0] = ' ';
 
		length = 1;
 
		fontMapping.End()[-1].first++;
 
		if (length == 0) {
 
			/* ICU's ParagraphLayout cannot handle empty strings, so fake one. */
 
			buff[0] = ' ';
 
			length = 1;
 
			fontMapping.End()[-1].first++;
 
		}
 

	
 
		/* Fill ICU's FontRuns with the right data. */
 
		FontRuns runs(fontMapping.Length());
 
		for (FontMap::iterator iter = fontMapping.Begin(); iter != fontMapping.End(); iter++) {
 
			runs.add(iter->second, iter->first);
 
		}
 

	
 
		LEErrorCode status = LE_NO_ERROR;
 
		/* ParagraphLayout does not copy "buff", so it must stay valid.
 
		 * "runs" is copied according to the ICU source, but the documentation does not specify anything, so this might break somewhen. */
 
		ParagraphLayout *p = new ParagraphLayout(buff, length, &runs, NULL, NULL, NULL, _current_text_dir == TD_RTL ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR, false, status);
 
		if (status != LE_NO_ERROR) {
 
			delete p;
 
			return NULL;
 
		}
 

	
 
		return new ICUParagraphLayout(p);
 
	}
 

	
 
	/* Fill ICU's FontRuns with the right data. */
 
	FontRuns runs(fontMapping.Length());
 
	for (FontMap::iterator iter = fontMapping.Begin(); iter != fontMapping.End(); iter++) {
 
		runs.add(iter->second, iter->first);
 
	static size_t AppendToBuffer(UChar *buff, const UChar *buffer_last, WChar c)
 
	{
 
		/* Transform from UTF-32 to internal ICU format of UTF-16. */
 
		int32 length = 0;
 
		UErrorCode err = U_ZERO_ERROR;
 
		u_strFromUTF32(buff, buffer_last - buff, &length, (UChar32*)&c, 1, &err);
 
		return length;
 
	}
 

	
 
	LEErrorCode status = LE_NO_ERROR;
 
	/* ParagraphLayout does not copy "buff", so it must stay valid.
 
	 * "runs" is copied according to the ICU source, but the documentation does not specify anything, so this might break somewhen. */
 
	ParagraphLayout *p = new ParagraphLayout(buff, length, &runs, NULL, NULL, NULL, _current_text_dir == TD_RTL ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR, false, status);
 
	if (status != LE_NO_ERROR) {
 
		delete p;
 
		return NULL;
 
	}
 

	
 
	return new ICUParagraphLayout(p);
 
}
 

	
 
};
 
#endif /* WITH_ICU_LAYOUT */
 

	
 
/*** Paragraph layout ***/
 
@@ -236,11 +241,6 @@ static ParagraphLayouter *GetParagraphLa
 
 */
 
class FallbackParagraphLayout : public ParagraphLayouter {
 
public:
 
	/** Helper for GetLayouter, to get the right type. */
 
	typedef WChar CharType;
 
	/** Helper for GetLayouter, to get whether the layouter supports RTL. */
 
	static const bool SUPPORTS_RTL = false;
 

	
 
	/** Visual run contains data about the bit of text with the same font. */
 
	class FallbackVisualRun : public ParagraphLayouter::VisualRun {
 
		Font *font;       ///< The font used to layout these.
 
@@ -281,6 +281,42 @@ public:
 
};
 

	
 
/**
 
 * Helper class to construct a new #FallbackParagraphLayout.
 
 */
 
class FallbackParagraphLayoutFactory {
 
public:
 
	/** Helper for GetLayouter, to get the right type. */
 
	typedef WChar CharType;
 
	/** Helper for GetLayouter, to get whether the layouter supports RTL. */
 
	static const bool SUPPORTS_RTL = false;
 

	
 
	/**
 
	 * Get the actual ParagraphLayout for the given buffer.
 
	 * @param buff The begin of the buffer.
 
	 * @param buff_end The location after the last element in the buffer.
 
	 * @param fontMapping THe mapping of the fonts.
 
	 * @return The ParagraphLayout instance.
 
	 */
 
	static ParagraphLayouter *GetParagraphLayout(WChar *buff, WChar *buff_end, FontMap &fontMapping)
 
	{
 
		return new FallbackParagraphLayout(buff, buff_end - buff, fontMapping);
 
	}
 

	
 
	/**
 
	 * Append a wide character to the internal buffer.
 
	 * @param buff        The buffer to append to.
 
	 * @param buffer_last The end of the buffer.
 
	 * @param c           The character to add.
 
	 * @return The number of buffer spaces that were used.
 
	 */
 
	static size_t AppendToBuffer(WChar *buff, const WChar *buffer_last, WChar c)
 
	{
 
		*buff = c;
 
		return 1;
 
	}
 
};
 

	
 
/**
 
 * Create the visual run.
 
 * @param font       The font to use for this run.
 
 * @param chars      The characters to use for this run.
 
@@ -537,31 +573,6 @@ const ParagraphLayouter::Line *FallbackP
 
}
 

	
 
/**
 
 * Appand a wide character to the internal buffer.
 
 * @param buff        The buffer to append to.
 
 * @param buffer_last The end of the buffer.
 
 * @param c           The character to add.
 
 * @return The number of buffer spaces that were used.
 
 */
 
static size_t AppendToBuffer(WChar *buff, const WChar *buffer_last, WChar c)
 
{
 
	*buff = c;
 
	return 1;
 
}
 

	
 
/**
 
 * Get the actual ParagraphLayout for the given buffer.
 
 * @param buff The begin of the buffer.
 
 * @param buff_end The location after the last element in the buffer.
 
 * @param fontMapping THe mapping of the fonts.
 
 * @return The ParagraphLayout instance.
 
 */
 
static FallbackParagraphLayout *GetParagraphLayout(WChar *buff, WChar *buff_end, FontMap &fontMapping)
 
{
 
	return new FallbackParagraphLayout(buff, buff_end - buff, fontMapping);
 
}
 

	
 
/**
 
 * Helper for getting a ParagraphLayouter of the given type.
 
 *
 
 * @note In case no ParagraphLayouter could be constructed, line.layout will be NULL.
 
@@ -605,7 +616,7 @@ static inline void GetLayouter(Layouter:
 
			 * will not be handled in the fallback non ICU case because they are
 
			 * mostly needed for RTL languages which need more ICU support. */
 
			if (!T::SUPPORTS_RTL && IsTextDirectionChar(c)) continue;
 
			buff += AppendToBuffer(buff, buffer_last, c);
 
			buff += T::AppendToBuffer(buff, buffer_last, c);
 
			continue;
 
		}
 

	
 
@@ -621,7 +632,7 @@ static inline void GetLayouter(Layouter:
 
	if (!fontMapping.Contains(buff - buff_begin)) {
 
		fontMapping.Insert(buff - buff_begin, f);
 
	}
 
	line.layout = GetParagraphLayout(buff_begin, buff, fontMapping);
 
	line.layout = T::GetParagraphLayout(buff_begin, buff, fontMapping);
 
	line.state_after = state;
 
}
 

	
 
@@ -658,7 +669,7 @@ Layouter::Layouter(const char *str, int 
 
			FontState old_state = state;
 
			const char *old_str = str;
 

	
 
			GetLayouter<ICUParagraphLayout>(line, str, state);
 
			GetLayouter<ICUParagraphLayoutFactory>(line, str, state);
 
			if (line.layout == NULL) {
 
				static bool warned = false;
 
				if (!warned) {
 
@@ -668,10 +679,10 @@ Layouter::Layouter(const char *str, int 
 

	
 
				state = old_state;
 
				str = old_str;
 
				GetLayouter<FallbackParagraphLayout>(line, str, state);
 
				GetLayouter<FallbackParagraphLayoutFactory>(line, str, state);
 
			}
 
#else
 
			GetLayouter<FallbackParagraphLayout>(line, str, state);
 
			GetLayouter<FallbackParagraphLayoutFactory>(line, str, state);
 
#endif
 
		}
 

	
0 comments (0 inline, 0 general)