diff --git a/CompileShadersD3D11/CompileShadersD3D11.cpp b/CompileShadersD3D11/CompileShadersD3D11.cpp index c98c4c5..943b0f5 100644 --- a/CompileShadersD3D11/CompileShadersD3D11.cpp +++ b/CompileShadersD3D11/CompileShadersD3D11.cpp @@ -23,7 +23,7 @@ const CompileJob kCompileJobs[] = { { L"ShaderSrc\\DrawQuadV.hlsl", - L"GpD3D\\ShadersD3D11\\DrawQuadV_D3D11.cpp", + L"GpDisplayDriver_D3D11\\CompiledShaders\\DrawQuadV_D3D11.cpp", "g_drawQuadV_D3D11", drawQuadDefs, "VSMain", @@ -31,7 +31,7 @@ const CompileJob kCompileJobs[] = }, { L"ShaderSrc\\DrawQuadRGBP.hlsl", - L"GpD3D\\ShadersD3D11\\DrawQuadRGBP_D3D11.cpp", + L"GpDisplayDriver_D3D11\\CompiledShaders\\DrawQuadRGBP_D3D11.cpp", "g_drawQuadRGBP_D3D11", drawQuadDefs, "PSMain", @@ -39,7 +39,7 @@ const CompileJob kCompileJobs[] = }, { L"ShaderSrc\\DrawQuadPaletteP.hlsl", - L"GpD3D\\ShadersD3D11\\DrawQuadPaletteP_D3D11.cpp", + L"GpDisplayDriver_D3D11\\CompiledShaders\\DrawQuadPaletteP_D3D11.cpp", "g_drawQuadPaletteP_D3D11", drawQuadDefs, "PSMain", @@ -47,7 +47,7 @@ const CompileJob kCompileJobs[] = }, { L"ShaderSrc\\DrawQuad15BitP.hlsl", - L"GpD3D\\ShadersD3D11\\DrawQuad15BitP_D3D11.cpp", + L"GpDisplayDriver_D3D11\\CompiledShaders\\DrawQuad15BitP_D3D11.cpp", "g_drawQuad15BitP_D3D11", drawQuadDefs, "PSMain", diff --git a/ConvertColorCursors/ConvertColorCursors.cpp b/ConvertColorCursors/ConvertColorCursors.cpp index 12debe3..19dc05d 100644 --- a/ConvertColorCursors/ConvertColorCursors.cpp +++ b/ConvertColorCursors/ConvertColorCursors.cpp @@ -3,6 +3,7 @@ #include "ResourceCompiledTypeList.h" #include "ResourceFile.h" #include "SharedTypes.h" +#include "QDStandardPalette.h" #include "PLBigEndian.h" #include @@ -83,24 +84,11 @@ void WriteToFileCallback(void *context, void *data, int size) fwrite(data, 1, size, static_cast(context)); } -int main(int argc, const char **argv) +void ConvertCursors(PortabilityLayer::ResourceFile *resFile) { - FILE *f = nullptr; - errno_t err = fopen_s(&f, "Packaged\\ApplicationResources.gpr", "rb"); - if (err) - return err; - - PortabilityLayer::CFileStream stream(f); - - PortabilityLayer::ResourceFile *resFile = new PortabilityLayer::ResourceFile(); - if (!resFile->Load(&stream)) - return -1; - - stream.Close(); - const PortabilityLayer::ResourceCompiledTypeList *typeList = resFile->GetResourceTypeList('crsr'); if (!typeList) - return -1; + return; const size_t numRefs = typeList->m_numRefs; for (size_t i = 0; i < numRefs; i++) @@ -247,6 +235,101 @@ int main(int argc, const char **argv) delete[] colorValues; delete[] pixelDataRGBA; } +} + +void ConvertIconFamily(PortabilityLayer::ResourceFile *resFile, int32_t iconBitmapType, int32_t iconColorType, const char *prefix, unsigned int dimension) +{ + const PortabilityLayer::ResourceCompiledTypeList *typeList = resFile->GetResourceTypeList(iconBitmapType); + if (!typeList) + return; + + const size_t numRefs = typeList->m_numRefs; + for (size_t i = 0; i < numRefs; i++) + { + const int resID = typeList->m_firstRef[i].m_resID; + const PortabilityLayer::MMHandleBlock *bwBlock = resFile->GetResource(iconBitmapType, resID, true); + const PortabilityLayer::MMHandleBlock *colorBlock = resFile->GetResource(iconColorType, resID, true); + + if (!bwBlock || !colorBlock) + continue; + + const uint8_t *bwIconData = static_cast(bwBlock->m_contents); + const uint8_t *bwMaskData = bwIconData + (dimension * dimension / 8); + + const uint8_t *indexedData = static_cast(colorBlock->m_contents); + + PortabilityLayer::RGBAColor *pixelData = new PortabilityLayer::RGBAColor[dimension * dimension * 4]; + + for (unsigned int i = 0; i < dimension * dimension; i++) + { + PortabilityLayer::RGBAColor &item = pixelData[i]; + + item = PortabilityLayer::StandardPalette::GetInstance()->GetColors()[indexedData[i]]; + + if (bwMaskData[i / 8] & (0x80 >> (i & 7))) + item.a = 255; + else + item.a = 0; + } + + char outPath[256]; + sprintf_s(outPath, "GpD3D\\ConvertedResources\\%s%i.ico", prefix, resID); + + FILE *outF = nullptr; + errno_t outErr = fopen_s(&outF, outPath, "wb"); + if (!outErr) + { + IconDir iconDir; + iconDir.m_reserved = 0; + iconDir.m_type = 1; + iconDir.m_numImages = 1; + + IconDirEntry iconDirEntry; + iconDirEntry.m_width = dimension; + iconDirEntry.m_height = dimension; + iconDirEntry.m_numColors = 0; + iconDirEntry.m_reserved = 0; + iconDirEntry.m_numPlanes_HotSpotX = 0; + iconDirEntry.m_bpp_HotSpotY = 32; + iconDirEntry.m_imageDataSize = 0; + iconDirEntry.m_imageDataOffset = sizeof(IconDir) + sizeof(IconDirEntry); + + fwrite(&iconDir, 1, sizeof(IconDir), outF); + fwrite(&iconDirEntry, 1, sizeof(IconDirEntry), outF); + + long imageDataStart = ftell(outF); + stbi_write_png_to_func(WriteToFileCallback, outF, dimension, dimension, 4, pixelData, dimension * 4); + long imageDataEnd = ftell(outF); + + fseek(outF, sizeof(IconDir), SEEK_SET); + + iconDirEntry.m_imageDataSize = static_cast(imageDataEnd - imageDataStart); + fwrite(&iconDirEntry, 1, sizeof(IconDirEntry), outF); + fclose(outF); + } + + delete[] pixelData; + } +} + +int main(int argc, const char **argv) +{ + FILE *f = nullptr; + errno_t err = fopen_s(&f, "Packaged\\ApplicationResources.gpr", "rb"); + if (err) + return err; + + PortabilityLayer::CFileStream stream(f); + + PortabilityLayer::ResourceFile *resFile = new PortabilityLayer::ResourceFile(); + if (!resFile->Load(&stream)) + return -1; + + stream.Close(); + + ConvertCursors(resFile); + ConvertIconFamily(resFile, 'ics#', 'ics8', "Small", 16); + ConvertIconFamily(resFile, 'ICN#', 'icl8', "Large", 32); return 0; } diff --git a/ConvertResources.bat b/ConvertResources.bat index 8870e26..c2a7830 100644 --- a/ConvertResources.bat +++ b/ConvertResources.bat @@ -1,6 +1,7 @@ mkdir Packaged mkdir Packaged\Houses mkdir Packaged\WinCursors +mkdir Packaged\WinIcons x64\Release\MiniRez.exe "GpApp2\Glider PRO.r" Packaged\ApplicationResources.gpr diff --git a/GlidePort.sln b/GlidePort.sln index 2befae8..f078dfc 100644 --- a/GlidePort.sln +++ b/GlidePort.sln @@ -27,6 +27,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CompileShadersD3D11", "Comp EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConvertColorCursors", "ConvertColorCursors\ConvertColorCursors.vcxproj", "{B852D549-4020-4477-8BFB-E199FF78B047}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GpDisplayDriver_D3D11", "GpDisplayDriver_D3D11\GpDisplayDriver_D3D11.vcxproj", "{FFC961AC-55B4-4A38-A83E-06AE98F59ACC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImportCharSet", "ImportCharSet\ImportCharSet.vcxproj", "{B3D152CB-CD52-4CD6-9213-710ADE1B8EB0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -131,6 +135,22 @@ Global {B852D549-4020-4477-8BFB-E199FF78B047}.Release|x64.Build.0 = Release|x64 {B852D549-4020-4477-8BFB-E199FF78B047}.Release|x86.ActiveCfg = Release|Win32 {B852D549-4020-4477-8BFB-E199FF78B047}.Release|x86.Build.0 = Release|Win32 + {FFC961AC-55B4-4A38-A83E-06AE98F59ACC}.Debug|x64.ActiveCfg = Debug|x64 + {FFC961AC-55B4-4A38-A83E-06AE98F59ACC}.Debug|x64.Build.0 = Debug|x64 + {FFC961AC-55B4-4A38-A83E-06AE98F59ACC}.Debug|x86.ActiveCfg = Debug|Win32 + {FFC961AC-55B4-4A38-A83E-06AE98F59ACC}.Debug|x86.Build.0 = Debug|Win32 + {FFC961AC-55B4-4A38-A83E-06AE98F59ACC}.Release|x64.ActiveCfg = Release|x64 + {FFC961AC-55B4-4A38-A83E-06AE98F59ACC}.Release|x64.Build.0 = Release|x64 + {FFC961AC-55B4-4A38-A83E-06AE98F59ACC}.Release|x86.ActiveCfg = Release|Win32 + {FFC961AC-55B4-4A38-A83E-06AE98F59ACC}.Release|x86.Build.0 = Release|Win32 + {B3D152CB-CD52-4CD6-9213-710ADE1B8EB0}.Debug|x64.ActiveCfg = Debug|x64 + {B3D152CB-CD52-4CD6-9213-710ADE1B8EB0}.Debug|x64.Build.0 = Debug|x64 + {B3D152CB-CD52-4CD6-9213-710ADE1B8EB0}.Debug|x86.ActiveCfg = Debug|Win32 + {B3D152CB-CD52-4CD6-9213-710ADE1B8EB0}.Debug|x86.Build.0 = Debug|Win32 + {B3D152CB-CD52-4CD6-9213-710ADE1B8EB0}.Release|x64.ActiveCfg = Release|x64 + {B3D152CB-CD52-4CD6-9213-710ADE1B8EB0}.Release|x64.Build.0 = Release|x64 + {B3D152CB-CD52-4CD6-9213-710ADE1B8EB0}.Release|x86.ActiveCfg = Release|Win32 + {B3D152CB-CD52-4CD6-9213-710ADE1B8EB0}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/GpApp/Environ.cpp b/GpApp/Environ.cpp index 99e4273..a67efc8 100644 --- a/GpApp/Environ.cpp +++ b/GpApp/Environ.cpp @@ -208,18 +208,18 @@ Boolean DoWeHaveDragManager (void) short WhatsOurDepth (void) { - PortabilityLayer::PixelFormat pixelFormat; + GpPixelFormat_t pixelFormat; PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(nil, nil, &pixelFormat); switch (pixelFormat) { - case PortabilityLayer::PixelFormat_8BitCustom: - case PortabilityLayer::PixelFormat_8BitStandard: + case GpPixelFormats::k8BitCustom: + case GpPixelFormats::k8BitStandard: return 8; - case PortabilityLayer::PixelFormat_RGB555: + case GpPixelFormats::kRGB555: return 16; - case PortabilityLayer::PixelFormat_RGB24: - case PortabilityLayer::PixelFormat_RGB32: + case GpPixelFormats::kRGB24: + case GpPixelFormats::kRGB32: return 32; default: return 0; diff --git a/GpCommon/GpColorCursor_Win32.h b/GpCommon/GpColorCursor_Win32.h index 40d58a1..0c24d51 100644 --- a/GpCommon/GpColorCursor_Win32.h +++ b/GpCommon/GpColorCursor_Win32.h @@ -1,17 +1,18 @@ #pragma once -#include "IGpColorCursor.h" +#include "IGpColorCursor_Win32.h" #include "GpWindows.h" -class GpColorCursor_Win32 final : public IGpColorCursor + +class GpColorCursor_Win32 final : public IGpColorCursor_Win32 { public: void Destroy() override; - const HCURSOR &GetHCursor() const; + const HCURSOR &GetHCursor() const override; - void IncRef(); - void DecRef(); + void IncRef() override; + void DecRef() override; static GpColorCursor_Win32 *Load(const wchar_t *path); diff --git a/GpD3D/GpComPtr.h b/GpCommon/GpComPtr.h similarity index 100% rename from GpD3D/GpComPtr.h rename to GpCommon/GpComPtr.h diff --git a/GpCommon/GpDisplayDriverProperties.h b/GpCommon/GpDisplayDriverProperties.h index 588265b..474c2d0 100644 --- a/GpCommon/GpDisplayDriverProperties.h +++ b/GpCommon/GpDisplayDriverProperties.h @@ -3,11 +3,11 @@ #include "EGpDisplayDriverType.h" struct IGpDisplayDriver; -class GpFiber; +struct IGpFiber; struct GpDisplayDriverProperties { - typedef void(*TickFunc_t)(void *context, GpFiber *vosFiber); + typedef void(*TickFunc_t)(void *context, IGpFiber *vosFiber); typedef void(*RenderFunc_t)(void *context); EGpDisplayDriverType m_type; diff --git a/GpCommon/GpPixelFormat.h b/GpCommon/GpPixelFormat.h new file mode 100644 index 0000000..8d6f362 --- /dev/null +++ b/GpCommon/GpPixelFormat.h @@ -0,0 +1,17 @@ +#pragma once + +namespace GpPixelFormats +{ + enum GpPixelFormat + { + kInvalid, + + k8BitStandard, + k8BitCustom, + kRGB555, + kRGB24, + kRGB32, + }; +} + +typedef GpPixelFormats::GpPixelFormat GpPixelFormat_t; diff --git a/GpD3D/GpRingBuffer.h b/GpCommon/GpRingBuffer.h similarity index 100% rename from GpD3D/GpRingBuffer.h rename to GpCommon/GpRingBuffer.h diff --git a/GpCommon/GpWindows.h b/GpCommon/GpWindows.h index 12dbe23..8e559f0 100644 --- a/GpCommon/GpWindows.h +++ b/GpCommon/GpWindows.h @@ -6,6 +6,11 @@ #include +#undef CreateMutex + +struct IGpFiber; +struct IGpColorCursor_Win32; + struct GpWindowsGlobals { HINSTANCE m_hInstance; @@ -13,8 +18,8 @@ struct GpWindowsGlobals LPCSTR m_cmdLine; LPCWSTR m_baseDir; int m_nCmdShow; + + IGpFiber *(*m_createFiberFunc)(LPVOID fiber); + IGpColorCursor_Win32 *(*m_loadColorCursorFunc)(const wchar_t *path); }; -extern GpWindowsGlobals g_gpWindowsGlobals; - -#undef CreateMutex diff --git a/GpCommon/IGpColorCursor_Win32.h b/GpCommon/IGpColorCursor_Win32.h new file mode 100644 index 0000000..480be90 --- /dev/null +++ b/GpCommon/IGpColorCursor_Win32.h @@ -0,0 +1,13 @@ +#pragma once + +#include "IGpColorCursor.h" +#include "GpWindows.h" + +struct IGpColorCursor_Win32 : public IGpColorCursor +{ +public: + virtual const HCURSOR &GetHCursor() const = 0; + + virtual void IncRef() = 0; + virtual void DecRef() = 0; +}; diff --git a/GpCommon/IGpDisplayDriver.h b/GpCommon/IGpDisplayDriver.h index 55152bf..46cc590 100644 --- a/GpCommon/IGpDisplayDriver.h +++ b/GpCommon/IGpDisplayDriver.h @@ -1,6 +1,6 @@ #pragma once -#include "PixelFormat.h" +#include "GpPixelFormat.h" #include "EGpStandardCursor.h" struct IGpDisplayDriverSurface; @@ -13,9 +13,9 @@ public: virtual void Run() = 0; virtual void Shutdown() = 0; - virtual void GetDisplayResolution(unsigned int *width, unsigned int *height, PortabilityLayer::PixelFormat *bpp) = 0; + virtual void GetDisplayResolution(unsigned int *width, unsigned int *height, GpPixelFormat_t *bpp) = 0; - virtual IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, PortabilityLayer::PixelFormat pixelFormat) = 0; + virtual IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, GpPixelFormat_t pixelFormat) = 0; virtual void DrawSurface(IGpDisplayDriverSurface *surface, size_t x, size_t y, size_t width, size_t height) = 0; virtual IGpColorCursor *LoadColorCursor(int cursorID) = 0; diff --git a/GpD3D/GpFiber.h b/GpCommon/IGpFiber.h similarity index 75% rename from GpD3D/GpFiber.h rename to GpCommon/IGpFiber.h index 01fbd2c..6b3a224 100644 --- a/GpD3D/GpFiber.h +++ b/GpCommon/IGpFiber.h @@ -2,9 +2,8 @@ #include "CoreDefs.h" -class GpFiber +struct IGpFiber { -public: virtual void YieldTo() = 0; virtual void Destroy() = 0; }; diff --git a/GpD3D/ConvertedResources/Large128.ico b/GpD3D/ConvertedResources/Large128.ico new file mode 100644 index 0000000..b60d12a Binary files /dev/null and b/GpD3D/ConvertedResources/Large128.ico differ diff --git a/GpD3D/ConvertedResources/Large129.ico b/GpD3D/ConvertedResources/Large129.ico new file mode 100644 index 0000000..b58419a Binary files /dev/null and b/GpD3D/ConvertedResources/Large129.ico differ diff --git a/GpD3D/ConvertedResources/Large130.ico b/GpD3D/ConvertedResources/Large130.ico new file mode 100644 index 0000000..2ac5de3 Binary files /dev/null and b/GpD3D/ConvertedResources/Large130.ico differ diff --git a/GpD3D/ConvertedResources/Large131.ico b/GpD3D/ConvertedResources/Large131.ico new file mode 100644 index 0000000..7d02b94 Binary files /dev/null and b/GpD3D/ConvertedResources/Large131.ico differ diff --git a/GpD3D/ConvertedResources/Large132.ico b/GpD3D/ConvertedResources/Large132.ico new file mode 100644 index 0000000..4a61a27 Binary files /dev/null and b/GpD3D/ConvertedResources/Large132.ico differ diff --git a/GpD3D/ConvertedResources/Large133.ico b/GpD3D/ConvertedResources/Large133.ico new file mode 100644 index 0000000..a79202a Binary files /dev/null and b/GpD3D/ConvertedResources/Large133.ico differ diff --git a/GpD3D/ConvertedResources/Small128.ico b/GpD3D/ConvertedResources/Small128.ico new file mode 100644 index 0000000..d06457d Binary files /dev/null and b/GpD3D/ConvertedResources/Small128.ico differ diff --git a/GpD3D/ConvertedResources/Small129.ico b/GpD3D/ConvertedResources/Small129.ico new file mode 100644 index 0000000..ace9115 Binary files /dev/null and b/GpD3D/ConvertedResources/Small129.ico differ diff --git a/GpD3D/ConvertedResources/Small130.ico b/GpD3D/ConvertedResources/Small130.ico new file mode 100644 index 0000000..3f15a8a Binary files /dev/null and b/GpD3D/ConvertedResources/Small130.ico differ diff --git a/GpD3D/ConvertedResources/Small133.ico b/GpD3D/ConvertedResources/Small133.ico new file mode 100644 index 0000000..1229934 Binary files /dev/null and b/GpD3D/ConvertedResources/Small133.ico differ diff --git a/GpD3D/GpAppEnvironment.cpp b/GpD3D/GpAppEnvironment.cpp index d288d20..89a8c11 100644 --- a/GpD3D/GpAppEnvironment.cpp +++ b/GpD3D/GpAppEnvironment.cpp @@ -4,8 +4,8 @@ #include "GpFontHandlerFactory.h" #include "GpPLGlueAudioDriver.h" #include "GpPLGlueDisplayDriver.h" -#include "GpFiber.h" #include "HostSuspendCallArgument.h" +#include "IGpFiber.h" #include @@ -31,7 +31,7 @@ void GpAppEnvironment::Init() { } -void GpAppEnvironment::Tick(GpFiber *vosFiber) +void GpAppEnvironment::Tick(IGpFiber *vosFiber) { GpAppInterface_Get()->PL_IncrementTickCounter(1); diff --git a/GpD3D/GpAppEnvironment.h b/GpD3D/GpAppEnvironment.h index 110fe13..f358836 100644 --- a/GpD3D/GpAppEnvironment.h +++ b/GpD3D/GpAppEnvironment.h @@ -14,7 +14,7 @@ namespace PortabilityLayer struct IGpDisplayDriver; struct IGpAudioDriver; -class GpFiber; +struct IGpFiber; class GpAppEnvironment { @@ -24,7 +24,7 @@ public: void Init(); - void Tick(GpFiber *vosFiber); + void Tick(IGpFiber *vosFiber); void Render(); void SetDisplayDriver(IGpDisplayDriver *displayDriver); @@ -55,8 +55,8 @@ private: IGpAudioDriver *m_audioDriver; PortabilityLayer::HostFontHandler *m_fontHandler; GpVOSEventQueue m_vosEventQueue; - GpFiber *m_applicationFiber; - GpFiber *m_vosFiber; + IGpFiber *m_applicationFiber; + IGpFiber *m_vosFiber; uint32_t m_delaySuspendTicks; diff --git a/GpD3D/GpAudioDriverXAudio2.h b/GpD3D/GpAudioDriverXAudio2.h deleted file mode 100644 index e69de29..0000000 diff --git a/GpCommon/GpColorCursor_Win32.cpp b/GpD3D/GpColorCursor_Win32.cpp similarity index 92% rename from GpCommon/GpColorCursor_Win32.cpp rename to GpD3D/GpColorCursor_Win32.cpp index 935a89c..cd23440 100644 --- a/GpCommon/GpColorCursor_Win32.cpp +++ b/GpD3D/GpColorCursor_Win32.cpp @@ -8,7 +8,7 @@ void GpColorCursor_Win32::Destroy() this->DecRef(); } -GpColorCursor_Win32 *GpColorCursor_Win32::Load(const wchar_t *path) +IGpColorCursor_Win32 *GpColorCursor_Win32::Load(const wchar_t *path) { HANDLE imageH = LoadImageW(nullptr, path, IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE); diff --git a/GpD3D/GpColorCursor_Win32.h b/GpD3D/GpColorCursor_Win32.h new file mode 100644 index 0000000..378e2b1 --- /dev/null +++ b/GpD3D/GpColorCursor_Win32.h @@ -0,0 +1,33 @@ +#pragma once + +#include "IGpColorCursor.h" +#include "GpWindows.h" + +struct IGpColorCursor_Win32 : public IGpColorCursor +{ + virtual const HCURSOR &GetHCursor() const = 0; + + virtual void IncRef() = 0; + virtual void DecRef() = 0; +}; + + +class GpColorCursor_Win32 final : public IGpColorCursor_Win32 +{ +public: + void Destroy() override; + + const HCURSOR &GetHCursor() const override; + + void IncRef() override; + void DecRef() override; + + static IGpColorCursor_Win32 *Load(const wchar_t *path); + +private: + GpColorCursor_Win32(HCURSOR cursor); + ~GpColorCursor_Win32(); + + HCURSOR m_cursor; + int m_refCount; +}; diff --git a/GpD3D/GpD3D.aps b/GpD3D/GpD3D.aps new file mode 100644 index 0000000..4407510 Binary files /dev/null and b/GpD3D/GpD3D.aps differ diff --git a/GpD3D/GpD3D.rc b/GpD3D/GpD3D.rc new file mode 100644 index 0000000..1abaef5 Binary files /dev/null and b/GpD3D/GpD3D.rc differ diff --git a/GpD3D/GpD3D.vcxproj b/GpD3D/GpD3D.vcxproj index 1908701..b154c77 100644 --- a/GpD3D/GpD3D.vcxproj +++ b/GpD3D/GpD3D.vcxproj @@ -143,12 +143,10 @@ - + - - @@ -157,7 +155,6 @@ - @@ -167,10 +164,6 @@ - - - - @@ -183,14 +176,10 @@ - - - - @@ -213,6 +202,7 @@ + @@ -224,6 +214,16 @@ {e3bdc783-8646-433e-adf0-8b6390d36669} + + {ffc961ac-55b4-4a38-a83e-06ae98f59acc} + + + + + + + + diff --git a/GpD3D/GpD3D.vcxproj.filters b/GpD3D/GpD3D.vcxproj.filters index bd557b8..f647b7a 100644 --- a/GpD3D/GpD3D.vcxproj.filters +++ b/GpD3D/GpD3D.vcxproj.filters @@ -13,9 +13,6 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - {6dd6af81-4f84-4e4f-aa25-9dd4c1b53536} - @@ -24,18 +21,12 @@ Source Files - - Source Files - Source Files Source Files - - Source Files - Source Files @@ -84,22 +75,7 @@ Source Files - - Source Files - - - Source Files\CompiledShaders - - - Source Files\CompiledShaders - - - Source Files\CompiledShaders - - - Source Files\CompiledShaders - - + Source Files @@ -122,9 +98,6 @@ Header Files - - Header Files - Header Files @@ -134,9 +107,6 @@ Header Files - - Header Files - Header Files @@ -179,9 +149,6 @@ Header Files - - Header Files - Header Files @@ -209,9 +176,6 @@ Header Files - - Header Files - Header Files @@ -224,5 +188,21 @@ Header Files + + Header Files + + + + + Resource Files + + + + + Resource Files + + + Resource Files + \ No newline at end of file diff --git a/GpD3D/GpFiberStarter.h b/GpD3D/GpFiberStarter.h index 24d98a8..7c12c9b 100644 --- a/GpD3D/GpFiberStarter.h +++ b/GpD3D/GpFiberStarter.h @@ -1,11 +1,11 @@ #pragma once -class GpFiber; +struct IGpFiber; class GpFiberStarter { public: typedef void(*ThreadFunc_t)(void *context); - static GpFiber *StartFiber(ThreadFunc_t threadFunc, void *context, GpFiber *creatingFiber); + static IGpFiber *StartFiber(ThreadFunc_t threadFunc, void *context, IGpFiber *creatingFiber); }; diff --git a/GpD3D/GpFiberStarter_Win32.cpp b/GpD3D/GpFiberStarter_Win32.cpp index d3d2c78..af05a87 100644 --- a/GpD3D/GpFiberStarter_Win32.cpp +++ b/GpD3D/GpFiberStarter_Win32.cpp @@ -9,7 +9,7 @@ namespace GpFiberStarter_Win32 struct FiberStartState { GpFiberStarter::ThreadFunc_t m_threadFunc; - GpFiber *m_creatingFiber; + IGpFiber *m_creatingFiber; void *m_context; }; @@ -18,7 +18,7 @@ namespace GpFiberStarter_Win32 const FiberStartState *tss = static_cast(lpThreadParameter); GpFiberStarter::ThreadFunc_t threadFunc = tss->m_threadFunc; - GpFiber *creatingFiber = tss->m_creatingFiber; + IGpFiber *creatingFiber = tss->m_creatingFiber; void *context = tss->m_context; creatingFiber->YieldTo(); @@ -28,7 +28,7 @@ namespace GpFiberStarter_Win32 } } -GpFiber *GpFiberStarter::StartFiber(ThreadFunc_t threadFunc, void *context, GpFiber *creatingFiber) +IGpFiber *GpFiberStarter::StartFiber(ThreadFunc_t threadFunc, void *context, IGpFiber *creatingFiber) { ULONG_PTR lowLimit; ULONG_PTR highLimit; @@ -48,5 +48,5 @@ GpFiber *GpFiberStarter::StartFiber(ThreadFunc_t threadFunc, void *context, GpFi SwitchToFiber(fiber); - return new GpFiber_Win32(fiber); + return GpFiber_Win32::Create(fiber); } diff --git a/GpD3D/GpFiber_Win32.cpp b/GpD3D/GpFiber_Win32.cpp index ade6202..8c5e6c8 100644 --- a/GpD3D/GpFiber_Win32.cpp +++ b/GpD3D/GpFiber_Win32.cpp @@ -1,4 +1,5 @@ -#include "GpFiber_Win32.h" +#include "GpFiber_Win32.h" +#include GpFiber_Win32::GpFiber_Win32(LPVOID fiber) : m_fiber(fiber) @@ -11,7 +12,21 @@ void GpFiber_Win32::YieldTo() } void GpFiber_Win32::Destroy() +{ + this->~GpFiber_Win32(); + free(this); +} + +GpFiber_Win32::~GpFiber_Win32() { DeleteFiber(m_fiber); - delete this; -} +} + +IGpFiber *GpFiber_Win32::Create(LPVOID fiber) +{ + void *storage = malloc(sizeof(GpFiber_Win32)); + if (!storage) + return nullptr; + + return new (storage) GpFiber_Win32(fiber); +} diff --git a/GpD3D/GpFiber_Win32.h b/GpD3D/GpFiber_Win32.h index 9d0ea9b..936f4ad 100644 --- a/GpD3D/GpFiber_Win32.h +++ b/GpD3D/GpFiber_Win32.h @@ -1,15 +1,18 @@ -#pragma once -#include "GpWindows.h" -#include "GpFiber.h" - -class GpFiber_Win32 final : public GpFiber -{ -public: - explicit GpFiber_Win32(LPVOID fiber); - - void YieldTo() override; - void Destroy() override; - -private: - LPVOID m_fiber; -}; +#pragma once +#include "GpWindows.h" +#include "IGpFiber.h" + +class GpFiber_Win32 final : public IGpFiber +{ +public: + void YieldTo() override; + void Destroy() override; + + static IGpFiber *Create(LPVOID fiber); + +private: + explicit GpFiber_Win32(LPVOID fiber); + ~GpFiber_Win32(); + + LPVOID m_fiber; +}; diff --git a/GpD3D/GpFileSystem_Win32.cpp b/GpD3D/GpFileSystem_Win32.cpp index ac7f064..2765a19 100644 --- a/GpD3D/GpFileSystem_Win32.cpp +++ b/GpD3D/GpFileSystem_Win32.cpp @@ -245,7 +245,13 @@ bool GpFileSystem_Win32::ResolvePath(PortabilityLayer::EVirtualDirectory virtual memcpy(outPath, baseDir, sizeof(wchar_t) * baseDirLen); for (size_t i = 0; i < pathLen; i++) - outPath[baseDirLen + i] = static_cast(path[i]); + { + char c = path[i]; + if (c == '/') + c = '\\'; + + outPath[baseDirLen + i] = static_cast(c); + } outPath[baseDirLen + pathLen] = static_cast(0); diff --git a/GpD3D/GpFontHandler_FreeType2.cpp b/GpD3D/GpFontHandler_FreeType2.cpp index 66ab908..f1c1324 100644 --- a/GpD3D/GpFontHandler_FreeType2.cpp +++ b/GpD3D/GpFontHandler_FreeType2.cpp @@ -1,30 +1,103 @@ #include "GpFontHandler_FreeType2.h" +#include "CoreDefs.h" #include "IOStream.h" #include "HostFont.h" +#include "HostFontRenderedGlyph.h" +#include "RenderedGlyphMetrics.h" #include #include FT_FREETYPE_H #include FT_MODULE_H +#include #include #include #include + +class GpFontRenderedGlyph_FreeType2 final : public PortabilityLayer::HostFontRenderedGlyph +{ +public: + const PortabilityLayer::RenderedGlyphMetrics &GetMetrics() const override; + const void *GetData() const override; + void Destroy() override; + + static GpFontRenderedGlyph_FreeType2 *Create(size_t dataSize, const PortabilityLayer::RenderedGlyphMetrics &metrics); + + void *GetMutableData(); + +private: + GpFontRenderedGlyph_FreeType2(void *data, const PortabilityLayer::RenderedGlyphMetrics &metrics); + ~GpFontRenderedGlyph_FreeType2(); + + void *m_data; + PortabilityLayer::RenderedGlyphMetrics m_metrics; +}; + class GpFont_FreeType2 final : public PortabilityLayer::HostFont { public: void Destroy() override; + GpFontRenderedGlyph_FreeType2 *Render(uint32_t unicodeCodePoint, unsigned int size) override; - static GpFont_FreeType2 *Create(FT_Face face); + static GpFont_FreeType2 *Create(const FT_StreamRec_ &streamRec, PortabilityLayer::IOStream *stream); + + bool FTLoad(const FT_Library &library); private: - explicit GpFont_FreeType2(FT_Face face); + explicit GpFont_FreeType2(const FT_StreamRec_ &streamRec, PortabilityLayer::IOStream *stream); ~GpFont_FreeType2(); + FT_StreamRec_ m_ftStream; FT_Face m_face; + PortabilityLayer::IOStream *m_stream; + unsigned int m_currentSize; }; +const PortabilityLayer::RenderedGlyphMetrics &GpFontRenderedGlyph_FreeType2::GetMetrics() const +{ + return m_metrics; +} + +const void *GpFontRenderedGlyph_FreeType2::GetData() const +{ + return m_data; +} + +void GpFontRenderedGlyph_FreeType2::Destroy() +{ + this->~GpFontRenderedGlyph_FreeType2(); + free(this); +} + +GpFontRenderedGlyph_FreeType2 *GpFontRenderedGlyph_FreeType2::Create(size_t dataSize, const PortabilityLayer::RenderedGlyphMetrics &metrics) +{ + size_t alignedPrefixSize = (sizeof(GpFontRenderedGlyph_FreeType2) + PL_SYSTEM_MEMORY_ALIGNMENT - 1); + alignedPrefixSize -= alignedPrefixSize % PL_SYSTEM_MEMORY_ALIGNMENT; + + void *storage = malloc(alignedPrefixSize + dataSize); + if (!storage) + return nullptr; + + return new (storage) GpFontRenderedGlyph_FreeType2(static_cast(storage) + alignedPrefixSize, metrics); +} + +void *GpFontRenderedGlyph_FreeType2::GetMutableData() +{ + return m_data; +} + + +GpFontRenderedGlyph_FreeType2::GpFontRenderedGlyph_FreeType2(void *data, const PortabilityLayer::RenderedGlyphMetrics &metrics) + : m_metrics(metrics) + , m_data(data) +{ +} + +GpFontRenderedGlyph_FreeType2::~GpFontRenderedGlyph_FreeType2() +{ +} void GpFont_FreeType2::Destroy() { @@ -32,23 +105,120 @@ void GpFont_FreeType2::Destroy() free(this); } -GpFont_FreeType2 *GpFont_FreeType2::Create(FT_Face face) +GpFontRenderedGlyph_FreeType2 *GpFont_FreeType2::Render(uint32_t unicodeCodePoint, unsigned int size) +{ + if (m_currentSize != size) + { + if (FT_Set_Pixel_Sizes(m_face, 0, size) != 0) + return nullptr; + + m_currentSize = size; + } + + FT_UInt glyphIndex = FT_Get_Char_Index(m_face, unicodeCodePoint); + if (!glyphIndex) + return nullptr; + + if (FT_Load_Glyph(m_face, glyphIndex, FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO) != 0) + return nullptr; + + if (FT_Render_Glyph(m_face->glyph, FT_RENDER_MODE_MONO) != 0) + return nullptr; + + const FT_GlyphSlot glyph = m_face->glyph; + + if (glyph->bitmap.pixel_mode != FT_PIXEL_MODE_MONO) + return nullptr; // ???? + + PortabilityLayer::RenderedGlyphMetrics metrics; + memset(&metrics, 0, sizeof(metrics)); + + metrics.m_bearingX = glyph->metrics.horiBearingX / 64; + metrics.m_bearingY = glyph->metrics.horiBearingY / 64; + metrics.m_glyphWidth = glyph->bitmap.width; + metrics.m_glyphHeight = glyph->bitmap.rows; + metrics.m_advanceX = glyph->metrics.horiAdvance / 64; + + const size_t numRowsRequired = glyph->bitmap.rows; + size_t pitchRequired = (glyph->bitmap.width + 7) / 8; + pitchRequired = pitchRequired + (PL_SYSTEM_MEMORY_ALIGNMENT - 1); + pitchRequired -= pitchRequired % PL_SYSTEM_MEMORY_ALIGNMENT; + + const size_t glyphDataSize = numRowsRequired * pitchRequired; + + metrics.m_glyphDataPitch = pitchRequired; + + GpFontRenderedGlyph_FreeType2 *renderedGlyph = GpFontRenderedGlyph_FreeType2::Create(glyphDataSize, metrics); + if (!renderedGlyph) + return nullptr; + + uint8_t *fillData = static_cast(renderedGlyph->GetMutableData()); + + unsigned int bmWidth = glyph->bitmap.width; + unsigned int bmHeight = glyph->bitmap.rows; + unsigned int bmPitch = glyph->bitmap.pitch; + unsigned int copyableBytesPerRow = (bmWidth + 7) / 8; + const uint8_t *bmBytes = glyph->bitmap.buffer; + + size_t fillOffset = 0; + for (unsigned int row = 0; row < bmHeight; row++) + { + const uint8_t *bmReadStart = bmBytes + bmPitch * row; + uint8_t *bmWriteStart = fillData + pitchRequired * row; + + for (unsigned int i = 0; i < copyableBytesPerRow; i++) + { + const uint8_t b = bmReadStart[i]; + + uint8_t fillByte = 0; + for (int bit = 0; bit < 8; bit++) + fillByte |= ((b >> (7 - bit)) & 1) << bit; + + bmWriteStart[i] = fillByte; + } + } + + return renderedGlyph; +} + +GpFont_FreeType2 *GpFont_FreeType2::Create(const FT_StreamRec_ &streamRec, PortabilityLayer::IOStream *stream) { void *storage = malloc(sizeof(GpFont_FreeType2)); if (!storage) return nullptr; - return new (storage) GpFont_FreeType2(face); + return new (storage) GpFont_FreeType2(streamRec, stream); } -GpFont_FreeType2::GpFont_FreeType2(FT_Face face) - : m_face(face) +bool GpFont_FreeType2::FTLoad(const FT_Library &library) { + FT_Open_Args openArgs; + memset(&openArgs, 0, sizeof(openArgs)); + openArgs.flags = FT_OPEN_STREAM; + openArgs.stream = &m_ftStream; + + FT_Error errorCode = FT_Open_Face(library, &openArgs, 0, &m_face); + if (errorCode != 0) + return false; + + return true; +} + +GpFont_FreeType2::GpFont_FreeType2(const FT_StreamRec_ &streamRec, PortabilityLayer::IOStream *stream) + : m_face(nullptr) + , m_ftStream(streamRec) + , m_stream(stream) + , m_currentSize(0) +{ + assert(stream); } GpFont_FreeType2::~GpFont_FreeType2() { - FT_Done_Face(m_face); + if (m_face) + FT_Done_Face(m_face); + + m_stream->Close(); } GpFontHandler_FreeType2 *GpFontHandler_FreeType2::Create() @@ -69,7 +239,6 @@ GpFontHandler_FreeType2 *GpFontHandler_FreeType2::Create() PortabilityLayer::HostFont *GpFontHandler_FreeType2::LoadFont(PortabilityLayer::IOStream *stream) { - FT_StreamRec_ ftStream; memset(&ftStream, 0, sizeof(ftStream)); ftStream.size = 0x7fffffff; @@ -78,26 +247,27 @@ PortabilityLayer::HostFont *GpFontHandler_FreeType2::LoadFont(PortabilityLayer:: ftStream.read = FTStreamIo; ftStream.close = FTStreamClose; - FT_Open_Args openArgs; - memset(&openArgs, 0, sizeof(openArgs)); - openArgs.flags = FT_OPEN_STREAM; - openArgs.stream = &ftStream; - - FT_Face face; - FT_Error errorCode = FT_Open_Face(m_library, &openArgs, 0, &face); - if (errorCode != 0) - return nullptr; - - GpFont_FreeType2 *font = GpFont_FreeType2::Create(face); + GpFont_FreeType2 *font = GpFont_FreeType2::Create(ftStream, stream); if (!font) { - FT_Done_Face(face); + stream->Close(); + return nullptr; + } + + if (!font->FTLoad(m_library)) + { + font->Destroy(); return nullptr; } return font; } +bool GpFontHandler_FreeType2::KeepStreamOpen() const +{ + return true; +} + void GpFontHandler_FreeType2::Shutdown() { this->~GpFontHandler_FreeType2(); @@ -120,17 +290,17 @@ GpFontHandler_FreeType2::~GpFontHandler_FreeType2() void *GpFontHandler_FreeType2::FTAllocThunk(FT_Memory memory, long size) { - return static_cast(memory->user)->FTAlloc(size); + return static_cast(memory->user)->FTAlloc(size); } - + void GpFontHandler_FreeType2::FTFreeThunk(FT_Memory memory, void* block) -{ - static_cast(memory->user)->FTFree(block); +{ + static_cast(memory->user)->FTFree(block); } - + void *GpFontHandler_FreeType2::FTReallocThunk(FT_Memory memory, long curSize, long newSize, void *block) { - return static_cast(memory->user)->FTRealloc(curSize, newSize, block); + return static_cast(memory->user)->FTRealloc(curSize, newSize, block); } @@ -147,9 +317,9 @@ unsigned long GpFontHandler_FreeType2::FTStreamIo(FT_Stream stream, unsigned lon } const size_t bytesRead = ioStream->Read(buffer, count); - return static_cast(bytesRead); + return static_cast(bytesRead); } - + void GpFontHandler_FreeType2::FTStreamClose(FT_Stream stream) { (void)stream; @@ -157,14 +327,14 @@ void GpFontHandler_FreeType2::FTStreamClose(FT_Stream stream) void *GpFontHandler_FreeType2::FTAlloc(long size) { - return malloc(static_cast(size)); + return malloc(static_cast(size)); } - -void GpFontHandler_FreeType2::FTFree(void* block) + +void GpFontHandler_FreeType2::FTFree(void* block) { - free(block); + free(block); } - + void *GpFontHandler_FreeType2::FTRealloc(long curSize, long newSize, void *block) { (void)curSize; diff --git a/GpD3D/GpFontHandler_FreeType2.h b/GpD3D/GpFontHandler_FreeType2.h index 47db028..0b90e7f 100644 --- a/GpD3D/GpFontHandler_FreeType2.h +++ b/GpD3D/GpFontHandler_FreeType2.h @@ -18,6 +18,8 @@ public: PortabilityLayer::HostFont *LoadFont(PortabilityLayer::IOStream *stream) override; void Shutdown() override; + bool KeepStreamOpen() const override; + static GpFontHandler_FreeType2 *Create(); private: diff --git a/GpD3D/GpMain.cpp b/GpD3D/GpMain.cpp index 737270a..d2f902f 100644 --- a/GpD3D/GpMain.cpp +++ b/GpD3D/GpMain.cpp @@ -13,7 +13,7 @@ namespace { - void TickAppEnvironment(void *context, GpFiber *vosFiber) + void TickAppEnvironment(void *context, IGpFiber *vosFiber) { static_cast(context)->Tick(vosFiber); } diff --git a/GpD3D/GpMain_Win32.cpp b/GpD3D/GpMain_Win32.cpp index 257c608..0000839 100644 --- a/GpD3D/GpMain_Win32.cpp +++ b/GpD3D/GpMain_Win32.cpp @@ -1,8 +1,9 @@ #include "GpMain.h" #include "GpAudioDriverFactory.h" +#include "GpColorCursor_Win32.h" #include "GpDisplayDriverFactory.h" -#include "GpDisplayDriverFactoryD3D11.h" #include "GpGlobalConfig.h" +#include "GpFiber_Win32.h" #include "GpFileSystem_Win32.h" #include "GpAppInterface.h" #include "GpSystemServices_Win32.h" @@ -16,6 +17,7 @@ GpWindowsGlobals g_gpWindowsGlobals; extern "C" __declspec(dllimport) IGpAudioDriver *GpDriver_CreateAudioDriver_XAudio2(const GpAudioDriverProperties &properties); +extern "C" __declspec(dllimport) IGpDisplayDriver *GpDriver_CreateDisplayDriver_D3D11(const GpDisplayDriverProperties &properties); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { @@ -28,10 +30,13 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine g_gpWindowsGlobals.m_nCmdShow = nCmdShow; g_gpWindowsGlobals.m_baseDir = GpFileSystem_Win32::GetInstance()->GetBasePath(); + g_gpWindowsGlobals.m_createFiberFunc = GpFiber_Win32::Create; + g_gpWindowsGlobals.m_loadColorCursorFunc = GpColorCursor_Win32::Load; + g_gpGlobalConfig.m_displayDriverType = EGpDisplayDriverType_D3D11; g_gpGlobalConfig.m_osGlobals = &g_gpWindowsGlobals; - GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType_D3D11, GpDisplayDriverFactoryD3D11::Create); + GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType_D3D11, GpDriver_CreateDisplayDriver_D3D11); GpAudioDriverFactory::RegisterAudioDriverFactory(EGpAudioDriverType_XAudio2, GpDriver_CreateAudioDriver_XAudio2); return GpMain::Run(); diff --git a/GpD3D/GpPLGlueDisplayDriver.cpp b/GpD3D/GpPLGlueDisplayDriver.cpp index df5d218..51ac94d 100644 --- a/GpD3D/GpPLGlueDisplayDriver.cpp +++ b/GpD3D/GpPLGlueDisplayDriver.cpp @@ -7,7 +7,7 @@ GpPLGlueDisplayDriver::GpPLGlueDisplayDriver() { } -void GpPLGlueDisplayDriver::GetDisplayResolution(unsigned int *width, unsigned int *height, PortabilityLayer::PixelFormat *bpp) +void GpPLGlueDisplayDriver::GetDisplayResolution(unsigned int *width, unsigned int *height, GpPixelFormat_t *bpp) { m_displayDriver->GetDisplayResolution(width, height, bpp); } diff --git a/GpD3D/GpPLGlueDisplayDriver.h b/GpD3D/GpPLGlueDisplayDriver.h index 5653f14..d958f8b 100644 --- a/GpD3D/GpPLGlueDisplayDriver.h +++ b/GpD3D/GpPLGlueDisplayDriver.h @@ -9,7 +9,7 @@ class GpPLGlueDisplayDriver final : public PortabilityLayer::HostDisplayDriver public: GpPLGlueDisplayDriver(); - void GetDisplayResolution(unsigned int *width, unsigned int *height, PortabilityLayer::PixelFormat *bpp) override; + void GetDisplayResolution(unsigned int *width, unsigned int *height, GpPixelFormat_t *bpp) override; IGpColorCursor *LoadColorCursor(int id) override; void SetColorCursor(IGpColorCursor *colorCursor) override; void SetStandardCursor(EGpStandardCursor_t standardCursor) override; diff --git a/GpD3D/resource.h b/GpD3D/resource.h new file mode 100644 index 0000000..4de3f86 --- /dev/null +++ b/GpD3D/resource.h @@ -0,0 +1,17 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by GpD3D.rc +// +#define IDI_ICON1 101 +#define IDI_ICON2 102 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/GpD3D/x64/Debug/GpD3D.res b/GpD3D/x64/Debug/GpD3D.res new file mode 100644 index 0000000..f1ee8fe Binary files /dev/null and b/GpD3D/x64/Debug/GpD3D.res differ diff --git a/GpD3D/ShadersD3D11/DrawQuad15BitP_D3D11.cpp b/GpDisplayDriver_D3D11/CompiledShaders/DrawQuad15BitP_D3D11.cpp similarity index 100% rename from GpD3D/ShadersD3D11/DrawQuad15BitP_D3D11.cpp rename to GpDisplayDriver_D3D11/CompiledShaders/DrawQuad15BitP_D3D11.cpp diff --git a/GpD3D/ShadersD3D11/DrawQuadPaletteP_D3D11.cpp b/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadPaletteP_D3D11.cpp similarity index 100% rename from GpD3D/ShadersD3D11/DrawQuadPaletteP_D3D11.cpp rename to GpDisplayDriver_D3D11/CompiledShaders/DrawQuadPaletteP_D3D11.cpp diff --git a/GpD3D/ShadersD3D11/DrawQuadRGBP_D3D11.cpp b/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadRGBP_D3D11.cpp similarity index 100% rename from GpD3D/ShadersD3D11/DrawQuadRGBP_D3D11.cpp rename to GpDisplayDriver_D3D11/CompiledShaders/DrawQuadRGBP_D3D11.cpp diff --git a/GpD3D/ShadersD3D11/DrawQuadV_D3D11.cpp b/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadV_D3D11.cpp similarity index 100% rename from GpD3D/ShadersD3D11/DrawQuadV_D3D11.cpp rename to GpDisplayDriver_D3D11/CompiledShaders/DrawQuadV_D3D11.cpp diff --git a/GpD3D/GpDisplayDriverD3D11.cpp b/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.cpp similarity index 94% rename from GpD3D/GpDisplayDriverD3D11.cpp rename to GpDisplayDriver_D3D11/GpDisplayDriverD3D11.cpp index 6a66e05..ba385ad 100644 --- a/GpD3D/GpDisplayDriverD3D11.cpp +++ b/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.cpp @@ -2,8 +2,8 @@ #include "GpDisplayDriverD3D11.h" #include "GpDisplayDriverSurfaceD3D11.h" #include "GpWindows.h" -#include "GpColorCursor_Win32.h" -#include "GpFiber_Win32.h" +#include "IGpColorCursor_Win32.h" +#include "IGpFiber.h" #include #include @@ -11,6 +11,7 @@ #include #include +#include #pragma comment (lib, "d3d11.lib") @@ -521,14 +522,14 @@ void GpDisplayDriverD3D11::Run() if (!fiber) return; // ??? - m_vosFiber = new GpFiber_Win32(fiber); + m_vosFiber = m_osGlobals->m_createFiberFunc(fiber); ZeroMemory(&wc, sizeof(wc)); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WinProc; - wc.hInstance = g_gpWindowsGlobals.m_hInstance; + wc.hInstance = m_osGlobals->m_hInstance; wc.hCursor = m_arrowCursor; wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.lpszClassName = "GPD3D11WindowClass"; @@ -542,9 +543,9 @@ void GpDisplayDriverD3D11::Run() RECT wr = { 0, 0, m_windowWidth, m_windowHeight }; AdjustWindowRect(&wr, windowStyle, menus != NULL); - m_hwnd = CreateWindowExW(NULL, L"GPD3D11WindowClass", L"GlidePort (Direct3D 11)", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, menus, g_gpWindowsGlobals.m_hInstance, NULL); + m_hwnd = CreateWindowExW(NULL, L"GPD3D11WindowClass", L"GlidePort (Direct3D 11)", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, menus, m_osGlobals->m_hInstance, NULL); - ShowWindow(m_hwnd, g_gpWindowsGlobals.m_nCmdShow); + ShowWindow(m_hwnd, m_osGlobals->m_nCmdShow); StartD3DForWindow(m_hwnd, m_swapChain, m_device, m_deviceContext); @@ -581,20 +582,21 @@ void GpDisplayDriverD3D11::Run() void GpDisplayDriverD3D11::Shutdown() { - delete this; + this->~GpDisplayDriverD3D11(); + free(this); } -void GpDisplayDriverD3D11::GetDisplayResolution(unsigned int *width, unsigned int *height, PortabilityLayer::PixelFormat *pixelFormat) +void GpDisplayDriverD3D11::GetDisplayResolution(unsigned int *width, unsigned int *height, GpPixelFormat_t *pixelFormat) { if (width) *width = m_windowWidth; if (height) *height = m_windowHeight; if (pixelFormat) - *pixelFormat = PortabilityLayer::PixelFormat_8BitStandard; + *pixelFormat = GpPixelFormats::k8BitStandard; } -IGpDisplayDriverSurface *GpDisplayDriverD3D11::CreateSurface(size_t width, size_t height, PortabilityLayer::PixelFormat pixelFormat) +IGpDisplayDriverSurface *GpDisplayDriverD3D11::CreateSurface(size_t width, size_t height, GpPixelFormat_t pixelFormat) { return GpDisplayDriverSurfaceD3D11::Create(m_device, m_deviceContext, width, height, pixelFormat); } @@ -645,8 +647,8 @@ void GpDisplayDriverD3D11::DrawSurface(IGpDisplayDriverSurface *surface, size_t }; m_deviceContext->PSSetSamplers(0, sizeof(samplerStates) / sizeof(samplerStates[0]), samplerStates); - PortabilityLayer::PixelFormat pixelFormat = d3d11Surface->GetPixelFormat(); - if (pixelFormat == PortabilityLayer::PixelFormat_8BitStandard || pixelFormat == PortabilityLayer::PixelFormat_8BitCustom) + GpPixelFormat_t pixelFormat = d3d11Surface->GetPixelFormat(); + if (pixelFormat == GpPixelFormats::k8BitStandard || pixelFormat == GpPixelFormats::k8BitCustom) { ID3D11ShaderResourceView *psResourceViews[] = { @@ -657,7 +659,7 @@ void GpDisplayDriverD3D11::DrawSurface(IGpDisplayDriverSurface *surface, size_t m_deviceContext->PSSetShader(m_drawQuadPalettePixelShader, nullptr, 0); m_deviceContext->PSSetShaderResources(0, sizeof(psResourceViews) / sizeof(psResourceViews[0]), psResourceViews); } - else if (pixelFormat == PortabilityLayer::PixelFormat_RGB555) + else if (pixelFormat == GpPixelFormats::kRGB555) { ID3D11ShaderResourceView *psResourceViews[] = { @@ -667,7 +669,7 @@ void GpDisplayDriverD3D11::DrawSurface(IGpDisplayDriverSurface *surface, size_t m_deviceContext->PSSetShader(m_drawQuad15BitPixelShader, nullptr, 0); m_deviceContext->PSSetShaderResources(0, sizeof(psResourceViews) / sizeof(psResourceViews[0]), psResourceViews); } - else if (pixelFormat == PortabilityLayer::PixelFormat_RGB32) + else if (pixelFormat == GpPixelFormats::kRGB32) { ID3D11ShaderResourceView *psResourceViews[] = { @@ -694,7 +696,7 @@ IGpColorCursor *GpDisplayDriverD3D11::LoadColorCursor(int cursorID) if (sz < 0 || static_cast(sz) >= bufSize) return nullptr; - return GpColorCursor_Win32::Load(path); + return m_osGlobals->m_loadColorCursorFunc(path); } // We can't just set the cursor because we want to post WM_SETCURSOR to keep it limited @@ -702,7 +704,7 @@ IGpColorCursor *GpDisplayDriverD3D11::LoadColorCursor(int cursorID) // the window thread. void GpDisplayDriverD3D11::SetColorCursor(IGpColorCursor *colorCursor) { - GpColorCursor_Win32 *winCursor = static_cast(colorCursor); + IGpColorCursor_Win32 *winCursor = static_cast(colorCursor); winCursor->IncRef(); @@ -745,7 +747,11 @@ void GpDisplayDriverD3D11::UpdatePalette(const void *paletteData) GpDisplayDriverD3D11 *GpDisplayDriverD3D11::Create(const GpDisplayDriverProperties &properties) { - return new GpDisplayDriverD3D11(properties); + void *storage = malloc(sizeof(GpDisplayDriverD3D11)); + if (!storage) + return nullptr; + + return new (storage) GpDisplayDriverD3D11(properties); } GpDisplayDriverD3D11::GpDisplayDriverD3D11(const GpDisplayDriverProperties &properties) @@ -774,3 +780,8 @@ GpDisplayDriverD3D11::~GpDisplayDriverD3D11() { // GP TODO: Sloppy cleanup... Close the window!! } + +extern "C" __declspec(dllexport) IGpDisplayDriver *GpDriver_CreateDisplayDriver_D3D11(const GpDisplayDriverProperties &properties) +{ + return GpDisplayDriverD3D11::Create(properties); +} diff --git a/GpD3D/GpDisplayDriverD3D11.h b/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.h similarity index 92% rename from GpD3D/GpDisplayDriverD3D11.h rename to GpDisplayDriver_D3D11/GpDisplayDriverD3D11.h index 1eaceb1..30e43e3 100644 --- a/GpD3D/GpDisplayDriverD3D11.h +++ b/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.h @@ -8,10 +8,11 @@ #include "GpDisplayDriverProperties.h" #include "GpComPtr.h" -#include "PixelFormat.h" +#include "GpPixelFormat.h" struct GpWindowsGlobals; -class GpColorCursor_Win32; +struct IGpColorCursor_Win32; +struct IGpFiber; struct IDXGISwapChain1; struct ID3D11Buffer; @@ -33,9 +34,9 @@ public: void Run() override; void Shutdown() override; - void GetDisplayResolution(unsigned int *width, unsigned int *height, PortabilityLayer::PixelFormat *bpp) override; + void GetDisplayResolution(unsigned int *width, unsigned int *height, GpPixelFormat_t *bpp) override; - IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, PortabilityLayer::PixelFormat pixelFormat) override; + IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, GpPixelFormat_t pixelFormat) override; void DrawSurface(IGpDisplayDriverSurface *surface, size_t x, size_t y, size_t width, size_t height) override; IGpColorCursor *LoadColorCursor(int cursorID) override; @@ -108,13 +109,13 @@ private: DWORD m_windowWidth; DWORD m_windowHeight; - GpColorCursor_Win32 *m_activeCursor; - GpColorCursor_Win32 *m_pendingCursor; + IGpColorCursor_Win32 *m_activeCursor; + IGpColorCursor_Win32 *m_pendingCursor; EGpStandardCursor_t m_currentStandardCursor; EGpStandardCursor_t m_pendingStandardCursor; bool m_mouseIsInClientArea; - GpFiber *m_vosFiber; + IGpFiber *m_vosFiber; GpWindowsGlobals *m_osGlobals; HCURSOR m_arrowCursor; diff --git a/GpD3D/GpDisplayDriverFactoryD3D11.cpp b/GpDisplayDriver_D3D11/GpDisplayDriverFactoryD3D11.cpp similarity index 100% rename from GpD3D/GpDisplayDriverFactoryD3D11.cpp rename to GpDisplayDriver_D3D11/GpDisplayDriverFactoryD3D11.cpp diff --git a/GpD3D/GpDisplayDriverFactoryD3D11.h b/GpDisplayDriver_D3D11/GpDisplayDriverFactoryD3D11.h similarity index 100% rename from GpD3D/GpDisplayDriverFactoryD3D11.h rename to GpDisplayDriver_D3D11/GpDisplayDriverFactoryD3D11.h diff --git a/GpD3D/GpDisplayDriverSurfaceD3D11.cpp b/GpDisplayDriver_D3D11/GpDisplayDriverSurfaceD3D11.cpp similarity index 88% rename from GpD3D/GpDisplayDriverSurfaceD3D11.cpp rename to GpDisplayDriver_D3D11/GpDisplayDriverSurfaceD3D11.cpp index c8ccadb..d123a6a 100644 --- a/GpD3D/GpDisplayDriverSurfaceD3D11.cpp +++ b/GpDisplayDriver_D3D11/GpDisplayDriverSurfaceD3D11.cpp @@ -64,7 +64,7 @@ ID3D11ShaderResourceView *GpDisplayDriverSurfaceD3D11::GetSRV() const return m_srv; } -PortabilityLayer::PixelFormat GpDisplayDriverSurfaceD3D11::GetPixelFormat() const +GpPixelFormat_t GpDisplayDriverSurfaceD3D11::GetPixelFormat() const { return m_pixelFormat; } @@ -79,23 +79,23 @@ size_t GpDisplayDriverSurfaceD3D11::GetHeight() const return m_height; } -GpDisplayDriverSurfaceD3D11 *GpDisplayDriverSurfaceD3D11::Create(ID3D11Device *device, ID3D11DeviceContext *deviceContext, size_t width, size_t height, PortabilityLayer::PixelFormat pixelFormat) +GpDisplayDriverSurfaceD3D11 *GpDisplayDriverSurfaceD3D11::Create(ID3D11Device *device, ID3D11DeviceContext *deviceContext, size_t width, size_t height, GpPixelFormat_t pixelFormat) { DXGI_FORMAT dxgiFormat = DXGI_FORMAT_R8_UNORM; switch (pixelFormat) { - case PortabilityLayer::PixelFormat_8BitCustom: - case PortabilityLayer::PixelFormat_8BitStandard: + case GpPixelFormats::k8BitCustom: + case GpPixelFormats::k8BitStandard: dxgiFormat = DXGI_FORMAT_R8_UINT; break; - case PortabilityLayer::PixelFormat_RGB555: + case GpPixelFormats::kRGB555: dxgiFormat = DXGI_FORMAT_R16_UINT; break; - case PortabilityLayer::PixelFormat_RGB32: + case GpPixelFormats::kRGB32: dxgiFormat = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; break; - case PortabilityLayer::PixelFormat_RGB24: // RGB24 is not supported as a surface format (PL must convert it) + case GpPixelFormats::kRGB24: // RGB24 is not supported as a surface format (PL must convert it) default: return nullptr; } @@ -117,7 +117,7 @@ GpDisplayDriverSurfaceD3D11 *GpDisplayDriverSurfaceD3D11::Create(ID3D11Device *d if (device->CreateTexture2D(&textureDesc, nullptr, texture.GetMutablePtr()) != S_OK) return nullptr; - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = dxgiFormat; srvDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MipLevels = 1; @@ -137,7 +137,7 @@ GpDisplayDriverSurfaceD3D11 *GpDisplayDriverSurfaceD3D11::Create(ID3D11Device *d return new (storage) GpDisplayDriverSurfaceD3D11(device, deviceContext, texture, srv, width, height, pixelFormat); } -GpDisplayDriverSurfaceD3D11::GpDisplayDriverSurfaceD3D11(ID3D11Device *device, ID3D11DeviceContext *deviceContext, ID3D11Texture2D *texture, ID3D11ShaderResourceView *srv, size_t width, size_t height, PortabilityLayer::PixelFormat pixelFormat) +GpDisplayDriverSurfaceD3D11::GpDisplayDriverSurfaceD3D11(ID3D11Device *device, ID3D11DeviceContext *deviceContext, ID3D11Texture2D *texture, ID3D11ShaderResourceView *srv, size_t width, size_t height, GpPixelFormat_t pixelFormat) : m_width(width) , m_height(height) , m_pixelFormat(pixelFormat) diff --git a/GpD3D/GpDisplayDriverSurfaceD3D11.h b/GpDisplayDriver_D3D11/GpDisplayDriverSurfaceD3D11.h similarity index 80% rename from GpD3D/GpDisplayDriverSurfaceD3D11.h rename to GpDisplayDriver_D3D11/GpDisplayDriverSurfaceD3D11.h index e084aa5..a7d7a9c 100644 --- a/GpD3D/GpDisplayDriverSurfaceD3D11.h +++ b/GpDisplayDriver_D3D11/GpDisplayDriverSurfaceD3D11.h @@ -2,7 +2,7 @@ #include "IGpDisplayDriverSurface.h" #include "GpComPtr.h" -#include "PixelFormat.h" +#include "GpPixelFormat.h" struct ID3D11Device; struct ID3D11DeviceContext; @@ -17,19 +17,19 @@ public: virtual void Destroy() override; ID3D11ShaderResourceView *GetSRV() const; - PortabilityLayer::PixelFormat GetPixelFormat() const; + GpPixelFormat_t GetPixelFormat() const; size_t GetWidth() const; size_t GetHeight() const; - static GpDisplayDriverSurfaceD3D11 *Create(ID3D11Device *device, ID3D11DeviceContext *deviceContext, size_t width, size_t height, PortabilityLayer::PixelFormat pixelFormat); + static GpDisplayDriverSurfaceD3D11 *Create(ID3D11Device *device, ID3D11DeviceContext *deviceContext, size_t width, size_t height, GpPixelFormat_t pixelFormat); private: - GpDisplayDriverSurfaceD3D11(ID3D11Device *device, ID3D11DeviceContext *deviceContext, ID3D11Texture2D *texture, ID3D11ShaderResourceView *srv, size_t width, size_t height, PortabilityLayer::PixelFormat pixelFormat); + GpDisplayDriverSurfaceD3D11(ID3D11Device *device, ID3D11DeviceContext *deviceContext, ID3D11Texture2D *texture, ID3D11ShaderResourceView *srv, size_t width, size_t height, GpPixelFormat_t pixelFormat); ~GpDisplayDriverSurfaceD3D11(); size_t m_width; size_t m_height; - PortabilityLayer::PixelFormat m_pixelFormat; + GpPixelFormat_t m_pixelFormat; ID3D11Device *m_device; ID3D11DeviceContext *m_deviceContext; diff --git a/GpDisplayDriver_D3D11/GpDisplayDriver_D3D11.vcxproj b/GpDisplayDriver_D3D11/GpDisplayDriver_D3D11.vcxproj new file mode 100644 index 0000000..80ef8c6 --- /dev/null +++ b/GpDisplayDriver_D3D11/GpDisplayDriver_D3D11.vcxproj @@ -0,0 +1,142 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {FFC961AC-55B4-4A38-A83E-06AE98F59ACC} + GpDisplayDriverD3D11 + 10.0.17763.0 + + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + DynamicLibrary + true + v141 + MultiByte + + + DynamicLibrary + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + true + + + + + Level3 + Disabled + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GpDisplayDriver_D3D11/GpDisplayDriver_D3D11.vcxproj.filters b/GpDisplayDriver_D3D11/GpDisplayDriver_D3D11.vcxproj.filters new file mode 100644 index 0000000..9f22b4f --- /dev/null +++ b/GpDisplayDriver_D3D11/GpDisplayDriver_D3D11.vcxproj.filters @@ -0,0 +1,54 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {05b8d8ff-66e2-4d10-83a1-29582f2ae9f1} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files\CompiledShaders + + + Source Files\CompiledShaders + + + Source Files\CompiledShaders + + + Source Files\CompiledShaders + + + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/ImportCharSet/ImportCharSet.cpp b/ImportCharSet/ImportCharSet.cpp new file mode 100644 index 0000000..d3bdabb --- /dev/null +++ b/ImportCharSet/ImportCharSet.cpp @@ -0,0 +1,217 @@ +#include +#include + +uint16_t g_toUnicode[256]; +uint8_t g_toUpper[256]; +uint8_t g_toLower[256]; +uint8_t g_stripDiacritic[256]; + +std::string g_charDescs[256]; + +template +void DumpListing(FILE *outF, const T *buf, const char *hexFormat, const char *title) +{ + fprintf(outF, "\t\tconst %s[256] =\n", title); + fprintf(outF, "\t\t{"); + + for (int i = 0; i < 256; i++) + { + if (i % 16 == 0) + fprintf(outF, "\n\t\t\t"); + + fprintf(outF, hexFormat, static_cast(buf[i])); + fputc(',', outF); + if (i % 16 != 15) + fputc(' ', outF); + } + + fprintf(outF, "\n\t\t};\n"); +} + +uint32_t ParseHexCode(const std::string &str) +{ + if (str.substr(0, 2) != "0x") + return 0; + + uint32_t result = 0; + for (size_t i = 2; i < str.length(); i++) + { + const char c = str[i]; + + result = result * 16; + + if (c >= 'a' && c <= 'f') + result += (c - 'a') + 0xA; + else if (c >= 'A' && c <= 'F') + result += (c - 'A') + 0xA; + else if (c >= '0' && c <= '9') + result += (c - '0'); + else + result = result / 16; + } + + return result; +} + +bool ParseLatinDesc(const std::string &str, bool &isSmall, bool &isCapital, std::string &remainder) +{ + if (str.substr(0, 6) != "LATIN ") + return false; + + isCapital = false; + isSmall = false; + + if (str.substr(6, 6) == "SMALL ") + { + isSmall = true; + remainder = str.substr(12); + } + else if (str.substr(6, 8) == "CAPITAL ") + { + isCapital = true; + remainder = str.substr(14); + } + else + remainder = str.substr(6); + + return true; +} + +void ProcessLine(const std::string &lineStr) +{ + std::string comment; + std::string contents; + + size_t commentPos = lineStr.find('#'); + if (commentPos == std::string::npos) + contents = lineStr; + else + { + comment = lineStr.substr(commentPos); + contents = lineStr.substr(0, commentPos); + } + + size_t tabLoc = contents.find('\t'); + if (tabLoc == std::string::npos) + return; + + std::string pageCode = contents.substr(0, tabLoc); + + size_t secondTabLoc = contents.find('\t', tabLoc + 1); + if (secondTabLoc == std::string::npos) + return; + + std::string unicodeCode = contents.substr(tabLoc + 1, secondTabLoc - tabLoc); + + uint32_t decodedUnicodeCode = ParseHexCode(unicodeCode); + uint32_t decodedCharCode = ParseHexCode(pageCode); + + size_t contentOffset = 1; + while (contentOffset < comment.length()) + { + const char c = comment[contentOffset]; + if (c <= ' ') + contentOffset++; + else + break; + } + + g_toUnicode[decodedCharCode] = decodedUnicodeCode; + g_charDescs[decodedCharCode] = comment.substr(contentOffset); +} + +int main(int argc, const char **argv) +{ + for (int i = 0; i < 256; i++) + { + g_toUnicode[i] = 0xffff; + g_toUpper[i] = i; + g_toLower[i] = i; + g_stripDiacritic[i] = i; + } + + FILE *f = nullptr; + + if (errno_t err = fopen_s(&f, "MiscData/MacRoman.txt", "rb")) + return err; + + std::string currentLine; + + while (!feof(f)) + { + char c = fgetc(f); + + if (c == '\n') + { + ProcessLine(currentLine); + currentLine = ""; + } + else + currentLine += c; + } + + fclose(f); + + // Fill unlisted codes + for (int i = 0; i < 0x20; i++) + g_toUnicode[i] = i; + + g_toUnicode[0x11] = 0x2318; + g_toUnicode[0x12] = 0x21e7; + g_toUnicode[0x13] = 0x2325; + g_toUnicode[0x14] = 0x2303; + + for (int i = 0; i < 256; i++) + { + bool isSmall = false; + bool isCapital = false; + std::string remainder; + + if (ParseLatinDesc(g_charDescs[i], isSmall, isCapital, remainder)) + { + for (int j = 0; j < 256; j++) + { + bool otherIsSmall = false; + bool otherIsCapital = false; + std::string otherRemainder = remainder; + + if (ParseLatinDesc(g_charDescs[j], otherIsSmall, otherIsCapital, otherRemainder)) + { + if (isCapital && otherIsSmall && remainder == otherRemainder) + { + g_toLower[i] = j; + g_toUpper[j] = i; + } + + if (isSmall == otherIsSmall && isCapital == otherIsCapital && otherRemainder.length() < remainder.length() && remainder.substr(0, otherRemainder.length()) == otherRemainder) + g_stripDiacritic[i] = j; + } + } + } + } + + FILE *outF; + if (errno_t err = fopen_s(&outF, "PortabilityLayer/MacRoman.cpp", "wb")) + return err; + + fprintf(outF, "#include \"MacRoman.h\"\n"); + fprintf(outF, "\n"); + fprintf(outF, "// This file is automatically generated by the ImportCharSet tool. DO NOT MODIFY THIS BY HAND.\n"); + fprintf(outF, "namespace PortabilityLayer\n"); + fprintf(outF, "{\n"); + fprintf(outF, "\tnamespace MacRoman\n"); + fprintf(outF, "\t{\n"); + DumpListing(outF, g_toUnicode, "0x%04x", "uint16_t g_toUnicode"); + fprintf(outF, "\n"); + DumpListing(outF, g_toUpper, "0x%02x", "uint8_t g_toUpper"); + fprintf(outF, "\n"); + DumpListing(outF, g_toLower, "0x%02x", "uint8_t g_toLower"); + fprintf(outF, "\n"); + DumpListing(outF, g_stripDiacritic, "0x%02x", "uint8_t g_stripDiacritic"); + fprintf(outF, "\t}\n"); + fprintf(outF, "}\n"); + + fclose(outF); + + return 0; +} diff --git a/ImportCharSet/ImportCharSet.vcxproj b/ImportCharSet/ImportCharSet.vcxproj new file mode 100644 index 0000000..e3344f5 --- /dev/null +++ b/ImportCharSet/ImportCharSet.vcxproj @@ -0,0 +1,123 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {B3D152CB-CD52-4CD6-9213-710ADE1B8EB0} + ImportCharSet + 10.0.17763.0 + + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + true + + + + + Level3 + Disabled + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + + + + + \ No newline at end of file diff --git a/ImportCharSet/ImportCharSet.vcxproj.filters b/ImportCharSet/ImportCharSet.vcxproj.filters new file mode 100644 index 0000000..b8d1ae9 --- /dev/null +++ b/ImportCharSet/ImportCharSet.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/MiscData/MacRoman.txt b/MiscData/MacRoman.txt new file mode 100644 index 0000000..5b3b8b4 --- /dev/null +++ b/MiscData/MacRoman.txt @@ -0,0 +1,370 @@ +#======================================================================= +# File name: ROMAN.TXT +# +# Contents: Map (external version) from Mac OS Roman +# character set to Unicode 2.1 and later. +# +# Copyright: (c) 1994-2002, 2005 by Apple Computer, Inc., all rights +# reserved. +# +# Contact: charsets@apple.com +# +# Changes: +# +# c02 2005-Apr-05 Update header comments. Matches internal xml +# and Text Encoding Converter 2.0. +# b4,c1 2002-Dec-19 Update URLs, notes. Matches internal +# utom. +# b03 1999-Sep-22 Update contact e-mail address. Matches +# internal utom, ufrm, and Text +# Encoding Converter version 1.5. +# b02 1998-Aug-18 Encoding changed for Mac OS 8.5; change +# mapping of 0xDB from CURRENCY SIGN to +# EURO SIGN. Matches internal utom, +# ufrm. +# n08 1998-Feb-05 Minor update to header comments +# n06 1997-Dec-14 Add warning about future changes to 0xDB +# from CURRENCY SIGN to EURO SIGN. Clarify +# some header information +# n04 1997-Dec-01 Update to match internal utom, ufrm: +# Change standard mapping for 0xBD from U+2126 +# to its canonical decomposition, U+03A9. +# n03 1995-Apr-15 First version (after fixing some typos). +# Matches internal ufrm. +# +# Standard header: +# ---------------- +# +# Apple, the Apple logo, and Macintosh are trademarks of Apple +# Computer, Inc., registered in the United States and other countries. +# Unicode is a trademark of Unicode Inc. For the sake of brevity, +# throughout this document, "Macintosh" can be used to refer to +# Macintosh computers and "Unicode" can be used to refer to the +# Unicode standard. +# +# Apple Computer, Inc. ("Apple") makes no warranty or representation, +# either express or implied, with respect to this document and the +# included data, its quality, accuracy, or fitness for a particular +# purpose. In no event will Apple be liable for direct, indirect, +# special, incidental, or consequential damages resulting from any +# defect or inaccuracy in this document or the included data. +# +# These mapping tables and character lists are subject to change. +# The latest tables should be available from the following: +# +# +# +# For general information about Mac OS encodings and these mapping +# tables, see the file "README.TXT". +# +# Format: +# ------- +# +# Three tab-separated columns; +# '#' begins a comment which continues to the end of the line. +# Column #1 is the Mac OS Roman code (in hex as 0xNN) +# Column #2 is the corresponding Unicode (in hex as 0xNNNN) +# Column #3 is a comment containing the Unicode name +# +# The entries are in Mac OS Roman code order. +# +# One of these mappings requires the use of a corporate character. +# See the file "CORPCHAR.TXT" and notes below. +# +# Control character mappings are not shown in this table, following +# the conventions of the standard UTC mapping tables. However, the +# Mac OS Roman character set uses the standard control characters at +# 0x00-0x1F and 0x7F. +# +# Notes on Mac OS Roman: +# ---------------------- +# +# This is a legacy Mac OS encoding; in the Mac OS X Carbon and Cocoa +# environments, it is only supported directly in programming +# interfaces for QuickDraw Text, the Script Manager, and related +# Text Utilities. For other purposes it is supported via transcoding +# to and from Unicode. +# +# This character set is used for at least the following Mac OS +# localizations: U.S., British, Canadian French, French, Swiss +# French, German, Swiss German, Italian, Swiss Italian, Dutch, +# Swedish, Norwegian, Danish, Finnish, Spanish, Catalan, +# Portuguese, Brazilian, and the default International system. +# +# Variants of Mac OS Roman are used for Croatian, Icelandic, +# Turkish, Romanian, and other encodings. Separate mapping tables +# are available for these encodings. +# +# Before Mac OS 8.5, code point 0xDB was CURRENCY SIGN, and was +# mapped to U+00A4. In Mac OS 8.5 and later versions, code point +# 0xDB is changed to EURO SIGN and maps to U+20AC; the standard +# Apple fonts are updated for Mac OS 8.5 to reflect this. There is +# a "currency sign" variant of the Mac OS Roman encoding that still +# maps 0xDB to U+00A4; this can be used for older fonts. +# +# Before Mac OS 8.5, the ROM bitmap versions of the fonts Chicago, +# New York, Geneva, and Monaco did not implement the full Mac OS +# Roman character set; they only supported character codes up to +# 0xD8. The TrueType versions of these fonts have always implemented +# the full character set, as with the bitmap and TrueType versions +# of the other standard Roman fonts. +# +# In all Mac OS encodings, fonts such as Chicago which are used +# as "system" fonts (for menus, dialogs, etc.) have four glyphs +# at code points 0x11-0x14 for transient use by the Menu Manager. +# These glyphs are not intended as characters for use in normal +# text, and the associated code points are not generally +# interpreted as associated with these glyphs; they are usually +# interpreted (if at all) as the control codes DC1-DC4. +# +# Unicode mapping issues and notes: +# --------------------------------- +# +# The following corporate zone Unicode character is used in this +# mapping: +# +# 0xF8FF Apple logo +# +# NOTE: The graphic image associated with the Apple logo character +# is not authorized for use without permission of Apple, and +# unauthorized use might constitute trademark infringement. +# +# Details of mapping changes in each version: +# ------------------------------------------- +# +# Changes from version n08 to version b02: +# +# - Encoding changed for Mac OS 8.5; change mapping of 0xDB from +# CURRENCY SIGN (U+00A4) to EURO SIGN (U+20AC). +# +# Changes from version n03 to version n04: +# +# - Change mapping of 0xBD from U+2126 to its canonical +# decomposition, U+03A9. +# +################## + +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +# +0x80 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0x81 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0x82 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0x83 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0x84 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0x85 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0x86 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0x87 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0x88 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0x89 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0x8A 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0x8B 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0x8C 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0x8D 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0x8E 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0x8F 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0x90 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0x91 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0x92 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0x93 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0x94 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0x95 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0x96 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0x97 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0x98 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0x99 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0x9A 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0x9B 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0x9C 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0x9D 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0x9E 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0x9F 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xA0 0x2020 # DAGGER +0xA1 0x00B0 # DEGREE SIGN +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A7 # SECTION SIGN +0xA5 0x2022 # BULLET +0xA6 0x00B6 # PILCROW SIGN +0xA7 0x00DF # LATIN SMALL LETTER SHARP S +0xA8 0x00AE # REGISTERED SIGN +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x2122 # TRADE MARK SIGN +0xAB 0x00B4 # ACUTE ACCENT +0xAC 0x00A8 # DIAERESIS +0xAD 0x2260 # NOT EQUAL TO +0xAE 0x00C6 # LATIN CAPITAL LETTER AE +0xAF 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xB0 0x221E # INFINITY +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x2264 # LESS-THAN OR EQUAL TO +0xB3 0x2265 # GREATER-THAN OR EQUAL TO +0xB4 0x00A5 # YEN SIGN +0xB5 0x00B5 # MICRO SIGN +0xB6 0x2202 # PARTIAL DIFFERENTIAL +0xB7 0x2211 # N-ARY SUMMATION +0xB8 0x220F # N-ARY PRODUCT +0xB9 0x03C0 # GREEK SMALL LETTER PI +0xBA 0x222B # INTEGRAL +0xBB 0x00AA # FEMININE ORDINAL INDICATOR +0xBC 0x00BA # MASCULINE ORDINAL INDICATOR +0xBD 0x03A9 # GREEK CAPITAL LETTER OMEGA +0xBE 0x00E6 # LATIN SMALL LETTER AE +0xBF 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xC0 0x00BF # INVERTED QUESTION MARK +0xC1 0x00A1 # INVERTED EXCLAMATION MARK +0xC2 0x00AC # NOT SIGN +0xC3 0x221A # SQUARE ROOT +0xC4 0x0192 # LATIN SMALL LETTER F WITH HOOK +0xC5 0x2248 # ALMOST EQUAL TO +0xC6 0x2206 # INCREMENT +0xC7 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xC8 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xC9 0x2026 # HORIZONTAL ELLIPSIS +0xCA 0x00A0 # NO-BREAK SPACE +0xCB 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xCC 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xCD 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xCE 0x0152 # LATIN CAPITAL LIGATURE OE +0xCF 0x0153 # LATIN SMALL LIGATURE OE +0xD0 0x2013 # EN DASH +0xD1 0x2014 # EM DASH +0xD2 0x201C # LEFT DOUBLE QUOTATION MARK +0xD3 0x201D # RIGHT DOUBLE QUOTATION MARK +0xD4 0x2018 # LEFT SINGLE QUOTATION MARK +0xD5 0x2019 # RIGHT SINGLE QUOTATION MARK +0xD6 0x00F7 # DIVISION SIGN +0xD7 0x25CA # LOZENGE +0xD8 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS +0xD9 0x0178 # LATIN CAPITAL LETTER Y WITH DIAERESIS +0xDA 0x2044 # FRACTION SLASH +0xDB 0x20AC # EURO SIGN +0xDC 0x2039 # SINGLE LEFT-POINTING ANGLE QUOTATION MARK +0xDD 0x203A # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0xDE 0xFB01 # LATIN SMALL LIGATURE FI +0xDF 0xFB02 # LATIN SMALL LIGATURE FL +0xE0 0x2021 # DOUBLE DAGGER +0xE1 0x00B7 # MIDDLE DOT +0xE2 0x201A # SINGLE LOW-9 QUOTATION MARK +0xE3 0x201E # DOUBLE LOW-9 QUOTATION MARK +0xE4 0x2030 # PER MILLE SIGN +0xE5 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xE6 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xE7 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xE8 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xE9 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xEA 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xEB 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xEC 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xED 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xEE 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xEF 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xF0 0xF8FF # Apple logo +0xF1 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xF2 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xF3 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xF4 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xF5 0x0131 # LATIN SMALL LETTER DOTLESS I +0xF6 0x02C6 # MODIFIER LETTER CIRCUMFLEX ACCENT +0xF7 0x02DC # SMALL TILDE +0xF8 0x00AF # MACRON +0xF9 0x02D8 # BREVE +0xFA 0x02D9 # DOT ABOVE +0xFB 0x02DA # RING ABOVE +0xFC 0x00B8 # CEDILLA +0xFD 0x02DD # DOUBLE ACUTE ACCENT +0xFE 0x02DB # OGONEK +0xFF 0x02C7 # CARON diff --git a/PictChecker/PictChecker.vcxproj b/PictChecker/PictChecker.vcxproj index d3e89db..4eff990 100644 --- a/PictChecker/PictChecker.vcxproj +++ b/PictChecker/PictChecker.vcxproj @@ -61,24 +61,28 @@ + + + + diff --git a/PortabilityLayer/FileManager.cpp b/PortabilityLayer/FileManager.cpp index 0a0b7c9..294aeb5 100644 --- a/PortabilityLayer/FileManager.cpp +++ b/PortabilityLayer/FileManager.cpp @@ -1,71 +1,71 @@ -#include "FileManager.h" -#include "HostFileSystem.h" -#include "HostMemoryBuffer.h" -#include "MemReaderStream.h" -#include "MacBinary2.h" -#include "MacFileMem.h" -#include "PLPasStr.h" -#include "PLErrorCodes.h" - -#include - -namespace PortabilityLayer -{ - class VirtualFile; - - class FileManagerImpl final : public FileManager - { - public: - bool FileExists(uint32_t dirID, const PLPasStr &filename) override; - - int OpenFileDF(uint32_t dirID, const PLPasStr &filename, EFilePermission filePermission, short *outRefNum) override; - int OpenFileRF(uint32_t dirID, const PLPasStr &filename, EFilePermission filePermission, short *outRefNum) override; +#include "FileManager.h" +#include "HostFileSystem.h" +#include "HostMemoryBuffer.h" +#include "MemReaderStream.h" +#include "MacBinary2.h" +#include "MacFileMem.h" +#include "PLPasStr.h" +#include "PLErrorCodes.h" + +#include + +namespace PortabilityLayer +{ + class VirtualFile; + + class FileManagerImpl final : public FileManager + { + public: + bool FileExists(uint32_t dirID, const PLPasStr &filename) override; + + int OpenFileDF(uint32_t dirID, const PLPasStr &filename, EFilePermission filePermission, short *outRefNum) override; + int OpenFileRF(uint32_t dirID, const PLPasStr &filename, EFilePermission filePermission, short *outRefNum) override; bool ReadFileProperties(uint32_t dirID, const PLPasStr &filename, MacFileProperties &properties) override; - IOStream *GetFileStream(int fileID) override; - - int RawOpenFileDF(uint32_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, IOStream **outStream) override; - int RawOpenFileRF(uint32_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, IOStream **outStream) override; - - static FileManagerImpl *GetInstance(); - - private: - typedef char ExtendedFileName_t[64 + 4]; - - struct OpenedFile - { - EVirtualDirectory m_dirID; - PascalStr<64> m_fileName; - - IOStream *m_stream; - }; - - int OpenFileFork(uint32_t dirID, const PLPasStr &filename, const char *ext, EFilePermission permission, short *outRefNum); - int RawOpenFileFork(uint32_t dirID, const PLPasStr &filename, const char *ext, EFilePermission permission, bool ignoreMeta, IOStream **outStream); - - static bool ConstructFilename(ExtendedFileName_t& extFN, const PLPasStr &fn, const char *extension); - - std::vector m_refs; - - static FileManagerImpl ms_instance; - }; - - bool FileManagerImpl::FileExists(uint32_t dirID, const PLPasStr &filename) - { - ExtendedFileName_t extFN; - if (!ConstructFilename(extFN, filename, ".gpf")) - return false; - - return HostFileSystem::GetInstance()->FileExists(static_cast(dirID), extFN); - } - - int FileManagerImpl::OpenFileDF(uint32_t dirID, const PLPasStr &filename, EFilePermission permission, short *outRefNum) - { - return OpenFileFork(dirID, filename, ".gpd", permission, outRefNum); - } - - int FileManagerImpl::OpenFileRF(uint32_t dirID, const PLPasStr &filename, EFilePermission permission, short *outRefNum) - { - return OpenFileFork(dirID, filename, ".gpr", permission, outRefNum); + IOStream *GetFileStream(int fileID) override; + + int RawOpenFileDF(uint32_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, IOStream **outStream) override; + int RawOpenFileRF(uint32_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, IOStream **outStream) override; + + static FileManagerImpl *GetInstance(); + + private: + typedef char ExtendedFileName_t[64 + 4]; + + struct OpenedFile + { + EVirtualDirectory m_dirID; + PascalStr<64> m_fileName; + + IOStream *m_stream; + }; + + int OpenFileFork(uint32_t dirID, const PLPasStr &filename, const char *ext, EFilePermission permission, short *outRefNum); + int RawOpenFileFork(uint32_t dirID, const PLPasStr &filename, const char *ext, EFilePermission permission, bool ignoreMeta, IOStream **outStream); + + static bool ConstructFilename(ExtendedFileName_t& extFN, const PLPasStr &fn, const char *extension); + + std::vector m_refs; + + static FileManagerImpl ms_instance; + }; + + bool FileManagerImpl::FileExists(uint32_t dirID, const PLPasStr &filename) + { + ExtendedFileName_t extFN; + if (!ConstructFilename(extFN, filename, ".gpf")) + return false; + + return HostFileSystem::GetInstance()->FileExists(static_cast(dirID), extFN); + } + + int FileManagerImpl::OpenFileDF(uint32_t dirID, const PLPasStr &filename, EFilePermission permission, short *outRefNum) + { + return OpenFileFork(dirID, filename, ".gpd", permission, outRefNum); + } + + int FileManagerImpl::OpenFileRF(uint32_t dirID, const PLPasStr &filename, EFilePermission permission, short *outRefNum) + { + return OpenFileFork(dirID, filename, ".gpr", permission, outRefNum); } bool FileManagerImpl::ReadFileProperties(uint32_t dirID, const PLPasStr &filename, MacFileProperties &properties) @@ -82,150 +82,150 @@ namespace PortabilityLayer if (readOk) serialized.Deserialize(properties); - return readOk; + return readOk; } IOStream *FileManagerImpl::GetFileStream(int fileID) { - return m_refs[fileID].m_stream; - } - - int FileManagerImpl::RawOpenFileDF(uint32_t dirID, const PLPasStr &filename, EFilePermission permission, bool ignoreMeta, IOStream **outStream) - { - return RawOpenFileFork(dirID, filename, ".gpd", permission, ignoreMeta, outStream); - } - - int FileManagerImpl::RawOpenFileRF(uint32_t dirID, const PLPasStr &filename, EFilePermission permission, bool ignoreMeta, IOStream **outStream) - { - return RawOpenFileFork(dirID, filename, ".gpr", permission, ignoreMeta, outStream); - } - - FileManagerImpl *FileManagerImpl::GetInstance() - { - return &ms_instance; - } - - int FileManagerImpl::OpenFileFork(uint32_t dirID, const PLPasStr &filename, const char *extension, EFilePermission permission, short *outRefNum) - { - const size_t numRefs = m_refs.size(); - size_t refIndex = m_refs.size(); - for (size_t i = 0; i < numRefs; i++) - { - if (m_refs[i].m_stream == nullptr) - { - refIndex = i; - break; - } - } - - if (refIndex == 0x8000) - return tmfoErr; - - IOStream *stream = nullptr; - int openError = RawOpenFileFork(dirID, filename, extension, permission, false, &stream); - if (openError != 0) - return openError; - - if (refIndex == numRefs) - m_refs.push_back(OpenedFile()); - - OpenedFile &of = m_refs[refIndex]; - of.m_stream = stream; - of.m_dirID = static_cast(dirID); - of.m_fileName.Set(filename.Length(), filename.Chars()); - - *outRefNum = static_cast(refIndex); - - return noErr; - } - - int FileManagerImpl::RawOpenFileFork(uint32_t dirID, const PLPasStr &filename, const char *ext, EFilePermission permission, bool ignoreMeta, IOStream **outStream) - { - ExtendedFileName_t gpfExtFN; - ExtendedFileName_t extFN; - - if (filename.Length() > 63) - return bdNamErr; - - if (!ignoreMeta) - { - if (!ConstructFilename(gpfExtFN, filename, ".gpf")) - return bdNamErr; - - if (!HostFileSystem::GetInstance()->FileExists(static_cast(dirID), gpfExtFN)) - return fnfErr; - } - - if (!ConstructFilename(extFN, filename, ext)) - return bdNamErr; - - const bool needToCreate = !(ignoreMeta || HostFileSystem::GetInstance()->FileExists(static_cast(dirID), extFN)); - - IOStream *fstream = nullptr; - switch (permission) - { - case EFilePermission_Any: - fstream = HostFileSystem::GetInstance()->OpenFile(static_cast(dirID), extFN, true, needToCreate); - if (fstream) - permission = EFilePermission_ReadWrite; - else - { - permission = EFilePermission_Read; - fstream = HostFileSystem::GetInstance()->OpenFile(static_cast(dirID), extFN, false, needToCreate); - } - break; - case EFilePermission_Read: - fstream = HostFileSystem::GetInstance()->OpenFile(static_cast(dirID), extFN, false, needToCreate); - break; - case EFilePermission_ReadWrite: - fstream = HostFileSystem::GetInstance()->OpenFile(static_cast(dirID), extFN, true, needToCreate); - break; - } - - if (!fstream) - return permErr; - - *outStream = fstream; - return noErr; - } - - bool FileManagerImpl::ConstructFilename(ExtendedFileName_t& extFN, const PLPasStr &fn, const char *extension) - { - const size_t fnameSize = fn.Length(); - if (fnameSize >= 64) - return false; - - memcpy(extFN, fn.Chars(), fnameSize); - memcpy(extFN + fnameSize, extension, strlen(extension) + 1); - - for (size_t i = 0; i < fnameSize; i++) - { - const char c = extFN[i]; - if (c >= '0' && c <= '9') - continue; - - if (c == '_' || c == '.' || c == '\'') - continue; - - if (c == ' ' && i != 0 && i != fnameSize - 1) - continue; - - if (c >= 'a' && c <= 'z') - continue; - - if (c >= 'A' && c <= 'Z') - continue; - - return false; - } - - return true; - } - - FileManagerImpl FileManagerImpl::ms_instance; - - FileManager *FileManager::GetInstance() - { - return FileManagerImpl::GetInstance(); - } -} + return m_refs[fileID].m_stream; + } + + int FileManagerImpl::RawOpenFileDF(uint32_t dirID, const PLPasStr &filename, EFilePermission permission, bool ignoreMeta, IOStream **outStream) + { + return RawOpenFileFork(dirID, filename, ".gpd", permission, ignoreMeta, outStream); + } + + int FileManagerImpl::RawOpenFileRF(uint32_t dirID, const PLPasStr &filename, EFilePermission permission, bool ignoreMeta, IOStream **outStream) + { + return RawOpenFileFork(dirID, filename, ".gpr", permission, ignoreMeta, outStream); + } + + FileManagerImpl *FileManagerImpl::GetInstance() + { + return &ms_instance; + } + + int FileManagerImpl::OpenFileFork(uint32_t dirID, const PLPasStr &filename, const char *extension, EFilePermission permission, short *outRefNum) + { + const size_t numRefs = m_refs.size(); + size_t refIndex = m_refs.size(); + for (size_t i = 0; i < numRefs; i++) + { + if (m_refs[i].m_stream == nullptr) + { + refIndex = i; + break; + } + } + + if (refIndex == 0x8000) + return tmfoErr; + + IOStream *stream = nullptr; + int openError = RawOpenFileFork(dirID, filename, extension, permission, false, &stream); + if (openError != 0) + return openError; + + if (refIndex == numRefs) + m_refs.push_back(OpenedFile()); + + OpenedFile &of = m_refs[refIndex]; + of.m_stream = stream; + of.m_dirID = static_cast(dirID); + of.m_fileName.Set(filename.Length(), filename.Chars()); + + *outRefNum = static_cast(refIndex); + + return noErr; + } + + int FileManagerImpl::RawOpenFileFork(uint32_t dirID, const PLPasStr &filename, const char *ext, EFilePermission permission, bool ignoreMeta, IOStream **outStream) + { + ExtendedFileName_t gpfExtFN; + ExtendedFileName_t extFN; + + if (filename.Length() > 63) + return bdNamErr; + + if (!ignoreMeta) + { + if (!ConstructFilename(gpfExtFN, filename, ".gpf")) + return bdNamErr; + + if (!HostFileSystem::GetInstance()->FileExists(static_cast(dirID), gpfExtFN)) + return fnfErr; + } + + if (!ConstructFilename(extFN, filename, ext)) + return bdNamErr; + + const bool needToCreate = !(ignoreMeta || HostFileSystem::GetInstance()->FileExists(static_cast(dirID), extFN)); + + IOStream *fstream = nullptr; + switch (permission) + { + case EFilePermission_Any: + fstream = HostFileSystem::GetInstance()->OpenFile(static_cast(dirID), extFN, true, needToCreate); + if (fstream) + permission = EFilePermission_ReadWrite; + else + { + permission = EFilePermission_Read; + fstream = HostFileSystem::GetInstance()->OpenFile(static_cast(dirID), extFN, false, needToCreate); + } + break; + case EFilePermission_Read: + fstream = HostFileSystem::GetInstance()->OpenFile(static_cast(dirID), extFN, false, needToCreate); + break; + case EFilePermission_ReadWrite: + fstream = HostFileSystem::GetInstance()->OpenFile(static_cast(dirID), extFN, true, needToCreate); + break; + } + + if (!fstream) + return permErr; + + *outStream = fstream; + return noErr; + } + + bool FileManagerImpl::ConstructFilename(ExtendedFileName_t& extFN, const PLPasStr &fn, const char *extension) + { + const size_t fnameSize = fn.Length(); + if (fnameSize >= 64) + return false; + + memcpy(extFN, fn.Chars(), fnameSize); + memcpy(extFN + fnameSize, extension, strlen(extension) + 1); + + for (size_t i = 0; i < fnameSize; i++) + { + const char c = extFN[i]; + if (c >= '0' && c <= '9') + continue; + + if (c == '_' || c == '.' || c == '\'') + continue; + + if (c == ' ' && i != 0 && i != fnameSize - 1) + continue; + + if (c >= 'a' && c <= 'z') + continue; + + if (c >= 'A' && c <= 'Z') + continue; + + return false; + } + + return true; + } + + FileManagerImpl FileManagerImpl::ms_instance; + + FileManager *FileManager::GetInstance() + { + return FileManagerImpl::GetInstance(); + } +} diff --git a/PortabilityLayer/FontFamily.cpp b/PortabilityLayer/FontFamily.cpp new file mode 100644 index 0000000..5ed54cf --- /dev/null +++ b/PortabilityLayer/FontFamily.cpp @@ -0,0 +1,95 @@ +#include "FontFamily.h" +#include "IOStream.h" +#include "HostFileSystem.h" +#include "HostFontHandler.h" +#include "HostFont.h" + +#include +#include + +namespace PortabilityLayer +{ + void FontFamily::AddFont(int flags, const char *path, FontHacks fontHacks) + { + PortabilityLayer::IOStream *sysFontStream = PortabilityLayer::HostFileSystem::GetInstance()->OpenFile(PortabilityLayer::EVirtualDirectory_Fonts, path, false, false); + if (!sysFontStream) + return; + + PortabilityLayer::HostFontHandler *fontHandler = PortabilityLayer::HostFontHandler::GetInstance(); + + PortabilityLayer::HostFont *font = fontHandler->LoadFont(sysFontStream); + + if (!fontHandler->KeepStreamOpen()) + sysFontStream->Close(); + + if (!font) + return; + + m_fonts[flags] = font; + m_hacks[flags] = fontHacks; + + if (m_fonts[0] == nullptr) + m_defaultVariation = flags; + } + + void FontFamily::SetDefaultVariation(int defaultVariation) + { + if (m_fonts[defaultVariation]) + m_defaultVariation = defaultVariation; + } + + int FontFamily::GetVariationForFlags(int variation) const + { + if (m_fonts[variation]) + return variation; + + if (m_fonts[0]) + return 0; + + return m_defaultVariation; + } + + PortabilityLayer::HostFont *FontFamily::GetFontForVariation(int variation) const + { + return m_fonts[variation]; + } + + PortabilityLayer::FontHacks FontFamily::GetHacksForVariation(int variation) const + { + return m_hacks[variation]; + } + + FontFamily *FontFamily::Create() + { + void *storage = malloc(sizeof(FontFamily)); + if (!storage) + return nullptr; + + return new (storage) FontFamily(); + } + + void FontFamily::Destroy() + { + this->~FontFamily(); + free(this); + } + + FontFamily::FontFamily() + : m_defaultVariation(0) + { + for (unsigned int i = 0; i < kNumVariations; i++) + { + m_fonts[i] = nullptr; + m_hacks[i] = FontHacks_None; + } + } + + FontFamily::~FontFamily() + { + for (unsigned int i = 0; i < kNumVariations; i++) + { + if (PortabilityLayer::HostFont *font = m_fonts[i]) + font->Destroy(); + } + } +} diff --git a/PortabilityLayer/FontFamily.h b/PortabilityLayer/FontFamily.h new file mode 100644 index 0000000..33c3aa4 --- /dev/null +++ b/PortabilityLayer/FontFamily.h @@ -0,0 +1,44 @@ +#pragma once + +#include "FontHacks.h" +#include + +class PLPasStr; + +namespace PortabilityLayer +{ + class HostFont; + + enum FontFamilyFlags + { + FontFamilyFlag_None = 0, + + FontFamilyFlag_Bold = 1, + + FontFamilyFlag_All = 1, + }; + + class FontFamily final + { + public: + static const unsigned int kNumVariations = FontFamilyFlag_All + 1; + + void AddFont(int flags, const char *path, FontHacks fontHacks); + void SetDefaultVariation(int defaultVariation); + + int GetVariationForFlags(int variation) const; + PortabilityLayer::HostFont *GetFontForVariation(int variation) const; + PortabilityLayer::FontHacks GetHacksForVariation(int variation) const; + + static FontFamily *Create(); + void Destroy(); + + private: + PortabilityLayer::FontHacks m_hacks[kNumVariations]; + PortabilityLayer::HostFont *m_fonts[kNumVariations]; + uint8_t m_defaultVariation; + + FontFamily(); + ~FontFamily(); + }; +} diff --git a/PortabilityLayer/FontHacks.h b/PortabilityLayer/FontHacks.h new file mode 100644 index 0000000..55a7444 --- /dev/null +++ b/PortabilityLayer/FontHacks.h @@ -0,0 +1,10 @@ +#pragma once + +namespace PortabilityLayer +{ + enum FontHacks + { + FontHacks_None, + FontHacks_Roboto, + }; +} diff --git a/PortabilityLayer/FontManager.cpp b/PortabilityLayer/FontManager.cpp index 789ff9e..d810746 100644 --- a/PortabilityLayer/FontManager.cpp +++ b/PortabilityLayer/FontManager.cpp @@ -1,45 +1,83 @@ #include "FontManager.h" +#include "FontFamily.h" +#include "FontRenderer.h" #include "HostFileSystem.h" #include "HostFont.h" #include "HostFontHandler.h" #include "IOStream.h" +#include "RenderedFont.h" + +#include +#include void PL_NotYetImplemented(); namespace PortabilityLayer -{ +{ class FontManagerImpl final : public FontManager { public: void Init() override; void Shutdown() override; + FontFamily *GetSystemFont(int textSize, int variationFlags) const override; + FontFamily *GetApplicationFont(int textSize, int variationFlags) const override; + + RenderedFont *GetRenderedFont(HostFont *font, int size, FontHacks fontHacks) override; + static FontManagerImpl *GetInstance(); private: + static const unsigned int kNumCachedRenderedFonts = 32; + + struct CachedRenderedFont + { + RenderedFont *m_rfont; + const HostFont *m_font; + int m_size; + uint32_t m_lastUsage; + }; + FontManagerImpl(); - PortabilityLayer::HostFont *m_systemFont; + void ResetUsageCounter(); + static int CRFSortPredicate(const void *a, const void *b); + + FontFamily *m_systemFont; + FontFamily *m_applicationFont; + uint32_t m_usageCounter; + + CachedRenderedFont m_cachedRenderedFonts[kNumCachedRenderedFonts]; static FontManagerImpl ms_instance; }; void FontManagerImpl::Init() { - m_systemFont = nullptr; + m_systemFont = FontFamily::Create(); + m_applicationFont = FontFamily::Create(); - if (IOStream *sysFontStream = HostFileSystem::GetInstance()->OpenFile(EVirtualDirectory_Fonts, "virtue.ttf", false, false)) + if (m_systemFont) + m_systemFont->AddFont(FontFamilyFlag_None, "Fonts/Virtue/virtue.ttf", FontHacks_None); + + if (m_applicationFont) { - HostFont *font = HostFontHandler::GetInstance()->LoadFont(sysFontStream); - sysFontStream->Close(); - - m_systemFont = font; + m_applicationFont->AddFont(FontFamilyFlag_None, "Fonts/Roboto/Roboto-Regular.ttf", FontHacks_Roboto); + m_applicationFont->AddFont(FontFamilyFlag_Bold, "Fonts/Roboto/Roboto-Bold.ttf", FontHacks_Roboto); } + + memset(m_cachedRenderedFonts, 0, sizeof(m_cachedRenderedFonts)); } void FontManagerImpl::Shutdown() { + if (m_systemFont) + m_systemFont->Destroy(); + + if (m_applicationFont) + m_applicationFont->Destroy(); + HostFontHandler *hfh = HostFontHandler::GetInstance(); if (m_systemFont) @@ -47,6 +85,76 @@ namespace PortabilityLayer m_systemFont->Destroy(); m_systemFont = nullptr; } + + for (int i = 0; i < sizeof(m_cachedRenderedFonts) / sizeof(m_cachedRenderedFonts[0]); i++) + { + CachedRenderedFont *crf = m_cachedRenderedFonts + i; + if (crf->m_rfont) + crf->m_rfont->Destroy(); + } + } + + FontFamily *FontManagerImpl::GetSystemFont(int textSize, int variationFlags) const + { + (void)textSize; + return m_systemFont; + } + + FontFamily *FontManagerImpl::GetApplicationFont(int textSize, int variationFlags) const + { + if (textSize < 11 && (variationFlags & FontFamilyFlag_Bold) != 0) + return m_systemFont; // Roboto Bold below 11pt doesn't even look bold, so use a better font + + return m_applicationFont; + } + + RenderedFont *FontManagerImpl::GetRenderedFont(HostFont *font, int size, FontHacks fontHacks) + { + CachedRenderedFont *newCacheSlot = &m_cachedRenderedFonts[0]; + + for (int i = 0; i < kNumCachedRenderedFonts; i++) + { + CachedRenderedFont &crf = m_cachedRenderedFonts[i]; + if (crf.m_rfont == nullptr) + { + newCacheSlot = &crf; + break; + } + + if (crf.m_font == font && crf.m_size == size) + { + crf.m_lastUsage = m_usageCounter; + RenderedFont *rf = crf.m_rfont; + if (m_usageCounter == UINT32_MAX) + ResetUsageCounter(); + else + m_usageCounter++; + + return rf; + } + + if (newCacheSlot->m_rfont != nullptr && crf.m_lastUsage < newCacheSlot->m_lastUsage) + newCacheSlot = &crf; + } + + RenderedFont *rfont = FontRenderer::GetInstance()->RenderFont(font, size, fontHacks); + if (!rfont) + return nullptr; + + if (newCacheSlot->m_rfont) + newCacheSlot->m_rfont->Destroy(); + + newCacheSlot->m_font = font; + newCacheSlot->m_lastUsage = m_usageCounter; + newCacheSlot->m_size = size; + newCacheSlot->m_rfont = rfont; + + if (m_usageCounter == UINT32_MAX) + ResetUsageCounter(); + else + m_usageCounter++; + + return rfont; } FontManagerImpl *FontManagerImpl::GetInstance() @@ -59,6 +167,47 @@ namespace PortabilityLayer { } + void FontManagerImpl::ResetUsageCounter() + { + // Resets the usage counter if it would overflow by sorting by ascending last usage and then resetting all counts to simple +1 increments + qsort(m_cachedRenderedFonts, kNumCachedRenderedFonts, sizeof(CachedRenderedFont), FontManagerImpl::CRFSortPredicate); + + m_usageCounter = 0; + + for (unsigned int i = 0; i < kNumCachedRenderedFonts; i++) + { + CachedRenderedFont &crf = m_cachedRenderedFonts[i]; + + if (!crf.m_rfont) + break; + + crf.m_lastUsage = m_usageCounter++; + } + } + + int FontManagerImpl::CRFSortPredicate(const void *a, const void *b) + { + const CachedRenderedFont *crfA = static_cast(a); + const CachedRenderedFont *crfB = static_cast(b); + + if (crfA->m_rfont == nullptr && crfB->m_rfont == nullptr) + return 0; + + if (crfA->m_rfont == nullptr && crfB->m_rfont != nullptr) + return 1; + + if (crfA->m_rfont != nullptr && crfB->m_rfont == nullptr) + return -1; + + if (crfA->m_lastUsage < crfB->m_lastUsage) + return -1; + + if (crfA->m_lastUsage > crfB->m_lastUsage) + return 1; + + return 0; + } + FontManagerImpl FontManagerImpl::ms_instance; FontManager *FontManager::GetInstance() diff --git a/PortabilityLayer/FontManager.h b/PortabilityLayer/FontManager.h index 1b12179..97175cb 100644 --- a/PortabilityLayer/FontManager.h +++ b/PortabilityLayer/FontManager.h @@ -1,13 +1,24 @@ -#pragma once +#pragma once + +#include "FontHacks.h" namespace PortabilityLayer -{ +{ + class FontFamily; + class HostFont; + class RenderedFont; + class FontManager { public: virtual void Init() = 0; virtual void Shutdown() = 0; + virtual FontFamily *GetSystemFont(int fontSize, int variationFlags) const = 0; + virtual FontFamily *GetApplicationFont(int fontSize, int variationFlags) const = 0; + + virtual RenderedFont *GetRenderedFont(HostFont *font, int size, FontHacks fontHacks) = 0; + static FontManager *GetInstance(); }; } diff --git a/PortabilityLayer/FontRenderer.cpp b/PortabilityLayer/FontRenderer.cpp new file mode 100644 index 0000000..e1d1590 --- /dev/null +++ b/PortabilityLayer/FontRenderer.cpp @@ -0,0 +1,198 @@ +#include "FontRenderer.h" + +#include "CoreDefs.h" +#include "HostFont.h" +#include "HostFontHandler.h" +#include "HostFontRenderedGlyph.h" +#include "MacRoman.h" +#include "RenderedFont.h" +#include "RenderedGlyphMetrics.h" + +#include +#include +#include +#include + +namespace PortabilityLayer +{ + class RenderedFontImpl final : public RenderedFont + { + public: + bool GetGlyph(unsigned int character, const RenderedGlyphMetrics **outMetricsPtr, const void **outData) const override; + + void Destroy() override; + + void SetCharData(unsigned int charID, const void *data, size_t dataOffset, const RenderedGlyphMetrics &metrics); + + static RenderedFontImpl *Create(size_t glyphDataSize); + + private: + explicit RenderedFontImpl(void *data); + ~RenderedFontImpl(); + + size_t m_dataOffsets[256]; + RenderedGlyphMetrics m_metrics[256]; + + void *m_data; + }; + + class FontRendererImpl final : public FontRenderer + { + public: + RenderedFont *RenderFont(HostFont *font, int size, FontHacks fontHacks) override; + + static FontRendererImpl *GetInstance(); + + private: + static FontRendererImpl ms_instance; + }; + + bool RenderedFontImpl::GetGlyph(unsigned int character, const RenderedGlyphMetrics **outMetricsPtr, const void **outData) const + { + const size_t dataOffset = m_dataOffsets[character]; + if (!dataOffset) + return false; + + *outMetricsPtr = m_metrics + character; + *outData = static_cast(m_data) + dataOffset; + + return true; + } + + void RenderedFontImpl::Destroy() + { + this->~RenderedFontImpl(); + free(this); + } + + void RenderedFontImpl::SetCharData(unsigned int charID, const void *data, size_t dataOffset, const RenderedGlyphMetrics &metrics) + { + m_dataOffsets[charID] = dataOffset; + m_metrics[charID] = metrics; + memcpy(static_cast(m_data) + dataOffset, data, metrics.m_glyphDataPitch * metrics.m_glyphHeight); + } + + RenderedFontImpl *RenderedFontImpl::Create(size_t glyphDataSize) + { + size_t alignedPrefixSize = sizeof(RenderedFontImpl) + PL_SYSTEM_MEMORY_ALIGNMENT - 1; + alignedPrefixSize -= alignedPrefixSize % PL_SYSTEM_MEMORY_ALIGNMENT; + + if (SIZE_MAX - alignedPrefixSize < glyphDataSize) + return nullptr; + + const size_t allocSize = alignedPrefixSize + glyphDataSize; + + void *storage = malloc(allocSize); + if (!storage) + return nullptr; + + memset(storage, 0, allocSize); + + return new (storage) RenderedFontImpl(static_cast(storage) + alignedPrefixSize); + } + + RenderedFontImpl::RenderedFontImpl(void *data) + : m_data(data) + { + memset(m_metrics, 0, sizeof(m_metrics)); + memset(m_dataOffsets, 0, sizeof(m_dataOffsets)); + } + + RenderedFontImpl::~RenderedFontImpl() + { + } + + RenderedFont *FontRendererImpl::RenderFont(HostFont *font, int size, FontHacks fontHacks) + { + const unsigned int numCharacters = 256; + + if (size < 1) + return nullptr; + + HostFontRenderedGlyph *glyphs[numCharacters]; + + for (unsigned int i = 0; i < numCharacters; i++) + glyphs[i] = nullptr; + + for (unsigned int i = 0; i < numCharacters; i++) + { + uint16_t unicodeCodePoint = MacRoman::g_toUnicode[i]; + if (unicodeCodePoint == 0xffff) + continue; + + glyphs[i] = font->Render(unicodeCodePoint, size); + } + + size_t glyphDataSize = PL_SYSTEM_MEMORY_ALIGNMENT; // So we can use 0 to mean no data + size_t numUsedGlyphs = 0; + for (unsigned int i = 0; i < numCharacters; i++) + { + if (glyphs[i]) + { + const RenderedGlyphMetrics &metrics = glyphs[i]->GetMetrics(); + glyphDataSize += metrics.m_glyphDataPitch * metrics.m_glyphHeight; + } + } + + RenderedFontImpl *rfont = RenderedFontImpl::Create(glyphDataSize); + if (rfont) + { + size_t fillOffset = PL_SYSTEM_MEMORY_ALIGNMENT; + + size_t numUsedGlyphs = 0; + for (unsigned int i = 0; i < numCharacters; i++) + { + if (glyphs[i]) + { + HostFontRenderedGlyph *glyph = glyphs[i]; + + RenderedGlyphMetrics metrics = glyph->GetMetrics(); + const void *data = glyph->GetData(); + + if (fontHacks == FontHacks_Roboto) + { + if (size < 32) + { + // 'r' is shifted up 1 pixel + if (i == 'r' && size < 32) + { + metrics.m_bearingY--; + } + + // ':' doesn't have enough spacing + if (i == ':') + { + metrics.m_bearingX++; + metrics.m_advanceX++; + } + } + } + + rfont->SetCharData(i, data, fillOffset, metrics); + + fillOffset += metrics.m_glyphDataPitch * metrics.m_glyphHeight; + } + } + } + + for (unsigned int i = 0; i < numCharacters; i++) + { + if (glyphs[i]) + glyphs[i]->Destroy(); + } + + return rfont; + } + + FontRendererImpl *FontRendererImpl::GetInstance() + { + return &ms_instance; + } + + FontRendererImpl FontRendererImpl::ms_instance; + + FontRenderer *FontRenderer::GetInstance() + { + return FontRendererImpl::GetInstance(); + } +} diff --git a/PortabilityLayer/FontRenderer.h b/PortabilityLayer/FontRenderer.h new file mode 100644 index 0000000..18b0c60 --- /dev/null +++ b/PortabilityLayer/FontRenderer.h @@ -0,0 +1,17 @@ +#pragma once + +#include "FontHacks.h" + +namespace PortabilityLayer +{ + class RenderedFont; + class HostFont; + + class FontRenderer + { + public: + virtual RenderedFont *RenderFont(HostFont *font, int size, FontHacks fontHacks) = 0; + + static FontRenderer *GetInstance(); + }; +} diff --git a/PortabilityLayer/HostDisplayDriver.h b/PortabilityLayer/HostDisplayDriver.h index f2dad90..b0b2c11 100644 --- a/PortabilityLayer/HostDisplayDriver.h +++ b/PortabilityLayer/HostDisplayDriver.h @@ -2,7 +2,7 @@ #ifndef __PL_HOST_DISPLAY_DRIVER_H__ #define __PL_HOST_DISPLAY_DRIVER_H__ -#include "PixelFormat.h" +#include "GpPixelFormat.h" #include "EGpStandardCursor.h" struct IGpColorCursor; @@ -12,7 +12,7 @@ namespace PortabilityLayer class HostDisplayDriver { public: - virtual void GetDisplayResolution(unsigned int *width, unsigned int *height, PixelFormat *pixelFormat) = 0; + virtual void GetDisplayResolution(unsigned int *width, unsigned int *height, GpPixelFormat_t *pixelFormat) = 0; virtual IGpColorCursor *LoadColorCursor(int id) = 0; virtual void SetColorCursor(IGpColorCursor *colorCursor) = 0; virtual void SetStandardCursor(EGpStandardCursor_t standardCursor) = 0; diff --git a/PortabilityLayer/HostFont.h b/PortabilityLayer/HostFont.h index 489772f..05ef6e5 100644 --- a/PortabilityLayer/HostFont.h +++ b/PortabilityLayer/HostFont.h @@ -1,10 +1,15 @@ -#pragma once +#pragma once + +#include namespace PortabilityLayer -{ +{ + class HostFontRenderedGlyph; + class HostFont { public: virtual void Destroy() = 0; + virtual HostFontRenderedGlyph *Render(uint32_t unicodeCodePoint, unsigned int size) = 0; }; } diff --git a/PortabilityLayer/HostFontHandler.h b/PortabilityLayer/HostFontHandler.h index 24ef1be..ef66f12 100644 --- a/PortabilityLayer/HostFontHandler.h +++ b/PortabilityLayer/HostFontHandler.h @@ -1,16 +1,18 @@ #pragma once - + namespace PortabilityLayer { class IOStream; class HostFont; - + class HostFontHandler { public: virtual void Shutdown() = 0; + virtual HostFont *LoadFont(IOStream *stream) = 0; + virtual bool KeepStreamOpen() const = 0; static void SetInstance(HostFontHandler *instance); static HostFontHandler *GetInstance(); diff --git a/PortabilityLayer/HostFontRenderedGlyph.h b/PortabilityLayer/HostFontRenderedGlyph.h new file mode 100644 index 0000000..8297a54 --- /dev/null +++ b/PortabilityLayer/HostFontRenderedGlyph.h @@ -0,0 +1,14 @@ +#pragma once + +namespace PortabilityLayer +{ + struct RenderedGlyphMetrics; + + class HostFontRenderedGlyph + { + public: + virtual const RenderedGlyphMetrics &GetMetrics() const = 0; + virtual const void *GetData() const = 0; + virtual void Destroy() = 0; + }; +} diff --git a/PortabilityLayer/IOStream.h b/PortabilityLayer/IOStream.h index 5f1ae50..6fceee8 100644 --- a/PortabilityLayer/IOStream.h +++ b/PortabilityLayer/IOStream.h @@ -1,29 +1,29 @@ -#pragma once - -#ifndef __PL_IOTREAM_H__ -#define __PL_IOTREAM_H__ - +#pragma once + +#ifndef __PL_IOTREAM_H__ +#define __PL_IOTREAM_H__ + #include "DataTypes.h" -#include "FilePos.h" - -namespace PortabilityLayer -{ - class IOStream - { - public: - virtual size_t Read(void *bytesOut, size_t size) = 0; - virtual size_t Write(const void *bytes, size_t size) = 0; - virtual bool IsSeekable() const = 0; - virtual bool IsReadOnly() const = 0; - virtual bool IsWriteOnly() const = 0; - virtual bool SeekStart(UFilePos_t loc) = 0; - virtual bool SeekCurrent(FilePos_t loc) = 0; - virtual bool SeekEnd(UFilePos_t loc) = 0; - virtual bool Truncate(UFilePos_t loc) = 0; - virtual UFilePos_t Size() const = 0; - virtual UFilePos_t Tell() const = 0; - virtual void Close() = 0; - }; -} - -#endif +#include "FilePos.h" + +namespace PortabilityLayer +{ + class IOStream + { + public: + virtual size_t Read(void *bytesOut, size_t size) = 0; + virtual size_t Write(const void *bytes, size_t size) = 0; + virtual bool IsSeekable() const = 0; + virtual bool IsReadOnly() const = 0; + virtual bool IsWriteOnly() const = 0; + virtual bool SeekStart(UFilePos_t loc) = 0; + virtual bool SeekCurrent(FilePos_t loc) = 0; + virtual bool SeekEnd(UFilePos_t loc) = 0; + virtual bool Truncate(UFilePos_t loc) = 0; + virtual UFilePos_t Size() const = 0; + virtual UFilePos_t Tell() const = 0; + virtual void Close() = 0; + }; +} + +#endif diff --git a/PortabilityLayer/MacLatin1.cpp b/PortabilityLayer/MacLatin1.cpp deleted file mode 100644 index 3b3a6c1..0000000 --- a/PortabilityLayer/MacLatin1.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "MacLatin.h" - -namespace PortabilityLayer -{ - namespace MacLatin - { - const uint16_t g_toUnicode[256] = - { - // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0 - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1 - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2 - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3 - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 4 - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 5 - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, // 6 - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, // 7 - - 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, // 8 - 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, // 9 - 0x00dd, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x00d7, 0x00b6, 0x00df, 0x00ae, 0x00a9, 0x00b2, 0x00b4, 0x00a8, 0x00b3, 0x00c6, 0x00d8, // 10 - 0x00b9, 0x00b1, 0x00bc, 0x00bd, 0x00a5, 0x00b5, 0xffff, 0xffff, 0xffff, 0xffff, 0x00be, 0x00aa, 0x00ba, 0xffff, 0x00e6, 0x00f8, // 11 - 0x00bf, 0x00a1, 0x00ac, 0x0141, 0x0192, 0x02cb, 0xffff, 0x00ab, 0x00bb, 0x00a6, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153, // 12 - 0x00ad, 0xffff, 0xffff, 0xffff, 0x0142, 0xffff, 0x00f7, 0xffff, 0x00ff, 0x0178, 0xffff, 0x00a4, 0x00d0, 0x00f0, 0x00de, 0x00fe, // 13 - 0x00fd, 0x00b7, 0xffff, 0xffff, 0xffff, 0x00c2, 0x00ca, 0x00c1, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, // 14 - 0xffff, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, 0x02c6, 0x02dc, 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7, // 15 - }; - - const uint8_t g_stripDiacritic[256] = - { - // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0 - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1 - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2 - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3 - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 4 - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 5 - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, // 6 - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, // 7 - - 'A', 'A', 'C', 'E', 'N', 'O', 'U', 'a', 'a', 'a', 'a', 'a', 'a', 'c', 'e', 'e', // 8 - 'e', 'e', 'i', 'i', 'i', 'i', 'n', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', // 9 - 'Y', 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 'O', // a - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 'o', // b - 192, 193, 194, 'L', 196, 197, 198, 199, 200, 201, 202, 'A', 'A', 'O', 206, 207, // c - 208, 209, 210, 211, 'l', 213, 214, 215, 'y', 'Y', 218, 219, 220, 221, 222, 223, // d - 224, 225, 226, 227, 228, 'A', 'E', 'A', 'E', 'E', 'I', 'I', 'I', 'I', 'O', 'O', // e - 240, 'O', 'U', 'U', 'U', 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, // f - }; - - const uint8_t g_toUpper[256] = - { - // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0 - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1 - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2 - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3 - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 4 - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 5 - 96, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', // 6 - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 123, 124, 125, 126, 127, // 7 - - 128, 129, 130, 131, 132, 133, 134, 231, 203, 229, 128, 204, 129, 130, 131, 143, // 8 - 230, 232, 234, 237, 235, 236, 132, 238, 241, 239, 133, 205, 242, 244, 243, 134, // 9 - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, // a - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 174, 175, // b - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 206, // c - 208, 209, 210, 211, 195, 213, 214, 215, 217, 217, 218, 219, 220, 220, 222, 222, // d - 160, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, // e - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, // f - }; - - const uint8_t g_toLower[256] = - { - // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0 - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1 - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2 - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3 - 64, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', // 4 - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 91, 92, 93, 94, 95, // 5 - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, // 6 - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, // 7 - - 138, 140, 141, 142, 150, 154, 159, 135, 136, 137, 138, 139, 140, 141, 142, 143, // 8 - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, // 9 - 224, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 190, 191, // a - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, // b - 192, 193, 194, 212, 196, 197, 198, 199, 200, 201, 202, 136, 139, 155, 207, 207, // c - 208, 209, 210, 211, 212, 213, 214, 215, 216, 216, 218, 219, 221, 221, 223, 223, // d - 224, 225, 226, 227, 228, 137, 144, 135, 145, 143, 146, 148, 149, 147, 151, 153, // e - 240, 152, 156, 158, 157, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, // f - }; - } -} diff --git a/PortabilityLayer/MacRoman.cpp b/PortabilityLayer/MacRoman.cpp new file mode 100644 index 0000000..c8e9cf6 --- /dev/null +++ b/PortabilityLayer/MacRoman.cpp @@ -0,0 +1,88 @@ +#include "MacRoman.h" + +// This file is automatically generated by the ImportCharSet tool. DO NOT MODIFY THIS BY HAND. +namespace PortabilityLayer +{ + namespace MacRoman + { + const uint16_t g_toUnicode[256] = + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x2318, 0x21e7, 0x2325, 0x2303, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0xffff, + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, + 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x03a9, 0x00e6, 0x00f8, + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x2206, 0x00ab, 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca, 0x00ff, 0x0178, 0x2044, 0x20ac, 0x2039, 0x203a, 0xfb01, 0xfb02, + 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + 0xf8ff, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, 0x02c6, 0x02dc, 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7, + }; + + const uint8_t g_toUpper[256] = + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0xe7, 0xcb, 0xe5, 0x80, 0xcc, 0x81, 0x82, 0x83, 0xe9, + 0xe6, 0xe8, 0xea, 0xed, 0xeb, 0xec, 0x84, 0xee, 0xf1, 0xef, 0x85, 0xcd, 0xf2, 0xf4, 0xf3, 0x86, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xae, 0xaf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xce, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd9, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + }; + + const uint8_t g_toLower[256] = + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x8a, 0x8c, 0x8d, 0x8e, 0x96, 0x9a, 0x9f, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xbe, 0xbf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0x88, 0x8b, 0x9b, 0xcf, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd8, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0x89, 0x90, 0x87, 0x91, 0x8f, 0x92, 0x94, 0x95, 0x93, 0x97, 0x99, + 0xf0, 0x98, 0x9c, 0x9e, 0x9d, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + }; + + const uint8_t g_stripDiacritic[256] = + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x41, 0x41, 0x43, 0x45, 0x4e, 0x4f, 0x55, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x63, 0x65, 0x65, + 0x65, 0x65, 0x69, 0x69, 0x69, 0x69, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x75, 0x75, 0x75, 0x75, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0x73, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0x41, 0x4f, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0x61, 0x6f, + 0xc0, 0xc1, 0xc2, 0xc3, 0x66, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0x41, 0x41, 0x4f, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x79, 0x59, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0x41, 0x45, 0x41, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4f, 0x4f, + 0xf0, 0x4f, 0x55, 0x55, 0x55, 0x64, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + }; + } +} diff --git a/PortabilityLayer/MacLatin.h b/PortabilityLayer/MacRoman.h similarity index 91% rename from PortabilityLayer/MacLatin.h rename to PortabilityLayer/MacRoman.h index d350511..e0230d9 100644 --- a/PortabilityLayer/MacLatin.h +++ b/PortabilityLayer/MacRoman.h @@ -1,10 +1,10 @@ #pragma once -#include +#include namespace PortabilityLayer { - namespace MacLatin + namespace MacRoman { extern const uint16_t g_toUnicode[256]; extern const uint8_t g_stripDiacritic[256]; diff --git a/PortabilityLayer/MenuManager.cpp b/PortabilityLayer/MenuManager.cpp index 2c4c959..850c875 100644 --- a/PortabilityLayer/MenuManager.cpp +++ b/PortabilityLayer/MenuManager.cpp @@ -10,6 +10,8 @@ struct MenuItem uint8_t key; uint8_t submenuID; uint8_t textStyle; + bool enabled; + bool checked; }; struct Menu @@ -18,7 +20,7 @@ struct Menu uint16_t width; uint16_t height; uint16_t commandID; - uint32_t itemEnabledMask; + bool enabled; PortabilityLayer::MMHandleBlock *stringBlobHandle; @@ -27,7 +29,7 @@ struct Menu size_t numMenuItems; MenuItem menuItems[1]; -}; +}; namespace PortabilityLayer { @@ -43,6 +45,9 @@ namespace PortabilityLayer void InsertMenuAfter(Menu **insertingMenu, Menu **existingMenu) override; void InsertMenuAtEnd(Menu **insertingMenu) override; void InsertMenuAtBeginning(Menu **insertingMenu) override; + void SetMenuEnabled(Menu **menuHandle, bool enabled) override; + void SetItemEnabled(Menu **menu, unsigned int index, bool enabled) override; + void SetItemChecked(Menu **menu, unsigned int index, bool checked) override; static MenuManagerImpl *GetInstance(); @@ -109,18 +114,22 @@ namespace PortabilityLayer return nullptr; } + uint32_t enableFlags = header.enableFlags; + Menu *menu = static_cast(menuData->m_contents); menu->menuID = header.menuID; menu->width = header.width; menu->height = header.height; menu->commandID = header.commandID; - menu->itemEnabledMask = header.enableFlags; + menu->enabled = ((enableFlags & 1) != 0); uint8_t *stringDataStart = static_cast(stringData->m_contents); uint8_t *stringDest = stringDataStart; memcpy(stringDest, resBytes + 14, 1 + resBytes[14]); stringDest += 1 + resBytes[14]; + enableFlags >>= 1; + MenuItem *currentItem = menu->menuItems; for (const uint8_t *menuItemStart = menuDataStart; *menuItemStart; menuItemStart += 5 + (*menuItemStart)) { @@ -132,7 +141,11 @@ namespace PortabilityLayer currentItem->key = menuItemStart[2 + itemNameLength]; currentItem->submenuID = menuItemStart[3 + itemNameLength]; currentItem->textStyle = menuItemStart[4 + itemNameLength]; - currentItem->nameOffsetInStringBlob = stringDest - stringDataStart; + currentItem->nameOffsetInStringBlob = static_cast(stringDest - stringDataStart); + currentItem->enabled = ((enableFlags & 1) != 0); + currentItem->checked = false; + + enableFlags >>= 1; currentItem++; stringDest += 1 + (*menuItemStart); @@ -215,6 +228,33 @@ namespace PortabilityLayer m_firstMenu = insertingMenu; } + void MenuManagerImpl::SetMenuEnabled(Menu **menuHandle, bool enabled) + { + Menu *menu = *menuHandle; + + menu->enabled = enabled; + } + + void MenuManagerImpl::SetItemEnabled(Menu **menuHandle, unsigned int index, bool enabled) + { + Menu *menu = *menuHandle; + + if (index >= menu->numMenuItems) + return; + + menu->menuItems[index].enabled = enabled; + } + + void MenuManagerImpl::SetItemChecked(Menu **menuHandle, unsigned int index, bool checked) + { + Menu *menu = *menuHandle; + + if (index >= menu->numMenuItems) + return; + + menu->menuItems[index].checked = checked; + } + MenuManagerImpl *MenuManagerImpl::GetInstance() { return &ms_instance; diff --git a/PortabilityLayer/MenuManager.h b/PortabilityLayer/MenuManager.h index c870495..c5306fc 100644 --- a/PortabilityLayer/MenuManager.h +++ b/PortabilityLayer/MenuManager.h @@ -13,6 +13,9 @@ namespace PortabilityLayer virtual void InsertMenuAfter(Menu **insertingMenu, Menu **existingMenu) = 0; virtual void InsertMenuAtEnd(Menu **insertingMenu) = 0; virtual void InsertMenuAtBeginning(Menu **insertingMenu) = 0; + virtual void SetMenuEnabled(Menu **menuHandle, bool enabled) = 0; + virtual void SetItemEnabled(Menu **menu, unsigned int index, bool enabled) = 0; + virtual void SetItemChecked(Menu **menu, unsigned int index, bool checked) = 0; static MenuManager *GetInstance(); }; diff --git a/PortabilityLayer/PLMenus.cpp b/PortabilityLayer/PLMenus.cpp index 20ad895..0300aa1 100644 --- a/PortabilityLayer/PLMenus.cpp +++ b/PortabilityLayer/PLMenus.cpp @@ -59,25 +59,34 @@ void DrawMenuBar() void HiliteMenu(int menu) { - PL_NotYetImplemented_TODO("Menus"); + PL_NotYetImplemented(); } void EnableMenuItem(MenuHandle menu, int index) { - PL_NotYetImplemented_TODO("Menus"); + PortabilityLayer::MenuManager *mm = PortabilityLayer::MenuManager::GetInstance(); + if (index == 0) + mm->SetMenuEnabled(menu, true); + else + mm->SetItemEnabled(menu, index - 1, true); } void DisableMenuItem(MenuHandle menu, int index) { - PL_NotYetImplemented_TODO("Menus"); + PortabilityLayer::MenuManager *mm = PortabilityLayer::MenuManager::GetInstance(); + if (index == 0) + mm->SetMenuEnabled(menu, false); + else + mm->SetItemEnabled(menu, index - 1, false); } void CheckMenuItem(MenuHandle menu, int index, Boolean checked) { - PL_NotYetImplemented_TODO("Menus"); + PortabilityLayer::MenuManager *mm = PortabilityLayer::MenuManager::GetInstance(); + mm->SetItemChecked(menu, index - 1, checked != 0); } void SetMenuItemText(MenuHandle menu, int index, const PLPasStr &text) { - PL_NotYetImplemented_TODO("Menus"); + PL_NotYetImplemented(); } diff --git a/PortabilityLayer/PLQDOffscreen.cpp b/PortabilityLayer/PLQDOffscreen.cpp index 678885e..4399243 100644 --- a/PortabilityLayer/PLQDOffscreen.cpp +++ b/PortabilityLayer/PLQDOffscreen.cpp @@ -129,7 +129,7 @@ namespace PortabilityLayer void *imageData = m_pixMap->GetPixelData(); - if (m_pixMap->GetPixelFormat() == PixelFormat_8BitStandard) + if (m_pixMap->GetPixelFormat() == GpPixelFormats::k8BitStandard) { switch (m_blitType) { @@ -301,7 +301,7 @@ void DrawPicture(PicHandle pict, Rect *bounds) switch (pixMap->GetPixelFormat()) { - case PortabilityLayer::PixelFormat_8BitStandard: + case GpPixelFormats::k8BitStandard: { PortabilityLayer::PixMapBlitEmitter blitEmitter(PortabilityLayer::Vec2i(bounds->left, bounds->top), pixMap); PortabilityLayer::QDPictDecoder decoder; diff --git a/PortabilityLayer/PLQuickdraw.cpp b/PortabilityLayer/PLQuickdraw.cpp index 9f77d99..28c23bc 100644 --- a/PortabilityLayer/PLQuickdraw.cpp +++ b/PortabilityLayer/PLQuickdraw.cpp @@ -2,8 +2,14 @@ #include "QDManager.h" #include "QDState.h" #include "DisplayDeviceManager.h" +#include "FontFamily.h" +#include "FontManager.h" #include "MMHandleBlock.h" #include "MemoryManager.h" +#include "HostFontHandler.h" +#include "PLPasStr.h" +#include "RenderedFont.h" +#include "RenderedGlyphMetrics.h" #include "ResourceManager.h" #include "ResTypeID.h" #include "RGBAColor.h" @@ -13,6 +19,7 @@ #include "QDPixMap.h" #include "QDUtils.h" +#include #include void GetPort(GrafPtr *graf) @@ -213,8 +220,8 @@ void Index2Color(int index, RGBColor *color) PortabilityLayer::QDManager::GetInstance()->GetPort(&port, nullptr); - PortabilityLayer::PixelFormat pf = port->GetPixelFormat(); - if (pf == PortabilityLayer::PixelFormat_8BitCustom) + GpPixelFormat_t pf = port->GetPixelFormat(); + if (pf == GpPixelFormats::k8BitCustom) { PL_NotYetImplemented(); } @@ -238,9 +245,127 @@ void RGBForeColor(const RGBColor *color) PortabilityLayer::QDManager::GetInstance()->GetState()->SetForeColor(truncatedColor); } +static void DrawGlyph(PortabilityLayer::QDState *qdState, PixMap *pixMap, const Rect &rect, Point &penPos, const PortabilityLayer::RenderedFont *rfont, unsigned int character) +{ + assert(rect.IsValid()); + + const PortabilityLayer::RenderedGlyphMetrics *metrics; + const void *data; + if (!rfont->GetGlyph(character, &metrics, &data)) + return; + + const Point originalPoint = penPos; + + penPos.h += metrics->m_advanceX; + + const int32_t leftCoord = originalPoint.h + metrics->m_bearingX; + const int32_t topCoord = originalPoint.v - metrics->m_bearingY; + const int32_t rightCoord = leftCoord + metrics->m_glyphWidth; + const int32_t bottomCoord = topCoord + metrics->m_glyphHeight; + + const int32_t clampedLeftCoord = std::max(leftCoord, rect.left); + const int32_t clampedTopCoord = std::max(topCoord, rect.top); + const int32_t clampedRightCoord = std::min(rightCoord, rect.right); + const int32_t clampedBottomCoord = std::min(bottomCoord, rect.bottom); + + if (clampedLeftCoord >= clampedRightCoord || clampedTopCoord >= clampedBottomCoord) + return; + + const uint32_t firstOutputRow = clampedTopCoord - rect.top; + const uint32_t firstOutputCol = clampedLeftCoord - rect.left; + + const uint32_t firstInputRow = clampedTopCoord - topCoord; + const uint32_t firstInputCol = clampedLeftCoord - leftCoord; + + const uint32_t numCols = clampedRightCoord - clampedLeftCoord; + const uint32_t numRows = clampedBottomCoord - clampedTopCoord; + + const size_t inputPitch = metrics->m_glyphDataPitch; + const size_t outputPitch = pixMap->m_pitch; + const uint8_t *firstInputRowData = static_cast(data) + firstInputRow * inputPitch; + + switch (pixMap->m_pixelFormat) + { + case GpPixelFormats::k8BitStandard: + { + uint8_t *firstOutputRowData = static_cast(pixMap->m_data) + firstOutputRow * outputPitch; + + const uint8_t color = qdState->ResolveForeColor8(nullptr, 0); + for (uint32_t row = 0; row < numRows; row++) + { + const uint8_t *inputRowData = firstInputRowData + row * inputPitch; + uint8_t *outputRowData = firstOutputRowData + row * outputPitch; + + // It should be possible to speed this up, if needed. The input is guaranteed to be well-aligned and not mutable within this loop. + for (uint32_t col = 0; col < numCols; col++) + { + const size_t inputOffset = firstInputCol + col; + if (inputRowData[inputOffset / 8] & (1 << (inputOffset & 0x7))) + outputRowData[firstOutputCol + col] = color; + } + } + } + break; + default: + PL_NotYetImplemented(); + } +} + void DrawString(const PLPasStr &str) { - PL_NotYetImplemented_TODO("Text"); + PortabilityLayer::QDManager *qdManager = PortabilityLayer::QDManager::GetInstance(); + + PortabilityLayer::QDPort *port = nullptr; + qdManager->GetPort(&port, nullptr); + + PortabilityLayer::QDState *qdState = qdManager->GetState(); + + PortabilityLayer::FontManager *fontManager = PortabilityLayer::FontManager::GetInstance(); + + const int textSize = qdState->m_textSize; + const int textFace = qdState->m_textFace; + const int fontID = qdState->m_fontID; + + int variationFlags = 0; + if (textFace & bold) + variationFlags |= PortabilityLayer::FontFamilyFlag_Bold; + + const PortabilityLayer::FontFamily *fontFamily = nullptr; + + switch (fontID) + { + case applFont: + fontFamily = fontManager->GetApplicationFont(textSize, variationFlags); + break; + case systemFont: + fontFamily = fontManager->GetSystemFont(textSize, variationFlags); + break; + default: + PL_NotYetImplemented(); + return; + } + + const int realVariation = fontFamily->GetVariationForFlags(variationFlags); + PortabilityLayer::HostFont *font = fontFamily->GetFontForVariation(realVariation); + + if (!font) + return; + + PortabilityLayer::RenderedFont *rfont = fontManager->GetRenderedFont(font, textSize, fontFamily->GetHacksForVariation(realVariation)); + + Point penPos = qdState->m_penPos; + const size_t len = str.Length(); + const uint8_t *chars = str.UChars(); + + PixMap *pixMap = *port->GetPixMap(); + + const Rect rect = pixMap->m_rect; + + if (!rect.IsValid()) + return; // ??? + + for (size_t i = 0; i < len; i++) + DrawGlyph(qdState, pixMap, rect, penPos, rfont, chars[i]); } void PaintRect(const Rect *rect) @@ -251,7 +376,7 @@ void PaintRect(const Rect *rect) PortabilityLayer::QDPort *qdPort; PortabilityLayer::QDManager::GetInstance()->GetPort(&qdPort, nullptr); - PortabilityLayer::PixelFormat pixelFormat = qdPort->GetPixelFormat(); + GpPixelFormat_t pixelFormat = qdPort->GetPixelFormat(); Rect constrainedRect = *rect; @@ -281,7 +406,7 @@ void PaintRect(const Rect *rect) switch (pixelFormat) { - case PortabilityLayer::PixelFormat_8BitStandard: + case GpPixelFormats::k8BitStandard: { const uint8_t color = qdState->ResolveForeColor8(nullptr, 0); @@ -417,7 +542,7 @@ void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect &srcBounds = srcBitmap->m_rect; const Rect &destBounds = destBitmap->m_rect; - const PortabilityLayer::PixelFormat pixelFormat = srcBitmap->m_pixelFormat; + const GpPixelFormat_t pixelFormat = srcBitmap->m_pixelFormat; const size_t srcPitch = srcBitmap->m_pitch; const size_t destPitch = destBitmap->m_pitch; @@ -462,17 +587,17 @@ void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRect, switch (pixelFormat) { - case PortabilityLayer::PixelFormat_8BitCustom: - case PortabilityLayer::PixelFormat_8BitStandard: + case GpPixelFormats::k8BitCustom: + case GpPixelFormats::k8BitStandard: pixelSizeBytes = 1; break; - case PortabilityLayer::PixelFormat_RGB555: + case GpPixelFormats::kRGB555: pixelSizeBytes = 2; break; - case PortabilityLayer::PixelFormat_RGB24: + case GpPixelFormats::kRGB24: pixelSizeBytes = 3; break; - case PortabilityLayer::PixelFormat_RGB32: + case GpPixelFormats::kRGB32: pixelSizeBytes = 4; break; }; @@ -628,7 +753,7 @@ RgnHandle GetGrayRgn() return nullptr; } -void BitMap::Init(const Rect &rect, PortabilityLayer::PixelFormat pixelFormat, size_t pitch, void *dataPtr) +void BitMap::Init(const Rect &rect, GpPixelFormat_t pixelFormat, size_t pitch, void *dataPtr) { m_rect = rect; m_pixelFormat = pixelFormat; diff --git a/PortabilityLayer/PLQuickdraw.h b/PortabilityLayer/PLQuickdraw.h index 491b3ad..2ae2bc1 100644 --- a/PortabilityLayer/PLQuickdraw.h +++ b/PortabilityLayer/PLQuickdraw.h @@ -26,33 +26,12 @@ enum IconSuiteFlags enum TextFlags { bold = 1, - italicBit = 2, - ulineBit = 4, - outlineBit = 8, - shadowBit = 16, - condenseBit = 32, - extendBit = 64, }; enum SystemFontID { systemFont = 0, // System font applFont = 1, // Application font - newYork = 2, - geneva = 3, - monaco = 4, - venice = 5, - london = 6, - athens = 7, - sanFran = 8, - toronto = 9, - cairo = 11, - losAngeles = 12, - times = 20, - helvetica = 21, - courier = 22, - symbol = 23, - mobile = 24, }; enum SystemColorID @@ -88,11 +67,11 @@ struct CIcon struct BitMap { Rect m_rect; - PortabilityLayer::PixelFormat m_pixelFormat; + GpPixelFormat_t m_pixelFormat; size_t m_pitch; void *m_data; - void Init(const Rect &rect, PortabilityLayer::PixelFormat pixelFormat, size_t pitch, void *dataPtr); + void Init(const Rect &rect, GpPixelFormat_t pixelFormat, size_t pitch, void *dataPtr); }; struct RGBColor diff --git a/PortabilityLayer/PLStringCompare.cpp b/PortabilityLayer/PLStringCompare.cpp index 6b9614a..67a5787 100644 --- a/PortabilityLayer/PLStringCompare.cpp +++ b/PortabilityLayer/PLStringCompare.cpp @@ -1,9 +1,9 @@ #include "PLStringCompare.h" -#include "MacLatin.h" +#include "MacRoman.h" #include - -Boolean EqualString(const PLPasStr &string1, const PLPasStr &string2, Boolean caseSensitive, Boolean diacriticSensitive) + +Boolean EqualString(const PLPasStr &string1, const PLPasStr &string2, Boolean caseSensitive, Boolean diacriticSensitive) { const size_t len = string1.Length(); if (len != string2.Length()) @@ -16,55 +16,55 @@ Boolean EqualString(const PLPasStr &string1, const PLPasStr &string2, Boolean ca { // Case sensitive if (diacriticSensitive) - { + { // Diacritic sensitive - return memcmp(chars1, chars2, len) ? PL_FALSE : PL_TRUE; + return memcmp(chars1, chars2, len) ? PL_FALSE : PL_TRUE; } else - { + { // Diacritic insensitive for (size_t i = 0; i < len; i++) { const uint8_t c1 = chars1[i]; const uint8_t c2 = chars2[i]; - - if (PortabilityLayer::MacLatin::g_stripDiacritic[c1] != PortabilityLayer::MacLatin::g_stripDiacritic[c2]) - return PL_FALSE; + + if (PortabilityLayer::MacRoman::g_stripDiacritic[c1] != PortabilityLayer::MacRoman::g_stripDiacritic[c2]) + return PL_FALSE; } - return PL_TRUE; - } + return PL_TRUE; + } } else - { + { // Case insensitive if (diacriticSensitive) - { + { // Diacritic sensitive for (size_t i = 0; i < len; i++) { const uint8_t c1 = chars1[i]; const uint8_t c2 = chars2[i]; - - if (PortabilityLayer::MacLatin::g_toLower[c1] != PortabilityLayer::MacLatin::g_toLower[c2]) - return PL_FALSE; + + if (PortabilityLayer::MacRoman::g_toLower[c1] != PortabilityLayer::MacRoman::g_toLower[c2]) + return PL_FALSE; } - return PL_TRUE; + return PL_TRUE; } else - { + { // Diacritic insensitive for (size_t i = 0; i < len; i++) { - const uint8_t c1 = PortabilityLayer::MacLatin::g_stripDiacritic[chars1[i]]; - const uint8_t c2 = PortabilityLayer::MacLatin::g_stripDiacritic[chars2[i]]; - - if (PortabilityLayer::MacLatin::g_toLower[c1] != PortabilityLayer::MacLatin::g_toLower[c2]) - return PL_FALSE; + const uint8_t c1 = PortabilityLayer::MacRoman::g_stripDiacritic[chars1[i]]; + const uint8_t c2 = PortabilityLayer::MacRoman::g_stripDiacritic[chars2[i]]; + + if (PortabilityLayer::MacRoman::g_toLower[c1] != PortabilityLayer::MacRoman::g_toLower[c2]) + return PL_FALSE; } - return PL_TRUE; - } - } + return PL_TRUE; + } + } } diff --git a/PortabilityLayer/PixelFormat.h b/PortabilityLayer/PixelFormat.h deleted file mode 100644 index 1869ebb..0000000 --- a/PortabilityLayer/PixelFormat.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -namespace PortabilityLayer -{ - enum PixelFormat - { - PixelFormat_Invalid, - - PixelFormat_8BitStandard, - PixelFormat_8BitCustom, - PixelFormat_RGB555, - PixelFormat_RGB24, - PixelFormat_RGB32, - }; -} diff --git a/PortabilityLayer/PortabilityLayer.vcxproj b/PortabilityLayer/PortabilityLayer.vcxproj index 54fb6bd..6834ed0 100644 --- a/PortabilityLayer/PortabilityLayer.vcxproj +++ b/PortabilityLayer/PortabilityLayer.vcxproj @@ -137,13 +137,16 @@ + + + @@ -159,7 +162,7 @@ - + @@ -201,6 +204,7 @@ + @@ -242,7 +246,9 @@ + + @@ -254,7 +260,7 @@ - + diff --git a/PortabilityLayer/PortabilityLayer.vcxproj.filters b/PortabilityLayer/PortabilityLayer.vcxproj.filters index 066bdc9..e7b73d7 100644 --- a/PortabilityLayer/PortabilityLayer.vcxproj.filters +++ b/PortabilityLayer/PortabilityLayer.vcxproj.filters @@ -318,9 +318,6 @@ Header Files - - Header Files - Header Files @@ -348,6 +345,21 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + @@ -500,9 +512,6 @@ Source Files - - Source Files - Source Files @@ -521,5 +530,14 @@ Source Files + + Source Files + + + Source Files + + + Source Files + \ No newline at end of file diff --git a/PortabilityLayer/QDGraf.h b/PortabilityLayer/QDGraf.h index 645ac3a..d9e8672 100644 --- a/PortabilityLayer/QDGraf.h +++ b/PortabilityLayer/QDGraf.h @@ -2,7 +2,7 @@ #include -#include "PixelFormat.h" +#include "GpPixelFormat.h" #include "QDState.h" #include "QDPort.h" @@ -24,7 +24,7 @@ struct CGraf { } - int Init(const Rect &rect, PortabilityLayer::PixelFormat pixelFormat) + int Init(const Rect &rect, GpPixelFormat_t pixelFormat) { if (int errorCode = m_port.Init(rect, pixelFormat)) return errorCode; diff --git a/PortabilityLayer/QDManager.cpp b/PortabilityLayer/QDManager.cpp index 61073c7..c6c64b2 100644 --- a/PortabilityLayer/QDManager.cpp +++ b/PortabilityLayer/QDManager.cpp @@ -54,18 +54,18 @@ namespace PortabilityLayer int QDManagerImpl::NewGWorld(CGraf **gw, int depth, const Rect &bounds, ColorTable **colorTable, GDevice **device, int flags) { - PixelFormat pixelFormat; + GpPixelFormat_t pixelFormat; switch (depth) { case 8: - pixelFormat = (colorTable == nullptr) ? PixelFormat_8BitStandard : PixelFormat_8BitCustom; + pixelFormat = (colorTable == nullptr) ? GpPixelFormats::k8BitStandard : GpPixelFormats::k8BitCustom; break; case 16: - pixelFormat = PixelFormat_RGB555; + pixelFormat = GpPixelFormats::kRGB555; break; case 32: - pixelFormat = PixelFormat_RGB32; + pixelFormat = GpPixelFormats::kRGB32; break; default: return genericErr; diff --git a/PortabilityLayer/QDPixMap.cpp b/PortabilityLayer/QDPixMap.cpp index d873a84..2ff3ab2 100644 --- a/PortabilityLayer/QDPixMap.cpp +++ b/PortabilityLayer/QDPixMap.cpp @@ -5,7 +5,7 @@ namespace PortabilityLayer { - PixMapImpl::PixMapImpl(int16_t left, int16_t top, uint16_t width, uint16_t height, PixelFormat pixelFormat) + PixMapImpl::PixMapImpl(int16_t left, int16_t top, uint16_t width, uint16_t height, GpPixelFormat_t pixelFormat) : m_left(left) , m_top(top) , m_width(width) @@ -22,7 +22,7 @@ namespace PortabilityLayer static_cast(this)->Init(rect, pixelFormat, PitchForWidth(width, pixelFormat), dataPtr); } - size_t PixMapImpl::SizeForDimensions(uint16_t width, uint16_t height, PixelFormat pixelFormat) + size_t PixMapImpl::SizeForDimensions(uint16_t width, uint16_t height, GpPixelFormat_t pixelFormat) { return AlignedSize() + PitchForWidth(width, pixelFormat) * height; } @@ -35,23 +35,23 @@ namespace PortabilityLayer return szAdjusted; } - size_t PixMapImpl::PitchForWidth(uint16_t width, PixelFormat pixelFormat) + size_t PixMapImpl::PitchForWidth(uint16_t width, GpPixelFormat_t pixelFormat) { size_t rowByteCount = 0; switch (pixelFormat) { - case PixelFormat_8BitCustom: - case PixelFormat_8BitStandard: + case GpPixelFormats::k8BitCustom: + case GpPixelFormats::k8BitStandard: rowByteCount = width; break; - case PixelFormat_RGB555: + case GpPixelFormats::kRGB555: rowByteCount = width * 2; break; - case PixelFormat_RGB24: + case GpPixelFormats::kRGB24: rowByteCount = width * 3; break; - case PixelFormat_RGB32: + case GpPixelFormats::kRGB32: rowByteCount = width * 4; break; default: @@ -65,7 +65,7 @@ namespace PortabilityLayer } } -void PixMap::Init(const Rect &rect, PortabilityLayer::PixelFormat pixelFormat, size_t pitch, void *dataPtr) +void PixMap::Init(const Rect &rect, GpPixelFormat_t pixelFormat, size_t pitch, void *dataPtr) { BitMap::Init(rect, pixelFormat, pitch, dataPtr); } diff --git a/PortabilityLayer/QDPixMap.h b/PortabilityLayer/QDPixMap.h index c1e20c5..b4efd15 100644 --- a/PortabilityLayer/QDPixMap.h +++ b/PortabilityLayer/QDPixMap.h @@ -1,65 +1,65 @@ -#pragma once - -#include "PLBigEndian.h" -#include "PLQuickdraw.h" -#include "PixelFormat.h" - -#include - -struct PixMap : public BitMap -{ - void Init(const Rect &rect, PortabilityLayer::PixelFormat pixelFormat, size_t pitch, void *dataPtr); -}; - -namespace PortabilityLayer -{ - class PixMapImpl final : public PixMap - { - public: - PixMapImpl(int16_t left, int16_t top, uint16_t width, uint16_t height, PixelFormat pixelFormat); - - PixelFormat GetPixelFormat() const; - size_t GetPitch() const; - void *GetPixelData(); - const void *GetPixelData() const; - size_t GetDataCapacity() const; - - static size_t SizeForDimensions(uint16_t width, uint16_t height, PixelFormat pixelFormat); - - private: - static size_t AlignedSize(); - static size_t PitchForWidth(uint16_t width, PixelFormat pixelFormat); - - int16_t m_left; - int16_t m_top; - uint16_t m_width; - uint16_t m_height; +#pragma once - size_t m_dataCapacity; - }; -} - -inline PortabilityLayer::PixelFormat PortabilityLayer::PixMapImpl::GetPixelFormat() const -{ - return m_pixelFormat; -} - -inline size_t PortabilityLayer::PixMapImpl::GetPitch() const -{ - return m_pitch; -} - -inline void *PortabilityLayer::PixMapImpl::GetPixelData() -{ - return m_data; -} - -inline const void *PortabilityLayer::PixMapImpl::GetPixelData() const -{ - return m_data; +#include "PLBigEndian.h" +#include "PLQuickdraw.h" +#include "GpPixelFormat.h" + +#include + +struct PixMap : public BitMap +{ + void Init(const Rect &rect, GpPixelFormat_t pixelFormat, size_t pitch, void *dataPtr); +}; + +namespace PortabilityLayer +{ + class PixMapImpl final : public PixMap + { + public: + PixMapImpl(int16_t left, int16_t top, uint16_t width, uint16_t height, GpPixelFormat_t pixelFormat); + + GpPixelFormat_t GetPixelFormat() const; + size_t GetPitch() const; + void *GetPixelData(); + const void *GetPixelData() const; + size_t GetDataCapacity() const; + + static size_t SizeForDimensions(uint16_t width, uint16_t height, GpPixelFormat_t pixelFormat); + + private: + static size_t AlignedSize(); + static size_t PitchForWidth(uint16_t width, GpPixelFormat_t pixelFormat); + + int16_t m_left; + int16_t m_top; + uint16_t m_width; + uint16_t m_height; + + size_t m_dataCapacity; + }; } - + +inline GpPixelFormat_t PortabilityLayer::PixMapImpl::GetPixelFormat() const +{ + return m_pixelFormat; +} + +inline size_t PortabilityLayer::PixMapImpl::GetPitch() const +{ + return m_pitch; +} + +inline void *PortabilityLayer::PixMapImpl::GetPixelData() +{ + return m_data; +} + +inline const void *PortabilityLayer::PixMapImpl::GetPixelData() const +{ + return m_data; +} + inline size_t PortabilityLayer::PixMapImpl::GetDataCapacity() const -{ - return m_dataCapacity; -} +{ + return m_dataCapacity; +} diff --git a/PortabilityLayer/QDPort.cpp b/PortabilityLayer/QDPort.cpp index 2b260a3..e18463d 100644 --- a/PortabilityLayer/QDPort.cpp +++ b/PortabilityLayer/QDPort.cpp @@ -13,7 +13,7 @@ namespace PortabilityLayer , m_width(0) , m_height(0) , m_pixMap(nullptr) - , m_pixelFormat(PixelFormat_Invalid) + , m_pixelFormat(GpPixelFormats::kInvalid) , m_dirtyFlags(0) { } @@ -33,7 +33,7 @@ namespace PortabilityLayer } } - int QDPort::Init(const Rect &rect, PixelFormat pixelFormat) + int QDPort::Init(const Rect &rect, GpPixelFormat_t pixelFormat) { m_pixMap = nullptr; m_pixelFormat = pixelFormat; @@ -57,6 +57,8 @@ namespace PortabilityLayer if (!pmBlock) return false; + memset(pmBlock->m_contents, 0, pixMapSize); + SetDirty(QDPortDirtyFlag_Size | QDPortDirtyFlag_Contents); m_left = rect.left; @@ -103,7 +105,7 @@ namespace PortabilityLayer return &m_state; } - PixelFormat QDPort::GetPixelFormat() const + GpPixelFormat_t QDPort::GetPixelFormat() const { return m_pixelFormat; } diff --git a/PortabilityLayer/QDPort.h b/PortabilityLayer/QDPort.h index 9e06025..f39c137 100644 --- a/PortabilityLayer/QDPort.h +++ b/PortabilityLayer/QDPort.h @@ -1,11 +1,11 @@ #pragma once #include -#include "PixelFormat.h" +#include "GpPixelFormat.h" #include "QDState.h" struct PixMap; -struct Rect; +struct Rect; namespace PortabilityLayer { @@ -14,28 +14,28 @@ namespace PortabilityLayer QDPortType_Invalid, QDPortType_CGraf, - QDPortType_Window, + QDPortType_Window, }; enum QDPortDirtyFlag - { + { QDPortDirtyFlag_Size = 1, QDPortDirtyFlag_Contents = 2, - }; + }; class QDPort { public: explicit QDPort(QDPortType portType); - ~QDPort(); + ~QDPort(); - int Init(const Rect &rect, PixelFormat pixelFormat); + int Init(const Rect &rect, GpPixelFormat_t pixelFormat); QDPortType GetPortType() const; - + PixMap **GetPixMap() const; const QDState *GetState() const; QDState *GetState(); - PixelFormat GetPixelFormat() const; + GpPixelFormat_t GetPixelFormat() const; Rect GetRect() const; bool Resize(const Rect &rect); @@ -47,17 +47,17 @@ namespace PortabilityLayer private: void DisposePixMap(); - QDPortType m_portType; + QDPortType m_portType; - QDState m_state; - PixMap **m_pixMap; - - int16_t m_left; - int16_t m_top; - uint16_t m_width; - uint16_t m_height; + QDState m_state; + PixMap **m_pixMap; + + int16_t m_left; + int16_t m_top; + uint16_t m_width; + uint16_t m_height; uint32_t m_dirtyFlags; - PixelFormat m_pixelFormat; + GpPixelFormat_t m_pixelFormat; }; inline QDPortType QDPort::GetPortType() const diff --git a/PortabilityLayer/RenderedFont.h b/PortabilityLayer/RenderedFont.h new file mode 100644 index 0000000..a742a8a --- /dev/null +++ b/PortabilityLayer/RenderedFont.h @@ -0,0 +1,14 @@ +#pragma once + +namespace PortabilityLayer +{ + struct RenderedGlyphMetrics; + + class RenderedFont + { + public: + virtual bool GetGlyph(unsigned int character, const RenderedGlyphMetrics **outMetricsPtr, const void **outData) const = 0; + + virtual void Destroy() = 0; + }; +} diff --git a/PortabilityLayer/RenderedGlyphMetrics.h b/PortabilityLayer/RenderedGlyphMetrics.h new file mode 100644 index 0000000..dac0a69 --- /dev/null +++ b/PortabilityLayer/RenderedGlyphMetrics.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace PortabilityLayer +{ + struct RenderedGlyphMetrics + { + size_t m_glyphDataPitch; + + uint32_t m_glyphWidth; + uint32_t m_glyphHeight; + + int16_t m_bearingX; + int16_t m_bearingY; + int16_t m_advanceX; + }; +} diff --git a/PortabilityLayer/SharedTypes.h b/PortabilityLayer/SharedTypes.h index a7f0294..a1c1f4b 100644 --- a/PortabilityLayer/SharedTypes.h +++ b/PortabilityLayer/SharedTypes.h @@ -1,8 +1,8 @@ #pragma once #include "CoreDefs.h" +#include "GpPixelFormat.h" #include "PLBigEndian.h" -#include "PixelFormat.h" #include "RGBAColor.h" struct Point @@ -93,7 +93,7 @@ struct BEColorTableItem struct GDevice { - PortabilityLayer::PixelFormat pixelFormat; + GpPixelFormat_t pixelFormat; uint8_t paletteStorage[256 * 4 + PL_SYSTEM_MEMORY_ALIGNMENT]; uint8_t paletteDataOffset; diff --git a/Resources/Fonts/Roboto/LICENSE b/Resources/Fonts/Roboto/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/Resources/Fonts/Roboto/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Resources/Fonts/Roboto/Roboto-Black.ttf b/Resources/Fonts/Roboto/Roboto-Black.ttf new file mode 100644 index 0000000..3ecbdef Binary files /dev/null and b/Resources/Fonts/Roboto/Roboto-Black.ttf differ diff --git a/Resources/Fonts/Roboto/Roboto-BlackItalic.ttf b/Resources/Fonts/Roboto/Roboto-BlackItalic.ttf new file mode 100644 index 0000000..44c086c Binary files /dev/null and b/Resources/Fonts/Roboto/Roboto-BlackItalic.ttf differ diff --git a/Resources/Fonts/Roboto/Roboto-Bold.ttf b/Resources/Fonts/Roboto/Roboto-Bold.ttf new file mode 100644 index 0000000..70def3f Binary files /dev/null and b/Resources/Fonts/Roboto/Roboto-Bold.ttf differ diff --git a/Resources/Fonts/Roboto/Roboto-BoldItalic.ttf b/Resources/Fonts/Roboto/Roboto-BoldItalic.ttf new file mode 100644 index 0000000..216f9ce Binary files /dev/null and b/Resources/Fonts/Roboto/Roboto-BoldItalic.ttf differ diff --git a/Resources/Fonts/Roboto/Roboto-Italic.ttf b/Resources/Fonts/Roboto/Roboto-Italic.ttf new file mode 100644 index 0000000..f0f33db Binary files /dev/null and b/Resources/Fonts/Roboto/Roboto-Italic.ttf differ diff --git a/Resources/Fonts/Roboto/Roboto-Light.ttf b/Resources/Fonts/Roboto/Roboto-Light.ttf new file mode 100644 index 0000000..3a03044 Binary files /dev/null and b/Resources/Fonts/Roboto/Roboto-Light.ttf differ diff --git a/Resources/Fonts/Roboto/Roboto-LightItalic.ttf b/Resources/Fonts/Roboto/Roboto-LightItalic.ttf new file mode 100644 index 0000000..983381b Binary files /dev/null and b/Resources/Fonts/Roboto/Roboto-LightItalic.ttf differ diff --git a/Resources/Fonts/Roboto/Roboto-Medium.ttf b/Resources/Fonts/Roboto/Roboto-Medium.ttf new file mode 100644 index 0000000..284b1ba Binary files /dev/null and b/Resources/Fonts/Roboto/Roboto-Medium.ttf differ diff --git a/Resources/Fonts/Roboto/Roboto-MediumItalic.ttf b/Resources/Fonts/Roboto/Roboto-MediumItalic.ttf new file mode 100644 index 0000000..a0b10d2 Binary files /dev/null and b/Resources/Fonts/Roboto/Roboto-MediumItalic.ttf differ diff --git a/Resources/Fonts/Roboto/Roboto-Regular.ttf b/Resources/Fonts/Roboto/Roboto-Regular.ttf new file mode 100644 index 0000000..500b104 Binary files /dev/null and b/Resources/Fonts/Roboto/Roboto-Regular.ttf differ diff --git a/Resources/Fonts/Roboto/Roboto-Thin.ttf b/Resources/Fonts/Roboto/Roboto-Thin.ttf new file mode 100644 index 0000000..0c7d50b Binary files /dev/null and b/Resources/Fonts/Roboto/Roboto-Thin.ttf differ diff --git a/Resources/Fonts/Roboto/Roboto-ThinItalic.ttf b/Resources/Fonts/Roboto/Roboto-ThinItalic.ttf new file mode 100644 index 0000000..277d8cf Binary files /dev/null and b/Resources/Fonts/Roboto/Roboto-ThinItalic.ttf differ diff --git a/Resources/Fonts/Roboto/RobotoCondensed-Bold.ttf b/Resources/Fonts/Roboto/RobotoCondensed-Bold.ttf new file mode 100644 index 0000000..f1de58f Binary files /dev/null and b/Resources/Fonts/Roboto/RobotoCondensed-Bold.ttf differ diff --git a/Resources/Fonts/Roboto/RobotoCondensed-BoldItalic.ttf b/Resources/Fonts/Roboto/RobotoCondensed-BoldItalic.ttf new file mode 100644 index 0000000..dc0ae5d Binary files /dev/null and b/Resources/Fonts/Roboto/RobotoCondensed-BoldItalic.ttf differ diff --git a/Resources/Fonts/Roboto/RobotoCondensed-Italic.ttf b/Resources/Fonts/Roboto/RobotoCondensed-Italic.ttf new file mode 100644 index 0000000..7f075cf Binary files /dev/null and b/Resources/Fonts/Roboto/RobotoCondensed-Italic.ttf differ diff --git a/Resources/Fonts/Roboto/RobotoCondensed-Light.ttf b/Resources/Fonts/Roboto/RobotoCondensed-Light.ttf new file mode 100644 index 0000000..2c514ba Binary files /dev/null and b/Resources/Fonts/Roboto/RobotoCondensed-Light.ttf differ diff --git a/Resources/Fonts/Roboto/RobotoCondensed-LightItalic.ttf b/Resources/Fonts/Roboto/RobotoCondensed-LightItalic.ttf new file mode 100644 index 0000000..248ffe8 Binary files /dev/null and b/Resources/Fonts/Roboto/RobotoCondensed-LightItalic.ttf differ diff --git a/Resources/Fonts/Roboto/RobotoCondensed-Medium.ttf b/Resources/Fonts/Roboto/RobotoCondensed-Medium.ttf new file mode 100644 index 0000000..b3393ed Binary files /dev/null and b/Resources/Fonts/Roboto/RobotoCondensed-Medium.ttf differ diff --git a/Resources/Fonts/Roboto/RobotoCondensed-MediumItalic.ttf b/Resources/Fonts/Roboto/RobotoCondensed-MediumItalic.ttf new file mode 100644 index 0000000..a8fd4f7 Binary files /dev/null and b/Resources/Fonts/Roboto/RobotoCondensed-MediumItalic.ttf differ diff --git a/Resources/Fonts/Roboto/RobotoCondensed-Regular.ttf b/Resources/Fonts/Roboto/RobotoCondensed-Regular.ttf new file mode 100644 index 0000000..5ae7043 Binary files /dev/null and b/Resources/Fonts/Roboto/RobotoCondensed-Regular.ttf differ diff --git a/Resources/virtue.ttf b/Resources/Fonts/Virtue/virtue.ttf similarity index 100% rename from Resources/virtue.ttf rename to Resources/Fonts/Virtue/virtue.ttf