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 .
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
34 template <> struct hash
< pair
< sal_UCS4
, FontWeight
> >
36 size_t operator()(const pair
< sal_UCS4
, FontWeight
>& rData
) const
39 o3tl::hash_combine(seed
, rData
.first
);
40 o3tl::hash_combine(seed
, rData
.second
);
47 LogicalFontInstance::LogicalFontInstance(const PhysicalFontFace
& rFontFace
, const FontSelectPattern
& rFontSelData
)
48 : mxFontMetric( new ImplFontMetricData( rFontSelData
))
49 , mpConversion( nullptr )
51 , mnOwnOrientation( 0 )
54 , mpFontCache( nullptr )
55 , m_aFontSelData(rFontSelData
)
57 , m_nAveWidthFactor(1.0f
)
58 , m_pFontFace(&const_cast<PhysicalFontFace
&>(rFontFace
))
62 LogicalFontInstance::~LogicalFontInstance()
64 mpUnicodeFallbackList
.reset();
65 mpFontCache
= nullptr;
66 mxFontMetric
= nullptr;
69 hb_font_destroy(m_pHbFont
);
72 hb_font_t
* LogicalFontInstance::InitHbFont(hb_face_t
* 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
);
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
))
93 GetScale(&nXScale
, nullptr);
94 nWidth
= hb_font_get_glyph_h_advance(pHbFont
, nIndex
) * nXScale
;
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
111 double nWidth(m_aFontSelData
.mnWidth
? m_aFontSelData
.mnWidth
* m_nAveWidthFactor
: nHeight
);
114 *nYScale
= nHeight
/ nUPEM
;
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
)
132 UnicodeFallbackList::const_iterator it
= mpUnicodeFallbackList
->find( std::pair
< sal_UCS4
, FontWeight
>(cChar
,eWeight
) );
133 if( it
== mpUnicodeFallbackList
->end() )
136 *pFontName
= (*it
).second
;
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() )
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
))
154 bool res
= ImplGetGlyphBoundRect(nID
, rRect
, bVertical
);
155 if (mpFontCache
&& res
)
156 mpFontCache
->CacheGlyphBoundRect(this, nID
, rRect
);
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: */