LibreOffice Module vcl (master)  1
fontinstance.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 
21 #include <hb-ot.h>
22 #include <hb-graphite2.h>
23 
24 #include <fontinstance.hxx>
25 #include <impfontcache.hxx>
26 
27 #include <PhysicalFontFace.hxx>
28 
29 // extend std namespace to add custom hash needed for LogicalFontInstance
30 
31 namespace std
32 {
33  template <> struct hash< pair< sal_UCS4, FontWeight > >
34  {
35  size_t operator()(const pair< sal_UCS4, FontWeight >& rData) const
36  {
37  std::size_t seed = 0;
38  boost::hash_combine(seed, rData.first);
39  boost::hash_combine(seed, rData.second);
40  return seed;
41  }
42  };
43 }
44 
45 
47  : mxFontMetric( new ImplFontMetricData( rFontSelData ))
48  , mpConversion( nullptr )
49  , mnLineHeight( 0 )
50  , mnOwnOrientation( 0 )
51  , mnOrientation( 0 )
52  , mbInit( false )
53  , mpFontCache( nullptr )
54  , m_aFontSelData(rFontSelData)
55  , m_pHbFont(nullptr)
56  , m_nAveWidthFactor(1.0f)
57  , m_pFontFace(&const_cast<PhysicalFontFace&>(rFontFace))
58 {
59 }
60 
62 {
63  mpUnicodeFallbackList.reset();
64  mpFontCache = nullptr;
65  mxFontMetric = nullptr;
66 
67  if (m_pHbFont)
68  hb_font_destroy(m_pHbFont);
69 }
70 
71 hb_font_t* LogicalFontInstance::InitHbFont(hb_face_t* pHbFace)
72 {
73  assert(pHbFace);
74  hb_font_t* pHbFont = hb_font_create(pHbFace);
75  unsigned int nUPEM = hb_face_get_upem(pHbFace);
76  hb_font_set_scale(pHbFont, nUPEM, nUPEM);
77  hb_ot_font_set_funcs(pHbFont);
78  // hb_font_t keeps a reference to hb_face_t, so destroy this one.
79  hb_face_destroy(pHbFace);
80  return pHbFont;
81 }
82 
84 {
85  hb_font_t* pHbFont = GetHbFont();
86  hb_position_t nWidth = 0;
87  hb_codepoint_t nIndex = 0;
88 
89  if (hb_font_get_glyph(pHbFont, 0x0640, 0, &nIndex))
90  {
91  double nXScale = 0;
92  GetScale(&nXScale, nullptr);
93  nWidth = hb_font_get_glyph_h_advance(pHbFont, nIndex) * nXScale;
94  }
95 
96  return nWidth;
97 }
98 
99 void LogicalFontInstance::GetScale(double* nXScale, double* nYScale)
100 {
101  hb_face_t* pHbFace = hb_font_get_face(GetHbFont());
102  unsigned int nUPEM = hb_face_get_upem(pHbFace);
103 
104  double nHeight(m_aFontSelData.mnHeight);
105 
106  // On Windows, mnWidth is relative to average char width not font height,
107  // and we need to keep it that way for GDI to correctly scale the glyphs.
108  // Here we compensate for this so that HarfBuzz gives us the correct glyph
109  // positions.
110  double nWidth(m_aFontSelData.mnWidth ? m_aFontSelData.mnWidth * m_nAveWidthFactor : nHeight);
111 
112  if (nYScale)
113  *nYScale = nHeight / nUPEM;
114 
115  if (nXScale)
116  *nXScale = nWidth / nUPEM;
117 }
118 
119 void LogicalFontInstance::AddFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, const OUString& rFontName )
120 {
121  if( !mpUnicodeFallbackList )
123  (*mpUnicodeFallbackList)[ std::pair< sal_UCS4, FontWeight >(cChar,eWeight) ] = rFontName;
124 }
125 
126 bool LogicalFontInstance::GetFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, OUString* pFontName ) const
127 {
128  if( !mpUnicodeFallbackList )
129  return false;
130 
131  UnicodeFallbackList::const_iterator it = mpUnicodeFallbackList->find( std::pair< sal_UCS4, FontWeight >(cChar,eWeight) );
132  if( it == mpUnicodeFallbackList->end() )
133  return false;
134 
135  *pFontName = (*it).second;
136  return true;
137 }
138 
139 void LogicalFontInstance::IgnoreFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, const OUString& rFontName )
140 {
141  UnicodeFallbackList::iterator it = mpUnicodeFallbackList->find( std::pair< sal_UCS4,FontWeight >(cChar,eWeight) );
142  if( it == mpUnicodeFallbackList->end() )
143  return;
144  if( (*it).second == rFontName )
145  mpUnicodeFallbackList->erase( it );
146 }
147 
149 {
150  if (mpFontCache && mpFontCache->GetCachedGlyphBoundRect(this, nID, rRect))
151  return true;
152 
153  bool res = ImplGetGlyphBoundRect(nID, rRect, bVertical);
154  if (mpFontCache && res)
155  mpFontCache->CacheGlyphBoundRect(this, nID, rRect);
156  return res;
157 }
158 
160 {
161  if (!m_xbIsGraphiteFont)
162  {
163  m_xbIsGraphiteFont = hb_graphite2_face_get_gr_face(hb_font_get_face(GetHbFont())) != nullptr;
164  }
165  return *m_xbIsGraphiteFont;
166 }
167 
168 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool GetGlyphBoundRect(sal_GlyphId, tools::Rectangle &, bool) const
::std::unordered_map< ::std::pair< sal_UCS4, FontWeight >, OUString > UnicodeFallbackList
ImplFontCache * mpFontCache
size_t operator()(const pair< sal_UCS4, FontWeight > &rData) const
bool GetFallbackForUnicode(sal_UCS4, FontWeight eWeight, OUString *pFontName) const
hb_font_t * GetHbFont()
LogicalFontInstance(const PhysicalFontFace &, const FontSelectPattern &)
ImplFontMetricDataRef mxFontMetric
sal_uInt16 sal_GlyphId
Definition: glyphitem.hxx:26
void GetScale(double *nXScale, double *nYScale)
abstract base class for physical font faces
static hb_font_t * InitHbFont(hb_face_t *pHbFace)
virtual bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle &, bool) const =0
boost::optional< bool > m_xbIsGraphiteFont
std::unique_ptr< UnicodeFallbackList > mpUnicodeFallbackList
void CacheGlyphBoundRect(const LogicalFontInstance *, sal_GlyphId, tools::Rectangle &)
Definition: fontcache.cxx:261
FontWeight
bool GetCachedGlyphBoundRect(const LogicalFontInstance *, sal_GlyphId, tools::Rectangle &)
Definition: fontcache.cxx:244
const FontSelectPattern m_aFontSelData
virtual ~LogicalFontInstance() override
void(* f)(TrueTypeTable *)
Definition: ttcr.cxx:466
sal_uInt32 sal_UCS4
Definition: fontcharmap.hxx:29
void AddFallbackForUnicode(sal_UCS4, FontWeight eWeight, const OUString &rFontName)
void IgnoreFallbackForUnicode(sal_UCS4, FontWeight eWeight, const OUString &rFontName)