[Libreoffice-commits] core.git: vcl/inc vcl/skia vcl/win
LuboÅ¡ LuÅák (via logerrit)
logerrit at kemper.freedesktop.org
Mon Dec 7 19:48:02 UTC 2020
vcl/inc/skia/win/gdiimpl.hxx | 14 -
vcl/inc/win/saldata.hxx | 2
vcl/inc/win/salgdi.h | 17 --
vcl/inc/win/wingdiimpl.hxx | 14 -
vcl/inc/win/winlayout.hxx | 88 ------------
vcl/skia/win/gdiimpl.cxx | 67 ---------
vcl/win/gdi/winlayout.cxx | 312 -------------------------------------------
7 files changed, 3 insertions(+), 511 deletions(-)
New commits:
commit daa0e2629e13883da0cb41c29fccbcff48b930c5
Author: Luboš Luňák <l.lunak at centrum.cz>
AuthorDate: Fri Dec 4 20:25:06 2020 +0000
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Mon Dec 7 20:47:18 2020 +0100
remove WinGlyphCache and related code
The code for separately rendering glyphs was used only by OpenGL
code (and temporarily by Skia code).
Change-Id: I8eee764045273705c108f3734b330a2237de15f7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107291
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak at collabora.com>
diff --git a/vcl/inc/skia/win/gdiimpl.hxx b/vcl/inc/skia/win/gdiimpl.hxx
index 167b57147bf3..fd39ca273609 100644
--- a/vcl/inc/skia/win/gdiimpl.hxx
+++ b/vcl/inc/skia/win/gdiimpl.hxx
@@ -31,21 +31,7 @@ class SkiaCompatibleDC : public CompatibleDC
public:
SkiaCompatibleDC(SalGraphics& rGraphics, int x, int y, int width, int height);
- virtual std::unique_ptr<Texture> getAsMaskTexture() const override;
-
- sk_sp<SkImage> getAsImage() const;
- sk_sp<SkImage> getAsMaskImage() const;
sk_sp<SkImage> getAsImageDiff(const SkiaCompatibleDC& white) const;
-
- struct Texture;
-};
-
-struct SkiaCompatibleDC::Texture : public CompatibleDC::Texture
-{
- sk_sp<SkImage> image;
- virtual bool isValid() const { return image.get(); }
- virtual int GetWidth() const { return image->width(); }
- virtual int GetHeight() const { return image->height(); }
};
class WinSkiaSalGraphicsImpl : public SkiaSalGraphicsImpl, public WinSalGraphicsImplBase
diff --git a/vcl/inc/win/saldata.hxx b/vcl/inc/win/saldata.hxx
index 8d2935216d87..80286d87d347 100644
--- a/vcl/inc/win/saldata.hxx
+++ b/vcl/inc/win/saldata.hxx
@@ -42,7 +42,6 @@ class WinSalFrame;
class WinSalVirtualDevice;
class WinSalPrinter;
namespace vcl { class Font; }
-struct GlobalWinGlyphCache;
struct HDCCache;
struct TempFontItem;
class TextOutRenderer;
@@ -128,7 +127,6 @@ public:
std::unique_ptr<TextOutRenderer> m_pD2DWriteTextOutRenderer;
// tdf#107205 need 2 instances because D2DWrite can't rotate text
std::unique_ptr<TextOutRenderer> m_pExTextOutRenderer;
- std::unique_ptr<GlobalWinGlyphCache> m_pGlobalWinGlyphCache;
#if HAVE_FEATURE_SKIA
std::unique_ptr<SkiaControlsCache> m_pSkiaControlsCache;
#endif
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index c01e9794160b..52b04aaf26b9 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -135,20 +135,6 @@ public:
/// Reset the DC with the defined color.
void fill(sal_uInt32 color);
-
- /// Base texture class (OpenGL and Skia will provide their implementations).
- struct Texture;
-
- /// Obtain the texture in format for WinSalGraphicsImplBase::DrawTextMask().
- virtual std::unique_ptr<Texture> getAsMaskTexture() const { abort(); };
-};
-
-struct CompatibleDC::Texture
-{
- virtual ~Texture() {};
- virtual bool isValid() const = 0;
- virtual int GetWidth() const = 0;
- virtual int GetHeight() const = 0;
};
class WinSalGraphics : public SalGraphics
@@ -179,9 +165,6 @@ private:
RGNDATA* mpStdClipRgnData; // Cache Standard-ClipRegion-Data
int mnPenWidth; // line width
- bool CacheGlyphs(const GenericSalLayout& rLayout);
- bool DrawCachedGlyphs(const GenericSalLayout& rLayout);
-
public:
HFONT ImplDoSetFont(FontSelectPattern const & i_rFont, const PhysicalFontFace * i_pFontFace, HFONT& o_rOldFont);
diff --git a/vcl/inc/win/wingdiimpl.hxx b/vcl/inc/win/wingdiimpl.hxx
index 2b1355cae9bf..6fc08f0a355a 100644
--- a/vcl/inc/win/wingdiimpl.hxx
+++ b/vcl/inc/win/wingdiimpl.hxx
@@ -42,20 +42,6 @@ public:
// Implementation for WinSalGraphics::DrawTextLayout().
// Returns true if handled, if false, then WinSalGraphics will handle it itself.
virtual bool DrawTextLayout(const GenericSalLayout&) { return false; }
- // If true is returned, the following functions are used for text rendering.
- virtual bool UseTextDraw() const { return false; }
- virtual void PreDrawText() {}
- virtual void PostDrawText() {}
- virtual void DrawTextMask(CompatibleDC::Texture* /*rTexture*/, Color /*nMaskColor*/,
- const SalTwoRect& /*rPosAry*/)
- {
- abort();
- };
- virtual void DeferredTextDraw(const CompatibleDC::Texture* /*pTexture*/, Color /*nMaskColor*/,
- const SalTwoRect& /*rPosAry*/)
- {
- abort();
- };
};
#endif // INCLUDED_VCL_INC_WIN_WINGDIIMPL_HXX
diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx
index 35a855a3722e..b4e51d8dc4bb 100644
--- a/vcl/inc/win/winlayout.hxx
+++ b/vcl/inc/win/winlayout.hxx
@@ -27,90 +27,6 @@
#include <win/salgdi.h>
#include <o3tl/sorted_vector.hxx>
-class WinFontInstance;
-
-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 WinGlyphDrawElement
-{
- tools::Rectangle maLocation;
- int maLeftOverhangs;
- std::unique_ptr<CompatibleDC::Texture> maTexture;
- int mnBaselineOffset;
- int mnHeight;
- bool mbVertical;
-
- int getExtraSpace() const
- {
- return std::max(mnHeight / GLYPH_SPACE_RATIO, 4);
- }
-
- int getExtraOffset() const
- {
- return std::max(mnHeight / GLYPH_OFFSET_RATIO, 2);
- }
-};
-
-class WinGlyphCache;
-
-struct GlobalWinGlyphCache
-{
- o3tl::sorted_vector<WinGlyphCache*> maWinGlyphCaches;
-
- static GlobalWinGlyphCache * get();
-
- virtual ~GlobalWinGlyphCache() {}
- virtual bool AllocateTexture(WinGlyphDrawElement& rElement, CompatibleDC* dc) = 0;
- virtual void NotifyElementUsed(WinGlyphDrawElement& /*rElement*/) {}
- virtual void Prune() {}
-};
-
-class WinGlyphCache
-{
-protected:
- std::unordered_map<int, WinGlyphDrawElement> maWinTextureCache;
-
-public:
- WinGlyphCache()
- {
- if(GlobalWinGlyphCache* c = GlobalWinGlyphCache::get())
- c->maWinGlyphCaches.insert(this);
- }
-
- virtual ~WinGlyphCache()
- {
- if(GlobalWinGlyphCache* c = GlobalWinGlyphCache::get())
- c->maWinGlyphCaches.erase(this);
- }
-
- void PutDrawElementInCache(WinGlyphDrawElement&& rElement, int nGlyphIndex)
- {
- assert(GlobalWinGlyphCache::get());
- assert(!IsGlyphCached(nGlyphIndex));
- maWinTextureCache[nGlyphIndex] = std::move( rElement );
- }
-
- WinGlyphDrawElement& GetDrawElement(int nGlyphIndex)
- {
- assert(GlobalWinGlyphCache::get());
- assert(IsGlyphCached(nGlyphIndex));
- WinGlyphDrawElement& element = maWinTextureCache[nGlyphIndex];
- GlobalWinGlyphCache::get()->NotifyElementUsed(element);
- return element;
- }
-
- bool IsGlyphCached(int nGlyphIndex) const
- {
- return maWinTextureCache.find(nGlyphIndex) != maWinTextureCache.end();
- }
-};
-
// win32 specific logical font instance
class WinFontInstance : public LogicalFontInstance
{
@@ -135,9 +51,6 @@ public:
const WinFontFace * GetFontFace() const { return static_cast<const WinFontFace *>(LogicalFontInstance::GetFontFace()); }
WinFontFace * GetFontFace() { return static_cast<WinFontFace *>(LogicalFontInstance::GetFontFace()); }
- bool CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, SalGraphics& rGraphics, const GenericSalLayout& rLayout);
- WinGlyphCache& GetWinGlyphCache() { return maWinGlyphCache; }
-
bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const override;
private:
@@ -149,7 +62,6 @@ private:
WinSalGraphics *m_pGraphics;
HFONT m_hFont;
float m_fScale;
- WinGlyphCache maWinGlyphCache;
};
class TextOutRenderer
diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx
index d170fa121ec8..054555ca6e41 100644
--- a/vcl/skia/win/gdiimpl.cxx
+++ b/vcl/skia/win/gdiimpl.cxx
@@ -256,73 +256,6 @@ SkiaCompatibleDC::SkiaCompatibleDC(SalGraphics& rGraphics, int x, int y, int wid
{
}
-std::unique_ptr<CompatibleDC::Texture> SkiaCompatibleDC::getAsMaskTexture() const
-{
- auto ret = std::make_unique<SkiaCompatibleDC::Texture>();
- ret->image = getAsMaskImage();
- return ret;
-}
-
-sk_sp<SkImage> SkiaCompatibleDC::getAsMaskImage() const
-{
- SkiaZone zone;
- // mpData is in the BGRA format, with A unused (and set to 0), and RGB are grey,
- // so convert it to Skia format, then to 8bit and finally use as alpha mask
- SkBitmap tmpBitmap;
- if (!tmpBitmap.installPixels(SkImageInfo::Make(maRects.mnSrcWidth, maRects.mnSrcHeight,
- kBGRA_8888_SkColorType, kOpaque_SkAlphaType),
- mpData, maRects.mnSrcWidth * 4))
- abort();
- tmpBitmap.setImmutable();
- SkBitmap bitmap8;
- if (!bitmap8.tryAllocPixels(SkImageInfo::Make(maRects.mnSrcWidth, maRects.mnSrcHeight,
- kGray_8_SkColorType, kOpaque_SkAlphaType)))
- abort();
- SkCanvas canvas8(bitmap8);
- SkPaint paint8;
- paint8.setBlendMode(SkBlendMode::kSrc); // copy and convert depth
- // The data we got is upside-down.
- SkMatrix matrix;
- matrix.preTranslate(0, maRects.mnSrcHeight);
- matrix.setConcat(matrix, SkMatrix::Scale(1, -1));
- canvas8.concat(matrix);
- canvas8.drawBitmap(tmpBitmap, 0, 0, &paint8);
- bitmap8.setImmutable();
- // use the 8bit data as an alpha channel
- SkBitmap alpha;
- alpha.setInfo(bitmap8.info().makeColorType(kAlpha_8_SkColorType), bitmap8.rowBytes());
- alpha.setPixelRef(sk_ref_sp(bitmap8.pixelRef()), bitmap8.pixelRefOrigin().x(),
- bitmap8.pixelRefOrigin().y());
- alpha.setImmutable();
- return SkiaHelper::createSkImage(alpha);
-}
-
-sk_sp<SkImage> SkiaCompatibleDC::getAsImage() const
-{
- SkiaZone zone;
- SkBitmap tmpBitmap;
- if (!tmpBitmap.installPixels(SkImageInfo::Make(maRects.mnSrcWidth, maRects.mnSrcHeight,
- kBGRA_8888_SkColorType, kUnpremul_SkAlphaType),
- mpData, maRects.mnSrcWidth * 4))
- abort();
- tmpBitmap.setImmutable();
- sk_sp<SkSurface> surface = SkiaHelper::createSkSurface(tmpBitmap.width(), tmpBitmap.height());
- SkPaint paint;
- paint.setBlendMode(SkBlendMode::kSrc); // set as is, including alpha
- SkCanvas* canvas = surface->getCanvas();
- canvas->save();
- // The data we got is upside-down.
- SkMatrix matrix;
- matrix.preTranslate(0, maRects.mnSrcHeight);
- matrix.setConcat(matrix, SkMatrix::Scale(1, -1));
- canvas->concat(matrix);
- canvas->drawBitmapRect(tmpBitmap,
- SkRect::MakeXYWH(0, 0, maRects.mnSrcWidth, maRects.mnSrcHeight),
- SkRect::MakeXYWH(0, 0, maRects.mnSrcWidth, maRects.mnSrcHeight), &paint);
- canvas->restore();
- return SkiaHelper::makeCheckedImageSnapshot(surface);
-}
-
sk_sp<SkImage> SkiaCompatibleDC::getAsImageDiff(const SkiaCompatibleDC& white) const
{
SkiaZone zone;
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index e0e375032280..760ef40ab986 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -53,153 +53,6 @@
#include <shlwapi.h>
#include <winver.h>
-GlobalWinGlyphCache* GlobalWinGlyphCache::get()
-{
- SalData* data = GetSalData();
- if (!data->m_pGlobalWinGlyphCache)
- {
- }
- return data->m_pGlobalWinGlyphCache.get();
-}
-
-bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex,
- SalGraphics& rGraphics, const GenericSalLayout& rLayout)
-{
- WinGlyphDrawElement aElement;
-
- ScopedHDC aHDC(CreateCompatibleDC(hDC));
-
- if (!aHDC)
- {
- SAL_WARN("vcl.gdi", "CreateCompatibleDC failed: " << WindowsErrorString(GetLastError()));
- return false;
- }
-
- const HFONT hOrigFont = static_cast<HFONT>(SelectObject(aHDC.get(), hFont));
- if (hOrigFont == nullptr)
- {
- SAL_WARN("vcl.gdi", "SelectObject failed: " << WindowsErrorString(GetLastError()));
- return false;
- }
- const ::comphelper::ScopeGuard aHFONTrestoreScopeGuard(
- [&aHDC, hOrigFont]() { SelectFont(aHDC.get(), hOrigFont); });
-
- // For now we assume DWrite is present and we won't bother with fallback paths.
- D2DWriteTextOutRenderer* pTxt
- = dynamic_cast<D2DWriteTextOutRenderer*>(&TextOutRenderer::get(true));
- if (!pTxt)
- return false;
-
- pTxt->changeTextAntiAliasMode(D2DTextAntiAliasMode::AntiAliased);
-
- if (!pTxt->BindFont(aHDC.get()))
- {
- SAL_WARN("vcl.gdi",
- "Binding of font failed. The font might not be supported by DirectWrite.");
- return false;
- }
- const ::comphelper::ScopeGuard aFontReleaseScopeGuard([&pTxt]() { pTxt->ReleaseFont(); });
-
- std::vector<WORD> aGlyphIndices(1);
- aGlyphIndices[0] = nGlyphIndex;
- // Fetch the ink boxes and calculate the size of the atlas.
- tools::Rectangle bounds(0, 0, 0, 0);
- auto aInkBoxes = pTxt->GetGlyphInkBoxes(aGlyphIndices.data(), aGlyphIndices.data() + 1);
- if (aInkBoxes.empty())
- return false;
-
- for (auto& box : aInkBoxes)
- bounds.Union(box + Point(bounds.Right(), 0));
-
- // bounds.Top() is the offset from the baseline at (0,0) to the top of the
- // inkbox.
- aElement.mnBaselineOffset = -bounds.Top();
- aElement.mnHeight = bounds.getHeight();
- aElement.mbVertical = false;
-
- // Try hard to avoid overlap as we want to be able to use
- // individual rectangles for each glyph. The ABC widths don't
- // take anti-aliasing into consideration. Let's hope that leaving
- // "extra" space between glyphs will help.
- std::vector<float> aGlyphAdv(1); // offsets between glyphs
- std::vector<DWRITE_GLYPH_OFFSET> aGlyphOffset(1, { 0.0f, 0.0f });
- std::vector<int> aEnds(1); // end of each glyph box
- float fHScale = getHScale();
- float totWidth = 0;
- {
- int overhang = aInkBoxes[0].Left();
- int blackWidth = aInkBoxes[0].getWidth() * fHScale; // width of non-AA pixels
- aElement.maLeftOverhangs = overhang;
-
- aGlyphAdv[0] = blackWidth + aElement.getExtraSpace();
- aGlyphOffset[0].advanceOffset = -overhang;
-
- totWidth += aGlyphAdv[0];
- aEnds[0] = totWidth;
- }
- // Leave extra space also at top and bottom
- int nBitmapWidth = totWidth;
- int nBitmapHeight = bounds.getHeight() + aElement.getExtraSpace();
-
- UINT nPos = 0;
-
- aElement.maLocation.SetLeft(nPos);
- aElement.maLocation.SetRight(aEnds[0]);
- aElement.maLocation.SetTop(0);
- aElement.maLocation.SetBottom(bounds.getHeight() + aElement.getExtraSpace());
- nPos = aEnds[0];
-
- std::unique_ptr<CompatibleDC> aDC(
- CompatibleDC::create(rGraphics, 0, 0, nBitmapWidth, nBitmapHeight));
-
- SetTextColor(aDC->getCompatibleHDC(), RGB(0, 0, 0));
- SetBkColor(aDC->getCompatibleHDC(), RGB(255, 255, 255));
-
- aDC->fill(RGB(0xff, 0xff, 0xff));
-
- pTxt->BindDC(aDC->getCompatibleHDC(), tools::Rectangle(0, 0, nBitmapWidth, nBitmapHeight));
- auto pRT = pTxt->GetRenderTarget();
-
- ID2D1SolidColorBrush* pBrush = nullptr;
- if (!SUCCEEDED(pRT->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &pBrush)))
- return false;
-
- D2D1_POINT_2F baseline
- = { static_cast<FLOAT>(aElement.getExtraOffset()),
- static_cast<FLOAT>(aElement.getExtraOffset() + aElement.mnBaselineOffset) };
-
- DWRITE_GLYPH_RUN glyphs
- = { pTxt->GetFontFace(), pTxt->GetEmHeight(), 1, aGlyphIndices.data(),
- aGlyphAdv.data(), aGlyphOffset.data(), false, 0 };
-
- WinFontTransformGuard aTransformGuard(pRT, fHScale, rLayout, baseline);
- pRT->BeginDraw();
- pRT->DrawGlyphRun(baseline, &glyphs, pBrush);
- HRESULT hResult = pRT->EndDraw();
-
- pBrush->Release();
-
- switch (hResult)
- {
- case S_OK:
- break;
- case D2DERR_RECREATE_TARGET:
- pTxt->CreateRenderTarget();
- break;
- default:
- SAL_WARN("vcl.gdi",
- "DrawGlyphRun-EndDraw failed: " << WindowsErrorString(GetLastError()));
- return false;
- }
-
- if (!GlobalWinGlyphCache::get()->AllocateTexture(aElement, aDC.get()))
- return false;
-
- maWinGlyphCache.PutDrawElementInCache(std::move(aElement), nGlyphIndex);
-
- return true;
-}
-
TextOutRenderer& TextOutRenderer::get(bool bUseDWrite)
{
SalData* const pSalData = GetSalData();
@@ -443,75 +296,6 @@ void WinFontInstance::SetGraphics(WinSalGraphics* pGraphics)
SelectObject(m_pGraphics->getHDC(), hOrigFont);
}
-bool WinSalGraphics::CacheGlyphs(const GenericSalLayout& rLayout)
-{
- static bool bDoGlyphCaching = (std::getenv("SAL_DISABLE_GLYPH_CACHING") == nullptr);
- if (!bDoGlyphCaching)
- return false;
-
- if (rLayout.GetOrientation())
- // Our caching is incomplete, skip it for non-horizontal text.
- return false;
-
- HDC hDC = getHDC();
- WinFontInstance& rFont = *static_cast<WinFontInstance*>(&rLayout.GetFont());
- HFONT hFONT = rFont.GetHFONT();
-
- int nStart = 0;
- Point aPos(0, 0);
- const GlyphItem* pGlyph;
- while (rLayout.GetNextGlyph(&pGlyph, aPos, nStart))
- {
- if (!rFont.GetWinGlyphCache().IsGlyphCached(pGlyph->glyphId()))
- {
- if (!rFont.CacheGlyphToAtlas(hDC, hFONT, pGlyph->glyphId(), *this, rLayout))
- return false;
- }
- }
-
- return true;
-}
-
-bool WinSalGraphics::DrawCachedGlyphs(const GenericSalLayout& rLayout)
-{
- HDC hDC = getHDC();
-
- tools::Rectangle aRect;
- rLayout.GetBoundRect(aRect);
-
- COLORREF color = GetTextColor(hDC);
- Color salColor(GetRValue(color), GetGValue(color), GetBValue(color));
-
- WinSalGraphicsImplBase* pImpl = dynamic_cast<WinSalGraphicsImplBase*>(mpImpl.get());
- if (!pImpl->UseTextDraw())
- return false;
-
- WinFontInstance& rFont = *static_cast<WinFontInstance*>(&rLayout.GetFont());
-
- int nStart = 0;
- Point aPos(0, 0);
- const GlyphItem* pGlyph;
- while (rLayout.GetNextGlyph(&pGlyph, aPos, nStart))
- {
- WinGlyphDrawElement& rElement(rFont.GetWinGlyphCache().GetDrawElement(pGlyph->glyphId()));
- const CompatibleDC::Texture* texture = rElement.maTexture.get();
-
- if (!texture || !texture->isValid())
- return false;
-
- SalTwoRect a2Rects(0, 0, texture->GetWidth(), texture->GetHeight(),
- aPos.X() - rElement.getExtraOffset() + rElement.maLeftOverhangs,
- aPos.Y() - rElement.mnBaselineOffset - rElement.getExtraOffset(),
- texture->GetWidth(), texture->GetHeight());
-
- pImpl->DeferredTextDraw(texture, salColor, a2Rects);
- }
-
- return true;
-}
-
-static void PruneGlyphCache() { GlobalWinGlyphCache::get()->Prune(); }
-
void WinSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout, HDC hDC, bool bUseDWrite)
{
TextOutRenderer& render = TextOutRenderer::get(bUseDWrite);
@@ -527,100 +311,10 @@ void WinSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout)
HDC hDC = getHDC();
const WinFontInstance* pWinFont = static_cast<const WinFontInstance*>(&rLayout.GetFont());
const HFONT hLayoutFont = pWinFont->GetHFONT();
- bool bUseClassic = !pImpl->UseTextDraw() || mbPrinter;
-
- // Our DirectWrite renderer is incomplete, skip it for vertical text where glyphs are not
- // rotated.
- bool bForceGDI = rLayout.GetFont().GetFontSelectPattern().mbVertical;
- if (bUseClassic)
- {
- // no OpenGL, just classic rendering
- const HFONT hOrigFont = ::SelectFont(hDC, hLayoutFont);
- DrawTextLayout(rLayout, hDC, false);
- ::SelectFont(hDC, hOrigFont);
- }
- // if we can't draw the cached OpenGL glyphs, try to draw a full OpenGL layout
- else if (!bForceGDI && CacheGlyphs(rLayout) && DrawCachedGlyphs(rLayout))
- {
- PruneGlyphCache();
- }
- else
- {
- PruneGlyphCache(); // prune the cache from the failed calls above
-
- // We have to render the text to a hidden texture, and draw it.
- //
- // Note that Windows GDI does not really support the alpha correctly
- // when drawing - ie. it draws nothing to the alpha channel when
- // rendering the text, even the antialiasing is done as 'real' pixels,
- // not alpha...
- //
- // Luckily, this does not really limit us:
- //
- // To blend properly, we draw the texture, but then use it as an alpha
- // channel for solid color (that will define the text color). This
- // destroys the subpixel antialiasing - turns it into 'classic'
- // antialiasing - but that is the best we can do, because the subpixel
- // antialiasing needs to know what is in the background: When the
- // background is white, or white-ish, it does the subpixel, but when
- // there is a color, it just darkens the color (and does this even
- // when part of the character is on a colored background, and part on
- // white). It has to work this way, the results would look strange
- // otherwise.
- //
- // For the GL rendering to work even with the subpixel antialiasing,
- // we would need to get the current texture from the screen, let GDI
- // draw the text to it (so that it can decide well where to use the
- // subpixel and where not), and draw the result - but in that case we
- // don't need alpha anyway.
- //
- // TODO: check the performance of this 2nd approach at some stage and
- // switch to that if it performs well.
-
- tools::Rectangle aRect;
- rLayout.GetBoundRect(aRect);
- if (aRect.IsEmpty())
- return;
-
- pImpl->PreDrawText();
-
- std::unique_ptr<CompatibleDC> aDC(CompatibleDC::create(
- *this, aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight()));
-
- // we are making changes to the DC, make sure we got a new one
- assert(aDC->getCompatibleHDC() != hDC);
-
- RECT aWinRect = { o3tl::narrowing<LONG>(aRect.Left()), o3tl::narrowing<LONG>(aRect.Top()),
- o3tl::narrowing<LONG>(aRect.Left() + aRect.GetWidth()),
- o3tl::narrowing<LONG>(aRect.Top() + aRect.GetHeight()) };
- ::FillRect(aDC->getCompatibleHDC(), &aWinRect,
- static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH)));
-
- // setup the hidden DC with black color and white background, we will
- // use the result of the text drawing later as a mask only
- const HFONT hOrigFont = ::SelectFont(aDC->getCompatibleHDC(), hLayoutFont);
-
- ::SetTextColor(aDC->getCompatibleHDC(), RGB(0, 0, 0));
- ::SetBkColor(aDC->getCompatibleHDC(), RGB(255, 255, 255));
-
- UINT nTextAlign = ::GetTextAlign(hDC);
- ::SetTextAlign(aDC->getCompatibleHDC(), nTextAlign);
-
- COLORREF color = ::GetTextColor(hDC);
- Color salColor(GetRValue(color), GetGValue(color), GetBValue(color));
-
- // the actual drawing
- DrawTextLayout(rLayout, aDC->getCompatibleHDC(), !bForceGDI);
-
- std::unique_ptr<CompatibleDC::Texture> xTexture(aDC->getAsMaskTexture());
- if (xTexture)
- pImpl->DrawTextMask(xTexture.get(), salColor, aDC->getTwoRect());
-
- ::SelectFont(aDC->getCompatibleHDC(), hOrigFont);
-
- pImpl->PostDrawText();
- }
+ const HFONT hOrigFont = ::SelectFont(hDC, hLayoutFont);
+ DrawTextLayout(rLayout, hDC, false);
+ ::SelectFont(hDC, hOrigFont);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list