File indexing completed on 2024-11-10 09:38:51
0001 /* 0002 * This file is part of the html renderer for KDE. 0003 * 0004 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) 0005 * Copyright (C) 2003 Apple Computer, Inc. 0006 * 0007 * This library is free software; you can redistribute it and/or 0008 * modify it under the terms of the GNU Library General Public 0009 * License as published by the Free Software Foundation; either 0010 * version 2 of the License, or (at your option) any later version. 0011 * 0012 * This library is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 * Library General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU Library General Public License 0018 * along with this library; see the file COPYING.LIB. If not, write to 0019 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 * Boston, MA 02110-1301, USA. 0021 * 0022 */ 0023 #ifndef BIDI_H 0024 #define BIDI_H 0025 0026 #include <QString> 0027 #include "rendering/render_object.h" 0028 0029 namespace khtml 0030 { 0031 class RenderArena; 0032 class RenderObject; 0033 class InlineBox; 0034 0035 class BidiContext 0036 { 0037 public: 0038 BidiContext(unsigned char level, QChar::Direction embedding, BidiContext *parent = nullptr, bool override = false); 0039 ~BidiContext(); 0040 0041 void ref() const; 0042 void deref() const; 0043 0044 unsigned char level; 0045 bool override : 1; 0046 QChar::Direction dir : 5; 0047 QChar::Direction basicDir : 5; 0048 0049 BidiContext *parent; 0050 0051 // refcounting.... 0052 mutable int count; 0053 }; 0054 0055 struct BidiRun { 0056 BidiRun(int _start, int _stop, RenderObject *_obj, BidiContext *context, QChar::Direction dir) 0057 : start(_start), stop(_stop), obj(_obj), box(nullptr), nextRun(nullptr) 0058 { 0059 if (dir == QChar::DirON) { 0060 dir = context->dir; 0061 } 0062 0063 level = context->level; 0064 0065 // add level of run (cases I1 & I2) 0066 if (level % 2) { 0067 if (dir == QChar::DirL || dir == QChar::DirAN || dir == QChar::DirEN) { 0068 level++; 0069 } 0070 } else { 0071 if (dir == QChar::DirR) { 0072 level++; 0073 } else if (dir == QChar::DirAN || dir == QChar::DirEN) { 0074 level += 2; 0075 } 0076 } 0077 } 0078 0079 void detach(RenderArena *renderArena); 0080 0081 // Overloaded new operator. 0082 void *operator new(size_t sz, RenderArena *renderArena) throw(); 0083 0084 // Overridden to prevent the normal delete from being called. 0085 void operator delete(void *ptr, size_t sz); 0086 0087 private: 0088 // The normal operator new is disallowed. 0089 void *operator new(size_t sz) throw(); 0090 0091 public: 0092 int start; 0093 int stop; 0094 0095 RenderObject *obj; 0096 InlineBox *box; 0097 0098 // explicit + implicit levels here 0099 uchar level; 0100 0101 bool compact : 1; 0102 0103 BidiRun *nextRun; 0104 }; 0105 0106 struct BidiIterator; 0107 struct BidiState; 0108 0109 struct BidiStatus { 0110 BidiStatus() : eor(QChar::DirON), lastStrong(QChar::DirON), last(QChar::DirON) {} 0111 0112 QChar::Direction eor; 0113 QChar::Direction lastStrong; 0114 QChar::Direction last; 0115 }; 0116 0117 struct InlineMinMaxIterator { 0118 /* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to 0119 inline min/max width calculations. Note the following about the way it walks: 0120 (1) Positioned content is skipped (since it does not contribute to min/max width of a block) 0121 (2) We do not drill into the children of floats or replaced elements, since you can't break 0122 in the middle of such an element. 0123 (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have 0124 distinct borders/margin/padding that contribute to the min/max width. 0125 */ 0126 RenderObject *parent; 0127 RenderObject *current; 0128 bool endOfInline; 0129 bool skipPositioned; 0130 InlineMinMaxIterator(RenderObject *p, RenderObject *o, bool eOI = false, bool skipPos = true) 0131 : parent(p), current(o), endOfInline(eOI), skipPositioned(skipPos) {} 0132 inline RenderObject *next(); 0133 }; 0134 0135 inline RenderObject *InlineMinMaxIterator::next() 0136 { 0137 RenderObject *result = nullptr; 0138 bool oldEndOfInline = endOfInline; 0139 endOfInline = false; 0140 while (current != nullptr || (current == parent)) { 0141 //qCDebug(KHTML_LOG) << "current = " << current; 0142 if (!oldEndOfInline && 0143 (current == parent || 0144 (!current->isFloating() && !current->isReplaced() && !current->isPositioned()))) { 0145 result = current->firstChild(); 0146 } 0147 if (!result) { 0148 // We hit the end of our inline. (It was empty, e.g., <span></span>.) 0149 if (!oldEndOfInline && current->isInlineFlow()) { 0150 result = current; 0151 endOfInline = true; 0152 break; 0153 } 0154 while (current && current != parent) { 0155 result = current->nextSibling(); 0156 if (result) { 0157 break; 0158 } 0159 current = current->parent(); 0160 if (current && current != parent && current->isInlineFlow()) { 0161 result = current; 0162 endOfInline = true; 0163 break; 0164 } 0165 } 0166 } 0167 0168 if (!result) { 0169 break; 0170 } 0171 0172 if ((!skipPositioned || !result->isPositioned()) && (result->isText() || result->isBR() || 0173 result->isFloatingOrPositioned() || result->isReplaced() || result->isGlyph() || result->isInlineFlow())) { 0174 break; 0175 } 0176 0177 current = result; 0178 result = nullptr; 0179 } 0180 0181 // Update our position. 0182 current = result; 0183 return current; 0184 } 0185 } 0186 0187 #endif