TuttleOFX  1
wuline.hpp
Go to the documentation of this file.
00001 // Copyright Tom Brinkman 2008. Distributed under the Boost
00002 // Software License, Version 1.0. (See accompanying
00003 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
00004 
00005 #ifndef _wuline_hpp_
00006 #define _wuline_hpp_
00007 
00008 #include "blend.hpp"
00009 
00010 template <typename view_t, typename value_type_t> inline 
00011 void wuline(const view_t& view, const value_type_t& pixel, 
00012         int X0, int Y0, int X1, int Y1, int NumLevels=256, int IntensityBits=8)
00013 {
00014         using namespace boost::gil;
00015         unsigned short IntensityShift, ErrorAdj, ErrorAcc;
00016         unsigned short ErrorAccTemp, Weighting, WeightingComplementMask;
00017         short DeltaX, DeltaY, Temp, XDir;
00018 
00019         if (Y0 > Y1) 
00020         {
00021                 Temp = Y0; Y0 = Y1; Y1 = Temp;
00022                 Temp = X0; X0 = X1; X1 = Temp;
00023         }
00024 
00025         view(X0,Y0) = pixel;
00026 
00027         if ((DeltaX = X1 - X0) >= 0) 
00028         {
00029                 XDir = 1;
00030         } 
00031         else 
00032         {
00033                 XDir = -1;
00034                 DeltaX = -DeltaX; 
00035         }
00036 
00037         if ((DeltaY = Y1 - Y0) == 0) 
00038         {
00039                 while (DeltaX-- != 0) 
00040                 {
00041                         X0 += XDir;
00042                         view(X0,Y0) = pixel;
00043                 }
00044                 
00045                 return;
00046         }
00047         
00048         if (DeltaX == 0) 
00049         {
00050                 do 
00051                 {
00052                         Y0++;
00053                         view(X0,Y0) = pixel;
00054                 } 
00055                 while (--DeltaY != 0);
00056 
00057                 return;
00058         }
00059 
00060         if (DeltaX == DeltaY) 
00061         {
00062                 do 
00063                 {
00064                         X0 += XDir;
00065                         Y0++;
00066                         view(X0,Y0) = pixel;
00067                 } 
00068                 while (--DeltaY != 0);
00069 
00070                 return;
00071         }
00072 
00073         ErrorAcc = 0;  
00074         IntensityShift = 16 - IntensityBits;
00075         WeightingComplementMask = NumLevels - 1;
00076 
00077         if (DeltaY > DeltaX) 
00078         {
00079                 ErrorAdj = ((unsigned long) DeltaX << 16) / (unsigned long) DeltaY;
00080 
00081                 while (--DeltaY) 
00082                 {
00083                         ErrorAccTemp = ErrorAcc;   
00084                         ErrorAcc += ErrorAdj;     
00085                 
00086                         if (ErrorAcc <= ErrorAccTemp) 
00087                                 X0 += XDir;
00088                         
00089                         Y0++;
00090 
00091                         Weighting = ErrorAcc >> IntensityShift;
00092         
00093                         value_type_t dst = pixel;
00094                         static_for_each(dst,view(X0,Y0), 
00095                                 alpha24_blend((Weighting ^ WeightingComplementMask)));
00096                         view(X0,Y0) = dst;
00097 
00098                         dst = pixel;
00099                         static_for_each(dst,view(X0 + XDir, Y0), alpha24_blend(Weighting));
00100                         view(X0 + XDir, Y0) = dst;
00101                 }
00102 
00103                 view(X1,Y1) = pixel;
00104                 return;
00105         }
00106 
00107         ErrorAdj = ((unsigned long) DeltaY << 16) / (unsigned long) DeltaX;
00108 
00109         while (--DeltaX) 
00110         {
00111                 ErrorAccTemp = ErrorAcc;   
00112                 ErrorAcc += ErrorAdj;     
00113                 
00114                 if (ErrorAcc <= ErrorAccTemp) 
00115                         Y0++;
00116 
00117                 X0 += XDir; 
00118                 
00119                 Weighting = ErrorAcc >> IntensityShift;
00120 
00121                 value_type_t dst = pixel;
00122                 static_for_each(dst,view(X0,Y0), 
00123                         alpha24_blend(Weighting ^ WeightingComplementMask));
00124                 view(X0,Y0) = dst;
00125         
00126                 dst = pixel;
00127                 static_for_each(dst,view(X0, Y0 + 1), 
00128                         alpha24_blend(Weighting));
00129                 view(X0, Y0 + 1) = dst;
00130         }
00131 
00132         view(X1,Y1) = pixel;
00133 }
00134 
00135 #endif