summaryrefslogtreecommitdiff
path: root/src/fontpack.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fontpack.c')
-rw-r--r--src/fontpack.c101
1 files changed, 100 insertions, 1 deletions
diff --git a/src/fontpack.c b/src/fontpack.c
index a440234e..924d4781 100644
--- a/src/fontpack.c
+++ b/src/fontpack.c
@@ -23,6 +23,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
23#include "fontpack.h" 23#include "fontpack.h"
24#include "resources.h" 24#include "resources.h"
25#include "ui/window.h" 25#include "ui/window.h"
26#include "gmrequest.h"
26#include "app.h" 27#include "app.h"
27 28
28#include <the_Foundation/archive.h> 29#include <the_Foundation/archive.h>
@@ -1018,6 +1019,7 @@ void install_Fonts(const iString *packId, const iBlock *data) {
1018 iRelease(f); 1019 iRelease(f);
1019 /* Newly installed fontpacks may have a higher priority that overrides other fonts. */ 1020 /* Newly installed fontpacks may have a higher priority that overrides other fonts. */
1020 reload_Fonts(); 1021 reload_Fonts();
1022 availableFontsChanged_App();
1021} 1023}
1022 1024
1023void installFontFile_Fonts(const iString *fileName, const iBlock *data) { 1025void installFontFile_Fonts(const iString *fileName, const iBlock *data) {
@@ -1028,6 +1030,7 @@ void installFontFile_Fonts(const iString *fileName, const iBlock *data) {
1028 } 1030 }
1029 iRelease(f); 1031 iRelease(f);
1030 reload_Fonts(); 1032 reload_Fonts();
1033 availableFontsChanged_App();
1031} 1034}
1032 1035
1033void enablePack_Fonts(const iString *packId, iBool enable) { 1036void enablePack_Fonts(const iString *packId, iBool enable) {
@@ -1040,6 +1043,7 @@ void enablePack_Fonts(const iString *packId, iBool enable) {
1040 } 1043 }
1041 updateActive_Fonts(); 1044 updateActive_Fonts();
1042 resetFonts_App(); 1045 resetFonts_App();
1046 availableFontsChanged_App();
1043 invalidate_Window(get_MainWindow()); 1047 invalidate_Window(get_MainWindow());
1044} 1048}
1045 1049
@@ -1047,5 +1051,100 @@ void updateActive_Fonts(void) {
1047 sortSpecs_Fonts_(&fonts_); 1051 sortSpecs_Fonts_(&fonts_);
1048} 1052}
1049 1053
1050iDefineClass(FontFile) 1054static void findCharactersInCMap_(iGmRequest *d, iGmRequest *req) {
1055 /* Note: Called in background thread. */
1056 iUnused(req);
1057 const iString *missingChars = userData_Object(d);
1058 if (isSuccess_GmStatusCode(status_GmRequest(d))) {
1059 iStringList *matchingPacks = new_StringList();
1060 iChar needed[20];
1061 iChar minChar = UINT32_MAX, maxChar = 0;
1062 size_t numNeeded = 0;
1063 iConstForEach(String, ch, missingChars) {
1064 needed[numNeeded++] = ch.value;
1065 minChar = iMin(minChar, ch.value);
1066 maxChar = iMax(maxChar, ch.value);
1067 if (numNeeded == iElemCount(needed)) {
1068 /* Shouldn't be that many. */
1069 break;
1070 }
1071 }
1072 iBlock *data = decompressGzip_Block(body_GmRequest(d));
1073 iRangecc line = iNullRange;
1074 while (nextSplit_Rangecc(range_Block(data), "\n", &line)) {
1075 iRangecc fontpackPath = iNullRange;
1076 for (const char *pos = line.start; pos < line.end; pos++) {
1077 if (*pos == ':') {
1078 fontpackPath.start = line.start;
1079 fontpackPath.end = pos;
1080 line.start = pos + 1;
1081 trimStart_Rangecc(&line);
1082 break;
1083 }
1084 }
1085 if (fontpackPath.start) {
1086 /* Parse the character ranges and see if any match what we need. */
1087 const char *pos = line.start;
1088 while (pos < line.end) {
1089 char *endp;
1090 uint32_t first = strtoul(pos, &endp, 10);
1091 uint32_t last = first;
1092 if (*endp == '-') {
1093 last = strtoul(endp + 1, &endp, 10);
1094 }
1095 if (maxChar < first) {
1096 break; /* The rest are even higher. */
1097 }
1098 if (minChar <= last) {
1099 for (size_t i = 0; i < numNeeded; i++) {
1100 if (needed[i] >= first && needed[i] <= last) {
1101 /* Got it. */
1102 pushBackRange_StringList(matchingPacks, fontpackPath);
1103 break;
1104 }
1105 }
1106 }
1107 pos = endp + 1;
1108 }
1109 }
1110 }
1111 delete_Block(data);
1112 iString result;
1113 init_String(&result);
1114 format_String(&result, "font.found chars:%s packs:", cstr_String(missingChars));
1115 iConstForEach(StringList, s, matchingPacks) {
1116 if (s.pos != 0) {
1117 appendCStr_String(&result, ",");
1118 }
1119 append_String(&result, s.value);
1120 }
1121 postCommandString_Root(NULL, &result);
1122 deinit_String(&result);
1123 iRelease(matchingPacks);
1124 }
1125 else {
1126 /* Report error. */
1127 postCommandf_Root(NULL,
1128 "font.found chars:%s error:%d msg:\x1b[1m%s\x1b[0m\n%s",
1129 cstr_String(missingChars),
1130 status_GmRequest(d),
1131 cstr_String(meta_GmRequest(d)),
1132 cstr_String(url_GmRequest(d)));
1133 }
1134// fflush(stdout);
1135 delete_String(userData_Object(d));
1136 /* We can't delete ourselves; threads must be joined from another thread. */
1137 SDL_PushEvent((SDL_Event *) &(SDL_UserEvent){
1138 .type = SDL_USEREVENT, .code = releaseObject_UserEventCode, .data1 = d });
1139}
1051 1140
1141void searchOnlineLibraryForCharacters_Fonts(const iString *chars) {
1142 /* Fetch the character map from skyjake.fi. */
1143 iGmRequest *req = new_GmRequest(certs_App());
1144 setUrl_GmRequest(req, collectNewCStr_String("gemini://skyjake.fi/fonts/cmap.txt.gz"));
1145 setUserData_Object(req, copy_String(chars));
1146 iConnect(GmRequest, req, finished, req, findCharactersInCMap_);
1147 submit_GmRequest(req);
1148}
1149
1150iDefineClass(FontFile)