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