diff --git a/src/sys/graphics/objgfx30.cpp b/src/sys/graphics/objgfx30.cpp index d83f155..80c0e92 100755 --- a/src/sys/graphics/objgfx30.cpp +++ b/src/sys/graphics/objgfx30.cpp @@ -287,6 +287,102 @@ } } // TGfx0::clear +bool +TGfx0::clipLine(Int32& x1, Int32& y1, Int32& x2, Int32& y2) { + /* + * clipLine() + * + * private method; clips a line to (0,0),(MaxX,MaxY); returns true if + * the line segment is in bounds, false if none of the line segment is + * on the screen. Uses HJI's line clipping algorithm. + */ + + Int32 tx1, ty1, tx2, ty2; + Int32 OutCode; + UInt32 AndResult, OrResult; + AndResult = 15; + OrResult = 0; + OutCode = 0; + if (x1<0) OutCode+=8; + if (x1>(Int32)MaxX) OutCode+=4; + if (y1<0) OutCode+=2; + if (y1>(Int32)MaxY) OutCode++; + + AndResult &= OutCode; + OrResult |= OutCode; + OutCode = 0; + + if (x2<0) OutCode+=8; + if (x2>(Int32)MaxX) OutCode+=4; + if (y2<0) OutCode+=2; + if (y2>(Int32)MaxY) OutCode++; + + AndResult &= OutCode; + OrResult |= OutCode; + + if (AndResult>0) return FALSE; + if (OrResult==0) return TRUE; + + // some clipping is required here. + + tx1 = x1; + ty1 = y1; + tx2 = x2; + ty2 = y2; + + if (x1<0) { + ty1 = (x2*y1-x1*y2) / (x2-x1); + tx1 = 0; + } // if + else + if (x2<0) { + ty2 = (x2*y1-x1*y2) / (x2-x1); + tx2 = 0; + } // elseif + + if (x1>(Int32)MaxX) { + ty1 = (y1*(x2-MaxX)+y2*(MaxX-x1)) / (x2-x1); + tx1 = MaxX; + } // if + else + if (x2>(Int32)MaxX) { + ty2 = (y1*(x2-MaxX)+y2*(MaxX-x1)) / (x2-x1); + tx2 = MaxX; + } // elseif + + if (((ty1<0) && (ty2<0)) || + ((ty1>(Int32)MaxY) && (ty2>(Int32)MaxY))) return FALSE; + + if (ty1<0) { + tx1 = (x1*y2-x2*y1) / (y2-y1); + ty1 = 0; + } // if + else + if (ty2<0) { + tx2 = (x1*y2-x2*y1) / (y2-y1); + ty2 = 0; + } // elseif + + if (ty1>(Int32)MaxY) { + tx1 = (x1*(y2-MaxY)+x2*(MaxY-y1)) / (y2-y1); + ty1 = MaxY; + } // if + else + if (ty2>(Int32)MaxY) { + tx2 = (x1*(y2-MaxY)+x2*(MaxY-y1)) / (y2-y1); + ty2 = MaxY; + } // elseif + + if (((UInt32)tx1>MaxX) || ((UInt32)tx2>MaxX)) return FALSE; + + x1 = tx1; + y1 = ty1; + x2 = tx2; + y2 = ty2; + + return TRUE; +} // TGfx0::clipLine + void TGfx0::clone(TGfx0& SrcObject) { TPixelFmt pixfmt; @@ -691,8 +787,15 @@ break; } // switch + return; } // TGfx0::hLine +void +TGfx0::line(Int32 x1, Int32 y1, Int32 x2, Int32 y2, UInt32 colour) { + if (clipLine(x1,y1,x2,y2)) rawLine(x1,y1,x2,y2,colour); + return; +} // TGfx0::line + void TGfx0::putPixel(UInt32 x, UInt32 y, UInt32 colour) { if ((Buffer==NULL) || (LineOfs==NULL)) return; @@ -761,6 +864,30 @@ return; } // TGfx0::putPixel +void +TGfx0::rawLine(UInt32 x1, UInt32 y1, UInt32 x2, UInt32 y2, UInt32 colour) { + /* + * TGfx0::rawLine() + * + * private method; draws an unclipped line from (x1,y1) to (x2,y2) + * + */ + + if ((Buffer==NULL) || (LineOfs==NULL)) return; + switch (BPP) { + case 8: + break; + case 15: + case 16: + break; + case 24: + break; + case 32: + break; + } // switch + return; +} // TGfx0::rawLine + UInt32 TGfx0::RGB(UInt8 red, UInt8 green, UInt8 blue) { UInt32 lastclr; diff --git a/src/sys/graphics/objgfx30.h b/src/sys/graphics/objgfx30.h index 59e8488..3e64d34 100755 --- a/src/sys/graphics/objgfx30.h +++ b/src/sys/graphics/objgfx30.h @@ -147,6 +147,8 @@ UInt8 RedShifter; UInt8 GreenShifter; UInt8 BlueShifter; + bool clipLine(Int32&, Int32&, Int32&, Int32&); + void rawLine(UInt32, UInt32, UInt32, UInt32, UInt32); public: TGfx0(void); bool alias(TGfx0&, UInt32, UInt32, UInt32, UInt32); @@ -176,10 +178,9 @@ UInt32 getTransparentColor(void); void hFlip(void); void hLine(Int32, Int32, Int32, UInt32); - // line + void line(Int32, Int32, Int32, Int32, UInt32); // loadPal void putPixel(UInt32, UInt32, UInt32); - // rawLine void rectangle(Int32, Int32, Int32, Int32, UInt32); UInt32 RGB(UInt8, UInt8, UInt8); // savePal