Getting Text Metrics in Firemonkey(delphiscience的博客)

Firemonkey’s abstract TCanvas class has been providing the dimensions of the bounding rectangle of some text on itself. On recent updates it has deprecated providing text rectangle directly in the canvas, in stead encouraged users to use TTextLayout abstract class which handles several text-based operations on the native context of the platforms. So it is possible to get the bounding rectangle of a string on any canvas. Is this enough? Though I am sure this class will improve to involve many new textual features, at current time it lacks some major needs of a developer who designs text drawing applications.
When words in different sizes aligned from top you can’t get a proper sentence view
For the first time, I have faced a feature lack when I saw even TMS’s HTML Text was unable to align words in an HTML notation that have got different sizes. Because having text rectangle is not enough to locate words in different sizes because of the missing baseline information. If you align the words from the top the smaller word’s baseline will be upper (as in the above image), if you align the bottoms the baseline will be lower, so to make a correct match you should know where are the baselines of each word exactly located. So we need to know the Ascent value of the text. If have got the ascent value, we can easily align the words on the baseline as seen on following image. For a complete information on typography see this article on Wikipedia.
For a proper drawing of words in different sizes you should align them on their baselines.
As seen on the above image, having the information of ascent values for each word we can align them properly on the baseline of the sentence. However FMX TTextLayout doesn’t provide this information. So I decided to add a new function to my PlatformExtensions unit to provide metrics information that are gathered from the drawing of that specific font in a specific size. The new function is GetTextMetrics and hast this following structure.
|
1
2
3
|
Class Procedure GetTextMetrics(Text:String; Font:TFont; var TextRect:TRectF; var Ascent,Descent:Single; var CapHeight,XHeight:Single);virtual;abstract; |
Getting Text Metrics in Windows
Firemonkey uses two different context types on Windows platform that are Windows GDIP and Direct2D. The default one is Windows GDI plus context which is a set of device independent drawing API based on the old GDI. Because of its device independency GDIP lacks of some important drawing features such as XOR brush, but it is always possible to handle these extra operations by locking the context to device dependent HDC and doing things on the device bitmap. What I mean is; getting font metrics is not as easy as it was old GDI based on HDC, so I used the limited information of the GDIP and estimated some others like (x height of text) by using statistical multipliers. However someone other can collapse the context to HDC level and calculate more detailed font metrics on that level. I didn’t prefer it to be consistent with the design logic of GDIP, and used TGPFontFamily class of GDIP to get the information about the font. Note that the metrics values gathered from this class is in logical units so should be converted to pixels using the proportions.
Here are my calculations:
|
1
2
3
4
5
6
7
8
9
10
11
|
fSize := FGPFont.GetHeight(FGraphics);cAscent := FGpFamily.GetCellAscent(FontStyle);cDescent := FGpFamily.GetCellDescent(FontStyle);emHeight := FGpFamily.GetEmHeight(FontStyle);lSpacing := FGPFamily.GetLineSpacing(FontStyle);iLeading := cAscent+cDescent - emHeight;eLeading := lSpacing - cAscent-cDescent;Ascent := fSize * (cAscent)/lSpacing;Descent := fSize * (descent)/lSpacing;CapHeight := fSize * (cAscent-iLeading)/lSpacing;XHeight := fsize * (cAscent-iLeading) *(7/10) /lSpacing; |
Note that the calculations use TGPFont, TGPFontFamily and TGPGraphics classes to deal with font metrics. The FGPFont and FGPGraphics objects are not accessible through standard class hierarchy, however we can use RTTI functions to access them.
|
1
2
3
4
5
6
7
8
9
10
11
12
|
RttiField := RttiContext.GetType(Layout.ClassType).GetField('FGPFont');if assigned(RttiField) thenbegin FGPFont := TGpFont(RttiField.GetValue(Layout).AsObject); RttiField := RttiContext.GetType(Layout.ClassType).GetField('FGraphics'); FGraphics := TGpGraphics(RttiField.GetValue(Layout).AsObject); FGPFamily := TGPFontFamily.Create; FGPFont.GetFamily(FGPFamily); // Get Metrics // ...end; |
Another point to be mentioned here is that, above calculations work only if the DefaultCanvas is a GDIP canvas. If the developer selects to use the D2D canvas, because of the absence of the FGPFont object in RTTI the text metrics will not be updated. Since I don’t have any experience on Direct2D I haven’t worked on it, but I will be happy if someone does it and send me so that I can put it in the class code by giving credits to his/her name.
Getting Text Metrics in Mac OS X
Things are always easier for programmers in Mac side. You can see below how it is easy getting font metrics using CoreText API of Cocoa.
|
1
2
3
4
5
6
|
LFontRef := CTFontCreateWithName(CFSTR(Layout.Font.Family), Layout.Font.Size, nil);Ascent := CTFontGetAscent(LFontRef);Descent := CTFontGetDescent(LFontRef);CapHeight := CTFontGetCapHeight(LFontRef);XHeight := CTFontGetXHeight(LFontRef);CFRelease(LFontRef); |
You can see all the details of using TTextLayout class and how to extend it to get Text/Font Metrics in my PlatformExtensions units. You can get the source code of the PlatformExtensions classes with the demo application from this SVN link. For non-programmers the compiledWin32, Win64, MacOSX (Thanks to Firemonkey) applications are also available to download.
https://delphiscience.wordpress.com/2013/01/06/getting-text-metrics-in-firemonkey/
Getting Text Metrics in Firemonkey(delphiscience的博客)的更多相关文章
- 博客代码美化(SyntaxHighlighter)
这篇博文主要讲解自己使用SyntaxHighlighter对代码进行美工中遇见的问题以及如何使用SyntaxHighlighter? 首先来看看SyntaxHighlighter对代码美工的效果吧! ...
- python实战--csdn博客专栏下载器
打算利用业余时间好好研究Python的web框架--web.py,深入剖析其实现原理,体会web.py精巧之美.但在研究源码的基础上至少得会用web.py.思前想后,没有好的Idea,于是打算开发一个 ...
- 【实战】如何通过html+css+mysql+php来快速的制作动态网页(以制作一个博客网站为列)
一.开发环境的搭建 (1)apache+php+mysql环境搭建 因为要用apache来做服务器,mysql作为数据库来存储数据,php来写代码以此实现网页与数据库的交互数据,所以需要下载上述软件, ...
- Sublime Text博客插件 --- iblog
iblog是一款 sublime 博客插件,目前只支持cnblog. 项目地址:https://github.com/iskeeter/iblog 功能介绍 新建和更新cnblog的博客 支持mark ...
- 一步步开发自己的博客 .NET版(10、前端对话框和消息框的实现)
关于前端对话框.消息框的优秀插件多不胜数.造轮子是为了更好的使用轮子,并不是说自己造的轮子肯定好.所以,这个博客系统基本上都是自己实现的,包括日志记录.响应式布局.评论功能等等一些本可以使用插件的.好 ...
- 一步步开发自己的博客 .NET版(1、基本显示)
前言 我们每个猿都有一个搭建自己独立博客的梦,我也不例外.以前想 现在想 以后也想.之所以一直迟迟没有着手,是因为难以跨出第一步.每次心里想着,等我以后技术好了再说,然后就没有然后了.以前用过word ...
- 一步步开发自己的博客 .NET版(3、注册登录功能)
前言 这次开发的博客主要功能或特点: 第一:可以兼容各终端,特别是手机端. 第二:到时会用到大量html5,炫啊. 第三:导入博客园的精华文章,并做分类.(不要封我) 第四:做 ...
- 一步步开发自己的博客 .NET版(4、文章发布功能)百度编辑器
前言 这次开发的博客主要功能或特点: 第一:可以兼容各终端,特别是手机端. 第二:到时会用到大量html5,炫啊. 第三:导入博客园的精华文章,并做分类.(不要封我) 第四:做个插件,任何网站上的技术 ...
- 一步步开发自己的博客 .NET版(5、Lucenne.Net 和 必应站内搜索)
前言 这次开发的博客主要功能或特点: 第一:可以兼容各终端,特别是手机端. 第二:到时会用到大量html5,炫啊. 第三:导入博客园的精华文章,并做分类.(不要封我) 第四:做 ...
随机推荐
- 修改mysql数据存储的地址
修改mysql数据存储的地址 修改步骤如下 1,修改前为默认路径/var/lib/mysql/,计划修改为/data/mysql/data mysql> show variables like ...
- codeforces 148D之概率DP
http://codeforces.com/problemset/problem/148/D D. Bag of mice time limit per test 2 seconds memory l ...
- HDFS集群balance(2)-- 架构概览
转载请注明博客地址:http://blog.csdn.net/suileisl HDFS集群balance,对应版本balance design 6 如需word版本,请QQ522173163联系索要 ...
- Linux/UNIX套接字连接
套接字连接 套接字是一种通信机子.凭借这样的机制.客户/server系统的开发工作既能够在本地单机上进行.也能够夸网络进行. 套接字的创建和使用与管道是有差别的.由于套接字明白地将客户和server区 ...
- 大数据笔记03:大数据之Hadoop的安装
1.安装Hadoop (1)准备Linux环境 (2)安装JDK (3)配置Hadoop 2.准备Linux环境 (1)我们用户可能都是使用Windows环境,一般用户都是先安装虚拟机,然后在虚拟机上 ...
- 使程序能够引入.json文件, 为网站添加 MIME 映射
确认启用了 MIME 映射,或使用命令行工具 appcmd.exe 为网站添加 MIME 映射. 若要设置 MIME 类型,请在 IIS Express 安装目录中运行以下命令: appcmd set ...
- OD: Ring0 & Kernel
开发技术讲究封装与模块化,安全技术强调底层安全性.安全技术需要打开封装.追根溯源! <0day 安全:软件漏洞分析技术(第2版)> 第21章 探索 Ring0 笔记 Intel x86 系 ...
- poj 1595
#include <iostream> #define N 10010 using namespace std; int a[N],b[N]; int prime(int a) { int ...
- css空格和去浮动的应用
今天做了项目用到css,请教前端解决,第一个是记得css空格之间的关系是隶属关系,但是在元素中却是并列关系,如<div class="right_side_item_moban gra ...
- 'swap file "xx" exists' linux
solution: 1)swap to another tty, kill processes using 'sudo kill -9 pid' 2)'Recover' the 'warn-openn ...