2012-05-16 5 views
5

Ecco il codice che uso per mostrare una parte di testo in grafica di base:core grafico del testo è il modo più veloce di Nucleo testo - mi sento come mi manca qualcosa

int y = MESSAGE_FRAME.origin.y + 8; 

if (month) y = y + 27; 
int height = [JHomeViewCellContentView heightOfMessage:self.entry.message]; 

CGRect rect = CGRectMake(MESSAGE_FRAME.origin.x + 8, y, MESSAGE_FRAME.size.width - 16, height); 

UIFont *font = [UIFont fontWithName:@"Crimson" size:15.0f]; 

[[UIColor colorWithWhite:0.2 alpha:1.0] setFill]; 

[self.entry.message drawInRect:rect withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft]; 

Ed ecco il codice se voglio mostrare la stesso testo in testo principale:

CGRect rect2 = CGRectMake(MESSAGE_FRAME.origin.x + 8, self.bounds.size.height - y - height + 2, MESSAGE_FRAME.size.width - 16, height); 


    UIFont *font = [UIFont fontWithName:@"Crimson" size:15.0f]; 
    CGFloat lineHeight = [font lineHeight]; 

    CTFontRef fontRef = CTFontCreateWithName((CFStringRef)@"Crimson", 15.0f, NULL); 

    CGFloat lineSpacing = 0; 

    CTParagraphStyleSetting settings[] = { 
     { kCTParagraphStyleSpecifierMinimumLineHeight, sizeof(lineHeight), &lineHeight }, 
     { kCTParagraphStyleSpecifierMaximumLineSpacing, sizeof(lineSpacing), &lineSpacing }, 

    }; 

    CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings, sizeof(settings)/sizeof(settings[0])); 

    NSMutableDictionary *attDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys: 
            (__bridge_transfer id)fontRef, (NSString *)kCTFontAttributeName, 
              (id)[[UIColor colorWithWhite:0.2 alpha:1.0] CGColor], (NSString *)kCTForegroundColorAttributeName, 
              paragraphStyle, kCTParagraphStyleAttributeName, 
              nil]; 

    NSAttributedString *attString = [[NSAttributedString alloc] initWithString:self.entry.message attributes:attDictionary]; 

    //Flip the coordinate system 
    CGContextSetTextMatrix(context, CGAffineTransformIdentity); 
    CGContextTranslateCTM(context, 0, self.bounds.size.height); 
    CGContextScaleCTM(context, 1.0, -1.0); 



    CGMutablePathRef path = CGPathCreateMutable(); 
    CGPathAddRect(path, NULL, rect2); 


    self.framesetter = CTFramesetterCreateWithAttributedString((__bridge_retained CFAttributedStringRef)attString); 
    CTFrameRef theFrame = CTFramesetterCreateFrame(self.framesetter, CFRangeMake(0, [attString length]), path, NULL); 

    CFRelease(path); 

    CTFrameDraw(theFrame, context); 
    CFRelease(theFrame); 

a quanto pare, pur essendo più prolisso, testo principale è destinata ad essere più veloce di core grafico, che è la ragione per cui ho imparato a farlo. Ma eseguendo questo codice attraverso gli strumenti, la core graphics raggiunge i 5ms, mentre il core text lo fa in 14ms. Mi sento come se mi mancasse qualcosa qui. drawInRect è quasi 3 volte più veloce e sento che dovrebbe essere più lento. Ho perfezionato il codice in fondo tanto quanto so come, ma non sono un esperto e gradirei qualsiasi aiuto.

Per chiarire, sto disegnando un blocco di testo su una vista. Questo è tutto ciò che desidero fare. E tutto il testo ha lo stesso aspetto.

+0

La forza del testo principale è nel layout del testo e il codice del disegno sottostante è implementato in Core Graphics, non vedo come potrebbe essere più veloce nel semplice disegno del testo. – overboming

risposta

2

Non uso le cose CT, ma mi sembra che tu stia impostando font invarianti e altri attributi su ogni estrazione. Prova di factoring tutto ciò fino al commento "Capovolgere il sistema di coordinate, e memorizzare nella cache l'attString.

Questo dovrebbe migliorare la velocità per una migliore prova di testa-a-testa.

+0

Il problema è che, sebbene gli attributi rimangano gli stessi, la stringa stessa cambia ogni volta. Come lo memorizzerei quando non è possibile impostare la stringa di NSMutableAttributedString? – Andrew

+0

Vedo. Hmm. Nessuno di questi attributi si riferisce al livello del personaggio, quindi una idea sarebbe quella di sostituire tutti i byte nella stringa attribuita mutabile, ma ciò sembra abbozzato. Per lo meno, è possibile memorizzare attDictionary nella cache (la maggior parte del lavoro è comunque disponibile) e quindi allocare una nuova stringa attribuita non mutabile ogni volta. – danh

1

NSMutableAttributedString vi fa cambiare la stringa attraverso replaceCharactersInRange: withString:

Una volta impostato il dizionario attributi, è possibile limitare ulteriori aggiornamenti stringa alla stringa attribuito tramite: [replaceCharactersInRange myAttString: NSMakeRange (0, myAttString.text.length) withString: newString]

e disegna il rect sporco. Inoltre, ho trovato che CGContextSetTextMatrix significa poco o nulla quando si utilizza CTFrameDraw.

Un'altra nota rapida, non vedo alcuna versione di CTFontRef e CTParagraphStyleRef. Seguono anche la "regola di creazione" e devono essere CFRelease() 'd.

Ultimamente sto attraversando la mia curva di apprendimento del Core Text e sembra che abbia ottenuto risultati promettenti. Spero che le tue ottimizzazioni ti diano una speranza simile.