bump product version to 7.2.5.1
[LibreOffice.git] / vcl / source / font / fontinstance.cxx
blob48e4c291c3501ff7c981bf0c8349a6a14f704d2e
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 .
21 #include <hb-ot.h>
22 #include <hb-graphite2.h>
24 #include <fontinstance.hxx>
25 #include <impfontcache.hxx>
26 #include <PhysicalFontFace.hxx>
28 #include <o3tl/hash_combine.hxx>
30 // extend std namespace to add custom hash needed for LogicalFontInstance
32 namespace std
34 template <> struct hash< pair< sal_UCS4, FontWeight > >
36 size_t operator()(const pair< sal_UCS4, FontWeight >& rData) const
38 std::size_t seed = 0;
39 o3tl::hash_combine(seed, rData.first);
40 o3tl::hash_combine(seed, rData.second);
41 return seed;
47 LogicalFontInstance::LogicalFontInstance(const PhysicalFontFace& rFontFace, const FontSelectPattern& rFontSelData )
48 : mxFontMetric( new ImplFontMetricData( rFontSelData ))
49 , mpConversion( nullptr )
50 , mnLineHeight( 0 )
51 , mnOwnOrientation( 0 )
52 , mnOrientation( 0 )
53 , mbInit( false )
54 , mpFontCache( nullptr )
55 , m_aFontSelData(rFontSelData)
56 , m_pHbFont(nullptr)
57 , m_nAveWidthFactor(1.0f)
58 , m_pFontFace(&const_cast<PhysicalFontFace&>(rFontFace))
62 LogicalFontInstance::~LogicalFontInstance()
64 mpUnicodeFallbackList.reset();
65 mpFontCache = nullptr;
66 mxFontMetric = nullptr;
68 if (m_pHbFont)
69 hb_font_destroy(m_pHbFont);
72 hb_font_t* LogicalFontInstance::InitHbFont(hb_face_t* pHbFace)
74 assert(pHbFace);
75 hb_font_t* pHbFont = hb_font_create(pHbFace);
76 unsigned int nUPEM = hb_face_get_upem(pHbFace);
77 hb_font_set_scale(pHbFont, nUPEM, nUPEM);
78 hb_ot_font_set_funcs(pHbFont);
79 // hb_font_t keeps a reference to hb_face_t, so destroy this one.
80 hb_face_destroy(pHbFace);
81 return pHbFont;
84 int LogicalFontInstance::GetKashidaWidth()
86 hb_font_t* pHbFont = GetHbFont();
87 hb_position_t nWidth = 0;
88 hb_codepoint_t nIndex = 0;
90 if (hb_font_get_glyph(pHbFont, 0x0640, 0, &nIndex))
92 double nXScale = 0;
93 GetScale(&nXScale, nullptr);
94 nWidth = hb_font_get_glyph_h_advance(pHbFont, nIndex) * nXScale;
97 return nWidth;
100 void LogicalFontInstance::GetScale(double* nXScale, double* nYScale)
102 hb_face_t* pHbFace = hb_font_get_face(GetHbFont());
103 unsigned int nUPEM = hb_face_get_upem(pHbFace);
105 double nHeight(m_aFontSelData.mnHeight);
107 // On Windows, mnWidth is relative to average char width not font height,
108 // and we need to keep it that way for GDI to correctly scale the glyphs.
109 // Here we compensate for this so that HarfBuzz gives us the correct glyph
110 // positions.
111 double nWidth(m_aFontSelData.mnWidth ? m_aFontSelData.mnWidth * m_nAveWidthFactor : nHeight);
113 if (nYScale)
114 *nYScale = nHeight / nUPEM;
116 if (nXScale)
117 *nXScale = nWidth / nUPEM;
120 void LogicalFontInstance::AddFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, const OUString& rFontName )
122 if( !mpUnicodeFallbackList )
123 mpUnicodeFallbackList.reset(new UnicodeFallbackList);
124 (*mpUnicodeFallbackList)[ std::pair< sal_UCS4, FontWeight >(cChar,eWeight) ] = rFontName;
127 bool LogicalFontInstance::GetFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, OUString* pFontName ) const
129 if( !mpUnicodeFallbackList )
130 return false;
132 UnicodeFallbackList::const_iterator it = mpUnicodeFallbackList->find( std::pair< sal_UCS4, FontWeight >(cChar,eWeight) );
133 if( it == mpUnicodeFallbackList->end() )
134 return false;
136 *pFontName = (*it).second;
137 return true;
140 void LogicalFontInstance::IgnoreFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, std::u16string_view rFontName )
142 UnicodeFallbackList::iterator it = mpUnicodeFallbackList->find( std::pair< sal_UCS4,FontWeight >(cChar,eWeight) );
143 if( it == mpUnicodeFallbackList->end() )
144 return;
145 if( (*it).second == rFontName )
146 mpUnicodeFallbackList->erase( it );
149 bool LogicalFontInstance::GetGlyphBoundRect(sal_GlyphId nID, tools::Rectangle &rRect, bool bVertical) const
151 if (mpFontCache && mpFontCache->GetCachedGlyphBoundRect(this, nID, rRect))
152 return true;
154 bool res = ImplGetGlyphBoundRect(nID, rRect, bVertical);
155 if (mpFontCache && res)
156 mpFontCache->CacheGlyphBoundRect(this, nID, rRect);
157 return res;
160 bool LogicalFontInstance::IsGraphiteFont()
162 if (!m_xbIsGraphiteFont)
164 m_xbIsGraphiteFont = hb_graphite2_face_get_gr_face(hb_font_get_face(GetHbFont())) != nullptr;
166 return *m_xbIsGraphiteFont;
169 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */