]> git.saurik.com Git - wxWidgets.git/blame - src/html/winpars.cpp
Propagate wxEVT_COMMAND_TEXT_UPDATED renaming to the real stc.cpp.
[wxWidgets.git] / src / html / winpars.cpp
CommitLineData
5526e819 1/////////////////////////////////////////////////////////////////////////////
93763ad5 2// Name: src/html/winpars.cpp
5526e819
VS
3// Purpose: wxHtmlParser class (generic parser)
4// Author: Vaclav Slavik
69941f05 5// RCS-ID: $Id$
5526e819 6// Copyright: (c) 1999 Vaclav Slavik
65571936 7// Licence: wxWindows licence
5526e819
VS
8/////////////////////////////////////////////////////////////////////////////
9
3096bd2f 10#include "wx/wxprec.h"
5526e819 11
2b5f62a0 12#ifdef __BORLANDC__
93763ad5 13 #pragma hdrstop
5526e819
VS
14#endif
15
93763ad5
WS
16#if wxUSE_HTML && wxUSE_STREAMS
17
b4f4d3dd 18#ifndef WX_PRECOMP
04dbb646
VZ
19 #include "wx/intl.h"
20 #include "wx/dc.h"
e4db172a 21 #include "wx/log.h"
9eddec69 22 #include "wx/settings.h"
5526e819
VS
23#endif
24
69941f05
VS
25#include "wx/html/htmldefs.h"
26#include "wx/html/winpars.h"
27#include "wx/html/htmlwin.h"
0d7acfb9 28#include "wx/html/styleparams.h"
b250d384 29#include "wx/fontmap.h"
3ec372c8 30#include "wx/uri.h"
5526e819
VS
31
32
33//-----------------------------------------------------------------------------
34// wxHtmlWinParser
35//-----------------------------------------------------------------------------
36
4f44ea36 37IMPLEMENT_ABSTRACT_CLASS(wxHtmlWinParser, wxHtmlParser)
5526e819
VS
38
39wxList wxHtmlWinParser::m_Modules;
40
bc55e31b 41wxHtmlWinParser::wxHtmlWinParser(wxHtmlWindowInterface *wndIface)
5526e819 42{
211dfedd
VS
43 m_tmpStrBuf = NULL;
44 m_tmpStrBufSize = 0;
bc55e31b 45 m_windowInterface = wndIface;
5526e819
VS
46 m_Container = NULL;
47 m_DC = NULL;
48 m_CharHeight = m_CharWidth = 0;
d1da8872 49 m_UseLink = false;
2b5f62a0 50#if !wxUSE_UNICODE
c7820964 51 m_nbsp = 0;
b250d384 52 m_EncConv = NULL;
2b5f62a0
VZ
53 m_InputEnc = wxFONTENCODING_ISO8859_1;
54 m_OutputEnc = wxFONTENCODING_DEFAULT;
55#endif
6a603a10 56 m_whitespaceMode = Whitespace_Normal;
b6d93b26 57 m_lastWordCell = NULL;
6a603a10 58 m_posColumn = 0;
5526e819
VS
59
60 {
61 int i, j, k, l, m;
62 for (i = 0; i < 2; i++)
63 for (j = 0; j < 2; j++)
64 for (k = 0; k < 2; k++)
65 for (l = 0; l < 2; l++)
3c8c8da2 66 for (m = 0; m < 7; m++)
e3c7fd79 67 {
5526e819 68 m_FontsTable[i][j][k][l][m] = NULL;
f1ad10f3 69 m_FontsFacesTable[i][j][k][l][m] = wxEmptyString;
2b5f62a0 70#if !wxUSE_UNICODE
b250d384 71 m_FontsEncTable[i][j][k][l][m] = wxFONTENCODING_DEFAULT;
2b5f62a0 72#endif
f1ad10f3 73 }
4eecf115
VS
74
75 SetFonts(wxEmptyString, wxEmptyString, NULL);
5526e819
VS
76 }
77
78 // fill in wxHtmlParser's tables:
222ed1d6 79 wxList::compatibility_iterator node = m_Modules.GetFirst();
3c8c8da2 80 while (node)
4f9297b0
VS
81 {
82 wxHtmlTagsModule *mod = (wxHtmlTagsModule*) node->GetData();
83 mod->FillHandlersTable(this);
84 node = node->GetNext();
5526e819
VS
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 }
2b5f62a0 101#if !wxUSE_UNICODE
211dfedd 102 delete m_EncConv;
2b5f62a0 103#endif
211dfedd 104 delete[] m_tmpStrBuf;
b250d384
VS
105}
106
5526e819
VS
107void wxHtmlWinParser::AddModule(wxHtmlTagsModule *module)
108{
109 m_Modules.Append(module);
110}
111
f6bcfd97
BP
112void wxHtmlWinParser::RemoveModule(wxHtmlTagsModule *module)
113{
114 m_Modules.DeleteObject(module);
115}
116
ba804ab2
VZ
117// build all HTML font sizes (1..7) from the given base size
118static void wxBuildFontSizes(int *sizes, int size)
119{
120 // using a fixed factor (1.2, from CSS2) is a bad idea as explained at
121 // http://www.w3.org/TR/CSS21/fonts.html#font-size-props but this is by far
122 // simplest thing to do so still do it like this for now
1d203ed8 123 sizes[0] = int(size * 0.75); // exception to 1.2 rule, otherwise too small
ba804ab2
VZ
124 sizes[1] = int(size * 0.83);
125 sizes[2] = size;
126 sizes[3] = int(size * 1.2);
127 sizes[4] = int(size * 1.44);
128 sizes[5] = int(size * 1.73);
129 sizes[6] = int(size * 2);
130}
131
1d203ed8
VZ
132static int wxGetDefaultHTMLFontSize()
133{
134 // base the default font size on the size of the default system font but
135 // also ensure that we have a font of reasonable size, otherwise small HTML
136 // fonts are unreadable
137 int size = wxNORMAL_FONT->GetPointSize();
138 if ( size < 10 )
139 size = 10;
140 return size;
141}
142
ba804ab2
VZ
143void wxHtmlWinParser::SetFonts(const wxString& normal_face,
144 const wxString& fixed_face,
4eecf115 145 const int *sizes)
5526e819 146{
ba804ab2
VZ
147 static int default_sizes[7] = { 0 };
148 if ( !sizes )
149 {
150 if ( !default_sizes[0] )
1d203ed8 151 wxBuildFontSizes(default_sizes, wxGetDefaultHTMLFontSize());
ba804ab2
VZ
152
153 sizes = default_sizes;
154 }
4eecf115 155
c9f56e70
VS
156 int i, j, k, l, m;
157
ba804ab2
VZ
158 for (i = 0; i < 7; i++)
159 m_FontsSizes[i] = sizes[i];
160
5526e819
VS
161 m_FontFaceFixed = fixed_face;
162 m_FontFaceNormal = normal_face;
3c8c8da2 163
2b5f62a0 164#if !wxUSE_UNICODE
b250d384 165 SetInputEncoding(m_InputEnc);
2b5f62a0 166#endif
c9f56e70
VS
167
168 for (i = 0; i < 2; i++)
169 for (j = 0; j < 2; j++)
170 for (k = 0; k < 2; k++)
171 for (l = 0; l < 2; l++)
172 for (m = 0; m < 7; m++) {
3c8c8da2 173 if (m_FontsTable[i][j][k][l][m] != NULL)
e3c7fd79 174 {
c9f56e70
VS
175 delete m_FontsTable[i][j][k][l][m];
176 m_FontsTable[i][j][k][l][m] = NULL;
177 }
178 }
5526e819
VS
179}
180
10e5c7ea
VS
181void wxHtmlWinParser::SetStandardFonts(int size,
182 const wxString& normal_face,
183 const wxString& fixed_face)
7acd3625 184{
ba804ab2 185 if (size == -1)
1d203ed8 186 size = wxGetDefaultHTMLFontSize();
d1da8872 187
7acd3625 188 int f_sizes[7];
ba804ab2
VZ
189 wxBuildFontSizes(f_sizes, size);
190
191 wxString normal = normal_face;
192 if ( normal.empty() )
193 normal = wxNORMAL_FONT->GetFaceName();
d1da8872 194
10e5c7ea 195 SetFonts(normal, fixed_face, f_sizes);
7acd3625
RD
196}
197
5526e819
VS
198void wxHtmlWinParser::InitParser(const wxString& source)
199{
200 wxHtmlParser::InitParser(source);
2b5f62a0 201 wxASSERT_MSG(m_DC != NULL, wxT("no DC assigned to wxHtmlWinParser!!"));
5526e819
VS
202
203 m_FontBold = m_FontItalic = m_FontUnderlined = m_FontFixed = FALSE;
f2c2fa4d 204 m_FontSize = 3; //default one
5526e819 205 CreateCurrentFont(); // we're selecting default font into
03647350 206
5620726f
RR
207 // we're not using GetCharWidth/Height() because of
208 // differences under X and win
209 wxCoord w,h;
210 m_DC->GetTextExtent( wxT("H"), &w, &h);
211 m_CharWidth = w;
212 m_CharHeight = h;
5526e819 213
d1da8872 214 m_UseLink = false;
9548f380 215 m_Link = wxHtmlLinkInfo( wxEmptyString );
5526e819
VS
216 m_LinkColor.Set(0, 0, 0xFF);
217 m_ActualColor.Set(0, 0, 0);
f5413b87
VZ
218 const wxColour windowColour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW) ;
219 m_ActualBackgroundColor = m_windowInterface
220 ? m_windowInterface->GetHTMLBackgroundColour()
221 : windowColour;
3ee9771b 222 m_ActualBackgroundMode = wxTRANSPARENT;
efba2b89 223 m_Align = wxHTML_ALIGN_LEFT;
3c115835
VS
224 m_ScriptMode = wxHTML_SCRIPT_NORMAL;
225 m_ScriptBaseline = 0;
d1da8872 226 m_tmpLastWasSpace = false;
b6d93b26 227 m_lastWordCell = NULL;
5526e819 228
69328c1a
VS
229 // open the toplevel container that contains everything else and that
230 // is never closed (this makes parser's life easier):
5526e819 231 OpenContainer();
69328c1a
VS
232
233 // then open the first container into which page's content will go:
5526e819 234 OpenContainer();
2b5f62a0 235
fa2f5d3b 236#if !wxUSE_UNICODE
2b5f62a0
VZ
237 wxString charset = ExtractCharsetInformation(source);
238 if (!charset.empty())
239 {
240 wxFontEncoding enc = wxFontMapper::Get()->CharsetToEncoding(charset);
241 if (enc != wxFONTENCODING_SYSTEM)
242 SetInputEncoding(enc);
243 }
244#endif
245
4f9297b0 246 m_Container->InsertCell(new wxHtmlColourCell(m_ActualColor));
bc55e31b
VS
247
248 m_Container->InsertCell
249 (
250 new wxHtmlColourCell
251 (
f5413b87 252 m_ActualBackgroundColor,
3ee9771b 253 m_ActualBackgroundMode == wxTRANSPARENT ? wxHTML_CLR_TRANSPARENT_BACKGROUND : wxHTML_CLR_BACKGROUND
bc55e31b
VS
254 )
255 );
256
4f9297b0 257 m_Container->InsertCell(new wxHtmlFontCell(CreateCurrentFont()));
5526e819
VS
258}
259
5526e819
VS
260void wxHtmlWinParser::DoneParser()
261{
262 m_Container = NULL;
2b5f62a0
VZ
263#if !wxUSE_UNICODE
264 SetInputEncoding(wxFONTENCODING_ISO8859_1); // for next call
265#endif
5526e819
VS
266 wxHtmlParser::DoneParser();
267}
268
bc55e31b
VS
269#if WXWIN_COMPATIBILITY_2_6
270wxHtmlWindow *wxHtmlWinParser::GetWindow()
271{
272 if (!m_windowInterface)
273 return NULL;
274 return wxDynamicCast(m_windowInterface->GetHTMLWindow(), wxHtmlWindow);
275}
276#endif
277
5526e819
VS
278wxObject* wxHtmlWinParser::GetProduct()
279{
280 wxHtmlContainerCell *top;
281
282 CloseContainer();
283 OpenContainer();
67cfebc2 284
5526e819 285 top = m_Container;
4f9297b0 286 while (top->GetParent()) top = top->GetParent();
ace0fab4
VS
287 top->RemoveExtraSpacing(true, true);
288
5526e819
VS
289 return top;
290}
291
0423bdc7 292wxFSFile *wxHtmlWinParser::OpenURL(wxHtmlURLType type,
6cc4e6b8 293 const wxString& url) const
04db5c3f 294{
bc55e31b
VS
295 if ( !m_windowInterface )
296 return wxHtmlParser::OpenURL(type, url);
297
298 wxString myurl(url);
299 wxHtmlOpeningStatus status;
300 for (;;)
6cc4e6b8 301 {
bc55e31b 302 wxString myfullurl(myurl);
4bfa3189 303
bc55e31b
VS
304 // consider url as absolute path first
305 wxURI current(myurl);
306 myfullurl = current.BuildUnescapedURI();
4bfa3189 307
bc55e31b
VS
308 // if not absolute then ...
309 if( current.IsReference() )
310 {
311 wxString basepath = GetFS()->GetPath();
312 wxURI base(basepath);
4bfa3189 313
bc55e31b
VS
314 // ... try to apply base path if valid ...
315 if( !base.IsReference() )
316 {
317 wxURI path(myfullurl);
318 path.Resolve( base );
319 myfullurl = path.BuildUnescapedURI();
320 }
321 else
322 {
323 // ... or force such addition if not included already
324 if( !current.GetPath().Contains(base.GetPath()) )
4bfa3189 325 {
bc55e31b
VS
326 basepath += myurl;
327 wxURI connected( basepath );
328 myfullurl = connected.BuildUnescapedURI();
4bfa3189
WS
329 }
330 }
6cc4e6b8 331 }
0423bdc7 332
bc55e31b
VS
333 wxString redirect;
334 status = m_windowInterface->OnHTMLOpeningURL(type, myfullurl, &redirect);
335 if ( status != wxHTML_REDIRECT )
336 break;
2c892c0b 337
bc55e31b 338 myurl = redirect;
6cc4e6b8 339 }
2c892c0b 340
bc55e31b
VS
341 if ( status == wxHTML_BLOCK )
342 return NULL;
343
5c4035d6
MW
344 int flags = wxFS_READ;
345 if (type == wxHTML_URL_IMAGE)
346 flags |= wxFS_SEEKABLE;
347
348 return GetFS()->OpenFile(myurl, flags);
04db5c3f 349}
5526e819 350
50967574
VS
351#define NBSP_UNICODE_VALUE (wxChar(160))
352#if !wxUSE_UNICODE
353 #define CUR_NBSP_VALUE m_nbsp
354#else
355 #define CUR_NBSP_VALUE NBSP_UNICODE_VALUE
356#endif
357
5bce3e6f 358void wxHtmlWinParser::AddText(const wxString& txt)
5526e819 359{
6a603a10
VS
360#if !wxUSE_UNICODE
361 if ( m_nbsp == 0 )
362 m_nbsp = GetEntitiesParser()->GetCharForCode(NBSP_UNICODE_VALUE);
6a603a10 363#endif
211dfedd 364
6a603a10 365 if ( m_whitespaceMode == Whitespace_Normal )
211dfedd 366 {
6a603a10 367 int templen = 0;
5bce3e6f 368
6a603a10
VS
369 size_t lng = txt.length();
370 if (lng+1 > m_tmpStrBufSize)
5bce3e6f 371 {
6a603a10
VS
372 delete[] m_tmpStrBuf;
373 m_tmpStrBuf = new wxChar[lng+1];
374 m_tmpStrBufSize = lng+1;
5bce3e6f 375 }
6a603a10 376 wxChar *temp = m_tmpStrBuf;
5526e819 377
6a603a10
VS
378 wxString::const_iterator i = txt.begin();
379 const wxString::const_iterator end = txt.end();
380
381 if (m_tmpLastWasSpace)
e3c7fd79 382 {
5bce3e6f 383 while ( (i < end) &&
6a603a10
VS
384 (*i == wxT('\n') || *i == wxT('\r') || *i == wxT(' ') ||
385 *i == wxT('\t')) )
5bce3e6f
VS
386 {
387 ++i;
5bce3e6f 388 }
5526e819 389 }
5526e819 390
6a603a10 391 while (i < end)
e3c7fd79 392 {
6a603a10 393 size_t x = 0;
50967574 394 const wxChar d = temp[templen++] = *i;
6a603a10
VS
395 if ((d == wxT('\n')) || (d == wxT('\r')) || (d == wxT(' ')) || (d == wxT('\t')))
396 {
397 ++i, ++x;
398 while ( (i < end) &&
399 (*i == wxT('\n') || *i == wxT('\r') ||
400 *i == wxT(' ') || *i == wxT('\t')) )
401 {
402 ++i;
403 ++x;
404 }
405 }
406 else
407 {
408 ++i;
409 }
410
6a603a10
VS
411 if (x)
412 {
413 temp[templen-1] = wxT(' ');
414 FlushWordBuf(temp, templen);
415 m_tmpLastWasSpace = true;
416 }
5526e819 417 }
af035b26 418
6a603a10
VS
419 if (templen && (templen > 1 || temp[0] != wxT(' ')))
420 {
421 FlushWordBuf(temp, templen);
422 m_tmpLastWasSpace = false;
423 }
424 }
425 else // m_whitespaceMode == Whitespace_Pre
4f9297b0 426 {
6a603a10
VS
427 if ( txt.find(CUR_NBSP_VALUE) != wxString::npos )
428 {
429 // we need to substitute spaces for &nbsp; here just like we
430 // did in the Whitespace_Normal branch above
431 wxString txt2(txt);
432 txt2.Replace(CUR_NBSP_VALUE, ' ');
433 AddPreBlock(txt2);
434 }
435 else
436 {
437 AddPreBlock(txt);
438 }
439
440 // don't eat any whitespace in <pre> block
97eac136
VS
441 m_tmpLastWasSpace = false;
442 }
443}
444
6a603a10 445void wxHtmlWinParser::FlushWordBuf(wxChar *buf, int& len)
97eac136 446{
6a603a10 447 buf[len] = 0;
c7820964 448
50967574
VS
449 for ( int i = 0; i < len; i++ )
450 {
451 if ( buf[i] == CUR_NBSP_VALUE )
452 buf[i] = ' ';
453 }
454
2b5f62a0 455#if !wxUSE_UNICODE
97eac136 456 if (m_EncConv)
6a603a10 457 m_EncConv->Convert(buf);
2b5f62a0 458#endif
97eac136 459
6a603a10 460 AddWord(wxString(buf, len));
97eac136 461
6a603a10
VS
462 len = 0;
463}
464
465void wxHtmlWinParser::AddWord(wxHtmlWordCell *word)
466{
467 ApplyStateToCell(word);
3c115835 468
6a603a10
VS
469 m_Container->InsertCell(word);
470 word->SetPreviousWord(m_lastWordCell);
471 m_lastWordCell = word;
5526e819
VS
472}
473
6a603a10
VS
474void wxHtmlWinParser::AddPreBlock(const wxString& text)
475{
476 if ( text.find('\t') != wxString::npos )
477 {
478 wxString text2;
479 text2.reserve(text.length());
480
481 const wxString::const_iterator end = text.end();
482 wxString::const_iterator copyFrom = text.begin();
6a603a10
VS
483 size_t pos = 0;
484 int posColumn = m_posColumn;
485 for ( wxString::const_iterator i = copyFrom; i != end; ++i, ++pos )
486 {
487 if ( *i == '\t' )
488 {
489 if ( copyFrom != i )
490 text2.append(copyFrom, i);
491
492 const unsigned SPACES_PER_TAB = 8;
493 const size_t expandTo = SPACES_PER_TAB - posColumn % SPACES_PER_TAB;
494 text2.append(expandTo, ' ');
495
496 posColumn += expandTo;
497 copyFrom = i + 1;
6a603a10
VS
498 }
499 else
500 {
501 ++posColumn;
502 }
503 }
504 if ( copyFrom != text.end() )
505 text2.append(copyFrom, text.end());
506
507 AddWord(new wxHtmlWordWithTabsCell(text2, text, m_posColumn, *(GetDC())));
508
509 m_posColumn = posColumn;
510 }
511 else
512 {
513 // no special formatting needed
514 AddWord(text);
515 m_posColumn += text.length();
516 }
517}
5526e819
VS
518
519
520wxHtmlContainerCell* wxHtmlWinParser::OpenContainer()
521{
522 m_Container = new wxHtmlContainerCell(m_Container);
4f9297b0 523 m_Container->SetAlignHor(m_Align);
6a603a10 524 m_posColumn = 0;
d1da8872 525 m_tmpLastWasSpace = true;
5526e819
VS
526 /* to avoid space being first character in paragraph */
527 return m_Container;
528}
529
530
531
532wxHtmlContainerCell* wxHtmlWinParser::SetContainer(wxHtmlContainerCell *c)
533{
d1da8872 534 m_tmpLastWasSpace = true;
5526e819
VS
535 /* to avoid space being first character in paragraph */
536 return m_Container = c;
537}
538
539
540
541wxHtmlContainerCell* wxHtmlWinParser::CloseContainer()
542{
4f9297b0 543 m_Container = m_Container->GetParent();
5526e819
VS
544 return m_Container;
545}
546
547
f2c2fa4d
VS
548void wxHtmlWinParser::SetFontSize(int s)
549{
8aef90e8
VS
550 if (s < 1)
551 s = 1;
552 else if (s > 7)
553 s = 7;
f2c2fa4d
VS
554 m_FontSize = s;
555}
556
557
c44a49b8
VS
558void wxHtmlWinParser::SetDC(wxDC *dc, double pixel_scale, double font_scale)
559{
560 m_DC = dc;
561 m_PixelScale = pixel_scale;
562 m_FontScale = font_scale;
563}
564
f68e16c5
VZ
565void wxHtmlWinParser::SetFontPointSize(int pt)
566{
567 if (pt <= m_FontsSizes[0])
568 m_FontSize = 1;
569 else if (pt >= m_FontsSizes[6])
570 m_FontSize = 7;
571 else
572 {
573 // Find the font closest to the given value with a simple linear search
574 // (binary search is not worth it here for so small number of elements)
575 for ( int n = 0; n < 6; n++ )
576 {
577 if ( (pt > m_FontsSizes[n]) && (pt <= m_FontsSizes[n + 1]) )
578 {
0199dae3
VZ
579 if ( (pt - m_FontsSizes[n]) >= (m_FontsSizes[n + 1] - pt) )
580 {
581 // The actual size is closer to the next entry than to this
582 // one, so use it.
583 n++;
584 }
585
586 // Notice that m_FontSize starts from 1, hence +1 here.
587 m_FontSize = n + 1;
f68e16c5
VZ
588
589 break;
590 }
591 }
592 }
593}
f2c2fa4d 594
5526e819
VS
595wxFont* wxHtmlWinParser::CreateCurrentFont()
596{
597 int fb = GetFontBold(),
598 fi = GetFontItalic(),
599 fu = GetFontUnderlined(),
600 ff = GetFontFixed(),
f2c2fa4d 601 fs = GetFontSize() - 1 /*remap from <1;7> to <0;6>*/ ;
5526e819 602
f1ad10f3
VS
603 wxString face = ff ? m_FontFaceFixed : m_FontFaceNormal;
604 wxString *faceptr = &(m_FontsFacesTable[fb][fi][fu][ff][fs]);
605 wxFont **fontptr = &(m_FontsTable[fb][fi][fu][ff][fs]);
2b5f62a0 606#if !wxUSE_UNICODE
b250d384 607 wxFontEncoding *encptr = &(m_FontsEncTable[fb][fi][fu][ff][fs]);
2b5f62a0 608#endif
f1ad10f3 609
2b5f62a0
VZ
610 if (*fontptr != NULL && (*faceptr != face
611#if !wxUSE_UNICODE
612 || *encptr != m_OutputEnc
613#endif
614 ))
4f9297b0 615 {
5276b0a5 616 wxDELETE(*fontptr);
f1ad10f3
VS
617 }
618
3c8c8da2 619 if (*fontptr == NULL)
4f9297b0 620 {
f1ad10f3
VS
621 *faceptr = face;
622 *fontptr = new wxFont(
c44a49b8 623 (int) (m_FontsSizes[fs] * m_FontScale),
f1ad10f3
VS
624 ff ? wxMODERN : wxSWISS,
625 fi ? wxITALIC : wxNORMAL,
626 fb ? wxBOLD : wxNORMAL,
d1da8872 627 fu ? true : false, face
2b5f62a0
VZ
628#if wxUSE_UNICODE
629 );
630#else
631 , m_OutputEnc);
632 *encptr = m_OutputEnc;
633#endif
5526e819 634 }
4f9297b0 635 m_DC->SetFont(**fontptr);
f1ad10f3 636 return (*fontptr);
5526e819
VS
637}
638
639
640
f2c2fa4d
VS
641void wxHtmlWinParser::SetLink(const wxHtmlLinkInfo& link)
642{
3c8c8da2 643 m_Link = link;
f2c2fa4d
VS
644 m_UseLink = (link.GetHref() != wxEmptyString);
645}
646
3c8c8da2 647void wxHtmlWinParser::SetFontFace(const wxString& face)
b250d384 648{
8aef90e8
VS
649 if (GetFontFixed())
650 m_FontFaceFixed = face;
651 else
652 m_FontFaceNormal = face;
b250d384 653
2b5f62a0 654#if !wxUSE_UNICODE
b250d384
VS
655 if (m_InputEnc != wxFONTENCODING_DEFAULT)
656 SetInputEncoding(m_InputEnc);
2b5f62a0 657#endif
b250d384
VS
658}
659
3c115835
VS
660void wxHtmlWinParser::ApplyStateToCell(wxHtmlCell *cell)
661{
662 // set the link:
663 if (m_UseLink)
664 cell->SetLink(GetLink());
665
666 // apply current script mode settings:
667 cell->SetScriptMode(GetScriptMode(), GetScriptBaseline());
668}
b250d384
VS
669
670
2b5f62a0 671#if !wxUSE_UNICODE
b250d384
VS
672void wxHtmlWinParser::SetInputEncoding(wxFontEncoding enc)
673{
c7820964
VS
674 // the character used for non-breakable space may change:
675 m_nbsp = 0;
676
b250d384 677 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
5276b0a5 678 wxDELETE(m_EncConv);
b250d384 679
8aef90e8
VS
680 if (enc == wxFONTENCODING_DEFAULT)
681 return;
b250d384
VS
682
683 wxFontEncoding altfix, altnorm;
684 bool availfix, availnorm;
3c8c8da2 685
142b3bc2
VS
686 availnorm = wxFontMapper::Get()->IsEncodingAvailable(enc, m_FontFaceNormal);
687 availfix = wxFontMapper::Get()->IsEncodingAvailable(enc, m_FontFaceFixed);
8aef90e8 688
3c8c8da2 689 if (availnorm && availfix)
8aef90e8
VS
690 {
691 // exact match?
b250d384 692 m_OutputEnc = enc;
8aef90e8 693 }
3c8c8da2 694
d1da8872
WS
695 else if (wxFontMapper::Get()->GetAltForEncoding(enc, &altnorm, m_FontFaceNormal, false) &&
696 wxFontMapper::Get()->GetAltForEncoding(enc, &altfix, m_FontFaceFixed, false) &&
b250d384 697 altnorm == altfix)
8aef90e8
VS
698 {
699 // alternatives?
b250d384 700 m_OutputEnc = altnorm;
8aef90e8 701 }
b250d384 702 else if (availnorm)
8aef90e8
VS
703 {
704 // at least normal face?
b250d384 705 m_OutputEnc = enc;
8aef90e8 706 }
d1da8872 707 else if (wxFontMapper::Get()->GetAltForEncoding(enc, &altnorm, m_FontFaceNormal, false))
8aef90e8 708 {
b250d384 709 m_OutputEnc = altnorm;
8aef90e8 710 }
b250d384 711 else
c83e1237
SC
712 {
713#ifndef __WXMAC__
6a17b868 714 // okay, let's convert to ISO_8859-1, available always
b250d384 715 m_OutputEnc = wxFONTENCODING_DEFAULT;
90548138 716#else
c83e1237 717 m_OutputEnc = wxLocale::GetSystemEncoding() ;
90548138 718#endif
c83e1237 719 }
3c8c8da2 720
b250d384 721 m_InputEnc = enc;
daa616fc 722 if (m_OutputEnc == wxFONTENCODING_DEFAULT)
8aef90e8 723 {
daa616fc 724 GetEntitiesParser()->SetEncoding(wxFONTENCODING_SYSTEM);
8aef90e8 725 }
daa616fc 726 else
8aef90e8 727 {
daa616fc 728 GetEntitiesParser()->SetEncoding(m_OutputEnc);
8aef90e8 729 }
3c8c8da2 730
8aef90e8
VS
731 if (m_InputEnc == m_OutputEnc)
732 return;
b250d384
VS
733
734 m_EncConv = new wxEncodingConverter();
3c8c8da2 735 if (!m_EncConv->Init(m_InputEnc,
b250d384
VS
736 (m_OutputEnc == wxFONTENCODING_DEFAULT) ?
737 wxFONTENCODING_ISO8859_1 : m_OutputEnc,
3c8c8da2 738 wxCONVERT_SUBSTITUTE))
6a17b868 739 { // total failure :-(
3c8c8da2
VZ
740 wxLogError(_("Failed to display HTML document in %s encoding"),
741 wxFontMapper::GetEncodingName(enc).c_str());
b250d384 742 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
5276b0a5 743 wxDELETE(m_EncConv);
b250d384
VS
744 }
745}
2b5f62a0 746#endif
b250d384
VS
747
748
f2c2fa4d 749
5526e819
VS
750
751//-----------------------------------------------------------------------------
752// wxHtmlWinTagHandler
753//-----------------------------------------------------------------------------
754
755IMPLEMENT_ABSTRACT_CLASS(wxHtmlWinTagHandler, wxHtmlTagHandler)
756
0d7acfb9
VZ
757void wxHtmlWinTagHandler::ApplyStyle(const wxHtmlStyleParams &styleParams)
758{
759 wxString str;
760
761 str = styleParams.GetParam(wxS("color"));
762 if ( !str.empty() )
763 {
764 wxColour clr;
765 if ( wxHtmlTag::ParseAsColour(str, &clr) )
766 {
767 m_WParser->SetActualColor(clr);
768 m_WParser->GetContainer()->InsertCell(new wxHtmlColourCell(clr));
769 }
770 }
771
772 str = styleParams.GetParam(wxS("background-color"));
773 if ( !str.empty() )
774 {
775 wxColour clr;
776 if ( wxHtmlTag::ParseAsColour(str, &clr) )
777 {
778 m_WParser->SetActualBackgroundColor(clr);
779 m_WParser->SetActualBackgroundMode(wxSOLID);
780 m_WParser->GetContainer()->InsertCell(new wxHtmlColourCell(clr, wxHTML_CLR_BACKGROUND));
781 }
782 }
783
784 str = styleParams.GetParam(wxS("font-size"));
785 if ( !str.empty() )
786 {
787 // Point size
788 int foundIndex = str.Find(wxS("pt"));
789 if (foundIndex != wxNOT_FOUND)
790 {
791 str.Truncate(foundIndex);
792
793 long sizeValue;
794 if (str.ToLong(&sizeValue) == true)
795 {
796 // Set point size
797 m_WParser->SetFontPointSize(sizeValue);
798 m_WParser->GetContainer()->InsertCell(
799 new wxHtmlFontCell(m_WParser->CreateCurrentFont()));
800 }
801 }
802 // else: check for other ways of specifying size (TODO)
803 }
804
805 str = styleParams.GetParam(wxS("font-weight"));
806 if ( !str.empty() )
807 {
808 // Only bold and normal supported just now
809 if ( str == wxS("bold") )
810 {
811 m_WParser->SetFontBold(true);
812 m_WParser->GetContainer()->InsertCell(
813 new wxHtmlFontCell(m_WParser->CreateCurrentFont()));
814 }
815 else if ( str == wxS("normal") )
816 {
817 m_WParser->SetFontBold(false);
818 m_WParser->GetContainer()->InsertCell(
819 new wxHtmlFontCell(m_WParser->CreateCurrentFont()));
820 }
821 }
822
823 str = styleParams.GetParam(wxS("font-style"));
824 if ( !str.empty() )
825 {
826 // "oblique" and "italic" are more or less the same.
827 // "inherit" (using the parent font) is not supported.
828 if ( str == wxS("oblique") || str == wxS("italic") )
829 {
830 m_WParser->SetFontItalic(true);
831 m_WParser->GetContainer()->InsertCell(
832 new wxHtmlFontCell(m_WParser->CreateCurrentFont()));
833 }
834 else if ( str == wxS("normal") )
835 {
836 m_WParser->SetFontItalic(false);
837 m_WParser->GetContainer()->InsertCell(
838 new wxHtmlFontCell(m_WParser->CreateCurrentFont()));
839 }
840 }
841
842 str = styleParams.GetParam(wxS("text-decoration"));
843 if ( !str.empty() )
844 {
845 // Only underline is supported.
846 if ( str == wxS("underline") )
847 {
848 m_WParser->SetFontUnderlined(true);
849 m_WParser->GetContainer()->InsertCell(
850 new wxHtmlFontCell(m_WParser->CreateCurrentFont()));
851 }
852 }
853
854 str = styleParams.GetParam(wxS("font-family"));
855 if ( !str.empty() )
856 {
857 m_WParser->SetFontFace(str);
858 m_WParser->GetContainer()->InsertCell(
859 new wxHtmlFontCell(m_WParser->CreateCurrentFont()));
860 }
861}
862
5526e819
VS
863//-----------------------------------------------------------------------------
864// wxHtmlTagsModule
865//-----------------------------------------------------------------------------
866
d6a6d666
VS
867// NB: This is *NOT* winpars.cpp's initialization and shutdown code!!
868// This module is an ancestor for tag handlers modules defined
869// in m_*.cpp files with TAGS_MODULE_BEGIN...TAGS_MODULE_END construct.
870//
871// Do not add any winpars.cpp shutdown or initialization code to it,
872// create a new module instead!
5526e819
VS
873
874IMPLEMENT_DYNAMIC_CLASS(wxHtmlTagsModule, wxModule)
875
5526e819
VS
876bool wxHtmlTagsModule::OnInit()
877{
878 wxHtmlWinParser::AddModule(this);
d1da8872 879 return true;
5526e819
VS
880}
881
5526e819
VS
882void wxHtmlTagsModule::OnExit()
883{
f6bcfd97 884 wxHtmlWinParser::RemoveModule(this);
5526e819 885}
d6a6d666 886
223d09f6 887#endif