Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* libcdr
3 : * Version: MPL 1.1 / GPLv2+ / LGPLv2+
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License or as specified alternatively below. You may obtain a copy of
8 : * the License at http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * Major Contributor(s):
16 : * Copyright (C) 2012 Fridrich Strba <fridrich.strba@bluewin.ch>
17 : *
18 : *
19 : * All Rights Reserved.
20 : *
21 : * For minor contributions see the git repository.
22 : *
23 : * Alternatively, the contents of this file may be used under the terms of
24 : * either the GNU General Public License Version 2 or later (the "GPLv2+"), or
25 : * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
26 : * in which case the provisions of the GPLv2+ or the LGPLv2+ are applicable
27 : * instead of those above.
28 : */
29 :
30 : #include <math.h>
31 : #include "CDRStylesCollector.h"
32 : #include "CDRInternalStream.h"
33 : #include "libcdr_utils.h"
34 :
35 : #ifndef M_PI
36 : #define M_PI 3.14159265358979323846
37 : #endif
38 :
39 : #ifndef DUMP_IMAGE
40 : #define DUMP_IMAGE 0
41 : #endif
42 :
43 0 : libcdr::CDRStylesCollector::CDRStylesCollector(libcdr::CDRParserState &ps) :
44 0 : m_ps(ps), m_page(8.5, 11.0, -4.25, -5.5), m_charStyles()
45 : {
46 0 : }
47 :
48 0 : libcdr::CDRStylesCollector::~CDRStylesCollector()
49 : {
50 0 : }
51 :
52 0 : void libcdr::CDRStylesCollector::collectFild(unsigned id, unsigned short fillType, const libcdr::CDRColor &color1, const libcdr::CDRColor &color2,
53 : const libcdr::CDRGradient &gradient, const libcdr::CDRImageFill &imageFill)
54 : {
55 0 : m_ps.m_fillStyles[id] = CDRFillStyle(fillType, color1, color2, gradient, imageFill);
56 0 : }
57 :
58 0 : void libcdr::CDRStylesCollector::collectOutl(unsigned id, unsigned short lineType, unsigned short capsType, unsigned short joinType, double lineWidth,
59 : double stretch, double angle, const CDRColor &color, const std::vector<unsigned> &dashArray,
60 : unsigned startMarkerId, unsigned endMarkerId)
61 : {
62 0 : m_ps.m_lineStyles[id] = CDRLineStyle(lineType, capsType, joinType, lineWidth, stretch, angle, color, dashArray, startMarkerId, endMarkerId);
63 0 : }
64 :
65 0 : void libcdr::CDRStylesCollector::collectBmp(unsigned imageId, unsigned colorModel, unsigned width, unsigned height, unsigned bpp, const std::vector<unsigned> &palette, const std::vector<unsigned char> &bitmap)
66 : {
67 0 : libcdr::CDRInternalStream stream(bitmap);
68 0 : WPXBinaryData image;
69 :
70 0 : unsigned tmpPixelSize = (unsigned)(height * width);
71 0 : if (tmpPixelSize < (unsigned)height) // overflow
72 : return;
73 :
74 0 : unsigned tmpDIBImageSize = tmpPixelSize * 4;
75 0 : if (tmpPixelSize > tmpDIBImageSize) // overflow !!!
76 : return;
77 :
78 0 : unsigned tmpDIBOffsetBits = 14 + 40;
79 0 : unsigned tmpDIBFileSize = tmpDIBOffsetBits + tmpDIBImageSize;
80 0 : if (tmpDIBImageSize > tmpDIBFileSize) // overflow !!!
81 : return;
82 :
83 : // Create DIB file header
84 0 : writeU16(image, 0x4D42); // Type
85 0 : writeU32(image, tmpDIBFileSize); // Size
86 0 : writeU16(image, 0); // Reserved1
87 0 : writeU16(image, 0); // Reserved2
88 0 : writeU32(image, tmpDIBOffsetBits); // OffsetBits
89 :
90 : // Create DIB Info header
91 0 : writeU32(image, 40); // Size
92 :
93 0 : writeU32(image, width); // Width
94 0 : writeU32(image, height); // Height
95 :
96 0 : writeU16(image, 1); // Planes
97 0 : writeU16(image, 32); // BitCount
98 0 : writeU32(image, 0); // Compression
99 0 : writeU32(image, tmpDIBImageSize); // SizeImage
100 0 : writeU32(image, 0); // XPelsPerMeter
101 0 : writeU32(image, 0); // YPelsPerMeter
102 0 : writeU32(image, 0); // ColorsUsed
103 0 : writeU32(image, 0); // ColorsImportant
104 :
105 : // Cater for eventual padding
106 0 : unsigned lineWidth = bitmap.size() / height;
107 :
108 0 : bool storeBMP = true;
109 :
110 0 : for (unsigned j = 0; j < height; ++j)
111 : {
112 0 : unsigned i = 0;
113 0 : unsigned k = 0;
114 0 : if (colorModel == 6)
115 : {
116 0 : while (i <lineWidth && k < width)
117 : {
118 0 : unsigned l = 0;
119 0 : unsigned char c = bitmap[j*lineWidth+i];
120 0 : i++;
121 0 : while (k < width && l < 8)
122 : {
123 0 : if (c & 0x80)
124 0 : writeU32(image, 0xffffff);
125 : else
126 0 : writeU32(image, 0);
127 0 : c <<= 1;
128 0 : l++;
129 0 : k++;
130 : }
131 : }
132 : }
133 0 : else if (colorModel == 5)
134 : {
135 0 : while (i <lineWidth && i < width)
136 : {
137 0 : unsigned char c = bitmap[j*lineWidth+i];
138 0 : i++;
139 0 : writeU32(image, m_ps.getBMPColor(libcdr::CDRColor(colorModel, c)));
140 : }
141 : }
142 0 : else if (!palette.empty())
143 : {
144 0 : while (i < lineWidth && i < width)
145 : {
146 0 : unsigned char c = bitmap[j*lineWidth+i];
147 0 : i++;
148 0 : writeU32(image, m_ps.getBMPColor(libcdr::CDRColor(colorModel, palette[c])));
149 : }
150 : }
151 0 : else if (bpp == 24)
152 : {
153 0 : while (i < lineWidth && k < width)
154 : {
155 0 : unsigned c = ((unsigned)bitmap[j*lineWidth+i+2] << 16) | ((unsigned)bitmap[j*lineWidth+i+1] << 8) | ((unsigned)bitmap[j*lineWidth+i]);
156 0 : i += 3;
157 0 : writeU32(image, m_ps.getBMPColor(libcdr::CDRColor(colorModel, c)));
158 0 : k++;
159 : }
160 : }
161 0 : else if (bpp == 32)
162 : {
163 0 : while (i < lineWidth && k < width)
164 : {
165 0 : unsigned c = (bitmap[j*lineWidth+i+3] << 24) | (bitmap[j*lineWidth+i+2] << 16) | (bitmap[j*lineWidth+i+1] << 8) | (bitmap[j*lineWidth+i]);
166 0 : i += 4;
167 0 : writeU32(image, m_ps.getBMPColor(libcdr::CDRColor(colorModel, c)));
168 0 : k++;
169 : }
170 : }
171 : else
172 0 : storeBMP = false;
173 : }
174 :
175 0 : if (storeBMP)
176 : {
177 : #if DUMP_IMAGE
178 : WPXString filename;
179 : filename.sprintf("bitmap%.8x.bmp", imageId);
180 : FILE *f = fopen(filename.cstr(), "wb");
181 : if (f)
182 : {
183 : const unsigned char *tmpBuffer = image.getDataBuffer();
184 : for (unsigned long k = 0; k < image.size(); k++)
185 : fprintf(f, "%c",tmpBuffer[k]);
186 : fclose(f);
187 : }
188 : #endif
189 :
190 0 : m_ps.m_bmps[imageId] = image;
191 0 : }
192 : }
193 :
194 0 : void libcdr::CDRStylesCollector::collectBmp(unsigned imageId, const std::vector<unsigned char> &bitmap)
195 : {
196 0 : WPXBinaryData image(&bitmap[0], bitmap.size());
197 : #if DUMP_IMAGE
198 : WPXString filename;
199 : filename.sprintf("bitmap%.8x.bmp", imageId);
200 : FILE *f = fopen(filename.cstr(), "wb");
201 : if (f)
202 : {
203 : const unsigned char *tmpBuffer = image.getDataBuffer();
204 : for (unsigned long k = 0; k < image.size(); k++)
205 : fprintf(f, "%c",tmpBuffer[k]);
206 : fclose(f);
207 : }
208 : #endif
209 :
210 0 : m_ps.m_bmps[imageId] = image;
211 0 : }
212 :
213 0 : void libcdr::CDRStylesCollector::collectPageSize(double width, double height, double offsetX, double offsetY)
214 : {
215 0 : if (m_ps.m_pages.empty())
216 0 : m_page = CDRPage(width, height, offsetX, offsetY);
217 : else
218 0 : m_ps.m_pages.back() = CDRPage(width, height, offsetX, offsetY);
219 0 : }
220 :
221 0 : void libcdr::CDRStylesCollector::collectPage(unsigned /* level */)
222 : {
223 0 : m_ps.m_pages.push_back(m_page);
224 0 : }
225 :
226 0 : void libcdr::CDRStylesCollector::collectBmpf(unsigned patternId, unsigned width, unsigned height, const std::vector<unsigned char> &pattern)
227 : {
228 0 : m_ps.m_patterns[patternId] = CDRPattern(width, height, pattern);
229 0 : }
230 :
231 0 : void libcdr::CDRStylesCollector::collectColorProfile(const std::vector<unsigned char> &profile)
232 : {
233 0 : if (!profile.empty())
234 0 : m_ps.setColorTransform(profile);
235 0 : }
236 :
237 0 : void libcdr::CDRStylesCollector::collectPaletteEntry(unsigned colorId, unsigned /* userId */, const libcdr::CDRColor &color)
238 : {
239 0 : m_ps.m_documentPalette[colorId] = color;
240 0 : }
241 :
242 0 : void libcdr::CDRStylesCollector::collectFont(unsigned fontId, unsigned short, const WPXString &font)
243 : {
244 0 : m_ps.m_fonts[fontId] = font;
245 0 : }
246 :
247 0 : void libcdr::CDRStylesCollector::collectText(unsigned textId, unsigned styleId, const std::vector<unsigned char> &data,
248 : const std::vector<uint64_t> &charDescriptions, const std::map<unsigned, CDRCharacterStyle> &styleOverrides)
249 : {
250 0 : if (data.empty() || charDescriptions.empty())
251 0 : return;
252 :
253 0 : WPXString text;
254 0 : uint32_t tmpCharDescription = 0;
255 0 : unsigned i = 0;
256 0 : unsigned j = 0;
257 0 : std::vector<unsigned char> tmpTextData;
258 0 : CDRCharacterStyle defaultCharStyle;
259 0 : CDRCharacterStyle tmpCharStyle;
260 :
261 0 : std::map<unsigned, CDRCharacterStyle>::const_iterator iter = m_charStyles.find(styleId);
262 0 : if (iter != m_charStyles.end())
263 0 : defaultCharStyle = iter->second;
264 0 : for (i=0, j=0; i<charDescriptions.size() && j<data.size(); ++i)
265 : {
266 0 : tmpCharStyle = defaultCharStyle;
267 0 : iter = styleOverrides.find((tmpCharDescription >> 16) & 0xff);
268 0 : if (iter != styleOverrides.end())
269 0 : tmpCharStyle.overrideCharacterStyle(iter->second);
270 0 : if ((uint32_t)(charDescriptions[i] & 0xffffff) != tmpCharDescription)
271 : {
272 0 : if (!tmpTextData.empty())
273 : {
274 0 : if (tmpCharDescription & 0x01)
275 0 : appendCharacters(text, tmpTextData);
276 : else
277 0 : appendCharacters(text, tmpTextData, tmpCharStyle.m_charSet);
278 : }
279 0 : tmpTextData.clear();
280 0 : tmpCharDescription = (uint32_t)(charDescriptions[i] & 0xffffff);
281 : }
282 0 : tmpTextData.push_back(data[j++]);
283 0 : if (tmpCharDescription & 0x01)
284 0 : tmpTextData.push_back(data[j++]);
285 : }
286 0 : if (!tmpTextData.empty())
287 : {
288 0 : if (tmpCharDescription & 0x01)
289 0 : appendCharacters(text, tmpTextData);
290 : else
291 0 : appendCharacters(text, tmpTextData, tmpCharStyle.m_charSet);
292 : }
293 :
294 : CDR_DEBUG_MSG(("CDRStylesCollector::collectText - Text: %s\n", text.cstr()));
295 0 : m_ps.m_texts[textId] = CDRText(text, tmpCharStyle);
296 : }
297 :
298 0 : void libcdr::CDRStylesCollector::collectStlt(const std::map<unsigned, CDRCharacterStyle> &charStyles)
299 : {
300 0 : m_charStyles = charStyles;
301 0 : }
302 :
303 : /* vim:set shiftwidth=2 softtabstop=2 expandtab: */
|