2012-07-08 10 views
5

Attualmente sto implementando FreeType 2 in un mio progetto e quindi ho bisogno dei percorsi file per Fonts sul mio sistema. Ho bisogno di una soluzione che prende solo il nome dei caratteri e lo stile del carattere desiderato (ad esempio in grassetto o in corsivo) e quindi restituisce il percorso file per il carattere.Ottieni un percorso file dal nome e dallo stile in C++/Windows

Ho già provato la risposta da questo Stack Overflow question, ma non funziona su Windows 7 (e probabilmente nessuno su Vista), ma ovviamente ho bisogno di una soluzione che funzioni anche su questi sistemi e sui sistemi futuri.

+0

Nessun tipo di API esiste, proprio come dice la risposta collegata. –

+1

Se hai il manico HFONT del font, puoi provare la mia [soluzione proposta] (http://stackoverflow.com/questions/16769758/get-a-font-filename-based-on-the-font-handle- HFONT). Non volevo aggiungere la risposta qui, perché la domanda non è chiara se hai un handle per il carattere o meno. –

risposta

5

Posso chiedere perché è necessario il percorso di un file fisico?

  • Se sono necessari i dati binari del carattere, è possibile utilizzare GetFontData.
  • Se sono necessarie le metriche del carattere, è possibile creare un HFONT, selezionare HFONT in un HDC del supporto del font e utilizzare GetOutlineTextMetrics.
  • Se avete bisogno di informazioni sul collegamento dei font, date un'occhiata al mio progetto: font_link.cpp.
  • Tutte le funzioni sopra sono puramente GDI. Se hai davvero bisogno del percorso del font, e non importa usare DirectWrite, dai un'occhiata a IDWriteFontFile::GetReferenceKey e IDWriteLocalFontFileLoader::GetFilePathFromKey. Questo ti darebbe più assicurazione futura rispetto a GDI.
7

Una volta ho scritto il codice per la piattaforma Windows per trovare un file di font basato su "Arial Bold" o un nome simile. Il codice è pubblicato qui sotto. Sta eseguendo la scansione del registro e sta cercando una corrispondenza per il nome del carattere in un file nella directory dei caratteri di Windows. Potrebbe non essere a prova di proiettile, ma ha funzionato. Una volta ottenuto il nome del file, è possibile passarlo a FreeType.

// Get system font file path 
std::string GetSystemFontFile(const std::string &faceName) { 

    static const LPWSTR fontRegistryPath = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"; 
    HKEY hKey; 
    LONG result; 
    std::wstring wsFaceName(faceName.begin(), faceName.end()); 

    // Open Windows font registry key 
    result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, fontRegistryPath, 0, KEY_READ, &hKey); 
    if (result != ERROR_SUCCESS) { 
    return ""; 
    } 

    DWORD maxValueNameSize, maxValueDataSize; 
    result = RegQueryInfoKey(hKey, 0, 0, 0, 0, 0, 0, 0, &maxValueNameSize, &maxValueDataSize, 0, 0); 
    if (result != ERROR_SUCCESS) { 
    return ""; 
    } 

    DWORD valueIndex = 0; 
    LPWSTR valueName = new WCHAR[maxValueNameSize]; 
    LPBYTE valueData = new BYTE[maxValueDataSize]; 
    DWORD valueNameSize, valueDataSize, valueType; 
    std::wstring wsFontFile; 

    // Look for a matching font name 
    do { 

    wsFontFile.clear(); 
    valueDataSize = maxValueDataSize; 
    valueNameSize = maxValueNameSize; 

    result = RegEnumValue(hKey, valueIndex, valueName, &valueNameSize, 0, &valueType, valueData, &valueDataSize); 

    valueIndex++; 

    if (result != ERROR_SUCCESS || valueType != REG_SZ) { 
     continue; 
    } 

    std::wstring wsValueName(valueName, valueNameSize); 

    // Found a match 
    if (_wcsnicmp(wsFaceName.c_str(), wsValueName.c_str(), wsFaceName.length()) == 0) { 

     wsFontFile.assign((LPWSTR)valueData, valueDataSize); 
     break; 
    } 
    } 
    while (result != ERROR_NO_MORE_ITEMS); 

    delete[] valueName; 
    delete[] valueData; 

    RegCloseKey(hKey); 

    if (wsFontFile.empty()) { 
    return ""; 
    } 

    // Build full font file path 
    WCHAR winDir[MAX_PATH]; 
    GetWindowsDirectory(winDir, MAX_PATH); 

    std::wstringstream ss; 
    ss << winDir << "\\Fonts\\" << wsFontFile; 
    wsFontFile = ss.str(); 

    return std::string(wsFontFile.begin(), wsFontFile.end()); 
} 
Problemi correlati