Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / vcl / inc / win / winlayout.hxx
blobe070ef5a724912003ed089d7050d425c76f42693
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_VCL_INC_WIN_WINLAYOUT_HXX
21 #define INCLUDED_VCL_INC_WIN_WINLAYOUT_HXX
23 #include <rtl/ustring.hxx>
25 #include <sallayout.hxx>
26 #include <svsys.h>
27 #include <win/salgdi.h>
29 #include <usp10.h>
30 #include <d2d1.h>
31 #include <dwrite.h>
33 #include "opengl/PackedTextureAtlas.hxx"
35 class WinFontInstance;
37 namespace
39 // Extra space at the top and bottom of the glyph in total = tmHeight / GLYPH_SPACE_RATIO;
40 const int GLYPH_SPACE_RATIO = 8;
41 // Border size at the top of the glyph = tmHeight / GLYPH_OFFSET_RATIO;
42 const int GLYPH_OFFSET_RATIO = GLYPH_SPACE_RATIO * 2;
45 struct OpenGLGlyphDrawElement
47 tools::Rectangle maLocation;
48 int maLeftOverhangs;
49 OpenGLTexture maTexture;
50 int mnBaselineOffset;
51 int mnHeight;
52 bool mbVertical;
54 int getExtraSpace() const
56 return std::max(mnHeight / GLYPH_SPACE_RATIO, 4);
59 int getExtraOffset() const
61 return std::max(mnHeight / GLYPH_OFFSET_RATIO, 2);
65 class GlyphCache;
67 struct GlobalGlyphCache
69 GlobalGlyphCache()
70 : maPackedTextureAtlas(2048, 2048)
73 PackedTextureAtlasManager maPackedTextureAtlas;
74 std::unordered_set<GlyphCache*> maGlyphCaches;
76 static GlobalGlyphCache * get();
79 class GlyphCache
81 private:
82 std::unordered_map<int, OpenGLGlyphDrawElement> maOpenGLTextureCache;
84 public:
85 GlyphCache()
87 GlobalGlyphCache::get()->maGlyphCaches.insert(this);
90 ~GlyphCache()
92 GlobalGlyphCache::get()->maGlyphCaches.erase(this);
95 static bool ReserveTextureSpace(OpenGLGlyphDrawElement& rElement, int nWidth, int nHeight)
97 GlobalGlyphCache* pGlobalGlyphCache = GlobalGlyphCache::get();
98 rElement.maTexture = pGlobalGlyphCache->maPackedTextureAtlas.Reserve(nWidth, nHeight);
99 if (!rElement.maTexture)
100 return false;
101 std::vector<GLuint> aTextureIDs = pGlobalGlyphCache->maPackedTextureAtlas.ReduceTextureNumber(8);
102 if (!aTextureIDs.empty())
104 for (auto& pGlyphCache: pGlobalGlyphCache->maGlyphCaches)
106 pGlyphCache->RemoveTextures(aTextureIDs);
109 return true;
112 void RemoveTextures(std::vector<GLuint>& rTextureIDs)
114 auto it = maOpenGLTextureCache.begin();
116 while (it != maOpenGLTextureCache.end())
118 GLuint nTextureID = it->second.maTexture.Id();
120 if (std::find(rTextureIDs.begin(), rTextureIDs.end(), nTextureID) != rTextureIDs.end())
122 it = maOpenGLTextureCache.erase(it);
124 else
126 ++it;
131 void PutDrawElementInCache(const OpenGLGlyphDrawElement& rElement, int nGlyphIndex)
133 assert(!IsGlyphCached(nGlyphIndex));
134 maOpenGLTextureCache[nGlyphIndex] = OpenGLGlyphDrawElement(rElement);
137 OpenGLGlyphDrawElement& GetDrawElement(int nGlyphIndex)
139 assert(IsGlyphCached(nGlyphIndex));
140 return maOpenGLTextureCache[nGlyphIndex];
143 bool IsGlyphCached(int nGlyphIndex) const
145 return maOpenGLTextureCache.find(nGlyphIndex) != maOpenGLTextureCache.end();
149 // win32 specific physical font instance
150 class WinFontInstance : public LogicalFontInstance
152 public:
153 explicit WinFontInstance( FontSelectPattern& );
154 virtual ~WinFontInstance() override;
156 private:
157 // TODO: also add HFONT??? Watch out for issues with too many active fonts...
159 GlyphCache maGlyphCache;
160 public:
161 bool CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, SalGraphics& rGraphics);
163 GlyphCache& GetGlyphCache()
165 return maGlyphCache;
169 class TextOutRenderer
171 protected:
172 explicit TextOutRenderer() = default;
173 TextOutRenderer(const TextOutRenderer &) = delete;
174 TextOutRenderer & operator = (const TextOutRenderer &) = delete;
176 public:
177 static TextOutRenderer & get(bool bUseDWrite);
179 virtual ~TextOutRenderer() = default;
181 virtual bool operator ()(CommonSalLayout const &rLayout,
182 SalGraphics &rGraphics,
183 HDC hDC) = 0;
186 class ExTextOutRenderer : public TextOutRenderer
188 ExTextOutRenderer(const ExTextOutRenderer &) = delete;
189 ExTextOutRenderer & operator = (const ExTextOutRenderer &) = delete;
191 public:
192 explicit ExTextOutRenderer() = default;
194 bool operator ()(CommonSalLayout const &rLayout,
195 SalGraphics &rGraphics,
196 HDC hDC) override;
199 enum class D2DTextAntiAliasMode
201 Default,
202 Aliased,
203 AntiAliased,
204 ClearType,
207 class D2DWriteTextOutRenderer : public TextOutRenderer
209 typedef HRESULT(WINAPI *pD2D1CreateFactory_t)(D2D1_FACTORY_TYPE,
210 REFIID, const D2D1_FACTORY_OPTIONS *, void **);
212 typedef HRESULT(WINAPI *pDWriteCreateFactory_t)(DWRITE_FACTORY_TYPE,
213 REFIID, IUnknown **);
215 static HINSTANCE mmD2d1, mmDWrite;
216 static pD2D1CreateFactory_t D2D1CreateFactory;
217 static pDWriteCreateFactory_t DWriteCreateFactory;
219 public:
220 static bool InitModules();
222 explicit D2DWriteTextOutRenderer();
223 virtual ~D2DWriteTextOutRenderer() override;
225 bool operator ()(CommonSalLayout const &rLayout,
226 SalGraphics &rGraphics,
227 HDC hDC) override;
229 HRESULT BindDC(HDC hDC, tools::Rectangle const & rRect = tools::Rectangle(0, 0, 1, 1));
231 bool BindFont(HDC hDC) /*override*/;
232 bool ReleaseFont() /*override*/;
234 std::vector<tools::Rectangle> GetGlyphInkBoxes(uint16_t * pGid, uint16_t * pGidEnd) const /*override*/;
235 ID2D1RenderTarget * GetRenderTarget() const { return mpRT; }
236 IDWriteFontFace * GetFontFace() const { return mpFontFace; }
237 float GetEmHeight() const { return mlfEmHeight; }
239 HRESULT CreateRenderTarget();
241 bool Ready() const { return mpGdiInterop && mpRT; }
243 void applyTextAntiAliasMode();
244 void changeTextAntiAliasMode(D2DTextAntiAliasMode eMode);
246 private:
247 static void CleanupModules();
249 // This is a singleton object disable copy ctor and assignment operator
250 D2DWriteTextOutRenderer(const D2DWriteTextOutRenderer &) = delete;
251 D2DWriteTextOutRenderer & operator = (const D2DWriteTextOutRenderer &) = delete;
253 bool GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** ppFontFace, float * lfSize) const;
254 bool performRender(CommonSalLayout const &rLayout, SalGraphics &rGraphics, HDC hDC, bool& bRetry);
256 ID2D1Factory * mpD2DFactory;
257 IDWriteFactory * mpDWriteFactory;
258 IDWriteGdiInterop * mpGdiInterop;
259 ID2D1DCRenderTarget * mpRT;
260 const D2D1_RENDER_TARGET_PROPERTIES mRTProps;
262 IDWriteFontFace * mpFontFace;
263 float mlfEmHeight;
264 HDC mhDC;
265 D2DTextAntiAliasMode meTextAntiAliasMode;
266 IDWriteRenderingParams* mpRenderingParameters;
269 #endif // INCLUDED_VCL_INC_WIN_WINLAYOUT_HXX
271 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */