Coverage Report

Created: 2025-11-16 09:57

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