#include "wx/richtext/richtextstyles.h"
#include "wx/richtext/richtextimagedlg.h"
#include "wx/richtext/richtextsizepage.h"
+#include "wx/richtext/richtextxml.h"
#include "wx/listimpl.cpp"
#include "wx/arrimpl.cpp"
// Helpers for efficiency
inline void wxCheckSetFont(wxDC& dc, const wxFont& font)
{
- // JACS: did I do this some time ago when testing? Should we re-enable it?
-#if 0
- const wxFont& font1 = dc.GetFont();
- if (font1.IsOk() && font.IsOk())
- {
- if (font1.GetPointSize() == font.GetPointSize() &&
- font1.GetFamily() == font.GetFamily() &&
- font1.GetStyle() == font.GetStyle() &&
- font1.GetWeight() == font.GetWeight() &&
- font1.GetUnderlined() == font.GetUnderlined() &&
- font1.GetFamily() == font.GetFamily() &&
- font1.GetFaceName() == font.GetFaceName())
- return;
- }
-#endif
dc.SetFont(font);
}
// Unscale
double scale = 1.0;
if (GetBuffer())
- scale = GetBuffer()->GetScale();
+ scale = GetBuffer()->GetScale() / GetBuffer()->GetDimensionScale();
int p = ConvertTenthsMMToPixels(dc.GetPPI().x, units, scale);
return p;
wxRichTextBuffer* wxRichTextObject::GetBuffer() const
{
const wxRichTextObject* obj = this;
- while (obj && !obj->IsKindOf(CLASSINFO(wxRichTextBuffer)))
+ while (obj && !wxDynamicCast(obj, wxRichTextBuffer))
obj = obj->GetParent();
return wxDynamicCast(obj, wxRichTextBuffer);
}
availableSpace = GetAvailableContentArea(dc, context, rect);
}
+ // Fix the width if we're at the top level
+ if (!GetParent())
+ attr.GetTextBoxAttr().GetWidth().SetValue(rect.GetWidth(), wxTEXT_ATTR_UNITS_PIXELS);
+
int leftMargin, rightMargin, topMargin, bottomMargin;
wxRichTextObject::GetTotalMargin(dc, GetBuffer(), attr, leftMargin, rightMargin,
topMargin, bottomMargin);
maxWidth = wxMax(maxWidth, w);
maxMaxWidth = wxMax(maxMaxWidth, w);
}
+ else
+ {
+ // TODO: Make sure the layout box's position reflects
+ // the position of the children, but without
+ // breaking layout of a box within a paragraph.
+ }
// TODO: (also in para layout) should set the
// object's size to an absolute one if specified,
wxRichTextAttr* cStyle = & defaultCharStyle;
wxRichTextParagraph* para = new wxRichTextParagraph(text, this, pStyle, cStyle);
+ para->GetAttributes().GetTextBoxAttr().Reset();
AppendChild(para);
size_t len = text.length();
wxString line;
wxRichTextParagraph* para = new wxRichTextParagraph(wxEmptyString, this, pStyle, cStyle);
+ para->GetAttributes().GetTextBoxAttr().Reset();
AppendChild(para);
plainText->SetText(line);
para = new wxRichTextParagraph(wxEmptyString, this, pStyle, cStyle);
+ para->GetAttributes().GetTextBoxAttr().Reset();
AppendChild(para);
wxRichTextAttr* cStyle = & defaultCharStyle;
wxRichTextParagraph* para = new wxRichTextParagraph(this, pStyle);
+ para->GetAttributes().GetTextBoxAttr().Reset();
AppendChild(para);
para->AppendChild(new wxRichTextImage(image, this, cStyle));
{
// Start with the base style
style = GetAttributes();
+ style.GetTextBoxAttr().Reset();
// Apply the paragraph style
wxRichTextApplyStyle(style, obj->GetAttributes());
if (childRange.GetLength() == 0 && GetRange().GetLength() == 1)
childRange.SetEnd(childRange.GetEnd()+1);
- if (!childRange.IsOutside(range) && child->IsKindOf(CLASSINFO(wxRichTextPlainText)))
+ if (!childRange.IsOutside(range) && wxDynamicCast(child, wxRichTextPlainText))
{
foundCount ++;
wxRichTextAttr textAttr = para->GetCombinedAttributes(child->GetAttributes());
- if (wxTextAttrEqPartial(textAttr, style))
+ if (textAttr.EqPartial(style, false /* strong test - attributes must be valid in both objects */))
matchingCount ++;
}
wxRichTextApplyStyle(textAttr, para->GetAttributes());
foundCount ++;
- if (wxTextAttrEqPartial(textAttr, style))
+ if (textAttr.EqPartial(style, false /* strong test */))
matchingCount ++;
}
}
wxRichTextApplyStyle(newPara->GetAttributes(), listStyle);
// Now we need to do numbering
- if (renumber)
+ // Preserve the existing list item continuation bullet style, if any
+ if (para->GetAttributes().HasBulletStyle() && (para->GetAttributes().GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_CONTINUATION))
+ newPara->GetAttributes().SetBulletStyle(newPara->GetAttributes().GetBulletStyle()|wxTEXT_ATTR_BULLET_STYLE_CONTINUATION);
+ else
{
- newPara->GetAttributes().SetBulletNumber(n);
- }
+ // Now we need to do numbering
+ if (renumber)
+ {
+ newPara->GetAttributes().SetBulletNumber(n);
+ }
- n ++;
+ n ++;
+ }
}
else if (!newPara->GetAttributes().GetListStyleName().IsEmpty())
{
wxRichTextAttr listStyle(defToUse->GetCombinedStyleForLevel(thisLevel, styleSheet));
wxRichTextApplyStyle(newPara->GetAttributes(), listStyle);
+ // Preserve the existing list item continuation bullet style, if any
+ if (para->GetAttributes().HasBulletStyle() && (para->GetAttributes().GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_CONTINUATION))
+ newPara->GetAttributes().SetBulletStyle(newPara->GetAttributes().GetBulletStyle()|wxTEXT_ATTR_BULLET_STYLE_CONTINUATION);
+
// OK, we've (re)applied the style, now let's get the numbering right.
if (currentLevel == -1)
}
else
{
- levels[currentLevel] ++;
+ if (!(para->GetAttributes().HasBulletStyle() && (para->GetAttributes().GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_CONTINUATION)))
+ levels[currentLevel] ++;
}
newPara->GetAttributes().SetBulletNumber(levels[currentLevel]);
/// position of the paragraph that it had to start looking from.
bool wxRichTextParagraphLayoutBox::FindNextParagraphNumber(wxRichTextParagraph* previousParagraph, wxRichTextAttr& attr) const
{
+ // Search for a paragraph that isn't a continuation paragraph (no bullet)
+ while (previousParagraph && previousParagraph->GetAttributes().HasBulletStyle() && previousParagraph->GetAttributes().GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_CONTINUATION)
+ {
+ wxRichTextObjectList::compatibility_iterator node = ((wxRichTextCompositeObject*) previousParagraph->GetParent())->GetChildren().Find(previousParagraph);
+ if (node)
+ {
+ node = node->GetPrevious();
+ if (node)
+ previousParagraph = wxDynamicCast(node->GetData(), wxRichTextParagraph);
+ else
+ previousParagraph = NULL;
+ }
+ else
+ previousParagraph = NULL;
+ }
+
if (!previousParagraph->GetAttributes().HasFlag(wxTEXT_ATTR_BULLET_STYLE) || previousParagraph->GetAttributes().GetBulletStyle() == wxTEXT_ATTR_BULLET_STYLE_NONE)
return false;
DrawBoxAttributes(dc, GetBuffer(), attr, paraRect);
// Draw the bullet, if any
- if (attr.GetBulletStyle() != wxTEXT_ATTR_BULLET_STYLE_NONE)
+ if ((attr.GetBulletStyle() == wxTEXT_ATTR_BULLET_STYLE_NONE) == 0 && (attr.GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_CONTINUATION) == 0)
{
if (attr.GetLeftSubIndent() != 0)
{
if (child->IsTopLevel())
{
// We can move it to the correct position at this point
- child->Move(GetPosition() + wxPoint(currentWidth, currentPosition.y));
+ // TODO: probably need to add margin
+ child->Move(GetPosition() + wxPoint(currentWidth + (wxMax(leftIndent, leftIndent + leftSubIndent)), currentPosition.y));
}
// Cases:
// Line end position shouldn't be the same as the end, or greater.
if (wrapPosition >= GetRange().GetEnd())
- wrapPosition = GetRange().GetEnd()-1;
+ wrapPosition = wxMax(0, GetRange().GetEnd()-1);
// wxLogDebug(wxT("Split at %ld"), wrapPosition);
// If floating, ignore. We already laid out floats.
// Also ignore if empty object, except if we haven't got any
// size yet.
- if (!child->IsFloating() && child->GetRange().GetLength() != 0 && !child->IsKindOf(CLASSINFO(wxRichTextPlainText)))
+ if (!child->IsFloating() && child->GetRange().GetLength() != 0 && !wxDynamicCast(child, wxRichTextPlainText))
{
if (child->GetCachedSize().x > minWidth)
minWidth = child->GetMinSize().x;
return;
wxPoint pos = line->GetPosition();
+ wxPoint originalPos = pos;
wxSize size = line->GetSize();
// centering, right-justification
pos.x = pos.x + rect.GetWidth() - size.x - rightIndent;
line->SetPosition(pos);
}
+
+ if (pos != originalPos)
+ {
+ wxPoint inc = pos - originalPos;
+
+ wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst();
+
+ while (node)
+ {
+ wxRichTextObject* child = node->GetData();
+ if (child->IsTopLevel() && !child->GetRange().IsOutside(line->GetAbsoluteRange()))
+ child->Move(child->GetPosition() + inc);
+
+ node = node->GetNext();
+ }
+ }
}
/// Insert text at the given position
wxString str = m_text;
wxString toRemove = wxRichTextLineBreakChar;
str.Replace(toRemove, wxT(" "));
- if (textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_CAPITALS))
+ if (textAttr.HasTextEffects() && (textAttr.GetTextEffects() & (wxTEXT_ATTR_EFFECT_CAPITALS|wxTEXT_ATTR_EFFECT_SMALL_CAPITALS)))
str.MakeUpper();
long len = range.GetLength();
int x, y;
if ( textFont.IsOk() )
{
+ if (textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_SMALL_CAPITALS))
+ {
+ textFont.SetPointSize((int) (textFont.GetPointSize()*0.75));
+ wxCheckSetFont(dc, textFont);
+ charHeight = dc.GetCharHeight();
+ }
+
if ( textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_SUPERSCRIPT) )
{
- double size = static_cast<double>(textFont.GetPointSize()) / wxSCRIPT_MUL_FACTOR;
- textFont.SetPointSize( static_cast<int>(size) );
- x = rect.x;
- y = rect.y;
+ if (textFont.IsUsingSizeInPixels())
+ {
+ double size = static_cast<double>(textFont.GetPixelSize().y) / wxSCRIPT_MUL_FACTOR;
+ textFont.SetPixelSize(wxSize(0, static_cast<int>(size)));
+ x = rect.x;
+ y = rect.y;
+ }
+ else
+ {
+ double size = static_cast<double>(textFont.GetPointSize()) / wxSCRIPT_MUL_FACTOR;
+ textFont.SetPointSize(static_cast<int>(size));
+ x = rect.x;
+ y = rect.y;
+ }
wxCheckSetFont(dc, textFont);
}
else if ( textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_SUBSCRIPT) )
{
- double size = static_cast<double>(textFont.GetPointSize()) / wxSCRIPT_MUL_FACTOR;
- textFont.SetPointSize( static_cast<int>(size) );
- x = rect.x;
- int sub_height = static_cast<int>( static_cast<double>(charHeight) / wxSCRIPT_MUL_FACTOR);
- y = rect.y + (rect.height - sub_height + (descent - m_descent));
+ if (textFont.IsUsingSizeInPixels())
+ {
+ double size = static_cast<double>(textFont.GetPixelSize().y) / wxSCRIPT_MUL_FACTOR;
+ textFont.SetPixelSize(wxSize(0, static_cast<int>(size)));
+ x = rect.x;
+ int sub_height = static_cast<int>(static_cast<double>(charHeight) / wxSCRIPT_MUL_FACTOR);
+ y = rect.y + (rect.height - sub_height + (descent - m_descent));
+ }
+ else
+ {
+ double size = static_cast<double>(textFont.GetPointSize()) / wxSCRIPT_MUL_FACTOR;
+ textFont.SetPointSize(static_cast<int>(size));
+ x = rect.x;
+ int sub_height = static_cast<int>(static_cast<double>(charHeight) / wxSCRIPT_MUL_FACTOR);
+ y = rect.y + (rect.height - sub_height + (descent - m_descent));
+ }
wxCheckSetFont(dc, textFont);
}
else
|| (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_SUBSCRIPT) ) )
{
wxFont textFont = font;
- double size = static_cast<double>(textFont.GetPointSize()) / wxSCRIPT_MUL_FACTOR;
- textFont.SetPointSize( static_cast<int>(size) );
+ if (textFont.IsUsingSizeInPixels())
+ {
+ double size = static_cast<double>(textFont.GetPixelSize().y) / wxSCRIPT_MUL_FACTOR;
+ textFont.SetPixelSize(wxSize(0, static_cast<int>(size)));
+ }
+ else
+ {
+ double size = static_cast<double>(textFont.GetPointSize()) / wxSCRIPT_MUL_FACTOR;
+ textFont.SetPointSize(static_cast<int>(size));
+ }
+ wxCheckSetFont(dc, textFont);
+ bScript = true;
+ }
+ else if (textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_SMALL_CAPITALS))
+ {
+ wxFont textFont = font;
+ textFont.SetPointSize((int) (textFont.GetPointSize()*0.75));
wxCheckSetFont(dc, textFont);
bScript = true;
}
wxString stringChunk = str.Mid(startPos, (size_t) len);
- if (textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_CAPITALS))
+ if (textAttr.HasTextEffects() && (textAttr.GetTextEffects() & (wxTEXT_ATTR_EFFECT_CAPITALS|wxTEXT_ATTR_EFFECT_SMALL_CAPITALS)))
stringChunk.MakeUpper();
wxCoord w, h;
/// Returns true if this object can merge itself with the given one.
bool wxRichTextPlainText::CanMerge(wxRichTextObject* object) const
{
- return object->GetClassInfo() == CLASSINFO(wxRichTextPlainText) &&
+ return object->GetClassInfo() == wxCLASSINFO(wxRichTextPlainText) &&
(m_text.empty() || (wxTextAttrEq(GetAttributes(), object->GetAttributes()) && m_properties == object->GetProperties()));
}
m_suppressUndo = 0;
m_handlerFlags = 0;
m_scale = 1.0;
+ m_dimensionScale = 1.0;
+ m_fontScale = 1.0;
SetMargins(4);
}
m_batchedCommand = NULL;
m_suppressUndo = obj.m_suppressUndo;
m_invalidRange = obj.m_invalidRange;
+ m_dimensionScale = obj.m_dimensionScale;
+ m_fontScale = obj.m_fontScale;
}
/// Push style sheet to top of stack
}
wxRichTextAttr attr(buffer->GetDefaultStyle());
+ // Don't include box attributes such as margins
+ attr.GetTextBoxAttr().Reset();
wxRichTextParagraph* newPara = new wxRichTextParagraph(wxEmptyString, this, & attr);
action->GetNewParagraphs().AppendChild(newPara);
action->SetPosition(pos);
- // Use the default character style
// Use the default character style
if (!buffer->GetDefaultStyle().IsDefault() && newPara->GetChildren().GetFirst())
{
// Check whether the default style merely reflects the paragraph/basic style,
// in which case don't apply it.
wxRichTextAttr defaultStyle(buffer->GetDefaultStyle());
+ defaultStyle.GetTextBoxAttr().Reset();
wxRichTextAttr toApply;
if (para)
{
wxRichTextAttr attr(buffer->GetDefaultStyle());
+ // Don't include box attributes such as margins
+ attr.GetTextBoxAttr().Reset();
+
wxRichTextParagraph* newPara = new wxRichTextParagraph(this, & attr);
if (p)
newPara->SetAttributes(*p);
wxRichTextAttr attr(buffer->GetDefaultStyle());
+ // Don't include box attributes such as margins
+ attr.GetTextBoxAttr().Reset();
+
wxRichTextParagraph* newPara = new wxRichTextParagraph(this, & attr);
if (p)
newPara->SetAttributes(*p);
wxRichTextAttr attr(buffer->GetDefaultStyle());
+ // Don't include box attributes such as margins
+ attr.GetTextBoxAttr().Reset();
+
wxRichTextParagraph* newPara = new wxRichTextParagraph(this, & attr);
if (p)
newPara->SetAttributes(*p);
bool wxRichTextBuffer::BeginStyle(const wxRichTextAttr& style)
{
wxRichTextAttr newStyle(GetDefaultStyle());
+ newStyle.GetTextBoxAttr().Reset();
// Save the old default style
- m_attributeStack.Append((wxObject*) new wxRichTextAttr(GetDefaultStyle()));
+ m_attributeStack.Append((wxObject*) new wxRichTextAttr(newStyle));
wxRichTextApplyStyle(newStyle, style);
newStyle.SetFlags(style.GetFlags()|newStyle.GetFlags());
}
}
+void wxRichTextBuffer::SetFontScale(double fontScale)
+{
+ m_fontScale = fontScale;
+ m_fontTable.SetFontScale(fontScale);
+}
+
+void wxRichTextBuffer::SetDimensionScale(double dimScale)
+{
+ m_dimensionScale = dimScale;
+}
+
bool wxRichTextStdRenderer::DrawStandardBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxRichTextAttr& bulletAttr, const wxRect& rect)
{
if (bulletAttr.GetTextColour().IsOk())
if ((attr.GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_SYMBOL) && !attr.GetBulletFont().IsEmpty() && attr.HasFont())
{
wxRichTextAttr fontAttr;
- fontAttr.SetFontSize(attr.GetFontSize());
+ if (attr.HasFontPixelSize())
+ fontAttr.SetFontPixelSize(attr.GetFontSize());
+ else
+ fontAttr.SetFontPointSize(attr.GetFontSize());
fontAttr.SetFontStyle(attr.GetFontStyle());
fontAttr.SetFontWeight(attr.GetFontWeight());
fontAttr.SetFontUnderlined(attr.GetFontUnderlined());
{
wxRichTextParagraphLayoutBox::Copy(obj);
- UpdateField();
+ UpdateField(GetBuffer());
}
// Edit properties via a GUI
return wxEmptyString;
}
-bool wxRichTextField::UpdateField()
+bool wxRichTextField::UpdateField(wxRichTextBuffer* buffer)
{
wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
if (fieldType)
- return fieldType->UpdateField((wxRichTextField*) this);
+ return fieldType->UpdateField(buffer, (wxRichTextField*) this);
return false;
}
wxRichTextObjectPropertiesDialog cellDlg(this, wxGetTopLevelParent(parent), wxID_ANY, caption);
cellDlg.SetAttributes(attr);
- wxRichTextSizePage* sizePage = wxDynamicCast(cellDlg.FindPage(CLASSINFO(wxRichTextSizePage)), wxRichTextSizePage);
+ wxRichTextSizePage* sizePage = wxDynamicCast(cellDlg.FindPage(wxCLASSINFO(wxRichTextSizePage)), wxRichTextSizePage);
if (sizePage)
{
// We don't want position and floating controls for a cell.
wxRichTextBuffer::SetRenderer(new wxRichTextStdRenderer);
wxRichTextBuffer::InitStandardHandlers();
wxRichTextParagraph::InitDefaultTabs();
+
+ wxRichTextXMLHandler::RegisterNodeName(wxT("text"), wxT("wxRichTextPlainText"));
+ wxRichTextXMLHandler::RegisterNodeName(wxT("symbol"), wxT("wxRichTextPlainText"));
+ wxRichTextXMLHandler::RegisterNodeName(wxT("image"), wxT("wxRichTextImage"));
+ wxRichTextXMLHandler::RegisterNodeName(wxT("paragraph"), wxT("wxRichTextParagraph"));
+ wxRichTextXMLHandler::RegisterNodeName(wxT("paragraphlayout"), wxT("wxRichTextParagraphLayoutBox"));
+ wxRichTextXMLHandler::RegisterNodeName(wxT("textbox"), wxT("wxRichTextBox"));
+ wxRichTextXMLHandler::RegisterNodeName(wxT("cell"), wxT("wxRichTextCell"));
+ wxRichTextXMLHandler::RegisterNodeName(wxT("table"), wxT("wxRichTextTable"));
+ wxRichTextXMLHandler::RegisterNodeName(wxT("field"), wxT("wxRichTextField"));
+
return true;
}
void OnExit()
wxRichTextBuffer::CleanUpHandlers();
wxRichTextBuffer::CleanUpDrawingHandlers();
wxRichTextBuffer::CleanUpFieldTypes();
+ wxRichTextXMLHandler::ClearNodeToClassMap();
wxRichTextDecimalToRoman(-1);
wxRichTextParagraph::ClearDefaultTabs();
wxRichTextCtrl::ClearAvailableFontNames();
// first, but of course this means we'll be doing it twice.
if (!m_buffer->IsDirty() && m_ctrl) // can only do optimisation if the buffer is already laid out correctly
{
- wxSize clientSize = m_ctrl->GetClientSize();
- wxPoint firstVisiblePt = m_ctrl->GetFirstVisiblePoint();
+ wxSize clientSize = m_ctrl->GetUnscaledSize(m_ctrl->GetClientSize());
+ wxPoint firstVisiblePt = m_ctrl->GetUnscaledPoint(m_ctrl->GetFirstVisiblePoint());
int lastY = firstVisiblePt.y + clientSize.y;
wxRichTextParagraph* para = container->GetParagraphAtPosition(GetRange().GetStart());
{
size_t i;
- wxSize clientSize = m_ctrl->GetClientSize();
- wxPoint firstVisiblePt = m_ctrl->GetFirstVisiblePoint();
+ wxSize clientSize = m_ctrl->GetUnscaledSize(m_ctrl->GetClientSize());
+ wxPoint firstVisiblePt = m_ctrl->GetUnscaledPoint(m_ctrl->GetFirstVisiblePoint());
// Start/end positions
int firstY = 0;
lastY = firstVisiblePt.y + clientSize.y;
// Convert to device coordinates
- wxRect rect(m_ctrl->GetPhysicalPoint(wxPoint(firstVisiblePt.x, firstY)), wxSize(clientSize.x, lastY - firstY));
+ wxRect rect(m_ctrl->GetPhysicalPoint(m_ctrl->GetScaledPoint(wxPoint(firstVisiblePt.x, firstY))), m_ctrl->GetScaledSize(wxSize(clientSize.x, lastY - firstY)));
m_ctrl->RefreshRect(rect);
}
else
return (attr1 == attr2);
}
-// Partial equality test taking flags into account
-bool wxTextAttrEqPartial(const wxRichTextAttr& attr1, const wxRichTextAttr& attr2)
-{
- return attr1.EqPartial(attr2);
-}
-
/// Compare tabs
bool wxRichTextTabsEq(const wxArrayInt& tabs1, const wxArrayInt& tabs2)
{
public:
wxRichTextFontTableData() {}
- wxFont FindFont(const wxRichTextAttr& fontSpec);
+ wxFont FindFont(const wxRichTextAttr& fontSpec, double fontScale);
wxRichTextFontTableHashMap m_hashMap;
};
-wxFont wxRichTextFontTableData::FindFont(const wxRichTextAttr& fontSpec)
+wxFont wxRichTextFontTableData::FindFont(const wxRichTextAttr& fontSpec, double fontScale)
{
wxString facename(fontSpec.GetFontFaceName());
- wxString spec(wxString::Format(wxT("%d-%d-%d-%d-%s-%d"), fontSpec.GetFontSize(), fontSpec.GetFontStyle(), fontSpec.GetFontWeight(), (int) fontSpec.GetFontUnderlined(), facename.c_str(), (int) fontSpec.GetFontEncoding()));
- wxRichTextFontTableHashMap::iterator entry = m_hashMap.find(spec);
+ int fontSize = fontSpec.GetFontSize();
+ if (fontScale != 1.0)
+ fontSize = (int) ((double(fontSize) * fontScale) + 0.5);
+
+ wxString units;
+ if (fontSpec.HasFontPixelSize() && !fontSpec.HasFontPointSize())
+ units = wxT("px");
+ else
+ units = wxT("pt");
+ wxString spec = wxString::Format(wxT("%d-%s-%d-%d-%d-%d-%s-%d"),
+ fontSize, units.c_str(), fontSpec.GetFontStyle(), fontSpec.GetFontWeight(), (int) fontSpec.GetFontUnderlined(), (int) fontSpec.GetFontStrikethrough(),
+ facename.c_str(), (int) fontSpec.GetFontEncoding());
+
+ wxRichTextFontTableHashMap::iterator entry = m_hashMap.find(spec);
if ( entry == m_hashMap.end() )
{
- wxFont font(fontSpec.GetFontSize(), wxDEFAULT, fontSpec.GetFontStyle(), fontSpec.GetFontWeight(), fontSpec.GetFontUnderlined(), facename.c_str());
- m_hashMap[spec] = font;
- return font;
+ if (fontSpec.HasFontPixelSize() && !fontSpec.HasFontPointSize())
+ {
+ wxFont font(wxSize(0, fontSize), wxFONTFAMILY_DEFAULT, fontSpec.GetFontStyle(), fontSpec.GetFontWeight(), fontSpec.GetFontUnderlined(), facename);
+ if (fontSpec.HasFontStrikethrough() && fontSpec.GetFontStrikethrough())
+ font.SetStrikethrough(true);
+ m_hashMap[spec] = font;
+ return font;
+ }
+ else
+ {
+ wxFont font(fontSize, wxFONTFAMILY_DEFAULT, fontSpec.GetFontStyle(), fontSpec.GetFontWeight(), fontSpec.GetFontUnderlined(), facename.c_str());
+ if (fontSpec.HasFontStrikethrough() && fontSpec.GetFontStrikethrough())
+ font.SetStrikethrough(true);
+
+ m_hashMap[spec] = font;
+ return font;
+ }
}
else
{
wxRichTextFontTable::wxRichTextFontTable()
{
m_refData = new wxRichTextFontTableData;
+ m_fontScale = 1.0;
}
wxRichTextFontTable::wxRichTextFontTable(const wxRichTextFontTable& table)
void wxRichTextFontTable::operator= (const wxRichTextFontTable& table)
{
Ref(table);
+ m_fontScale = table.m_fontScale;
}
wxFont wxRichTextFontTable::FindFont(const wxRichTextAttr& fontSpec)
{
wxRichTextFontTableData* data = (wxRichTextFontTableData*) m_refData;
if (data)
- return data->FindFont(fontSpec);
+ return data->FindFont(fontSpec, m_fontScale);
else
return wxFont();
}
data->m_hashMap.clear();
}
+void wxRichTextFontTable::SetFontScale(double fontScale)
+{
+ if (fontScale != m_fontScale)
+ Clear();
+ m_fontScale = fontScale;
+}
+
// wxTextBoxAttr
void wxTextBoxAttr::Reset()
}
// Partial equality test
-bool wxTextBoxAttr::EqPartial(const wxTextBoxAttr& attr) const
+bool wxTextBoxAttr::EqPartial(const wxTextBoxAttr& attr, bool weakTest) const
{
+ if (!weakTest &&
+ ((!HasFloatMode() && attr.HasFloatMode()) ||
+ (!HasClearMode() && attr.HasClearMode()) ||
+ (!HasCollapseBorders() && attr.HasCollapseBorders()) ||
+ (!HasVerticalAlignment() && attr.HasVerticalAlignment()) ||
+ (!HasBoxStyleName() && attr.HasBoxStyleName())))
+ {
+ return false;
+ }
if (attr.HasFloatMode() && HasFloatMode() && (GetFloatMode() != attr.GetFloatMode()))
return false;
// Position
- if (!m_position.EqPartial(attr.m_position))
+ if (!m_position.EqPartial(attr.m_position, weakTest))
return false;
// Size
- if (!m_size.EqPartial(attr.m_size))
+ if (!m_size.EqPartial(attr.m_size, weakTest))
return false;
- if (!m_minSize.EqPartial(attr.m_minSize))
+ if (!m_minSize.EqPartial(attr.m_minSize, weakTest))
return false;
- if (!m_maxSize.EqPartial(attr.m_maxSize))
+ if (!m_maxSize.EqPartial(attr.m_maxSize, weakTest))
return false;
// Margins
- if (!m_margins.EqPartial(attr.m_margins))
+ if (!m_margins.EqPartial(attr.m_margins, weakTest))
return false;
// Padding
- if (!m_padding.EqPartial(attr.m_padding))
+ if (!m_padding.EqPartial(attr.m_padding, weakTest))
return false;
// Border
- if (!GetBorder().EqPartial(attr.GetBorder()))
+ if (!GetBorder().EqPartial(attr.GetBorder(), weakTest))
return false;
// Outline
- if (!GetOutline().EqPartial(attr.GetOutline()))
+ if (!GetOutline().EqPartial(attr.GetOutline(), weakTest))
return false;
return true;
return (m_textBoxAttr == attr.m_textBoxAttr);
}
-// Partial equality test taking comparison object into account
-bool wxRichTextAttr::EqPartial(const wxRichTextAttr& attr) const
+// Partial equality test
+bool wxRichTextAttr::EqPartial(const wxRichTextAttr& attr, bool weakTest) const
{
- if (!(wxTextAttr::EqPartial(attr)))
+ if (!(wxTextAttr::EqPartial(attr, weakTest)))
return false;
- return m_textBoxAttr.EqPartial(attr.m_textBoxAttr);
+ return m_textBoxAttr.EqPartial(attr.m_textBoxAttr, weakTest);
}
// Merges the given attributes. If compareWith
}
// Partial equality test
-bool wxTextAttrBorder::EqPartial(const wxTextAttrBorder& border) const
+bool wxTextAttrBorder::EqPartial(const wxTextAttrBorder& border, bool weakTest) const
{
- if (border.HasStyle() && !HasStyle() && (border.GetStyle() != GetStyle()))
+ if (!weakTest &&
+ ((!HasStyle() && border.HasStyle()) ||
+ (!HasColour() && border.HasColour()) ||
+ (!HasWidth() && border.HasWidth())))
+ {
return false;
+ }
- if (border.HasColour() && !HasColour() && (border.GetColourLong() != GetColourLong()))
+ if (border.HasStyle() && HasStyle() && (border.GetStyle() != GetStyle()))
return false;
- if (border.HasWidth() && !HasWidth() && !(border.GetWidth() == GetWidth()))
+ if (border.HasColour() && HasColour() && (border.GetColourLong() != GetColourLong()))
+ return false;
+
+ if (border.HasWidth() && HasWidth() && !(border.GetWidth() == GetWidth()))
return false;
return true;
}
// Partial equality test
-bool wxTextAttrBorders::EqPartial(const wxTextAttrBorders& borders) const
+bool wxTextAttrBorders::EqPartial(const wxTextAttrBorders& borders, bool weakTest) const
{
- return m_left.EqPartial(borders.m_left) && m_right.EqPartial(borders.m_right) &&
- m_top.EqPartial(borders.m_top) && m_bottom.EqPartial(borders.m_bottom);
+ return m_left.EqPartial(borders.m_left, weakTest) && m_right.EqPartial(borders.m_right, weakTest) &&
+ m_top.EqPartial(borders.m_top, weakTest) && m_bottom.EqPartial(borders.m_bottom, weakTest);
}
// Apply border to 'this', but not if the same as compareWith
}
// Partial equality test
-bool wxTextAttrDimension::EqPartial(const wxTextAttrDimension& dim) const
+bool wxTextAttrDimension::EqPartial(const wxTextAttrDimension& dim, bool weakTest) const
{
+ if (!weakTest && !IsValid() && dim.IsValid())
+ return false;
+
if (dim.IsValid() && IsValid() && !((*this) == dim))
return false;
else
}
// Partial equality test
-bool wxTextAttrDimensions::EqPartial(const wxTextAttrDimensions& dims) const
+bool wxTextAttrDimensions::EqPartial(const wxTextAttrDimensions& dims, bool weakTest) const
{
- if (!m_left.EqPartial(dims.m_left))
+ if (!m_left.EqPartial(dims.m_left, weakTest))
return false;
- if (!m_right.EqPartial(dims.m_right))
+ if (!m_right.EqPartial(dims.m_right, weakTest))
return false;
- if (!m_top.EqPartial(dims.m_top))
+ if (!m_top.EqPartial(dims.m_top, weakTest))
return false;
- if (!m_bottom.EqPartial(dims.m_bottom))
+ if (!m_bottom.EqPartial(dims.m_bottom, weakTest))
return false;
return true;
}
// Partial equality test
-bool wxTextAttrSize::EqPartial(const wxTextAttrSize& size) const
+bool wxTextAttrSize::EqPartial(const wxTextAttrSize& size, bool weakTest) const
{
- if (!m_width.EqPartial(size.m_width))
+ if (!m_width.EqPartial(size.m_width, weakTest))
return false;
- if (!m_height.EqPartial(size.m_height))
+ if (!m_height.EqPartial(size.m_height, weakTest))
return false;
return true;
if (attr.HasFont())
{
- if (attr.HasFontSize() && !wxHasStyle(forbiddenFlags, wxTEXT_ATTR_FONT_SIZE))
+ // If different font size units are being used, this is a clash.
+ if (((attr.GetFlags() & wxTEXT_ATTR_FONT_SIZE) | (currentStyle.GetFlags() & wxTEXT_ATTR_FONT_SIZE)) == wxTEXT_ATTR_FONT_SIZE)
{
- if (currentStyle.HasFontSize())
+ currentStyle.SetFontSize(0);
+ currentStyle.RemoveFlag(wxTEXT_ATTR_FONT_SIZE);
+ clashingAttr.AddFlag(wxTEXT_ATTR_FONT_SIZE);
+ }
+ else
+ {
+ if (attr.HasFontPointSize() && !wxHasStyle(forbiddenFlags, wxTEXT_ATTR_FONT_POINT_SIZE))
{
- if (currentStyle.GetFontSize() != attr.GetFontSize())
+ if (currentStyle.HasFontPointSize())
{
- // Clash of attr - mark as such
- clashingAttr.AddFlag(wxTEXT_ATTR_FONT_SIZE);
- currentStyle.RemoveFlag(wxTEXT_ATTR_FONT_SIZE);
+ if (currentStyle.GetFontSize() != attr.GetFontSize())
+ {
+ // Clash of attr - mark as such
+ clashingAttr.AddFlag(wxTEXT_ATTR_FONT_POINT_SIZE);
+ currentStyle.RemoveFlag(wxTEXT_ATTR_FONT_POINT_SIZE);
+ }
}
+ else
+ currentStyle.SetFontSize(attr.GetFontSize());
+ }
+
+ if (attr.HasFontPixelSize() && !wxHasStyle(forbiddenFlags, wxTEXT_ATTR_FONT_PIXEL_SIZE))
+ {
+ if (currentStyle.HasFontPixelSize())
+ {
+ if (currentStyle.GetFontSize() != attr.GetFontSize())
+ {
+ // Clash of attr - mark as such
+ clashingAttr.AddFlag(wxTEXT_ATTR_FONT_PIXEL_SIZE);
+ currentStyle.RemoveFlag(wxTEXT_ATTR_FONT_PIXEL_SIZE);
+ }
+ }
+ else
+ currentStyle.SetFontPixelSize(attr.GetFontSize());
}
- else
- currentStyle.SetFontSize(attr.GetFontSize());
}
if (attr.HasFontItalic() && !wxHasStyle(forbiddenFlags, wxTEXT_ATTR_FONT_ITALIC))
else
currentStyle.SetFontUnderlined(attr.GetFontUnderlined());
}
+
+ if (attr.HasFontStrikethrough() && !wxHasStyle(forbiddenFlags, wxTEXT_ATTR_FONT_STRIKETHROUGH))
+ {
+ if (currentStyle.HasFontStrikethrough())
+ {
+ if (currentStyle.GetFontStrikethrough() != attr.GetFontStrikethrough())
+ {
+ // Clash of attr - mark as such
+ clashingAttr.AddFlag(wxTEXT_ATTR_FONT_STRIKETHROUGH);
+ currentStyle.RemoveFlag(wxTEXT_ATTR_FONT_STRIKETHROUGH);
+ }
+ }
+ else
+ currentStyle.SetFontStrikethrough(attr.GetFontStrikethrough());
+ }
}
if (attr.HasTextColour() && !wxHasStyle(forbiddenFlags, wxTEXT_ATTR_TEXT_COLOUR))