Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/xmloff/source/style/weighhdl.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 "weighhdl.hxx"
21
22
#include <sax/tools/converter.hxx>
23
24
#include <xmloff/xmltoken.hxx>
25
26
#include <rtl/ustring.hxx>
27
28
#include <com/sun/star/uno/Any.hxx>
29
#include <com/sun/star/awt/FontWeight.hpp>
30
31
using namespace ::com::sun::star::uno;
32
using namespace ::xmloff::token;
33
34
namespace {
35
36
struct FontWeightMapper
37
{
38
    float fWeight;
39
    sal_uInt16 nValue;
40
};
41
42
}
43
44
// ODF specifies the valid fo:font-weight values, but does not provide mapping
45
// between weight names to numeric values:
46
// https://docs.oasis-open.org/office/v1.2/cd05/OpenDocument-v1.2-cd05-part1.html#a_20_184_fo_font-weight
47
//
48
// The mapping here is the same as OpenType/windows.h:
49
// https://learn.microsoft.com/en-us/typography/opentype/spec/os2#usweightclass
50
FontWeightMapper const aFontWeightMap[] =
51
{
52
    { css::awt::FontWeight::DONTKNOW,              0 },
53
    { css::awt::FontWeight::THIN,                  100 },
54
    { css::awt::FontWeight::ULTRALIGHT,            200 },
55
    { css::awt::FontWeight::LIGHT,                 300 },
56
    { css::awt::FontWeight::SEMILIGHT,             350 },
57
    { css::awt::FontWeight::NORMAL,                400 },
58
    { css::awt::FontWeight::MEDIUM,                500 },
59
    { css::awt::FontWeight::SEMIBOLD,              600 },
60
    { css::awt::FontWeight::BOLD,                  700 },
61
    { css::awt::FontWeight::ULTRABOLD,             800 },
62
    { css::awt::FontWeight::BLACK,                 900 },
63
    { css::awt::FontWeight::DONTKNOW,             1000 }
64
};
65
66
67
XMLFontWeightPropHdl::~XMLFontWeightPropHdl()
68
82.3k
{
69
    // Nothing to do
70
82.3k
}
71
72
bool XMLFontWeightPropHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& ) const
73
22.9k
{
74
22.9k
    bool bRet = false;
75
22.9k
    sal_uInt16 nWeight = 0;
76
77
22.9k
    if( IsXMLToken( rStrImpValue, XML_NORMAL ) )
78
906
    {
79
906
        nWeight = 400;
80
906
        bRet = true;
81
906
    }
82
22.0k
    else if( IsXMLToken( rStrImpValue, XML_BOLD ) )
83
10.6k
    {
84
10.6k
        nWeight = 700;
85
10.6k
        bRet = true;
86
10.6k
    }
87
11.3k
    else
88
11.3k
    {
89
11.3k
        sal_Int32 nTemp;
90
11.3k
        bRet = ::sax::Converter::convertNumber(nTemp, rStrImpValue, 100, 900);
91
11.3k
        if( bRet )
92
8.17k
            nWeight = sal::static_int_cast< sal_uInt16 >(nTemp);
93
11.3k
    }
94
95
22.9k
    if( bRet )
96
19.7k
    {
97
19.7k
        bRet = false;
98
19.7k
        int const nCount = SAL_N_ELEMENTS(aFontWeightMap);
99
129k
        for (int i = 0; i < (nCount-1); ++i)
100
129k
        {
101
129k
            if( (nWeight >= aFontWeightMap[i].nValue) && (nWeight <= aFontWeightMap[i+1].nValue) )
102
19.7k
            {
103
19.7k
                sal_uInt16 nDiff1 = nWeight - aFontWeightMap[i].nValue;
104
19.7k
                sal_uInt16 nDiff2 = aFontWeightMap[i+1].nValue - nWeight;
105
106
19.7k
                if( nDiff1 < nDiff2 )
107
14
                    rValue <<= aFontWeightMap[i].fWeight;
108
19.7k
                else
109
19.7k
                    rValue <<= aFontWeightMap[i+1].fWeight;
110
111
19.7k
                bRet = true;
112
19.7k
                break;
113
19.7k
            }
114
129k
        }
115
19.7k
    }
116
117
22.9k
    return bRet;
118
22.9k
}
119
120
bool XMLFontWeightPropHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& ) const
121
400
{
122
400
    bool bRet = false;
123
124
400
    float fValue = float();
125
400
    if( !( rValue >>= fValue ) )
126
0
    {
127
0
        sal_Int32 nValue = 0;
128
0
        if( rValue >>= nValue )
129
0
        {
130
0
            fValue = static_cast<float>(nValue);
131
0
            bRet = true;
132
0
        }
133
0
    }
134
400
    else
135
400
        bRet = true;
136
137
400
    if( bRet )
138
400
    {
139
400
        sal_uInt16 nWeight = 0;
140
400
        for( auto const & pair : aFontWeightMap )
141
1.80k
        {
142
1.80k
            if( fValue <= pair.fWeight )
143
400
            {
144
400
                 nWeight = pair.nValue;
145
400
                 break;
146
400
            }
147
1.80k
        }
148
149
400
        if( 400 == nWeight )
150
203
            rStrExpValue = GetXMLToken(XML_NORMAL);
151
197
        else if( 700 == nWeight )
152
49
            rStrExpValue = GetXMLToken(XML_BOLD);
153
148
        else
154
148
            rStrExpValue = OUString::number( nWeight );
155
400
    }
156
157
400
    return bRet;
158
400
}
159
160
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */