+wxHtmlCell::~wxHtmlCell()
+{
+ delete m_Link;
+}
+
+// Update the descent value when whe are in a <sub> or <sup>.
+// prevbase is the parent base
+void wxHtmlCell::SetScriptMode(wxHtmlScriptMode mode, long previousBase)
+{
+ m_ScriptMode = mode;
+
+ if (mode == wxHTML_SCRIPT_SUP)
+ m_ScriptBaseline = previousBase - (m_Height + 1) / 2;
+ else if (mode == wxHTML_SCRIPT_SUB)
+ m_ScriptBaseline = previousBase + (m_Height + 1) / 6;
+ else
+ m_ScriptBaseline = 0;
+
+ m_Descent += m_ScriptBaseline;
+}
+
+#if WXWIN_COMPATIBILITY_2_6
+
+struct wxHtmlCellOnMouseClickCompatHelper;
+
+static wxHtmlCellOnMouseClickCompatHelper *gs_helperOnMouseClick = NULL;
+
+// helper for routing calls to new ProcessMouseClick() method to deprecated
+// OnMouseClick() method
+struct wxHtmlCellOnMouseClickCompatHelper
+{
+ wxHtmlCellOnMouseClickCompatHelper(wxHtmlWindowInterface *window_,
+ const wxPoint& pos_,
+ const wxMouseEvent& event_)
+ : window(window_), pos(pos_), event(event_), retval(false)
+ {
+ }
+
+ bool CallOnMouseClick(wxHtmlCell *cell)
+ {
+ wxHtmlCellOnMouseClickCompatHelper *oldHelper = gs_helperOnMouseClick;
+ gs_helperOnMouseClick = this;
+ cell->OnMouseClick
+ (
+ window ? window->GetHTMLWindow() : NULL,
+ pos.x, pos.y,
+ event
+ );
+ gs_helperOnMouseClick = oldHelper;
+ return retval;
+ }
+
+ wxHtmlWindowInterface *window;
+ const wxPoint& pos;
+ const wxMouseEvent& event;
+ bool retval;
+};
+#endif // WXWIN_COMPATIBILITY_2_6
+
+bool wxHtmlCell::ProcessMouseClick(wxHtmlWindowInterface *window,
+ const wxPoint& pos,
+ const wxMouseEvent& event)
+{
+ wxCHECK_MSG( window, false, wxT("window interface must be provided") );
+
+#if WXWIN_COMPATIBILITY_2_6
+ // NB: this hack puts the body of ProcessMouseClick() into OnMouseClick()
+ // (for which it has to pass the arguments and return value via a
+ // helper variable because these two methods have different
+ // signatures), so that old code overriding OnMouseClick will continue
+ // to work
+ wxHtmlCellOnMouseClickCompatHelper compat(window, pos, event);
+ return compat.CallOnMouseClick(this);
+}
+
+void wxHtmlCell::OnMouseClick(wxWindow *, int, int, const wxMouseEvent& event)
+{
+ wxCHECK_RET( gs_helperOnMouseClick, wxT("unexpected call to OnMouseClick") );
+ wxHtmlWindowInterface *window = gs_helperOnMouseClick->window;
+ const wxPoint& pos = gs_helperOnMouseClick->pos;
+#endif // WXWIN_COMPATIBILITY_2_6
+
+ wxHtmlLinkInfo *lnk = GetLink(pos.x, pos.y);
+ bool retval = false;
+
+ if (lnk)
+ {
+ wxHtmlLinkInfo lnk2(*lnk);
+ lnk2.SetEvent(&event);
+ lnk2.SetHtmlCell(this);
+
+ window->OnHTMLLinkClicked(lnk2);
+ retval = true;
+ }
+
+#if WXWIN_COMPATIBILITY_2_6
+ gs_helperOnMouseClick->retval = retval;
+#else
+ return retval;
+#endif // WXWIN_COMPATIBILITY_2_6
+}
+
+#if WXWIN_COMPATIBILITY_2_6
+wxCursor wxHtmlCell::GetCursor() const
+{
+ return wxNullCursor;
+}
+#endif // WXWIN_COMPATIBILITY_2_6
+
+wxCursor
+wxHtmlCell::GetMouseCursor(wxHtmlWindowInterface* WXUNUSED(window)) const
+{
+ // This is never called directly, only from GetMouseCursorAt() and we
+ // return an invalid cursor by default to let it delegate to the window.
+ return wxNullCursor;
+}
+
+wxCursor
+wxHtmlCell::GetMouseCursorAt(wxHtmlWindowInterface *window,
+ const wxPoint& relPos) const
+{
+#if WXWIN_COMPATIBILITY_2_6
+ // NB: Older versions of wx used GetCursor() virtual method in place of
+ // GetMouseCursor(interface). This code ensures that user code that
+ // overridden GetCursor() continues to work. The trick is that the base
+ // wxHtmlCell::GetCursor() method simply returns wxNullCursor, so we
+ // know that GetCursor() was overridden iff it returns valid cursor.
+ wxCursor cur = GetCursor();
+ if (cur.IsOk())
+ return cur;
+#endif // WXWIN_COMPATIBILITY_2_6
+
+ const wxCursor curCell = GetMouseCursor(window);
+ if ( curCell.IsOk() )
+ return curCell;
+
+ if ( GetLink(relPos.x, relPos.y) )
+ {
+ return window->GetHTMLCursor(wxHtmlWindowInterface::HTMLCursor_Link);
+ }
+ else
+ {
+ return window->GetHTMLCursor(wxHtmlWindowInterface::HTMLCursor_Default);
+ }
+}
+
+
+bool
+wxHtmlCell::AdjustPagebreak(int *pagebreak,
+ const wxArrayInt& WXUNUSED(known_pagebreaks),
+ int pageHeight) const
+{
+ // Notice that we always break the cells bigger than the page height here
+ // as otherwise we wouldn't be able to break them at all.
+ if ( m_Height <= pageHeight &&
+ (!m_CanLiveOnPagebreak &&
+ m_PosY < *pagebreak && m_PosY + m_Height > *pagebreak) )
+ {
+ *pagebreak = m_PosY;
+ return true;
+ }
+
+ return false;
+}
+
+
+
+void wxHtmlCell::SetLink(const wxHtmlLinkInfo& link)
+{
+ wxDELETE(m_Link);
+ if (link.GetHref() != wxEmptyString)
+ m_Link = new wxHtmlLinkInfo(link);
+}
+
+
+void wxHtmlCell::Layout(int WXUNUSED(w))
+{
+ SetPos(0, 0);
+}
+
+
+
+const wxHtmlCell* wxHtmlCell::Find(int WXUNUSED(condition), const void* WXUNUSED(param)) const
+{
+ return NULL;
+}
+
+
+wxHtmlCell *wxHtmlCell::FindCellByPos(wxCoord x, wxCoord y,
+ unsigned flags) const
+{
+ if ( x >= 0 && x < m_Width && y >= 0 && y < m_Height )
+ {
+ return wxConstCast(this, wxHtmlCell);
+ }
+ else
+ {
+ if ((flags & wxHTML_FIND_NEAREST_AFTER) &&
+ (y < 0 || (y < 0+m_Height && x < 0+m_Width)))
+ return wxConstCast(this, wxHtmlCell);
+ else if ((flags & wxHTML_FIND_NEAREST_BEFORE) &&
+ (y >= 0+m_Height || (y >= 0 && x >= 0)))
+ return wxConstCast(this, wxHtmlCell);
+ else
+ return NULL;
+ }
+}
+
+
+wxPoint wxHtmlCell::GetAbsPos(wxHtmlCell *rootCell) const
+{
+ wxPoint p(m_PosX, m_PosY);
+ for (wxHtmlCell *parent = m_Parent; parent && parent != rootCell;
+ parent = parent->m_Parent)
+ {
+ p.x += parent->m_PosX;
+ p.y += parent->m_PosY;
+ }
+ return p;
+}
+
+wxHtmlCell *wxHtmlCell::GetRootCell() const
+{
+ wxHtmlCell *c = wxConstCast(this, wxHtmlCell);
+ while ( c->m_Parent )
+ c = c->m_Parent;
+ return c;
+}
+
+unsigned wxHtmlCell::GetDepth() const
+{
+ unsigned d = 0;
+ for (wxHtmlCell *p = m_Parent; p; p = p->m_Parent)
+ d++;
+ return d;
+}
+
+bool wxHtmlCell::IsBefore(wxHtmlCell *cell) const
+{
+ const wxHtmlCell *c1 = this;
+ const wxHtmlCell *c2 = cell;
+ unsigned d1 = GetDepth();
+ unsigned d2 = cell->GetDepth();
+
+ if ( d1 > d2 )
+ for (; d1 != d2; d1-- )
+ c1 = c1->m_Parent;
+ else if ( d1 < d2 )
+ for (; d1 != d2; d2-- )
+ c2 = c2->m_Parent;
+
+ if ( cell == this )
+ return true;
+
+ while ( c1 && c2 )
+ {
+ if ( c1->m_Parent == c2->m_Parent )
+ {
+ while ( c1 )
+ {
+ if ( c1 == c2 )
+ return true;
+ c1 = c1->GetNext();
+ }
+ return false;
+ }
+ else
+ {
+ c1 = c1->m_Parent;
+ c2 = c2->m_Parent;
+ }
+ }
+
+ wxFAIL_MSG(wxT("Cells are in different trees"));
+ return false;
+}