tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / vcl / qt5 / QtGraphics_Text.cxx
blob3bd998cdbdd516c5a31e3a23c1657b22ec76d46b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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 #include <sal/config.h>
22 #include <QtGraphics.hxx>
23 #include <QtFontFace.hxx>
24 #include <QtFont.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)
47 if (!m_pTextStyle[i])
48 break;
49 m_pTextStyle[i].clear();
52 if (!pReqFont)
53 return;
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());
66 rFMD->SetSlant(0);
67 rFMD->SetWidth(aRawFont.averageCharWidth());
69 rFMD->SetMinKashida(m_pTextStyle[nFallbackLevel]->GetKashidaWidth());
72 FontCharMapRef QtGraphics::GetFontCharMap() const
74 if (!m_pTextStyle[0])
75 return FontCharMapRef(new FontCharMap());
76 return m_pTextStyle[0]->GetFontFace()->GetFontCharMap();
79 bool QtGraphics::GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities) const
81 if (!m_pTextStyle[0])
82 return false;
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"));
90 if (pPFC->Count())
91 return;
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);
101 if (!pFont)
102 continue;
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);
115 if (bUseFontconfig)
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));
122 #else
123 QFontDatabase aFDB;
124 for (auto& family : aFDB.families())
125 for (auto& style : aFDB.styles(family))
126 pPFC->Add(QtFontFace::fromQFontDatabase(family, style));
127 #endif
130 void QtGraphics::ClearDevFontCache() {}
132 bool QtGraphics::AddTempDevFont(vcl::font::PhysicalFontCollection*, const OUString& /*rFileURL*/,
133 const OUString& /*rFontName*/)
135 return false;
138 namespace
140 class QtCommonSalLayout : public GenericSalLayout
142 public:
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])
156 return nullptr;
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)
169 QFont aFont(rFont);
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());
179 assert(pFont);
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();
190 if (nOrientation)
191 pQtLayout->SetOrientation(0_deg10);
193 basegfx::B2DPoint aPos;
194 const GlyphItem* pGlyph;
195 int nStart = 0;
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())
204 return;
206 if (nOrientation)
207 pQtLayout->SetOrientation(nOrientation);
209 QGlyphRun aGlyphRun;
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);
218 if (nOrientation)
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);
226 QTransform p;
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: */