]> git.saurik.com Git - wxWidgets.git/blame - src/html/winpars.cpp
minus one show stopper typo and a couple of warnings on mingw.
[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__
1aedb1dd 12#pragma implementation "winpars.h"
5526e819
VS
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
04db5c3f 43wxHtmlWinParser::wxHtmlWinParser(wxHtmlWindow *wnd) : wxHtmlParser()
5526e819 44{
211dfedd
VS
45 m_tmpStrBuf = NULL;
46 m_tmpStrBufSize = 0;
5526e819
VS
47 m_Window = wnd;
48 m_Container = NULL;
49 m_DC = NULL;
50 m_CharHeight = m_CharWidth = 0;
51 m_UseLink = FALSE;
b250d384
VS
52 m_EncConv = NULL;
53 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
5526e819
VS
54
55 {
56 int i, j, k, l, m;
57 for (i = 0; i < 2; i++)
58 for (j = 0; j < 2; j++)
59 for (k = 0; k < 2; k++)
60 for (l = 0; l < 2; l++)
3c8c8da2 61 for (m = 0; m < 7; m++)
e3c7fd79 62 {
5526e819 63 m_FontsTable[i][j][k][l][m] = NULL;
f1ad10f3 64 m_FontsFacesTable[i][j][k][l][m] = wxEmptyString;
b250d384 65 m_FontsEncTable[i][j][k][l][m] = wxFONTENCODING_DEFAULT;
f1ad10f3 66 }
5526e819 67#ifdef __WXMSW__
1bb27b0c 68 static int default_sizes[7] = {7, 8, 10, 12, 16, 22, 30};
cc638fc6
VS
69#elif defined(__WXMAC__)
70 static int default_sizes[7] = {9, 12, 14, 18, 24, 30, 36};
5526e819 71#else
1bb27b0c 72 static int default_sizes[7] = {10, 12, 14, 16, 19, 24, 32};
5526e819 73#endif
8eb2940f 74 SetFonts("", "", default_sizes);
5526e819
VS
75 }
76
77 // fill in wxHtmlParser's tables:
78 wxNode *node = m_Modules.GetFirst();
3c8c8da2 79 while (node)
4f9297b0
VS
80 {
81 wxHtmlTagsModule *mod = (wxHtmlTagsModule*) node->GetData();
82 mod->FillHandlersTable(this);
83 node = node->GetNext();
5526e819
VS
84 }
85}
86
b250d384
VS
87wxHtmlWinParser::~wxHtmlWinParser()
88{
89 int i, j, k, l, m;
90
91 for (i = 0; i < 2; i++)
92 for (j = 0; j < 2; j++)
93 for (k = 0; k < 2; k++)
94 for (l = 0; l < 2; l++)
3c8c8da2 95 for (m = 0; m < 7; m++)
e3c7fd79 96 {
3c8c8da2 97 if (m_FontsTable[i][j][k][l][m] != NULL)
b250d384
VS
98 delete m_FontsTable[i][j][k][l][m];
99 }
211dfedd
VS
100 delete m_EncConv;
101 delete[] m_tmpStrBuf;
b250d384
VS
102}
103
5526e819
VS
104void wxHtmlWinParser::AddModule(wxHtmlTagsModule *module)
105{
106 m_Modules.Append(module);
107}
108
f6bcfd97
BP
109void wxHtmlWinParser::RemoveModule(wxHtmlTagsModule *module)
110{
111 m_Modules.DeleteObject(module);
112}
113
8eb2940f 114void wxHtmlWinParser::SetFonts(wxString normal_face, wxString fixed_face, const int *sizes)
5526e819 115{
c9f56e70
VS
116 int i, j, k, l, m;
117
118 for (i = 0; i < 7; i++) m_FontsSizes[i] = sizes[i];
5526e819
VS
119 m_FontFaceFixed = fixed_face;
120 m_FontFaceNormal = normal_face;
3c8c8da2 121
b250d384 122 SetInputEncoding(m_InputEnc);
c9f56e70
VS
123
124 for (i = 0; i < 2; i++)
125 for (j = 0; j < 2; j++)
126 for (k = 0; k < 2; k++)
127 for (l = 0; l < 2; l++)
128 for (m = 0; m < 7; m++) {
3c8c8da2 129 if (m_FontsTable[i][j][k][l][m] != NULL)
e3c7fd79 130 {
c9f56e70
VS
131 delete m_FontsTable[i][j][k][l][m];
132 m_FontsTable[i][j][k][l][m] = NULL;
133 }
134 }
5526e819
VS
135}
136
5526e819
VS
137void wxHtmlWinParser::InitParser(const wxString& source)
138{
139 wxHtmlParser::InitParser(source);
0e8c8233 140 wxASSERT_MSG(m_DC != NULL, _T("no DC assigned to wxHtmlWinParser!!"));
5526e819
VS
141
142 m_FontBold = m_FontItalic = m_FontUnderlined = m_FontFixed = FALSE;
f2c2fa4d 143 m_FontSize = 3; //default one
5526e819 144 CreateCurrentFont(); // we're selecting default font into
4f9297b0 145 m_DC->GetTextExtent("H", &m_CharWidth, &m_CharHeight);
5526e819 146 /* NOTE : we're not using GetCharWidth/Height() because
0e8c8233 147 of differences under X and win
5526e819
VS
148 */
149
f2c2fa4d
VS
150 m_UseLink = FALSE;
151 m_Link = wxHtmlLinkInfo("", "");
5526e819
VS
152 m_LinkColor.Set(0, 0, 0xFF);
153 m_ActualColor.Set(0, 0, 0);
efba2b89 154 m_Align = wxHTML_ALIGN_LEFT;
5526e819
VS
155 m_tmpLastWasSpace = FALSE;
156
157 OpenContainer();
158
159 OpenContainer();
4f9297b0
VS
160 m_Container->InsertCell(new wxHtmlColourCell(m_ActualColor));
161 m_Container->InsertCell(new wxHtmlFontCell(CreateCurrentFont()));
5526e819
VS
162}
163
5526e819
VS
164void wxHtmlWinParser::DoneParser()
165{
166 m_Container = NULL;
b250d384 167 SetInputEncoding(wxFONTENCODING_DEFAULT); // for next call
5526e819
VS
168 wxHtmlParser::DoneParser();
169}
170
5526e819
VS
171wxObject* wxHtmlWinParser::GetProduct()
172{
173 wxHtmlContainerCell *top;
174
175 CloseContainer();
176 OpenContainer();
67cfebc2 177
5526e819 178 top = m_Container;
4f9297b0 179 while (top->GetParent()) top = top->GetParent();
5526e819
VS
180 return top;
181}
182
0423bdc7 183wxFSFile *wxHtmlWinParser::OpenURL(wxHtmlURLType type,
6cc4e6b8 184 const wxString& url) const
04db5c3f
VS
185{
186 // FIXME - normalize the URL to full path before passing to
187 // OnOpeningURL!!
188 if ( m_Window )
6cc4e6b8 189 {
6cc4e6b8
VS
190 wxString myurl(url);
191 wxHtmlOpeningStatus status;
192 for (;;)
193 {
0423bdc7
VZ
194 wxString redirect;
195 status = m_Window->OnOpeningURL(type, myurl, &redirect);
196 if ( status != wxHTML_REDIRECT )
6cc4e6b8 197 break;
0423bdc7
VZ
198
199 myurl = redirect;
6cc4e6b8 200 }
0423bdc7 201
6cc4e6b8
VS
202 if ( status == wxHTML_BLOCK )
203 return NULL;
2c892c0b
VZ
204
205 return GetFS()->OpenFile(myurl);
6cc4e6b8 206 }
2c892c0b
VZ
207
208 return wxHtmlParser::OpenURL(type, url);
04db5c3f 209}
5526e819 210
211dfedd 211void wxHtmlWinParser::AddText(const wxChar* txt)
5526e819
VS
212{
213 wxHtmlCell *c;
e3c7fd79
VZ
214 size_t i = 0,
215 x,
216 lng = wxStrlen(txt);
211dfedd 217 register wxChar d;
5526e819 218 int templen = 0;
f23e92e7 219 wxChar nbsp = GetEntitiesParser()->GetCharForCode(160 /* nbsp */);
211dfedd
VS
220
221 if (lng+1 > m_tmpStrBufSize)
222 {
223 delete[] m_tmpStrBuf;
224 m_tmpStrBuf = new wxChar[lng+1];
225 m_tmpStrBufSize = lng+1;
226 }
227 wxChar *temp = m_tmpStrBuf;
3c8c8da2
VZ
228
229 if (m_tmpLastWasSpace)
4f9297b0 230 {
3c8c8da2
VZ
231 while ((i < lng) &&
232 ((txt[i] == wxT('\n')) || (txt[i] == wxT('\r')) || (txt[i] == wxT(' ')) ||
211dfedd 233 (txt[i] == wxT('\t')))) i++;
5526e819
VS
234 }
235
3c8c8da2 236 while (i < lng)
4f9297b0 237 {
5526e819
VS
238 x = 0;
239 d = temp[templen++] = txt[i];
3c8c8da2 240 if ((d == wxT('\n')) || (d == wxT('\r')) || (d == wxT(' ')) || (d == wxT('\t')))
e3c7fd79 241 {
5526e819 242 i++, x++;
3c8c8da2 243 while ((i < lng) && ((txt[i] == wxT('\n')) || (txt[i] == wxT('\r')) ||
211dfedd 244 (txt[i] == wxT(' ')) || (txt[i] == wxT('\t')))) i++, x++;
5526e819
VS
245 }
246 else i++;
247
3c8c8da2 248 if (x)
e3c7fd79 249 {
211dfedd 250 temp[templen-1] = wxT(' ');
5526e819 251 temp[templen] = 0;
0d5b4bc2 252#if 0 // VS - WHY was this here?!
af035b26 253 if (templen == 1) continue;
0d5b4bc2 254#endif
5526e819 255 templen = 0;
3c8c8da2 256 if (m_EncConv)
daa616fc 257 m_EncConv->Convert(temp);
88dcf47c 258 size_t len = wxStrlen(temp);
f23e92e7 259 for (size_t j = 0; j < len; j++)
88dcf47c
VS
260 if (temp[j] == nbsp)
261 temp[j] = wxT(' ');
262 c = new wxHtmlWordCell(temp, *(GetDC()));
3c8c8da2 263 if (m_UseLink)
daa616fc 264 c->SetLink(m_Link);
4f9297b0 265 m_Container->InsertCell(c);
5526e819
VS
266 m_tmpLastWasSpace = TRUE;
267 }
268 }
af035b26
VS
269
270 if (templen && (templen > 1 || temp[0] != wxT(' ')))
4f9297b0 271 {
5526e819 272 temp[templen] = 0;
3c8c8da2 273 if (m_EncConv)
daa616fc 274 m_EncConv->Convert(temp);
88dcf47c 275 size_t len = wxStrlen(temp);
f23e92e7 276 for (size_t j = 0; j < len; j++)
88dcf47c
VS
277 if (temp[j] == nbsp)
278 temp[j] = wxT(' ');
279 c = new wxHtmlWordCell(temp, *(GetDC()));
211dfedd 280 if (m_UseLink)
daa616fc 281 c->SetLink(m_Link);
4f9297b0 282 m_Container->InsertCell(c);
5526e819
VS
283 m_tmpLastWasSpace = FALSE;
284 }
285}
286
287
288
289wxHtmlContainerCell* wxHtmlWinParser::OpenContainer()
290{
291 m_Container = new wxHtmlContainerCell(m_Container);
4f9297b0 292 m_Container->SetAlignHor(m_Align);
5526e819
VS
293 m_tmpLastWasSpace = TRUE;
294 /* to avoid space being first character in paragraph */
295 return m_Container;
296}
297
298
299
300wxHtmlContainerCell* wxHtmlWinParser::SetContainer(wxHtmlContainerCell *c)
301{
302 m_tmpLastWasSpace = TRUE;
303 /* to avoid space being first character in paragraph */
304 return m_Container = c;
305}
306
307
308
309wxHtmlContainerCell* wxHtmlWinParser::CloseContainer()
310{
4f9297b0 311 m_Container = m_Container->GetParent();
5526e819
VS
312 return m_Container;
313}
314
315
f2c2fa4d
VS
316void wxHtmlWinParser::SetFontSize(int s)
317{
318 if (s < 1) s = 1;
319 else if (s > 7) s = 7;
320 m_FontSize = s;
321}
322
323
324
5526e819
VS
325wxFont* wxHtmlWinParser::CreateCurrentFont()
326{
327 int fb = GetFontBold(),
328 fi = GetFontItalic(),
329 fu = GetFontUnderlined(),
330 ff = GetFontFixed(),
f2c2fa4d 331 fs = GetFontSize() - 1 /*remap from <1;7> to <0;6>*/ ;
5526e819 332
f1ad10f3
VS
333 wxString face = ff ? m_FontFaceFixed : m_FontFaceNormal;
334 wxString *faceptr = &(m_FontsFacesTable[fb][fi][fu][ff][fs]);
335 wxFont **fontptr = &(m_FontsTable[fb][fi][fu][ff][fs]);
b250d384 336 wxFontEncoding *encptr = &(m_FontsEncTable[fb][fi][fu][ff][fs]);
f1ad10f3 337
3c8c8da2 338 if (*fontptr != NULL && (*faceptr != face || *encptr != m_OutputEnc))
4f9297b0 339 {
f1ad10f3
VS
340 delete *fontptr;
341 *fontptr = NULL;
342 }
343
3c8c8da2 344 if (*fontptr == NULL)
4f9297b0 345 {
f1ad10f3 346 *faceptr = face;
b250d384 347 *encptr = m_OutputEnc;
f1ad10f3 348 *fontptr = new wxFont(
7a5e6267 349 (int) (m_FontsSizes[fs] * m_PixelScale),
f1ad10f3
VS
350 ff ? wxMODERN : wxSWISS,
351 fi ? wxITALIC : wxNORMAL,
352 fb ? wxBOLD : wxNORMAL,
b250d384
VS
353 fu ? TRUE : FALSE, face,
354 m_OutputEnc);
5526e819 355 }
4f9297b0 356 m_DC->SetFont(**fontptr);
f1ad10f3 357 return (*fontptr);
5526e819
VS
358}
359
360
361
f2c2fa4d
VS
362void wxHtmlWinParser::SetLink(const wxHtmlLinkInfo& link)
363{
3c8c8da2 364 m_Link = link;
f2c2fa4d
VS
365 m_UseLink = (link.GetHref() != wxEmptyString);
366}
367
368
3c8c8da2 369void wxHtmlWinParser::SetFontFace(const wxString& face)
b250d384 370{
3c8c8da2 371 if (GetFontFixed()) m_FontFaceFixed = face;
b250d384
VS
372 else m_FontFaceNormal = face;
373
374 if (m_InputEnc != wxFONTENCODING_DEFAULT)
375 SetInputEncoding(m_InputEnc);
376}
377
378
379
380void wxHtmlWinParser::SetInputEncoding(wxFontEncoding enc)
381{
382 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
3c8c8da2 383 if (m_EncConv)
daa616fc 384 {
3c8c8da2 385 delete m_EncConv;
daa616fc
VS
386 m_EncConv = NULL;
387 }
b250d384
VS
388
389 if (enc == wxFONTENCODING_DEFAULT) return;
390
391 wxFontEncoding altfix, altnorm;
392 bool availfix, availnorm;
3c8c8da2
VZ
393
394 // exact match?
142b3bc2
VS
395 availnorm = wxFontMapper::Get()->IsEncodingAvailable(enc, m_FontFaceNormal);
396 availfix = wxFontMapper::Get()->IsEncodingAvailable(enc, m_FontFaceFixed);
3c8c8da2 397 if (availnorm && availfix)
b250d384 398 m_OutputEnc = enc;
3c8c8da2 399
b250d384 400 // alternatives?
142b3bc2
VS
401 else if (wxFontMapper::Get()->GetAltForEncoding(enc, &altnorm, m_FontFaceNormal, FALSE) &&
402 wxFontMapper::Get()->GetAltForEncoding(enc, &altfix, m_FontFaceFixed, FALSE) &&
b250d384
VS
403 altnorm == altfix)
404 m_OutputEnc = altnorm;
3c8c8da2 405
b250d384
VS
406 // at least normal face?
407 else if (availnorm)
408 m_OutputEnc = enc;
142b3bc2 409 else if (wxFontMapper::Get()->GetAltForEncoding(enc, &altnorm, m_FontFaceNormal, FALSE))
b250d384 410 m_OutputEnc = altnorm;
3c8c8da2 411
b250d384
VS
412 // okay, let convert to ISO_8859-1, available always
413 else
414 m_OutputEnc = wxFONTENCODING_DEFAULT;
3c8c8da2 415
b250d384 416 m_InputEnc = enc;
daa616fc
VS
417 if (m_OutputEnc == wxFONTENCODING_DEFAULT)
418 GetEntitiesParser()->SetEncoding(wxFONTENCODING_SYSTEM);
419 else
420 GetEntitiesParser()->SetEncoding(m_OutputEnc);
3c8c8da2 421
b250d384
VS
422 if (m_InputEnc == m_OutputEnc) return;
423
424 m_EncConv = new wxEncodingConverter();
3c8c8da2 425 if (!m_EncConv->Init(m_InputEnc,
b250d384
VS
426 (m_OutputEnc == wxFONTENCODING_DEFAULT) ?
427 wxFONTENCODING_ISO8859_1 : m_OutputEnc,
3c8c8da2 428 wxCONVERT_SUBSTITUTE))
b250d384 429 { // total failture :-(
3c8c8da2
VZ
430 wxLogError(_("Failed to display HTML document in %s encoding"),
431 wxFontMapper::GetEncodingName(enc).c_str());
b250d384
VS
432 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
433 delete m_EncConv;
434 m_EncConv = NULL;
435 }
436}
437
438
439
f2c2fa4d 440
5526e819
VS
441
442//-----------------------------------------------------------------------------
443// wxHtmlWinTagHandler
444//-----------------------------------------------------------------------------
445
446IMPLEMENT_ABSTRACT_CLASS(wxHtmlWinTagHandler, wxHtmlTagHandler)
447
5526e819
VS
448//-----------------------------------------------------------------------------
449// wxHtmlTagsModule
450//-----------------------------------------------------------------------------
451
d6a6d666
VS
452// NB: This is *NOT* winpars.cpp's initialization and shutdown code!!
453// This module is an ancestor for tag handlers modules defined
454// in m_*.cpp files with TAGS_MODULE_BEGIN...TAGS_MODULE_END construct.
455//
456// Do not add any winpars.cpp shutdown or initialization code to it,
457// create a new module instead!
5526e819
VS
458
459IMPLEMENT_DYNAMIC_CLASS(wxHtmlTagsModule, wxModule)
460
5526e819
VS
461bool wxHtmlTagsModule::OnInit()
462{
463 wxHtmlWinParser::AddModule(this);
464 return TRUE;
465}
466
5526e819
VS
467void wxHtmlTagsModule::OnExit()
468{
f6bcfd97 469 wxHtmlWinParser::RemoveModule(this);
5526e819 470}
d6a6d666 471
223d09f6 472#endif
5526e819 473