开发者

How to disable console logging on certain PDF generated by CGContextDrawPDFPage

I have a problem with certain PDF's logging to console some Node numbers and Font family and it is making my application slow. Anybody know how to disable the开发者_开发百科 logging?

I used: CGContextDrawPDFPage(context, page);

This does not happen on all PDFs, one explanation in another SO question is that the logging happens when renderer doesn't know the font used by PDF. The PDF I used is http://dl.dropbox.com/u/861361/test.pdf

FYI, I'm using version 3.2 iOS (iPad)


Unfortunately i dont know how to suppress the logging.

There is a way to obtain the glyphs though and draw the text as vector elements instead text, thus avoiding font issues. (credit: jegeblad). Glyphs are not directly characters.

Create a font:

//NSString * fontName;
CGFont cgfont = CGFontCreateWithFontName ((CFStringRef)fontName);
CGContextSetFont(cg, cgfont);
CGContextSetFontSize(cg, fontSize);

If we wish to draw e.g. an NSString called word..get some info about the glyph:

int count = [word.s length];
unichar * buffer = new unichar[count+1];
CGGlyph * glyphs = new CGGlyph[count+1];
int * adv = new int[count+1];
CGRect * rects = new CGRect[count+1];
[word.s getCharacters:buffer];
CGFontGetGlyphsForUnichars(cgfont, buffer, glyphs, [word.s length]);
CGFontGetGlyphAdvances(cgfont,glyphs,count,adv);
CGFontGetGlyphBBoxes(cgfont, glyphs, count, rects);

In other words, we get the glyphs for the letters of the word and then we get the dimensions and advances of the individual glyphs. Note: I could not find any way to determine the number of glyphs for a word. Now we are ready to draw the glyphs:

CGContextShowGlyphsAtPoint(outputCG, x, y, glyphs,count);

That's neat but it doesn't solve the whole font-embedding problem. However, we can solve that problem if get quartz to draw the text as vector elements instead of ... well... text. We simply change the way text is drawn using the function:

CGContextSetTextDrawingMode (outputCG, kCGTextClip);

This will use the text as a clipping path instead of simply drawing it. If we first call CGContextShowGlyphsAtPoint and then draw a filled rectangle around the area where the glyphs are shown, that rectangle will be clipped to the glyphs and essentially we are drawing the letters of the word. However, since we are drawing a rectangle and not text, the resulting PDF file will not include the text but instead a set of vector elements that look like text. Therefore Quartz no longer needs to embed the fonts in the PDF file. One way to do this is by the following loop:

double scale = ffontSize / double( CGFontGetUnitsPerEm(cgfont) );
for (size_t i = 0; i < count; ++i) {
CGContextSaveGState(outputCG);
CGContextShowGlyphsAtPoint(outputCG, x, p.y + spaceH, &glyphs[i], 1 );  
CGContextBeginPath(outputCG);
CGContextAddRect(outputCG, 
CGRectMake(x+scale* rects[i].origin.x , p.y + spaceH + scale*(rects[i].origin.y),
scale*(rects[i].size.width), scale*(rects[i].size.height)) );
CGContextFillPath(outputCG);
CGContextRestoreGState(outputCG);
x += adv[i] * scale;
}

draw one glyph at a time by setting the clipping path to the individual glyph and drawing a filled rectangle behind it. I have of course set the current fill color to the color I want the text in.

Remember to release the font when you are done:

CGFontRelease(cgfont);


The logs are generated are flushed to STDOUT, if you REALLY want to disable the logging, close STDOUT and redirect STDOUT to /dev/null or other streams that is not STDOUT ;)

int fileDes = creat("/dev/null", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
dup2(fileDes, STDOUT_FILENO);
close(fileDes);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜