<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="css/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>风与水的天堂</title><link>http://www.rtoslab.net/</link><description>much's  BLOG</description><generator>RainbowSoft Studio Z-Blog 1.8 Walle Build 100427</generator><language>zh-CN</language><copyright>Copyright 2008 RTosLab.Net. Some Rights Reserved.豫ICP备09027498号var lainframe;</copyright><pubDate>Tue, 22 Jun 2010 17:13:32 +0800</pubDate><item><title>Win7 快捷键 </title><author>netmuch@gmail.com (much)</author><link>http://www.rtoslab.net/2010/06/201062217737.html</link><pubDate>Tue, 22 Jun 2010 17:07:37 +0800</pubDate><guid>http://www.rtoslab.net/2010/06/201062217737.html</guid><description><![CDATA[<p>1. 轻松访问键盘快捷方式<br /><br />按住右Shift 八秒钟： 启用和关闭筛选键<br /><br />按左 Alt+左 Shift+PrtScn(或 PrtScn)：启用或关闭高对比度<br /><br />按左 Alt+左 Shift+Num Lock ：启用或关闭鼠标键<br /><br />按 Shift 五次： 启用或关闭粘滞键<br /><br />按住 Num Lock 五秒钟：启用或关闭切换键<br /><br />Windows 徽标键 + U ： 打开轻松访问中心<br /><br />2. 常规键盘快捷方式<br /><br />F1 显示帮助<br /><br />Ctrl+C&nbsp; 复制选择的项目<br /><br />Ctrl+X&nbsp; 剪切选择的项目<br /><br />Ctrl+V&nbsp; 粘贴选择的项目<br /><br />Ctrl+Z&nbsp; 撤消操作<br /><br />Ctrl+Y&nbsp; 重新执行某项操作<br /><br />Delete&nbsp; 删除所选项目并将其移动到&ldquo;回收站&rdquo;<br /><br />Shift+Delete&nbsp; 不先将所选项目移动到&ldquo;回收站&rdquo;而直接将其删除<br /><br />F2 重命名选定项目<br /><br />Ctrl+向右键 将光标移动到下一个字词的起始处<br /><br />Ctrl+向左键 将光标移动到上一个字词的起始处<br /><br />Ctrl+向下键 将光标移动到下一个段落的起始处<br /><br />Ctrl+向上键 将光标移动到上一个段落的起始处<br /><br />Ctrl+Shift 加某个箭头键 选择一块文本<br /><br />Shift 加任意箭头键 在窗口中或桌面上选择多个项目，或者在文档中选择文本<br /><br />Ctrl 加任意箭头键+空格键 选择窗口中或桌面上的多个单个项目<br /><br />Ctrl+A 选择文档或窗口中的所有项目<br /><br />F3 搜索文件或文件夹<br /><br />Alt+Enter 显示所选项的属性<br /><br />Alt+F4 关闭活动项目或者退出活动程序<br /><br />Alt+空格键 为活动窗口打开快捷方式菜单<br /><br />Ctrl+F4 关闭活动文档(在允许同时打开多个文档的程序中)<br /><br />Alt+Tab 在打开的项目之间切换<br /><br />Ctrl+Alt+Tab 使用箭头键在打开的项目之间切换<br /><br />Ctrl+鼠标滚轮 更改桌面上的图标大小<br /><br />Windows 徽标键 + Tab 使用 Aero Flip 3-D 循环切换任务栏上的程序<br /><br />Ctrl + Windows 徽标键 + Tab 通过 Aero Flip 3-D 使用箭头键循环切换任务栏上的程序<br /><br />Alt+Esc 以项目打开的顺序循环切换项目<br /><br />F6 在窗口中或桌面上循环切换屏幕元素<br /><br />F4 在 Windows 资源管理器中显示地址栏列表<br /><br />Shift+F10 显示选定项目的快捷菜单<br /><br />Ctrl+Esc 打开「开始」菜单<br /><br />Alt+加下划线的字母 显示相应的菜单<br /><br />Alt+加下划线的字母 执行菜单命令(或其他有下划线的命令)<br /><br />F10 激活活动程序中的菜单栏<br /><br />向右键 打开右侧的下一个菜单或者打开子菜单<br /><br />向左键 打开左侧的下一个菜单或者关闭子菜单<br /><br />F5 刷新活动窗口<br /><br />Alt+向上键 在 Windows 资源管理器中查看上一级文件夹<br /><br />Esc 取消当前任务<br /><br />Ctrl+Shift+Esc 打开任务管理器<br /><br />插入 CD 时按住 Shift 阻止 CD 自动播放<br /><br />3. 对话框键盘快捷方式<br /><br />Ctrl+Tab&nbsp; 在选项卡上向前移动<br /><br />Ctrl+Shift+Tab&nbsp; 在选项卡上向后移动<br /><br />Tab&nbsp; 在选项上向前移动<br /><br />Shift+Tab&nbsp; 在选项上向后移动<br /><br />Alt+加下划线的字母&nbsp; 执行与该字母匹配的命令(或选择选项)<br /><br />Enter&nbsp; 对于许多选定命令代替单击鼠标<br /><br />空格键 如果活动选项是复选框，则选中或清除该复选框<br /><br />箭头键 如果活动选项是一组选项按钮，则选择某个按钮<br /><br />F1 显示帮助<br /><br />F4 显示活动列表中的项目<br /><br />Backspace 如果在&ldquo;另存为&rdquo;或&ldquo;打开&rdquo;对话框中选中了某个文件夹，则打开上一级文件夹<br /><br /><br />4. Windows 徽标键相关的快捷键<br /><br />Windows徽标键就是显示为Windows旗帜，或标有文字Win或Windows的按键，以下简称Win键。XP时代有4个经典的 Win 键组合：R/E/F/L。到了 Win7，花样更多了。<br /><br />Win：打开或关闭开始菜单<br /><br />Win + Pause：显示系统属性对话框<br /><br />Win + D：显示桌面<br /><br />Win + M：最小化所有窗口<br /><br />Win + SHIFT + M：还原最小化窗口到桌面上<br /><br />Win + E：打开我的电脑<br /><br />Win + F：搜索文件或文件夹<br /><br />Ctrl + Win + F：搜索计算机(如果您在网络上)<br /><br />Win + L：锁定您的计算机或切换用户<br /><br />Win + R：打开运行对话框<br /><br />Win + T：切换任务栏上的程序(感觉是和alt+ESC 一样 )<br /><br />Win + 数字：让位于任务栏指定位置(按下的数字作为序号)的程序，新开一个实例。(感觉这个比较新颖，貌似快速启动。) Shift + Windows logo key +number：Start a new instance of the program pinned to the taskbar in the position indicated by the number<br /><br />Ctrl + Win + 数字：让位于任务栏指定位置(按下的数字作为序号)的程序，切换到上一次的活动窗口。 Ctrl+Windows logo key +number：Switch to the last active window of the program pinned to the taskbar in the position indicated by the number<br /><br />ALT + Win + 数字：让位于任务栏指定位置(按下的数字作为序号)的程序，显示跳转清单。 Alt+Windows logo key +number： Open the Jump List for the program pinned to the taskbar in the position indicated by the number<br /><br />Win + TAB：循环切换任务栏上的程序并使用的Aero三维效果<br /><br />Ctrl + Win + TAB：使用方向键来循环循环切换任务栏上的程序，并使用的Aero三维效果<br /><br />按Ctrl + Win + B：切换到在通知区域中显示信息的程序<br /><br />Win + 空格：预览桌面<br /><br />Win + &uarr;：最大化窗口<br /><br />Win + &darr;：最小化窗口<br /><br />Win + &larr;：最大化到窗口左侧的屏幕上<br /><br />Win + &rarr;：最大化窗口到右侧的屏幕上<br /><br />Win + Home：最小化所有窗口，除了当前激活窗口<br /><br />Win+ SHIFT + &uarr;：拉伸窗口的到屏幕的顶部和底部<br /><br />Win+ SHIFT + &rarr;/&larr;：移动一个窗口，从一个显示器到另一个<br /><br />Win + P：选择一个演示文稿显示模式<br /><br />Win + G：循环切换侧边栏的小工具<br /><br />Win + U：打开轻松访问中心<br /><br />Win + x：打开Windows移动中心<br /><br />5. Windows Explorer相关快捷键<br /><br />Ctrl+N 打开新窗口<br /><br />Ctrl+Shift+N 新建文件夹<br /><br />End 显示活动窗口的底部<br /><br />Home 显示活动窗口的顶部<br /><br />F11 最大化或最小化活动窗口<br /><br />Num Lock+小键盘星号(*) 显示选中文件夹的所有子文件夹<br /><br />Num Lock+小键盘加号(+) 显示选中文件夹的内容<br /><br />Num Lock+小键盘减号(-) 折叠选中文件夹<br /><br />左方向键 折叠当前展开的选中文件夹或选中上层文件夹<br /><br />Alt+Enter 打开选中项目的属性对话框<br /><br />Alt+P 显示预览窗格<br /><br />Alt+左方向键 切换到前一次打开的文件夹<br /><br />右方向键 显示(展开)当前选中项目或选中第一个子文件夹<br /><br />Alt+右方向键 切换到下一次后打开的文件夹<br /><br />Alt+上方向键 打开上层文件夹<br /><br />Ctrl+鼠标滚轮 改变文件和文件夹图标的大小和外观<br /><br />Alt+D 选中地址栏(定位到地址栏)<br /><br />Ctrl+E 选中搜索框(定位到搜索框)<br /><br />6. 放大镜键盘快捷方式<br /><br />Windows 徽标键 + 加号或减号 放大或缩小<br /><br />Ctrl+Alt+空格键 显示鼠标指针<br /><br />Ctrl+Alt+F 切换到全屏模式<br /><br />Ctrl+Alt+L 切换到镜头模式<br /><br />Ctrl+Alt+D 切换到停靠模式<br /><br />Ctrl+Alt+I 反色<br /><br />Ctrl+Alt+箭头键 按箭头键的方向平移<br /><br />Ctrl+Alt+R 调整镜头的大小<br /><br />Windows 徽标键 + Esc 退出放大镜<br /><br />7. 远程桌面相关快捷键<br /><br />Alt+Page Up 按从左向右顺序切换程序<br /><br />Alt+Page Down 按从右向左切换程序<br /><br />Alt+Insert 按程序打开先后顺序循环切换程序<br /><br />Alt+Home 显示&ldquo;开始&rdquo;菜单<br /><br />Ctrl+Alt+Break 在窗口模式和全屏之间切换<br /><br />Ctrl+Alt+End 显示Windows安全性对话框<br /><br />Alt+Delete 显示当前窗口的系统菜单<br /><br />Ctrl+Alt+-(小键盘减号) 当前活动窗口截图<br /><br />Ctrl+Alt++(小键盘加号) 全屏截图<br /><br />Ctrl+Alt+向右键 从远程桌面控件&ldquo;跳转&rdquo;到主机程序中的控件(如按钮或文本框)。将远程桌面控件嵌入到其他(主机)程序后，此功能非常有用。<br /><br />Ctrl+Alt+向左键 从远程桌面控件&ldquo;跳转&rdquo;到主机程序中的控件(如按钮或文本框)。将远程桌面控件嵌入到其他(主机)程序后，此功能非常有用。<br /><br />8. 画图键盘快捷方式<br /><br />Ctrl+N 创建新的图片<br /><br />Ctrl+O 打开现有图片<br /><br />Ctrl+S 将更改保存到图片<br /><br />F12 将此图片另存为新文件<br /><br />Ctrl+P 打印图片<br /><br />Alt+F4 关闭图片及其画图窗口<br /><br />Ctrl+Z 撤消更改<br /><br />Ctrl+Y 恢复更改<br /><br />Ctrl+A 选择整个图片<br /><br />Ctrl+X 剪切选择内容<br /><br />Ctrl+C 将选择内容复制到剪贴板<br /><br />Ctrl+V 从剪贴板粘贴选择内容<br /><br />向右键 将选择内容或活动图形向右移动一个像素<br /><br />向左键 将选择内容或活动图形向左移动一个像素<br /><br />向下键 将选择内容或活动图形向下移动一个像素<br /><br />向上键 将选择内容或活动图形向上移动一个像素<br /><br />Esc 取消某个选择<br /><br />Delete 删除某个选择<br /><br />Ctrl+B 粗体选择文本<br /><br />Ctrl++ 将画笔、直线或形状轮廓的宽度增加一个像素<br /><br />Ctrl+- 将画笔、直线或形状轮廓的宽度减少一个像素<br /><br />Ctrl+I 将所选文本改为斜体<br /><br />Ctrl+U 为所选文本添加下划线<br /><br />Ctrl+E 打开&ldquo;属性&rdquo;对话框<br /><br />Ctrl+W 打开&ldquo;调整大小和扭曲&rdquo;对话框<br /><br />Ctrl+Page Up 放大<br /><br />Ctrl+Page Down 缩小<br /><br />F11 以全屏模式查看图片<br /><br />Ctrl+R 显示或隐藏标尺<br /><br />Ctrl+G 显示或隐藏网格线<br /><br />F10 或 Alt 显示快捷键提示<br /><br />Shift+F10 显示当前快捷菜单<br /><br />F1 打开&ldquo;画图&rdquo;帮助<br /><br />9. 写字板的键盘快捷方式<br /><br />Ctrl+N 新建一个文档<br /><br />Ctrl+O 打开一个现有文档<br /><br />Ctrl+S 将更改保存到文档<br /><br />F12 将此文档另存为新文件<br /><br />Ctrl+P 打印文档<br /><br />Alt+F4 关闭&ldquo;写字板&rdquo;<br /><br />Ctrl+Z 撤消更改<br /><br />Ctrl+Y 恢复更改<br /><br />Ctrl+A 选择整个文档<br /><br />Ctrl+X 剪切选择内容<br /><br />Ctrl+C 将选择内容复制到剪贴板<br /><br />Ctrl+V 从剪贴板粘贴选择内容<br /><br />Ctrl+B 将所选文本改为粗体<br /><br />Ctrl+I 将所选文本改为斜体<br /><br />Ctrl+U 为所选文本添加下划线<br /><br />Ctrl+= 使选择的文本成为下标<br /><br />Ctrl+Shift+= 使选择的文本成为上标<br /><br />Ctrl+L 向左对齐文本<br /><br />Ctrl+E 向中心对齐文本<br /><br />Ctrl+R 向右对齐文本<br /><br />Ctrl+J 对齐文本<br /><br />Ctrl+1 设置单倍行距<br /><br />Ctrl+2 设置双倍行距<br /><br />Ctrl+5 将行距设置为 1.5<br /><br />Ctrl+Shift+&gt; 增加字体大小<br /><br />Ctrl+Shift+&lt; 减小字体大小<br /><br />Ctrl+Shift+A 将字符更改为全部使用大写字母<br /><br />Ctrl+Shift+L 更改项目符号样式<br /><br />Ctrl+D 插入 Microsoft 画图图片<br /><br />Ctrl+F 在文档中查找文本<br /><br />F3 在&ldquo;查找&rdquo;对话框中查找文本的下一个实例<br /><br />Ctrl+H 在文档中替换文本<br /><br />Ctrl+向左键 将光标向左移动一个字<br /><br />Ctrl+向右键 将光标向右移动一个字<br /><br />Ctrl+向上键 将光标移动到上一行<br /><br />Ctrl+向下键 将光标移动到下一行<br /><br />Ctrl+Home 移动到文档的开头<br /><br />Ctrl+End 移动到文档的结尾<br /><br />Ctrl+Page Up 向上移动一个页面<br /><br />Ctrl+Page Down 向下移动一个页面<br /><br />Ctrl+Delete 删除下一个字<br /><br />F10 显示快捷键提示<br /><br />Shift+F10 显示当前快捷菜单<br /><br />F1 打开&ldquo;写字板&rdquo;帮助<br /><br />10. 计算器的键盘快捷方式<br /><br />Atl+1 切换到标准模式<br /><br />Alt+2 切换到科学型模式<br /><br />Alt+3 切换到程序员模式<br /><br />Alt+4 切换到统计信息模式<br /><br />Ctrl+E 打开日期计算<br /><br />Ctrl+H 将计算历史记录打开或关闭<br /><br />Ctrl+U 打开单位转换<br /><br />Alt+C 计算或解决日期计算和工作表<br /><br />F1 打开&ldquo;计算器&rdquo;帮助<br /><br />Ctrl+Q 按下 M- 按钮<br /><br />Ctrl+P 按下 M+ 按钮<br /><br />Ctrl+M 按下 MS 按钮<br /><br />Ctrl+R 按下 MR 按钮<br /><br />Ctrl+L 按下 MC 按钮<br /><br />% 按下 % 按钮<br /><br />F9 按下 +/&ndash; 按钮<br /><br />/ 按下 / 按钮<br /><br />* 按下 * 按钮<br /><br />+ 按下 + 按钮<br /><br />- 按下 &ndash; 按钮<br /><br />R 按下 1/&times; 按钮<br /><br />@ 按下平方根按钮<br /><br />0-9 按下数字按钮 (0-9)<br /><br />= 按下 = 按钮<br /><br />. 按下 .(小数点)按钮<br /><br />Backspace 按下 Backspace 按钮<br /><br />Esc 按下 C 按钮<br /><br />Del 按下 CE 按钮<br /><br />Ctrl+Shift+D 清除计算历史记录<br /><br />F2 编辑计算历史记录<br /><br />向上箭头键 在计算历史记录中向上导航<br /><br />向下箭头键 在计算历史记录中向下导航<br /><br />Esc 取消编辑计算历史记录<br /><br />Enter 编辑后重新计算计算历史记录<br /><br />F3 在科学型模式下选择&ldquo;角度&rdquo;<br /><br />F4 在科学型模式下选择&ldquo;弧度&rdquo;<br /><br />F5 在科学型模式下选择&ldquo;梯度&rdquo;<br /><br />I 在科学型模式下按 Inv 按钮<br /><br />D 在科学型模式下按 Mod 按钮<br /><br />Ctrl+S 在科学型模式下按 sinh 按钮<br /><br />Ctrl+O 在科学型模式下按 cosh 按钮<br /><br />Ctrl+T 在科学型模式下按 tanh 按钮<br /><br />( 在科学型模式下按 ( 按钮<br /><br />) 在科学型模式下按 ) 按钮<br /><br />N 在科学型模式下按 ln 按钮<br /><br />; 在科学型模式下按 Int 按钮<br /><br />S 在科学型模式下按 sin 按钮<br /><br />O 在科学型模式下按 cos 按钮<br /><br />T 在科学型模式下按 tan 按钮<br /><br />M 在科学型模式下按 dms 按钮<br /><br />P 在科学型模式下按 pi 按钮<br /><br />V 在科学型模式下按 F-E 按钮<br /><br />X 在科学型模式下按 Exp 按钮<br /><br />Q 在科学型模式下按 x^2 按钮<br /><br />Y 在科学型模式下按 x^y 按钮<br /><br /># 在科学型模式下按 x^3 按钮<br /><br />L 在科学型模式下按 log 按钮<br /><br />! 在科学型模式下按 n! 按钮<br /><br />Ctrl+Y 在科学型模式下按 y&radic;x 按钮<br /><br />Ctrl+B 在科学型模式下按 3&radic;x 按钮<br /><br />Ctrl+G 在科学型模式下按 10x 按钮<br /><br />F5 在程序员模式下选择 Hex<br /><br />F6 在程序员模式下选择 Dec<br /><br />F7 在程序员模式下选择 Oct<br /><br />F8 在程序员模式下选择 Bin<br /><br />F12 在程序员模式下选择 QWord<br /><br />F2 在程序员模式下选择 Dword<br /><br />F3 在程序员模式下选择 Word<br /><br />F4 在程序员模式下选择 Byte<br /><br />K 在程序员模式下按 RoR 按钮<br /><br />J 在程序员模式下按 RoL 按钮<br /><br />% 在程序员模式下按 Mod 按钮<br /><br />( 在程序员模式下按 ( 按钮<br /><br />) 在程序员模式下按 ) 按钮<br /><br />| 在程序员模式下按 Or 按钮<br /><br />^ 在程序员模式下按 Xor 按钮<br /><br />~ 在程序员模式下按 Not 按钮<br /><br />&amp; 在程序员模式下按 And 按钮<br /><br />A-F 在程序员模式下按 A-F 按钮<br /><br />空格键 在程序员模式下切换位值<br /><br />A 在统计信息模式下按 Average 按钮<br /><br />Ctrl+A 在统计信息模式下按 Average Sq 按钮<br /><br />S 在统计信息模式下按 Sum 按钮<br /><br />Ctrl+S 在统计信息模式下按 Sum Sq 按钮<br /><br />T 在统计信息模式下按 S.D. 按钮<br /><br />Ctrl+T 在统计信息模式下按 Inv S.D. 按钮<br /><br />D 在统计信息模式下按 CAD 按钮<br /><br />11. Windows 日记本键盘快捷方式<br /><br />Ctrl+N 开始新的便笺<br /><br />Ctrl+O 打开最近使用的便笺<br /><br />Ctrl+S 将更改保存到便笺<br /><br />Ctrl+Shift+V 将便笺移动到特定的文件夹<br /><br />Ctrl+P 打印便笺<br /><br />Alt+F4 关闭便笺及其日记本窗口<br /><br />Ctrl+Z 撤消更改<br /><br />Ctrl+Y 恢复更改<br /><br />Ctrl+A 选择页面上的所有项目<br /><br />Ctrl+X 剪切选择内容<br /><br />Ctrl+C 将选择内容复制到剪贴板<br /><br />Ctrl+V 从剪贴板粘贴选择内容<br /><br />Esc 取消某个选择<br /><br />Delete 删除某个选择<br /><br />Ctrl+F 开始基本查找<br /><br />Ctrl+G 转到页面<br /><br />F5 刷新查找结果<br /><br />F5 刷新便笺列表<br /><br />F6 在便笺列表和便笺之间切换<br /><br />Ctrl+Shift+C 显示便笺列表中列标题的快捷菜单<br /><br />F11 以全屏模式查看便笺<br /><br />F1 打开&ldquo;日记本&rdquo;帮助<br /><br />12. Windows 帮助查看器键盘快捷方式<br /><br />Alt+C 显示目录<br /><br />Alt+N 显示&ldquo;连接设置&rdquo;菜单<br /><br />F10 显示&ldquo;选项&rdquo;菜单<br /><br />Alt+向左键 返回先前查看过的主题<br /><br />Alt+向右键 向前移动到下一个(先前已查看过的)主题<br /><br />Alt+A 显示客户支持页面<br /><br />Alt+Home 显示帮助和支持主页<br /><br />Home 移动到主题的开头<br /><br />End 移动到主题的末尾<br /><br />Ctrl+F 搜索当前主题<br /><br />Ctrl+P 打印主题<br /><br />F3 将光标移动到搜索框</p><p>Copyright © 2010</p><p><a href="http://www.rtoslab.net/2010/06/201062217737.html" target="_blank">继续阅读《Win7 快捷键 》的全文内容...</a></p><p>分类: <a href="http://www.rtoslab.net/post/clutter.html">杂七杂八</a> | Tags: <a href="http://www.rtoslab.net/catalog.asp?tags=windows7++%E5%BF%AB%E6%8D%B7%E9%94%AE">windows7  快捷键</a>&nbsp;&nbsp; | <a href="http://www.rtoslab.net/2010/06/201062217737.html#comment" target="_blank">添加评论</a>(0)</p><p><a href="http://www.rtoslab.net/2010/06/201062217737.html#comment" target="_blank">还没有相关文章，您来说两句？</a></p>]]></description><category>杂七杂八</category><comments>http://www.rtoslab.net/2010/06/201062217737.html#comment</comments><wfw:comment>http://www.rtoslab.net/</wfw:comment><wfw:commentRss>http://www.rtoslab.net/feed.asp?cmt=82</wfw:commentRss><trackback:ping>http://www.rtoslab.net/cmd.asp?act=tb&amp;id=82&amp;key=a37a56e0</trackback:ping></item><item><title>翻出以前学习WindML的一些笔记记录。</title><author>netmuch@gmail.com (much)</author><link>http://www.rtoslab.net/2010/06/2010618105518.html</link><pubDate>Fri, 18 Jun 2010 10:55:18 +0800</pubDate><guid>http://www.rtoslab.net/2010/06/2010618105518.html</guid><description><![CDATA[<p><meta content="text/html; charset=utf-8" http-equiv="Content-Type" /><meta content="Word.Document" name="ProgId" /><meta content="Microsoft Word 14" name="Generator" /><meta content="Microsoft Word 14" name="Originator" /><link href="file:///C:\Users\much\AppData\Local\Temp\msohtmlclip1\01\clip_filelist.xml" rel="File-List" /><!--[if gte mso 9]><xml><o:OfficeDocumentSettings><o:AllowPNG /></o:OfficeDocumentSettings></xml><![endif]--><link href="file:///C:\Users\much\AppData\Local\Temp\msohtmlclip1\01\clip_themedata.thmx" rel="themeData" /><link href="file:///C:\Users\much\AppData\Local\Temp\msohtmlclip1\01\clip_colorschememapping.xml" rel="colorSchemeMapping" /><!--[if gte mso 9]><xml><w:WordDocument><w:View>Normal</w:View><w:Zoom>0</w:Zoom><w:TrackMoves /><w:TrackFormatting /><w:PunctuationKerning /><w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing><w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery><w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery><w:ValidateAgainstSchemas /><w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid><w:IgnoreMixedContent>false</w:IgnoreMixedContent><w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText><w:DoNotPromoteQF /><w:LidThemeOther>EN-US</w:LidThemeOther><w:LidThemeAsian>ZH-CN</w:LidThemeAsian><w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript><w:Compatibility><w:SpaceForUL /><w:BalanceSingleByteDoubleByteWidth /><w:DoNotLeaveBackslashAlone /><w:ULTrailSpace /><w:DoNotExpandShiftReturn /><w:AdjustLineHeightInTable /><w:BreakWrappedTables /><w:SnapToGridInCell /><w:WrapTextWithPunct /><w:UseAsianBreakRules /><w:DontGrowAutofit /><w:SplitPgBreakAndParaMark /><w:EnableOpenTypeKerning /><w:DontFlipMirrorIndents /><w:OverrideTableStyleHps /><w:UseFELayout /></w:Compatibility><m:mathPr><m:mathFont m:val="Cambria Math" /><m:brkBin m:val="before" /><m:brkBinSub m:val="&#45;-" /><m:smallFrac m:val="off" /><m:dispDef /><m:lMargin m:val="0" /><m:rMargin m:val="0" /><m:defJc m:val="centerGroup" /><m:wrapIndent m:val="1440" /><m:intLim m:val="subSup" /><m:naryLim m:val="undOvr" /></m:mathPr></w:WordDocument></xml><![endif]--><!--[if gte mso 9]><xml><w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"DefSemiHidden="true" DefQFormat="false" DefPriority="99"LatentStyleCount="267"><w:LsdException Locked="false" Priority="0" SemiHidden="false"UnhideWhenUsed="false" QFormat="true" Name="Normal" /><w:LsdException Locked="false" Priority="9" SemiHidden="false"UnhideWhenUsed="false" QFormat="true" Name="heading 1" /><w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2" /><w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3" /><w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4" /><w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5" /><w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6" /><w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7" /><w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8" /><w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9" /><w:LsdException Locked="false" Priority="39" Name="toc 1" /><w:LsdException Locked="false" Priority="39" Name="toc 2" /><w:LsdException Locked="false" Priority="39" Name="toc 3" /><w:LsdException Locked="false" Priority="39" Name="toc 4" /><w:LsdException Locked="false" Priority="39" Name="toc 5" /><w:LsdException Locked="false" Priority="39" Name="toc 6" /><w:LsdException Locked="false" Priority="39" Name="toc 7" /><w:LsdException Locked="false" Priority="39" Name="toc 8" /><w:LsdException Locked="false" Priority="39" Name="toc 9" /><w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption" /><w:LsdException Locked="false" Priority="10" SemiHidden="false"UnhideWhenUsed="false" QFormat="true" Name="Title" /><w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font" /><w:LsdException Locked="false" Priority="11" SemiHidden="false"UnhideWhenUsed="false" QFormat="true" Name="Subtitle" /><w:LsdException Locked="false" Priority="22" SemiHidden="false"UnhideWhenUsed="false" QFormat="true" Name="Strong" /><w:LsdException Locked="false" Priority="20" SemiHidden="false"UnhideWhenUsed="false" QFormat="true" Name="Emphasis" /><w:LsdException Locked="false" Priority="59" SemiHidden="false"UnhideWhenUsed="false" Name="Table Grid" /><w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text" /><w:LsdException Locked="false" Priority="1" SemiHidden="false"UnhideWhenUsed="false" QFormat="true" Name="No Spacing" /><w:LsdException Locked="false" Priority="60" SemiHidden="false"UnhideWhenUsed="false" Name="Light Shading" /><w:LsdException Locked="false" Priority="61" SemiHidden="false"UnhideWhenUsed="false" Name="Light List" /><w:LsdException Locked="false" Priority="62" SemiHidden="false"UnhideWhenUsed="false" Name="Light Grid" /><w:LsdException Locked="false" Priority="63" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Shading 1" /><w:LsdException Locked="false" Priority="64" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Shading 2" /><w:LsdException Locked="false" Priority="65" SemiHidden="false"UnhideWhenUsed="false" Name="Medium List 1" /><w:LsdException Locked="false" Priority="66" SemiHidden="false"UnhideWhenUsed="false" Name="Medium List 2" /><w:LsdException Locked="false" Priority="67" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 1" /><w:LsdException Locked="false" Priority="68" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 2" /><w:LsdException Locked="false" Priority="69" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 3" /><w:LsdException Locked="false" Priority="70" SemiHidden="false"UnhideWhenUsed="false" Name="Dark List" /><w:LsdException Locked="false" Priority="71" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful Shading" /><w:LsdException Locked="false" Priority="72" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful List" /><w:LsdException Locked="false" Priority="73" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful Grid" /><w:LsdException Locked="false" Priority="60" SemiHidden="false"UnhideWhenUsed="false" Name="Light Shading Accent 1" /><w:LsdException Locked="false" Priority="61" SemiHidden="false"UnhideWhenUsed="false" Name="Light List Accent 1" /><w:LsdException Locked="false" Priority="62" SemiHidden="false"UnhideWhenUsed="false" Name="Light Grid Accent 1" /><w:LsdException Locked="false" Priority="63" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1" /><w:LsdException Locked="false" Priority="64" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1" /><w:LsdException Locked="false" Priority="65" SemiHidden="false"UnhideWhenUsed="false" Name="Medium List 1 Accent 1" /><w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision" /><w:LsdException Locked="false" Priority="34" SemiHidden="false"UnhideWhenUsed="false" QFormat="true" Name="List Paragraph" /><w:LsdException Locked="false" Priority="29" SemiHidden="false"UnhideWhenUsed="false" QFormat="true" Name="Quote" /><w:LsdException Locked="false" Priority="30" SemiHidden="false"UnhideWhenUsed="false" QFormat="true" Name="Intense Quote" /><w:LsdException Locked="false" Priority="66" SemiHidden="false"UnhideWhenUsed="false" Name="Medium List 2 Accent 1" /><w:LsdException Locked="false" Priority="67" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1" /><w:LsdException Locked="false" Priority="68" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1" /><w:LsdException Locked="false" Priority="69" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1" /><w:LsdException Locked="false" Priority="70" SemiHidden="false"UnhideWhenUsed="false" Name="Dark List Accent 1" /><w:LsdException Locked="false" Priority="71" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful Shading Accent 1" /><w:LsdException Locked="false" Priority="72" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful List Accent 1" /><w:LsdException Locked="false" Priority="73" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful Grid Accent 1" /><w:LsdException Locked="false" Priority="60" SemiHidden="false"UnhideWhenUsed="false" Name="Light Shading Accent 2" /><w:LsdException Locked="false" Priority="61" SemiHidden="false"UnhideWhenUsed="false" Name="Light List Accent 2" /><w:LsdException Locked="false" Priority="62" SemiHidden="false"UnhideWhenUsed="false" Name="Light Grid Accent 2" /><w:LsdException Locked="false" Priority="63" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2" /><w:LsdException Locked="false" Priority="64" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2" /><w:LsdException Locked="false" Priority="65" SemiHidden="false"UnhideWhenUsed="false" Name="Medium List 1 Accent 2" /><w:LsdException Locked="false" Priority="66" SemiHidden="false"UnhideWhenUsed="false" Name="Medium List 2 Accent 2" /><w:LsdException Locked="false" Priority="67" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2" /><w:LsdException Locked="false" Priority="68" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2" /><w:LsdException Locked="false" Priority="69" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2" /><w:LsdException Locked="false" Priority="70" SemiHidden="false"UnhideWhenUsed="false" Name="Dark List Accent 2" /><w:LsdException Locked="false" Priority="71" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful Shading Accent 2" /><w:LsdException Locked="false" Priority="72" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful List Accent 2" /><w:LsdException Locked="false" Priority="73" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful Grid Accent 2" /><w:LsdException Locked="false" Priority="60" SemiHidden="false"UnhideWhenUsed="false" Name="Light Shading Accent 3" /><w:LsdException Locked="false" Priority="61" SemiHidden="false"UnhideWhenUsed="false" Name="Light List Accent 3" /><w:LsdException Locked="false" Priority="62" SemiHidden="false"UnhideWhenUsed="false" Name="Light Grid Accent 3" /><w:LsdException Locked="false" Priority="63" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3" /><w:LsdException Locked="false" Priority="64" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3" /><w:LsdException Locked="false" Priority="65" SemiHidden="false"UnhideWhenUsed="false" Name="Medium List 1 Accent 3" /><w:LsdException Locked="false" Priority="66" SemiHidden="false"UnhideWhenUsed="false" Name="Medium List 2 Accent 3" /><w:LsdException Locked="false" Priority="67" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3" /><w:LsdException Locked="false" Priority="68" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3" /><w:LsdException Locked="false" Priority="69" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3" /><w:LsdException Locked="false" Priority="70" SemiHidden="false"UnhideWhenUsed="false" Name="Dark List Accent 3" /><w:LsdException Locked="false" Priority="71" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful Shading Accent 3" /><w:LsdException Locked="false" Priority="72" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful List Accent 3" /><w:LsdException Locked="false" Priority="73" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful Grid Accent 3" /><w:LsdException Locked="false" Priority="60" SemiHidden="false"UnhideWhenUsed="false" Name="Light Shading Accent 4" /><w:LsdException Locked="false" Priority="61" SemiHidden="false"UnhideWhenUsed="false" Name="Light List Accent 4" /><w:LsdException Locked="false" Priority="62" SemiHidden="false"UnhideWhenUsed="false" Name="Light Grid Accent 4" /><w:LsdException Locked="false" Priority="63" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4" /><w:LsdException Locked="false" Priority="64" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4" /><w:LsdException Locked="false" Priority="65" SemiHidden="false"UnhideWhenUsed="false" Name="Medium List 1 Accent 4" /><w:LsdException Locked="false" Priority="66" SemiHidden="false"UnhideWhenUsed="false" Name="Medium List 2 Accent 4" /><w:LsdException Locked="false" Priority="67" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4" /><w:LsdException Locked="false" Priority="68" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4" /><w:LsdException Locked="false" Priority="69" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4" /><w:LsdException Locked="false" Priority="70" SemiHidden="false"UnhideWhenUsed="false" Name="Dark List Accent 4" /><w:LsdException Locked="false" Priority="71" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful Shading Accent 4" /><w:LsdException Locked="false" Priority="72" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful List Accent 4" /><w:LsdException Locked="false" Priority="73" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful Grid Accent 4" /><w:LsdException Locked="false" Priority="60" SemiHidden="false"UnhideWhenUsed="false" Name="Light Shading Accent 5" /><w:LsdException Locked="false" Priority="61" SemiHidden="false"UnhideWhenUsed="false" Name="Light List Accent 5" /><w:LsdException Locked="false" Priority="62" SemiHidden="false"UnhideWhenUsed="false" Name="Light Grid Accent 5" /><w:LsdException Locked="false" Priority="63" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5" /><w:LsdException Locked="false" Priority="64" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5" /><w:LsdException Locked="false" Priority="65" SemiHidden="false"UnhideWhenUsed="false" Name="Medium List 1 Accent 5" /><w:LsdException Locked="false" Priority="66" SemiHidden="false"UnhideWhenUsed="false" Name="Medium List 2 Accent 5" /><w:LsdException Locked="false" Priority="67" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5" /><w:LsdException Locked="false" Priority="68" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5" /><w:LsdException Locked="false" Priority="69" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5" /><w:LsdException Locked="false" Priority="70" SemiHidden="false"UnhideWhenUsed="false" Name="Dark List Accent 5" /><w:LsdException Locked="false" Priority="71" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful Shading Accent 5" /><w:LsdException Locked="false" Priority="72" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful List Accent 5" /><w:LsdException Locked="false" Priority="73" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful Grid Accent 5" /><w:LsdException Locked="false" Priority="60" SemiHidden="false"UnhideWhenUsed="false" Name="Light Shading Accent 6" /><w:LsdException Locked="false" Priority="61" SemiHidden="false"UnhideWhenUsed="false" Name="Light List Accent 6" /><w:LsdException Locked="false" Priority="62" SemiHidden="false"UnhideWhenUsed="false" Name="Light Grid Accent 6" /><w:LsdException Locked="false" Priority="63" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6" /><w:LsdException Locked="false" Priority="64" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6" /><w:LsdException Locked="false" Priority="65" SemiHidden="false"UnhideWhenUsed="false" Name="Medium List 1 Accent 6" /><w:LsdException Locked="false" Priority="66" SemiHidden="false"UnhideWhenUsed="false" Name="Medium List 2 Accent 6" /><w:LsdException Locked="false" Priority="67" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6" /><w:LsdException Locked="false" Priority="68" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6" /><w:LsdException Locked="false" Priority="69" SemiHidden="false"UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6" /><w:LsdException Locked="false" Priority="70" SemiHidden="false"UnhideWhenUsed="false" Name="Dark List Accent 6" /><w:LsdException Locked="false" Priority="71" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful Shading Accent 6" /><w:LsdException Locked="false" Priority="72" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful List Accent 6" /><w:LsdException Locked="false" Priority="73" SemiHidden="false"UnhideWhenUsed="false" Name="Colorful Grid Accent 6" /><w:LsdException Locked="false" Priority="19" SemiHidden="false"UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis" /><w:LsdException Locked="false" Priority="21" SemiHidden="false"UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis" /><w:LsdException Locked="false" Priority="31" SemiHidden="false"UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference" /><w:LsdException Locked="false" Priority="32" SemiHidden="false"UnhideWhenUsed="false" QFormat="true" Name="Intense Reference" /><w:LsdException Locked="false" Priority="33" SemiHidden="false"UnhideWhenUsed="false" QFormat="true" Name="Book Title" /><w:LsdException Locked="false" Priority="37" Name="Bibliography" /><w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading" /></w:LatentStyles></xml><![endif]--><style type="text/css"><!-- /* Font Definitions */ @font-face	{font-family:宋体;	panose-1:2 1 6 0 3 1 1 1 1 1;	mso-font-alt:SimSun;	mso-font-charset:134;	mso-generic-font-family:auto;	mso-font-pitch:variable;	mso-font-signature:3 680460288 22 0 262145 0;}@font-face	{font-family:宋体;	panose-1:2 1 6 0 3 1 1 1 1 1;	mso-font-alt:SimSun;	mso-font-charset:134;	mso-generic-font-family:auto;	mso-font-pitch:variable;	mso-font-signature:3 680460288 22 0 262145 0;}@font-face	{font-family:"\@宋体";	panose-1:2 1 6 0 3 1 1 1 1 1;	mso-font-charset:134;	mso-generic-font-family:auto;	mso-font-pitch:variable;	mso-font-signature:3 680460288 22 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal	{mso-style-unhide:no;	mso-style-qformat:yes;	mso-style-parent:"";	margin:0cm;	margin-bottom:.0001pt;	text-align:justify;	text-justify:inter-ideograph;	mso-pagination:none;	font-size:10.5pt;	mso-bidi-font-size:10.0pt;	font-family:"Times New Roman","serif";	mso-fareast-font-family:宋体;	mso-font-kerning:1.0pt;}p	{mso-style-noshow:yes;	mso-style-priority:99;	mso-margin-top-alt:auto;	margin-right:0cm;	mso-margin-bottom-alt:auto;	margin-left:0cm;	mso-pagination:widow-orphan;	font-size:12.0pt;	font-family:宋体;	mso-bidi-font-family:宋体;}.MsoChpDefault	{mso-style-type:export-only;	mso-default-props:yes;	font-family:"Calibri","sans-serif";	mso-bidi-font-family:"Times New Roman";	mso-bidi-theme-font:minor-bidi;} /* Page Definitions */ @page	{mso-page-border-surround-header:no;	mso-page-border-surround-footer:no;}@page WordSection1	{size:612.0pt 792.0pt;	margin:72.0pt 90.0pt 72.0pt 90.0pt;	mso-header-margin:36.0pt;	mso-footer-margin:36.0pt;	mso-paper-source:0;}div.WordSection1	{page:WordSection1;}--></style><!--[if gte mso 10]><style>/* Style Definitions */table.MsoNormalTable{mso-style-name:普通表格;mso-tstyle-rowband-size:0;mso-tstyle-colband-size:0;mso-style-noshow:yes;mso-style-priority:99;mso-style-parent:"";mso-padding-alt:0cm 5.4pt 0cm 5.4pt;mso-para-margin:0cm;mso-para-margin-bottom:.0001pt;mso-pagination:widow-orphan;font-size:10.5pt;mso-bidi-font-size:11.0pt;font-family:"Calibri","sans-serif";mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:"Times New Roman";mso-bidi-theme-font:minor-bidi;mso-font-kerning:1.0pt;}</style><![endif]--></p><p>整理硬盘时，翻出了一些以前的资料。<span lang="EN-US"><o:p></o:p></span></p><p>现在回过头来看看当时的记录，一番感慨。<span lang="EN-US"><o:p></o:p></span></p><p>学习<span lang="EN-US">windml</span>之前没有接触过任何嵌入式<span lang="EN-US">GUI</span>。在<span lang="EN-US">2008</span>年初时，开始摸索<span lang="EN-US">windml</span>，然后，就是整整一年的时间在理解<span lang="EN-US">windml</span>，并编写基于<span lang="EN-US">windml</span>的 应用程序。其中的煎熬，就不在说了吧！<span lang="EN-US"><o:p></o:p></span></p><p>而且，在这期间，对<span lang="EN-US">UCGUI</span>也是稍作了解，学习到很多，而且有一部分应用到<span lang="EN-US">windml</span>上了。<span lang="EN-US"><o:p></o:p></span></p><p><span lang="EN-US"><o:p>&nbsp;</o:p></span></p><p>下面内容是当时的不完整的，且不怎么成熟的笔记记录。<span lang="EN-US"><o:p></o:p></span></p><p>原汁原味吧，我就不在修改了。<span lang="EN-US"><o:p></o:p></span></p><p>其实，是我偷懒！<span lang="EN-US"><o:p></o:p></span></p><p><span lang="EN-US"><o:p>&nbsp;</o:p></span></p><p><span lang="EN-US">Much<span style="">&nbsp; </span>2010-06-18<o:p></o:p></span></p><p>&nbsp;</p><p><a target="_blank" href="../../../upload/2010/6/windml旧时简单记录.pdf">windml旧时简单记录.pdf</a></p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>Copyright © 2010</p><p><a href="http://www.rtoslab.net/2010/06/2010618105518.html" target="_blank">继续阅读《翻出以前学习WindML的一些笔记记录。》的全文内容...</a></p><p>分类: <a href="http://www.rtoslab.net/post/VxWorks.html">VxWorks</a> | Tags: <a href="http://www.rtoslab.net/catalog.asp?tags=windml">windml</a>&nbsp;&nbsp;<a href="http://www.rtoslab.net/catalog.asp?tags=wwm">wwm</a>&nbsp;&nbsp; | <a href="http://www.rtoslab.net/2010/06/2010618105518.html#comment" target="_blank">添加评论</a>(0)</p><h3>相关文章:</h3><ul><p><a  href="http://www.rtoslab.net/2009/12/200912219553.html">贪吃蛇 for WindMl3.0 更新源代码！</a>&nbsp;&nbsp;(2009-12-2 19:5:53)</p><p><a  href="http://www.rtoslab.net/2009/12/2009121183920.html">编译windml时需要注意的！</a>&nbsp;&nbsp;(2009-12-1 18:39:20)</p><p><a  href="http://www.rtoslab.net/2009/08/20098156366.html">wwm中的链表UGL_LIST</a>&nbsp;&nbsp;(2009-8-15 6:36:6)</p><p><a  href="http://www.rtoslab.net/2009/08/200981184637.html">贪吃蛇 for WindMl3.0</a>&nbsp;&nbsp;(2009-8-11 8:46:37)</p><p><a  href="http://www.rtoslab.net/2009/06/2009614181622.html"><转>WindML PC-BIOS 驱动实现细节概述</a>&nbsp;&nbsp;(2009-6-14 18:16:22)</p></ul>]]></description><category>VxWorks</category><comments>http://www.rtoslab.net/2010/06/2010618105518.html#comment</comments><wfw:comment>http://www.rtoslab.net/</wfw:comment><wfw:commentRss>http://www.rtoslab.net/feed.asp?cmt=81</wfw:commentRss><trackback:ping>http://www.rtoslab.net/cmd.asp?act=tb&amp;id=81&amp;key=4c3caaf8</trackback:ping></item><item><title>FreeType2教程(转)</title><author>netmuch@gmail.com (much)</author><link>http://www.rtoslab.net/2010/04/2010414223630.html</link><pubDate>Wed, 14 Apr 2010 22:36:30 +0800</pubDate><guid>http://www.rtoslab.net/2010/04/2010414223630.html</guid><description><![CDATA[<p>&nbsp;</p><p><span style="color: rgb(255, 0, 0);">本文转自：</span><a target="_blank" href="http://blog.csdn.net/fengrx/archive/2009/06/30/4310274.aspx">blog.csdn.net/fengrx/archive/2009/06/30/4310274.aspx</a></p><p>&nbsp;</p><p><strong>第一步 －－ 简易的字形装载</strong>  <br /><br /><strong>介绍</strong>  <br /><br />这是&ldquo;FreeType2 教程&rdquo;的第一部分。它将教会你如何： <br /><br />* 初始化库 <br />* 通过创建一个新的 face 对象来打开一个字体文件 <br />* 以点或者象素的形式选择一个字符大小 <br />* 装载一个字形(glyph)图像，并把它转换为位图 <br />* 渲染一个简单的字符串 <br />* 容易地渲染一个旋转的字符串 <br /><br /><strong>1.头文件</strong>  <br /><br />下面的内容是编译一个使用了FreeType2库的应用程序所需要的指令。请谨慎阅读，自最近一次版本更新后我们已经更改了少许东西。 <br /><br /><strong>1.FreeType2 include 目录</strong>  <br /><br />你必须把FreeType2头文件的目录添加到编译包含(include)目录中。 <br /><br />注意，现在在Unix系统，你可以运行freetype-config脚本加上--cflags选项来获得正确的编译标记。这个脚本也可以用来检查安装在 你系统中的库的版本，以及需要的库和连接标记。 <br /><br /><strong>2. 包含名为ft2build.h的文件</strong>  <br /><br />Ft2build.h包含了接下来要#include的公共FreeType2头文件的宏声明。 <br /><br /><strong>3. 包含主要的FreeType2 API头文件</strong>  <br /><br />你要使用FT_FREETYPE_H宏来完成这个工作，就像下面这样： <br /><br />#include &lt;ft2build.h&gt; <br />#include FT_FREETYPE_H <br /><br />FT_FREETYPE_H是在ftheader.h中定义的一个特别的宏。Ftheader.h包含了一些安装所特定的宏，这些宏指名了 FreeType2 API的其他公共头文件。 <br /><br />你可以阅读&ldquo;FreeType 2 API参考&rdquo;的这个部分来获得头文件的完整列表。 <br /><br />＃include语句中宏的用法是服从ANSI的。这有几个原因： <br /><br />* 这可以避免一些令人痛苦的与FreeType 1.x公共头文件的冲突。 <br /><br />*  宏名字不受限于DOS的8.3文件命名限制。象FT_MULTIPLE_MASTERS_H或FT_SFNT_NAMES_H这样的名字比真实的文件名 ftmm.h和fsnames.h更具可读性并且更容易理解。 <br /><br />* 它允许特别的安装技巧，我们不在这里讨论它。 <br /><br />注意：从FreeType 2.1.6开始，旧式的头文件包含模式将不会再被支持。这意味着现在如果你做了象下面那样的事情，你将得到一个错误： <br /><br />#include &lt;freetype/freetype.h&gt; <br />#include &lt;freetype/ftglyph.h&gt; <br />. . . <br /><br /><strong>2. 初始化库</strong>  <br /><br />简单地创建一个FT_Library类型的变量，例如library，然后象下面那样调用函数FT_Init_FreeType： <br /><br />#include &lt;ft2build.h&gt; <br />#include FT_FREETYPE_H <br /><br />FT_LIBRARY library; <br /><br />. . . <br /><br />Error = FT_Init_FreeType ( &amp;library ); <br />If ( error ) <br />{ <br />. . . 当初始化库时发生了一个错误 . . . <br />} <br /><br />这个函数负责下面的事情： <br /><br />* 它创建一个FreeType 2库的新实例，并且设置句柄library为它。 <br /><br />* 它装载库中FreeType所知道的每一个模块。除了别的以外，你新建的library对象可以优雅地处理TrueType, Type 1,  CID-keyed 和OpenType/CFF字体。 <br /><br />就像你所看到的，这个函数返回一个错误代码，如同FreeType  API的大部分其他函数一样。值为0的错误代码始终意味着操作成功了，否则，返回值指示错误，library设为NULL。 <br /><br /><strong>3．装载一个字体face</strong>  <br /><br /><strong>a.从一个字体文件装载</strong>  <br /><br />应用程序通过调用FT_New_Face创建一个新的face对象。一个face对象描述了一个特定的字样和风格。例如，&rsquo;Times New  Roman Regular&rsquo;和&rsquo;Times New Roman Italic&rsquo;对应两个不同的face。 <br /><br />FT_Library library; /* 库的句柄 */ <br />FT_Face face; /* face对象的句柄 */ <br /><br />error = FT_Init_FreeType( &amp;library ); <br />if ( error ) { ... } <br /><br />error = FT_New_Face( library, <br />&quot;/usr/share/fonts/truetype/arial.ttf&quot;, <br />0, <br />&amp;face ); <br />if ( error == FT_Err_Unknown_File_Format ) <br />{ <br />... 可以打开和读这个文件，但不支持它的字体格式 <br />} <br />else if ( error ) <br />{ <br />... 其它的错误码意味着这个字体文件不能打开和读，或者简单的说它损坏了... <br />} <br /><br />就如你所想到的，FT_NEW_Face打开一个字体文件，然后设法从中提取一个face。它的参数为： <br /><br />Library <br />一个FreeType库实例的句柄，face对象从中建立 <br /><br />Filepathname <br />字体文件路径名（一个标准的C字符串） <br /><br />Face_index <br />某些字体格式允许把几个字体face嵌入到同一个文件中。 <br />这个索引指示你想装载的face。 <br />如果这个值太大，函数将会返回一个错误。Index 0总是正确的。 <br /><br />Face <br />一个指向新建的face对象的指针。 <br />当失败时其值被置为NULL。 <br /><br />要知道一个字体文件包含多少个face，只要简单地装载它的第一个face(把face_index设置为0)，face-&gt;num_faces的 值就指示出了有多少个face嵌入在该字体文件中。 <br /><br /><strong>b.从内存装载</strong>  <br /><br />如果你已经把字体文件装载到内存，你可以简单地使用FT_New_Memory_Face为它新建一个face对象，如下所示： <br /><br />FT_Library library; /* 库的句柄 */ <br />FT_Face face; /* face对象的句柄 */ <br /><br /><br />error = FT_Init_FreeType( &amp;library ); <br />if ( error ) { ... } <br /><br />error = FT_New_Memory_Face( library, <br />buffer, /* 缓存的第一个字节 */ <br />size, /* 缓存的大小（以字节表示） */ <br />0, /* face索引 */ <br />&amp;face ); <br />if ( error ) { ... } <br /><br />如你所看到的，FT_New_Memory_Face简单地用字体文件缓存的指针和它的大小（以字节计算）代替文件路径。除此之外，它与 FT_New_Face的语义一致。 <br /><br /><strong>c.从其他来源装载（压缩文件，网络，等）</strong>  <br /><br />使用文件路径或者预装载文件到内存是简单的，但还不足够。FreeType 2可以支持通过你自己实现的I/O程序来装载文件。 <br /><br />这是通过FT_Open_Face函数来完成的。FT_Open_Face可以实现使用一个自定义的输入流，选择一个特定的驱动器来打开，乃至当创建该对 象时传递外部参数给字体驱动器。我们建议你查阅&ldquo;FreeType 2参考手册&rdquo;，学习如何使用它。 <br /><br /><strong>4．访问face内容</strong>  <br /><br />一个face对象包含该face的全部全局描述信息。通常的，这些数据可以通过分别查询句柄来直接访问，例如face-&gt;num_glyphs。 <br /><br />FT_FaceRec结构描述包含了可用字段的完整列表。我们在这里详细描述其中的某些： <br /><br />Num_glyphs <br />这个值给出了该字体face中可用的字形(glyphs)数目。简单来说，一个字形就是一个字符图像。但它不一定符合一个字符代码。 <br /><br />Flags <br />一 个32位整数，包含一些用来描述face特性的位标记。例如，标记FT_FACE_FLAG_SCALABLE用来指示该face的字体格式是可伸缩并且 该字形图像可以渲染到任何字符象素尺寸。要了解face标记的更多信息，请阅读&ldquo;FreeType 2 API 参考&rdquo;。 <br /><br />Units_per_EM <br />这个字段只对可伸缩格式有效，在其他格式它将会置为0。它指示了EM所覆盖的字体单位的个数。 <br /><br />Num_fixed_size <br />这个字段给出了当前face中嵌入的位图的个数。简单来说，一个strike就是某一特定字符象素尺寸下的一系列字形图像。例如，一个字体face可以包 含象素尺寸为10、12和14的strike。要注意的是即使是可伸缩的字体格式野可以包含嵌入的位图！ <br /><br />Fixed_sizes <br />一个指向FT_Bitmap_Size成员组成的数组的指针。每一个FT_Bitmap_Size指示face中的每一个strike的水平和垂直字符象 素尺寸。 <br />注意，通常来说，这不是位图strike的单元尺寸。 <br /><br /><strong>5．设置当前象素尺寸</strong>  <br /><br />对于特定face中与字符大小相关的信息，FreeType  2使用size对象来构造。例如，当字符大小为12点时，使用一个size对象以1/64象素为单位保存某些规格（如ascender或者文字高度）的 值。 <br /><br />当FT_New_Face或它的亲戚被调用，它会自动在face中新建一个size对象，并返回。该size对象可以通过face-&gt;size直接 访问。 <br /><br />注意：一个face对象可以同时处理一个或多个size对象，但只有很少程序员需要用到这个功能，因而，我们决定简化该API，（例如，每个face对象 只拥有一个size对象）但是这个特性我们仍然通过附加的函数提供。 <br /><br />当一个新的face对象建立时，对于可伸缩字体格式，size对象默认值为字符大小水平和垂直均为10象素。对于定长字体格式，这个大小是未定义的，这就 是你必须在装载一个字形前设置该值的原因。 <br /><br />使用FT_Set_Char_Size完成该功能。这里有一个例子，它在一个300x300dpi设备上把字符大小设置为16pt。 <br /><br />error = FT_Set_Char_Size( <br />face, /* face对象的句柄 */ <br />0, /* 以1/64点为单位的字符宽度 */ <br />16*64, /* 以1/64点为单位的字符高度 */ <br />300, /* 设备水平分辨率 */ <br />300 ); /* 设备垂直分辨率 */ <br /><br />注意： <br /><br />* 字符宽度和高度以1/64点为单位表示。一个点是一个1/72英寸的物理距离。通常，这不等于一个象素。 <br /><br />*  设备的水平和垂直分辨率以每英寸点数(dpi)为单位表示。显示设备（如显示器）的常规值为72dpi或96dpi。这个分辨率是用来从字符点数计算字符 象素大小的。 <br /><br />* 字符宽度为0意味着&ldquo;与字符高度相同&rdquo;，字符高度为0意味着&ldquo;与字符宽度相同&rdquo;。对于其他情况则意味着指定不一样的字符宽度和高度。 <br /><br />* 水平或垂直分辨率为0时表示使用默认值72dpi。 <br /><br />* 第一个参数是face对象的句柄，不是size对象的。 <br /><br />这个函数计算对应字符宽度、高度和设备分辨率的字符象素大小。然而，如果你想自己指定象素大小，你可以简单地调用FT_Set_Pixel_Sizes， 就像这样： <br /><br />error = FT_Set_Pixel_Sizes( <br />face, /* face对象句柄 */ <br />0, /* 象素宽度 */ <br />16 ); /* 象素高度 */ <br /><br />这个例子把字符象素设置为16x16象素。如前所说的，尺寸中的任一个为0意味着&ldquo;与另一个尺寸值相等&rdquo;。 <br /><br />注意这两个函数都返回错误码。通常，错误会发生在尝试对定长字体格式（如FNT或PCF）设置不在face-&gt;fixed_size数组中的象素尺 寸值。 <br /><br /><strong>6．装载一个字形图像</strong>  <br /><br /><strong>a.把一个字符码转换为一个字形索引</strong>  <br /><br />通常，一个应用程序想通过字符码来装载它的字形图像。字符码是一个特定编码中代表该字符的数值。例如，字符码64代表了ASCII编码中的&rsquo;A&rsquo;。 <br /><br />一 个face对象包含一个或多个字符表(charmap)，字符表是用来转换字符码到字形索引的。例如，很多TrueType字体包含两个字符表，一个用来 转换Unicode字符码到字形索引，另一个用来转换Apple Roman编码到字形索引。这样的字体既可以用在Windows（使用Unicode）和Macintosh（使用Apple Roman）。同时要注意，一个特定的字符表可能没有覆盖完字体里面的全部字形。 <br /><br />当新建一个face对象时，它默认选择 Unicode字符表。如果字体没包含Unicode字符表，FreeType会尝试在字形名的基础上模拟一个。注意，如果字形名是不标准的那么模拟的字 符表有可能遗漏某些字形。对于某些字体，包括符号字体和旧的亚洲手写字体，Unicode模拟是不可能的。 <br /><br />我们将在稍后叙述如何寻找face中特定的字符表。现在我们假设face包含至少一个Unicode字符表，并且在调用FT_New_Face时已经被选 中。我们使用FT_Get_Char_Index把一个Unicode字符码转换为字形索引，如下所示： <br /><br />glyph_index = FT_Get_Char_Index( face, charcode ); <br /><br />这个函数会在face里被选中的字符表中查找与给出的字符码对应的字形索引。如果没有字符表被选中，这个函数简单的返回字符码。 <br /><br />注意，这个函数是FreeType中罕有的不返回错误码的函数中的一个。然而，当一个特定的字符码在face中没有字形图像，函数返回0。按照约定，它对 应一个特殊的字形图像――缺失字形，通常会显示一个框或一个空格。 <br /><br /><strong>b.从face中装载一个字形</strong>  <br /><br />一 旦你获得了字形索引，你便可以装载对应的字形图像。在不同的字体中字形图像存储为不同的格式。对于固定尺寸字体格式，如FNT或者PCF，每一个图像都是 一个位图。对于可伸缩字体格式，如TrueType或者Type1，使用名为轮廓(outlines)的矢量形状来描述每一个字形。一些字体格式可能有更 特殊的途径来表示字形（如MetaFont――但这个格式不被支持）。幸运的，FreeType2有足够的灵活性，可以通过一个简单的API支持任何类型 的字形格式。 <br /><br />字形图像存储在一个特别的对象――字形槽(glyph slot)中。就如其名所暗示的，一个字形槽只是一个简单的容器，它一次只能容纳一个字形图像，可以是位图，可以是轮廓，或者其他。每一个face对象都 有一个字形槽对象，可以通过face-&gt;glyph来访问。它的字段在FT_GlyphSlotRec结构的文档中解释了。 <br /><br />通过调用FT_Load_Glyph来装载一个字形图像到字形槽中，如下： <br /><br />error = FT_Load_Glyph( <br />face, /* face对象的句柄 */ <br />glyph_index, /* 字形索引 */ <br />load_flags ); /* 装载标志，参考下面 */ <br /><br />load_flags的值是位标志集合，是用来指示某些特殊操作的。其默认值是FT_LOAD_DEFAULT即0。 <br /><br />这个函数会设法从face中装载对应的字形图像： <br /><br />*  如果找到一个对应该字形和象素尺寸的位图，那么它将会被装载到字形槽中。嵌入的位图总是比原生的图像格式优先装载。因为我们假定对一个字形，它有更高质量 的版本。这可以用FT_LOAD_NO_BITMAP标志来改变。 <br /><br />* 否则，将装载一个该字形的原生图像，把它伸缩到当前的象素尺寸，并且对应如TrueType和Type1这些格式，也会完成hinted操作。 <br /><br />字段face-&gt;glyph-&gt;format描述了字形槽中存储的字形图像的格式。如果它的值不是 FT_GLYPH_FORMAT_BITMAP，你可以通过FT_Render_Glyph把它直接转换为一个位图。如下： <br /><br />error = FT_Render_Glyph( face-&gt;glyph, /* 字形槽 */ <br />render_mode ); /* 渲染模式 */ <br /><br />render_mode参数是一个位标志集合，用来指示如何渲染字形图像。把它设为FT_RENDER_MODE_NORMAL渲染出一个高质量的抗锯齿 (256级灰度)位图。这是默认情况，如果你想生成黑白位图，可以使用FT_RENDER_MODE_MONO标志。 <br /><br />一旦你生成了一个字形图像的位图，你可以通过glyph-&gt;bitmap(一个简单的位图描述符)直接访问，同时用 glyph-&gt;bitmap_left和glyph-&gt;bitmap_top来指定起始位置。 <br /><br />要注意，bitmap_left是从字形位图当前笔位置到最左边界的水平距离，而bitmap_top是从笔位置（位于基线）到最高边界得垂直距离。他么 是正数，指示一个向上的距离。 <br /><br />下一部分将给出字形槽内容的更多细节，以及如何访问特定的字形信息（包括度量）。 <br /><br /><strong>c.使用其他字符表</strong>  <br /><br />如 前面所说的，当一个新face对象创建时，它会寻找一个Unicode字符表并且选择它。当前被选中的字符表可以通过face-&gt;charmap访 问。当没有字符表被选中时，该字段为NULL。这种情况在你从一个不含Unicode字符表的字体文件（这种文件现在非常罕见）创建一个新的 FT_Face对象时发生。 <br /><br />有两种途径可以在FreeType  2中选择不同的字符表。最轻松的途径是你所需的编码已经有对应的枚举定义在FT_FREETYPE_H中，例如FT_ENCODING_BIG5。在这种 情况下，你可以简单地调用FT_Select_CharMap，如下： <br /><br />error = FT_Select_CharMap( <br />face, /* 目标face对象 */ <br />FT_ENCODING_BIG5 ); /* 编码 */ <br /><br />另 一种途径是手动为face解析字符表。这通过face对象的字段num_charmaps和charmaps(注意这是复数)来访问。如你想到的，前者是 face中的字符表的数目，后者是一个嵌入在face中的指向字符表的指针表(a table of pointers to the charmaps)。 <br /><br />每一个字符表有一些可见的字段，用来更精确地描述它，主要用到的字段是charmap-&gt;platform_id和 charmap-&gt;encoding_id。这两者定义了一个值组合，以更普 <br />通的形式用来描述该字符表。 <br /><br />每一个值组合对应一个特定的编码。例如组合(3,1)对应Unicode。组合列表定义在TrueType规范中，但你也可以使用文件 FT_TRUETYPE_IDS_H来处理它们，该文件定义了几个有用的常数。 <br /><br />要选择一个具体的编码，你需要在规范中找到一个对应的值组合，然后在字符表列表中寻找它。别忘记，由于历史的原因，某些编码会对应几个值组合。这里是一些 代码： <br /><br />FT_CharMap found = 0; <br />FT_CharMap charmap; <br />int n; <br /><br /><br />for ( n = 0; n &lt; face-&gt;num_charmaps; n++ ) <br />{ <br />charmap = face-&gt;charmaps[n]; <br />if ( charmap-&gt;platform_id == my_platform_id &amp;&amp; <br />charmap-&gt;encoding_id == my_encoding_id ) <br />{ <br />found = charmap; <br />break; <br />} <br />} <br /><br />if ( !found ) { ... } <br /><br />/* 现在，选择face对象的字符表*/ <br />error = FT_Set_CharMap( face, found ); <br />if ( error ) { ... } <br /><br />一旦某个字符表被选中，无论通过FT_Select_CharMap还是通过FT_Set_CharMap，它都会在后面的 FT_Get_Char_Index调用使用。 <br /><br /><strong>d.字形变换</strong>  <br /><br />当字形图像被装载时，可以对该字形图像进行仿射变换。当然，这只适用于可伸缩（矢量）字体格式。 <br /><br />简单地调用FT_Set_Transform来完成这个工作，如下： <br /><br />error = FT_Set_Transform( <br />face, /* 目标face对象 */ <br />&amp;matrix, /* 指向2x2矩阵的指针 */ <br />&amp;delta ); /* 指向2维矢量的指针 */ <br /><br />这个函数将对指定的face对象设置变换。它的第二个参数是一个指向FT_Matrix结 <br />构的指针。该结构描述了一个2x2仿射矩阵。第三个参数是一个指向FT_Vector结构的指针。该结构描述了一个简单的二维矢量。该矢量用来在2x2变 换后对字形图像平移。 <br /><br />注意，矩阵指针可以设置为NULL，在这种情况下将进行恒等变换。矩阵的系数是16.16形式的固定浮点单位。 <br /><br />矢量指针也可以设置为NULL，在这种情况下将使用(0,  0)的delta。矢量坐标以一个象素的1/64为单位表示（即通常所说的26.6固定浮点格式）。 <br /><br />注意：变换将适用于使用FT_Load_Glyph装载的全部字形，并且完全独立于任何hinting处理。这意味着你对一个12象素的字形进行2倍放大 变换不会得到与24象素字形相同的结果（除非你禁止hints）。 <br /><br />如果你需要使用非正交变换和最佳hints，你首先必须把你的变换分解为一个伸缩部分和一个旋转/剪切部分。使用伸缩部分来计算一个新的字符象素大小，然 后使用旋转/剪切部分来调用FT_Set_Transform。这在本教程的后面部分有详细解释。 <br /><br />同时要注意，对一个字形位图进行非同一性变换将产生错误。 <br /><br /><strong>7. 简单的文字渲染</strong>  <br /><br />现在我们将给出一个非常简单的例子程序，该例子程序渲染一个8位Latin-1文本字符串，并且假定face包含一个Unicode字符表。 <br /><br />该程序的思想是建立一个循环，在该循环的每一次迭代中装载一个字形图像，把它转换为一个抗锯齿位图，把它绘制到目标表面(surface)上，然后增加当 前笔的位置。 <br /><br /><strong>a.基本代码</strong>  <br /><br />下面的代码完成我们上面提到的简单文本渲染和其他功能。 <br /><br />FT_GlyphSlot slot = face-&gt;glyph; /* 一个小捷径 */ <br />int pen_x, pen_y, n; <br /><br /><br />... initialize library ... <br />... create face object ... <br />... set character size ... <br /><br />pen_x = 300; <br />pen_y = 200; <br /><br />for ( n = 0; n &lt; num_chars; n++ ) <br />{ <br />FT_UInt glyph_index; <br /><br /><br />/* 从字符码检索字形索引 */ <br />glyph_index = FT_Get_Char_Index( face, text[n] ); <br /><br />/* 装载字形图像到字形槽（将会抹掉先前的字形图像） */ <br />error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT ); <br />if ( error ) <br />continue; /* 忽略错误 */ <br /><br />/* 转换为一个抗锯齿位图 */ <br />error = FT_Render_Glyph( face-&gt;glyph, ft_render_mode_normal ); <br />if ( error ) <br />continue; <br /><br />/* 现在，绘制到我们的目标表面(surface) */ <br />my_draw_bitmap( &amp;slot-&gt;bitmap, <br />pen_x + slot-&gt;bitmap_left, <br />pen_y - slot-&gt;bitmap_top ); <br /><br />/* 增加笔位置 */ <br />pen_x += slot-&gt;advance.x &gt;&gt; 6; <br />pen_y += slot-&gt;advance.y &gt;&gt; 6; /* 现在还是没用的 */ <br />} <br /><br />这个代码需要一些解释： <br /><br />*  我们定义了一个名为slot的句柄，它指向face对象的字形槽。（FT_GlyphSlot类型是一个指针）。这是为了便于避免每次都使用 face-&gt;glyph-&gt;XXX。 <br /><br />*  我们以slot-&gt;advance增加笔位置，slot-&gt;advance符合字形的步进宽度（也就是通常所说的走格 (escapement)）。步进矢量以象素的1/64为单位表示，并且在每一次迭代中删减为整数象素。 <br /><br />*  函数my_draw_bitmap不是FreeType的一部分，但必须由应用程序提供以用来绘制位图到目标表面。在这个例子中，该函数以一个 FT_Bitmap描述符的指针和它的左上角位置为参数。 <br /><br />*  Slot-&gt;bitmap_top的值是正数，指字形图像顶点与pen_y的垂直距离。我们假定my_draw_bitmap采用的坐标使用一样的 约定（增加Y值对应向下的扫描线）。我们用pen_y减它，而不是加它。 <br /><br /><strong>b.精练的代码</strong>  <br /><br />下面的代码是上面例子程序的精练版本。它使用了FreeType 2中我们还没有介绍的特性和函数，我们将在下面解释： <br /><br />FT_GlyphSlot slot = face-&gt;glyph; /* 一个小捷径 */ <br />FT_UInt glyph_index; <br />int pen_x, pen_y, n; <br /><br /><br />... initialize library ... <br />... create face object ... <br />... set character size ... <br /><br />pen_x = 300; <br />pen_y = 200; <br /><br />for ( n = 0; n &lt; num_chars; n++ ) <br />{ <br />/* 装载字形图像到字形槽（将会抹掉先前的字形图像） */ <br />error = FT_Load_Char( face, text[n], FT_LOAD_RENDER ); <br />if ( error ) <br />continue; /* 忽略错误 */ <br /><br />/* 现在，绘制到我们的目标表面(surface) */ <br />my_draw_bitmap( &amp;slot-&gt;bitmap, <br />pen_x + slot-&gt;bitmap_left, <br />pen_y - slot-&gt;bitmap_top ); <br /><br />/* 增加笔位置 */ <br />pen_x += slot-&gt;advance.x &gt;&gt; 6; <br />} <br /><br />我们简化了代码的长度，但它完成相同的工作： <br /><br />*  我们使用函数FT_Loac_Char代替FT_Load_Glyph。如你大概想到的，它相当于先调用GT_Get_Char_Index然后调用 FT_Get_Load_Glyph。 <br /><br />*  我们不使用FT_LOAD_DEFAULT作为装载模式，使用FT_LOAD_RENDER。它指示了字形图像必须立即转换为一个抗锯齿位图。这是一个捷 径，可以取消明显的调用FT_Render_Glyph，但功能是相同的。 <br />注意，你也可以指定通过附加FT_LOAD_MONOCHROME装载标志来获得一个单色位图。 <br /><br /><strong>c.更高级的渲染</strong>  <br /><br />现在，让我们来尝试渲染变换文字（例如通过一个环）。我们可以用FT_Set_Transform来完成。这里是示例代码： <br /><br />FT_GlyphSlot slot; <br />FT_Matrix matrix; /* 变换矩阵 */ <br />FT_UInt glyph_index; <br />FT_Vector pen; /* 非变换原点 */ <br />int n; <br /><br /><br />... initialize library ... <br />... create face object ... <br />... set character size ... <br /><br />slot = face-&gt;glyph; /* 一个小捷径 */ <br /><br />/* 准备矩阵 */ <br />matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L ); <br />matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L ); <br />matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L ); <br />matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L ); <br /><br />/* 26.6 笛卡儿空间坐标中笔的位置，以(300, 200)为起始 */ <br />pen.x = 300 * 64; <br />pen.y = ( my_target_height - 200 ) * 64; <br /><br />for ( n = 0; n &lt; num_chars; n++ ) <br />{ <br />/* 设置变换 */ <br />FT_Set_Transform( face, &amp;matrix, &amp;pen ); <br /><br />/* 装载字形图像到字形槽（将会抹掉先前的字形图像） */ <br />error = FT_Load_Char( face, text[n], FT_LOAD_RENDER ); <br />if ( error ) <br />continue; /* 忽略错误 */ <br /><br />/* 现在，绘制到我们的目标表面（变换位置） */ <br />my_draw_bitmap( &amp;slot-&gt;bitmap, <br />slot-&gt;bitmap_left, <br />my_target_height - slot-&gt;bitmap_top ); <br /><br />/* 增加笔位置 */ <br />pen.x += slot-&gt;advance.x; <br />pen.y += slot-&gt;advance.y; <br />} <br /><br />一些说明： <br /><br />* 现在我们使用一个FT_Vector类型的矢量来存储笔位置，其坐标以象素的1/64为单位表示，并且倍增。该位置表示在笛卡儿空间。 <br /><br />*  不同于系统典型的对位图使用的坐标系（其最高的扫描线是坐标0），FreeType中，字形图像的装载、变换和描述总是采用笛卡儿坐标系（这意味着增加Y 对应向上的扫描线）。因此当我们定义笔位置和计算位图左上角时必须在两个系统之间转换。 <br /><br />* 我们对每一个字形设置变换来指示旋转矩阵以及使用一个delta来移动转换后的图像到当前笔位置（在笛卡儿空间，不是位图空间）。结 果，bitmap_left和bitmap_top的值对应目标空间象素中的位图原点。因此，我们在调用my_draw_bitmap时不在它们的值上加 pen.x或pen.y。 <br /><br />* 步进宽度总会在变换后返回，这就是它可以直接加到当前笔位置的原因。注意，这次它不会四舍五入。 <br /><br />一个例子完整的源代码可以在这里找到。 <br /><br />要很注意，虽然这个例子比前面的更复杂，但是变换效果是完全一致的。因此它可以作为一个替换（但更强大）。 <br /><br />然而该例子有少许缺点，我们将在本教程的下一部分中解释和解决。 <br /><br /><strong>结论</strong>  <br /><br />在这个部分，你已经学习了FreeType2的基础以及渲染旋转文字的充分知识。</p><p>Copyright © 2010</p><p><a href="http://www.rtoslab.net/2010/04/2010414223630.html" target="_blank">继续阅读《FreeType2教程(转)》的全文内容...</a></p><p>分类: <a href="http://www.rtoslab.net/post/jade.html">他山之玉</a> | Tags: <a href="http://www.rtoslab.net/catalog.asp?tags=Freetype">Freetype</a>&nbsp;&nbsp;<a href="http://www.rtoslab.net/catalog.asp?tags=%E7%9F%A2%E9%87%8F%E5%AD%97%E4%BD%93">矢量字体</a>&nbsp;&nbsp; | <a href="http://www.rtoslab.net/2010/04/2010414223630.html#comment" target="_blank">添加评论</a>(1)</p><h3>相关文章:</h3><ul><p><a  href="http://www.rtoslab.net/2010/04/2010414223340.html">FreeType2的简单使用(转)</a>&nbsp;&nbsp;(2010-4-14 22:33:40)</p><p><a  href="http://www.rtoslab.net/2010/04/2010414222519.html">《FreeType 2的设计》中译版(转)</a>&nbsp;&nbsp;(2010-4-14 22:25:19)</p><p><a  href="http://www.rtoslab.net/2010/04/201041422012.html">《FreeType字形约定》中译版(转)</a>&nbsp;&nbsp;(2010-4-14 22:0:12)</p><p><a  href="http://www.rtoslab.net/2008/09/2008950831.html">Freetype学习笔记</a>&nbsp;&nbsp;(2008-9-5 0:8:31)</p></ul>]]></description><category>他山之玉</category><comments>http://www.rtoslab.net/2010/04/2010414223630.html#comment</comments><wfw:comment>http://www.rtoslab.net/</wfw:comment><wfw:commentRss>http://www.rtoslab.net/feed.asp?cmt=80</wfw:commentRss><trackback:ping>http://www.rtoslab.net/cmd.asp?act=tb&amp;id=80&amp;key=2d1133f3</trackback:ping></item><item><title>FreeType2的简单使用(转)</title><author>netmuch@gmail.com (much)</author><link>http://www.rtoslab.net/2010/04/2010414223340.html</link><pubDate>Wed, 14 Apr 2010 22:33:40 +0800</pubDate><guid>http://www.rtoslab.net/2010/04/2010414223340.html</guid><description><![CDATA[<p class="font-bodytop" style="text-align: left;">&nbsp;</p><p class="font-bodytop" style="text-align: left;"><span style="color: rgb(255, 0, 0);">本文转自：</span><a href="http://blog.csdn.net/fengrx/archive/2009/06/30/4310323.aspx" target="_blank">blog.csdn.net/fengrx/archive/2009/06/30/4310323.aspx</a></p><p class="font-bodytop" style="text-align: left;">&nbsp;</p><p class="font-bodytop" style="text-align: left;">FreeType2的简单使用:---字体绘制技术</p><p align="center">&nbsp;</p><p>FreeType2是一个简单的跨平台的字体绘制引擎.目前支持TrueType Type1  Type2等字体格式.不过目前好象还不支持OpenType.</p><p>使用FreeType的应用很多.著名的FTGL就是使用FreeType的.能在OpenGL高效率的绘制矢量字体.<br />FTGL我没用过.因为不想在没了解该怎么用FreeType的情况下就去用FTGL.</p><p>经过一个晚上的阅读代码(我的代码阅读能力是很差的).终于知道了如何使用FreeType2了。不过是简单的使用，还不知道如何设置Bold  Itainly等属性.主要是简单的演示.以后准备做成一个完善的字体引擎.<br />下面简单的介绍一下.</p><p>首先当然是包含头文件了。头文件要这样包含:<br />#include [ft2build.h]<br />#include FT_FREETYPE_H <br />不知道为什么.反正就是要这么包含.<br />以下为FT2的初始化代码.和绘制以及释放的代码&gt;<br />注意这里绘制代码接受的字符是Unicode.表示你这样旧可以绘制了</p><p>FT2_Obj font;<br />font.Init(&quot;SimSun.ttf&quot;,32);<br />wchat_t pText[]=L&quot;潘李亮是一头野猪&quot;;<br />for(int n = 0 ; n&lt; wcslen(pText);n++)<br />{<br />font.DrawAUnicode(pText[n]; <br />}<br />font.Free();</p><p>//以下为FT2_Obj的代码.<br />//主要参考了Nehe的Lesson 43<br />class FT2_Obj<br />{ <br />FT_Library library;<br />int h ;<br />FT_Face face;</p><p>public:<br />void Init(const char * fname, unsigned int h);<br />void Free();<br />void DrawAUnicode(wchar_t ch) <br />};<br />void FT2_Obj::Init(const char * fname, unsigned int h) <br />{<br />this-&gt;h=h;</p><p>//初始化FreeType库..</p><p>if (FT_Init_FreeType( &amp;library )) <br />throw std::runtime_error(&quot;FT_Init_FreeType failed&quot;);</p><p>//加载一个字体,取默认的Face,一般为Regualer<br />if (FT_New_Face( library, fname, 0, &amp;face )) <br />throw std::runtime_error(&quot;FT_New_Face failed (there is probably a  problem with your font file)&quot;);</p><p>//大小要乘64.这是规定。照做就可以了。<br />FT_Set_Char_Size( face,h&lt;&lt; 6, h &lt;&lt; 6, 96, 96);<br />FT_Matrix matrix; /* transformation matrix */<br />FT_UInt glyph_index;<br />FT_Vector pen;<br /><br />//给它设置个旋转矩阵<br />float angle = -20/180.* 3.14;<br />matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );<br />matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );<br />matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );<br />matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );</p><p>FT_Set_Transform( face, &amp;matrix, &amp;pen );<br />}.</p><p>void FT2_Obj::DrawAUnicode(wchar_t ch)<br />{<br />if(FT_Load_Glyph( face, FT_Get_Char_Index( face, ch ), FT_LOAD_DEFAULT  ))<br />throw std::runtime_error(&quot;FT_Load_Glyph failed&quot;);</p><p>//得到字模<br />FT_Glyph glyph;<br />if(FT_Get_Glyph( face-&gt;glyph, &amp;glyph ))<br />throw std::runtime_error(&quot;FT_Get_Glyph failed&quot;);</p><p>//转化成位图<br />FT_Render_Glyph( face-&gt;glyph, FT_RENDER_MODE_NORMAL ); <br />FT_Glyph_To_Bitmap( &amp;glyph, ft_render_mode_normal, 0, 1 );<br />FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;</p><p>//取道位图数据<br />FT_Bitmap&amp; bitmap=bitmap_glyph-&gt;bitmap;</p><p>//把位图数据拷贝自己定义的数据区里.这样旧可以画到需要的东西上面了。<br />int width = bitmap.width;<br />int height = bitmap.rows;</p><p>usigned char* expanded_data = new usigned char[ 3 * width * height];</p><p>for(int j=0; j &lt;height;j++) <br />{<br />for(int i=0; i &lt; width; i++)<br />{<br />expanded_data[3*(i+(height-j-1)*width)]= <br />expanded_data[3*(i+(height-j-1)*width)+1] = <br />expanded_data[3*(i+(height-j-1)*width)+2] =<br />(i&gt;=bitmap.width || j&gt;=bitmap.rows) ?<br />0 : bitmap.buffer[i + bitmap.width*j];</p><p>}<br />}</p><p>/*<br />绘制操作.<br />*/<br />}</p><p>void FT2_Obj::Free()<br />{<br />FT_Done_Face(face);<br />FT_Done_FreeType(library);<br />}</p><p>Copyright © 2010</p><p><a href="http://www.rtoslab.net/2010/04/2010414223340.html" target="_blank">继续阅读《FreeType2的简单使用(转)》的全文内容...</a></p><p>分类: <a href="http://www.rtoslab.net/post/jade.html">他山之玉</a> | Tags: <a href="http://www.rtoslab.net/catalog.asp?tags=Freetype">Freetype</a>&nbsp;&nbsp;<a href="http://www.rtoslab.net/catalog.asp?tags=%E7%9F%A2%E9%87%8F%E5%AD%97%E4%BD%93">矢量字体</a>&nbsp;&nbsp; | <a href="http://www.rtoslab.net/2010/04/2010414223340.html#comment" target="_blank">添加评论</a>(0)</p><h3>相关文章:</h3><ul><p><a  href="http://www.rtoslab.net/2010/04/2010414223630.html">FreeType2教程(转)</a>&nbsp;&nbsp;(2010-4-14 22:36:30)</p><p><a  href="http://www.rtoslab.net/2010/04/2010414222519.html">《FreeType 2的设计》中译版(转)</a>&nbsp;&nbsp;(2010-4-14 22:25:19)</p><p><a  href="http://www.rtoslab.net/2010/04/201041422012.html">《FreeType字形约定》中译版(转)</a>&nbsp;&nbsp;(2010-4-14 22:0:12)</p><p><a  href="http://www.rtoslab.net/2008/09/2008950831.html">Freetype学习笔记</a>&nbsp;&nbsp;(2008-9-5 0:8:31)</p></ul>]]></description><category>他山之玉</category><comments>http://www.rtoslab.net/2010/04/2010414223340.html#comment</comments><wfw:comment>http://www.rtoslab.net/</wfw:comment><wfw:commentRss>http://www.rtoslab.net/feed.asp?cmt=79</wfw:commentRss><trackback:ping>http://www.rtoslab.net/cmd.asp?act=tb&amp;id=79&amp;key=2154eaf0</trackback:ping></item><item><title>《FreeType 2的设计》中译版(转)</title><author>netmuch@gmail.com (much)</author><link>http://www.rtoslab.net/2010/04/2010414222519.html</link><pubDate>Wed, 14 Apr 2010 22:25:19 +0800</pubDate><guid>http://www.rtoslab.net/2010/04/2010414222519.html</guid><description><![CDATA[<p>&nbsp;</p><p><span style="color: rgb(255, 0, 0);">本文转自：</span><a href="http://blog.csdn.net/fengrx/archive/2009/06/30/4310331.aspx" target="_blank">blog.csdn.net/fengrx/archive/2009/06/30/4310331.aspx</a></p><p>&nbsp;</p><p>FreeType 2的设计 <br /><br />介绍 <br />这份文档提供了FreeType 2函数库设计与实现的细节。本文档的目标是让开发人员更好的理解FreeType  2是如何组织的，并让他们扩充、定制和调试它。 <br />首先，我们先了解这个库的目的，也就是说，为什么会写这个库： <br />* 它让客户应用程序方便的访问字体文件，无论字体文件存储在哪里，并且与字体格式无关。 <br />* 方便的提取全局字体数据，这些数据在平常的字体格式中普遍存在。（例如：全局度量标准，字符编码/字符映射表，等等） <br />* 方便的提取某个字符的字形数据（度量标准，图像，名字，其他任何东西） <br />* 访问字体格式特定的功能（例如，SFNT表，多重控制，OpenType轮廓表） <br />Freetype 2的设计也受如下要求很大的影响： <br />* 高可移植性。这个库必须可以运行在任何环境中。这个要求引入了一些非常激烈的选择，这些是FreeType2的低级系统界面的一部分。 <br />* 可扩展性。新特性应该可以在极少改动库基础代码的前提下添加。这个要求引入了非常简单的设计：几乎所有操作都是以模块的形式提供的。 <br />* 可定制。它应该能够很容易建立一个只包含某个特定项目所需的特性的版本。当你需要集成它到一个嵌入式图形库的字体服务器中时，这是非常重要的。 <br />* 简洁高效。这个库的主要目标是只有很少cpu和内存资源的嵌入式系统。 <br />这份文档的其他部分分为几个部分。首先，一些章节介绍了库的基本设计以及Freetype 2内部对象/数据的管理。 <br />接下来的章节专注于库的定制和与这个话题相关的系统特定的界面，如何写你自己的模块和如何按需裁减库初始化和编译。 <br /><br /><br />一、组件和API <br />FT可以看作是一组组件，每个组件负责一部分任务，它们包括 <br /><br />* 客户应用程序一般会调用FT高层API，它的功能都在一个组件中，叫做基础层。 <br />* 根据上下文和环境，基础层会调用一个或多个模块进行工作，大多数情况下，客户应用程序不知道使用那个模块。 <br />*  基础层还包含一组例程来进行一些共通处理，例如内存分配，列表处理、io流解析、固定点计算等等，这些函数可以被模块随意调用，它们形成了一个底层基础 API。 <br /><br />如下图，表明它们的关系 <br /><img height="313" width="394" alt="Basic FreeType design" src="http://freetype.sourceforge.net/freetype2/docs/design/basic-design.png" /> &nbsp;&nbsp;<br /><br />另外， <br /><br />*  为了一些特殊的构建，基础层的有些部分可以替换掉，也可以看作组件。例如ftsystem组件，负责实现内存管理和输入流访问，还有ftinit，负责库 初始化。 <br />*  FT还有一些可选的组件，可以根据客户端应用灵活使用，例如ftglyph组件提供一个简单的API来管理字形映象，而不依赖它们内部表示法。或者是访问 特定格式的特性，例如ftmm组件用来访问和管理Type1字体中Multiple Masters数据。 <br />*  最后，一个模块可以调用其他模块提供的函数，这对在多个字体驱动模块中共享代码和表非常有用，例如truetype和cff模块都使用sfnt模块提供的 函数。 <br /><br />见下图，是对上图的一个细化。 <br /><img height="429" width="390" alt="Detailed FreeType design" src="http://freetype.sourceforge.net/freetype2/docs/design/detailed-design.png" /> &nbsp;<br /><br />请注意一些要点： <br /><br />* 一个可选的组件可以用在高层API，也可以用在底层API，例如上面的ftglyph； <br />* 有些可选组件使用模块特定的接口，而不是基础层的接口，上例中，ftmm直接访问Type1模块来访问数据； <br />* 一个可替代的组件能够提供一个高层API的函数，例如，ftinit提供FT_Init_FreeType() <br /><br /><br />二、公共对象和类 <br /><br /><br />1、FT中的面向对象 <br />虽然FT是使用ANSI C编写，但是采用面向对象的思想，是这个库非常容易扩展，因此，下面有一些代码规约。 <br /><br />1. 每个对象类型/类都有一个对应的结构类型和一个对应的结构指针类型，后者称为类型/类的句柄类型 <br /><br />设想我们需要管理FT中一个foo类的对象，可以定义如下 <br /><br />typedef struct FT_FooRec_* FT_Foo; <br /><br />typedef struct FT_FooRec_ <br /><br />{ <br /><br />// fields for the foo class <br /><br />&hellip; <br /><br />}FT_FooRec; <br /><br />依照规约，句柄类型使用简单而有含义的标识符，并以FT_开始，如FT_Foo，而结构体使用相同的名称但是加上Rec后缀。Rec是记录的缩写。每个类 类型都有对应的句柄类型； <br /><br />2. 类继承通过将基类包装到一个新类中实现，例如，我们定义一个foobar类，从foo类继承，可以实现为 <br /><br />typedef struct FT_FooBarRec_ * FT_FooBar; <br /><br />typedef struct FT_FooBarRec_ <br />{ <br />FT_FooRec root; //基类 <br /><br />}FT_FooBarRec; <br /><br />可以看到，将一个FT_FooRec放在FT_FooBarRec定义的开始，并约定名为root，可以确保一个foobar对象也是一个foo对象。 <br /><br />在实际使用中，可以进行类型转换。 <br /><br />后面 <br /><br />2、FT_Library类 <br />这个类型对应一个库的单一实例句柄，没有定义相应的FT_LibraryRec，使客户应用无法访问它的内部属性。 <br /><br />库对象是所有FT其他对象的父亲，你需要在做任何事情前创建一个新的库实例，销毁它时会自动销毁他所有的孩子，如face和module等。 <br /><br />通常客户程序应该调用FT_Init_FreeType()来创建新的库对象，准备作其他操作时使用。 <br /><br />另一个方式是通过调用函数FT_New_Library()来创建一个新的库对象，它在&lt;freetype/ftmodule.h&gt;中定义， 这个函数返回一个空的库，没有任何模块注册，你可以通过调用FT_Add_Module()来安装模块。 <br /><br />调 用FT_Init_FreeType()更方便一些，因为他会缺省地注册一些模块。这个方式中，模块列表在构建时动态计算，并依赖ftinit部件的内 容。（见ftinit.c[l73]行，include FT_CONFIG_MODULES_H，其实就是包含ftmodule.h，在ftmodule.h中定义缺省的模块，所以模块数组 ft_default_modules的大小是在编译时动态确定的。） <br /><br />3、FT_Face类 <br />一个外观对象对应单个字体外观，即一个特定风格的特定外观类型，例如Arial和Arial Italic是两个不同的外观。 <br /><br />一个外观对象通常使用FT_New_Face()来创建，这个函数接受如下参数：一个FT_Library句柄，一个表示字体文件的C文件路径名，一个决 定从文件中装载外观的索引（一个文件中可能有不同的外观），和FT_Face句柄的地址，它返回一个错误码。 <br /><br />FT_Error FT_New_Face( FT_Library library, <br />const char* filepathname, <br />FT_Long face_index, <br />FT_Face* face); <br /><br />函数调用成功，返回0，face参数将被设置成一个非NULL值。 <br /><br />外观对象包含一些用来描述全局字体数据的属性，可以被客户程序直接访问。例如外观中字形的数量、外观家族的名称、风格名称、EM大小等，详见 FT_FaceRec定义。 <br /><br />4、FT_Size类 <br />每个FT_Face对象都有一个或多个FT_Size对象，一个尺寸对象用来存放指定字符宽度和高度的特定数据，每个新创建的外观对象有一个尺寸，可以通 过face-&gt;size直接访问。 <br /><br />尺寸对象的内容可以通过调用FT_Set_Pixel_Sizes()或FT_Set_Char_Size()来改变。 <br /><br />一个新的尺寸对象可以通过FT_New_Size()创建，通过FT_Done_Size()销毁，一般客户程序无需做这一步，它们通常可以使用每个 FT_Face缺省提供的尺寸对象。 <br /><br />FT_Size 公共属性定义在FT_SizeRec中，但是需要注意的是有些字体驱动定义它们自己的FT_Size的子类，以存储重要的内部数据，在每次字符大小改变时 计算。大多数情况下，它们是尺寸特定的字体hint。例如，TrueType驱动存储CVT表，通过cvt程序执行将结果放入TT_Size结构体中，而 Type1驱动将scaled global metrics放在T1_Size对象中。 <br /><br />5、FT_GlyphSlot类 <br />字 形槽的目的是提供一个地方，可以很容易地一个个地装入字形映象，而不管它的格式（位图、向量轮廓或其他）。理想的，一旦一个字形槽创建了，任何字形映象可 以装入，无需其他的内存分配。在实际中，只对于特定格式才如此，像TrueType，它显式地提供数据来计算一个槽地最大尺寸。 <br /><br />另一个字形槽地原因是他用来为指定字形保存格式特定的hint，以及其他为正确装入字形的必要数据。 <br /><br />基本的FT_GlyphSlotRec结构体只向客户程序展现了字形metics和映象，而真正的实现回包含更多的数据。 <br /><br />例如，TrueType特定的TT_GlyphSlotRec结构包含附加的属性，存放字形特定的字节码、在hint过程中暂时的轮廓和其他一些东西。 <br /><br />最后，每个外观对象有一个单一字形槽，可以用face-&gt;glyph直接访问。 <br /><br />6、FT_CharMap类 <br />FT_CharMap类型用来作为一个字符地图对象的句柄，一个字符图是一种表或字典，用来将字符码从某种编码转换成字体的字形索引。 <br /><br />单个外观可能包含若干字符图，每个对应一个指定的字符指令系统，例如Unicode、Apple Roman、Windows codepages等等。  <br /><br />每个FT_CharMap对象包含一个platform和encoding属性，用来标识它对应的字符指令系统。每个字体格式都提供它们自己的 FT_CharMapRec的继承类型并实现它们。 <br /><br />7、对象关系 <br />下图正好概述了我们之前所说的关于库里的公共类托管，除此之外还明确描述了它们之前的关系。<br /><img height="378" width="453" alt="Simple library model" src="http://freetype.sourceforge.net/freetype2/docs/design/simple-model.png" /> <br />三、内部对象和类 <br />1、内存管理 <br />所 有内存管理操作通过基础层中3个特定例程完成，叫做FT_Alloc、FT_Realloc、 FT_Free，每个函数需要一个 FT_Memory句柄作为它的第一个参数。它是一个用来描述当前内存池/管理器对象的指针。在库初始化时，在FT_Init_FreeType中调用函 数FT_New_Memory创建一个内存管理器，这个函数位于ftsystem部件当中。 <br /><br />缺省情况下，这个管理器使用ANSI malloc、realloc和free函数，不过ftsystem是基础层中一个可替换的部分，库的特定构建可以提供不同的内存管理器。即使使用缺省的 版本，客户程序仍然可以提供自己的内存管理器，通过如下的步骤，调用FT_Init_FreeType实现： <br /><br />1. 手工创建一个FT_Memory对象，FT_MemoryRec位于公共文件&lt;freetype/ftsystem.h&gt;中。 <br /><br />2. 使用你自己的内存管理器，调用FT_New_Library()创建一个新的库实例。新的库没有包含任何已注册的模块。 <br /><br />3.  通过调用函数FT_Add_Default_Modules()（在ftinit部件中）注册缺省的模块，或者通过反复调用FT_Add_Module手 工注册你的驱动。 <br /><br />2、输入流 <br />字 体文件总是通过FT_Stream对象读取，FT_StreamRec的定义位于公共文件&lt;freetype/ftsystem.h&gt;中，可 以允许客户开发者提供自己的流实现。FT_New_Face()函数会自动根据他第二个参数，一个C路径名创建一个新的流对象。它通过调用由 ftsystem部件提供的FT_New_Stream()完成，后者时可替换的，在不同平台上，流的实现可能大不一样。 <br /><br />举例来说，流的缺省实现位于文件src/base/ftsystem.c并使用ANSI  fopen/fseek和fread函数。不过在FT2的Unix版本中，提供了另一个使用内存映射文件的实现，对于主机系统来说，可以大大提高速度。 <br /><br />FT区分基于内存和基于磁盘的流，对于前者，所有数据在内存直接访问（例如ROM、只写静态数据和内存映射文件），而后者，使用帧（frame）的概念从 字体文件中读出一部分，使用典型的seek/read操作并暂时缓冲。 <br /><br />FT_New_Memory_Face 函数可以用来直接从内存中可读取的数据创建/打开一个FT_Face对象。最后，如果需要客户输入流，客户程序能够使用FT_Open_Face()函数 接受客户输入流。这在压缩或远程字体文件的情况下，以及从特定文档抽取嵌入式字体文件非常有用。 <br /><br />注意每个外观拥有一个流，并且通过FT_Done_Face被销毁。总的来说，保持多个FT_Face在打开状态不是一个很好的主意。 <br /><br />3、模块 <br />FT2 模块本身是一段代码，库调用FT_Add_Moudle（）函数注册模块，并为每个模块创建了一个FT_Module对象。FT_ModuleRec的定 义对客户程序不是公开的，但是每个模块类型通过一个简单的公共结构FT_Module_Class描述，它定义在&lt; freetype/ftmodule.h&gt;中，后面将详述。 <br /><br />当调用FT_Add_Module是，需要指定一个FT_Module_Class结构的指针，它的声明如下： <br /><br />FT_Error FT_Add_Module( FT_Library library, <br /><br />const FT_Module_Class* clazz); <br /><br />调用这个函数将作如下操作： <br /><br />* 检查库中是否已经有对应FT_Module_Class指名的模块对象； <br /><br />*  如果是，比较模块的版本号看是否可以升级，如果模块类的版本号小于已装入的模块，函数立即返回。当然，还要检查正在运行的FT版本是否满足待装模块所需 FT的版本。 <br /><br />* 创建一个新的FT_Module对象，使用模块类的数据的标志决定它的大小和如何初始化； <br /><br />* 如果在模块类中有一个模块初始器，它将被调用完成模块对象的初始化； <br /><br />* 新的模块加入到库的&ldquo;已注册&rdquo;模块列表中，对升级的情况，先前的模块对象只要简单的销毁。 <br /><br />注意这个函数并不返回FT_Module句柄，它完全是库内部的事情，客户程序不应该摆弄他。最后，要知道FT2识别和管理若干种模块，这在后面将有详 述，这里列举如下： <br /><br />* 渲染器模块用来将原始字形映象转换成位图或象素图。FT2自带两个渲染器，一个是生成单色位图，另一个生成高质量反走样的象素图。 <br /><br />*  字体驱动模块用来支持多种字体格式，典型的字体驱动需要提供特定的FT_Face、FT_Size、FT_GlyphSlot和FT_CharMap的实 现； <br /><br />* 助手模块被多个字体驱动共享，例如sfnt模块分析和管理基于SFNT字体格式的表，用于TrueType和OpenType字体驱动； <br /><br />* 最后，auto-hinter模块在库设计中有特殊位置，它不管原始字体格式，处理向量字形轮廓，使之产生优质效果。 <br /><br />注意每个FT_Face对象依据原始字体文件格式，都属于相应的字体驱动。这就是说，当一个模块从一个库实例移除/取消注册后，所有的外观对象都被销毁 （通常是调用FT_Remove_Module()函数）。 <br /><br />因此，你要注意当你升级或移除一个模块时，没有打开FT_Face对象，因为这会导致不预期的对象删除。 <br /><br />4、库 <br />现在来说说FT_Library对象，如上所述，一个库实例至少包含如下： <br /><br />* 一个内存管理对象（FT_Memory），用来在实例中分配、释放内存； <br /><br />*  一个FT_Module对象列表，对应&ldquo;已安装&rdquo;或&ldquo;已注册&rdquo;的模块，它可以随时通过FT_Add_Module()和 FT_Remove_Module()管理； <br /><br />* 记住外观对象属于字体驱动，字体驱动模块属于库。 <br /><br />还有一个对象属于库实例，但仍未提到：raster pool <br /><br />光栅池是一个固定大小的一块内存，为一些内存需要大的操作作为内部的&ldquo;草稿区域&rdquo;，避免内存分配。例如，它用在每个渲染器转换一个向量字形轮廓到一个位图 时（这其实就是它为何叫光栅池的原因）。 <br /><br />光栅池的大小在初始化的时候定下来的（缺省为16k字节），运行期不能修改。当一个瞬时操作需要的内存超出这个池的大小，可以另外分配一块作为例外条件， 或者是递归细分任务，以确保不会超出池的极限。 <br /><br />这种极度的内存保守行为是为了FT的性能考虑，特别在某些地方，如字形渲染、扫描线转换等。 <br /><br />5、总结 <br />最后，下图展示的上面所述内容，他表示FT基本设计的对象图 <br /><br /><img height="405" width="411" alt="Complete library model" src="http://freetype.sourceforge.net/freetype2/docs/design/library-model.png" /> <br />四、模块类 <br /><br />在FT中有若干种模块 <br /><br />*  渲染模块，用来管理可缩放的字形映象。这意味这转换它们、计算边框、并将它们转换成单色和反走样位图。FT可以处理任何类型的字形映像，只要为它提供了一 个渲染模块，FT缺省带了两个渲染器 <br /><br />raster 支持从向量轮廓（由FT_Outline对象描述）到单色位图的转换 <br /><br />smooth 支持同样的轮廓转换到高质量反走样的象素图，使用256级灰度。这个渲染器也支持直接生成span。 <br /><br />* 字体驱动模块，用来支持一种或多种特定字体格式，缺省情况下，FT由下列字体驱动 <br /><br />truetype 支持TrueType字体文件 <br /><br />type1 支持PostScript Type1字体，可以是二进制（.pfb）和ASCII(.pfa)格式，包括Multiple  Master字体 <br /><br />cid 支持Postscript CID-keyed字体 <br /><br />cff 支持OpenType、CFF和CEF字体（CEF是CFF的一个变种，在Adobe的SVG Viewer中使用 <br /><br />winfonts 支持Windows位图字体，.fon和.fnt <br /><br /><br />字体驱动可以支持位图和可缩放的字形映象，一个特定支持Bezier轮廓的字体驱动通过FT_Outline可以提供他自己的hinter，或依赖FT的 autohinter模块。 <br /><br />* 助手模块，用来处理一些共享代码，通常被多个字体驱动，甚至是其他模块使用，缺省的助手如下 <br /><br />sfnt 用来支持基于SFNT存储纲要的字体格式，TrueType和OpenType字体和其他变种 <br /><br />psnames  用来提供有关字形名称排序和Postscript编码/字符集的函数。例如他可以从一个Type1字形名称字典中自动合成一个Unicode字符图。 <br /><br />psaux 用来提供有关Type1字符解码的函数，type1、cid和cff都需要这个特性 <br /><br /><br />* 最后，autohinter模块在FT中是特殊角色，当一个字体驱动没有提供自己的hint引擎时，他可以在字形装载时处理各自的字形轮廓。 <br /><br />我们现在来学习模块是如何描述以及如何被FreeType2库管理的。 <br />1 FT_Module_Class结构 <br /><br /><br />2 FT_Module类型</p><p>Copyright © 2010</p><p><a href="http://www.rtoslab.net/2010/04/2010414222519.html" target="_blank">继续阅读《《FreeType 2的设计》中译版(转)》的全文内容...</a></p><p>分类: <a href="http://www.rtoslab.net/post/jade.html">他山之玉</a> | Tags: <a href="http://www.rtoslab.net/catalog.asp?tags=Freetype">Freetype</a>&nbsp;&nbsp;<a href="http://www.rtoslab.net/catalog.asp?tags=%E7%9F%A2%E9%87%8F%E5%AD%97%E4%BD%93">矢量字体</a>&nbsp;&nbsp; | <a href="http://www.rtoslab.net/2010/04/2010414222519.html#comment" target="_blank">添加评论</a>(0)</p><h3>相关文章:</h3><ul><p><a  href="http://www.rtoslab.net/2010/04/2010414223630.html">FreeType2教程(转)</a>&nbsp;&nbsp;(2010-4-14 22:36:30)</p><p><a  href="http://www.rtoslab.net/2010/04/2010414223340.html">FreeType2的简单使用(转)</a>&nbsp;&nbsp;(2010-4-14 22:33:40)</p><p><a  href="http://www.rtoslab.net/2010/04/201041422012.html">《FreeType字形约定》中译版(转)</a>&nbsp;&nbsp;(2010-4-14 22:0:12)</p><p><a  href="http://www.rtoslab.net/2008/09/2008950831.html">Freetype学习笔记</a>&nbsp;&nbsp;(2008-9-5 0:8:31)</p></ul>]]></description><category>他山之玉</category><comments>http://www.rtoslab.net/2010/04/2010414222519.html#comment</comments><wfw:comment>http://www.rtoslab.net/</wfw:comment><wfw:commentRss>http://www.rtoslab.net/feed.asp?cmt=78</wfw:commentRss><trackback:ping>http://www.rtoslab.net/cmd.asp?act=tb&amp;id=78&amp;key=1300fcce</trackback:ping></item><item><title>《FreeType字形约定》中译版(转)</title><author>netmuch@gmail.com (much)</author><link>http://www.rtoslab.net/2010/04/201041422012.html</link><pubDate>Wed, 14 Apr 2010 22:00:12 +0800</pubDate><guid>http://www.rtoslab.net/2010/04/201041422012.html</guid><description><![CDATA[<p>&nbsp;</p><p><span style="color: rgb(255, 0, 0);">本文转自：</span><a href="http://blog.csdn.net/fengrx/archive/2009/06/30/4310328.aspx" target="_blank">blog.csdn.net/fengrx/archive/2009/06/30/4310328.aspx</a></p><p>FreeType字形约定 <br /><br />一、基本印刷概念 <br />1、字体文件、格式和信息 <br />字体是一组 可以被显示和打印的多样的字符映像，在单个字体中共享一些共有的特性，包括外表、风格、衬线等。按印刷领域的说法，它必须区别一个字体家族和多种字体外 观，后者通常是从同样的模板而来，但是风格不同。例如，Palatino Regular 和 Palatino Italic是两种不同的外观，但是属于同样的家族Palatino。 <br /><br />单个字体术语根据上下文既可以指家族也可指外观。例如，大多文 字处理器的用户用字体指不同的字体家族，然而，大多这些家族根据它们的格式会通过多个数据文件实现。对于 TrueType来讲，通常是每个外观一个文件（arial.ttf对应Arial Regular外观，ariali.ttf对应Arial Italic外观）这个文件也叫字体，但是实际上只是一个字体外观。 <br /><br />数字字体是一个可以包含一个和多个字体外观的数据文件，它们每个 都包含字符映像、字符度量，以及其他各种有关文本布局和特定字符编码的重要信息。对有些难用的格式，像Adobe的Type1，一个字体外观由几个文件描 述（一个包含字符映象，一个包含字符度量等）。在这里我们忽略这种情况，只考虑一个外观一个文件的情况，不过在FT2.0中，能够处理多文件字体。 <br /><br />为了方便说明，一个包含多个外观的字体文件我们叫做字体集合，这种情况不多见，但是多数亚洲字体都是如此，它们会包含两种或多种表现形式的映像，例如横向 和纵向布局。 <br /><br />2、字符映象和图 <br />字 符映象叫做字形，根据书写、用法和上下文，单个字符能够有多个不同的映象，即多个字形。多个字符也可以有一个字形（例如Roman？？）。字符和字形之间 的关系可能是非常复杂，本文不多述。而且，多数字体格式都使用不太难用的方案存储和访问字形。为了清晰的原因，当说明FT时，保持下面的观念 <br /><br />*  一个字体文件包含一组字形，每个字形可以存成位图、向量表示或其他结构（更可缩放的格式使用一种数学表示和控制数据/程序的结合方式）。这些字形可以以任 意顺序存在字体文件中，通常通过一个简单的字形索引访问。 <br /><br />* 字体文件包含一个或多个表，叫做字符图，用来为某种字符编码将字符码转换成字形索引，例如ASCII、Unicode、Big5等等。单个字体文件可能包 含多个字符图，例如大多TrueType字体文件都会包含一个Apple特定的字符图和Unicode字符图，使它在Mac和Windows平台都可以使 用。 <br /><br />3、字符和字体度量 <br />每个字符映象都关联多种度量，被用来在渲染文本时，描述如何放置和管理它们。在后面会有详述，它们和字形位置、光标步进和文本布局有关。它们在渲染一个文 本串时计算文本流时非常重要。 <br /><br />每个可缩放的字体格式也包含一些全局的度量，用概念单位表示，描述同一种外观的所有字形的一些特性，例如最大字形外框，字体的上行字符、下行字符和文本高 度等。 <br /><br />虽然这些度量也会存在于一些不可缩放格式，但它们只应用于一组指定字符维度和分辨率，并且通常用象素表示。 <br /><br /><br />二、字形轮廓 <br />1、象素、点和设备解析度 <br />当处理计算机图形程序时，指定象素的物理尺寸不是正方的。通常，输出设备是屏幕或打印机，在水平和垂直方向都有多种分辨率，当渲染文本是要注意这些情况。  <br /><br />定 义设备的分辨率通常使用用dpi（每英寸点(dot)数）表示的两个数，例如，一个打印机的分辨率为300x600dpi表示在水平方向，每英寸有300 个象素，在垂直方向有600个象素。一个典型的计算机显示器根据它的大小，分辨率不同（15&rsquo;&rsquo;和17&rsquo;&rsquo;显示器对640x480象素大小不同），当然图 形模式分辨率也不一样。 <br /><br />所以，文本的大小通常用点（point）表示，而不是用设备特定的象素。点是一种简单的物理单位，在数字印刷中，一点等于1/72英寸。例如，大多罗马书 籍使用10到14点大小印刷文字内容。 <br /><br />可以用点数大小来计算象素数，公式如下： <br /><br />象素数 = 点数*分辨率/72 <br /><br />分辨率用dpi表示，因为水平和垂直分辨率可以不同，单个点数通常定义不同象素文本宽度和高度。 <br /><br />2、向量表示 <br />字体轮廓的源格式是一组封闭的路径，叫做轮廓线。每个轮廓线划定字形的外部或内部区域，它们可以是线段或是Bezier曲线。 <br /><br />曲 线通过控制点定义，根据字体格式，可以是二次(conic Beziers)或三次(cubic Beziers)多项式。在文献中，conic Bezier通常称为quadratic Beziers。因此，轮廓中每个点都有一个标志表示它的类型是一般还是控制点，缩放这些点将缩放整个轮廓。 <br /><br />每个字形最初的轮廓点放置在一个不可分割单元的网格中，点通常在字体文件中以16位整型网格坐标存储，网格的原点在(0,0)，它的范围是-16384到 16383（虽然有的格式如Type1使用浮点型，但为简便起见，我们约定用整型分析）。 <br /><br />网格的方向和传统数学二维平面一致，x轴从左到右，y轴从下到上。 <br /><br />在创建字形轮廓时，一个字体设计者使用一个假想的正方形，叫做EM正方形。他可以想象成一个画字符的平面。正方形的大小，即它边长的网格单元是很重要的， 原因是 <br /><br />*  它是用来将轮廓缩放到指定文本尺寸的参考，例如在300x300dpi中的12pt大小对应12*300/72=50象素。从网格单元缩放到象素可以使用 下面的公式 <br /><br />象素数 ＝ 点数 &times; 分辨率/72 <br />象素坐标＝ 网格坐标*象素数/EM大小 <br /><br />*  EM尺寸越大，可以达到更大的分辨率，例如一个极端的例子，一个4单元的EM，只有25个点位置，显然不够，通常TrueType字体之用2048单元的 EM；Type1 PostScript字体有一个固定1000网格单元的EM，但是点坐标可以用浮点值表示。 <br /><br />注意，字形可以自由超出EM正方形。网格单元通常交错字体单元或EM单元。上边的象素数并不是指实际字符的大小，而是EM正方形显示的大小，所以不同字 体，虽然同样大小，但是它们的高度可能不同。 <br /><br />3、Hinting和位图渲染 <br />存储在一个字体文件中的轮廓叫&ldquo;主&rdquo;轮廓，它的点坐标用字体单元表示，在它被转换成一个位图时，它必须缩放至指定大小。这通过一个简单的转换完成，但是总 会产生一些不想要的副作用，例如像字母E和H，它们主干的宽度和高度会不相同。 <br /><br />所 以，优秀的字形渲染过程在缩放&ldquo;点&rdquo;是，需要通过一个网格对齐(grid-fitting)的操作（通常叫hinting），将它们对齐到目标设备的象素 网格。这主要目的之一是为了确保整个字体中，重要的宽度和高度能够一致。例如对于字符I和T来说，它们那个垂直笔划要保持同样象素宽度。另外，它的目的还 有管理如stem和overshoot的特性，这在小象素字体会引起一些问题。 <br /><br />有若干种方式来处理网格对齐，多数可缩放格式中，每种字形轮廓都有一些控制数据和程序。 <br /><br />* 显式网格对齐 <br /><br />TrueType格式定义了一个基于栈的虚拟机（VM），可以借助多于200中操作码（大多是几何操作）来编写程序，每个字形都由一个轮廓和一个控制程序 组成，后者可以处理实际的网格对齐，他由字体设计者定义。 <br /><br />* 隐式网格对齐（也叫hinting） <br /><br />Type1格式有一个更简单的方式，每个字形由一个轮廓以及若干叫hints的片断组成，后者用来描述字形的某些重要特性，例如主干的存在、某些宽度匀称 性等诸如此类。没有多少种hint，要看渲染器如何解释hint来产生一个对齐的轮廓。 <br /><br />* 自动网格对齐 <br /><br />有些格式很简单，没有包括控制信息，将字体度量如步进、宽度和高度分开。要靠渲染器来猜测轮廓的一些特性来实现得体的网格对齐。 <br /><br />下面总结了每种方案的优点和缺点 <br /><br />方案 优点 缺点 <br /><br />显式 质量：对小字体有很好的结果，这对屏幕显示非常重要。 速度：如果程序很复杂，解释字节码很慢 <br />一致性：所有渲染器产生同样的字形位图。 大小：字形程序会很长。 <br />技术难度：编写优秀的hinting程序非常难，没有好的工具支持。 <br /><br />隐式 大小：Hint通常比显式字形程序小的多 质量：小字体不好，最后结合反走样 <br />速度：网格对齐会非常快 不一致：不同渲染器结果不同，甚至同一引擎不同版本也不同。 <br /><br />自动 大小：不需要控制信息，导致更小的字体文件 质量：小字体不好，最后结合反走样 <br />速度：依赖对齐算法，通常比显式对齐快。 速度：依赖算法 <br />不一致：不同渲染器结果不同，甚至同一引擎不同版本也不同。 <br /><br /><br />三、字形度量 <br />1、基线(baseline)、笔(pen)和布局(layout) <br />基线是一个假想的线，用来在渲染文本时知道字形，它可以是水平（如Roman）和是垂直的（如中文）。而且，为了渲染文本，在基线上有一个虚拟的点，叫做 笔位置（pen position）或原点（origin），他用来定位字形。 <br /><br />每种布局使用不同的规约来放置字形： <br /><br />* 对水平布局，字形简单地搁在基线上，通过增加笔位置来渲染文本，既可以向右也可以向左增加。 <br /><br />两个相邻笔位置之间的距离是根据字形不同的，叫做步进宽度（advance  width）。注意这个值总是正数，即使是从右往左的方向排列字符，如Arabic。这和文本渲染的方式有些不同。 <br /><br />笔位置总是放置在基线上。 <br /><br /><br />* 对垂直布局，字形在基线上居中放置： <br /><br /><br />2、印刷度量和边界框 <br />在指定字体中，定义了多种外观度量。 <br /><br />* 上行高度（ascent）。从基线到放置轮廓点最高/上的网格坐标，因为Y轴方向是向上的，所以它是一个正值。 <br /><br />* 下行高度（descent）。从基线到放置轮廓点最低/下的网格坐标，因为Y轴方向是向上的，所以它是一个负值。 <br /><br />* 行距（linegap）。两行文本间必须的距离，基线到基线的距离应该计算成 <br /><br />上行高度 － 下行高度 ＋ 行距 <br /><br />* 边界框（bounding box，bbox）。这是一个假想的框子，他尽可能紧密的装入字形。通过四个值来表示，叫做xMin、yMin、xMax、yMax，对任何轮廓都可以计 算，它们可以是字体单元（测量原始轮廓）或者整型象素单元（测量已缩放的轮廓）。注意，如果不是为了网格对齐，你无需知道这个框子的这个值，只需知道它的 大小即可。但为了正确渲染一个对齐的字形，需要保存每个字形在基线上转换、放置的重要对齐。 <br /><br />* 内部leading。这个概念从传统印刷业而来，他表示字形出了EM正方形空间数量，通常计算如下 <br /><br />internal leading = ascent &ndash; descent &ndash; EM_size <br /><br />* 外部leading。行距的别名。 <br /><br />3、跨距（bearing）和步进 <br />每个字形都有叫跨距和步进的距离，它们的定义是常量，但是它们的值依赖布局，同样的字形可以用来渲染横向或纵向文字。 <br /><br />* 左跨距或bearingX。从当前笔位置到字形左bbox边界的水平距离，对水平布局是正数，对垂直布局大多是负值。 <br /><br />* 上跨距或bearingY。从基线到bbox上边界的垂直距离，对水平布局是正值，对垂直布局是负值。 <br /><br />*  步进宽度或advanceX。当处理文本渲染一个字形后，笔位置必须增加（从左向右）或减少（从右向左）的水平距离。对水平布局总是正值，垂直布局为 null。 <br /><br />* 步进高度或advanceY。当每个字形渲染后，笔位置必须减少的垂直距离。对水平布局为null，对垂直布局总是正值。 <br /><br />*  字形宽度。字形的水平长度。对未缩放的字体坐标，它是bbox.xMax-bbox.xMin，对已缩放字形，它的计算要看特定情况，视乎不同的网格对齐 而定。 <br /><br />*  字形高度。字形的垂直长度。对未缩放的字体坐标，它是bbox.yMax-bbox.yMin，对已缩放字形，它的计算要看特定情况，视乎不同的网格对齐 而定。 <br /><br />* 右跨距。只用于水平布局，描述从bbox右边到步进宽度的距离，通常是一个非负值。 <br /><br />advance_width &ndash; left_side_bearing &ndash; (xMax-xMin) <br /><br />下图是水平布局所有的度量 <br /><br /><br />下图是垂直布局的度量 <br /><br /><br />4、网格对齐的效果 <br />因 为hinting将字形的控制点对齐到象素网格，这个过程将稍稍修改字符映象的尺寸，和简单的缩放有所区别。例如，小写字母m的映象在主网格中有时是一个 正方形，但是为了使它在小象素大小情况下可以辨别，hinting试图扩大它已缩放轮廓，以让它三条腿区分开来，这将导致一个更大的字符位图。 <br /><br />字形度量也会受网格对齐过程的影响： <br /><br />* 映象的宽度和高度改变了，即使只是一个象素，对于小象素大小字形区别都很大； <br /><br />* 映象的边界框改变了，也改变了跨距； <br /><br />* 步进必须更改，例如如果被hint的位图比缩放的位图大时，必须增加步进宽度，来反映扩大的字形宽度。 <br /><br />这有一些含义如下， <br /><br />* 因为hinting，简单缩放字体上行或下行高度可能不会有正确的结果，一个可能的方法时保持被缩放上行高度的顶和被缩放下行高度的底。 <br /><br />*  没有容易的方法去hint一个范围内字形并步进它们宽度，因为hinting对每个轮廓工作都不一样。唯一的方法时单独hint每个字形，并记录返回值。 有些格式，如TrueType，包含一些表对一些通用字符预先计算出它们的象素大小。 <br /><br />* hinting依赖最终字符宽度和高度的象素值，意味着它非常依赖分辨率，这个特性使得正确的所见即所得布局非常难以实现。 <br /><br />在FT 中，对字形轮廓处理2D变换很简单，但是对一个已hint的轮廓，需要注意专有地使用整型象素距离（意味着FT_Outline_Translate() 函数的参数应该都乘以64，因为点坐标都是26.6固定浮点格式），否则，变换将破坏hinter的工作，导致非常难看的位图。 <br /><br />5、文本宽度和边界框 <br />如上所示，指定字形的原点对应基线上笔的位置，没有必要定位字形边界框的某个角，这不像多数典型的位图字体格式。有些情况，原点可以在边界框的外边，有 时，也可以在里边，这要看给定的字形外形了。 <br /><br />同样，字形的步进宽度是在布局时应用于笔位置的增量，而不是字形的宽度，那是字形边界的宽度。对文本串，具有相同的规约，这意味着： <br /><br />* 指定文本串的边界框没有必要包含文本光标，也不需要后边的字形放置在它的角上。 <br /><br />* 字符串的步进宽度和它的边界框大小无关，特别时它在开始和最后包含空格或tab。 <br /><br />* 最后，附加的处理如间距调整能够创建文本串，它的大小不直接依赖单独字形度量并列排列。例如，VA的步进宽度不是V和A各自的步进之和。 <br /><br /><br />四、字距调整 <br />字距调整这个术语指用来在一个文本串中调整重合字形的相对位置的特定信息。 <br /><br />1、字距调整对 <br />字距调整包括根据相邻字形的轮廓修改它们之间的距离。例如T和y可以贴得更近一点，因为y的上缘正好在T的右上角一横的下边。 <br /><br />当仅仅根据字形的标准宽度来布局文本，一些连续的字符看上去有点太挤和太松，例如下图中A和V的就显得距离太远。 <br /><br /><br />比较一下下图，同样的单词，A和V的距离拉近些 <br /><br /><br />可以看到，这个调整可以导致很大的区别。有的字体外观包含一个表，它包含文本布局所需的指定字形对的字距距离。 <br /><br />* 这个对是顺序的，AV对的距离和VA对不一定一致； <br /><br />* 依据布局或书写，字距可以表示水平或垂直方向。 <br /><br />* 字距表示成网格单元，它们通常是X轴方向的，意味着负值表示两个字形需要在水平方向放的更近一点。 <br /><br />2、应用字距调整 <br />在渲染文本时应用字据调整是一个比较简单的过程，只需要在写下一个字形时，将缩放的字距加到笔位置即可。然而，正确的渲染器要考虑的更细一点。 <br /><br />&ldquo;滑动点&rdquo;问题是一个很好的例子：很多字体外观包括一个大写字符（如T、F）和一个点.之间的字距调整，以将点正好放置在前者的主腿的右侧。 <br /><br /><br />根据字符的外形，有时候需要在点和随后的字符间作附加的调整，当应用&ldquo;标准&rdquo;的字距调整，上面的句子如下 <br /><br /><br />这显然太紧凑了。一个方案是，只在需要时滑动点，当然这需要对文本的意思有了解。如果当我们在渲染特定段落的最后一个点时，上面的调整就不适合了。这只是 一个例子，还有很多其他例子显示一个真正的印刷工人需要恰当地布局文本。 <br /><br />有一个很简单地算法，可以避免滑动点问题。 <br /><br />1. 在基线上放置第一个字形； <br />2. 将笔位置保存到pen1； <br />3. 根据第一个和第二个字形的字距距离调整笔位置； <br />4. 放置第二个字形，并计算下个笔位置，放到pen2； <br />5. 如果pen1大于pen2，使用pen1作为下个笔位置，否则使用pen2。 <br /><br /><br />五、文本处理 <br />1、书写简单文本串 <br />在第一个例子中，我们将生成一个简单的Roman文字串，即采用水平的自左向右布局，使用专有的象素度量，这个过程如下： <br /><br />1. 将字符串转换成一系列字形索引； <br />2. 将笔放置在光标位置； <br />3. 获得或装入字形映象； <br />4. 平移字形以使它的原点匹配笔位置； <br />5. 将字形渲染到目标设备； <br />6. 根据字形的步进象素增加笔位置； <br />7. 对剩余的字形进行第三步； <br />8. 当所有字形都处理了，在新的笔位置设置文本光标。 <br /><br />注意字距调整不在这个算法中。 <br /><br />2、子象素定位 <br />在渲染文本时使用子象素定位有时很有用。这非常重要，例如为了提供半所见即所得的文本布局，文本渲染的算法和上一节很相似，但是有些区别： <br /><br />* 笔位置表示成小数形式的象素； <br />* 因为将一个已经hint过的轮廓平移一个非整型距离将破坏网格对齐，字形原点的位置在渲染字符映象前必须取整； <br />* 步进宽度表示成小数形式的象素，没有必要是整型。 <br /><br />这里是算法的改进版本： <br /><br />1. 将字符串转换成一系列字形索引； <br />2. 将笔放置在光标位置，这可以是一个非整型点； <br />3. 获得或装入字形映象； <br />4. 平移字形以使它的原点匹配取整后的笔位置； <br />5. 将字形渲染到目标设备； <br />6. 根据字形的步进象素宽度增加笔位置，这个宽度可以是小数形式； <br />7. 对剩余的字形进行第三步； <br />8. 当所有字形都处理了，在新的笔位置设置文本光标。 <br /><br />注意使用小数象素定位后，两个指定字符间的空间将不是固定的，它右先前的取整操作堆积的数决定。 <br /><br />3、简单字距调整 <br />在基本文本渲染算法上增加字距调整非常简单，当一个字距调整对发现了，简单地在第4步前，将缩放后的调整距离增加到笔位置即可。淡然，这个距离在算法1需 要被取整，算法2不必要。 <br /><br />4、自右向左布局 <br />布局Arabic或Heberw文字的过程非常相似，区别只是在字形渲染前，笔位置需要减少（记住步进宽度总是正值） <br /><br />5、垂直布局 <br />布局垂直文字也是同样的过程，重要的区别如下： <br /><br />* 基线是垂直的，使用垂直的度量而不是水平度量； <br />* 左跨距通常是负的，但字形原点必须在基线上； <br />* 步进高度总是正值，所以笔位置必须减少以从上至下书写； <br /><br />6、所见即所得布局 <br /><br /><br />六、FT轮廓 <br />1、FT轮廓描述和结构 <br />a. 轮廓曲线分解 <br />一个轮廓是2D平面上一系列封闭的轮廓线。每个轮廓线由一系列线段和Bezier弧组成，根据文件格式不同，曲线可以是二次和三次多项式，前者叫 quadratic或conic弧，它们在TrueType格式中用到，后者叫cubic弧，多数用于Type1格式。 <br /><br />每条弧由一系列起点、终点和控制点描述，轮廓的每个点有一个特定的标记，表示它用来描述一个线段还是一条弧。这个标记可以有以下值： <br /><br />FT_Curve_Tag_On  当点在曲线上，这对应线段和弧的起点和终点。其他标记叫做&ldquo;Off&rdquo;点，即它不在轮廓线上，但是作为Bezier弧的控制点。 <br />FT_Curve_Tag_Conic 一个Off点，控制一个conic Bezier弧 <br />FT_Curve_Tag_Cubic 一个Off点，控制一个cubic Bezier弧 <br /><br />下面的规则应用于将轮廓点分解成线段和弧 <br /><br />* 两个相邻的&ldquo;on&rdquo;点表示一条线段； <br />* 一个conic Off点在两个on点之间表示一个conic Bezier弧，off点是控制点，on点是起点和终点； <br />* 两个相邻的cubic off点在两个on点之间表示一个cubic Bezier弧，它必须有两个cubic控制点和两个on点。 <br />* 最后，两个相邻的conic  off点强制？？在它们正中间创建一个虚拟的on点。这大大方便定义连续的conic弧。TrueType规范就是这么定义的。</p><p class="post">&nbsp;</p><table border="0">    <tbody>        <tr>            <td><img height="166" width="221" alt="segment example" src="http://www.freetype.org/freetype2/docs/glyphs/points_segment.png" /></td>            <td><img height="183" width="236" alt="conic arc example" src="http://www.freetype.org/freetype2/docs/glyphs/points_conic.png" /></td>        </tr>        <tr>            <td><img height="162" width="214" alt="cubic arc example" src="http://www.freetype.org/freetype2/docs/glyphs/points_cubic.png" /></td>            <td><img height="204" width="225" alt="cubic arc with virtual 'on' point" src="http://www.freetype.org/freetype2/docs/glyphs/points_conic2.png" /></td>        </tr>    </tbody></table><p class="post"><br /><br />注意，在单个轮廓线中可以混合使用conic和cubic弧，不过现在没有那种字体驱动产生这样的轮廓。 <br /><br /><br /><br />b. 轮廓描述符 <br />FT轮廓通过一个简单的结构描述 <br /><br />FT_Outline <br />n_points 轮廓中的点数 <br />n_contours 轮廓中轮廓线数 <br />points 点坐标数组 <br />contours 轮廓线端点索引数组 <br />tags 点标记数组 <br /><br />这里，points是一个FT_Vector记录数组的指针，用来存储每个轮廓点的向量坐标。它表示为一个象素1/64，也叫做26.6固定浮点格式。 <br /><br />contours是一组点索引，用来划定轮廓的轮廓线。例如，第一个轮廓线总是从0点开始，以contours[0]点结束。第二个轮廓线从 contours[0]+1点开始，以contours[1]结束，等等。 <br /><br />注意，每条轮廓线都是封闭的，n_points应该和contours[n_controus-1]+1相同。最后，tags是一组字节，用来存放每个轮 廓的点标记。 <br /><br />2、边界和控制框计算 <br />边 界框（bbox）是一个完全包含指定轮廓的矩形，所要的是最小的边界框。因为弧的定义，bezier的控制点无需包含在轮廓的边界框中。例如轮廓的上缘是 一个Bezier弧，一个off点就位于bbox的上面。不过这在字符轮廓中很少出现，因为大多字体设计者和创建工具都会在每个曲线拐点处放一个on点， 这会使hinting更加容易。于是我们定义了控制框（cbox），它是一个包含轮廓所有点的最小矩形，很明显，它包含bbox，通常它们是一样的。不想 bbox，cbox计算起来非常快。</p><p>Unlike the bbox, the cbox is much faster to compute.</p><table border="0">    <tbody>        <tr>            <td><img height="264" width="228" alt="a glyph with different bbox and cbox" src="http://www.freetype.org/freetype2/docs/glyphs/bbox1.png" /></td>            <td><img height="229" width="217" alt="a glyph with identical bbox and cbox" src="http://www.freetype.org/freetype2/docs/glyphs/bbox2.png" /></td>        </tr>    </tbody></table><p><br /><br /><br />控 制框和边界框可以通过函数FT_Outline_Get_CBox()和 FT_Outline_Get_BBox()自动计算，前者总是非常快，后者在有外界控制点的情况下会慢一点，因为需要找到conic和cubic弧的末 端，如果不是这种情况，它和计算控制框一样快。 <br /><br />注意，虽然大多字形轮廓为易于hint具有相同的cbox和bbox，这在它们进行变换以后，如旋转，就不再是这种情况了。 <br /><br />3、坐标、缩放和网格对齐 <br />轮廓点的向量坐标表示为26.6格式，即一个象素的1/64。因此，坐标（1.0,-2.5）存放整型对（x:64,y:-192）。 <br /><br />在主字形轮廓从EM网格缩放到当前字符大小后，hinter负责对齐重要的轮廓点到象素网格。虽然这个过程很难几句话说清楚，但是它的目的也就是取整点的 位置，以保持字形重要的特性，如宽度、主干等。下面的操作可以用来将26.6格式的向量距离取整到网格： <br /><br />round(x) == (x + 32) &amp; -64 <br />floor(x) == x &amp; -64 <br />ceiling(x) == (x + 63) &amp; -64 <br /><br />一旦一个字形轮廓经过对齐或变换，在渲染之前通常要计算字形的映象象素大小。做到这一点，必须考虑如下： <br /><br />扫描线转换器画出所有中心在字形形状中的象素，他也可以检测drop-outs？？？ <br /><br />这导致如下的计算： <br /><br />* 计算bbox； <br />* 对齐bbox如下： <br />xmin = floor(bbox.xMin) <br />xmax = ceiling(bbox.xMax) <br />ymin = floor(bbox.yMin) <br />ymax = ceiling(bbox.yMax) <br />* 返回象素尺寸，即 <br />width = (xmax-xmin) / 64 <br />和 <br />height = (ymax-ymin) / 64 <br /><br />通过对齐bbox，可以保证所有的象素中心将画到，包括那些从drop-out控制来的，将在调整后的框子之中。接着，框子的象素尺寸可以计算出来。 <br /><br />同时注意，当平移一个对齐的轮廓，应该总是使用整型距离来移动。否则，字形的边缘将不再对齐象素网格，hinter的工作将无效，产生非常难看的位图。 <br /><br /><br />七、FT位图 <br />1、向量坐标和象素坐标对比 <br />这里阐述了向量坐标的象素坐标的区别，为了更清楚的说明，使用方括号来表示象素坐标，使用圆括号表示向量坐标。 <br /><br />在象素坐标中，我们使用Y轴向上的规约，坐标[0,0]总是指位图左下角象素，坐标[width-1,  rows-1]是右上角象素。在向量坐标中，点坐标用浮点单位表示，如(1.25,  -2.3)，这个位置并不是指一个特定象素，而是在2D平面上一个非实质性的点。 <br /><br />象 素其实在2D平面上是一个方块，它的中心是象素坐标值的一半，例如位图的左下角象素通过方块(0,0)-(1,1)界定，它的中心位于 (0.5,0.5)。注意这儿用的是向量坐标表示。这对计算距离就会发生一些区别。例如，[0,0]-[10.0]一条线的象素长度是11，然而， (0,0)-(10,0)的向量程度覆盖了10个象素，因此它的长度是10。 <br /><img height="390" width="402" alt="bitmap and vector grid" src="http://www.freetype.org/freetype2/docs/glyphs/grid_1.png" /> &nbsp;<br /><br />2、FT位图和象素图描述符 <br />一个位图和象素图通过一个叫FT_Bitmap的单一结构描述，他定义在&lt;freetype/ftimage.h&gt;中，属性如下 <br /><br />FT_Bitmap <br />rows 行数，即位图中的水平线数 <br />width 位图的水平象素数 <br />pitch 它的绝对值是位图每行占的字节数，根据位图向量方向，可以是正值或是负值 <br />buffer 一个指向位图象素缓冲的无类型指针 <br />pixel_mode  一个枚举值，用来表示位图的象素格式；例如ft_pixel_mode_mono表示1位单色位图，ft_pixel_mode_grays表示8位反走 样灰度值 <br />num_grays 这只用于灰度象素模式，它给出描述反走样灰度级别的级数，FT缺省值为255。 <br /><br />pitch 属性值的正负符号确定象素缓冲中的行是升序还是降序存放。上面说道FT在2D平面上使用Y轴向上的规约，这意味着(0,0)总是指向位图的左下角。如果 picth是正值，按照向量减少的方向存储行，即象素缓冲的第一个字节表示位图最上一行的部分。如果是负值，第一个字节将表示位图最下一行的部分。对所有 的情况，pitch可以看作是在指定位图缓冲中，跳到下一个扫描行的字节增量。</p><table border="0">    <tbody>        <tr>            <td><img height="261" width="275" alt="negative 'pitch'" src="http://www.freetype.org/freetype2/docs/glyphs/up_flow.png" /></td>            <td><img height="263" width="273" alt="positive 'pitch'" src="http://www.freetype.org/freetype2/docs/glyphs/down_flow.png" /></td>        </tr>    </tbody></table><p><br /><br />通常都使用正pitch，当然有的系统会使用负值。 <br /><br />3、轮廓转换到位图和象素图 <br />使用FT从一个向量映象转换到位图和象素图非常简单，但是，在转换前，必须理解有关在2D平面上放置轮廓的一些问题： <br /><br />* 字形转载器和hinter在2D平面上放置轮廓时，总将(0,0)匹配到字符原点，这意味着字形轮廓，及对应的边界框，可以在平面中放置于任何地方。  <br /><br />* 目标位图映射到2D平面上，左下角在(0,0)上，这就是说一个[w,h]大小的位图和象素图将被映射到(0,0)-(w,h)界定的2D矩形窗口。  <br /><br />* 当扫描转换轮廓，所有在这个位图窗口的部分将被渲染，其他的被忽略。 <br /><br />很多使用FT的开发者都会有个误解，认为一个装入的轮廓可以直接渲染成一个适当大小的位图，下面的图像表明这个问题。 <br /><img height="151" width="539" alt="clipping algorithm" src="http://www.freetype.org/freetype2/docs/glyphs/clipping.png" /> <br />* 第一个图表明一个2D平面上一个装入的轮廓； <br /><br />* 第二个表示一个任意大小[w,h]维护的目标窗口； <br /><br />* 第三个表示在2D平面上轮廓和窗口的合并； <br /><br />* 最后一个表示位图实际被渲染的部分。 <br /><br /><br />实际上，几乎所有的情况，装入或变换过的轮廓必须在渲染成目标位图之前作平移操作，以调整到相对目标窗口的位置。 <br /><br />例如，创建一个单独的字形位图正确的方法如下： <br /><br />* 计算字形位图的大小，可以直接从字形度量计算出来，或者计算它的边界框（这在经过变换后非常有用，此时字形度量不再有效）。 <br /><br />* 根据计算的大小创建位图，别忘了用背景色填充象素缓冲； <br /><br />* 平移轮廓，使左下角匹配到(0,0)。别忘了为了hinting，应该使用整型。通常，这就是说平移一个向量（-ROUND(xMin),  -ROUND(yMin)）。 <br /><br />* 调用渲染功能，例如FT_Outline_Render()函数。 <br /><br />在将字形映象直接写入一个大位图的情况，轮廓必须经过平移，以将它们的向量位置对应到当前文本光标/字符原点上。 <br /><br /><br />良好的沟通能力 和 积极的行动 是成功的钥匙。</p><p>Copyright © 2010</p><p><a href="http://www.rtoslab.net/2010/04/201041422012.html" target="_blank">继续阅读《《FreeType字形约定》中译版(转)》的全文内容...</a></p><p>分类: <a href="http://www.rtoslab.net/post/jade.html">他山之玉</a> | Tags: <a href="http://www.rtoslab.net/catalog.asp?tags=Freetype">Freetype</a>&nbsp;&nbsp;<a href="http://www.rtoslab.net/catalog.asp?tags=%E7%9F%A2%E9%87%8F%E5%AD%97%E4%BD%93">矢量字体</a>&nbsp;&nbsp; | <a href="http://www.rtoslab.net/2010/04/201041422012.html#comment" target="_blank">添加评论</a>(0)</p><h3>相关文章:</h3><ul><p><a  href="http://www.rtoslab.net/2010/04/2010414223630.html">FreeType2教程(转)</a>&nbsp;&nbsp;(2010-4-14 22:36:30)</p><p><a  href="http://www.rtoslab.net/2010/04/2010414223340.html">FreeType2的简单使用(转)</a>&nbsp;&nbsp;(2010-4-14 22:33:40)</p><p><a  href="http://www.rtoslab.net/2010/04/2010414222519.html">《FreeType 2的设计》中译版(转)</a>&nbsp;&nbsp;(2010-4-14 22:25:19)</p><p><a  href="http://www.rtoslab.net/2008/09/2008950831.html">Freetype学习笔记</a>&nbsp;&nbsp;(2008-9-5 0:8:31)</p></ul>]]></description><category>他山之玉</category><comments>http://www.rtoslab.net/2010/04/201041422012.html#comment</comments><wfw:comment>http://www.rtoslab.net/</wfw:comment><wfw:commentRss>http://www.rtoslab.net/feed.asp?cmt=77</wfw:commentRss><trackback:ping>http://www.rtoslab.net/cmd.asp?act=tb&amp;id=77&amp;key=0086a58d</trackback:ping></item><item><title>www.ucgui.com的临时替代域名</title><author>netmuch@gmail.com (much)</author><link>http://www.rtoslab.net/2010/04/201042215540.html</link><pubDate>Fri, 02 Apr 2010 21:55:40 +0800</pubDate><guid>http://www.rtoslab.net/2010/04/201042215540.html</guid><description><![CDATA[<p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>从网友admin_ucgui那里获知，</p><p>由于<a href="http://www.ucgui.com" target="_blank">www.ucgui.com</a>域名的原因，暂时无法使用，</p><p>暂时使用<a href="http://ucgui.vc.91cdn.com/bbs/" target="_blank">http://ucgui.vc.91cdn.com/bbs/</a>进行替代。</p><p>&nbsp;</p><p><a href="http://www.ucgui.com" target="_blank">www.ucgui.com</a>再次启用时间待定！</p><p>2010-04-17注：<a href="http://www.ucgui.com" target="_blank">www.ucgui.com</a>似乎已经启用了！福音！</p><p>&nbsp;</p><p>Copyright © 2010</p><p><a href="http://www.rtoslab.net/2010/04/201042215540.html" target="_blank">继续阅读《www.ucgui.com的临时替代域名》的全文内容...</a></p><p>分类: <a href="http://www.rtoslab.net/post/clutter.html">杂七杂八</a> | Tags: <a href="http://www.rtoslab.net/catalog.asp?tags=ucgui">ucgui</a>&nbsp;&nbsp; | <a href="http://www.rtoslab.net/2010/04/201042215540.html#comment" target="_blank">添加评论</a>(0)</p><h3>相关文章:</h3><ul><p><a  href="http://www.rtoslab.net/2008/08/20088270296.html">修改UCGUI源代码以支持多个独立窗体的说明</a>&nbsp;&nbsp;(2008-8-27 0:29:6)</p><p><a  href="http://www.rtoslab.net/2008/08/200882702515.html">如何在uC/GUI中实现窗体半透明效果（二） </a>&nbsp;&nbsp;(2008-8-27 0:25:15)</p><p><a  href="http://www.rtoslab.net/2008/08/20088270193.html">如何在uC/GUI中实现窗体半透明效果（一） </a>&nbsp;&nbsp;(2008-8-27 0:19:3)</p><p><a  href="http://www.rtoslab.net/2008/07/200878225338.html">UC/GUI的3.24源码！</a>&nbsp;&nbsp;(2008-7-8 22:53:38)</p></ul>]]></description><category>杂七杂八</category><comments>http://www.rtoslab.net/2010/04/201042215540.html#comment</comments><wfw:comment>http://www.rtoslab.net/</wfw:comment><wfw:commentRss>http://www.rtoslab.net/feed.asp?cmt=76</wfw:commentRss><trackback:ping>http://www.rtoslab.net/cmd.asp?act=tb&amp;id=76&amp;key=b8d9dfe2</trackback:ping></item><item><title>VC6编译fltk2错误汇总&amp;lt;转&amp;gt;</title><author>netmuch@gmail.com (much)</author><link>http://www.rtoslab.net/2010/03/201032821854.html</link><pubDate>Sun, 28 Mar 2010 21:08:54 +0800</pubDate><guid>http://www.rtoslab.net/2010/03/201032821854.html</guid><description><![CDATA[本文系转帖。<br/>原文地址：http://crasyrobot.blogbus.com/tag/fltk2/<br/><br/>软件：VC6,XP-SP2,fltk-2.0.x-r6879<br/><br/>fltk2的软件作者显然不是很仔细，：（<br/><br/>1) 首先最开始编译就出现#warning和#error等fatal错误<br/>经过核查，该项目工程的VC工程中，在visualc目录下有个config.h文件，而如果编译linux版本时，会由./configure生成项目根目录下的config.h文件，我是先编译的linux版本，因此这两个config.h文件都同时存在，而这两个config.h显然在有些变量的定义上是完全不同的，所以比较简单的方法就是在编译VC版本的时候，删除这个linux版本的config.h，项目在编译的时候，会根据目录顺序，先找项目根目录下的，再找visualc目录下的，找到第一个就退出。<br/><br/> <br/><br/>2) # warning "This method will not work on this system. (you can ignore this warning)"<br/>这是由于在项目中没有定义__WIN32__这个宏，加入到project->setting的预定义宏即可。<br/><br/>3) BITMAPV5HEADER 结构无定义<br/>在config.h的最前面加入<br/>#undef WINVER<br/>#define WINVER 0x0500即可<br/><br/><br/>4)编译出现LNK2001 ： unresolved external symbol错误<br/><br/>Linking...<br/>fltk2.lib(Widget.obj) : error LNK2001: unresolved external symbol "void __cdecl<br/>delete_associations_for(class fltk::Widget *)"<br/>(?delete_associations_for <at> <at> [EMAIL PROTECTED] <at> <at> <at> Z)<br/>fltk2.lib(ShortcutAssignment.obj) : error LNK2001: unresolved external symbol<br/>"public: void __thiscall fltk::Widget::add(class fltk::AssociationType const<br/>&,void *)" ([EMAIL PROTECTED] <at> fltk <at> <at> [EMAIL PROTECTED] <at> [EMAIL PROTECTED])<br/>fltk2.lib(ShortcutAssignment.obj) : error LNK2001: unresolved external symbol<br/>"public: bool __thiscall fltk::Widget::find(class fltk::AssociationType const<br/>&,void *)const " ([EMAIL PROTECTED] <at> fltk <at> <at> [EMAIL PROTECTED] <at> [EMAIL PROTECTED])<br/>fltk2.lib(ShortcutAssignment.obj) : error LNK2001: unresolved external symbol<br/>"public: bool __thiscall fltk::Widget::remove(class fltk::AssociationType const<br/>&,void *)" ([EMAIL PROTECTED] <at> fltk <at> <at> [EMAIL PROTECTED] <at> [EMAIL PROTECTED])<br/>fltk2.lib(ShortcutAssignment.obj) : error LNK2001: unresolved external symbol<br/>"public: void __thiscall fltk::Widget::set(class fltk::AssociationType const<br/>&,void *)" ([EMAIL PROTECTED] <at> fltk <at> <at> [EMAIL PROTECTED] <at> [EMAIL PROTECTED])<br/>fltk2.lib(ShortcutAssignment.obj) : error LNK2001: unresolved external symbol<br/>"public: void * __thiscall fltk::Widget::get(class fltk::AssociationType const<br/>&)const " ([EMAIL PROTECTED] <at> fltk <at> <at> [EMAIL PROTECTED] <at> <at> Z)<br/>fltk2.lib(ShortcutAssignment.obj) : error LNK2001: unresolved external symbol<br/>"public: void * __thiscall fltk::Widget::foreach(class fltk::AssociationType<br/>const &,class fltk::AssociationFunctor &)const " ([EMAIL<br/>PROTECTED] <at> fltk <at> <at> QBEPAXABVAssociationTy<br/>[EMAIL PROTECTED] <at> [EMAIL PROTECTED] <at> <at> Z)<br/>fltk2.lib(ShortcutAssignment.obj) : error LNK2001: unresolved external symbol<br/>"void * __cdecl fltk::foreach(class fltk::AssociationType const *,class<br/>fltk::Widget const *,class fltk::AssociationFunctor &)" ([EMAIL<br/>PROTECTED] <at> <at> [EMAIL PROTECTED] <at> P<br/>[EMAIL PROTECTED] <at> [EMAIL PROTECTED] <at> <at> Z)<br/><br/>这是因为项目VC6的fltk工程中的source中缺少了WidgetAssociation.cxx文件，因此加入即可。真是晕啊。。。。<br/><br/><br/>5) 编译出现 error C2664<br/>WidgetAssociation.cxx<br/>D:\C--Project\fltk-2.0.x-r6879\src\WidgetAssociation.cxx(315) : error C2664: 'foreach' : cannot convert parameter 1 from 'struct PrimaryAssociation *' to 'const class fltk::AssociationType *'<br/>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast<br/>D:\C--Project\fltk-2.0.x-r6879\src\WidgetAssociation.cxx(325) : error C2664: 'foreach' : cannot convert parameter 1 from 'struct PrimaryAssociation *' to 'const class fltk::AssociationType *'<br/>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast<br/>Generating Code...<br/>Error executing cl.exe.<br/><br/>将下面的修改如下即可：<br/><br/>void* fltk::foreach(const AssociationType* at, const Widget* wg,<br/>AssociationFunctor& fkt) {<br/>[...]<br/>//    return foreach(node, at, fkt);  // causes compilation errors with VS6<br/>    return ::foreach(node, at, fkt);<br/>[...]<br/>//        void * res = foreach(node, at, fkt);  // causes compilation errors with VS6<br/>        void * res = ::foreach(node, at, fkt);<br/><br/> 到现在，终于可以说是编译成功了！将test目录下的demo和编译出来的fltk2.lib进行编译生成执行程序，运行ok！<p>Copyright © 2010</p><p><a href="http://www.rtoslab.net/2010/03/201032821854.html" target="_blank">继续阅读《VC6编译fltk2错误汇总<转>》的全文内容...</a></p><p>分类: <a href="http://www.rtoslab.net/post/jade.html">他山之玉</a> | Tags: <a href="http://www.rtoslab.net/catalog.asp?tags=FLTK">FLTK</a>&nbsp;&nbsp;<a href="http://www.rtoslab.net/catalog.asp?tags=gui">gui</a>&nbsp;&nbsp;<a href="http://www.rtoslab.net/catalog.asp?tags=VC6">VC6</a>&nbsp;&nbsp; | <a href="http://www.rtoslab.net/2010/03/201032821854.html#comment" target="_blank">添加评论</a>(0)</p><h3>相关文章:</h3><ul><p><a  href="http://www.rtoslab.net/2010/03/201039172417_2888.html">FLTK编程模型<转></a>&nbsp;&nbsp;(2010-3-9 17:24:17)</p><p><a  href="http://www.rtoslab.net/2009/12/20091215233958.html">几种GUI中的图形上下文比较</a>&nbsp;&nbsp;(2009-12-15 23:39:58)</p></ul>]]></description><category>他山之玉</category><comments>http://www.rtoslab.net/2010/03/201032821854.html#comment</comments><wfw:comment>http://www.rtoslab.net/</wfw:comment><wfw:commentRss>http://www.rtoslab.net/feed.asp?cmt=75</wfw:commentRss><trackback:ping>http://www.rtoslab.net/cmd.asp?act=tb&amp;id=75&amp;key=f6a95d74</trackback:ping></item><item><title>FLTK编程模型&amp;lt;转&amp;gt;</title><author>netmuch@gmail.com (much)</author><link>http://www.rtoslab.net/2010/03/201039172417_2888.html</link><pubDate>Tue, 09 Mar 2010 17:24:17 +0800</pubDate><guid>http://www.rtoslab.net/2010/03/201039172417_2888.html</guid><description><![CDATA[<p><img height="1" width="10" alt="" src="http://www.ibm.com/i/c.gif" /></p><p>本文为转帖，来源于：http://www.ibm.com/developerworks/cn/linux/l-fltk/</p><p>&nbsp;</p><p>级别： 初级</p><p><a href="http://www.ibm.com/developerworks/cn/linux/l-fltk/#author">左锦</a> (<a href="mailto:zuo170@163.com?subject=FLTK%E7%BC%96%E7%A8%8B%E6%A8%A1%E5%9E%8B&amp;cc=">zuo170@163.com</a>)南沙资讯科技园</p><p>2003 年  5 月  10 日</p><blockquote>FLTK(Fast Light Tool Kit 发音为fulltick) 是一种使用C++开发的GUI工具包，它可以应用于Unix,Linux,MS-Windows95/98/NT/2000和MacOS操作系统平台，相 对于其它的许多图形接口开发工具包（如MFC、GTK、QT等），它具有体积很小、速度比较快，且有着更好的移植性。</blockquote><!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters -->  <!--END RESERVED FOR FUTURE USE INCLUDE FILES--><p><a href="http://www.fltk.org/">FLTK</a>(Fast Light Tool Kit 发音为fulltick) 是一种使用C++开发的GUI工具包，它可以应用于Unix，Linux，MS-Windows95/98/NT/2000和MacOS操作系统平台，相 对于其它的许多图形接口开发工具包（如MFC、GTK、QT等），它具有体积很小、速度比较快，且有着更好的移植性。本文就FLTK编程的一些基本方法进 行介绍。</p><p><a name="N1003F"><span class="atitle">FLTK功能简介</span></a></p><p>1.	提供丰富的跨平台的GUI构件(Widget)。有按钮，菜单，窗口等，近六十个。</p><p>2.	支持OpenGL，提供Fl_GL_Window，支持OpenGL相关的操作。</p><p>3.	提供界面设计工具FLUID，非常方便进行界面的设计。</p><p>4.	良好的跨平台移植性。</p><p>5.	支持多种C++编译器，Gcc，BC，VC等等。</p><p>6.	灵活性。FLTK本身可以定制，以满足不同的需要。这使得FLTK在嵌入式开发上有着极大的竞争力，这正是我要推荐使用FLTK的原因。</p><p>本文就FLTK编程的一些基本方法进行介绍。</p><p>&nbsp;</p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td><img height="1" width="100%" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" /><br />            <img height="6" border="0" width="8" alt="" src="http://www.ibm.com/i/c.gif" /></td>        </tr>    </tbody></table><table cellspacing="0" cellpadding="0" align="right" class="no-print">    <tbody>        <tr align="right">            <td><img height="4" width="100%" src="http://www.ibm.com/i/c.gif" alt="" /><br />            <table cellspacing="0" cellpadding="0" border="0">                <tbody>                    <tr>                        <td valign="middle"><img height="16" border="0" width="16" src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" /></td>                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/linux/l-fltk/#main" class="fbox"><b>回页首</b></a></td>                    </tr>                </tbody>            </table>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p><a name="N1005A"><span class="atitle">安装</span></a></p><p>安 装FLTK很简单，我们只需要下载它的源文件，解压缩到目录下，在Linux下我们只需要输入make，编译完成然后make install就头文件安装到/usr/include/FL目录下。库文件就在/usr/lib下，也可以自己编译之后把这些文件复制到这些目录，或者 不需要复制，只在编译连接的时候指定路径。</p><p>在window下可以使用VC，BC打开相应目录下的工程文件编译即可。</p><p>&nbsp;</p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td><img height="1" width="100%" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" /><br />            <img height="6" border="0" width="8" alt="" src="http://www.ibm.com/i/c.gif" /></td>        </tr>    </tbody></table><table cellspacing="0" cellpadding="0" align="right" class="no-print">    <tbody>        <tr align="right">            <td><img height="4" width="100%" src="http://www.ibm.com/i/c.gif" alt="" /><br />            <table cellspacing="0" cellpadding="0" border="0">                <tbody>                    <tr>                        <td valign="middle"><img height="16" border="0" width="16" src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" /></td>                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/linux/l-fltk/#main" class="fbox"><b>回页首</b></a></td>                    </tr>                </tbody>            </table>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p><a name="N10066"><span class="atitle">FLTK构件简介</span></a></p><p>FLTK作为GUI开发包，包含了常用的图形用户接口需要的一些构件，视觉表现非常丰富，如下两图所示：</p><p><img height="333" border="0" width="553" alt="" src="http://www.ibm.com/developerworks/cn/linux/l-fltk/images/image002.jpg" /></p><p><img height="415" border="0" width="553" alt="" src="http://www.ibm.com/developerworks/cn/linux/l-fltk/images/image004.jpg" /></p><p><b>常用按钮构件</b></p><table border="1" width="80%">    <tbody>        <tr>            <td>按钮名称</td>            <td>头文件</td>            <td>按钮名称</td>            <td>头文件</td>        </tr>        <tr>            <td>Fl_Button</td>            <td>Fl_Button.H</td>            <td>Fl_Check_Button</td>            <td>Fl_Check_Button.H</td>        </tr>        <tr>            <td>Fl_Light_Button</td>            <td>Fl_Light_Button.H</td>            <td>Fl_Repeat_Button</td>            <td>Fl_Repeat_Button.H</td>        </tr>        <tr>            <td>Fl_Return_Button</td>            <td>Fl_Return_Button.H</td>            <td>Fl_Round_Button</td>            <td>Fl_Round_Button.H</td>        </tr>    </tbody></table><p>对于具有Fl_Check_Button、Fl_Loght_Button和Fl_Round_Button当状态为off时value() =0 ，On时value()返回1。</p><p>处理按钮时间可以使用回调(callback)函数,参见后面的事件处理。</p><p><b>文本处理构件</b></p><table border="1" width="80%">    <tbody>        <tr>            <td>构件名称</td>            <td>头文件</td>            <td>构件名称</td>            <td>头文件</td>        </tr>        <tr>            <td>Fl_Input</td>            <td>Fl_Input.H</td>            <td>Fl_Output</td>            <td>Fl_Output.H</td>        </tr>        <tr>            <td>Fl_Multiline_Input</td>            <td>Fl_Multiline_Input.H</td>            <td>Fl_Multiline_output</td>            <td>Fl_Multiline_output.H</td>        </tr>    </tbody></table><p>设置和取得文本内容使用value();</p><p>如：</p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td class="code-outline">            <pre class="displaycode">(new  Fl_Input(x,y,width,height,&quot;Label&quot;))-&gt;value(&quot;Hello World!&quot;);</pre>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p><b>其他构件</b></p><p>参见FLTK.org的         <a href="http://www.fltk.org/documentation.php">文档</a>说明。</p><p>这些构件是使用C++开发的，具有完善的继承关系，下面是构件继承关系图</p><p><img height="478" border="0" width="319" alt="" src="http://www.ibm.com/developerworks/cn/linux/l-fltk/images/image005.jpg" /></p><p><img height="413" border="0" width="307" alt="" src="http://www.ibm.com/developerworks/cn/linux/l-fltk/images/image006.jpg" /></p><p>构件使用例子－HelloWorld</p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td class="code-outline">            <pre class="displaycode">#include &lt;FL/Fl.H&gt;#include &lt;FL/Fl_Window.H&gt;#include &lt;FL/Fl_Box.H&gt;int  main (int argc, char *argv[]){    Fl_Window  *window;    Fl_Box  *box;window  =  new  Fl_Window (300, 180);window-&gt; label(&quot;HelloWorld!&quot;);   //添加window的标题    box  =  new Fl_Box (20, 40, 260, 100, &quot;Hello World!&quot;);    box-&gt;box (FL_UP_BOX);    box-&gt;labelsize (36);    box-&gt;labelfont (FL_BOLD+FL_ITALIC);  //设置字体box-&gt;labeltype (FL_SHADOW_LABEL);  //设置label的类型/***************************************************************进入FLTK的事件循环处理过程***************************************************************/    window-&gt;end ();    window-&gt;show (argc, argv);    return  Fl::run();}</pre>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p>在window下程序编译运行后如图所示：[使用VC6编译优化后大小为116K]</p><p><img height="205" border="0" width="306" alt="" src="http://www.ibm.com/developerworks/cn/linux/l-fltk/images/image007.jpg" /></p><p>Linux下图片[编译未优化大小358K]</p><p><img height="206" border="0" width="312" alt="" src="http://www.ibm.com/developerworks/cn/linux/l-fltk/images/image008.png" /></p><p>&nbsp;</p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td><img height="1" width="100%" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" /><br />            <img height="6" border="0" width="8" alt="" src="http://www.ibm.com/i/c.gif" /></td>        </tr>    </tbody></table><table cellspacing="0" cellpadding="0" align="right" class="no-print">    <tbody>        <tr align="right">            <td><img height="4" width="100%" src="http://www.ibm.com/i/c.gif" alt="" /><br />            <table cellspacing="0" cellpadding="0" border="0">                <tbody>                    <tr>                        <td valign="middle"><img height="16" border="0" width="16" src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" /></td>                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/linux/l-fltk/#main" class="fbox"><b>回页首</b></a></td>                    </tr>                </tbody>            </table>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p><a name="N10163"><span class="atitle">FLTK事件处理</span></a></p><p>对于一般构件的如按钮，菜单等常用事件的处理一般可以使用回调函数实现，回调函数的原型是：</p><pre>void  XXX_callback( Fl_Widget *w,void *data ){//添加自己处理的内容}</pre><p>使用F1_Widget-&gt;callback( XXX_callback,data) 注册回调函数</p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td class="code-outline">            <pre class="displaycode">/***************************************************************按钮事件例子***************************************************************/#include &lt;FL/Fl.H&gt;#include &lt;FL/Fl_Window.H&gt;#include &lt;FL/Fl_Button.H&gt;#include &lt;FL/Fl_ask.H&gt;void Btn01_cb(Fl_Widget *w,void *data){ ((Fl_Button *)w)-&gt;label((char *)data);fl_alert(&quot;Hello&quot;); }int main(int argc, char **argv) { char *buff =&quot;Hello&quot;; Fl_Window* w = new Fl_Window(272, 144); Fl_Button* Btn01 = new Fl_Button(85, 50, 105, 25, &quot;&amp;Test callback&quot;); Btn01-&gt;shortcut(FL_ALT+'t');               //定义按钮的快捷键 Btn01-&gt;callback((Fl_Callback*)Btn01_cb,buff); //调用处理函数 buff作为参数  w-&gt;end(); w-&gt;show(argc, argv);  return Fl::run();}</pre>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p>编译运行程序，鼠标点击按钮，按钮标签会发生改变，并且会弹出提示框。</p><p>通常的callback是当构件的value改变时调用，可以使用when()改变为其他事件发生调用回调函数，主要事件有以下事件</p><table border="1" width="80%">    <tbody>        <tr>            <td>事件</td>            <td>说明</td>        </tr>        <tr>            <td>FL_WHEN_NERVER</td>            <td>从不调用回调函数</td>        </tr>        <tr>            <td>FL_WHEN_CHANGED</td>            <td>当构件值改变时调用</td>        </tr>        <tr>            <td>FL_WHEN_RELEASE</td>            <td>当释放按键或者鼠标并且构件值改变</td>        </tr>        <tr>            <td>FL_WHEN_RELEASE_ALWAYS</td>            <td>当释放按键或者鼠标，即使构件值没有改变</td>        </tr>        <tr>            <td>FL_WHEN_ENTER_KEY</td>            <td>按下Enter键并且构件值改变</td>        </tr>        <tr>            <td>FL_WHEN_ENTER_KEY_ALWAYS</td>            <td>按下Enter键，即使构件值没有改变</td>        </tr>    </tbody></table><p>通过使用F1_Widget-&gt;when(FL_WHEN_XXXX)来改变回调事件。</p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td class="code-outline">            <pre class="displaycode">#include &lt;FL/Fl.H&gt;#include &lt;FL/Fl_Window.H&gt;#include &lt;FL/Fl_Button.H&gt;#include &lt;FL/Fl_ask.H&gt;void Btn01_cb(Fl_Widget *w, void *data){  fl_alert(&quot;Hello&quot;); }int main(int argc, char **argv) { char *buff = &quot;Hello&quot;; Fl_Window* w = new Fl_Window(272, 144); Fl_Button* Btn01 = new Fl_Button(85, 50, 105, 25, &quot;&amp;Test callback&quot;); Btn01-&gt;shortcut(FL_ALT + 't'); Btn01-&gt;callback((Fl_Callback*) Btn01_cb, buff); Btn01-&gt;when(FL_WHEN_RELEASE_ALWAYS); w-&gt;end(); w-&gt;show(argc,  argv);  return Fl::run();}</pre>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p>编译运行程序，在按钮上按下鼠标左键，移动到按钮外，松开鼠标按键，仍然会弹出对话框，对比上面的两程序，看看有什么不同。</p><p>&nbsp;</p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td><img height="1" width="100%" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" /><br />            <img height="6" border="0" width="8" alt="" src="http://www.ibm.com/i/c.gif" /></td>        </tr>    </tbody></table><table cellspacing="0" cellpadding="0" align="right" class="no-print">    <tbody>        <tr align="right">            <td><img height="4" width="100%" src="http://www.ibm.com/i/c.gif" alt="" /><br />            <table cellspacing="0" cellpadding="0" border="0">                <tbody>                    <tr>                        <td valign="middle"><img height="16" border="0" width="16" src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" /></td>                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/linux/l-fltk/#main" class="fbox"><b>回页首</b></a></td>                    </tr>                </tbody>            </table>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p><a name="N101CA"><span class="atitle">FLTK消息处理</span></a></p><p>在FLTK中是通过Fl_Widegt::handle(),虚拟函数来处理系统的消息。我们可以查看Fltk的源代码来分析系统是怎样处理一些系统消息的，如按钮的消息处理</p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td class="code-outline">            <pre class="displaycode">/*******************************************************Fl_Button中处理消息的代码，省略了具体的处理代码*******************************************************/int Fl_Button::handle(int event) {switch (event) {case FL_ENTER:case FL_LEAVE:     return 1;case FL_PUSH:         &hellip;&hellip;case FL_DRAG:        &hellip;&hellip;case FL_RELEASE:     &hellip;&hellip;case FL_SHORTCUT:   &hellip;&hellip;case FL_FOCUS :       &hellip;&hellip;case FL_UNFOCUS :    &hellip;&hellip;case FL_KEYBOARD :  &hellip;&hellip;default:return 0;}}</pre>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p>可以看出了，系统的一些消息，都是在构件的handle()中进行处理的。</p><p>系统的主要消息有以下</p><table border="1" width="80%">    <tbody>        <tr>            <td>鼠标事件消息</td>            <td>焦点事件消息</td>        </tr>        <tr>            <td>FL_PUSH</td>            <td>FL_ENTER</td>        </tr>        <tr>            <td>FL_DRAG</td>            <td>FL_LEAVE</td>        </tr>        <tr>            <td>FL_RELEASE</td>            <td>FL_FOCUS</td>        </tr>        <tr>            <td>FL_MOVE</td>            <td>FL_UNFOCUS</td>        </tr>        <tr>            <td>键盘事件消息</td>            <td>剪贴板事件消息</td>        </tr>        <tr>            <td>FL_KEYBOARD</td>            <td>FL_PASTE</td>        </tr>        <tr>            <td>FL_SHORTCUT</td>            <td>FL_SELECTIONCLEAR</td>        </tr>        <tr>            <td>　</td>            <td>构件事件消息</td>        </tr>        <tr>            <td>FL_DEACTIVATE</td>            <td>FL_ACTIVE</td>        </tr>        <tr>            <td>FL_HIDE</td>            <td>FL_SHOW</td>        </tr>    </tbody></table><p>通过重载handle函数我们可扩充标准构件，下面是一个鼠标移动到上面就改变颜色的按钮的实现源代码。</p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td class="code-outline">            <pre class="displaycode">#include &lt;FL/Fl.H&gt;#include &lt;FL/Fl_Window.H&gt;#include &lt;FL/Fl_Button.H&gt;#include &lt;FL/fl_ask.H&gt; class EnterButton : public Fl_Button {  int handle(int e) {  switch (e)   {      case  FL_ENTER:              color(FL_GREEN);              labelsize(18); redraw();               return 1;      case   FL_LEAVE:             color(FL_GRAY);             labelsize(18); redraw();              return 1;       default:            return Fl_Button::handle(e);         }}public:  EnterButton(int  x,  int y,  int w, int  h, const char  *l )                         : Fl_Button(x,y,w,h,l) {   }};static void  cb(Fl_Widget* s,  void *data){  fl_alert( &quot;Hello World!&quot; );}int main(int argc, char **argv) {      Fl_Window* w  =  new  Fl_Window(130, 50);      EnterButton *eBtn  =  new  EnterButton(25,50,120,25,&quot;HelloWorld&quot;);      eBtn-&gt;callback((Fl_Callback*)cb);      w-&gt;end();      w-&gt;show(argc, argv);      return Fl::run();}</pre>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p>运行显示效果如图:</p><p><img height="50" border="0" width="130" alt="" src="http://www.ibm.com/developerworks/cn/linux/l-fltk/images/image010.jpg" />         <img height="50" border="0" width="130" alt="" src="http://www.ibm.com/developerworks/cn/linux/l-fltk/images/image011.jpg" /></p><p>Linux下演示[截屏时鼠标没有取到]</p><p><img height="76" border="0" width="142" alt="" src="http://www.ibm.com/developerworks/cn/linux/l-fltk/images/image013.jpg" />         <img height="74" border="0" width="134" alt="" src="http://www.ibm.com/developerworks/cn/linux/l-fltk/images/image015.jpg" /></p><p>&nbsp;</p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td><img height="1" width="100%" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" /><br />            <img height="6" border="0" width="8" alt="" src="http://www.ibm.com/i/c.gif" /></td>        </tr>    </tbody></table><table cellspacing="0" cellpadding="0" align="right" class="no-print">    <tbody>        <tr align="right">            <td><img height="4" width="100%" src="http://www.ibm.com/i/c.gif" alt="" /><br />            <table cellspacing="0" cellpadding="0" border="0">                <tbody>                    <tr>                        <td valign="middle"><img height="16" border="0" width="16" src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" /></td>                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/linux/l-fltk/#main" class="fbox"><b>回页首</b></a></td>                    </tr>                </tbody>            </table>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p><a name="N10278"><span class="atitle">FLUID简介</span></a></p><p>FLUID （FLTK UserInteface Designer）是FLTK进行程序界面设计的有力工具，如同GTK界面开发工具Glade一样。</p><p>它包含在FLTK源代码中，需要自己编译成可执行文件。在Window平台可以使用VC/BC编译成可执行文件。启动和设计时界面如图所示：</p><p><img height="342" border="0" width="517" alt="" src="http://www.ibm.com/developerworks/cn/linux/l-fltk/images/image017.jpg" /></p><p><img height="351" border="0" width="529" alt="" src="http://www.ibm.com/developerworks/cn/linux/l-fltk/images/image019.jpg" /></p><p>Fluid 非常容易使用，首先是新建,输入文件名，后点Bin 窗口的Function 图标，建立main主函数[清空name就可以]，然后可以选择window 图标，建立窗口，然后拖放其他构件，可以在双击构件设置构件的属性【如下图】，在GUI属性页中设置标签和快捷键，位置大小，图片，提示，对齐方式等，在 style中设置它的显示风格等，在C++中设置名字，书写它的回调函数等。</p><p><img height="418" border="0" width="391" alt="" src="http://www.ibm.com/developerworks/cn/linux/l-fltk/images/image020.jpg" /></p><p>设计好界面后，我们可以把这些转换为C++源代码，选菜单File中的write Code即可，使用编辑器可以打开与工程同名的源文件和头文件，怎么做，不再赘述。</p><p>&nbsp;</p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td><img height="1" width="100%" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" /><br />            <img height="6" border="0" width="8" alt="" src="http://www.ibm.com/i/c.gif" /></td>        </tr>    </tbody></table><table cellspacing="0" cellpadding="0" align="right" class="no-print">    <tbody>        <tr align="right">            <td><img height="4" width="100%" src="http://www.ibm.com/i/c.gif" alt="" /><br />            <table cellspacing="0" cellpadding="0" border="0">                <tbody>                    <tr>                        <td valign="middle"><img height="16" border="0" width="16" src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" /></td>                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/linux/l-fltk/#main" class="fbox"><b>回页首</b></a></td>                    </tr>                </tbody>            </table>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p><a name="N102AE"><span class="atitle">OpenGL编程</span></a></p><p>在FLTK中很容易使用OpenGL进行图形编程的，我们只需要使用它的Fl_Gl_Window构件，重新定义一个派生于Fl_Gl_Window的类，重载draw()和handle()就可以。所需要的代码和步骤如下：</p><p><b>包含以下头文件</b></p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td class="code-outline">            <pre class="displaycode">#include &lt;FL/Fl.H&gt;#include &lt;FL/gl.h&gt;#include &lt;FL/Fl_Gl_Window.H&gt;</pre>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p><b>定义一个子类，如下代码所示</b></p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td class="code-outline">            <pre class="displaycode">class MYGLWindow : public Fl_Gl_Window{	void draw(); //作图操作    void handle( int ); //消息事件处理	public : 		MYGLWindow(int x,int y,int w,int h,const char *L) : Fl_Gl_Window(x,y,w,h,L){};<!-- code sample is too wide -->};</pre>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p><b>实现draw()事件</b></p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td class="code-outline">            <pre class="displaycode">void MYGLWindow::draw() //作图{	if ( ! valid() )		{          //设置viewport窗口大小等等 例如        /********************************************** valid(1);        glLoadIdentity();        glViewport(0,0,w(),h());        ***********************************************/		}	   //添加使用OPENGL作图操作 	  /* &hellip;&hellip;..*/};</pre>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p><b>事件处理实现</b></p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td class="code-outline">            <pre class="displaycode">void MYGLWindow::handle( int event) //事件处理{  switch (event) {  case FL_PUSH :  //操作等                return 1;    case &hellip;&hellip;.}}</pre>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p><b>注意</b></p><p>1.	编译时需要包含openGL32的库文件，名字在不同的平台名字稍微不同。</p><p>2.	使用&lt;FL/gl.h&gt;代替&lt;GL/gl.h&gt;头文件，不要使用后者的头文件。</p><p>例子程序比较长，附在参考中。运行显示，弹出菜单后如图所示：</p><p><img height="288" border="0" width="288" alt="" src="http://www.ibm.com/developerworks/cn/linux/l-fltk/images/image022.jpg" /></p><p>&nbsp;</p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td><img height="1" width="100%" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" /><br />            <img height="6" border="0" width="8" alt="" src="http://www.ibm.com/i/c.gif" /></td>        </tr>    </tbody></table><table cellspacing="0" cellpadding="0" align="right" class="no-print">    <tbody>        <tr align="right">            <td><img height="4" width="100%" src="http://www.ibm.com/i/c.gif" alt="" /><br />            <table cellspacing="0" cellpadding="0" border="0">                <tbody>                    <tr>                        <td valign="middle"><img height="16" border="0" width="16" src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" /></td>                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/linux/l-fltk/#main" class="fbox"><b>回页首</b></a></td>                    </tr>                </tbody>            </table>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p><a name="N102FA"><span class="atitle">VC中使用FLTK</span></a></p><p>在Vc中无法直接使用FLTK，需要下载FLTK的源文件编译之后再进行一些简单的设置，设置步骤如下：</p><p>1.	打开Project-&gt;Settings-&gt;Link, 添加以下库文件:         <br />wsock32.lib opengl32.lib glu32.lib fltk.lib fltkgl.lib          <br />[fltk.lib fltkgl.lib 需要自己编译FLTK源文件生成,直接打开源文件下的visualc目录下的工程文件就可以编译]</p><p>2.	在Project-&gt;Settings-&gt;Link的PROJECT OPTIONS中 添加 /nodefaultlib:&quot;LIBCD&quot;，如果你要生成release版本的那么是 /nodefaultlib:&quot;LIBC&quot;</p><p>3.	在Tools-&gt;Options-&gt;Directories, 选择 include files  添加路径如         <br />C:\Program Files\fltk   [对照自己的修改]</p><p>4.	在Tools-&gt;Options-&gt;Directories, 选择 library files 设定为如下所示         <br />C:\Program Files\fltk\lib [对照自己的修改]</p><p>5.	Project-&gt;Settings-&gt;C/C++ 中的category 选择 C++ Language</p><p>6.	在Project-&gt;Settings-&gt;C/C++,的PROJECT OPTIONS添加:         <br />/I &quot;c:\program files\fltk&quot;  [对照修改]，此处不修改也可以编译</p><p>&nbsp;</p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td><img height="1" width="100%" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" /><br />            <img height="6" border="0" width="8" alt="" src="http://www.ibm.com/i/c.gif" /></td>        </tr>    </tbody></table><table cellspacing="0" cellpadding="0" align="right" class="no-print">    <tbody>        <tr align="right">            <td><img height="4" width="100%" src="http://www.ibm.com/i/c.gif" alt="" /><br />            <table cellspacing="0" cellpadding="0" border="0">                <tbody>                    <tr>                        <td valign="middle"><img height="16" border="0" width="16" src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" /></td>                        <td valign="top" align="right"><a href="http://www.ibm.com/developerworks/cn/linux/l-fltk/#main" class="fbox"><b>回页首</b></a></td>                    </tr>                </tbody>            </table>            </td>        </tr>    </tbody></table><p>&nbsp;</p><p><a name="N1031F"><span class="atitle">KDevelop中使用FLTK</span></a></p><p>作为跨平台的一种轻量级的GUI Tools，在Linux下得到更为广泛的使用，所以我们使用Linux下的最常用的Kdevelop也能很方便使用它。下面简述需要注意的配置步骤：</p><p>1.	我们建立C++工程后，需要修改的配置都在菜单[项目]--&gt;[选项]'[连接器选项]中修改</p><p>2.	在[库]中选定 X11和Xext，根据自己的需要还需要选定 math等库</p><p>3.	在[附加库]那里输入 -L/usr/X11R6/lib -lfltk</p><p>4.	如果开发OpenGL应用需要 在附加库中输入 -lfltk_gl -lglut 指定连接库。</p><p><img height="343" border="0" width="533" alt="" src="http://www.ibm.com/developerworks/cn/linux/l-fltk/images/image024.jpg" /></p><p>提示：因为我使用的Linux为RedHat 8,为选择中文环境，所以配置说明也是中文，英文版本可能有所不同，对照修改即可.</p><p>&nbsp;</p><p><a name="resources"><span class="atitle">参考资料 </span></a></p><p>1.	想了解更多的FLTK的知识和下载FLTK源代码等可以到         <a href="http://www.fltk.org/">www.fltk.org</a> 网站。         <a href="http://www.fltk.org/documentation.php">FLTK的编程手册</a>你想了解FLTK构件的事件方法等都在里面。OpenGL</p><p>2.	还是参考一下         <a href="http://www.opengl.org/">www.opengl.org</a>上的资料吧，有文档说明还有教学和源代码。</p><p>&nbsp;</p><p><a name="author"><span class="atitle">关于作者</span></a></p><table cellspacing="0" cellpadding="0" border="0" width="100%">    <tbody>        <tr>            <td colspan="3"><img height="5" width="100%" alt="" src="http://www.ibm.com/i/c.gif" /></td>        </tr>        <tr valign="top" align="left">            <td>&nbsp;</td>            <td><img height="5" width="4" alt="" src="http://www.ibm.com/i/c.gif" /></td>            <td width="100%">            <p>左锦，就职南沙资讯科技园，喜爱 Linux，Java 还有蓝天白云青山绿水。通过         <a href="mailto:zuo170@163.com?cc=">zuo170@163.com</a>和他联系。</p>            </td>        </tr>    </tbody></table><p>Copyright © 2010</p><p><a href="http://www.rtoslab.net/2010/03/201039172417_2888.html" target="_blank">继续阅读《FLTK编程模型<转>》的全文内容...</a></p><p>分类: <a href="http://www.rtoslab.net/post/jade.html">他山之玉</a> | Tags: <a href="http://www.rtoslab.net/catalog.asp?tags=FLTK">FLTK</a>&nbsp;&nbsp;<a href="http://www.rtoslab.net/catalog.asp?tags=gui">gui</a>&nbsp;&nbsp; | <a href="http://www.rtoslab.net/2010/03/201039172417_2888.html#comment" target="_blank">添加评论</a>(0)</p><h3>相关文章:</h3><ul><p><a  href="http://www.rtoslab.net/2010/03/201032821854.html">VC6编译fltk2错误汇总<转></a>&nbsp;&nbsp;(2010-3-28 21:8:54)</p><p><a  href="http://www.rtoslab.net/2009/12/20091215233958.html">几种GUI中的图形上下文比较</a>&nbsp;&nbsp;(2009-12-15 23:39:58)</p></ul>]]></description><category>他山之玉</category><comments>http://www.rtoslab.net/2010/03/201039172417_2888.html#comment</comments><wfw:comment>http://www.rtoslab.net/</wfw:comment><wfw:commentRss>http://www.rtoslab.net/feed.asp?cmt=74</wfw:commentRss><trackback:ping>http://www.rtoslab.net/cmd.asp?act=tb&amp;id=74&amp;key=2c4342d6</trackback:ping></item><item><title>Tcl on VxWorks(出自Tcl.tk的wiki)</title><author>netmuch@gmail.com (much)</author><link>http://www.rtoslab.net/2010/01/2010118202243.html</link><pubDate>Mon, 18 Jan 2010 20:22:43 +0800</pubDate><guid>http://www.rtoslab.net/2010/01/2010118202243.html</guid><description><![CDATA[<h2>文章为转载，出处为<a target="_blank" href="http://wiki.tcl.tk/21062">tcl官方网站的wiki</a></h2><p>&nbsp;</p><p>This file is far from being a readily mergeable patch -- see some of the ugly technical details below -- but it should get someone started who is desperate to run Tcl on VxWorks.These instructions will result in a Tcl DKM (downloadable kernel module) that can be run and interacted with on the console. Running as a VxWorks RTP (real-time process) mode is not supported, although that should be a comparatively small step.</p><hr /><div class="centered"><h2 id="pagetoce288c788">Building Tcl for VxWorks</h2></div><hr /><p>These instructions are for a cross-build from</p><p><a href="http://wiki.tcl.tk/4473">Microsoft Windows</a></p><p>to, for reference, the &quot;SIMNTgnu&quot; target (which is the Windows-based VxWorks simulator that comes with Workbench) from the</p><p><a href="http://wiki.tcl.tk/1866">Cygwin</a></p><p>command line.  For other targets, update the tools and their parameters accordingly (e.g., use the</p><p><i>ccppc</i></p><p>compiler instead of</p><p><i>ccpentium</i></p><p>for PowerPC targets).</p><h3 id="pagetoc27f0a796">Apply VxWorks Patch</h3><p>Download the Tcl 8.5.2 source code.Download the patch:</p><p><a rel="nofollow" href="http://sourceforge.net/tracker/download.php?group_id=10894&amp;atid=360894&amp;file_id=276425&amp;aid=1955146">http://sourceforge.net/tracker/download.php?group_id=10894&amp;atid=360894&amp;file_id=276425&amp;aid=1955146</a></p><p>(this is a plain-text file).Apply the patch to the Tcl 8.5.2 source code using the &quot;patch&quot; program.</p><h3 id="pagetoc6dea177d">Configure for SIMNTgnu</h3><p>Some of these settings must be adjusted based on your target.</p><pre>  export WIND_BASE=&quot;c:\\WindRiver\\vxworks-6.3&quot;  export CC=&quot;ccpentium&quot;  export CPPFLAGS=&quot;-D_WRS_KERNEL -DCPU=SIMNT -DTOOL_FAMILY=gnu -DTOOL=gnu -Ic:/WindRiver/vxworks-6.3/target/h -Ic:/WindRiver/vxworks-6.3/target/h/wrn/coreip -DUSE_FIONBIO&quot;  export CFLAGS=&quot;-mtune=i486 -march=i486 -ansi&quot;  export LDFLAGS=&quot;-r -nostdlib&quot;  export EXTRA_TCLSH_LIBS=&quot;-Wl,-X -T `cygpath --mixed ${WIND_BASE}/target/h/tool/gnu/ldscripts/link.OUT`&quot;  export DL_OBJS=&quot;tclLoadVxWorks.o&quot;  export SHLIB_SUFFIX=&quot;.out&quot;  export SHLIB_LD=&quot;ccpentium -r -nostdlib&quot;  export SHLIB_LD_LIBS=&quot;-Wl,-X -T `cygpath --mixed ${WIND_BASE}/target/h/tool/gnu/ldscripts/link.OUT`&quot;  export AR=&quot;arpentium&quot;  export ac_cv_c_bigendian=no</pre><h3 id="pagetoc18301c34">Generic Configuration</h3><p>These settings are to convince the</p><p><i>configure</i></p><p>script of the existence of various VxWorks functionality, rather than determining the host's functionality.</p><pre> export ac_cv_func_memcmp_clean=yes export ac_cv_func_strtoll=no export ac_cv_func_strtoull=no export ac_cv_func_strncasecmp=no export ac_cv_func_realpath=no export ac_cv_func_uname=no export ac_cv_func_gethostbyname_r=no export ac_cv_func_gethostbyaddr_r=no export tcl_cv_strstr_unbroken=ok export tcl_cv_strtoul_unbroken=ok export tcl_cv_strtod_unbroken=ok export tcl_cv_strtod_buggy=ok export tcl_cv_timezone_long=no export tcl_cv_timezone_time=no export tcl_cv_putenv_copy=yes export ac_cv_lib_pthread_pthread_mutex_init=yes export no_pipe=yes</pre><h3 id="pagetoc86a9edcf">Run Configure</h3><p>Now run the autoconf script:</p><pre> ./configure --enable-threads --disable-shared --enable-symbols --host=vxworksdkm</pre><h3 id="pagetoc88843d01">Fix Makefiles for Cygwin</h3><p>When building on Windows using Cygwin, the Makefile needs to be hacked so that</p><p><i>make</i></p><p>sees cygwin-style paths while the compiler sees Windows-style paths:</p><pre> sed -e 's/\$(CC)\(.*\)\(\$[A-Za-z0-9_./()]*\)$/$(CC)\1\`cygpath --windows \2\`/' &lt; Makefile &gt; Makefile.1 sed -e 's/-I\(\${[A-Z_]*}\)/-I\`cygpath --windows \1\`/g' &lt; Makefile.1 &gt; Makefile.2 sed -e 's%-L/cygdrive/\(.\)\(/[A-Za-z0-9._/]*\)%-L\1:\2%g' &lt; Makefile.2 &gt; Makefile.3 sed -e 's%\t\t\(\$(GENERIC_DIR)/tclPkgConfig.c\)%\t\t\`cygpath --windows \1\`%' &lt; Makefile.3 &gt; Makefile.4 sed -e 's%\t\t\(\$(UNIX_DIR)/tclUnixInit.c\)%\t\t\`cygpath --windows \1\`%' &lt; Makefile.4 &gt; Makefile.5</pre><p>This shouldn't be necessary for a cross-build from Unix.</p><h3 id="pagetoc8fd94107">Build</h3><p>After all of the above, Tcl should build fine.  On Windows, use the hacked</p><p><i>Makefile.5</i></p><p>(see above).This should result in the loadable module</p><p><b>tclsh.out</b></p><p>.</p><hr /><div class="centered"><h2 id="pagetoc39382f82">Using Tcl</h2></div><hr /><p>In the VxWorks</p><p><a href="http://wiki.tcl.tk/1387">C</a></p><p>interpreter, load the Tcl DKM built above -- assumed to be in the</p><p><i>/tcl</i></p><p>directory, adjust as necessary -- using</p><pre> ld &lt; /tcl/tclsh.out</pre><p>Before starting Tcl, the</p><p><i>pre-init</i></p><p>script must be set to configure Tcl's library path, e.g., by running the following command in the VxWorks C interpreter:</p><pre> TclSetPreInitScript (&quot;set ::tclDefaultLibrary /tcl/library&quot;);</pre><p>Note: if this step omitted, then Tcl will fail, complaining that it can not find the</p><p><i>init.tcl</i></p><p>file.  Then it will crash.The Tcl module provides two entry points that can be called from the C interpreter:</p><dl><dt><tt>tcl</tt></dt><dd>Enters an interactive Tcl shell session.  Line editing and history follows the usual VxWorks rules.  Use <tt>shellConfigSet INTERPRETER=C</tt> to return to the C interpreter. Tcl interpreter state is preserved when switching in and out of the interactive session. Ctrl-C can be used to restart the interpreter (at which point state is lost).</dd><dt><tt>tclsh <i>file</i></tt></dt><dd>This executes the contents of <i>file</i> in a new Tcl interpreter (no state is shared with other sessions).</dd></dl><hr /><div class="centered"><h2 id="pagetocedbe8b2c">Tcl Extensions</h2></div><hr /><p>The following VxWorks-specific commands are available:</p><h3 id="pagetoc092637eb">shellConfigSet</h3><p>Usage:</p><pre> shellConfigSet config</pre><p>This calls</p><p><tt>shellConfigSet (CURRENT_SHELL_SESSION, <i>config</i>)</tt></p><p>.The primary purpose of this command is to switch back from an interactive Tcl session to the C interpreter using</p><p><tt>shellConfigSet INTERPRETER=C</tt></p><p>.  See the</p><p><tt>shellLib</tt></p><p>documentation for more information.</p><h3 id="pagetoc049c166e">shellEvaluate</h3><p>Usage:</p><pre> shellEvaluate cmd ?interpreter?</pre><p>This evaluates</p><p><i>cmd</i></p><p>in</p><p><i>interpreter</i></p><p>and returns the result.  If omitted,</p><p><i>interpreter</i></p><p>defaults to</p><p><tt>C</tt></p><p>.See the documentation for</p><p><tt>shellInterpEvaluate()</tt></p><p>for more information.Only integer-type return values are supported.  While</p><p><tt>shellInterpEvaluate()</tt></p><p>appears to return the polymorphic type</p><p><tt>SHELL_EVAL_VALUE</tt></p><p>, it is not documented, and I have not seen its</p><p><tt>type</tt></p><p>field be anything else than</p><p><tt>SHELL_INT</tt></p><p>.</p><h3 id="pagetoc9abd2f80">shellExec</h3><p>Usage:</p><pre> shellExec cmd ?interpreter?</pre><p>This evaluates</p><p><i>cmd</i></p><p>in</p><p><i>interpreter</i></p><p>and returns the output, similar to capturing a process' standard output.  If omitted,</p><p><i>interpreter</i></p><p>defaults to</p><p><tt>C</tt></p><p>.The shell echoes commands as they are interpreted, so</p><p><tt>cmd</tt></p><p>is included in the output. The C shell also prints the value that each individual command evaluates to. So some post-processing of the returned value is necessary.A new interpreter session is created, which has its working directory initialized to some default, rather than inheriting Tcl's working directory.</p><p><i>cmd</i></p><p>should use absolute file names or change to the desired directory before accessing any files.This command may hang if</p><p><i>cmd</i></p><p>attempts to read from the console.</p><h3 id="pagetoc723f4d1e">exit</h3><p>The</p><p><tt>exit</tt></p><p>command is replaced to delete the current interpreter rather than exiting from the process -- the latter would make Tcl unusable. If this happens at an inopportune time, the error &quot;eval called on a deleted interpreter&quot; may occur. This is harmless, but Tcl should be modified to avoid this error.If</p><p><tt>exit</tt></p><p>is used in an interactive session, the current Tcl interpreter is deleted, and the session is returned to the C interpreter. When</p><p><tt>tcl</tt></p><p>is called again, a new Tcl interpreter session is started.</p><hr /><div class="centered"><h2 id="pagetoc0e50e585">BSP Features</h2></div><hr /><p>For reference, I needed to enable the following features in the kernel configurator beyond the &quot;default&quot;:</p><ul>    <li>INCLUDE_GETADDRINFO</li>    <li>INCLUDE_GETIFADDRS</li>    <li>INCLUDE_GETNAMEINFO</li>    <li>INCLUDE_GETNAMEINFO_SYSCTL</li>    <li>INCLUDE_GETSERVBYNAME</li>    <li>INCLUDE_STRICMP</li></ul><hr /><div class="centered"><h2 id="pagetoc98e9b44b">Tcl Features</h2></div><hr /><p>Loadable Tcl modules must be built as DKMs, and should be stub-enabled.Sorry, no threads yet.No pipes or</p><p><a href="http://wiki.tcl.tk/1039">exec</a></p><p>.</p><hr /><div class="centered"><h2 id="pagetoc00bf0aed">The Gory Details</h2></div><hr /><p>Here are some implementation details of the VxWorks port:</p><ul>    <li>For better or worse, the patch modifies Tcl's <tt>unix</tt> port rather than creating a separate <tt>vxworks</tt> port.  That kept the patch smaller, but makes it impossible to merge.</li>    <li>The patch does not make use of some the POSIX APIs that were added in more recent versions of VxWorks, but instead uses the legacy APIs.</li>    <li>When <tt>TclpObjAccess()</tt> is called with an <tt>R_OK</tt> (is the file readable?) parameter, it is replaced with a check for <tt>F_OK</tt> (does the file exist?).  VxWorks' <tt>access(...,R_OK)</tt> erroneously returned false for files on NFS-mounted volumes even though they were readable.  This means that <tt><a href="http://wiki.tcl.tk/1041">file</a> readable</tt> may now return a false positive in some cases.</li>    <li>The probably greatest hack is the use of the event-based rather than the threaded notifier. The major reason is that VxWorks does not have anonymous pipes (the <tt>pipe()</tt> system call) that the threaded notifier uses. VxWorks does have named pipes which could be used instead, but I did not get around to implementing that. So far, the event-based notifier seems to hold up well even when multiple threads are running. However, given that I don't understand all the details, I can't guarantee that this won't cause issues in more complex applications.</li>    <li>In VxWorks DKM mode, everything runs as tasks (threads) in the kernel &quot;process&quot;.  Calling <tt>exit()</tt> is therefore not possible.  <tt>Tcl_Exit()</tt> calls <tt>Tcl_Finalize()</tt>, which renders the Tcl state unusable for other threads.  <tt>Tcl_SetExitProc()</tt> was not an option since it is expected to not return.  Therefore the patch overload's Tcl's <a href="http://wiki.tcl.tk/1040">exit</a> command to delete the current interpreter instead. That seems to work for the most part, except for a few places where Tcl kept calling <tt>Tcl_Eval()</tt> without checking for interpreter deletion first -- so I added the appropriate checks in the places that I came across.</li>    <li>VxWorks has no timezone, user id, group id, or <tt>/etc/passwd</tt>, so those features are commented out. Note that many VxWorks systems do not have real-time clocks, so unless the time is explicitly set (e.g., using <a href="http://wiki.tcl.tk/3391">Network Time Protocol - NTP</a>), the clock starts at zero.</li>    <li>I shied away from implementing threads so far, because they depend on <tt>pthread_exit()</tt>.  Its equivalent in the VxWorks legacy API, <tt>taskDelete()</tt>, does not clean up resources that the thread was using, and might thus cause memory leaks and other issues.</li></ul><p>Copyright © 2010</p><p><a href="http://www.rtoslab.net/2010/01/2010118202243.html" target="_blank">继续阅读《Tcl on VxWorks(出自Tcl.tk的wiki)》的全文内容...</a></p><p>分类: <a href="http://www.rtoslab.net/post/wrinfo.html">风河资料库</a> | Tags: <a href="http://www.rtoslab.net/catalog.asp?tags=Tcl+vxWorks">Tcl vxWorks</a>&nbsp;&nbsp; | <a href="http://www.rtoslab.net/2010/01/2010118202243.html#comment" target="_blank">添加评论</a>(0)</p><p><a href="http://www.rtoslab.net/2010/01/2010118202243.html#comment" target="_blank">还没有相关文章，您来说两句？</a></p>]]></description><category>风河资料库</category><comments>http://www.rtoslab.net/2010/01/2010118202243.html#comment</comments><wfw:comment>http://www.rtoslab.net/</wfw:comment><wfw:commentRss>http://www.rtoslab.net/feed.asp?cmt=72</wfw:commentRss><trackback:ping>http://www.rtoslab.net/cmd.asp?act=tb&amp;id=72&amp;key=4d872451</trackback:ping></item></channel></rss>
