उर्सुला ले गिनी की पुस्तक "द विजार्ड ऑफ द सीसाइड" में जादू ने जादूगर के साथ काम करने वाले "सही नाम" के ज्ञान की मांग की। मुझे लगता है कि कोई भी प्रोग्रामर सहमत होगा कि विचार ध्वनि है। URL, UUID और वस्तुओं के अन्य विशिष्ट पहचानकर्ता हैं जो हम हर समय व्यवहार करते हैं। और, दुनिया की तरह, इन सच्चे नामों को पता लगाना इतना आसान नहीं है। कम से कम फ़ॉन्ट नामों के लिए यह है।
मुझे हमारे सॉफ्टवेयर उत्पाद में पाठ ब्लॉक के निर्यात को पीडीएफ में लागू करने की आवश्यकता है। मालिकाना एडोब पीडीएफ लाइब्रेरी (http://datalogics.com/products/pdfl/) और ऐड-ऑन DLI (Datalogics लाइब्रेरी इंटरफ़ेस) ऐड-ऑन का उपयोग निर्यात के लिए किया जाता है। मैं इन पुस्तकालयों में तल्लीन नहीं करूँगा, मुझे लगता है कि वे किसी के लिए कम रुचि रखते हैं। लेकिन मेरा मानना है कि मुझे जो समस्या आई है वह पीडीएफ निर्यात के किसी भी कार्यान्वयन के लिए सामान्य है।
प्रत्येक फ़ॉन्ट (उदाहरण के लिए, एरियल) की 4 अलग-अलग शैलियाँ हैं - नियमित, बोल्ड, तिरछा और बोल्ड तिरछा। यानी एरियल, एरियल बोल्ड, एरियल इटैलिक और एरियल बोल्ड इटैलिक। प्रत्येक शैली को एक अलग TTF फ़ाइल या TTC फ़ाइल के एक अलग अनुभाग में संग्रहीत किया जाता है। और अगर हम एक पीडीएफ फाइल में एक तिरछा या बोल्ड फ़ॉन्ट प्रिंट करना चाहते हैं, तो हमें संबंधित फ़ंक्शन के लिए कॉल में "एरियल इटैलिक" या "एरियल बोल्ड" को स्पष्ट रूप से इंगित करना चाहिए। लेकिन हमारे द्वारा निर्यात किए जाने वाले टेक्स्ट ब्लॉक में, यह इंगित किया जाता है कि इसका फ़ॉन्ट "एरियल" है और बोल्ड और इटैलिक विशेषताओं को अलग-अलग सेट किया गया है। और EnumFontsFamiliesEx ने हमें केवल "एरियल" नाम दिया है और यह है! Q हमें "एरियल इटैलिक" स्ट्रिंग कैसे चाहिए?
स्पष्ट समाधान - बस फ़ॉन्ट नाम के लिए "इटैलिक" लाइन निर्दिष्ट करना - हमेशा काम नहीं करता है। उदाहरण के लिए, यह "Lucida Sans टाइपराइटर" फ़ॉन्ट के साथ काम नहीं करता है। यदि हम “Lucida Sans टाइपराइटर इटैलिक” पास करते हैं, तो PDF लाइब्रेरी एक एरर फेंक देती है।
निर्णय की कुंजी (सजा का उद्देश्य) HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion / फ़ॉन्ट्स है। बस इस कुंजी की सामग्री को देखें और यह स्पष्ट हो जाता है कि "ल्यूसिडा सैंस टाइपराइटर ओब्लिक" को प्रसारित करना आवश्यक था। फिर सब कुछ काम करता है।
इस कुंजी में प्रविष्टियों का प्रारूप कहीं भी प्रलेखित नहीं है, लेकिन यह स्पष्ट प्रतीत होता है:
"एरियल (ट्रू टाइप)" = "arial.ttf"
"एरियल इटैलिक (ट्रू टाइप)" = "ariali.ttf"
"एरियल बोल्ड (ट्रू टाइप)" = "arialbd.ttf"
"एरियल बोल्ड इटैलिक (ट्रू टाइप)" = "arialbi.ttf"
"बटांग और बटांगछे और गंगसुश और गंगसुखे (ट्रू टाइप)" = "बटांग। एचटीटीसी"
...
"मंगल (ट्रू टाइप)" = "मंगल"
"मंगल बोल्ड (ट्रू टाइप)" = "मंगलगीत"
"Meiryo और Meiryo इटैलिक और Meiryo UI और Meiryo UI इटैलिक (ट्रू टाइप)" = "meiryo.ttc"
"मीरियो बोल्ड और मीरियो बोल्ड इटैलिक और मीरियो यूआई बोल्ड और मीरियो यूआई बोल्ड इटैलिक (ट्रू टाइप)" = "meiryob.ttc"
"एमएस गोथिक और एमएस पीजीओथिक और एमएस यूआई गोथिक (ट्रू टाइप)" = "msgothic.c"
...
"ल्यूसिडा सैंस टाइपराइटर रेगुलर (ट्रू टाइप)" = "LTYPE.TTF"
"लुसिडा सैंस टाइपराइटर बोल्ड (ट्रू टाइप)" = "LTYPEB.TTF"
"लुसिडा सैंस टाइपराइटर बोल्ड ऑब्लिक (ट्रू टाइप)" = "LTYPEBO.TTF"
"ल्यूसिडा सैंस टाइपराइटर ऑब्लिक (ट्रू टाइप)" = "LTYPEO.TTF"
यह देखा जा सकता है कि टीटीसी संग्रह के लिए, उनमें निहित फोंट “&” द्वारा इंगित किए गए हैं।
एक सामान्य फ़ॉन्ट नाम और फ़ॉन्ट नामों के बीच एक पत्राचार स्थापित करने के लिए एल्गोरिथ्म इस प्रकार है: प्रत्येक फ़ॉन्ट नाम के लिए हम अंत से एक शब्द काटते हैं, जब तक कि शेष EnumFontsFamiliesEx से प्राप्त किसी भी नाम से मेल नहीं खाता। इसके अलावा, कट ऑफ शब्दों को "बोल्ड", "अवैध", "सेमिबॉल्ड", "ओब्लिक" शब्दों के साथ संयोग के लिए जांचा जाता है और हम इस शैली के लिए इसी विशेषता को याद करते हैं। उदाहरण के लिए, "लुसिडा सैंस टाइपराइटर" परिवार के लिए:
ल्यूसिडा सैंस टाइपराइटर रेगुलर -> ल्यूसिडा सैन्स टाइपराइटर
लुसिडा सैंस टाइपराइटर बोल्ड ->
ल्यूसिडा सैन्स टाइपराइटरल्यूसिडा सैंस टाइपराइटर ओब्लिक ->
ल्यूसिडा सैन्स टाइपराइटरल्यूसिडा सैंस टाइपराइटर बोल्ड ऑब्लिक ->
ल्यूसिडा सैन्स टाइपराइटर बोल्ड ->
ल्यूसिडा सैन्स टाइपराइटरअब अगर हमें फ़ॉन्ट "Lucida Sans टाइपराइटर बोल्ड ओब्लिक" को बोल्ड और तिरछा में प्रिंट करने की आवश्यकता है, तो हम जानते हैं कि यह फ़ॉन्ट फ़ॉन्ट से मेल खाता है और इस नाम को पीडीएफ लाइब्रेरी में स्थानांतरित करता है।
हालांकि, एक और परेशानी का इंतजार है। उदाहरण के लिए, फ़ॉन्ट "मंगल" में केवल एक बोल्ड चेहरा ("मंगल बोल्ड") है, लेकिन इसमें तिरछा नहीं है। यद्यपि हम इस फ़ॉन्ट के लिए "तिरछा" विशेषता सेट कर सकते हैं और इस मामले में Windows GDI स्क्रीन पर प्रदर्शित होने पर मौजूदा शैली को स्वतंत्र रूप से विकृत कर देगा। पीडीएफ को निर्यात करते समय, आपको इसे स्वयं करना होगा। एक पीडीएफ लाइब्रेरी आपको टेक्स्ट आउटपुट के लिए ट्रांसफ़ॉर्मेशन मैट्रिक्स निर्दिष्ट करने की अनुमति दे सकती है। उदाहरण के लिए, मेरे मामले में, यह इस तरह दिखता था:
ASFixedMatrix fontSkew;
अगर (bSimulateItalic)
{
डबल कोण = 15;
fontSkew.a = fixedOne; // एक्स स्केल
fontSkew.b = fixedZero; // घुमाएँ और तिरछा करें
fontSkew.c = FloatToASFixed (tan (_PI * angle / 180)); // घुमाएँ और तिरछा करें
fontSkew.d = fixedOne; // y स्केल
fontSkew.h = 0; // एक्स अनुवाद
fontSkew.v = 0; // y अनुवाद
dlpdfcontentfontskew (..., और fontSkew);
}
मुझे बोल्ड अनुकरण करने के लिए एक सुंदर समाधान नहीं मिला। मैं बस एक ऐसी लाइन प्रिंट करता हूं, जिसमें थोड़ी सी शिफ्ट के साथ कई बार बोल्ड होना पड़ता है। नेत्रहीन, सब कुछ ठीक लग रहा है, लेकिन यह निराशाजनक है कि पीडीएफ फाइल में पाठ डुप्लिकेट है।
लेकिन यह अंत नहीं है। हम जो उत्पाद विकसित कर रहे हैं, उसका एक जापानी संस्करण है। इसलिए, एशियाई फोंट के साथ सही काम पर विशेष ध्यान दिया जाता है। और यहाँ दो और समस्याएं सामने आती हैं:
- "MS P with ッ ク is" नाम वाला एक फ़ॉन्ट HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ फ़ॉन्ट्स में मौजूद नहीं है और यह पता चलता है कि हम इस फ़ॉन्ट के फ़ॉन्ट नामों का पता नहीं लगा सकते हैं।
- पीडीएफ लाइब्रेरी यूनिकोड में फ़ॉन्ट नामों को बिल्कुल भी नहीं समझती है।
आइए पहली समस्या से शुरू करें (हालांकि ऐतिहासिक रूप से यह सब दूसरे के साथ शुरू हुआ था, लेकिन कहानी की सहजता के लिए)। Google हमें बताता है कि फ़ॉन्ट "font P シ font font font" वास्तव में एमएस गॉथिक है। यह पता चला है कि अगर सिस्टम में जापानी लोकेल सेट की जाती है तो उसे एक जापानी नाम मिलता है। इसके अलावा, रजिस्ट्री में, निश्चित रूप से, वह एमएस गोथिक नाम के तहत बनी हुई है। यह, यह पता चला है, EnumFontsFamiliesEx का नियमित व्यवहार है। यहाँ इसके लिए प्रलेखन से एक उद्धरण दिया गया है: “कई पूर्व एशियाई भाषाओं के फोंट में दो टाइपफेस नाम अंग्रेजी नाम और एक स्थानीय नाम होता है। "EnumFonts, EnumFontFamilies और EnumFontFamiliesEx अंग्रेजी टाइपफेस नाम लौटाते हैं यदि सिस्टम लोकेल फ़ॉन्ट की भाषा से मेल नहीं खाता है।"
वैसे, अगर हमें पता चलता है कि "एमएस गॉथिक" "way we we we we we" है, तो यह दूसरी समस्या को भी हल करता है, कम से कम मामले के लिए जब अंग्रेजी नाम रजिस्ट्री में संग्रहीत होता है। हम सिर्फ "एमएस गोथिक" नाम को पीडीएफ लाइब्रेरी में स्थानांतरित करते हैं और यह काम करता है। यह पत्राचार स्थापित करने के लिए बनी हुई है।
HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ फ़ॉन्ट्स से अधिकांश शैलियों के लिए, हमने EnumFontsFamiliesEx से फ़ॉन्ट नामों को मैप किया है। लेकिन कुछ शैलियों के लिए, कोई जोड़ी नहीं मिली। फिर भी - रजिस्ट्री में हमारे पास "एमएस गॉथिक" है, और एनुमफोन्सफैमिलीज़एक्स ने "MS シ ッ P ゴ“ "लौटाया।
इस स्थिति में, यह केवल TTF / TTC फ़ाइल को स्वतंत्र रूप से पार्स करने के लिए बना रहता है और वहां पर संबंधित जापानी नाम खोजता है।
एक TTC / TTF फ़ाइल पार्स करना एक सरल कार्य है। एक कार्यशील नमूने के लिए, आप "ttf2eot"
प्रोजेक्ट कोड का स्रोत कोड ले सकते हैं। Googlep
/ ttf2eot। TTF / TTC प्रारूप स्वयं Microsoft वेबसाइट पर अच्छी तरह से प्रलेखित है:
www.microsoft.com/typography/otspec । इस तथ्य पर ध्यान देना आवश्यक है कि टीटीएफ में सभी डेटा को बड़े एंडियन प्रारूप में संग्रहीत किया जाता है, ताकि उपयोग से पहले सभी संख्याओं और यूनिकोड के तारों को परिवर्तित किया जाना चाहिए।
दुर्भाग्य से, मुझे अपना कोड बिछाने का कोई अधिकार नहीं है, इसलिए मैं सिर्फ यहां लिखूंगा कि क्या देखना है।
हम टेबल "नाम"
www.microsoft.com/typography/otspec/name.htm में रुचि रखते हैं। के साथ रिकॉर्ड का चयन करें:
- nPlatformId = 3: विंडोज। मैं मानता हूं कि यदि फ़ॉन्ट विंडोज के तहत स्थापित है, तो ये प्रविष्टियां होनी चाहिए। शायद मैं गलत हूं, लेकिन पहले इस तरह के फ़ॉन्ट को पूरा करने दो, फिर हम इसका पता लगाएंगे।
- nNameId = 1: फ़ॉन्ट परिवार का नाम। चार फ़ॉन्ट तक फ़ॉन्ट परिवार का नाम साझा कर सकते हैं, एक फॉन्ट स्टाइल लिंकिंग ग्रुप बना सकते हैं (नियमित, इटैलिक, बोल्ड, बोल्ड इटैलिक - जैसा कि OS / 2.fsSelection bit settings द्वारा परिभाषित है)। यानी यह वास्तव में नाम है कि EnumFontFamiliesEx देता है।
- nEncodingId = 0 - सिंगल-बाइट ASCII स्ट्रिंग या 1 - डबल-बाइट USC2 स्ट्रिंग। शेष एन्कोडिंग्स को अनदेखा किया जा सकता है: विनिर्देश स्पष्ट रूप से आवश्यक है कि इन दोनों में से कम से कम एक एन्कोडिंग मौजूद हो: "विंडोज के लिए यूनिकोड फ़ॉन्ट बनाते समय, प्लेटफ़ॉर्म आईडी 3 होनी चाहिए और एन्कोडिंग आईडी होनी चाहिए। 1. विंडोज के लिए प्रतीक फ़ॉन्ट बनाते समय, प्लेटफ़ॉर्म आईडी 3 होनी चाहिए और एन्कोडिंग आईडी 0. होनी चाहिए। ”
पाया गया नामों में से एक EnumFontFamiliesEx से कुछ नाम से मेल खाएगा।
उदाहरण के लिए, "Meiryo Bold Italic" शैली के लिए, meiryob.ttc की जांच करने पर, हमें पता चलता है कि EnumFontFamiliesEx से "the イ リ“ "नाम इस शैली से मेल खाता है।
यह देखा जाना बाकी है कि क्या यह शैली बोल्ड और तिरछा है। इस जानकारी को फ़ॉन्ट से भी लेना शुरू कर देता है, लेकिन, जैसा कि यह प्रायोगिक रूप से निकला है, फ़ॉन्ट फ़ाइल में ये विशेषताएँ गलत हो सकती हैं। इसलिए, हम उन्हें रूपरेखा ("मीर्यो बोल्ड इटैलिक") के नाम से लेते हैं, जैसा कि पहले से ही ऊपर किया गया है। हम केवल तब तक शब्दों को काट देंगे जब तक कि शेष टीटीएफ फ़ाइल से निकाले गए किसी भी नाम से मेल नहीं खाता, और एनुमोंटफैमिलीज़एक्स के आउटपुट से नहीं।
इस प्रकार, यदि आप "イ you リ オ" नाम के साथ तिरछा और बोल्ड में टेक्स्ट ब्लॉक करना चाहते हैं, तो हम "Meiryo Bold Italic" नाम को पीडीएफ लाइब्रेरी में ट्रांसफर कर देते हैं। लाभ!