YSTest: TextRenderer.cpp 源文件

YSTest PreAlpha_b800_20170810 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

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