YSTest: ydraw.cpp 源文件

YSTest PreAlpha_b500_20140530 The YSLib Test Project

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

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
ydraw.cpp
浏览该文件的文档.
1 /*
2 © 2011-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_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 YAssertNonnull(dst),
43 YAssert(bounds.Width <= w, "Wrong boundary or width found.");
44 if(!bounds.IsUnstrictlyEmpty()
45 && IsInInterval<SPos>(y - bounds.Y, bounds.Height))
46 {
47 const auto bx(bounds.X);
48 const auto bxw(bx + bounds.Width);
49
50 if(!((x1 < bx && x2 < bx) || (x1 >= bxw && x2 >= bxw)))
51 {
52 RestrictInInterval(x1, bx, bxw),
53 RestrictInInterval(x2, bx, bxw + 1);
54 RestrictLessEqual(x1, x2);
55 FillPixel<PixelType>(&dst[y * w + x1], x2 - x1, c);
56 }
57 }
58 }
59
60 void
61 PlotVLineSeg(BitmapPtr dst, const Rect& bounds, SDst w, SPos x, SPos y1,
62 SPos y2, Color c)
63 {
64 YAssertNonnull(dst),
65 YAssert(bounds.Width <= w, "Wrong boundary or width found.");
66 if(!bounds.IsUnstrictlyEmpty()
67 && IsInInterval<SPos>(x - bounds.X, bounds.Width))
68 {
69 const auto by(bounds.Y);
70 const auto byh(by + bounds.Height);
71
72 if(!((y1 < by && y2 < by) || (y1 >= byh && y2 >= byh)))
73 {
74 RestrictInInterval(y1, by, byh),
75 RestrictInInterval(y2, by, byh + 1);
76 RestrictLessEqual(y1, y2);
77 FillVerticalLine<PixelType>(&dst[y1 * w + x], y2 - y1, w, c);
78 }
79 }
80 }
81
82 void
83 PlotLineSeg(BitmapPtr dst, const Rect& bounds, SDst w, SPos x1, SPos y1,
84 SPos x2, SPos y2, Color c)
85 {
86 if(y1 == y2)
87 PlotHLineSeg(dst, bounds, w, y1, x1, x2 + 1, c);
88 else if(x1 == x2)
89 PlotVLineSeg(dst, bounds, w, x1, y1, y2 + 1, c);
90 else
91 {
92 /*
93 一般 Bresenham 算法：实现自
94 http://cg.sjtu.edu.cn/lecture_site/chap2/mainframe212.htm 伪代码。
95 */
96 //起点 (x1, y1) 和终点 (x2, y2) 不同。
97
98 const s8 sx(FetchSign(x2 - x1)), sy(FetchSign(y2 - y1));
99 SDst dx(std::abs(x2 - x1)), dy(std::abs(y2 - y1));
100 bool f(dy > dx);
101
102 if(f)
103 std::swap(dx, dy);
104
105 //初始化误差项以补偿非零截断。
106 const SDst dx2(dx << 1), dy2(dy << 1);
107 int e(dy2 - dx);
108
109 //主循环。
110 while(dx-- != 0)
111 {
112 PlotPixel(dst, bounds, w, x1, y1, c);
113 if(e >= 0)
114 {
115 if(f)
116 x1 += sx;
117 else
118 y1 += sy;
119 e -= dx2;
120 }
121 if(f)
122 y1 += sy;
123 else
124 x1 += sx;
125 e += dy2;
126 }
127 }
128 }
129
130 void
131 DrawRect(const Graphics& g, const Rect& bounds, const Point& pt, const Size& s,
132 Color c)
133 {
134 const SPos x1(pt.X), y1(pt.Y), x2(x1 + s.Width - 1), y2(y1 + s.Height - 1);
135
136 if(YB_LIKELY(x1 < x2 && y1 < y2))
137 {
138 DrawVLineSeg(g, bounds, x1, y1, y2, c),
139 DrawHLineSeg(g, bounds, y2, x1, x2 + 1, c),
140 DrawVLineSeg(g, bounds, x2, y1, y2, c),
141 DrawHLineSeg(g, bounds, y1, x1, x2, c);
142 }
143 }
144
145 void
146 FillRect(const Graphics& g, const Rect& r, Color c)
147 {
148 YAssert(bool(g), "Invalid graphics context found.");
149 FillRectRaw<PixelType>(g.GetBufferPtr(), g.GetSize(), r, c);
150 }
151
152 namespace
153 {
154
156 void
157 PlotCircle(void(*plotter)(const Graphics&, const Rect&, SPos, SPos, SDst, SDst,
158 Color), const Graphics& g, const Rect& bounds, const Point& pt, SDst r,
159 Color c)
160 {
161 YAssertNonnull(plotter);
162 if(r != 0)
163 // Bresenham circle algorithm implementation.
164 // See http://willperone.net/Code/codecircle.php .
165 for(SPos x(0), y(r), p(3 - 2 * r); y >= x;
166 p += p < 0 ? (4 * x++ + 6) : (4 * (x++ - y--) + 10))
167 plotter(g, bounds, pt.X, pt.Y, x, y, c);
168 }
169
170 } // unnamed namespace;
171
172 void
173 DrawCircle(const Graphics& g, const Rect& bounds, const Point& pt, SDst r,
174 Color c)
175 {
176 PlotCircle([](const Graphics& g, const Rect& bounds, SPos x, SPos y,
177 SDst dx, SDst dy, Color c){
178 using namespace std;
179 using namespace placeholders;
180 const auto plot(bind(PlotPixel, g.GetBufferPtr(), cref(bounds),
181 g.GetWidth(), _1, _2, c));
182
183 plot(x + dx, y + dy),
184 plot(x - dx, y + dy),
185 plot(x - dx, y - dy),
186 plot(x + dx, y - dy),
187 plot(x + dy, y + dx),
188 plot(x - dy, y + dx),
189 plot(x - dy, y - dx),
190 plot(x + dy, y - dx);
191 }, g, bounds, pt, r, c);
192 }
193
194 void
195 FillCircle(const Graphics& g, const Rect& bounds, const Point& pt, SDst r,
196 Color c)
197 {
198 PlotCircle([](const Graphics& g, const Rect& bounds, SPos x, SPos y,
199 SDst dx, SDst dy, Color c){
200 using namespace std;
201 using namespace placeholders;
202 const auto plot(bind(PlotHLineSeg, g.GetBufferPtr(), cref(bounds),
203 g.GetWidth(), _1, _2, _3, c));
204
205 plot(y + dy, x - dx, x + dx + 1),
206 plot(y - dy, x - dx, x + dx + 1),
207 plot(y + dx, x - dy, x + dy + 1),
208 plot(y - dx, x - dy, x + dy + 1);
209 }, g, bounds, pt, r, c);
210 }
211
212 } // namespace Drawing;
213
214 } // namespace YSLib;
215
YSLib::Drawing::DrawVLineSeg
void DrawVLineSeg(const Graphics &g, const Rect &bounds, SPos x, SPos y1, SPos y2, Color c)
描画竖直线段。
Definition: ydraw.h:153
YSLib::Drawing::FillCircle
YF_API void FillCircle(const Graphics &, const Rect &, const Point &, SDst, Color c)
填充圆形。
Definition: ydraw.cpp:195
YSLib::Drawing::FillRect
YF_API void FillRect(const Graphics &g, const Rect &, Color c)
填充标准矩形。
Definition: ydraw.cpp:146
YSLib::Drawing::bounds
bounds
Definition: ydraw.h:188
YSLib::Drawing::PlotLineSeg
YF_API void PlotLineSeg(BitmapPtr dst, const Rect &bounds, SDst w, SPos x1, SPos y1, SPos x2, SPos y2, Color)
绘制线段：在宽 w 的缓冲区内的区域 bounds 绘制端点为 p1(x1, y1) 和 p2(x2, y2) 的线段。 ...
Definition: ydraw.cpp:83
YSLib::Drawing::Size::Height
SDst Height
宽和高。
Definition: ygdibase.h:258
platform::SDst
std::uint16_t SDst
屏幕坐标距离。
Definition: Video.h:39
platform::SPos
std::int16_t SPos
屏幕坐标度量。
Definition: Video.h:38
ystdex::swap
void swap(any &x, any &y)
交换对象。
Definition: any.h:729
YSLib::Drawing::DrawCircle
bounds c YF_API void DrawCircle(const Graphics &, const Rect &, const Point &, SDst, Color c)
描画圆形。
Definition: ydraw.cpp:173
YSLib::Drawing::DrawHLineSeg
void DrawHLineSeg(const Graphics &g, const Rect &bounds, SPos y, SPos x1, SPos x2, Color c)
描画水平线段。
Definition: ydraw.h:128
YSLib::Drawing::GBinaryGroup::Y
_type Y
分量。
Definition: ygdibase.h:59
YSLib::FetchSign
yconstfn s8 FetchSign(int a, int b=0) ynothrow
整数类型符号函数。
Definition: ycutil.h:89
YSLib::Drawing::Rect
屏幕标准矩形：表示屏幕矩形区域。
Definition: ygdibase.h:416
YSLib::s8
std::int8_t s8
Definition: yadaptor.h:71
YSLib::RestrictLessEqual
void RestrictLessEqual(_type &a, _type &b) ynothrow
约束关系：a ≤ b 。
Definition: ycutil.h:327
YSLib::Drawing::GBinaryGroup< SPos >
YAssertNonnull
#define YAssertNonnull(_expr)
Definition: cassert.h:81
YSLib::Drawing::GBinaryGroup::X
_type X
Definition: ygdibase.h:59
YSLib::Drawing::Graphics
二维图形接口上下文。
Definition: ygdibase.h:721
YSLib::UI::f
_tWidget _fCallable && f
Definition: ywgtevt.h:597
YSLib::Drawing::PlotPixel
void PlotPixel(BitmapPtr dst, const Rect &bounds, SDst w, SPos x, SPos y, Color c)
绘制指定位置的像素：(x, y) 。
Definition: ydraw.h:89
YSLib::Drawing::PlotVLineSeg
YF_API void PlotVLineSeg(BitmapPtr dst, const Rect &bounds, SDst w, SPos x, SPos y1, SPos y2, Color)
绘制竖直线段：在宽 w 的缓冲区内的区域 bounds 绘制指定竖直水平坐标 x ， 竖直坐标 y1 - 1 、 y2 。 ...
Definition: ydraw.cpp:61
platform_ex::Windows::s
return s
Definition: MinGW32.cpp:49
YSLib::Drawing::c
c
Definition: ystyle.h:93
YSLib::RestrictInInterval
void RestrictInInterval(_type &i, int a, int b) ynothrow
约束整数 i 在左闭右开区间 [a, b) 中。
Definition: ycutil.h:283
platform::BitmapPtr
PixelType * BitmapPtr
Definition: Video.h:295
YSLib::Drawing::r
bounds & r
Definition: ydraw.h:220
YSLib::Drawing::g
c yconstfn g
Definition: ystyle.h:104
YB_LIKELY
#define YB_LIKELY(expr)
Definition: ydef.h:297
platform::Color
颜色。
Definition: Video.h:339
YModules.h
YSLib::Drawing::Size
屏幕区域大小。
Definition: ygdibase.h:249
YSLib::Drawing::Size::Width
SDst Width
Definition: ygdibase.h:258
YSLib::Drawing::DrawRect
p1 p1 p2 p2 c YF_API void DrawRect(const Graphics &g, const Rect &bounds, const Point &pt, const Size &s, Color c)
描画标准矩形。
Definition: ydraw.cpp:131
YAssert
#define YAssert(_expr, _msg)
Definition: cassert.h:73
YSLib::Drawing::PlotHLineSeg
YF_API void PlotHLineSeg(BitmapPtr dst, const Rect &bounds, SDst w, SPos y, SPos x1, SPos x2, Color)
绘制水平线段：在宽 w 的缓冲区内的区域 bounds 绘制指定端点水平坐标 x1 、 x2 - 1 ，竖直坐标 y 。 ...
Definition: ydraw.cpp:39