登录 用户中心() [退出] 后台管理 注册
   
您的位置: 首页 >> CLQ工作室开源代码 >> 主题: [老代码/思想不老]一份在粗糙的老操作系统上能得到惊艳平滑字体的代码 [codeview字幕歌词]     [回主站]     [分站链接]
标题
[老代码/思想不老]一份在粗糙的老操作系统上能得到惊艳平滑字体的代码 [codeview字幕歌词]
clq
浏览(291) + 2023-07-23 00:12:49 发表 编辑

关键字:

[2023-07-23 00:27:56 最后更新]

[老代码/思想不老]一份在粗糙的老操作系统上能得到惊艳平滑字体的代码 [codeview字幕歌词]

自从我在 gtk 的 cairo 和 golang 的 gg 库中可以画出高质量的平滑字体库后就没有再关注这方面的技术。
但高清屏普及后,高质量平滑字体效果更是唾手可得,更加遗忘了这个实现方法。但今天偶然在一台老显示器上看纯文本时又想起了它。

确实那个时候能出这样的效果实在是太棒了,而且实现的思路异常的巧妙。

核心代码如下:

//---------------------开始:画字符串阴影--------------------------------------
//ReleaseDC(Self.Handle,hdcScreen); tmp.Free; Exit;

for i :=
1
to
shadowSize//14//文字描边的宽度//默认为 8 , 14 的效果也不错
do
begin
pen.SetWidth(i);
pen.SetColor(MakeColor(62, 0, 2, 2));//用了 alpha 颜色,所以是渐变的描边
pen.SetLineJoin(LineJoinRound); //指定圆形联接。这将在两条线之间产生平滑的圆弧。
graphics.DrawPath(pen,path);
end;
//---------------------开始:画背景框和背景图----------------------------------

其实就是利用 gidplus 的功能,多画上几层半透明的外框。
关键的画法是使用 path 将字体作为路径实现的,这样可以非常精确的定位。实在是巧妙。

更完整的代码如下,改天我传到 github 上,顺便将我以此为基础的一个简单的纯文本阅读器也上传。后来很忙,也没有心思看小说,这个阅读器也不知道扔哪去了,改天找找吧。

----------------------------------------------------------------

function TForm1.DrawString(pszbuf: WideString):Boolean;
var
hdcScreen: HDC;
//hBitMap: Windows.HBITMAP;
rct: TRect;
graphics: IGPGraphics; //封装一个 GDI+ 绘图图面
fontFamily: IGPFontFamily; //定义有着相似的基本设计但在形式上有某些差异的一组字样
path: IGPGraphicsPath; //表示一系列相互连接的直线和曲线
strFormat: IGPStringFormat;//封装文本布局信息,显示操作
pen,pen1,pen2: IGPPen; //定义用于绘制直线和曲线的对象
linGrBrush,linGrBrushW: IGPLinearGradientBrush; //使用线性渐变封装 Brush
brush: IGPSolidBrush; //定义单色画笔,画笔用于填充图形形状
image: TGPImage; //使用这个类来创建和操作GDI+图像
i: Integer;

graphics_form: IGPGraphics;
tmp:TBitmap;
tmpg:TGPBitmap;

st,sl:Integer;

begin
//---------------------开始:初始化操作--------------------------------------

hdcScreen := GetDC(Self.Handle);
//GetWindowRect(Self.Handle,rct);
rct := GetClientRect;

tmp := TBitmap.Create;
tmp.Width := rct.Right - rct.Left;//100;
tmp.Height := rct.Bottom - rct.Top;

//双缓冲背景色
// tmp.Canvas.Brush.Color := RGB(30, 30, 30);//clBlack;//test
// tmp.Canvas.FillRect(rct);//test

//tmpg := TGPBitmap.Create(tmp);//奇怪,不能放这里

graphics := TGPGraphics.Create(tmp.Canvas.Handle);
//graphics := TGPGraphics.Create(hdcScreen);
graphics_form := TGPGraphics.Create(hdcScreen);



graphics.SetSmoothingMode(SmoothingModeAntiAlias); //指定平滑(抗锯齿)
graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);//指定的高品质,双三次插值
//fontFamily := TGPFontFamily.Create('微软雅黑'); //△字体,效果图为'微软雅黑'字体
fontFamily := TGPFontFamily.Create('宋体'); //△字体,效果图为'微软雅黑'字体
strFormat := TGPStringFormat.Create();
path := TGPGraphicsPath.Create();
//---------------------结束:初始化操作--------------------------------------
//--------------------------------------------------
//可画多行文本
//fontFamily.ge

// path.AddString(pszbuf, //要添加的 String
// fontFamily, //表示绘制文本所用字体的名称
// 0, //指定应用到文本的字形信息,这里为普通文本
// 64,//clq 这个控件字体大小?//38, //限定字符的 Em(字体大小)方框的高度
// MakePoint(10,10), //一个 Point,它表示文本从其起始的点
// strFormat); //指定文本格式设置信息
//
// path.AddString(pszbuf, //要添加的 String
// fontFamily, //表示绘制文本所用字体的名称
// 0, //指定应用到文本的字形信息,这里为普通文本
// 64,//clq 这个控件字体大小?//38, //限定字符的 Em(字体大小)方框的高度
// MakePoint(200,200), //一个 Point,它表示文本从其起始的点
// strFormat); //指定文本格式设置信息

for i := 0 to stringsForDraw.Count-1 do
begin
st := i * fontSize + drawOffTop;
sl := drawOffLeft;

path.AddString(stringsForDraw[i], //要添加的 String
fontFamily, //表示绘制文本所用字体的名称
0, //指定应用到文本的字形信息,这里为普通文本
fontSize,//64,//clq 这个控件字体大小?//38, //限定字符的 Em(字体大小)方框的高度
MakePoint(sl, st),//MakePoint(100,100), //一个 Point,它表示文本从其起始的点
strFormat); //指定文本格式设置信息

end;


//可画多行文本 _end;
//--------------------------------------------------

pen := TGPPen.Create(MakeColor(155,215,215,215),3); //颜色、宽度
graphics.DrawPath(pen,path); //初步绘制GraphicsPath

// linGrBrush := TGPLinearGradientBrush.Create(MakePoint(0,0), //线性渐变起始点
// MakePoint(0,90), //线性渐变终结点
// MakeColor(255,255,255,255), //线性渐变起始色
// MakeColor(255,30,120,195)); //线性渐变结束色
if True then
linGrBrush := TGPLinearGradientBrush.Create(MakePoint(0, drawOffTop), //线性渐变起始点
MakePoint(0, fontSize + drawOffTop), //线性渐变终结点
MakeColor(255,255,255,255), //线性渐变起始色
MakeColor(255,128,174,213)); //线性渐变结束色,注意第1个参数是 Alpha 通道


//纯白刷
// linGrBrush := TGPLinearGradientBrush.Create(MakePoint(0,0), //线性渐变起始点
// MakePoint(0,90), //线性渐变终结点
// MakeColor(255,255,255,255), //线性渐变起始色
// MakeColor(255,255,255,255)); //线性渐变结束色


//彩白折刷?特殊效果
if False then
linGrBrush := TGPLinearGradientBrush.Create(MakePoint(0, drawOffTop), //线性渐变起始点
MakePoint(0, Trunc((fontSize*0.5)) + drawOffTop), //线性渐变终结点
MakeColor(255,255,255,255), //线性渐变起始色
//MakeColor(255,30,120,195)); //线性渐变结束色
MakeColor(255,30,120,195)); //线性渐变结束色,注意第1个参数是 Alpha 通道


// linGrBrushW := TGPLinearGradientBrush.Create(MakePoint(0,10),
// //MakePoint(0,60),
// MakePoint(0,90),//clq 这个控制渐变高度?
// MakeColor(255,255,255,255),
// MakeColor(15,1,1,1));
//---------------------开始:画字符串阴影--------------------------------------
//ReleaseDC(Self.Handle,hdcScreen); tmp.Free; Exit;

for i :=
1
to
shadowSize//14//文字描边的宽度//默认为 8 , 14 的效果也不错
do
begin
pen.SetWidth(i);
pen.SetColor(MakeColor(62, 0, 2, 2));//用了 alpha 颜色,所以是渐变的描边
pen.SetLineJoin(LineJoinRound); //指定圆形联接。这将在两条线之间产生平滑的圆弧。
graphics.DrawPath(pen,path);
end;
//---------------------开始:画背景框和背景图----------------------------------
//if bBack then
if true then
begin
// brush := TGPSolidBrush.Create(MakeColor(25,228,228,228));
// pen1 := TGPPen.Create(MakeColor(155,223,223,223));
// pen2 := TGPPen.Create(MakeColor(55,223,223,223));
// image := TGPImage.Create('back.png'); //背景图片
// graphics.FillRectangle(brush,3,5,750,90); //填充背景框色//这个会极大的影响性能
// graphics.DrawRectangle(pen1,2,6,751,91); //内层背景框
// graphics.DrawRectangle(pen2,1,5,753,93); //外层背景框
// graphics.DrawImage(image,600,25);
end;
//---------------------开始:以渐变色笔刷填充GraphicsPath内部-----------------
//ReleaseDC(Self.Handle,hdcScreen); tmp.Free; Exit;

graphics.FillPath(linGrBrush,path); //似乎主要是这个的效果
// graphics.FillPath(linGrBrushW,path);

//---------------------开始:更新一个分层的窗口的位置,大小,形状,内容和半透明度---
//ReleaseDC(Self.Handle,hdcScreen); tmp.Free; Exit;
tmpg := TGPBitmap.Create(tmp);
graphics_form.DrawImage(tmpg, 0, 0);//双缓冲

//---------------------开始:释放和删除--------------------------------------
ReleaseDC(Self.Handle,hdcScreen);
//tmpg.Free;//似乎不需要
tmp.Free;

end;




含有高速下载地址,但您没有文件高速下载权限。请先开通1元包年会员:
了解/开通会员
clq
2023-07-23 00:17:47 发表 编辑

[图片]

效果如图,在如今有苹果 imac 超高清屏对比的情况下,这个效果依然不输于它。真的很棒。一直到 win11 后 windows 的字体渲染才勉强能和苹果一比。
当然我更喜欢 ubuntu 22.04 的效果。


clq
2023-07-23 00:20:01 发表 编辑


用到 gdiplus 的 IGDIPlus 第三方库。


总数:2 页次:1/1 首页 尾页  
总数:2 页次:1/1 首页 尾页  


所在合集/目录



发表评论:
文本/html模式切换 插入图片 文本/html模式切换


附件:



NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.

Copyright © 2005-2020 clq, All Rights Reserved
版权所有
桂ICP备15002303号-1