⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 khtml_caret.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    while (n) { r = n; n = n->firstChild(); }    return const_cast<NodeImpl *>(r);  }/*end if*/  n = r->previousSibling();  if (n) {    r = n;    while (n) { r = n; n = n->firstChild(); }    return const_cast<NodeImpl *>(r);  }/*end if*/  n = r->parentNode();  if (n == baseElem) n = 0;  while (n) {    r = n;    n = r->previousSibling();    if (n) {      r = n;      n = r->lastChild();      while (n) { r = n; n = n->lastChild(); }      return const_cast<NodeImpl *>(r);    }/*end if*/    n = r->parentNode();    if (n == baseElem) n = 0;  }/*wend*/  return 0;}#endif/** Maps a DOM Range position to the corresponding caret position. * * The offset boundary is not checked for validity. * @param node DOM node * @param offset zero-based offset within node * @param r returns render object (may be 0 if DOM node has no render object) * @param r_ofs returns the appropriate offset for the found render object r * @param outside returns true when offset is applied to the outside of *	\c r, or false for the inside. * @param outsideEnd return true when the caret position is at the outside end. */void /*KDE_NO_EXPORT*/ mapDOMPosToRenderPos(NodeImpl *node, long offset,		RenderObject *&r, long &r_ofs, bool &outside, bool &outsideEnd){  if (node->nodeType() == Node::TEXT_NODE) {    outside = false;    outsideEnd = false;    r = node->renderer();    r_ofs = offset;  } else if (node->nodeType() == Node::ELEMENT_NODE || node->nodeType() == Node::DOCUMENT_NODE) {    // Though offset points between two children, attach it to the visually    // most suitable one (and only there, because the mapping must stay bijective)    if (node->firstChild()) {      outside = true;      NodeImpl *child = offset <= 0 ? node->firstChild()      				// childNode is expensive      				: node->childNode((unsigned long)offset);      // index was child count or out of bounds      bool atEnd = !child;#if DEBUG_CARETMODE > 5      kdDebug(6200) << "mapDTR: child " << child << "@" << (child ? child->nodeName().string() : QString::null) << " atEnd " << atEnd << endl;#endif      if (atEnd) child = node->lastChild();      r = child->renderer();      r_ofs = 0;      outsideEnd = atEnd;      // Outside text nodes most likely stem from a continuation. Seek      // the enclosing continued render object and use this one instead.      if (r && child->nodeType() == Node::TEXT_NODE) {        r = r->parent();        RenderObject *o = node->renderer();	while (o->continuation() && o->continuation() != r)	  o = o->continuation();	if (!r || o->continuation() != r) {	  r = child->renderer();	}      }/*end if*/      // BRs cause troubles. Returns the previous render object instead,      // giving it the attributes outside, outside end.      if (r && r->isBR()) {        r = r->objectAbove();        outsideEnd = true;      }/*end if*/    } else {      // Element has no children, treat offset to be inside the node.      outside = false;      outsideEnd = false;      r = node->renderer();      r_ofs = 0;	// only offset 0 possible    }  } else {    r = 0;    kdWarning() << k_funcinfo << "Mapping from nodes of type " << node->nodeType()        << " not supported!" << endl;  }}/** Maps a caret position to the corresponding DOM Range position. * * @param r render object * @param r_ofs offset within render object * @param outside true when offset is interpreted to be on the outside of *	\c r, or false if on the inside. * @param outsideEnd true when the caret position is at the outside end. * @param node returns DOM node * @param offset returns zero-based offset within node */void /*KDE_NO_EXPORT*/ mapRenderPosToDOMPos(RenderObject *r, long r_ofs,		bool outside, bool outsideEnd, NodeImpl *&node, long &offset){  node = r->element();  Q_ASSERT(node);#if DEBUG_CARETMODE > 5      kdDebug(6200) << "mapRTD: r " << r << "@" << (r ? r->renderName() : QString::null) << (r && r->element() ? QString(".node ") + QString::number((unsigned)r->element(),16) + "@" + r->element()->nodeName().string() : QString::null) << " outside " << outside << " outsideEnd " << outsideEnd << endl;#endif  if (node->nodeType() == Node::ELEMENT_NODE || node->nodeType() == Node::TEXT_NODE) {    if (outside) {      NodeImpl *parent = node->parent();      // If this is part of a continuation, use the actual node as the parent,      // and the first render child as the node.      if (r != node->renderer()) {        RenderObject *o = node->renderer();	while (o->continuation() && o->continuation() != r)	  o = o->continuation();	if (o->continuation() == r) {	  parent = node;	  // ### What if the first render child does not map to a child of	  // the continued node?	  node = r->firstChild() ? r->firstChild()->element() : node;	}      }/*end if*/      if (!parent) goto inside;      offset = (long)node->nodeIndex() + outsideEnd;      node = parent;#if DEBUG_CARETMODE > 5   kdDebug(6200) << node << "@" << (node ? node->nodeName().string() : QString::null) << " offset " << offset << endl;#endif    } else {	// !outsideinside:      offset = r_ofs;    }  } else {    offset = 0;    kdWarning() << k_funcinfo << "Mapping to nodes of type " << node->nodeType()        << " not supported!" << endl;  }}/** Make sure the given node is a leaf node. */static inline void ensureLeafNode(NodeImpl *&node, NodeImpl *base){  if (node && node->hasChildNodes()) node = nextLeafNode(node, base);}/** Converts a caret position to its respective object traversal state. * @param outside whether the caret is outside the object * @param atEnd whether the caret position is at the end * @param toBegin \c true when advancing towards the beginning * @param trav returns the corresponding traversal state */static inline void mapRenderPosToTraversalState(bool outside, bool atEnd,		bool toBegin, ObjectTraversalState &trav){  if (!outside) atEnd = !toBegin;  if (!atEnd ^ toBegin)    trav = outside ? OutsideDescending : InsideDescending;  else    trav = outside ? OutsideAscending : InsideAscending;}/** Converts a traversal state to its respective caret position * @param trav object traversal state * @param toBegin \c true when advancing towards the beginning * @param outside whether the caret is outside the object * @param atEnd whether the caret position is at the end */static inline void mapTraversalStateToRenderPos(ObjectTraversalState trav,		bool toBegin, bool &outside, bool &atEnd){  outside = false;  switch (trav) {    case OutsideDescending: outside = true; // fall through    case InsideDescending: atEnd = toBegin; break;    case OutsideAscending: outside = true; // fall through    case InsideAscending: atEnd = !toBegin; break;  }}/** Finds the next node that has a renderer. * * Note that if the initial @p node has a renderer, this will be returned, * regardless of the caret advance policy. * Otherwise, for the next nodes, only leaf nodes are considered. * @param node node to start with, will be updated accordingly * @param offset offset of caret within \c node * @param base base render object which this method must not advance beyond *	(0 means document) * @param r_ofs return the caret offset within the returned renderer * @param outside returns whether offset is to be interpreted to the outside  *	(true) or the inside (false) of the render object. * @param outsideEnd returns whether the end of the outside position is meant * @return renderer or 0 if no following node has a renderer. */static RenderObject* findRenderer(NodeImpl *&node, long offset,			RenderObject *base, long &r_ofs,                        bool &outside, bool &outsideEnd){  if (!node) return 0;  RenderObject *r;  mapDOMPosToRenderPos(node, offset, r, r_ofs, outside, outsideEnd);#if DEBUG_CARETMODE > 2   kdDebug(6200) << "findRenderer: node " << node << " " << (node ? node->nodeName().string() : QString::null) << " offset " << offset << " r " << r << "[" << (r ? r->renderName() : QString::null) << "] r_ofs " << r_ofs << " outside " << outside << " outsideEnd " << outsideEnd << endl;#endif  if (r) return r;  NodeImpl *baseElem = base ? base->element() : 0;  while (!r) {    node = nextLeafNode(node, baseElem);    if (!node) break;    r = node->renderer();    if (r) r_ofs = offset;  }#if DEBUG_CARETMODE > 3  kdDebug(6200) << "1r " << r << endl;#endif  ObjectTraversalState trav;  int state;		// not used  mapRenderPosToTraversalState(outside, outsideEnd, false, trav);  if (r && isUnsuitable(r, trav)) {    r = advanceSuitableObject(r, trav, false, base, state);    mapTraversalStateToRenderPos(trav, false, outside, outsideEnd);    if (r) r_ofs = r->minOffset();  }#if DEBUG_CARETMODE > 3  kdDebug(6200) << "2r " << r << endl;#endif  return r;}/** returns a suitable base element * @param caretNode current node containing caret. */static ElementImpl *determineBaseElement(NodeImpl *caretNode){  // ### for now, only body is delivered for html documents,  // and 0 for xml documents.  DocumentImpl *doc = caretNode->getDocument();  if (!doc) return 0;	// should not happen, but who knows.  if (doc->isHTMLDocument())    return static_cast<HTMLDocumentImpl *>(doc)->body();  return 0;}// == class CaretBox implementation#if DEBUG_CARETMODE > 0void CaretBox::dump(QTextStream &ts, const QString &ind) const{  ts << ind << "b@" << _box;  if (_box) {    ts << "<" << _box->object() << ":" << _box->object()->renderName() << ">";  }/*end if*/  ts << " " << _x << "+" << _y << "+" << _w << "*" << _h;  ts << " cb@" << cb;  if (cb) ts << ":" << cb->renderName();  ts << " " << (_outside ? (outside_end ? "oe" : "o-") : "i-");//  ts << endl;}#endif// == class CaretBoxLine implementation#if DEBUG_CARETMODE > 0#  define DEBUG_ACIB 1#else#  define DEBUG_ACIB DEBUG_CARETMODE#endifvoid CaretBoxLine::addConvertedInlineBox(InlineBox *box, SeekBoxParams &sbp) /*KDE_NO_EXPORT*/{  // Generate only one outside caret box between two elements. If  // coalesceOutsideBoxes is true, generating left outside boxes is inhibited.  bool coalesceOutsideBoxes = false;  CaretBoxIterator lastCoalescedBox;  for (; box; box = box->nextOnLine()) {#if DEBUG_ACIBkdDebug(6200) << "box " << box << endl;kdDebug(6200) << "box->object " << box->object() << endl;kdDebug(6200) << "x " << box->m_x << " y " << box->m_y << " w " << box->m_width << " h " << box->m_height << " baseline " << box->m_baseline << " ifb " << box->isInlineFlowBox() << " itb " << box->isInlineTextBox() << " rlb " << box->isRootInlineBox() << endl;#endif    // ### Why the hell can object() ever be 0?!    if (!box->object()) continue;    RenderStyle *s = box->object()->style(box->m_firstLine);    // parent style for outside caret boxes    RenderStyle *ps = box->parent() && box->parent()->object()    		? box->parent()->object()->style(box->parent()->m_firstLine)		: s;    if (box->isInlineFlowBox()) {#if DEBUG_ACIBkdDebug(6200) << "isinlineflowbox " << box << endl;#endif      InlineFlowBox *flowBox = static_cast<InlineFlowBox *>(box);      bool rtl = ps->direction() == RTL;      const QFontMetrics &pfm = ps->fontMetrics();      if (flowBox->includeLeftEdge()) {        // If this box is to be coalesced with the outside end box of its        // predecessor, then check if it is the searched box. If it is, we        // substitute the outside end box.        if (coalesceOutsideBoxes) {          if (sbp.equalsBox(flowBox, true, false)) {            sbp.it = lastCoalescedBox;            Q_ASSERT(!sbp.found);            sbp.found = true;          }        } else {          addCreatedFlowBoxEdge(flowBox, pfm, true, rtl);          sbp.check(preEnd());        }      }/*end if*/      if (flowBox->firstChild()) {#if DEBUG_ACIBkdDebug(6200) << "this " << this << " flowBox " << flowBox << " firstChild " << flowBox->firstChild() << endl;kdDebug(6200) << "== recursive invocation" << endl;#endif        addConvertedInlineBox(flowBox->firstChild(), sbp);#if DEBUG_ACIBkdDebug(6200) << "== recursive invocation end" << endl;#endif}      else {        addCreatedFlowBoxInside(flowBox, s->fontMetrics());        sbp.check(preEnd());      }      if (flowBox->includeRightEdge()) {        addCreatedFlowBoxEdge(flowBox, pfm, false, rtl);        lastCoalescedBox = preEnd();        sbp.check(lastCoalescedBox);        coalesceOutsideBoxes = true;      }    } else if (box->isInlineTextBox()) {#if DEBUG_ACIBkdDebug(6200) << "isinlinetextbox " << box << (box->object() ? QString(" contains \"%1\"").arg(QConstString(static_cast<RenderText *>(box->object())->str->s+box->minOffset(), kMin(box->maxOffset() - box->minOffset(), 15L)).string()) : QString::null) << endl;#endif      caret_boxes.append(new CaretBox(box, false, false));      sbp.check(preEnd());      // coalescing has been interrupted      coalesceOutsideBoxes = false;    } else {#if DEBUG_ACIBkdDebug(6200) << "some replaced or what " << box << endl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -