Looks OK here (though I wish macOS enjoyed high-DPI canvas support).
Code: Select all
; This app makes use of the Source Code Pro font, which is © 2023 Adobe (http://www.adobe.com/),
; with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the
; United States and/or other countries.
;
; The Source Code Pro repository and license details can be found at:
; https://github.com/adobe-fonts/source-code-pro/
;
; A copy of the license should be downloaded and made available with this program upon launch,
; as precondition for downloading the actual fonts.
;
EnableExplicit
UseZipPacker()
UseSHA3Fingerprint() ; Definitely not overkill.
; Constants.
; ═══════════════════════════════════════════════════════
#OUT_DIR = "pb-" + #PB_Compiler_Version + "-otf-ttf-test/"
#OUT_LICENSE = #OUT_DIR + "LICENSE.md"
#OUT_PKG_OTF = #OUT_DIR + "source-code-pro-2.042-otf.zip"
#OUT_PKG_TTF = #OUT_DIR + "source-code-pro-2.042-ttf.zip"
#OUT_FNT_OTF = #OUT_DIR + "source-code-pro-semibold.otf"
#OUT_FNT_TTF = #OUT_DIR + "source-code-pro-extralight.ttf"
#SRC_LICENSE = "https://raw.githubusercontent.com/adobe-fonts/source-code-pro/f1680b3312c48cff23da1374515b0b7c1ff87cee/LICENSE.md"
#SRC_PKG_OTF = "https://github.com/adobe-fonts/source-code-pro/releases/download/2.042R-u%2F1.062R-i%2F1.026R-vf/OTF-source-code-pro-2.042R-u_1.062R-i.zip"
#SRC_PKG_TTF = "https://github.com/adobe-fonts/source-code-pro/releases/download/2.042R-u%2F1.062R-i%2F1.026R-vf/TTF-source-code-pro-2.042R-u_1.062R-i.zip"
#SRC_ARC_OTF = "OTF/SourceCodePro-Semibold.otf"
#SRC_ARC_TTF = "TTF/SourceCodePro-ExtraLight.ttf"
#CRC_LICENSE = "fb5eb2de5735e2208b8427aad9b9b90ecfcc86ea220fe021ff2cd58770aff83b6cf79ca4f87e07462871430ceb1da4dd1f595195724fe21fdd7f9f34716de91c"
#CRC_PKG_OTF = "c1b4ffe67bc6474ce42fe57d8d0abea60d55fb9ec1b72931536e4b4c77864770ea0f5d646bc2c5dc8ca20899832839e998f3efaca0a55319ba08f72272e6f144"
#CRC_PKG_TTF = "211074c8d86b2ed022ebad8cbd02ed78a30b10615cc38745f519e21b514a614c9e375fad1bd886e1bde24e4333dde353eee2474635cf21c5a8456183f1f9d194"
#CRC_FNT_OTF = "d1b3ca3858659590bb641df62547857b02ae67f38ac82203ab30bc5d462e76172ca4e06606fc5bc0c132bef97c7936498a4c1792fe0916e08e0230246776ae98"
#CRC_FNT_TTF = "f27846e9a6ffafe97d4e72e8360ee23d285fa1482f191c7bc1df8e4e6bdcff4c88af70497a9cf46dfdb146d8de9a8548144b772a4b9b6cd64e9c98f27b34e0d9"
#FNT_NAME_OTF = "Source Code Pro Semibold"
#FNT_NAME_TTF = "Source Code Pro ExtraLight"
; Whether or not a dummy StartDrawing():StopDrawing() sequence should be executed prior to
; registering fonts.
; For reproducing Linux bug: https://www.purebasic.fr/english/viewtopic.php?t=81284
#TEST_SHOULD_DUMMY_DRAW_BEFORE_REGISTER_FONT = #True
; Whether or not the OTF font should be registered.
#TEST_LOAD_OTF = #True
; Whether or not the TTF font should be registered.
#TEST_LOAD_TTF = #True
; Helpers.
; ═══════════════════════════════════════════════════════
Procedure DownloadIfNotPresent(url.s, outPath.s, expectedHash.s)
Protected humanName.s = GetFilePart(outPath)
; Exit early if already present with expected hash.
If FileSize(outPath) > 0 And FileFingerprint(outPath, #PB_Cipher_SHA3, 512) = expectedHash
Debug "Reusing existing " + humanName + "!"
ProcedureReturn
EndIf
; Attempt download...
Debug "Downloading " + humanName + "..."
If Not ReceiveHTTPFile(url, outPath)
Debug "Download failed!"
End
EndIf
; Verify hash of downloaded file...
Protected resultHash.s = FileFingerprint(outPath, #PB_Cipher_SHA3, 512)
If resultHash <> expectedHash
Debug "Resulting hash " + resultHash + " does not match expectation of: " + expectedHash
End
EndIf
Debug "Download OK!" + #CRLF$
EndProcedure
Procedure ExtractIfNotPresent(archivePath.s, archiveEntryPath.s, outPath.s, expectedHash.s)
Protected humanName.s = GetFilePart(outPath)
; Exit early if already present with expected hash.
If FileSize(outPath) > 0 And FileFingerprint(outPath, #PB_Cipher_SHA3, 512) = expectedHash
Debug "Reusing existing " + humanName + "!"
ProcedureReturn
EndIf
; Attempt extract...
Protected pack = OpenPack(#PB_Any, archivePath, #PB_PackerPlugin_Zip)
Debug "Extracting " + archiveEntryPath + "..."
If Not pack
Debug "Failed to open pack: " + archivePath
End
EndIf
If UncompressPackFile(pack, outPath, archiveEntryPath) <= 0
Debug "Failed to decompress file '" + archiveEntryPath + "' of archive: " + archivePath
End
EndIf
; Verify hash of extracted file...
Protected resultHash.s = FileFingerprint(outPath, #PB_Cipher_SHA3, 512)
If resultHash <> expectedHash
Debug "Resulting hash " + resultHash + " does not match expectation of: " + expectedHash
End
EndIf
ClosePack(pack)
Debug "Extract OK!" + #CRLF$
EndProcedure
; Entry.
; ═══════════════════════════════════════════════════════
; Create directory if missing.
If FileSize(#OUT_DIR) <> -2
CreateDirectory(#OUT_DIR)
EndIf
; Download license + fonts if missing...
DownloadIfNotPresent(#SRC_LICENSE, #OUT_LICENSE, #CRC_LICENSE)
DownloadIfNotPresent(#SRC_PKG_OTF, #OUT_PKG_OTF, #CRC_PKG_OTF)
DownloadIfNotPresent(#SRC_PKG_TTF, #OUT_PKG_TTF, #CRC_PKG_TTF)
; Extract fonts...
ExtractIfNotPresent(#OUT_PKG_OTF, #SRC_ARC_OTF, #OUT_FNT_OTF, #CRC_FNT_OTF)
ExtractIfNotPresent(#OUT_PKG_TTF, #SRC_ARC_TTF, #OUT_FNT_TTF, #CRC_FNT_TTF)
; Trigger a Linux font use bug where desired.
CompilerIf #TEST_SHOULD_DUMMY_DRAW_BEFORE_REGISTER_FONT
Define dummyImg = CreateImage(#PB_Any, 512, 512, 32)
StartDrawing(ImageOutput(dummyImg))
StopDrawing()
FreeImage(dummyImg)
CompilerEndIf
; Register OTF unless disabled.
CompilerIf #TEST_LOAD_OTF
Define regFontRes = RegisterFontFile(#OUT_FNT_OTF)
Debug "Register OTF (" + #OUT_FNT_OTF + "): " + regFontRes
CompilerEndIf
; Register TTF unless disabled.
CompilerIf #TEST_LOAD_TTF
Define regFontRes = RegisterFontFile(#OUT_FNT_TTF)
Debug "Register TTF (" + #OUT_FNT_TTF + "): " + regFontRes
CompilerEndIf
; Try and load fonts.
Global fntOTF = LoadFont(#PB_Any, #FNT_NAME_OTF, 16)
Global fntTTF = LoadFont(#PB_Any, #FNT_NAME_TTF, 16)
; Various pangrams because the quick brown fox tired itself out jumping over dogs all day.
Global Dim pangrams.s(3)
pangrams(0) = "Sphinx of black quartz, judge my vow."
pangrams(1) = "The five boxing wizards jump quickly."
pangrams(2) = "Jackdaws love my big sphinx of quartz."
pangrams(3) = "Pack my box with five dozen liquor jugs."
; Finally... create window and render.
Global wnd = OpenWindow(#PB_Any, 0, 0, 800, 360, "OTF/TTF RegisterFont(...) Test", #PB_Window_ScreenCentered |
#PB_Window_MinimizeGadget |
#PB_Window_MaximizeGadget |
#PB_Window_SizeGadget |
#PB_Window_Invisible)
Global canvas = CanvasGadget(#PB_Any, 0, 0, WindowWidth(wnd) / 2, WindowHeight(wnd) - 20)
Global labelLicense = TextGadget(#PB_Any, 0, WindowHeight(wnd) - 20, WindowWidth(wnd), 20, "See 3rd party font licenses: " + #OUT_LICENSE, #PB_Text_Center)
SetGadgetColor(labelLicense, #PB_Gadget_BackColor, $000000)
SetGadgetColor(labelLicense, #PB_Gadget_FrontColor, $ffffff)
SetWindowColor(wnd, 0)
SmartWindowRefresh(wnd, #True)
AddKeyboardShortcut(wnd, #PB_Shortcut_Escape, 1)
Procedure render()
Protected y
StartDrawing(CanvasOutput(canvas))
Box(0, 0, OutputWidth(), OutputHeight(), $151515)
DrawingMode(#PB_2DDrawing_Transparent)
DrawingFont(#PB_Default)
DrawText(8, 8, "OTF", $ffffff)
DrawingFont(FontID(fntOTF))
For y = 0 To ArraySize(pangrams())
DrawText(8, DesktopScaledY(32 + 32 * y), pangrams(y), $ffffff)
Next y
DrawingFont(#PB_Default)
DrawText(8, 8 + OutputHeight() / 2, "TTF", $ffffff)
DrawingFont(FontID(fntTTF))
For y = 0 To ArraySize(pangrams())
DrawText(8, DesktopScaledY(32 + 32 * y) + OutputHeight() / 2, pangrams(y), $ffffff)
Next y
StopDrawing()
EndProcedure
Procedure onResize()
Protected wndWidth = WindowWidth(wnd)
Protected wndHeight = WindowHeight(wnd)
Protected canvasHeight = wndHeight - 20
If canvasHeight < 1
canvasHeight = 1
EndIf
ResizeGadget(canvas, #PB_Ignore, #PB_Ignore, wndWidth, canvasHeight)
ResizeGadget(labelLicense, #PB_Ignore, wndHeight - 20, wndWidth, #PB_Ignore)
render()
EndProcedure
BindEvent(#PB_Event_SizeWindow, @onResize())
onResize()
HideWindow(wnd, #False)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow, #PB_Event_Menu
Break
EndSelect
ForEver