/
vTech
/
FcApps
Обзор
Документация
Войти
/
vTech
/
FcApps
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
FcLibs/FcFont/src/FcFont.c
350 строк
11 KB
vTech
alpha_00
03 дек 2025, 17:45
03 дек 2025, 17:45
ab8382d
Код
Авторство
О чём код?
#include "FcFont.h" #ifdef _WIN32 LPCTSTR fontRegistryPath = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"); const TCHAR fontPath[] = TEXT("C:\\Windows\\Fonts\\"); FcFont_Error_t FcFont_GetSystemFonts_malloc(FcFont_TrueType_systemFonts_t** resultFontFiles) { //TCHAR winDir[MAX_PATH]; HKEY hKey; LONG mError; DWORD i, j, mOffset; DWORD maxValueNameLength, maxValueDataLength, pathLength; DWORD valueNameLength, valueDataLength, valueType, nameLength, dataLength, ptrSize; DWORD lpcCount; LPTSTR valueName, mDst; LPBYTE valueData; LPCTSTR mSrc; FcFont_TrueType_systemFonts_t* mArrayFonts; nameLength = dataLength = 0; valueData = NULL; valueName = NULL; mError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, fontRegistryPath, 0, KEY_READ, &hKey); if (mError != ERROR_SUCCESS) goto gError; mError = RegQueryInfoKey(hKey, 0, 0, 0, 0, 0, 0, &lpcCount, &maxValueNameLength, &maxValueDataLength, 0, 0); if (mError != ERROR_SUCCESS) goto gError; pathLength = (sizeof(fontPath) - 1) / sizeof(TCHAR); valueName = (LPTSTR)calloc(1, (maxValueNameLength + 1) * sizeof(TCHAR)); valueData = (LPBYTE)calloc(1, (maxValueDataLength + 1) * sizeof(BYTE)); if (valueName == NULL) goto gError; if (valueData == NULL) goto gError; for (i = 0; i < lpcCount; i++) { valueDataLength = maxValueDataLength; valueNameLength = maxValueNameLength; mError = RegEnumValue(hKey, i, valueName, &valueNameLength, 0, &valueType, valueData, &valueDataLength); if (mError != ERROR_SUCCESS || valueType != REG_SZ) continue; nameLength += valueNameLength + 1; dataLength += valueDataLength + pathLength + 1; } ptrSize = lpcCount * (sizeof(FcFont_TrueType_systemFonts_t) - sizeof(size_t)) + sizeof(size_t); mArrayFonts = (FcFont_TrueType_systemFonts_t*)malloc(nameLength * sizeof(TCHAR) + dataLength * sizeof(TCHAR) + ptrSize + sizeof(TCHAR*)); if (lpcCount == 0 || !mArrayFonts) { free(mArrayFonts); *resultFontFiles = NULL; goto gError;; } *resultFontFiles = mArrayFonts; mArrayFonts->mNumberFonts = lpcCount; valueDataLength = 0; valueNameLength = 0; mOffset = nameLength; nameLength = 0; dataLength = 0; for (i = 0; i < lpcCount; i++) { valueDataLength = maxValueDataLength; valueNameLength = maxValueNameLength; mArrayFonts->mFont[i].name = ((TCHAR*) &mArrayFonts->mFont[lpcCount].name) + nameLength; mArrayFonts->mFont[i].data = ((TCHAR*) &mArrayFonts->mFont[lpcCount].name) + mOffset + dataLength; mError = RegEnumValue(hKey, i, valueName, &valueNameLength, 0, &valueType, valueData, &valueDataLength); if (mError != ERROR_SUCCESS || valueType != REG_SZ) continue; mSrc = valueName; mDst = mArrayFonts->mFont[i].name; for (j = 0; j <= valueNameLength; j++) mDst[j] = mSrc[j]; mSrc = fontPath; mDst = mArrayFonts->mFont[i].data; for (j = 0; j < pathLength; j++) mDst[j] = mSrc[j]; mSrc = valueData; mDst = mArrayFonts->mFont[i].data + j; for (j = 0; j < valueDataLength; j++) mDst[j] = mSrc[j]; nameLength += valueNameLength + 1; dataLength += valueDataLength + pathLength + 1; } gError: RegCloseKey(hKey); free(valueName); free(valueData); if (mError) { SetLastError(mError); return FCFONT_ERROR_WINAPI; } else return mError; } FcFont_Error_t FcFont_GetSystemFontFile_malloc(const TCHAR* fontName, TCHAR** resultFontFile) { TCHAR winDir[MAX_PATH]; TCHAR* ptrResultFontFile; HKEY hKey; LONG mError; DWORD valueIndex, i, i_end, dirLength; DWORD maxValueNameSize, maxValueDataSize; DWORD valueNameLength, valueDataLength, valueType; LPTSTR valueName; LPBYTE valueData; const size_t cSize = _tcslen(fontName) + 1; valueData = NULL; valueName = NULL; mError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, fontRegistryPath, 0, KEY_READ, &hKey); if (mError != ERROR_SUCCESS) goto gError; mError = RegQueryInfoKey(hKey, 0, 0, 0, 0, 0, 0, 0, &maxValueNameSize, &maxValueDataSize, 0, 0); if (mError != ERROR_SUCCESS) goto gError; dirLength = GetWindowsDirectory(winDir, MAX_PATH); if (dirLength == 0) goto gError; valueIndex = 0; valueName = (LPTSTR)malloc(maxValueNameSize * sizeof(TCHAR)); valueData = (LPBYTE)malloc(maxValueDataSize * sizeof(BYTE)); if (valueName == NULL) goto gError; if (valueData == NULL) goto gError; do { valueDataLength = maxValueDataSize; valueNameLength = maxValueNameSize; mError = RegEnumValue(hKey, valueIndex, valueName, &valueNameLength, 0, &valueType, valueData, &valueDataLength); valueIndex++; if (mError != ERROR_SUCCESS || valueType != REG_SZ) continue; if (_tcsnicmp(fontName, valueName, cSize) == 0) break; } while (mError != ERROR_NO_MORE_ITEMS); if (mError == ERROR_NO_MORE_ITEMS) goto gError;; ptrResultFontFile = (TCHAR*)calloc(1, (sizeof("\\Fonts\\") + dirLength + valueDataLength) * sizeof(TCHAR)); *resultFontFile = ptrResultFontFile; if (ptrResultFontFile == NULL) goto gError; for (i = 0, i_end = dirLength; i < i_end; i++) ptrResultFontFile[i] = winDir[i]; ptrResultFontFile[i + 0] = (TCHAR)'\\'; ptrResultFontFile[i + 1] = (TCHAR)'F'; ptrResultFontFile[i + 2] = (TCHAR)'o'; ptrResultFontFile[i + 3] = (TCHAR)'n'; ptrResultFontFile[i + 4] = (TCHAR)'t'; ptrResultFontFile[i + 5] = (TCHAR)'s'; ptrResultFontFile[i + 6] = (TCHAR)'\\'; for (i = 0, i_end = valueDataLength; i < i_end; i++) ptrResultFontFile[dirLength + (sizeof("\\Fonts\\") - 1) + i] = valueData[i]; gError: RegCloseKey(hKey); free(valueName); free(valueData); if (mError) { SetLastError(mError); return FCFONT_ERROR_WINAPI; } else return mError; } #endif #if defined(linux) || defined(__linux) #include <sys/types.h> #include <dirent.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <stddef.h> #include <errno.h> const char* fontDirectory[] = { "/usr/share/fonts", "/usr/local/share/fonts", "~/.fonts" }; const char* fontConfigs[] = { "/etc/fonts/fonts.conf", "/etc/fonts/local.conf." }; char* FcFont_GetSystemFonts_findfiles(size_t* numberFiles, size_t** namesOffsets) { size_t m_numberDirs = 1; size_t m_sizeNames = 256; size_t m_sizeDirNames = 256; size_t m_numberNames = 0; size_t m_numberPath = sizeof(fontDirectory) / sizeof(fontDirectory[0]); size_t i, j0, j1, j2, j3, j4, m_nextOffset = 0; DIR* m_dir; char* m_names = (char*)malloc(m_sizeNames * sizeof(char)); size_t* m_namesOffsets = NULL; char* m_nameDirs = (char*)malloc(m_sizeDirNames); size_t* m_offsetDirs = (size_t*)malloc(m_numberDirs * sizeof(size_t)); *numberFiles = 0; m_offsetDirs[0] = 0; for (j4 = 0; j4 < m_numberPath; j4++) { i = 0; m_numberDirs = 1; size_t m_length = strlen(fontDirectory[j4]); j3 = m_offsetDirs[i]; j0 = m_offsetDirs[m_numberDirs - 1]; do { if (j0 >= m_sizeDirNames) { m_sizeDirNames += m_length + 2; m_nameDirs = (char*)realloc(m_nameDirs, m_sizeDirNames); } for (j1 = 0; j0 < m_sizeDirNames && fontDirectory[j4][j1]; j1++, j0++) m_nameDirs[j0] = fontDirectory[j4][j1]; if (j0 < m_sizeDirNames && fontDirectory[j4][j1] == 0) m_nameDirs[j0] = 0; m_offsetDirs[i] = j0 + 1; } while (j0 >= m_sizeDirNames); for (i = 0; i < m_numberDirs; i++) { if ((m_dir = opendir(m_nameDirs + j3)) != NULL) { struct dirent* entry; while ((entry = readdir(m_dir)) != NULL) { if (entry->d_name[0] == '.') continue; if (entry->d_name[0] == '.' && entry->d_name[1] == '.') continue; m_length = strlen(entry->d_name); if (entry->d_type == DT_DIR) { j0 = m_offsetDirs[m_numberDirs - 1]; j2 = j3; j1 = 0; do { if (j0 >= m_sizeDirNames) { m_sizeDirNames += m_length + 1; m_nameDirs = (char*)realloc(m_nameDirs, m_sizeDirNames); } for (; j0 < m_sizeDirNames && m_nameDirs[j2]; j0++, j2++) m_nameDirs[j0] = m_nameDirs[j2]; if (j0 < m_sizeDirNames && m_nameDirs[j2] == 0 && j1 == 0) m_nameDirs[j0++] = '/'; for (; j0 < m_sizeDirNames && entry->d_name[j1]; j1++, j0++) m_nameDirs[j0] = entry->d_name[j1]; } while (j0 >= m_sizeDirNames); m_nameDirs[j0] = 0; m_numberDirs++; m_offsetDirs = (size_t*)realloc(m_offsetDirs, m_numberDirs * sizeof(size_t)); m_offsetDirs[m_numberDirs - 1] = j0 + 1; } else if (entry->d_type == DT_REG) { if (m_length < 3) continue; if (entry->d_name[m_length - 1] != 'f' || entry->d_name[m_length - 2] != 't' || entry->d_name[m_length - 3] != 't') continue; j0 = m_nextOffset; j2 = j3; j1 = 0; do { if (j0 >= m_sizeNames) { m_sizeNames += m_length + 1; m_names = (char*)realloc(m_names, m_sizeNames); } for (; j0 < m_sizeNames && m_nameDirs[j2]; j0++, j2++) m_names[j0] = m_nameDirs[j2]; if (j0 < m_sizeNames && m_nameDirs[j2] == 0 && j1 == 0) m_names[j0++] = '/'; for (; j0 < m_sizeNames && entry->d_name[j1]; j1++, j0++) m_names[j0] = entry->d_name[j1]; } while (j0 >= m_sizeNames); m_names[j0] = 0; m_numberNames++; m_namesOffsets = (size_t*)realloc(m_namesOffsets, m_numberNames * sizeof(size_t)); m_namesOffsets[m_numberNames - 1] = m_nextOffset; m_nextOffset = j0 + 1; } } closedir(m_dir); } j3 = m_offsetDirs[i]; } } for (i = 0; i < m_numberNames; i++) printf("%s\n", m_names + m_namesOffsets[i]); free(m_nameDirs); free(m_offsetDirs); *numberFiles = m_numberNames; *namesOffsets = m_namesOffsets; return m_names; } FcFont_Error_t FcFont_GetSystemFonts_malloc(FcFont_TrueType_systemFonts_t** resultFontFiles) { FcFont_TrueType_systemFonts_t* m_font; uint32_t i, j, j_end; size_t* m_namesOffset; size_t m_numberFiles; char* m_names = FcFont_GetSystemFonts_findfiles(&m_numberFiles, &m_namesOffset); m_font = NULL; if (m_names) { j_end = m_namesOffset[m_numberFiles - 1]; m_font = malloc(offsetof(FcFont_TrueType_systemFonts_t, mFont) + m_numberFiles * 2 * sizeof(char*) + j_end); m_font->mNumberFonts = m_numberFiles; for (i = 0; i < m_numberFiles; i++) { m_font->mFont[i].data = ((char*)(m_font->mFont + m_numberFiles)) + m_namesOffset[i]; } for (j = 0; j < j_end; j++) ((char*)(m_font->mFont + m_numberFiles))[j] = m_names[j]; for (i = 1; i < m_numberFiles; i++) { for (j = m_namesOffset[i] - 1; j && ((char*)(m_font->mFont + m_numberFiles))[j] != '/'; j--) m_font->mFont[i - 1].name = ((char*)(m_font->mFont + m_numberFiles)) + j + 1; } if (j_end) { for (j = j_end - 1; j && ((char*)(m_font->mFont + m_numberFiles))[j] != '/'; j--) m_font->mFont[i - 1].name = ((char*)(m_font->mFont + m_numberFiles)) + j + 1; } } free(m_namesOffset); free(m_names); *resultFontFiles = m_font; return 0; } FcFont_Error_t FcFont_GetSystemFontFile_malloc(const TCHAR* faceName, TCHAR** resultFontFile) { size_t i, j = 0, j_end; size_t* m_namesOffset; size_t m_numberFiles; char* m_names = FcFont_GetSystemFonts_findfiles(&m_numberFiles, &m_namesOffset); if (m_names) { for (i = 0; i < m_numberFiles; i++) { if (strcmp(m_names + m_namesOffset[i], faceName) == 0) { j_end = strlen(m_names + m_namesOffset[i]); *resultFontFile = (char*)malloc(j_end + 1); for (j = 0; j < j_end; j++) (*resultFontFile)[j] = (m_names + m_namesOffset[i])[j]; (*resultFontFile)[j] = 0; i = m_numberFiles; } } } free(m_namesOffset); free(m_names); return 0; } #endif