Add Inter font, map Chicago system symbol reservations using it, use Command symbol on macOS

This commit is contained in:
elasota
2021-08-01 22:24:41 -04:00
parent f9109850a6
commit c04aeeb962
26 changed files with 389 additions and 101 deletions

View File

@@ -0,0 +1,64 @@
#include "CompositeRenderedFont.h"
#include "GpRenderedFontMetrics.h"
#include "GpRenderedGlyphMetrics.h"
#include <assert.h>
PortabilityLayer::CompositeRenderedFont::CompositeRenderedFont(RenderedFont *rfont, RenderedFont *fallbackFont)
: m_font(rfont)
, m_fallbackFont(fallbackFont)
, m_metrics(rfont->GetMetrics())
{
assert(rfont->IsAntiAliased() == fallbackFont->IsAntiAliased());
const GpRenderedFontMetrics fallbackMetrics = fallbackFont->GetMetrics();
if (fallbackMetrics.m_ascent > m_metrics.m_ascent)
m_metrics.m_ascent = fallbackMetrics.m_ascent;
if (fallbackMetrics.m_descent < m_metrics.m_descent)
m_metrics.m_descent = fallbackMetrics.m_descent;
if (fallbackMetrics.m_linegap > m_metrics.m_linegap)
m_metrics.m_linegap = fallbackMetrics.m_linegap;
}
bool PortabilityLayer::CompositeRenderedFont::GetGlyph(unsigned int character, const GpRenderedGlyphMetrics *&outMetricsPtr, const void *&outData) const
{
if (m_font->GetGlyph(character, outMetricsPtr, outData))
return true;
return m_fallbackFont->GetGlyph(character, outMetricsPtr, outData);
}
const GpRenderedFontMetrics &PortabilityLayer::CompositeRenderedFont::GetMetrics() const
{
return m_metrics;
}
size_t PortabilityLayer::CompositeRenderedFont::MeasureString(const uint8_t *chars, size_t len) const
{
int32_t measure = 0;
for (size_t i = 0; i < len; i++)
{
const uint8_t character = chars[i];
const GpRenderedGlyphMetrics *metrics = nullptr;
const void *data = nullptr;
if (m_font->GetGlyph(chars[i], metrics, data))
measure += metrics->m_advanceX;
else if (m_fallbackFont->GetGlyph(chars[i], metrics, data))
measure += metrics->m_advanceX;
}
return static_cast<size_t>(measure);
}
bool PortabilityLayer::CompositeRenderedFont::IsAntiAliased() const
{
return m_font->IsAntiAliased();
}
void PortabilityLayer::CompositeRenderedFont::Destroy()
{
assert(false);
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include "RenderedFont.h"
#include "GpRenderedFontMetrics.h"
namespace PortabilityLayer
{
class CompositeRenderedFont : public RenderedFont
{
public:
CompositeRenderedFont(RenderedFont *rfont, RenderedFont *fallbackFont);
bool GetGlyph(unsigned int character, const GpRenderedGlyphMetrics *&outMetricsPtr, const void *&outData) const override;
const GpRenderedFontMetrics &GetMetrics() const override;
size_t MeasureString(const uint8_t *chars, size_t len) const override;
bool IsAntiAliased() const override;
void Destroy() override;
size_t MeasureCharStr(const char *str, size_t len) const;
size_t MeasurePStr(const PLPasStr &pstr) const;
private:
GpRenderedFontMetrics m_metrics;
RenderedFont *m_font;
RenderedFont *m_fallbackFont;
};
}

View File

@@ -6,6 +6,7 @@ namespace PortabilityLayer
{
enum FontFamilyID
{
kSystemSymbols,
kSystem,
kApplication,
kMonospace,

View File

@@ -7,5 +7,6 @@ namespace PortabilityLayer
FontHacks_None,
FontHacks_Roboto,
FontHacks_SyntheticBold_OpenSans,
FontHacks_SystemSymbols,
};
}

View File

@@ -91,6 +91,9 @@ namespace PortabilityLayer
for (int i = 0; i < FontFamilyIDs::kCount; i++)
m_fontFamilies[static_cast<FontFamilyID_t>(i)] = FontFamily::Create(static_cast<FontFamilyID_t>(i));
if (m_fontFamilies[FontFamilyIDs::kSystemSymbols])
m_fontFamilies[FontFamilyIDs::kSystemSymbols]->AddFont(FontFamilyFlag_None, VirtualDirectories::kFonts, "Fonts/Inter/Inter-SemiBold.ttf", 0, FontHacks_SystemSymbols);
if (m_fontFamilies[FontFamilyIDs::kSystem])
m_fontFamilies[FontFamilyIDs::kSystem]->AddFont(FontFamilyFlag_None, VirtualDirectories::kFonts, "Fonts/OpenSans/OpenSans-ExtraBold.ttf", 0, FontHacks_None);
@@ -409,6 +412,8 @@ namespace PortabilityLayer
FontManagerImpl::FontPreset FontManagerImpl::ms_fontPresets[FontPresets::kCount] =
{
{ FontFamilyIDs::kSystemSymbols, 12, FontFamilyFlag_None, true },
{ FontFamilyIDs::kSystem, 12, FontFamilyFlag_None, true },
{ FontFamilyIDs::kSystem, 12, FontFamilyFlag_Bold, true },

View File

@@ -6,6 +6,8 @@ namespace PortabilityLayer
{
enum FontPreset
{
kSystemSymbols12,
kSystem12,
kSystem12Bold,

View File

@@ -105,6 +105,7 @@ namespace PortabilityLayer
private:
static void SynthesizeBoldAA(IGpFontRenderedGlyph *&glyph, unsigned int xScale, unsigned int yScale, bool aa, uint8_t character, int size, FontHacks fontHacks);
static uint16_t ResolveSystemSymbol(uint8_t character);
static FontRendererImpl ms_instance;
};
@@ -396,6 +397,10 @@ namespace PortabilityLayer
for (unsigned int i = 0; i < numCharacters; i++)
{
uint16_t unicodeCodePoint = MacRoman::ToUnicode(i);
if (fontHacks == FontHacks_SystemSymbols)
unicodeCodePoint = ResolveSystemSymbol(i);
if (unicodeCodePoint == 0xffff)
continue;
@@ -668,6 +673,35 @@ namespace PortabilityLayer
glyph = newGlyph;
}
uint16_t FontRendererImpl::ResolveSystemSymbol(uint8_t character)
{
// This emulates Chicago system symbol mappings
switch (character)
{
case 0x02: return 0x21e5;
case 0x03: return 0x21e4;
case 0x05: return 0x21e7;
case 0x06: return 0x2303;
case 0x07: return 0x2325;
case 0x0a: return 0x2326;
case 0x0b: return 0x21a9;
case 0x0c: return 0x21aa;
case 0x10: return 0x2193;
case 0x11: return 0x2318;
case 0x12: return 0x27a3;
case 0x13: return 0x25c6;
case 0x14: return 0x2764; // Supposed to be Apple logo but, uh yeah
case 0x17: return 0x232b;
case 0x18: return 0x2190;
case 0x19: return 0x2191;
case 0x1a: return 0x2192;
case 0x1b: return 0x238b;
case 0x1c: return 0x2327;
default:
return 0xffff;
}
}
FontRendererImpl *FontRendererImpl::GetInstance()
{
return &ms_instance;

View File

@@ -1,9 +1,11 @@
#include "MenuManager.h"
#include "CompositeRenderedFont.h"
#include "DisplayDeviceManager.h"
#include "FontFamily.h"
#include "FontManager.h"
#include "IGpFont.h"
#include "IGpDisplayDriver.h"
#include "IGpSystemServices.h"
#include "MemoryManager.h"
#include "ResourceManager.h"
#include "SimpleGraphic.h"
@@ -119,6 +121,8 @@ struct Menu
namespace PortabilityLayer
{
class CompositeRenderedFont;
class MenuManagerImpl final : public MenuManager
{
public:
@@ -163,9 +167,6 @@ namespace PortabilityLayer
void RenderFrame(IGpDisplayDriver *displayDriver) override;
void SetMenuTouchScreenStyle(bool isTouchScreen) override;
bool IsMenuTouchScreenStyle() const override;
static MenuManagerImpl *GetInstance();
private:
@@ -213,9 +214,7 @@ namespace PortabilityLayer
static const unsigned int kIconResID = 128;
static const unsigned int kMenuBarIconYOffset = 2;
static const unsigned int kMenuBarTextYOffset = 14;
static const unsigned int kTouchScreenMenuBarTextYOffset = 40;
static const unsigned int kMenuBarHeight = 20;
static const unsigned int kTouchscreenMenuBarHeight = 54;
static const unsigned int kMenuBarItemPadding = 6;
static const unsigned int kMenuBarInitialPadding = 16;
@@ -233,10 +232,9 @@ namespace PortabilityLayer
static const unsigned int kMenuItemLeftPadding = 16 + 2 + 2; // 2 for left border, 16 for icon, 2 for spacing
static const int kMenuFontFlags = PortabilityLayer::FontFamilyFlag_Bold;
static const int kTouchScreenMenuFontFlags = PortabilityLayer::FontFamilyFlag_None;
static const FontPreset_t kMenuFontSymbolsPreset = FontPresets::kSystemSymbols12;
static const FontPreset_t kMenuFontPreset = FontPresets::kSystem12Bold;
static const FontPreset_t kTouchScreenMenuFontPreset = FontPresets::kApplication40;
DrawSurface *m_menuBarGraf;
@@ -245,7 +243,6 @@ namespace PortabilityLayer
bool m_haveMenuBarLayout;
bool m_haveIcon;
bool m_menuBarVisible;
bool m_isTouchScreen;
uint8_t m_iconColors[16 * 16];
uint8_t m_iconMask[32];
@@ -257,6 +254,7 @@ namespace PortabilityLayer
static const int kHintTextCapacity = 6;
static size_t FormatHintText(uint8_t *buffer, uint8_t key);
static CompositeRenderedFont GetMenuTextCompositeFont();
static MenuManagerImpl ms_instance;
};
@@ -267,7 +265,6 @@ namespace PortabilityLayer
, m_haveIcon(false)
, m_iconGraphic(nullptr)
, m_menuBarVisible(false)
, m_isTouchScreen(false)
{
}
@@ -945,7 +942,7 @@ namespace PortabilityLayer
PortabilityLayer::QDManager *qdManager = PortabilityLayer::QDManager::GetInstance();
const int16_t menuHeight = m_isTouchScreen ? kTouchscreenMenuBarHeight : kMenuBarHeight;
const int16_t menuHeight = kMenuBarHeight;
const Rect menuRect = Rect::Create(0, 0, menuHeight, width);
@@ -1048,18 +1045,9 @@ namespace PortabilityLayer
// Text items
ResolveCachingColor barNormalTextColor = gs_barNormalTextColor;
PortabilityLayer::RenderedFont *sysFont = nullptr;
unsigned int textYOffset = 0;
if (m_isTouchScreen)
{
sysFont = GetFont(kTouchScreenMenuFontPreset);
textYOffset = kTouchScreenMenuBarTextYOffset;
}
else
{
sysFont = GetFont(kMenuFontPreset);
textYOffset = kMenuBarTextYOffset;
}
PortabilityLayer::CompositeRenderedFont sysFont = GetMenuTextCompositeFont();
const unsigned int textYOffset = kMenuBarTextYOffset;
{
Menu **menuHdl = m_firstMenu;
@@ -1081,7 +1069,7 @@ namespace PortabilityLayer
if (menuHdl != selectedMenuHdl)
{
const Point itemPos = Point::Create(static_cast<int16_t>(xCoordinate), textYOffset);
graf->DrawString(itemPos, PLPasStr(static_cast<const uint8_t*>(menu->stringBlobHandle->m_contents)), barNormalTextColor, sysFont);
graf->DrawString(itemPos, PLPasStr(static_cast<const uint8_t*>(menu->stringBlobHandle->m_contents)), barNormalTextColor, &sysFont);
}
}
}
@@ -1101,7 +1089,7 @@ namespace PortabilityLayer
size_t xCoordinate = menu->cumulativeOffset + (menu->menuIndex * 2) * kMenuBarItemPadding + kMenuBarInitialPadding;
const Point itemPos = Point::Create(static_cast<int16_t>(xCoordinate), textYOffset);
graf->DrawString(itemPos, PLPasStr(static_cast<const uint8_t*>(menu->stringBlobHandle->m_contents)), barHighlightTextColor, sysFont);
graf->DrawString(itemPos, PLPasStr(static_cast<const uint8_t*>(menu->stringBlobHandle->m_contents)), barHighlightTextColor, &sysFont);
}
}
@@ -1130,15 +1118,8 @@ namespace PortabilityLayer
const PixMap *pixMap = *m_menuBarGraf->m_port.GetPixMap();
const size_t width = pixMap->m_rect.right - pixMap->m_rect.left;
const size_t height = pixMap->m_rect.bottom - pixMap->m_rect.top;
int32_t y = 0;
if (m_isTouchScreen)
{
unsigned int displayHeight = WindowManager::GetInstance()->GetDisplayResolution().m_y;
y = static_cast<int32_t>(displayHeight) - kTouchscreenMenuBarHeight;
}
displayDriver->DrawSurface(m_menuBarGraf->m_ddSurface, 0, y, width, height, nullptr);
displayDriver->DrawSurface(m_menuBarGraf->m_ddSurface, 0, 0, width, height, nullptr);
}
}
@@ -1167,16 +1148,6 @@ namespace PortabilityLayer
}
}
void MenuManagerImpl::SetMenuTouchScreenStyle(bool isTouchScreenStyle)
{
m_isTouchScreen = isTouchScreenStyle;
}
bool MenuManagerImpl::IsMenuTouchScreenStyle() const
{
return m_isTouchScreen;
}
void MenuManagerImpl::RefreshMenuBarLayout()
{
if (m_haveMenuBarLayout)
@@ -1184,19 +1155,7 @@ namespace PortabilityLayer
PortabilityLayer::FontManager *fontManager = PortabilityLayer::FontManager::GetInstance();
PortabilityLayer::RenderedFont *rfont = nullptr;
PortabilityLayer::FontFamily *fontFamily = nullptr;
unsigned int fontSize = 0;
unsigned int fontFlags = 0;
if (m_isTouchScreen)
rfont = GetFont(kTouchScreenMenuFontPreset);
else
rfont = GetFont(kMenuFontPreset);
if (!rfont)
return;
PortabilityLayer::CompositeRenderedFont sysFont = GetMenuTextCompositeFont();
unsigned int index = 0;
size_t measuredWidth = 0;
@@ -1217,7 +1176,7 @@ namespace PortabilityLayer
menu->isIcon = true;
}
else
menu->unpaddedTitleWidth = rfont->MeasureString(pascalStr.UChars(), pascalStr.Length());
menu->unpaddedTitleWidth = sysFont.MeasureString(pascalStr.UChars(), pascalStr.Length());
measuredWidth += menu->unpaddedTitleWidth;
@@ -1234,9 +1193,7 @@ namespace PortabilityLayer
PortabilityLayer::FontManager *fontManager = PortabilityLayer::FontManager::GetInstance();
PortabilityLayer::RenderedFont *rfont = GetFont(kMenuFontPreset);
if (!rfont)
return;
PortabilityLayer::CompositeRenderedFont rfont = GetMenuTextCompositeFont();
const uint8_t *strBlob = static_cast<const uint8_t*>(menu->stringBlobHandle->m_contents);
@@ -1258,7 +1215,7 @@ namespace PortabilityLayer
const uint8_t *itemName = strBlob + item.nameOffsetInStringBlob;
const PLPasStr itemNamePStr = PLPasStr(itemName);
const size_t nameWidth = rfont->MeasureString(itemNamePStr.UChars(), itemNamePStr.Length());
const size_t nameWidth = rfont.MeasureString(itemNamePStr.UChars(), itemNamePStr.Length());
const size_t paddedWidth = nameWidth + kMenuItemLeftPadding + kMenuItemRightPadding;
@@ -1270,7 +1227,7 @@ namespace PortabilityLayer
{
uint8_t hintText[kHintTextCapacity];
const size_t hintLength = FormatHintText(hintText, item.key);
hintWidth = std::max<size_t>(rfont->MeasureString(hintText, hintLength) + kMenuItemRightPadding, hintWidth);
hintWidth = std::max<size_t>(rfont.MeasureString(hintText, hintLength) + kMenuItemRightPadding, hintWidth);
}
}
@@ -1386,13 +1343,7 @@ namespace PortabilityLayer
bool MenuManagerImpl::IsYInMenuBarRange(int32_t y) const
{
if (m_isTouchScreen)
{
unsigned int displayHeight = WindowManager::GetInstance()->GetDisplayResolution().m_y;
return y >= (static_cast<int32_t>(displayHeight - kTouchscreenMenuBarHeight)) && y < static_cast<int32_t>(displayHeight);
}
else
return y >= 0 && y < static_cast<int32_t>(kMenuBarHeight);
return y >= 0 && y < static_cast<int32_t>(kMenuBarHeight);
}
bool MenuManagerImpl::ItemIsSeparator(const Menu &menu, const MenuItem &item)
@@ -1405,14 +1356,31 @@ namespace PortabilityLayer
size_t MenuManagerImpl::FormatHintText(uint8_t *buffer, uint8_t key)
{
buffer[0] = 'C';
buffer[1] = 't';
buffer[2] = 'r';
buffer[3] = 'l';
buffer[4] = '+';
buffer[5] = key;
if (PLDrivers::GetSystemServices()->GetOperatingSystem() == GpOperatingSystems::kMacOS)
{
buffer[0] = 0x11; // Command symbol
buffer[1] = key;
return 2;
}
else
{
buffer[0] = 'C';
buffer[1] = 't';
buffer[2] = 'r';
buffer[3] = 'l';
buffer[4] = '+';
buffer[5] = key;
return 6;
}
}
return 6;
CompositeRenderedFont MenuManagerImpl::GetMenuTextCompositeFont()
{
PortabilityLayer::RenderedFont *sysFont = GetFont(kMenuFontPreset);
PortabilityLayer::RenderedFont *symbolsFont = GetFont(kMenuFontSymbolsPreset);
return CompositeRenderedFont(symbolsFont, sysFont);
}
MenuManagerImpl *MenuManagerImpl::GetInstance()
@@ -1580,7 +1548,7 @@ namespace PortabilityLayer
surface->FillRect(Rect::Create(static_cast<int16_t>(menu->layoutFinalHeight - 1), 1, static_cast<int16_t>(menu->layoutFinalHeight), static_cast<int16_t>(menu->layoutWidth - 1)), darkGrayColor);
}
PortabilityLayer::RenderedFont *sysFont = GetFont(kMenuFontPreset);
PortabilityLayer::CompositeRenderedFont compositeFont = GetMenuTextCompositeFont();
const uint8_t *strBlob = static_cast<const uint8_t*>(menu->stringBlobHandle->m_contents);
@@ -1611,7 +1579,7 @@ namespace PortabilityLayer
else
itemTextAndCheckColor = gs_barDisabledTextColor;
surface->DrawString(itemPos, PLPasStr(strBlob + item.nameOffsetInStringBlob), itemTextAndCheckColor, sysFont);
surface->DrawString(itemPos, PLPasStr(strBlob + item.nameOffsetInStringBlob), itemTextAndCheckColor, &compositeFont);
if (item.key)
{
@@ -1619,7 +1587,7 @@ namespace PortabilityLayer
uint8_t hintText[kHintTextCapacity];
const size_t hintLength = FormatHintText(hintText, item.key);
surface->DrawString(hintPos, PLPasStr(hintLength, reinterpret_cast<const char*>(hintText)), itemTextAndCheckColor, sysFont);
surface->DrawString(hintPos, PLPasStr(hintLength, reinterpret_cast<const char*>(hintText)), itemTextAndCheckColor, &compositeFont);
}
if (item.checked)
@@ -1651,7 +1619,7 @@ namespace PortabilityLayer
itemPos.v = item.layoutYOffset + kMenuItemTextYOffset;
surface->DrawString(itemPos, PLPasStr(strBlob + item.nameOffsetInStringBlob), barHighlightTextColor, sysFont);
surface->DrawString(itemPos, PLPasStr(strBlob + item.nameOffsetInStringBlob), barHighlightTextColor, &compositeFont);
if (item.key)
{
@@ -1659,7 +1627,7 @@ namespace PortabilityLayer
uint8_t hintText[kHintTextCapacity];
const size_t hintLength = FormatHintText(hintText, item.key);
surface->DrawString(hintPos, PLPasStr(hintLength, reinterpret_cast<const char*>(hintText)), barHighlightTextColor, sysFont);
surface->DrawString(hintPos, PLPasStr(hintLength, reinterpret_cast<const char*>(hintText)), barHighlightTextColor, &compositeFont);
if (item.checked)
surface->FillRect(Rect::Create(item.layoutYOffset + kMenuItemCheckTopOffset, kMenuItemCheckLeftOffset, item.layoutYOffset + kMenuItemCheckBottomOffset, kMenuItemCheckRightOffset), barHighlightTextColor);

View File

@@ -58,9 +58,6 @@ namespace PortabilityLayer
virtual void RenderFrame(IGpDisplayDriver *displayDriver) = 0;
virtual void SetMenuTouchScreenStyle(bool isTouchScreenStyle) = 0;
virtual bool IsMenuTouchScreenStyle() const = 0;
static MenuManager *GetInstance();
};
}

View File

@@ -93,6 +93,7 @@
<ClInclude Include="ByteUnpack.h" />
<ClInclude Include="CFileStream.h" />
<ClInclude Include="CombinedTimestamp.h" />
<ClInclude Include="CompositeRenderedFont.h" />
<ClInclude Include="DataTypes.h" />
<ClInclude Include="DeflateCodec.h" />
<ClInclude Include="DialogManager.h" />
@@ -226,6 +227,7 @@
<ClCompile Include="BitmapImage.cpp" />
<ClCompile Include="ByteSwap.cpp" />
<ClCompile Include="CFileStream.cpp" />
<ClCompile Include="CompositeRenderedFont.cpp" />
<ClCompile Include="DeflateCodec.cpp" />
<ClCompile Include="DialogManager.cpp" />
<ClCompile Include="DisplayDeviceManager.cpp" />

View File

@@ -426,6 +426,9 @@
<ClInclude Include="FontPresets.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CompositeRenderedFont.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CFileStream.cpp">
@@ -683,5 +686,8 @@
<ClCompile Include="InflateStream.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CompositeRenderedFont.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -1476,7 +1476,7 @@ namespace PortabilityLayer
logger->Printf(IGpLogDriver::Category_Information, "WindowManagerImpl: Resizing from %ix%i to %ix%i", static_cast<int>(prevWidth), static_cast<int>(prevHeight), static_cast<int>(newWidth), static_cast<int>(newHeight));
const uint32_t menuBarHeight = PortabilityLayer::MenuManager::GetInstance()->GetMenuBarHeight();
const bool menuIsTouchScreen = PortabilityLayer::MenuManager::GetInstance()->IsMenuTouchScreenStyle();
const bool menuIsTouchScreen = false; //PortabilityLayer::MenuManager::GetInstance()->IsMenuTouchScreenStyle();
for (PortabilityLayer::WindowImpl *window = m_windowStackTop; window != nullptr; window = window->GetWindowBelow())
{