]> git.saurik.com Git - wxWidgets.git/blame - src/html/winpars.cpp
added wxHtmlCell::Get/SetId
[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{
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
87
b250d384
VS
88wxHtmlWinParser::~wxHtmlWinParser()
89{
90 int i, j, k, l, m;
91
92 for (i = 0; i < 2; i++)
93 for (j = 0; j < 2; j++)
94 for (k = 0; k < 2; k++)
95 for (l = 0; l < 2; l++)
3c8c8da2 96 for (m = 0; m < 7; m++)
e3c7fd79 97 {
3c8c8da2 98 if (m_FontsTable[i][j][k][l][m] != NULL)
b250d384
VS
99 delete m_FontsTable[i][j][k][l][m];
100 }
211dfedd
VS
101 delete m_EncConv;
102 delete[] m_tmpStrBuf;
b250d384
VS
103}
104
5526e819
VS
105
106void wxHtmlWinParser::AddModule(wxHtmlTagsModule *module)
107{
108 m_Modules.Append(module);
109}
110
111
112
f6bcfd97
BP
113void wxHtmlWinParser::RemoveModule(wxHtmlTagsModule *module)
114{
115 m_Modules.DeleteObject(module);
116}
117
118
119
8eb2940f 120void wxHtmlWinParser::SetFonts(wxString normal_face, wxString fixed_face, const int *sizes)
5526e819 121{
c9f56e70
VS
122 int i, j, k, l, m;
123
124 for (i = 0; i < 7; i++) m_FontsSizes[i] = sizes[i];
5526e819
VS
125 m_FontFaceFixed = fixed_face;
126 m_FontFaceNormal = normal_face;
3c8c8da2 127
b250d384 128 SetInputEncoding(m_InputEnc);
c9f56e70
VS
129
130 for (i = 0; i < 2; i++)
131 for (j = 0; j < 2; j++)
132 for (k = 0; k < 2; k++)
133 for (l = 0; l < 2; l++)
134 for (m = 0; m < 7; m++) {
3c8c8da2 135 if (m_FontsTable[i][j][k][l][m] != NULL)
e3c7fd79 136 {
c9f56e70
VS
137 delete m_FontsTable[i][j][k][l][m];
138 m_FontsTable[i][j][k][l][m] = NULL;
139 }
140 }
5526e819
VS
141}
142
143
144
145void wxHtmlWinParser::InitParser(const wxString& source)
146{
147 wxHtmlParser::InitParser(source);
0e8c8233 148 wxASSERT_MSG(m_DC != NULL, _T("no DC assigned to wxHtmlWinParser!!"));
5526e819
VS
149
150 m_FontBold = m_FontItalic = m_FontUnderlined = m_FontFixed = FALSE;
f2c2fa4d 151 m_FontSize = 3; //default one
5526e819 152 CreateCurrentFont(); // we're selecting default font into
4f9297b0 153 m_DC->GetTextExtent("H", &m_CharWidth, &m_CharHeight);
5526e819 154 /* NOTE : we're not using GetCharWidth/Height() because
0e8c8233 155 of differences under X and win
5526e819
VS
156 */
157
f2c2fa4d
VS
158 m_UseLink = FALSE;
159 m_Link = wxHtmlLinkInfo("", "");
5526e819
VS
160 m_LinkColor.Set(0, 0, 0xFF);
161 m_ActualColor.Set(0, 0, 0);
efba2b89 162 m_Align = wxHTML_ALIGN_LEFT;
5526e819
VS
163 m_tmpLastWasSpace = FALSE;
164
165 OpenContainer();
166
167 OpenContainer();
4f9297b0
VS
168 m_Container->InsertCell(new wxHtmlColourCell(m_ActualColor));
169 m_Container->InsertCell(new wxHtmlFontCell(CreateCurrentFont()));
5526e819
VS
170}
171
172
173
174void wxHtmlWinParser::DoneParser()
175{
176 m_Container = NULL;
b250d384 177 SetInputEncoding(wxFONTENCODING_DEFAULT); // for next call
5526e819
VS
178 wxHtmlParser::DoneParser();
179}
180
181
182
183wxObject* wxHtmlWinParser::GetProduct()
184{
185 wxHtmlContainerCell *top;
186
187 CloseContainer();
188 OpenContainer();
67cfebc2 189
5526e819 190 top = m_Container;
4f9297b0 191 while (top->GetParent()) top = top->GetParent();
5526e819
VS
192 return top;
193}
194
195
211dfedd 196void wxHtmlWinParser::AddText(const wxChar* txt)
5526e819
VS
197{
198 wxHtmlCell *c;
e3c7fd79
VZ
199 size_t i = 0,
200 x,
201 lng = wxStrlen(txt);
211dfedd 202 register wxChar d;
5526e819 203 int templen = 0;
f23e92e7 204 wxChar nbsp = GetEntitiesParser()->GetCharForCode(160 /* nbsp */);
211dfedd
VS
205
206 if (lng+1 > m_tmpStrBufSize)
207 {
208 delete[] m_tmpStrBuf;
209 m_tmpStrBuf = new wxChar[lng+1];
210 m_tmpStrBufSize = lng+1;
211 }
212 wxChar *temp = m_tmpStrBuf;
3c8c8da2
VZ
213
214 if (m_tmpLastWasSpace)
4f9297b0 215 {
3c8c8da2
VZ
216 while ((i < lng) &&
217 ((txt[i] == wxT('\n')) || (txt[i] == wxT('\r')) || (txt[i] == wxT(' ')) ||
211dfedd 218 (txt[i] == wxT('\t')))) i++;
5526e819
VS
219 }
220
3c8c8da2 221 while (i < lng)
4f9297b0 222 {
5526e819
VS
223 x = 0;
224 d = temp[templen++] = txt[i];
3c8c8da2 225 if ((d == wxT('\n')) || (d == wxT('\r')) || (d == wxT(' ')) || (d == wxT('\t')))
e3c7fd79 226 {
5526e819 227 i++, x++;
3c8c8da2 228 while ((i < lng) && ((txt[i] == wxT('\n')) || (txt[i] == wxT('\r')) ||
211dfedd 229 (txt[i] == wxT(' ')) || (txt[i] == wxT('\t')))) i++, x++;
5526e819
VS
230 }
231 else i++;
232
3c8c8da2 233 if (x)
e3c7fd79 234 {
211dfedd 235 temp[templen-1] = wxT(' ');
5526e819 236 temp[templen] = 0;
af035b26 237 if (templen == 1) continue;
5526e819 238 templen = 0;
3c8c8da2 239 if (m_EncConv)
daa616fc 240 m_EncConv->Convert(temp);
f23e92e7
VS
241 wxString str = GetEntitiesParser()->Parse(temp);
242 size_t len = str.Len();
243 for (size_t j = 0; j < len; j++)
244 if (str.GetChar(j) == nbsp)
245 str[j] = wxT(' ');
246 c = new wxHtmlWordCell(str, *(GetDC()));
3c8c8da2 247 if (m_UseLink)
daa616fc 248 c->SetLink(m_Link);
4f9297b0 249 m_Container->InsertCell(c);
5526e819
VS
250 m_tmpLastWasSpace = TRUE;
251 }
252 }
af035b26
VS
253
254 if (templen && (templen > 1 || temp[0] != wxT(' ')))
4f9297b0 255 {
5526e819 256 temp[templen] = 0;
3c8c8da2 257 if (m_EncConv)
daa616fc 258 m_EncConv->Convert(temp);
f23e92e7
VS
259 wxString str = GetEntitiesParser()->Parse(temp);
260 size_t len = str.Len();
261 for (size_t j = 0; j < len; j++)
262 if (str.GetChar(j) == nbsp)
263 str[j] = wxT(' ');
264 c = new wxHtmlWordCell(str, *(GetDC()));
211dfedd 265 if (m_UseLink)
daa616fc 266 c->SetLink(m_Link);
4f9297b0 267 m_Container->InsertCell(c);
5526e819
VS
268 m_tmpLastWasSpace = FALSE;
269 }
270}
271
272
273
274wxHtmlContainerCell* wxHtmlWinParser::OpenContainer()
275{
276 m_Container = new wxHtmlContainerCell(m_Container);
4f9297b0 277 m_Container->SetAlignHor(m_Align);
5526e819
VS
278 m_tmpLastWasSpace = TRUE;
279 /* to avoid space being first character in paragraph */
280 return m_Container;
281}
282
283
284
285wxHtmlContainerCell* wxHtmlWinParser::SetContainer(wxHtmlContainerCell *c)
286{
287 m_tmpLastWasSpace = TRUE;
288 /* to avoid space being first character in paragraph */
289 return m_Container = c;
290}
291
292
293
294wxHtmlContainerCell* wxHtmlWinParser::CloseContainer()
295{
4f9297b0 296 m_Container = m_Container->GetParent();
5526e819
VS
297 return m_Container;
298}
299
300
f2c2fa4d
VS
301void wxHtmlWinParser::SetFontSize(int s)
302{
303 if (s < 1) s = 1;
304 else if (s > 7) s = 7;
305 m_FontSize = s;
306}
307
308
309
5526e819
VS
310wxFont* wxHtmlWinParser::CreateCurrentFont()
311{
312 int fb = GetFontBold(),
313 fi = GetFontItalic(),
314 fu = GetFontUnderlined(),
315 ff = GetFontFixed(),
f2c2fa4d 316 fs = GetFontSize() - 1 /*remap from <1;7> to <0;6>*/ ;
5526e819 317
f1ad10f3
VS
318 wxString face = ff ? m_FontFaceFixed : m_FontFaceNormal;
319 wxString *faceptr = &(m_FontsFacesTable[fb][fi][fu][ff][fs]);
320 wxFont **fontptr = &(m_FontsTable[fb][fi][fu][ff][fs]);
b250d384 321 wxFontEncoding *encptr = &(m_FontsEncTable[fb][fi][fu][ff][fs]);
f1ad10f3 322
3c8c8da2 323 if (*fontptr != NULL && (*faceptr != face || *encptr != m_OutputEnc))
4f9297b0 324 {
f1ad10f3
VS
325 delete *fontptr;
326 *fontptr = NULL;
327 }
328
3c8c8da2 329 if (*fontptr == NULL)
4f9297b0 330 {
f1ad10f3 331 *faceptr = face;
b250d384 332 *encptr = m_OutputEnc;
f1ad10f3 333 *fontptr = new wxFont(
7a5e6267 334 (int) (m_FontsSizes[fs] * m_PixelScale),
f1ad10f3
VS
335 ff ? wxMODERN : wxSWISS,
336 fi ? wxITALIC : wxNORMAL,
337 fb ? wxBOLD : wxNORMAL,
b250d384
VS
338 fu ? TRUE : FALSE, face,
339 m_OutputEnc);
5526e819 340 }
4f9297b0 341 m_DC->SetFont(**fontptr);
f1ad10f3 342 return (*fontptr);
5526e819
VS
343}
344
345
346
f2c2fa4d
VS
347void wxHtmlWinParser::SetLink(const wxHtmlLinkInfo& link)
348{
3c8c8da2 349 m_Link = link;
f2c2fa4d
VS
350 m_UseLink = (link.GetHref() != wxEmptyString);
351}
352
353
3c8c8da2 354void wxHtmlWinParser::SetFontFace(const wxString& face)
b250d384 355{
3c8c8da2 356 if (GetFontFixed()) m_FontFaceFixed = face;
b250d384
VS
357 else m_FontFaceNormal = face;
358
359 if (m_InputEnc != wxFONTENCODING_DEFAULT)
360 SetInputEncoding(m_InputEnc);
361}
362
363
364
365void wxHtmlWinParser::SetInputEncoding(wxFontEncoding enc)
366{
367 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
3c8c8da2 368 if (m_EncConv)
daa616fc 369 {
3c8c8da2 370 delete m_EncConv;
daa616fc
VS
371 m_EncConv = NULL;
372 }
b250d384
VS
373
374 if (enc == wxFONTENCODING_DEFAULT) return;
375
376 wxFontEncoding altfix, altnorm;
377 bool availfix, availnorm;
3c8c8da2
VZ
378
379 // exact match?
4f9297b0
VS
380 availnorm = wxTheFontMapper->IsEncodingAvailable(enc, m_FontFaceNormal);
381 availfix = wxTheFontMapper->IsEncodingAvailable(enc, m_FontFaceFixed);
3c8c8da2 382 if (availnorm && availfix)
b250d384 383 m_OutputEnc = enc;
3c8c8da2 384
b250d384 385 // alternatives?
4f9297b0
VS
386 else if (wxTheFontMapper->GetAltForEncoding(enc, &altnorm, m_FontFaceNormal, FALSE) &&
387 wxTheFontMapper->GetAltForEncoding(enc, &altfix, m_FontFaceFixed, FALSE) &&
b250d384
VS
388 altnorm == altfix)
389 m_OutputEnc = altnorm;
3c8c8da2 390
b250d384
VS
391 // at least normal face?
392 else if (availnorm)
393 m_OutputEnc = enc;
4f9297b0 394 else if (wxTheFontMapper->GetAltForEncoding(enc, &altnorm, m_FontFaceNormal, FALSE))
b250d384 395 m_OutputEnc = altnorm;
3c8c8da2 396
b250d384
VS
397 // okay, let convert to ISO_8859-1, available always
398 else
399 m_OutputEnc = wxFONTENCODING_DEFAULT;
3c8c8da2 400
b250d384 401 m_InputEnc = enc;
daa616fc
VS
402 if (m_OutputEnc == wxFONTENCODING_DEFAULT)
403 GetEntitiesParser()->SetEncoding(wxFONTENCODING_SYSTEM);
404 else
405 GetEntitiesParser()->SetEncoding(m_OutputEnc);
3c8c8da2 406
b250d384
VS
407 if (m_InputEnc == m_OutputEnc) return;
408
409 m_EncConv = new wxEncodingConverter();
3c8c8da2 410 if (!m_EncConv->Init(m_InputEnc,
b250d384
VS
411 (m_OutputEnc == wxFONTENCODING_DEFAULT) ?
412 wxFONTENCODING_ISO8859_1 : m_OutputEnc,
3c8c8da2 413 wxCONVERT_SUBSTITUTE))
b250d384 414 { // total failture :-(
3c8c8da2
VZ
415 wxLogError(_("Failed to display HTML document in %s encoding"),
416 wxFontMapper::GetEncodingName(enc).c_str());
b250d384
VS
417 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
418 delete m_EncConv;
419 m_EncConv = NULL;
420 }
421}
422
423
424
f2c2fa4d 425
5526e819
VS
426
427//-----------------------------------------------------------------------------
428// wxHtmlWinTagHandler
429//-----------------------------------------------------------------------------
430
431IMPLEMENT_ABSTRACT_CLASS(wxHtmlWinTagHandler, wxHtmlTagHandler)
432
433
434
435//-----------------------------------------------------------------------------
436// wxHtmlTagsModule
437//-----------------------------------------------------------------------------
438
439
440IMPLEMENT_DYNAMIC_CLASS(wxHtmlTagsModule, wxModule)
441
442
443bool wxHtmlTagsModule::OnInit()
444{
445 wxHtmlWinParser::AddModule(this);
446 return TRUE;
447}
448
449
450
451void wxHtmlTagsModule::OnExit()
452{
f6bcfd97 453 wxHtmlWinParser::RemoveModule(this);
5526e819 454}
223d09f6 455#endif
5526e819 456