Code:
unit dglSvg;
interface
procedure GL_SetForeground (fg: integer);
procedure GL_SetPicForeground ();
procedure InitDrawing (style: integer; thick: integer; fg: integer);
procedure GL_VideoInvert (width: integer; height: integer; x: integer; y: integer);
procedure GL_DrawEmptyRectangle (fg: integer; x: single; y: single; width: single; height: single; thick: single);
procedure GL_DrawRectangle (fg: integer; x: single; y: single; width: single; height: single);
procedure GL_DrawLine (x1: integer; y1: integer; x2: integer; y2: integer; round: boolean);
procedure GL_DrawArc (x: single; y: single; w: single; h: single; startAngle: integer; sweepAngle: integer; filled: boolean);
procedure DrawOval (frame: integer; thick: integer; style: integer; x: integer; y: integer; width: integer;
height: integer; rx: integer; ry: integer; fg: integer; bg: integer; pattern: integer);
implementation
uses dglOpenGL;
const
M_PI = 3.14159265358979323846;
CSLICES = 360;
SLICES_SIZE = 361;
var
S_thick: integer;
Opacity: GLubyte = 255;
FillOpacity: GLubyte = 255;
StrokeOpacity: GLubyte = 255;
Fill_style: boolean = TRUE;
X_Clip: integer = 0;
Y_Clip: integer = 0;
Width_Clip: integer = 0;
Height_Clip: integer = 0;
(*----------------------------------------------------------------------
GL_SetForeground : set color before drawing a or many vertex
----------------------------------------------------------------------*)
procedure GL_SetForeground (fg: integer);
var
red, green, blue: byte;
us_opac: GLubyte;
begin
if (Fill_style) then
us_opac := FillOpacity
else
begin
us_opac := StrokeOpacity;
Fill_style := TRUE;
end;
// TtaGiveThotRGB (fg, &red, &green, &blue);
red:=0;
green:=0;
blue:=255;
glColor4ub ( GLubyte( red ), GLubyte( green ), GLubyte ( blue ), us_opac );
end;
(*----------------------------------------------------------------------
GL_SetPicForeground : set opacity before drawing a or many vertex
----------------------------------------------------------------------*)
procedure GL_SetPicForeground ();
var
us_opac: GLubyte;
begin
us_opac := FillOpacity;
glColor4ub ( 255, 255, 255, us_opac);
end;
(*----------------------------------------------------------------------
InitDrawing update the Graphic Context accordingly to parameters.
The parameter fg indicates the drawing color
----------------------------------------------------------------------*)
procedure InitDrawing (style: integer; thick: integer; fg: integer);
begin
if (style >= 5) then
begin
// solid
if (thick>0) then
begin
S_thick := thick;
glLineWidth ( thick );
glPointSize ( thick );
end
else
begin
glLineWidth ( 0.5 );
glPointSize ( 0.5 );
end;
glDisable (GL_LINE_STIPPLE);
end
else
begin
if (thick>0) then
begin
S_thick := thick;
if (style = 3) then
begin
// dotted
glLineStipple (thick, $5555);
glEnable (GL_LINE_STIPPLE);
end
else
begin
// dashed
glLineStipple (thick, $1F1F);
glEnable (GL_LINE_STIPPLE);
end;
glLineWidth ( thick );
glPointSize ( thick );
end
else
begin
glLineWidth ( 0.5 );
glPointSize ( 0.5 );
end;
end;
Fill_style := FALSE;
GL_SetForeground (fg);
end;
(*----------------------------------------------------------------------
GL_VideoInvert :
using a transparent yellow instead of inverting... much simpler !
----------------------------------------------------------------------*)
procedure GL_VideoInvert (width: integer; height: integer; x: integer; y: integer);
begin
(*a blend func like that could be coool ?
(GL_ONE_MINUS_DST_COLOR,GL_ZERO) *)
glColor4ub (127, 127, 127, 80);
glBegin (GL_QUADS);
glVertex2i (x, y);
glVertex2i (x + width, y);
glVertex2i (x + width, y + height);
glVertex2i (x, y + height);
glEnd ();
end;
(*----------------------------------------------------------------------
GL_DrawEmptyRectangle Outlined rectangle
----------------------------------------------------------------------*)
procedure GL_DrawEmptyRectangle (fg: integer; x: single; y: single; width: single; height: single; thick: single);
begin
GL_SetForeground (fg);
if ((thick - 1)=0) then
begin
glBegin (GL_LINE_LOOP);
glVertex2f (x, y );
glVertex2f (x + width, y);
glVertex2f (x + width, y + height);
glVertex2f (x, y + height);
end
else
begin
thick := thick / 2;
glBegin (GL_QUADS);
glVertex2f (x - thick, y - thick);
glVertex2f (x + thick + width, y - thick);
glVertex2f (x + thick + width, y + thick);
glVertex2f (x - thick, y + thick);
glVertex2f (x - thick, y - thick + height);
glVertex2f (x + thick + width, y - thick + height);
glVertex2f (x + thick + width, y + thick + height);
glVertex2f (x - thick, y + thick + height);
glVertex2f (x - thick, y - thick);
glVertex2f (x + thick, y - thick);
glVertex2f (x + thick, y + thick + height);
glVertex2f (x - thick, y + thick + height);
glVertex2f (x - thick + width, y - thick);
glVertex2f (x + thick + width, y - thick);
glVertex2f (x + thick + width, y + thick + height);
glVertex2f (x - thick + width, y + thick + height);
end;
glEnd ();
end;
(*----------------------------------------------------------------------
GL_DrawRectangle
(don't use glrect because it's exactly the same but require opengl 1.2)
----------------------------------------------------------------------*)
procedure GL_DrawRectangle (fg: integer; x: single; y: single; width: single; height: single);
begin
GL_SetForeground (fg);
glBegin (GL_QUADS);
glVertex2f (x, y);
glVertex2f (x + width, y);
glVertex2f (x + width, y + height);
glVertex2f (x, y + height);
glEnd ();
end;
(*----------------------------------------------------------------------
GL_DrawLine
----------------------------------------------------------------------*)
procedure GL_DrawLine (x1: integer; y1: integer; x2: integer; y2: integer; round: boolean);
begin
if ( (S_thick > 1) AND round) then
begin
// round line join
glBegin (GL_POINTS);
glVertex2i (x1, y1);
glVertex2i (x2, y2);
glEnd ();
end;
glBegin (GL_LINES) ;
glVertex2i (x1, y1);
glVertex2i (x2, y2);
glEnd ();
end;
(*----------------------------------------------------------------------
GL_DrawArc : Draw an arc
----------------------------------------------------------------------*)
procedure GL_DrawArc (x: single; y: single; w: single; h: single; startAngle: integer; sweepAngle: integer; filled: boolean);
var
i, slices: GLint;
angleOffset: single;
sinCache: array[0..SLICES_SIZE] of single;
cosCache: array[0..SLICES_SIZE] of single;
y_cache: array[0..SLICES_SIZE] of single;
x_cache: array[0..SLICES_SIZE] of single;
angle: single;
fastx, fasty, width, height: single;
begin
width := (w) / 2;
height := (h) / 2;
fastx := (x) + width;
fasty := (y) + height;
if (w < 10) AND (h < 10) then
begin
glPointSize ( 0.1 );
slices := 36;
end
else
slices := CSLICES;
startAngle := startAngle;
sweepAngle := sweepAngle;
// Cache is the vertex locations cache
angleOffset := (startAngle / 180.0 * M_PI);
for i := 0 to slices do
begin
angle := angleOffset + ((M_PI * sweepAngle) / 180.0) * i / slices;
cosCache[i] := COS(angle);
sinCache[i] := SIN(angle);
end;
if (abs (sweepAngle - 360.0) < 0.0001) then
begin
sinCache[slices] := sinCache[0];
cosCache[slices] := cosCache[0];
end;
for i := 0 to slices do
begin
x_cache[i] := fastx + (width * cosCache[i]);
y_cache[i] := fasty - (height * sinCache[i]);
end;
if (filled) then
begin
glBegin (GL_TRIANGLE_FAN);
// The center
glVertex2d (fastx, fasty);
for i := 0 to slices do
glVertex2d (x_cache[i], y_cache[i]);
glEnd();
end;
if (filled=FALSE) then
begin
if (w < 20) AND (h < 20) then
glBegin(GL_POINTS)
else
glBegin(GL_LINE_STRIP);
slices := slices -1;
for i := 0 to slices do
glVertex2d (x_cache[i], y_cache[i]);
glEnd();
end;
end;
(*----------------------------------------------------------------------
GL_Point :
Draw a point using GL primitives
----------------------------------------------------------------------*)
procedure GL_Point (fg: integer; width: single; x: single; y:single);
begin
GL_SetForeground (fg);
glPointSize (width);
glBegin (GL_POINTS);
glVertex2f (x, y);
glEnd ();
end;
type tarc = record
width: integer;
height: integer;
x: integer;
y: integer;
angle1: integer;
angle2: integer;
end;
tseg = record
x1: integer;
x2: integer;
y1: integer;
y2: integer;
end;
tpoint = record
x: integer;
y: integer;
end;
(*----------------------------------------------------------------------
GL_DrawSegments
----------------------------------------------------------------------*)
procedure GL_DrawSegments (var point: array of tseg; npoints: integer);
var
i: integer;
begin
if (S_thick > 1) then
begin
glBegin (GL_POINTS);
for i:=0 to npoints-1 do
begin
glVertex2f ( point[i].x1 ,
point[i].y1 );
glVertex2f (point[i].x2 ,
point[i].y2 );
end;
glEnd ();
end;
glBegin (GL_LINES) ;
for i:=0 to npoints-1 do
begin
glVertex2f ( point[i].x1 ,
point[i].y1);
glVertex2f ( point[i].x2 ,
point[i].y2);
end;
glEnd ();
end;
(*----------------------------------------------------------------------
GL_DrawPolygon : tesselation handles
convex, concave and polygon with holes
----------------------------------------------------------------------*)
procedure GL_DrawPolygon (var points: array of tpoint; npoints: integer);
begin
//MakefloatMesh (points, npoints);
end;
(*----------------------------------------------------------------------
DrawOval draw a rectangle with rounded corners.
Parameters fg, bg, and pattern are for drawing
color, background color and fill pattern.
----------------------------------------------------------------------*)
procedure DrawOval (frame: integer; thick: integer; style: integer; x: integer; y: integer; width: integer;
height: integer; rx: integer; ry: integer; fg: integer; bg: integer; pattern: integer);
var
i: integer;
arc, dx, dy: integer;
xf, yf: integer;
xarc: array[0..4] of tarc;
seg: array[0..4] of tseg;
point: array[0..13] of tpoint;
begin
//width := width - thick;
//height := height - thick;
//x := x+thick div 2;
//y := y+thick div 2;
y := y; //+FrameTable[frame].FrTopMargin;
// radius of arcs
if (rx = 0) AND (ry <> 0) then
rx := ry
else if (ry = 0) AND (rx <> 0) then
ry := rx;
arc := width div 2;
if (rx > arc) then
rx := arc;
arc := height div 2;
if (ry > arc) then
ry := arc;
dx := rx;
dy := ry;
rx := rx * 2;
ry := ry * 2;
xf := x + width - 1;
yf := y + height - 1;
xarc[0].x := x;
xarc[0].y := y;
xarc[0].width := rx;
xarc[0].height := ry;
xarc[0].angle1 := 90;
xarc[0].angle2 := 90;
xarc[1].x := xf - rx;
xarc[1].y := xarc[0].y;
xarc[1].width := rx;
xarc[1].height := ry;
xarc[1].angle1 := 0;
xarc[1].angle2 := xarc[0].angle2;
xarc[2].x := xarc[0].x;
xarc[2].y := yf - ry;
xarc[2].width := rx;
xarc[2].height := ry;
xarc[2].angle1 := 180;
xarc[2].angle2 := xarc[0].angle2;
xarc[3].x := xarc[1].x;
xarc[3].y := xarc[2].y;
xarc[3].width := rx;
xarc[3].height := ry;
xarc[3].angle1 := 270;
xarc[3].angle2 := xarc[0].angle2;
seg[0].x1 := x + dx;
seg[0].x2 := xf - dx;
seg[0].y1 := y;
seg[0].y2 := seg[0].y1;
seg[1].x1 := xf;
seg[1].x2 := seg[1].x1;
seg[1].y1 := y + dy;
seg[1].y2 := yf - dy;
seg[2].x1 := seg[0].x1;
seg[2].x2 := seg[0].x2;
seg[2].y1 := yf;
seg[2].y2 := seg[2].y1;
seg[3].x1 := x;
seg[3].x2 := seg[3].x1;
seg[3].y1 := seg[1].y1;
seg[3].y2 := seg[1].y2;
// Fill in the figure
if (pattern = 2) then
begin
// Polygone inscrit: (seg0)
// 0--1
// 10-| |-3
// (seg3) | |(seg1)
// 9--| |-4
// 7--6
// (seg2)
point[0].x := seg[0].x1;
point[0].y := seg[0].y1;
point[1].x := seg[0].x2;
point[1].y := point[0].y;
point[2].x := point[1].x;
point[2].y := seg[1].y1;
point[3].x := seg[1].x1;
point[3].y := point[2].y;
point[4].x := point[3].x;
point[4].y := seg[1].y2;
point[5].x := seg[2].x2;
point[5].y := point[4].y;
point[6].x := point[5].x;
point[6].y := seg[2].y2;
point[7].x := seg[2].x1;
point[7].y := point[6].y;
point[8].x := point[7].x;
point[8].y := seg[3].y2;
point[9].x := seg[3].x2;
point[9].y := point[8].y;
point[10].x := point[9].x;
point[10].y := seg[3].y1;
point[11].x := point[0].x;
point[11].y := point[10].y;
point[12].x := point[0].x;
point[12].y := point[0].y;
GL_SetForeground (bg);
GL_DrawPolygon (point, 13); //not implemented yet
for i:=0 to 3 do
begin
GL_DrawArc (xarc[i].x + thick/4, xarc[i].y + thick/4,
xarc[i].width - thick/4, xarc[i].height-thick/4,
xarc[i].angle1, xarc[i].angle2,
TRUE);
end;
end;
// Draw the border
if (thick > 0) AND (fg >= 0) then
begin
InitDrawing (style, thick, fg);
for i:=0 to 3 do
GL_DrawArc (xarc[i].x, xarc[i].y,
xarc[i].width, xarc[i].height,
xarc[i].angle1, xarc[i].angle2,
FALSE);
//GL_DrawSegments (seg, 4);
end;
end;
end.
Bookmarks