2012-07-08 16 views
5

में नाम और शैली से एक फ़ॉन्ट फ़ाइलपैथ प्राप्त करें, मैं वर्तमान में मेरी परियोजना में फ्रीटाइप 2 को कार्यान्वित कर रहा हूं और इस प्रकार मेरे सिस्टम पर फ़ॉन्ट्स के लिए फ़ाइलपैथ की आवश्यकता है। मुझे एक समाधान की आवश्यकता है जो केवल फ़ॉन्ट नाम और वांछित फ़ॉन्ट शैली (उदाहरण के लिए बोल्ड या इटालिक) लेता है और फिर फ़ॉन्ट के लिए फ़ाइलपैथ देता है।सी ++/विंडोज

मैंने पहले ही इस Stack Overflow question से उत्तर देने का प्रयास किया है, लेकिन यह विंडोज 7 (और शायद न तो Vista पर) पर काम नहीं करता है, लेकिन स्पष्ट रूप से मुझे ऐसे समाधान की आवश्यकता है जो इन सिस्टमों और भविष्य की प्रणालियों पर भी काम करे।

+0

ऐसा कोई एपीआई मौजूद नहीं है, जैसा कि लिंक किए गए उत्तर की तरह है। –

+1

यदि आपके पास फ़ॉन्ट का HFONT हैंडल है, तो आप मेरे [प्रस्तावित समाधान] (http://stackoverflow.com/questions/16769758/get-a-font-filename-based-on-the-font-handle- hfont)। मैं यहां जवाब जोड़ना नहीं चाहता था, क्योंकि अगर आपके पास फ़ॉन्ट के लिए हैंडल है या नहीं तो सवाल अस्पष्ट है। –

उत्तर

5

क्या मैं पूछ सकता हूं कि आपको भौतिक फ़ाइल के पथ की आवश्यकता क्यों है?

  • यदि आपको केवल फ़ॉन्ट के बाइनरी डेटा की आवश्यकता है, तो आप GetFontData का उपयोग कर सकते हैं।
  • यदि फ़ॉन्ट के मीट्रिक की आवश्यकता है, तो आप एक एचएफओटी बना सकते हैं, एचएफओटी को फ़ॉन्ट धारक एचडीसी में चुनें और GetOutlineTextMetrics का उपयोग करें।
  • यदि आपको फ़ॉन्ट लिंकिंग के बारे में जानकारी चाहिए, तो मेरी परियोजना पर एक नज़र डालें: font_link.cpp
  • उपरोक्त सभी शुद्ध जीडीआई कार्य हैं। यदि आपको वास्तव में फ़ॉन्ट पथ की आवश्यकता है, और डायरेक्टवाइट का उपयोग करके दिमाग में नहीं है, तो IDWriteFontFile::GetReferenceKey और IDWriteLocalFontFileLoader::GetFilePathFromKey पर नज़र डालें। यह आपको जीडीआई की तुलना में अधिक भविष्य बीमा देगा।
7

मैंने एक बार "एरियल बोल्ड" या इस तरह के नाम के आधार पर एक फ़ॉन्ट फ़ाइल खोजने के लिए विंडोज प्लेटफ़ॉर्म के लिए कोड लिखा था। कोड नीचे पोस्ट किया गया है। यह रजिस्ट्री स्कैन कर रहा है और विंडोज फोंट निर्देशिका में फ़ाइल चेहरे के नाम के लिए एक मैच खोजने का प्रयास कर रहा है। यह बुलेटप्रूफ नहीं हो सकता है, लेकिन यह काम करता है। एक बार आपके पास फ़ाइल का नाम हो जाने के बाद आप इसे फ्रीटाइप में पास कर सकते हैं।

// 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()); 
}