From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- Doc/doxygen/html/_bitmap_8cpp_source.html | 1736 +++++++++++++++++++++++++++++ 1 file changed, 1736 insertions(+) create mode 100644 Doc/doxygen/html/_bitmap_8cpp_source.html (limited to 'Doc/doxygen/html/_bitmap_8cpp_source.html') diff --git a/Doc/doxygen/html/_bitmap_8cpp_source.html b/Doc/doxygen/html/_bitmap_8cpp_source.html new file mode 100644 index 0000000..de0e22e --- /dev/null +++ b/Doc/doxygen/html/_bitmap_8cpp_source.html @@ -0,0 +1,1736 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/nGenEx/Bitmap.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
Bitmap.cpp
+
+
+Go to the documentation of this file.
1 /* Project nGenEx
+
2  Destroyer Studios LLC
+
3  Copyright © 1997-2004. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: nGenEx.lib
+
6  FILE: Bitmap.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  Bitmap Resource class
+
13 */
+
14 
+
15 #include "MemDebug.h"
+
16 #include "Bitmap.h"
+
17 #include "Video.h"
+
18 #include "Color.h"
+
19 #include "Game.h"
+
20 
+
21 // +--------------------------------------------------------------------+
+
22 
+
23 DWORD GetRealTime();
+
24 
+
25 static inline void swap(int& a, int& b) { int tmp=a; a=b; b=tmp; }
+
26 static inline void sort(int& a, int& b) { if (a>b) swap(a,b); }
+
27 static inline void swap(double& a, double& b) { double tmp=a; a=b; b=tmp; }
+
28 static inline void sort(double& a, double& b) { if (a>b) swap(a,b); }
+
29 static void draw_strip(BYTE* dst, int pitch, int pixsize, int x, int y, int len, Color color);
+
30 static void draw_vline(BYTE* dst, int pitch, int pixsize, int x, int y, int len, Color color);
+
31 
+
32 class WinPlot
+
33 {
+
34 public:
+
35  WinPlot(Bitmap* bmp);
+
36  void plot(int x, int y, DWORD val, int exch=0);
+
37 
+
38 private:
+
39  BYTE* s;
+
40  int pitch, pixsize;
+
41 };
+
42 
+ +
44 {
+
45  s = bmp->GetSurface();
+
46  pitch = bmp->Pitch();
+
47  pixsize = bmp->PixSize();
+
48 }
+
49 
+
50 void WinPlot::plot(int x, int y, DWORD val, int exch)
+
51 {
+
52  if (exch) swap(x,y);
+
53  BYTE* dst = s + y*pitch + x*pixsize;
+
54 
+
55  switch (pixsize) {
+
56  case 1: *dst = (BYTE) val; break;
+
57  case 2: { LPWORD dst2 = (LPWORD) dst; *dst2 = (WORD) val; } break;
+
58  case 4: { LPDWORD dst4 = (LPDWORD) dst; *dst4 = (DWORD) val; } break;
+
59  }
+
60 }
+
61 
+
62 // +--------------------------------------------------------------------+
+
63 
+ +
65 : type(BMP_SOLID), width(0), height(0),
+
66 ownpix(false), alpha_loaded(false), texture(false),
+
67 pix(0), hipix(0), mapsize(0),
+
68 last_modified(0)
+
69 {
+
70  strcpy_s(filename, "Bitmap()");
+
71 }
+
72 
+
73 Bitmap::Bitmap(int w, int h, ColorIndex* p, int t)
+
74 : type(t), width(w), height(h),
+
75 ownpix(false), alpha_loaded(false), texture(false),
+
76 pix(p), hipix(0), mapsize(w*h),
+
77 last_modified(GetRealTime())
+
78 {
+
79  sprintf_s(filename, "Bitmap(%d, %d, index, type=%d)", w, h, (int) t);
+
80 }
+
81 
+
82 Bitmap::Bitmap(int w, int h, Color* p, int t)
+
83 : type(t), width(w), height(h),
+
84 ownpix(false), alpha_loaded(false), texture(false),
+
85 pix(0), hipix(p), mapsize(w*h),
+
86 last_modified(GetRealTime())
+
87 {
+
88  sprintf_s(filename, "Bitmap(%d, %d, hicolor, type=%d)", w, h, (int) t);
+
89 }
+
90 
+
91 // +--------------------------------------------------------------------+
+
92 
+ +
94 {
+
95  if (ownpix) {
+
96  delete [] pix;
+
97  delete [] hipix;
+
98  }
+
99 }
+
100 
+
101 // +--------------------------------------------------------------------+
+
102 
+
103 int
+ +
105 {
+
106  return mapsize * PixSize();
+
107 }
+
108 
+
109 int
+ +
111 {
+
112  return width;
+
113 }
+
114 
+
115 int
+ +
117 {
+
118  return width * PixSize();
+
119 }
+
120 
+
121 int
+ +
123 {
+
124  if (hipix)
+
125  return sizeof(Color);
+
126 
+
127  else if (pix)
+
128  return sizeof(ColorIndex);
+
129 
+
130  return 0;
+
131 }
+
132 
+
133 BYTE*
+ +
135 {
+
136  if (ownpix) {
+
137  if (hipix)
+
138  return (BYTE*) hipix;
+
139 
+
140  return (BYTE*) pix;
+
141  }
+
142 
+
143  return 0;
+
144 }
+
145 
+
146 // +--------------------------------------------------------------------+
+
147 
+
148 void
+
149 Bitmap::BitBlt(int x, int y, const Bitmap& srcBmp, int sx, int sy, int w, int h, bool blend)
+
150 {
+
151  if (!ownpix || x < 0 || y < 0 || x >= width || y >= height)
+
152  return;
+
153 
+
154  if (sx < 0 || sy < 0 || sx >= srcBmp.Width() || sy >= srcBmp.Height())
+
155  return;
+
156 
+
157  if (hipix) {
+
158  if (srcBmp.HiPixels()) {
+
159  int dpitch = width;
+
160  int spitch = srcBmp.Width();
+
161  int rowlen = w * sizeof(Color);
+
162  Color* dst = hipix + (y*dpitch) + x;
+
163  Color* src = srcBmp.HiPixels() + (sy*spitch) + sx;
+
164 
+
165  if (!blend) {
+
166  for (int i = 0; i < h; i++) {
+
167  memcpy(dst, src, rowlen);
+
168  dst += dpitch;
+
169  src += spitch;
+
170  }
+
171  }
+
172  else {
+
173  for (int i = 0; i < h; i++) {
+
174  Color* ps = src;
+
175  Color* pd = dst;
+
176 
+
177  for (int n = 0; n < w; n++) {
+
178  if (ps->Value())
+
179  pd->Set(Color::FormattedBlend(ps->Value(), pd->Value()));
+
180  ps++;
+
181  pd++;
+
182  }
+
183 
+
184  dst += dpitch;
+
185  src += spitch;
+
186  }
+
187  }
+
188  }
+
189 
+
190  else {
+
191  int dpitch = width;
+
192  int spitch = srcBmp.Width();
+
193  Color* dst = hipix + (y*dpitch) + x;
+
194  ColorIndex* src = srcBmp.Pixels() + (sy*spitch) + sx;
+
195 
+
196  if (!blend) {
+
197  for (int j = 0; j < h; j++) {
+
198  for (int i = 0; i < w; i++) {
+
199  dst[i].Set(src[i].Formatted());
+
200  }
+
201 
+
202  dst += dpitch;
+
203  src += spitch;
+
204  }
+
205  }
+
206  else {
+
207  for (int i = 0; i < h; i++) {
+
208  ColorIndex* ps = src;
+
209  Color* pd = dst;
+
210 
+
211  for (int n = 0; n < w; n++) {
+
212  if (ps->Index())
+
213  pd->Set(Color::FormattedBlend(ps->Formatted(), pd->Value()));
+
214  ps++;
+
215  pd++;
+
216  }
+
217  }
+
218 
+
219  dst += dpitch;
+
220  src += spitch;
+
221  }
+
222  }
+
223  }
+
224 
+
225  else if (pix) {
+
226  if (srcBmp.Pixels()) {
+
227  int dpitch = width;
+
228  int spitch = srcBmp.Width();
+
229  int rowlen = w;
+
230  Color* dst = hipix + (y*dpitch) + x;
+
231  Color* src = srcBmp.HiPixels() + (sy*spitch) + sx;
+
232 
+
233  for (int i = 0; i < h; i++) {
+
234 #pragma warning(suppress: 28183)
+
235  memcpy(dst, src, rowlen);
+
236  dst += dpitch;
+
237  src += spitch;
+
238  }
+
239  }
+
240  }
+
241 
+
242  alpha_loaded = srcBmp.alpha_loaded;
+ +
244 }
+
245 
+
246 // +--------------------------------------------------------------------+
+
247 
+
248 void
+ +
250 {
+
251  if (ownpix) {
+
252  delete [] pix;
+
253  delete [] hipix;
+
254  pix = 0;
+
255  hipix = 0;
+
256  }
+
257 
+
258  type = rhs.type;
+
259  width = rhs.width;
+
260  height = rhs.height;
+ +
262  texture = rhs.texture;
+
263  ownpix = true;
+
264 
+
265  mapsize = width * height;
+
266 
+
267  if (rhs.pix) {
+
268  pix = new(__FILE__,__LINE__) ColorIndex[mapsize];
+
269 
+
270  if (!pix) {
+
271  width = 0;
+
272  height = 0;
+
273  mapsize = 0;
+
274  }
+
275 
+
276  else {
+
277  memcpy(pix, rhs.pix, mapsize*sizeof(ColorIndex));
+
278  }
+
279  }
+
280 
+
281  if (rhs.hipix) {
+
282  hipix = new(__FILE__,__LINE__) Color[mapsize];
+
283 
+
284  if (!hipix && !pix) {
+
285  width = 0;
+
286  height = 0;
+
287  mapsize = 0;
+
288  }
+
289 
+
290  else {
+
291  memcpy(hipix, rhs.hipix, mapsize*sizeof(Color));
+
292  }
+
293  }
+
294 
+ +
296 }
+
297 
+
298 // +--------------------------------------------------------------------+
+
299 
+
300 void
+ +
302 {
+
303  if (ownpix) {
+
304  delete [] pix;
+
305  delete [] hipix;
+
306  pix = 0;
+
307  hipix = 0;
+
308  }
+
309 
+
310  type = BMP_SOLID;
+
311  width = 0;
+
312  height = 0;
+
313  mapsize = 0;
+
314  ownpix = false;
+
315  texture = false;
+
316 
+ +
318 }
+
319 
+
320 // +--------------------------------------------------------------------+
+
321 
+
322 void
+
323 Bitmap::CopyImage(int w, int h, BYTE* p, int t)
+
324 {
+
325  if (ownpix) {
+
326  delete [] pix;
+
327  pix = 0;
+
328  }
+
329  else {
+
330  hipix = 0;
+
331  }
+
332 
+
333  type = t;
+
334  width = w;
+
335  height = h;
+
336  ownpix = true;
+
337  texture = false;
+
338  mapsize = w * h;
+
339 
+
340  pix = new(__FILE__,__LINE__) ColorIndex[mapsize];
+
341 
+
342  if (!pix) {
+
343  width = 0;
+
344  height = 0;
+
345  mapsize = 0;
+
346  }
+
347 
+
348  else {
+
349  memcpy(pix, p, mapsize);
+
350  }
+
351 
+ +
353 }
+
354 
+
355 // +--------------------------------------------------------------------+
+
356 
+
357 void
+
358 Bitmap::CopyHighColorImage(int w, int h, DWORD* p, int t)
+
359 {
+
360  if (ownpix) {
+
361  delete [] hipix;
+
362  hipix = 0;
+
363  }
+
364  else {
+
365  pix = 0;
+
366  }
+
367 
+
368  type = t;
+
369  width = w;
+
370  height = h;
+
371  ownpix = true;
+
372  texture = false;
+
373  mapsize = w * h;
+
374 
+
375  hipix = new(__FILE__,__LINE__) Color[mapsize];
+
376 
+
377  if (!hipix) {
+
378  width = 0;
+
379  height = 0;
+
380  mapsize = 0;
+
381  }
+
382 
+
383  else {
+
384  memcpy(hipix, p, mapsize*sizeof(DWORD));
+
385  }
+
386 
+ +
388 }
+
389 
+
390 // +--------------------------------------------------------------------+
+
391 
+
392 void
+
393 Bitmap::CopyAlphaImage(int w, int h, BYTE* a)
+
394 {
+
395  if (!hipix || width != w || height != h)
+
396  return;
+
397 
+ +
399  alpha_loaded = true;
+
400 
+
401  Color* p = hipix;
+
402 
+
403  for (int i = 0; i < mapsize; i++) {
+
404  p->SetAlpha(*a);
+
405  p++;
+
406  a++;
+
407  }
+
408 
+ +
410 }
+
411 
+
412 void
+
413 Bitmap::CopyAlphaRedChannel(int w, int h, DWORD* a)
+
414 {
+
415  if (!hipix || width != w || height != h)
+
416  return;
+
417 
+ +
419  alpha_loaded = true;
+
420 
+
421  Color* p = hipix;
+
422 
+
423  for (int i = 0; i < mapsize; i++) {
+
424  p->SetAlpha((BYTE) ((*a & Color::RMask) >> Color::RShift));
+
425  p++;
+
426  a++;
+
427  }
+
428 
+ +
430 }
+
431 
+
432 // +--------------------------------------------------------------------+
+
433 
+
434 void
+
435 Bitmap::AutoMask(DWORD mask)
+
436 {
+
437  if (!hipix || !mapsize || alpha_loaded)
+
438  return;
+
439 
+ +
441  alpha_loaded = true;
+
442 
+
443  Color* p = hipix;
+
444  DWORD m = mask & Color::RGBMask;
+
445 
+
446  for (int i = 0; i < mapsize; i++) {
+
447  if ((p->Value() & Color::RGBMask) == m)
+
448  p->SetAlpha(0);
+
449  else
+
450  p->SetAlpha(255);
+
451 
+
452  p++;
+
453  }
+
454 
+ +
456 }
+
457 
+
458 // +--------------------------------------------------------------------+
+
459 
+
460 void
+ +
462 {
+
463  if (!width || !height)
+
464  return;
+
465 
+
466  if (pix) {
+
467  ColorIndex* p = pix;
+
468  BYTE index = c.Index();
+
469 
+
470  for (int i = 0; i < mapsize; i++)
+
471  *p++ = index;
+
472  }
+
473 
+
474  if (hipix) {
+
475  Color* p = hipix;
+
476  DWORD value = c.Value();
+
477 
+
478  for (int i = 0; i < mapsize; i++) {
+
479  p->Set(value);
+
480  p++;
+
481  }
+
482  }
+
483 
+ +
485 }
+
486 
+
487 // +--------------------------------------------------------------------+
+
488 
+
489 void
+
490 Bitmap::ScaleTo(int w, int h)
+
491 {
+
492  if (w < 1 || h < 1)
+
493  return;
+
494 
+
495  double dx = (double) width / (double) w;
+
496  double dy = (double) height / (double) h;
+
497 
+
498  bool mem_ok = true;
+
499 
+
500  if (hipix) {
+
501  Color* src = hipix;
+
502  Color* buf = new(__FILE__,__LINE__) Color[w*h];
+
503  Color* dst = buf;
+
504 
+
505  if (!buf) {
+
506  mem_ok = false;
+
507  }
+
508 
+
509  else {
+
510  for (int y = 0; y < h; y++) {
+
511  int y_offset = (int) (y * dy);
+
512  for (int x = 0; x < w; x++) {
+
513  int x_offset = (int) (x * dx);
+
514  src = hipix + (y_offset * width) + x_offset;
+
515  *dst++ = *src;
+
516  }
+
517  }
+
518 
+
519  if (ownpix)
+
520  delete [] hipix;
+
521 
+
522  hipix = buf;
+
523  ownpix = true;
+
524  }
+
525  }
+
526 
+
527  if (pix) {
+
528  ColorIndex* src = pix;
+
529  ColorIndex* buf = new(__FILE__,__LINE__) ColorIndex[w*h];
+
530  ColorIndex* dst = buf;
+
531 
+
532  if (!buf) {
+
533  mem_ok = false;
+
534  }
+
535 
+
536  else {
+
537  for (int y = 0; y < h; y++) {
+
538  int y_offset = (int) (y * dy);
+
539  for (int x = 0; x < w; x++) {
+
540  int x_offset = (int) (x * dx);
+
541  src = pix + (y_offset * width) + x_offset;
+
542  *dst++ = *src;
+
543  }
+
544  }
+
545 
+
546  if (ownpix)
+
547  delete [] pix;
+
548 
+
549  pix = buf;
+
550  ownpix = true;
+
551  }
+
552  }
+
553 
+
554  if (mem_ok) {
+
555  width = w;
+
556  height = h;
+
557  mapsize = width * height;
+
558  }
+
559 }
+
560 
+
561 // +--------------------------------------------------------------------+
+
562 
+
563 void
+ +
565 {
+
566  if (hipix) {
+
567  if (pix && ownpix)
+
568  delete [] pix;
+
569  pix = new(__FILE__,__LINE__) ColorIndex[mapsize];
+
570 
+
571  if (pix) {
+
572  Color* src = hipix;
+
573  ColorIndex* dst = pix;
+
574 
+
575  for (int y = 0; y < height; y++) {
+
576  for (int x = 0; x < width; x++) {
+
577  *dst++ = src->Index();
+
578  src++;
+
579  }
+
580  }
+
581 
+
582  if (!ownpix)
+
583  hipix = 0;
+
584 
+
585  ownpix = true;
+
586  }
+
587  }
+
588 }
+
589 
+
590 // +--------------------------------------------------------------------+
+
591 
+
592 void
+ +
594 {
+
595  if (pix) {
+
596  if (hipix && ownpix)
+
597  delete [] hipix;
+
598 
+
599  hipix = new(__FILE__,__LINE__) Color[mapsize];
+
600 
+
601  if (hipix) {
+
602  ColorIndex* src = pix;
+
603  Color* dst = hipix;
+
604 
+
605  for (int y = 0; y < height; y++) {
+
606  for (int x = 0; x < width; x++) {
+
607  *dst++ = src->Index();
+
608  src++;
+
609  }
+
610  }
+
611 
+
612  if (!ownpix)
+
613  pix = 0;
+
614 
+
615  ownpix = true;
+
616  }
+
617  }
+
618 }
+
619 
+
620 // +--------------------------------------------------------------------+
+
621 
+
622 static int FindBestTexSize(int n, int max_size)
+
623 {
+
624  int delta = 100000;
+
625  int best = 1;
+
626 
+
627  for (int i = 0; i < 12; i++) {
+
628  int size = 1 << i;
+
629 
+
630  if (size > max_size)
+
631  break;
+
632 
+
633  int dx = abs(n-size);
+
634 
+
635  if (size < n)
+
636  dx *= 4;
+
637 
+
638  if (dx < delta) {
+
639  delta = dx;
+
640  best = size;
+
641  }
+
642  }
+
643 
+
644  return best;
+
645 }
+
646 
+
647 void
+ +
649 {
+
650  if (width < 1 || height < 1 || (!pix && !hipix)) {
+
651  if (ownpix) {
+
652  delete [] pix;
+
653  delete [] hipix;
+
654  }
+
655 
+
656  width = 0;
+
657  height = 0;
+
658  pix = 0;
+
659  hipix = 0;
+
660  texture = false;
+
661  return;
+
662  }
+
663 
+
664  // texture surface format is 32-bit RGBA:
+
665  if (pix && !hipix) {
+
666  MakeHighColor();
+
667  }
+
668 
+
669  // check size and aspect ratio:
+
670  int max_tex_size = Game::MaxTexSize();
+
671  int max_tex_aspect = Game::MaxTexAspect();
+
672 
+
673  int best_width = FindBestTexSize(width, max_tex_size);
+
674  int best_height = FindBestTexSize(height, max_tex_size);
+
675  int aspect = 1;
+
676 
+
677  // correct sizes for aspect if necessary:
+
678  if (best_width > best_height) {
+
679  aspect = best_width / best_height;
+
680 
+
681  if (aspect > max_tex_aspect)
+
682  best_height = best_width / max_tex_aspect;
+
683  }
+
684 
+
685  else {
+
686  aspect = best_height / best_width;
+
687 
+
688  if (aspect > max_tex_aspect)
+
689  best_width = best_height / max_tex_aspect;
+
690  }
+
691 
+
692  // rescale if necessary:
+
693  if (width != best_width || height != best_height)
+
694  ScaleTo(best_width, best_width);
+
695 
+
696  texture = true;
+
697 }
+
698 
+
699 // +--------------------------------------------------------------------+
+
700 
+ +
702 Bitmap::GetIndex(int x, int y) const
+
703 {
+
704  ColorIndex result(0);
+
705 
+
706  if (x < 0 || y < 0 || x > width-1 || y > height-1)
+
707  return result;
+
708 
+
709  if (pix) {
+
710  result = *(pix + y*width + x);
+
711  }
+
712  else if (hipix) {
+
713  result = (hipix + y*width + x)->Index();
+
714  }
+
715 
+
716  return result;
+
717 }
+
718 
+
719 // +--------------------------------------------------------------------+
+
720 
+
721 Color
+
722 Bitmap::GetColor(int x, int y) const
+
723 {
+
724  Color result = Color::Black;
+
725 
+
726  if (x < 0 || y < 0 || x > width-1 || y > height-1)
+
727  return result;
+
728 
+
729  if (pix) {
+
730  result = (pix + y*width + x)->Index();
+
731  }
+
732  else if (hipix) {
+
733  result = *(hipix + y*width + x);
+
734  }
+
735 
+
736  return result;
+
737 }
+
738 
+
739 // +--------------------------------------------------------------------+
+
740 
+
741 void
+
742 Bitmap::SetIndex(int x, int y, ColorIndex c)
+
743 {
+
744  if (x < 0 || y < 0 || x > width || y > height)
+
745  return;
+
746 
+
747  if (pix) {
+
748  *(pix + y*width + x) = c;
+
749  }
+
750  else if (hipix) {
+
751  *(hipix + y*width + x) = c.Index();
+
752  }
+
753 
+ +
755 }
+
756 
+
757 // +--------------------------------------------------------------------+
+
758 
+
759 void
+
760 Bitmap::SetColor(int x, int y, Color c)
+
761 {
+
762  if (x < 0 || y < 0 || x > width || y > height)
+
763  return;
+
764 
+
765  if (pix) {
+
766  *(pix + y*width + x) = c.Index();
+
767  }
+
768  else if (hipix) {
+
769  *(hipix + y*width + x) = c;
+
770  }
+
771 
+ +
773 }
+
774 
+
775 // +--------------------------------------------------------------------+
+
776 
+
777 void
+
778 Bitmap::SetFilename(const char* s)
+
779 {
+
780  if (s) {
+
781  int n = strlen(s);
+
782 
+
783  if (n >= 60) {
+
784  ZeroMemory(filename, sizeof(filename));
+
785  strcpy_s(filename, "...");
+
786  strcat_s(filename, s + n - 59);
+
787  filename[63] = 0;
+
788  }
+
789 
+
790  else {
+
791  strcpy_s(filename, s);
+
792  }
+
793  }
+
794 }
+
795 
+
796 // +--------------------------------------------------------------------+
+
797 
+
798 Bitmap*
+ +
800 {
+
801  static Bitmap def;
+
802 
+
803  if (!def.width) {
+
804  def.width = def.height = 64;
+
805  def.mapsize = 64*64;
+
806  def.ownpix = true;
+
807  def.pix = new(__FILE__,__LINE__) ColorIndex[def.mapsize];
+
808 
+
809  // 8 bit palette mode
+
810  if (def.pix) {
+
811  ColorIndex* p = def.pix;
+
812 
+
813  for (int y = 0; y < 64; y++) {
+
814  for (int x = 0; x < 64; x++) {
+
815  double distance = sqrt((x-32.0)*(x-32.0) + (y-32.0)*(y-32.0));
+
816  if (distance > 31.0) distance = 31.0;
+
817  BYTE color = 24 + (BYTE) distance;
+
818 
+
819  if (x == 0 || y == 0) color = 255;
+
820  else if (x == 32 || y == 32) color = 251;
+
821 
+
822  *p++ = color;
+
823  }
+
824  }
+
825  }
+
826  }
+
827 
+
828  return &def;
+
829 }
+
830 
+
831 // +--------------------------------------------------------------------+
+
832 
+
833 static List<Bitmap> bitmap_cache;
+
834 
+
835 Bitmap*
+
836 Bitmap::GetBitmapByID(HANDLE bmp_id)
+
837 {
+
838  for (int i = 0; i < bitmap_cache.size(); i++) {
+
839  if (bitmap_cache[i]->Handle() == bmp_id) {
+
840  return bitmap_cache[i];
+
841  }
+
842  }
+
843 
+
844  return 0;
+
845 }
+
846 
+
847 Bitmap*
+
848 Bitmap::CheckCache(const char* filename)
+
849 {
+
850  for (int i = 0; i < bitmap_cache.size(); i++) {
+
851  if (!_stricmp(bitmap_cache[i]->GetFilename(), filename)) {
+
852  return bitmap_cache[i];
+
853  }
+
854  }
+
855 
+
856  return 0;
+
857 }
+
858 
+
859 void
+ +
861 {
+
862  bitmap_cache.append(bmp);
+
863 }
+
864 
+
865 void
+ +
867 {
+
868  for (int i = 0; i < bitmap_cache.size(); i++) {
+
869  Bitmap* bmp = bitmap_cache[i];
+
870 
+
871  if (bmp->IsTexture())
+
872  bmp->MakeTexture();
+
873  }
+
874 }
+
875 
+
876 void
+ +
878 {
+
879  bitmap_cache.destroy();
+
880 }
+
881 
+
882 DWORD
+ +
884 {
+
885  DWORD result = sizeof(bitmap_cache);
+
886  result += bitmap_cache.size() * sizeof(Bitmap*);
+
887 
+
888  for (int i = 0; i < bitmap_cache.size(); i++) {
+
889  Bitmap* bmp = bitmap_cache[i];
+
890 
+
891  if (bmp->pix)
+
892  result += bmp->mapsize * sizeof(ColorIndex);
+
893 
+
894  if (bmp->hipix)
+
895  result += bmp->mapsize * sizeof(Color);
+
896  }
+
897 
+
898  return result;
+
899 }
+
900 
+
901 // +--------------------------------------------------------------------+
+
902 
+
903 bool
+
904 Bitmap::ClipLine(int& x1, int& y1, int& x2, int& y2)
+
905 {
+
906  // vertical lines:
+
907  if (x1==x2) {
+
908  clip_vertical:
+
909  sort(y1,y2);
+
910  if (x1 < 0 || x1 >= width) return false;
+
911  if (y1 < 0) y1 = 0;
+
912  if (y2 >= height) y2 = height;
+
913  return true;
+
914  }
+
915 
+
916  // horizontal lines:
+
917  if (y1==y2) {
+
918  clip_horizontal:
+
919  sort(x1,x2);
+
920  if (y1 < 0 || y1 >= height) return false;
+
921  if (x1 < 0) x1 = 0;
+
922  if (x2 > width) x2 = width;
+
923  return true;
+
924  }
+
925 
+
926  // general lines:
+
927 
+
928  // sort left to right:
+
929  if (x1 > x2) {
+
930  swap(x1,x2);
+
931  swap(y1,y2);
+
932  }
+
933 
+
934  double m = (double)(y2-y1) / (double)(x2-x1);
+
935  double b = (double) y1 - (m * x1);
+
936 
+
937  // clip:
+
938  if (x1 < 0) { x1 = 0; y1 = (int) b; }
+
939  if (x1 >= width) return false;
+
940  if (x2 < 0) return false;
+
941  if (x2 > width-1) { x2 = width-1; y2 = (int) (m * x2 + b); }
+
942 
+
943  if (y1 < 0 && y2 < 0) return false;
+
944  if (y1 >= height && y2 >= height) return false;
+
945 
+
946  if (y1 < 0) { y1 = 0; x1 = (int) (-b/m); }
+
947  if (y1 >= height) { y1 = height-1; x1 = (int) ((y1-b)/m); }
+
948  if (y2 < 0) { y2 = 0; x2 = (int) (-b/m); }
+
949  if (y2 >= height) { y2 = height-1; x2 = (int) ((y2-b)/m); }
+
950 
+
951  if (x1 == x2)
+
952  goto clip_vertical;
+
953 
+
954  if (y1 == y2)
+
955  goto clip_horizontal;
+
956 
+
957  return true;
+
958 }
+
959 
+
960 // +--------------------------------------------------------------------+
+
961 
+
962 bool
+
963 Bitmap::ClipLine(double& x1, double& y1, double& x2, double& y2)
+
964 {
+
965  // vertical lines:
+
966  if (x1==x2) {
+
967  clip_vertical:
+
968  sort(y1,y2);
+
969  if (x1 < 0 || x1 >= width) return false;
+
970  if (y1 < 0) y1 = 0;
+
971  if (y2 >= height) y2 = height;
+
972  return true;
+
973  }
+
974 
+
975  // horizontal lines:
+
976  if (y1==y2) {
+
977  clip_horizontal:
+
978  sort(x1,x2);
+
979  if (y1 < 0 || y1 >= height) return false;
+
980  if (x1 < 0) x1 = 0;
+
981  if (x2 > width) x2 = width;
+
982  return true;
+
983  }
+
984 
+
985  // general lines:
+
986 
+
987  // sort left to right:
+
988  if (x1 > x2) {
+
989  swap(x1,x2);
+
990  swap(y1,y2);
+
991  }
+
992 
+
993  double m = (double)(y2-y1) / (double)(x2-x1);
+
994  double b = (double) y1 - (m * x1);
+
995 
+
996  // clip:
+
997  if (x1 < 0) { x1 = 0; y1 = b; }
+
998  if (x1 >= width) return false;
+
999  if (x2 < 0) return false;
+
1000  if (x2 > width-1) { x2 = width-1; y2 = (m * x2 + b); }
+
1001 
+
1002  if (y1 < 0 && y2 < 0) return false;
+
1003  if (y1 >= height && y2 >= height) return false;
+
1004 
+
1005  if (y1 < 0) { y1 = 0; x1 = (-b/m); }
+
1006  if (y1 >= height) { y1 = height-1; x1 = ((y1-b)/m); }
+
1007  if (y2 < 0) { y2 = 0; x2 = (-b/m); }
+
1008  if (y2 >= height) { y2 = height-1; x2 = ((y2-b)/m); }
+
1009 
+
1010  if (x1 == x2)
+
1011  goto clip_vertical;
+
1012 
+
1013  if (y1 == y2)
+
1014  goto clip_horizontal;
+
1015 
+
1016  return true;
+
1017 }
+
1018 
+
1019 // +--------------------------------------------------------------------+
+
1020 
+
1021 void
+
1022 Bitmap::DrawLine(int x1, int y1, int x2, int y2, Color color)
+
1023 {
+
1024  BYTE* s = GetSurface();
+
1025 
+
1026  if (!s) return;
+
1027 
+ +
1029 
+
1030  // vertical lines:
+
1031  if (x1==x2) {
+
1032  draw_vertical:
+
1033  sort(y1,y2);
+
1034  int fh = y2-y1;
+
1035  if (x1 < 0 || x1 >= width) return;
+
1036  if (y1 < 0) y1 = 0;
+
1037  if (y2 >= height) y2 = height;
+
1038  fh = y2-y1;
+
1039  draw_vline(s, Pitch(), PixSize(), x1, y1, fh, color);
+
1040  return;
+
1041  }
+
1042 
+
1043  // horizontal lines:
+
1044  if (y1==y2) {
+
1045  draw_horizontal:
+
1046  sort(x1,x2);
+
1047  int fw = x2-x1;
+
1048  if (y1 < 0 || y1 >= height) return;
+
1049  if (x1 < 0) x1 = 0;
+
1050  if (x2 > width) x2 = width;
+
1051  fw = x2-x1;
+
1052  draw_strip(s, Pitch(), PixSize(), x1, y1, fw, color);
+
1053  return;
+
1054  }
+
1055 
+
1056  // general lines:
+
1057 
+
1058  // sort left to right:
+
1059  if (x1 > x2) {
+
1060  swap(x1,x2);
+
1061  swap(y1,y2);
+
1062  }
+
1063 
+
1064  double m = (double)(y2-y1) / (double)(x2-x1);
+
1065  double b = (double) y1 - (m * x1);
+
1066 
+
1067  // clip:
+
1068  if (x1 < 0) { x1 = 0; y1 = (int) b; }
+
1069  if (x1 >= width) return;
+
1070  if (x2 < 0) return;
+
1071  if (x2 > width-1) { x2 = width-1; y2 = (int) (m * x2 + b); }
+
1072 
+
1073  if (y1 < 0 && y2 < 0) return;
+
1074  if (y1 >= height && y2 >= height) return;
+
1075 
+
1076  if (y1 < 0) { y1 = 0; x1 = (int) (-b/m); }
+
1077  if (y1 >= height) { y1 = height-1; x1 = (int) ((y1-b)/m); }
+
1078  if (y2 < 0) { y2 = 0; x2 = (int) (-b/m); }
+
1079  if (y2 >= height) { y2 = height-1; x2 = (int) ((y2-b)/m); }
+
1080 
+
1081  if (x1 > x2)
+
1082  return;
+
1083 
+
1084  if (x1 == x2)
+
1085  goto draw_vertical;
+
1086 
+
1087  if (y1 == y2)
+
1088  goto draw_horizontal;
+
1089 
+
1090  // plot the line using
+
1091  /*
+
1092  Symmetric Double Step Line Algorithm
+
1093  by Brian Wyvill
+
1094  from "Graphics Gems", Academic Press, 1990
+
1095 */
+
1096 
+
1097  WinPlot plotter(this);
+
1098 
+
1099  DWORD pix = color.Value();
+
1100  int sign_x=1, sign_y=1, step, reflect;
+
1101  int i, inc1, inc2, c, D, x_end, pixleft;
+
1102  int dx = x2 - x1;
+
1103  int dy = y2 - y1;
+
1104 
+
1105  if (dx < 0) {
+
1106  sign_x = -1;
+
1107  dx *= -1;
+
1108  }
+
1109  if (dy < 0) {
+
1110  sign_y = -1;
+
1111  dy *= -1;
+
1112  }
+
1113 
+
1114  // decide increment sign by the slope sign
+
1115  if (sign_x == sign_y)
+
1116  step = 1;
+
1117  else
+
1118  step = -1;
+
1119 
+
1120  if (dy > dx) { // chooses axis of greatest movement (make * dx)
+
1121  swap(x1, y1);
+
1122  swap(x2, y2);
+
1123  swap(dx, dy);
+
1124  reflect = 1;
+
1125  } else
+
1126  reflect = 0;
+
1127 
+
1128  if (x1 > x2) { // start from the smaller coordinate
+
1129  swap(x1,x2);
+
1130  swap(y1,y2);
+
1131  }
+
1132 
+
1133  /* Note dx=n implies 0 - n or (dx+1) pixels to be set */
+
1134  /* Go round loop dx/4 times then plot last 0,1,2 or 3 pixels */
+
1135  /* In fact (dx-1)/4 as 2 pixels are already plottted */
+
1136  x_end = (dx - 1) / 4;
+
1137  pixleft = (dx - 1) % 4; /* number of pixels left over at the end */
+
1138 
+
1139  plotter.plot(x1, y1, pix, reflect);
+
1140  plotter.plot(x2, y2, pix, reflect); /* plot first two points */
+
1141 
+
1142  inc2 = 4 * dy - 2 * dx;
+
1143  if (inc2 < 0) { /* slope less than 1/2 */
+
1144  c = 2 * dy;
+
1145  inc1 = 2 * c;
+
1146  D = inc1 - dx;
+
1147 
+
1148  for (i = 0; i < x_end; i++) { /* plotting loop */
+
1149  ++x1;
+
1150  --x2;
+
1151  if (D < 0) {
+
1152  /* pattern 1 forwards */
+
1153  plotter.plot(x1, y1, pix, reflect);
+
1154  plotter.plot(++x1, y1, pix, reflect);
+
1155  /* pattern 1 backwards */
+
1156  plotter.plot(x2, y2, pix, reflect);
+
1157  plotter.plot(--x2, y2, pix, reflect);
+
1158  D += inc1;
+
1159  }
+
1160  else {
+
1161  if (D < c) {
+
1162  /* pattern 2 forwards */
+
1163  plotter.plot(x1, y1, pix, reflect);
+
1164  plotter.plot(++x1, y1 += step, pix, reflect);
+
1165  /* pattern 2 backwards */
+
1166  plotter.plot(x2, y2, pix, reflect);
+
1167  plotter.plot(--x2, y2 -= step, pix, reflect);
+
1168  }
+
1169  else {
+
1170  /* pattern 3 forwards */
+
1171  plotter.plot(x1, y1 += step, pix, reflect);
+
1172  plotter.plot(++x1, y1, pix, reflect);
+
1173  /* pattern 3 backwards */
+
1174  plotter.plot(x2, y2 -= step, pix, reflect);
+
1175  plotter.plot(--x2, y2, pix, reflect);
+
1176  }
+
1177  D += inc2;
+
1178  }
+
1179  } /* end for */
+
1180 
+
1181  /* plot last pattern */
+
1182  if (pixleft) {
+
1183  if (D < 0) {
+
1184  plotter.plot(++x1, y1, pix, reflect); /* pattern 1 */
+
1185  if (pixleft > 1)
+
1186  plotter.plot(++x1, y1, pix, reflect);
+
1187  if (pixleft > 2)
+
1188  plotter.plot(--x2, y2, pix, reflect);
+
1189  }
+
1190  else {
+
1191  if (D < c) {
+
1192  plotter.plot(++x1, y1, pix, reflect); /* pattern 2 */
+
1193  if (pixleft > 1)
+
1194  plotter.plot(++x1, y1 += step, pix, reflect);
+
1195  if (pixleft > 2)
+
1196  plotter.plot(--x2, y2, pix, reflect);
+
1197  }
+
1198  else {
+
1199  /* pattern 3 */
+
1200  plotter.plot(++x1, y1 += step, pix, reflect);
+
1201  if (pixleft > 1)
+
1202  plotter.plot(++x1, y1, pix, reflect);
+
1203  if (pixleft > 2)
+
1204  plotter.plot(--x2, y2 -= step, pix, reflect);
+
1205  }
+
1206  }
+
1207  } /* end if pixleft */
+
1208  }
+
1209  /* end slope < 1/2 */
+
1210  else { /* slope greater than 1/2 */
+
1211  c = 2 * (dy - dx);
+
1212  inc1 = 2 * c;
+
1213  D = inc1 + dx;
+
1214  for (i = 0; i < x_end; i++) {
+
1215  ++x1;
+
1216  --x2;
+
1217  if (D > 0) {
+
1218  /* pattern 4 forwards */
+
1219  plotter.plot(x1, y1 += step, pix, reflect);
+
1220  plotter.plot(++x1, y1 += step, pix, reflect);
+
1221  /* pattern 4 backwards */
+
1222  plotter.plot(x2, y2 -= step, pix, reflect);
+
1223  plotter.plot(--x2, y2 -= step, pix, reflect);
+
1224  D += inc1;
+
1225  } else {
+
1226  if (D < c) {
+
1227  /* pattern 2 forwards */
+
1228  plotter.plot(x1, y1, pix, reflect);
+
1229  plotter.plot(++x1, y1 += step, pix, reflect);
+
1230 
+
1231  /* pattern 2 backwards */
+
1232  plotter.plot(x2, y2, pix, reflect);
+
1233  plotter.plot(--x2, y2 -= step, pix, reflect);
+
1234  } else {
+
1235  /* pattern 3 forwards */
+
1236  plotter.plot(x1, y1 += step, pix, reflect);
+
1237  plotter.plot(++x1, y1, pix, reflect);
+
1238  /* pattern 3 backwards */
+
1239  plotter.plot(x2, y2 -= step, pix, reflect);
+
1240  plotter.plot(--x2, y2, pix, reflect);
+
1241  }
+
1242  D += inc2;
+
1243  }
+
1244  } /* end for */
+
1245  /* plot last pattern */
+
1246  if (pixleft) {
+
1247  if (D > 0) {
+
1248  plotter.plot(++x1, y1 += step, pix, reflect); /* pattern 4 */
+
1249  if (pixleft > 1)
+
1250  plotter.plot(++x1, y1 += step, pix, reflect);
+
1251  if (pixleft > 2)
+
1252  plotter.plot(--x2, y2 -= step, pix, reflect);
+
1253  } else {
+
1254  if (D < c) {
+
1255  plotter.plot(++x1, y1, pix, reflect); /* pattern 2 */
+
1256  if (pixleft > 1)
+
1257  plotter.plot(++x1, y1 += step, pix, reflect);
+
1258  if (pixleft > 2)
+
1259  plotter.plot(--x2, y2, pix, reflect);
+
1260  } else {
+
1261  /* pattern 3 */
+
1262  plotter.plot(++x1, y1 += step, pix, reflect);
+
1263  if (pixleft > 1)
+
1264  plotter.plot(++x1, y1, pix, reflect);
+
1265  if (pixleft > 2) {
+
1266  if (D > c) /* step 3 */
+
1267  plotter.plot(--x2, y2 -= step, pix, reflect);
+
1268  else /* step 2 */
+
1269  plotter.plot(--x2, y2, pix, reflect);
+
1270  }
+
1271  }
+
1272  }
+
1273  }
+
1274  }
+
1275 }
+
1276 
+
1277 // +--------------------------------------------------------------------+
+
1278 
+
1279 void
+
1280 Bitmap::DrawRect(int x1, int y1, int x2, int y2, Color color)
+
1281 {
+
1282  sort(x1,x2);
+
1283  sort(y1,y2);
+
1284 
+
1285  int fw = x2-x1;
+
1286  int fh = y2-y1;
+
1287 
+
1288  if (fw == 0 || fh == 0) return;
+
1289 
+
1290  // perform clip
+
1291  int left = (x1 >= 0);
+
1292  int right = (x2 <= width);
+
1293  int top = (y1 >= 0);
+
1294  int bottom = (y2 <= height);
+
1295 
+
1296  BYTE* s = GetSurface();
+
1297  if (!s) return;
+
1298  int pitch = Pitch();
+
1299  int pixsize = PixSize();
+
1300 
+
1301  if (left) draw_vline(s, pitch, pixsize, x1, y1, fh, color);
+
1302  if (right) draw_vline(s, pitch, pixsize, x2, y1, fh, color);
+
1303  if (top) draw_strip(s, pitch, pixsize, x1, y1, fw, color);
+
1304  if (bottom) draw_strip(s, pitch, pixsize, x1, y2, fw, color);
+
1305 
+ +
1307 }
+
1308 
+
1309 // +--------------------------------------------------------------------+
+
1310 
+
1311 void
+
1312 Bitmap::DrawRect(const Rect& r, Color color)
+
1313 {
+
1314  if (r.w == 0 || r.h == 0) return;
+
1315 
+
1316  int x1 = r.x;
+
1317  int y1 = r.y;
+
1318  int x2 = r.x + r.w;
+
1319  int y2 = r.y + r.h;
+
1320 
+
1321  // perform clip
+
1322  int left = (x1 >= 0);
+
1323  int right = (x2 <= width);
+
1324  int top = (y1 >= 0);
+
1325  int bottom = (y2 <= height);
+
1326 
+
1327  BYTE* s = GetSurface();
+
1328  if (!s) return;
+
1329  int pitch = Pitch();
+
1330  int pixsize = PixSize();
+
1331 
+
1332  if (left) draw_vline(s, pitch, pixsize, x1, y1, r.h, color);
+
1333  if (right) draw_vline(s, pitch, pixsize, x2, y1, r.h, color);
+
1334  if (top) draw_strip(s, pitch, pixsize, x1, y1, r.w, color);
+
1335  if (bottom) draw_strip(s, pitch, pixsize, x1, y2, r.w, color);
+
1336 
+ +
1338 }
+
1339 
+
1340 // +--------------------------------------------------------------------+
+
1341 
+
1342 void
+
1343 Bitmap::FillRect(int x1, int y1, int x2, int y2, Color color)
+
1344 {
+
1345  // perform clip
+
1346  if (x1 < 0) x1 = 0;
+
1347  if (x2 > width-1) x2 = width-1;
+
1348  if (y1 < 0) y1 = 0;
+
1349  if (y2 > height) y2 = height;
+
1350 
+
1351  int fw = x2-x1;
+
1352  int fh = y2-y1;
+
1353 
+
1354  if (fw == 0 || fh == 0) return;
+
1355 
+
1356  BYTE* s = GetSurface();
+
1357  if (!s) return;
+
1358  int pitch = Pitch();
+
1359  int pixsize = PixSize();
+
1360 
+
1361  for (int i = 0; i < fh; i++)
+
1362  draw_strip(s, pitch, pixsize, x1, y1+i, fw, color);
+
1363 
+ +
1365 }
+
1366 
+
1367 // +--------------------------------------------------------------------+
+
1368 
+
1369 void
+
1370 Bitmap::FillRect(const Rect& r, Color color)
+
1371 {
+
1372  int x1 = r.x;
+
1373  int y1 = r.y;
+
1374  int x2 = r.x + r.w;
+
1375  int y2 = r.y + r.h;
+
1376 
+
1377  // perform clip
+
1378  if (x1 < 0) x1 = 0;
+
1379  if (x2 > width-1) x2 = width-1;
+
1380  if (y1 < 0) y1 = 0;
+
1381  if (y2 > height) y2 = height;
+
1382 
+
1383  int fw = x2-x1;
+
1384  int fh = y2-y1;
+
1385 
+
1386  if (fw == 0 || fh == 0) return;
+
1387 
+
1388  BYTE* s = GetSurface();
+
1389  if (!s) return;
+
1390  int pitch = Pitch();
+
1391  int pixsize = PixSize();
+
1392 
+
1393  for (int i = 0; i < fh; i++)
+
1394  draw_strip(s, pitch, pixsize, x1, y1+i, fw, color);
+
1395 
+ +
1397 }
+
1398 
+
1399 // +--------------------------------------------------------------------+
+
1400 
+
1401 void
+
1402 Bitmap::DrawEllipse(int x1, int y1, int x2, int y2, Color color, BYTE quad)
+
1403 {
+
1404  BYTE* orig = GetSurface();
+
1405  BYTE* s = orig;
+
1406 
+
1407  if (!s) return;
+
1408 
+
1409  sort(x1,x2);
+
1410  sort(y1,y2);
+
1411 
+
1412  int fw = x2-x1;
+
1413  int fh = y2-y1;
+
1414 
+
1415  if (fw < 1 || fh < 1) return;
+
1416 
+
1417  // clip:
+
1418  if (x1 >= width || x2 < 0) return;
+
1419  if (y1 >= height || y2 < 0) return;
+
1420 
+
1421  double a = fw / 2.0;
+
1422  double b = fh / 2.0;
+
1423  double a2 = a*a;
+
1424  double b2 = b*b;
+
1425 
+
1426  int x = 0;
+
1427  int y = (int) b;
+
1428  int x0 = (x1+x2)/2;
+
1429  int y0 = (y1+y2)/2;
+
1430 
+
1431  // clip super-giant ellipses:
+
1432  if (x1 < 0 && y1 < 0 && x2 > width && y2 > height) {
+
1433  double r2 = (a2<b2) ? a2 : b2;
+
1434 
+
1435  if (r2 > 32 * height)
+
1436  return;
+
1437 
+
1438  double ul = (x1-x0)*(x1-x0) + (y1-y0)*(y1-y0);
+
1439  double ur = (x2-x0)*(x2-x0) + (y1-y0)*(y1-y0);
+
1440  double ll = (x1-x0)*(x1-x0) + (y2-y0)*(y2-y0);
+
1441  double lr = (x2-x0)*(x2-x0) + (y2-y0)*(y2-y0);
+
1442 
+
1443  if (ul > r2 && ur > r2 && ll > r2 && lr > r2)
+
1444  return;
+
1445  }
+
1446 
+
1447  DrawEllipsePoints(x0,y0,x,y,color,quad);
+
1448 
+
1449  // region 1
+
1450  double d1 = (b2)-(a2*b)+(0.25*a2);
+
1451  while ((a2)*(y-0.5) > (b2)*(x+1)) {
+
1452  if (d1 < 0)
+
1453  d1 += b2*(2*x+3);
+
1454  else {
+
1455  d1 += b2*(2*x+3) + a2*(-2*y+2);
+
1456  y--;
+
1457  }
+
1458  x++;
+
1459 
+
1460  DrawEllipsePoints(x0,y0,x,y,color,quad);
+
1461  }
+
1462 
+
1463  // region 2
+
1464  double d2 = b2*(x+0.5)*(x+0.5) + a2*(y-1)*(y-1) - a2*b2;
+
1465  while (y > 0) {
+
1466  if (d2 < 0) {
+
1467  d2 += b2*(2*x+2) + a2*(-2*y+3);
+
1468  x++;
+
1469  }
+
1470  else
+
1471  d2 += a2*(-2*y+3);
+
1472  y--;
+
1473 
+
1474  DrawEllipsePoints(x0,y0,x,y,color,quad);
+
1475  }
+
1476 
+ +
1478 }
+
1479 
+
1480 void
+
1481 Bitmap::DrawEllipsePoints(int x0, int y0, int x, int y, Color c, BYTE quad)
+
1482 {
+
1483  BYTE* s = GetSurface();
+
1484 
+
1485  if (!s) return;
+
1486 
+
1487  int pitch = Pitch();
+
1488  int pixsize = PixSize();
+
1489 
+
1490  int left = x0-x;
+
1491  int right = x0+x+1;
+
1492  int top = y0-y;
+
1493  int bottom = y0+y+1;
+
1494 
+
1495  // clip:
+
1496  if (left >= width || right < 0) return;
+
1497  if (top >= height || bottom < 0) return;
+
1498 
+
1499  BYTE* dst = 0;
+
1500  DWORD cf = c.Value();
+
1501 
+
1502  if (left >= 0 && top >= 0 && quad&1) {
+
1503  dst = s + top*pitch + left*pixsize;
+
1504 
+
1505  switch (pixsize) {
+
1506  case 1: *dst = (BYTE) cf; break;
+
1507  case 2: { LPWORD sw = (LPWORD) dst; *sw = (WORD) cf; } break;
+
1508  case 4: { LPDWORD sd = (LPDWORD) dst; *sd = (DWORD) cf; } break;
+
1509  }
+
1510  }
+
1511 
+
1512  if (right < width && top >= 0 && quad&2) {
+
1513  dst = s + top*pitch + right*pixsize;
+
1514 
+
1515  switch (pixsize) {
+
1516  case 1: *dst = (BYTE) cf; break;
+
1517  case 2: { LPWORD sw = (LPWORD) dst; *sw = (WORD) cf; } break;
+
1518  case 4: { LPDWORD sd = (LPDWORD) dst; *sd = (DWORD) cf; } break;
+
1519  }
+
1520  }
+
1521 
+
1522  if (left >= 0 && bottom < height && quad&4) {
+
1523  dst = s + bottom*pitch + left*pixsize;
+
1524 
+
1525  switch (pixsize) {
+
1526  case 1: *dst = (BYTE) cf; break;
+
1527  case 2: { LPWORD sw = (LPWORD) dst; *sw = (WORD) cf; } break;
+
1528  case 4: { LPDWORD sd = (LPDWORD) dst; *sd = (DWORD) cf; } break;
+
1529  }
+
1530  }
+
1531 
+
1532  if (right < width && bottom < height && quad&4) {
+
1533  dst = s + bottom*pitch + right*pixsize;
+
1534 
+
1535  switch (pixsize) {
+
1536  case 1: *dst = (BYTE) cf; break;
+
1537  case 2: { LPWORD sw = (LPWORD) dst; *sw = (WORD) cf; } break;
+
1538  case 4: { LPDWORD sd = (LPDWORD) dst; *sd = (DWORD) cf; } break;
+
1539  }
+
1540  }
+
1541 }
+
1542 
+
1543 // +--------------------------------------------------------------------+
+
1544 
+
1545 static void draw_strip(BYTE* s, int pitch, int pixsize, int x, int y, int len, Color color)
+
1546 {
+
1547  if (!s) return;
+
1548  s += y*pitch + x*pixsize;
+
1549 
+
1550  DWORD value = color.Formatted();
+
1551 
+
1552  switch (pixsize) {
+
1553  case 1: {
+
1554  if (len > 1)
+
1555  memset(s, (BYTE) value, len);
+
1556  }
+
1557  break;
+
1558 
+
1559  case 2: {
+
1560  LPWORD sw = (LPWORD) s;
+
1561  for (int x = 0; x < len; x++) {
+
1562  *sw++ = (WORD) value;
+
1563  }
+
1564  }
+
1565  break;
+
1566 
+
1567  case 4: {
+
1568  Color* sd = (Color*) s;
+
1569  for (int x = 0; x < len; x++) {
+
1570  *sd++ = color;
+
1571  }
+
1572  }
+
1573  break;
+
1574  }
+
1575 }
+
1576 
+
1577 // +--------------------------------------------------------------------+
+
1578 
+
1579 static void draw_vline(BYTE* s, int pitch, int pixsize, int x, int y, int len, Color color)
+
1580 {
+
1581  if (!s) return;
+
1582  s += (y)*pitch + (x)*pixsize;
+
1583 
+
1584  DWORD value = color.Formatted();
+
1585 
+
1586  switch (pixsize) {
+
1587  case 1: {
+
1588  for (int y = 0; y < len; y++) {
+
1589  *s = (BYTE) value;
+
1590  s += pitch;
+
1591  }
+
1592  }
+
1593  break;
+
1594 
+
1595  case 2: {
+
1596  LPWORD sw = (LPWORD) s;
+
1597  pitch /= 2;
+
1598 
+
1599  for (int y = 0; y < len; y++) {
+
1600  *sw = (WORD) value;
+
1601  sw += pitch;
+
1602  }
+
1603  }
+
1604  break;
+
1605 
+
1606  case 4: {
+
1607  Color* sd = (Color*) s;
+
1608  pitch /= 4;
+
1609 
+
1610  for (int y = 0; y < len; y++) {
+
1611  *sd = color;
+
1612  sd += pitch;
+
1613  }
+
1614  }
+
1615  break;
+
1616  }
+
1617 }
+
1618 
+
1619 
+
+
+ + + + -- cgit v1.1