~ubuntu-branches/ubuntu/quantal/libwpd/quantal

« back to all changes in this revision

Viewing changes to src/lib/WP6FontDescriptorPacket.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2007-11-21 17:45:38 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20071121174538-ue68b9jzc5y8wq8e
Tags: 0.8.12-1ubuntu1
* Merge from debian unstable, remaining changes:
  - Add debian/patches/gcc43.diff and build rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include <limits>
27
27
#include "WP6FontDescriptorPacket.h"
28
28
#include "libwpd_internal.h"
 
29
#include <string>
29
30
 
30
 
const char *FONT_WEIGHT_STRINGS[] = {   "Bold", "bold", "Demi", "demi", "Extended", "extended",
 
31
const char * FONT_WEIGHT_STRINGS [] = { "Bold", "bold", "Demi", "demi", "Extended", "extended",
31
32
                                        "Extra", "extra", "Headline", "headline", "Light", "light",
32
33
                                        "Medium", "medium", "Normal", "normal", "Regular", "regular",
33
34
                                        "Standaard", "standaard", "Standard", "standard" };
54
55
        m_fontType(0),
55
56
        m_fontSourceFileType(0),
56
57
        m_fontNameLength(0),
57
 
        m_fontName(0)
 
58
        m_fontName()
58
59
{
59
60
        _read(input, dataOffset, dataSize);
60
61
}
61
62
 
62
63
WP6FontDescriptorPacket::~WP6FontDescriptorPacket()
63
64
{
64
 
        delete [] m_fontName;
65
65
}
66
66
 
67
67
void WP6FontDescriptorPacket::_readContents(WPXInputStream *input)
68
68
{
69
 
   // short sized characteristics
70
 
   m_characterWidth = readU16(input);
71
 
   m_ascenderHeight = readU16(input);
72
 
   m_xHeight = readU16(input);
73
 
   m_descenderHeight = readU16(input);
74
 
   m_italicsAdjust = readU16(input);
75
 
   // byte sized characteristics
76
 
   m_primaryFamilyMemberId = readU8(input);
77
 
   m_primaryFamilyId = readU8(input);
78
 
   m_scriptingSystem = readU8(input);
79
 
   m_primaryCharacterSet = readU8(input);
80
 
   m_width = readU8(input);
81
 
   m_weight = readU8(input);
82
 
   m_attributes = readU8(input);
83
 
   m_generalCharacteristics = readU8(input);
84
 
   m_classification = readU8(input);
85
 
   m_fill = readU8(input);
86
 
   m_fontType = readU8(input);
87
 
   m_fontSourceFileType = readU8(input);
88
 
 
89
 
   m_fontNameLength = readU16(input); 
90
 
 
91
 
 
92
 
   if (m_fontNameLength > ((std::numeric_limits<uint16_t>::max)() / 2))
 
69
        // short sized characteristics
 
70
        m_characterWidth = readU16(input);
 
71
        m_ascenderHeight = readU16(input);
 
72
        m_xHeight = readU16(input);
 
73
        m_descenderHeight = readU16(input);
 
74
        m_italicsAdjust = readU16(input);
 
75
        // byte sized characteristics
 
76
        m_primaryFamilyMemberId = readU8(input);
 
77
        m_primaryFamilyId = readU8(input);
 
78
        m_scriptingSystem = readU8(input);
 
79
        m_primaryCharacterSet = readU8(input);
 
80
        m_width = readU8(input);
 
81
        m_weight = readU8(input);
 
82
        m_attributes = readU8(input);
 
83
        m_generalCharacteristics = readU8(input);
 
84
        m_classification = readU8(input);
 
85
        m_fill = readU8(input);
 
86
        m_fontType = readU8(input);
 
87
        m_fontSourceFileType = readU8(input);
 
88
 
 
89
        m_fontNameLength = readU16(input); 
 
90
 
 
91
 
 
92
        if (m_fontNameLength > ((std::numeric_limits<uint16_t>::max)() / 2))
93
93
        m_fontNameLength = ((std::numeric_limits<uint16_t>::max)() / 2);
94
 
   if (m_fontNameLength == 0) 
95
 
           {
96
 
                   m_fontName = new char[1];
97
 
                   m_fontName[0]='\0';
98
 
           }
99
 
   
100
 
   else 
101
 
           {
102
 
                   m_fontName = new char[m_fontNameLength];
103
 
 
104
 
                   uint16_t tempLength=0;
105
 
                   int numTokens=0;
106
 
                   int lastTokenPosition=0;
107
 
                   for (uint16_t i=0; i<(m_fontNameLength/2); i++) 
108
 
                   {
109
 
                           uint16_t charWord = readU16(input);
110
 
 
111
 
                           uint8_t characterSet = (uint8_t)((charWord >> 8) & 0x00FF);
112
 
                           uint8_t character = (uint8_t)(charWord & 0xFF);
113
 
                           
114
 
                           const uint16_t *chars;
115
 
                           extendedCharacterWP6ToUCS2(character, characterSet, &chars);
116
 
                           /* We are only using ascii characters here, and
117
 
                            * if we have more than one character, that's
118
 
                            * going to be an international character, so
119
 
                            * we don't actually iterate through the list of
120
 
                            * characters returned - we assume that just one
121
 
                            * character was returned.
122
 
                            */
123
 
                           if (chars[0] == 0x20) {
124
 
                                   m_fontName[tempLength]=' ';
125
 
                                   tempLength++;
126
 
                                   numTokens++;
127
 
                                   lastTokenPosition=tempLength;
128
 
                           }
129
 
                           else if (chars[0] != 0x00 && chars[0] < 0x7F) {
130
 
                                   m_fontName[tempLength]=(char) chars[0];
131
 
                                   tempLength++;
132
 
                           }
133
 
                   }
134
 
                   m_fontName[tempLength]='\0';
135
 
                   // TODO/HACK: probably should create a proper static function for doing this
136
 
                   // consume the last token (by replacing the first char with a null-terminator) if its a weight signifier
137
 
                   // also remove annoying -WP postfix
138
 
                   // (NB: not all wp fonts are terminated by weight, just enough of them to make this annoying)
139
 
                   // NB: also this is O(n^2). Could be a performance hotspot.
140
 
                   WPD_DEBUG_MSG(("WordPerfect: stripping font name (original: %s)\n", m_fontName));
141
 
                   for (int stringPosition=(tempLength-1); stringPosition>=0; stringPosition--)
142
 
                   {
143
 
                           unsigned int k;                         
144
 
                           for (k=0; k<countElements(FONT_WEIGHT_STRINGS); k++) 
145
 
                           {
146
 
                                   if (stringPosition > 0 && !strcmp(FONT_WEIGHT_STRINGS[k], &m_fontName[stringPosition])) 
147
 
                                   {
148
 
                                           m_fontName[stringPosition-1]='\0';
149
 
                                           tempLength = (uint16_t)(stringPosition-1);
150
 
                                           break;
151
 
                                   }
152
 
                           }
153
 
                           // SPECIAL CASE: eliminate the -WP postfix (if it's there), which isn't spaced out from
154
 
                           // the rest of the font
155
 
                           if (k==countElements(FONT_WEIGHT_STRINGS))
156
 
                           {
157
 
                                   if (!strcmp(USELESS_WP_POSTFIX, &m_fontName[stringPosition])) 
158
 
                                   {
159
 
                                           m_fontName[stringPosition]='\0';
160
 
                                           tempLength = (uint16_t)(stringPosition - 1);
161
 
                                   }
162
 
                           }
163
 
                           // also consume any whitespace at the end of the font..
164
 
                           while ((tempLength - 1) > 0 && m_fontName[tempLength-1] == ' ')
165
 
                           {
166
 
                                   m_fontName[tempLength-1] = '\0';
167
 
                           }
168
 
                   }
169
 
                   WPD_DEBUG_MSG(("WordPerfect: stripping font name (final: %s)\n", m_fontName));
170
 
           }
171
 
   WPD_DEBUG_MSG(("WordPerfect: Read Font (primary family id: %i, family member id: %i, font type: %i, font source file type: %i font name length: %i, font name: %s)\n", (int) m_primaryFamilyId, (int) m_primaryFamilyMemberId, (int) m_fontType, (int) m_fontSourceFileType, (int) m_fontNameLength, m_fontName));
172
 
 
 
94
        if (m_fontNameLength) 
 
95
        {
 
96
                for (uint16_t i=0; i<(m_fontNameLength/2); i++) 
 
97
                {
 
98
                        uint16_t charWord = readU16(input);
 
99
                        uint8_t characterSet = (uint8_t)((charWord >> 8) & 0x00FF);
 
100
                        uint8_t character = (uint8_t)(charWord & 0xFF);
 
101
 
 
102
                        if (character == 0x00 && characterSet == 0x00)
 
103
                                break;
 
104
 
 
105
                        const uint16_t *chars;
 
106
                        int len = extendedCharacterWP6ToUCS2(character, characterSet, &chars);
 
107
 
 
108
                        for (int j = 0; j < len; j++)
 
109
                                appendUCS4(m_fontName, (uint32_t)chars[j]);
 
110
                }
 
111
 
 
112
                WPD_DEBUG_MSG(("WordPerfect: stripping font name (original: %s)\n", m_fontName.cstr()));
 
113
                std::string stringValue(m_fontName.cstr());
 
114
                std::string::size_type pos;
 
115
                for (unsigned k = 0; k < countElements(FONT_WEIGHT_STRINGS); k++)
 
116
                {
 
117
                        if (!stringValue.empty())
 
118
                                while ((pos = stringValue.find(FONT_WEIGHT_STRINGS[k])) != std::string::npos)
 
119
                                        stringValue.replace(pos, strlen(FONT_WEIGHT_STRINGS[k]),"");
 
120
                }
 
121
                // SPECIAL CASE: eliminate the -WP postfix (if it's there), which isn't spaced out from
 
122
                // the rest of the font
 
123
                if (!stringValue.empty())
 
124
                        while ((pos = stringValue.find(USELESS_WP_POSTFIX)) != std::string::npos)
 
125
                        stringValue.replace(pos, strlen(USELESS_WP_POSTFIX), "");
 
126
                        // also consume any whitespace at the end of the font.
 
127
                if (!stringValue.empty())
 
128
                        while ((pos = stringValue.find("  ")) != std::string::npos)
 
129
                        stringValue.replace(pos, strlen("  "), " ");
 
130
                if (!stringValue.empty())
 
131
                        while ((pos = stringValue.find(" ", stringValue.size() - 1)) != std::string::npos)
 
132
                        stringValue.replace(pos, strlen(" "), "");
 
133
                if (!stringValue.empty())
 
134
                        while ((pos = stringValue.find("-", stringValue.size() - 1)) != std::string::npos)
 
135
                        stringValue.replace(pos, strlen("-"), "");
 
136
        
 
137
                m_fontName = WPXString(stringValue.c_str());
 
138
                        WPD_DEBUG_MSG(("WordPerfect: stripping font name (final: %s)\n", m_fontName.cstr()));
 
139
        }
 
140
        WPD_DEBUG_MSG(("WordPerfect: Read Font (primary family id: %i, family member id: %i, font type: %i, font source file type: %i font name length: %i, font name: %s)\n",
 
141
                (int) m_primaryFamilyId, (int) m_primaryFamilyMemberId, (int) m_fontType, (int) m_fontSourceFileType, (int) m_fontNameLength, m_fontName.cstr()));
173
142
}