From eccc77a8c8e25ddc50dbc8cd85ad96b76e90ece5 Mon Sep 17 00:00:00 2001
From: David Marcec <dmarcecguzman@gmail.com>
Date: Thu, 23 Aug 2018 14:42:06 +1000
Subject: [PATCH 1/2] Added SharedFonts loading via TTF

By having the following TTF files in your yuzu sysdata directory. You can load sharedfonts via TTF files.
FontStandard.ttf
FontChineseSimplified.ttf
FontExtendedChineseSimplified.ttf
FontChineseTraditional.ttf
FontKorean.ttf
FontNintendoExtended.ttf
FontNintendoExtended2.ttf
---
 src/core/hle/service/ns/pl_u.cpp | 55 +++++++++++++++++++++++++++++---
 1 file changed, 50 insertions(+), 5 deletions(-)

diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp
index 53cbf1a6e..77f6da478 100644
--- a/src/core/hle/service/ns/pl_u.cpp
+++ b/src/core/hle/service/ns/pl_u.cpp
@@ -35,6 +35,14 @@ static constexpr std::array<std::pair<FontArchives, const char*>, 7> SHARED_FONT
     std::make_pair(FontArchives::Extension, "nintendo_ext_003.bfttf"),
     std::make_pair(FontArchives::Extension, "nintendo_ext2_003.bfttf")};
 
+static constexpr std::array<const char*, 7> SHARED_FONTS_TTF{"FontStandard.ttf",
+                                                             "FontChineseSimplified.ttf",
+                                                             "FontExtendedChineseSimplified.ttf",
+                                                             "FontChineseTraditional.ttf",
+                                                             "FontKorean.ttf",
+                                                             "FontNintendoExtended.ttf",
+                                                             "FontNintendoExtended2.ttf"};
+
 // The below data is specific to shared font data dumped from Switch on f/w 2.2
 // Virtual address and offsets/sizes likely will vary by dump
 static constexpr VAddr SHARED_FONT_MEM_VADDR{0x00000009d3016000ULL};
@@ -76,6 +84,16 @@ void DecryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output, s
     offset += transformed_font.size() * sizeof(u32);
 }
 
+void EncryptSharedFont(const std::vector<u8>& input, std::vector<u8>& output, size_t& offset) {
+    ASSERT_MSG(offset + input.size() + 8 < SHARED_FONT_MEM_SIZE, "Shared fonts exceeds 17mb!");
+    const u32 KEY = EXPECTED_MAGIC ^ EXPECTED_RESULT;
+    std::memcpy(output.data() + offset, &EXPECTED_RESULT, sizeof(u32)); // Magic header
+    const u32 ENC_SIZE = static_cast<u32>(input.size()) ^ KEY;
+    std::memcpy(output.data() + offset + sizeof(u32), &ENC_SIZE, sizeof(u32));
+    std::memcpy(output.data() + offset + (sizeof(u32) * 2), input.data(), input.size());
+    offset += input.size() + (sizeof(u32) * 2);
+}
+
 static u32 GetU32Swapped(const u8* data) {
     u32 value;
     std::memcpy(&value, data, sizeof(value));
@@ -109,10 +127,10 @@ PL_U::PL_U() : ServiceFramework("pl:u") {
     RegisterHandlers(functions);
     // Attempt to load shared font data from disk
     const auto nand = FileSystem::GetSystemNANDContents();
+    size_t offset = 0;
     // Rebuild shared fonts from data ncas
     if (nand->HasEntry(static_cast<u64>(FontArchives::Standard),
                        FileSys::ContentRecordType::Data)) {
-        size_t offset = 0;
         shared_font = std::make_shared<std::vector<u8>>(SHARED_FONT_MEM_SIZE);
         for (auto font : SHARED_FONTS) {
             const auto nca =
@@ -152,18 +170,45 @@ PL_U::PL_U() : ServiceFramework("pl:u") {
             DecryptSharedFont(font_data_u32, *shared_font, offset);
             SHARED_FONT_REGIONS.push_back(region);
         }
+
     } else {
-        const std::string filepath{FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir) +
-                                   SHARED_FONT};
+        shared_font = std::make_shared<std::vector<u8>>(
+            SHARED_FONT_MEM_SIZE); // Shared memory needs to always be allocated and a fixed size
+
+        const std::string user_path = FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir);
+        const std::string filepath{user_path + SHARED_FONT};
+
         // Create path if not already created
         if (!FileUtil::CreateFullPath(filepath)) {
             LOG_ERROR(Service_NS, "Failed to create sharedfonts path \"{}\"!", filepath);
             return;
         }
+
+        bool using_ttf = false;
+        for (auto FontTTF : SHARED_FONTS_TTF) {
+            if (FileUtil::Exists(user_path + FontTTF)) {
+                using_ttf = true;
+                FileUtil::IOFile file(user_path + FontTTF, "rb");
+                if (file.IsOpen()) {
+                    std::vector<u8> ttf_bytes(file.GetSize());
+                    file.ReadBytes<u8>(ttf_bytes.data(), ttf_bytes.size());
+                    FontRegion region{
+                        static_cast<u32>(offset + 8),
+                        static_cast<u32>(ttf_bytes.size())}; // Font offset and size do not account
+                                                             // for the header
+                    EncryptSharedFont(ttf_bytes, *shared_font, offset);
+                    SHARED_FONT_REGIONS.push_back(region);
+                } else {
+                    LOG_WARNING(Service_NS, "Unable to load font: {}", FontTTF);
+                }
+            } else if (using_ttf) {
+                LOG_WARNING(Service_NS, "Unable to find font: {}", FontTTF);
+            }
+        }
+        if (using_ttf)
+            return;
         FileUtil::IOFile file(filepath, "rb");
 
-        shared_font = std::make_shared<std::vector<u8>>(
-            SHARED_FONT_MEM_SIZE); // Shared memory needs to always be allocated and a fixed size
         if (file.IsOpen()) {
             // Read shared font data
             ASSERT(file.GetSize() == SHARED_FONT_MEM_SIZE);

From 78b109d19533af6c10414894cf75b6db1a3801be Mon Sep 17 00:00:00 2001
From: David Marcec <dmarcecguzman@gmail.com>
Date: Fri, 24 Aug 2018 02:18:04 +1000
Subject: [PATCH 2/2] Addressed plu TTF changes

---
 src/core/hle/service/ns/pl_u.cpp | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp
index 77f6da478..923a52cc5 100644
--- a/src/core/hle/service/ns/pl_u.cpp
+++ b/src/core/hle/service/ns/pl_u.cpp
@@ -84,7 +84,8 @@ void DecryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output, s
     offset += transformed_font.size() * sizeof(u32);
 }
 
-void EncryptSharedFont(const std::vector<u8>& input, std::vector<u8>& output, size_t& offset) {
+static void EncryptSharedFont(const std::vector<u8>& input, std::vector<u8>& output,
+                              size_t& offset) {
     ASSERT_MSG(offset + input.size() + 8 < SHARED_FONT_MEM_SIZE, "Shared fonts exceeds 17mb!");
     const u32 KEY = EXPECTED_MAGIC ^ EXPECTED_RESULT;
     std::memcpy(output.data() + offset, &EXPECTED_RESULT, sizeof(u32)); // Magic header
@@ -185,10 +186,10 @@ PL_U::PL_U() : ServiceFramework("pl:u") {
         }
 
         bool using_ttf = false;
-        for (auto FontTTF : SHARED_FONTS_TTF) {
-            if (FileUtil::Exists(user_path + FontTTF)) {
+        for (const char* font_ttf : SHARED_FONTS_TTF) {
+            if (FileUtil::Exists(user_path + font_ttf)) {
                 using_ttf = true;
-                FileUtil::IOFile file(user_path + FontTTF, "rb");
+                FileUtil::IOFile file(user_path + font_ttf, "rb");
                 if (file.IsOpen()) {
                     std::vector<u8> ttf_bytes(file.GetSize());
                     file.ReadBytes<u8>(ttf_bytes.data(), ttf_bytes.size());
@@ -199,10 +200,10 @@ PL_U::PL_U() : ServiceFramework("pl:u") {
                     EncryptSharedFont(ttf_bytes, *shared_font, offset);
                     SHARED_FONT_REGIONS.push_back(region);
                 } else {
-                    LOG_WARNING(Service_NS, "Unable to load font: {}", FontTTF);
+                    LOG_WARNING(Service_NS, "Unable to load font: {}", font_ttf);
                 }
             } else if (using_ttf) {
-                LOG_WARNING(Service_NS, "Unable to find font: {}", FontTTF);
+                LOG_WARNING(Service_NS, "Unable to find font: {}", font_ttf);
             }
         }
         if (using_ttf)