Skip to content

Instantly share code, notes, and snippets.

@nonkit
Last active September 12, 2022 09:50
Show Gist options
  • Save nonkit/42a3cf9f1430213c9942c370fd0e6729 to your computer and use it in GitHub Desktop.
Save nonkit/42a3cf9f1430213c9942c370fd0e6729 to your computer and use it in GitHub Desktop.
Small Basic Pseudo GraphicsWindow Object
Sub GW_DrawGrid
' GraphicsWindow | draw grid
_gw = GraphicsWindow.Width
_gh = GraphicsWindow.Height
_c100 = "#66000000"
_c10 = "#33000000"
For _x = 0 To _gw Step 10
If Math.Remainder(_x / 10, 10) = 0 Then
GraphicsWindow.PenColor = _c100
Else
GraphicsWindow.PenColor = _c10
EndIf
GraphicsWindow.DrawLine(_x, 0, _x, _gh)
EndFor
For _y = 0 To _gh Step 10
If Math.Remainder(_y / 10, 10) = 0 Then
GraphicsWindow.PenColor = _c100
Else
GraphicsWindow.PenColor = _c10
EndIf
GraphicsWindow.DrawLine(0, _y, _gw, _y)
EndFor
EndSub
Sub GW_DrawHexagon
' param x, y - the left top coordinate of the parallelogram
' param width, height - the size of the parallelogram
' param ratio - the delta x per height
dx = height * ratio
If dx < 0 Then
dx = 0
ElseIf Math.Ceiling(width / 2) < dx Then
dx = Math.Ceiling(width / 2)
EndIf
edge = width - 2 * dx
vx[1] = x + dx
vy[1] = y
vx[2] = vx[1] + edge
vy[2] = vy[1]
vx[3] = x + width
vy[3] = y + height / 2
vx[4] = vx[2]
vy[4] = y + height
vx[5] = vx[1]
vy[5] = vy[4]
vx[6] = x
vy[6] = vy[3]
For i = 1 To 6
j = i + 1
If j = 7 Then
j = 1
EndIf
GraphicsWindow.DrawLine(vx[i], vy[i], vx[j], vy[j])
EndFor
EndSub
Sub GW_DrawPolylineWithVaryingWidth
' GraphicsWindow | draw polyline with varying width
' param circles - text "cx,cy,d ..."
' while cx - center x of a circle
' cy - center y of a circle
' d - diameter of a circle (width of the polyline)
txt = circles
delim = " "
Text_Split()
_circle = arry
delim = ","
_bc = GraphicsWindow.BrushColor
GraphicsWindow.BrushColor = GraphicsWindow.PenColor
For _i = 1 To Array.GetItemCount(_circle)
txt = _circle[_i]
Text_Split()
x[_i] = arry[1]
y[_i] = arry[2]
d[_i] = arry[3]
If 0 < d[_i] Then
_x = x[_i] - d[_i] / 2
_y = y[_i] - d[_i] / 2
GraphicsWindow.FillEllipse(_x, _y, d[_i], d[_i])
EndIf
If 1 < _i Then
_Connect_Circles()
EndIf
EndFor
GraphicsWindow.BrushColor = _bc
EndSub
Sub _Connect_Circles
' Connect circle[_i-1] and circle[_i]
' param _i
_pw = GraphicsWindow.PenWidth
GraphicsWindow.PenWidth = Math.Min(d[_i - 1], d[_i])
GraphicsWindow.DrawLine(x[_i - 1], y[_i - 1], x[_i], y[_i])
GraphicsWindow.PenWidth = _pw
If d[_i - 1] <> d[_i] Then
If d[_i - 1] < d[_i] Then
min = _i - 1
max = _i
Else
min = _i
max = _i - 1
EndIf
dx = x[min] - x[max]
dy = y[min] - y[max]
_x = x ' save x
_y = y ' save y
x = dx
y = dy
Math_CartesianToPolar()
θ = Math.GetRadians(a)
l = r
x = _x ' restore x
y = _y ' restore y
β = Math.ArcCos((d[max] - d[min]) / 2 / l)
If d[min] = 0 Then
x1 = x[min]
y1 = y[min]
x3 = x[max] + d[max] / 2 * Math.Cos(θ - β)
y3 = y[max] + d[max] / 2 * Math.Sin(θ - β)
x4 = x[max] + d[max] / 2 * Math.Cos(θ + β)
y4 = y[max] + d[max] / 2 * Math.Sin(θ + β)
GraphicsWindow.FillTriangle(x1, y1, x3, y3, x4, y4)
Else
x1 = x[min] + d[min] / 2 * Math.Cos(θ - β)
y1 = y[min] + d[min] / 2 * Math.Sin(θ - β)
x3 = x[max] + d[max] / 2 * Math.Cos(θ - β)
y3 = y[max] + d[max] / 2 * Math.Sin(θ - β)
x5 = x[max]
y5 = y[max]
GraphicsWindow.FillTriangle(x1, y1, x3, y3, x5, y5)
x2 = x[min] + d[min] / 2 * Math.Cos(θ + β)
y2 = y[min] + d[min] / 2 * Math.Sin(θ + β)
x4 = x[max] + d[max] / 2 * Math.Cos(θ + β)
y4 = y[max] + d[max] / 2 * Math.Sin(θ + β)
GraphicsWindow.FillTriangle(x2, y2, x4, y4, x5, y5)
EndIf
EndIf
EndSub
Sub GW_DrawArc
' GraphicsWindow | draw arc
' param x - co-ordinate of the center
' param y - co-ordinate of the center
' param a1 - start angle
' param a2 - end angle
Stack.PushValue("local", param)
Stack.PushValue("local", local)
Stack.PushValue("local", a)
local = param
param = ""
local["pw"] = GraphicsWindow.PenWidth
local["pc"] = GraphicsWindow.PenColor
local["bc"] = GraphicsWindow.BrushColor
GraphicsWindow.BrushColor = local["pc"]
local["r1"] = local["r"] - local["pw"] / 2
local["r2"] = local["r"] + local["pw"] / 2
For a = local["a1"] To local["a2"] Step local["da"]
local["rad"] = Math.GetRadians(a)
param["x1"] = local["x"] + local["r1"] * Math.Cos(local["rad"])
param["y1"] = local["y"] + local["r1"] * Math.Sin(local["rad"])
param["x2"] = local["x"] + local["r2"] * Math.Cos(local["rad"])
param["y2"] = local["y"] + local["r2"] * Math.Sin(local["rad"])
If local["a1"] < a Then
GW_FillQuadrangle()
EndIf
param["x4"] = param["x1"]
param["y4"] = param["y1"]
param["x3"] = param["x2"]
param["y3"] = param["y2"]
EndFor
GraphicsWindow.BrushColor = local["bc"]
a = Stack.PopValue("local")
local = Stack.PopValue("local")
param = Stack.PopValue("local")
EndSub
Sub GW_DrawRoundRectangle
' GraphicsWindow | draw round rectangle
' param x - co-ordinate of the rectangle
' param y - co-ordinate of the rectangle
' param width - of the rectangle
' param height - of the rectangle
' param border-radius
Stack.PushValue("local", param)
Stack.PushValue("local", local)
local = param
param = ""
param["r"] = local["border-radius"]
If (local["width"] / 2 < param["r"]) Or (local["height"] / 2 < param["r"]) Then
param["r"] = Math.Min(local["width"] / 2, local["height"] / 2)
EndIf
param["da"] = 5
param["x"] = local["x"] + param["r"]
param["y"] = local["y"] + param["r"]
param["a1"] = 180
param["a2"] = 270
GW_DrawArc()
GraphicsWindow.DrawLine(local["x"] + param["r"], local["y"], local["x"] + local["width"] - param["r"], local["y"])
param["x"] = local["x"] + local["width"] - param["r"]
param["y"] = local["y"] + param["r"]
param["a1"] = 270
param["a2"] = 360
GW_DrawArc()
GraphicsWindow.DrawLine(local["x"] + local["width"], local["y"] + param["r"], local["x"] + local["width"], local["y"] + local["height"] - param["r"])
param["x"] = local["x"] + local["width"] - param["r"]
param["y"] = local["y"] + local["height"] - param["r"]
param["a1"] = 0
param["a2"] = 90
GW_DrawArc()
GraphicsWindow.DrawLine(local["x"] + param["r"], local["y"] + local["height"], local["x"] + local["width"] - param["r"], local["y"] + local["height"])
param["x"] = local["x"] + param["r"]
param["y"] = local["y"] + local["height"] - param["r"]
param["a1"] = 90
param["a2"] = 180
GW_DrawArc()
GraphicsWindow.DrawLine(local["x"], local["y"] + param["r"], local["x"], local["y"] + local["height"] - param["r"])
local = Stack.PopValue("local")
param = Stack.PopValue("local")
EndSub
Sub GW_FillQuadrangle
' GraphicsWindow | fill quadrangle
' param x1 - the x co-ordinate of the first point
' param y1 - the y co-ordinate of the first point
' param x2 - the x co-ordinate of the second point
' param y2 - the y co-ordinate of the second point
' param x3 - the x co-ordinate of the third point
' param y3 - the y co-ordinate of the third point
' param x4 - the x co-ordinate of the fourth point
' param y4 - the y co-ordinate of the fourth point
GraphicsWindow.FillTriangle(param["x1"], param["y1"], param["x2"], param["y2"], param["x3"], param["y3"])
GraphicsWindow.FillTriangle(param["x3"], param["y3"], param["x4"], param["y4"], param["x1"], param["y1"])
EndSub
Sub GW_FillHexagon
' param x, y - the left top coordinate of the parallelogram
' param width, height - the size of the parallelogram
' param ratio - the delta x per height
dx = height * ratio
If dx < 0 Then
dx = 0
ElseIf Math.Ceiling(width / 2) < dx Then
dx = Math.Ceiling(width / 2)
EndIf
edge = width - 2 * dx
vx[1] = x + dx
vy[1] = y
vx[2] = vx[1] + edge
vy[2] = vy[1]
vx[3] = x + width
vy[3] = y + height / 2
vx[4] = vx[2]
vy[4] = y + height
vx[5] = vx[1]
vy[5] = vy[4]
vx[6] = x
vy[6] = vy[3]
GraphicsWindow.FillTriangle(vx[1], vy[1], vx[5], vy[5], vx[6], vy[6])
GraphicsWindow.FillRectangle(vx[1], vy[1], edge, height)
GraphicsWindow.FillTriangle(vx[2], vy[2], vx[3], vy[3], vx[4], vy[4])
EndSub
Sub GW_DrawLine
' GraphicsWindow | draw line
' param r, g, b - red, green blue
' param angle
' param x1, y1, x2, y2 - edges of line
GraphicsWindow.PenColor = GraphicsWindow.GetColorFromRGB(r, g, b)
If 0 <= angle And angle < 45 Then
GraphicsWindow.DrawLine(x1 + x0, y1 + y0, x2 + x0, y2 + y0)
ElseIf 45 <= angle And angle < 90 Then
GraphicsWindow.DrawLine(y1 + x0, x1 + y0, y2 + x0, x2 + y0)
ElseIf 90 <= angle And angle < 135 Then
GraphicsWindow.DrawLine(-y1 + x0 + width, x1 + y0, -y2 + x0 + width, x2 + y0)
ElseIf 135 <= angle And angle < 180 Then
GraphicsWindow.DrawLine(-x1 + x0 + width, y1 + y0, -x2 + x0 + width, y2 + y0)
ElseIf 180 <= angle And angle < 225 Then
GraphicsWindow.DrawLine(-x1 + x0 + width, -y1 + y0 + height, -x2 + x0 + width, -y2 + y0 + height)
ElseIf 225 <= angle And angle < 270 Then
GraphicsWindow.DrawLine(-y1 + x0 + width, -x1 + y0 + height, -y2 + x0 + width, -x2 + y0 + height)
ElseIf 270 <= angle And angle < 315 Then
GraphicsWindow.DrawLine(y1 + x0, -x1 + y0 + height, y2 + x0, -x2 + y0 + height)
ElseIf 315 <= angle And angle < 360 Then
GraphicsWindow.DrawLine(x1 + x0, -y1 + y0 + height, x2 + x0, -y2 + y0 + height)
EndIf
EndSub
Sub GW_FillLinearGradientRectangle
' GraphicsWindow | fill linear gradient rectangle
' param["x"], param["y"] - position of the rectangle
' param["width"], param["height"] - size of the rectangle
' param["angle"] - angle of gradient
' param["0"]..param["100"] - 0% to 100% colors
x0 = param["x"]
y0 = param["y"]
width = param["width"]
height = param["height"]
angle = param["angle"]
n = Array.GetItemCount(param)
index = Array.GetAllIndices(param)
color = ""
For i = 1 To n
If index[i] + 0 = index[i] And 0 <= index[i] And index[i] <= 100 Then
c = param[index[i]]
Color_NameToColor()
color[index[i]] = c
EndIf
EndFor
If color[0] = "" Then
color[0] = GraphicsWindow.BrushColor
EndIf
If color[100] = "" Then
color[100] = GraphicsWindow.BrushColor
EndIf
n = Array.GetItemCount(color)
index = Array.GetAllIndices(color)
a45 = Math.Remainder(angle, 45)
If 0 <= angle And angle < 45 Then
w45 = width
h45 = height
ElseIf 45 <= angle And angle < 90 Then
w45 = height
h45 = width
a45 = 45 - a45
ElseIf 90 <= angle And angle < 135 Then
w45 = height
h45 = width
ElseIf 135 <= angle And angle < 180 Then
w45 = width
h45 = height
a45 = 45 - a45
ElseIf 180 <= angle And angle < 225 Then
w45 = width
h45 = height
ElseIf 225 <= angle And angle < 270 Then
w45 = height
h45 = width
a45 = 45 - a45
ElseIf 270 <= angle And angle < 315 Then
w45 = height
h45 = width
ElseIf 315 <= angle And angle < 360 Then
w45 = width
h45 = height
a45 = 45 - a45
EndIf
If a45 = 0 Then
For x = 0 To w45
percent = Math.Floor(x * 100 / w45)
Color_PercentToRGB()
x1 = x
y1 = 0
x2 = x
y2 = h45
GW_DrawLine()
EndFor
ElseIf 0 < a45 And a45 <= 45 Then
tan = Math.Tan(Math.GetRadians(a45))
If h45 <= w45 Then
dx = Math.Floor(h45 * tan)
For x = 0 To dx
percent = Math.Floor(x * 100 / (w45 + dx))
Color_PercentToRGB()
x1 = x
y1 = 0
x2 = 0
y2 = Math.Floor(x / tan)
GW_DrawLine()
EndFor
For x = dx To w45
percent = Math.Floor(x * 100 / (w45 + dx))
Color_PercentToRGB()
x1 = x
y1 = 0
x2 = x - dx
y2 = h45
GW_DrawLine()
EndFor
For x = w45 To w45 + dx
percent = Math.Floor(x * 100 / (w45 + dx))
Color_PercentToRGB()
x1 = x - dx
y1 = h45
x2 = w45
y2 = Math.Floor((x - w45) / tan)
GW_DrawLine()
EndFor
Else ' width < height
dx = Math.Floor(h45 * tan - w45)
dy = Math.Floor(w45 / tan)
For x = 0 To w45
percent = Math.Floor(x * 100 / (2 * w45 + dx))
Color_PercentToRGB()
x1 = x
y1 = 0
x2 = 0
y2 = Math.Floor(x / tan)
GW_DrawLine()
EndFor
For x = 0 To dx
percent = Math.Floor((x + w45) * 100 / (2 * w45 + dx))
Color_PercentToRGB()
x1 = w45
y1 = Math.Floor(x / tan)
x2 = 0
y2 = y1 + dy
GW_DrawLine()
EndFor
dy = h45 - Math.Floor(w45 / tan)
For x = 0 To w45
percent = Math.Floor((x + w45 + dx) * 100 / (2 * w45 + dx))
Color_PercentToRGB()
x1 = x
y1 = h45
x2 = w45
y2 = dy + Math.Floor(x / tan)
GW_DrawLine()
EndFor
EndIf
EndIf
EndSub
Sub _GetPoints
' param points - points text
' return p - points array
' return n - number of points
_p = 1
n = 0
len = Text.GetLength(points)
While _p <= len
_s = Text.GetIndexOf(Text.GetSubTextToEnd(points, _p), " ")
If 0 < _s Then
point = Text.GetSubText(points, _p, _s - 1)
_p = _p + _s
Else
point = Text.GetSubTextToEnd(points, _p)
_p = len + 1
EndIf
_c = Text.GetIndexOf(point, ",")
If 0 < _c Then
n = n + 1
_point["x"] = Text.GetSubText(point, 1, _c - 1)
_point["y"] = Text.GetSubTextToEnd(point, _c + 1)
p[n] = _point
EndIf
EndWhile
EndSub
Sub GW_FillPolygon
' GraphicsWindow | fill polygon
' param points - points text
_GetPoints()
i[1] = 1
i[2] = 2
i[3] = 3
a = 4
d = n
v = 2
For _i = 1 To n - 2
_p1 = p[i[1]]
_p2 = p[i[2]]
_p3 = p[i[3]]
GraphicsWindow.FillTriangle(_p1["x"], _p1["y"], _p2["x"], _p2["y"], _p3["x"], _p3["y"])
If Math.Remainder(_i, 2) = 1 Then
i[v] = d
d = d - 1
Else
i[v] = a
a = a + 1
EndIf
v = v - 1
If v < 1 Then
v = 3
EndIf
EndFor
EndSub
Sub GW_FillRoundRectangle
' GraphicsWindow | fill round rectangle
' param x - co-ordinate of the rectangle
' param y - co-ordinate of the rectangle
' param width - of the rectangle
' param height - of the rectangle
' param border-radius
Stack.PushValue("local", param)
If (param["width"] / 2 < param["border-radius"]) Or (param["height"] / 2 < param["border-radius"]) Then
param["border-radius"] = Math.Min(param["width"] / 2, param["height"] / 2)
EndIf
GraphicsWindow.FillEllipse(param["x"], param["y"], param["border-radius"] * 2, param["border-radius"] * 2)
GraphicsWindow.FillRectangle(param["x"] + param["border-radius"], param["y"], param["width"] - param["border-radius"] * 2, param["height"])
GraphicsWindow.FillEllipse(param["x"] + param["width"] - param["border-radius"] * 2, param["y"], param["border-radius"] * 2, param["border-radius"] * 2)
GraphicsWindow.FillRectangle(param["x"], param["y"] + param["border-radius"], param["width"], param["height"] - param["border-radius"] * 2)
GraphicsWindow.FillEllipse(param["x"], param["y"] + param["height"] - param["border-radius"] * 2, param["border-radius"] * 2, param["border-radius"] * 2)
GraphicsWindow.FillEllipse(param["x"] + param["width"] - param["border-radius"] * 2, param["y"] + param["height"] - param["border-radius"] * 2, param["border-radius"] * 2, param["border-radius"] * 2)
param = Stack.PopValue("local")
EndSub
Sub GW_GetTextWidth
' GraphicsWindow | get text width
' param fs - font size
' param fn - font name
' param fb - font bold
' param fi - font italic
' param txt - text to get width in px
' return width - text width
yc = 4
bc = "#FFFFFF"
bc6 = Text.GetSubTextToEnd(bc, Text.GetLength(bc) - 5)
fc = "#FEFEFE"
GraphicsWindow.BrushColor = bc
GraphicsWindow.FillRectangle(0, yc, gw, gh - yc)
GraphicsWindow.FontSize = fs
GraphicsWindow.FontName = fn
GraphicsWindow.FontBold = fb
GraphicsWindow.FontItalic = fi
GraphicsWindow.BrushColor = fc
GraphicsWindow.DrawText(0, yc, "||")
y0 = yc
y1 = yc + fs
x0 = 0
x1 = fs * 2
If gw < x1 Then
x1 = gw - 1
EndIf
GW_Measure()
px0 = px
GraphicsWindow.BrushColor = bc
GraphicsWindow.FillRectangle(0, yc, gw, gh - yc)
str = "|" + txt + "|"
GraphicsWindow.BrushColor = fc
GraphicsWindow.DrawText(0, yc, str)
x1 = fs * Text.GetLength(str)
If gw < x1 Then
x1 = gw - 1
EndIf
GW_Measure()
width = px - px0
EndSub
Sub GW_Measure
' GraphicsWindow | measure text width
' return px - width in pixel (px)
_y = Math.Floor((y0 + y1) / 2)
For _x = x0 To x1
color = GraphicsWindow.GetPixel(_x, _y)
If Not[Text.EndsWith(color, bc6)] Then
left = _x
_x = x1 ' exit For
EndIf
EndFor
For _x = x1 To x0 Step -1
color = GraphicsWindow.GetPixel(_x, _y)
If Not[Text.EndsWith(color, bc6)] Then
right = _x
_x = x0 ' exit For
EndIf
EndFor
For _x = right To x0 Step -1
color = GraphicsWindow.GetPixel(_x, _y)
If Text.EndsWith(color, "FFFFFF") Then
right = _x + 1
_x = x0 ' exit For
EndIf
EndFor
px = right - left
EndSub
@nonkit
Copy link
Author

nonkit commented Apr 1, 2020

Variables Not, gw and gh should be initialized before calling GW_GetTextWidth(). Sample Program ID is KTK906-4.

@nonkit
Copy link
Author

nonkit commented Apr 1, 2020

Changed to use Color_NameToColor in GW_FillLinearGradientRectangle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment