1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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>
32 #include <sallayout.hxx>
33 #include <font/PhysicalFontCollection.hxx>
35 #include <QtGui/QGlyphRun>
36 #include <QtGui/QFontDatabase>
37 #include <QtGui/QRawFont>
38 #include <QtCore/QStringList>
40 void QtGraphics::SetTextColor(Color nColor
) { m_aTextColor
= nColor
; }
42 void QtGraphics::SetFont(LogicalFontInstance
* pReqFont
, int nFallbackLevel
)
44 // release the text styles
45 for (int i
= nFallbackLevel
; i
< MAX_FALLBACK
; ++i
)
49 m_pTextStyle
[i
].clear();
55 m_pTextStyle
[nFallbackLevel
] = static_cast<QtFont
*>(pReqFont
);
58 void QtGraphics::GetFontMetric(FontMetricDataRef
& rFMD
, int nFallbackLevel
)
60 QRawFont
aRawFont(QRawFont::fromFont(*m_pTextStyle
[nFallbackLevel
]));
61 QtFontFace::fillAttributesFromQFont(*m_pTextStyle
[nFallbackLevel
], *rFMD
);
63 rFMD
->ImplCalcLineSpacing(m_pTextStyle
[nFallbackLevel
].get());
64 rFMD
->ImplInitBaselines(m_pTextStyle
[nFallbackLevel
].get());
67 rFMD
->SetWidth(aRawFont
.averageCharWidth());
69 rFMD
->SetMinKashida(m_pTextStyle
[nFallbackLevel
]->GetKashidaWidth());
72 FontCharMapRef
QtGraphics::GetFontCharMap() const
75 return FontCharMapRef(new FontCharMap());
76 return m_pTextStyle
[0]->GetFontFace()->GetFontCharMap();
79 bool QtGraphics::GetFontCapabilities(vcl::FontCapabilities
& rFontCapabilities
) const
83 return m_pTextStyle
[0]->GetFontFace()->GetFontCapabilities(rFontCapabilities
);
86 void QtGraphics::GetDevFontList(vcl::font::PhysicalFontCollection
* pPFC
)
88 static const bool bUseFontconfig
= (nullptr == getenv("SAL_VCL_QT_NO_FONTCONFIG"));
93 FreetypeManager
& rFontManager
= FreetypeManager::get();
94 psp::PrintFontManager
& rMgr
= psp::PrintFontManager::get();
95 ::std::vector
<psp::fontID
> aList
;
97 rMgr
.getFontList(aList
);
98 for (auto const& nFontId
: aList
)
100 auto const* pFont
= rMgr
.getFont(nFontId
);
104 // normalize face number to the FreetypeManager
105 int nFaceNum
= rMgr
.getFontFaceNumber(nFontId
);
106 int nVariantNum
= rMgr
.getFontFaceVariation(nFontId
);
108 // inform FreetypeManager about this font provided by the PsPrint subsystem
109 FontAttributes aFA
= pFont
->m_aFontAttributes
;
110 aFA
.IncreaseQualityBy(4096);
111 const OString aFileName
= rMgr
.getFontFileSysPath(nFontId
);
112 rFontManager
.AddFontFile(aFileName
, nFaceNum
, nVariantNum
, nFontId
, aFA
);
116 SalGenericInstance::RegisterFontSubstitutors(pPFC
);
118 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
119 for (auto& family
: QFontDatabase::families())
120 for (auto& style
: QFontDatabase::styles(family
))
121 pPFC
->Add(QtFontFace::fromQFontDatabase(family
, style
));
124 for (auto& family
: aFDB
.families())
125 for (auto& style
: aFDB
.styles(family
))
126 pPFC
->Add(QtFontFace::fromQFontDatabase(family
, style
));
130 void QtGraphics::ClearDevFontCache() {}
132 bool QtGraphics::AddTempDevFont(vcl::font::PhysicalFontCollection
*, const OUString
& /*rFileURL*/,
133 const OUString
& /*rFontName*/)
140 class QtCommonSalLayout
: public GenericSalLayout
143 QtCommonSalLayout(LogicalFontInstance
& rLFI
)
144 : GenericSalLayout(rLFI
)
148 void SetOrientation(Degree10 nOrientation
) { mnOrientation
= nOrientation
; }
152 std::unique_ptr
<GenericSalLayout
> QtGraphics::GetTextLayout(int nFallbackLevel
)
154 assert(m_pTextStyle
[nFallbackLevel
]);
155 if (!m_pTextStyle
[nFallbackLevel
])
157 return std::make_unique
<QtCommonSalLayout
>(*m_pTextStyle
[nFallbackLevel
]);
160 static QRawFont
GetRawFont(const QFont
& rFont
, bool bWithoutHintingInTextDirection
)
162 QFont::HintingPreference eHinting
= rFont
.hintingPreference();
163 static bool bAllowDefaultHinting
= getenv("SAL_ALLOW_DEFAULT_HINTING") != nullptr;
164 bool bAllowedHintStyle
165 = !bWithoutHintingInTextDirection
|| bAllowDefaultHinting
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());
180 QRawFont
aRawFont(GetRawFont(*pFont
, rLayout
.GetSubpixelPositioning()));
182 QVector
<quint32
> glyphIndexes
;
183 QVector
<QPointF
> positions
;
185 // prevent glyph rotation inside the SalLayout
186 // probably better to add a parameter to GetNextGlyphs?
187 QtCommonSalLayout
* pQtLayout
188 = static_cast<QtCommonSalLayout
*>(const_cast<GenericSalLayout
*>(&rLayout
));
189 Degree10 nOrientation
= rLayout
.GetOrientation();
191 pQtLayout
->SetOrientation(0_deg10
);
193 basegfx::B2DPoint aPos
;
194 const GlyphItem
* pGlyph
;
196 while (rLayout
.GetNextGlyph(&pGlyph
, aPos
, nStart
))
198 glyphIndexes
.push_back(pGlyph
->glyphId());
199 positions
.push_back(QPointF(aPos
.getX(), aPos
.getY()));
202 // seems to be common to try to layout an empty string...
203 if (positions
.empty())
207 pQtLayout
->SetOrientation(nOrientation
);
210 aGlyphRun
.setPositions(positions
);
211 aGlyphRun
.setGlyphIndexes(glyphIndexes
);
212 aGlyphRun
.setRawFont(aRawFont
);
214 QtPainter
aPainter(*m_pBackend
);
215 QColor aColor
= toQColor(m_aTextColor
);
216 aPainter
.setPen(aColor
);
220 // make text position the center of the rotation
221 // then rotate and move back
222 QRect window
= aPainter
.window();
223 window
.moveTo(-positions
[0].x(), -positions
[0].y());
224 aPainter
.setWindow(window
);
227 p
.rotate(-static_cast<qreal
>(nOrientation
.get()) / 10.0);
228 p
.translate(-positions
[0].x(), -positions
[0].y());
229 aPainter
.setTransform(p
);
232 aPainter
.drawGlyphRun(QPointF(), aGlyphRun
);
235 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */