summaryrefslogtreecommitdiffstats
path: root/vcl/source/font/fontinstance.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/font/fontinstance.cxx')
-rw-r--r--vcl/source/font/fontinstance.cxx168
1 files changed, 168 insertions, 0 deletions
diff --git a/vcl/source/font/fontinstance.cxx b/vcl/source/font/fontinstance.cxx
new file mode 100644
index 000000000..40e334bd6
--- /dev/null
+++ b/vcl/source/font/fontinstance.cxx
@@ -0,0 +1,168 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <hb-ot.h>
+#include <hb-graphite2.h>
+
+#include <fontinstance.hxx>
+#include <impfontcache.hxx>
+
+#include <PhysicalFontFace.hxx>
+
+// extend std namespace to add custom hash needed for LogicalFontInstance
+
+namespace std
+{
+ template <> struct hash< pair< sal_UCS4, FontWeight > >
+ {
+ size_t operator()(const pair< sal_UCS4, FontWeight >& rData) const
+ {
+ std::size_t seed = 0;
+ boost::hash_combine(seed, rData.first);
+ boost::hash_combine(seed, rData.second);
+ return seed;
+ }
+ };
+}
+
+
+LogicalFontInstance::LogicalFontInstance(const PhysicalFontFace& rFontFace, const FontSelectPattern& rFontSelData )
+ : mxFontMetric( new ImplFontMetricData( rFontSelData ))
+ , mpConversion( nullptr )
+ , mnLineHeight( 0 )
+ , mnOwnOrientation( 0 )
+ , mnOrientation( 0 )
+ , mbInit( false )
+ , mpFontCache( nullptr )
+ , m_aFontSelData(rFontSelData)
+ , m_pHbFont(nullptr)
+ , m_nAveWidthFactor(1.0f)
+ , m_pFontFace(&const_cast<PhysicalFontFace&>(rFontFace))
+{
+}
+
+LogicalFontInstance::~LogicalFontInstance()
+{
+ mpUnicodeFallbackList.reset();
+ mpFontCache = nullptr;
+ mxFontMetric = nullptr;
+
+ if (m_pHbFont)
+ hb_font_destroy(m_pHbFont);
+}
+
+hb_font_t* LogicalFontInstance::InitHbFont(hb_face_t* pHbFace)
+{
+ assert(pHbFace);
+ hb_font_t* pHbFont = hb_font_create(pHbFace);
+ unsigned int nUPEM = hb_face_get_upem(pHbFace);
+ hb_font_set_scale(pHbFont, nUPEM, nUPEM);
+ hb_ot_font_set_funcs(pHbFont);
+ // hb_font_t keeps a reference to hb_face_t, so destroy this one.
+ hb_face_destroy(pHbFace);
+ return pHbFont;
+}
+
+int LogicalFontInstance::GetKashidaWidth()
+{
+ hb_font_t* pHbFont = GetHbFont();
+ hb_position_t nWidth = 0;
+ hb_codepoint_t nIndex = 0;
+
+ if (hb_font_get_glyph(pHbFont, 0x0640, 0, &nIndex))
+ {
+ double nXScale = 0;
+ GetScale(&nXScale, nullptr);
+ nWidth = hb_font_get_glyph_h_advance(pHbFont, nIndex) * nXScale;
+ }
+
+ return nWidth;
+}
+
+void LogicalFontInstance::GetScale(double* nXScale, double* nYScale)
+{
+ hb_face_t* pHbFace = hb_font_get_face(GetHbFont());
+ unsigned int nUPEM = hb_face_get_upem(pHbFace);
+
+ double nHeight(m_aFontSelData.mnHeight);
+
+ // On Windows, mnWidth is relative to average char width not font height,
+ // and we need to keep it that way for GDI to correctly scale the glyphs.
+ // Here we compensate for this so that HarfBuzz gives us the correct glyph
+ // positions.
+ double nWidth(m_aFontSelData.mnWidth ? m_aFontSelData.mnWidth * m_nAveWidthFactor : nHeight);
+
+ if (nYScale)
+ *nYScale = nHeight / nUPEM;
+
+ if (nXScale)
+ *nXScale = nWidth / nUPEM;
+}
+
+void LogicalFontInstance::AddFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, const OUString& rFontName )
+{
+ if( !mpUnicodeFallbackList )
+ mpUnicodeFallbackList.reset(new UnicodeFallbackList);
+ (*mpUnicodeFallbackList)[ std::pair< sal_UCS4, FontWeight >(cChar,eWeight) ] = rFontName;
+}
+
+bool LogicalFontInstance::GetFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, OUString* pFontName ) const
+{
+ if( !mpUnicodeFallbackList )
+ return false;
+
+ UnicodeFallbackList::const_iterator it = mpUnicodeFallbackList->find( std::pair< sal_UCS4, FontWeight >(cChar,eWeight) );
+ if( it == mpUnicodeFallbackList->end() )
+ return false;
+
+ *pFontName = (*it).second;
+ return true;
+}
+
+void LogicalFontInstance::IgnoreFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, const OUString& rFontName )
+{
+ UnicodeFallbackList::iterator it = mpUnicodeFallbackList->find( std::pair< sal_UCS4,FontWeight >(cChar,eWeight) );
+ if( it == mpUnicodeFallbackList->end() )
+ return;
+ if( (*it).second == rFontName )
+ mpUnicodeFallbackList->erase( it );
+}
+
+bool LogicalFontInstance::GetGlyphBoundRect(sal_GlyphId nID, tools::Rectangle &rRect, bool bVertical) const
+{
+ if (mpFontCache && mpFontCache->GetCachedGlyphBoundRect(this, nID, rRect))
+ return true;
+
+ bool res = ImplGetGlyphBoundRect(nID, rRect, bVertical);
+ if (mpFontCache && res)
+ mpFontCache->CacheGlyphBoundRect(this, nID, rRect);
+ return res;
+}
+
+bool LogicalFontInstance::IsGraphiteFont()
+{
+ if (!m_xbIsGraphiteFont)
+ {
+ m_xbIsGraphiteFont = hb_graphite2_face_get_gr_face(hb_font_get_face(GetHbFont())) != nullptr;
+ }
+ return *m_xbIsGraphiteFont;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */