summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/inc/CommonSalLayout.hxx3
-rw-r--r--vcl/inc/win/salgdi.h3
-rw-r--r--vcl/inc/win/winlayout.hxx2
-rw-r--r--vcl/source/gdi/CommonSalLayout.cxx1
-rw-r--r--vcl/win/gdi/winlayout.cxx95
5 files changed, 90 insertions, 14 deletions
diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx
index e5345d77a65b..e2f3a114eee1 100644
--- a/vcl/inc/CommonSalLayout.hxx
+++ b/vcl/inc/CommonSalLayout.hxx
@@ -45,6 +45,7 @@ class CommonSalLayout : public GenericSalLayout
#ifdef _WIN32
HDC mhDC;
HFONT mhFont;
+ WinFontInstance& mrWinFontInstance;
double mnAveWidthFactor;
#elif defined(MACOSX) || defined(IOS)
const CoreTextStyle& mrCoreTextStyle;
@@ -65,6 +66,8 @@ public:
#if defined(_WIN32)
explicit CommonSalLayout(HDC, WinFontInstance&, const WinFontFace&);
const FontSelectPattern& getFontSelData() const { return mrFontSelData; };
+ HFONT getHFONT() const { return mhFont; }
+ WinFontInstance& getWinFontInstance() const { return mrWinFontInstance; }
#elif defined(MACOSX) || defined(IOS)
explicit CommonSalLayout(const CoreTextStyle&);
const CoreTextStyle& getFontData() const { return mrCoreTextStyle; };
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 305005540841..14310f90411e 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -236,6 +236,9 @@ private:
LogicalFontInstance* GetWinFontEntry(int nFallbackLevel);
+ bool CacheGlyphs(const CommonSalLayout& rLayout);
+ bool DrawCachedGlyphs(const CommonSalLayout& rLayout);
+
public:
HDC getHDC() const { return mhLocalDC; }
void setHDC(HDC aNew) { mhLocalDC = aNew; }
diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx
index 7b15e7e4f5f3..8ceebeac3882 100644
--- a/vcl/inc/win/winlayout.hxx
+++ b/vcl/inc/win/winlayout.hxx
@@ -193,7 +193,7 @@ public:
private:
GlyphCache maGlyphCache;
public:
- bool CacheGlyphToAtlas(bool bRealGlyphIndices, int nGlyphIndex, const WinLayout& rLayout, SalGraphics& rGraphics);
+ bool CacheGlyphToAtlas(bool bRealGlyphIndices, HDC hDC, HFONT hFont, int nGlyphIndex, SalGraphics& rGraphics);
GlyphCache& GetGlyphCache()
{
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index dbc3fa89695c..8ab8eb3abf9c 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -181,6 +181,7 @@ CommonSalLayout::CommonSalLayout(HDC hDC, WinFontInstance& rWinFontInstance, con
: mrFontSelData(rWinFontInstance.maFontSelData)
, mhDC(hDC)
, mhFont(static_cast<HFONT>(GetCurrentObject(hDC, OBJ_FONT)))
+, mrWinFontInstance(rWinFontInstance)
, mnAveWidthFactor(1.0f)
, mpVertGlyphs(nullptr)
{
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index c693b31c9fb2..2d351758b2c6 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -66,7 +66,7 @@ inline int WinFontInstance::GetCachedGlyphWidth( int nCharCode ) const
return it->second;
}
-bool WinFontInstance::CacheGlyphToAtlas(bool bRealGlyphIndices, int nGlyphIndex, const WinLayout& rLayout, SalGraphics& rGraphics)
+bool WinFontInstance::CacheGlyphToAtlas(bool bRealGlyphIndices, HDC hDC, HFONT hFont, int nGlyphIndex, SalGraphics& rGraphics)
{
if (nGlyphIndex == DROPPED_OUTGLYPH)
return true;
@@ -77,17 +77,17 @@ bool WinFontInstance::CacheGlyphToAtlas(bool bRealGlyphIndices, int nGlyphIndex,
std::vector<uint32_t> aCodePointsOrGlyphIndices(1);
aCodePointsOrGlyphIndices[0] = nGlyphIndex;
- HDC hDC = CreateCompatibleDC(rLayout.mhDC);
- if (hDC == nullptr)
+ HDC hNewDC = CreateCompatibleDC(hDC);
+ if (hNewDC == nullptr)
{
SAL_WARN("vcl.gdi", "CreateCompatibleDC failed: " << WindowsErrorString(GetLastError()));
return false;
}
- HFONT hOrigFont = static_cast<HFONT>(SelectObject(hDC, rLayout.mhFont));
+ HFONT hOrigFont = static_cast<HFONT>(SelectObject(hNewDC, hFont));
if (hOrigFont == nullptr)
{
SAL_WARN("vcl.gdi", "SelectObject failed: " << WindowsErrorString(GetLastError()));
- DeleteDC(hDC);
+ DeleteDC(hNewDC);
return false;
}
@@ -96,26 +96,26 @@ bool WinFontInstance::CacheGlyphToAtlas(bool bRealGlyphIndices, int nGlyphIndex,
if (!pTxt)
return false;
- if (!pTxt->BindFont(hDC))
+ if (!pTxt->BindFont(hNewDC))
{
SAL_WARN("vcl.gdi", "Binding of font failed. The font might not be supported by Direct Write.");
- DeleteDC(hDC);
+ DeleteDC(hNewDC);
return false;
}
// Bail for non-horizontal text.
{
wchar_t sFaceName[200];
- int nFaceNameLen = GetTextFaceW(hDC, SAL_N_ELEMENTS(sFaceName), sFaceName);
+ int nFaceNameLen = GetTextFaceW(hNewDC, SAL_N_ELEMENTS(sFaceName), sFaceName);
if (!nFaceNameLen)
SAL_WARN("vcl.gdi", "GetTextFace failed: " << WindowsErrorString(GetLastError()));
LOGFONTW aLogFont;
- GetObjectW(rLayout.mhFont, sizeof(LOGFONTW), &aLogFont);
+ GetObjectW(hFont, sizeof(LOGFONTW), &aLogFont);
- SelectObject(hDC, hOrigFont);
- DeleteDC(hDC);
+ SelectObject(hNewDC, hOrigFont);
+ DeleteDC(hNewDC);
if (sFaceName[0] == '@' || aLogFont.lfOrientation != 0 || aLogFont.lfEscapement != 0)
{
@@ -1160,7 +1160,7 @@ bool SimpleWinLayout::CacheGlyphs(SalGraphics& rGraphics) const
if (!mrWinFontEntry.GetGlyphCache().IsGlyphCached(nCodePoint))
{
- if (!mrWinFontEntry.CacheGlyphToAtlas(false, nCodePoint, *this, rGraphics))
+ if (!mrWinFontEntry.CacheGlyphToAtlas(false, mhDC, mhFont, nCodePoint, rGraphics))
return false;
}
}
@@ -2409,7 +2409,7 @@ bool UniscribeLayout::CacheGlyphs(SalGraphics& rGraphics) const
int nCodePoint = mpOutGlyphs[i];
if (!mrWinFontEntry.GetGlyphCache().IsGlyphCached(nCodePoint))
{
- if (!mrWinFontEntry.CacheGlyphToAtlas(true, nCodePoint, *this, rGraphics))
+ if (!mrWinFontEntry.CacheGlyphToAtlas(true, mhDC, mhFont, nCodePoint, rGraphics))
return false;
}
}
@@ -3778,6 +3778,70 @@ LogicalFontInstance* WinFontFace::CreateFontInstance( FontSelectPattern& rFSD )
return pFontInstance;
}
+bool WinSalGraphics::CacheGlyphs(const CommonSalLayout& rLayout)
+{
+ static bool bDoGlyphCaching = (std::getenv("SAL_DISABLE_GLYPH_CACHING") == nullptr);
+ if (!bDoGlyphCaching)
+ return false;
+
+ HDC hDC = getHDC();
+ HFONT hFONT = rLayout.getHFONT();
+ WinFontInstance& rFont = rLayout.getWinFontInstance();
+
+ int nStart = 0;
+ Point aPos(0, 0);
+ sal_GlyphId nGlyph;
+ while (rLayout.GetNextGlyphs(1, &nGlyph, aPos, nStart))
+ {
+ if (!rFont.GetGlyphCache().IsGlyphCached(nGlyph))
+ {
+ if (!rFont.CacheGlyphToAtlas(true, hDC, hFONT, nGlyph, *this))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool WinSalGraphics::DrawCachedGlyphs(const CommonSalLayout& rLayout)
+{
+ HDC hDC = getHDC();
+
+ Rectangle aRect;
+ rLayout.GetBoundRect(*this, aRect);
+
+ COLORREF color = GetTextColor(hDC);
+ SalColor salColor = MAKE_SALCOLOR(GetRValue(color), GetGValue(color), GetBValue(color));
+
+ WinOpenGLSalGraphicsImpl *pImpl = dynamic_cast<WinOpenGLSalGraphicsImpl*>(mpImpl.get());
+ if (!pImpl)
+ return false;
+
+ WinFontInstance& rFont = rLayout.getWinFontInstance();
+
+ int nStart = 0;
+ Point aPos(0, 0);
+ sal_GlyphId nGlyph;
+ while (rLayout.GetNextGlyphs(1, &nGlyph, aPos, nStart))
+ {
+ OpenGLGlyphDrawElement& rElement(rFont.GetGlyphCache().GetDrawElement(nGlyph));
+ OpenGLTexture& rTexture = rElement.maTexture;
+
+ if (!rTexture)
+ return false;
+
+ SalTwoRect a2Rects(0, 0,
+ rTexture.GetWidth(), rTexture.GetHeight(),
+ aPos.X() - rElement.getExtraOffset() + rElement.maLeftOverhangs,
+ aPos.Y() - rElement.mnBaselineOffset - rElement.getExtraOffset(),
+ rTexture.GetWidth(), rTexture.GetHeight());
+
+ pImpl->DeferredTextDraw(rTexture, salColor, a2Rects);
+ }
+
+ return true;
+}
+
void WinSalGraphics::DrawTextLayout(const CommonSalLayout& rLayout, HDC hDC, bool bUseDWrite)
{
Point aPos(0, 0);
@@ -3796,6 +3860,11 @@ void WinSalGraphics::DrawSalLayout(const CommonSalLayout& rLayout)
// no OpenGL, just classic rendering
DrawTextLayout(rLayout, hDC, false);
}
+ else if (CacheGlyphs(rLayout) &&
+ DrawCachedGlyphs(rLayout))
+ {
+ // Nothing
+ }
else
{
// We have to render the text to a hidden texture, and draw it.