]> git.saurik.com Git - wxWidgets.git/commitdiff
PCH build fix.
authorWłodzimierz Skiba <abx@abx.art.pl>
Tue, 25 Jul 2006 06:50:19 +0000 (06:50 +0000)
committerWłodzimierz Skiba <abx@abx.art.pl>
Tue, 25 Jul 2006 06:50:19 +0000 (06:50 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@43599 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/latex/wx/richtexthtmlhandler.tex
include/wx/richtext/richtexthtml.h
samples/richtext/richtext.cpp
src/richtext/richtexthtml.cpp

index fb0cd23d29d599fa1562db26fbc11985c591b877..f0808f8a72fae4b5bf34d410e2938caeb416a539 100644 (file)
@@ -74,6 +74,12 @@ for example after the user has viewed the HTML file.
 
 Saves the buffer content to the HTML stream.
 
 
 Saves the buffer content to the HTML stream.
 
+\membersection{wxRichTextHTMLHandler::GetFontSizeMapping}\label{wxrichtexthtmlhandlergetfontsizemapping}
+
+\func{wxArrayInt}{GetFontSizeMapping}{\void}
+
+Returns the mapping for converting point sizes to HTML font sizes.
+
 \membersection{wxRichTextHTMLHandler::GetTempDir}\label{wxrichtexthtmlhandlergettempdir}
 
 \constfunc{const wxString\&}{GetTempDir}{\void}
 \membersection{wxRichTextHTMLHandler::GetTempDir}\label{wxrichtexthtmlhandlergettempdir}
 
 \constfunc{const wxString\&}{GetTempDir}{\void}
@@ -92,6 +98,29 @@ Returns the image locations for the last operation.
 
 Reset the file counter, in case, for example, the same names are required each time
 
 
 Reset the file counter, in case, for example, the same names are required each time
 
+\membersection{wxRichTextHTMLHandler::SetFontSizeMapping}\label{wxrichtexthtmlhandlersetfontsizemapping}
+
+\func{void}{SetFontSizeMapping}{\param{const wxArrayInt\& }{fontSizeMapping}}
+
+Sets the mapping for converting point sizes to HTML font sizes.
+There should be 7 elements, one for each HTML font size, each element specifying the maximum point size for that
+HTML font size.
+
+For example:
+
+\begin{verbatim}
+    wxArrayInt fontSizeMapping;
+    fontSizeMapping.Add(7);
+    fontSizeMapping.Add(9);
+    fontSizeMapping.Add(11);
+    fontSizeMapping.Add(12);
+    fontSizeMapping.Add(14);
+    fontSizeMapping.Add(22);
+    fontSizeMapping.Add(100);
+    
+    htmlHandler.SetFontSizeMapping(fontSizeMapping);
+\end{verbatim}
+
 \membersection{wxRichTextHTMLHandler::SetTempDir}\label{wxrichtexthtmlhandlersettempdir}
 
 \func{void}{SetTempDir}{\param{const wxString\& }{tempDir}}
 \membersection{wxRichTextHTMLHandler::SetTempDir}\label{wxrichtexthtmlhandlersettempdir}
 
 \func{void}{SetTempDir}{\param{const wxString\& }{tempDir}}
index 20c86ed60a8f485cc9bf76fa7f172e3f12a51002..f71ed68d9d86c4d2a60158aac111c721605d5319 100644 (file)
@@ -26,9 +26,7 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextHTMLHandler: public wxRichTextFileHandler
 {
     DECLARE_CLASS(wxRichTextHTMLHandler)
 public:
 {
     DECLARE_CLASS(wxRichTextHTMLHandler)
 public:
-    wxRichTextHTMLHandler(const wxString& name = wxT("HTML"), const wxString& ext = wxT("html"), int type = wxRICHTEXT_TYPE_HTML)
-        : wxRichTextFileHandler(name, ext, type), m_indent(0), m_font(false), m_list(false), m_is_ul(false)
-        { }
+    wxRichTextHTMLHandler(const wxString& name = wxT("HTML"), const wxString& ext = wxT("html"), int type = wxRICHTEXT_TYPE_HTML);
 
     /// Can we save using this handler?
     virtual bool CanSave() const { return true; }
 
     /// Can we save using this handler?
     virtual bool CanSave() const { return true; }
@@ -64,6 +62,12 @@ public:
     void SetTempDir(const wxString& tempDir) { m_tempDir = tempDir; }
     const wxString& GetTempDir() const { return m_tempDir; }
 
     void SetTempDir(const wxString& tempDir) { m_tempDir = tempDir; }
     const wxString& GetTempDir() const { return m_tempDir; }
 
+    /// Set and get mapping from point size to HTML font size. There should be 7 elements,
+    /// one for each HTML font size, each element specifying the maximum point size for that
+    /// HTML font size. E.g. 8, 10, 13, 17, 22, 29, 100
+    void SetFontSizeMapping(const wxArrayInt& fontSizeMapping) { m_fontSizeMapping = fontSizeMapping; }
+    wxArrayInt GetFontSizeMapping() const { return m_fontSizeMapping; }
+
 protected:
 
 // Implementation
 protected:
 
 // Implementation
@@ -73,20 +77,21 @@ protected:
     virtual bool DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& stream);
 
     /// Output character formatting
     virtual bool DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& stream);
 
     /// Output character formatting
-    virtual void BeginCharacterFormatting(const wxTextAttrEx& currentStyle, const wxTextAttrEx& thisStyle, const wxTextAttrEx& paraStyle, wxOutputStream& stream );
-    virtual void EndCharacterFormatting(const wxTextAttrEx& WXUNUSED(currentStyle), const wxTextAttrEx& thisStyle, const wxTextAttrEx& paraStyle, wxOutputStream& stream );
+    void BeginCharacterFormatting(const wxTextAttrEx& currentStyle, const wxTextAttrEx& thisStyle, const wxTextAttrEx& paraStyle, wxTextOutputStream& stream );
+    void EndCharacterFormatting(const wxTextAttrEx& currentStyle, const wxTextAttrEx& thisStyle, const wxTextAttrEx& paraStyle, wxTextOutputStream& stream );
 
     /// Output paragraph formatting
 
     /// Output paragraph formatting
-    virtual void OutputParagraphFormatting(const wxTextAttrEx& WXUNUSED(currentStyle), const wxTextAttrEx& thisStyle, wxOutputStream& stream/*, bool start*/);
+    void BeginParagraphFormatting(const wxTextAttrEx& currentStyle, const wxTextAttrEx& thisStyle, wxTextOutputStream& stream);
+    void EndParagraphFormatting(const wxTextAttrEx& currentStyle, const wxTextAttrEx& thisStyle, wxTextOutputStream& stream);
 
 
-    /// Writes an image to its base64 equivalent, or to the memory filesystem, or to a file
-    void WriteImage(wxRichTextImage* image, wxOutputStream& stream);
+    /// Output font tag
+    void OutputFont(const wxTextAttrEx& style, wxTextOutputStream& stream);
 
 
-    /// Builds required indentation
-    void Indent(const wxTextAttrEx& thisStyle, wxTextOutputStream& str);
+    /// Closes lists to level (-1 means close all)
+    void CloseLists(int level, wxTextOutputStream& str);
 
 
-    /// Left indent
-    void LIndent(const wxTextAttrEx& thisStyle, wxTextOutputStream& str);
+    /// Writes an image to its base64 equivalent, or to the memory filesystem, or to a file
+    void WriteImage(wxRichTextImage* image, wxOutputStream& stream);
 
     /// Converts from pt to size property compatible height
     long PtToSize(long size);
 
     /// Converts from pt to size property compatible height
     long PtToSize(long size);
@@ -104,28 +109,24 @@ protected:
     wxString SymbolicIndent(long indent);
 
     /// Finds the html equivalent of the specified bullet
     wxString SymbolicIndent(long indent);
 
     /// Finds the html equivalent of the specified bullet
-    void TypeOfList(const wxTextAttrEx& thisStyle, wxString& tag);
-
-    /// Closes existings or Opens new tables for navigation to an item's horizontal position.
-    void NavigateToListPosition(const wxTextAttrEx& thisStyle, wxTextOutputStream& str);
+    int TypeOfList(const wxTextAttrEx& thisStyle, wxString& tag);
 #endif
 
 // Data members
 
 #endif
 
 // Data members
 
+    wxRichTextBuffer* m_buffer;
+
     /// Indentation values of the table tags
     wxArrayInt      m_indents;
 
     /// Indentation values of the table tags
     wxArrayInt      m_indents;
 
-    /// Horizontal position of the current table
-    long            m_indent;
+    /// Stack of list types: 0 = ol, 1 = ul
+    wxArrayInt      m_listTypes;
 
 
-    /// Is there any opened font tag
+    /// Is there any opened font tag?
     bool            m_font;
 
     bool            m_font;
 
-    /// Is there any opened ul/ol tag
-    bool            m_list;
-
-    /// type of list, ul or ol?
-    bool            m_is_ul;
+    /// Are we in a table?
+    bool            m_inTable;
 
     /// A list of the image files or in-memory images created by the last operation.
     wxArrayString   m_imageLocations;
 
     /// A list of the image files or in-memory images created by the last operation.
     wxArrayString   m_imageLocations;
@@ -133,6 +134,9 @@ protected:
     /// A location for the temporary files
     wxString        m_tempDir;
 
     /// A location for the temporary files
     wxString        m_tempDir;
 
+    /// A mapping from point size to HTML font size
+    wxArrayInt      m_fontSizeMapping;
+
     /// A counter for generating filenames
     static int      sm_fileCounter;
 };
     /// A counter for generating filenames
     static int      sm_fileCounter;
 };
index ec18b3373a92fe233d10e2b7752a1b0fb22c75f1..9577212f44364d91bc850ea6745e08383aa87057 100644 (file)
@@ -724,9 +724,10 @@ MyFrame::MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos,
     r.BeginBold();
 
     r.BeginFontSize(14);
     r.BeginBold();
 
     r.BeginFontSize(14);
-    r.WriteText(wxT("Welcome to wxRichTextCtrl, a wxWidgets control"));
-    r.LineBreak();
-    r.WriteText(wxT("for editing and presenting styled text and images"));
+    
+    wxString lineBreak = (wxChar) 29;
+    
+    r.WriteText(wxString(wxT("Welcome to wxRichTextCtrl, a wxWidgets control")) + lineBreak + wxT("for editing and presenting styled text and images"));
     r.EndFontSize();
     r.Newline();
 
     r.EndFontSize();
     r.Newline();
 
@@ -1331,6 +1332,17 @@ void MyFrame::OnViewHTML(wxCommandEvent& WXUNUSED(event))
 
     wxRichTextHTMLHandler htmlHandler;
     htmlHandler.SetFlags(wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY);
 
     wxRichTextHTMLHandler htmlHandler;
     htmlHandler.SetFlags(wxRICHTEXT_HANDLER_SAVE_IMAGES_TO_MEMORY);
+    
+    wxArrayInt fontSizeMapping;
+    fontSizeMapping.Add(7);
+    fontSizeMapping.Add(9);
+    fontSizeMapping.Add(11);
+    fontSizeMapping.Add(12);
+    fontSizeMapping.Add(14);
+    fontSizeMapping.Add(22);
+    fontSizeMapping.Add(100);
+    
+    htmlHandler.SetFontSizeMapping(fontSizeMapping);
 
     if (htmlHandler.SaveFile(& m_richTextCtrl->GetBuffer(), strStream))
     {
 
     if (htmlHandler.SaveFile(& m_richTextCtrl->GetBuffer(), strStream))
     {
index 95ed0c1d4c5c597bec289d8ec4e596a65956c42e..a24b6f9db82aa8129a5ad767f102a785588f0615 100644 (file)
@@ -19,6 +19,7 @@
 #if wxUSE_RICHTEXT
 
 #include "wx/richtext/richtexthtml.h"
 #if wxUSE_RICHTEXT
 
 #include "wx/richtext/richtexthtml.h"
+#include "wx/richtext/richtextstyles.h"
 
 #ifndef WX_PRECOMP
 #endif
 
 #ifndef WX_PRECOMP
 #endif
@@ -36,6 +37,18 @@ IMPLEMENT_DYNAMIC_CLASS(wxRichTextHTMLHandler, wxRichTextFileHandler)
 
 int wxRichTextHTMLHandler::sm_fileCounter = 1;
 
 
 int wxRichTextHTMLHandler::sm_fileCounter = 1;
 
+wxRichTextHTMLHandler::wxRichTextHTMLHandler(const wxString& name, const wxString& ext, int type)
+    : wxRichTextFileHandler(name, ext, type), m_buffer(NULL), m_font(false), m_inTable(false)
+{
+    m_fontSizeMapping.Add(8);
+    m_fontSizeMapping.Add(10);
+    m_fontSizeMapping.Add(13);
+    m_fontSizeMapping.Add(17);
+    m_fontSizeMapping.Add(22);
+    m_fontSizeMapping.Add(30);
+    m_fontSizeMapping.Add(100);
+}
+
 /// Can we handle this filename (if using files)? By default, checks the extension.
 bool wxRichTextHTMLHandler::CanHandle(const wxString& filename) const
 {
 /// Can we handle this filename (if using files)? By default, checks the extension.
 bool wxRichTextHTMLHandler::CanHandle(const wxString& filename) const
 {
@@ -58,10 +71,12 @@ bool wxRichTextHTMLHandler::DoLoadFile(wxRichTextBuffer *WXUNUSED(buffer), wxInp
 
 bool wxRichTextHTMLHandler::DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& stream)
 {
 
 bool wxRichTextHTMLHandler::DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& stream)
 {
+    m_buffer = buffer;
+
     ClearTemporaryImageLocations();
 
     buffer->Defragment();
     ClearTemporaryImageLocations();
 
     buffer->Defragment();
-
+    
     wxTextOutputStream str(stream);
 
     wxTextAttrEx currentParaStyle = buffer->GetAttributes();
     wxTextOutputStream str(stream);
 
     wxTextAttrEx currentParaStyle = buffer->GetAttributes();
@@ -70,15 +85,15 @@ bool wxRichTextHTMLHandler::DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream&
     if ((GetFlags() & wxRICHTEXT_HANDLER_NO_HEADER_FOOTER) == 0)
         str << wxT("<html><head></head><body>\n");
 
     if ((GetFlags() & wxRICHTEXT_HANDLER_NO_HEADER_FOOTER) == 0)
         str << wxT("<html><head></head><body>\n");
 
-    str << wxT("<table border=0 cellpadding=0 cellspacing=0><tr><td width=\"100%\">\n");
-
-    str << wxString::Format(wxT("<font face=\"%s\" size=\"%ld\" color=\"%s\" >"),
-        currentParaStyle.GetFont().GetFaceName().c_str(), PtToSize(currentParaStyle.GetFont().GetPointSize()),
-        currentParaStyle.GetTextColour().GetAsString(wxC2S_HTML_SYNTAX).c_str());
+    str << wxT("<table border=0 cellpadding=0 cellspacing=0><tr><td width=\"100%\">");
 
 
+    OutputFont(currentParaStyle, str);
+    
     m_font = false;
     m_font = false;
-    m_indent = 0;
-    m_list = false;
+    m_inTable = false;
+    
+    m_indents.Clear();
+    m_listTypes.Clear();
 
     wxRichTextObjectList::compatibility_iterator node = buffer->GetChildren().GetFirst();
     while (node)
 
     wxRichTextObjectList::compatibility_iterator node = buffer->GetChildren().GetFirst();
     while (node)
@@ -90,7 +105,7 @@ bool wxRichTextHTMLHandler::DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream&
         {
             wxTextAttrEx paraStyle(para->GetCombinedAttributes());
             
         {
             wxTextAttrEx paraStyle(para->GetCombinedAttributes());
             
-            OutputParagraphFormatting(currentParaStyle, paraStyle, stream);
+            BeginParagraphFormatting(currentParaStyle, paraStyle, str);
 
             wxRichTextObjectList::compatibility_iterator node2 = para->GetChildren().GetFirst();
             while (node2)
 
             wxRichTextObjectList::compatibility_iterator node2 = para->GetChildren().GetFirst();
             while (node2)
@@ -100,16 +115,19 @@ bool wxRichTextHTMLHandler::DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream&
                 if (textObj && !textObj->IsEmpty())
                 {
                     wxTextAttrEx charStyle(para->GetCombinedAttributes(obj->GetAttributes()));
                 if (textObj && !textObj->IsEmpty())
                 {
                     wxTextAttrEx charStyle(para->GetCombinedAttributes(obj->GetAttributes()));
-                    BeginCharacterFormatting(currentCharStyle, charStyle, paraStyle, stream);
+                    BeginCharacterFormatting(currentCharStyle, charStyle, paraStyle, str);
                     
                     wxString text = textObj->GetText();
 
                     if (charStyle.HasTextEffects() && (charStyle.GetTextEffects() & wxTEXT_ATTR_EFFECT_CAPITALS))
                         text.MakeUpper();
 
                     
                     wxString text = textObj->GetText();
 
                     if (charStyle.HasTextEffects() && (charStyle.GetTextEffects() & wxTEXT_ATTR_EFFECT_CAPITALS))
                         text.MakeUpper();
 
+                    wxString toReplace = wxRichTextLineBreakChar;
+                    text.Replace(toReplace, wxT("<br>"));
+
                     str << text;
 
                     str << text;
 
-                    EndCharacterFormatting(currentCharStyle, charStyle, paraStyle, stream);
+                    EndCharacterFormatting(currentCharStyle, charStyle, paraStyle, str);
                 }
 
                 wxRichTextImage* image = wxDynamicCast(obj, wxRichTextImage);
                 }
 
                 wxRichTextImage* image = wxDynamicCast(obj, wxRichTextImage);
@@ -118,156 +136,32 @@ bool wxRichTextHTMLHandler::DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream&
 
                 node2 = node2->GetNext();
             }
 
                 node2 = node2->GetNext();
             }
+
+            EndParagraphFormatting(currentParaStyle, paraStyle, str);
+
             str << wxT("\n");
         }
         node = node->GetNext();
     }
             str << wxT("\n");
         }
         node = node->GetNext();
     }
+    
+    CloseLists(-1, str);
 
 
-    str << wxT("</font></td></tr></table>");
+    str << wxT("</font>");
+    
+    str << wxT("</td></tr></table><p>");
 
     if ((GetFlags() & wxRICHTEXT_HANDLER_NO_HEADER_FOOTER) == 0)
         str << wxT("</body></html>");
     
     str << wxT("\n");
 
 
     if ((GetFlags() & wxRICHTEXT_HANDLER_NO_HEADER_FOOTER) == 0)
         str << wxT("</body></html>");
     
     str << wxT("\n");
 
+    m_buffer = NULL;
+
     return true;
 }
 
     return true;
 }
 
-void wxRichTextHTMLHandler::BeginCharacterFormatting(const wxTextAttrEx& currentStyle, const wxTextAttrEx& thisStyle, const wxTextAttrEx& paraStyle, wxOutputStream& stream)
+void wxRichTextHTMLHandler::BeginCharacterFormatting(const wxTextAttrEx& currentStyle, const wxTextAttrEx& thisStyle, const wxTextAttrEx& WXUNUSED(paraStyle), wxTextOutputStream& str)
 {
 {
-    wxTextOutputStream str(stream);
-
-    // Is the item a bulleted one?
-    if ( paraStyle.GetBulletStyle() != wxTEXT_ATTR_BULLET_STYLE_NONE )
-    {
-        // Is there any opened list?
-        if (m_list)
-        {
-            // Yes there is
-
-            // Is the item among the previous ones?
-            // Is the item one of the previous list tag's child items?            
-            if ((paraStyle.GetLeftIndent() == (m_indent + 100)) || (paraStyle.GetLeftIndent() < 100))
-                str << wxT("<li>"); //Yes it is
-            else
-            {
-                // No it isn't, so we should close the list tag
-                str << (m_is_ul ? wxT("</ul>") : wxT("</ol>"));
-
-                // And renavigate to new list's horizontal position
-                NavigateToListPosition(paraStyle, str);
-
-                // Get the appropriate tag, an ol for numerical values, an ul for dot, square etc.
-                wxString tag;
-                TypeOfList(paraStyle, tag);
-                str << tag << wxT("<li>");
-            }
-        }
-        else
-        {
-            // No there isn't a list.
-            // navigate to new list's horizontal position(indent)
-            NavigateToListPosition(paraStyle, str);
-
-            // Get the appropriate tag, an ol for numerical values, an ul for dot, square etc.
-            wxString tag;
-            TypeOfList(paraStyle, tag);
-            str << tag << wxT("<li>");
-
-            // Now we have a list, mark it.
-            m_list = true;
-        }
-    }
-    else if( m_list )
-    {
-        // The item is not bulleted and there is a list that should be closed now.
-        // So close the list
-
-        str << (m_is_ul ? wxT("</ul>") : wxT("</ol>"));
-
-        // And mark as there is no an opened list
-        m_list = false;
-    }
-
-    // does the item have an indentation ?
-    if( paraStyle.GetLeftIndent() )
-    {
-        if (paraStyle.GetBulletStyle() == wxTEXT_ATTR_BULLET_STYLE_NONE)
-        {
-            if (m_indent)
-            {
-                if ((paraStyle.GetLeftIndent() + paraStyle.GetLeftSubIndent()) == m_indent)
-                {
-                    if (paraStyle.GetLeftSubIndent() < 0)
-                    {
-                        str << SymbolicIndent(~paraStyle.GetLeftSubIndent());
-                    }
-                }
-                else
-                {
-                    if (paraStyle.GetLeftIndent() + paraStyle.GetLeftSubIndent() > m_indent)
-                    {
-                        Indent(paraStyle, str);
-                        m_indent = paraStyle.GetLeftIndent() + paraStyle.GetLeftSubIndent();
-                        m_indents.Add( m_indent );
-                    }
-                    else
-                    {
-                        int i = m_indents.size() - 1;
-                        for (; i > -1; i--)
-                        {
-                            if (m_indent < (paraStyle.GetLeftIndent() + paraStyle.GetLeftSubIndent()))
-                            {
-                                Indent(paraStyle, str);
-                                m_indent = paraStyle.GetLeftIndent() + paraStyle.GetLeftSubIndent();
-                                m_indents.Add( m_indent );
-
-                                break;
-                            }
-                            else if (m_indent == (paraStyle.GetLeftIndent() + paraStyle.GetLeftSubIndent()))
-                            {
-                                if (paraStyle.GetLeftSubIndent() < 0)
-                                {
-                                    str << SymbolicIndent(~paraStyle.GetLeftSubIndent());
-                                }
-                                break;
-                            }
-                            else
-                            {
-                                str << wxT("</td></tr></table>");
-
-                                m_indents.RemoveAt(i);
-
-                                if(i < 1)
-                                {
-                                    m_indent=0; break;
-                                }
-                                m_indent = m_indents[i-1];
-                            }
-                        }
-                    }
-                }
-            }
-            else
-            {
-                Indent(paraStyle, str);
-                m_indent = paraStyle.GetLeftIndent() + paraStyle.GetLeftSubIndent();
-                m_indents.Add( m_indent );
-            }
-        }
-    }
-    else if (m_indent)
-    {
-        // The item is not indented and there is a table(s) that should be closed now.
-
-        for (unsigned int i = 0; i < m_indents.size(); i++)
-            str << wxT("</td></tr></table>");
-
-        m_indent = 0;
-        m_indents.Clear();
-    }
-
-
     wxString style;
 
     // Is there any change in the font properties of the item?
     wxString style;
 
     // Is there any change in the font properties of the item?
@@ -301,165 +195,149 @@ void wxRichTextHTMLHandler::BeginCharacterFormatting(const wxTextAttrEx& current
         str << wxT("<a href=\"") << thisStyle.GetURL() << wxT("\">");
 }
 
         str << wxT("<a href=\"") << thisStyle.GetURL() << wxT("\">");
 }
 
-void wxRichTextHTMLHandler::EndCharacterFormatting(const wxTextAttrEx& WXUNUSED(currentStyle), const wxTextAttrEx& thisStyle, const wxTextAttrEx& WXUNUSED(paraStyle), wxOutputStream& stream)
+void wxRichTextHTMLHandler::EndCharacterFormatting(const wxTextAttrEx& WXUNUSED(currentStyle), const wxTextAttrEx& thisStyle, const wxTextAttrEx& WXUNUSED(paraStyle), wxTextOutputStream& stream)
 {
 {
-    wxTextOutputStream str(stream);
-
     if (thisStyle.HasURL())
     if (thisStyle.HasURL())
-        str << wxT("</a>");
+        stream << wxT("</a>");
 
     if (thisStyle.GetFont().GetUnderlined())
 
     if (thisStyle.GetFont().GetUnderlined())
-        str << wxT("</u>");
+        stream << wxT("</u>");
     if (thisStyle.GetFont().GetStyle() == wxITALIC)
     if (thisStyle.GetFont().GetStyle() == wxITALIC)
-        str << wxT("</i>");
+        stream << wxT("</i>");
     if (thisStyle.GetFont().GetWeight() == wxBOLD)
     if (thisStyle.GetFont().GetWeight() == wxBOLD)
-        str << wxT("</b>");
+        stream << wxT("</b>");
 
     if (m_font)
     {
         m_font = false;
 
     if (m_font)
     {
         m_font = false;
-        str << wxT("</font>");
+        stream << wxT("</font>");
     }
 }
 
     }
 }
 
-/// Output paragraph formatting
-void wxRichTextHTMLHandler::OutputParagraphFormatting(const wxTextAttrEx& WXUNUSED(currentStyle), const wxTextAttrEx& thisStyle, wxOutputStream& stream)
+/// Begin paragraph formatting
+void wxRichTextHTMLHandler::BeginParagraphFormatting(const wxTextAttrEx& WXUNUSED(currentStyle), const wxTextAttrEx& thisStyle, wxTextOutputStream& str)
 {
 {
-    // If there is no opened list currently, insert a <p> after every paragraph
-    if (!m_list)
-    {
-        wxTextOutputStream str(stream);
-        wxString align = GetAlignment(thisStyle);
-        str << wxString::Format(wxT("<p align=\"%s\">"), align.c_str());
-    }
-    
     if (thisStyle.HasPageBreak())
     {
     if (thisStyle.HasPageBreak())
     {
-        wxTextOutputStream str(stream);
+        str << wxT("</tr></td></table>");
         str << wxT("<div style=\"page-break-after:always\"></div>\n");
         str << wxT("<div style=\"page-break-after:always\"></div>\n");
+        str << wxT("<table border=0 cellpadding=0 cellspacing=0><tr><td width=\"100%\">");
     }
     }
-}
-
-void wxRichTextHTMLHandler::NavigateToListPosition(const wxTextAttrEx& thisStyle, wxTextOutputStream& str)
-{
-    // indenting an item using an ul/ol tag is equal to inserting 5 x &nbsp; on its left side.
-    // so we should start from 100 point left
-
-    // Is the second td's left wall of the current indentaion table at the 100+ point-left-side
-    // of the item, horizontally?
-    if (m_indent + 100 < thisStyle.GetLeftIndent())
-    {
-        // yes it is
-        LIndent(thisStyle, str);
-        m_indent = thisStyle.GetLeftIndent() - 100;
-        m_indents.Add( m_indent );
-        return;
-    }
-    // No it isn't
 
 
-    int i = m_indents.size() - 1;
-    for (; i > -1; i--)
+    if (thisStyle.HasLeftIndent())
     {
     {
-        //Is the second td's left wall of the current indentaion table at the 100+ point-left-side
-        //of the item ?
-        if (m_indent + 100 < thisStyle.GetLeftIndent())
+        if (thisStyle.HasBulletStyle())
         {
         {
-            // Yes it is
-            LIndent(thisStyle, str);
-            m_indent = thisStyle.GetLeftIndent() - 100;
-            m_indents.Add( m_indent );
-            break;
+            int indent = thisStyle.GetLeftIndent();
+
+            // Close levels high than this
+            CloseLists(indent, str);
+            
+            if (m_indents.GetCount() > 0 && indent == m_indents.Last())
+            {
+                // Same level, no need to start a new list
+            }
+            else if (m_indents.GetCount() == 0 || indent > m_indents.Last())
+            {
+                m_indents.Add(indent);
+                
+                wxString tag;
+                int listType = TypeOfList(thisStyle, tag);
+                m_listTypes.Add(listType);
+                
+                wxString align = GetAlignment(thisStyle);
+                str << wxString::Format(wxT("<p align=\"%s\">"), align.c_str());
+                
+                str << tag;
+            }
+            
+            str << wxT("<li> ");
         }
         }
-        else if (m_indent + 100 == thisStyle.GetLeftIndent())
-            break; //exact match
         else
         {
         else
         {
-            // No it is not, the second td's left wall of the current indentaion table is at the
-            //right side of the current item horizontally, so close it.
-            str << wxT("</td></tr></table>");
+            CloseLists(-1, str);
+            
+            wxString align = GetAlignment(thisStyle);
+            str << wxString::Format(wxT("<p align=\"%s\">"), align.c_str());
 
 
-            m_indents.RemoveAt(i);
+            // Use a table
+            int indentTenthsMM = thisStyle.GetLeftIndent() + thisStyle.GetLeftSubIndent();
+            // TODO: convert to pixels
+            int indentPixels = indentTenthsMM/4;
+            str << wxString::Format(wxT("<table border=0 cellpadding=0 cellspacing=0><tr><td width=\"%d\"></td><td>"), indentPixels);
+
+            OutputFont(thisStyle, str);
 
 
-            if (i < 1)
+            if (thisStyle.GetLeftSubIndent() < 0)
             {
             {
-                m_indent=0; break;
+                str << SymbolicIndent( - thisStyle.GetLeftSubIndent());
             }
             }
-            m_indent = m_indents[i-1];
+
+            m_inTable = true;            
         }
     }
         }
     }
+    else
+    {
+        CloseLists(-1, str);
+
+        wxString align = GetAlignment(thisStyle);
+        str << wxString::Format(wxT("<p align=\"%s\">"), align.c_str());
+    }    
 }
 }
-void wxRichTextHTMLHandler::Indent( const wxTextAttrEx& thisStyle, wxTextOutputStream& str )
+
+/// End paragraph formatting
+void wxRichTextHTMLHandler::EndParagraphFormatting(const wxTextAttrEx& WXUNUSED(currentStyle), const wxTextAttrEx& thisStyle, wxTextOutputStream& stream)
 {
 {
-    //There is no way to indent an item in HTML, but we can use tables.
-
-    // Item -> "Hello world"
-    // Its Left Indentation -> 100
-    // Its Left Sub-Indentation ->40
-    // A typical indentation-table for the item will be construct as the following
-
-    // 3 x nbsp = 60
-    // 2 x nbsp = 40
-    // LSI = Left Sub Indent
-    // LI = Left Indent - LSI
-    //
-    // -------------------------------------------
-    // |&nbsp;&nbsp;nbsp;|nbsp;nbsp;Hello World  |
-    // |      |          |    |                  |
-    // |        V        |    V                  |
-    // |      --LI--     | --LSI--               |
-    // -------------------------------------------
-
-    str << wxT("<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr>");
-
-    wxString symbolic_indent = SymbolicIndent( (thisStyle.GetLeftIndent() + thisStyle.GetLeftSubIndent()) - m_indent );
-    str << wxString::Format( wxT("<td>%s</td>"), symbolic_indent.c_str() );
-    str << wxT("<td width=\"100%\">");
-
-    if (thisStyle.GetLeftSubIndent() < 0)
+    if (m_inTable)
     {
     {
-        str << SymbolicIndent(~thisStyle.GetLeftSubIndent());
+        if (thisStyle.HasFont())
+            stream << wxT("</font>");
+            
+        stream << wxT("</td></tr></table>\n");
+        m_inTable = false;
     }
 }
 
     }
 }
 
-void wxRichTextHTMLHandler::LIndent( const wxTextAttrEx& thisStyle, wxTextOutputStream& str )
+/// Closes lists to level (-1 means close all)
+void wxRichTextHTMLHandler::CloseLists(int level, wxTextOutputStream& str)
+{
+    // Close levels high than this
+    int i = m_indents.GetCount()-1;
+    while (i >= 0)
+    {
+        int l = m_indents[i];
+        if (l > level)
+        {
+            if (m_listTypes[i] == 0)
+                str << wxT("</ol>");
+            else
+                str << wxT("</ul>");
+            m_indents.RemoveAt(i);
+            m_listTypes.RemoveAt(i);
+        }
+        else
+            break;
+        i --;
+     }
+}
+
+/// Output font tag
+void wxRichTextHTMLHandler::OutputFont(const wxTextAttrEx& style, wxTextOutputStream& stream)
 {
 {
-    // Code:
-    // r.BeginNumberedBullet(1, 200, 60);
-    // r.Newline();
-    // r.WriteText(wxT("first item"));
-    // r.EndNumberedBullet();
-    // r.BeginNumberedBullet(2, 200, 60);
-    // r.Newline();
-    // r.WriteText(wxT("second item."));
-    // r.EndNumberedBullet();
-    //
-    // A typical indentation-table for the item will be construct as the following
-
-    // 1 x nbsp = 20 point
-    // ULI -> 100pt (UL/OL tag indents its sub element by 100 point)
-    // <--------- 100 pt ---------->|
-    // ------------------------------------------------------
-    // |&nbsp;&nbsp;nbsp;&nbsp;nbsp;|<ul>                   |
-    // |                            |<-ULI-><li>first item  |
-    // |                            |<-ULI-><li>second item |
-    // |                            |</ul>                  |
-    // ------------------------------------------------------
-    //                              |<-100->|
-
-
-    str << wxT("<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr>");
-
-    wxString symbolic_indent = SymbolicIndent( (thisStyle.GetLeftIndent() - m_indent) - 100);
-    str << wxString::Format( wxT("<td>%s</td>"), symbolic_indent.c_str() );
-    str << wxT("<td width=\"100%\">");
+    if (style.HasFont())
+    {
+        stream << wxString::Format(wxT("<font face=\"%s\" size=\"%ld\" color=\"%s\" >"),
+                style.GetFont().GetFaceName().c_str(), PtToSize(style.GetFont().GetPointSize()),
+                style.GetTextColour().GetAsString(wxC2S_HTML_SYNTAX).c_str());
+    }
 }
 
 }
 
-void wxRichTextHTMLHandler::TypeOfList( const wxTextAttrEx& thisStyle, wxString& tag )
+int wxRichTextHTMLHandler::TypeOfList( const wxTextAttrEx& thisStyle, wxString& tag )
 {
     // We can use number attribute of li tag but not all the browsers support it.
     // also wxHtmlWindow doesn't support type attribute.
 
 {
     // We can use number attribute of li tag but not all the browsers support it.
     // also wxHtmlWindow doesn't support type attribute.
 
-    m_is_ul = false;
+    bool m_is_ul = false;
     if (thisStyle.GetBulletStyle() == (wxTEXT_ATTR_BULLET_STYLE_ARABIC|wxTEXT_ATTR_BULLET_STYLE_PERIOD))
         tag = wxT("<ol type=\"1\">");
     else if (thisStyle.GetBulletStyle() == wxTEXT_ATTR_BULLET_STYLE_LETTERS_UPPER)
     if (thisStyle.GetBulletStyle() == (wxTEXT_ATTR_BULLET_STYLE_ARABIC|wxTEXT_ATTR_BULLET_STYLE_PERIOD))
         tag = wxT("<ol type=\"1\">");
     else if (thisStyle.GetBulletStyle() == wxTEXT_ATTR_BULLET_STYLE_LETTERS_UPPER)
@@ -475,6 +353,11 @@ void wxRichTextHTMLHandler::TypeOfList( const wxTextAttrEx& thisStyle, wxString&
         tag = wxT("<ul>");
         m_is_ul = true;
     }
         tag = wxT("<ul>");
         m_is_ul = true;
     }
+    
+    if (m_is_ul)
+        return 1;
+    else
+        return 0;
 }
 
 wxString wxRichTextHTMLHandler::GetAlignment( const wxTextAttrEx& thisStyle )
 }
 
 wxString wxRichTextHTMLHandler::GetAlignment( const wxTextAttrEx& thisStyle )
@@ -570,14 +453,12 @@ void wxRichTextHTMLHandler::WriteImage(wxRichTextImage* image, wxOutputStream& s
 
 long wxRichTextHTMLHandler::PtToSize(long size)
 {
 
 long wxRichTextHTMLHandler::PtToSize(long size)
 {
-    // return approximate size
-    if (size < 9 ) return 1;
-    else if( size < 11 ) return 2;
-    else if( size < 14 ) return 3;
-    else if( size < 18 ) return 4;
-    else if( size < 23 ) return 5;
-    else if( size < 30 ) return 6;
-    else return 7;
+    int i;
+    int len = m_fontSizeMapping.GetCount();
+    for (i = 0; i < len; i++)
+        if (size <= m_fontSizeMapping[i])
+            return i+1;
+    return 7;        
 }
 
 wxString wxRichTextHTMLHandler::SymbolicIndent(long indent)
 }
 
 wxString wxRichTextHTMLHandler::SymbolicIndent(long indent)