YSTest  PreAlpha_b500_20140530
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
TextRenderer.cpp
浏览该文件的文档.
1 /*
2  © 2009-2014 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 
33 using namespace ystdex;
34 
35 namespace YSLib
36 {
37 
38 using namespace Drawing;
39 using namespace Text;
40 
41 namespace Drawing
42 {
43 
44 namespace
45 {
46 
48 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 SDst
61 FetchBMPSrcWidth(const CharBitmap& cbmp)
62 {
63  const SDst abs_pitch(std::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(ucs4_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(std::iswgraph(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()(ucs4_t c)
113 {
114  RenderCharFrom<decltype(RenderChar), RenderChar>(c, GetContext(), State,
115  ClipArea);
116 }
117 
118 void
119 TextRenderer::ClearLine(u16 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 - l;
128  ClearPixel(g[l], g.GetWidth() * n);
129  }
130 }
131 
132 
133 TextRegion::TextRegion()
135 {
136  InitializeFont();
137 }
138 
139 void
140 TextRegion::operator()(ucs4_t c)
141 {
142  RenderCharFrom<decltype(RenderCharAlpha), RenderCharAlpha>(c,
143  TextRegion::GetContext(), GetTextState(), Rect(GetSize())
144  + GetTextState().Margin, GetBufferAlphaPtr());
145 }
146 
147 void
149 {
150  Font.SetSize(Font::DefaultSize);
151  ResetPen();
152 }
153 
154 void
156 {
157  const auto& g(GetContext());
158 
159  if(YB_UNLIKELY(l > g.GetHeight()))
160  return;
161  if(!n)
162  --n;
163  if(YB_LIKELY(bool(g) && pBufferAlpha))
164  {
165  const u32 t(
166  (l + n > g.GetHeight() ? g.GetHeight() - l : n) * g.GetWidth());
167 
168  yunseq(ClearPixel(g[l], t),
169  ClearPixel(&pBufferAlpha[l * g.GetWidth()], t));
170  }
171 }
172 
173 void
175 {
176  auto& ts(GetTextState());
178 
179  ClearLine(ts.Margin.Top + h * l, h);
180 }
181 
182 void
183 TextRegion::Scroll(ptrdiff_t n)
184 {
185  if(YB_LIKELY(GetHeight() > Margin.Bottom))
186  Scroll(n, GetHeight() - Margin.Bottom);
187 }
188 void
189 TextRegion::Scroll(ptrdiff_t n, SDst h)
190 {
191  if(YB_LIKELY(pBuffer && pBufferAlpha))
192  {
193  const s32 t(((h + Margin.Bottom > GetHeight()
194  ? GetHeight() - Margin.Bottom : h)
195  - Margin.Top - std::abs(n)) * GetWidth());
196 
197  if(YB_LIKELY(n && t > 0))
198  {
199  u32 d(Margin.Top), s(d);
200 
201  if(n > 0)
202  d += n;
203  else
204  s -= n;
205  yunseq(s *= GetWidth(), d *= GetWidth());
206  yunseq(ystdex::pod_move_n(&pBuffer[s], t, &pBuffer[d]),
207  ystdex::pod_move_n(&pBufferAlpha[s], t, &pBufferAlpha[d]));
208  }
209  }
210 }
211 
212 
213 void
214 DrawClippedText(const Graphics& g, const Rect& mask, TextState& ts,
215  const String& str, bool line_wrap)
216 {
217  TextRenderer tr(ts, g, mask);
218 
219  PutText(line_wrap, tr, str);
220 }
221 void
222 DrawClippedText(const Graphics& g, const Rect& mask, const Rect& bounds,
223  const String& str, const Padding& m, Color c, bool line_wrap,
224  const Font& fnt)
225 {
226  TextState ts(fnt);
227  const Rect txt_bounds(bounds + m);
228 
229  ts.Margin = FetchMargin(txt_bounds, g.GetSize()),
230  ts.ResetPen(bounds.GetPoint(), m);
231  ts.Color = c;
232  DrawClippedText(g, mask & txt_bounds, ts, str, line_wrap);
233 }
234 
235 void
236 DrawText(const Graphics& g, TextState& ts, const String& str, bool line_wrap)
237 {
238  DrawClippedText(g, Rect(g.GetSize()), ts, str, line_wrap);
239 }
240 void
241 DrawText(const Graphics& g, const Rect& bounds, const String& str,
242  const Padding& m, Color c, bool line_wrap, const Font& fnt)
243 {
244  DrawClippedText(g, Rect(g.GetSize()), bounds, str, m, c, line_wrap, fnt);
245 }
246 void
247 DrawText(TextRegion& tr, const Graphics& g, const Point& pt, const Size& s,
248  const String& str, bool line_wrap)
249 {
250  PutText(line_wrap, tr, str);
251  BlitTo(g.GetBufferPtr(), tr, g.GetSize(), Point(), pt, s);
252 }
253 
254 } // namespace Drawing;
255 
256 } // namespace YSLib;
257 
YF_API Padding FetchMargin(const Rect &, const Size &)
取内边界相对于外边界的边距。
Definition: ygdi.cpp:51
std::uint32_t u32
Definition: yadaptor.h:69
yconstfn const string _tParams && args
Definition: Loader.h:111
void ClearLine(u16 l, SDst n)
清除缓冲区第 l 行起始的 n 行像素。
YF_API void DrawClippedText(const Graphics &g, const Rect &mask, TextState &ts, const String &str, bool line_wrap)
绘制剪切区域的文本。
_tOut ClearPixel(_tOut dst, size_t n) ynothrow
清除指定位置的 n 个连续像素。
Definition: yblit.h:424
void ClearTextLine(u16)
清除缓冲区中的指定行号的文本行。
YF_API Point ClipBounds(Rect &, const Rect &)
根据指定源的边界优化绘制上下文的剪切区域。
Definition: ygdi.cpp:59
std::uint16_t SDst
屏幕坐标距离。
Definition: Video.h:39
文本渲染器静态多态基类模板。
Definition: TextRenderer.h:328
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:722
CompactPixmapEx(ConstBitmapPtr, SDst, SDst)
构造:使用指定位图指针和大小。
Padding Margin
边距:文本区域到显示区域的距离。
Definition: TextBase.h:94
#define YB_UNLIKELY(expr)
分支预测提示。
Definition: ydef.h:298
YSLib 标准字符串(使用 UCS-2 作为内部编码)。
Definition: ystring.h:47
GBinaryGroup< SPos > Point
屏幕二维点(直角坐标表示)。
Definition: ygdibase.h:235
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:748
YF_API void DrawText(const Graphics &g, TextState &ts, const String &str, bool line_wrap)
绘制文本。
文本状态。
Definition: TextBase.h:87
文本渲染器:简单实现。
Definition: TextRenderer.h:361
屏幕标准矩形:表示屏幕矩形区域。
Definition: ygdibase.h:416
void InitializeFont()
初始化字体。
Drawing::Color Color
笔颜色。
Definition: TextBase.h:58
二维图形接口上下文。
Definition: ygdibase.h:721
std::int32_t s32
Definition: yadaptor.h:73
空白样式。
Definition: ygdi.h:46
char32_t ucs4_t
UCS-4 字符类型。
Definition: chrdef.h:45
_type * pod_move_n(const _type *first, size_t n, _type *result)
Definition: algorithm.hpp:99
bounds & r
Definition: ydraw.h:220
void PutText(bool multi, _tParams &&...args)
打印文本。
Definition: TextRenderer.h:281
c yconstfn g
Definition: ystyle.h:104
#define YB_LIKELY(expr)
Definition: ydef.h:297
字体:字模,包含字型、样式和大小。
Definition: Font.h:546
std::uint16_t u16
Definition: yadaptor.h:68
颜色。
Definition: Video.h:339
static yconstexpr FontSize DefaultSize
Definition: Font.h:549
屏幕区域大小。
Definition: ygdibase.h:249
void Scroll(ptrdiff_t n)
缓冲区特效:整体移动 n 像素。
SDst GetTextLineHeightExOf(const TextState &ts)
取当前指定文本状态的字体设置对应的行高与行距之和。
Definition: TextBase.h:173
PDefHOp(TextState &,=, const PenStyle &ps) ImplRet(PenStyle void ResetPen()
赋值:笔样式。
Definition: TextBase.h:145
#define YAssert(_expr, _msg)
Definition: cassert.h:73
YF_API bool BlitTo(BitmapPtr, const CompactPixmapEx &, const Size &, const Point &, const Point &, const Size &, Rotation=RDeg0)
贴图:位图缓冲区向指针指定的缓冲区以贴图算法复制。
Definition: ygdi.cpp:253