Direct2D实现文字的描边和填充
一、实现思路
通过继承IDWriteTextRenderer定义自己的文本渲染类并重写DrawGlyphRun方法,最终将该类实例作为 IDWriteTextLayout::Draw的参数传入进行文本的绘制。
二、代码实现
1、自定义文本渲染类
class CustomTextRenderer : public IDWriteTextRenderer
{
protected:ULONG m_cRef;ID2D1Factory* m_pD2DFactory;ID2D1RenderTarget *m_pRenderTarget;ID2D1Brush *m_pTextBodyBrush;ID2D1SolidColorBrush *m_pTextOutlineBrush;float mStrokeWidth;public:CustomTextRenderer(ID2D1Factory* pD2DFactory, ID2D1RenderTarget* pRenderTarget,ID2D1Brush *pTextBodyBrush, ID2D1SolidColorBrush *pTextOutlineBrush, float strokeWidth = 1.0f);~CustomTextRenderer();STDMETHOD(DrawGlyphRun)(void *clientDrawingContext,FLOAT baselineOriginX,FLOAT baselineOriginY,DWRITE_MEASURING_MODE measuringMode,DWRITE_GLYPH_RUN const *glyphRun,DWRITE_GLYPH_RUN_DESCRIPTION const *glyphRunDescription,IUnknown *clientDrawingEffect);STDMETHOD(DrawUnderline)(void *clientDrawingContext,FLOAT baselineOriginX,FLOAT baselineOriginY,DWRITE_UNDERLINE const *underline,IUnknown *clientDrawingEffect);STDMETHOD(DrawStrikethrough)(void *clientDrawingContext,FLOAT baselineOriginX,FLOAT baselineOriginY,DWRITE_STRIKETHROUGH const *strikethrough,IUnknown *clientDrawingEffect);STDMETHOD(DrawInlineObject)(void *clientDrawingContext,FLOAT originX,FLOAT originY,IDWriteInlineObject *inlineObject,BOOL isSideways,BOOL isRightToLeft,IUnknown *clientDrawingEffect){return E_NOTIMPL;}STDMETHOD(IsPixelSnappingDisabled)(void* clientDrawingContext,BOOL* isDisabled){*isDisabled = FALSE;return S_OK;}STDMETHOD(GetCurrentTransform)(void* clientDrawingContext,DWRITE_MATRIX* transform){m_pRenderTarget->GetTransform(reinterpret_cast<D2D1_MATRIX_3X2_F*>(transform));return S_OK;}STDMETHOD(GetPixelsPerDip)(void* clientDrawingContext,FLOAT* pixelsPerDip){float x, yUnused;m_pRenderTarget->GetDpi(&x, &yUnused);*pixelsPerDip = x / 96;return S_OK;}HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void FAR* FAR* ppvObj){if (iid == IID_IUnknown /*|| iid == IID_IDWritePixelSnapping || iid == IID_IDWriteTextRenderer*/){*ppvObj = this;AddRef();return NOERROR;}return E_NOINTERFACE;}ULONG STDMETHODCALLTYPE AddRef(){ return ++m_cRef;}ULONG STDMETHODCALLTYPE Release(){// Decrement the object's internal counter.if (0 == --m_cRef){delete this;}return m_cRef;}
};
2、DrawGlyphRun方法实现
HRESULT CustomTextRenderer::DrawGlyphRun(void *clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY,DWRITE_MEASURING_MODE measuringMode, DWRITE_GLYPH_RUN const *glyphRun,DWRITE_GLYPH_RUN_DESCRIPTION const *glyphRunDescription, IUnknown *clientDrawingEffect)
{HRESULT hr = S_OK;ID2D1PathGeometry* pPathGeometry = nullptr;hr = m_pD2DFactory->CreatePathGeometry(&pPathGeometry);ID2D1GeometrySink* pSink = nullptr; hr = pPathGeometry->Open(&pSink);hr = glyphRun->fontFace->GetGlyphRunOutline(glyphRun->fontEmSize,glyphRun->glyphIndices,glyphRun->glyphAdvances,glyphRun->glyphOffsets,glyphRun->glyphCount,glyphRun->isSideways,glyphRun->bidiLevel,pSink);hr = pSink->Close();// Initialize a matrix to translate the origin of the glyph run.D2D1::Matrix3x2F const matrix = D2D1::Matrix3x2F(1.0f, 0.0f,0.0f, 1.0f,baselineOriginX, baselineOriginY);ID2D1TransformedGeometry *pTransformedGeometry = nullptr;hr = m_pD2DFactory->CreateTransformedGeometry(pPathGeometry, &matrix, &pTransformedGeometry);// 绘制文字描边部分m_pRenderTarget->DrawGeometry(pTransformedGeometry, m_pTextOutlineBrush, mStrokeWidth);// 绘制文字填充部分m_pRenderTarget->FillGeometry(pTransformedGeometry, m_pTextBodyBrush);SafeRelease(&pPathGeometry);SafeRelease(&pSink);SafeRelease(&pTransformedGeometry);return hr;
}
3、使用自定义渲染对象绘制文本
m_pTextRenderer = new CustomTextRenderer(
m_pDirect2dFactory, m_pRenderTarget,
m_pTextBodyBrush, m_pTextOutlineBrush, strokeWidth);m_pRenderTarget->BeginDraw();
m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
m_pTextLayout->Draw(nullptr, m_pTextRenderer, 0.0f, 0.0f);
m_pRenderTarget->EndDraw();
三、绘制结果
1、只有描边部分
2、只有填充部分
3、描边和填充
四、总结
1、自定义文本渲染类的核心是重写IDWriteTextRenderer::DrawGlyphRun这个回调函数。
2、使用自定义文本渲染类绘制文字必须调用IDWriteTextLayout::Draw,而不是ID2D1RenderTarget::DrawText和ID2D1RenderTarget::DrawTextLayout。
PS:
本文代码是基于微软官方文档示例所实现,详情可参考:
how-to-implement-a-custom-text-renderer
direct2d-quickstart
Direct2D实现文字的描边和填充相关推荐
- Ai 文字正确描边 文字描边
Ai 文字正确描边 文字描边 每次制作宣传材料的时候,这个问题都困扰着我.我一般都是文字转曲后再操作,但这样在再次修改文字的时候会变的非常麻烦,需要重新新一遍,或在转曲的时候备份一份. 现在终于解决了 ...
- html文字加描边效果,怎么用css给文字加描边?
怎么用css给文字加描边?下面本篇文章给大家介绍一下使用CSS给文字添加描边效果的方法.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 方法1:使用text-shadow属性给文字加 ...
- 3 photolemur 样式_css3怎么给文字加描边?css3实现字体描边样式的方法(代码详解)...
css3怎么给文字加描边?本篇文章就给大家介绍css3给文字加描边的方法,让大家了解css text-stroke属性实现字体描边样式的具体方法.有一定的参考价值,有需要的朋友可以参考一下,希望对你们 ...
- html给图片加描边,photoshop中如何给图片文字加描边
在图片的后期处理中,图片上的文字就如男人的手表.女人的首饰一样,适当而精彩的文字能给图片起到点睛的装饰作用.当然文字的添加,并不是单纯地打 字上图那么简单,无论是构图.编排.修饰都要反复斟酌,很多软件 ...
- html语言填充没有只有描边,HTML5 Canvas笔记——交互绘制文本(描边、填充、阴影、渐变填充、图案填充、文本的属性设置)...
(1)文本的描边.填充.阴影 (2)文本的渐变填充 (3)文本的图案填充 (4)文本的属性设置及效果呈现 交互绘制文本.html 交互绘制文本 body { background: #eeeeee; ...
- Illustrator 描边,填充,扩展
Illustrator 首先 ai中的是以线为形状的. 视图→轮廓中可以看到都是一条条线 视图,轮廓在这 描边 ai中的描边是对于线进行描边. 填充 ai中的填充是封闭图形进行填充 对比 一样的正方形 ...
- css字体描边加阴影,css text-shadow 轻松实现文字投影/描边/浮雕/剪纸/发光效果
css3很多知识值得我们去了解,一些我们惯常用图片制作出来的效果,也许用CSS3几行代码就能实现,正如本文介绍的,使用css text-shadow 属性,就能轻松实现文字投影/描边/浮雕/剪纸/发光 ...
- 2020.9.25--PS--图片合成、图片描边和填充、变形
图片合成 把一张图片中的物体抠出来放到另一张的合适位置进行调整 图片描边和填充 打开一张图片,用矩形选框工具或椭圆选框工具画出矩形选区或圆形选区,点"编辑"中"描边&qu ...
- 2020.10.10--PS--路径运算、路径总结、路径描边和填充
路径运算 路径组合.路径加减:画出需要的路径形状在菜单栏下面一行进行组合,加减 路径总结 一个图形可以用多个锚点组成最少可以用两个锚点组成,控制锚点的手柄进行制作 路径描边.填充 用钢笔工具画出路径, ...
最新文章
- Linux下root密码忘记的解决办法
- itstime后面跟什么_一文讲透什么是引流
- 网站SEO优化中长尾关键词的特征有哪些?
- 2018\National _C_C++_B\1.换零钞
- 为什么我放弃饿了么产品总监,却要从事自由职业?
- springMVC接受参数总结
- 如何自定义FusionCharts图表上的工具提示?
- 5动态显示图片_单片机入门 数码管的静态显示和动态显示 壁纸
- python中spider的用法_Spider-PyQuery基本用法(示例代码)
- 从数据库中读取数据,创建XML文件并更新维护XML
- 文档交接说明书(模板)
- apple tv 开发_如何在Apple TV上播放计算机中的视频文件
- finereport与finebi差别_FineBI与FineReport对比
- C++ 常用数学函数
- Eclips IDE安装Python
- 阿龙的学习笔记---如何用C++ STL 实现一个 LRU缓存
- UE4.26源码版学习广域网独立服务器时遇到的客户端运行黑屏问题
- vim教程之基本使用
- Python采集二手房源数据信息 基础版, 多线程版
- 数字图像处理知识点梳理——第二章 数字图像基础