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 
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
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
186 {
187  decltype(GetAreaOf(GetSize())) s(w * h);
188 
189  if(YB_UNLIKELY(s == 0))
190  {
192  pBuffer = nullptr;
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
228 {
229  const u32 t = GetAreaOf(size);
230 
231  ClearPixel(pBuffer, 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