Coverage Report

Created: 2026-10-28 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwpd/src/lib/WP6FontDescriptorPacket.cpp
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2
/* libwpd
3
 * Version: MPL 2.0 / LGPLv2.1+
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
 * Major Contributor(s):
10
 * Copyright (C) 2002 William Lachance (wrlach@gmail.com)
11
 * Copyright (C) 2002 Marc Maurer (uwog@uwog.net)
12
 *
13
 * For minor contributions see the git repository.
14
 *
15
 * Alternatively, the contents of this file may be used under the terms
16
 * of the GNU Lesser General Public License Version 2.1 or later
17
 * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
18
 * applicable instead of those above.
19
 *
20
 * For further information visit http://libwpd.sourceforge.net
21
 */
22
23
/* "This product is not manufactured, approved, or supported by
24
 * Corel Corporation or Corel Corporation Limited."
25
 */
26
#include <string.h>
27
#include <limits>
28
#include "WP6FontDescriptorPacket.h"
29
#include "libwpd_internal.h"
30
#include <string>
31
32
const char* const FONT_WEIGHT_STRINGS [] = { "Bold", "bold", "Demi", "demi", "Extended", "extended",
33
                                        "Extra", "extra", "Headline", "headline", "Light", "light",
34
                                        "Medium", "medium", "Normal", "normal", "Regular", "regular",
35
                                        "Standaard", "standaard", "Standard", "standard"
36
                                     };
37
const char *USELESS_WP_POSTFIX = "-WP";
38
#define countElements(a) ((sizeof(a) / sizeof(a[0])))
39
40
WP6FontDescriptorPacket::WP6FontDescriptorPacket(librevenge::RVNGInputStream *input, WPXEncryption *encryption, int /* id */, unsigned dataOffset, unsigned dataSize) :
41
19.3k
  WP6PrefixDataPacket(input, encryption),
42
19.3k
  m_characterWidth(0),
43
19.3k
  m_ascenderHeight(0),
44
19.3k
  m_xHeight(0),
45
19.3k
  m_descenderHeight(0),
46
19.3k
  m_italicsAdjust(0),
47
19.3k
  m_primaryFamilyId(0),
48
19.3k
  m_primaryFamilyMemberId(0),
49
19.3k
  m_scriptingSystem(0),
50
19.3k
  m_primaryCharacterSet(0),
51
19.3k
  m_width(0),
52
19.3k
  m_weight(0),
53
19.3k
  m_attributes(0),
54
19.3k
  m_generalCharacteristics(0),
55
19.3k
  m_classification(0),
56
19.3k
  m_fill(0),
57
19.3k
  m_fontType(0),
58
19.3k
  m_fontSourceFileType(0),
59
19.3k
  m_fontNameLength(0),
60
19.3k
  m_fontName()
61
19.3k
{
62
19.3k
  _read(input, encryption, dataOffset, dataSize);
63
19.3k
}
64
65
WP6FontDescriptorPacket::~WP6FontDescriptorPacket()
66
19.1k
{
67
19.1k
}
68
69
void WP6FontDescriptorPacket::_readContents(librevenge::RVNGInputStream *input, WPXEncryption *encryption)
70
19.3k
{
71
  // short sized characteristics
72
19.3k
  m_characterWidth = readU16(input, encryption);
73
19.3k
  m_ascenderHeight = readU16(input, encryption);
74
19.3k
  m_xHeight = readU16(input, encryption);
75
19.3k
  m_descenderHeight = readU16(input, encryption);
76
19.3k
  m_italicsAdjust = readU16(input, encryption);
77
  // byte sized characteristics
78
19.3k
  m_primaryFamilyMemberId = readU8(input, encryption);
79
19.3k
  m_primaryFamilyId = readU8(input, encryption);
80
19.3k
  m_scriptingSystem = readU8(input, encryption);
81
19.3k
  m_primaryCharacterSet = readU8(input, encryption);
82
19.3k
  m_width = readU8(input, encryption);
83
19.3k
  m_weight = readU8(input, encryption);
84
19.3k
  m_attributes = readU8(input, encryption);
85
19.3k
  m_generalCharacteristics = readU8(input, encryption);
86
19.3k
  m_classification = readU8(input, encryption);
87
19.3k
  m_fill = readU8(input, encryption);
88
19.3k
  m_fontType = readU8(input, encryption);
89
19.3k
  m_fontSourceFileType = readU8(input, encryption);
90
91
19.3k
  m_fontNameLength = readU16(input, encryption);
92
93
19.3k
  _readFontName(input, encryption);
94
19.3k
}
95
96
void WP6FontDescriptorPacket::_readFontName(librevenge::RVNGInputStream *input, WPXEncryption *encryption)
97
19.1k
{
98
19.1k
  if (m_fontNameLength > ((std::numeric_limits<unsigned short>::max)() / 2))
99
4.90k
    m_fontNameLength = ((std::numeric_limits<unsigned short>::max)() / 2);
100
19.1k
  if (m_fontNameLength)
101
17.5k
  {
102
3.65M
    for (unsigned short i=0; i<(m_fontNameLength/2); i++)
103
3.65M
    {
104
3.65M
      unsigned short charWord = readU16(input, encryption);
105
3.65M
      auto characterSet = (unsigned char)((charWord >> 8) & 0x00FF);
106
3.65M
      auto character = (unsigned char)(charWord & 0xFF);
107
108
3.65M
      if (character == 0x00 && characterSet == 0x00)
109
14.8k
        break;
110
111
3.64M
      const unsigned *chars;
112
3.64M
      int len = extendedCharacterWP6ToUCS4(character, characterSet, &chars);
113
114
7.39M
      for (int j = 0; j < len; j++)
115
3.74M
        appendUCS4(m_fontName, chars[j]);
116
3.64M
    }
117
118
17.5k
    WPD_DEBUG_MSG(("WordPerfect: stripping font name (original: %s)\n", m_fontName.cstr()));
119
17.5k
    std::string stringValue(m_fontName.cstr());
120
17.5k
    std::string::size_type pos;
121
17.5k
    for (const auto &k : FONT_WEIGHT_STRINGS)
122
384k
    {
123
384k
      if (!stringValue.empty())
124
349k
        while ((pos = stringValue.find(k)) != std::string::npos)
125
239
          stringValue.replace(pos, strlen(k),"");
126
384k
    }
127
    // SPECIAL CASE: eliminate the -WP postfix (if it's there), which isn't spaced out from
128
    // the rest of the font
129
17.5k
    if (!stringValue.empty())
130
17.0k
      while ((pos = stringValue.find(USELESS_WP_POSTFIX)) != std::string::npos)
131
1.17k
        stringValue.replace(pos, strlen(USELESS_WP_POSTFIX), "");
132
    // also consume any whitespace at the end of the font.
133
17.5k
    if (!stringValue.empty())
134
1.40M
      while ((pos = stringValue.find("  ")) != std::string::npos)
135
1.38M
        stringValue.replace(pos, strlen("  "), " ");
136
17.5k
    if (!stringValue.empty())
137
27.0k
      while ((pos = stringValue.find(" ", stringValue.size() - 1)) != std::string::npos)
138
11.1k
        stringValue.replace(pos, strlen(" "), "");
139
17.5k
    if (!stringValue.empty())
140
13.9k
      while ((pos = stringValue.find("-", stringValue.size() - 1)) != std::string::npos)
141
893
        stringValue.replace(pos, strlen("-"), "");
142
143
17.5k
    m_fontName = librevenge::RVNGString(stringValue.c_str());
144
17.5k
    WPD_DEBUG_MSG(("WordPerfect: stripping font name (final: %s)\n", m_fontName.cstr()));
145
17.5k
  }
146
19.1k
}
147
/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */