Changeset - r28451:c8ec2474d01b
[Not reviewed]
master
0 11 0
Michael Lutz - 5 months ago 2023-12-15 23:06:19
michi@icosahedron.de
Change: Allow TrueType fonts to provide our private-use glyphs.
11 files changed with 29 insertions and 27 deletions:
0 comments (0 inline, 0 general)
src/fontcache.h
Show inline comments
 
@@ -108,9 +108,10 @@ public:
 
	/**
 
	 * Map a character into a glyph.
 
	 * @param key The character.
 
	 * @param fallback Allow fallback to the parent font.
 
	 * @return The glyph ID used to draw the character.
 
	 */
 
	virtual GlyphID MapCharToGlyph(char32_t key) = 0;
 
	virtual GlyphID MapCharToGlyph(char32_t key, bool fallback = true) = 0;
 

	
 
	/**
 
	 * Read a font table from the font.
src/fontcache/freetypefontcache.cpp
Show inline comments
 
@@ -41,7 +41,7 @@ public:
 
	FreeTypeFontCache(FontSize fs, FT_Face face, int pixels);
 
	~FreeTypeFontCache();
 
	void ClearFontCache() override;
 
	GlyphID MapCharToGlyph(char32_t key) override;
 
	GlyphID MapCharToGlyph(char32_t key, bool allow_fallback = true) override;
 
	std::string GetFontName() override { return fmt::format("{}, {}", face->family_name, face->style_name); }
 
	bool IsBuiltInFont() override { return false; }
 
	const void *GetOSHandle() override { return &face; }
 
@@ -276,15 +276,17 @@ const Sprite *FreeTypeFontCache::Interna
 
}
 

	
 

	
 
GlyphID FreeTypeFontCache::MapCharToGlyph(char32_t key)
 
GlyphID FreeTypeFontCache::MapCharToGlyph(char32_t key, bool allow_fallback)
 
{
 
	assert(IsPrintable(key));
 

	
 
	if (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
 
	FT_UInt glyph = FT_Get_Char_Index(this->face, key);
 

	
 
	if (glyph == 0 && allow_fallback && key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
 
		return this->parent->MapCharToGlyph(key);
 
	}
 

	
 
	return FT_Get_Char_Index(this->face, key);
 
	return glyph;
 
}
 

	
 
const void *FreeTypeFontCache::InternalGetFontTable(uint32_t tag, size_t &length)
src/fontcache/spritefontcache.h
Show inline comments
 
@@ -29,7 +29,7 @@ public:
 
	const Sprite *GetGlyph(GlyphID key) override;
 
	uint GetGlyphWidth(GlyphID key) override;
 
	bool GetDrawGlyphShadow() override;
 
	GlyphID MapCharToGlyph(char32_t key) override { assert(IsPrintable(key)); return SPRITE_GLYPH | key; }
 
	GlyphID MapCharToGlyph(char32_t key, [[maybe_unused]] bool allow_fallback = true) override { assert(IsPrintable(key)); return SPRITE_GLYPH | key; }
 
	const void *GetFontTable(uint32_t, size_t &length) override { length = 0; return nullptr; }
 
	std::string GetFontName() override { return "sprite"; }
 
	bool IsBuiltInFont() override { return true; }
src/gfx_layout_icu.cpp
Show inline comments
 
@@ -193,7 +193,7 @@ void ICURun::Shape(UChar *buff, size_t b
 
	for (unsigned int i = 0; i < glyph_count; i++) {
 
		int x_advance;
 

	
 
		if (buff[glyph_info[i].cluster] >= SCC_SPRITE_START && buff[glyph_info[i].cluster] <= SCC_SPRITE_END) {
 
		if (buff[glyph_info[i].cluster] >= SCC_SPRITE_START && buff[glyph_info[i].cluster] <= SCC_SPRITE_END && glyph_info[i].codepoint == 0) {
 
			auto glyph = this->font->fc->MapCharToGlyph(buff[glyph_info[i].cluster]);
 

	
 
			this->glyphs.push_back(glyph);
src/os/macosx/font_osx.cpp
Show inline comments
 
@@ -180,14 +180,10 @@ void CoreTextFontCache::SetFontSize(int 
 
	Debug(fontcache, 2, "Loaded font '{}' with size {}", this->font_name, pixels);
 
}
 

	
 
GlyphID CoreTextFontCache::MapCharToGlyph(char32_t key)
 
GlyphID CoreTextFontCache::MapCharToGlyph(char32_t key, bool allow_fallback)
 
{
 
	assert(IsPrintable(key));
 

	
 
	if (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
 
		return this->parent->MapCharToGlyph(key);
 
	}
 

	
 
	/* Convert characters outside of the Basic Multilingual Plane into surrogate pairs. */
 
	UniChar chars[2];
 
	if (key >= 0x010000U) {
 
@@ -202,6 +198,10 @@ GlyphID CoreTextFontCache::MapCharToGlyp
 
		return glyph[0];
 
	}
 

	
 
	if (allow_fallback && key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
 
		return this->parent->MapCharToGlyph(key);
 
	}
 

	
 
	return 0;
 
}
 

	
src/os/macosx/font_osx.h
Show inline comments
 
@@ -29,7 +29,7 @@ public:
 
	~CoreTextFontCache() {}
 

	
 
	void ClearFontCache() override;
 
	GlyphID MapCharToGlyph(char32_t key) override;
 
	GlyphID MapCharToGlyph(char32_t key, bool allow_fallback = true) override;
 
	std::string GetFontName() override { return font_name; }
 
	bool IsBuiltInFont() override { return false; }
 
	const void *GetOSHandle() override { return font.get(); }
src/os/macosx/string_osx.cpp
Show inline comments
 
@@ -189,9 +189,9 @@ static CTRunDelegateCallbacks _sprite_fo
 
		CFAttributedStringSetAttribute(str.get(), CFRangeMake(last, i.first - last), kCTForegroundColorAttributeName, color);
 
		CGColorRelease(color);
 

	
 
		/* Install a size callback for our special sprite glyphs. */
 
		/* Install a size callback for our special private-use sprite glyphs in case the font does not provide them. */
 
		for (ssize_t c = last; c < i.first; c++) {
 
			if (buff[c] >= SCC_SPRITE_START && buff[c] <= SCC_SPRITE_END) {
 
			if (buff[c] >= SCC_SPRITE_START && buff[c] <= SCC_SPRITE_END && i.second->fc->MapCharToGlyph(buff[c], false) == 0) {
 
				CFAutoRelease<CTRunDelegateRef> del(CTRunDelegateCreate(&_sprite_font_callback, (void *)(size_t)(buff[c] | (i.second->fc->GetSize() << 24))));
 
				CFAttributedStringSetAttribute(str.get(), CFRangeMake(c, 1), kCTRunDelegateAttributeName, del.get());
 
			}
 
@@ -242,7 +242,7 @@ CoreTextParagraphLayout::CoreTextVisualR
 
	CGGlyph gl[this->glyphs.size()];
 
	CTRunGetGlyphs(run, CFRangeMake(0, 0), gl);
 
	for (size_t i = 0; i < this->glyphs.size(); i++) {
 
		if (buff[this->glyph_to_char[i]] >= SCC_SPRITE_START && buff[this->glyph_to_char[i]] <= SCC_SPRITE_END) {
 
		if (buff[this->glyph_to_char[i]] >= SCC_SPRITE_START && buff[this->glyph_to_char[i]] <= SCC_SPRITE_END && gl[i] == 0) {
 
			this->glyphs[i] = font->fc->MapCharToGlyph(buff[this->glyph_to_char[i]]);
 
			this->positions[i * 2 + 0] = pts[i].x;
 
			this->positions[i * 2 + 1] = (font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(font->fc->GetSize()))) / 2; // Align sprite font to centre
src/os/windows/font_win32.cpp
Show inline comments
 
@@ -282,14 +282,10 @@ void Win32FontCache::ClearFontCache()
 
	return new_glyph.sprite;
 
}
 

	
 
/* virtual */ GlyphID Win32FontCache::MapCharToGlyph(char32_t key)
 
/* virtual */ GlyphID Win32FontCache::MapCharToGlyph(char32_t key, bool allow_fallback)
 
{
 
	assert(IsPrintable(key));
 

	
 
	if (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
 
		return this->parent->MapCharToGlyph(key);
 
	}
 

	
 
	/* Convert characters outside of the BMP into surrogate pairs. */
 
	WCHAR chars[2];
 
	if (key >= 0x010000U) {
 
@@ -302,7 +298,8 @@ void Win32FontCache::ClearFontCache()
 
	WORD glyphs[2] = { 0, 0 };
 
	GetGlyphIndicesW(this->dc, chars, key >= 0x010000U ? 2 : 1, glyphs, GGI_MARK_NONEXISTING_GLYPHS);
 

	
 
	return glyphs[0] != 0xFFFF ? glyphs[0] : 0;
 
	if (glyphs[0] != 0xFFFF) return glyphs[0];
 
	return allow_fallback && key >= SCC_SPRITE_START && key <= SCC_SPRITE_END ? this->parent->MapCharToGlyph(key) : 0;
 
}
 

	
 
/* virtual */ const void *Win32FontCache::InternalGetFontTable(uint32_t tag, size_t &length)
src/os/windows/font_win32.h
Show inline comments
 
@@ -35,7 +35,7 @@ public:
 
	Win32FontCache(FontSize fs, const LOGFONT &logfont, int pixels);
 
	~Win32FontCache();
 
	void ClearFontCache() override;
 
	GlyphID MapCharToGlyph(char32_t key) override;
 
	GlyphID MapCharToGlyph(char32_t key, bool allow_fallback = true) override;
 
	std::string GetFontName() override { return this->fontname; }
 
	const void *GetOSHandle() override { return &this->logfont; }
 
};
src/os/windows/string_uniscribe.cpp
Show inline comments
 
@@ -194,9 +194,11 @@ static bool UniscribeShapeRun(const Unis
 
				for (int i = 0; i < range.len; i++) {
 
					if (buff[range.pos + i] >= SCC_SPRITE_START && buff[range.pos + i] <= SCC_SPRITE_END) {
 
						auto pos = range.char_to_glyph[i];
 
						range.ft_glyphs[pos] = range.font->fc->MapCharToGlyph(buff[range.pos + i]);
 
						range.offsets[pos].dv = (range.font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(range.font->fc->GetSize()))) / 2; // Align sprite font to centre
 
						range.advances[pos] = range.font->fc->GetGlyphWidth(range.ft_glyphs[pos]);
 
						if (range.ft_glyphs[pos] == 0) { // Font doesn't have our special glyph, so remap.
 
							range.ft_glyphs[pos] = range.font->fc->MapCharToGlyph(buff[range.pos + i]);
 
							range.offsets[pos].dv = (range.font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(range.font->fc->GetSize()))) / 2; // Align sprite font to centre
 
							range.advances[pos] = range.font->fc->GetGlyphWidth(range.ft_glyphs[pos]);
 
						}
 
					}
 
				}
 

	
src/tests/mock_fontcache.h
Show inline comments
 
@@ -29,7 +29,7 @@ public:
 
	const Sprite *GetGlyph(GlyphID) override { return nullptr; }
 
	uint GetGlyphWidth(GlyphID) override { return this->height / 2; }
 
	bool GetDrawGlyphShadow() override { return false; }
 
	GlyphID MapCharToGlyph(char32_t key) override { return key; }
 
	GlyphID MapCharToGlyph(char32_t key, [[maybe_unused]] bool allow_fallback = true) override { return key; }
 
	const void *GetFontTable(uint32_t, size_t &length) override { length = 0; return nullptr; }
 
	std::string GetFontName() override { return "mock"; }
 
	bool IsBuiltInFont() override { return true; }
0 comments (0 inline, 0 general)