Skip to content

Commit

Permalink
changed the way window scaling is done
Browse files Browse the repository at this point in the history
to support high DPI scaling, use the FramebufferSize functions in glfwcanvas and sdlcanvas to determine the canvas size
  • Loading branch information
tfriedel6 committed Feb 11, 2020
1 parent 259bb9e commit a80e377
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 47 deletions.
14 changes: 14 additions & 0 deletions examples/drawing/drawing.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ func main() {
cv.SetFillStyle("#000")
cv.FillRect(0, 0, w, h)

// Estimated size used for scaling
const (
contentWidth = 1000
contentHeight = 350
)

// Calculate scaling
sx := w / contentWidth
sy := h / contentHeight
scale := math.Min(sx, sy)
cv.Save()
defer cv.Restore()
cv.Scale(scale, scale)

// Draw lines with different colors and line thickness
for x := 1.0; x < 10.5; x += 1.0 {
cv.SetStrokeStyle(int(x*25), 255, 255)
Expand Down
26 changes: 9 additions & 17 deletions glfwcanvas/glfwcanvas.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ type Window struct {
KeyUp func(scancode int, rn rune, name string)
KeyChar func(rn rune)
SizeChange func(w, h int)
scalex float64
scaley float64
}

// CreateWindow creates a window using SDL and initializes the OpenGL context
Expand Down Expand Up @@ -79,8 +77,6 @@ func CreateWindow(w, h int, title string) (*Window, *canvas.Canvas, error) {
wnd := &Window{
Window: window,
canvas: cv,
scalex: float64(fbw) / float64(w),
scaley: float64(fbh) / float64(h),
}

var mx, my int
Expand All @@ -93,7 +89,7 @@ func CreateWindow(w, h int, title string) (*Window, *canvas.Canvas, error) {
}
})
window.SetCursorPosCallback(func(w *glfw.Window, xpos, ypos float64) {
mx, my = int(math.Round(xpos*wnd.scalex)), int(math.Round(ypos*wnd.scaley))
mx, my = int(math.Round(xpos)), int(math.Round(ypos))
if wnd.MouseMove != nil {
wnd.MouseMove(mx, my)
}
Expand All @@ -116,12 +112,10 @@ func CreateWindow(w, h int, title string) (*Window, *canvas.Canvas, error) {
}
})
window.SetSizeCallback(func(w *glfw.Window, width, height int) {
fbw, fbh := window.GetFramebufferSize()
wnd.scalex = float64(fbw) / float64(width)
wnd.scaley = float64(fbh) / float64(height)
if wnd.SizeChange != nil {
wnd.SizeChange(width, height)
} else {
fbw, fbh := window.GetFramebufferSize()
backend.SetBounds(0, 0, fbw, fbh)
}
})
Expand Down Expand Up @@ -168,25 +162,23 @@ func (wnd *Window) FinishFrame() {
func (wnd *Window) MainLoop(run func()) {
for !wnd.close {
wnd.StartFrame()
if wnd.scalex != 1 || wnd.scaley != 1 {
wnd.canvas.Save()
wnd.canvas.Scale(wnd.scalex, wnd.scaley)
}
run()
if wnd.scalex != 1 || wnd.scaley != 1 {
wnd.canvas.Restore()
}
wnd.FinishFrame()
}
}

// Size returns the current width and height of the window
// Size returns the current width and height of the window.
// Note that this size may not be the same as the size of the
// framebuffer, since some operating systems scale the window.
// Use the Width/Height/Size function on Canvas to determine
// the drawing size
func (wnd *Window) Size() (int, int) {
return wnd.Window.GetSize()
}

// FramebufferSize returns the current width and height of
// the framebuffer
// the framebuffer, which is also the internal size of the
// canvas
func (wnd *Window) FramebufferSize() (int, int) {
return wnd.Window.GetFramebufferSize()
}
41 changes: 11 additions & 30 deletions sdlcanvas/sdlcanvas.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
_ "image/gif" // Imported here so that applications based on this package support these formats by default
_ "image/jpeg"
_ "image/png"
"math"
"runtime"
"time"
"unicode/utf8"
Expand Down Expand Up @@ -39,8 +38,6 @@ type Window struct {
KeyUp func(scancode int, rn rune, name string)
KeyChar func(rn rune)
SizeChange func(w, h int)
scalex float64
scaley float64
}

// CreateWindow creates a window using SDL and initializes the OpenGL context
Expand Down Expand Up @@ -108,8 +105,6 @@ func CreateWindow(w, h int, title string) (*Window, *canvas.Canvas, error) {
Backend: backend,
canvas: cv,
events: make([]sdl.Event, 0, 100),
scalex: float64(fbw) / float64(w),
scaley: float64(fbh) / float64(h),
}

return wnd, cv, nil
Expand Down Expand Up @@ -150,27 +145,23 @@ func (wnd *Window) StartFrame() error {
case *sdl.MouseButtonEvent:
if e.Type == sdl.MOUSEBUTTONDOWN {
if wnd.MouseDown != nil {
mx, my := wnd.mpos(e.X, e.Y)
wnd.MouseDown(int(e.Button), mx, my)
wnd.MouseDown(int(e.Button), int(e.X), int(e.Y))
handled = true
}
} else if e.Type == sdl.MOUSEBUTTONUP {
if wnd.MouseUp != nil {
mx, my := wnd.mpos(e.X, e.Y)
wnd.MouseUp(int(e.Button), mx, my)
wnd.MouseUp(int(e.Button), int(e.X), int(e.Y))
handled = true
}
}
case *sdl.MouseMotionEvent:
if wnd.MouseMove != nil {
mx, my := wnd.mpos(e.X, e.Y)
wnd.MouseMove(mx, my)
wnd.MouseMove(int(e.X), int(e.Y))
handled = true
}
case *sdl.MouseWheelEvent:
if wnd.MouseWheel != nil {
mx, my := wnd.mpos(e.X, e.Y)
wnd.MouseWheel(mx, my)
wnd.MouseWheel(int(e.X), int(e.Y))
handled = true
}
case *sdl.KeyboardEvent:
Expand All @@ -195,8 +186,6 @@ func (wnd *Window) StartFrame() error {
if e.WindowID == wnd.WindowID {
if e.Event == sdl.WINDOWEVENT_SIZE_CHANGED {
fbw, fbh := wnd.Window.GLGetDrawableSize()
wnd.scalex = float64(fbw) / float64(e.Data1)
wnd.scaley = float64(fbh) / float64(e.Data2)
if wnd.SizeChange != nil {
wnd.SizeChange(int(e.Data1), int(e.Data2))
handled = true
Expand All @@ -220,12 +209,6 @@ func (wnd *Window) StartFrame() error {
return nil
}

func (wnd *Window) mpos(x, y int32) (int, int) {
mx := int(math.Round(float64(x) * wnd.scalex))
my := int(math.Round(float64(y) * wnd.scaley))
return mx, my
}

// FinishFrame updates the FPS count and displays the frame
func (wnd *Window) FinishFrame() {
now := time.Now()
Expand Down Expand Up @@ -267,27 +250,25 @@ func (wnd *Window) MainLoop(run func()) {
}
}

if wnd.scalex != 1 || wnd.scaley != 1 {
wnd.canvas.Save()
wnd.canvas.Scale(wnd.scalex, wnd.scaley)
}
run()
if wnd.scalex != 1 || wnd.scaley != 1 {
wnd.canvas.Restore()
}

wnd.FinishFrame()
}
}

// Size returns the current width and height of the window
// Size returns the current width and height of the window.
// Note that this size may not be the same as the size of the
// framebuffer, since some operating systems scale the window.
// Use the Width/Height/Size function on Canvas to determine
// the drawing size
func (wnd *Window) Size() (int, int) {
w, h := wnd.Window.GetSize()
return int(w), int(h)
}

// FramebufferSize returns the current width and height of
// the framebuffer
// the framebuffer, which is also the internal size of the
// canvas
func (wnd *Window) FramebufferSize() (int, int) {
w, h := wnd.Window.GLGetDrawableSize()
return int(w), int(h)
Expand Down

0 comments on commit a80e377

Please sign in to comment.