calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / vcl / qt5 / QtGraphics_Text.cxx
blob18790086bbf385f717562e25ffd0795e083fc96b
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 #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>
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)
48 if (!m_pTextStyle[i])
49 break;
50 m_pTextStyle[i].clear();
53 if (!pReqFont)
54 return;
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());
67 rFMD->SetSlant(0);
68 rFMD->SetWidth(aRawFont.averageCharWidth());
70 rFMD->SetMinKashida(m_pTextStyle[nFallbackLevel]->GetKashidaWidth());
73 FontCharMapRef QtGraphics::GetFontCharMap() const
75 if (!m_pTextStyle[0])
76 return FontCharMapRef(new FontCharMap());
77 return m_pTextStyle[0]->GetFontFace()->GetFontCharMap();
80 bool QtGraphics::GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities) const
82 if (!m_pTextStyle[0])
83 return false;
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"));
91 if (pPFC->Count())
92 return;
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))
103 continue;
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);
116 if (bUseFontconfig)
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));
123 #else
124 QFontDatabase aFDB;
125 for (auto& family : aFDB.families())
126 for (auto& style : aFDB.styles(family))
127 pPFC->Add(QtFontFace::fromQFontDatabase(family, style));
128 #endif
131 void QtGraphics::ClearDevFontCache() {}
133 bool QtGraphics::AddTempDevFont(vcl::font::PhysicalFontCollection*, const OUString& /*rFileURL*/,
134 const OUString& /*rFontName*/)
136 return false;
139 namespace
141 class QtCommonSalLayout : public GenericSalLayout
143 public:
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])
157 return nullptr;
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)
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(
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();
191 if (nOrientation)
192 pQtLayout->SetOrientation(0_deg10);
194 DevicePoint aPos;
195 const GlyphItem* pGlyph;
196 int nStart = 0;
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())
205 return;
207 if (nOrientation)
208 pQtLayout->SetOrientation(nOrientation);
210 QGlyphRun aGlyphRun;
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);
219 if (nOrientation)
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);
227 QTransform p;
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: */