It is very easy to use quartz core to draw text. Apple's quartz 2D reference demonstrates how to use the cgcontextshowtextatpoint function to draw text. Unfortunately, this function does not support Unicode character rendering (this function only supports macroman encoding ). If you use Chinese, Japanese, and other Asian fonts, you have to be miserable.
Many shoes will certainly be attracted by this sentence in the document:
"If you want to use text encoding other than macroman, Zookeeper calls cgcontextshowglyphsatpoint to replace cgcontextshowtextatpoint ."
If you adopt this approach, another tragedy will emerge.I. Challenges of cgcontextshowglyphsatpoint
The cgcontextshowglyphsatpoint function uses the cgglyph array for the 4th parameters. It means that you need to map the unichar characters to the glyph (character graphics, including the modulus and character lattice) indexes in the font file. If you do not use a private framework, this is an almost impossible task.
In fact, most programmers recommend that you use the uikit framework or the [nsstring drawatpoint:] method instead of the nsstringcgcontextshowglyphsatpoint method to draw Unicode characters.
If you really want to draw a few lines of text on uiview, drawatpoint can meet your needs and you don't have to read the following content.
However, does cgcontextshowglyphsatpoint actually have no use?
In fact, Apple initially designed this API to provide the application with the ability to use custom fonts. Basically, IOS provides very few system fonts. In some apps, we have to use our own font files to achieve some effects (such as making the fonts clearer, these APIs are necessary at this time.
However, there are few apple documents describing the use of custom fonts. We only know three quartz functions, including cgcontextsetfont, cgcontextsetfontsize, and cgcontextshowglyphsatpoint. All Google Documents are vague. Obviously, it is not that easy to use custom fonts.
So where are the real challenges?
Someone posted a post on stackoverflow asking how to draw Japanese characters (the same is true for Chinese characters ). Among them, Brad Larson's reply description is very accurate:
You may also be able to print custom characters withcgcontextshowglyphsatpoint (), but the challenge is generating the glyphs on theiphone. This post has an example: gogo-robot.com/devblog /? P = 5-Brad Larson
The real challenge is how to obtain the unichar à glyph, that is, the 4th parameters of cgcontextshowglyphsatpoint. The example mentioned by Brad actually describes an impossible situation. He assumes that the glyph encoding in the font file is composed of a fixed offset (magic number) based on the Unicode encoding. In fact, for a. TTF/. otf font file, we cannot obtain this magicnumber. We cannot compile program code by making guesses.
We only have to parse the data structure of the font file. Fortunately, Kevin Ballard of Zynga game networks implements a ing from unichar to glyph. Project address: https://github.com/~ga/fontlabel.
We can use this implementation to parse the font files whose cmap is format4 and format12.
For cmap content, see the true type font file documentation (Microsoft and Apple websites ).
II. Implementation Process
1. Load the TTF file in the program
The first problem to be solved is to load the. TTF/otf file in the program. We added a "正. TTF" file to the resource bundle of the sample program. This file is searched from the MAC system and should be a font file provided by Microsoft Office. We use the following code to load it:
Nsstring * fontpath = [[nsbundlemainbundle] pathforresource: @ "正" oftype: @ "TTF"];
Cgdataproviderreffontdataprovider = cgdataprovidercreatewithfilename ([fontpath utf8string]);
Font_ref = cgfontcreatewithdataprovider (fontdataprovider );
Currenttable = readfonttablefromcgfont (font_ref );
Cgdataproviderrelease (fontdataprovider );
Tip: After ios3.2, you can add a Custom font by adding the uiappfonts key to the plist file. See the apple documentation"Custom font support"Topic.
2. Obtain the glyph from the font file
This part of implementation comes from ballard's fontlabel. Thank you very much! The entire implementation mainly includes two function definitions:
Staticfonttable * readfonttablefromcgfont (cgfontref font );
Staticvoidmapcharacterstoglyphsinfont (constfonttable * Table, unichar characters , size_t charlen, cgglyph outglyphs , size_t * outglyphlen );
The first function is used to read the cmap table from cgfont, and the second function is used to map the unichar array to the glyphs array (implement the cmap format4 and format12 sub-tables ).
3. Draw characters
Quartz plot is performed in the drawrect method of uiview, and the characters are no exception. The following code is used to draw characters:
Cgcontextref context = uigraphicsgetcurrentcontext ();
Cgcontextclearrect (context, rect );
Cgcontextsetfont (context, font_ref );
Cgcontextsettextdrawingmode (context, kcgtextfillstroke );
Cgcontextsetfillcolorwithcolor (context, fontcolor. cgcolor );
Uicolor * strokecolor = [uicolorblackcolor];
Cgcontextsetstrokecolorwithcolor (context, strokecolor. cgcolor );
Cgcontextsetfontsize (context, 24366f );
Cgglyph glyphs [[self. textlength];
Unichar textchars [[textlength];
[Textgetcharacters: textchars range: nsmakerange (0, text. Length)];
Mapcharacterstoglyphsinfont (currenttable, textchars, text. length, glyphs, & glyphcount );
Cgaffinetransform texttransform = cgaffinetransformmake (1.0, 0.0, 0.0,-1.0, 0.0, 0.0 );
Cgcontextsettextmatrix (context, texttransform );
Cgcontextshowglyphsatpoint (context, 20, 30, glyphs, [self. textlength]);
In the code, use the mapcharacterstoglyphsinfont function implemented by Ballard to convert Unicode characters to the glyphs array, and then use cgcontextshowglyphsatpoint to draw.
Note: The quartz space and the user space coordinate system are different (the quartz space coordinate origin is located in the lower-left corner of the screen, and the user space coordinate origin is located in the upper-left corner of the screen. Only Y coordinates are needed for the two coordinates to be reversed ), so we use a gradient reflection for Coordinate Transformation and apply it to the text matrix.
4. Running Effect
5. Download source code
For the entire example project, see resource download: http://download.csdn.net/detail/kmyhy/4359481