Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
dtschump committed Apr 9, 2024
2 parents 2a483df + edc58f7 commit 2c0a876
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 98 deletions.
202 changes: 106 additions & 96 deletions CImg.h
Original file line number Diff line number Diff line change
Expand Up @@ -1062,13 +1062,13 @@ extern "C" {
((_n1##x&3)==2?(img)._height - 1 - ++y:--x))))?0:1)

#define cimg_for_lineXY(x,y,x0,y0,x1,y1) \
for (int x = (int)(x0), y = (int)(y0), _sx = 1, _sy = 1, _steep = 0, \
for (int x = (int)(x0), y = (int)(y0), _sx = 1, _sy = 1, _slope = 0, \
_dx=(x1)>(x0)?(int)(x1) - (int)(x0):(_sx=-1,(int)(x0) - (int)(x1)), \
_dy=(y1)>(y0)?(int)(y1) - (int)(y0):(_sy=-1,(int)(y0) - (int)(y1)), \
_counter = _dx, \
_err = _dx>_dy?(_dy>>1):((_steep=1),(_counter=_dy),(_dx>>1)); \
_err = _dx>_dy?(_dy>>1):((_slope=1),(_counter=_dy),(_dx>>1)); \
_counter>=0; \
--_counter, x+=_steep? \
--_counter, x+=_slope? \
(y+=_sy,(_err-=_dx)<0?_err+=_dy,_sx:0): \
(y+=(_err-=_dy)<0?_err+=_dx,_sy:0,_sx))

Expand Down Expand Up @@ -48648,31 +48648,30 @@ namespace cimg_library {
const tc *const color, const float opacity=1,
const unsigned int pattern=~0U, const bool init_hatch=true) {
if (is_empty() || !opacity || !pattern ||
std::min(y0,y1)>=height() || std::max(y0,y1)<0 ||
std::min(x0,x1)>=width() || std::max(x0,x1)<0) return *this;
std::min(y0,y1)>=height() || std::max(y0,y1)<0 || std::min(x0,x1)>=width() || std::max(x0,x1)<0)
return *this;
int
w1 = width() - 1, h1 = height() - 1,
dx01 = x1 - x0, dy01 = y1 - y0;

const bool is_horizontal = cimg::abs(dx01)>cimg::abs(dy01);
if (is_horizontal) cimg::swap(x0,y0,x1,y1,w1,h1,dx01,dy01);
if (pattern==~0U && y0>y1) { cimg::swap(x0,x1,y0,y1); dx01*=-1; dy01*=-1; }
if (pattern==~0U && y0>y1) {
cimg::swap(x0,x1,y0,y1);
dx01*=-1; dy01*=-1;
}
const float slope_x = dy01?(float)dx01/dy01:0;

static unsigned int hatch = ~0U - (~0U>>1);
if (init_hatch) hatch = ~0U - (~0U>>1);
cimg_init_scanline(opacity);
const int
step = y0<=y1?1:-1,
hdy01 = dy01*cimg::sign(dx01)/2,
cy0 = cimg::cut(y0,0,h1),
cy1 = cimg::cut(y1,0,h1) + step;
const int step = y0<=y1?1:-1, cy0 = cimg::cut(y0,0,h1), cy1 = cimg::cut(y1,0,h1) + step;
dy01+=dy01?0:1;

for (int y = cy0; y!=cy1; y+=step) {
const int
yy0 = y - y0,
x = x0 + (dx01*yy0 + hdy01)/dy01;
if (x>=0 && x<=w1 && pattern&hatch) {
const int yy0 = y - y0;
const float fx = x0 + yy0*slope_x;
if (fx>=0 && fx<=w1 && pattern&hatch) {
const int x = (int)(fx + 0.5f);
T *const ptrd = is_horizontal?data(y,x):data(x,y);
cimg_forC(*this,c) {
const T val = color[c];
Expand Down Expand Up @@ -48715,44 +48714,45 @@ namespace cimg_library {
"different dimensions.",
cimg_instance,
zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data);

if (std::min(y0,y1)>=height() || std::max(y0,y1)<0 || std::min(x0,x1)>=width() || std::max(x0,x1)<0) return *this;

float iz0 = 1/z0, iz1 = 1/z1;
if (std::min(y0,y1)>=height() || std::max(y0,y1)<0 || std::min(x0,x1)>=width() || std::max(x0,x1)<0)
return *this;
int
w1 = width() - 1, h1 = height() - 1,
dx01 = x1 - x0, dy01 = y1 - y0;
float diz01 = iz1 - iz0;
float iz0 = 1/z0, iz1 = 1/z1, diz01 = iz1 - iz0;

const bool is_horizontal = cimg::abs(dx01)>cimg::abs(dy01);
if (is_horizontal) cimg::swap(x0,y0,x1,y1,w1,h1,dx01,dy01);
if (pattern==~0U && y0>y1) {
cimg::swap(x0,x1,y0,y1,iz0,iz1);
dx01*=-1; dy01*=-1; diz01*=-1;
}
const float
slope_x = dy01?(float)dx01/dy01:0,
slope_iz = dy01?(float)diz01/dy01:0;

static unsigned int hatch = ~0U - (~0U>>1);
if (init_hatch) hatch = ~0U - (~0U>>1);
cimg_init_scanline(opacity);

const int
step = y0<=y1?1:-1, hdy01 = dy01*cimg::sign(dx01)/2,
cy0 = cimg::cut(y0,0,h1), cy1 = cimg::cut(y1,0,h1) + step;
const int step = y0<=y1?1:-1, cy0 = cimg::cut(y0,0,h1), cy1 = cimg::cut(y1,0,h1) + step;
dy01+=dy01?0:1;

for (int y = cy0; y!=cy1; y+=step) {
const int
yy0 = y - y0,
x = x0 + (dx01*yy0 + hdy01)/dy01;
const float iz = iz0 + diz01*yy0/dy01;
tz *const ptrz = is_horizontal?zbuffer.data(y,x):zbuffer.data(x,y);

if (x>=0 && x<=w1 && pattern&hatch && iz>=*ptrz) {
*ptrz = (tz)iz;
T *const ptrd = is_horizontal?data(y,x):data(x,y);
cimg_forC(*this,c) {
const T val = color[c];
ptrd[c*_sc_whd] = opacity>=1?val:(T)(val*_sc_nopacity + ptrd[c*_sc_whd]*_sc_copacity);
const int yy0 = y - y0;
const float
fx = x0 + yy0*slope_x,
iz = iz0 + yy0*slope_iz;
if (fx>=0 && fx<=w1 && pattern&hatch) {
const int x = (int)(fx + 0.5f);
tz *const ptrz = is_horizontal?zbuffer.data(y,x):zbuffer.data(x,y);
if (iz>=*ptrz) {
*ptrz = (tz)iz;
T *const ptrd = is_horizontal?data(y,x):data(x,y);
cimg_forC(*this,c) {
const T val = color[c];
ptrd[c*_sc_whd] = opacity>=1?val:(T)(val*_sc_nopacity + ptrd[c*_sc_whd]*_sc_copacity);
}
}
}
if (!(hatch>>=1)) hatch = ~0U - (~0U>>1);
Expand Down Expand Up @@ -48799,41 +48799,43 @@ namespace cimg_library {
cimg_instance,
texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
if (is_overlapped(texture)) return draw_line(x0,y0,x1,y1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch);

if (std::min(y0,y1)>=height() || std::max(y0,y1)<0 || std::min(x0,x1)>=width() || std::max(x0,x1)<0) return *this;

int w1 = width() - 1, h1 = height() - 1;
longT
dx01 = (longT)x1 - x0, dy01 = (longT)y1 - y0,
dtx01 = (longT)tx1 - tx0, dty01 = (longT)ty1 - ty0;
if (std::min(y0,y1)>=height() || std::max(y0,y1)<0 || std::min(x0,x1)>=width() || std::max(x0,x1)<0)
return *this;
int
w1 = width() - 1, h1 = height() - 1,
dx01 = x1 - x0, dy01 = y1 - y0,
dtx01 = tx1 - tx0, dty01 = ty1 - ty0;

const bool is_horizontal = cimg::abs(dx01)>cimg::abs(dy01);
if (is_horizontal) cimg::swap(x0,y0,x1,y1,w1,h1,dx01,dy01);
if (pattern==~0U && y0>y1) {
cimg::swap(x0,x1,y0,y1,tx0,tx1,ty0,ty1);
dx01*=-1; dy01*=-1; dtx01*=-1; dty01*=-1;
}
const float
slope_x = dy01?(float)dx01/dy01:0,
slope_tx = dy01?(float)dtx01/dy01:0,
slope_ty = dy01?(float)dty01/dy01:0;

const ulongT twhd = (ulongT)texture._width*texture._height*texture._depth;
static unsigned int hatch = ~0U - (~0U>>1);
if (init_hatch) hatch = ~0U - (~0U>>1);
cimg_init_scanline(opacity);

const int step = y0<=y1?1:-1, cy0 = cimg::cut(y0,0,h1), cy1 = cimg::cut(y1,0,h1) + step;
const longT
hdy01 = dy01*cimg::sign(dx01)/2,
hdy01tx = dy01*cimg::sign(dtx01)/2,
hdy01ty = dy01*cimg::sign(dty01)/2;

dy01+=dy01?0:1;

for (int y = cy0; y!=cy1; y+=step) {
const longT
yy0 = (longT)y - y0,
x = x0 + (dx01*yy0 + hdy01)/dy01,
tx = tx0 + (dtx01*yy0 + hdy01tx)/dy01,
ty = ty0 + (dty01*yy0 + hdy01ty)/dy01;
if (x>=0 && x<=w1 && pattern&hatch) {
const int yy0 = y - y0;
const float
fx = x0 + yy0*slope_x,
ftx = tx0 + yy0*slope_tx,
fty = ty0 + yy0*slope_ty;
if (fx>=0 && fx<=w1 && pattern&hatch) {
const int
x = (int)(fx + 0.5f),
tx = (int)(ftx + 0.5f),
ty = (int)(fty + 0.5f);
T *const ptrd = is_horizontal?data(y,x):data(x,y);
const tc *const color = &texture._atXY(tx,ty);
cimg_forC(*this,c) {
Expand Down Expand Up @@ -48879,13 +48881,13 @@ namespace cimg_library {
texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
if (is_overlapped(texture))
return draw_line(x0,y0,z0,x1,y1,z1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch);

if (std::min(y0,y1)>=height() || std::max(y0,y1)<0 || std::min(x0,x1)>=width() || std::max(x0,x1)<0) return *this;

float iz0 = 1/z0, iz1 = 1/z1;
int w1 = width() - 1, h1 = height() - 1;
longT dx01 = (longT)x1 - x0, dy01 = (longT)y1 - y0;
if (std::min(y0,y1)>=height() || std::max(y0,y1)<0 || std::min(x0,x1)>=width() || std::max(x0,x1)<0)
return *this;
int
w1 = width() - 1, h1 = height() - 1,
dx01 = x1 - x0, dy01 = y1 - y0;
float
iz0 = 1/z0, iz1 = 1/z1,
diz01 = iz1 - iz0,
txz0 = tx0*iz0, txz1 = tx1*iz1,
tyz0 = ty0*iz0, tyz1 = ty1*iz1,
Expand All @@ -48897,29 +48899,32 @@ namespace cimg_library {
cimg::swap(x0,x1,y0,y1,iz0,iz1,txz0,txz1,tyz0,tyz1);
dx01*=-1; dy01*=-1; diz01*=-1; dtxz01*=-1; dtyz01*=-1;
}
const float
slope_x = dy01?(float)dx01/dy01:0,
slope_iz = dy01?(float)diz01/dy01:0,
slope_txz = dy01?(float)dtxz01/dy01:0,
slope_tyz = dy01?(float)dtyz01/dy01:0;

const ulongT twhd = (ulongT)texture._width*texture._height*texture._depth;
static unsigned int hatch = ~0U - (~0U>>1);
if (init_hatch) hatch = ~0U - (~0U>>1);
cimg_init_scanline(opacity);

const int step = y0<=y1?1:-1, cy0 = cimg::cut(y0,0,h1), cy1 = cimg::cut(y1,0,h1) + step;
const longT hdy01 = dy01*cimg::sign(dx01)/2;

dy01+=dy01?0:1;

for (int y = cy0; y!=cy1; y+=step) {
const longT
yy0 = (longT)y - y0,
x = x0 + (dx01*yy0 + hdy01)/dy01;
const int yy0 = y - y0;
const float
iz = iz0 + diz01*yy0/dy01,
txz = txz0 + dtxz01*yy0/dy01,
tyz = tyz0 + dtyz01*yy0/dy01;
if (x>=0 && x<=w1 && pattern&hatch) {
fx = x0 + yy0*slope_x,
iz = iz0 + yy0*slope_iz,
ftxz = txz0 + yy0*slope_txz,
ftyz = tyz0 + yy0*slope_tyz;
if (fx>=0 && fx<=w1 && pattern&hatch) {
const int
tx = (int)cimg::round(txz/iz),
ty = (int)cimg::round(tyz/iz);
x = (int)(fx + 0.5f),
tx = (int)(ftxz/iz + 0.5f),
ty = (int)(ftyz/iz + 0.5f);
T *const ptrd = is_horizontal?data(y,x):data(x,y);
const tc *const color = &texture._atXY(tx,ty);
cimg_forC(*this,c) {
Expand Down Expand Up @@ -48973,13 +48978,14 @@ namespace cimg_library {
texture._width,texture._height,texture._depth,texture._spectrum,texture._data);
if (is_overlapped(texture))
return draw_line(zbuffer,x0,y0,z0,x1,y1,z1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch);
if (std::min(y0,y1)>=height() || std::max(y0,y1)<0 || std::min(x0,x1)>=width() || std::max(x0,x1)<0)
return *this;

if (std::min(y0,y1)>=height() || std::max(y0,y1)<0 || std::min(x0,x1)>=width() || std::max(x0,x1)<0) return *this;

float iz0 = 1/z0, iz1 = 1/z1;
int w1 = width() - 1, h1 = height() - 1;
longT dx01 = (longT)x1 - x0, dy01 = (longT)y1 - y0;
int
w1 = width() - 1, h1 = height() - 1,
dx01 = x1 - x0, dy01 = y1 - y0;
float
iz0 = 1/z0, iz1 = 1/z1,
diz01 = iz1 - iz0,
txz0 = tx0*iz0, txz1 = tx1*iz1,
tyz0 = ty0*iz0, tyz1 = ty1*iz1,
Expand All @@ -48991,37 +48997,41 @@ namespace cimg_library {
cimg::swap(x0,x1,y0,y1,iz0,iz1,txz0,txz1,tyz0,tyz1);
dx01*=-1; dy01*=-1; diz01*=-1; dtxz01*=-1; dtyz01*=-1;
}
const float
slope_x = dy01?(float)dx01/dy01:0,
slope_iz = dy01?(float)diz01/dy01:0,
slope_txz = dy01?(float)dtxz01/dy01:0,
slope_tyz = dy01?(float)dtyz01/dy01:0;

const ulongT twhd = (ulongT)texture._width*texture._height*texture._depth;
static unsigned int hatch = ~0U - (~0U>>1);
if (init_hatch) hatch = ~0U - (~0U>>1);
cimg_init_scanline(opacity);

const int step = y0<=y1?1:-1, cy0 = cimg::cut(y0,0,h1), cy1 = cimg::cut(y1,0,h1) + step;
const longT hdy01 = dy01*cimg::sign(dx01)/2;

dy01+=dy01?0:1;

for (int y = cy0; y!=cy1; y+=step) {
const longT
yy0 = (longT)y - y0,
x = x0 + (dx01*yy0 + hdy01)/dy01;
const int yy0 = y - y0;
const float
iz = iz0 + diz01*yy0/dy01,
txz = txz0 + dtxz01*yy0/dy01,
tyz = tyz0 + dtyz01*yy0/dy01;
tz *const ptrz = is_horizontal?zbuffer.data(y,x):zbuffer.data(x,y);

if (x>=0 && x<=w1 && pattern&hatch && iz>=*ptrz) {
*ptrz = (tz)iz;
const int
tx = (int)cimg::round(txz/iz),
ty = (int)cimg::round(tyz/iz);
T *const ptrd = is_horizontal?data(y,x):data(x,y);
const tc *const color = &texture._atXY(tx,ty);
cimg_forC(*this,c) {
const T val = color[c*twhd];
ptrd[c*_sc_whd] = opacity>=1?val:(T)(val*_sc_nopacity + ptrd[c*_sc_whd]*_sc_copacity);
fx = x0 + yy0*slope_x,
iz = iz0 + yy0*slope_iz,
ftxz = txz0 + yy0*slope_txz,
ftyz = tyz0 + yy0*slope_tyz;
if (fx>=0 && fx<=w1 && pattern&hatch) {
const int x = (int)(fx + 0.5f);
tz *const ptrz = is_horizontal?zbuffer.data(y,x):zbuffer.data(x,y);
if (iz>=*ptrz) {
*ptrz = (tz)iz;
const int
tx = (int)(ftxz/iz + 0.5f),
ty = (int)(ftyz/iz + 0.5f);
T *const ptrd = is_horizontal?data(y,x):data(x,y);
const tc *const color = &texture._atXY(tx,ty);
cimg_forC(*this,c) {
const T val = color[c*twhd];
ptrd[c*_sc_whd] = opacity>=1?val:(T)(val*_sc_nopacity + ptrd[c*_sc_whd]*_sc_copacity);
}
}
}
if (!(hatch>>=1)) hatch = ~0U - (~0U>>1);
Expand Down
2 changes: 1 addition & 1 deletion html/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<div class="header">
<a href="index.html"><img alt="Logo" src="img/logo_header.jpg" class="center_image" style="margin-top:1em;"/></a>
<h2 style="padding-bottom: 1em">
Latest stable version: <b><a href="http://cimg.eu/files/CImg_.zip">3.3.5</a></b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Current pre-release: <b><a href="http://cimg.eu/files/CImg_latest.zip">3.3.6</a></b> (2024/03/17)
Latest stable version: <b><a href="http://cimg.eu/files/CImg_.zip">3.3.5</a></b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Current pre-release: <b><a href="http://cimg.eu/files/CImg_latest.zip">3.3.6</a></b> (2024/03/28)
</h2>

<hr/>
Expand Down
2 changes: 1 addition & 1 deletion html/header_doxygen.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<div class="header">
<a href="../index.html"><img alt="Logo" src="../img/logo_header.jpg" class="center_image" style="margin-top:1em;"/></a>
<h2 style="padding-bottom: 1em">
Latest stable version: <b><a href="http://cimg.eu/files/CImg_.zip">3.3.5</a></b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Current pre-release: <b><a href="http://cimg.eu/files/CImg_latest.zip">3.3.6</a></b> (2024/03/17)
Latest stable version: <b><a href="http://cimg.eu/files/CImg_.zip">3.3.5</a></b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Current pre-release: <b><a href="http://cimg.eu/files/CImg_latest.zip">3.3.6</a></b> (2024/03/28)
</h2>

<hr/>
Expand Down

0 comments on commit 2c0a876

Please sign in to comment.