Kaydet (Commit) bc535264 authored tarafından Miklos Vajna's avatar Miklos Vajna Kaydeden (comit) Andras Timar

tdf#93884 windows opengl: make space around cached glyphs depend on font size

Cached glyphs used to have a 2px border in all font sizes, that's too
small for larger fonts. Make the border size depend on the font size for
larger fonts to make sure that the rendered glyphs are indeed
independent.  The introduced GLYPH_SPACE_RATIO = 8 constant is the
smallest value where I don't see overflows anymore for large fonts.

With this, not even the bugdoc renders correctly when presenting, but
also the text is OK when the font size is set to the max allowed by the
UI (96pt).

Change-Id: I52aa5c4444583fc0467291463697a63f2b8fc86c
(cherry picked from commit 840248a4)
Reviewed-on: https://gerrit.libreoffice.org/18369Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarJan Holesovsky <kendy@collabora.com>
üst c82559b7
...@@ -59,6 +59,14 @@ typedef std::unordered_map<int,int> IntMap; ...@@ -59,6 +59,14 @@ typedef std::unordered_map<int,int> IntMap;
#include <config_mingw.h> #include <config_mingw.h>
namespace
{
// Extra space at the top and bottom of the glyph in total = tmHeight / GLYPH_SPACE_RATIO;
const int GLYPH_SPACE_RATIO = 8;
// Border size at the top of the glyph = tmHeight / GLYPH_OFFSET_RATIO;
const int GLYPH_OFFSET_RATIO = GLYPH_SPACE_RATIO * 2;
}
struct OpenGLGlyphCacheChunk struct OpenGLGlyphCacheChunk
{ {
WORD mnFirstGlyph; WORD mnFirstGlyph;
...@@ -66,7 +74,18 @@ struct OpenGLGlyphCacheChunk ...@@ -66,7 +74,18 @@ struct OpenGLGlyphCacheChunk
std::vector<Rectangle> maLocation; std::vector<Rectangle> maLocation;
std::shared_ptr<OpenGLTexture> mpTexture; std::shared_ptr<OpenGLTexture> mpTexture;
int mnAscent; int mnAscent;
int mnHeight;
bool mbVertical; bool mbVertical;
int getExtraSpace() const
{
return std::max(mnHeight / GLYPH_SPACE_RATIO, 4);
}
int getExtraOffset() const
{
return std::max(mnHeight / GLYPH_OFFSET_RATIO, 2);
}
}; };
// win32 specific physical font instance // win32 specific physical font instance
...@@ -278,10 +297,21 @@ bool ImplWinFontEntry::AddChunkOfGlyphs(int nGlyphIndex, const WinLayout& rLayou ...@@ -278,10 +297,21 @@ bool ImplWinFontEntry::AddChunkOfGlyphs(int nGlyphIndex, const WinLayout& rLayou
sLine << aABC[i].abcA << ":" << aABC[i].abcB << ":" << aABC[i].abcC << " "; sLine << aABC[i].abcA << ":" << aABC[i].abcB << ":" << aABC[i].abcC << " ";
SAL_INFO("vcl.gdi.opengl", "ABC widths: " << sLine.str()); SAL_INFO("vcl.gdi.opengl", "ABC widths: " << sLine.str());
TEXTMETRICW aTextMetric;
if (!GetTextMetricsW(hDC, &aTextMetric))
{
SAL_WARN("vcl.gdi", "GetTextMetrics failed: " << WindowsErrorString(GetLastError()));
SelectObject(hDC, hOrigFont);
DeleteDC(hDC);
return false;
}
aChunk.mnAscent = aTextMetric.tmAscent;
aChunk.mnHeight = aTextMetric.tmHeight;
// Try hard to avoid overlap as we want to be able to use // Try hard to avoid overlap as we want to be able to use
// individual rectangles for each glyph. The ABC widths don't // individual rectangles for each glyph. The ABC widths don't
// take anti-alising into consideration. Let's hope that leaving // take anti-alising into consideration. Let's hope that leaving
// four pixels of "extra" space inbetween glyphs will help. // "extra" space inbetween glyphs will help.
std::vector<int> aDX(nCount); std::vector<int> aDX(nCount);
int totWidth = 0; int totWidth = 0;
for (int i = 0; i < nCount; i++) for (int i = 0; i < nCount; i++)
...@@ -291,20 +321,10 @@ bool ImplWinFontEntry::AddChunkOfGlyphs(int nGlyphIndex, const WinLayout& rLayou ...@@ -291,20 +321,10 @@ bool ImplWinFontEntry::AddChunkOfGlyphs(int nGlyphIndex, const WinLayout& rLayou
aDX[0] += std::abs(aABC[0].abcA); aDX[0] += std::abs(aABC[0].abcA);
if (i < nCount-1) if (i < nCount-1)
aDX[i] += std::abs(aABC[i+1].abcA); aDX[i] += std::abs(aABC[i+1].abcA);
aDX[i] += 4; aDX[i] += aChunk.getExtraSpace();
totWidth += aDX[i]; totWidth += aDX[i];
} }
TEXTMETRICW aTextMetric;
if (!GetTextMetricsW(hDC, &aTextMetric))
{
SAL_WARN("vcl.gdi", "GetTextMetrics failed: " << WindowsErrorString(GetLastError()));
SelectObject(hDC, hOrigFont);
DeleteDC(hDC);
return false;
}
aChunk.mnAscent = aTextMetric.tmAscent;
LOGFONTW aLogfont; LOGFONTW aLogfont;
if (!GetObjectW(rLayout.mhFont, sizeof(aLogfont), &aLogfont)) if (!GetObjectW(rLayout.mhFont, sizeof(aLogfont), &aLogfont))
{ {
...@@ -336,18 +356,18 @@ bool ImplWinFontEntry::AddChunkOfGlyphs(int nGlyphIndex, const WinLayout& rLayou ...@@ -336,18 +356,18 @@ bool ImplWinFontEntry::AddChunkOfGlyphs(int nGlyphIndex, const WinLayout& rLayou
if (!DeleteDC(hDC)) if (!DeleteDC(hDC))
SAL_WARN("vcl.gdi", "DeleteDC failed: " << WindowsErrorString(GetLastError())); SAL_WARN("vcl.gdi", "DeleteDC failed: " << WindowsErrorString(GetLastError()));
// Leave two pixels of extra space also at top and bottom // Leave extra space also at top and bottom
int nBitmapWidth, nBitmapHeight; int nBitmapWidth, nBitmapHeight;
if (sFaceName[0] == '@') if (sFaceName[0] == '@')
{ {
nBitmapWidth = aSize.cy + 4; nBitmapWidth = aSize.cy + aChunk.getExtraSpace();
nBitmapHeight = totWidth; nBitmapHeight = totWidth;
aChunk.mbVertical = true; aChunk.mbVertical = true;
} }
else else
{ {
nBitmapWidth = totWidth; nBitmapWidth = totWidth;
nBitmapHeight = aSize.cy + 4; nBitmapHeight = aSize.cy + aChunk.getExtraSpace();
aChunk.mbVertical = false; aChunk.mbVertical = false;
} }
...@@ -384,9 +404,8 @@ bool ImplWinFontEntry::AddChunkOfGlyphs(int nGlyphIndex, const WinLayout& rLayou ...@@ -384,9 +404,8 @@ bool ImplWinFontEntry::AddChunkOfGlyphs(int nGlyphIndex, const WinLayout& rLayou
aDC.fill(MAKE_SALCOLOR(0xff, 0xff, 0xff)); aDC.fill(MAKE_SALCOLOR(0xff, 0xff, 0xff));
// The 2,2 is for the extra space int nY = aChunk.getExtraOffset();
int nY = 2; int nX = nY;
int nX = 2;
if (aChunk.mbVertical) if (aChunk.mbVertical)
nX += aDX[0]; nX += aDX[0];
if (!ExtTextOutW(aDC.getCompatibleHDC(), nX, nY, ETO_GLYPH_INDEX, NULL, aGlyphIndices.data(), nCount, aDX.data())) if (!ExtTextOutW(aDC.getCompatibleHDC(), nX, nY, ETO_GLYPH_INDEX, NULL, aGlyphIndices.data(), nCount, aDX.data()))
...@@ -416,7 +435,7 @@ bool ImplWinFontEntry::AddChunkOfGlyphs(int nGlyphIndex, const WinLayout& rLayou ...@@ -416,7 +435,7 @@ bool ImplWinFontEntry::AddChunkOfGlyphs(int nGlyphIndex, const WinLayout& rLayou
aChunk.maLocation[i].Right() = nPos + aDX[i]; aChunk.maLocation[i].Right() = nPos + aDX[i];
nPos = aChunk.maLocation[i].Right(); nPos = aChunk.maLocation[i].Right();
aChunk.maLocation[i].Top() = 0; aChunk.maLocation[i].Top() = 0;
aChunk.maLocation[i].Bottom() = aSize.cy + 4; aChunk.maLocation[i].Bottom() = aSize.cy + aChunk.getExtraSpace();
} }
} }
...@@ -1761,7 +1780,7 @@ bool UniscribeLayout::DrawCachedGlyphs(SalGraphics& rGraphics) const ...@@ -1761,7 +1780,7 @@ bool UniscribeLayout::DrawCachedGlyphs(SalGraphics& rGraphics) const
{ {
SalTwoRect a2Rects(rChunk.maLocation[n].Left(), rChunk.maLocation[n].Top(), SalTwoRect a2Rects(rChunk.maLocation[n].Left(), rChunk.maLocation[n].Top(),
rChunk.maLocation[n].getWidth(), rChunk.maLocation[n].getHeight(), rChunk.maLocation[n].getWidth(), rChunk.maLocation[n].getHeight(),
nAdvance + aPos.X() + mpGlyphOffsets[i].du - 2, aPos.Y() + mpGlyphOffsets[i].dv - rChunk.mnAscent - 2, nAdvance + aPos.X() + mpGlyphOffsets[i].du - rChunk.getExtraOffset(), aPos.Y() + mpGlyphOffsets[i].dv - rChunk.mnAscent - rChunk.getExtraOffset(),
rChunk.maLocation[n].getWidth(), rChunk.maLocation[n].getHeight()); // ??? rChunk.maLocation[n].getWidth(), rChunk.maLocation[n].getHeight()); // ???
pImpl->DrawMask(*rChunk.mpTexture, salColor, a2Rects); pImpl->DrawMask(*rChunk.mpTexture, salColor, a2Rects);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment