Browse Source

Let's add some emojis!

Michael Ragazzon 6 years ago
parent
commit
5655f84cf4

+ 97 - 0
Samples/assets/LICENSE.txt

@@ -0,0 +1,97 @@
+The Noto Emoji font, located in the file 'NotoEmoji-Regular.ttf', is part of the Noto Project. See google.com/get/noto for more information. The font is licensed under the SIL Open Font License v1.1. Full license stated below.
+
+
+-----------------------------------------------------------
+
+This Font Software is licensed under the SIL Open Font License,
+Version 1.1.
+
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font
+creation efforts of academic and linguistic communities, and to
+provide a free and open framework in which fonts may be shared and
+improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply to
+any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software
+components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to,
+deleting, or substituting -- in part or in whole -- any of the
+components of the Original Version, by changing formats or by porting
+the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed,
+modify, redistribute, and sell modified and unmodified copies of the
+Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in
+Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the
+corresponding Copyright Holder. This restriction only applies to the
+primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created using
+the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.

BIN
Samples/assets/NotoEmoji-Regular.ttf


+ 7 - 1
Samples/basic/demo/data/demo.rml

@@ -116,6 +116,11 @@ button:focus {
 {
 	decorator: ninepatch(button-active, button-inner-active);
 }
+.emoji-test
+{
+	font-family: Noto Emoji;
+	font-size: 35px;
+}
 
 </style>
 </head>
@@ -124,7 +129,8 @@ button:focus {
 
 <div style="font-size: 0.85em; text-align: left;" id="fps"></div>
 
-<p><br/><br/>Strings: abc (æøå) def</p>
+<p class="font-test"><br/><br/>abc Å (æø 😍 å∞) Å def</p>
+<p class="emoji-test">abc 😍 def</p>
 
 <tabset id="menu">
 <tab>Decorators</tab>

+ 2 - 1
Samples/shell/src/Shell.cpp

@@ -32,11 +32,12 @@
 /// Loads the default fonts from the given path.
 void Shell::LoadFonts(const char* directory)
 {
-	Rml::Core::String font_names[4];
+	Rml::Core::String font_names[5];
 	font_names[0] = "Delicious-Roman.otf";
 	font_names[1] = "Delicious-Italic.otf";
 	font_names[2] = "Delicious-Bold.otf";
 	font_names[3] = "Delicious-BoldItalic.otf";
+	font_names[4] = "NotoEmoji-Regular.ttf";
 
 	for (int i = 0; i < sizeof(font_names) / sizeof(Rml::Core::String); i++)
 	{

+ 1 - 1
Source/Controls/WidgetTextInput.cpp

@@ -476,7 +476,7 @@ bool WidgetTextInput::AddCharacter(Rml::Core::CodePoint character)
 	Core::String insert = Core::StringUtilities::ToUTF8(character);
 	value.insert(GetCursorIndex(), insert);
 
-	edit_index += 1;
+	edit_index += insert.size();
 
 	GetElement()->SetAttribute("value", value);
 	DispatchChangeEvent();

+ 43 - 31
Source/Core/FreeType/FontFaceHandle.cpp

@@ -36,7 +36,7 @@
 namespace Rml {
 namespace Core {
 
-static FontGlyph BuildGlyph(FT_GlyphSlot ft_glyph);
+static bool BuildGlyph(FT_Face ft_face, CodePoint code_point, FontGlyphMap& glyphs);
 static void BuildGlyphMap(FT_Face ft_face, FontGlyphMap& glyphs, int size);
 static void GenerateMetrics(FT_Face ft_face, const FontGlyphMap& glyphs, FontMetrics& metrics);
 
@@ -77,40 +77,25 @@ bool FontFaceHandle_FreeType::Initialise(FT_Face ft_face, int size)
 	return true;
 }
 
+
 static void BuildGlyphMap(FT_Face ft_face, FontGlyphMap& glyphs, int size)
 {
-	// TODO: ASCII range for now
+	glyphs.reserve(128);
+
+	// Add the ASCII character set
+	// TODO: only ASCII range for now
 	FT_ULong code_min = 32;
 	FT_ULong code_max = 126;
 
-	glyphs.reserve(code_max - code_min + 2);
-
 	for (FT_ULong character_code = code_min; character_code <= code_max; ++character_code)
-	{
-		// Add 'ø' character for testing. TODO: Remove!
-		if (character_code == 126)
-			character_code = 0xf8;
+		BuildGlyph(ft_face, (CodePoint)character_code, glyphs);
 
-		int index = FT_Get_Char_Index(ft_face, character_code);
-		if (index != 0)
-		{
-			FT_Error error = FT_Load_Glyph(ft_face, index, 0);
-			if (error != 0)
-			{
-				Log::Message(Log::LT_WARNING, "Unable to load glyph for character '%u' on the font face '%s %s'; error code: %d.", character_code, ft_face->family_name, ft_face->style_name, error);
-				continue;
-			}
-
-			error = FT_Render_Glyph(ft_face->glyph, FT_RENDER_MODE_NORMAL);
-			if (error != 0)
-			{
-				Log::Message(Log::LT_WARNING, "Unable to render glyph for character '%u' on the font face '%s %s'; error code: %d.", character_code, ft_face->family_name, ft_face->style_name, error);
-				continue;
-			}
-
-			glyphs[(CodePoint)character_code] = BuildGlyph(ft_face->glyph);
-		}
-	}
+	// Add some widebyte characters (in UTF-8) for testing. TODO: Remove!
+	BuildGlyph(ft_face, (CodePoint)0xe5, glyphs); // 'å'
+	BuildGlyph(ft_face, (CodePoint)0xe6, glyphs); // 'æ'
+	BuildGlyph(ft_face, (CodePoint)0xf8, glyphs); // 'ø'
+	BuildGlyph(ft_face, (CodePoint)0x221e, glyphs); // '∞'
+	BuildGlyph(ft_face, (CodePoint)0x1f60d, glyphs); // '😍'
 
 	// Add a replacement character for rendering unknown characters.
 	CodePoint replacement_character = CodePoint::Replacement;
@@ -140,9 +125,36 @@ static void BuildGlyphMap(FT_Face ft_face, FontGlyphMap& glyphs, int size)
 	}
 }
 
-static FontGlyph BuildGlyph(FT_GlyphSlot ft_glyph)
+static bool BuildGlyph(FT_Face ft_face, CodePoint code_point, FontGlyphMap& glyphs)
 {
-	FontGlyph glyph;
+	int index = FT_Get_Char_Index(ft_face, (FT_ULong)code_point);
+	if (index == 0)
+		return false;
+	
+	FT_Error error = FT_Load_Glyph(ft_face, index, 0);
+	if (error != 0)
+	{
+		Log::Message(Log::LT_WARNING, "Unable to load glyph for character '%u' on the font face '%s %s'; error code: %d.", code_point, ft_face->family_name, ft_face->style_name, error);
+		return false;
+	}
+
+	error = FT_Render_Glyph(ft_face->glyph, FT_RENDER_MODE_NORMAL);
+	if (error != 0)
+	{
+		Log::Message(Log::LT_WARNING, "Unable to render glyph for character '%u' on the font face '%s %s'; error code: %d.", code_point, ft_face->family_name, ft_face->style_name, error);
+		return false;
+	}
+
+	auto result = glyphs.emplace(code_point, FontGlyph{});
+	if (!result.second)
+	{
+		Log::Message(Log::LT_WARNING, "Glyph character '%u' is already loaded in the font face '%s %s'.", code_point, ft_face->family_name, ft_face->style_name);
+		return false;
+	}
+
+	FontGlyph& glyph = result.first->second;
+
+	FT_GlyphSlot ft_glyph = ft_face->glyph;
 
 	// Set the glyph's dimensions.
 	glyph.dimensions.x = ft_glyph->metrics.width >> 6;
@@ -226,7 +238,7 @@ static FontGlyph BuildGlyph(FT_GlyphSlot ft_glyph)
 		glyph.bitmap_data = nullptr;
 	}
 
-	return glyph;
+	return true;
 }
 
 

+ 1 - 1
Source/Core/StringUtilities.cpp

@@ -337,7 +337,7 @@ CodePoint StringUtilities::ToCodePoint(const char* p)
 			return CodePoint::Null;
 		}
 
-		code |= ((byte & 0b0011'1111) << 8 * i);
+		code = ((code << 6) | (byte & 0b0011'1111));
 	}
 
 	return static_cast<CodePoint>(code);