2012-06-23 21 views
12

में किसी चरित्र का पता लगाने के लिए पथ प्राप्त करें मान लीजिए मेरे पास एक कस्टम फ़ॉन्ट "फू" है जिसका मैं अपने आईओएस ऐप में उपयोग कर रहा हूं। मैंने इसे अपनी परियोजना, प्लिस्ट इत्यादि में जोड़ा है और मैं UILabel एस प्रस्तुत करने में सक्षम हूं और इसके साथ ही ठीक है।आईओएस यूआईएफओटी

अब, यदि मैं उन बिंदुओं का अनुक्रम खोजना चाहता हूं जो उस फ़ॉन्ट में 'पी' अक्षर को "पता लगाएंगे", तो मुझे अंक के अनुक्रम को कैसे प्राप्त होगा? उदाहरण के लिए, मान लीजिए कि मैं CGPath का उपयोग करना चाहता हूं ताकि पत्र 'पी' धीरे-धीरे एक प्लॉटटर की तरह आकर्षित किया जा सके ...

मुझे केवल एक सरणी में CGPoints का अनुक्रम चाहिए, यदि पथ के रूप में खींचा गया तो 'पी' '।

मुझे एहसास है कि 'टी' जैसे कुछ अक्षरों के लिए, यह समझ में नहीं आता है, क्योंकि पेन को 'टी' पार करने के लिए उठाया जाना चाहिए। तो शायद मुझे CGPath एस के अनुक्रम की आवश्यकता है ...

इसे पूरा करने के तरीके पर कोई संकेत?

धन्यवाद!

+1

[आपने क्या प्रयास किया है?] (Http://whathaveyoutried.com) – EmilioPelaez

उत्तर

29

"पी" पत्र से अंक के अनुक्रम में जाने से कई कदम शामिल हैं। आपको कोर टेक्स्ट का उपयोग करने की आवश्यकता होगी।

  1. CTFont बनाएं। आईओएस 7 के बाद से, आप UIFont का उपयोग कर सकते हैं जहां CTFont की आवश्यकता है (वे "टोल-फ्री ब्रिज" हैं)। आप CTFontCreateWithGraphicsFont फ़ंक्शन का उपयोग करके, CTFontCreateWithName (या कुछ अन्य विधियों का उपयोग करके) नाम से CGFont पर सीधे CTFont बना सकते हैं।

  2. CTFontGetGlyphsForCharacters फ़ंक्शन का उपयोग कर पत्र के लिए ग्लिफ प्राप्त करें। पत्र "पी" के लिए सिर्फ एक ग्लिफ होना चाहिए। गैर-अंग्रेजी स्क्रिप्ट में कुछ पात्रों के लिए आपको एकाधिक (संयोजन) ग्लिफ मिल सकते हैं।

  3. CTFontCreatePathForGlyph फ़ंक्शन का उपयोग CGPath ग्लाइफ के लिए प्राप्त करने के लिए करें।

  4. पथ के तत्वों का आकलन करने के लिए CGPathApply का उपयोग करें।

  5. प्रत्येक पंक्ति, चौकोर वक्र, और बिंदुओं के अनुक्रम के पथ के घन वक्र तत्व को कनवर्ट करें। ऐप्पल ऐसा करने के लिए कोई सार्वजनिक एपीआई प्रदान नहीं करता है। आपको इसे स्वयं करने की आवश्यकता होगी। सीधे लाइन तत्वों के लिए यह आसान है। वक्र तत्वों के लिए, आपको कुछ शोध करने की आवश्यकता होगी यदि आप पहले से ही नहीं जानते कि बेज़ीयर वक्र कैसे प्रस्तुत किया जाए। उदाहरण के लिए, convert bezier curve to polygonal chain? देखें।

हम आसानी से एक स्विफ्ट खेल के मैदान में इस के साथ प्रयोग कर सकते हैं:

import UIKit 
import CoreText 
import XCPlayground 

let font = UIFont(name: "HelveticaNeue", size: 64)! 

var unichars = [UniChar]("P".utf16) 
var glyphs = [CGGlyph](count: unichars.count, repeatedValue: 0) 
let gotGlyphs = CTFontGetGlyphsForCharacters(font, &unichars, &glyphs, unichars.count) 
if gotGlyphs { 
    let cgpath = CTFontCreatePathForGlyph(font, glyphs[0], nil)! 
    let path = UIBezierPath(CGPath: cgpath) 
    print(path) 
    XCPlaygroundPage.currentPage.captureValue(path, withIdentifier: "glyph \(glyphs[0])") 
} 

परिणाम:

<UIBezierPath: 0x7fbc89e0d370; <MoveTo {11.072000000000001, 23.808}>, 
<LineTo {11.072000000000001, 40.576000000000001}>, 
<LineTo {22.975999999999999, 40.576000000000001}>, 
<QuadCurveTo {30.560000000000002, 38.432000000000002} - {28.16, 40.576000000000001}>, 
<QuadCurveTo {32.960000000000001, 32.192} - {32.960000000000001, 36.288000000000004}>, 
<QuadCurveTo {30.560000000000002, 25.920000000000002} - {32.960000000000001, 28.096}>, 
<QuadCurveTo {22.975999999999999, 23.808} - {28.16, 23.744}>, 
<Close>, 
<MoveTo {4.992, 45.695999999999998}>, 
<LineTo {4.992, 0}>, 
<LineTo {11.072000000000001, 0}>, 
<LineTo {11.072000000000001, 18.687999999999999}>, 
<LineTo {25.024000000000001, 18.687999999999999}>, 
<QuadCurveTo {35.488, 22.208000000000002} - {31.936, 18.623999999999999}>, 
<QuadCurveTo {39.039999999999999, 32.192} - {39.039999999999999, 25.792000000000002}>, 
<QuadCurveTo {35.488, 42.143999999999998} - {39.039999999999999, 38.591999999999999}>, 
<QuadCurveTo {25.024000000000001, 45.695999999999998} - {31.936, 45.695999999999998}>, 
<Close> 

P glyph path

+0

धन्यवाद! मैं इसे एक शॉट दूंगा और वापस रिपोर्ट करूंगा ... – Joel

+0

@RobMayoff उत्कृष्ट जवाब!बस मैं क्या देख रहा था! चूंकि आप अपने CGPaths को जानते हैं, क्या आप जानते हैं कि मैं सिर्फ बनाए गए पथ में एक पंक्ति कैसे जोड़ सकता हूं? उदाहरण के लिए शुरुआती बिंदु पर वापस कहें। बस जोड़ते हुए: 'pathP = CGPathCreateMutableCopy (CGPathCreateMutableCopy (cgpath)) CGPathAddLineToPoint (pathP, nil, 0, 0)' काम नहीं लग रहा है। ' – user594883

+0

"काम नहीं लग रहा है" का मतलब क्या है? आपको अपना कोड, आउटपुट (अपने संशोधित पथ को डंप करने) का एक नया प्रश्न पोस्ट करना होगा, और यह बताएं कि आउटपुट में क्या गलत है। –

2

उन लोगों के लिए जो उद्देश्य सी में एक ही समाधान देख रहे हैं

UIFont *font = [UIFont fontWithName:@"HelveticaNeue" size:64]; 
    CGFontRef fontref = CGFontCreateWithFontName((__bridge CFStringRef)font.fontName); 
    NSString *unichars = @"I"; 
    CFStringRef yourFriendlyCFString = (__bridge CFStringRef)unichars; 
    CGGlyph glyphs = CGFontGetGlyphWithGlyphName(fontref, yourFriendlyCFString); 
    CTFontRef fontCT = CTFontCreateWithName((__bridge CFStringRef)font.fontName, font.pointSize, NULL); 
    CGPathRef cgpath = CTFontCreatePathForGlyph(fontCT, glyphs, nil); 
    UIBezierPath *path = [UIBezierPath bezierPathWithCGPath:cgpath]; 
    NSLog(@"Complete path For p is %@", path); 
    CGPathApply(cgpath, (__bridge void * _Nullable)(bezierPoints), MyCGPathApplierFunc); 
    NSLog(@"Points on path %@", bezierPoints); 
    for(NSValue *point in bezierPoints){ 

     //Do your work 
    } 

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^