यदि आप कॉफी ग्राइंडर (रेफ्रिजरेटर, जेडएक्स स्पेक्ट्रम, टीवी, एम्बेडेड सिस्टम, पुराने कंप्यूटर - आपको जोर देने की आवश्यकता है) के लिए प्रोग्राम लिखते हैं, और सुंदर फॉण्ट का उपयोग करना चाहते हैं, तो रास्टर प्रारूप में अक्षरों को बचाने के लिए जल्दी मत करो। क्योंकि अब मैं आपको बताऊंगा कि वेक्टर फोंट के एक रैस्टराइज़र को एक किलो किलोबाइट के आकार का कैसे बनाया जाए, जो कि हाईटाइप 2 की गुणवत्ता से हीन नहीं है।
लेख उन लोगों के लिए दिलचस्प होगा जो सिर्फ यह पता लगाना चाहते हैं कि रैस्टराइज़र लाइब्रेरी कैसे काम करती है।
एसवीजी प्रारूप में वेक्टर फोंट
रैस्टराइज़र बनाने के लिए, आपको सबसे पहले यह समझना होगा कि वेक्टर फोंट कैसे काम करते हैं। मैंने एसवीजी को मुख्य फ़ॉन्ट प्रारूप के रूप में चुना क्योंकि यह एक्सएमएल पर आधारित है और शायद मनुष्यों के लिए सबसे पठनीय और समझने योग्य है।
पहला फॉन्ट जो मैंने अध्ययन के लिए लिया, वह है डेवजु सन्स मोनो बोल्ड। यहां बताया गया है कि यह अंदर से कैसा दिखता है:
<? xml संस्करण = "1.0" स्टैंडअलोन = "नहीं" ?>
<! DOCTYPE svg PUBLIC "- // W3C // DTD SVG 1.0 // EN" "http://www.w3.org/TR/2001/REC-
SVG-20010904 / DTD / svg10.dtd ">
<svg xmlns = " www.w3.org/2000/svg" चौड़ाई = "100%" ऊंचाई = "100%" >
<ढ्डह्म >
<font horiz-adv-x = "1233" > <font-face
फ़ॉन्ट-परिवार = "देजावु संन मोनो"
इकाइयां-प्रति-एम = "2048"
पैनोसे -1 = "2 11 7 9 3 6 4 4 2 2 4"
चढ़ाई = "1901"
वंश = "-483"
अक्षर = "0" />
<ग्लिफ़ यूनिकोड = "" ग्लिफ़-नाम = "स्पेस" />
<ग्लिफ़ यूनिकोड = "$" ग्लिफ़-नाम = "डॉलर" डी = "एम ६ ९ ४28२ V वी २२६ क्यू 2५2 २३५ Q ९ २ २ 27४४ टी
827 375 Q 827 437 793 476 T 694 528 Z M 553 817 V 1100 Q 491 1092 460 1059 T 428
967 क्यू 428 910 459 872 टी 553 817 जेड एम 694-301 एच 553 एल 552 0 क्यू 465 3 370 26 टी 172
92 वी 354 क्यू 275 293 371 260 टी 553 226 वी 555 क्यू 356
594 260 689 T 164 942 Q 164 1109 266 1208 T 553 1319 V 1556 H 694 L 613 1319 Q
766 1315 842 1301 T 999 1262 V 1006 Q 937 1046 861 1070 T 694 1100 V V33 891
762 991 659 टी 1092 383 क्यू 1092 219 984 114 टी 695 0 एल 694-301 जेड " >
<! - ... लोप हो गया .... ->
<ग्लिफ़ यूनिकोड = "~" ग्लिफ़-नाम = "एसिसिटिल्ड" d = "एम 1145 811 वी 578 क्यू 1070 518 999
491 T 848 463 Q 758 463 645 514 Q 623 524 612 528 Q 535 562 484 574 T 381 586 Q
303 586 233 557 T 88 465 V 694 Q 166 755 239 782 T 395 809 Q 448 809 498 798 T
622 756 क्यू 633 751 655 741 क्यू 771 686 864
686 क्यू 934 686 1003 716 टी 1145 811 जेड " />
</ font >
</ defs >
</ svg >
एसवीजी प्रारूप का मुख्य भाग
पथ है । वे अधिकांश छवि जानकारी संग्रहीत करते हैं। समोच्च टैग इस तरह दिखता है:
<path d=" M 1145 811 V 578 Q 1070 518 999 491 T 848 463 Q 758 463 645 514 Q 623 524 612 528 Q 535 562 484 574 T 381 586 Q 303 586 233 557 T 88 465 V 694 Q 166 755 239 782 T 395 809 Q 448 809 498 798 T 622 756 Q 633 751 655 741 Q 771 686 864 686 Q 934 686 1003 716 T 1145 811 Z " id="path4840" style="fill:#000000;stroke:#000000;stroke-width:1px;stroke- linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
शैली भरण और स्ट्रोक के रंग का वर्णन करती है,
आईडी पथ के नाम को इंगित करता है, और
डी स्वयं पथ है।
रुकिए ... एक मिनट रुकिए! फ़ॉन्ट से
ग्लिफ़ टैग:
<glyph unicode="~" glyph-name="asciitilde" d=" M 1145 811 V 578 Q 1070 518 999 491 T 848 463 Q 758 463 645 514 Q 623 524 612 528 Q 535 562 484 574 T 381 586 Q 303 586 233 557 T 88 465 V 694 Q 166 755 239 782 T 395 809 Q 448 809 498 798 T 622 756 Q 633 751 655 741 Q 771 686 864 686 Q 934 686 1003 716 T 1145 811 Z " />
यहाँ यह है। अक्षर (ग्लिफ़) के आकार को उसी प्रकार वर्णित किया गया है जैसे एसवीजी के आकृति। पूर्ण
पैरामीटर d का विवरण
विनिर्देश में पाया जा सकता है, और मैं नीचे एक संक्षिप्त विवरण देता हूं:

x_prev और y_prev - पिछले बिंदु के निर्देशांक
xc_prev और yc_prev - पिछले नियंत्रण बिंदु के निर्देशांक
ग्लिफ़ की रूपरेखा और प्रारंभिक रेखांकन
बेज़ियर कर्व्स को आउटपुट करने और इस लाइब्रेरी के कमांड्स में SVG पाथ टैग के कमांड्स को परिवर्तित करने के लिए लाइब्रेरी का हाथ होने पर, आप आसानी से और जल्दी से किसी भी ग्लिफ़ के ऑफलाइन (स्ट्रोक) प्राप्त कर सकते हैं।
हमारे पास वेक्टर ग्लिफ़ हैं, और स्क्रीन रेखापुंज है। इसका मतलब यह है कि ऑफ़लाइन आउटपुट करने का कार्य खंडों और बेजियर वक्रों के एक सेट से पिक्सेल की एक सरणी प्राप्त करना है। सेगमेंट को पिक्सेल में बदलना बहुत आसान है, बहुत सारे एल्गोरिदम हैं, वे अच्छे और अलग हैं।
बेज़ियर कर्व्स के लिए, आप प्रारंभ बिंदु (xz0, yz0), अंत बिंदु (xz2, yz2) और नियंत्रण बिंदु (xz1, yz1) के निर्देशांक द्वारा वक्र के कई बिंदुओं को पा सकते हैं। यह इस प्रकार किया जाता है:
for (step=0;step<10;step++) { t=step/10; bx[step]=(1-t)*(1-t)*xz0+2*t*(1-t)*xz1+t*t*xz2; by[step]=(1-t)*(1-t)*yz0+2*t*(1-t)*yz1+t*t*yz2; }
परिणामस्वरूप, हमारे पास बेज़ियर वक्र से संबंधित बिंदुओं के 10 निर्देशांक हैं। विभेदक समीकरणों की एक जटिल प्रणाली से वक्र की लंबाई के आधार पर, जिस बिंदु पर आप विभाजन को विभाजित करना चाहते हैं, वह संख्या पाई जाती है (अर्थात, चरण का सबसे बड़ा मूल्य)।
हालाँकि, बेज़ियर कर्व्स को पॉइंट्स के हिसाब से पिक्सल्स में बदलना धीमा और बुरा है। यदि वक्र आकार और लंबे समय में जटिल है, तो अंकों की संख्या की गणना करने में बहुत लंबा समय लगेगा। और यदि आप एक बेज़ियर वक्र को बिंदुओं से खींचते हैं, और ये बिंदु आवश्यक से कम निकलते हैं, तो ऑफ़लाइन ग्लिफ़ में अंतराल होंगे, जो अस्वीकार्य है। इसलिए, बेज़ियर वक्रों को खंडों में विभाजित किया गया है। सेगमेंट के शुरुआती और समाप्ति निर्देशांक को वक्र पर स्थित बिंदुओं के निर्देशांक के रूप में लिया जाता है। ज्यादातर मामलों में, यह सन्निकटन अच्छे परिणाम देता है।
खंडों की संख्या कैसे निर्धारित करें? मेरा मानना है कि यह शुरुआत और अंत निर्देशांक (उदाहरण के लिए, चरण = (xz2-yz2) / 100) के बीच के अंतर के अनुपात को अधिकतम करने के लिए पर्याप्त है। वैसे, मेरे सभी फोंट के लिए, जो कि 32 पिक्सेल से कम की ग्लाइफ ऊंचाई के साथ मिले, यह बेजियर घटता को दो खंडों में विभाजित करने के लिए पर्याप्त है।
रेखापुंज का परिणाम कुछ इस प्रकार होगा:

एक ग्लिफ़ की रूपरेखा को भरना रेखांकन का मुख्य चरण है
यह सब अच्छा है, लेकिन स्क्रीन पर हम उन पत्रों को देखते हैं जो रंग से भरे हुए हैं। तो, किसी तरह यह संभव है? मैंने पहले से ही विचित्र समोच्च को भरने के लिए एल्गोरिदम में सुधार करने पर लगभग दो महीने बिताए, और अंत में मुझे विश्वास हो गया कि यह दृष्टिकोण मौलिक रूप से गलत था। वेक्टर छवियों को भरने के लिए, रेखापुंज भरना उपयुक्त नहीं है।
इस मज़ेदार कार्य के समाधान की तलाश में, मैं कंप्यूटर ग्राफिक्स पर MIT OCW व्याख्यान देने आया। मुझे त्रि-आयामी ग्राफिक्स (जैसे, त्रिकोणीय बहुभुज) को रेखांकन पर एक व्याख्यान में दिलचस्पी थी। विधि का सार इस प्रकार था: एक वेक्टर रूप में, स्क्रीन पर एक त्रिकोणीय बहुभुज का प्रक्षेपण बनाया गया था, और फिर वेक्टर त्रिकोण पर चित्रित किया गया था। छायांकन निम्नानुसार किया गया था: स्क्रीन का एक क्षेत्र चुना गया था जिसके बाहर त्रिकोण स्पष्ट रूप से बाहर नहीं जाता है, और इस क्षेत्र के प्रत्येक बिंदु के लिए यह निर्धारित किया गया था कि क्या यह इस त्रिकोण से संबंधित है।
एक ही व्याख्यान में दावा किया गया है कि स्वीपिंग लाइन भराव विधि (जो काहिरा और फ्रीटाइप का उपयोग करती है) को पदावनत किया जाता है, लेकिन बाद में इस पद्धति पर और अधिक।यह सीखना है कि कैसे निर्धारित किया जाए कि एक बिंदु ग्लिफ़ की रूपरेखा से संबंधित है या नहीं। ग्लिफ़ की रूपरेखा हमेशा बंद रहती है। इसलिए, यदि हम किसी बिंदु से किसी भी दिशा में एक किरण खींचते हैं, और यह विषम संख्या में ग्लिफ़ की सीमा को पार करता है, तो बिंदु ग्लिफ़ से संबंधित है, और यदि यह है भी, तो यह नहीं है।
दिलचस्प है, यह विधि तब भी काम करती है जब सर्किट में स्व-चौराहे या छेद होते हैं। यह पता चला है कि यह एल्गोरिथ्म पाठ्यपुस्तक है, और इसका एक कार्यान्वयन है
इस प्रकार है:
xp = new Array (10, 20, 30, 40); yp = new Array (30, 40, 20, 10); function inPoly(x,y){ npol = xp.length; j = npol - 1; var c = 0; for (i = 0; i < npol;i++){ if ((((yp[i]<=y) && (y<yp[j])) || ((yp[j]<=y) && (y<yp[i]))) && (x > (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i])) { c = !c;} j = i;} return c;}
यहाँ
xp और
yp बहुभुज के कोने के निर्देशांक के सरणियाँ हैं। समारोह में (x, y)
1 या 0 रिटर्न - बिंदु बहुभुज के अंतर्गत आता है या नहीं। यह देखते हुए कि हम कर सकते हैं
ग्लिफ़ की रूपरेखा को खंडों में विभाजित करें (यानी बहुभुज के किनारे), फिर यह कार्य
हमारे लिए बहुत अच्छा है।
सबसे सरल रेखापुंज
अब, ग्लिफ़ को xp और yp वर्टिकल की एक सरणी में अनुवाद करते हुए, हम एक साधारण रैस्टराइज़र लिख सकते हैं। सरणी को 0 से 2000 तक निर्देशांक वाले खंडों में शामिल करें। तब:
function simple(){ for (x=0;x<2000;x++) { for (y=0;y<2000;y++) { if (inPoly(x,y)>0) raster[x][y]=1;}}}
यह सबसे सरल कार्य रैस्टर [x] [y] एरे में एक रेखित ग्लिफ़ इमेज बनाएगा। स्क्रीन पर प्रदर्शित परिणाम कुछ इस तरह दिखाई देगा (मैंने बदले में कई ग्लिफ़ प्रदर्शित किए, और छवि को लगभग 20 गुना बढ़ा दिया:)

स्क्रीन पर 2000x2000 पिक्सेल के रिज़ॉल्यूशन वाले ग्लिफ़ की किसी को भी आवश्यकता नहीं है, और इनोली एल्गोरिथ्म बहुत धीरे-धीरे प्रोसेस करेगा। छोटे ग्लिफ़ को प्रदर्शित करने के लिए, ऐसा कुछ करें:
function simple(scalefactor){ for (x=0;x<2000/scalefactor;x++) { for (y=0;y<2000/scalefactor;y++) { if (inPoly(x*scalefactor,y*scalefactor)>0) raster[x][y]=1;}}}
यदि स्केलफैक्टर = 2, तो ग्लिफ़ को 1000x1000 पिक्सेल के वर्ग में प्रदर्शित किया जाएगा, और यदि स्केलफैक्टर = 100, तो 20x20 के वर्ग में (स्क्रीन फोंट के लिए एक सामान्य आकार)।
यह रैस्टराइज़र सबसे तेज (और सबसे असमान) कंट्रोस को प्रदर्शित करता है, और इसे किसी अन्य रैस्टराइज़र से अधिक हिन्टिंग और कटऑफ कंट्रोल एल्गोरिदम की आवश्यकता होती है (वे रिज़ॉल्यूशन के आधार पर समोच्च के आकार को बदलते हैं)। एक rasterized ग्लिफ़ को मेमोरी में स्टोर करने के लिए, x * y / 8 बाइट्स की आवश्यकता होती है। ASCII वर्णों का एक पूरा सेट मेमोरी में x * y * 32 बाइट्स से अधिक नहीं होगा (32x बाइट्स के लिए 10x10 फॉन्ट और 16x16 फॉन्ट के लिए 8192 बाइट्स)। रेखांकन प्रक्रिया अंकों की तुलना में थोड़ा अधिक उपयोग करती है * 2 * 4 बाइट्स मेमोरी (जहां अंक ग्लिफ़ में बिंदुओं की संख्या है, अंक आमतौर पर 100 से कम होते हैं, और कभी-कभी 10 से कम होते हैं)।
एंटी-एलियासिंग (स्मूथिंग)
चौरसाई के साथ रेखांकन अधिक बेहतर परिणाम देता है। FreeType 1 लाइब्रेरी का उपयोग किया गया
5-हाल्फटोन एंटी-अलियासिंग, अब FreeType2 कुछ अधिक पर्याप्त (10-और-17-हॉलफ़टोन एंटी-अलियासिंग का उपयोग करता है, मैं विवरण में नहीं गया था)। प्रयोग करने के बाद, मुझे विश्वास हो गया कि 10-ग्रेस्केल स्मूदी 5-ग्रेस्केल की तुलना में बहुत बेहतर है।
function aadraw(scalefactor){
यहां आकार ग्लिफ़ का आकार है (एक साधारण रैस्टराइज़र में, मैंने आकार के बजाय 2000 प्रतिस्थापित किया है)। परिदृश्य सरणी का उपयोग मध्यवर्ती डेटा को संग्रहीत करने के लिए किया जाता है, और अंतिम परिणाम रंग [x] [y] बाइट सरणी में संग्रहीत किया जाता है।

उपपीठ मृदुकरण
Subpixel एंटी-अलियासिंग का उपयोग अक्सर एलसीडी मॉनिटर पर फोंट प्रदर्शित करने के लिए किया जाता है। पारंपरिक मॉनीटर पर, सबपिक्सल स्मूथिंग सामान्य स्मूथिंग के रूप में लगभग समान परिणाम देता है, लेकिन एलसीडी पर, सबपिक्सल द्वारा स्मूथिंग आपको तीन बार क्षैतिज रिज़ॉल्यूशन बढ़ाने की अनुमति देता है। विधि का सार इस प्रकार है: मानव आँख छाया के बजाय तीव्रता को बेहतर तरीके से अलग करती है। विवरण कई स्रोतों में हैं, और यहां तक कि
रूसी विकिपीडिया पृष्ठ पर, वर्णन व्यावहारिक उपयोग के लिए पर्याप्त है।
सरल उप-पिक्सेल एंटी-अलियासिंग के साथ समस्या यह है कि आउटपुट में छवि गुणवत्ता 10-स्केल स्केल-अलियासिंग एल्गोरिदम की तुलना में कम है। गुणवत्ता बढ़ाने के लिए, मैं लंबवत रूप से चार-हाफ़टोन स्मूथिंग का उपयोग करता हूं, और क्षैतिज रूप से उप-पिक्सेल चौरसाई करता हूं। डायरेक्टरी से सबपिक्सल स्मूथिंग एल्गोरिदम यहाँ ऐसे भयानक परिणाम देता है:

बहु-रंगीन "स्मूदीज़" से छुटकारा पाने के लिए, मैंने धब्बा गुणांक को बदल दिया
क्षैतिज रूप से, और इसके अलावा थोड़ा सरगम बदल दिया। परिणाम इस तरह दिखता है (सबसे अच्छा
एलसीडी मॉनिटर पर देखने पर गुणवत्ता प्राप्त होती है):

function xdraw(scalefactor){
व्यापक लाइन विधि मुख्य विचार
आइए inPoly एल्गोरिथ्म को देखें जिसके बारे में मैंने फिर से बात की। यह काम करता है, लेकिन बड़े पात्रों पर यह धीरे-धीरे काम करता है। क्यों? क्योंकि प्रसंस्करण की गति वर्ग के आकार के आनुपातिक है। आकार दोगुना, गति चार गुना घट गई, आकार में चार गुना वृद्धि हुई - गति 16 गुना कम हो गई।
यदि आप अल्गोरिद्म को थोड़ा देखते हैं और सोचते हैं, तो आप पाएंगे कि हम जो छांटते हैं उनमें से प्रत्येक बिंदु के लिए, एक क्षैतिज किरण उत्सर्जित होती है और आकृति के साथ इसके चौराहों का निर्धारण किया जाता है। यह पता चला है कि गणना का एक गुच्छा व्यर्थ में किया जाता है: एक ही वाई समन्वय के साथ सभी बिंदुओं के लिए, इन बिंदुओं से गुजरने वाली क्षैतिज रेखा का समीकरण समान होगा।
पहले, हमें प्रत्येक बिंदु के लिए एक किरण मिली, और गिना गया कि कितनी बार यह आकृति को पार करता है। हमने चौराहा निर्देशांक पाया, लेकिन बचा नहीं। और अब इसे करने की कोशिश करते हैं: हम किरण को केवल बिंदुओं (0, y) के लिए पाएंगे, और आकृति के साथ किरणों के प्रतिच्छेदन के निर्देशांक को बचाएंगे।
ध्यान दें:
1) यदि समोच्च का हिस्सा क्षैतिज है और व्यापक लाइनों के साथ मेल खाता है, तो समोच्च के इस हिस्से के साथ चौराहों पर ध्यान नहीं दिया जाता है।
2) एक स्वीपिंग पर हमेशा एक समान संख्या में प्रतिच्छेदन बिंदु होते हैं, क्योंकि सर्किट बंद होता है।
जो कुछ भी रहता है वह विषम और सम बिंदुओं के बीच के रिक्त स्थान को भरना है, और सम और विषम चौराहे के बिंदुओं के बीच रिक्त स्थान छोड़ना है (जब रेखा दाएं से बाएं गुजरती है)। फोंट को अच्छी तरह से डिज़ाइन किया जाना चाहिए, और ग्लिफ़ का रिज़ॉल्यूशन छोटा नहीं होना चाहिए, फिर गुणवत्ता को नुकसान नहीं होगा।
गति की तुलना करें। हमारी पुरानी एल्गोरिथ्म 9x9 बिंदुओं से किरणों का उत्सर्जन करना होगा और आकृति के साथ उनके चौराहे के निर्देशांक ढूंढना होगा। नया एल्गोरिथ्म केवल 9 किरणों का उत्सर्जन करता है - अर्थात, यह तेजी से परिमाण के एक क्रम का काम करता है। और एक ही समय में, व्यापक लाइन एल्गोरिथ्म एल्गोरिथ्म के बहुत करीब है जो हमारे पास था।
स्वीपिंग लाइन। InPoly कोड परिवर्तन
तो, हम inPoly फ़ंक्शन है। चलिए इससे स्वीप फंक्शन बनाते हैं।
function inPoly(x,y){ npol = xp.length; j = npol - 1; var c = 0; for (i = 0; i < npol;i++){ if ((((yp[i]<=y) && (y<yp[j])) || ((yp[j]<=y) && (y<yp[i]))) && (x > (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i])) { c = !c;} j = i;} return c;}
जाहिर है, इनपुट पैरामीटर x की अब आवश्यकता नहीं है। इनपुट स्वीप फ़ंक्शन केवल वर्तमान लाइन नंबर प्राप्त करता है। लेकिन इनपुट पैरामीटर स्केल उपयोगी है - वांछित पैमाने पर तुरंत x प्राप्त करने के लिए।
कुछ सीधे समोच्च के साथ वर्तमान व्यापक लाइन के चौराहे का x समन्वय इस प्रकार पाया गया:
(x >(xp[j]- xp[i])*(y - yp[i])/(yp[j]- yp[i])+ xp[i]))
यही है, यह अब होगा:
x =(xp[j]- xp[i])*(y - yp[i])/(yp[j]- yp[i])+ xp[i])
फ़ंक्शन के आउटपुट में, हमें चौराहे के बिंदुओं के निर्देशांक से एक सरणी प्राप्त करनी चाहिए। इस सरणी की लंबाई जानना अच्छा होगा। तो अब यह c =! C नहीं होगा, बल्कि c ++ होगा।
परिणामस्वरूप, हमारे पास यह है:
function sweep(y,scale){ npol = xp.length;
और फिर से - एक सरल रेखापुंज
इसलिए, प्रत्येक पंक्ति के लिए, हम स्वीप कहते हैं, स्वीपिंग लाइन के चौराहों को ढूंढते हैं और इन चौराहों पर सरणी में भरते हैं। हालांकि, स्वीप फ़ंक्शन हमारे पास लौट सकता है, उदाहरण के लिए, इस तरह के निर्देशांक:
14, 8, 16, 7
समोच्च को सही ढंग से भरने के लिए, आपको इसे लाइनों (7, y) - (8, y) और (14, y) - (16, y) से भरना होगा। एक शब्द में, आपको स्वीप फ़ंक्शन के परिणामों को क्रमबद्ध करने की आवश्यकता है। क्विकॉर्ट अच्छी तरह से काम करता है, और बड़ी संख्या में निर्देशांक के साथ इसका उपयोग करना उचित है। हालाँकि, मेरे हाथ में जो फोंट थे, उनके लिए कर्वलाइन सरणी में मूल रूप से 2 से 8 चौराहे निर्देशांक थे, और मेरे जीवन को जटिल नहीं करने के लिए, मैंने बबल सॉर्टिंग का उपयोग किया। मेरा
बबल फ़ंक्शन एक सरणी और इसकी लंबाई को इनपुट के रूप में स्वीकार करता है, स्पष्ट रूप से कुछ भी वापस नहीं करता है, लेकिन सरणी सॉर्ट हो जाती है।
हम सीधे रैस्टराइज़र के लिए आगे बढ़ते हैं। पहले हमें प्रत्येक पंक्ति के लिए स्वीप को कॉल करने की आवश्यकता है, फिर बबल कमांड के साथ कर्नेल एरे को सॉर्ट करें:
for(y=0;y<size/scale;y++){
सरणी 0 से शुरू होती है - इसलिए आपको क्यूरलाइन [0 + x] से कर्वलाइन [1 + x] तक लाइनें खींचने की आवश्यकता होती है। वह सब है। हमें लैंडस्केप एरे मिला है, और आपको पहले की तरह ही इसके साथ काम करने की जरूरत है। यही है, इसके बाद इसे एंटी-अलियासिंग या सबपिक्सल स्मूथिंग, या दोनों द्वारा सुचारू किया जा सकता है। मुख्य बात इस तथ्य पर ध्यान देना है कि पैमाने को स्वीप फ़ंक्शन में भी स्थानांतरित किया जाता है, यह क्षैतिज विस्तार को निर्धारित करता है।
काम के परिणाम
अब आप जानते हैं कि अपने स्वयं के हाथों से वेक्टर फोंट का एक रेखापुंज कैसे बनाया जाए। रैस्टराइज़र का एक कार्यशील उदाहरण
यहाँ डाउनलोड किया जा सकता
है , लेकिन इसे हमिंगबर्ड ऑपरेटिंग सिस्टम के लिए लिखा गया है (इसलिए यदि आप इस उदाहरण को चलाना चाहते हैं तो आपको इसे डाउनलोड करना होगा)। संकलित कार्यक्रम का आकार 2589 बाइट्स है, रैम का अधिकतम उपयोग लगभग 300 किलोबाइट है। और यह सीमा नहीं है!