YSTest: TextRenderer.cpp 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

TextRenderer.cpp
浏览该文件的文档.
1 /*
2 © 2009-2015, 2017, 2019 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #include "YSLib/Service/YModules.h"
29 #include YFM_YSLib_Service_TextRenderer // for ystdex::max;
30 #include YFM_YSLib_Service_YBlit
31 #include YFM_YSLib_Service_TextLayout // for FetchLastLineBasePosition;
32 #include <ystdex/cwctype.h> // for ystdex::iswgraph;
33
34 using namespace ystdex;
35
36 namespace YSLib
37 {
38
39 using namespace Text;
40
41 namespace Drawing
42 {
43
44 namespace
45 {
46
48 YB_ATTR_nodiscard PaintContext
49 ClipChar(const Graphics& g, const Point& pen, const CharBitmap& cbmp, Rect r)
50 {
51 YAssert(bool(g), "Invalid graphics context found.");
52
53 const auto pt(ClipBounds(r, Rect(pen.X + cbmp.GetLeft(),
54 pen.Y - cbmp.GetTop(), cbmp.GetWidth(), cbmp.GetHeight())));
55
56 return {g, pt, r};
57 }
58
60 YB_ATTR_nodiscard YB_PURE SDst
61 FetchBMPSrcWidth(const CharBitmap& cbmp)
62 {
63 const SDst abs_pitch(SDst(abs(cbmp.GetPitch())));
64
65 switch(cbmp.GetFormat())
66 {
67 case CharBitmap::Mono:
68 return abs_pitch * 8;
69 case CharBitmap::Gray2:
70 return abs_pitch * 4;
71 case CharBitmap::Gray4:
72 return abs_pitch * 2;
73 default:
74 break;
75 }
76 return abs_pitch;
77 }
78
80 template<typename _tCharRenderer, _tCharRenderer& _fCharRenderer,
81 typename... _tParams>
82 void
83 RenderCharFrom(char32_t c, const Graphics& g, TextState& ts, const Rect& clip,
84 _tParams&&... args)
85 {
86 const auto cbmp(ts.Font.GetGlyph(c));
87
88 if(YB_LIKELY(cbmp))
89 {
90 // TODO: Show a special glyph when no bitmap found.
91 // TODO: Use fast glyph advance fetching for non-graph characters
92 // when possible.
93 // TODO: Handle '\t'.
94 if(ystdex::iswgraph(wchar_t(c)))
95 if(const auto cbuf = cbmp.GetBuffer())
96 {
97 auto&& pc(ClipChar(g, ts.Pen, cbmp, clip));
98
99 // TODO: Test support for bitmaps with negative pitch.
100 if(!pc.ClipArea.IsUnstrictlyEmpty())
101 _fCharRenderer(std::move(pc), ts.Color, cbmp.GetPitch() < 0,
102 cbuf, cbmp.GetFormat(), {FetchBMPSrcWidth(cbmp),
103 cbmp.GetHeight()}, yforward(args)...);
104 }
105 ts.Pen.X += cbmp.GetXAdvance();
106 }
107 }
108
109 } // unnamed namespace;
110
111 void
112 TextRenderer::operator()(char32_t c)
113 {
114 RenderCharFrom<decltype(RenderChar), RenderChar>(c, GetContext(), State,
115 ClipArea);
116 }
117
118 void
119 TextRenderer::ClearLine(size_t l, SDst n)
120 {
121 const auto& g(GetContext());
122 const auto h(g.GetHeight());
123
124 if(YB_LIKELY(bool(g) && l < h))
125 {
126 if(n == 0 || l + n > h)
127 n = h - SDst(l);
128 ClearPixels(g[l], size_t(g.GetWidth() * n));
129 }
130 }
131
132
133 TextRegion::TextRegion()
134 : GTextRendererBase<TextRegion>(), TextState(), CompactPixmapEx()
135 {
136 InitializeFont();
137 }
138 ImplDeDtor(TextRegion)
139
140 void
141 TextRegion::operator()(char32_t c)
142 {
143 RenderCharFrom<decltype(RenderCharAlpha), RenderCharAlpha>(c,
144 TextRegion::GetContext(), GetTextState(), Rect(GetSize())
145 + GetTextState().Margin, GetBufferAlphaPtr());
146 }
147
148 void
149 TextRegion::InitializeFont()
150 {
151 Font.SetSize(Font::DefaultSize);
152 ResetPen();
153 }
154
155 void
156 TextRegion::ClearLine(size_t l, SDst n)
157 {
158 const auto& g(GetContext());
159
160 if(YB_UNLIKELY(l > g.GetHeight()))
161 return;
162 if(!n)
163 --n;
164 if(YB_LIKELY(bool(g) && pBufferAlpha))
165 {
166 const size_t t((l + n > g.GetHeight() ? g.GetHeight() - l : n)
167 * g.GetWidth());
168
169 yunseq(ClearPixels(g[l], t),
170 ClearPixels(&pBufferAlpha[l * g.GetWidth()], t));
171 }
172 }
173
174 void
175 TextRegion::ClearTextLine(size_t l)
176 {
177 auto& ts(GetTextState());
178 SDst h(GetTextLineHeightExOf(ts));
179
180 // XXX: Conversion to 'SPos' might be implementation-defined.
181 // TODO: Is the 1st argument safe?
182 ClearLine(size_t(ts.Margin.Top + SPos(h * l)), h);
183 }
184
185 void
186 TextRegion::Scroll(ptrdiff_t n)
187 {
188 if(YB_LIKELY(Margin.Bottom < 0 || GetHeight() > SDst(Margin.Bottom)))
189 Scroll(n, GetHeight() - SDst(Margin.Bottom));
190 }
191 void
192 TextRegion::Scroll(ptrdiff_t n, SDst h)
193 {
194 if(YB_LIKELY(n != 0 && pBuffer && pBufferAlpha))
195 {
196 SDst top(SDst(ystdex::max(Margin.Top, SPos()))),
197 bottom(SDst(ystdex::max(Margin.Bottom, SPos())));
198 const auto& size(GetSize());
199
200 if(size.Height > top + bottom)
201 {
202 const auto t(size_t(((h + top > size.Height ? size.Height - bottom
203 : h) - top - SDst(abs(n))) * size.Width));
204
205 if(YB_LIKELY(t > 0))
206 {
207 size_t d(top), s(d);
208
209 if(n > 0)
210 d += size_t(n);
211 else
212 s -= size_t(n);
213 yunseq(s *= size.Width, d *= size.Width);
214 yunseq(ystdex::trivially_move_n(&pBuffer[s], t, &pBuffer[d]),
215 ystdex::trivially_move_n(&pBufferAlpha[s], t,
216 &pBufferAlpha[d]));
217 }
218 }
219 }
220 }
221
222
223 void
224 DrawClippedText(const Graphics& g, const Rect& bounds, TextState& ts,
225 const String& str, bool line_wrap)
226 {
227 TextRenderer tr(ts, g, bounds);
228
229 PutText(line_wrap, tr, str);
230 }
231 void
232 DrawClippedText(const Graphics& g, const Rect& bounds, const Rect& r,
233 const String& str, const Padding& m, Color c, bool line_wrap,
234 const Font& fnt)
235 {
236 TextState ts(fnt);
237 const Rect txt_bounds(r + m);
238
239 ts.Margin = FetchMargin(txt_bounds, g.GetSize()),
240 ts.ResetPen(r.GetPoint(), m);
241 ts.Color = c;
242 DrawClippedText(g, bounds & txt_bounds, ts, str, line_wrap);
243 }
244
245 void
246 DrawText(const Graphics& g, TextState& ts, const String& str, bool line_wrap)
247 {
248 DrawClippedText(g, Rect(g.GetSize()), ts, str, line_wrap);
249 }
250 void
251 DrawText(const Graphics& g, const Rect& bounds, const String& str,
252 const Padding& m, Color c, bool line_wrap, const Font& fnt)
253 {
254 DrawClippedText(g, Rect(g.GetSize()), bounds, str, m, c, line_wrap, fnt);
255 }
256 void
257 DrawText(TextRegion& tr, const Graphics& g, const Point& pt, const Size& s,
258 const String& str, bool line_wrap)
259 {
260 PutText(line_wrap, tr, str);
261 BlitTo(g.GetBufferPtr(), tr, g.GetSize(), Point(), pt, s);
262 }
263
264 } // namespace Drawing;
265
266 } // namespace YSLib;
267
YSLib::Drawing::TextState
文本状态。
Definition: TextBase.h:87
YB_ATTR_nodiscard
#define YB_ATTR_nodiscard
标记返回值不被忽略的属性。
Definition: ydef.h:715
YSLib::Drawing::TextRenderer
文本渲染器：简单实现。
Definition: TextRenderer.h:399
YSLib::Drawing::Color
The boundary is out of the const Rect SDst SPos SPos SPos Color
Definition: YDraw.h:128
size
size_t size
Definition: memory_resource.cpp:295
YSLib::Drawing::Size
屏幕区域大小。
Definition: YGDIBase.h:536
CHRLib::c
c
Definition: CharacterProcessing.h:84
YSLib::Drawing::BlitTo
dst src rot dst src rot YF_API bool BlitTo(BitmapPtr, const CompactPixmapEx &, const Size &, const Point &, const Point &, const Size &, Rotation=RDeg0)
贴图：位图缓冲区向指针指定的缓冲区以贴图算法复制。
Definition: YGDI.cpp:238
YB_PURE
#define YB_PURE
指示函数或函数模板实例为纯函数。
Definition: ydef.h:919
YSLib::Drawing::Graphics
GGraphics< BitmapPtr > Graphics
Definition: YGraphics.h:163
YSLib::Drawing::c
The boundary is out of the const Graphics const Rect const Point const Point Color c const Rect const Rect Color c
Definition: YDraw.h:174
YSLib::Drawing::TextRegion::Scroll
void Scroll(ptrdiff_t n)
缓冲区特效：整体移动 n 像素。
Definition: TextRenderer.cpp:186
YSLib::Drawing::GGraphics< unique_ptr< Pixel[]> >::pBuffer
PointerType pBuffer
显示缓冲区指针。
Definition: YGraphics.h:79
YSLib::Drawing::r
The boundary is out of the const Graphics const Rect const Point const Point Color c const Rect const Rect & r
Definition: YDraw.h:174
YSLib::Drawing::CompactPixmapEx::size_t
const CompactPixmapEx &buf AlphaType pBufferAlpha size_t
Definition: YGDI.h:372
YSLib::Drawing::GGraphics< unique_ptr< Pixel[]> >::s
const SizeType & s
Definition: YGraphics.h:88
YSLib::Drawing::ts
const TextState &ts const TextState &ts const TextState &ts TextState & ts
Definition: TextBase.h:190
CHRLib::d
_tDst * d
Definition: CharacterProcessing.h:142
YSLib::Drawing::GetTextLineHeightExOf
GetTextLineHeightExOf
Definition: TextBase.h:169
YSLib::Drawing::TextState::Pen
Point Pen
笔坐标。
Definition: TextBase.h:98
ystdex::cpp2014::max
const _type & max(const _type &a, const _type &b, _fComp comp=less< _type >())
取较大的元素。
Definition: algorithm.hpp:635
YSLib::Drawing::TextRegion::ClearLine
void ClearLine(size_t l, SDst n)
清除缓冲区第 l 行起始的 n 行像素。
Definition: TextRenderer.cpp:156
YModules.h
YSLib 服务模块配置文件。
YSLib::Drawing::TextState::ResetPen
PDefHOp(TextState &,=, const PenStyle &ps) ImplRet(PenStyle void ResetPen()
赋值：笔样式。
Definition: TextBase.h:145
YAssert
#define YAssert(_expr, _msg)
Definition: cassert.h:154
YSLib::Drawing::g
The boundary is out of the const Graphics & g
Definition: YDraw.h:161
CHRLib::args
YB_ATTR_nodiscard _tParams && args
Definition: CharacterProcessing.h:649
YSLib::Drawing::CompactPixmapEx::pBufferAlpha
unique_ptr< AlphaType[]> pBufferAlpha
Alpha 缓冲区指针。
Definition: YGDI.h:344
YSLib::Drawing::TextRegion
文本区域。
Definition: TextRenderer.h:492
YSLib::Drawing::CompactPixmapEx
使用 8 位 Alpha 扩展的标准矩形像素图缓冲区。
Definition: YGDI.h:338
YSLib::Drawing::TextState::Color
Drawing::Color Color
Definition: TextBase.h:58
YSLib::Drawing::TextRegion::ClearTextLine
void ClearTextLine(size_t)
清除缓冲区中的指定行号的文本行。
Definition: TextRenderer.cpp:175
YSLib::Drawing::Padding::Top
SPos Top
Definition: YGDI.h:52
YSLib::Drawing::GGraphics
二维图形接口上下文模板。
Definition: YGraphics.h:63
YSLib::Drawing::TextState::Font
Drawing::Font Font
Definition: TextBase.h:57
YSLib::Drawing::Point
GBinaryGroup< SPos > Point
屏幕二维点（直角坐标表示）。
Definition: YGDIBase.h:520
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 转发对应参数。
Definition: ydef.h:1508
YSLib::Text::String
YSLib 标准字符串（使用 UCS-2 作为内部编码）。
Definition: YString.h:47
YSLib::Drawing::GTextRendererBase
文本渲染器静态多态基类模板。
Definition: TextRenderer.h:361
YSLib::Drawing::Padding
空白样式。
Definition: YGDI.h:47
YSLib::Drawing::ClipBounds
Point ClipBounds(Rect &clip, const Rect &bounds) ynothrow
Definition: YGDI.cpp:60
cwctype.h
ISO C 宽字符分类操作扩展。
YSLib::Drawing::GBinaryGroup< SPos >
YSLib::Drawing::ClearPixels
_tOut ClearPixels(_tOut dst, size_t n) ynothrowv
显示缓存操作：清除/以纯色像素填充。
Definition: YBlit.h:517
YSLib::Drawing::ImplDeDtor
ImplDeDtor(FontException) namespace
Definition: Font.cpp:80
YSLib::Drawing::GetSize
dst GetSize()
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:1535
platform::SDst
std::uint16_t SDst
屏幕坐标距离。
Definition: Video.h:44
YSLib::Drawing::TextState::Margin
Padding Margin
边距：文本区域到显示区域的距离。
Definition: TextBase.h:93
YSLib::Drawing::GBinaryGroup::X
_type X
分量。
Definition: YGDIBase.h:305
YSLib::Drawing::Rect
屏幕标准矩形：表示屏幕矩形区域。
Definition: YGDIBase.h:788
YSLib
YSLib 命名空间。
Definition: AndroidHost.h:46
CHRLib::s
_tDst const _tSrc * s
Definition: CharacterProcessing.h:143
YB_LIKELY
#define YB_LIKELY(_expr)
Definition: ydef.h:827
YSLib::str
const char * str
Definition: YException.cpp:60
YSLib::Drawing::Padding::Bottom
SPos Bottom
Definition: YGDI.h:52
YSLib::Drawing::bounds
The boundary is out of the const Rect & bounds
Definition: YDraw.h:127
YSLib::Drawing::DrawText
YF_API void DrawText(const Graphics &g, TextState &ts, const String &str, bool line_wrap)
绘制文本。
Definition: TextRenderer.cpp:246
ystdex
<memory> 特性测试宏。
Definition: ydef.h:1262
YSLib::_tParams
YB_ATTR_nodiscard YB_PURE typename _tParams
Definition: ValueNode.h:1294
YSLib::Drawing::TextRegion::InitializeFont
void InitializeFont()
初始化字体。
Definition: TextRenderer.cpp:149
ystdex::trivially_move_n
_type * trivially_move_n(const _type *first, size_t n, _type *result)
复制可能覆盖的序列。
Definition: algorithm.hpp:497
YSLib::Drawing::Font
字体：字模，包含字型、样式和大小。
Definition: Font.h:589
YSLib::Drawing::CompactPixmapEx::SDst
SDst
Definition: YGDI.h:351
YSLib::Drawing::FetchMargin
Padding FetchMargin(const Rect &r, const Size &s) ynothrow
Definition: YGDI.cpp:51
YB_UNLIKELY
#define YB_UNLIKELY(_expr)
分支预测提示。
Definition: ydef.h:828
YSLib::Drawing::PutText
void PutText(bool multi, _tParams &&... args)
打印文本。
Definition: TextRenderer.h:312
platform::SPos
std::int16_t SPos
屏幕坐标度量。
Definition: Video.h:43
YSLib::Drawing::DrawClippedText
YF_API void DrawClippedText(const Graphics &g, const Rect &bounds, TextState &ts, const String &str, bool line_wrap)
绘制剪切区域的文本。
Definition: TextRenderer.cpp:224
YSLib::Drawing::GetHeight
YB_ATTR_nodiscard YB_PURE tr GetHeight())) inline PDefH(void
按字体高度和行距调整文本区域的底边距。
YSLib::Drawing::char32_t
YB_ATTR_nodiscard YB_PURE tr TextRegion &tr char32_t
Definition: TextLayout.h:93
ystdex::iswgraph
bool iswgraph(wchar_t wc)
区域无关的 std::iswgraph 实现。
Definition: cwctype.h:62
YSLib::Drawing::Font::DefaultSize
static yconstexpr const FontSize DefaultSize
Definition: Font.h:591
platform::l
return l
Definition: YCLib/FileSystem.h:402