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.lu...@centrum.cz> AuthorDate: Fri Dec 4 20:25:06 2020 +0000 Commit: Luboš Luňák <l.lu...@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.lu...@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: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits