/* -*- 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 .
*/
//sort normal to the start staticint sortWeightValue(FontWeight eWeight)
{ if (eWeight < WEIGHT_NORMAL) return eWeight + 1; if (eWeight > WEIGHT_NORMAL) return eWeight - 1; return 0; // eWeight == WEIGHT_NORMAL
}
static sal_Int32 ImplCompareFontMetric(const ImplFontListFontMetric* pInfo1, const ImplFontListFontMetric* pInfo2)
{ //Sort non italic before italics if ( pInfo1->GetItalic() < pInfo2->GetItalic() ) return -1; elseif ( pInfo1->GetItalic() > pInfo2->GetItalic() ) return 1;
//Sort normal weight to the start, followed by lightest to heaviest weights int nWeight1 = sortWeightValue(pInfo1->GetWeight()); int nWeight2 = sortWeightValue(pInfo2->GetWeight());
static OUString ImplMakeSearchStringFromName(std::u16string_view rStr)
{ // check for features before alternate font separator if (size_t nColon = rStr.find(':'); nColon != std::u16string_view::npos) if (size_t nSemiColon = rStr.find(';'); nSemiColon == std::u16string_view::npos || nColon < nSemiColon) return ImplMakeSearchString(OUString(o3tl::getToken(rStr, 0, ':' ))); return ImplMakeSearchString(OUString(o3tl::getToken(rStr, 0, ';' )));
}
ImplFontListNameInfo* FontList::ImplFind(std::u16string_view rSearchName, sal_uInt32* pIndex) const
{ // Append if there is no entry in the list or if the entry is larger // then the last one. We only compare to the last entry as the list of VCL // is returned sorted, which increases the probability that appending // is more likely if (m_Entries.empty())
{ if ( pIndex )
*pIndex = SAL_MAX_UINT32; return nullptr;
} else
{ const ImplFontListNameInfo* pCmpData = m_Entries.back().get();
sal_Int32 nComp = rSearchName.compare( pCmpData->maSearchName ); if (nComp > 0)
{ if ( pIndex )
*pIndex = SAL_MAX_UINT32; return nullptr;
} elseif (nComp == 0) returnconst_cast<ImplFontListNameInfo*>(pCmpData);
}
// search fonts in the list const ImplFontListNameInfo* pCompareData; const ImplFontListNameInfo* pFoundData = nullptr;
size_t nLow = 0;
size_t nHigh = m_Entries.size() - 1;
size_t nMid;
// inquire all fonts from the device int n = pDevice->GetFontFaceCollectionCount(); if (n == 0 && comphelper::LibreOfficeKit::isActive())
{
pDevice->RefreshFontData(true);
n = pDevice->GetFontFaceCollectionCount();
}
for (int i = 0; i < n; ++i)
{
FontMetric aFontMetric = pDevice->GetFontMetricFromCollection( i );
OUString aSearchName(aFontMetric.GetFamilyName());
ImplFontListNameInfo* pData;
sal_uInt32 nIndex;
aSearchName = ImplMakeSearchString(aSearchName);
pData = ImplFind( aSearchName, &nIndex );
if ( !pData )
{ if ( bInsertData )
{
ImplFontListFontMetric* pNewInfo = new ImplFontListFontMetric( aFontMetric );
pData = new ImplFontListNameInfo( aSearchName );
pData->mpFirst = pNewInfo;
pNewInfo->mpNext = nullptr;
if (nIndex < static_cast<sal_uInt32>(m_Entries.size()))
m_Entries.insert(m_Entries.begin()+nIndex,
std::unique_ptr<ImplFontListNameInfo>(pData)); else
m_Entries.push_back(std::unique_ptr<ImplFontListNameInfo>(pData));
}
} else
{ if ( bInsertData )
{ bool bInsert = true;
ImplFontListFontMetric* pPrev = nullptr;
ImplFontListFontMetric* pTemp = pData->mpFirst;
ImplFontListFontMetric* pNewInfo = new ImplFontListFontMetric( aFontMetric ); while ( pTemp )
{
sal_Int32 eComp = ImplCompareFontMetric( pNewInfo, pTemp ); if ( eComp <= 0 )
{ if ( eComp == 0 )
{ // Overwrite charset, because charset should match // with the system charset if ( (pTemp->GetCharSet() != eSystemEncoding) &&
(pNewInfo->GetCharSet() == eSystemEncoding) )
{
ImplFontListFontMetric* pTemp2 = pTemp->mpNext;
*static_cast<FontMetric*>(pTemp) = *static_cast<FontMetric*>(pNewInfo);
pTemp->mpNext = pTemp2;
} delete pNewInfo;
bInsert = false;
}
// if required compare to the screen fonts // in order to map the duplicates to Equal bool bCompareWindow = false; if ( !pDevice2 && (pDevice->GetOutDevType() == OUTDEV_PRINTER) )
{
bCompareWindow = true;
pDevice2 = Application::GetDefaultDevice();
}
if ( !bNotSynthetic )
{ if (maMapStyleNotAvailable.isEmpty()) const_cast<FontList*>(this)->maMapStyleNotAvailable = SvtResId(STR_SVT_FONTMAP_STYLENOTAVAILABLE); return maMapStyleNotAvailable;
}
}
// Only Printer-Font? if ( nType == FontListFontNameType::PRINTER )
{ if (maMapPrinterOnly.isEmpty()) const_cast<FontList*>(this)->maMapPrinterOnly = SvtResId(STR_SVT_FONTMAP_PRINTERONLY); return maMapPrinterOnly;
} else
{ if (maMapBoth.isEmpty()) const_cast<FontList*>(this)->maMapBoth = SvtResId(STR_SVT_FONTMAP_BOTH); return maMapBoth;
}
}
namespace
{
FontMetric makeMissing(ImplFontListFontMetric const * pFontNameInfo, std::u16string_view rName,
FontWeight eWeight, FontItalic eItalic)
{
FontMetric aInfo; // if the fontname matches, we copy as much as possible if (pFontNameInfo)
{
aInfo = *pFontNameInfo;
aInfo.SetStyleName(OUString());
}
//If this is a known but uninstalled symbol font which we can remap to //OpenSymbol then toggle its charset to be a symbol font if (ConvertChar::GetRecodeData(rName, u"OpenSymbol"))
aInfo.SetCharSet(RTL_TEXTENCODING_SYMBOL);
// reproduce attributes if data could not be found
FontMetric aInfo; if ( !pFontMetric )
{
FontWeight eWeight = WEIGHT_DONTKNOW;
FontItalic eItalic = ITALIC_NONE;
// reproduce attributes if data could not be found
FontMetric aInfo; if ( !pFontMetric )
aInfo = makeMissing(pFontNameInfo, rName, eWeight, eItalic); else
aInfo = *pFontMetric;
// set Fontname to keep FontAlias
aInfo.SetFamilyName( rName );
if (MsLangId::isSimplifiedChinese(eLanguage))
{ // equivalent for traditional chinese disabled by popular request, #i89077#
mpArray = aImplSimplifiedChinese;
mnElem = SAL_N_ELEMENTS(aImplSimplifiedChinese);
} else
{
mpArray = nullptr;
mnElem = 0;
}
}
// linear search is sufficient for this rare case for( tools::Long i = mnElem; --i >= 0; ) if ( aName == mpArray[i].mszUtf8Name ) return mpArray[i].mnSize;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.