मेरा प्रश्न यह है कि विंडोज 7 के तहत सही तरीके से काम करने के लिए फ़ॉन्ट हैंडलिंग को कैसे बदला जाना चाहिए। मुझे यकीन है कि मैंने इस बारे में एक धारणा बनाई है ऐसा कुछ जो पहले मान्य था, लेकिन अब मान्य नहीं है। लेकिन मुझे यह भी नहीं पता कि कहां दिखना शुरू करें! मैं प्रार्थना कर रहा हूं कि कोई मदद कर सके! यहां विवरण हैं जिन्हें मैं समझता हूं (मैंने यह प्रश्न माइक्रोसॉफ्ट विंडोज डेवलपर्स फोरम पर भी पोस्ट किया है, लेकिन वे जवाब नहीं दे रहे हैं):Win7 में कुछ फोंट काम नहीं करते हैं जैसे कि Win2K/XP
हां, मैं समय के पीछे हूं (बिल्ली, मैं अभी भी WIN32 लिखता हूं सादा सी में कोड!) मेरे पास 10 साल पुराना डीएलएल है जो मैंने लिखा है कि खिड़की के क्लाइंट एरिया के भीतर एक पुरानी डॉस स्क्रीन I/O लाइब्रेरी की नकल करता है। कहने की जरूरत नहीं है, यह केवल निश्चित चौड़ाई फोंट के उपयोग की अनुमति देता है। जब डीएलएल का उपयोग करने वाले कुछ प्रोग्राम विंडोज 7 में स्थानांतरित हो जाते हैं, तो एक अजीब झिलमिलाहट होती है जो तब दिखाई देता है जब एक निश्चित-चौड़ाई सत्य प्रकार फ़ॉन्ट का उपयोग किया जाता है (बिटमैप फोंट अभी भी पूरी तरह से काम करते हैं।) हमने इस तथ्य को नीचे तथ्य को ट्रैक किया है कि ExtTextOut
के साथ लिखा गया एक भी वर्ण यह होना चाहिए जितना व्यापक होना चाहिए। मैंने माप को तीन अलग-अलग तरीकों की जांच की है (GetTextExtentPoint32
को 132 वर्ण स्ट्रिंग पर और 132 तक विभाजित करके GetTextMetrics
पर कॉल करके और सभी 256 अक्षरों के लिए GetCharABCWidths
का उपयोग करके) और वे सभी सहमत हैं कि फ़ॉन्ट एक ही चौड़ाई है। लेकिन ExtTextOut
पृष्ठभूमि आयत को फ़ॉन्ट चौड़ाई से एक या दो पिक्सल चौड़ा कर रहा है। पैरामीटर में दी गई स्थिति के बाईं ओर पिक्सेल या दो को पृष्ठभूमि में प्रस्तुत करने से पहले या यह पृष्ठभूमि शुरू हो रही है [मैं इसे इस तरह कहते हैं: ExtTextOut(hdc, r.left, r.top, ETO_OPAQUE, &r, &ch, 1, NULL)
।] और याद रखें, यह सटीक कोड विंडोज 2000, विंडोज एक्सपी और पूरी तरह से काम करता है, विंडोज 7 पर बिटमैप फोंट के साथ - लेकिन यह अब विंडोज 7 के तहत निश्चित-चौड़ाई वाले सही प्रकार के फ़ॉन्ट्स के साथ सही तरीके से काम नहीं करता है।
जो भी मुझे करने की ज़रूरत नहीं है, उसे समझने के लिए: प्रति वर्ग एक चरित्र लिखने की कल्पना करने का प्रयास करें ग्राफ पेपर के टुकड़े पर। प्रत्येक वर्ग एक ही फ़ॉन्ट का उपयोग करता है, लेकिन एक अलग अग्रभूमि और/या पृष्ठभूमि रंग हो सकता है। मैं TA_TOP|TA_LEFT
टेक्स्ट संरेखण का उपयोग करता हूं, क्योंकि यह सबसे सरल और किसी भी लगातार लागू संरेखण को निश्चित-चौड़ाई फ़ॉन्ट के लिए काम करना चाहिए।
जो मैं देख रहा हूं वह यह है कि ExtTextOut RECT *
पैरामीटर में निर्दिष्ट किए गए एक बड़े पृष्ठभूमि आयत को उत्सर्जित कर रहा है। चूंकि मैं जो आयताकार प्रदान कर रहा हूं वह फ़ॉन्ट के रिपोर्ट किए गए आकार से बनाया गया है, यह कभी नहीं होना चाहिए - और यह कभी भी विंडोज एक्सपी और पहले कभी नहीं हुआ, और यह विंडोज 7 के तहत बिटमैप (यानी एफओएन) फोंट के साथ नहीं होता है, या तो। लेकिन यह हमेशा विंडोज 7 के तहत फिक्स्ड-चौड़ाई ट्रू टाइप फ़ॉन्ट्स के साथ होता है। यह विंडोज 2000, विंडोज एक्सपी और विंडोज 7 (32 & 64) पर बिल्कुल सही निष्पादन योग्य है। हालांकि मुझे बस यह कहना अच्छा लगेगा कि विंडोज 7 में एक बग है, मैं यह मानने के इच्छुक हूं कि विंडोज के तहत फ़ॉन्ट हैंडलिंग के बारे में मैंने कुछ मूलभूत धारणा नहीं की है (विंडोज़ के लिए सॉफ्टवेयर लिखने के 20 साल बाद।)
लेकिन मुझे नहीं पता कि कैसे या कहां खोजना है क्या हो सकता है! कृपया, कृपया मेरी मदद करो! जब तक मैं विपरीत करने के लिए दस्तावेज़ प्राप्त -
--- संशोधन --- किसी को दिलचस्पी के लिए
, मैं आस-पास काम करने के लिए मैं क्या एक बग पर विचार कर रहा हूँ प्रबंधित किया है।
- आकार 'X' के बजाय
TEXTMETRICS
से डेटा के कीGetTextExtentPoint32()
से लौटे का उपयोग करें: मेरे वैकल्पिक हल मेरी लाइब्रेरी में दो परिवर्तन के होते हैं। - सभी
ExtTextOut()
कॉल मेंETO_CLIPPING
ध्वज शामिल करें।
पहले, मैं टेक्स्ट की लगातार पंक्तियों के शीर्ष के बीच पिक्सल की संख्या के लिए tmHeight+tmExternalLeading
का उपयोग कर रहा था, जैसा कि दस्तावेज है। मैंने आकार का पता लगाया।GetTextExtentPoint32(
से वापस आने वाला साइ वैल्यू वही नहीं था और अधिक सटीक लग रहा था। मैंने पाया सबसे खराब उदाहरण ओसीआरबी सच प्रकार फ़ॉन्ट था।
ocrbtm.tmHeight = 11
ocrbtm.tmExternalLeading = 7
ocrbsize.cy = 11
तो, कुछ कारण यह है कि मैं अभी तक है की खोज करने के लिए, Windows बाहरी अग्रणी अनदेखी कर रहा है के लिए: यहाँ है कि मैं क्या मैं बनाया चाहते OCRB फ़ॉन्ट के लिए डीबगर में देखा (सिस्टम फ़ॉन्ट चयन संवाद का प्रयोग करके) है ओसीआरबी फ़ॉन्ट के लिए परिभाषित मूल्य। टीएम के बजाय आकार मूल्य का उपयोग करना, साफ, साफ, बंद पैक वाले पाठ में परिणाम, जो मैं चाहता था।
ETO_CLIPPING
ध्वज मेरे लिए आवश्यक है क्योंकि मैं आयत की स्थापना कर रहा हूँ नहीं होना चाहिए करने के लिए वास्तव में एक एकल वर्ण के आयामों और ETO_OPAQUE
का उपयोग कर पृष्ठभूमि में भरने (और पिछले सेल सामग्री को अधिलेखित।) लेकिन कतरन ध्वज के बिना करने के लिए, आकार, टेक्स्ट मेट्रिक, या एबीसी चौड़ाई के मुकाबले एक भी वर्ण व्यापक है - कम से कम, यह अब तक के सभी दस्तावेजों पर आधारित है।
मेरा मानना है कि HEIGHT समस्या लंबे समय से अस्तित्व में है, लेकिन शेष तब तक अनावश्यक थे जब तक कि हम विंडोज 7 के तहत हमारे सॉफ़्टवेयर को नहीं चलाते। मैं यह देखने के लिए अपने प्रश्न में जोड़ रहा हूं कि कोई यह स्पष्ट कर सकता है कि मैं स्पष्ट रूप से क्या नहीं कर सकता समझना।
- संशोधन 2 -
1: सभी प्रलेखन मैं पा सकते हैं का कहना है कि tmHeight+tmExternalLeading
पाठ की एकल दूरी पर लाइनों का उत्पादन करना चाहिए। अवधि। लेकिन यह हमेशा सत्य नहीं होता है और मुझे यह दस्तावेज नहीं मिल रहा है कि विंडोज विभिन्न मानों को निर्धारित करता है जो कभी-कभी GetTextExtentPoint32()
द्वारा लौटाए जाते हैं।
2: Win7 (शायद Vista) ExtTextOut
के तहत इसे थोड़ा और अधिक पृष्ठभूमि में भरना शुरू करना चाहिए (दाईं ओर कुछ अतिरिक्त पिक्सल जोड़कर), लेकिन केवल तभी जब एक सही प्रकार का फ़ॉन्ट चुना जाता है। ऐसा तब भी होता है जब आयत डबल चरित्र के अपेक्षित आकार (दोनों आयामों में) डीपीआई/स्केलिंग एक कारक हो सकता है, लेकिन चूंकि मेरा सिस्टम 100% पर सेट हो गया है, ऐसा लगता है कि विंडोज़ में समस्या है एक 1: 1 स्केलिंग कारक और यह एक बग प्रतीत होता है। तथ्य यह है कि यह केवल सही प्रकार को प्रभावित करता है और बिटमैप (एफओएन) फोंट भी स्केलिंग से बाहर निकलने लगता है (जब तक स्केलिंग सिस्टम में एक बग है), क्योंकि विंडोज़ को सभी टेक्स्ट स्केल करने का प्रयास करना चाहिए, न केवल कुछ इसका साथ ही, "कस्टम डीपीआई सेटिंग" संवाद में एक ग्रेड (लेकिन चेक) सेटिंग "विंडोज एक्सपी स्टाइल डीपीआई स्केलिंग का उपयोग करें" सेटिंग है। अंत में, यह संपूर्ण मुद्दा एरो या अन्य Win7 मूल विषयों में से किसी एक के बजाय विंडोज क्लासिक थीम के तहत चलने का नतीजा हो सकता है।
- संशोधन 3 -
सीधे शब्दों में बुला SetProcessDPIAware() मुद्दा मैं आ रही है पर कोई प्रभाव नहीं है। चूंकि मेरी समस्या 100% डीपीआई सेटिंग (स्केल 1: 1) पर मौजूद है, अगर मेरी समस्या डीपीआई से संबंधित है, तो मुझे डीपीआई वर्चुअलाइजेशन में एक बग की खोज करनी चाहिए क्योंकि माइक्रोसॉफ्ट इस सुविधा का वर्णन करता है:
यह सुविधा एप्लिकेशन में "वर्चुअलाइज्ड" सिस्टम मेट्रिक्स और UI तत्व प्रदान करके काम करती है, जैसे कि यह 96 डीपीआई पर चल रहा था। एप्लिकेशन तब 96-डीपीआई ऑफ़-स्क्रीन सतह पर प्रस्तुत करता है, और डेस्कटॉप विंडोज मैनेजर डीपीआई सेटिंग से मेल खाने के लिए परिणामी एप्लिकेशन विंडो को स्केल करता है।
मेरी सभी सेटिंग्स से पता चलता है कि मैं 100% स्केलिंग पर हूं, और कस्टम सेटिंग्स बॉक्स में देखकर स्पष्ट रूप से दिखाता है कि इसका मतलब 96 डीपीआई है। इसलिए, यदि डीपीआई वर्चुअलाइजेशन 96 डीपीआई से 96 डीपीआई मेरे निश्चित चौड़ाई वाले वास्तविक प्रकार फोंट के लिए काम नहीं कर रहा है, तो विंडोज़ में कोई समस्या है, है ना? या क्या कोई ऐसा फ़ंक्शन है जिसे मुझे कॉल करने की आवश्यकता है (या कॉल करना बंद करें?) क्रम में डीपीआई वर्चुअलाइज़र सही तरीके से काम करने की अनुमति देता है?
मुझे अभी भी विश्वास नहीं है कि स्केलिंग समस्या वास्तव में फ़ॉन्ट आकार के साथ उतनी ही है जितनी मैंने मूल रूप से सोचा था। ऐसा इसलिए है क्योंकि समस्या पृष्ठभूमि आयताकार में प्रकट होने वाले पाठ वर्ण के बजाय ExtTextOut()
से भरी जा रही है। जब फ़ॉन्ट सही प्रकार होता है तो पृष्ठभूमि आयताकार थोड़ा बड़ा हो जाता है। मैंने अब भी सत्यापित किया है कि यह समस्या तब होती है जब Windows क्लासिक थीम या मानक विंडोज एयरो थीम का उपयोग करना है। अब एक सरलीकृत उदाहरण बनाने के लिए ताकि अन्य इसके साथ प्रयोग कर सकें।
- संशोधन 4 -
मैं एक न्यूनतम प्रदर्शन कार्यक्रम बना लिया है पता चलता है कि मैं क्या दिखाई दे रही है दृश्य स्टूडियो 2010 परियोजना/स्रोत http://www.svalli.com/files/fwtt.7z से डाउनलोड किया जा सकता है (और मैं क्या कर रहा हूँ।) - मैंने जानबूझकर निष्पादन योग्य शामिल नहीं किए क्योंकि मैं मैलवेयर फैलाने का जोखिम नहीं लेना चाहता हूं। कार्यक्रम में आपने एक निश्चित चौड़ाई वाला फ़ॉन्ट चुना है और उसके बाद ग्राहक क्षेत्र में दो 5x5 वर्ण ग्रिड लिखते हैं, एक GetTextExtentPoint32
आकार का उपयोग करके बनाया गया है और एक माइक्रोसॉफ्ट द्वारा दस्तावेज के रूप में TEXTMETRIC
आकार का उपयोग कर रहा है। ग्रिड एक काले & सफेद चेकरबोर्ड पैटर्न में हैं, जो ओवरलैप प्रभाव दिखाने के लिए केंद्र में आखिरी बार लिखे गए लाल चरित्र पर पीले रंग के होते हैं (आपको इसे स्पष्ट रूप से देखने के लिए ज़ूम उपयोगिता की आवश्यकता हो सकती है।) कार्यक्रम 5 स्ट्रिंग के साथ शुरू होने वाली स्ट्रिंग भी खींचता है अलग-अलग अक्षरों को रखने की मेरी विधि के लिए तुलना के रूप में उपयोग करने के लिए, उसी बाएं ऑफसेट से शुरू होने वाले ग्रिड के ठीक नीचे (मैं स्ट्रिंग से मेल खाता हूं।) मेनू ExtTextOut
में क्लिपिंग चालू/बंद करने और अन्य फ़ॉन्ट्स के चयन को टॉगल करने की अनुमति देता है। एक कमांड लाइन विकल्प dpiaware
(केस-सेंसिटिव) भी है जो प्रोग्राम को SetProcessDPIAware()
पर कॉल होने पर कॉल करने का कारण बनता है, ताकि उस कॉल के प्रभाव का भी मूल्यांकन किया जा सके।
ExtTextOut
सही पृष्ठभूमि आयत भरने है, लेकिन चरित्र एक अपारदर्शी पृष्ठभूमि के साथ प्रदान की गई की जा रही व्यापक होना चाहिए उस से और भी शुरू नहीं हो सकता जहां
ExtTextOut
ड्राइंग शुरू करने के लिए कहा गया था हो सकता है बनाने से
! मैंने कहा "होना चाहिए" क्योंकि चरित्र अंतर मैं मैचों के साथ समाप्त हो रहा हूं जब मुझे ExtTextOut
एक पूर्ण स्ट्रिंग प्रस्तुत करता है। ओवरलैप स्पष्ट रूप से दिए गए आयताकार के दोनों या दोनों तरफ हो सकता है, उदाहरण के लिए, ओसीआरबी चरित्र कक्ष के बाएं और दाएं किनारों पर एक अतिरिक्त पिक्सेल जोड़ता है जबकि अन्य सच्चे प्रकार के फोंट जिन्हें मैंने चेक किया है, दाईं ओर दो पिक्सल जोड़ते हैं धार।
मैं वास्तव में यह "सही" तरीका करना चाहता हूं, लेकिन मुझे कोई दस्तावेज नहीं मिल रहा है जो दिखाता है कि मैं क्या गलत कर रहा हूं या गायब हूं। खैर, मैं शायद 100% के अलावा स्केल पर डीपीआई जागरूकता के लिए कुछ खो रहा हूं, लेकिन अन्यथा, मैं बस परेशान हूं।
- संशोधन 5 -
थोड़ा कम चकित ... समस्या ClearType के कारण होता है। क्लियरटाइप को बंद करने से सभी फोंट फिर से काम करते हैं। XP के तहत ClearType चालू करना एक ही समस्या का कारण बनता है। स्पष्ट रूप से ClearType चुपचाप (जब तक कोई मुझे यह पता लगाने के लिए नहीं कहता है) छायांकित पिक्सल के लिए जगह बनाने के लिए अक्षरों को क्षैतिज रूप से खींचें, यह चिकनी चीज़ों में जोड़ता है।
इस समस्या के आसपास एकमात्र तरीका क्लिपिंग कर रहा है?
- संशोधन 6 -
ऊपर मेरी कतरन सवाल काआंशिक जवाब: जब अब मुझे क्या करना एक नया फ़ॉन्ट बनाने निम्नलिखित (छद्म कोड में):
CreateFontIndirect
SelectFont
GetTextMetrics
if((tmPitchAndFamily & TMPF_TRUETYPE) && Win6.x or above)
if(SystemParametersInfo(SPI_GETCLEARTYPE))
lfQuality = NONANTIALIASED_QUALITY
DeleteObject(font)
CreateFontIndirect
इस कतरन सक्रिय करने के बिना लगभग हमेशा मेरे द्वारा उपयोग किए जा रहे फ़ॉन्ट आकारों के साथ काम करता है, हालांकि मुझे कुछ ऐसे मिल गए हैं जो अभी भी वर्ण कक्ष के दाएं (या बाएं) को अतिरिक्त पिक्सेल प्रस्तुत करते हैं। सौभाग्य से, वे इंटरनेट पर पाए गए मुफ्त फोंट प्रतीत होते हैं, इसलिए उनकी समग्र गुणवत्ता पेशेवर फ़ॉन्ट फाउंड्री के मानकों से कम हो सकती है।
यदि कोई बेहतर जवाब प्राप्त कर सकता है, तो मैं वास्तव में, वास्तव में इसे सुनना अच्छा लगा! तब तक, मुझे लगता है कि यह उतना अच्छा होगा जितना इसे मिलेगा। यहां तक इसे पढ़ने के लिए धन्यवाद!
ट्रू-टाइप संकेत प्राचीन जीडीआई पाठ कार्यों के साथ पकड़ा गया है। पृष्ठभूमिकर्ता यहां है: http://support.microsoft.com/kb/200262 –
लिंक के लिए धन्यवाद, लेकिन लेख मेरी समस्या के विपरीत संबोधित कर रहा है: मैं एक वर्ण के लिए सही आयताकार की गणना करने की कोशिश कर रहा हूं एक मौजूदा फिक्स्ड-चौड़ाई फ़ॉन्ट जबकि लेख एक फ़ॉन्ट बनाने के बारे में है जो एक स्ट्रिंग को एक विशिष्ट आयत के भीतर फिट करने की अनुमति देगा। साथ ही, यह लेख विंडोज 98 और विंडोज़ पर लागू होता है, इसलिए यह संभव नहीं है कि इसमें जो कुछ शामिल है वह कुछ ऐसा है जो Vista/Win7 में ही बदला गया है। लेकिन यह दिलचस्प है और मैं इसे फिर से विस्तार से पढ़ रहा हूं। धन्यवाद। –