YSTest: ygdi.cpp 源文件

YSTest PreAlpha_b400_20130424 The YSLib Test Project

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

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
ygdi.cpp
浏览该文件的文档.
1 ﻿/*
2 Copyright by FrankHB 2009 - 2013.
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/ygdi.h"
29 #include "YSLib/Service/yblit.h"
30
31 using namespace ystdex;
32
33 YSL_BEGIN
34
35 YSL_BEGIN_NAMESPACE(Drawing)
36
37 Rect
38 operator+(const Rect& r, const Padding& m)
39 {
40 return Rect(r.X + m.Left, r.Y + m.Top,
41 max<int>(0, r.Width - m.Left - m.Right),
42 max<int>(0, r.Height - m.Top - m.Bottom));
43 }
44
45
46 Padding
47 FetchMargin(const Rect& r, const Size& s)
48 {
49 return Padding(r.X, s.Width - r.X - r.Width,
50 r.Y, s.Height - r.Y - r.Height);
51 }
52
53
54 Point
55 ClipBounds(Rect& clip, const Rect& bounds)
56 {
57 if(!clip.IsUnstrictlyEmpty() && Clip(clip, bounds)
58 && !clip.IsUnstrictlyEmpty())
59 return clip.GetPoint() - bounds.GetPoint();
60 clip.GetSizeRef() = {};
61 return {};
62 }
63
64 Point
65 ClipMargin(PaintContext& pc, const Padding& m, const Size& ss)
66 {
67 const Size& ds(pc.Target.GetSize());
68
69 if(GetHorizontalOf(m) < ds.Width && GetVerticalOf(m) < ds.Height)
70 {
71 const auto& pt(pc.Location);
72 const Point dp(max<int>(m.Left, pt.X), max<int>(m.Top, pt.Y));
73 const Point sp(dp - pt);
74 const auto scx(min<int>(ss.Width, ds.Width - m.Right - dp.X) - sp.X),
75 scy(min<int>(ss.Height, ds.Height - m.Bottom - dp.Y) - sp.Y);
76
77 if(scx > 0 && scy > 0)
78 {
79 pc.ClipArea &= Rect(dp, scx, scy);
80 return pc.ClipArea.GetPoint() - pt;
81 }
82 }
83 pc.ClipArea.GetSizeRef() = {};
84 return {};
85 }
86
87
88 BitmapBuffer::BitmapBuffer(ConstBitmapPtr i, SDst w, SDst h)
89 : Graphics()
90 //不能提前初始化 size ，否则指针非空和面积非零状态不一致。
91 {
92 SetSize(w, h);
93 if(i)
94 std::copy_n(i, GetAreaOf(GetSize()), pBuffer);
95 }
96 BitmapBuffer::BitmapBuffer(const BitmapBuffer& buf)
97 : Graphics()
98 {
99 SetSize(buf.GetWidth(), buf.GetHeight());
100 if(const auto p = buf.GetBufferPtr())
101 std::copy_n(p, GetAreaOf(GetSize()), pBuffer);
102 }
103 BitmapBuffer::BitmapBuffer(BitmapBuffer&& buf) ynothrow
104 : Graphics(nullptr, buf.GetSize())
105 {
106 // TODO: Change Graphics::SetSize interface.
107 // buf.SetSize(0, 0);
108 std::swap<Graphics>(*this, buf);
109 }
110
111 void
112 BitmapBuffer::SetContent(ConstBitmapPtr s, SDst w, SDst h)
113 {
114 SetSize(w, h);
115 if(YB_LIKELY(pBuffer && s))
116 std::copy_n(s, GetAreaOf(GetSize()), pBuffer);
117 }
118 void
119 BitmapBuffer::SetSize(SDst w, SDst h)
120 {
121 decltype(GetAreaOf(GetSize())) s(w * h);
122
123 if(YB_UNLIKELY(s == 0))
124 {
125 ydelete_array(pBuffer);
126 pBuffer = nullptr;
127 }
128 else if(GetAreaOf(GetSize()) < s)
129 try
130 {
131 BitmapPtr pBufferNew(ynew PixelType[s]);
132
133 std::swap(pBuffer, pBufferNew);
134 ydelete_array(pBufferNew);
135 }
136 catch(std::bad_alloc&)
137 {
138 throw LoggedEvent("Allocation failed.", 1);
139 }
140
141 YAssert(!((pBuffer != nullptr) ^ (s != 0)), "Buffer corruptied.");
142
143 yunseq(size.Width = w, size.Height = h);
144 ClearImage();
145 }
146 void
147 BitmapBuffer::SetSizeSwap()
148 {
149 std::swap(size.Width, size.Height);
150 ClearImage();
151 }
152
153 void
154 BitmapBuffer::ClearImage() const
155 {
156 Drawing::ClearImage(*this);
157 }
158
159
160 BitmapBufferEx::BitmapBufferEx(ConstBitmapPtr i, SDst w, SDst h)
161 : BitmapBuffer(), pBufferAlpha()
162 {
163 SetSize(w, h);
164 if(i)
165 std::copy_n(i, GetAreaOf(GetSize()), pBuffer);
166 }
167 BitmapBufferEx::BitmapBufferEx(const BitmapBufferEx& buf)
168 : BitmapBuffer(), pBufferAlpha()
169 {
170 SetSize(buf.GetWidth(), buf.GetHeight());
171 if(const auto p = buf.GetBufferPtr())
172 {
173 std::copy_n(p, GetAreaOf(GetSize()), pBuffer),
174 std::copy_n(buf.GetBufferAlphaPtr(), GetAreaOf(GetSize()),
175 pBufferAlpha);
176 }
177 }
178 BitmapBufferEx::BitmapBufferEx(BitmapBufferEx&& buf) ynothrow
179 : BitmapBuffer(std::move(buf)), pBufferAlpha(buf.GetBufferAlphaPtr())
180 {
181 buf.pBufferAlpha = nullptr;
182 }
183
184 void
185 BitmapBufferEx::SetSize(SDst w, SDst h)
186 {
187 decltype(GetAreaOf(GetSize())) s(w * h);
188
189 if(YB_UNLIKELY(s == 0))
190 {
191 ydelete_array(pBuffer);
192 pBuffer = nullptr;
193 ydelete_array(pBufferAlpha);
194 pBufferAlpha = nullptr;
195 }
196 else if(GetAreaOf(size) < s)
197 {
198 BitmapPtr pBufferNew(nullptr);
199
200 try
201 {
202 pBufferNew = ynew PixelType[s];
203
204 u8* pBufferAlphaNew(ynew u8[s]);
205
206 std::swap(pBuffer, pBufferNew);
207 ydelete_array(pBufferNew);
208 std::swap(pBufferAlpha, pBufferAlphaNew);
209 ydelete_array(pBufferAlphaNew);
210 }
211 catch(std::bad_alloc&)
212 {
213 ydelete_array(pBufferNew);
214 throw LoggedEvent("Allocation failed.", 1);
215 }
216 }
217
218 YAssert(!((pBuffer != nullptr) ^ (s != 0)), "Buffer corruptied.");
219 YAssert(!((pBufferAlpha != nullptr) ^ (s != 0)), "Buffer corruptied.");
220
221 size.Width = w;
222 size.Height = h;
223 ClearImage();
224 }
225
226 void
227 BitmapBufferEx::ClearImage() const
228 {
229 const u32 t = GetAreaOf(size);
230
231 ClearPixel(pBuffer, t);
232 ClearPixel(pBufferAlpha, t);
233 }
234
235 bool
236 CopyTo(BitmapPtr dst, const Graphics& g, const Size& ds,
237 const Point& dp, const Point& sp, const Size& sc, Rotation rot)
238 {
239 if(~rot & 1 && dst && bool(g))
240 {
241 (rot == RDeg0
242 ? Blit<BlitLoop, false, false, BitmapPtr, ConstBitmapPtr>
243 : Blit<BlitLoop, true, true, BitmapPtr, ConstBitmapPtr>)(
244 dst, ds, g.GetBufferPtr(), g.GetSize(), dp, sp, sc);
245 return true;
246 }
247 return false;
248 }
249 bool
250 CopyTo(BitmapPtr dst, const BitmapBufferEx& buf, const Size& ds,
251 const Point& dp, const Point& sp, const Size& sc, Rotation rot)
252 {
253 if(~rot & 1 && dst && bool(buf))
254 {
255 (rot == RDeg0
256 ? Blit<BlitTransparentLoop, false, false, BitmapPtr, IteratorPair>
257 : Blit<BlitTransparentLoop, true, true, BitmapPtr, IteratorPair>)(
258 dst, ds, IteratorPair(buf.GetBufferPtr(), buf.GetBufferAlphaPtr()),
259 buf.GetSize(), dp, sp, sc);
260 return true;
261 }
262 return false;
263 }
264
265 bool
266 BlitTo(BitmapPtr dst, const BitmapBufferEx& buf, const Size& ds,
267 const Point& dp, const Point& sp, const Size& sc, Rotation rot)
268 {
269 if(~rot & 1 && dst && bool(buf))
270 {
271 (rot == RDeg0
272 ? Blit<BlitBlendLoop, false, false, BitmapPtr, IteratorPair>
273 : Blit<BlitBlendLoop, true, true, BitmapPtr, IteratorPair>)(
274 dst, ds, IteratorPair(buf.GetBufferPtr(), buf.GetBufferAlphaPtr()),
275 buf.GetSize(), dp, sp, sc);
276 return true;
277 }
278 return false;
279 }
280
281 YSL_END_NAMESPACE(Drawing)
282
283 YSL_END
284