]> git.saurik.com Git - wxWidgets.git/blame - src/html/winpars.cpp
merged MapBitmap() from 2.2 branch
[wxWidgets.git] / src / html / winpars.cpp
CommitLineData
5526e819 1/////////////////////////////////////////////////////////////////////////////
69941f05 2// Name: winpars.cpp
5526e819
VS
3// Purpose: wxHtmlParser class (generic parser)
4// Author: Vaclav Slavik
69941f05 5// RCS-ID: $Id$
5526e819
VS
6// Copyright: (c) 1999 Vaclav Slavik
7// Licence: wxWindows Licence
8/////////////////////////////////////////////////////////////////////////////
9
10
11#ifdef __GNUG__
12#pragma implementation
13#endif
14
3096bd2f 15#include "wx/wxprec.h"
5526e819
VS
16
17#include "wx/defs.h"
f6bcfd97 18#if wxUSE_HTML && wxUSE_STREAMS
5526e819
VS
19
20#ifdef __BORDLANDC__
21#pragma hdrstop
22#endif
23
24#ifndef WXPRECOMP
04dbb646
VZ
25 #include "wx/intl.h"
26 #include "wx/dc.h"
5526e819
VS
27#endif
28
69941f05
VS
29#include "wx/html/htmldefs.h"
30#include "wx/html/winpars.h"
31#include "wx/html/htmlwin.h"
b250d384 32#include "wx/fontmap.h"
f3c82859 33#include "wx/log.h"
5526e819
VS
34
35
36//-----------------------------------------------------------------------------
37// wxHtmlWinParser
38//-----------------------------------------------------------------------------
39
5526e819
VS
40
41wxList wxHtmlWinParser::m_Modules;
42
43wxHtmlWinParser::wxHtmlWinParser(wxWindow *wnd) : wxHtmlParser()
44{
45 m_Window = wnd;
46 m_Container = NULL;
47 m_DC = NULL;
48 m_CharHeight = m_CharWidth = 0;
49 m_UseLink = FALSE;
b250d384
VS
50 m_EncConv = NULL;
51 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
5526e819
VS
52
53 {
54 int i, j, k, l, m;
55 for (i = 0; i < 2; i++)
56 for (j = 0; j < 2; j++)
57 for (k = 0; k < 2; k++)
58 for (l = 0; l < 2; l++)
4f9297b0
VS
59 for (m = 0; m < 7; m++)
60 {
5526e819 61 m_FontsTable[i][j][k][l][m] = NULL;
f1ad10f3 62 m_FontsFacesTable[i][j][k][l][m] = wxEmptyString;
b250d384 63 m_FontsEncTable[i][j][k][l][m] = wxFONTENCODING_DEFAULT;
f1ad10f3 64 }
5526e819 65#ifdef __WXMSW__
1bb27b0c 66 static int default_sizes[7] = {7, 8, 10, 12, 16, 22, 30};
cc638fc6
VS
67#elif defined(__WXMAC__)
68 static int default_sizes[7] = {9, 12, 14, 18, 24, 30, 36};
5526e819 69#else
1bb27b0c 70 static int default_sizes[7] = {10, 12, 14, 16, 19, 24, 32};
5526e819 71#endif
8eb2940f 72 SetFonts("", "", default_sizes);
5526e819
VS
73 }
74
75 // fill in wxHtmlParser's tables:
76 wxNode *node = m_Modules.GetFirst();
4f9297b0
VS
77 while (node)
78 {
79 wxHtmlTagsModule *mod = (wxHtmlTagsModule*) node->GetData();
80 mod->FillHandlersTable(this);
81 node = node->GetNext();
5526e819
VS
82 }
83}
84
85
b250d384
VS
86wxHtmlWinParser::~wxHtmlWinParser()
87{
88 int i, j, k, l, m;
89
90 for (i = 0; i < 2; i++)
91 for (j = 0; j < 2; j++)
92 for (k = 0; k < 2; k++)
93 for (l = 0; l < 2; l++)
4f9297b0
VS
94 for (m = 0; m < 7; m++)
95 {
b250d384
VS
96 if (m_FontsTable[i][j][k][l][m] != NULL)
97 delete m_FontsTable[i][j][k][l][m];
98 }
99 if (m_EncConv) delete m_EncConv;
100}
101
5526e819
VS
102
103void wxHtmlWinParser::AddModule(wxHtmlTagsModule *module)
104{
105 m_Modules.Append(module);
106}
107
108
109
f6bcfd97
BP
110void wxHtmlWinParser::RemoveModule(wxHtmlTagsModule *module)
111{
112 m_Modules.DeleteObject(module);
113}
114
115
116
8eb2940f 117void wxHtmlWinParser::SetFonts(wxString normal_face, wxString fixed_face, const int *sizes)
5526e819 118{
c9f56e70
VS
119 int i, j, k, l, m;
120
121 for (i = 0; i < 7; i++) m_FontsSizes[i] = sizes[i];
5526e819
VS
122 m_FontFaceFixed = fixed_face;
123 m_FontFaceNormal = normal_face;
b250d384
VS
124
125 SetInputEncoding(m_InputEnc);
c9f56e70
VS
126
127 for (i = 0; i < 2; i++)
128 for (j = 0; j < 2; j++)
129 for (k = 0; k < 2; k++)
130 for (l = 0; l < 2; l++)
131 for (m = 0; m < 7; m++) {
4f9297b0
VS
132 if (m_FontsTable[i][j][k][l][m] != NULL)
133 {
c9f56e70
VS
134 delete m_FontsTable[i][j][k][l][m];
135 m_FontsTable[i][j][k][l][m] = NULL;
136 }
137 }
5526e819
VS
138}
139
140
141
142void wxHtmlWinParser::InitParser(const wxString& source)
143{
144 wxHtmlParser::InitParser(source);
0e8c8233 145 wxASSERT_MSG(m_DC != NULL, _T("no DC assigned to wxHtmlWinParser!!"));
5526e819
VS
146
147 m_FontBold = m_FontItalic = m_FontUnderlined = m_FontFixed = FALSE;
f2c2fa4d 148 m_FontSize = 3; //default one
5526e819 149 CreateCurrentFont(); // we're selecting default font into
4f9297b0 150 m_DC->GetTextExtent("H", &m_CharWidth, &m_CharHeight);
5526e819 151 /* NOTE : we're not using GetCharWidth/Height() because
0e8c8233 152 of differences under X and win
5526e819
VS
153 */
154
f2c2fa4d
VS
155 m_UseLink = FALSE;
156 m_Link = wxHtmlLinkInfo("", "");
5526e819
VS
157 m_LinkColor.Set(0, 0, 0xFF);
158 m_ActualColor.Set(0, 0, 0);
efba2b89 159 m_Align = wxHTML_ALIGN_LEFT;
5526e819
VS
160 m_tmpLastWasSpace = FALSE;
161
162 OpenContainer();
163
164 OpenContainer();
4f9297b0
VS
165 m_Container->InsertCell(new wxHtmlColourCell(m_ActualColor));
166 m_Container->InsertCell(new wxHtmlFontCell(CreateCurrentFont()));
5526e819
VS
167}
168
169
170
171void wxHtmlWinParser::DoneParser()
172{
173 m_Container = NULL;
b250d384 174 SetInputEncoding(wxFONTENCODING_DEFAULT); // for next call
5526e819
VS
175 wxHtmlParser::DoneParser();
176}
177
178
179
180wxObject* wxHtmlWinParser::GetProduct()
181{
182 wxHtmlContainerCell *top;
183
184 CloseContainer();
185 OpenContainer();
67cfebc2 186
5526e819 187 top = m_Container;
4f9297b0 188 while (top->GetParent()) top = top->GetParent();
5526e819
VS
189 return top;
190}
191
192
193
5526e819
VS
194void wxHtmlWinParser::AddText(const char* txt)
195{
196 wxHtmlCell *c;
197 int i = 0, x, lng = strlen(txt);
efba2b89 198 char temp[wxHTML_BUFLEN];
5526e819
VS
199 register char d;
200 int templen = 0;
daa616fc 201
4f9297b0
VS
202 if (m_tmpLastWasSpace)
203 {
daa616fc
VS
204 while ((i < lng) &&
205 ((txt[i] == '\n') || (txt[i] == '\r') || (txt[i] == ' ') ||
206 (txt[i] == '\t'))) i++;
5526e819
VS
207 }
208
4f9297b0
VS
209 while (i < lng)
210 {
5526e819
VS
211 x = 0;
212 d = temp[templen++] = txt[i];
4f9297b0
VS
213 if ((d == '\n') || (d == '\r') || (d == ' ') || (d == '\t'))
214 {
5526e819 215 i++, x++;
daa616fc
VS
216 while ((i < lng) && ((txt[i] == '\n') || (txt[i] == '\r') ||
217 (txt[i] == ' ') || (txt[i] == '\t'))) i++, x++;
5526e819
VS
218 }
219 else i++;
220
4f9297b0
VS
221 if (x)
222 {
5526e819
VS
223 temp[templen-1] = ' ';
224 temp[templen] = 0;
225 templen = 0;
daa616fc
VS
226 if (m_EncConv)
227 m_EncConv->Convert(temp);
228 c = new wxHtmlWordCell(GetEntitiesParser()->Parse(temp), *(GetDC()));
229 if (m_UseLink)
230 c->SetLink(m_Link);
4f9297b0 231 m_Container->InsertCell(c);
5526e819
VS
232 m_tmpLastWasSpace = TRUE;
233 }
234 }
4f9297b0
VS
235 if (templen)
236 {
5526e819 237 temp[templen] = 0;
daa616fc
VS
238 if (m_EncConv)
239 m_EncConv->Convert(temp);
240 c = new wxHtmlWordCell(GetEntitiesParser()->Parse(temp), *(GetDC()));
241 if (m_UseLink)
242 c->SetLink(m_Link);
4f9297b0 243 m_Container->InsertCell(c);
5526e819
VS
244 m_tmpLastWasSpace = FALSE;
245 }
246}
247
248
249
250wxHtmlContainerCell* wxHtmlWinParser::OpenContainer()
251{
252 m_Container = new wxHtmlContainerCell(m_Container);
4f9297b0 253 m_Container->SetAlignHor(m_Align);
5526e819
VS
254 m_tmpLastWasSpace = TRUE;
255 /* to avoid space being first character in paragraph */
256 return m_Container;
257}
258
259
260
261wxHtmlContainerCell* wxHtmlWinParser::SetContainer(wxHtmlContainerCell *c)
262{
263 m_tmpLastWasSpace = TRUE;
264 /* to avoid space being first character in paragraph */
265 return m_Container = c;
266}
267
268
269
270wxHtmlContainerCell* wxHtmlWinParser::CloseContainer()
271{
4f9297b0 272 m_Container = m_Container->GetParent();
5526e819
VS
273 return m_Container;
274}
275
276
f2c2fa4d
VS
277void wxHtmlWinParser::SetFontSize(int s)
278{
279 if (s < 1) s = 1;
280 else if (s > 7) s = 7;
281 m_FontSize = s;
282}
283
284
285
5526e819
VS
286wxFont* wxHtmlWinParser::CreateCurrentFont()
287{
288 int fb = GetFontBold(),
289 fi = GetFontItalic(),
290 fu = GetFontUnderlined(),
291 ff = GetFontFixed(),
f2c2fa4d 292 fs = GetFontSize() - 1 /*remap from <1;7> to <0;6>*/ ;
5526e819 293
f1ad10f3
VS
294 wxString face = ff ? m_FontFaceFixed : m_FontFaceNormal;
295 wxString *faceptr = &(m_FontsFacesTable[fb][fi][fu][ff][fs]);
296 wxFont **fontptr = &(m_FontsTable[fb][fi][fu][ff][fs]);
b250d384 297 wxFontEncoding *encptr = &(m_FontsEncTable[fb][fi][fu][ff][fs]);
f1ad10f3 298
4f9297b0
VS
299 if (*fontptr != NULL && (*faceptr != face || *encptr != m_OutputEnc))
300 {
f1ad10f3
VS
301 delete *fontptr;
302 *fontptr = NULL;
303 }
304
4f9297b0
VS
305 if (*fontptr == NULL)
306 {
f1ad10f3 307 *faceptr = face;
b250d384 308 *encptr = m_OutputEnc;
f1ad10f3 309 *fontptr = new wxFont(
7a5e6267 310 (int) (m_FontsSizes[fs] * m_PixelScale),
f1ad10f3
VS
311 ff ? wxMODERN : wxSWISS,
312 fi ? wxITALIC : wxNORMAL,
313 fb ? wxBOLD : wxNORMAL,
b250d384
VS
314 fu ? TRUE : FALSE, face,
315 m_OutputEnc);
5526e819 316 }
4f9297b0 317 m_DC->SetFont(**fontptr);
f1ad10f3 318 return (*fontptr);
5526e819
VS
319}
320
321
322
f2c2fa4d
VS
323void wxHtmlWinParser::SetLink(const wxHtmlLinkInfo& link)
324{
325 m_Link = link;
326 m_UseLink = (link.GetHref() != wxEmptyString);
327}
328
329
b250d384
VS
330void wxHtmlWinParser::SetFontFace(const wxString& face)
331{
332 if (GetFontFixed()) m_FontFaceFixed = face;
333 else m_FontFaceNormal = face;
334
335 if (m_InputEnc != wxFONTENCODING_DEFAULT)
336 SetInputEncoding(m_InputEnc);
337}
338
339
340
341void wxHtmlWinParser::SetInputEncoding(wxFontEncoding enc)
342{
343 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
daa616fc
VS
344 if (m_EncConv)
345 {
346 delete m_EncConv;
347 m_EncConv = NULL;
348 }
b250d384
VS
349
350 if (enc == wxFONTENCODING_DEFAULT) return;
351
352 wxFontEncoding altfix, altnorm;
353 bool availfix, availnorm;
354
355 // exact match?
4f9297b0
VS
356 availnorm = wxTheFontMapper->IsEncodingAvailable(enc, m_FontFaceNormal);
357 availfix = wxTheFontMapper->IsEncodingAvailable(enc, m_FontFaceFixed);
b250d384
VS
358 if (availnorm && availfix)
359 m_OutputEnc = enc;
360
361 // alternatives?
4f9297b0
VS
362 else if (wxTheFontMapper->GetAltForEncoding(enc, &altnorm, m_FontFaceNormal, FALSE) &&
363 wxTheFontMapper->GetAltForEncoding(enc, &altfix, m_FontFaceFixed, FALSE) &&
b250d384
VS
364 altnorm == altfix)
365 m_OutputEnc = altnorm;
366
367 // at least normal face?
368 else if (availnorm)
369 m_OutputEnc = enc;
4f9297b0 370 else if (wxTheFontMapper->GetAltForEncoding(enc, &altnorm, m_FontFaceNormal, FALSE))
b250d384
VS
371 m_OutputEnc = altnorm;
372
373 // okay, let convert to ISO_8859-1, available always
374 else
375 m_OutputEnc = wxFONTENCODING_DEFAULT;
376
377 m_InputEnc = enc;
daa616fc
VS
378 if (m_OutputEnc == wxFONTENCODING_DEFAULT)
379 GetEntitiesParser()->SetEncoding(wxFONTENCODING_SYSTEM);
380 else
381 GetEntitiesParser()->SetEncoding(m_OutputEnc);
b250d384
VS
382
383 if (m_InputEnc == m_OutputEnc) return;
384
385 m_EncConv = new wxEncodingConverter();
4f9297b0 386 if (!m_EncConv->Init(m_InputEnc,
b250d384
VS
387 (m_OutputEnc == wxFONTENCODING_DEFAULT) ?
388 wxFONTENCODING_ISO8859_1 : m_OutputEnc,
389 wxCONVERT_SUBSTITUTE))
390 { // total failture :-(
f3c82859 391 wxLogError(_("Failed to display HTML document in %s encoding"),
f6bcfd97 392 wxFontMapper::GetEncodingName(enc).c_str());
b250d384
VS
393 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
394 delete m_EncConv;
395 m_EncConv = NULL;
396 }
397}
398
399
400
f2c2fa4d 401
5526e819
VS
402
403//-----------------------------------------------------------------------------
404// wxHtmlWinTagHandler
405//-----------------------------------------------------------------------------
406
407IMPLEMENT_ABSTRACT_CLASS(wxHtmlWinTagHandler, wxHtmlTagHandler)
408
409
410
411//-----------------------------------------------------------------------------
412// wxHtmlTagsModule
413//-----------------------------------------------------------------------------
414
415
416IMPLEMENT_DYNAMIC_CLASS(wxHtmlTagsModule, wxModule)
417
418
419bool wxHtmlTagsModule::OnInit()
420{
421 wxHtmlWinParser::AddModule(this);
422 return TRUE;
423}
424
425
426
427void wxHtmlTagsModule::OnExit()
428{
f6bcfd97 429 wxHtmlWinParser::RemoveModule(this);
5526e819 430}
223d09f6 431#endif
5526e819 432