Skip to content

Commit

Permalink
fix: Much refactoring to graphics
Browse files Browse the repository at this point in the history
* Move text rendering Lua-side.
* Simplified digit font to use 32x8 font bitmap like everything else.
* All Canvases are now internally backed by a 32-bit buffer, to simplify
  rendering.
* All custom inverted drawing logic moved from Canvas to CGContext,
  CGContext.draw() now being given direct access to the Canvas backing
  buffer to facilitate that.
* Direct (non-CoreGraphics) line drawing logic now used for all modes,
  not just inverted, for consistency (no more hairy lines as a result).
  Also fixed off-by-two error in that logic when drawing lines with
  negative x or y direction.
* Box drawing also updated to use direct line drawing.
* All invert operations now supported on colour drawables as well as
  greyscale ones.
* Invert supported on all gCOPY (and now by extension, text rendering)
  operations.
* Improved performance of text rendering with optimised .copy and .mcopy
  operations.
* Canvas.swift and CGContext.swift no longer rely on anything from
  UIKit.
* More consistent support for gSETPENWIDTH.
* Be bug-compatible with allowing negative colour values in gCOLOR.
  • Loading branch information
tomsci committed Oct 24, 2024
1 parent da2e49a commit 8d4c412
Show file tree
Hide file tree
Showing 28 changed files with 938 additions and 650 deletions.
4 changes: 0 additions & 4 deletions OpoLua.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@
D8C3BD652774BEC2003B1AD0 /* Console.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8C3BD642774BEC2003B1AD0 /* Console.swift */; };
D8C3BD672774BF1F003B1AD0 /* OpoLuaError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8C3BD662774BF1F003B1AD0 /* OpoLuaError.swift */; };
D8C3BD6A2774F4A2003B1AD0 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8C3BD692774F4A2003B1AD0 /* GameController.framework */; };
D8C409632C3CF62900C9E857 /* OpoIoHandler_UIKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8C409622C3CF62900C9E857 /* OpoIoHandler_UIKit.swift */; };
D8C409862C3CF6DB00C9E857 /* CGImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8C409852C3CF6DB00C9E857 /* CGImage.swift */; };
D8C43DF527C3EFEF00944A11 /* RootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8C43DF427C3EFEF00944A11 /* RootViewController.swift */; };
D8C679BA27483B5600BD8720 /* DirectoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8C679B927483B5600BD8720 /* DirectoryViewController.swift */; };
Expand Down Expand Up @@ -211,7 +210,6 @@
D8C3BD642774BEC2003B1AD0 /* Console.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Console.swift; sourceTree = "<group>"; };
D8C3BD662774BF1F003B1AD0 /* OpoLuaError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpoLuaError.swift; sourceTree = "<group>"; };
D8C3BD692774F4A2003B1AD0 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/System/Library/Frameworks/GameController.framework; sourceTree = DEVELOPER_DIR; };
D8C409622C3CF62900C9E857 /* OpoIoHandler_UIKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpoIoHandler_UIKit.swift; sourceTree = "<group>"; };
D8C409852C3CF6DB00C9E857 /* CGImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGImage.swift; sourceTree = "<group>"; };
D8C43DF427C3EFEF00944A11 /* RootViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootViewController.swift; sourceTree = "<group>"; };
D8C679B927483B5600BD8720 /* DirectoryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DirectoryViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -503,7 +501,6 @@
DB0B9149276E1BC5006F5CD0 /* OplKeyCode.swift */,
DB79FFE52742E596005E904F /* OpoInterpreter.swift */,
DB5AC9752757B6ED0043FE5C /* OpoIoHandler_CoreGraphics.swift */,
D8C409622C3CF62900C9E857 /* OpoIoHandler_UIKit.swift */,
DB79001B2746B88F005E904F /* OpoIoHandler.swift */,
DB0366A72C42E85500187DD0 /* PsiLuaEnv.swift */,
);
Expand Down Expand Up @@ -613,7 +610,6 @@
D884A3D52779025A008954A0 /* SystemFileSystem.swift in Sources */,
D80D65A8279DD2060020F994 /* Icon.swift in Sources */,
D8FE60052757177200711717 /* Settings.swift in Sources */,
D8C409632C3CF62900C9E857 /* OpoIoHandler_UIKit.swift in Sources */,
D81B875E2790DAAD00E71960 /* InstallerViewController.swift in Sources */,
D8DCD040277ACD7800760302 /* CanvasSprite.swift in Sources */,
D86724F22771672A009C7246 /* InterpreterThread.swift in Sources */,
Expand Down
403 changes: 221 additions & 182 deletions OpoLua/Extensions/CGContext.swift

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions OpoLua/Model/Program.swift
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,12 @@ class Program {
windowServer.createWindow(id: id, rect: rect, mode: mode, shadowSize: shadowSize)
return .nothing

case .loadFont(let drawableId, let fontUid):
if let metrics = windowServer.load(font: fontUid, into: drawableId) {
return .fontMetrics(metrics)
} else {
return .error(.invalidArguments)
}
case .close(let drawableId):
windowServer.close(drawableId: drawableId)
return .nothing
Expand All @@ -367,10 +373,6 @@ class Program {
windowServer.setVisiblity(handle: drawableId, visible: flag)
return .nothing

case .textSize(let string, let fontInfo):
let metrics = WindowServer.textSize(string: string, fontInfo: fontInfo)
return .textMetrics(metrics)

case .busy(let drawableId, let delay):
windowServer.busy(drawableId: drawableId, delay: delay)
return .nothing
Expand Down
50 changes: 25 additions & 25 deletions OpoLua/Model/WindowServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,6 @@ protocol WindowServerDelegate: CanvasViewDelegate {

class WindowServer {

static func textSize(string: String, fontInfo: Graphics.FontInfo) -> Graphics.TextMetrics {
if let font = fontInfo.toBitmapFont() {
let bold = fontInfo.flags.contains(.bold)
let renderer = BitmapFontCache.shared.getRenderer(font: font, embolden: bold)
let (w, h) = renderer.getTextSize(string)
return Graphics.TextMetrics(size: Graphics.Size(width: w, height: h), ascent: font.ascent, descent: font.descent)
} else {
let font = fontInfo.toUiFont()! // One or other has to return non-nil
let attribStr = NSAttributedString(string: string, attributes: [.font: font])
let sz = attribStr.size()
// This is not really the right definition for ascent but it seems to work for where epoc expects
// the text to be, so...
let ascent = Int(ceil(sz.height) + font.descender)
let descent = Int(ceil(font.descender))
return Graphics.TextMetrics(size: Graphics.Size(width: Int(ceil(sz.width)), height: Int(ceil(sz.height))),
ascent: ascent, descent: descent)
}
}

weak var delegate: WindowServerDelegate?

private var device: Device
Expand Down Expand Up @@ -239,7 +220,8 @@ class WindowServer {
if let cursor {
let op = Graphics.DrawCommand.OpType.fill(cursor.rect.size)
let col: Graphics.Color = cursor.flags.contains(.grey) ? .midGray : .black
cursorDrawCmd = Graphics.DrawCommand(drawableId: cursor.id, type: op, mode: .invert, origin: cursor.rect.origin, color: col, bgcolor: .white, penWidth: 1, greyMode: .normal)
cursorDrawCmd = Graphics.DrawCommand(drawableId: cursor.id, type: op, mode: .invert,
origin: cursor.rect.origin, color: col, bgcolor: .white, penWidth: 1, greyMode: .normal)
let _ = window(for: cursor.id)?.draw(cursorDrawCmd!, provider: self)
cursorCurrentlyDrawn = true
if !cursor.flags.contains(.notFlashing) {
Expand Down Expand Up @@ -491,6 +473,23 @@ class WindowServer {
return result
}

func load(font fontUid: UInt32, into drawableId: Graphics.DrawableId) -> Graphics.FontMetrics? {
dispatchPrecondition(condition: .onQueue(.main))
guard let font = BitmapFontInfo(uid: fontUid) else {
return nil
}
let bmpSize = Graphics.Size(width: font.charw * 32, height: font.charh * 8)
let canvas = Canvas(id: drawableId, size: bmpSize, mode: .gray2)
drawablesById[canvas.id] = canvas

let img = UIImage(named: "fonts/\(font.bitmapName)/\(font.bitmapName)")!.cgImage!
// Note this won't work for the digit font which is (currently) the only one which doesn't use a 32x8 character
// bitmap for its characters.
canvas.draw(image: img)

return Graphics.FontMetrics(height: font.charh, maxwidth: font.charw, ascent: font.ascent, descent: font.descent, widths: font.widths)
}

}

extension WindowServer: CanvasViewDelegate {
Expand Down Expand Up @@ -527,11 +526,12 @@ extension WindowServer: RootViewDelegate {

extension WindowServer: DrawableImageProvider {

func getImageFor(drawable: Graphics.DrawableId) -> CGImage? {
guard let canvas = self.drawable(for: drawable) else {
return nil
}
return canvas.getImage()
func getDrawable(_ id: Graphics.DrawableId) -> Drawable? {
return self.drawable(for: id)
}

func getDitherImage() -> CGImage {
return UIImage.ditherPattern().cgImage!
}

}
250 changes: 248 additions & 2 deletions OpoLua/Resources/fonts/10000128/10000128.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,56 @@
"ascent": 35,
"maxwidth": 12,
"encoding": "windows-1252",
"firstch": 48,
"firstch": 0,
"widths": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
12,
6,
0,
12,
12,
12,
Expand All @@ -15,6 +62,205 @@
12,
12,
12,
12
12,
12,
6,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
Binary file modified OpoLua/Resources/fonts/10000128/10000128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed OpoLua/Resources/fonts/10000128/U+002D.png
Binary file not shown.
Binary file removed OpoLua/Resources/fonts/10000128/U+002E.png
Binary file not shown.
Binary file removed OpoLua/Resources/fonts/10000128/U+003A.png
Binary file not shown.
Loading

0 comments on commit 8d4c412

Please sign in to comment.