#ifndef WX_PRECOMP
#include "wx/intl.h"
#include "wx/module.h"
+ #include "wx/log.h"
#endif
#include "wx/filename.h"
}
else if (childName == wxT("image"))
{
- int imageType = wxBITMAP_TYPE_PNG;
- wxString value = node->GetAttribute(wxT("imagetype"), wxEmptyString);
+ wxBitmapType imageType = wxBITMAP_TYPE_PNG;
+ wxString value = child->GetAttribute(wxT("imagetype"), wxEmptyString);
if (!value.empty())
- imageType = wxAtoi(value);
+ {
+ int type = wxAtoi(value);
+
+ // note: 0 == wxBITMAP_TYPE_INVALID
+ if (type <= 0 || type >= wxBITMAP_TYPE_MAX)
+ wxLogWarning("Invalid bitmap type specified for <image> tag: %d", type);
+ else
+ imageType = (wxBitmapType)type;
+ }
wxString data;
if (!data.empty())
{
wxRichTextImage* imageObj = new wxRichTextImage(para);
+ GetStyle(imageObj->GetAttributes(), child, false);
para->AppendChild(imageObj);
wxStringInputStream strStream(data);
OutputString(stream, str.Mid(last, i - last), convMem, convFile);
}
+static wxString AttributeToXML(const wxString& str)
+{
+ wxString str1;
+ size_t i, last, len;
+ wxChar c;
+
+ len = str.Len();
+ last = 0;
+ for (i = 0; i < len; i++)
+ {
+ c = str.GetChar(i);
+
+ // Original code excluded "&" but we _do_ want to convert
+ // the ampersand beginning & because otherwise when read in,
+ // the original "&" becomes "&".
+
+ if (c == wxT('<') || c == wxT('>') || c == wxT('"') ||
+ (c == wxT('&') /* && (str.Mid(i+1, 4) != wxT("amp;")) */ ))
+ {
+ str1 += str.Mid(last, i - last);
+ switch (c)
+ {
+ case wxT('<'):
+ str1 += wxT("<");
+ break;
+ case wxT('>'):
+ str1 += wxT(">");
+ break;
+ case wxT('&'):
+ str1 += wxT("&");
+ break;
+ case wxT('"'):
+ str1 += wxT(""");
+ break;
+ default: break;
+ }
+ last = i + 1;
+ }
+ else if (wxUChar(c) > 127)
+ {
+ str1 += str.Mid(last, i - last);
+
+ wxString s(wxT("&#"));
+ s << (int) c;
+ s << wxT(";");
+ str1 += s;
+ last = i + 1;
+ }
+ }
+ str1 += str.Mid(last, i - last);
+ return str1;
+}
+
inline static void OutputIndentation(wxOutputStream& stream, int indent)
{
wxString str = wxT("\n");
int last = 0;
const wxString& text = textObj.GetText();
int len = (int) text.Length();
- for (i = 0; i < len; i++)
+
+ if (len == 0)
+ {
+ i = 0;
+ OutputIndentation(stream, indent);
+ OutputString(stream, wxT("<") + objectName, convMem, convFile);
+ OutputString(stream, style + wxT(">"), convMem, convFile);
+ OutputString(stream, wxT("</text>"), convMem, convFile);
+ }
+ else for (i = 0; i < len; i++)
{
int c = (int) text[i];
- if (c < 32 && c != 9 && c != 10 && c != 13)
+ if ((c < 32 || c == 34) && c != 9 && c != 10 && c != 13)
{
if (i > 0)
{
{
wxRichTextImage& imageObj = (wxRichTextImage&) obj;
+ wxString style = CreateStyle(obj.GetAttributes(), false);
+
if (imageObj.GetImage().Ok() && !imageObj.GetImageBlock().Ok())
imageObj.MakeBlock();
if (!imageObj.GetImageBlock().Ok())
{
// No data
- OutputString(stream, wxT(">"), convMem, convFile);
+ OutputString(stream, style + wxT(">"), convMem, convFile);
}
else
{
- OutputString(stream, wxString::Format(wxT(" imagetype=\"%d\">"), (int) imageObj.GetImageBlock().GetImageType()));
+ OutputString(stream, wxString::Format(wxT(" imagetype=\"%d\"") + style + wxT(">"), (int) imageObj.GetImageBlock().GetImageType()));
}
OutputIndentation(stream, indent+1);
str << wxT(" characterstyle=\"") << wxString(attr.GetCharacterStyleName()) << wxT("\"");
if (attr.HasURL())
- str << wxT(" url=\"") << attr.GetURL() << wxT("\"");
+ str << wxT(" url=\"") << AttributeToXML(attr.GetURL()) << wxT("\"");
if (isPara)
{
return str;
}
+/// Replace face name with current name for platform.
+/// TODO: introduce a virtual function or settable table to
+/// do this comprehensively.
+bool wxRichTextFixFaceName(wxString& facename)
+{
+ if (facename.IsEmpty())
+ return false;
+
+#ifdef __WXMSW__
+ if (facename == wxT("Times"))
+ {
+ facename = wxT("Times New Roman");
+ return true;
+ }
+ else if (facename == wxT("Helvetica"))
+ {
+ facename = wxT("Arial");
+ return true;
+ }
+ else if (facename == wxT("Courier"))
+ {
+ facename = wxT("Courier New");
+ return true;
+ }
+ else
+ return false;
+#else
+ if (facename == wxT("Times New Roman"))
+ {
+ facename = wxT("Times");
+ return true;
+ }
+ else if (facename == wxT("Arial"))
+ {
+ facename = wxT("Helvetica");
+ return true;
+ }
+ else if (facename == wxT("Courier New"))
+ {
+ facename = wxT("Courier");
+ return true;
+ }
+ else
+ return false;
+#endif
+}
+
/// Get style parameters
bool wxRichTextXMLHandler::GetStyle(wxTextAttr& attr, wxXmlNode* node, bool isPara)
{
fontFacename = node->GetAttribute(wxT("fontface"), wxEmptyString);
if (!fontFacename.IsEmpty())
+ {
attr.SetFontFaceName(fontFacename);
+ if (GetFlags() & wxRICHTEXT_HANDLER_CONVERT_FACENAMES)
+ wxRichTextFixFaceName(fontFacename);
+ }
+
wxString value;
//value = node->GetAttribute(wxT("fontfamily"), wxEmptyString);
attr.SetTextColour(value);
}
- value = node->GetAttribute(wxT("backgroundcolor"), wxEmptyString);
+ value = node->GetAttribute(wxT("bgcolor"), wxEmptyString);
if (!value.empty())
{
if (value[0] == wxT('#'))