1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
27 #include <win/salgdi.h>
33 #include "opengl/PackedTextureAtlas.hxx"
35 class WinFontInstance
;
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
;
49 OpenGLTexture maTexture
;
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);
67 struct GlobalGlyphCache
70 : maPackedTextureAtlas(2048, 2048)
73 PackedTextureAtlasManager maPackedTextureAtlas
;
74 std::unordered_set
<GlyphCache
*> maGlyphCaches
;
76 static GlobalGlyphCache
* get();
82 std::unordered_map
<int, OpenGLGlyphDrawElement
> maOpenGLTextureCache
;
87 GlobalGlyphCache::get()->maGlyphCaches
.insert(this);
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
)
101 std::vector
<GLuint
> aTextureIDs
= pGlobalGlyphCache
->maPackedTextureAtlas
.ReduceTextureNumber(8);
102 if (!aTextureIDs
.empty())
104 for (auto& pGlyphCache
: pGlobalGlyphCache
->maGlyphCaches
)
106 pGlyphCache
->RemoveTextures(aTextureIDs
);
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
);
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
153 explicit WinFontInstance( FontSelectPattern
& );
154 virtual ~WinFontInstance() override
;
157 // TODO: also add HFONT??? Watch out for issues with too many active fonts...
159 GlyphCache maGlyphCache
;
161 bool CacheGlyphToAtlas(HDC hDC
, HFONT hFont
, int nGlyphIndex
, SalGraphics
& rGraphics
);
163 GlyphCache
& GetGlyphCache()
169 class TextOutRenderer
172 explicit TextOutRenderer() = default;
173 TextOutRenderer(const TextOutRenderer
&) = delete;
174 TextOutRenderer
& operator = (const TextOutRenderer
&) = delete;
177 static TextOutRenderer
& get(bool bUseDWrite
);
179 virtual ~TextOutRenderer() = default;
181 virtual bool operator ()(CommonSalLayout
const &rLayout
,
182 SalGraphics
&rGraphics
,
186 class ExTextOutRenderer
: public TextOutRenderer
188 ExTextOutRenderer(const ExTextOutRenderer
&) = delete;
189 ExTextOutRenderer
& operator = (const ExTextOutRenderer
&) = delete;
192 explicit ExTextOutRenderer() = default;
194 bool operator ()(CommonSalLayout
const &rLayout
,
195 SalGraphics
&rGraphics
,
199 enum class D2DTextAntiAliasMode
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
;
220 static bool InitModules();
222 explicit D2DWriteTextOutRenderer();
223 virtual ~D2DWriteTextOutRenderer() override
;
225 bool operator ()(CommonSalLayout
const &rLayout
,
226 SalGraphics
&rGraphics
,
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
);
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
;
265 D2DTextAntiAliasMode meTextAntiAliasMode
;
266 IDWriteRenderingParams
* mpRenderingParameters
;
269 #endif // INCLUDED_VCL_INC_WIN_WINLAYOUT_HXX
271 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */