Anti-Grain Geometry - AGG (libagg)
2.5
|
00001 //---------------------------------------------------------------------------- 00002 // Anti-Grain Geometry (AGG) - Version 2.5 00003 // A high quality rendering engine for C++ 00004 // Copyright (C) 2002-2006 Maxim Shemanarev 00005 // Contact: mcseem@antigrain.com 00006 // mcseemagg@yahoo.com 00007 // http://antigrain.com 00008 // 00009 // AGG is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU General Public License 00011 // as published by the Free Software Foundation; either version 2 00012 // of the License, or (at your option) any later version. 00013 // 00014 // AGG is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with AGG; if not, write to the Free Software 00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00022 // MA 02110-1301, USA. 00023 //---------------------------------------------------------------------------- 00024 // 00025 // Adaptation for 32-bit screen coordinates has been sponsored by 00026 // Liberty Technology Systems, Inc., visit http://lib-sys.com 00027 // 00028 // Liberty Technology Systems, Inc. is the provider of 00029 // PostScript and PDF technology for software developers. 00030 // 00031 //---------------------------------------------------------------------------- 00032 00033 00034 #ifndef AGG_SCANLINE_STORAGE_BIN_INCLUDED 00035 #define AGG_SCANLINE_STORAGE_BIN_INCLUDED 00036 00037 #include <string.h> 00038 #include <stdlib.h> 00039 #include <math.h> 00040 #include "agg_array.h" 00041 00042 00043 namespace agg 00044 { 00045 00046 //-----------------------------------------------scanline_storage_bin 00047 class scanline_storage_bin 00048 { 00049 public: 00050 //--------------------------------------------------------------- 00051 struct span_data 00052 { 00053 int32 x; 00054 int32 len; 00055 }; 00056 00057 //--------------------------------------------------------------- 00058 struct scanline_data 00059 { 00060 int y; 00061 unsigned num_spans; 00062 unsigned start_span; 00063 }; 00064 00065 00066 //--------------------------------------------------------------- 00067 class embedded_scanline 00068 { 00069 public: 00070 00071 //----------------------------------------------------------- 00072 class const_iterator 00073 { 00074 public: 00075 const_iterator() : m_storage(0) {} 00076 const_iterator(const embedded_scanline& sl) : 00077 m_storage(sl.m_storage), 00078 m_span_idx(sl.m_scanline.start_span) 00079 { 00080 m_span = m_storage->span_by_index(m_span_idx); 00081 } 00082 00083 const span_data& operator*() const { return m_span; } 00084 const span_data* operator->() const { return &m_span; } 00085 00086 void operator ++ () 00087 { 00088 ++m_span_idx; 00089 m_span = m_storage->span_by_index(m_span_idx); 00090 } 00091 00092 private: 00093 const scanline_storage_bin* m_storage; 00094 unsigned m_span_idx; 00095 span_data m_span; 00096 }; 00097 00098 friend class const_iterator; 00099 00100 00101 //----------------------------------------------------------- 00102 embedded_scanline(const scanline_storage_bin& storage) : 00103 m_storage(&storage) 00104 { 00105 setup(0); 00106 } 00107 00108 //----------------------------------------------------------- 00109 void reset(int, int) {} 00110 unsigned num_spans() const { return m_scanline.num_spans; } 00111 int y() const { return m_scanline.y; } 00112 const_iterator begin() const { return const_iterator(*this); } 00113 00114 //----------------------------------------------------------- 00115 void setup(unsigned scanline_idx) 00116 { 00117 m_scanline_idx = scanline_idx; 00118 m_scanline = m_storage->scanline_by_index(m_scanline_idx); 00119 } 00120 00121 private: 00122 const scanline_storage_bin* m_storage; 00123 scanline_data m_scanline; 00124 unsigned m_scanline_idx; 00125 }; 00126 00127 00128 //--------------------------------------------------------------- 00129 scanline_storage_bin() : 00130 m_spans(256-2), // Block increment size 00131 m_scanlines(), 00132 m_min_x( 0x7FFFFFFF), 00133 m_min_y( 0x7FFFFFFF), 00134 m_max_x(-0x7FFFFFFF), 00135 m_max_y(-0x7FFFFFFF), 00136 m_cur_scanline(0) 00137 { 00138 m_fake_scanline.y = 0; 00139 m_fake_scanline.num_spans = 0; 00140 m_fake_scanline.start_span = 0; 00141 m_fake_span.x = 0; 00142 m_fake_span.len = 0; 00143 } 00144 00145 // Renderer Interface 00146 //--------------------------------------------------------------- 00147 void prepare() 00148 { 00149 m_scanlines.remove_all(); 00150 m_spans.remove_all(); 00151 m_min_x = 0x7FFFFFFF; 00152 m_min_y = 0x7FFFFFFF; 00153 m_max_x = -0x7FFFFFFF; 00154 m_max_y = -0x7FFFFFFF; 00155 m_cur_scanline = 0; 00156 } 00157 00158 //--------------------------------------------------------------- 00159 template<class Scanline> void render(const Scanline& sl) 00160 { 00161 scanline_data sl_this; 00162 00163 int y = sl.y(); 00164 if(y < m_min_y) m_min_y = y; 00165 if(y > m_max_y) m_max_y = y; 00166 00167 sl_this.y = y; 00168 sl_this.num_spans = sl.num_spans(); 00169 sl_this.start_span = m_spans.size(); 00170 typename Scanline::const_iterator span_iterator = sl.begin(); 00171 00172 unsigned num_spans = sl_this.num_spans; 00173 for(;;) 00174 { 00175 span_data sp; 00176 sp.x = span_iterator->x; 00177 sp.len = (int32)abs((int)(span_iterator->len)); 00178 m_spans.add(sp); 00179 int x1 = sp.x; 00180 int x2 = sp.x + sp.len - 1; 00181 if(x1 < m_min_x) m_min_x = x1; 00182 if(x2 > m_max_x) m_max_x = x2; 00183 if(--num_spans == 0) break; 00184 ++span_iterator; 00185 } 00186 m_scanlines.add(sl_this); 00187 } 00188 00189 00190 //--------------------------------------------------------------- 00191 // Iterate scanlines interface 00192 int min_x() const { return m_min_x; } 00193 int min_y() const { return m_min_y; } 00194 int max_x() const { return m_max_x; } 00195 int max_y() const { return m_max_y; } 00196 00197 //--------------------------------------------------------------- 00198 bool rewind_scanlines() 00199 { 00200 m_cur_scanline = 0; 00201 return m_scanlines.size() > 0; 00202 } 00203 00204 00205 //--------------------------------------------------------------- 00206 template<class Scanline> bool sweep_scanline(Scanline& sl) 00207 { 00208 sl.reset_spans(); 00209 for(;;) 00210 { 00211 if(m_cur_scanline >= m_scanlines.size()) return false; 00212 const scanline_data& sl_this = m_scanlines[m_cur_scanline]; 00213 00214 unsigned num_spans = sl_this.num_spans; 00215 unsigned span_idx = sl_this.start_span; 00216 do 00217 { 00218 const span_data& sp = m_spans[span_idx++]; 00219 sl.add_span(sp.x, sp.len, cover_full); 00220 } 00221 while(--num_spans); 00222 00223 ++m_cur_scanline; 00224 if(sl.num_spans()) 00225 { 00226 sl.finalize(sl_this.y); 00227 break; 00228 } 00229 } 00230 return true; 00231 } 00232 00233 00234 //--------------------------------------------------------------- 00235 // Specialization for embedded_scanline 00236 bool sweep_scanline(embedded_scanline& sl) 00237 { 00238 do 00239 { 00240 if(m_cur_scanline >= m_scanlines.size()) return false; 00241 sl.setup(m_cur_scanline); 00242 ++m_cur_scanline; 00243 } 00244 while(sl.num_spans() == 0); 00245 return true; 00246 } 00247 00248 00249 //--------------------------------------------------------------- 00250 unsigned byte_size() const 00251 { 00252 unsigned i; 00253 unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y 00254 00255 for(i = 0; i < m_scanlines.size(); ++i) 00256 { 00257 size += sizeof(int32) * 2 + // Y, num_spans 00258 unsigned(m_scanlines[i].num_spans) * sizeof(int32) * 2; // X, span_len 00259 } 00260 return size; 00261 } 00262 00263 00264 //--------------------------------------------------------------- 00265 static void write_int32(int8u* dst, int32 val) 00266 { 00267 dst[0] = ((const int8u*)&val)[0]; 00268 dst[1] = ((const int8u*)&val)[1]; 00269 dst[2] = ((const int8u*)&val)[2]; 00270 dst[3] = ((const int8u*)&val)[3]; 00271 } 00272 00273 00274 //--------------------------------------------------------------- 00275 void serialize(int8u* data) const 00276 { 00277 unsigned i; 00278 00279 write_int32(data, min_x()); // min_x 00280 data += sizeof(int32); 00281 write_int32(data, min_y()); // min_y 00282 data += sizeof(int32); 00283 write_int32(data, max_x()); // max_x 00284 data += sizeof(int32); 00285 write_int32(data, max_y()); // max_y 00286 data += sizeof(int32); 00287 00288 for(i = 0; i < m_scanlines.size(); ++i) 00289 { 00290 const scanline_data& sl_this = m_scanlines[i]; 00291 00292 write_int32(data, sl_this.y); // Y 00293 data += sizeof(int32); 00294 00295 write_int32(data, sl_this.num_spans); // num_spans 00296 data += sizeof(int32); 00297 00298 unsigned num_spans = sl_this.num_spans; 00299 unsigned span_idx = sl_this.start_span; 00300 do 00301 { 00302 const span_data& sp = m_spans[span_idx++]; 00303 00304 write_int32(data, sp.x); // X 00305 data += sizeof(int32); 00306 00307 write_int32(data, sp.len); // len 00308 data += sizeof(int32); 00309 } 00310 while(--num_spans); 00311 } 00312 } 00313 00314 00315 //--------------------------------------------------------------- 00316 const scanline_data& scanline_by_index(unsigned i) const 00317 { 00318 return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline; 00319 } 00320 00321 //--------------------------------------------------------------- 00322 const span_data& span_by_index(unsigned i) const 00323 { 00324 return (i < m_spans.size()) ? m_spans[i] : m_fake_span; 00325 } 00326 00327 00328 private: 00329 pod_bvector<span_data, 10> m_spans; 00330 pod_bvector<scanline_data, 8> m_scanlines; 00331 span_data m_fake_span; 00332 scanline_data m_fake_scanline; 00333 int m_min_x; 00334 int m_min_y; 00335 int m_max_x; 00336 int m_max_y; 00337 unsigned m_cur_scanline; 00338 }; 00339 00340 00341 00342 00343 00344 00345 00346 00347 00348 00349 00350 00351 00352 //---------------------------------------serialized_scanlines_adaptor_bin 00353 class serialized_scanlines_adaptor_bin 00354 { 00355 public: 00356 typedef bool cover_type; 00357 00358 //-------------------------------------------------------------------- 00359 class embedded_scanline 00360 { 00361 public: 00362 00363 //---------------------------------------------------------------- 00364 class const_iterator 00365 { 00366 public: 00367 struct span 00368 { 00369 int32 x; 00370 int32 len; 00371 }; 00372 00373 const_iterator() : m_ptr(0) {} 00374 const_iterator(const embedded_scanline& sl) : 00375 m_ptr(sl.m_ptr), 00376 m_dx(sl.m_dx) 00377 { 00378 m_span.x = read_int32() + m_dx; 00379 m_span.len = read_int32(); 00380 } 00381 00382 const span& operator*() const { return m_span; } 00383 const span* operator->() const { return &m_span; } 00384 00385 void operator ++ () 00386 { 00387 m_span.x = read_int32() + m_dx; 00388 m_span.len = read_int32(); 00389 } 00390 00391 private: 00392 int read_int32() 00393 { 00394 int32 val; 00395 ((int8u*)&val)[0] = *m_ptr++; 00396 ((int8u*)&val)[1] = *m_ptr++; 00397 ((int8u*)&val)[2] = *m_ptr++; 00398 ((int8u*)&val)[3] = *m_ptr++; 00399 return val; 00400 } 00401 00402 const int8u* m_ptr; 00403 span m_span; 00404 int m_dx; 00405 }; 00406 00407 friend class const_iterator; 00408 00409 00410 //---------------------------------------------------------------- 00411 embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {} 00412 00413 //---------------------------------------------------------------- 00414 void reset(int, int) {} 00415 unsigned num_spans() const { return m_num_spans; } 00416 int y() const { return m_y; } 00417 const_iterator begin() const { return const_iterator(*this); } 00418 00419 00420 private: 00421 //---------------------------------------------------------------- 00422 int read_int32() 00423 { 00424 int32 val; 00425 ((int8u*)&val)[0] = *m_ptr++; 00426 ((int8u*)&val)[1] = *m_ptr++; 00427 ((int8u*)&val)[2] = *m_ptr++; 00428 ((int8u*)&val)[3] = *m_ptr++; 00429 return val; 00430 } 00431 00432 public: 00433 //---------------------------------------------------------------- 00434 void init(const int8u* ptr, int dx, int dy) 00435 { 00436 m_ptr = ptr; 00437 m_y = read_int32() + dy; 00438 m_num_spans = unsigned(read_int32()); 00439 m_dx = dx; 00440 } 00441 00442 private: 00443 const int8u* m_ptr; 00444 int m_y; 00445 unsigned m_num_spans; 00446 int m_dx; 00447 }; 00448 00449 00450 00451 public: 00452 //-------------------------------------------------------------------- 00453 serialized_scanlines_adaptor_bin() : 00454 m_data(0), 00455 m_end(0), 00456 m_ptr(0), 00457 m_dx(0), 00458 m_dy(0), 00459 m_min_x(0x7FFFFFFF), 00460 m_min_y(0x7FFFFFFF), 00461 m_max_x(-0x7FFFFFFF), 00462 m_max_y(-0x7FFFFFFF) 00463 {} 00464 00465 //-------------------------------------------------------------------- 00466 serialized_scanlines_adaptor_bin(const int8u* data, unsigned size, 00467 double dx, double dy) : 00468 m_data(data), 00469 m_end(data + size), 00470 m_ptr(data), 00471 m_dx(iround(dx)), 00472 m_dy(iround(dy)), 00473 m_min_x(0x7FFFFFFF), 00474 m_min_y(0x7FFFFFFF), 00475 m_max_x(-0x7FFFFFFF), 00476 m_max_y(-0x7FFFFFFF) 00477 {} 00478 00479 //-------------------------------------------------------------------- 00480 void init(const int8u* data, unsigned size, double dx, double dy) 00481 { 00482 m_data = data; 00483 m_end = data + size; 00484 m_ptr = data; 00485 m_dx = iround(dx); 00486 m_dy = iround(dy); 00487 m_min_x = 0x7FFFFFFF; 00488 m_min_y = 0x7FFFFFFF; 00489 m_max_x = -0x7FFFFFFF; 00490 m_max_y = -0x7FFFFFFF; 00491 } 00492 00493 private: 00494 //-------------------------------------------------------------------- 00495 int read_int32() 00496 { 00497 int32 val; 00498 ((int8u*)&val)[0] = *m_ptr++; 00499 ((int8u*)&val)[1] = *m_ptr++; 00500 ((int8u*)&val)[2] = *m_ptr++; 00501 ((int8u*)&val)[3] = *m_ptr++; 00502 return val; 00503 } 00504 00505 public: 00506 // Iterate scanlines interface 00507 //-------------------------------------------------------------------- 00508 bool rewind_scanlines() 00509 { 00510 m_ptr = m_data; 00511 if(m_ptr < m_end) 00512 { 00513 m_min_x = read_int32() + m_dx; 00514 m_min_y = read_int32() + m_dy; 00515 m_max_x = read_int32() + m_dx; 00516 m_max_y = read_int32() + m_dy; 00517 } 00518 return m_ptr < m_end; 00519 } 00520 00521 //-------------------------------------------------------------------- 00522 int min_x() const { return m_min_x; } 00523 int min_y() const { return m_min_y; } 00524 int max_x() const { return m_max_x; } 00525 int max_y() const { return m_max_y; } 00526 00527 //-------------------------------------------------------------------- 00528 template<class Scanline> bool sweep_scanline(Scanline& sl) 00529 { 00530 sl.reset_spans(); 00531 for(;;) 00532 { 00533 if(m_ptr >= m_end) return false; 00534 00535 int y = read_int32() + m_dy; 00536 unsigned num_spans = read_int32(); 00537 00538 do 00539 { 00540 int x = read_int32() + m_dx; 00541 int len = read_int32(); 00542 00543 if(len < 0) len = -len; 00544 sl.add_span(x, unsigned(len), cover_full); 00545 } 00546 while(--num_spans); 00547 00548 if(sl.num_spans()) 00549 { 00550 sl.finalize(y); 00551 break; 00552 } 00553 } 00554 return true; 00555 } 00556 00557 00558 //-------------------------------------------------------------------- 00559 // Specialization for embedded_scanline 00560 bool sweep_scanline(embedded_scanline& sl) 00561 { 00562 do 00563 { 00564 if(m_ptr >= m_end) return false; 00565 00566 sl.init(m_ptr, m_dx, m_dy); 00567 00568 // Jump to the next scanline 00569 //-------------------------- 00570 read_int32(); // Y 00571 int num_spans = read_int32(); // num_spans 00572 m_ptr += num_spans * sizeof(int32) * 2; 00573 } 00574 while(sl.num_spans() == 0); 00575 return true; 00576 } 00577 00578 private: 00579 const int8u* m_data; 00580 const int8u* m_end; 00581 const int8u* m_ptr; 00582 int m_dx; 00583 int m_dy; 00584 int m_min_x; 00585 int m_min_y; 00586 int m_max_x; 00587 int m_max_y; 00588 }; 00589 00590 00591 00592 } 00593 00594 #endif 00595