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 #include <sal/config.h>
22 #include <QtGraphics.hxx>
23 #include <QtFontFace.hxx>
25 #include <QtPainter.hxx>
27 #include <vcl/fontcharmap.hxx>
28 #include <unx/geninst.h>
29 #include <unx/fontmanager.hxx>
30 #include <unx/glyphcache.hxx>
31 #include <unx/genpspgraphics.h>
33 #include <sallayout.hxx>
34 #include <font/PhysicalFontCollection.hxx>
36 #include <QtGui/QGlyphRun>
37 #include <QtGui/QFontDatabase>
38 #include <QtGui/QRawFont>
39 #include <QtCore/QStringList>
41 void QtGraphics::SetTextColor(Color nColor
) { m_aTextColor
= nColor
; }
43 void QtGraphics::SetFont(LogicalFontInstance
* pReqFont
, int nFallbackLevel
)
45 // release the text styles
46 for (int i
= nFallbackLevel
; i
< MAX_FALLBACK
; ++i
)
50 m_pTextStyle
[i
].clear();
56 m_pTextStyle
[nFallbackLevel
] = static_cast<QtFont
*>(pReqFont
);
59 void QtGraphics::GetFontMetric(ImplFontMetricDataRef
& rFMD
, int nFallbackLevel
)
61 QRawFont
aRawFont(QRawFont::fromFont(*m_pTextStyle
[nFallbackLevel
]));
62 QtFontFace::fillAttributesFromQFont(*m_pTextStyle
[nFallbackLevel
], *rFMD
);
64 rFMD
->ImplCalcLineSpacing(m_pTextStyle
[nFallbackLevel
].get());
65 rFMD
->ImplInitBaselines(m_pTextStyle
[nFallbackLevel
].get());
68 rFMD
->SetWidth(aRawFont
.averageCharWidth());
70 rFMD
->SetMinKashida(m_pTextStyle
[nFallbackLevel
]->GetKashidaWidth());
73 FontCharMapRef
QtGraphics::GetFontCharMap() const
76 return FontCharMapRef(new FontCharMap());
77 return m_pTextStyle
[0]->GetFontFace()->GetFontCharMap();
80 bool QtGraphics::GetFontCapabilities(vcl::FontCapabilities
& rFontCapabilities
) const
84 return m_pTextStyle
[0]->GetFontFace()->GetFontCapabilities(rFontCapabilities
);
87 void QtGraphics::GetDevFontList(vcl::font::PhysicalFontCollection
* pPFC
)
89 static const bool bUseFontconfig
= (nullptr == getenv("SAL_VCL_QT5_NO_FONTCONFIG"));
94 FreetypeManager
& rFontManager
= FreetypeManager::get();
95 psp::PrintFontManager
& rMgr
= psp::PrintFontManager::get();
96 ::std::vector
<psp::fontID
> aList
;
97 psp::FastPrintFontInfo aInfo
;
99 rMgr
.getFontList(aList
);
100 for (auto const& elem
: aList
)
102 if (!rMgr
.getFontFastInfo(elem
, aInfo
))
105 // normalize face number to the FreetypeManager
106 int nFaceNum
= rMgr
.getFontFaceNumber(aInfo
.m_nID
);
107 int nVariantNum
= rMgr
.getFontFaceVariation(aInfo
.m_nID
);
109 // inform FreetypeManager about this font provided by the PsPrint subsystem
110 FontAttributes aDFA
= GenPspGraphics::Info2FontAttributes(aInfo
);
111 aDFA
.IncreaseQualityBy(4096);
112 const OString
& rFileName
= rMgr
.getFontFileSysPath(aInfo
.m_nID
);
113 rFontManager
.AddFontFile(rFileName
, nFaceNum
, nVariantNum
, aInfo
.m_nID
, aDFA
);
117 SalGenericInstance::RegisterFontSubstitutors(pPFC
);
119 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
120 for (auto& family
: QFontDatabase::families())
121 for (auto& style
: QFontDatabase::styles(family
))
122 pPFC
->Add(QtFontFace::fromQFontDatabase(family
, style
));
125 for (auto& family
: aFDB
.families())
126 for (auto& style
: aFDB
.styles(family
))
127 pPFC
->Add(QtFontFace::fromQFontDatabase(family
, style
));
131 void QtGraphics::ClearDevFontCache() {}
133 bool QtGraphics::AddTempDevFont(vcl::font::PhysicalFontCollection
*, const OUString
& /*rFileURL*/,
134 const OUString
& /*rFontName*/)
141 class QtCommonSalLayout
: public GenericSalLayout
144 QtCommonSalLayout(LogicalFontInstance
& rLFI
)
145 : GenericSalLayout(rLFI
)
149 void SetOrientation(Degree10 nOrientation
) { mnOrientation
= nOrientation
; }
153 std::unique_ptr
<GenericSalLayout
> QtGraphics::GetTextLayout(int nFallbackLevel
)
155 assert(m_pTextStyle
[nFallbackLevel
]);
156 if (!m_pTextStyle
[nFallbackLevel
])
158 return std::make_unique
<QtCommonSalLayout
>(*m_pTextStyle
[nFallbackLevel
]);
161 static QRawFont
GetRawFont(const QFont
& rFont
, bool bWithoutHintingInTextDirection
)
163 QFont::HintingPreference eHinting
= rFont
.hintingPreference();
164 bool bAllowedHintStyle
165 = !bWithoutHintingInTextDirection
166 || (eHinting
== QFont::PreferNoHinting
|| eHinting
== QFont::PreferVerticalHinting
);
167 if (bWithoutHintingInTextDirection
&& !bAllowedHintStyle
)
170 aFont
.setHintingPreference(QFont::PreferVerticalHinting
);
171 return QRawFont::fromFont(aFont
);
173 return QRawFont::fromFont(rFont
);
176 void QtGraphics::DrawTextLayout(const GenericSalLayout
& rLayout
)
178 const QtFont
* pFont
= static_cast<const QtFont
*>(&rLayout
.GetFont());
181 GetRawFont(*pFont
, rLayout
.GetTextRenderModeForResolutionIndependentLayout()));
183 QVector
<quint32
> glyphIndexes
;
184 QVector
<QPointF
> positions
;
186 // prevent glyph rotation inside the SalLayout
187 // probably better to add a parameter to GetNextGlyphs?
188 QtCommonSalLayout
* pQtLayout
189 = static_cast<QtCommonSalLayout
*>(const_cast<GenericSalLayout
*>(&rLayout
));
190 Degree10 nOrientation
= rLayout
.GetOrientation();
192 pQtLayout
->SetOrientation(0_deg10
);
195 const GlyphItem
* pGlyph
;
197 while (rLayout
.GetNextGlyph(&pGlyph
, aPos
, nStart
))
199 glyphIndexes
.push_back(pGlyph
->glyphId());
200 positions
.push_back(QPointF(aPos
.getX(), aPos
.getY()));
203 // seems to be common to try to layout an empty string...
204 if (positions
.empty())
208 pQtLayout
->SetOrientation(nOrientation
);
211 aGlyphRun
.setPositions(positions
);
212 aGlyphRun
.setGlyphIndexes(glyphIndexes
);
213 aGlyphRun
.setRawFont(aRawFont
);
215 QtPainter
aPainter(*m_pBackend
);
216 QColor aColor
= toQColor(m_aTextColor
);
217 aPainter
.setPen(aColor
);
221 // make text position the center of the rotation
222 // then rotate and move back
223 QRect window
= aPainter
.window();
224 window
.moveTo(-positions
[0].x(), -positions
[0].y());
225 aPainter
.setWindow(window
);
228 p
.rotate(-static_cast<qreal
>(nOrientation
.get()) / 10.0);
229 p
.translate(-positions
[0].x(), -positions
[0].y());
230 aPainter
.setTransform(p
);
233 aPainter
.drawGlyphRun(QPointF(), aGlyphRun
);
236 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */