]> git.saurik.com Git - wxWidgets.git/blob - src/html/winpars.cpp
Support using GetTextExtent() with empty string to get descent in wxOSX.
[wxWidgets.git] / src / html / winpars.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/html/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 #include "wx/wxprec.h"
11
12 #ifdef __BORLANDC__
13 #pragma hdrstop
14 #endif
15
16 #if wxUSE_HTML && wxUSE_STREAMS
17
18 #ifndef WX_PRECOMP
19 #include "wx/intl.h"
20 #include "wx/dc.h"
21 #include "wx/log.h"
22 #include "wx/settings.h"
23 #endif
24
25 #include "wx/html/htmldefs.h"
26 #include "wx/html/winpars.h"
27 #include "wx/html/htmlwin.h"
28 #include "wx/html/styleparams.h"
29 #include "wx/fontmap.h"
30 #include "wx/uri.h"
31
32
33 //-----------------------------------------------------------------------------
34 // wxHtmlWinParser
35 //-----------------------------------------------------------------------------
36
37 IMPLEMENT_ABSTRACT_CLASS(wxHtmlWinParser, wxHtmlParser)
38
39 wxList wxHtmlWinParser::m_Modules;
40
41 wxHtmlWinParser::wxHtmlWinParser(wxHtmlWindowInterface *wndIface)
42 {
43 m_tmpStrBuf = NULL;
44 m_tmpStrBufSize = 0;
45 m_windowInterface = wndIface;
46 m_Container = NULL;
47 m_DC = NULL;
48 m_CharHeight = m_CharWidth = 0;
49 m_UseLink = false;
50 #if !wxUSE_UNICODE
51 m_nbsp = 0;
52 m_EncConv = NULL;
53 m_InputEnc = wxFONTENCODING_ISO8859_1;
54 m_OutputEnc = wxFONTENCODING_DEFAULT;
55 #endif
56 m_whitespaceMode = Whitespace_Normal;
57 m_lastWordCell = NULL;
58 m_posColumn = 0;
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++)
66 for (m = 0; m < 7; m++)
67 {
68 m_FontsTable[i][j][k][l][m] = NULL;
69 m_FontsFacesTable[i][j][k][l][m] = wxEmptyString;
70 #if !wxUSE_UNICODE
71 m_FontsEncTable[i][j][k][l][m] = wxFONTENCODING_DEFAULT;
72 #endif
73 }
74
75 SetFonts(wxEmptyString, wxEmptyString, NULL);
76 }
77
78 // fill in wxHtmlParser's tables:
79 wxList::compatibility_iterator node = m_Modules.GetFirst();
80 while (node)
81 {
82 wxHtmlTagsModule *mod = (wxHtmlTagsModule*) node->GetData();
83 mod->FillHandlersTable(this);
84 node = node->GetNext();
85 }
86 }
87
88 wxHtmlWinParser::~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++)
96 for (m = 0; m < 7; m++)
97 {
98 if (m_FontsTable[i][j][k][l][m] != NULL)
99 delete m_FontsTable[i][j][k][l][m];
100 }
101 #if !wxUSE_UNICODE
102 delete m_EncConv;
103 #endif
104 delete[] m_tmpStrBuf;
105 }
106
107 void wxHtmlWinParser::AddModule(wxHtmlTagsModule *module)
108 {
109 m_Modules.Append(module);
110 }
111
112 void wxHtmlWinParser::RemoveModule(wxHtmlTagsModule *module)
113 {
114 m_Modules.DeleteObject(module);
115 }
116
117 // build all HTML font sizes (1..7) from the given base size
118 static 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
123 sizes[0] = int(size * 0.75); // exception to 1.2 rule, otherwise too small
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
132 static 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
143 void wxHtmlWinParser::SetFonts(const wxString& normal_face,
144 const wxString& fixed_face,
145 const int *sizes)
146 {
147 static int default_sizes[7] = { 0 };
148 if ( !sizes )
149 {
150 if ( !default_sizes[0] )
151 wxBuildFontSizes(default_sizes, wxGetDefaultHTMLFontSize());
152
153 sizes = default_sizes;
154 }
155
156 int i, j, k, l, m;
157
158 for (i = 0; i < 7; i++)
159 m_FontsSizes[i] = sizes[i];
160
161 m_FontFaceFixed = fixed_face;
162 m_FontFaceNormal = normal_face;
163
164 #if !wxUSE_UNICODE
165 SetInputEncoding(m_InputEnc);
166 #endif
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++) {
173 if (m_FontsTable[i][j][k][l][m] != NULL)
174 {
175 delete m_FontsTable[i][j][k][l][m];
176 m_FontsTable[i][j][k][l][m] = NULL;
177 }
178 }
179 }
180
181 void wxHtmlWinParser::SetStandardFonts(int size,
182 const wxString& normal_face,
183 const wxString& fixed_face)
184 {
185 if (size == -1)
186 size = wxGetDefaultHTMLFontSize();
187
188 int f_sizes[7];
189 wxBuildFontSizes(f_sizes, size);
190
191 wxString normal = normal_face;
192 if ( normal.empty() )
193 normal = wxNORMAL_FONT->GetFaceName();
194
195 SetFonts(normal, fixed_face, f_sizes);
196 }
197
198 void wxHtmlWinParser::InitParser(const wxString& source)
199 {
200 wxHtmlParser::InitParser(source);
201 wxASSERT_MSG(m_DC != NULL, wxT("no DC assigned to wxHtmlWinParser!!"));
202
203 m_FontBold = m_FontItalic = m_FontUnderlined = m_FontFixed = FALSE;
204 m_FontSize = 3; //default one
205 CreateCurrentFont(); // we're selecting default font into
206
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;
213
214 m_UseLink = false;
215 m_Link = wxHtmlLinkInfo( wxEmptyString );
216 m_LinkColor.Set(0, 0, 0xFF);
217 m_ActualColor.Set(0, 0, 0);
218 const wxColour windowColour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW) ;
219 m_ActualBackgroundColor = m_windowInterface
220 ? m_windowInterface->GetHTMLBackgroundColour()
221 : windowColour;
222 m_ActualBackgroundMode = wxTRANSPARENT;
223 m_Align = wxHTML_ALIGN_LEFT;
224 m_ScriptMode = wxHTML_SCRIPT_NORMAL;
225 m_ScriptBaseline = 0;
226 m_tmpLastWasSpace = false;
227 m_lastWordCell = NULL;
228
229 // open the toplevel container that contains everything else and that
230 // is never closed (this makes parser's life easier):
231 OpenContainer();
232
233 // then open the first container into which page's content will go:
234 OpenContainer();
235
236 #if !wxUSE_UNICODE
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
246 m_Container->InsertCell(new wxHtmlColourCell(m_ActualColor));
247
248 m_Container->InsertCell
249 (
250 new wxHtmlColourCell
251 (
252 m_ActualBackgroundColor,
253 m_ActualBackgroundMode == wxTRANSPARENT ? wxHTML_CLR_TRANSPARENT_BACKGROUND : wxHTML_CLR_BACKGROUND
254 )
255 );
256
257 m_Container->InsertCell(new wxHtmlFontCell(CreateCurrentFont()));
258 }
259
260 void wxHtmlWinParser::DoneParser()
261 {
262 m_Container = NULL;
263 #if !wxUSE_UNICODE
264 SetInputEncoding(wxFONTENCODING_ISO8859_1); // for next call
265 #endif
266 wxHtmlParser::DoneParser();
267 }
268
269 #if WXWIN_COMPATIBILITY_2_6
270 wxHtmlWindow *wxHtmlWinParser::GetWindow()
271 {
272 if (!m_windowInterface)
273 return NULL;
274 return wxDynamicCast(m_windowInterface->GetHTMLWindow(), wxHtmlWindow);
275 }
276 #endif
277
278 wxObject* wxHtmlWinParser::GetProduct()
279 {
280 wxHtmlContainerCell *top;
281
282 CloseContainer();
283 OpenContainer();
284
285 top = m_Container;
286 while (top->GetParent()) top = top->GetParent();
287 top->RemoveExtraSpacing(true, true);
288
289 return top;
290 }
291
292 wxFSFile *wxHtmlWinParser::OpenURL(wxHtmlURLType type,
293 const wxString& url) const
294 {
295 if ( !m_windowInterface )
296 return wxHtmlParser::OpenURL(type, url);
297
298 wxString myurl(url);
299 wxHtmlOpeningStatus status;
300 for (;;)
301 {
302 wxString myfullurl(myurl);
303
304 // consider url as absolute path first
305 wxURI current(myurl);
306 myfullurl = current.BuildUnescapedURI();
307
308 // if not absolute then ...
309 if( current.IsReference() )
310 {
311 wxString basepath = GetFS()->GetPath();
312 wxURI base(basepath);
313
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()) )
325 {
326 basepath += myurl;
327 wxURI connected( basepath );
328 myfullurl = connected.BuildUnescapedURI();
329 }
330 }
331 }
332
333 wxString redirect;
334 status = m_windowInterface->OnHTMLOpeningURL(type, myfullurl, &redirect);
335 if ( status != wxHTML_REDIRECT )
336 break;
337
338 myurl = redirect;
339 }
340
341 if ( status == wxHTML_BLOCK )
342 return NULL;
343
344 int flags = wxFS_READ;
345 if (type == wxHTML_URL_IMAGE)
346 flags |= wxFS_SEEKABLE;
347
348 return GetFS()->OpenFile(myurl, flags);
349 }
350
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
358 void wxHtmlWinParser::AddText(const wxString& txt)
359 {
360 #if !wxUSE_UNICODE
361 if ( m_nbsp == 0 )
362 m_nbsp = GetEntitiesParser()->GetCharForCode(NBSP_UNICODE_VALUE);
363 #endif
364
365 if ( m_whitespaceMode == Whitespace_Normal )
366 {
367 int templen = 0;
368
369 size_t lng = txt.length();
370 if (lng+1 > m_tmpStrBufSize)
371 {
372 delete[] m_tmpStrBuf;
373 m_tmpStrBuf = new wxChar[lng+1];
374 m_tmpStrBufSize = lng+1;
375 }
376 wxChar *temp = m_tmpStrBuf;
377
378 wxString::const_iterator i = txt.begin();
379 const wxString::const_iterator end = txt.end();
380
381 if (m_tmpLastWasSpace)
382 {
383 while ( (i < end) &&
384 (*i == wxT('\n') || *i == wxT('\r') || *i == wxT(' ') ||
385 *i == wxT('\t')) )
386 {
387 ++i;
388 }
389 }
390
391 while (i < end)
392 {
393 size_t x = 0;
394 const wxChar d = temp[templen++] = *i;
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
411 if (x)
412 {
413 temp[templen-1] = wxT(' ');
414 FlushWordBuf(temp, templen);
415 m_tmpLastWasSpace = true;
416 }
417 }
418
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
426 {
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
441 m_tmpLastWasSpace = false;
442 }
443 }
444
445 void wxHtmlWinParser::FlushWordBuf(wxChar *buf, int& len)
446 {
447 buf[len] = 0;
448
449 for ( int i = 0; i < len; i++ )
450 {
451 if ( buf[i] == CUR_NBSP_VALUE )
452 buf[i] = ' ';
453 }
454
455 #if !wxUSE_UNICODE
456 if (m_EncConv)
457 m_EncConv->Convert(buf);
458 #endif
459
460 AddWord(wxString(buf, len));
461
462 len = 0;
463 }
464
465 void wxHtmlWinParser::AddWord(wxHtmlWordCell *word)
466 {
467 ApplyStateToCell(word);
468
469 m_Container->InsertCell(word);
470 word->SetPreviousWord(m_lastWordCell);
471 m_lastWordCell = word;
472 }
473
474 void 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();
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;
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 }
518
519
520 wxHtmlContainerCell* wxHtmlWinParser::OpenContainer()
521 {
522 m_Container = new wxHtmlContainerCell(m_Container);
523 m_Container->SetAlignHor(m_Align);
524 m_posColumn = 0;
525 m_tmpLastWasSpace = true;
526 /* to avoid space being first character in paragraph */
527 return m_Container;
528 }
529
530
531
532 wxHtmlContainerCell* wxHtmlWinParser::SetContainer(wxHtmlContainerCell *c)
533 {
534 m_tmpLastWasSpace = true;
535 /* to avoid space being first character in paragraph */
536 return m_Container = c;
537 }
538
539
540
541 wxHtmlContainerCell* wxHtmlWinParser::CloseContainer()
542 {
543 m_Container = m_Container->GetParent();
544 return m_Container;
545 }
546
547
548 void wxHtmlWinParser::SetFontSize(int s)
549 {
550 if (s < 1)
551 s = 1;
552 else if (s > 7)
553 s = 7;
554 m_FontSize = s;
555 }
556
557
558 void 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
565 void 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 {
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;
588
589 break;
590 }
591 }
592 }
593 }
594
595 wxFont* wxHtmlWinParser::CreateCurrentFont()
596 {
597 int fb = GetFontBold(),
598 fi = GetFontItalic(),
599 fu = GetFontUnderlined(),
600 ff = GetFontFixed(),
601 fs = GetFontSize() - 1 /*remap from <1;7> to <0;6>*/ ;
602
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]);
606 #if !wxUSE_UNICODE
607 wxFontEncoding *encptr = &(m_FontsEncTable[fb][fi][fu][ff][fs]);
608 #endif
609
610 if (*fontptr != NULL && (*faceptr != face
611 #if !wxUSE_UNICODE
612 || *encptr != m_OutputEnc
613 #endif
614 ))
615 {
616 wxDELETE(*fontptr);
617 }
618
619 if (*fontptr == NULL)
620 {
621 *faceptr = face;
622 *fontptr = new wxFont(
623 (int) (m_FontsSizes[fs] * m_FontScale),
624 ff ? wxMODERN : wxSWISS,
625 fi ? wxITALIC : wxNORMAL,
626 fb ? wxBOLD : wxNORMAL,
627 fu ? true : false, face
628 #if wxUSE_UNICODE
629 );
630 #else
631 , m_OutputEnc);
632 *encptr = m_OutputEnc;
633 #endif
634 }
635 m_DC->SetFont(**fontptr);
636 return (*fontptr);
637 }
638
639
640
641 void wxHtmlWinParser::SetLink(const wxHtmlLinkInfo& link)
642 {
643 m_Link = link;
644 m_UseLink = (link.GetHref() != wxEmptyString);
645 }
646
647 void wxHtmlWinParser::SetFontFace(const wxString& face)
648 {
649 if (GetFontFixed())
650 m_FontFaceFixed = face;
651 else
652 m_FontFaceNormal = face;
653
654 #if !wxUSE_UNICODE
655 if (m_InputEnc != wxFONTENCODING_DEFAULT)
656 SetInputEncoding(m_InputEnc);
657 #endif
658 }
659
660 void 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 }
669
670
671 #if !wxUSE_UNICODE
672 void wxHtmlWinParser::SetInputEncoding(wxFontEncoding enc)
673 {
674 // the character used for non-breakable space may change:
675 m_nbsp = 0;
676
677 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
678 wxDELETE(m_EncConv);
679
680 if (enc == wxFONTENCODING_DEFAULT)
681 return;
682
683 wxFontEncoding altfix, altnorm;
684 bool availfix, availnorm;
685
686 availnorm = wxFontMapper::Get()->IsEncodingAvailable(enc, m_FontFaceNormal);
687 availfix = wxFontMapper::Get()->IsEncodingAvailable(enc, m_FontFaceFixed);
688
689 if (availnorm && availfix)
690 {
691 // exact match?
692 m_OutputEnc = enc;
693 }
694
695 else if (wxFontMapper::Get()->GetAltForEncoding(enc, &altnorm, m_FontFaceNormal, false) &&
696 wxFontMapper::Get()->GetAltForEncoding(enc, &altfix, m_FontFaceFixed, false) &&
697 altnorm == altfix)
698 {
699 // alternatives?
700 m_OutputEnc = altnorm;
701 }
702 else if (availnorm)
703 {
704 // at least normal face?
705 m_OutputEnc = enc;
706 }
707 else if (wxFontMapper::Get()->GetAltForEncoding(enc, &altnorm, m_FontFaceNormal, false))
708 {
709 m_OutputEnc = altnorm;
710 }
711 else
712 {
713 #ifndef __WXMAC__
714 // okay, let's convert to ISO_8859-1, available always
715 m_OutputEnc = wxFONTENCODING_DEFAULT;
716 #else
717 m_OutputEnc = wxLocale::GetSystemEncoding() ;
718 #endif
719 }
720
721 m_InputEnc = enc;
722 if (m_OutputEnc == wxFONTENCODING_DEFAULT)
723 {
724 GetEntitiesParser()->SetEncoding(wxFONTENCODING_SYSTEM);
725 }
726 else
727 {
728 GetEntitiesParser()->SetEncoding(m_OutputEnc);
729 }
730
731 if (m_InputEnc == m_OutputEnc)
732 return;
733
734 m_EncConv = new wxEncodingConverter();
735 if (!m_EncConv->Init(m_InputEnc,
736 (m_OutputEnc == wxFONTENCODING_DEFAULT) ?
737 wxFONTENCODING_ISO8859_1 : m_OutputEnc,
738 wxCONVERT_SUBSTITUTE))
739 { // total failure :-(
740 wxLogError(_("Failed to display HTML document in %s encoding"),
741 wxFontMapper::GetEncodingName(enc).c_str());
742 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
743 wxDELETE(m_EncConv);
744 }
745 }
746 #endif
747
748
749
750
751 //-----------------------------------------------------------------------------
752 // wxHtmlWinTagHandler
753 //-----------------------------------------------------------------------------
754
755 IMPLEMENT_ABSTRACT_CLASS(wxHtmlWinTagHandler, wxHtmlTagHandler)
756
757 void 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
863 //-----------------------------------------------------------------------------
864 // wxHtmlTagsModule
865 //-----------------------------------------------------------------------------
866
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!
873
874 IMPLEMENT_DYNAMIC_CLASS(wxHtmlTagsModule, wxModule)
875
876 bool wxHtmlTagsModule::OnInit()
877 {
878 wxHtmlWinParser::AddModule(this);
879 return true;
880 }
881
882 void wxHtmlTagsModule::OnExit()
883 {
884 wxHtmlWinParser::RemoveModule(this);
885 }
886
887 #endif