Value * TextSelection::GetPropertyValue (DependencyProperty *formatting) const { Value *value = start.GetParent()->GetValue (formatting); Value *current_value; DocumentWalker walker (start.GetParentNode(), DocumentWalker::Forward); walker.Step ();// skip the ::Leave for the start node while (true) { IDocumentNode *node; DocumentWalker::StepType step = walker.Step (&node); switch (step) { case DocumentWalker::Enter: current_value = node->AsDependencyObject()->GetValue (formatting); if (!Value::AreEqual (value, current_value)) return NULL; if (node == end.GetParentNode()) return value; case DocumentWalker::Leave: break; case DocumentWalker::Done: // this shouldn't happen, but do we care? g_warning ("TextSelecion::GetPropertyValue document walker found the end of the document before finding the selection end."); break; return NULL; } } }
TextPointer TextPointer::GetPositionInsideRun (int offset) const { DependencyObject *parent = GetParent (); if (parent == NULL) return *this; if (offset > 0) { if (parent->Is(Type::RUN)) { int location = ResolveLocation (); const char *text = ((Run*)parent)->GetText(); if ((guint)location < strlen (text)) return GetPositionAtOffset_np (1, LogicalDirectionForward); } // we're at the end of the run (or not in a run at all). we need to walk the document until we hit another run. DocumentWalker walker (IDocumentNode::CastToIDocumentNode (parent), DocumentWalker::Forward); walker.Step (); while (true) { IDocumentNode *node; DocumentWalker::StepType type = walker.Step (&node); switch (type) { case DocumentWalker::Done: // there is no position beyond this return *this; case DocumentWalker::Enter: if (node->AsDependencyObject()->Is(Type::RUN)) return ((Run*)node->AsDependencyObject())->GetContentStart_np(); break; case DocumentWalker::Leave: // do nothing here break; } } } else { if (parent->Is(Type::RUN)) { int location = ResolveLocation (); if (location > 0) return GetPositionAtOffset_np (-1, LogicalDirectionForward); } // we're at the start of the run (or not in a run at all). we need to walk the document until we hit another run. DocumentWalker walker (IDocumentNode::CastToIDocumentNode (parent), DocumentWalker::Backward); walker.Step (); while (true) { IDocumentNode *node; DocumentWalker::StepType type = walker.Step (&node); switch (type) { case DocumentWalker::Done: // there is no position before this return *this; case DocumentWalker::Enter: if (node->AsDependencyObject()->Is(Type::RUN)) return ((Run*)node->AsDependencyObject())->GetContentEnd_np(); break; case DocumentWalker::Leave: // do nothing here break; } } } return *this; }