YSTest: YDraw.cpp 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

YDraw.cpp
浏览该文件的文档.
1 /*
2 © 2011-2016, 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_YDraw
30 #include YFM_YSLib_Service_YBlit
31
32 namespace YSLib
33 {
34
35 namespace Drawing
36 {
37
38 void
39 PlotHLineSeg(BitmapPtr dst, const Rect& bounds, SDst w, SPos y, SPos x1,
40 SPos x2, Color c)
41 {
42 YAssert(bounds.Width <= w, "Wrong boundary or width found.");
43 // XXX: Conversion to 'SPos' might be implementation-defined.
44 if(!bounds.IsUnstrictlyEmpty()
45 && IsInInterval(SPos(y - bounds.Y), SPos(bounds.Height)))
46 {
47 const SPos bx(bounds.X), bxw(bounds.GetRight());
48
49 if(!((x1 < bx && x2 < bx)
50 || (x1 >= 0 && x2 >= 0 && x1 >= bxw && x2 >= bxw)))
51 {
52 RestrictInInterval(x1, bx, bxw),
53 RestrictInInterval(x2, bx, SPos(bxw + 1));
54 RestrictLessEqual(x1, x2);
55 // XXX: Conversion to 'SPos' might be implementation-defined.
56 FillPixels<Pixel>(&Nonnull(dst)[y * ptrdiff_t(w) + x1],
57 SDst(x2 - x1), c);
58 }
59 }
60 }
61
62 void
63 PlotVLineSeg(BitmapPtr dst, const Rect& bounds, SDst w, SPos x, SPos y1,
64 SPos y2, Color c)
65 {
66 YAssert(bounds.Width <= w, "Wrong boundary or width found.");
67 // XXX: Conversion to 'SPos' might be implementation-defined.
68 if(!bounds.IsUnstrictlyEmpty()
69 && IsInInterval(SPos(x - bounds.X), SPos(bounds.Width)))
70 {
71 const SPos by(bounds.Y), byh(bounds.GetBottom());
72
73 if(!((y1 < by && y2 < by)
74 || (y1 >= 0 && y2 >= 0 && y1 >= byh && y2 >= byh)))
75 {
76 RestrictInInterval(y1, by, byh),
77 RestrictInInterval(y2, by, SPos(byh + 1));
78 RestrictLessEqual(y1, y2);
79 // XXX: Conversion to 'SPos' might be implementation-defined.
80 FillVerticalLine<Pixel>(&Nonnull(dst)[y1 * ptrdiff_t(w) + x],
81 SDst(y2 - y1), w, c);
82 }
83 }
84 }
85
86 void
87 PlotLineSeg(BitmapPtr dst, const Rect& bounds, SDst w, SPos x1, SPos y1,
88 SPos x2, SPos y2, Color c)
89 {
90 if(y1 == y2)
91 PlotHLineSeg(dst, bounds, w, y1, x1, x2 + 1, c);
92 else if(x1 == x2)
93 PlotVLineSeg(dst, bounds, w, x1, y1, y2 + 1, c);
94 else
95 {
96 /*
97 一般 Bresenham 算法：实现自
98 http://cg.sjtu.edu.cn/lecture_site/chap2/mainframe212.htm 伪代码。
99 */
100 //起点 (x1, y1) 和终点 (x2, y2) 不同。
101
102 const std::int8_t sx(FetchSign(x2 - x1)), sy(FetchSign(y2 - y1));
103 SDst dx(SDst(abs(x2 - x1))), dy(SDst(abs(y2 - y1)));
104 bool f(dy > dx);
105
106 if(f)
107 std::swap(dx, dy);
108
109 //初始化误差项以补偿非零截断。
110 // XXX: Conversion to 'SPos' might be implementation-defined.
111 const SPos dx2(SPos(dx << 1)), dy2(SPos(dy << 1));
112 SPos e(dy2 - SPos(dx));
113
114 //主循环。
115 while(dx-- != 0)
116 {
117 PlotPixel(dst, bounds, w, x1, y1, c);
118 if(e >= 0)
119 {
120 if(f)
121 x1 += sx;
122 else
123 y1 += sy;
124 e -= dx2;
125 }
126 if(f)
127 y1 += sy;
128 else
129 x1 += sx;
130 e += dy2;
131 }
132 }
133 }
134
135 void
136 DrawRect(const Graphics& g, const Rect& bounds, const Rect& r, Color c)
137 {
138 const SPos x1(r.X), y1(r.Y), x2(r.GetRight() - 1), y2(r.GetBottom() - 1);
139
140 if(YB_LIKELY(x1 < x2 && y1 < y2))
141 {
142 DrawVLineSeg(g, bounds, x1, y1, y2, c),
143 DrawHLineSeg(g, bounds, y2, x1, x2 + 1, c),
144 DrawVLineSeg(g, bounds, x2, y1, y2, c),
145 DrawHLineSeg(g, bounds, y1, x1, x2, c);
146 }
147 }
148
149 void
150 FillRect(const Graphics& g, const Rect& r, Color c)
151 {
152 YAssert(bool(g), "Invalid graphics context found.");
153 FillRectRaw(g.GetBufferPtr(), Pixel(c), g.GetSize(), r);
154 }
155
156 namespace
157 {
158
160 void
161 PlotCircle(void(*plotter)(const Graphics&, const Rect&, SPos, SPos, SPos, SPos,
162 Color), const Graphics& g, const Rect& bounds, const Point& pt, SDst r,
163 Color c)
164 {
165 YAssertNonnull(plotter),
166 YAssert(bounds.IsUnstrictlyEmpty() || Rect(g.GetSize()).Contains(bounds),
167 "The boundary is out of the buffer.");
168 if(r != 0)
169 // Bresenham circle algorithm implementation.
170 // See http://willperone.net/Code/codecircle.php.
171 // XXX: Conversion to 'SPos' might be implementation-defined.
172 for(SPos x(0), y((SPos(r))), p(SPos(3 - 2 * r)); y >= x;
173 p += p < 0 ? (4 * x++ + 6) : (4 * (x++ - y--) + 10))
174 plotter(g, bounds, pt.X, pt.Y, x, y, c);
175 }
176
177 } // unnamed namespace;
178
179 void
180 DrawCircle(const Graphics& g_, const Rect& bounds_, const Point& pt, SDst r,
181 Color c_)
182 {
183 PlotCircle([](const Graphics& g, const Rect& bounds, SPos x, SPos y,
184 SPos dx, SPos dy, Color c){
185 using namespace std;
186 using namespace placeholders;
187 const auto plot(bind(PlotPixel, g.GetBufferPtr(), std::cref(bounds),
188 g.GetWidth(), _1, _2, c));
189
190 plot(x + dx, y + dy),
191 plot(x - dx, y + dy),
192 plot(x - dx, y - dy),
193 plot(x + dx, y - dy),
194 plot(x + dy, y + dx),
195 plot(x - dy, y + dx),
196 plot(x - dy, y - dx),
197 plot(x + dy, y - dx);
198 }, g_, bounds_, pt, r, c_);
199 }
200
201 void
202 FillCircle(const Graphics& g_, const Rect& bounds_, const Point& pt, SDst r,
203 Color c_)
204 {
205 PlotCircle([](const Graphics& g, const Rect& bounds, SPos x, SPos y,
206 SPos dx, SPos dy, Color c){
207 using namespace std;
208 using namespace placeholders;
209 const auto plot(bind(PlotHLineSeg, g.GetBufferPtr(), std::cref(bounds),
210 g.GetWidth(), _1, _2, _3, c));
211
212 plot(y + dy, x - dx, x + dx + 1),
213 plot(y - dy, x - dx, x + dx + 1),
214 plot(y + dx, x - dy, x + dy + 1),
215 plot(y - dx, x - dy, x + dy + 1);
216 }, g_, bounds_, pt, r, c_);
217 }
218
219 } // namespace Drawing;
220
221 } // namespace YSLib;
222
YSLib::Drawing::FillRectRaw
void FillRectRaw(_tOut dst, _tPixel c, _tParams &&... args)
使用指定像素填充指定的标准矩形区域。
Definition: YBlit.h:549
YSLib::Drawing::SPos
YB_ATTR_nodiscard yconstfn YB_PURE x x x Bottom YB_ATTR_nodiscard yconstfn YB_PURE x Right y x Top y x Bottom y Bottom YB_ATTR_nodiscard yconstfn YB_PURE x Right y x Top y x Bottom y Bottom YB_ATTR_nodiscard yconstfn YB_PURE SPos(x.Right *ptrdiff_t(n))
YSLib::Drawing::Color
The boundary is out of the const Rect SDst SPos SPos SPos Color
Definition: YDraw.h:128
CHRLib::e
const char const char * e
Definition: CharacterProcessing.h:112
YSLib::Drawing::PlotVLineSeg
The boundary is out of the PlotVLineSeg(g.GetBufferPtr(), bounds, g.GetWidth(), x, y1, y2, c)) YF_API void PlotLineSeg(BitmapPtr dst
绘制线段：在宽 w 的缓冲区内的区域 bounds 绘制端点为 p1(x1, y1) 和 p2(x2, y2) 的线段。
YSLib::RestrictInInterval
void RestrictInInterval(_type &i, const _type &a, const _type &b) ynothrow
约束整数 i 在左闭右开区间 [a, b) 中。
Definition: YCoreUtilities.h:221
platform::Nonnull
YB_PURE _type && Nonnull(_type &&p) ynothrowv
断言并返回非空参数。
Definition: Debug.h:518
ystdex::cpp2017::swap
void swap(optional< _type > &x, optional< _type > &y)
Definition: optional.h:888
YSLib::Drawing::Rect::Width
SDst Width
长。
Definition: YGDIBase.h:545
YSLib::Drawing::y2
The boundary is out of the const Rect SDst SPos SPos SPos y2
Definition: YDraw.h:128
YSLib::RestrictLessEqual
void RestrictLessEqual(_type &a, _type &b) ynothrow
约束关系：a ≤ b 。
Definition: YCoreUtilities.h:267
YSLib::Drawing::FillRect
c YF_API void FillRect(const Graphics &g, const Rect &r, Color c)
填充标准矩形。
Definition: YDraw.cpp:150
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::x1
The boundary is out of the const Rect SDst SPos x1
Definition: YDraw.h:148
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::PlotHLineSeg
The boundary is out of the PlotHLineSeg(g.GetBufferPtr(), bounds, g.GetWidth(), y, x1, x2, c)) YF_API void PlotVLineSeg(BitmapPtr dst
绘制竖直线段：在宽 w 的缓冲区内的区域 bounds 绘制指定竖直水平坐标 x ， 竖直坐标 y1 - 1 、 y2 。
YSLib::Drawing::x
const TextState &ts const TextState &ts const TextState &ts TextState SPos x
Definition: TextBase.h:190
YSLib::Drawing::PlotLineSeg
The boundary is out of the PlotLineSeg(g.GetBufferPtr(), bounds, g.GetWidth(), x1, y1, x2, y2, c)) inline PDefH(void
ystdex::cref
lref< const _type > cref(const _type &t)
Definition: ref.hpp:130
YSLib::Drawing::x2
The boundary is out of the const Rect SDst SPos SPos SPos x2
Definition: YDraw.h:149
CHRLib::f
f(d, s)
YModules.h
YSLib 服务模块配置文件。
YSLib::Drawing::g
The boundary is out of the const Graphics & g
Definition: YDraw.h:161
YSLib::Drawing::Rect::Contains
YB_ATTR_nodiscard YB_PURE bool Contains(SPos px, SPos py) const ynothrow
判断点 (px, py) 是否在矩形内或边上。
Definition: YGDIBase.cpp:91
YSLib::Drawing::DrawCircle
bounds c YF_API void DrawCircle(const Graphics &g, const Rect &bounds, const Point &, SDst, Color)
描画圆形。
Definition: YDraw.cpp:180
YSLib::YAssert
YAssert(!(v< Deref(a)), "Value less than lower bound found.")
YSLib::Drawing::GGraphics
二维图形接口上下文模板。
Definition: YGraphics.h:63
std
Definition: optional.h:982
YAssertNonnull
#define YAssertNonnull(_expr)
Definition: cassert.h:165
YSLib::Drawing::GBinaryGroup< SPos >
platform::SDst
std::uint16_t SDst
屏幕坐标距离。
Definition: Video.h:44
YSLib::Drawing::FillCircle
YF_API void FillCircle(const Graphics &g, const Rect &bounds, const Point &, SDst, Color)
填充圆形。
Definition: YDraw.cpp:202
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
YSLib::Drawing::GBinaryGroup::X
_type X
分量。
Definition: YGDIBase.h:305
YSLib::Drawing::Rect
屏幕标准矩形：表示屏幕矩形区域。
Definition: YGDIBase.h:788
YSLib
YSLib 命名空间。
Definition: AndroidHost.h:46
YB_LIKELY
#define YB_LIKELY(_expr)
Definition: ydef.h:827
YSLib::Drawing::Rect::Height
SDst Height
宽。
Definition: YGDIBase.h:545
YSLib::Drawing::y1
The boundary is out of the const Rect SDst SPos SPos y1
Definition: YDraw.h:127
YSLib::IsInInterval
YB_STATELESS bool IsInInterval(_type i, _type b) ynothrow
判断 i 是否在左闭右开区间 [_type(0), b) 中。
Definition: YCoreUtilities.h:85
YSLib::Drawing::bounds
The boundary is out of the const Rect & bounds
Definition: YDraw.h:127
YSLib::Drawing::w
The boundary is out of the const Rect SDst w
Definition: YDraw.h:127
YSLib::Drawing::GBinaryGroup::Y
_type Y
Definition: YGDIBase.h:305
platform::p
return p p
Definition: YCLib/FileSystem.h:209
platform::SPos
std::int16_t SPos
屏幕坐标度量。
Definition: Video.h:43
NPL::dst
YF_API const char src const string const char * dst
Definition: Dependency.h:96
YSLib::Drawing::BitmapPtr
Pixel * BitmapPtr
Definition: YGraphics.h:42
YSLib::Drawing::DrawRect
void DrawRect(const Graphics &g, const Rect &bounds, const Rect &r, Color c)
Definition: YDraw.cpp:136
YSLib::FetchSign
YB_STATELESS yconstfn std::int_fast8_t FetchSign(_type a, _type b=_type(0)) ynothrow
符号函数。
Definition: YCoreUtilities.h:46