iOS 定制应用程序字体

OpenType字体规范解析(三)cmap表 我们在设计中经常需要使用字体文件,有时候会想一窥究竟字体文件到底是以怎样的格式存储的,OpenType就是定义字体文件存储格式的规范。这篇文章介绍了cmap表。cmap表定义了字符代码到字形索引的映射。字符代码如果没有对应任何字形,应映射到字形索引0,该位置上的字形必须是一个特殊的字形,表示缺失字符,通常称为 .notdef。每个子表有七种可能的格式之一,并以一个格式字段开始,指示所使用的格式。前四种格式——格式 0、2、4 和 6——最初是在 Unicode 2.0 之前定义的。 阅读详情

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.youkuaiyun.com/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

使用Quartz Core绘制文字非常简单,苹果的Quartz 2D参考中演示了如何使用CGContextShowTextAtPoint函数绘制文本。不幸的是,这个函数不支持Unicode字符的绘制(这个函数只支持MacRoman一种编码)。如果你使用中文、日文等亚洲字体,那么就不得不悲催了。

许多童鞋肯定会被文档中的这句话所吸引:

“如果想使用MacRoman以外的文本编码,⋯⋯调用CGContextShowGlyphsAtPoint替代CGContextShowTextAtPoint。”

如果你采用这种办法,那么另一种悲剧就产生了。

一、CGContextShowGlyphsAtPoint的挑战

 

CGContextShowGlyphsAtPoint 函数的第4个参数要使用到CGGlyph数组。意思是你需要自己把unichar字符自已映射成字体文件中的Glyph(字符图形,有称字模、字符点阵)索引。如果你不使用私有框架,那么这是一个几乎不可能完成的任务。

实际上,大部分程序员会建议你用UIKit框架或者[NSString drawAtPoint:]方法而不是NSStringCGContextShowGlyphsAtPoint来绘制unicode字符。

如果你真是只是想在UIView上绘制几句文本,那么drawAtPoint能够满足你的需要,下面的内容你也不必要看了。

 

但是,CGContextShowGlyphsAtPoint就真的没有任何用处了吗?

实际上,苹果最初设计这个API的目的,是为了提供给Application使用定制字体的能力。基本上iOS提供的系统字体非常少,我们在一些app中为了实现一些效果(比如让字体更加清晰)不得不使用自己的字体文件,这个时候这些API就显得非常必要。

然而,关于使用自定字体,苹果的文档描述得非常少。我们知道的仅仅是CGContextSetFont和CGContextSetFontSize、CGContextShowGlyphsAtPoint等3个Quartz函数。所有的google文档都语焉不详。显然,真正要想使用自定字体,根本没有这么简单。

那么真正的挑战在哪里?

StackOverFlow上有人发了一个帖子,帖子问到如何用绘制日文字符(中文也是一样)。其中 Brad Larson 的回复描述得很精确:

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

真正的挑战是unicharàglyph,也就是 CGContextShowGlyphsAtPoint的第4个参数如何获得。Brad提到的例子实际上描述了一种不可能的情况,他假设字体文件中的glyph编码是在unicode编码的基础上加一个固定的偏移量(他称之为Magic Number)构成。实际上对于某个.ttf/.otf字体文件,我们无法获得这个MagicNumber,我们不能靠猜测来编写程序代码。

那么我们只有自己解析字体文件的数据结构了。万幸的是,Zynga Game Networks的 Kevin Ballard实现了一个unichar到glyph的映射。项目地址:https://github.com/zynga/FontLabel。

我们可以利用这个实现来解析cmap为format4和format12的字体文件。

关于cmap的内容,请参考True Type 字体文件相关文档(微软和苹果的网站)。

二、实现过程

1、在程序中加载ttf文件

首先要解决的问题,是在程序中加载.ttf/otf文件。我们在示例程序的资源束中加入了一个“方正大黑简体.ttf”的文件。这个文件是我从Mac系统中搜索到的,应该是MicrosoftOffice中提供的字体文件。我们用以下代码来加载它:

NSString *fontPath = [[NSBundlemainBundle] pathForResource:@"方正大黑简体" ofType:@"ttf"];

    CGDataProviderReffontDataProvider = CGDataProviderCreateWithFilename([fontPath UTF8String]);

    font_ref =CGFontCreateWithDataProvider(fontDataProvider);

    currentTable=readFontTableFromCGFont(font_ref);

    CGDataProviderRelease(fontDataProvider);

提示:在iOS3.2以后,还可以在plist文件中添加 UIAppFonts键的方式添加自定字体。见苹果文档“Custom Font Support”主题。

2、从字体文件中获取Glyph

这部分的实现来自Ballard的FontLabel,非常感谢!整个实现主要包含2个函数定义:

staticfontTable*readFontTableFromCGFont(CGFontRef font);

 

staticvoidmapCharactersToGlyphsInFont(constfontTable *table, unichar characters[], size_t charLen, CGGlyph outGlyphs[], size_t *outGlyphLen) ;

第一个函数用于从CGFont中读取cmap表,第二个函数用于将unichar数组映射为Glyphs数组(实现cmap format4和format12子表)。

3、绘制字符

Quartz绘图是在UIView的drawRect方法中进行,字符也不例外。下面是字符绘制代码:

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, 24.0f);

   

    CGGlyph glyphs[[self.textlength]];

    size_t glyphCount;

    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]);

代码中先使用Ballard实现的mapCharactersToGlyphsInFont函数将unicode字符转换为Glyphs数组,然后用CGContextShowGlyphsAtPoint进行绘制。

注意:由于Quartz空间和用户空间的坐标系统不同(Quartz空间坐标原点位于屏幕左下角,用户空间坐标原点位于屏幕左上角,二者坐标转换只需y坐标取反即可),所以我们使用了一个渐变反射来进行坐标转换并应用于文字矩阵。

4、运行效果

图片

5、源代码下载

整个示例工程见资源下载:http://download.youkuaiyun.com/detail/kmyhy/4359481



           

给我老师的人工智能教程打call!http://blog.youkuaiyun.com/jiangjunshow
这里写图片描述
25、iOS 开发:Table View 的深度定制与使用 本文深入讲解了iOS开发中Table View的深度定制与使用方法,涵盖了UITableViewDelegate委托协议的实现,包括行缩进、行选择控制、字体和行高调整等内容。同时,文章详细介绍了自定义Table View单元格的多种方式,包括以编程方式添加子视图、从nib文件加载单元格等。还提供了常见问题的解决方案和流程图总结,帮助开发者更好地掌握Table View的高级用法。 阅读详情

相关推荐

VS Code配置MASM32汇编环境:从安装到调试的完整指南

本文提供了一份详尽的指南,教你如何在VS Code中配置MASM32汇编开发环境,实现从安装、环境变量设置到编写、编译和调试32位Windows汇编窗口程序的完整工作流。通过集成现代编辑器的便利性与经典汇编工具链,旨在降低学习门槛,提升底层开发效率。

nn3456的博客 483

RewriteCond: NoCase option for non-regex pattern '-f' is not supported and will be ignored.

报错提示: [Tue Dec 02 13:00:53.567492 2014] [rewrite:warn] [pid 10140:tid 3520] AH00665: RewriteCond: NoCase option for non-regex pattern '-f' is not supported and will be ignored. (/home/xxx/.htaccess

____ 3600

Keil5 安装与卸载全攻略:从零开始到完美避坑

本文提供了Keil5集成开发环境的完整安装与卸载指南。针对嵌入式开发新手,详细解析了安装前的关键准备、MDK核心与C51双环境的安装激活步骤、常见问题排查,并重点介绍了如何彻底卸载软件以避免残留问题,帮助用户从零开始搭建稳定高效的开发环境。

weixin_29172963的博客 636

绘制文本

CGContextRef为绘制文字提供了如下函数。 CGAffineTransform CGContextGetTextMatrix(CGContextRef c):获取当前对文本执行变换的变换矩阵。 CGPoint CGContextGetTextPosition(CGContextRef c):获取该CGContextRef中当前绘制文本的位置。 CGContextSelec

qq_22981537的专栏 958

Seedance2.5本地部署指南:从环境配置到生产优化的完整实践

在 AI 内容生成领域,本地部署方案正逐渐成为开发者和技术团队关注的焦点。Seedance2.5 作为一款支持图像和视频生成的 AI 工具,其完全离线运行的能力解决了云端服务在数据隐私、使用成本和访问稳定性方面的痛点。对于需要处理敏感内容、频繁生成素材或希望完全掌控生成流程的技术人员来说,掌握本地部署方法具有实际价值。 本文将以 Seedance2.5 的本地部署为例,详细介绍从环境准备、依赖配置到运行验证的完整流程,同时深入分析关键参数配置、常见问题排查方法以及生产环境下的优化建议。通过实际部署过程,理解

weixin_33139275的博客 731

如何利用三阈值游程理论识别干旱事件_python

如果当前时间点与上一个干旱事件的结束位置相隔不超过一个月(`index - current_event['end_index']

weixin_44259522的博客 1945

初识CoreText

一、基本知识介绍 1.字符(Character)和字形(Glyphs) 排版系统中文本显示的一个重要的过程就是字符到字形的转换,字符是信息本身的元素,而字形是字符的图形表征,字符还会有其它表征比如发音。 字符在计算机中其实就是一个编码,某个字符集中的编码,比如Unicode字符集,就囊括了大都数存在的字符。 而字形则是图形,一般都存储在字体文件中,字形也有它的编码,也就是它在字体中的索引。 一...

weixin_30621711的博客 235

自顶向下与自底向上编程思想的对比

一、核心定义与本质差异自顶向下编程思想如同绘制一幅完整的地图,从整体轮廓逐步细化到局部细节。其本质是从系统的整体目标出发,通过逐层分解将复杂问题简化为可实现的子问题,强调先定义 “做什么”,再考虑 “如何做”。自底向上编程思想则类似于搭建积木,从基础组件开始逐步构建复杂系统。其本质是从现有资源和基础功能出发,通过组合和扩展简单组件来实现复杂功能,强调先解决 “如何做” 的细节,再整合为 “做什么” 的整体。二、设计起点与逻辑流程对比设计起点:以系统的整体目标和业务需求为起点。例如设计一个电商平台,首先明确

二进制君 834

ios编程 定制应用程序字体

源码下载:201208261028444663.zip 使用Quartz Core绘制文字非常简单,苹果的Quartz 2D参考中演示了如何使用CGContextShowTextAtPoint函数绘制文本。不幸的是,这个函数不支持Unicode字符的绘制(这个函数只支持MacRoman一种编码)。如果你使用中文、日文等亚洲字体,那么就不得不悲催了。 许多童鞋肯定会被文档中的这句...

dlt86904的博客 151

6、 实时家禽健康识别与疾病检测系统的深入解析

本文深入解析了一种基于物联网的实时家禽健康识别与疾病检测系统,结合图像分析和音频分析技术,能够有效识别病鸡并防止疾病传播。文章详细介绍了系统的测试环境、数据采集与预处理方法、图像与音频分析流程,并对系统性能进行了全面评估。最后提出了未来改进方向,包括多模态融合、深度学习应用及实时性优化等。

weixin_28840811的博客 186

LeRobot 入门教程(四)SO-101机械臂组装教程

《SO-101机器人组装与配置指南》详细介绍了旗舰机器人SO-101的完整搭建流程。从获取3D打印零件、安装LeRobot软件和FeetechSDK,到分步组装6个关节的机械臂结构(含夹爪/手柄选项),指南提供了清晰的螺丝规格和安装位置说明。重点包括:电机ID/波特率设置方法、USB端口识别技巧、领导者/跟随者臂的校准流程,以及故障排查建议。完成组装后,用户可通过配套Python脚本校准机器人,为后续的自主学习任务做好准备。文档附有视频演示和技术支持通道,确保用户顺利完成机器人部署。

2506_90492529的博客 2582

iOS 添加定制字体到应用程序中

查找字体文件所在的位置 点击字体册,选中相应的中文字体文件位置: 将需要的字体文件拷贝到应用程序包。 编辑 App 中的 info.plist 文件  接下来打开 App 中的 info.plist 文件,该文件应该在 Supporting Files 文件夹 下。添加一个新的 Key,通过右键点击

宇宙神帝 617

nvidia系列教程-AGX-Orin基础环境搭建

NVIDIA Jetson AGX Orin 是一款功能强大的嵌入式AI平台,专为需要高性能和低功耗的边缘计算应用设计。无论是自动驾驶、机器人,还是智能监控系统,Jetson AGX Orin 都能为这些应用提供强大的计算能力。本篇博客将为大家详细介绍如何在AGX Orin(32GB)上搭建基础开发环境,包括系统安装、CUDA和cuDNN的配置等,帮助你快速上手这个强大的平台。架构: 搭载 56 个 Tensor Core 的 1792 核 NVIDIA Ampere c GPUCUDA Cores。

flypig has a dream! 2797

添加定制字体到iOS 应用程序中

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34402408的博客 162

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

iOS学习笔记7- iOS 添加定制字体到应用程序中

目录(?)[+] 查找字体文件所在的位置 点击字体册,选中相应的中文字体文件位置: 将需要的字体文件拷贝到应用程序包。 编辑 App 中的 info.plist 文件  接下来打开 App 中的 info.plist 文件,该文件应该在 Supporting Files 文件夹 下。添加一个新的 Key,通过右键点击 戒者

探路者_iOS 411

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

iOS系统font 大全

1 label.font = [UIFont fontWithName:@"Arial-BoldItalicMT" size:18]; 字体名如下: Font Family: American Typewriter Font: AmericanTypewriter Font: AmericanTypewriter-Bold Font Family: AppleGoth

sxwlyp924app的专栏 517

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

iOS 导航栏颜色设置

//设置返回按钮颜色     self.navigationController.navigationBar.tintColor = [UIColor whiteColor];     //设置导航条背景颜色     self.navigationController.navigationBar.barTintColor = ThemeColor;     //

qq_33646463的博客 1812

使用UIAppearance协议自定义视图

iOS 5的重要补充功能:通过苹果原生类库自定义视图外观。在iOS 5以前,自定义原生控件的外观并没有原生支持,因此开发人员感觉很麻烦。开发人员经常面临的问题是修改一个控件所有实例的外观。解决这个问题的正确方法是重写一遍控件。但由于这么做非常费时,一些开发人员开始覆盖或混写一些方法,如drawRect:。 从iOS 5开始,苹果通过两个协议(UIAppearance和UIAppearance

lf20105103039的专栏 535
上一篇: NSThread NSRunLoop 和 Dispatch Queue
下一篇: Cocos2d开发系列(九)
普通网友
博客等级 码龄8年 4粉丝 110原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值