标题
[老代码/思想不老]一份在粗糙的老操作系统上能得到惊艳平滑字体的代码 [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 第三方库。
NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.