Improve synthetic bold quality and use synthetic bold for most Open Sans uses

This commit is contained in:
elasota
2021-04-18 18:11:38 -04:00
parent d826a908e9
commit f15a87041a
15 changed files with 122 additions and 61 deletions

View File

@@ -119,7 +119,7 @@ void DrawBannerMessage (Point topLeft)
PasStringCopy((*thisHouse)->banner, bannerStr);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
@@ -224,7 +224,7 @@ void DisplayStarsRemaining(void)
DrawSurface *surface = starsWindow->GetDrawSurface();
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
NumToString((long)numStarsRemaining, theStr);

View File

@@ -108,7 +108,7 @@ void SetUpFinalScreen (void)
{
GetLineOfText(tempStr, count, subStr);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
offset = ((thisMac.constrainedScreen.right - thisMac.constrainedScreen.left) -
appFont->MeasurePStr(subStr)) / 2;

View File

@@ -149,7 +149,7 @@ void DrawHighScores (DrawSurface *surface)
DisposeGWorld(tempMap);
DisposeGWorld(tempMask);
PortabilityLayer::RenderedFont *appFont14 = GetFont(PortabilityLayer::FontPresets::kApplication14Bold);
PortabilityLayer::RenderedFont *appFont14 = GetFont(PortabilityLayer::FontPresets::kApplication14SyntheticBold);
PasStringCopy(PSTR("\xa5 "), tempStr);
PasStringConcat(tempStr, thisHouseName);
@@ -161,7 +161,7 @@ void DrawHighScores (DrawSurface *surface)
const Point scoreTextPoint = Point::Create(scoreLeft + ((kScoreWide - appFont14->MeasurePStr(tempStr)) / 2), dropIt - 65);
surface->DrawString(scoreTextPoint, tempStr, cyanColor, appFont14);
PortabilityLayer::RenderedFont *appFont12 = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
PortabilityLayer::RenderedFont *appFont12 = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
thisHousePtr = *thisHouse;
// message for score #1
@@ -268,7 +268,7 @@ void DrawHighScores (DrawSurface *surface)
}
}
PortabilityLayer::RenderedFont *appFont9 = GetFont(PortabilityLayer::FontPresets::kApplication9Bold);
PortabilityLayer::RenderedFont *appFont9 = GetFont(PortabilityLayer::FontPresets::kApplication9SyntheticBold);
const Point textPos = Point::Create(scoreLeft + 80, dropIt - 1 + (10 * kScoreSpacing));
GetLocalizedString(8, tempStr);

View File

@@ -72,7 +72,7 @@ void DrawOnSplash(DrawSurface *surface)
if ((thisMac.hasQT) && (hasMovie))
PasStringConcat(houseLoadedStr, PSTR(" (TV)"));
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9Bold);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9SyntheticBold);
const Point textPoint = Point::Create(splashOriginH + 436, splashOriginV + 314);
if (thisMac.isDepth == 4)

View File

@@ -1057,7 +1057,7 @@ void DrawCalendar (Rect *theRect)
backSrcMap->DrawPicture(thePicture, bounds);
thePicture.Dispose();
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9Bold);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9SyntheticBold);
GetTime(&timeRec);
GetIndString(monthStr, kMonthStringID, timeRec.month);

View File

@@ -176,7 +176,7 @@ void RefreshRoomTitle (short mode)
const Point strShadowPoint = Point::Create(1, 10);
const Point strPoint = Point::Create(0, 9);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
switch (mode)
{
@@ -221,7 +221,7 @@ void RefreshNumGliders (void)
long displayMortals;
DrawSurface *surface = boardGSrcMap;
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
PortabilityLayer::ResolveCachingColor theRGBColor = PortabilityLayer::ResolveCachingColor::FromStandardColor(kGrayBackgroundColor);
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
@@ -256,7 +256,7 @@ void RefreshPoints (void)
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
PortabilityLayer::ResolveCachingColor whiteColor = StdColors::White();
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
surface->FillRect(boardPSrcRect, theRGBColor);
@@ -286,7 +286,7 @@ void QuickGlidersRefresh (void)
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
PortabilityLayer::ResolveCachingColor whiteColor = StdColors::White();
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
surface->FillRect(boardGSrcRect, theRGBColor);
@@ -316,7 +316,7 @@ void QuickScoreRefresh (void)
PortabilityLayer::ResolveCachingColor blackColor = StdColors::Black();
PortabilityLayer::ResolveCachingColor whiteColor = StdColors::White();
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12Bold);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication12SyntheticBold);
surface->FillRect(boardPSrcRect, theRGBColor);

View File

@@ -156,7 +156,7 @@ void DrawToolName (DrawSurface *surface)
const Point textPoint = Point::Create(toolTextRect.left + 3, toolTextRect.bottom - 6);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9Bold);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication9SyntheticBold);
ColorText(surface, textPoint, theString, 171L, appFont);
}
#endif

View File

@@ -12,4 +12,6 @@ struct GpRenderedGlyphMetrics
int16_t m_bearingX;
int16_t m_bearingY;
int16_t m_advanceX;
int16_t m_bitmapOffsetX;
int16_t m_bitmapOffsetY;
};

View File

@@ -172,6 +172,8 @@ IGpFontRenderedGlyph *GpFont_FreeType2::Render(uint32_t unicodeCodePoint, unsign
metrics.m_glyphWidth = glyph->bitmap.width;
metrics.m_glyphHeight = glyph->bitmap.rows;
metrics.m_advanceX = glyph->metrics.horiAdvance / 64;
metrics.m_bitmapOffsetX = glyph->bitmap_left;
metrics.m_bitmapOffsetY = glyph->bitmap_top;
const size_t numRowsRequired = glyph->bitmap.rows;
size_t pitchRequired = 0;

View File

@@ -16,8 +16,9 @@ namespace PortabilityLayer
FontFamilyFlag_None = 0,
FontFamilyFlag_Bold = 1,
FontFamilyFlag_SyntheticBold = 2,
FontFamilyFlag_All = 1,
FontFamilyFlag_All = (FontFamilyFlag_Bold | FontFamilyFlag_SyntheticBold),
};
class FontFamily final

View File

@@ -6,6 +6,6 @@ namespace PortabilityLayer
{
FontHacks_None,
FontHacks_Roboto,
FontHacks_SyntheticBold,
FontHacks_SyntheticBold_OpenSans,
};
}

View File

@@ -50,8 +50,9 @@ namespace PortabilityLayer
RenderedFont *m_rfont;
int m_fontCacheID;
int m_size;
uint32_t m_lastUsage;
int m_flags;
bool m_aa;
uint32_t m_lastUsage;
};
struct FontPreset
@@ -64,7 +65,7 @@ namespace PortabilityLayer
FontManagerImpl();
bool FindOrReserveCacheSlot(int cacheID, int size, bool aa, CachedRenderedFont *&outCacheSlot, RenderedFont *&outRF);
bool FindOrReserveCacheSlot(int cacheID, int size, bool aa, int flags, CachedRenderedFont *&outCacheSlot, RenderedFont *&outRF);
void ReplaceCachedRenderedFont(CachedRenderedFont &cacheSlot, RenderedFont *rfont, int cacheID, int size, bool aa, int flags);
void ResetUsageCounter();
@@ -97,6 +98,7 @@ namespace PortabilityLayer
{
m_fontFamilies[FontFamilyIDs::kApplication]->AddFont(FontFamilyFlag_None, VirtualDirectories::kFonts, "Fonts/OpenSans/OpenSans-SemiBold.ttf", 0, FontHacks_None);
m_fontFamilies[FontFamilyIDs::kApplication]->AddFont(FontFamilyFlag_Bold, VirtualDirectories::kFonts, "Fonts/OpenSans/OpenSans-Bold.ttf", 0, FontHacks_None);
m_fontFamilies[FontFamilyIDs::kApplication]->AddFont(FontFamilyFlag_SyntheticBold, VirtualDirectories::kFonts, "Fonts/OpenSans/OpenSans-Regular.ttf", 0, FontHacks_SyntheticBold_OpenSans);
}
if (m_fontFamilies[FontFamilyIDs::kHandwriting])
@@ -143,23 +145,10 @@ namespace PortabilityLayer
*outAA = ms_fontPresets[preset].m_aa;
if (outFamilyID)
{
switch (ms_fontPresets[preset].m_familyID)
{
case FontFamilyIDs::kApplication:
if (!m_hasPreinstalledFonts && ms_fontPresets[preset].m_textSize < 11 && (ms_fontPresets[preset].m_variationFlags & FontFamilyFlag_Bold) != 0)
*outFamilyID = FontFamilyIDs::kSystem; // Use heavier font below 11pt
else
*outFamilyID = FontFamilyIDs::kApplication;
break;
default:
*outFamilyID = ms_fontPresets[preset].m_familyID;
break;
}
}
*outFamilyID = ms_fontPresets[preset].m_familyID;
}
bool FontManagerImpl::FindOrReserveCacheSlot(int cacheID, int size, bool aa, CachedRenderedFont *&outCacheSlot, RenderedFont *&outRF)
bool FontManagerImpl::FindOrReserveCacheSlot(int cacheID, int size, bool aa, int flags, CachedRenderedFont *&outCacheSlot, RenderedFont *&outRF)
{
CachedRenderedFont *newCacheSlot = &m_cachedRenderedFonts[0];
@@ -172,7 +161,7 @@ namespace PortabilityLayer
break;
}
if (crf.m_fontCacheID == cacheID && crf.m_size == size && crf.m_aa == aa)
if (crf.m_fontCacheID == cacheID && crf.m_size == size && crf.m_aa == aa && crf.m_flags == flags)
{
crf.m_lastUsage = m_usageCounter;
RenderedFont *rf = crf.m_rfont;
@@ -203,6 +192,7 @@ namespace PortabilityLayer
cacheSlot.m_size = size;
cacheSlot.m_rfont = rfont;
cacheSlot.m_aa = aa;
cacheSlot.m_flags = flags;
if (m_usageCounter == UINT32_MAX)
ResetUsageCounter();
@@ -231,7 +221,7 @@ namespace PortabilityLayer
CachedRenderedFont *cacheSlot = nullptr;
RenderedFont *rfont = nullptr;
if (this->FindOrReserveCacheSlot(familyID, size, aa, cacheSlot, rfont))
if (this->FindOrReserveCacheSlot(familyID, size, aa, flags, cacheSlot, rfont))
return rfont;
rfont = LoadAndRenderFont(familyID, size, aa, flags);
@@ -424,11 +414,12 @@ namespace PortabilityLayer
{ FontFamilyIDs::kApplication, 8, FontFamilyFlag_None, true },
{ FontFamilyIDs::kApplication, 9, FontFamilyFlag_None, true },
{ FontFamilyIDs::kApplication, 9, FontFamilyFlag_Bold, true },
{ FontFamilyIDs::kApplication, 10, FontFamilyFlag_Bold, true },
{ FontFamilyIDs::kApplication, 9, FontFamilyFlag_SyntheticBold, true },
{ FontFamilyIDs::kApplication, 10, FontFamilyFlag_SyntheticBold, true },
{ FontFamilyIDs::kApplication, 12, FontFamilyFlag_Bold, true },
{ FontFamilyIDs::kApplication, 12, FontFamilyFlag_SyntheticBold, true },
{ FontFamilyIDs::kApplication, 14, FontFamilyFlag_None, true },
{ FontFamilyIDs::kApplication, 14, FontFamilyFlag_Bold, true },
{ FontFamilyIDs::kApplication, 14, FontFamilyFlag_SyntheticBold, true },
{ FontFamilyIDs::kApplication, 18, FontFamilyFlag_None, true },
{ FontFamilyIDs::kApplication, 40, FontFamilyFlag_None, true },

View File

@@ -11,11 +11,12 @@ namespace PortabilityLayer
kApplication8,
kApplication9,
kApplication9Bold,
kApplication10Bold,
kApplication9SyntheticBold,
kApplication10SyntheticBold,
kApplication12Bold,
kApplication12SyntheticBold,
kApplication14,
kApplication14Bold,
kApplication14SyntheticBold,
kApplication18,
kApplication40,

View File

@@ -59,6 +59,8 @@ namespace PortabilityLayer
BEInt16_t m_bearingX;
BEInt16_t m_bearingY;
BEInt16_t m_advanceX;
BEInt16_t m_bitmapOffsetX;
BEInt16_t m_bitmapOffsetY;
};
struct SerializedFontMetrics
@@ -101,7 +103,7 @@ namespace PortabilityLayer
static FontRendererImpl *GetInstance();
private:
static void SynthesizeBoldAA(IGpFontRenderedGlyph *&glyph, unsigned int xScale, unsigned int yScale, bool aa);
static void SynthesizeBoldAA(IGpFontRenderedGlyph *&glyph, unsigned int xScale, unsigned int yScale, bool aa, uint8_t character, int size, FontHacks fontHacks);
static FontRendererImpl ms_instance;
};
@@ -315,6 +317,8 @@ namespace PortabilityLayer
result.m_glyphDataPitch = static_cast<uint32_t>(metrics.m_glyphDataPitch);
result.m_glyphHeight = metrics.m_glyphHeight;
result.m_glyphWidth = metrics.m_glyphWidth;
result.m_bitmapOffsetX = metrics.m_bitmapOffsetX;
result.m_bitmapOffsetY = metrics.m_bitmapOffsetY;
return result;
}
@@ -328,6 +332,8 @@ namespace PortabilityLayer
result.m_glyphDataPitch = static_cast<uint32_t>(metrics.m_glyphDataPitch);
result.m_glyphHeight = metrics.m_glyphHeight;
result.m_glyphWidth = metrics.m_glyphWidth;
result.m_bitmapOffsetX = metrics.m_bitmapOffsetX;
result.m_bitmapOffsetY = metrics.m_bitmapOffsetY;
return result;
}
@@ -369,16 +375,20 @@ namespace PortabilityLayer
for (unsigned int i = 0; i < numCharacters; i++)
glyphs[i] = nullptr;
bool isSyntheticBold = false;
if (fontHacks == FontHacks_SyntheticBold_OpenSans)
isSyntheticBold = true;
unsigned int xScale = 1;
unsigned int yScale = 1;
bool syntheticBoldAA = false;
if (fontHacks == FontHacks_SyntheticBold)
if (isSyntheticBold)
{
if (aa)
{
syntheticBoldAA = true;
xScale = 16;
yScale = 16;
xScale = 8;
yScale = 8;
}
}
@@ -391,14 +401,14 @@ namespace PortabilityLayer
glyphs[i] = font->Render(unicodeCodePoint, size, xScale, yScale, aa);
}
if (fontHacks == FontHacks_SyntheticBold)
if (isSyntheticBold)
{
if (syntheticBoldAA)
{
for (unsigned int i = 0; i < numCharacters; i++)
{
if (glyphs[i])
SynthesizeBoldAA(glyphs[i], xScale, yScale, syntheticBoldAA);
SynthesizeBoldAA(glyphs[i], xScale, yScale, syntheticBoldAA, i, size, fontHacks);
}
}
}
@@ -448,6 +458,20 @@ namespace PortabilityLayer
}
}
/*
if (fontHacks == FontHacks_SyntheticBold_OpenSans && size == 12)
{
if (i == 'i')
metrics.m_bearingX++;
}
if (fontHacks == FontHacks_SyntheticBold_OpenSans && size == 9)
{
if (i == 'V')
metrics.m_advanceX++;
}
*/
rfont->SetCharData(i, data, fillOffset, metrics);
fillOffset += metrics.m_glyphDataPitch * metrics.m_glyphHeight;
@@ -512,16 +536,45 @@ namespace PortabilityLayer
return true;
}
void FontRendererImpl::SynthesizeBoldAA(IGpFontRenderedGlyph *&glyph, unsigned int xScale, unsigned int yScale, bool aa)
void FontRendererImpl::SynthesizeBoldAA(IGpFontRenderedGlyph *&glyph, unsigned int xScale, unsigned int yScale, bool aa, uint8_t character, int size, FontHacks fontHacks)
{
unsigned int extraWidth = 1;
GpRenderedGlyphMetrics metrics = glyph->GetMetrics();
const void *existingData = glyph->GetData();
uint32_t existingWidth = metrics.m_glyphWidth;
uint32_t existingHeight = metrics.m_glyphHeight;
uint32_t newWidth = (existingWidth + xScale - 1) / xScale + 1;
uint32_t newHeight = (existingHeight + yScale - 1) / yScale;
uint32_t leftPadding = 0;
uint32_t topPadding = 0;
{
const int32_t leftCoord = metrics.m_bitmapOffsetX;
int32_t leftCoordRemainder = leftCoord % static_cast<int32_t>(xScale);
if (leftCoordRemainder > 0)
leftPadding = leftCoordRemainder;
else if (leftCoordRemainder < 0)
leftPadding = leftCoordRemainder + static_cast<int32_t>(xScale);
const int32_t topCoord = metrics.m_bitmapOffsetY;
int32_t topCoordRemainder = topCoord % static_cast<int32_t>(yScale);
if (topCoordRemainder != 0)
{
if (topCoordRemainder < 0)
topCoordRemainder += static_cast<int32_t>(yScale);
topPadding = static_cast<int32_t>(yScale) - topCoordRemainder;
}
}
uint32_t paddedWidth = existingWidth + leftPadding;
uint32_t paddedHeight = existingHeight + topPadding;
uint32_t newWidth = (paddedWidth + xScale - 1) / xScale + extraWidth;
uint32_t newHeight = (paddedHeight + yScale - 1) / yScale;
ReRenderedGlyph *newGlyph = ReRenderedGlyph::Create(newWidth, newHeight, aa);
if (!newGlyph)
@@ -535,9 +588,11 @@ namespace PortabilityLayer
}
GpRenderedGlyphMetrics &newMetrics = newGlyph->GetMutableMetrics();
newMetrics.m_advanceX = metrics.m_advanceX + 1;
newMetrics.m_bearingX = metrics.m_bearingX;
newMetrics.m_bearingY = metrics.m_bearingY;
newMetrics.m_advanceX = metrics.m_advanceX + static_cast<int16_t>(extraWidth);
newMetrics.m_bearingX = (metrics.m_bitmapOffsetX - static_cast<int16_t>(leftPadding)) / static_cast<int16_t>(xScale);
newMetrics.m_bearingY = (metrics.m_bitmapOffsetY + static_cast<int16_t>(topPadding)) / static_cast<int16_t>(yScale);
newMetrics.m_bitmapOffsetX = newMetrics.m_bearingX;
newMetrics.m_bitmapOffsetY = newMetrics.m_bearingY;
const size_t existingDataPitch = metrics.m_glyphDataPitch;
const size_t newPitch = newMetrics.m_glyphDataPitch;
@@ -549,7 +604,11 @@ namespace PortabilityLayer
for (unsigned int subY = 0; subY < yScale; subY++)
{
unsigned int originalY = subY + outY * yScale;
uint32_t originalY = subY + outY * yScale;
if (originalY < topPadding)
continue;
originalY -= topPadding;
if (originalY >= existingHeight)
break;
@@ -558,14 +617,19 @@ namespace PortabilityLayer
unsigned int streakCounter = 0;
unsigned int outX = 0;
unsigned int outSubX = 0;
for (unsigned int originalX = 0; originalX < newWidth * xScale; originalX++)
for (unsigned int unpaddedOriginalX = 0; unpaddedOriginalX < newWidth * xScale; unpaddedOriginalX++)
{
if (originalX < existingWidth)
if (unpaddedOriginalX > leftPadding)
{
//if (existingRow[originalX / 8] & (1 << (originalX & 7)))
uint8_t v = ((existingRow[originalX / 2] >> ((originalX & 1) * 4)) & 0xf);
if (v >= 8)
streakCounter = xScale + 1;
uint32_t originalX = unpaddedOriginalX - leftPadding;
if (originalX < existingWidth)
{
//if (existingRow[originalX / 8] & (1 << (originalX & 7)))
uint8_t v = ((existingRow[originalX / 2] >> ((originalX & 1) * 4)) & 0xf);
if (v >= 8)
streakCounter = xScale + 1;
}
}
if (streakCounter > 0)

View File

@@ -593,7 +593,7 @@ namespace PortabilityLayer
if (window->GetStyleFlags() & WindowStyleFlags::kCloseBox)
RenderChromeCloseBox(surface, rect, false);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication10Bold);
PortabilityLayer::RenderedFont *appFont = GetFont(PortabilityLayer::FontPresets::kApplication10SyntheticBold);
int32_t ascender = appFont->GetMetrics().m_ascent;
const PLPasStr titlePStr = window->GetTitle().ToShortStr();