Coverage Report

Created: 2026-06-30 11:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/source/uibase/config/fontcfg.cxx
Line
Count
Source
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
#include <fontcfg.hxx>
21
#include <i18nlangtag/mslangid.hxx>
22
#include <osl/diagnose.h>
23
#include <tools/UnitConversion.hxx>
24
#include <vcl/outdev.hxx>
25
#include <vcl/rendercontext/GetDefaultFontFlags.hxx>
26
#include <comphelper/configuration.hxx>
27
#include <unotools/fontdefs.hxx>
28
#include <unotools/lingucfg.hxx>
29
#include <com/sun/star/uno/Sequence.hxx>
30
#include <com/sun/star/i18n/ScriptType.hpp>
31
32
using namespace utl;
33
using namespace com::sun::star::uno;
34
35
static LanguageType lcl_LanguageOfType(sal_Int16 nType, LanguageType eWestern, LanguageType eCJK, LanguageType eCTL)
36
1.01M
{
37
1.01M
    return nType < FONT_STANDARD_CJK
38
1.01M
           ? eWestern
39
1.01M
           : nType >= FONT_STANDARD_CTL ? eCTL : eCJK;
40
1.01M
}
41
42
Sequence<OUString> const & SwStdFontConfig::GetPropertyNames()
43
9
{
44
9
    static Sequence<OUString> aNames {
45
9
        u"DefaultFont/Standard"_ustr,    // 0
46
9
        u"DefaultFont/Heading"_ustr,     // 1
47
9
        u"DefaultFont/List"_ustr,        // 2
48
9
        u"DefaultFont/Caption"_ustr,     // 3
49
9
        u"DefaultFont/Index"_ustr,       // 4
50
9
        u"DefaultFontCJK/Standard"_ustr, // 5
51
9
        u"DefaultFontCJK/Heading"_ustr,  // 6
52
9
        u"DefaultFontCJK/List"_ustr,     // 7
53
9
        u"DefaultFontCJK/Caption"_ustr,  // 8
54
9
        u"DefaultFontCJK/Index"_ustr,    // 9
55
9
        u"DefaultFontCTL/Standard"_ustr, // 10
56
9
        u"DefaultFontCTL/Heading"_ustr,  // 11
57
9
        u"DefaultFontCTL/List"_ustr,     // 12
58
9
        u"DefaultFontCTL/Caption"_ustr,  // 13
59
9
        u"DefaultFontCTL/Index"_ustr,    // 14
60
9
        u"DefaultFont/StandardHeight"_ustr,    // 15
61
9
        u"DefaultFont/HeadingHeight"_ustr,     // 16
62
9
        u"DefaultFont/ListHeight"_ustr,        // 17
63
9
        u"DefaultFont/CaptionHeight"_ustr,     // 18
64
9
        u"DefaultFont/IndexHeight"_ustr,       // 19
65
9
        u"DefaultFontCJK/StandardHeight"_ustr, // 20
66
9
        u"DefaultFontCJK/HeadingHeight"_ustr,  // 21
67
9
        u"DefaultFontCJK/ListHeight"_ustr,     // 22
68
9
        u"DefaultFontCJK/CaptionHeight"_ustr,  // 23
69
9
        u"DefaultFontCJK/IndexHeight"_ustr,    // 24
70
9
        u"DefaultFontCTL/StandardHeight"_ustr, // 25
71
9
        u"DefaultFontCTL/HeadingHeight"_ustr,  // 26
72
9
        u"DefaultFontCTL/ListHeight"_ustr,     // 27
73
9
        u"DefaultFontCTL/CaptionHeight"_ustr,  // 28
74
9
        u"DefaultFontCTL/IndexHeight"_ustr     // 29
75
9
    };
76
9
    return aNames;
77
9
}
78
79
SwStdFontConfig::SwStdFontConfig() :
80
9
    utl::ConfigItem(u"Office.Writer"_ustr)
81
9
{
82
9
    SvtLinguOptions aLinguOpt;
83
84
9
    if (!comphelper::IsFuzzing())
85
0
        SvtLinguConfig().GetOptions( aLinguOpt );
86
87
9
    LanguageType eWestern = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage, css::i18n::ScriptType::LATIN),
88
9
                 eCJK = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CJK, css::i18n::ScriptType::ASIAN),
89
9
                 eCTL = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CTL, css::i18n::ScriptType::COMPLEX);
90
91
144
    for(sal_Int16 i = 0; i < DEF_FONT_COUNT; i++)
92
135
    {
93
135
        m_sDefaultFonts[i] = GetDefaultFor(i,
94
135
            lcl_LanguageOfType(i, eWestern, eCJK, eCTL));
95
135
        m_nDefaultFontHeight[i] = -1;
96
135
    }
97
98
9
    Sequence<OUString> aNames = GetPropertyNames();
99
9
    Sequence<Any> aValues = GetProperties(aNames);
100
9
    const Any* pValues = aValues.getConstArray();
101
9
    OSL_ENSURE(aValues.getLength() == aNames.getLength(), "GetProperties failed");
102
9
    if(aValues.getLength() != aNames.getLength())
103
0
        return;
104
105
279
    for(int nProp = 0; nProp < aNames.getLength(); nProp++)
106
270
    {
107
270
        if(pValues[nProp].hasValue())
108
0
        {
109
0
            if( nProp < DEF_FONT_COUNT)
110
0
            {
111
0
                OUString sVal;
112
0
                pValues[nProp] >>= sVal;
113
0
                m_sDefaultFonts[nProp] = sVal;
114
0
            }
115
0
            else
116
0
            {
117
0
               pValues[nProp] >>= m_nDefaultFontHeight[nProp - DEF_FONT_COUNT];
118
0
               m_nDefaultFontHeight[nProp - DEF_FONT_COUNT] = o3tl::toTwips(m_nDefaultFontHeight[nProp - DEF_FONT_COUNT], o3tl::Length::mm100);
119
0
            }
120
0
        }
121
270
    }
122
9
}
123
124
void SwStdFontConfig::ImplCommit()
125
0
{
126
0
    Sequence<OUString> aNames = GetPropertyNames();
127
0
    Sequence<Any> aValues(aNames.getLength());
128
0
    Any* pValues = aValues.getArray();
129
0
    SvtLinguOptions aLinguOpt;
130
131
0
    SvtLinguConfig().GetOptions( aLinguOpt );
132
133
0
    LanguageType eWestern = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage, css::i18n::ScriptType::LATIN),
134
0
                 eCJK = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CJK, css::i18n::ScriptType::ASIAN),
135
0
                 eCTL = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CTL, css::i18n::ScriptType::COMPLEX);
136
137
0
    for(sal_uInt16 nProp = 0;
138
0
        nProp < sal::static_int_cast< sal_uInt16, sal_Int32 >( aNames.getLength() );
139
0
            nProp++)
140
0
    {
141
0
        if( nProp < DEF_FONT_COUNT )
142
0
        {
143
0
            if(GetDefaultFor(nProp, lcl_LanguageOfType(nProp, eWestern, eCJK, eCTL)) != m_sDefaultFonts[nProp])
144
0
                pValues[nProp] <<= m_sDefaultFonts[nProp];
145
0
        }
146
0
        else
147
0
        {
148
0
            if(m_nDefaultFontHeight[nProp - DEF_FONT_COUNT] > 0)
149
0
                pValues[nProp] <<= static_cast<sal_Int32>(convertTwipToMm100(m_nDefaultFontHeight[nProp - DEF_FONT_COUNT]));
150
0
        }
151
0
    }
152
0
    PutProperties(aNames, aValues);
153
0
}
154
155
SwStdFontConfig::~SwStdFontConfig()
156
0
{
157
0
}
158
159
bool SwStdFontConfig::IsFontDefault(sal_uInt16 nFontType) const
160
1.01M
{
161
1.01M
    bool bSame = false;
162
1.01M
    SvtLinguOptions aLinguOpt;
163
164
1.01M
    if (!comphelper::IsFuzzing())
165
0
        SvtLinguConfig().GetOptions(aLinguOpt);
166
167
1.01M
    LanguageType eWestern = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage, css::i18n::ScriptType::LATIN),
168
1.01M
                 eCJK = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CJK, css::i18n::ScriptType::ASIAN),
169
1.01M
                 eCTL = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CTL, css::i18n::ScriptType::COMPLEX);
170
171
1.01M
    OUString sDefFont(GetDefaultFor(FONT_STANDARD, eWestern));
172
1.01M
    OUString sDefFontCJK(GetDefaultFor(FONT_STANDARD_CJK, eCJK));
173
1.01M
    OUString sDefFontCTL(GetDefaultFor(FONT_STANDARD_CTL, eCTL));
174
1.01M
    LanguageType eLang = lcl_LanguageOfType(nFontType, eWestern, eCJK, eCTL);
175
1.01M
    switch( nFontType )
176
1.01M
    {
177
67.3k
        case FONT_STANDARD:
178
67.3k
            bSame = m_sDefaultFonts[nFontType] == sDefFont;
179
67.3k
        break;
180
67.3k
        case FONT_STANDARD_CJK:
181
67.3k
            bSame = m_sDefaultFonts[nFontType] == sDefFontCJK;
182
67.3k
        break;
183
67.3k
        case FONT_STANDARD_CTL:
184
67.3k
            bSame = m_sDefaultFonts[nFontType] == sDefFontCTL;
185
67.3k
        break;
186
67.3k
        case FONT_OUTLINE :
187
134k
        case FONT_OUTLINE_CJK :
188
202k
        case FONT_OUTLINE_CTL :
189
202k
            bSame = m_sDefaultFonts[nFontType] ==
190
202k
                GetDefaultFor(nFontType, eLang);
191
202k
        break;
192
67.3k
        case FONT_LIST    :
193
134k
        case FONT_CAPTION :
194
202k
        case FONT_INDEX   :
195
202k
            bSame = m_sDefaultFonts[nFontType] == sDefFont &&
196
202k
                    m_sDefaultFonts[FONT_STANDARD] == sDefFont;
197
202k
        break;
198
67.3k
        case FONT_LIST_CJK    :
199
134k
        case FONT_CAPTION_CJK :
200
202k
        case FONT_INDEX_CJK   :
201
202k
        {
202
202k
            bool b1 = m_sDefaultFonts[FONT_STANDARD_CJK] == sDefFontCJK;
203
202k
            bSame = b1 && m_sDefaultFonts[nFontType] == sDefFontCJK;
204
202k
        }
205
202k
        break;
206
67.3k
        case FONT_LIST_CTL    :
207
134k
        case FONT_CAPTION_CTL :
208
202k
        case FONT_INDEX_CTL   :
209
202k
        {
210
202k
            bool b1 = m_sDefaultFonts[FONT_STANDARD_CJK] == sDefFontCTL;
211
202k
            bSame = b1 && m_sDefaultFonts[nFontType] == sDefFontCTL;
212
202k
        }
213
202k
        break;
214
1.01M
    }
215
1.01M
    return bSame;
216
1.01M
}
217
218
OUString  SwStdFontConfig::GetDefaultFor(sal_uInt16 nFontType, LanguageType eLang)
219
3.23M
{
220
3.23M
    DefaultFontType nFontId;
221
3.23M
    switch( nFontType )
222
3.23M
    {
223
67.3k
        case FONT_OUTLINE :
224
67.3k
            nFontId = DefaultFontType::LATIN_HEADING;
225
67.3k
        break;
226
67.3k
        case FONT_OUTLINE_CJK :
227
67.3k
            nFontId = DefaultFontType::CJK_HEADING;
228
67.3k
        break;
229
67.3k
        case FONT_OUTLINE_CTL :
230
67.3k
            nFontId = DefaultFontType::CTL_HEADING;
231
67.3k
        break;
232
1.01M
        case FONT_STANDARD_CJK:
233
1.01M
        case FONT_LIST_CJK    :
234
1.01M
        case FONT_CAPTION_CJK :
235
1.01M
        case FONT_INDEX_CJK   :
236
1.01M
            nFontId = DefaultFontType::CJK_TEXT;
237
1.01M
        break;
238
1.01M
        case FONT_STANDARD_CTL:
239
1.01M
        case FONT_LIST_CTL    :
240
1.01M
        case FONT_CAPTION_CTL :
241
1.01M
        case FONT_INDEX_CTL   :
242
1.01M
            nFontId = DefaultFontType::CTL_TEXT;
243
1.01M
        break;
244
1.01M
        default:
245
1.01M
            nFontId = DefaultFontType::LATIN_TEXT;
246
3.23M
    }
247
3.23M
    vcl::Font aFont = OutputDevice::GetDefaultFont(nFontId, eLang, GetDefaultFontFlags::OnlyOne);
248
3.23M
    return  aFont.GetFamilyName();
249
3.23M
}
250
251
sal_Int32 SwStdFontConfig::GetDefaultHeightFor(sal_uInt16 nFontType, LanguageType eLang)
252
1.01M
{
253
1.01M
    sal_Int32 nRet = FONTSIZE_DEFAULT;
254
1.01M
    switch( nFontType )
255
1.01M
    {
256
67.3k
        case  FONT_OUTLINE:
257
134k
        case  FONT_OUTLINE_CJK:
258
202k
        case  FONT_OUTLINE_CTL:
259
202k
            nRet = FONTSIZE_OUTLINE;
260
202k
            break;
261
67.3k
        case FONT_STANDARD_CJK:
262
67.3k
            nRet = FONTSIZE_CJK_DEFAULT;
263
67.3k
            break;
264
1.01M
    }
265
1.01M
    if( eLang == LANGUAGE_THAI && nFontType >= FONT_STANDARD_CTL )
266
0
    {
267
0
        nRet = nRet * 4 / 3;
268
0
    }
269
1.01M
    if( eLang == LANGUAGE_KOREAN )
270
0
    {
271
0
        nRet = FONTSIZE_KOREAN_DEFAULT;
272
0
    }
273
1.01M
    return nRet;
274
1.01M
}
275
276
void SwStdFontConfig::ChangeInt( sal_uInt16 nFontType, sal_Int32 nHeight )
277
0
{
278
0
    OSL_ENSURE( nFontType < DEF_FONT_COUNT, "invalid index in SwStdFontConfig::ChangeInt()");
279
0
    if( nFontType >= DEF_FONT_COUNT || m_nDefaultFontHeight[nFontType] == nHeight)
280
0
        return;
281
282
0
    SvtLinguOptions aLinguOpt;
283
0
    if (!comphelper::IsFuzzing())
284
0
        SvtLinguConfig().GetOptions( aLinguOpt );
285
286
0
    LanguageType eWestern = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage, css::i18n::ScriptType::LATIN),
287
0
                 eCJK = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CJK, css::i18n::ScriptType::ASIAN),
288
0
                 eCTL = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CTL, css::i18n::ScriptType::COMPLEX);
289
290
    // #i92090# default height value sets back to -1
291
0
    const sal_Int32 nDefaultHeight = GetDefaultHeightFor(nFontType, lcl_LanguageOfType(nFontType, eWestern, eCJK, eCTL));
292
0
    const bool bIsDefaultHeight = nHeight == nDefaultHeight;
293
0
    if( bIsDefaultHeight && m_nDefaultFontHeight[nFontType] > 0 )
294
0
    {
295
0
        SetModified();
296
0
        m_nDefaultFontHeight[nFontType] = -1;
297
0
    }
298
0
    else if( !bIsDefaultHeight && nHeight != m_nDefaultFontHeight[nFontType] )
299
0
    {
300
0
        SetModified();
301
0
        m_nDefaultFontHeight[nFontType] = nHeight;
302
0
    }
303
0
}
304
305
sal_Int32 SwStdFontConfig::GetFontHeight( sal_uInt8 nFont, sal_uInt8 nScriptType, LanguageType eLang )
306
1.01M
{
307
1.01M
    OSL_ENSURE(nFont + FONT_PER_GROUP * nScriptType < DEF_FONT_COUNT, "wrong index in SwStdFontConfig::GetFontHeight()");
308
1.01M
    sal_Int32 nRet = m_nDefaultFontHeight[nFont + FONT_PER_GROUP * nScriptType];
309
1.01M
    if(nRet <= 0)
310
1.01M
        return GetDefaultHeightFor(nFont + FONT_PER_GROUP * nScriptType, eLang);
311
0
    return nRet;
312
1.01M
}
313
314
0
void SwStdFontConfig::Notify( const css::uno::Sequence< OUString >& ) {}
315
316
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */