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