From dfe289850f068f19ba4a83ab4e7e22a7e09c13c9 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sat, 26 Jan 2013 13:17:21 -0600 Subject: Rename a number of libraries and executables to avoid conflicts with KDE4 --- khtml/rendering/CMakeLists.txt | 46 - khtml/rendering/Makefile.am | 57 - khtml/rendering/bidi.cpp | 2250 ------------------------ khtml/rendering/bidi.h | 172 -- khtml/rendering/break_lines.cpp | 126 -- khtml/rendering/break_lines.h | 163 -- khtml/rendering/counter_tree.cpp | 222 --- khtml/rendering/counter_tree.h | 114 -- khtml/rendering/enumerate.cpp | 411 ----- khtml/rendering/enumerate.h | 66 - khtml/rendering/font.cpp | 502 ------ khtml/rendering/font.h | 188 -- khtml/rendering/img-loading.png | Bin 318 -> 0 bytes khtml/rendering/loading_icon.cpp | 25 - khtml/rendering/render_applet.cpp | 145 -- khtml/rendering/render_applet.h | 60 - khtml/rendering/render_arena.cpp | 146 -- khtml/rendering/render_arena.h | 72 - khtml/rendering/render_block.cpp | 3155 ---------------------------------- khtml/rendering/render_block.h | 378 ---- khtml/rendering/render_body.cpp | 121 -- khtml/rendering/render_body.h | 56 - khtml/rendering/render_box.cpp | 2325 ------------------------- khtml/rendering/render_box.h | 213 --- khtml/rendering/render_br.cpp | 79 - khtml/rendering/render_br.h | 77 - khtml/rendering/render_canvas.cpp | 780 --------- khtml/rendering/render_canvas.h | 250 --- khtml/rendering/render_container.cpp | 597 ------- khtml/rendering/render_container.h | 85 - khtml/rendering/render_flow.cpp | 412 ----- khtml/rendering/render_flow.h | 96 -- khtml/rendering/render_form.cpp | 1914 --------------------- khtml/rendering/render_form.h | 511 ------ khtml/rendering/render_frames.cpp | 1025 ----------- khtml/rendering/render_frames.h | 172 -- khtml/rendering/render_generated.cpp | 392 ----- khtml/rendering/render_generated.h | 125 -- khtml/rendering/render_image.cpp | 604 ------- khtml/rendering/render_image.h | 105 -- khtml/rendering/render_inline.cpp | 935 ---------- khtml/rendering/render_inline.h | 94 - khtml/rendering/render_layer.cpp | 1830 -------------------- khtml/rendering/render_layer.h | 342 ---- khtml/rendering/render_line.cpp | 996 ----------- khtml/rendering/render_line.h | 310 ---- khtml/rendering/render_list.cpp | 586 ------- khtml/rendering/render_list.h | 140 -- khtml/rendering/render_object.cpp | 2330 ------------------------- khtml/rendering/render_object.h | 866 ---------- khtml/rendering/render_replaced.cpp | 940 ---------- khtml/rendering/render_replaced.h | 169 -- khtml/rendering/render_style.cpp | 1301 -------------- khtml/rendering/render_style.h | 1524 ---------------- khtml/rendering/render_table.cpp | 3070 --------------------------------- khtml/rendering/render_table.h | 524 ------ khtml/rendering/render_text.cpp | 1546 ----------------- khtml/rendering/render_text.h | 345 ---- khtml/rendering/table_layout.cpp | 1193 ------------- khtml/rendering/table_layout.h | 112 -- khtml/rendering/table_layout.txt | 74 - 61 files changed, 37464 deletions(-) delete mode 100644 khtml/rendering/CMakeLists.txt delete mode 100644 khtml/rendering/Makefile.am delete mode 100644 khtml/rendering/bidi.cpp delete mode 100644 khtml/rendering/bidi.h delete mode 100644 khtml/rendering/break_lines.cpp delete mode 100644 khtml/rendering/break_lines.h delete mode 100644 khtml/rendering/counter_tree.cpp delete mode 100644 khtml/rendering/counter_tree.h delete mode 100644 khtml/rendering/enumerate.cpp delete mode 100644 khtml/rendering/enumerate.h delete mode 100644 khtml/rendering/font.cpp delete mode 100644 khtml/rendering/font.h delete mode 100644 khtml/rendering/img-loading.png delete mode 100644 khtml/rendering/loading_icon.cpp delete mode 100644 khtml/rendering/render_applet.cpp delete mode 100644 khtml/rendering/render_applet.h delete mode 100644 khtml/rendering/render_arena.cpp delete mode 100644 khtml/rendering/render_arena.h delete mode 100644 khtml/rendering/render_block.cpp delete mode 100644 khtml/rendering/render_block.h delete mode 100644 khtml/rendering/render_body.cpp delete mode 100644 khtml/rendering/render_body.h delete mode 100644 khtml/rendering/render_box.cpp delete mode 100644 khtml/rendering/render_box.h delete mode 100644 khtml/rendering/render_br.cpp delete mode 100644 khtml/rendering/render_br.h delete mode 100644 khtml/rendering/render_canvas.cpp delete mode 100644 khtml/rendering/render_canvas.h delete mode 100644 khtml/rendering/render_container.cpp delete mode 100644 khtml/rendering/render_container.h delete mode 100644 khtml/rendering/render_flow.cpp delete mode 100644 khtml/rendering/render_flow.h delete mode 100644 khtml/rendering/render_form.cpp delete mode 100644 khtml/rendering/render_form.h delete mode 100644 khtml/rendering/render_frames.cpp delete mode 100644 khtml/rendering/render_frames.h delete mode 100644 khtml/rendering/render_generated.cpp delete mode 100644 khtml/rendering/render_generated.h delete mode 100644 khtml/rendering/render_image.cpp delete mode 100644 khtml/rendering/render_image.h delete mode 100644 khtml/rendering/render_inline.cpp delete mode 100644 khtml/rendering/render_inline.h delete mode 100644 khtml/rendering/render_layer.cpp delete mode 100644 khtml/rendering/render_layer.h delete mode 100644 khtml/rendering/render_line.cpp delete mode 100644 khtml/rendering/render_line.h delete mode 100644 khtml/rendering/render_list.cpp delete mode 100644 khtml/rendering/render_list.h delete mode 100644 khtml/rendering/render_object.cpp delete mode 100644 khtml/rendering/render_object.h delete mode 100644 khtml/rendering/render_replaced.cpp delete mode 100644 khtml/rendering/render_replaced.h delete mode 100644 khtml/rendering/render_style.cpp delete mode 100644 khtml/rendering/render_style.h delete mode 100644 khtml/rendering/render_table.cpp delete mode 100644 khtml/rendering/render_table.h delete mode 100644 khtml/rendering/render_text.cpp delete mode 100644 khtml/rendering/render_text.h delete mode 100644 khtml/rendering/table_layout.cpp delete mode 100644 khtml/rendering/table_layout.h delete mode 100644 khtml/rendering/table_layout.txt (limited to 'khtml/rendering') diff --git a/khtml/rendering/CMakeLists.txt b/khtml/rendering/CMakeLists.txt deleted file mode 100644 index fe3301265..000000000 --- a/khtml/rendering/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -################################################# -# -# (C) 2010 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -include_directories( - ${TQT_INCLUDE_DIRS} - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_BINARY_DIR}/tdecore - ${CMAKE_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/khtml - ${CMAKE_SOURCE_DIR}/tdecore - ${CMAKE_SOURCE_DIR}/tdeui - ${CMAKE_SOURCE_DIR}/kio - ${CMAKE_SOURCE_DIR}/kio/kio - ${CMAKE_SOURCE_DIR}/kio/kfile - ${CMAKE_SOURCE_DIR}/kutils -) - - -##### khtmlrender-static ######################### - -set( target khtmlrender ) - -set( ${target}_SRCS - bidi.cpp break_lines.cpp render_block.cpp render_inline.cpp - render_style.cpp render_object.cpp render_container.cpp render_box.cpp - render_flow.cpp render_text.cpp render_arena.cpp render_layer.cpp - render_image.cpp render_table.cpp table_layout.cpp - render_replaced.cpp render_form.cpp render_list.cpp - render_canvas.cpp render_frames.cpp render_br.cpp - render_body.cpp font.cpp render_line.cpp render_generated.cpp - enumerate.cpp counter_tree.cpp -) - -tde_add_library( ${target} STATIC_PIC AUTOMOC - SOURCES ${${target}_SRCS} -) diff --git a/khtml/rendering/Makefile.am b/khtml/rendering/Makefile.am deleted file mode 100644 index d41638f27..000000000 --- a/khtml/rendering/Makefile.am +++ /dev/null @@ -1,57 +0,0 @@ -# This file is part of the KDE libraries -# Copyright (C) 1997 Martin Jones (mjones@kde.org) -# (C) 1997 Torben Weis (weis@kde.org) - -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Library General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. - -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. - -# You should have received a copy of the GNU Library General Public License -# along with this library; see the file COPYING.LIB. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -# Boston, MA 02110-1301, USA. - -KDE_CXXFLAGS = $(WOVERLOADED_VIRTUAL) - -noinst_LTLIBRARIES = libkhtmlrender.la -libkhtmlrender_la_SOURCES = \ - bidi.cpp break_lines.cpp render_block.cpp render_inline.cpp \ - render_style.cpp render_object.cpp render_container.cpp render_box.cpp \ - render_flow.cpp render_text.cpp render_arena.cpp render_layer.cpp \ - render_image.cpp render_table.cpp table_layout.cpp \ - render_replaced.cpp render_form.cpp render_list.cpp \ - render_canvas.cpp render_frames.cpp render_br.cpp \ - render_body.cpp font.cpp render_line.cpp render_generated.cpp \ - enumerate.cpp counter_tree.cpp - -libkhtmlrender_la_METASOURCES = AUTO - -noinst_HEADERS = \ - bidi.h break_lines.h \ - render_arena.h render_layer.h \ - render_style.h render_object.h render_container.h render_box.h \ - render_flow.h render_text.h render_table.h render_replaced.h \ - render_form.h render_list.h render_canvas.h render_frames.h \ - render_br.h render_applet.h font.h table_layout.h render_line.h \ - render_generated.h enumerate.h - -INCLUDES = -I$(top_srcdir)/kimgio -I$(top_srcdir)/kio -I$(top_srcdir)/dcop \ - -I$(top_srcdir)/kfile -I$(top_srcdir)/khtml -I$(top_srcdir)/kutils -I$(top_srcdir) $(all_includes) - -SRCDOC_DEST=$(kde_htmldir)/en/tdelibs/khtml - -## generate lib documentation -srcdoc: - $(mkinstalldirs) $(SRCDOC_DEST) - kdoc -H -d $(SRCDOC_DEST) tdecore -lqt - -## maintainer: regen loading icon -loading-icon: - bin2c -sploading_icon $(srcdir)/img-loading.png > $(srcdir)/loading_icon.cpp - diff --git a/khtml/rendering/bidi.cpp b/khtml/rendering/bidi.cpp deleted file mode 100644 index 2dcfe48c9..000000000 --- a/khtml/rendering/bidi.cpp +++ /dev/null @@ -1,2250 +0,0 @@ -/** - * This file is part of the html renderer for KDE. - * - * Copyright (C) 2000-2003 Lars Knoll (knoll@kde.org) - * (C) 2003-2005 Apple Computer, Inc. - * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#include "rendering/bidi.h" -#include "rendering/break_lines.h" -#include "rendering/render_block.h" -#include "rendering/render_text.h" -#include "rendering/render_arena.h" -#include "rendering/render_layer.h" -#include "rendering/render_canvas.h" -#include "xml/dom_docimpl.h" - -#include "kdebug.h" -#include "tqdatetime.h" -#include "tqfontmetrics.h" - -#define BIDI_DEBUG 0 -//#define DEBUG_LINEBREAKS -//#define PAGE_DEBUG - -namespace khtml { - - -// an iterator which goes through a BidiParagraph -struct BidiIterator -{ - BidiIterator() : par(0), obj(0), pos(0), endOfInline(0) {} - BidiIterator(RenderBlock *_par, RenderObject *_obj, unsigned int _pos, bool eoi=false) : par(_par), obj(_obj), pos(_pos), endOfInline(eoi) {} - - void increment( BidiState &bidi, bool skipInlines=true ); - - bool atEnd() const; - - const TQChar ¤t() const; - TQChar::Direction direction() const; - - RenderBlock *par; - RenderObject *obj; - unsigned int pos; - bool endOfInline; -}; - - -struct BidiStatus { - BidiStatus() : eor(TQChar::DirON), lastStrong(TQChar::DirON), last(TQChar::DirON) {} - - TQChar::Direction eor; - TQChar::Direction lastStrong; - TQChar::Direction last; -}; - -struct BidiState { - BidiState() : context(0) {} - - BidiIterator sor; - BidiIterator eor; - BidiIterator last; - BidiIterator current; - BidiContext *context; - BidiStatus status; -}; - -// Used to track a list of chained bidi runs. -static BidiRun* sFirstBidiRun; -static BidiRun* sLastBidiRun; -static int sBidiRunCount; -static BidiRun* sCompactFirstBidiRun; -static BidiRun* sCompactLastBidiRun; -static int sCompactBidiRunCount; -static bool sBuildingCompactRuns; - -// Midpoint globals. The goal is not to do any allocation when dealing with -// these midpoints, so we just keep an array around and never clear it. We track -// the number of items and position using the two other variables. -static TQMemArray *smidpoints; -static uint sNumMidpoints; -static uint sCurrMidpoint; -static bool betweenMidpoints; - -static bool isLineEmpty = true; -static bool previousLineBrokeAtBR = true; -static TQChar::Direction dir; -static bool adjustEmbedding; -static bool emptyRun = true; -static int numSpaces; - -static void embed( TQChar::Direction d, BidiState &bidi ); -static void appendRun( BidiState &bidi ); - -static int getBPMWidth(int childValue, Length cssUnit) -{ - if (!cssUnit.isVariable()) - return (cssUnit.isFixed() ? cssUnit.value() : childValue); - return 0; -} - -static int getBorderPaddingMargin(RenderObject* child, bool endOfInline) -{ - RenderStyle* cstyle = child->style(); - int result = 0; - bool leftSide = (cstyle->direction() == LTR) ? !endOfInline : endOfInline; - result += getBPMWidth((leftSide ? child->marginLeft() : child->marginRight()), - (leftSide ? cstyle->marginLeft() : - cstyle->marginRight())); - result += getBPMWidth((leftSide ? child->paddingLeft() : child->paddingRight()), - (leftSide ? cstyle->paddingLeft() : - cstyle->paddingRight())); - result += leftSide ? child->borderLeft() : child->borderRight(); - return result; -} - -#ifndef NDEBUG -static bool inBidiRunDetach; -#endif - -void BidiRun::detach(RenderArena* renderArena) -{ -#ifndef NDEBUG - inBidiRunDetach = true; -#endif - delete this; -#ifndef NDEBUG - inBidiRunDetach = false; -#endif - - // Recover the size left there for us by operator delete and free the memory. - renderArena->free(*(size_t *)this, this); -} - -void* BidiRun::operator new(size_t sz, RenderArena* renderArena) throw() -{ - return renderArena->allocate(sz); -} - -void BidiRun::operator delete(void* ptr, size_t sz) -{ - assert(inBidiRunDetach); - - // Stash size where detach can find it. - *(size_t*)ptr = sz; -} - -static void deleteBidiRuns(RenderArena* arena) -{ - if (!sFirstBidiRun) - return; - - BidiRun* curr = sFirstBidiRun; - while (curr) { - BidiRun* s = curr->nextRun; - curr->detach(arena); - curr = s; - } - - sFirstBidiRun = 0; - sLastBidiRun = 0; - sBidiRunCount = 0; -} - -// --------------------------------------------------------------------- - -/* a small helper class used internally to resolve Bidi embedding levels. - Each line of text caches the embedding level at the start of the line for faster - relayouting -*/ -BidiContext::BidiContext(unsigned char l, TQChar::Direction e, BidiContext *p, bool o) - : level(l) , override(o), dir(e) -{ - parent = p; - if(p) { - p->ref(); - basicDir = p->basicDir; - } else - basicDir = e; - count = 0; -} - -BidiContext::~BidiContext() -{ - if(parent) parent->deref(); -} - -void BidiContext::ref() const -{ - count++; -} - -void BidiContext::deref() const -{ - count--; - if(count <= 0) delete this; -} - -// --------------------------------------------------------------------- - -inline bool operator==( const BidiIterator &it1, const BidiIterator &it2 ) -{ - if(it1.pos != it2.pos) return false; - if(it1.obj != it2.obj) return false; - return true; -} - -inline bool operator!=( const BidiIterator &it1, const BidiIterator &it2 ) -{ - if(it1.pos != it2.pos) return true; - if(it1.obj != it2.obj) return true; - return false; -} - -// when modifying this function, make sure you check InlineMinMaxIterator::next() as well. -static inline RenderObject *Bidinext(RenderObject *par, RenderObject *current, BidiState &bidi, - bool skipInlines = true, bool *endOfInline = 0 ) -{ - RenderObject *next = 0; - bool oldEndOfInline = endOfInline ? *endOfInline : false; - if (oldEndOfInline) - *endOfInline = false; - - while(current != 0) - { - //kdDebug( 6040 ) << "current = " << current << endl; - if (!oldEndOfInline && !current->isFloating() && !current->isReplaced() && !current->isPositioned()) { - next = current->firstChild(); - if ( next && adjustEmbedding ) { - EUnicodeBidi ub = next->style()->unicodeBidi(); - if ( ub != UBNormal && !emptyRun ) { - EDirection dir = next->style()->direction(); - TQChar::Direction d = ( ub == Embed ? ( dir == RTL ? TQChar::DirRLE : TQChar::DirLRE ) - : ( dir == RTL ? TQChar::DirRLO : TQChar::DirLRO ) ); - embed( d, bidi ); - } - } - } - if (!next) { - if (!skipInlines && !oldEndOfInline && current->isInlineFlow() && endOfInline) { - next = current; - *endOfInline = true; - break; - } - - while (current && current != par) { - next = current->nextSibling(); - if (next) break; - if ( adjustEmbedding && current->style()->unicodeBidi() != UBNormal && !emptyRun ) { - embed( TQChar::DirPDF, bidi ); - } - current = current->parent(); - if (!skipInlines && current && current != par && current->isInlineFlow() && endOfInline) { - next = current; - *endOfInline = true; - break; - } - } - } - - if (!next) break; - - if (next->isText() || next->isBR() || next->isFloating() || next->isReplaced() || next->isPositioned() || next->isGlyph() - || ((!skipInlines || !next->firstChild()) // Always return EMPTY inlines. - && next->isInlineFlow())) - break; - current = next; - } - return next; -} - -static RenderObject *first( RenderObject *par, BidiState &bidi, bool skipInlines = true ) -{ - if(!par->firstChild()) return 0; - RenderObject *o = par->firstChild(); - - if (o->isInlineFlow()) { - if (skipInlines && o->firstChild()) - o = Bidinext( par, o, bidi, skipInlines ); - else - return o; // Never skip empty inlines. - } - - if (o && !o->isText() && !o->isBR() && !o->isReplaced() && !o->isFloating() && !o->isPositioned() && !o->isGlyph()) - o = Bidinext( par, o, bidi, skipInlines ); - return o; -} - -inline void BidiIterator::increment (BidiState &bidi, bool skipInlines) -{ - if(!obj) return; - if(obj->isText()) { - pos++; - if(pos >= static_cast(obj)->stringLength()) { - obj = Bidinext( par, obj, bidi, skipInlines ); - pos = 0; - } - } else { - obj = Bidinext( par, obj, bidi, skipInlines, &endOfInline ); - pos = 0; - } -} - -inline bool BidiIterator::atEnd() const -{ - if(!obj) return true; - return false; -} - -const TQChar &BidiIterator::current() const -{ - static TQChar nonBreakingSpace(0xA0); - - if (!obj || !obj->isText()) - return nonBreakingSpace; - - RenderText* text = static_cast(obj); - if (!text->text()) - return nonBreakingSpace; - - return text->text()[pos]; -} - -inline TQChar::Direction BidiIterator::direction() const -{ - if(!obj || !obj->isText() ) return TQChar::DirON; - - RenderText *renderTxt = static_cast( obj ); - if ( pos >= renderTxt->stringLength() ) - return TQChar::DirON; - return renderTxt->text()[pos].direction(); -} - -// ------------------------------------------------------------------------------------------------- - -static void addRun(BidiRun* bidiRun) -{ - if (!sFirstBidiRun) - sFirstBidiRun = sLastBidiRun = bidiRun; - else { - sLastBidiRun->nextRun = bidiRun; - sLastBidiRun = bidiRun; - } - sBidiRunCount++; - bidiRun->compact = sBuildingCompactRuns; - - // Compute the number of spaces in this run, - if (bidiRun->obj && bidiRun->obj->isText()) { - RenderText* text = static_cast(bidiRun->obj); - if (text->text()) { - for (int i = bidiRun->start; i < bidiRun->stop; i++) { - const TQChar c = text->text()[i]; - if (c.category() == TQChar::Separator_Space || c == '\n') - numSpaces++; - } - } - } -} - -static void reverseRuns(int start, int end) -{ - if (start >= end) - return; - - assert(start >= 0 && end < sBidiRunCount); - - // Get the item before the start of the runs to reverse and put it in - // |beforeStart|. |curr| should point to the first run to reverse. - BidiRun* curr = sFirstBidiRun; - BidiRun* beforeStart = 0; - int i = 0; - while (i < start) { - i++; - beforeStart = curr; - curr = curr->nextRun; - } - - BidiRun* startRun = curr; - while (i < end) { - i++; - curr = curr->nextRun; - } - BidiRun* endRun = curr; - BidiRun* afterEnd = curr->nextRun; - - i = start; - curr = startRun; - BidiRun* newNext = afterEnd; - while (i <= end) { - // Do the reversal. - BidiRun* next = curr->nextRun; - curr->nextRun = newNext; - newNext = curr; - curr = next; - i++; - } - - // Now hook up beforeStart and afterEnd to the newStart and newEnd. - if (beforeStart) - beforeStart->nextRun = endRun; - else - sFirstBidiRun = endRun; - - startRun->nextRun = afterEnd; - if (!afterEnd) - sLastBidiRun = startRun; -} - -static void chopMidpointsAt(RenderObject* obj, uint pos) -{ - if (!sNumMidpoints) return; - BidiIterator* midpoints = smidpoints->data(); - for (uint i = 0; i < sNumMidpoints; i++) { - const BidiIterator& point = midpoints[i]; - if (point.obj == obj && point.pos == pos) { - sNumMidpoints = i; - break; - } - } -} - -static void checkMidpoints(BidiIterator& lBreak, BidiState &bidi) -{ - // Check to see if our last midpoint is a start point beyond the line break. If so, - // shave it off the list, and shave off a trailing space if the previous end point isn't - // white-space: pre. - if (lBreak.obj && sNumMidpoints && sNumMidpoints%2 == 0) { - BidiIterator* midpoints = smidpoints->data(); - BidiIterator& endpoint = midpoints[sNumMidpoints-2]; - const BidiIterator& startpoint = midpoints[sNumMidpoints-1]; - BidiIterator currpoint = endpoint; - while (!currpoint.atEnd() && currpoint != startpoint && currpoint != lBreak) - currpoint.increment( bidi ); - if (currpoint == lBreak) { - // We hit the line break before the start point. Shave off the start point. - sNumMidpoints--; - if (!endpoint.obj->style()->preserveWS()) { - if (endpoint.obj->isText()) { - // Don't shave a character off the endpoint if it was from a soft hyphen. - RenderText* textObj = static_cast(endpoint.obj); - if (endpoint.pos+1 < textObj->length() && - textObj->text()[endpoint.pos+1].unicode() == SOFT_HYPHEN) - return; - } - endpoint.pos--; - } - } - } -} - -static void addMidpoint(const BidiIterator& midpoint) -{ - if (!smidpoints) - return; - - if (smidpoints->size() <= sNumMidpoints) - smidpoints->resize(sNumMidpoints+10); - - BidiIterator* midpoints = smidpoints->data(); - midpoints[sNumMidpoints++] = midpoint; -} - -static void appendRunsForObject(int start, int end, RenderObject* obj, BidiState &bidi) -{ - if (start > end || obj->isFloating() || - (obj->isPositioned() && !obj->hasStaticX() && !obj->hasStaticY())) - return; - - bool haveNextMidpoint = (smidpoints && sCurrMidpoint < sNumMidpoints); - BidiIterator nextMidpoint; - if (haveNextMidpoint) - nextMidpoint = smidpoints->at(sCurrMidpoint); - if (betweenMidpoints) { - if (!(haveNextMidpoint && nextMidpoint.obj == obj)) - return; - // This is a new start point. Stop ignoring objects and - // adjust our start. - betweenMidpoints = false; - start = nextMidpoint.pos; - sCurrMidpoint++; - if (start < end) - return appendRunsForObject(start, end, obj, bidi); - } - else { - if (!smidpoints || !haveNextMidpoint || (obj != nextMidpoint.obj)) { - addRun(new (obj->renderArena()) BidiRun(start, end, obj, bidi.context, dir)); - return; - } - - // An end midpoint has been encountered within our object. We - // need to go ahead and append a run with our endpoint. - if (int(nextMidpoint.pos+1) <= end) { - betweenMidpoints = true; - sCurrMidpoint++; - if (nextMidpoint.pos != UINT_MAX) { // UINT_MAX means stop at the object and don't include any of it. - addRun(new (obj->renderArena()) - BidiRun(start, nextMidpoint.pos+1, obj, bidi.context, dir)); - return appendRunsForObject(nextMidpoint.pos+1, end, obj, bidi); - } - } - else - addRun(new (obj->renderArena()) BidiRun(start, end, obj, bidi.context, dir)); - } -} - -static void appendRun( BidiState &bidi ) -{ - if ( emptyRun ) return; -#if BIDI_DEBUG > 1 - kdDebug(6041) << "appendRun: dir="<<(int)dir<length(), obj, bidi); - start = 0; - obj = Bidinext( bidi.sor.par, obj, bidi ); - } - if (obj) - appendRunsForObject(start, bidi.eor.pos+1, obj, bidi); - - bidi.eor.increment( bidi ); - bidi.sor = bidi.eor; - dir = TQChar::DirON; - bidi.status.eor = TQChar::DirON; - adjustEmbedding = b; -} - -static void embed( TQChar::Direction d, BidiState &bidi ) -{ -#if BIDI_DEBUG > 1 - tqDebug("*** embed dir=%d emptyrun=%d", d, emptyRun ); -#endif - bool b = adjustEmbedding ; - adjustEmbedding = false; - if ( d == TQChar::DirPDF ) { - BidiContext *c = bidi.context->parent; - if (c) { - if ( bidi.eor != bidi.last ) { - appendRun( bidi ); - bidi.eor = bidi.last; - } - appendRun( bidi ); - emptyRun = true; - bidi.status.last = bidi.context->dir; - bidi.context->deref(); - bidi.context = c; - if(bidi.context->override) - dir = bidi.context->dir; - else - dir = TQChar::DirON; - bidi.status.lastStrong = bidi.context->dir; - } - } else { - TQChar::Direction runDir; - if( d == TQChar::DirRLE || d == TQChar::DirRLO ) - runDir = TQChar::DirR; - else - runDir = TQChar::DirL; - bool override; - if( d == TQChar::DirLRO || d == TQChar::DirRLO ) - override = true; - else - override = false; - - unsigned char level = bidi.context->level; - if ( runDir == TQChar::DirR ) { - if(level%2) // we have an odd level - level += 2; - else - level++; - } else { - if(level%2) // we have an odd level - level++; - else - level += 2; - } - - if(level < 61) { - if ( bidi.eor != bidi.last ) { - appendRun( bidi ); - bidi.eor = bidi.last; - } - appendRun( bidi ); - emptyRun = true; - - bidi.context = new BidiContext(level, runDir, bidi.context, override); - bidi.context->ref(); - dir = runDir; - bidi.status.last = runDir; - bidi.status.lastStrong = runDir; - bidi.status.eor = runDir; - } - } - adjustEmbedding = b; -} - -InlineFlowBox* RenderBlock::createLineBoxes(RenderObject* obj) -{ - // See if we have an unconstructed line box for this object that is also - // the last item on the line. - KHTMLAssert(obj->isInlineFlow() || obj == this); - RenderFlow* flow = static_cast(obj); - - // Get the last box we made for this render object. - InlineFlowBox* box = flow->lastLineBox(); - - // If this box is constructed then it is from a previous line, and we need - // to make a new box for our line. If this box is unconstructed but it has - // something following it on the line, then we know we have to make a new box - // as well. In this situation our inline has actually been split in two on - // the same line (this can happen with very fancy language mixtures). - if (!box || box->isConstructed() || box->nextOnLine()) { - // We need to make a new box for this render object. Once - // made, we need to place it at the end of the current line. - InlineBox* newBox = obj->createInlineBox(false, obj == this); - KHTMLAssert(newBox->isInlineFlowBox()); - box = static_cast(newBox); - box->setFirstLineStyleBit(m_firstLine); - - // We have a new box. Append it to the inline box we get by constructing our - // parent. If we have hit the block itself, then |box| represents the root - // inline box for the line, and it doesn't have to be appended to any parent - // inline. - if (obj != this) { - InlineFlowBox* parentBox = createLineBoxes(obj->parent()); - parentBox->addToLine(box); - } - } - - return box; -} - -InlineFlowBox* RenderBlock::constructLine(const BidiIterator &/*start*/, const BidiIterator &end) -{ - if (!sFirstBidiRun) - return 0; // We had no runs. Don't make a root inline box at all. The line is empty. - - InlineFlowBox* parentBox = 0; - for (BidiRun* r = sFirstBidiRun; r; r = r->nextRun) { - // Create a box for our object. - r->box = r->obj->createInlineBox(r->obj->isPositioned(), false); - - // If we have no parent box yet, or if the run is not simply a sibling, - // then we need to construct inline boxes as necessary to properly enclose the - // run's inline box. - if (!parentBox || (parentBox->object() != r->obj->parent())) - // Create new inline boxes all the way back to the appropriate insertion point. - parentBox = createLineBoxes(r->obj->parent()); - - // Append the inline box to this line. - parentBox->addToLine(r->box); - } - - // We should have a root inline box. It should be unconstructed and - // be the last continuation of our line list. - KHTMLAssert(lastLineBox() && !lastLineBox()->isConstructed()); - - // Set bits on our inline flow boxes that indicate which sides should - // paint borders/margins/padding. This knowledge will ultimately be used when - // we determine the horizontal positions and widths of all the inline boxes on - // the line. - RenderObject* endObject = 0; - bool lastLine = !end.obj; - if (end.obj && end.pos == 0) - endObject = end.obj; - lastLineBox()->determineSpacingForFlowBoxes(lastLine, endObject); - - // Now mark the line boxes as being constructed. - lastLineBox()->setConstructed(); - - // Return the last line. - return lastLineBox(); -} - -void RenderBlock::computeHorizontalPositionsForLine(InlineFlowBox* lineBox, BidiState &bidi) -{ - // First determine our total width. - int totWidth = lineBox->getFlowSpacingWidth(); - BidiRun* r = 0; - for (r = sFirstBidiRun; r; r = r->nextRun) { - if (r->obj->isPositioned()) - continue; // Positioned objects are only participating to figure out their - // correct static x position. They have no effect on the width. - if (r->obj->isText()) - r->box->setWidth(static_cast(r->obj)->width(r->start, r->stop-r->start, m_firstLine)); - else if (!r->obj->isInlineFlow()) { - r->obj->calcWidth(); - r->box->setWidth(r->obj->width()); - totWidth += r->obj->marginLeft() + r->obj->marginRight(); - } - totWidth += r->box->width(); - } - - // Armed with the total width of the line (without justification), - // we now examine our text-align property in order to determine where to position the - // objects horizontally. The total width of the line can be increased if we end up - // justifying text. - int x = leftOffset(m_height); - int availableWidth = lineWidth(m_height); - switch(style()->textAlign()) { - case LEFT: - case KHTML_LEFT: - numSpaces = 0; - break; - case JUSTIFY: - if (numSpaces != 0 && !bidi.current.atEnd() && !bidi.current.obj->isBR() ) - break; - // fall through - case TAAUTO: - numSpaces = 0; - // for right to left fall through to right aligned - if (bidi.context->basicDir == TQChar::DirL) - break; - case RIGHT: - case KHTML_RIGHT: - x += availableWidth - totWidth; - numSpaces = 0; - break; - case CENTER: - case KHTML_CENTER: - int xd = (availableWidth - totWidth)/2; - x += xd >0 ? xd : 0; - numSpaces = 0; - break; - } - - if (numSpaces > 0) { - for (r = sFirstBidiRun; r; r = r->nextRun) { - int spaceAdd = 0; - if (numSpaces > 0 && r->obj->isText()) { - // get the number of spaces in the run - int spaces = 0; - for ( int i = r->start; i < r->stop; i++ ) { - const TQChar c = static_cast(r->obj)->text()[i]; - if (c.category() == TQChar::Separator_Space || c == '\n') - spaces++; - } - - KHTMLAssert(spaces <= numSpaces); - - // Only justify text with white-space: normal. - if (r->obj->style()->whiteSpace() == NORMAL) { - spaceAdd = (availableWidth - totWidth)*spaces/numSpaces; - static_cast(r->box)->setSpaceAdd(spaceAdd); - totWidth += spaceAdd; - } - numSpaces -= spaces; - } - } - } - - // The widths of all runs are now known. We can now place every inline box (and - // compute accurate widths for the inline flow boxes). - int rightPos = lineBox->placeBoxesHorizontally(x); - if (rightPos > m_overflowWidth) - m_overflowWidth = rightPos; // FIXME: Work for rtl overflow also. - if (x < 0) - m_overflowLeft = kMin(m_overflowLeft, x); -} - -void RenderBlock::computeVerticalPositionsForLine(InlineFlowBox* lineBox) -{ - lineBox->verticallyAlignBoxes(m_height); -// lineBox->setBlockHeight(m_height); - - // Check for page-breaks - if (canvas()->pagedMode() && !lineBox->afterPageBreak()) - // If we get a page-break we might need to redo the line-break - if (clearLineOfPageBreaks(lineBox) && hasFloats()) return; - - // See if the line spilled out. If so set overflow height accordingly. - int bottomOfLine = lineBox->bottomOverflow(); - if (bottomOfLine > m_height && bottomOfLine > m_overflowHeight) - m_overflowHeight = bottomOfLine; - - bool beforeContent = true; - - // Now make sure we place replaced render objects correctly. - for (BidiRun* r = sFirstBidiRun; r; r = r->nextRun) { - - // For positioned placeholders, cache the static Y position an object with non-inline display would have. - // Either it is unchanged if it comes before any real linebox, or it must clear the current line (already accounted in m_height). - // This value will be picked up by position() if relevant. - if (r->obj->isPositioned()) - r->box->setYPos( beforeContent && r->obj->isBox() ? static_cast(r->obj)->staticY() : m_height ); - else if (beforeContent) - beforeContent = false; - - // Position is used to properly position both replaced elements and - // to update the static normal flow x/y of positioned elements. - r->obj->position(r->box, r->start, r->stop - r->start, r->level%2); - } -} - -bool RenderBlock::clearLineOfPageBreaks(InlineFlowBox* lineBox) -{ - bool doPageBreak = false; - // Check for physical page-breaks - int xpage = crossesPageBreak(lineBox->topOverflow(), lineBox->bottomOverflow()); - if (xpage) { -#ifdef PAGE_DEBUG - kdDebug(6040) << renderName() << " Line crosses to page " << xpage << endl; - kdDebug(6040) << renderName() << " at pos " << lineBox->yPos() << " height " << lineBox->height() << endl; -#endif - - doPageBreak = true; - // check page-break-inside - if (!style()->pageBreakInside()) { - if (parent()->canClear(this, PageBreakNormal)) { - setNeedsPageClear(true); - doPageBreak = false; - } -#ifdef PAGE_DEBUG - else - kdDebug(6040) << "Ignoring page-break-inside: avoid" << endl; -#endif - } - // check orphans - int orphans = 0; - InlineRunBox* box = lineBox->prevLineBox(); - while (box && orphans < style()->orphans()) { - orphans++; - box = box->prevLineBox(); - } - - if (orphans == 0) { - setNeedsPageClear(true); - doPageBreak = false; - } else - if (orphans < style()->orphans() ) { -#ifdef PAGE_DEBUG - kdDebug(6040) << "Orphans: " << orphans << endl; -#endif - // Orphans is a level 2 page-break rule and can be broken only - // if the break is physically required. - if (parent()->canClear(this, PageBreakHarder)) { - // move block instead - setNeedsPageClear(true); - doPageBreak = false; - } -#ifdef PAGE_DEBUG - else - kdDebug(6040) << "Ignoring violated orphans" << endl; -#endif - } - if (doPageBreak) { - int pTop = pageTopAfter(lineBox->yPos()); - - m_height = pTop; - lineBox->setAfterPageBreak(true); - lineBox->verticallyAlignBoxes(m_height); - if (lineBox->yPos() < pTop) { - // ### serious crap. render_line is sometimes placing lines too high - kdDebug(6040) << "page top overflow by repositioned line" << endl; - int heightIncrease = pTop - lineBox->yPos(); - m_height = pTop + heightIncrease; - lineBox->verticallyAlignBoxes(m_height); - } -#ifdef PAGE_DEBUG - kdDebug(6040) << "Cleared line " << lineBox->yPos() - oldYPos << "px" << endl; -#endif - setContainsPageBreak(true); - } - } - return doPageBreak; -} - -// collects one line of the paragraph and transforms it to visual order -void RenderBlock::bidiReorderLine(const BidiIterator &start, const BidiIterator &end, BidiState &bidi) -{ - if ( start == end ) { - if ( start.current() == '\n' ) { - m_height += lineHeight( m_firstLine ); - } - return; - } - -#if BIDI_DEBUG > 1 - kdDebug(6041) << "reordering Line from " << start.obj << "/" << start.pos << " to " << end.obj << "/" << end.pos << endl; -#endif - - sFirstBidiRun = 0; - sLastBidiRun = 0; - sBidiRunCount = 0; - - // context->ref(); - - dir = TQChar::DirON; - emptyRun = true; - - numSpaces = 0; - - bidi.current = start; - bidi.last = bidi.current; - bool atEnd = false; - while( 1 ) { - - TQChar::Direction dirCurrent; - if (atEnd) { - //kdDebug(6041) << "atEnd" << endl; - BidiContext *c = bidi.context; - if ( bidi.current.atEnd()) - while ( c->parent ) - c = c->parent; - dirCurrent = c->dir; - } else { - dirCurrent = bidi.current.direction(); - } - -#ifndef QT_NO_UNICODETABLES - -#if BIDI_DEBUG > 1 - kdDebug(6041) << "directions: dir=" << (int)dir << " current=" << (int)dirCurrent << " last=" << status.last << " eor=" << status.eor << " lastStrong=" << status.lastStrong << " embedding=" << (int)context->dir << " level =" << (int)context->level << endl; -#endif - - switch(dirCurrent) { - - // embedding and overrides (X1-X9 in the Bidi specs) - case TQChar::DirRLE: - case TQChar::DirLRE: - case TQChar::DirRLO: - case TQChar::DirLRO: - case TQChar::DirPDF: - embed( dirCurrent, bidi ); - break; - - // strong types - case TQChar::DirL: - if(dir == TQChar::DirON) - dir = TQChar::DirL; - switch(bidi.status.last) - { - case TQChar::DirL: - bidi.eor = bidi.current; bidi.status.eor = TQChar::DirL; break; - case TQChar::DirR: - case TQChar::DirAL: - case TQChar::DirEN: - case TQChar::DirAN: - appendRun( bidi ); - break; - case TQChar::DirES: - case TQChar::DirET: - case TQChar::DirCS: - case TQChar::DirBN: - case TQChar::DirB: - case TQChar::DirS: - case TQChar::DirWS: - case TQChar::DirON: - if( bidi.status.eor != TQChar::DirL ) { - //last stuff takes embedding dir - if(bidi.context->dir == TQChar::DirL || bidi.status.lastStrong == TQChar::DirL) { - if ( bidi.status.eor != TQChar::DirEN && bidi.status.eor != TQChar::DirAN && bidi.status.eor != TQChar::DirON ) - appendRun( bidi ); - dir = TQChar::DirL; - bidi.eor = bidi.current; - bidi.status.eor = TQChar::DirL; - } else { - if ( bidi.status.eor == TQChar::DirEN || bidi.status.eor == TQChar::DirAN ) - { - dir = bidi.status.eor; - appendRun( bidi ); - } - dir = TQChar::DirR; - bidi.eor = bidi.last; - appendRun( bidi ); - dir = TQChar::DirL; - bidi.status.eor = TQChar::DirL; - } - } else { - bidi.eor = bidi.current; bidi.status.eor = TQChar::DirL; - } - default: - break; - } - bidi.status.lastStrong = TQChar::DirL; - break; - case TQChar::DirAL: - case TQChar::DirR: - if(dir == TQChar::DirON) dir = TQChar::DirR; - switch(bidi.status.last) - { - case TQChar::DirR: - case TQChar::DirAL: - bidi.eor = bidi.current; bidi.status.eor = TQChar::DirR; break; - case TQChar::DirL: - case TQChar::DirEN: - case TQChar::DirAN: - appendRun( bidi ); - dir = TQChar::DirR; - bidi.eor = bidi.current; - bidi.status.eor = TQChar::DirR; - break; - case TQChar::DirES: - case TQChar::DirET: - case TQChar::DirCS: - case TQChar::DirBN: - case TQChar::DirB: - case TQChar::DirS: - case TQChar::DirWS: - case TQChar::DirON: - if( !(bidi.status.eor == TQChar::DirR) && !(bidi.status.eor == TQChar::DirAL) ) { - //last stuff takes embedding dir - if(bidi.context->dir == TQChar::DirR || bidi.status.lastStrong == TQChar::DirR - || bidi.status.lastStrong == TQChar::DirAL) { - appendRun( bidi ); - dir = TQChar::DirR; - bidi.eor = bidi.current; - bidi.status.eor = TQChar::DirR; - } else { - dir = TQChar::DirL; - bidi.eor = bidi.last; - appendRun( bidi ); - dir = TQChar::DirR; - bidi.status.eor = TQChar::DirR; - } - } else { - bidi.eor = bidi.current; bidi.status.eor = TQChar::DirR; - } - default: - break; - } - bidi.status.lastStrong = dirCurrent; - break; - - // weak types: - - case TQChar::DirNSM: - // ### if @sor, set dir to dirSor - break; - case TQChar::DirEN: - if(!(bidi.status.lastStrong == TQChar::DirAL)) { - // if last strong was AL change EN to AN - if(dir == TQChar::DirON) { - dir = TQChar::DirL; - } - switch(bidi.status.last) - { - case TQChar::DirET: - if ( bidi.status.lastStrong == TQChar::DirR || bidi.status.lastStrong == TQChar::DirAL ) { - appendRun( bidi ); - dir = TQChar::DirEN; - bidi.status.eor = TQChar::DirEN; - } - // fall through - case TQChar::DirEN: - case TQChar::DirL: - bidi.eor = bidi.current; - bidi.status.eor = dirCurrent; - break; - case TQChar::DirR: - case TQChar::DirAL: - case TQChar::DirAN: - appendRun( bidi ); - bidi.status.eor = TQChar::DirEN; - dir = TQChar::DirEN; break; - case TQChar::DirES: - case TQChar::DirCS: - if(bidi.status.eor == TQChar::DirEN) { - bidi.eor = bidi.current; break; - } - case TQChar::DirBN: - case TQChar::DirB: - case TQChar::DirS: - case TQChar::DirWS: - case TQChar::DirON: - if(bidi.status.eor == TQChar::DirR) { - // neutrals go to R - bidi.eor = bidi.last; - appendRun( bidi ); - dir = TQChar::DirEN; - bidi.status.eor = TQChar::DirEN; - } - else if( bidi.status.eor == TQChar::DirL || - (bidi.status.eor == TQChar::DirEN && bidi.status.lastStrong == TQChar::DirL)) { - bidi.eor = bidi.current; bidi.status.eor = dirCurrent; - } else { - // numbers on both sides, neutrals get right to left direction - if(dir != TQChar::DirL) { - appendRun( bidi ); - bidi.eor = bidi.last; - dir = TQChar::DirR; - appendRun( bidi ); - dir = TQChar::DirEN; - bidi.status.eor = TQChar::DirEN; - } else { - bidi.eor = bidi.current; bidi.status.eor = dirCurrent; - } - } - default: - break; - } - break; - } - case TQChar::DirAN: - dirCurrent = TQChar::DirAN; - if(dir == TQChar::DirON) dir = TQChar::DirAN; - switch(bidi.status.last) - { - case TQChar::DirL: - case TQChar::DirAN: - bidi.eor = bidi.current; bidi.status.eor = TQChar::DirAN; break; - case TQChar::DirR: - case TQChar::DirAL: - case TQChar::DirEN: - appendRun( bidi ); - dir = TQChar::DirAN; bidi.status.eor = TQChar::DirAN; - break; - case TQChar::DirCS: - if(bidi.status.eor == TQChar::DirAN) { - bidi.eor = bidi.current; break; - } - case TQChar::DirES: - case TQChar::DirET: - case TQChar::DirBN: - case TQChar::DirB: - case TQChar::DirS: - case TQChar::DirWS: - case TQChar::DirON: - if(bidi.status.eor == TQChar::DirR) { - // neutrals go to R - bidi.eor = bidi.last; - appendRun( bidi ); - dir = TQChar::DirAN; - bidi.status.eor = TQChar::DirAN; - } else if( bidi.status.eor == TQChar::DirL || - (bidi.status.eor == TQChar::DirEN && bidi.status.lastStrong == TQChar::DirL)) { - bidi.eor = bidi.current; bidi.status.eor = dirCurrent; - } else { - // numbers on both sides, neutrals get right to left direction - if(dir != TQChar::DirL) { - appendRun( bidi ); - bidi.eor = bidi.last; - dir = TQChar::DirR; - appendRun( bidi ); - dir = TQChar::DirAN; - bidi.status.eor = TQChar::DirAN; - } else { - bidi.eor = bidi.current; bidi.status.eor = dirCurrent; - } - } - default: - break; - } - break; - case TQChar::DirES: - case TQChar::DirCS: - break; - case TQChar::DirET: - if(bidi.status.last == TQChar::DirEN) { - dirCurrent = TQChar::DirEN; - bidi.eor = bidi.current; bidi.status.eor = dirCurrent; - break; - } - break; - - // boundary neutrals should be ignored - case TQChar::DirBN: - break; - // neutrals - case TQChar::DirB: - // ### what do we do with newline and paragraph seperators that come to here? - break; - case TQChar::DirS: - // ### implement rule L1 - break; - case TQChar::DirWS: - break; - case TQChar::DirON: - break; - default: - break; - } - - //cout << " after: dir=" << // dir << " current=" << dirCurrent << " last=" << status.last << " eor=" << status.eor << " lastStrong=" << status.lastStrong << " embedding=" << context->dir << endl; - - if(bidi.current.atEnd()) break; - - // set status.last as needed. - switch(dirCurrent) - { - case TQChar::DirET: - case TQChar::DirES: - case TQChar::DirCS: - case TQChar::DirS: - case TQChar::DirWS: - case TQChar::DirON: - switch(bidi.status.last) - { - case TQChar::DirL: - case TQChar::DirR: - case TQChar::DirAL: - case TQChar::DirEN: - case TQChar::DirAN: - bidi.status.last = dirCurrent; - break; - default: - bidi.status.last = TQChar::DirON; - } - break; - case TQChar::DirNSM: - case TQChar::DirBN: - // ignore these - break; - case TQChar::DirEN: - if ( bidi.status.last == TQChar::DirL ) { - break; - } - // fall through - default: - bidi.status.last = dirCurrent; - } -#endif - - if ( atEnd ) break; - bidi.last = bidi.current; - - if ( emptyRun ) { - bidi.sor = bidi.current; - bidi.eor = bidi.current; - emptyRun = false; - } - - // this causes the operator ++ to open and close embedding levels as needed - // for the CSS unicode-bidi property - adjustEmbedding = true; - bidi.current.increment( bidi ); - adjustEmbedding = false; - - if ( bidi.current == end ) { - if ( emptyRun ) - break; - atEnd = true; - } - } - -#if BIDI_DEBUG > 0 - kdDebug(6041) << "reached end of line current=" << current.obj << "/" << current.pos - << ", eor=" << eor.obj << "/" << eor.pos << endl; -#endif - if ( !emptyRun && bidi.sor != bidi.current ) { - bidi.eor = bidi.last; - appendRun( bidi ); - } - - // reorder line according to run structure... - - // first find highest and lowest levels - uchar levelLow = 128; - uchar levelHigh = 0; - BidiRun *r = sFirstBidiRun; - while ( r ) { - if ( r->level > levelHigh ) - levelHigh = r->level; - if ( r->level < levelLow ) - levelLow = r->level; - r = r->nextRun; - } - - // implements reordering of the line (L2 according to Bidi spec): - // L2. From the highest level found in the text to the lowest odd level on each line, - // reverse any contiguous sequence of characters that are at that level or higher. - - // reversing is only done up to the lowest odd level - if( !(levelLow%2) ) levelLow++; - -#if BIDI_DEBUG > 0 - kdDebug(6041) << "lineLow = " << (uint)levelLow << ", lineHigh = " << (uint)levelHigh << endl; - kdDebug(6041) << "logical order is:" << endl; - TQPtrListIterator it2(runs); - BidiRun *r2; - for ( ; (r2 = it2.current()); ++it2 ) - kdDebug(6041) << " " << r2 << " start=" << r2->start << " stop=" << r2->stop << " level=" << (uint)r2->level << endl; -#endif - - int count = sBidiRunCount - 1; - - // do not reverse for visually ordered web sites - if(!style()->visuallyOrdered()) { - while(levelHigh >= levelLow) { - int i = 0; - BidiRun* currRun = sFirstBidiRun; - while ( i < count ) { - while(i < count && currRun && currRun->level < levelHigh) { - i++; - currRun = currRun->nextRun; - } - int start = i; - while(i <= count && currRun && currRun->level >= levelHigh) { - i++; - currRun = currRun->nextRun; - } - int end = i-1; - reverseRuns(start, end); - } - levelHigh--; - } - } - -#if BIDI_DEBUG > 0 - kdDebug(6041) << "visual order is:" << endl; - for (BidiRun* curr = sFirstRun; curr; curr = curr->nextRun) - kdDebug(6041) << " " << curr << endl; -#endif -} - -void RenderBlock::layoutInlineChildren(bool relayoutChildren, int breakBeforeLine) -{ - BidiState bidi; - - m_overflowHeight = 0; - - invalidateVerticalPositions(); -#ifdef DEBUG_LAYOUT - TQTime qt; - qt.start(); - kdDebug( 6040 ) << renderName() << " layoutInlineChildren( " << this <<" )" << endl; -#endif -#if BIDI_DEBUG > 1 || defined( DEBUG_LINEBREAKS ) - kdDebug(6041) << " ------- bidi start " << this << " -------" << endl; -#endif - - m_height = borderTop() + paddingTop(); - int toAdd = borderBottom() + paddingBottom(); - if (m_layer && scrollsOverflowX() && style()->height().isVariable()) - toAdd += m_layer->horizontalScrollbarHeight(); - - // Clear out our line boxes. - deleteInlineBoxes(); - - // Text truncation only kicks in if your overflow isn't visible and your - // text-overflow-mode isn't clip. - bool hasTextOverflow = style()->textOverflow() && hasOverflowClip(); - - // Walk all the lines and delete our ellipsis line boxes if they exist. - if (hasTextOverflow) - deleteEllipsisLineBoxes(); - - if (firstChild()) { - // layout replaced elements - RenderObject *o = first( this, bidi, false ); - while ( o ) { - if (o->markedForRepaint()) { - o->repaintDuringLayout(); - o->setMarkedForRepaint(false); - } - if (o->isReplaced() || o->isFloating() || o->isPositioned()) { - // clear the placeHolderBox - if (o->isBox()) - static_cast(o)->RenderBox::deleteInlineBoxes(); - - //kdDebug(6041) << "layouting replaced or floating child" << endl; - if (relayoutChildren || o->style()->width().isPercent() || o->style()->height().isPercent()) - o->setChildNeedsLayout(true, false); - if (o->isPositioned()) - o->containingBlock()->insertPositionedObject(o); - else - o->layoutIfNeeded(); - } - else { - o->deleteInlineBoxes(); - o->setNeedsLayout(false); - } - o = Bidinext( this, o, bidi, false ); - } - - BidiContext *startEmbed; - if( style()->direction() == LTR ) { - startEmbed = new BidiContext( 0, TQChar::DirL ); - bidi.status.eor = TQChar::DirL; - } else { - startEmbed = new BidiContext( 1, TQChar::DirR ); - bidi.status.eor = TQChar::DirR; - } - startEmbed->ref(); - - bidi.status.lastStrong = TQChar::DirON; - bidi.status.last = TQChar::DirON; - - bidi.context = startEmbed; - adjustEmbedding = true; - BidiIterator start(this, first(this, bidi), 0); - adjustEmbedding = false; - BidiIterator end = start; - - m_firstLine = true; - - if (!smidpoints) - smidpoints = new TQMemArray; - - sNumMidpoints = 0; - sCurrMidpoint = 0; - sCompactFirstBidiRun = sCompactLastBidiRun = 0; - sCompactBidiRunCount = 0; - - previousLineBrokeAtBR = true; - - int lineCount = 0; - bool pagebreakHint = false; - int oldPos = 0; - BidiIterator oldStart; - BidiState oldBidi; - const bool pagedMode = canvas()->pagedMode(); -// - while( !end.atEnd() ) { - start = end; - lineCount++; - betweenMidpoints = false; - isLineEmpty = true; - pagebreakHint = false; - if (pagedMode) { - oldPos = m_height; - oldStart = start; - oldBidi = bidi; - } - if (lineCount == breakBeforeLine) { - m_height = pageTopAfter(oldPos); - pagebreakHint = true; - } -redo_linebreak: - end = findNextLineBreak(start, bidi); - if( start.atEnd() ) break; - if (!isLineEmpty) { - bidiReorderLine(start, end, bidi); - - // Now that the runs have been ordered, we create the line boxes. - // At the same time we figure out where border/padding/margin should be applied for - // inline flow boxes. - - if (sBidiRunCount) { - InlineFlowBox* lineBox = constructLine(start, end); - if (lineBox) { - if (pagebreakHint) lineBox->setAfterPageBreak(true); - - // Now we position all of our text runs horizontally. - computeHorizontalPositionsForLine(lineBox, bidi); - - // Now position our text runs vertically. - computeVerticalPositionsForLine(lineBox); - - deleteBidiRuns(renderArena()); - - if (lineBox->afterPageBreak() && hasFloats() && !pagebreakHint) { - start = end = oldStart; - bidi = oldBidi; - m_height = pageTopAfter(oldPos); - deleteLastLineBox(renderArena()); - pagebreakHint = true; - goto redo_linebreak; - } - } - } - - if( end == start || (end.obj && end.obj->isBR() && !start.obj->isBR() ) ) { - adjustEmbedding = true; - end.increment(bidi); - adjustEmbedding = false; - } else if (end.obj && end.obj->style()->preserveLF() && end.current() == TQChar('\n')) { - adjustEmbedding = true; - end.increment(bidi); - adjustEmbedding = false; - } - - m_firstLine = false; - newLine(); - } - - sNumMidpoints = 0; - sCurrMidpoint = 0; - sCompactFirstBidiRun = sCompactLastBidiRun = 0; - sCompactBidiRunCount = 0; - } - startEmbed->deref(); - //embed->deref(); - } - - sNumMidpoints = 0; - sCurrMidpoint = 0; - - // If we violate widows page-breaking rules, we set a hint and relayout. - // Note that the widows rule might still be violated afterwards if the lines have become wider - if (canvas()->pagedMode() && containsPageBreak() && breakBeforeLine == 0) - { - int orphans = 0; - int widows = 0; - // find breaking line - InlineRunBox* lineBox = firstLineBox(); - while (lineBox) { - if (lineBox->isInlineFlowBox()) { - InlineFlowBox* flowBox = static_cast(lineBox); - if (flowBox->afterPageBreak()) break; - } - orphans++; - lineBox = lineBox->nextLineBox(); - } - InlineFlowBox* pageBreaker = static_cast(lineBox); - if (!pageBreaker) goto no_break; - // count widows - while (lineBox && widows < style()->widows()) { - if (lineBox->hasTextChildren()) - widows++; - lineBox = lineBox->nextLineBox(); - } - // Widows rule broken and more orphans left to use - if (widows < style()->widows() && orphans > 0) { - kdDebug( 6040 ) << "Widows: " << widows << endl; - // Check if we have enough orphans after respecting widows count - int newOrphans = orphans - (style()->widows() - widows); - if (newOrphans < style()->orphans()) { - if (parent()->canClear(this,PageBreakHarder)) { - // Relayout to remove incorrect page-break - setNeedsPageClear(true); - setContainsPageBreak(false); - layoutInlineChildren(relayoutChildren, -1); - return; - } - } else { - // Set hint and try again - layoutInlineChildren(relayoutChildren, newOrphans+1); - return; - } - } - } - no_break: - - // in case we have a float on the last line, it might not be positioned up to now. - // This has to be done before adding in the bottom border/padding, or the float will - // include the padding incorrectly. -dwh - positionNewFloats(); - - // Now add in the bottom border/padding. - m_height += toAdd; - - // Always make sure this is at least our height. - m_overflowHeight = kMax(m_height, m_overflowHeight); - - // See if any lines spill out of the block. If so, we need to update our overflow width. - checkLinesForOverflow(); - - // See if we have any lines that spill out of our block. If we do, then we will - // possibly need to truncate text. - if (hasTextOverflow) - checkLinesForTextOverflow(); - -#if BIDI_DEBUG > 1 - kdDebug(6041) << " ------- bidi end " << this << " -------" << endl; -#endif - //kdDebug() << "RenderBlock::layoutInlineChildren time used " << qt.elapsed() << endl; - //kdDebug(6040) << "height = " << m_height <style()->isOriginalDisplayInlineType(); - nssx = o->hasStaticX(); - if (nssx && !isInlineType && o->isBox()) { - static_cast(o)->setStaticX(o->parent()->style()->direction() == LTR ? - p->borderLeft()+p->paddingLeft() : - p->borderRight()+p->paddingRight()); - nssx = false; - } - - // If our original display was an INLINE type, then we can - // determine our static y position now. - nssy = o->hasStaticY(); - if (nssy && o->isBox()) { - static_cast(o)->setStaticY(p->height()); - nssy = !isInlineType; - } - if (needToSetStaticX) *needToSetStaticX = nssx; - if (needToSetStaticY) *needToSetStaticY = nssy; -} - -BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, BidiState &bidi) -{ - int width = lineWidth(m_height); - int w = 0; - int tmpW = 0; -#ifdef DEBUG_LINEBREAKS - kdDebug(6041) << "findNextLineBreak: line at " << m_height << " line width " << width << endl; - kdDebug(6041) << "sol: " << start.obj << " " << start.pos << endl; -#endif - - BidiIterator posStart = start; - bool hadPosStart = false; - - // eliminate spaces at beginning of line - // remove leading spaces. Any inline flows we encounter will be empty and should also - // be skipped. - while (!start.atEnd() && (start.obj->isInlineFlow() || (!start.obj->style()->preserveWS() && !start.obj->isBR() && -#ifndef QT_NO_UNICODETABLES - ( (start.current().unicode() == (ushort)0x0020) || // ASCII space - (start.current().unicode() == (ushort)0x0009) || // ASCII tab - (start.current().unicode() == (ushort)0x000A) || // ASCII line feed - (start.current().unicode() == (ushort)0x000C) || // ASCII form feed - (start.current().unicode() == (ushort)0x200B) || // Zero-width space - start.obj->isFloatingOrPositioned() ) -#else - ( start.current() == ' ' || start.current() == '\n' || start.obj->isFloatingOrPositioned() ) -#endif - ))) { - if( start.obj->isFloatingOrPositioned() ) { - RenderObject *o = start.obj; - // add to special objects... - if (o->isFloating()) { - insertFloatingObject(o); - positionNewFloats(); - width = lineWidth(m_height); - } - else if (o->isBox() && o->isPositioned()) { - if (!hadPosStart) { - hadPosStart = true; - posStart = start; - // end - addMidpoint(BidiIterator(0, o, 0)); - } else { - // start/end - addMidpoint(BidiIterator(0, o, 0)); - addMidpoint(BidiIterator(0, o, 0)); - } - setStaticPosition(this, o); - } - } - adjustEmbedding = true; - start.increment(bidi, false /*skipInlines*/); - adjustEmbedding = false; - } - - if (hadPosStart && !start.atEnd()) - addMidpoint(start); - - if ( start.atEnd() ){ - if (hadPosStart) { - start = posStart; - posStart.increment(bidi); - return posStart; - } - return start; - } - - // This variable says we have encountered an object after which initial whitespace should be ignored (e.g. InlineFlows at the begining of a line). - // Either we have nothing to do, if there is no whitespace after the object... or we have to enter the ignoringSpaces state. - // This dilemma will be resolved when we have a peek at the next object. - bool checkShouldIgnoreInitialWhitespace = false; - - // This variable is used only if whitespace isn't set to PRE, and it tells us whether - // or not we are currently ignoring whitespace. - bool ignoringSpaces = false; - BidiIterator ignoreStart; - - // This variable tracks whether the very last character we saw was a space. We use - // this to detect when we encounter a second space so we know we have to terminate - // a run. - bool currentCharacterIsSpace = false; - RenderObject* trailingSpaceObject = 0; - - BidiIterator lBreak = start; - - InlineMinMaxIterator it(start.par, start.obj, start.endOfInline, false /*skipPositioned*/); - InlineMinMaxIterator lastIt = it; - int pos = start.pos; - - bool prevLineBrokeCleanly = previousLineBrokeAtBR; - previousLineBrokeAtBR = false; - - RenderObject* o = it.current; - while( o ) { -#ifdef DEBUG_LINEBREAKS - kdDebug(6041) << "new object "<< o <<" width = " << w <<" tmpw = " << tmpW << endl; -#endif - if(o->isBR()) { - if( w + tmpW <= width ) { - lBreak.obj = o; - lBreak.pos = 0; - lBreak.endOfInline = it.endOfInline; - - // A
always breaks a line, so don't let the line be collapsed - // away. Also, the space at the end of a line with a
does not - // get collapsed away. It only does this if the previous line broke - // cleanly. Otherwise the
has no effect on whether the line is - // empty or not. - if (prevLineBrokeCleanly) - isLineEmpty = false; - trailingSpaceObject = 0; - previousLineBrokeAtBR = true; - - if (!isLineEmpty) { - // only check the clear status for non-empty lines. - EClear clear = o->style()->clear(); - if(clear != CNONE) - m_clearStatus = (EClear) (m_clearStatus | clear); - } - } - goto end; - } - if( o->isFloatingOrPositioned() ) { - // add to special objects... - if(o->isFloating()) { - insertFloatingObject(o); - // check if it fits in the current line. - // If it does, position it now, otherwise, position - // it after moving to next line (in newLine() func) - if (o->width()+o->marginLeft()+o->marginRight()+w+tmpW <= width) { - positionNewFloats(); - width = lineWidth(m_height); - } - } - else if (o->isPositioned()) { - bool needToSetStaticX; - bool needToSetStaticY; - setStaticPosition(this, o, &needToSetStaticX, &needToSetStaticY); - - // If we're ignoring spaces, we have to stop and include this object and - // then start ignoring spaces again. - if (needToSetStaticX || needToSetStaticY) { - trailingSpaceObject = 0; - ignoreStart.obj = o; - ignoreStart.pos = 0; - if (ignoringSpaces) { - addMidpoint(ignoreStart); // Stop ignoring spaces. - addMidpoint(ignoreStart); // Start ignoring again. - } - } - } - } else if (o->isInlineFlow()) { - tmpW += getBorderPaddingMargin(o, it.endOfInline); - if (isLineEmpty) isLineEmpty = !tmpW; - if (o->isWordBreak()) { // #### shouldn't be an InlineFlow! - w += tmpW; - tmpW = 0; - lBreak.obj = o; - lBreak.pos = 0; - lBreak.endOfInline = it.endOfInline; - } else if (!it.endOfInline) { - // this is the beginning of the line (other non-initial inline flows are handled directly when - // incrementing the iterator below). We want to skip initial whitespace as much as possible. - checkShouldIgnoreInitialWhitespace = true; - } - } else if ( o->isReplaced() || o->isGlyph() ) { - EWhiteSpace currWS = o->style()->whiteSpace(); - EWhiteSpace lastWS = lastIt.current->style()->whiteSpace(); - - // WinIE marquees have different whitespace characteristics by default when viewed from - // the outside vs. the inside. Text inside is NOWRAP, and so we altered the marquee's - // style to reflect this, but we now have to get back to the original whitespace value - // for the marquee when checking for line breaking. - if (o->isHTMLMarquee() && o->layer() && o->layer()->marquee()) - currWS = o->layer()->marquee()->whiteSpace(); - if (lastIt.current->isHTMLMarquee() && lastIt.current->layer() && lastIt.current->layer()->marquee()) - lastWS = lastIt.current->layer()->marquee()->whiteSpace(); - - // Break on replaced elements if either has normal white-space. - if (currWS == NORMAL || lastWS == NORMAL) { - w += tmpW; - tmpW = 0; - lBreak.obj = o; - lBreak.pos = 0; - lBreak.endOfInline = false; - } - - tmpW += o->width()+o->marginLeft()+o->marginRight(); - if (ignoringSpaces) { - BidiIterator startMid( 0, o, 0 ); - addMidpoint(startMid); - } - isLineEmpty = false; - ignoringSpaces = false; - currentCharacterIsSpace = false; - trailingSpaceObject = 0; - - if (o->isListMarker() && o->style()->listStylePosition() == OUTSIDE) { - checkShouldIgnoreInitialWhitespace = true; - } - } else if ( o->isText() ) { - RenderText *t = static_cast(o); - int strlen = t->stringLength(); - int len = strlen - pos; - TQChar *str = t->text(); - - const Font *f = t->htmlFont( m_firstLine ); - // proportional font, needs a bit more work. - int lastSpace = pos; - bool autoWrap = o->style()->autoWrap(); - bool preserveWS = o->style()->preserveWS(); - bool preserveLF = o->style()->preserveLF(); -#ifdef APPLE_CHANGES - int wordSpacing = o->style()->wordSpacing(); -#endif - bool nextIsSoftBreakable = false; - bool checkBreakWord = autoWrap && (o->style()->wordWrap() == WWBREAKWORD); - - while(len) { - bool previousCharacterIsSpace = currentCharacterIsSpace; - bool isSoftBreakable = nextIsSoftBreakable; - nextIsSoftBreakable = false; - const TQChar c = str[pos]; - currentCharacterIsSpace = c == ' '; - checkBreakWord &= !w; // only break words when no other breaking opportunity exists earlier - // on the line (even within the text object we are currently processing) - - if (preserveWS || !currentCharacterIsSpace) - isLineEmpty = false; - - // Check for soft hyphens. Go ahead and ignore them. - if (c.unicode() == SOFT_HYPHEN && pos > 0) { - nextIsSoftBreakable = true; - if (!ignoringSpaces) { - // Ignore soft hyphens - BidiIterator endMid(0, o, pos-1); - addMidpoint(endMid); - - // Add the width up to but not including the hyphen. - tmpW += t->width(lastSpace, pos - lastSpace, f); - - // For wrapping text only, include the hyphen. We need to ensure it will fit - // on the line if it shows when we break. - if (o->style()->autoWrap()) - tmpW += t->width(pos, 1, f); - - BidiIterator startMid(0, o, pos+1); - addMidpoint(startMid); - } - - pos++; - len--; - lastSpace = pos; // Cheesy hack to prevent adding in widths of the run twice. - continue; - } -#ifdef APPLE_CHANGES // KDE applies wordspacing differently - bool applyWordSpacing = false; -#endif - if (ignoringSpaces) { - // We need to stop ignoring spaces, if we encounter a non-space or - // a run that doesn't collapse spaces. - if (!currentCharacterIsSpace || preserveWS) { - // Stop ignoring spaces and begin at this - // new point. - ignoringSpaces = false; - lastSpace = pos; // e.g., "Foo goo", don't add in any of the ignored spaces. - BidiIterator startMid ( 0, o, pos ); - addMidpoint(startMid); - } - else { - // Just keep ignoring these spaces. - pos++; - len--; - continue; - } - } - - const bool isbreakablePosition = (preserveLF && c == '\n') || (autoWrap && - (isBreakable( str, pos, strlen ) || isSoftBreakable)); - if ( isbreakablePosition || checkBreakWord ) { - - tmpW += t->width(lastSpace, pos - lastSpace, f); -#ifdef APPLE_CHANGES - applyWordSpacing = (wordSpacing && currentCharacterIsSpace && !previousCharacterIsSpace && - !t->containsOnlyWhitespace(pos+1, strlen-(pos+1))); -#endif -#ifdef DEBUG_LINEBREAKS - kdDebug(6041) << "found space at " << pos << " in string '" << TQString( str, strlen ).latin1() << "' adding " << tmpW << " new width = " << w << endl; -#endif - if ( autoWrap && w + tmpW > width && w == 0 ) { - int fb = nearestFloatBottom(m_height); - int newLineWidth = lineWidth(fb); - // See if |tmpW| will fit on the new line. As long as it does not, - // keep adjusting our float bottom until we find some room. - int lastFloatBottom = m_height; - while (lastFloatBottom < fb && tmpW > newLineWidth) { - lastFloatBottom = fb; - fb = nearestFloatBottom(fb); - newLineWidth = lineWidth(fb); - } - - if(!w && m_height < fb && width < newLineWidth) { - m_height = fb; - width = newLineWidth; -#ifdef DEBUG_LINEBREAKS - kdDebug() << "RenderBlock::findNextLineBreak new position at " << m_height << " newWidth " << width << endl; -#endif - } - } - - if (autoWrap) { - if (w+tmpW > width) { - if (checkBreakWord && pos) { - lBreak.obj = o; - lBreak.pos = pos-1; - lBreak.endOfInline = false; - } - goto end; - } else if ( (pos > 1 && str[pos-1].unicode() == SOFT_HYPHEN) ) - // Subtract the width of the soft hyphen out since we fit on a line. - tmpW -= t->width(pos-1, 1, f); - } - - if( preserveLF && *(str+pos) == '\n' ) { - lBreak.obj = o; - lBreak.pos = pos; - lBreak.endOfInline = false; - -#ifdef DEBUG_LINEBREAKS - kdDebug(6041) << "forced break sol: " << start.obj << " " << start.pos << " end: " << lBreak.obj << " " << lBreak.pos << " width=" << w << endl; -#endif - return lBreak; - } - - if ( autoWrap && isbreakablePosition ) { - w += tmpW; - tmpW = 0; - lBreak.obj = o; - lBreak.pos = pos; - lBreak.endOfInline = false; - } - - lastSpace = pos; -#ifdef APPLE_CHANGES - if (applyWordSpacing) - w += wordSpacing; -#endif - } - - if (!ignoringSpaces && !preserveWS) { - // If we encounter a second space, we need to go ahead and break up this run - // and enter a mode where we start collapsing spaces. - if (currentCharacterIsSpace && previousCharacterIsSpace) { - ignoringSpaces = true; - - // We just entered a mode where we are ignoring - // spaces. Create a midpoint to terminate the run - // before the second space. - addMidpoint(ignoreStart); - lastSpace = pos; - } - } - - if (currentCharacterIsSpace && !previousCharacterIsSpace) { - ignoreStart.obj = o; - ignoreStart.pos = pos; - } - - if (!preserveWS && currentCharacterIsSpace && !ignoringSpaces) - trailingSpaceObject = o; - else if (preserveWS || !currentCharacterIsSpace) - trailingSpaceObject = 0; - - pos++; - len--; - } - - if (!ignoringSpaces) { - // We didn't find any space that would be beyond the line |width|. - // Lets add to |tmpW| the remaining width since the last space we found. - // Before we test this new |tmpW| however, we will have to look ahead to check - // if the next object/position can serve as a line breaking opportunity. - tmpW += t->width(lastSpace, pos - lastSpace, f); - if (checkBreakWord && !w && pos && tmpW > width) { - // Avoid doing the costly lookahead for break-word, - // since we know we are allowed to break. - lBreak.obj = o; - lBreak.pos = pos-1; - lBreak.endOfInline = false; - goto end; - } - } - } else - KHTMLAssert( false ); - - InlineMinMaxIterator savedIt = lastIt; - lastIt = it; - o = it.next(); - - // advance the iterator to the next non-inline-flow - while (o && o->isInlineFlow() && !o->isWordBreak()) { - tmpW += getBorderPaddingMargin(o, it.endOfInline); - if (isLineEmpty) isLineEmpty = !tmpW; - o = it.next(); - } - - if (checkShouldIgnoreInitialWhitespace) { - // Check if we should switch to ignoringSpaces state - if (!style()->preserveWS() && it.current && it.current->isText()) { - const RenderText* rt = static_cast(it.current); - if (rt->stringLength() > 0 && (rt->text()[0].category() == TQChar::Separator_Space || rt->text()[0] == '\n')) { - currentCharacterIsSpace = true; - ignoringSpaces = true; - BidiIterator endMid( 0, lastIt.current, 0 ); - addMidpoint(endMid); - } - } - checkShouldIgnoreInitialWhitespace = false; - } - - bool autoWrap = lastIt.current->style()->autoWrap(); - bool checkForBreak = autoWrap; - if (w && w + tmpW > width && lBreak.obj && !lastIt.current->style()->preserveLF() && !autoWrap) - checkForBreak = true; - else if (it.current && lastIt.current->isText() && it.current->isText() && !it.current->isBR()) { - if (autoWrap || it.current->style()->autoWrap()) { - if (currentCharacterIsSpace) - checkForBreak = true; - else { - checkForBreak = false; - RenderText* nextText = static_cast(it.current); - if (nextText->stringLength() != 0) { - TQChar c = nextText->text()[0]; - if (c == ' ' || c == '\t' || (c == '\n' && !it.current->style()->preserveLF())) { - // If the next item on the line is text, and if we did not end with - // a space, then the next text run continues our word (and so it needs to - // keep adding to |tmpW|. Just update and continue. - checkForBreak = true; - } - } - - bool canPlaceOnLine = (w + tmpW <= width) || !autoWrap; - if (canPlaceOnLine && checkForBreak) { - w += tmpW; - tmpW = 0; - lBreak.obj = it.current; - lBreak.pos = 0; - lBreak.endOfInline = it.endOfInline; - } - } - } - } - - if (checkForBreak && (w + tmpW > width)) { - //kdDebug() << " too wide w=" << w << " tmpW = " << tmpW << " width = " << width << endl; - //kdDebug() << "start=" << start.obj << " current=" << o << endl; - // if we have floats, try to get below them. - if (currentCharacterIsSpace && !ignoringSpaces && !lastIt.current->style()->preserveWS()) - trailingSpaceObject = 0; - - int fb = nearestFloatBottom(m_height); - int newLineWidth = lineWidth(fb); - // See if |tmpW| will fit on the new line. As long as it does not, - // keep adjusting our float bottom until we find some room. - int lastFloatBottom = m_height; - while (lastFloatBottom < fb && tmpW > newLineWidth) { - lastFloatBottom = fb; - fb = nearestFloatBottom(fb); - newLineWidth = lineWidth(fb); - } - if( !w && m_height < fb && width < newLineWidth ) { - m_height = fb; - width = newLineWidth; -#ifdef DEBUG_LINEBREAKS - kdDebug() << "RenderBlock::findNextLineBreak new position at " << m_height << " newWidth " << width << endl; -#endif - } - - // |width| may have been adjusted because we got shoved down past a float (thus - // giving us more room), so we need to retest, and only jump to - // the end label if we still don't fit on the line. -dwh - if (w + tmpW > width) { - it = lastIt; - lastIt = savedIt; - o = it.current; - goto end; - } - } - - if (!lastIt.current->isFloatingOrPositioned() && lastIt.current->isReplaced() && lastIt.current->style()->autoWrap()) { - // Go ahead and add in tmpW. - w += tmpW; - tmpW = 0; - lBreak.obj = o; - lBreak.pos = 0; - lBreak.endOfInline = it.endOfInline; - } - - // Clear out our character space bool, since inline
s don't collapse whitespace
-        // with adjacent inline normal/nowrap spans.
-        if (lastIt.current->style()->preserveWS())
-            currentCharacterIsSpace = false;
-
-        pos = 0;
-    }
-
-#ifdef DEBUG_LINEBREAKS
-    kdDebug( 6041 ) << "end of par, width = " << width << " linewidth = " << w + tmpW << endl;
-#endif
-    if( w + tmpW <= width || (lastIt.current && !lastIt.current->style()->autoWrap())) {
-        lBreak.obj = 0;
-        lBreak.pos = 0;
-        lBreak.endOfInline = false;
-    }
-
- end:
-
-    if( lBreak == start && !lBreak.obj->isBR() ) {
-        // we just add as much as possible
-        if ( style()->whiteSpace() == PRE ) {
-            // FIXME: Don't really understand this case.
-            if(pos != 0) {
-                lBreak.obj = o;
-                lBreak.pos = pos - 1;
-                lBreak.endOfInline = it.endOfInline;
-            } else {
-                lBreak.obj = lastIt.current;
-                lBreak.pos = lastIt.current->isText() ? lastIt.current->length() : 0;
-                lBreak.endOfInline = lastIt.endOfInline;
-            }
-        } else if( lBreak.obj ) {
-            if( lastIt.current != o ) {
-                // better to break between object boundaries than in the middle of a word
-                lBreak.obj = o;
-                lBreak.pos = 0;
-                lBreak.endOfInline = it.endOfInline;
-            } else {
-                // Don't ever break in the middle of a word if we can help it.
-                // There's no room at all. We just have to be on this line,
-                // even though we'll spill out.
-                lBreak.obj = o;
-                lBreak.pos = pos;
-                lBreak.endOfInline = it.endOfInline;
-            }
-        }
-    }
-
-    if (hadPosStart)
-        start = posStart;
-
-    // make sure we consume at least one char/object.
-    // and avoid returning an InlineFlow
-    // (FIXME: turn those wordbreaks into empty text objects - they shouldn't be inline flows!)
-    if( lBreak == start || (lBreak.obj && lBreak.obj->isInlineFlow() && !lBreak.obj->isWordBreak())) {
-        lBreak.increment(bidi);
-    }
-
-#ifdef DEBUG_LINEBREAKS
-    kdDebug(6041) << "regular break sol: " << start.obj << " " << start.pos << "   end: " << lBreak.obj << " " << lBreak.pos << "   width=" << w << endl;
-#endif
-
-    // Sanity check our midpoints.
-    checkMidpoints(lBreak, bidi);
-
-    if (trailingSpaceObject) {
-        // This object is either going to be part of the last midpoint, or it is going
-        // to be the actual endpoint.  In both cases we just decrease our pos by 1 level to
-        // exclude the space, allowing it to - in effect - collapse into the newline.
-        if (sNumMidpoints%2==1) {
-            BidiIterator* midpoints = smidpoints->data();
-            midpoints[sNumMidpoints-1].pos--;
-        }
-        //else if (lBreak.pos > 0)
-        //    lBreak.pos--;
-        else if (lBreak.obj == 0 && trailingSpaceObject->isText()) {
-            // Add a new end midpoint that stops right at the very end.
-            RenderText* text = static_cast(trailingSpaceObject);
-            unsigned pos = text->length() >=2 ? text->length() - 2 : UINT_MAX;
-            BidiIterator endMid ( 0, trailingSpaceObject, pos );
-            addMidpoint(endMid);
-        }
-    }
-
-    // We might have made lBreak an iterator that points past the end
-    // of the object. Do this adjustment to make it point to the start
-    // of the next object instead to avoid confusing the rest of the
-    // code.
-    if (lBreak.pos > 0) {
-        lBreak.pos--;
-        lBreak.increment(bidi);
-    }
-
-    if (lBreak.obj && lBreak.pos >= 2 && lBreak.obj->isText()) {
-        // For soft hyphens on line breaks, we have to chop out the midpoints that made us
-        // ignore the hyphen so that it will render at the end of the line.
-        TQChar c = static_cast(lBreak.obj)->text()[lBreak.pos-1];
-        if (c.unicode() == SOFT_HYPHEN)
-            chopMidpointsAt(lBreak.obj, lBreak.pos-2);
-    }
-
-    return lBreak;
-}
-
-void RenderBlock::checkLinesForOverflow()
-{
-    for (RootInlineBox* curr = static_cast(firstLineBox()); curr; curr = static_cast(curr->nextLineBox())) {
-//         m_overflowLeft = min(curr->leftOverflow(), m_overflowLeft);
-        m_overflowTop = kMin(curr->topOverflow(), m_overflowTop);
-//         m_overflowWidth = max(curr->rightOverflow(), m_overflowWidth);
-        m_overflowHeight = kMax(curr->bottomOverflow(), m_overflowHeight);
-    }
-}
-
-void RenderBlock::deleteEllipsisLineBoxes()
-{
-    for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox())
-        curr->clearTruncation();
-}
-
-void RenderBlock::checkLinesForTextOverflow()
-{
-    // Determine the width of the ellipsis using the current font.
-    TQChar ellipsis = 0x2026; // FIXME: CSS3 says this is configurable, also need to use 0x002E (FULL STOP) if 0x2026 not renderable
-    static TQString ellipsisStr(ellipsis);
-    const Font& firstLineFont = style(true)->htmlFont();
-    const Font& font = style()->htmlFont();
-    int firstLineEllipsisWidth = firstLineFont.width(&ellipsis, 1, 0);
-    int ellipsisWidth = (font == firstLineFont) ? firstLineEllipsisWidth : font.width(&ellipsis, 1, 0);
-
-    // For LTR text truncation, we want to get the right edge of our padding box, and then we want to see
-    // if the right edge of a line box exceeds that.  For RTL, we use the left edge of the padding box and
-    // check the left edge of the line box to see if it is less
-    // Include the scrollbar for overflow blocks, which means we want to use "contentWidth()"
-    bool ltr = style()->direction() == LTR;
-    for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
-        int blockEdge = ltr ? rightOffset(curr->yPos()) : leftOffset(curr->yPos());
-        int lineBoxEdge = ltr ? curr->xPos() + curr->width() : curr->xPos();
-        if ((ltr && lineBoxEdge > blockEdge) || (!ltr && lineBoxEdge < blockEdge)) {
-            // This line spills out of our box in the appropriate direction.  Now we need to see if the line
-            // can be truncated.  In order for truncation to be possible, the line must have sufficient space to
-            // accommodate our truncation string, and no replaced elements (images, tables) can overlap the ellipsis
-            // space.
-            int width = curr == firstRootBox() ? firstLineEllipsisWidth : ellipsisWidth;
-            if (curr->canAccommodateEllipsis(ltr, blockEdge, lineBoxEdge, width))
-                curr->placeEllipsis(ellipsisStr, ltr, blockEdge, width);
-        }
-    }
-}
-
-// For --enable-final
-#undef BIDI_DEBUG
-#undef DEBUG_LINEBREAKS
-#undef DEBUG_LAYOUT
-
-}
diff --git a/khtml/rendering/bidi.h b/khtml/rendering/bidi.h
deleted file mode 100644
index c8776ce19..000000000
--- a/khtml/rendering/bidi.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * This file is part of the html renderer for KDE.
- *
- * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2003 Apple Computer, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-#ifndef BIDI_H
-#define BIDI_H
-
-#include 
-#include "rendering/render_object.h"
-
-namespace khtml {
-    class RenderArena;
-    class RenderBlock;
-    class RenderObject;
-    class InlineBox;
-
-    class BidiContext {
-    public:
-	BidiContext(unsigned char level, TQChar::Direction embedding, BidiContext *parent = 0, bool override = false);
-	~BidiContext();
-
-	void ref() const;
-	void deref() const;
-
-	unsigned char level;
-	bool override : 1;
-	TQChar::Direction dir : 5;
-	TQChar::Direction basicDir : 5;
-
-	BidiContext *parent;
-
-
-	// refcounting....
-	mutable int count;
-    };
-
-    struct BidiRun {
-	BidiRun(int _start, int _stop, RenderObject *_obj, BidiContext *context, TQChar::Direction dir)
-	    :  start( _start ), stop( _stop ), obj( _obj ), box(0), nextRun(0)
-	{
-	    if(dir == TQChar::DirON) dir = context->dir;
-
-	    level = context->level;
-
-	    // add level of run (cases I1 & I2)
-	    if( level % 2 ) {
-		if(dir == TQChar::DirL || dir == TQChar::DirAN || dir == TQChar::DirEN)
-		    level++;
-	    } else {
-		if( dir == TQChar::DirR )
-		    level++;
-		else if( dir == TQChar::DirAN || dir == TQChar::DirEN)
-		    level += 2;
-	    }
-	}
-
-        void detach(RenderArena* renderArena);
-
-        // Overloaded new operator.
-        void* operator new(size_t sz, RenderArena* renderArena) throw();
-
-        // Overridden to prevent the normal delete from being called.
-        void operator delete(void* ptr, size_t sz);
-
-private:
-        // The normal operator new is disallowed.
-        void* operator new(size_t sz) throw();
-
-public:
-	int start;
-	int stop;
-
-        RenderObject *obj;
-        InlineBox* box;
-
-	// explicit + implicit levels here
-	uchar level;
-
-        bool compact : 1;
-
-        BidiRun* nextRun;
-    };
-
-    struct BidiIterator;
-    struct BidiState;
-
-    struct InlineMinMaxIterator
-    {
-    /* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to
-       inline min/max width calculations.  Note the following about the way it walks:
-       (1) Positioned content is skipped (since it does not contribute to min/max width of a block)
-       (2) We do not drill into the children of floats or replaced elements, since you can't break
-           in the middle of such an element.
-       (3) Inline flows (e.g., , , ) are walked twice, since each side can have
-           distinct borders/margin/padding that contribute to the min/max width.
-    */
-        RenderObject* parent;
-        RenderObject* current;
-        bool endOfInline;
-        bool skipPositioned;
-        InlineMinMaxIterator(RenderObject* p, RenderObject* o, bool eOI=false, bool skipPos=true)
-            :parent(p), current(o), endOfInline(eOI), skipPositioned(skipPos) {}
-        inline RenderObject* next();
-    };
-
-    inline RenderObject* InlineMinMaxIterator::next()
-    {
-        RenderObject* result = 0;
-        bool oldEndOfInline = endOfInline;
-        endOfInline = false;
-        while (current != 0 || (current == parent))
-        {
-            //kDebug( 6040 ) << "current = " << current;
-            if (!oldEndOfInline &&
-                (current == parent ||
-                (!current->isFloating() && !current->isReplaced() && !current->isPositioned())))
-                result = current->firstChild();
-            if (!result) {
-                // We hit the end of our inline. (It was empty, e.g., .)
-                if (!oldEndOfInline && current->isInlineFlow()) {
-                    result = current;
-                    endOfInline = true;
-                    break;
-                }
-                while (current && current != parent) {
-                    result = current->nextSibling();
-                    if (result) break;
-                    current = current->parent();
-                    if (current && current != parent && current->isInlineFlow()) {
-                        result = current;
-                        endOfInline = true;
-                        break;
-                    }
-                }
-            }
-
-            if (!result) break;
-
-            if ((!skipPositioned || !result->isPositioned()) && (result->isText() || result->isBR() ||
-                result->isFloatingOrPositioned() || result->isReplaced() || result->isGlyph() || result->isInlineFlow()))
-                break;
-
-            current = result;
-            result = 0;
-        }
-
-        // Update our position.
-        current = result;
-        return current;
-    }
-
-}
-
-#endif
diff --git a/khtml/rendering/break_lines.cpp b/khtml/rendering/break_lines.cpp
deleted file mode 100644
index a0d314cee..000000000
--- a/khtml/rendering/break_lines.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-#include 
-#include 
-#include "tqcstring.h"
-#include 
-#include 
-#include 
-
-
-/* If HAVE_LIBTHAI is defined, libkhtml will link against 
- * libthai since compile time. Otherwise it will try to 
- * dlopen at run-time
- *
- * Ott Pattara Nov 14, 2004
- */
-
-#ifndef HAVE_LIBTHAI
-typedef int (*th_brk_def)(const unsigned char*, int[], int);
-static th_brk_def th_brk;
-#else
-#include 
-#include 
-#endif
-
-namespace khtml {
-    struct ThaiCache
-    {
-        ThaiCache() {
-            string = 0;
-            allocated = 0x400;
-            wbrpos = (int *) malloc(allocated*sizeof(int));
-            numwbrpos = 0;
-            numisbreakable = 0x400;
-            isbreakable = (int *) malloc(numisbreakable*sizeof(int));
-	    library = 0;
-        }
-        ~ThaiCache() {
-            free(wbrpos);
-            free(isbreakable);
-            if (library) library->unload();
-        }
-        const TQChar *string;
-        int *wbrpos;
-        int *isbreakable;
-        int allocated;
-        int numwbrpos,numisbreakable;
-        KLibrary *library;
-    };
-    static ThaiCache *cache = 0;
-
-    void cleanup_thaibreaks()
-    {
-        delete cache;
-        cache = 0;
-#ifndef HAVE_LIBTHAI
-        th_brk = 0;
-#endif
-    }
-
-    bool isBreakableThai( const TQChar *string, const int pos, const int len)
-    {
-        static TQTextCodec *thaiCodec = TQTextCodec::codecForMib(2259);
-	//printf("Entering isBreakableThai with pos = %d\n", pos);
-
-#ifndef HAVE_LIBTHAI
-	
-	KLibrary *lib = 0;
-
-        /* load libthai dynamically */
-	if (( !th_brk ) && thaiCodec  ) {
-	    printf("Try to load libthai dynamically...\n");
-            KLibLoader *loader = KLibLoader::self();
-            lib = loader->library("libthai");
-            if (lib && lib->hasSymbol("th_brk")) {
-                th_brk = (th_brk_def) lib->symbol("th_brk");
-            } else {
-                // indication that loading failed and we shouldn't try to load again
-		printf("Error, can't load libthai...\n");
-                thaiCodec = 0;
-                if (lib)
-                    lib->unload();
-            }
-        }
-
-        if (!th_brk ) {
-            return true;
-        }
-#endif
-
-	if (!cache ) {
-            cache = new ThaiCache;
-#ifndef HAVE_LIBTHAI
-            cache->library = lib;
-#endif
-	}
-
-        // build up string of thai chars
-        if ( string != cache->string ) {
-            //fprintf(stderr,"new string found (not in cache), calling libthai\n");
-            TQCString cstr = thaiCodec->fromUnicode( TQConstString(string,len).string());
-            //printf("About to call libthai::th_brk with str: %s",cstr.data());
-
-            cache->numwbrpos = th_brk((const unsigned char*) cstr.data(), cache->wbrpos, cache->allocated);
-            //fprintf(stderr,"libthai returns with value %d\n",cache->numwbrpos);
-            if (cache->numwbrpos > cache->allocated) {
-                cache->allocated = cache->numwbrpos;
-                cache->wbrpos = (int *)realloc(cache->wbrpos, cache->allocated*sizeof(int));
-                cache->numwbrpos = th_brk((const unsigned char*) cstr.data(), cache->wbrpos, cache->allocated);
-            }
-	    if ( len > cache->numisbreakable ) {
-		cache->numisbreakable=len;
-                cache->isbreakable = (int *)realloc(cache->isbreakable, cache->numisbreakable*sizeof(int));
-	    }
-	    for (int i = 0 ; i < len ; ++i) {
-		cache->isbreakable[i] = 0;
-	    }
-            if ( cache->numwbrpos > 0 ) {
-            	for (int i = cache->numwbrpos-1; i >= 0; --i) {
-                	cache->isbreakable[cache->wbrpos[i]] = 1;
-		}
-	    }
-            cache->string = string;
-        }
-	//printf("Returning %d\n", cache->isbreakable[pos]);
-	return cache->isbreakable[pos];
-    }
-}
diff --git a/khtml/rendering/break_lines.h b/khtml/rendering/break_lines.h
deleted file mode 100644
index 5176e5fb0..000000000
--- a/khtml/rendering/break_lines.h
+++ /dev/null
@@ -1,163 +0,0 @@
-#ifndef BREAK_LINES_H
-#define BREAK_LINES_H
-
-#include 
-
-namespace khtml {
-
-    /*
-      array of unicode codes where breaking shouldn't occur.
-      (in sorted order because of using with binary search)
-      these are currently for Japanese, though simply adding
-      Korean, Chinese ones should work as well
-    */
-    /*
-      dontbreakbefore[] contains characters not covered by TQChar::Punctuation_Close that shouldn't be broken before.
-      chars included in TQChar::Punctuation_Close are listed below.(look at UAX #14)
-         - 3001 ideographic comma
-         - 3002 ideographic full stop
-         - FE50 small comma
-         - FF52 small full stop
-         - FF0C fullwidth comma
-         - FF0E fullwidth full stop
-         - FF61 halfwidth ideographic full stop
-         - FF64 halfwidth ideographic comma
-      these character is commented out.
-    */
-    const ushort dontbreakbefore[] = {
-        //0x3001,   //ideographic comma
-        //0x3002,   //ideographic full stop
-        0x3005, //ideographic iteration mark
-        0x3009, //right angle bracket
-        0x300b, //right double angle bracket
-        0x300d, //right corner bracket
-        0x300f, //right white corner bracket
-        0x3011, //right black lenticular bracket
-        0x3015, //right tortoise shell bracket
-        0x3041, //small a hiragana
-        0x3043, //small i hiragana
-        0x3045, //small u hiragana
-        0x3047, //small e hiragana
-        0x3049, //small o hiragana
-        0x3063, //small tsu hiragana
-        0x3083, //small ya hiragana
-        0x3085, //small yu hiragana
-        0x3087, //small yo hiragana
-        0x308E, //small wa hiragana
-        0x309B, //jap voiced sound mark
-        0x309C, //jap semi-voiced sound mark
-        0x309D, //jap iteration mark hiragana
-        0x309E, //jap voiced iteration mark hiragana
-        0x30A1, //small a katakana
-        0x30A3, //small i katakana
-        0x30A5, //small u katakana
-        0x30A7, //small e katakana
-        0x30A9, //small o katakana
-        0x30C3, //small tsu katakana
-        0x30E3, //small ya katakana
-        0x30E5, //small yu katakana
-        0x30E7, //small yo katakana
-        0x30EE, //small wa katakana
-        0x30F5, //small ka katakana
-        0x30F6, //small ke katakana
-        0x30FC, //jap prolonged sound mark
-        0x30FD, //jap iteration mark katakana
-        0x30FE, //jap voiced iteration mark katakana
-        //0xFE50,   //small comma
-        //0xFF52,   //small full stop
-        0xFF01, //fullwidth exclamation mark
-        0xFF09, //fullwidth right parenthesis
-        //0xFF0C,   //fullwidth comma
-        0xFF0D, //fullwidth hypen-minus
-        //0xFF0E,   //fullwidth full stop
-        0xFF1F, //fullwidth question mark
-        0xFF3D, //fullwidth right square bracket
-        0xFF5D, //fullwidth right curly bracket
-        //0xFF61,   //halfwidth ideographic full stop
-        0xFF63, //halfwidth right corner bracket
-        //0xFF64,   //halfwidth ideographic comma
-        0xFF67, //halfwidth katakana letter small a
-        0xFF68, //halfwidth katakana letter small i
-        0xFF69, //halfwidth katakana letter small u
-        0xFF6a, //halfwidth katakana letter small e
-        0xFF6b, //halfwidth katakana letter small o
-        0xFF6c, //halfwidth katakana letter small ya
-        0xFF6d, //halfwidth katakana letter small yu
-        0xFF6e, //halfwidth katakana letter small yo
-        0xFF6f, //halfwidth katakana letter small tu
-        0xFF70  //halfwidth katakana-hiragana prolonged sound mark
-    };
-
-    // characters that aren't covered by TQChar::Punctuation_Open
-    const ushort dontbreakafter[] = {
-        0x3012, //postal mark
-        0xFF03, //full width pound mark
-        0xFF04, //full width dollar sign
-        0xFF20, //full width @
-        0xFFE1, //full width british pound sign
-        0xFFE5  //full width yen sign
-    };
-
-    inline bool break_bsearch( const ushort* arr, const ushort val ) {
-        int left = 0;
-        int right = (sizeof(arr) / sizeof(ushort)) - 1;
-
-        while (1) {
-            if (left == right)
-                return val != arr[left];
-
-            int i = (left + right) >> 1;
-            if ( val == arr[i] )
-                return false;
-            if ( val < arr[i] )
-                right = i;
-            else
-                left = i + 1;
-        }
-    }
-    
-    bool isBreakableThai( const TQChar *string, const int pos, const int len);
-    void cleanup_thaibreaks();
-
-    inline bool isBreakable( const TQChar *str, const int pos, int len )
-    {
-	const TQChar *c = str+pos;
-	unsigned short ch = c->unicode();
-	if ( ch > 0xff ) {
-	    // not latin1, need to do more sophisticated checks for asian fonts
-	    unsigned char row = c->row();
-	    if ( row == 0x0e ) {
-		// 0e00 - 0e7f == Thai
-		if ( c->cell() < 0x80 ) {
-		    // consult libthai
-		    return isBreakableThai(str, pos, len);
-		} else
-		    return false;
-	    }
-	    if ( row > 0x2d && row < 0xfb || row == 0x11 ) {
-                /* asian line breaking. */
-                if ( pos == 0 )
-                    return false; // never break before first character
-
-                // check for simple punctuation cases
-                TQChar::Category cat = c->category();
-                if ( cat == TQChar::Punctuation_Close ||
-                     cat == TQChar::Punctuation_Other ||
-                     (str+(pos-1))->category() == TQChar::Punctuation_Open )
-                    return false;
-
-                // do binary search in dontbreak[]
-                return break_bsearch(dontbreakbefore, c->unicode()) &&
-                       break_bsearch(dontbreakafter, (str+(pos-1))->unicode());
-            } else // no asian font
-		return c->isSpace();
-	} else {
-	    if ( ch == ' ' || ch == '\n' )
-		return true;
-	}
-	return false;
-    }
-
-}
-
-#endif
diff --git a/khtml/rendering/counter_tree.cpp b/khtml/rendering/counter_tree.cpp
deleted file mode 100644
index 5b178d96e..000000000
--- a/khtml/rendering/counter_tree.cpp
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * This file is part of the HTML rendering engine for KDE.
- *
- * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "rendering/counter_tree.h"
-#include "rendering/render_object.h"
-
-namespace khtml {
-
-CounterNode::CounterNode(RenderObject *o)
-    : m_hasCounters(false), m_isVisual(false),
-      m_value(0), m_count(0), m_parent(0), m_previous(0), m_next(0),
-      m_renderer(o) {}
-
-CounterNode::~CounterNode()
-{
-    if (m_parent) m_parent->removeChild(this);
-}
-
-void CounterNode::insertAfter ( CounterNode *, CounterNode *)
-{
-    Q_ASSERT( false);
-}
-
-void CounterNode::removeChild ( CounterNode *)
-{
-    Q_ASSERT( false);
-}
-
-void CounterNode::remove ()
-{
-    if (m_parent) m_parent->removeChild(this);
-    else {
-        Q_ASSERT(isReset());
-        Q_ASSERT(!firstChild());
-        Q_ASSERT(!lastChild());
-    }
-}
-
-void CounterNode::setHasCounters ()
-{
-    m_hasCounters = true;
-    if (parent())
-        parent()->setHasCounters();
-}
-
-void CounterNode::recount (bool first)
-{
-    int old_count = m_count;
-    if (m_previous)
-        m_count = m_previous->count() + m_value;
-    else {
-        assert(m_parent->firstChild() == this);
-        m_count = m_parent->value() + m_value;
-    }
-    if (old_count != m_count && !first)
-        setSelfDirty();
-    if (old_count != m_count || first) {
-        if (m_parent) m_parent->updateTotal(m_count);
-        if (m_next) m_next->recount();
-    }
-}
-
-void CounterNode::setSelfDirty ()
-{
-    if (m_renderer && m_isVisual)
-        m_renderer->setNeedsLayoutAndMinMaxRecalc();
-}
-
-void CounterNode::setParentDirty ()
-{
-    if (m_renderer && m_isVisual && m_hasCounters)
-        m_renderer->setNeedsLayoutAndMinMaxRecalc();
-}
-
-CounterReset::CounterReset(RenderObject *o) : CounterNode(o), m_total(0), m_first(0), m_last(0) {}
-CounterReset::~CounterReset() {}
-
-void CounterReset::insertAfter ( CounterNode *newChild, CounterNode *refChild )
-{
-    Q_ASSERT( newChild );
-    Q_ASSERT( !refChild || refChild->parent() == this );
-
-    newChild->m_parent = this;
-    newChild->m_previous = refChild;
-
-    if (refChild) {
-        newChild->m_next = refChild->m_next;
-        refChild->m_next = newChild;
-    } else {
-        newChild->m_next = m_first;
-        m_first = newChild;
-    }
-
-    if (newChild->m_next) {
-        assert(newChild->m_next->m_previous == refChild);
-        newChild->m_next->m_previous = newChild;
-    }
-    else {
-        assert (m_last == refChild);
-        m_last = newChild;
-    }
-
-    newChild->recount(true);
-}
-
-void CounterReset::removeChild ( CounterNode *oldChild )
-{
-    Q_ASSERT( oldChild );
-
-    CounterNode* next = oldChild->m_next;
-    CounterNode* prev = oldChild->m_previous;
-
-    if (oldChild->firstChild()) {
-        CounterNode* first = oldChild->firstChild();
-        CounterNode* last = oldChild->lastChild();
-        if (prev) {
-            prev->m_next = first;
-            first->m_previous = prev;
-        }
-        else {
-            assert ( m_first == oldChild );
-            m_first = first;
-         }
-
-        if (next) {
-            next->m_previous = last;
-            last->m_next = next;
-        }
-        else {
-            assert ( m_last == oldChild );
-            m_last = last;
-        }
-
-        next = first;
-        while (next) {
-            next->m_parent = this;
-            if (next == last) break;
-            next = next->m_next;
-        }
-
-        first->recount(true);
-    }
-    else {
-        if (prev) prev->m_next = next;
-        else {
-            assert ( m_first == oldChild );
-            m_first = next;
-        }
-        if (next) next->m_previous = prev;
-        else {
-            assert ( m_last == oldChild );
-            m_last = prev;
-        }
-        if (next)
-            next->recount();
-    }
-
-
-    oldChild->m_next = 0;
-    oldChild->m_previous = 0;
-    oldChild->m_parent = 0;
-}
-
-void CounterReset::recount (bool first)
-{
-    int old_count = m_count;
-    if (m_previous)
-        m_count = m_previous->count();
-    else if (m_parent)
-        m_count = m_parent->value();
-    else
-        m_count = 0;
-
-    updateTotal(m_value);
-    if (!first) setSelfDirty();
-    if (first || m_count != old_count) {
-        if (m_next) m_next->recount();
-    }
-}
-
-void CounterReset::setSelfDirty ()
-{
-    setParentDirty();
-}
-
-void CounterReset::setParentDirty ()
-{
-    if (hasCounters()) {
-        if (m_renderer && m_isVisual) m_renderer->setNeedsLayoutAndMinMaxRecalc();
-        CounterNode* n = firstChild();
-        for(; n; n = n->nextSibling())
-        {
-            n->setParentDirty();
-        }
-    }
-}
-
-void CounterReset::updateTotal (int value)
-{
-    if (value > m_total) m_total = value;
-}
-
-} // namespace
diff --git a/khtml/rendering/counter_tree.h b/khtml/rendering/counter_tree.h
deleted file mode 100644
index 55b924b80..000000000
--- a/khtml/rendering/counter_tree.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * This file is part of the HTML rendering engine for KDE.
- *
- * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-#ifndef _Counter_Tree_h_
-#define _Counter_Tree_h_
-
-#include "misc/shared.h"
-#include "rendering/render_object.h"
-
-namespace khtml {
-
-class CounterReset;
-
-// This file implements a counter-tree that is used for finding all parents in counters() lookup,
-// and for propagating count-changes when nodes are added or removed.
-// Please note that only counter-reset and root can be parents here, and that render-tree parents
-// are just counter-tree siblings
-
-// Implementation of counter-increment and counter-content
-class CounterNode
-{
-public:
-    CounterNode(RenderObject *o);
-    virtual ~CounterNode();
-
-    CounterReset* parent() const { return m_parent; }
-    CounterNode* previousSibling() const { return m_previous; }
-    CounterNode* nextSibling() const { return m_next; }
-    virtual CounterNode* firstChild() const { return 0; } ;
-    virtual CounterNode* lastChild() const { return 0; };
-    virtual void insertAfter ( CounterNode *newChild, CounterNode *refChild );
-    virtual void removeChild ( CounterNode *oldChild );
-    // Convenient self-refering version of the above
-    void remove();
-
-    int value() const { return m_value; };
-    void setValue(short v) { m_value = v; };
-    int count() const { return m_count; };
-
-    virtual bool isReset() { return false; };
-    virtual void recount( bool first = false );
-    virtual void setSelfDirty();
-    virtual void setParentDirty();
-
-    bool hasCounters() const { return m_hasCounters; };
-    bool isVisual() const { return m_isVisual; };
-    void setHasCounters();
-    void setIsVisual() { m_isVisual = true; };
-    bool isRoot() { return m_renderer && m_renderer->isRoot(); };
-
-    void setRenderer(RenderObject *o) { m_renderer = o; };
-    RenderObject* renderer() const { return m_renderer; };
-
-    friend class CounterReset;
-protected:
-    bool m_hasCounters : 1;
-    bool m_isVisual : 1;
-    short m_value;
-    short m_count;
-    CounterReset *m_parent;
-    CounterNode *m_previous;
-    CounterNode *m_next;
-    RenderObject *m_renderer;
-};
-
-// Implementation of counter-reset and root
-class CounterReset : public CounterNode
-{
-public:
-    CounterReset(RenderObject *o);
-    virtual ~CounterReset();
-
-    virtual CounterNode *firstChild() const { return m_first; };
-    virtual CounterNode *lastChild() const { return m_last; };
-    virtual void insertAfter ( CounterNode *newChild, CounterNode *refChild );
-    virtual void removeChild ( CounterNode *oldChild );
-
-    virtual bool isReset() { return true; };
-    virtual void recount( bool first = false );
-    virtual void setSelfDirty();
-    virtual void setParentDirty();
-
-    void updateTotal(int value);
-    // The highest value among children
-    int total() const { return m_total; };
-
-protected:
-    int m_total;
-    CounterNode *m_first;
-    CounterNode *m_last;
-};
-
-} // namespace
-
-#endif
-
diff --git a/khtml/rendering/enumerate.cpp b/khtml/rendering/enumerate.cpp
deleted file mode 100644
index 9cfe149ad..000000000
--- a/khtml/rendering/enumerate.cpp
+++ /dev/null
@@ -1,411 +0,0 @@
-/**
- * This file is part of the HTML rendering engine for KDE.
- *
- * Copyright (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
- *
- *           (C) Hebrew algorithm by herouth@netvision.net.il
- *                               and schlpbch@iam.unibe.ch
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "rendering/enumerate.h"
-
-#include 
-#include 
-
-namespace khtml {
-
-namespace Enumerate {
-
-TQString toRoman( int number, bool upper )
-{
-    if (number < 1 || number > 3999) return TQString::number(number);
-    TQString roman;
-    static const TQChar ldigits[] = { 'i', 'v', 'x', 'l', 'c', 'd', 'm' };
-    static const TQChar udigits[] = { 'I', 'V', 'X', 'L', 'C', 'D', 'M' };
-    const TQChar *digits = upper ? udigits : ldigits;
-    int i, d = 0;
-
-    do
-    {
-        int num = number % 10;
-
-        if ( num % 5 < 4 )
-            for ( i = num % 5; i > 0; i-- )
-                roman.prepend( digits[ d ] );
-
-        if ( num >= 4 && num <= 8)
-            roman.prepend( digits[ d+1 ] );
-
-        if ( num == 9 )
-            roman.prepend( digits[ d+2 ] );
-
-        if ( num % 5 == 4 )
-            roman.prepend( digits[ d ] );
-
-        number /= 10;
-        d += 2;
-    }
-    while ( number );
-
-    return roman;
-}
-
-TQString toGeorgian( int number )
-{
-    TQString georgian;
-    const TQChar tenthousand = 0x10ef;
-    static const TQChar thousands[9] = {0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec,
-                          0x10ed, 0x10ee, 0x10f4, 0x10f5 };
-    static const TQChar hundreds[9] = {0x10e0, 0x10e1, 0x10e2, 0x10e3, 0x10f3,
-                         0x10e4, 0x10e5, 0x10e6, 0x10e7 };
-    static const TQChar tens[9] = {0x10d8, 0x10d9, 0x10da, 0x10db, 0x10dc,
-                     0x10f2, 0x10dd, 0x10de, 0x10df };
-    static const TQChar units[9] = {0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4,
-                      0x10d5, 0x10d6, 0x10f1, 0x10d7 };
-
-    if (number < 1 || number > 19999) return TQString::number(number);
-    if (number >= 10000) {
-        georgian.append(tenthousand);
-        number = number - 10000;
-    }
-    if (number >= 1000) {
-        georgian.append(thousands[number/1000-1]);
-        number = number % 1000;
-    }
-    if (number >= 100) {
-        georgian.append(hundreds[number/100-1]);
-        number = number % 100;
-    }
-    if (number >= 10) {
-        georgian.append(tens[number/10-1]);
-        number = number % 10;
-    }
-    if (number >= 1)  {
-        georgian.append(units[number-1]);
-    }
-
-    return georgian;
-}
-
-TQString toArmenian( int number )
-{
-    TQString armenian;
-    int onethousand = 0x57c;
-    int hundreds = 0x572;
-    int tens = 0x569;
-    int units = 0x560;
-
-    // The standard defines values over 1999, but 7000 is very hard to render
-    if (number < 1 || number > 1999) return TQString::number(number);
-    if (number >= 1000) {
-        armenian.append(TQChar(onethousand));
-        number = number - 1000;
-    }
-    if (number >= 100) {
-        armenian.append(TQChar(hundreds+number/100));
-        number = number % 100;
-    }
-    if (number >= 10) {
-        armenian.append(TQChar(tens+number/10));
-        number = number % 10;
-    }
-    if (number >= 1)  {
-        armenian.append(TQChar(units+number));
-    }
-
-    return armenian;
-}
-
-TQString toHebrew( int number ) {
-    static const TQChar tenDigit[] = {1497, 1499, 1500, 1502, 1504, 1505, 1506, 1508, 1510};
-
-    TQString letter;
-    if (number < 1) return TQString::number(number);
-    if (number>999) {
-  	letter = toHebrew(number/1000) + TQString::fromLatin1("'");
-   	number = number%1000;
-    }
-
-    int hunderts = (number/400);
-    if (hunderts > 0) {
-	for(int i=0; i 0 && !(number == 15 || number == 16)) {
-	letter += tenDigit[tens-1];
-    }
-    if (number == 15 || number == 16) { // special because of religious
-	letter += TQChar(1487 + 9);       // reasons
-    	letter += TQChar(1487 + number - 9);
-    } else {
-        number = number % 10;
-        if (number != 0) {
-            letter += TQChar (1487 + number);
-        }
-    }
-    return letter;
-}
-
-static inline TQString toLatin( int number, int base ) {
-    if (number < 1) return TQString::number(number);
-    TQValueList letters;
-    while(number > 0) {
-        number--; // number 0 is letter a
-        TQChar letter = (TQChar) (base + (number % 26));
-        letters.prepend(letter);
-        number /= 26;
-    }
-    TQString str;
-    str.setLength(letters.size());
-    int i=0;
-    while(!letters.isEmpty()) {
-        str[i++] = letters.front();
-        letters.pop_front();
-    }
-    return str;
-}
-
-TQString toLowerLatin( int number ) {
-    return toLatin( number, 'a' );
-}
-
-TQString toUpperLatin( int number ) {
-    return toLatin( number, 'A' );
-}
-
-static inline TQString toAlphabetic( int number, int base, const TQChar alphabet[] ) {
-    if (number < 1) return TQString::number(number);
-    TQValueList letters;
-    while(number > 0) {
-        number--; // number 0 is letter 1
-        TQChar letter = alphabet[number % base];
-        letters.prepend(letter);
-        number /= base;
-    }
-    TQString str;
-    str.setLength(letters.size());
-    int i=0;
-    while(!letters.isEmpty()) {
-        str[i++] = letters.front();
-        letters.pop_front();
-    }
-    return str;
-}
-
-TQString toHiragana( int number ) {
-    static const TQChar hiragana[48] = {0x3042, 0x3044, 0x3046, 0x3048, 0x304A, 0x304B, 0x304D,
-                                 0x304F, 0x3051, 0x3053, 0x3055, 0x3057, 0x3059, 0x305B, 0x305D,
-                                 0x305F, 0x3061, 0x3064, 0x3066, 0x3068, 0x306A, 0x306B,
-                                 0x306C, 0x306D, 0x306E, 0x306F, 0x3072, 0x3075, 0x3078,
-                                 0x307B, 0x307E, 0x307F, 0x3080, 0x3081, 0x3082, 0x3084, 0x3086,
-                                 0x3088, 0x3089, 0x308A, 0x308B, 0x308C, 0x308D, 0x308F,
-                                 0x3090, 0x3091, 0x9092, 0x3093};
-    return toAlphabetic( number, 48, hiragana );
-}
-
-TQString toHiraganaIroha( int number ) {
-    static const TQChar hiragana[47] = {0x3044, 0x308D, 0x306F, 0x306B, 0x307B, 0x3078, 0x3068,
-                                 0x3061, 0x308A, 0x306C, 0x308B, 0x3092, 0x308F, 0x304B,
-                                 0x3088, 0x305F, 0x308C, 0x305D, 0x3064, 0x306D, 0x306A,
-                                 0x3089, 0x3080, 0x3046, 0x3090, 0x306E, 0x304A, 0x304F, 0x3084,
-                                 0x307E, 0x3051, 0x3075, 0x3053, 0x3048, 0x3066, 0x3042, 0x3055,
-                                 0x304D, 0x3086, 0x3081, 0x307F, 0x3057, 0x3091, 0x3072, 0x3082,
-                                 0x305B, 0x3059 };
-    return toAlphabetic( number, 47, hiragana );
-}
-
-TQString toKatakana( int number ) {
-    static const TQChar katakana[48] = {0x30A2, 0x30A4, 0x30A6, 0x30A8, 0x30AA, 0x30AB, 0x30AD,
-                                 0x30AF, 0x30B1, 0x30B3, 0x30B5, 0x30B7, 0x30B9, 0x30BB,
-                                 0x30BD, 0x30BF, 0x30C1, 0x30C4, 0x30C6, 0x30C8, 0x30CA,
-                                 0x30CB, 0x30CC, 0x30CD, 0x30CE, 0x30CF, 0x30D2, 0x30D5,
-                                 0x30D8, 0x30DB, 0x30DE, 0x30DF, 0x30E0, 0x30E1, 0x30E2,
-                                 0x30E4, 0x30E6, 0x30E8, 0x30E9, 0x30EA, 0x30EB, 0x30EC,
-                                 0x30ED, 0x30EF, 0x30F0, 0x30F1, 0x90F2, 0x30F3};
-    return toAlphabetic( number, 48, katakana );
-}
-
-TQString toKatakanaIroha( int number ) {
-    static const TQChar katakana[47] = {0x30A4, 0x30ED, 0x30CF, 0x30CB, 0x30DB, 0x30D8, 0x30C8,
-                                 0x30C1, 0x30EA, 0x30CC, 0x30EB, 0x30F2, 0x30EF, 0x30AB,
-                                 0x30E8, 0x30BF, 0x30EC, 0x30ED, 0x30C4, 0x30CD, 0x30CA,
-                                 0x30E9, 0x30E0, 0x30A6, 0x30F0, 0x30CE, 0x30AA, 0x30AF,
-                                 0x30E4, 0x30DE, 0x30B1, 0x30D5, 0x30B3, 0x30A8, 0x30C6,
-                                 0x30A2, 0x30B5, 0x30AD, 0x30E6, 0x30E1, 0x30DF, 0x30B7,
-                                 0x30F1, 0x30D2, 0x30E2, 0x30BB, 0x90B9};
-    return toAlphabetic( number, 47, katakana );
-}
-
-TQString toLowerGreek( int number ) {
-    static const TQChar greek[24] = { 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7,
-                               0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE,
-                               0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6,
-                               0x3C7, 0x3C8, 0x3C0};
-
-    return toAlphabetic( number, 24, greek );
-}
-
-TQString toUpperGreek( int number ) {
-    // The standard claims to be base 24, but only lists 19 letters.
-    static const TQChar greek[19] = { 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398,
-                               0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F,
-                               0x3A0, 0x3A1, 0x3A3, 0x3A9};
-
-    return toAlphabetic( number, 19, greek );
-}
-
-static inline TQString toNumeric( int number, int base ) {
-    TQString letter = TQString::number(number);
-    for(unsigned int i = 0; i < letter.length(); i++) {
-        if (letter[i].isDigit())
-        letter[i] = TQChar(letter[i].digitValue()+base);
-    }
-    return letter;
-}
-
-TQString toArabicIndic( int number ) {
-    return toNumeric(number, 0x660);
-}
-
-TQString toPersianUrdu( int number ) {
-    return toNumeric(number, 0x6F0);
-}
-
-TQString toLao( int number ) {
-    return toNumeric(number, 0xED0);
-}
-
-TQString toThai( int number ) {
-    return toNumeric(number, 0xE50);
-}
-
-TQString toTibetan( int number ) {
-    return toNumeric(number, 0xF20);
-}
-
-static inline TQString toIdeographic(int number, const TQChar digits[], const TQChar digitmarkers[]) {
-    if (number < 0 || number > 9999) return TQString::number(number);
-
-    TQString grp = TQString::number(number);
-
-    // ### Append group markers to handle numbers > 9999
-
-    TQString str;
-
-    // special case
-    if (number < 20 && number >= 10) {
-        str.append(digitmarkers[0]);
-        str.append(digits[grp[1].digitValue()]);
-        return str;
-    }
-
-    int len = grp.length();
-    bool collapseZero = false;
-    for (int i = 0; i < len ; i++) {
-        int digit = grp[i].digitValue();
-        // Add digit markers to digits > 0
-        if ((len-i-1) > 0 && digit > 0)
-            str.append(digitmarkers[(len-i-2)]);
-        // Add digit, but collapse consecutive zeros
-        if (!collapseZero || digit > 0) {
-            str.append(digits[digit]);
-
-            if (digit == 0)
-                collapseZero = true;
-            else
-                collapseZero = false;
-        }
-    }
-    return str;
-}
-
-TQString toTradChineseFormal( int number ) {
-//     static const TQChar groupMarkers[3] = {0x4e07, 0x4ebf, 0x5146};
-    static const TQChar digitMarkers[3] = {0x4e07, 0x4ebf, 0x5146};
-    static const TQChar digits[10] = {0x96f6, 0x4e00,
-                                     0x4ebc, 0x4e09,
-                                     0x56db, 0x4e94,
-                                     0x516d, 0x4e03,
-                                     0x516b, 0x4e5d};
-    return toIdeographic(number, digits, digitMarkers);
-}
-
-TQString toTradChineseInformal( int number ) {
-//     static const TQChar groupMarkers[3] = {0x842c, 0x5104, 0x5146};
-    static const TQChar digitMarkers[3] = {0x842c, 0x5104, 0x5146};
-    static const TQChar digits[10] = {0x96f6, 0x4e00,
-                                     0x4ebc, 0x4e09,
-                                     0x56db, 0x4e94,
-                                     0x516d, 0x4e03,
-                                     0x516b, 0x4e5d};
-    return toIdeographic(number, digits, digitMarkers);
-}
-
-TQString toSimpChineseFormal( int number ) {
-//     static const TQChar groupMarkers[3] = {0x4e07, 0x5104, 0x5146};
-    static const TQChar digitMarkers[3] = {0x4e07, 0x4ebf, 0x5146};
-    static const TQChar digits[10] = {0x96f6, 0x58f9,
-                                     0x8cb3, 0x53c3,
-                                     0x8086, 0x4f0d,
-                                     0x9678, 0x67d2,
-                                     0x634c, 0x7396};
-    return toIdeographic(number, digits, digitMarkers);
-}
-
-TQString toSimpChineseInformal( int number ) {
-//     static const TQChar groupMarkers[3] = {0x842c, 0x5104, 0x5146};
-    static const TQChar digitMarkers[3] = {0x842c, 0x5104, 0x5146};
-    static const TQChar digits[10] = {0x96f6, 0x58f9,
-                                     0x8cb3, 0x53c3,
-                                     0x8086, 0x4f0d,
-                                     0x9678, 0x67d2,
-                                     0x634c, 0x7396};
-    return toIdeographic(number, digits, digitMarkers);
-}
-
-TQString toJapaneseFormal( int number ) {
-//     static const TQChar groupMarkers[3] = {0x4e07, 0x5104, 0x5146};
-    static const TQChar digitMarkers[3] = {0x62fe, 0x4f70, 0x4edf};
-    static const TQChar digits[10] = {0x96f6, 0x58f9,
-                                     0x8cb3, 0x53c3,
-                                     0x8086, 0x4f0d,
-                                     0x9678, 0x67d2,
-                                     0x634c, 0x7396};
-    return toIdeographic(number, digits, digitMarkers);
-}
-
-TQString toJapaneseInformal( int number ) {
-//     static const TQChar groupMarkers[3] = {0x842c, 0x5104, 0x5146};
-    static const TQChar digitMarkers[3] = {0x842c, 0x5104, 0x5146};
-    static const TQChar digits[10] = {0x96f6, 0x58f9,
-                                     0x8d30, 0x53c1,
-                                     0x8086, 0x4f0d,
-                                     0x9646, 0x67d2,
-                                     0x634c, 0x7396};
-    return toIdeographic(number, digits, digitMarkers);
-}
-
-}} // namespace
diff --git a/khtml/rendering/enumerate.h b/khtml/rendering/enumerate.h
deleted file mode 100644
index c8df6549a..000000000
--- a/khtml/rendering/enumerate.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * This file is part of the HTML rendering engine for KDE.
- *
- * Copyright (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ENUMERATE_H
-#define ENUMERATE_H
-
-class TQChar;
-class TQString;
-
-namespace khtml {
-
-namespace Enumerate {
-
-// Numeric
-    TQString toArabicIndic( int number );
-    TQString toLao( int number );
-    TQString toPersianUrdu( int number );
-    TQString toThai( int number );
-    TQString toTibetan( int number );
-
-// Alphabetic
-    TQString toLowerLatin( int number );
-    TQString toUpperLatin( int number );
-    TQString toLowerGreek( int number );
-    TQString toUpperGreek( int number );
-    TQString toHiragana( int number );
-    TQString toHiraganaIroha( int number );
-    TQString toKatakana( int number );
-    TQString toKatakanaIroha( int number );
-
-// Algorithmic
-    TQString toRoman( int number, bool upper );
-    TQString toHebrew( int number );
-    TQString toGeorgian( int number );
-    TQString toArmenian( int number );
-
-// Ideographic
-    TQString toJapaneseFormal   ( int number );
-    TQString toJapaneseInformal ( int number );
-    TQString toSimpChineseFormal   ( int number );
-    TQString toSimpChineseInformal ( int number );
-    TQString toTradChineseFormal   ( int number );
-    TQString toTradChineseInformal ( int number );
-
-}} // namespaces
-
-#endif
diff --git a/khtml/rendering/font.cpp b/khtml/rendering/font.cpp
deleted file mode 100644
index 1a0591192..000000000
--- a/khtml/rendering/font.cpp
+++ /dev/null
@@ -1,502 +0,0 @@
-/**
- * This file is part of the html renderer for KDE.
- *
- * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
- *           (C) 1999 Antti Koivisto (koivisto@kde.org)
- *           (C) 2000 Dirk Mueller (mueller@kde.org)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-
-#ifdef HAVE_ALLOCA_H
-#include 
-#endif
-
-#include "font.h"
-#include "khtml_factory.h"
-#include "khtml_settings.h"
-
-#include 
-#include 
-
-#include 
-#include 
-#include 
-
-using namespace khtml;
-
-/** closes the current word and returns its width in pixels
- * @param fm metrics of font to be used
- * @param str string
- * @param pos zero-indexed position within @p str upon which all other
- *	indices are based
- * @param wordStart relative index pointing to the position where the word started
- * @param wordEnd relative index pointing one position after the word ended
- * @return the width in pixels. May be 0 if @p wordStart and @p wordEnd were
- *	equal.
- */
-inline int closeWordAndGetWidth(const TQFontMetrics &fm, const TQChar *str, int pos,
-	int wordStart, int wordEnd)
-{
-    if (wordEnd <= wordStart) return 0;
-
-    TQConstString s(str + pos + wordStart, wordEnd - wordStart);
-    return fm.width(s.string());
-}
-
-/** closes the current word and draws it
- * @param p painter
- * @param d text direction
- * @param x current x position, will be inc-/decremented correctly according
- *	to text direction
- * @param y baseline of text
- * @param widths list of widths; width of word is expected at position
- *		wordStart
- * @param str string
- * @param pos zero-indexed position within @p str upon which all other
- *	indices are based
- * @param wordStart relative index pointing to the position where the word started,
- *	will be set to wordEnd after function
- * @param wordEnd relative index pointing one position after the word ended
- */
-inline void closeAndDrawWord(TQPainter *p, TQPainter::TextDirection d,
-	int &x, int y, const short widths[], const TQChar *str, int pos,
-	int &wordStart, int wordEnd)
-{
-    if (wordEnd <= wordStart) return;
-
-    int width = widths[wordStart];
-    if (d == TQPainter::RTL)
-      x -= width;
-
-    TQConstString s(str + pos + wordStart, wordEnd - wordStart);
-    p->drawText(x, y, s.string(), -1, d);
-
-    if (d != TQPainter::RTL)
-      x += width;
-
-    wordStart = wordEnd;
-}
-
-void Font::drawText( TQPainter *p, int x, int y, TQChar *str, int slen, int pos, int len,
-        int toAdd, TQPainter::TextDirection d, int from, int to, TQColor bg, int uy, int h, int deco ) const
-{
-    if (!str) return;
-    TQConstString cstr = TQConstString(str, slen);
-    TQString qstr = cstr.string();
-
-    // ### fixme for RTL
-    if ( !scFont && !letterSpacing && !wordSpacing && !toAdd && from==-1 ) {
-	// simply draw it
-	// Due to some unfounded cause TQPainter::drawText traverses the
-        // *whole* string when painting, not only the specified
-        // [pos, pos + len) segment. This makes painting *extremely* slow for
-        // long render texts (in the order of several megabytes).
-        // Hence, only hand over the piece of text of the actual inline text box
-	TQConstString cstr = TQConstString(str + pos, len);
-	p->drawText( x, y, cstr.string(), 0, len, d );
-    } else {
-	if (from < 0) from = 0;
-	if (to < 0) to = len;
-
-	int numSpaces = 0;
-	if ( toAdd ) {
-	    for( int i = 0; i < len; ++i )
-		if ( str[i+pos].category() == TQChar::Separator_Space )
-		    ++numSpaces;
-	}
-
-	const int totWidth = width( str, slen, pos, len );
-	if ( d == TQPainter::RTL ) {
-	    x += totWidth + toAdd;
-	}
-	TQString upper = qstr;
-	TQFontMetrics sc_fm = fm;
-	if ( scFont ) {
-	    // draw in small caps
-	    upper = qstr.upper();
-	    sc_fm = TQFontMetrics( *scFont );
-	}
-
-	// ### sc could be optimized by only painting uppercase letters extra,
-	// and treat the rest WordWise, but I think it's not worth it.
-	// Somebody else may volunteer, and implement this ;-) (LS)
-
-	// The mode determines whether the text is displayed character by
-	// character, word by word, or as a whole
-	enum { CharacterWise, WordWise, Whole }
-	mode = Whole;
-	if (!letterSpacing && !scFont && (wordSpacing || toAdd > 0))
-	  mode = WordWise;
-	else if (letterSpacing || scFont)
-	  mode = CharacterWise;
-
-	if (mode == Whole) {	// most likely variant is treated extra
-
-	    if (to < 0) to = len;
-	    const TQConstString cstr(str + pos, len);
-	    const TQConstString segStr(str + pos + from, to - from);
-	    const int preSegmentWidth = fm.width(cstr.string(), from);
-	    const int segmentWidth = fm.width(segStr.string());
-	    const int eff_x = d == TQPainter::RTL ? x - preSegmentWidth - segmentWidth
-					: x + preSegmentWidth;
-
-	    // draw whole string segment, with optional background
-	    if ( bg.isValid() )
-		p->fillRect( eff_x, uy, segmentWidth, h, bg );
-	    p->drawText(eff_x, y, segStr.string(), -1, d);
-	    if (deco)
-	        drawDecoration(p, eff_x, uy, y - uy, segmentWidth - 1, h, deco);
-	    return;
-	}
-
-	// We are using two passes. In the first pass, the widths are collected,
-	// and stored. In the second, the actual characters are drawn.
-
-	// For each letter in the text box, save the width of the character.
-	// When word-wise, only the first letter contains the width, but of the
-	// whole word.
-        short* const widthList = (short *)alloca(to*sizeof(short));
-
-	// First pass: gather widths
-	int preSegmentWidth = 0;
-	int segmentWidth = 0;
-        int lastWordBegin = 0;
-	bool onSegment = from == 0;
-	for( int i = 0; i < to; ++i ) {
-	    if (i == from) {
-                // Also close words on visibility boundary
-	        if (mode == WordWise) {
-	            const int width = closeWordAndGetWidth(fm, str, pos, lastWordBegin, i);
-
-		    if (lastWordBegin < i) {
-		        widthList[lastWordBegin] = (short)width;
-		        lastWordBegin = i;
-		        preSegmentWidth += width;
-		    }
-		}
-		onSegment = true;
-	    }
-
-	    const TQChar ch = str[pos+i];
-	    bool lowercase = (ch.category() == TQChar::Letter_Lowercase);
-	    bool is_space = (ch.category() == TQChar::Separator_Space);
-	    int chw = 0;
-	    if ( letterSpacing )
-		chw += letterSpacing;
-	    if ( (wordSpacing || toAdd) && is_space ) {
-	        if (mode == WordWise) {
-		    const int width = closeWordAndGetWidth(fm, str, pos, lastWordBegin, i);
-		    if (lastWordBegin < i) {
-		        widthList[lastWordBegin] = (short)width;
-			lastWordBegin = i;
-		        (onSegment ? segmentWidth : preSegmentWidth) += width;
-		    }
-		    ++lastWordBegin;		// ignore this space
-		}
-		chw += wordSpacing;
-		if ( numSpaces ) {
-		    const int a = toAdd/numSpaces;
-		    chw += a;
-		    toAdd -= a;
-		    --numSpaces;
-		}
-	    }
-	    if (is_space || mode == CharacterWise) {
-	        chw += lowercase ? sc_fm.charWidth( upper, pos+i ) : fm.charWidth( qstr, pos+i );
-		widthList[i] = (short)chw;
-
-		(onSegment ? segmentWidth : preSegmentWidth) += chw;
-	    }
-
-	}
-
-	// close last word
-	Q_ASSERT(onSegment);
-	if (mode == WordWise) {
-	    const int width = closeWordAndGetWidth(fm, str, pos, lastWordBegin, to);
-	    segmentWidth += width;
-	    widthList[lastWordBegin] = (short)width;
-	}
-
-        if (d == TQPainter::RTL) x -= preSegmentWidth;
-	else x += preSegmentWidth;
-
-        const int startx = d == TQPainter::RTL ? x-segmentWidth : x;
-
-	// optionally draw background
-	if ( bg.isValid() )
-	    p->fillRect( startx, uy, segmentWidth, h, bg );
-
-	// second pass: do the actual drawing
-        lastWordBegin = from;
-	for( int i = from; i < to; ++i ) {
-	    const TQChar ch = str[pos+i];
-	    bool lowercase = (ch.category() == TQChar::Letter_Lowercase);
-	    bool is_space = ch.category() == TQChar::Separator_Space;
-	    if ( is_space ) {
-	        if (mode == WordWise) {
-		    closeAndDrawWord(p, d, x, y, widthList, str, pos, lastWordBegin, i);
-		    ++lastWordBegin;	// jump over space
-		}
-	    }
-	    if (is_space || mode == CharacterWise) {
-	        const int chw = widthList[i];
-	        if (d == TQPainter::RTL)
-		    x -= chw;
-
-		if ( scFont )
-		    p->setFont( lowercase ? *scFont : f );
-		p->drawText( x, y, (lowercase ? upper : qstr), pos+i, 1, d );
-
-	        if (d != TQPainter::RTL)
-		    x += chw;
-	    }
-
-	}
-
-	// don't forget to draw last word
-	if (mode == WordWise) {
-	    closeAndDrawWord(p, d, x, y, widthList, str, pos, lastWordBegin, to);
-	}
-
-	if (deco)
-	    drawDecoration(p, startx, uy, y - uy, segmentWidth - 1, h, deco);
-
-	if ( scFont )
-	    p->setFont( f );
-    }
-}
-
-
-int Font::width( TQChar *chs, int, int pos, int len, int start, int end, int toAdd ) const
-{
-    const TQConstString cstr(chs+pos, len);
-    int w = 0;
-
-    const TQString qstr = cstr.string();
-    if ( scFont ) {
-	const TQString upper = qstr.upper();
-	const TQChar *uc = qstr.unicode();
-	const TQFontMetrics sc_fm( *scFont );
-	for ( int i = 0; i < len; ++i ) {
-	    if ( (uc+i)->category() == TQChar::Letter_Lowercase )
-		w += sc_fm.charWidth( upper, i );
-	    else
-		w += fm.charWidth( qstr, i );
-	}
-    } else {
-	// ### might be a little inaccurate
-	w = fm.width( qstr );
-    }
-
-    if ( letterSpacing )
-	w += len*letterSpacing;
-
-    if ( wordSpacing )
-	// add amount
-	for( int i = 0; i < len; ++i ) {
-	    if( chs[i+pos].category() == TQChar::Separator_Space )
-		w += wordSpacing;
-	}
-
-    if ( toAdd ) {
-        // first gather count of spaces
-        int numSpaces = 0;
-        for( int i = start; i != end; ++i )
-            if ( chs[i].category() == TQChar::Separator_Space )
-                ++numSpaces;
-        // distribute pixels evenly among spaces, but count only those within
-        // [pos, pos+len)
-        for ( int i = start; numSpaces && i != pos + len; i++ )
-            if ( chs[i].category() == TQChar::Separator_Space ) {
-                const int a = toAdd/numSpaces;
-                if ( i >= pos ) w += a;
-                toAdd -= a;
-                --numSpaces;
-            }
-    }
-
-    return w;
-}
-
-int Font::width( TQChar *chs, int slen, int pos ) const
-{
-    int w;
-	if ( scFont && chs[pos].category() == TQChar::Letter_Lowercase ) {
-	    TQString str( chs, slen );
-	    str[pos] = chs[pos].upper();
-	    w = TQFontMetrics( *scFont ).charWidth( str, pos );
-	} else {
-	    const TQConstString cstr( chs, slen );
-	    w = fm.charWidth( cstr.string(), pos );
-	}
-    if ( letterSpacing )
-	w += letterSpacing;
-
-    if ( wordSpacing && (chs+pos)->category() == TQChar::Separator_Space )
-		w += wordSpacing;
-    return w;
-}
-
-/** Querying QFontDB whether something is scalable is expensive, so we cache. */
-struct Font::ScalKey 
-{
-    TQString family;
-    int     weight;
-    int     italic;
-
-    ScalKey(const TQFont& font) : 
-            family(font.family()), weight(font.weight()), italic(font.italic())
-    {}
-
-    ScalKey() {}
-
-    bool operator<(const ScalKey& other) const {
-        if (weight < other.weight)
-            return true;
-        if (weight > other.weight)
-            return false;
-
-        if (italic < other.italic)
-            return true;
-        if (italic > other.italic)
-            return false;
-
-        return family < other.family;
-    }
-
-    bool operator==(const ScalKey& other) const {
-        return (weight == other.weight &&
-                italic == other.italic && 
-                family == other.family);
-    }
-};
-
-TQMap*   Font::scalCache;
-TQMap >* Font::scalSizesCache;
-
-bool Font::isFontScalable(TQFontDatabase& db, const TQFont& font) 
-{
-    if (!scalCache)
-        scalCache = new TQMap;
-
-    ScalKey key(font);
-
-    ScalInfo &s = (*scalCache)[key];
-    if (s == Unknown) {
-        s = db.isSmoothlyScalable(font.family(), db.styleString(font)) ? Yes : No;
-
-        if (s == No) {
-            /* Cache size info */
-            if (!scalSizesCache)
-                scalSizesCache = new TQMap >;
-            (*scalSizesCache)[key] = db.smoothSizes(font.family(), db.styleString(font));
-        }
-    }
-
-    return (s == Yes);
-}
-
-
-void Font::update( TQPaintDeviceMetrics* devMetrics ) const
-{
-    f.setFamily( fontDef.family.isEmpty() ? KHTMLFactory::defaultHTMLSettings()->stdFontName() : fontDef.family );
-    f.setItalic( fontDef.italic );
-    f.setWeight( fontDef.weight );
-
-    TQFontDatabase db;
-
-    int size = fontDef.size;
-    const int lDpiY = kMax(devMetrics->logicalDpiY(), 96);
-
-    // ok, now some magic to get a nice unscaled font
-    // all other font properties should be set before this one!!!!
-    if( !isFontScalable(db, f) )
-    {
-        const TQValueList& pointSizes = (*scalSizesCache)[ScalKey(f)];
-        // lets see if we find a nice looking font, which is not too far away
-        // from the requested one.
-        // kdDebug(6080) << "khtml::setFontSize family = " << f.family() << " size requested=" << size << endl;
-
-
-        float diff = 1; // ### 100% deviation
-        float bestSize = 0;
-
-        TQValueList::ConstIterator it = pointSizes.begin();
-        const TQValueList::ConstIterator itEnd = pointSizes.end();
-
-        for( ; it != itEnd; ++it )
-        {
-            float newDiff = ((*it)*(lDpiY/72.) - float(size))/float(size);
-            //kdDebug( 6080 ) << "smooth font size: " << *it << " diff=" << newDiff << endl;
-            if(newDiff < 0) newDiff = -newDiff;
-            if(newDiff < diff)
-            {
-                diff = newDiff;
-                bestSize = *it;
-            }
-        }
-        //kdDebug( 6080 ) << "best smooth font size: " << bestSize << " diff=" << diff << endl;
-        if ( bestSize != 0 && diff < 0.2 ) // 20% deviation, otherwise we use a scaled font...
-            size = (int)((bestSize*lDpiY) / 72);
-    }
-
-    // make sure we don't bust up X11
-    // Also, Qt does not support sizing a TQFont to zero.
-    size = kMax(1, kMin(255, size));
-
-//       tqDebug("setting font to %s, italic=%d, weight=%d, size=%d", fontDef.family.latin1(), fontDef.italic,
-//    	   fontDef.weight, size );
-
-
-    f.setPixelSize( size );
-
-    fm = TQFontMetrics( f );
-
-    // small caps
-    delete scFont;
-    scFont = 0;
-
-    if ( fontDef.smallCaps ) {
-	scFont = new TQFont( f );
-	scFont->setPixelSize( kMax(1, f.pixelSize()*7/10) );
-    }
-}
-
-void Font::drawDecoration(TQPainter *pt, int _tx, int _ty, int baseline, int width, int height, int deco) const
-{
-    Q_UNUSED(height);
-    // thick lines on small fonts look ugly
-    const int thickness = fm.height() > 20 ? fm.lineWidth() : 1;
-    const TQBrush brush = pt->pen().color();
-    if (deco & UNDERLINE) {
-        int underlineOffset = ( fm.height() + baseline ) / 2;
-        if (underlineOffset <= baseline) underlineOffset = baseline+1;
-
-        pt->fillRect(_tx, _ty + underlineOffset, width + 1, thickness, brush );
-    }
-    if (deco & OVERLINE) {
-        pt->fillRect(_tx, _ty, width + 1, thickness, brush );
-    }
-    if (deco & LINE_THROUGH) {
-        pt->fillRect(_tx, _ty + 2*baseline/3, width + 1, thickness, brush );
-    }
-}
-
diff --git a/khtml/rendering/font.h b/khtml/rendering/font.h
deleted file mode 100644
index 714b03829..000000000
--- a/khtml/rendering/font.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * This file is part of the html renderer for KDE.
- *
- * Copyright (C) 2000-2003 Lars Knoll (knoll@kde.org)
- *           (C) 2000 Antti Koivisto (koivisto@kde.org)
- *           (C) 2000 Dirk Mueller (mueller@kde.org)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef KHTMLFONT_H
-#define KHTMLFONT_H
-
-#include 
-#include 
-#include 
-#include 
-
-class TQFontDatabase;
-class TQPaintDeviceMetrics;
-
-namespace khtml
-{
-class RenderStyle;
-class CSSStyleSelector;
-
-class FontDef
-{
-public:
-    FontDef()
-        : size( 0 ), italic( false ), smallCaps( false ), weight( 50 ) {}
-    bool operator == ( const FontDef &other ) const {
-        return ( family == other.family &&
-                 size == other.size &&
-                 italic == other.italic &&
-                 smallCaps == other.smallCaps &&
-                 weight == other.weight );
-    }
-
-    TQString family;
-    short int size;
-    bool italic 		: 1;
-    bool smallCaps 		: 1;
-    unsigned int weight 		: 8;
-};
-
-
-class Font
-{
-    friend class RenderStyle;
-    friend class CSSStyleSelector;
-
-public:
-    Font() : fontDef(), f(), fm( f ), scFont( 0 ), letterSpacing( 0 ), wordSpacing( 0 ) {}
-    Font( const FontDef &fd )
-        :  fontDef( fd ), f(), fm( f ), scFont( 0 ), letterSpacing( 0 ), wordSpacing( 0 )
-        {}
-    Font(const Font& o)
-        : fontDef(o.fontDef), f(o.f), fm(o.fm), scFont(o.scFont), letterSpacing(o.letterSpacing), wordSpacing(o.wordSpacing) { if (o.scFont) scFont = new TQFont(*o.scFont); }
-    ~Font() { delete scFont; }
-
-    bool operator == ( const Font &other ) const {
-        return (fontDef == other.fontDef &&
-                letterSpacing == other.letterSpacing &&
-                wordSpacing == other.wordSpacing );
-    }
-
-    const FontDef& getFontDef() const { return fontDef; }
-
-    void update( TQPaintDeviceMetrics *devMetrics ) const;
-
-    /**
-     * Draws a piece from the given piece of text.
-     * @param p painter
-     * @param x x-coordinate to begin drawing, always denotes leftmost position
-     * @param y y-coordinate of baseline of text
-     * @param str string to draw a piece from
-     * @param slen total length of string
-     * @param pos zero-based offset of beginning of piece
-     * @param len length of piece
-     * @param width additional pixels to be distributed equally among all
-     *		spaces
-     * @param d text direction
-     * @param from begin with this position relative to @p pos, -1 to start
-     *		at @p pos
-     * @param to stop before this position relative to @p pos, -1 to use full
-     *		length of piece
-     * @param bg if valid, fill the background of the drawn piece with this
-     *		color
-     * @param uy y-coordinate of top position, used for background and text
-     *		decoration painting
-     * @param h total height of line, only used for background and text
-     *		decoration painting
-     * @param deco combined text decoration (see Decoration)
-     */
-    void drawText( TQPainter *p, int x, int y, TQChar *str, int slen, int pos, int len, int width,
-                   TQPainter::TextDirection d, int from=-1, int to=-1, TQColor bg=TQColor(),
-		   int uy=-1, int h=-1, int deco=0 ) const;
-
-    /** returns the width of the given string chunk in pixels.
-     *
-     * The method also considers various styles like text-align and font-variant
-     * @param str pointer to string
-     * @param slen total length of string
-     * @param pos zero-based position in string where to start measuring
-     * @param len count of characters up to which the width should be determined
-     * @param start starting position of inline text box within str, only
-     * used when toAdd is specified.
-     * @param end ending position of inline text box within str, only
-     * used when toAdd is specified.
-     * @param toAdd amount of pixels to distribute evenly among all spaces of
-     * str. Note that toAdd applies to all spaces within str, but only those
-     * within [pos, pos+len) are counted towards the width.
-     */
-    int width( TQChar *str, int slen, int pos, int len, int start = 0, int end = 0, int toAdd = 0 ) const;
-    /** return the width of the given char in pixels.
-     *
-     * The method also considers various styles like text-align and font-variant
-     * @param str pointer to string
-     * @param slen total length of string
-     * @param pos zero-based position of char in string
-     */
-    int width( TQChar *str, int slen, int pos) const;
-
-    /** Text decoration constants.
-     *
-     * The enumeration constant values match those of ETextDecoration, but only
-     * a subset is supported.
-     */
-    enum Decoration { UNDERLINE = 0x1, OVERLINE = 0x2, LINE_THROUGH= 0x4 };
-    // Keep in sync with ETextDecoration
-
-    /** draws text decoration
-     * @param p painter
-     * @param x x-coordinate
-     * @param y top y-coordinate of line box
-     * @param baseline baseline
-     * @param width length of decoration in pixels
-     * @param height height of line box
-     * @param deco decoration to be drawn (see Decoration). The enumeration
-     *		constants may be combined.
-     */
-    void drawDecoration(TQPainter *p, int x, int y, int baseline, int width, int height, int deco) const;
-
-    /** returns letter spacing
-     */
-    int getLetterSpacing() const { return letterSpacing; }
-    /** returns word spacing
-     */
-    int getWordSpacing() const { return wordSpacing; }
-
-private:
-    mutable FontDef fontDef;
-    mutable TQFont f;
-    mutable TQFontMetrics fm;
-    mutable TQFont *scFont;
-    short letterSpacing;
-    short wordSpacing;
-
-    struct ScalKey;
-    enum   ScalInfo {
-        Unknown,
-        No,
-        Yes
-    };
-
-    static TQMap* scalCache;
-    static TQMap >* scalSizesCache;
-    static bool isFontScalable(TQFontDatabase& db, const TQFont& font);
-};
-
-} // namespace
-
-#endif
diff --git a/khtml/rendering/img-loading.png b/khtml/rendering/img-loading.png
deleted file mode 100644
index ae5a9732f..000000000
Binary files a/khtml/rendering/img-loading.png and /dev/null differ
diff --git a/khtml/rendering/loading_icon.cpp b/khtml/rendering/loading_icon.cpp
deleted file mode 100644
index 218befcf8..000000000
--- a/khtml/rendering/loading_icon.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-static const unsigned char loading_icon_data[] = {
-0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,
-0x52,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x10,0x08,0x04,0x00,0x00,0x00,0x8c,
-0x9d,0x86,0xb1,0x00,0x00,0x00,0x04,0x67,0x41,0x4d,0x41,0x00,0x00,0xb1,0x8f,
-0x0b,0xfc,0x61,0x05,0x00,0x00,0x00,0x02,0x62,0x4b,0x47,0x44,0x00,0xff,0x87,
-0x8f,0xcc,0xbf,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x12,
-0x00,0x00,0x0b,0x12,0x01,0xd2,0xdd,0x7e,0xfc,0x00,0x00,0x00,0x07,0x74,0x49,
-0x4d,0x45,0x07,0xd4,0x0c,0x17,0x10,0x00,0x23,0xf3,0x04,0xa4,0xbc,0x00,0x00,
-0x00,0xbf,0x49,0x44,0x41,0x54,0x78,0x9c,0x75,0xd1,0x31,0x4e,0x04,0x31,0x0c,
-0x85,0xe1,0x2f,0xc9,0x1c,0x63,0xee,0x02,0x82,0x9a,0x23,0x70,0x01,0xba,0xad,
-0xe8,0x98,0x0d,0x35,0xab,0xe9,0x10,0xf7,0x80,0x76,0xe0,0x32,0x7b,0x01,0x44,
-0x9d,0x84,0x22,0xc3,0x32,0xd2,0x82,0x5d,0xd9,0xbf,0xf5,0xe4,0x67,0x07,0xd9,
-0x59,0x4c,0xf2,0x04,0x91,0xf6,0x47,0x3e,0x64,0x18,0xe0,0x1d,0x51,0x15,0x05,
-0x05,0xc1,0x5e,0xc8,0x79,0x1a,0xba,0x50,0x54,0x3d,0x49,0x76,0xa2,0xaa,0x61,
-0x4f,0x8e,0x1d,0x05,0xb3,0x1b,0xc5,0xb5,0x2a,0x79,0x14,0x04,0xb9,0xcb,0x06,
-0x45,0xf1,0x2a,0x21,0x2a,0x16,0x5c,0x09,0x1d,0x16,0xd1,0xbd,0x4b,0x2c,0xaa,
-0xa4,0x48,0x4e,0x0b,0xf5,0x58,0x24,0xcd,0x2d,0x38,0x6a,0xdd,0x0a,0xd1,0x41,
-0x41,0x01,0xcf,0xa7,0xf1,0x08,0xd5,0x68,0x16,0x11,0x70,0xe7,0x73,0x0b,0x13,
-0x46,0x07,0x34,0x47,0x47,0x5f,0x2b,0x1c,0xa0,0x81,0xd1,0x6c,0x67,0xd9,0x9c,
-0x71,0xe8,0xb2,0x2f,0x6b,0xf9,0xe6,0x43,0xd0,0xd4,0x5f,0x98,0x2c,0x48,0x9a,
-0xba,0xb6,0x37,0x56,0x2e,0xce,0x1f,0xf3,0x03,0xc3,0x3f,0x88,0x6f,0xc1,0xe0,
-0x3e,0x9e,0x60,0xe9,0x10,0xaa,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,
-0x42,0x60,0x82
-};
-static const unsigned int loading_icon_len = 318;
diff --git a/khtml/rendering/render_applet.cpp b/khtml/rendering/render_applet.cpp
deleted file mode 100644
index fce22f7c8..000000000
--- a/khtml/rendering/render_applet.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/**
- * This file is part of the HTML widget for KDE.
- *
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-#include 
-#include 
-
-#include 
-
-#include "rendering/render_applet.h"
-#include "rendering/render_canvas.h"
-#include "xml/dom_docimpl.h"
-#include "khtmlview.h"
-#include "khtml_part.h"
-
-#include 
-
-#ifndef Q_WS_QWS // We don't have Java in Qt Embedded
-
-#include "java/kjavaappletwidget.h"
-#include "misc/htmltags.h"
-#include "html/html_objectimpl.h"
-
-using namespace khtml;
-using namespace DOM;
-
-RenderApplet::RenderApplet(HTMLElementImpl *applet, const TQMap &args )
-    : RenderWidget(applet)
-{
-    // init RenderObject attributes
-    setInline(true);
-
-    KJavaAppletContext *context = 0;
-    KHTMLView *_view = applet->getDocument()->view();
-    if ( _view ) {
-        KHTMLPart *part = _view->part();
-        context = part->createJavaContext();
-    }
-
-    if ( context ) {
-        //kdDebug(6100) << "RenderApplet::RenderApplet, setting TQWidget" << endl;
-        setQWidget( new KJavaAppletWidget(context, _view->viewport()) );
-        processArguments(args);
-    }
-}
-
-RenderApplet::~RenderApplet()
-{
-}
-
-short RenderApplet::intrinsicWidth() const
-{
-    int rval = 300;
-
-    if( m_widget )
-        rval = ((KJavaAppletWidget*)(m_widget))->sizeHint().width();
-
-    return rval > 10 ? rval : 50;
-}
-
-int RenderApplet::intrinsicHeight() const
-{
-    int rval = 150;
-
-    if( m_widget )
-        rval = m_widget->sizeHint().height();
-
-    return rval > 10 ? rval : 50;
-}
-
-void RenderApplet::layout()
-{
-    //kdDebug(6100) << "RenderApplet::layout" << endl;
-
-    KHTMLAssert( needsLayout() );
-    KHTMLAssert( minMaxKnown() );
-
-    calcWidth();
-    calcHeight();
-
-    KJavaAppletWidget *tmp = static_cast(m_widget);
-    if ( tmp ) {
-        NodeImpl *child = element()->firstChild();
-
-        while(child) {
-
-            if(child->id() == ID_PARAM) {
-                HTMLParamElementImpl *p = static_cast(child);
-                if(tmp->applet())
-                    tmp->applet()->setParameter( p->name(), p->value());
-            }
-            child = child->nextSibling();
-        }
-        //kdDebug(6100) << "setting applet widget to size: " << m_width << ", " << m_height << endl;
-        m_widget->resize(m_width-borderLeft()-borderRight()-paddingLeft()-paddingRight(),
-                         m_height-borderTop()-borderBottom()-paddingTop()-paddingBottom());
-        tmp->showApplet();
-    }
-
-    setNeedsLayout(false);
-}
-
-void RenderApplet::processArguments(const TQMap &args)
-{
-    KJavaAppletWidget *w = static_cast(m_widget);
-    KJavaApplet* applet = w ? w->applet() : 0;
-
-    if ( applet ) {
-        applet->setBaseURL( args[TQString::fromLatin1("baseURL") ] );
-        applet->setAppletClass( args[TQString::fromLatin1("code") ] );
-
-	TQString str = args[TQString::fromLatin1("codeBase") ];
-        if( !str.isEmpty() )
-            applet->setCodeBase( str );
-
-	str = args[TQString::fromLatin1("name") ];
-        if( !str.isNull() )
-            applet->setAppletName( str );
-        else
-            applet->setAppletName( args[TQString::fromLatin1("code") ] );
-
-	str = args[TQString::fromLatin1("archive") ];
-        if( !str.isEmpty() )
-            applet->setArchives( args[TQString::fromLatin1("archive") ] );
-    }
-}
-
-#endif
diff --git a/khtml/rendering/render_applet.h b/khtml/rendering/render_applet.h
deleted file mode 100644
index 184697a7c..000000000
--- a/khtml/rendering/render_applet.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * This file is part of the HTML widget for KDE.
- *
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-#ifndef render_applet_h
-#define render_applet_h
-
-#include "rendering/render_replaced.h"
-#include "html/html_objectimpl.h"
-
-#include 
-#include 
-
-class KHTMLView;
-
-namespace DOM {
-    class HTMLElementImpl;
-}
-
-namespace khtml {
-
-class RenderApplet : public RenderWidget
-{
-public:
-    RenderApplet(DOM::HTMLElementImpl* node, const TQMap &args);
-    virtual ~RenderApplet();
-
-    virtual const char *renderName() const { return "RenderApplet"; }
-
-    virtual void layout();
-    virtual short intrinsicWidth() const;
-    virtual int intrinsicHeight() const;
-    virtual bool isApplet() const { return true; }
-
-    DOM::HTMLElementImpl *element() const
-    { return static_cast(RenderObject::element()); }
-
-private:
-    void processArguments( const TQMap &args );
-};
-
-}
-#endif
diff --git a/khtml/rendering/render_arena.cpp b/khtml/rendering/render_arena.cpp
deleted file mode 100644
index 99fbf4f4d..000000000
--- a/khtml/rendering/render_arena.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2002 Apple Computer, Inc.
- * Copyright (C) 2003 Dirk Mueller (mueller@kde.org)
- *
- * Portions are Copyright (C) 1998 Netscape Communications Corporation.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Alternatively, the contents of this file may be used under the terms
- * of either the Mozilla Public License Version 1.1, found at
- * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
- * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
- * (the "GPL"), in which case the provisions of the MPL or the GPL are
- * applicable instead of those above.  If you wish to allow use of your
- * version of this file only under the terms of one of those two
- * licenses (the MPL or the GPL) and not to allow others to use your
- * version of this file under the LGPL, indicate your decision by
- * deletingthe provisions above and replace them with the notice and
- * other provisions required by the MPL or the GPL, as the case may be.
- * If you do not delete the provisions above, a recipient may use your
- * version of this file under any of the LGPL, the MPL or the GPL.
- */
-
-#include "render_arena.h"
-
-#include 
-#include 
-
-using namespace khtml;
-
-namespace khtml {
-
-//#ifdef NDEBUG
-#define KHTML_USE_ARENA_ALLOCATOR
-//#endif
-
-typedef struct {
-    RenderArena *arena;
-    size_t size;
-} RenderArenaDebugHeader;
-
-#ifdef VALGRIND_SUPPORT
-Arena* findContainingArena(ArenaPool* pool, void* ptr) {
-    uword ptrBits = reinterpret_cast(ptr);
-    for (Arena* a = &pool->first; a; a = a->next)
-        if (ptrBits >= a->base && ptrBits < a->limit)
-            return a;
-    return 0; //Should not happen
-}
-#endif
-
-RenderArena::RenderArena(unsigned int arenaSize)
-{
-    // Initialize the arena pool
-    INIT_ARENA_POOL(&m_pool, "RenderArena", arenaSize);
-
-    // Zero out the recyclers array
-    memset(m_recyclers, 0, sizeof(m_recyclers));
-}
-
-RenderArena::~RenderArena()
-{
-    // Free the arena in the pool and finish using it
-    FreeArenaPool(&m_pool);
-}
-
-void* RenderArena::allocate(size_t size)
-{
-#ifndef KHTML_USE_ARENA_ALLOCATOR
-    // Use standard malloc so that memory debugging tools work.
-    void *block = ::malloc(sizeof(RenderArenaDebugHeader) + size);
-    RenderArenaDebugHeader *header = (RenderArenaDebugHeader *)block;
-    header->arena = this;
-    header->size = size;
-    return header + 1;
-#else
-    void* result = 0;
-
-    // Ensure we have correct alignment for pointers.  Important for Tru64
-    size = KHTML_ROUNDUP(size, sizeof(void*));
-
-    // Check recyclers first
-    if (size < KHTML_MAX_RECYCLED_SIZE) {
-        const int   index = size >> 2;
-
-        result = m_recyclers[index];
-        if (result) {
-#ifdef VALGRIND_SUPPORT
-            VALGRIND_MEMPOOL_ALLOC(findContainingArena(&m_pool, result)->base, result, size);
-#endif
-            // Need to move to the next object
-            void* next = *((void**)result);
-            m_recyclers[index] = next;
-        }
-    }
-
-    if (!result) {
-        // Allocate a new chunk from the arena
-        ARENA_ALLOCATE(result, &m_pool, size);
-    }
-
-    return result;
-#endif
-}
-
-void RenderArena::free(size_t size, void* ptr)
-{
-#ifndef KHTML_USE_ARENA_ALLOCATOR
-    // Use standard free so that memory debugging tools work.
-    assert(this);
-    RenderArenaDebugHeader *header = (RenderArenaDebugHeader *)ptr - 1;
-    assert(header->size == size);
-    assert(header->arena == this);
-    ::free(header);
-#else
-
-#ifdef VALGRIND_SUPPORT
-    VALGRIND_MEMPOOL_FREE(findContainingArena(&m_pool, ptr)->base, ptr);
-#endif
-
-    // Ensure we have correct alignment for pointers.  Important for Tru64
-    size = KHTML_ROUNDUP(size, sizeof(void*));
-
-    // See if it's a size that we recycle
-    if (size < KHTML_MAX_RECYCLED_SIZE) {
-        const int   index = size >> 2;
-        void*       currentTop = m_recyclers[index];
-        m_recyclers[index] = ptr;
-        *((void**)ptr) = currentTop;
-    }
-#endif
-}
-
-}
diff --git a/khtml/rendering/render_arena.h b/khtml/rendering/render_arena.h
deleted file mode 100644
index 786cd208a..000000000
--- a/khtml/rendering/render_arena.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2002 Apple Computer, Inc.
- * Copyright (C) 2003 Dirk Mueller (mueller@kde.org)
- *
- * Portions are Copyright (C) 1998 Netscape Communications Corporation.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Alternatively, the contents of this file may be used under the terms
- * of either the Mozilla Public License Version 1.1, found at
- * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
- * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
- * (the "GPL"), in which case the provisions of the MPL or the GPL are
- * applicable instead of those above.  If you wish to allow use of your
- * version of this file only under the terms of one of those two
- * licenses (the MPL or the GPL) and not to allow others to use your
- * version of this file under the LGPL, indicate your decision by
- * deletingthe provisions above and replace them with the notice and
- * other provisions required by the MPL or the GPL, as the case may be.
- * If you do not delete the provisions above, a recipient may use your
- * version of this file under any of the LGPL, the MPL or the GPL.
- */
-
-#ifndef RENDERARENA_H
-#define RENDERARENA_H
-
-#include "misc/arena.h"
-#include "misc/shared.h"
-
-#include 
-
-namespace khtml {
-
-#define KHTML_MAX_RECYCLED_SIZE 400
-#define KHTML_ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y))
-
-class RenderArena: public Shared {
-public:
-   RenderArena(unsigned int arenaSize = 4096);
-    ~RenderArena();
-
-  // Memory management functions
-  void* allocate(size_t size);
-  void  free(size_t size, void* ptr);
-
-private:
-  // Underlying arena pool
-  ArenaPool m_pool;
-
-  // The recycler array is sparse with the indices being multiples of 4,
-  // i.e., 0, 4, 8, 12, 16, 20, ...
-  void* m_recyclers[KHTML_MAX_RECYCLED_SIZE >> 2];
-};
-
-
-} // namespace
-
-
-#endif
-
diff --git a/khtml/rendering/render_block.cpp b/khtml/rendering/render_block.cpp
deleted file mode 100644
index ccbb6fad0..000000000
--- a/khtml/rendering/render_block.cpp
+++ /dev/null
@@ -1,3155 +0,0 @@
-/*
- * This file is part of the render object implementation for KHTML.
- *
- * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
- *           (C) 1999-2003 Antti Koivisto (koivisto@kde.org)
- *           (C) 2002-2003 Dirk Mueller (mueller@kde.org)
- *           (C) 2003,2005 Apple Computer, Inc.
- *           (C) 2004 Germain Garand (germain@ebooksfrance.org)
- *           (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
- *           (C) 2006 Charles Samuels (charles@kde.org)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-//#define DEBUG
-//#define DEBUG_LAYOUT
-//#define BOX_DEBUG
-//#define FLOAT_DEBUG
-//#define PAGE_DEBUG
-
-#include 
-#include "rendering/render_text.h"
-#include "rendering/render_table.h"
-#include "rendering/render_canvas.h"
-#include "rendering/render_layer.h"
-#include "rendering/render_block.h"
-
-#include "xml/dom_nodeimpl.h"
-#include "xml/dom_docimpl.h"
-#include "html/html_formimpl.h"
-#include "misc/htmltags.h"
-
-#include "khtmlview.h"
-
-using namespace DOM;
-
-namespace khtml {
-
-// -------------------------------------------------------------------------------------------------------
-
-// Our MarginInfo state used when laying out block children.
-RenderBlock::MarginInfo::MarginInfo(RenderBlock* block, int top, int bottom)
-{
-    // Whether or not we can collapse our own margins with our children.  We don't do this
-    // if we had any border/padding (obviously), if we're the root or HTML elements, or if
-    // we're positioned, floating, a table cell.
-    m_canCollapseWithChildren = !block->isCanvas() && !block->isRoot() && !block->isPositioned() &&
-        !block->isFloating() && !block->isTableCell() && !block->hasOverflowClip() && !block->isInlineBlockOrInlineTable();
-
-    m_canCollapseTopWithChildren = m_canCollapseWithChildren && (top == 0) /*&& block->style()->marginTopCollapse() != MSEPARATE */;
-
-    // If any height other than auto is specified in CSS, then we don't collapse our bottom
-    // margins with our children's margins.  To do otherwise would be to risk odd visual
-    // effects when the children overflow out of the parent block and yet still collapse
-    // with it.  We also don't collapse if we have any bottom border/padding.
-    m_canCollapseBottomWithChildren = m_canCollapseWithChildren && (bottom == 0) &&
-        (block->style()->height().isVariable() && block->style()->height().value() == 0) /*&& block->style()->marginBottomCollapse() != MSEPARATE*/;
-
-    m_quirkContainer = block->isTableCell() || block->isBody() /*|| block->style()->marginTopCollapse() == MDISCARD ||
-        block->style()->marginBottomCollapse() == MDISCARD*/;
-
-    m_atTopOfBlock = true;
-    m_atBottomOfBlock = false;
-
-    m_posMargin = m_canCollapseTopWithChildren ? block->maxTopMargin(true) : 0;
-    m_negMargin = m_canCollapseTopWithChildren ? block->maxTopMargin(false) : 0;
-
-    m_selfCollapsingBlockClearedFloat = false;
-
-    m_topQuirk = m_bottomQuirk = m_determinedTopQuirk = false;
-}
-
-// -------------------------------------------------------------------------------------------------------
-
-RenderBlock::RenderBlock(DOM::NodeImpl* node)
-    : RenderFlow(node)
-{
-    m_childrenInline = true;
-    m_floatingObjects = 0;
-    m_positionedObjects = 0;
-    m_firstLine = false;
-    m_avoidPageBreak = false;
-    m_clearStatus = CNONE;
-    m_maxTopPosMargin = m_maxTopNegMargin = m_maxBottomPosMargin = m_maxBottomNegMargin = 0;
-    m_topMarginQuirk = m_bottomMarginQuirk = false;
-    m_overflowHeight = m_overflowWidth = 0;
-    m_overflowLeft = m_overflowTop = 0;
-}
-
-RenderBlock::~RenderBlock()
-{
-    delete m_floatingObjects;
-    delete m_positionedObjects;
-}
-
-void RenderBlock::setStyle(RenderStyle* _style)
-{
-    setReplaced(_style->isDisplayReplacedType());
-
-    RenderFlow::setStyle(_style);
-
-    // ### we could save this call when the change only affected
-    // non inherited properties
-    RenderObject *child = firstChild();
-    while (child != 0)
-    {
-        if (child->isAnonymousBlock())
-        {
-            RenderStyle* newStyle = new RenderStyle();
-            newStyle->inheritFrom(style());
-            newStyle->setDisplay(BLOCK);
-            child->setStyle(newStyle);
-        }
-        child = child->nextSibling();
-    }
-
-    if (attached()) {
-        // Update generated content and ::inside
-        updateReplacedContent();
-        // Update pseudos for :before and :after
-        updatePseudoChildren();
-    }
-
-    // handled by close() during parsing
-    // ### remove close move upto updatePseudo
-    if (!document()->parsing()) {
-        updateFirstLetter();
-    }
-}
-
-// Attach handles initial setStyle that requires parent nodes
-void RenderBlock::attach()
-{
-    RenderFlow::attach();
-
-    updateReplacedContent();
-    updatePseudoChildren();
-}
-
-void RenderBlock::updateFirstLetter()
-{
-    // Only blocks with inline-children can generate a first-letter
-    if (!childrenInline() || !firstChild()) return;
-
-    // Don't recurse
-    if (style()->styleType() == RenderStyle::FIRST_LETTER) return;
-
-    // The first-letter style is inheritable.
-    RenderStyle *pseudoStyle = style()->getPseudoStyle(RenderStyle::FIRST_LETTER);
-    RenderObject *o = this;
-    while (o && !pseudoStyle) {
-        // ### We should ignore empty preceding siblings
-        if (o->parent() && o->parent()->firstChild() == this)
-            o = o->parent();
-        else
-            break;
-        pseudoStyle = o->style()->getPseudoStyle(RenderStyle::FIRST_LETTER);
-    };
-
-    // FIXME: Currently we don't delete first-letters, this is
-    // handled instead in NodeImpl::diff by issuing Detach on first-letter changes.
-    if (!pseudoStyle) {
-        return;
-    }
-
-    // Drill into inlines looking for our first text child.
-    RenderObject* firstText = firstChild();
-    while (firstText && firstText->needsLayout() && !firstText->isFloating() && !firstText->isRenderBlock() && !firstText->isReplaced() && !firstText->isText())
-        // ### We should skip first children with only white-space and punctuation
-        firstText = firstText->firstChild();
-
-    if (firstText && firstText->isText() && !firstText->isBR()) {
-        RenderObject* firstLetterObject = 0;
-        // Find the old first-letter
-        if (firstText->parent()->style()->styleType() == RenderStyle::FIRST_LETTER)
-            firstLetterObject = firstText->parent();
-
-        // Force inline display (except for floating first-letters)
-        pseudoStyle->setDisplay( pseudoStyle->isFloating() ? BLOCK : INLINE);
-        pseudoStyle->setPosition( STATIC ); // CSS2 says first-letter can't be positioned.
-
-        if (firstLetterObject != 0) {
-            firstLetterObject->setStyle( pseudoStyle );
-            RenderStyle* newStyle = new RenderStyle();
-            newStyle->inheritFrom( pseudoStyle );
-            firstText->setStyle( newStyle );
-            return;
-        }
-
-        RenderText* textObj = static_cast(firstText);
-        RenderObject* firstLetterContainer = firstText->parent();
-
-        firstLetterObject = RenderFlow::createFlow(node(), pseudoStyle, renderArena() );
-        firstLetterObject->setIsAnonymous( true );
-        firstLetterContainer->addChild(firstLetterObject, firstLetterContainer->firstChild());
-
-        // if this object is the result of a :begin, then the text may have not been
-        // generated yet if it is a counter
-        if (textObj->recalcMinMax())
-            textObj->recalcMinMaxWidths();
-
-        // The original string is going to be either a generated content string or a DOM node's
-        // string.  We want the original string before it got transformed in case first-letter has
-        // no text-transform or a different text-transform applied to it.
-        DOMStringImpl* oldText = textObj->originalString();
-        if (!oldText)
-            oldText = textObj->string();
-        // ### In theory a first-letter can stretch across multiple text objects, if they only contain
-        // punctuation and white-space
-        if(oldText->l >= 1) {
-            oldText->ref();
-            // begin: we need skip leading whitespace so that RenderBlock::findNextLineBreak
-            // won't think we're continuing from a previous run
-            unsigned int begin = 0; // the position that first-letter begins
-            unsigned int length = 0; // the position that "the rest" begins
-            while ( length < oldText->l && (oldText->s+length)->isSpace() )
-                length++;
-            begin = length;
-            while ( length < oldText->l &&
-                    ( (oldText->s+length)->isPunct()) || (oldText->s+length)->isSpace() )
-                length++;
-            if ( length < oldText->l &&
-                    !( (oldText->s+length)->isSpace() || (oldText->s+length)->isPunct() ))
-                length++;
-            while ( length < oldText->l && (oldText->s+length)->isMark() )
-                length++;
-
-            // we need to generated a remainingText object even if no text is left
-            // because it holds the place and style for the old textObj
-            RenderTextFragment* remainingText =
-                new (renderArena()) RenderTextFragment(textObj->node(), oldText, length, oldText->l-length);
-            remainingText->setIsAnonymous( textObj->isAnonymous() );
-            remainingText->setStyle(textObj->style());
-            if (remainingText->element())
-                remainingText->element()->setRenderer(remainingText);
-
-            RenderObject* nextObj = textObj->nextSibling();
-            textObj->detach();
-            firstLetterContainer->addChild(remainingText, nextObj);
-
-            RenderTextFragment* letter =
-                new (renderArena()) RenderTextFragment(remainingText->node(), oldText, begin, length-begin);
-            letter->setIsAnonymous( remainingText->isAnonymous() );
-            RenderStyle* newStyle = new RenderStyle();
-            newStyle->inheritFrom(pseudoStyle);
-            letter->setStyle(newStyle);
-            firstLetterObject->addChild(letter);
-            oldText->deref();
-        }
-        firstLetterObject->close();
-    }
-}
-
-void RenderBlock::addChildToFlow(RenderObject* newChild, RenderObject* beforeChild)
-{
-    // Make sure we don't append things after :after-generated content if we have it.
-    if ( !beforeChild && lastChild() && lastChild()->style()->styleType() == RenderStyle::AFTER )
-        beforeChild = lastChild();
-
-    bool madeBoxesNonInline = false;
-
-    // If the requested beforeChild is not one of our children, then this is most likely because
-    // there is an anonymous block box within this object that contains the beforeChild. So
-    // just insert the child into the anonymous block box instead of here. This may also be
-    // needed in cases of things like anonymous tables.
-    if (beforeChild && beforeChild->parent() != this) {
-
-        KHTMLAssert(beforeChild->parent());
-
-        // In the special case where we are prepending a block-level element before
-        // something contained inside an anonymous block, we can just prepend it before
-        // the anonymous block.
-        if (!newChild->isInline() && beforeChild->parent()->isAnonymousBlock() &&
-            beforeChild->parent()->parent() == this &&
-            beforeChild->parent()->firstChild() == beforeChild)
-            return addChildToFlow(newChild, beforeChild->parent());
-
-        // Otherwise find our kid inside which the beforeChild is, and delegate to it.
-        // This may be many levels deep due to anonymous tables, table sections, etc.
-        RenderObject* responsible = beforeChild->parent();
-        while (responsible->parent() != this)
-            responsible = responsible->parent();
-
-        return responsible->addChild(newChild,beforeChild);
-    }
-
-    // prevent elements that haven't received a layout yet from getting painted by pushing
-    // them far above the top of the page
-    if (!newChild->isInline())
-        newChild->setPos(newChild->xPos(), -500000);
-
-    if (!newChild->isText() && newChild->style()->position() != STATIC)
-        setOverhangingContents();
-
-    // A block has to either have all of its children inline, or all of its children as blocks.
-    // So, if our children are currently inline and a block child has to be inserted, we move all our
-    // inline children into anonymous block boxes
-    if ( m_childrenInline && !newChild->isInline() && !newChild->isFloatingOrPositioned() )
-    {
-        // This is a block with inline content. Wrap the inline content in anonymous blocks.
-        makeChildrenNonInline(beforeChild);
-        madeBoxesNonInline = true;
-
-        if (beforeChild && beforeChild->parent() != this) {
-            beforeChild = beforeChild->parent();
-            KHTMLAssert(beforeChild->isAnonymousBlock());
-            KHTMLAssert(beforeChild->parent() == this);
-        }
-    }
-    else if (!m_childrenInline && !newChild->isFloatingOrPositioned())
-    {
-        // If we're inserting an inline child but all of our children are blocks, then we have to make sure
-        // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
-        // a new one is created and inserted into our list of children in the appropriate position.
-        if (newChild->isInline()) {
-            if (beforeChild) {
-                if ( beforeChild->previousSibling() && beforeChild->previousSibling()->isAnonymousBlock() ) {
-                    beforeChild->previousSibling()->addChild(newChild);
-                    return;
-                }
-            }
-            else {
-                if ( m_last && m_last->isAnonymousBlock() ) {
-                    m_last->addChild(newChild);
-                    return;
-                }
-            }
-
-            // no suitable existing anonymous box - create a new one
-            RenderBlock* newBox = createAnonymousBlock();
-            RenderBox::addChild(newBox,beforeChild);
-            newBox->addChild(newChild);
-
-            //the above may actually destroy newBox in case an anonymous
-            //table got created, and made the anonymous block redundant.
-            //so look up what to hide indirectly.
-            RenderObject* toHide = newChild;
-            while (toHide->parent() != this)
-                toHide = toHide->parent();
-
-            toHide->setPos(toHide->xPos(), -500000);
-            return;
-        }
-        else {
-            // We are adding another block child... if the current last child is an anonymous box
-            // then it needs to be closed.
-            // ### get rid of the closing thing altogether this will only work during initial parsing
-            if (lastChild() && lastChild()->isAnonymous()) {
-                lastChild()->close();
-            }
-        }
-    }
-
-    RenderBox::addChild(newChild,beforeChild);
-    // ### care about aligned stuff
-
-    if ( madeBoxesNonInline )
-        removeLeftoverAnonymousBoxes();
-}
-
-static void getInlineRun(RenderObject* start, RenderObject* stop,
-                         RenderObject*& inlineRunStart,
-                         RenderObject*& inlineRunEnd)
-{
-    // Beginning at |start| we find the largest contiguous run of inlines that
-    // we can.  We denote the run with start and end points, |inlineRunStart|
-    // and |inlineRunEnd|.  Note that these two values may be the same if
-    // we encounter only one inline.
-    //
-    // We skip any non-inlines we encounter as long as we haven't found any
-    // inlines yet.
-    //
-    // |stop| indicates a non-inclusive stop point.  Regardless of whether |stop|
-    // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered
-    // a non-inline.
-    
-    RenderObject * curr = start;
-    bool sawInline;
-    do {
-        while (curr && !(curr->isInline() || curr->isFloatingOrPositioned()))
-            curr = curr->nextSibling();
-        
-        inlineRunStart = inlineRunEnd = curr;
-        
-        if (!curr)
-            return; // No more inline children to be found.
-        
-        sawInline = curr->isInline();
-        
-        curr = curr->nextSibling();
-        while (curr && (curr->isInline() || curr->isFloatingOrPositioned()) && (curr != stop)) {
-            inlineRunEnd = curr;
-            if (curr->isInline())
-                sawInline = true;
-            curr = curr->nextSibling();
-        }
-    } while (!sawInline);
-
-}
-
-void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
-{
-    // makeChildrenNonInline takes a block whose children are *all* inline and it
-    // makes sure that inline children are coalesced under anonymous
-    // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
-    // the new block child that is causing us to have to wrap all the inlines.  This
-    // means that we cannot coalesce inlines before |insertionPoint| with inlines following
-    // |insertionPoint|, because the new child is going to be inserted in between the inlines,
-    // splitting them.
-    KHTMLAssert(isReplacedBlock() || !isInline());
-    KHTMLAssert(!insertionPoint || insertionPoint->parent() == this);
-
-    m_childrenInline = false;
-
-    RenderObject *child = firstChild();
-
-    while (child) {
-        RenderObject *inlineRunStart, *inlineRunEnd;
-        getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
-
-        if (!inlineRunStart)
-            break;
-
-        child = inlineRunEnd->nextSibling();
-
-        RenderBlock* box = createAnonymousBlock();
-        insertChildNode(box, inlineRunStart);
-        RenderObject* o = inlineRunStart;
-        while(o != inlineRunEnd)
-        {
-            RenderObject* no = o;
-            o = no->nextSibling();
-            box->appendChildNode(removeChildNode(no));
-        }
-        box->appendChildNode(removeChildNode(inlineRunEnd));
-        box->close();
-        box->setPos(box->xPos(), -500000);
-    }
-}
-
-void RenderBlock::makePageBreakAvoidBlocks()
-{
-    KHTMLAssert(!childrenInline());
-    KHTMLAssert(canvas()->pagedMode());
-
-    RenderObject *breakAfter = firstChild();
-    RenderObject *breakBefore = breakAfter ? breakAfter->nextSibling() : 0;
-
-    RenderBlock* pageRun = 0;
-
-    // ### Should follow margin-collapsing rules, skipping self-collapsing blocks
-    // and exporting page-breaks from first/last child when collapsing with parent margin.
-    while (breakAfter) {
-        if (breakAfter->isRenderBlock() && !breakAfter->childrenInline())
-            static_cast(breakAfter)->makePageBreakAvoidBlocks();
-        EPageBreak pbafter = breakAfter->style()->pageBreakAfter();
-        EPageBreak pbbefore = breakBefore ? breakBefore->style()->pageBreakBefore() : PBALWAYS;
-        if ((pbafter == PBAVOID && pbbefore == PBAVOID) ||
-            (pbafter == PBAVOID && pbbefore == PBAUTO) ||
-            (pbafter == PBAUTO && pbbefore == PBAVOID))
-        {
-            if (!pageRun) {
-                pageRun = createAnonymousBlock();
-                pageRun->m_avoidPageBreak = true;
-                pageRun->setChildrenInline(false);
-            }
-            pageRun->appendChildNode(removeChildNode(breakAfter));
-        } else
-        {
-            if (pageRun) {
-                pageRun->appendChildNode(removeChildNode(breakAfter));
-                pageRun->close();
-                insertChildNode(pageRun, breakBefore);
-                pageRun = 0;
-            }
-        }
-        breakAfter = breakBefore;
-        breakBefore = breakBefore ? breakBefore->nextSibling() : 0;
-    }
-
-    // recurse into positioned block children as well.
-    if (m_positionedObjects) {
-        TQPtrListIterator it(*m_positionedObjects);
-        for ( ; it.current(); ++it ) {
-            if (it.current()->isRenderBlock() && !it.current()->childrenInline()) {
-                static_cast(it.current())->makePageBreakAvoidBlocks();
-            }
-        }
-    }
-
-    // recurse into floating block children.
-    if (m_floatingObjects) {
-        TQPtrListIterator it(*m_floatingObjects);
-        for ( ; it.current(); ++it ) {
-            if (it.current()->node->isRenderBlock() && !it.current()->node->childrenInline()) {
-                static_cast(it.current()->node)->makePageBreakAvoidBlocks();
-            }
-        }
-    }
-}
-
-void RenderBlock::removeChild(RenderObject *oldChild)
-{
-    // If this child is a block, and if our previous and next siblings are
-    // both anonymous blocks with inline content, then we can go ahead and
-    // fold the inline content back together.
-    RenderObject* prev = oldChild->previousSibling();
-    RenderObject* next = oldChild->nextSibling();
-    bool mergedBlocks = false;
-    if (document()->renderer() && !isInline() && !oldChild->isInline() && !oldChild->continuation() &&
-        prev && prev->isAnonymousBlock() && prev->childrenInline() &&
-        next && next->isAnonymousBlock() && next->childrenInline()) {
-        // Take all the children out of the |next| block and put them in
-        // the |prev| block.
-        RenderObject* o = next->firstChild();
-        while (o) {
-            RenderObject* no = o;
-            o = no->nextSibling();
-            prev->appendChildNode(next->removeChildNode(no));
-            no->setNeedsLayoutAndMinMaxRecalc();
-        }
-        prev->setNeedsLayoutAndMinMaxRecalc();
-
-        // Nuke the now-empty block.
-        next->detach();
-
-        mergedBlocks = true;
-    }
-
-    RenderFlow::removeChild(oldChild);
-
-    if (mergedBlocks && prev && !prev->previousSibling() && !prev->nextSibling()) {
-        // The remerge has knocked us down to containing only a single anonymous
-        // box.  We can go ahead and pull the content right back up into our
-        // box.
-        RenderObject* anonBlock = removeChildNode(prev);
-        m_childrenInline = true;
-        RenderObject* o = anonBlock->firstChild();
-        while (o) {
-            RenderObject* no = o;
-            o = no->nextSibling();
-            appendChildNode(anonBlock->removeChildNode(no));
-            no->setNeedsLayoutAndMinMaxRecalc();
-        }
-
-        // Nuke the now-empty block.
-        anonBlock->detach();
-    }
-}
-
-bool RenderBlock::isSelfCollapsingBlock() const
-{
-    // We are not self-collapsing if we
-    // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
-    // (b) are a table,
-    // (c) have border/padding,
-    // (d) have a min-height
-    if (m_height > 0 ||
-        isTable() || (borderBottom() + paddingBottom() + borderTop() + paddingTop()) != 0 ||
-        style()->minHeight().value() > 0)
-        return false;
-
-    bool hasAutoHeight = style()->height().isVariable();
-    if (style()->height().isPercent() && !style()->htmlHacks()) {
-        hasAutoHeight = true;
-        for (RenderBlock* cb = containingBlock(); !cb->isCanvas(); cb = cb->containingBlock()) {
-            if (cb->style()->height().isFixed() || cb->isTableCell())
-                hasAutoHeight = false;
-        }
-    }
-
-    // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
-    // on whether we have content that is all self-collapsing or not.
-    if (hasAutoHeight || ((style()->height().isFixed() || style()->height().isPercent()) && style()->height().value() == 0)) {
-        // If the block has inline children, see if we generated any line boxes.  If we have any
-        // line boxes, then we can't be self-collapsing, since we have content.
-        if (childrenInline())
-            return !firstLineBox();
-
-        // Whether or not we collapse is dependent on whether all our normal flow children
-        // are also self-collapsing.
-        for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
-            if (child->isFloatingOrPositioned())
-                continue;
-            if (!child->isSelfCollapsingBlock())
-                return false;
-        }
-        return true;
-    }
-    return false;
-}
-
-void RenderBlock::layout()
-{
-    // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
-    // layoutBlock().
-    layoutBlock(false);
-}
-
-void RenderBlock::layoutBlock(bool relayoutChildren)
-{
-    if (isInline() && !isReplacedBlock()) {
-        setNeedsLayout(false);
-        return;
-    }
-    //    kdDebug( 6040 ) << renderName() << " " << this << "::layoutBlock() start" << endl;
-    //     TQTime t;
-    //     t.start();
-    KHTMLAssert( needsLayout() );
-    KHTMLAssert( minMaxKnown() );
-
-    if (canvas()->pagedMode()) relayoutChildren = true;
-
-    if (!relayoutChildren && posChildNeedsLayout() && !normalChildNeedsLayout() && !selfNeedsLayout()) {
-        // All we have to is lay out our positioned objects.
-        layoutPositionedObjects(relayoutChildren);
-        if (hasOverflowClip())
-            m_layer->checkScrollbarsAfterLayout();
-        setNeedsLayout(false);
-        return;
-    }
-
-    if (markedForRepaint()) {
-        repaintDuringLayout();
-        setMarkedForRepaint(false);
-    }
-
-    int oldWidth = m_width;
-
-    calcWidth();
-    m_overflowWidth = m_width;
-    m_overflowLeft = 0;
-    if (style()->direction() == LTR )
-    {
-        int cw=0;
-        if (style()->textIndent().isPercent())
-            cw = containingBlock()->contentWidth();
-        m_overflowLeft = kMin(0, style()->textIndent().minWidth(cw));
-    }
-
-    if ( oldWidth != m_width )
-        relayoutChildren = true;
-
-    //     kdDebug( 6040 ) << floatingObjects << "," << oldWidth << ","
-    //                     << m_width << ","<< needsLayout() << "," << isAnonymousBox() << ","
-    //                     << overhangingContents() << "," << isPositioned() << endl;
-
-#ifdef DEBUG_LAYOUT
-    kdDebug( 6040 ) << renderName() << "(RenderBlock) " << this << " ::layout() width=" << m_width << ", needsLayout=" << needsLayout() << endl;
-    if(containingBlock() == static_cast(this))
-        kdDebug( 6040 ) << renderName() << ": containingBlock == this" << endl;
-#endif
-
-    clearFloats();
-
-    int previousHeight = m_height;
-    m_height = 0;
-    m_overflowHeight = 0;
-    m_clearStatus = CNONE;
-
-    // We use four values, maxTopPos, maxPosNeg, maxBottomPos, and maxBottomNeg, to track
-    // our current maximal positive and negative margins.  These values are used when we
-    // are collapsed with adjacent blocks, so for example, if you have block A and B
-    // collapsing together, then you'd take the maximal positive margin from both A and B
-    // and subtract it from the maximal negative margin from both A and B to get the
-    // true collapsed margin.  This algorithm is recursive, so when we finish layout()
-    // our block knows its current maximal positive/negative values.
-    //
-    // Start out by setting our margin values to our current margins.  Table cells have
-    // no margins, so we don't fill in the values for table cells.
-    if (!isTableCell()) {
-        initMaxMarginValues();
-
-        m_topMarginQuirk = style()->marginTop().isQuirk();
-        m_bottomMarginQuirk = style()->marginBottom().isQuirk();
-
-        if (element() && element()->id() == ID_FORM && static_cast(element())->isMalformed())
-            // See if this form is malformed (i.e., unclosed). If so, don't give the form
-            // a bottom margin.
-            m_maxBottomPosMargin = m_maxBottomNegMargin = 0;
-    }
-
-    if (scrollsOverflow() && m_layer) {
-        // For overflow:scroll blocks, ensure we have both scrollbars in place always.
-        if (style()->overflowX() == OSCROLL)
-            m_layer->showScrollbar( Qt::Horizontal, true );
-        if (style()->overflowY() == OSCROLL)
-            m_layer->showScrollbar( Qt::Vertical, true );
-    }
-
-    setContainsPageBreak(false);
-
-    if (childrenInline())
-        layoutInlineChildren( relayoutChildren );
-    else
-        layoutBlockChildren( relayoutChildren );
-
-    // Expand our intrinsic height to encompass floats.
-    int toAdd = borderBottom() + paddingBottom();
-    if (m_layer && scrollsOverflowX() && style()->height().isVariable())
-        toAdd += m_layer->horizontalScrollbarHeight();
-    if ( hasOverhangingFloats() && (isFloatingOrPositioned() || flowAroundFloats()) )
-        m_overflowHeight = m_height = floatBottom() + toAdd;
-
-    int oldHeight = m_height;
-    calcHeight();
-    if (oldHeight != m_height) {
-        m_overflowHeight -= toAdd;
-        if (m_layer && scrollsOverflowY()) {
-            // overflow-height only includes padding-bottom when it scrolls
-            m_overflowHeight += paddingBottom();
-        }
-        // If the block got expanded in size, then increase our overflowheight to match.
-        if (m_overflowHeight < m_height)
-            m_overflowHeight = m_height;
-    }
-    if (previousHeight != m_height)
-        relayoutChildren = true;
-
-    if (isTableCell()) {
-        // Table cells need to grow to accommodate both overhanging floats and
-        // blocks that have overflowed content.
-        // Check for an overhanging float first.
-        // FIXME: This needs to look at the last flow, not the last child.
-        if (lastChild() && lastChild()->hasOverhangingFloats() && !lastChild()->hasOverflowClip()) {
-            KHTMLAssert(lastChild()->isRenderBlock());
-            m_height = lastChild()->yPos() + static_cast(lastChild())->floatBottom();
-            m_height += borderBottom() + paddingBottom();
-        }
-
-        if (m_overflowHeight > m_height && !hasOverflowClip())
-            m_height = m_overflowHeight + borderBottom() + paddingBottom();
-    }
-
-    if( hasOverhangingFloats() && ((isFloating() && style()->height().isVariable()) || isTableCell())) {
-        m_height = floatBottom();
-        m_height += borderBottom() + paddingBottom();
-    }
-
-    if (canvas()->pagedMode()) {
-#ifdef PAGE_DEBUG
-        kdDebug(6040) << renderName() << " Page Bottom: " << pageTopAfter(0) << endl;
-        kdDebug(6040) << renderName() << " Bottom: " << m_height << endl;
-#endif
-        bool needsPageBreak = false;
-        int xpage = crossesPageBreak(0, m_height);
-        if (xpage) {
-            needsPageBreak = true;
-#ifdef PAGE_DEBUG
-            kdDebug( 6040 ) << renderName() << " crosses to page " << xpage << endl;
-#endif
-        }
-        if (needsPageBreak && !containsPageBreak()) {
-            setNeedsPageClear(true);
-#ifdef PAGE_DEBUG
-            kdDebug( 6040 ) << renderName() << " marked for page-clear" << endl;
-#endif
-        }
-    }
-
-    layoutPositionedObjects( relayoutChildren );
-
-    // Always ensure our overflow width/height are at least as large as our width/height.
-    m_overflowWidth = kMax(m_overflowWidth, (int)m_width);
-    m_overflowHeight = kMax(m_overflowHeight, m_height);
-
-    // Update our scrollbars if we're overflow:auto/scroll now that we know if
-    // we overflow or not.
-    if (hasOverflowClip() && m_layer)
-        m_layer->checkScrollbarsAfterLayout();
-
-    setNeedsLayout(false);
-}
-
-void RenderBlock::adjustPositionedBlock(RenderObject* child, const MarginInfo& marginInfo)
-{
-    if (child->isBox() && child->hasStaticX()) {
-        if (style()->direction() == LTR)
-            static_cast(child)->setStaticX(borderLeft() + paddingLeft());
-        else
-            static_cast(child)->setStaticX(borderRight() + paddingRight());
-    }
-
-    if (child->isBox() && child->hasStaticY()) {
-        int y = m_height;
-        if (!marginInfo.canCollapseWithTop()) {
-            child->calcVerticalMargins();
-            int marginTop = child->marginTop();
-            int collapsedTopPos = marginInfo.posMargin();
-            int collapsedTopNeg = marginInfo.negMargin();
-            if (marginTop > 0) {
-                if (marginTop > collapsedTopPos)
-                    collapsedTopPos = marginTop;
-            } else {
-                if (-marginTop > collapsedTopNeg)
-                    collapsedTopNeg = -marginTop;
-            }
-            y += (collapsedTopPos - collapsedTopNeg) - marginTop;
-        }
-        static_cast(child)->setStaticY(y);
-    }
-}
-
-void RenderBlock::adjustFloatingBlock(const MarginInfo& marginInfo)
-{
-    // The float should be positioned taking into account the bottom margin
-    // of the previous flow.  We add that margin into the height, get the
-    // float positioned properly, and then subtract the margin out of the
-    // height again.  In the case of self-collapsing blocks, we always just
-    // use the top margins, since the self-collapsing block collapsed its
-    // own bottom margin into its top margin.
-    //
-    // Note also that the previous flow may collapse its margin into the top of
-    // our block.  If this is the case, then we do not add the margin in to our
-    // height when computing the position of the float.   This condition can be tested
-    // for by simply calling canCollapseWithTop.  See
-    // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
-    // an example of this scenario.
-    int marginOffset = marginInfo.canCollapseWithTop() ? 0 : marginInfo.margin();
-    m_height += marginOffset;
-    positionNewFloats();
-    m_height -= marginOffset;
-}
-
-RenderObject* RenderBlock::handleSpecialChild(RenderObject* child, const MarginInfo& marginInfo, CompactInfo& compactInfo, bool& handled)
-{
-    // Handle positioned children first.
-    RenderObject* next = handlePositionedChild(child, marginInfo, handled);
-    if (handled) return next;
-
-    // Handle floating children next.
-    next = handleFloatingChild(child, marginInfo, handled);
-    if (handled) return next;
-
-    // See if we have a compact element.  If we do, then try to tuck the compact element into the margin space of the next block.
-    next = handleCompactChild(child, compactInfo, marginInfo, handled);
-    if (handled) return next;
-
-    // Finally, see if we have a run-in element.
-    return handleRunInChild(child, handled);
-}
-
-RenderObject* RenderBlock::handlePositionedChild(RenderObject* child, const MarginInfo& marginInfo, bool& handled)
-{
-    if (child->isPositioned()) {
-        handled = true;
-        child->containingBlock()->insertPositionedObject(child);
-        adjustPositionedBlock(child, marginInfo);
-        return child->nextSibling();
-    }
-    return 0;
-}
-
-RenderObject* RenderBlock::handleFloatingChild(RenderObject* child, const MarginInfo& marginInfo, bool& handled)
-{
-    if (child->isFloating()) {
-        handled = true;
-        insertFloatingObject(child);
-        adjustFloatingBlock(marginInfo);
-        return child->nextSibling();
-    }
-    return 0;
-}
-
-static inline bool isAnonymousWhitespace( RenderObject* o ) {
-    if (!o->isAnonymous())
-        return false;
-    RenderObject *fc = o->firstChild();
-    return fc && fc == o->lastChild() && fc->isText() && static_cast(fc)->stringLength() == 1 &&
-           static_cast(fc)->text()[0].unicode() == ' ';
-}
-
-RenderObject* RenderBlock::handleCompactChild(RenderObject* child, CompactInfo& compactInfo, const MarginInfo& marginInfo, bool& handled)
-{
-    // FIXME: We only deal with one compact at a time.  It is unclear what should be
-    // done if multiple contiguous compacts are encountered.  For now we assume that
-    // compact A followed by another compact B should simply be treated as block A.
-    if (child->isCompact() && !compactInfo.compact() && (child->childrenInline() || child->isReplaced())) {
-        // Get the next non-positioned/non-floating RenderBlock.
-        RenderObject* next = child->nextSibling();
-        RenderObject* curr = next;
-        while (curr && (curr->isFloatingOrPositioned() || isAnonymousWhitespace(curr)) )
-            curr = curr->nextSibling();
-        if (curr && curr->isRenderBlock() && !curr->isCompact() && !curr->isRunIn()) {
-            curr->calcWidth(); // So that horizontal margins are correct.
-            // Need to compute margins for the child as though it is a block.
-            child->style()->setDisplay(BLOCK);
-            child->calcWidth();
-            child->style()->setDisplay(COMPACT);
-
-            int childMargins = child->marginLeft() + child->marginRight();
-            int margin = style()->direction() == LTR ? curr->marginLeft() : curr->marginRight();
-            if (margin >= (childMargins + child->maxWidth())) {
-                // The compact will fit in the margin.
-                handled = true;
-                compactInfo.set(child, curr);
-                child->layoutIfNeeded();
-                int off = marginInfo.margin();
-                m_height += off + curr->marginTop() < child->marginTop() ?
-                            child->marginTop() - curr->marginTop() -off: 0;
-
-                child->setPos(0,0); // This position will be updated to reflect the compact's
-                                    // desired position and the line box for the compact will
-                                    // pick that position up.
-                return next;
-            }
-        }
-    }
-    return 0;
-}
-
-void RenderBlock::adjustSizeForCompactIfNeeded(RenderObject* child, CompactInfo& compactInfo)
-{
-    // if the compact is bigger than the block it was run into
-    // then "this" block should take the height of the compact
-    if (compactInfo.matches(child)) {
-        // We have a compact child to squeeze in.
-        RenderObject* compactChild = compactInfo.compact();
-        if (compactChild->height() > child->height())
-            m_height += compactChild->height() - child->height();
-    }
-}
-
-void RenderBlock::insertCompactIfNeeded(RenderObject* child, CompactInfo& compactInfo)
-{
-    if (compactInfo.matches(child)) {
-        // We have a compact child to squeeze in.
-        RenderObject* compactChild = compactInfo.compact();
-        int compactXPos = borderLeft() + paddingLeft() + compactChild->marginLeft();
-        if (style()->direction() == RTL) {
-            compactChild->calcWidth(); // have to do this because of the capped maxwidth
-            compactXPos = width() - borderRight() - paddingRight() -
-                compactChild->width() - compactChild->marginRight();
-        }
-
-        int compactYPos = child->yPos() + child->borderTop() + child->paddingTop()
-                            - compactChild->paddingTop() - compactChild->borderTop();
-        int adj = 0;
-        KHTMLAssert(child->isRenderBlock());
-        InlineRunBox *b = static_cast(child)->firstLineBox();
-        InlineRunBox *c = static_cast(compactChild)->firstLineBox();
-        if (b && c) {
-            // adjust our vertical position
-            int vpos = compactChild->getVerticalPosition( true, child );
-            if (vpos == PositionBottom)
-                adj = b->height() > c->height() ? (b->height() + b->yPos() - c->height() - c->yPos()) : 0;
-            else if (vpos == PositionTop)
-                adj = b->yPos() - c->yPos();
-            else
-                adj = vpos;
-            compactYPos += adj;
-        }
-        Length newLineHeight( kMax(compactChild->lineHeight(true)+adj, (int)child->lineHeight(true)), khtml::Fixed);
-        child->style()->setLineHeight( newLineHeight );
-        child->setNeedsLayout( true, false );
-        child->layout();
-
-        compactChild->setPos(compactXPos, compactYPos); // Set the x position.
-        compactInfo.clear();
-    }
-}
-
-RenderObject* RenderBlock::handleRunInChild(RenderObject* child, bool& handled)
-{
-    // See if we have a run-in element with inline children.  If the
-    // children aren't inline, then just treat the run-in as a normal
-    // block.
-    if (child->isRunIn() && (child->childrenInline() || child->isReplaced())) {
-        // Get the next non-positioned/non-floating RenderBlock.
-        RenderObject* curr = child->nextSibling();
-        while (curr && (curr->isFloatingOrPositioned() || isAnonymousWhitespace(curr)) )
-            curr = curr->nextSibling();
-        if (curr && (curr->isRenderBlock() && curr->childrenInline() && !curr->isCompact() && !curr->isRunIn())) {
-            // The block acts like an inline, so just null out its
-            // position.
-            handled = true;
-            child->setInline(true);
-            child->setPos(0,0);
-
-            // Remove the child.
-            RenderObject* next = child->nextSibling();
-            removeChildNode(child);
-
-            // Now insert the child under |curr|.
-            curr->insertChildNode(child, curr->firstChild());
-            return next;
-        }
-    }
-    return 0;
-}
-
-void RenderBlock::collapseMargins(RenderObject* child, MarginInfo& marginInfo, int yPosEstimate)
-{
-    // Get our max pos and neg top margins.
-    int posTop = child->maxTopMargin(true);
-    int negTop = child->maxTopMargin(false);
-
-    // For self-collapsing blocks, collapse our bottom margins into our
-    // top to get new posTop and negTop values.
-    if (child->isSelfCollapsingBlock()) {
-        posTop = kMax(posTop, (int)child->maxBottomMargin(true));
-        negTop = kMax(negTop, (int)child->maxBottomMargin(false));
-    }
-
-    // See if the top margin is quirky. We only care if this child has
-    // margins that will collapse with us.
-    bool topQuirk = child->isTopMarginQuirk() /*|| style()->marginTopCollapse() == MDISCARD*/;
-
-    if (marginInfo.canCollapseWithTop()) {
-        // This child is collapsing with the top of the
-        // block.  If it has larger margin values, then we need to update
-        // our own maximal values.
-        if (!style()->htmlHacks() || !marginInfo.quirkContainer() || !topQuirk) {
-            m_maxTopPosMargin = kMax(posTop, (int)m_maxTopPosMargin);
-            m_maxTopNegMargin = kMax(negTop, (int)m_maxTopNegMargin);
-        }
-
-        // The minute any of the margins involved isn't a quirk, don't
-        // collapse it away, even if the margin is smaller (www.webreference.com
-        // has an example of this, a 
with 0.8em author-specified inside - // a
inside a . - if (!marginInfo.determinedTopQuirk() && !topQuirk && (posTop-negTop)) { - m_topMarginQuirk = false; - marginInfo.setDeterminedTopQuirk(true); - } - - if (!marginInfo.determinedTopQuirk() && topQuirk && marginTop() == 0) - // We have no top margin and our top child has a quirky margin. - // We will pick up this quirky margin and pass it through. - // This deals with the

case. - // Don't do this for a block that split two inlines though. You do - // still apply margins in this case. - m_topMarginQuirk = true; - } - - if (marginInfo.quirkContainer() && marginInfo.atTopOfBlock() && (posTop - negTop)) - marginInfo.setTopQuirk(topQuirk); - - int ypos = m_height; - if (child->isSelfCollapsingBlock()) { - // This child has no height. We need to compute our - // position before we collapse the child's margins together, - // so that we can get an accurate position for the zero-height block. - int collapsedTopPos = kMax(marginInfo.posMargin(), (int)child->maxTopMargin(true)); - int collapsedTopNeg = kMax(marginInfo.negMargin(), (int)child->maxTopMargin(false)); - marginInfo.setMargin(collapsedTopPos, collapsedTopNeg); - - // Now collapse the child's margins together, which means examining our - // bottom margin values as well. - marginInfo.setPosMarginIfLarger(child->maxBottomMargin(true)); - marginInfo.setNegMarginIfLarger(child->maxBottomMargin(false)); - - if (!marginInfo.canCollapseWithTop()) - // We need to make sure that the position of the self-collapsing block - // is correct, since it could have overflowing content - // that needs to be positioned correctly (e.g., a block that - // had a specified height of 0 but that actually had subcontent). - ypos = m_height + collapsedTopPos - collapsedTopNeg; - } - else { -#ifdef APPLE_CHANGES - if (child->style()->marginTopCollapse() == MSEPARATE) { - m_height += marginInfo.margin() + child->marginTop(); - ypos = m_height; - } - else -#endif - if (!marginInfo.atTopOfBlock() || - (!marginInfo.canCollapseTopWithChildren() - && (!style()->htmlHacks() || !marginInfo.quirkContainer() || !marginInfo.topQuirk()))) { - // We're collapsing with a previous sibling's margins and not - // with the top of the block. - m_height += kMax(marginInfo.posMargin(), posTop) - kMax(marginInfo.negMargin(), negTop); - ypos = m_height; - } - - marginInfo.setPosMargin(child->maxBottomMargin(true)); - marginInfo.setNegMargin(child->maxBottomMargin(false)); - - if (marginInfo.margin()) - marginInfo.setBottomQuirk(child->isBottomMarginQuirk() /*|| style()->marginBottomCollapse() == MDISCARD*/); - - marginInfo.setSelfCollapsingBlockClearedFloat(false); - } - - child->setPos(child->xPos(), ypos); - if (ypos != yPosEstimate) { - if (child->style()->width().isPercent() && child->usesLineWidth()) - // The child's width is a percentage of the line width. - // When the child shifts to clear an item, its width can - // change (because it has more available line width). - // So go ahead and mark the item as dirty. - child->setChildNeedsLayout(true); - - if (!child->flowAroundFloats() && child->hasFloats()) - child->markAllDescendantsWithFloatsForLayout(); - - // Our guess was wrong. Make the child lay itself out again. - child->layoutIfNeeded(); - } -} - -void RenderBlock::clearFloatsIfNeeded(RenderObject* child, MarginInfo& marginInfo, int oldTopPosMargin, int oldTopNegMargin) -{ - int heightIncrease = getClearDelta(child); - if (heightIncrease) { - // The child needs to be lowered. Move the child so that it just clears the float. - child->setPos(child->xPos(), child->yPos() + heightIncrease); - - // Increase our height by the amount we had to clear. - bool selfCollapsing = child->isSelfCollapsingBlock(); - if (!selfCollapsing) - m_height += heightIncrease; - else { - // For self-collapsing blocks that clear, they may end up collapsing - // into the bottom of the parent block. We simulate this behavior by - // setting our positive margin value to compensate for the clear. - marginInfo.setPosMargin(kMax(0, child->yPos() - m_height)); - marginInfo.setNegMargin(0); - marginInfo.setSelfCollapsingBlockClearedFloat(true); - } - - if (marginInfo.canCollapseWithTop()) { - // We can no longer collapse with the top of the block since a clear - // occurred. The empty blocks collapse into the cleared block. - // FIXME: This isn't quite correct. Need clarification for what to do - // if the height the cleared block is offset by is smaller than the - // margins involved. - m_maxTopPosMargin = oldTopPosMargin; - m_maxTopNegMargin = oldTopNegMargin; - marginInfo.setAtTopOfBlock(false); - } - - // If our value of clear caused us to be repositioned vertically to be - // underneath a float, we might have to do another layout to take into account - // the extra space we now have available. - if (!selfCollapsing && !child->style()->width().isFixed() && child->usesLineWidth()) - // The child's width is a percentage of the line width. - // When the child shifts to clear an item, its width can - // change (because it has more available line width). - // So go ahead and mark the item as dirty. - child->setChildNeedsLayout(true); - if (!child->flowAroundFloats() && child->hasFloats()) - child->markAllDescendantsWithFloatsForLayout(); - child->layoutIfNeeded(); - } -} - -bool RenderBlock::canClear(RenderObject *child, PageBreakLevel level) -{ - KHTMLAssert(child->parent() && child->parent() == this); - KHTMLAssert(canvas()->pagedMode()); - - // Positioned elements cannot be moved. Only normal flow and floating. - if (child->isPositioned() || child->isRelPositioned()) return false; - - switch(level) { - case PageBreakNormal: - // check page-break-inside: avoid - if (!style()->pageBreakInside()) - // we cannot, but can our parent? - if(!parent()->canClear(this, level)) return false; - case PageBreakHarder: - // check page-break-after/before: avoid - if (m_avoidPageBreak) - // we cannot, but can our parent? - if(!parent()->canClear(this, level)) return false; - case PageBreakForced: - // child is larger than page-height and is forced to break - if(child->height() > canvas()->pageHeight()) return false; - return true; - } - assert(false); - return false; -} - -void RenderBlock::clearPageBreak(RenderObject* child, int pageBottom) -{ - KHTMLAssert(child->parent() && child->parent() == this); - KHTMLAssert(canvas()->pagedMode()); - - if (child->yPos() >= pageBottom) return; - - int heightIncrease = 0; - - heightIncrease = pageBottom - child->yPos(); - - // ### should never happen, canClear should have been called to detect it. - if (child->height() > canvas()->pageHeight()) { - kdDebug(6040) << "### child is too large to clear: " << child->height() << " > " << canvas()->pageHeight() << endl; - return; - } - - // The child needs to be lowered. Move the child so that it just clears the break. - child->setPos(child->xPos(), pageBottom); - -#ifdef PAGE_DEBUG - kdDebug(6040) << "Cleared block " << heightIncrease << "px" << endl; -#endif - - // Increase our height by the amount we had to clear. - m_height += heightIncrease; - - // We might have to do another layout to take into account - // the extra space we now have available. - if (!child->style()->width().isFixed() && child->usesLineWidth()) - // The child's width is a percentage of the line width. - // When the child shifts to clear a page-break, its width can - // change (because it has more available line width). - // So go ahead and mark the item as dirty. - child->setChildNeedsLayout(true); - if (!child->flowAroundFloats() && child->hasFloats()) - child->markAllDescendantsWithFloatsForLayout(); - if (child->containsPageBreak()) - child->setNeedsLayout(true); - child->layoutIfNeeded(); - - child->setAfterPageBreak(true); -} - -int RenderBlock::estimateVerticalPosition(RenderObject* child, const MarginInfo& marginInfo) -{ - // FIXME: We need to eliminate the estimation of vertical position, because - // when it's wrong we sometimes trigger a pathological relayout if there are - // intruding floats. - int yPosEstimate = m_height; - if (!marginInfo.canCollapseWithTop()) { - int childMarginTop = child->selfNeedsLayout() ? child->marginTop() : child->collapsedMarginTop(); - yPosEstimate += kMax(marginInfo.margin(), childMarginTop); - } - return yPosEstimate; -} - -void RenderBlock::determineHorizontalPosition(RenderObject* child) -{ - if (style()->direction() == LTR) { - int xPos = borderLeft() + paddingLeft(); - - // Add in our left margin. - int chPos = xPos + child->marginLeft(); - - // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats. They need - // to shift over as necessary to dodge any floats that might get in the way. - if (child->flowAroundFloats()) { - int leftOff = leftOffset(m_height); - if (style()->textAlign() != KHTML_CENTER && !child->style()->marginLeft().isVariable()) { - if (child->marginLeft() < 0) - leftOff += child->marginLeft(); - chPos = kMax(chPos, leftOff); // Let the float sit in the child's margin if it can fit. - } - else if (leftOff != xPos) { - // The object is shifting right. The object might be centered, so we need to - // recalculate our horizontal margins. Note that the containing block content - // width computation will take into account the delta between |leftOff| and |xPos| - // so that we can just pass the content width in directly to the |calcHorizontalMargins| - // function. - static_cast(child)->calcHorizontalMargins(child->style()->marginLeft(), child->style()->marginRight(), lineWidth(child->yPos())); - chPos = leftOff + child->marginLeft(); - } - } - - child->setPos(chPos, child->yPos()); - } else { - int xPos = m_width - borderRight() - paddingRight(); - if (m_layer && scrollsOverflowY()) - xPos -= m_layer->verticalScrollbarWidth(); - int chPos = xPos - (child->width() + child->marginRight()); - if (child->flowAroundFloats()) { - int rightOff = rightOffset(m_height); - if (style()->textAlign() != KHTML_CENTER && !child->style()->marginRight().isVariable()) { - if (child->marginRight() < 0) - rightOff -= child->marginRight(); - chPos = kMin(chPos, rightOff - child->width()); // Let the float sit in the child's margin if it can fit. - } else if (rightOff != xPos) { - // The object is shifting left. The object might be centered, so we need to - // recalculate our horizontal margins. Note that the containing block content - // width computation will take into account the delta between |rightOff| and |xPos| - // so that we can just pass the content width in directly to the |calcHorizontalMargins| - // function. - static_cast(child)->calcHorizontalMargins(child->style()->marginLeft(), child->style()->marginRight(), lineWidth(child->yPos())); - chPos = rightOff - child->marginRight() - child->width(); - } - } - child->setPos(chPos, child->yPos()); - } -} - -void RenderBlock::setCollapsedBottomMargin(const MarginInfo& marginInfo) -{ - if (marginInfo.canCollapseWithBottom() && !marginInfo.canCollapseWithTop()) { - // Update our max pos/neg bottom margins, since we collapsed our bottom margins - // with our children. - m_maxBottomPosMargin = kMax((int)m_maxBottomPosMargin, marginInfo.posMargin()); - m_maxBottomNegMargin = kMax((int)m_maxBottomNegMargin, marginInfo.negMargin()); - - if (!marginInfo.bottomQuirk()) - m_bottomMarginQuirk = false; - - if (marginInfo.bottomQuirk() && marginBottom() == 0) - // We have no bottom margin and our last child has a quirky margin. - // We will pick up this quirky margin and pass it through. - // This deals with the

case. - m_bottomMarginQuirk = true; - } -} - -void RenderBlock::handleBottomOfBlock(int top, int bottom, MarginInfo& marginInfo) -{ - // If our last flow was a self-collapsing block that cleared a float, then we don't - // collapse it with the bottom of the block. - if (!marginInfo.selfCollapsingBlockClearedFloat()) - marginInfo.setAtBottomOfBlock(true); - - // If we can't collapse with children then go ahead and add in the bottom margin. - if (!marginInfo.canCollapseWithBottom() && !marginInfo.canCollapseWithTop() - && (!style()->htmlHacks() || !marginInfo.quirkContainer() || !marginInfo.bottomQuirk())) - m_height += marginInfo.margin(); - - // Now add in our bottom border/padding. - m_height += bottom; - - // Negative margins can cause our height to shrink below our minimal height (border/padding). - // If this happens, ensure that the computed height is increased to the minimal height. - m_height = kMax(m_height, top + bottom); - - // Always make sure our overflow height is at least our height. - m_overflowHeight = kMax(m_height, m_overflowHeight); - - // Update our bottom collapsed margin info. - setCollapsedBottomMargin(marginInfo); -} - -void RenderBlock::layoutBlockChildren( bool relayoutChildren ) -{ -#ifdef DEBUG_LAYOUT - kdDebug( 6040 ) << renderName() << " layoutBlockChildren( " << this <<" ), relayoutChildren="<< relayoutChildren << endl; -#endif - - int top = borderTop() + paddingTop(); - int bottom = borderBottom() + paddingBottom(); - if (m_layer && scrollsOverflowX() && style()->height().isVariable()) - bottom += m_layer->horizontalScrollbarHeight(); - - m_height = m_overflowHeight = top; - - // The margin struct caches all our current margin collapsing state. - // The compact struct caches state when we encounter compacts. - MarginInfo marginInfo(this, top, bottom); - CompactInfo compactInfo; - - // Fieldsets need to find their legend and position it inside the border of the object. - // The legend then gets skipped during normal layout. - RenderObject* legend = layoutLegend(relayoutChildren); - - PageBreakInfo pageBreakInfo(pageTopAfter(0)); - - RenderObject* child = firstChild(); - while( child != 0 ) - { - if (legend == child) { - child = child->nextSibling(); - continue; // Skip the legend, since it has already been positioned up in the fieldset's border. - } - - int oldTopPosMargin = m_maxTopPosMargin; - int oldTopNegMargin = m_maxTopNegMargin; - - // make sure we relayout children if we need it. - if (!child->isPositioned() && (relayoutChildren || - (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())) || - (child->isRenderBlock() && child->style()->height().isPercent()) || - (child->isBody() && child->style()->htmlHacks()))) - { - child->setChildNeedsLayout(true); - } - - // Handle the four types of special elements first. These include positioned content, floating content, compacts and - // run-ins. When we encounter these four types of objects, we don't actually lay them out as normal flow blocks. - bool handled = false; - RenderObject* next = handleSpecialChild(child, marginInfo, compactInfo, handled); - if (handled) { child = next; continue; } - - // The child is a normal flow object. Compute its vertical margins now. - child->calcVerticalMargins(); - -#ifdef APPLE_CHANGES /* margin-*-collapse not merged yet */ - // Do not allow a collapse if the margin top collapse style is set to SEPARATE. - if (child->style()->marginTopCollapse() == MSEPARATE) { - marginInfo.setAtTopOfBlock(false); - marginInfo.clearMargin(); - } -#endif - - // Try to guess our correct y position. In most cases this guess will - // be correct. Only if we're wrong (when we compute the real y position) - // will we have to potentially relayout. - int yPosEstimate = estimateVerticalPosition(child, marginInfo); - - // If an element might be affected by the presence of floats, then always mark it for - // layout. - if ( !child->flowAroundFloats() || child->usesLineWidth() ) { - int fb = floatBottom(); - if (fb > m_height || fb > yPosEstimate) - child->setChildNeedsLayout(true); - } - - // Go ahead and position the child as though it didn't collapse with the top. - child->setPos(child->xPos(), yPosEstimate); - child->layoutIfNeeded(); - - // Now determine the correct ypos based on examination of collapsing margin - // values. - collapseMargins(child, marginInfo, yPosEstimate); - - // Now check for clear. - clearFloatsIfNeeded(child, marginInfo, oldTopPosMargin, oldTopNegMargin); - - // We are no longer at the top of the block if we encounter a non-empty child. - // This has to be done after checking for clear, so that margins can be reset if a clear occurred. - if (marginInfo.atTopOfBlock() && !child->isSelfCollapsingBlock()) - marginInfo.setAtTopOfBlock(false); - - // Now place the child in the correct horizontal position - determineHorizontalPosition(child); - - adjustSizeForCompactIfNeeded(child, compactInfo); - // Update our height now that the child has been placed in the correct position. - m_height += child->height(); - -#ifdef APPLE_CHANGES - if (child->style()->marginBottomCollapse() == MSEPARATE) { - m_height += child->marginBottom(); - marginInfo.clearMargin(); - } -#endif - - // Check for page-breaks - if (canvas()->pagedMode()) - clearChildOfPageBreaks(child, pageBreakInfo, marginInfo); - - if (child->hasOverhangingFloats() && !child->flowAroundFloats()) { - // need to add the child's floats to our floating objects list, but not in the case where - // overflow is auto/scroll - addOverHangingFloats( static_cast(child), -child->xPos(), -child->yPos(), true ); - } - - // See if this child has made our overflow need to grow. - int effX = child->effectiveXPos(); - int effY = child->effectiveYPos(); - m_overflowWidth = kMax(effX + child->effectiveWidth(), m_overflowWidth); - m_overflowLeft = kMin(effX, m_overflowLeft); - m_overflowHeight = kMax(effY + child->effectiveHeight(), m_overflowHeight); - m_overflowTop = kMin(effY, m_overflowTop); - - // Insert our compact into the block margin if we have one. - insertCompactIfNeeded(child, compactInfo); - - child = child->nextSibling(); - } - - // The last child had forced page-break-after - if (pageBreakInfo.forcePageBreak()) - m_height = pageBreakInfo.pageBottom(); - - // Now do the handling of the bottom of the block, adding in our bottom border/padding and - // determining the correct collapsed bottom margin information. - handleBottomOfBlock(top, bottom, marginInfo); - - setNeedsLayout(false); -} - -void RenderBlock::clearChildOfPageBreaks(RenderObject *child, PageBreakInfo &pageBreakInfo, MarginInfo &marginInfo) -{ - (void)marginInfo; - int childTop = child->yPos(); - int childBottom = child->yPos()+child->height(); -#ifdef PAGE_DEBUG - kdDebug(6040) << renderName() << " ChildTop: " << childTop << " ChildBottom: " << childBottom << endl; -#endif - - bool forcePageBreak = pageBreakInfo.forcePageBreak() || child->style()->pageBreakBefore() == PBALWAYS; -#ifdef PAGE_DEBUG - if (forcePageBreak) - kdDebug(6040) << renderName() << "Forced break required" << endl; -#endif - - int xpage = crossesPageBreak(childTop, childBottom); - if (xpage || forcePageBreak) - { - if (!forcePageBreak && child->containsPageBreak() && !child->needsPageClear()) { -#ifdef PAGE_DEBUG - kdDebug(6040) << renderName() << " Child contains page-break to page " << xpage << endl; -#endif - // ### Actually this assumes floating children are breaking/clearing - // nicely as well. - setContainsPageBreak(true); - } - else { - bool doBreak = true; - // don't break before the first child or when page-break-inside is avoid - if (!forcePageBreak && (!style()->pageBreakInside() || m_avoidPageBreak || child == firstChild())) { - if (parent()->canClear(this, (m_avoidPageBreak) ? PageBreakHarder : PageBreakNormal )) { -#ifdef PAGE_DEBUG - kdDebug(6040) << renderName() << "Avoid page-break inside" << endl; -#endif - child->setNeedsPageClear(false); - setNeedsPageClear(true); - doBreak = false; - } -#ifdef PAGE_DEBUG - else - kdDebug(6040) << renderName() << "Ignoring page-break avoid" << endl; -#endif - } - if (doBreak) { -#ifdef PAGE_DEBUG - kdDebug(6040) << renderName() << " Clearing child of page-break" << endl; - kdDebug(6040) << renderName() << " child top of page " << xpage << endl; -#endif - clearPageBreak(child, pageBreakInfo.pageBottom()); - child->setNeedsPageClear(false); - setContainsPageBreak(true); - } - } - pageBreakInfo.setPageBottom(pageBreakInfo.pageBottom() + canvas()->pageHeight()); - } - else - if (child->yPos() >= pageBreakInfo.pageBottom()) { - bool doBreak = true; -#ifdef PAGE_DEBUG - kdDebug(6040) << "Page-break between children" << endl; -#endif - if (!style()->pageBreakInside() || m_avoidPageBreak) { - if(parent()->canClear(this, (m_avoidPageBreak) ? PageBreakHarder : PageBreakNormal )) { -#ifdef PAGE_DEBUG - kdDebug(6040) << "Avoid page-break inside" << endl; -#endif - child->setNeedsPageClear(false); - setNeedsPageClear(true); - doBreak = false; - } -#ifdef PAGE_DEBUG - else - kdDebug(6040) << "Ignoring page-break avoid" << endl; -#endif - } - if (doBreak) { - // Break between children - setContainsPageBreak(true); - // ### Should collapse top-margin with page-margin - } - pageBreakInfo.setPageBottom(pageBreakInfo.pageBottom() + canvas()->pageHeight()); - } - - // Do we need a forced page-break before next child? - pageBreakInfo.setForcePageBreak(false); - if (child->style()->pageBreakAfter() == PBALWAYS) - pageBreakInfo.setForcePageBreak(true); -} - -void RenderBlock::layoutPositionedObjects(bool relayoutChildren) -{ - if (m_positionedObjects) { - //kdDebug( 6040 ) << renderName() << " " << this << "::layoutPositionedObjects() start" << endl; - RenderObject* r; - TQPtrListIterator it(*m_positionedObjects); - for ( ; (r = it.current()); ++it ) { - //kdDebug(6040) << " have a positioned object" << endl; - if (r->markedForRepaint()) { - r->repaintDuringLayout(); - r->setMarkedForRepaint(false); - } - if ( relayoutChildren || r->style()->position() == FIXED || - ((r->hasStaticY()||r->hasStaticX()) && r->parent() != this && r->parent()->isBlockFlow()) ) { - r->setChildNeedsLayout(true); - r->dirtyFormattingContext(false); - } - r->layoutIfNeeded(); - } - } -} - -void RenderBlock::paint(PaintInfo& pI, int _tx, int _ty) -{ - _tx += m_x; - _ty += m_y; - - // check if we need to do anything at all... - if (!isRoot() && !isInlineFlow() && !overhangingContents() && !isRelPositioned() && !isPositioned() ) - { - int h = m_overflowHeight; - int yPos = _ty; - if (m_floatingObjects && floatBottom() > h) - h = floatBottom(); - - yPos += overflowTop(); - - int os = maximalOutlineSize(pI.phase); - if( (yPos > pI.r.bottom() + os) || (_ty + h <= pI.r.y() - os)) - return; - } - - paintObject(pI, _tx, _ty); -} - -void RenderBlock::paintObject(PaintInfo& pI, int _tx, int _ty, bool shouldPaintOutline) -{ -#ifdef DEBUG_LAYOUT - //kdDebug( 6040 ) << renderName() << "(RenderBlock) " << this << " ::paintObject() w/h = (" << width() << "/" << height() << ")" << endl; -#endif - - // If we're a repositioned run-in, don't paint background/borders. - bool inlineFlow = isInlineFlow(); - - // 1. paint background, borders etc - if (!inlineFlow && - (pI.phase == PaintActionElementBackground || pI.phase == PaintActionChildBackground ) && - shouldPaintBackgroundOrBorder() && style()->visibility() == VISIBLE) - paintBoxDecorations(pI, _tx, _ty); - - if ( pI.phase == PaintActionElementBackground ) - return; - if ( pI.phase == PaintActionChildBackgrounds ) - pI.phase = PaintActionChildBackground; - - // 2. paint contents - int scrolledX = _tx; - int scrolledY = _ty; - if (hasOverflowClip() && m_layer) - m_layer->subtractScrollOffset(scrolledX, scrolledY); - - if (childrenInline()) - paintLines(pI, scrolledX, scrolledY); - else { - for(RenderObject *child = firstChild(); child; child = child->nextSibling()) - if(!child->layer() && !child->isFloating()) - child->paint(pI, scrolledX, scrolledY); - } - - // 3. paint floats. - if (!inlineFlow && (pI.phase == PaintActionFloat || pI.phase == PaintActionSelection)) - paintFloats(pI, scrolledX, scrolledY, pI.phase == PaintActionSelection); - - // 4. paint outline. - if (shouldPaintOutline && !inlineFlow && pI.phase == PaintActionOutline && - style()->outlineWidth() && style()->visibility() == VISIBLE) - paintOutline(pI.p, _tx, _ty, width(), height(), style()); - -#ifdef BOX_DEBUG - if ( style() && style()->visibility() == VISIBLE ) { - if(isAnonymous()) - outlineBox(pI.p, _tx, _ty, "green"); - if(isFloating()) - outlineBox(pI.p, _tx, _ty, "yellow"); - else - outlineBox(pI.p, _tx, _ty); - } -#endif -} - -void RenderBlock::paintFloats(PaintInfo& pI, int _tx, int _ty, bool paintSelection) -{ - if (!m_floatingObjects) - return; - - FloatingObject* r; - TQPtrListIterator it(*m_floatingObjects); - for ( ; (r = it.current()); ++it) { - // Only paint the object if our noPaint flag isn't set. - if (r->node->isFloating() && !r->noPaint && !r->node->layer()) { - PaintAction oldphase = pI.phase; - if (paintSelection) { - pI.phase = PaintActionSelection; - r->node->paint(pI, _tx + r->left - r->node->xPos() + r->node->marginLeft(), - _ty + r->startY - r->node->yPos() + r->node->marginTop()); - } - else { - pI.phase = PaintActionElementBackground; - r->node->paint(pI, - _tx + r->left - r->node->xPos() + r->node->marginLeft(), - _ty + r->startY - r->node->yPos() + r->node->marginTop()); - pI.phase = PaintActionChildBackgrounds; - r->node->paint(pI, - _tx + r->left - r->node->xPos() + r->node->marginLeft(), - _ty + r->startY - r->node->yPos() + r->node->marginTop()); - pI.phase = PaintActionFloat; - r->node->paint(pI, - _tx + r->left - r->node->xPos() + r->node->marginLeft(), - _ty + r->startY - r->node->yPos() + r->node->marginTop()); - pI.phase = PaintActionForeground; - r->node->paint(pI, - _tx + r->left - r->node->xPos() + r->node->marginLeft(), - _ty + r->startY - r->node->yPos() + r->node->marginTop()); - pI.phase = PaintActionOutline; - r->node->paint(pI, - _tx + r->left - r->node->xPos() + r->node->marginLeft(), - _ty + r->startY - r->node->yPos() + r->node->marginTop()); - } - pI.phase = oldphase; - } - } -} - -void RenderBlock::insertPositionedObject(RenderObject *o) -{ - // Create the list of special objects if we don't aleady have one - if (!m_positionedObjects) { - m_positionedObjects = new TQPtrList; - m_positionedObjects->setAutoDelete(false); - } - else { - // Don't insert the object again if it's already in the list - TQPtrListIterator it(*m_positionedObjects); - RenderObject* f; - while ( (f = it.current()) ) { - if (f == o) return; - ++it; - } - } - - // Create the special object entry & append it to the list - setOverhangingContents(); - m_positionedObjects->append(o); -} - -void RenderBlock::removePositionedObject(RenderObject *o) -{ - if (m_positionedObjects) { - TQPtrListIterator it(*m_positionedObjects); - while (it.current()) { - if (it.current() == o) - m_positionedObjects->removeRef(it.current()); - ++it; - } - if (m_positionedObjects->isEmpty()) { - delete m_positionedObjects; - m_positionedObjects = 0; - } - } -} - -void RenderBlock::insertFloatingObject(RenderObject *o) -{ - // Create the list of special objects if we don't aleady have one - if (!m_floatingObjects) { - m_floatingObjects = new TQPtrList; - m_floatingObjects->setAutoDelete(true); - } - else { - // Don't insert the object again if it's already in the list - TQPtrListIterator it(*m_floatingObjects); - FloatingObject* f; - while ( (f = it.current()) ) { - if (f->node == o) return; - ++it; - } - } - - // Create the special object entry & append it to the list - - FloatingObject *newObj; - if (o->isFloating()) { - // floating object - o->layoutIfNeeded(); - - if(o->style()->floating() & FLEFT) - newObj = new FloatingObject(FloatingObject::FloatLeft); - else - newObj = new FloatingObject(FloatingObject::FloatRight); - - newObj->startY = -500000; - newObj->endY = -500000; - newObj->width = o->width() + o->marginLeft() + o->marginRight(); - } - else { - // We should never get here, as insertFloatingObject() should only ever be called with floating - // objects. - KHTMLAssert(false); - newObj = 0; // keep gcc's uninitialized variable warnings happy - } - - newObj->node = o; - - m_floatingObjects->append(newObj); -} - -void RenderBlock::removeFloatingObject(RenderObject *o) -{ - if (m_floatingObjects) { - TQPtrListIterator it(*m_floatingObjects); - while (it.current()) { - if (it.current()->node == o) - m_floatingObjects->removeRef(it.current()); - ++it; - } - } -} - -void RenderBlock::positionNewFloats() -{ - if(!m_floatingObjects) return; - FloatingObject *f = m_floatingObjects->getLast(); - if(!f || f->startY != -500000) return; - FloatingObject *lastFloat; - while(1) - { - lastFloat = m_floatingObjects->prev(); - if (!lastFloat || lastFloat->startY != -500000) { - m_floatingObjects->next(); - break; - } - f = lastFloat; - } - - int y = m_height; - - - // the float can not start above the y position of the last positioned float. - if(lastFloat && lastFloat->startY > y) - y = lastFloat->startY; - - while(f) - { - //skip elements copied from elsewhere and positioned elements - if (f->node->containingBlock()!=this) - { - f = m_floatingObjects->next(); - continue; - } - - RenderObject *o = f->node; - int _height = o->height() + o->marginTop() + o->marginBottom(); - - // floats avoid page-breaks - if(canvas()->pagedMode()) - { - int top = y; - int bottom = y + o->height(); - if (crossesPageBreak(top, bottom) && o->height() < canvas()->pageHeight() ) { - int newY = pageTopAfter(top); -#ifdef PAGE_DEBUG - kdDebug(6040) << renderName() << " clearing float " << newY - y << "px" << endl; -#endif - y = newY; - } - } - - int ro = rightOffset(); // Constant part of right offset. - int lo = leftOffset(); // Constant part of left offset. - int fwidth = f->width; // The width we look for. - //kdDebug( 6040 ) << " Object width: " << fwidth << " available width: " << ro - lo << endl; - - // in quirk mode, floated auto-width tables try to fit within remaining linewidth - bool ftQuirk = o->isTable() && style()->htmlHacks() && o->style()->width().isVariable(); - if (ftQuirk) - fwidth = kMin( o->minWidth()+o->marginLeft()+o->marginRight(), fwidth ); - - if (ro - lo < fwidth) - fwidth = ro - lo; // Never look for more than what will be available. - - if ( o->style()->clear() & CLEFT ) - y = kMax( leftBottom(), y ); - if ( o->style()->clear() & CRIGHT ) - y = kMax( rightBottom(), y ); - - bool canClearLine; - if (o->style()->floating() & FLEFT) - { - int heightRemainingLeft = 1; - int heightRemainingRight = 1; - int fx = leftRelOffset(y,lo, false, &heightRemainingLeft, &canClearLine); - if (canClearLine) - { - while (rightRelOffset(y,ro, false, &heightRemainingRight)-fx < fwidth) - { - y += kMin( heightRemainingLeft, heightRemainingRight ); - fx = leftRelOffset(y,lo, false, &heightRemainingLeft); - } - } - if (ftQuirk && (rightRelOffset(y,ro, false)-fx < f->width)) { - o->setPos( o->xPos(), y + o->marginTop() ); - o->setChildNeedsLayout(true, false); - o->layoutIfNeeded(); - _height = o->height() + o->marginTop() + o->marginBottom(); - f->width = o->width() + o->marginLeft() + o->marginRight(); - } - f->left = fx; - //kdDebug( 6040 ) << "positioning left aligned float at (" << fx + o->marginLeft() << "/" << y + o->marginTop() << ") fx=" << fx << endl; - o->setPos(fx + o->marginLeft(), y + o->marginTop()); - } - else - { - int heightRemainingLeft = 1; - int heightRemainingRight = 1; - int fx = rightRelOffset(y,ro, false, &heightRemainingRight, &canClearLine); - if (canClearLine) - { - while (fx - leftRelOffset(y,lo, false, &heightRemainingLeft) < fwidth) - { - y += kMin(heightRemainingLeft, heightRemainingRight); - fx = rightRelOffset(y,ro, false, &heightRemainingRight); - } - } - if (ftQuirk && (fx - leftRelOffset(y,lo, false) < f->width)) { - o->setPos( o->xPos(), y + o->marginTop() ); - o->setChildNeedsLayout(true, false); - o->layoutIfNeeded(); - _height = o->height() + o->marginTop() + o->marginBottom(); - f->width = o->width() + o->marginLeft() + o->marginRight(); - } - f->left = fx - f->width; - //kdDebug( 6040 ) << "positioning right aligned float at (" << fx - o->marginRight() - o->width() << "/" << y + o->marginTop() << ")" << endl; - o->setPos(fx - o->marginRight() - o->width(), y + o->marginTop()); - } - - if ( m_layer && hasOverflowClip()) { - if (o->xPos()+o->width() > m_overflowWidth) - m_overflowWidth = o->xPos()+o->width(); - else - if (o->xPos() < m_overflowLeft) - m_overflowLeft = o->xPos(); - } - - f->startY = y; - f->endY = f->startY + _height; - - - //kdDebug( 6040 ) << "floatingObject x/y= (" << f->left << "/" << f->startY << "-" << f->width << "/" << f->endY - f->startY << ")" << endl; - - f = m_floatingObjects->next(); - } -} - -void RenderBlock::newLine() -{ - positionNewFloats(); - // set y position - int newY = 0; - switch(m_clearStatus) - { - case CLEFT: - newY = leftBottom(); - break; - case CRIGHT: - newY = rightBottom(); - break; - case CBOTH: - newY = floatBottom(); - default: - break; - } - if(m_height < newY) - { - // kdDebug( 6040 ) << "adjusting y position" << endl; - m_height = newY; - } - m_clearStatus = CNONE; -} - -int -RenderBlock::leftOffset() const -{ - return borderLeft()+paddingLeft(); -} - -int -RenderBlock::leftRelOffset(int y, int fixedOffset, bool applyTextIndent, int *heightRemaining, bool *canClearLine ) const -{ - int left = fixedOffset; - if (canClearLine) *canClearLine = true; - - if (m_floatingObjects) { - if ( heightRemaining ) *heightRemaining = 1; - FloatingObject* r; - TQPtrListIterator it(*m_floatingObjects); - for ( ; (r = it.current()); ++it ) - { - //kdDebug( 6040 ) <<(void *)this << " left: sy, ey, x, w " << r->startY << "," << r->endY << "," << r->left << "," << r->width << " " << endl; - if (r->startY <= y && r->endY > y && - r->type == FloatingObject::FloatLeft && - r->left + r->width > left) { - left = r->left + r->width; - if ( heightRemaining ) *heightRemaining = r->endY - y; - if ( canClearLine ) *canClearLine = (r->node->style()->floating() != FLEFT_ALIGN); - } - } - } - - if (applyTextIndent && m_firstLine && style()->direction() == LTR ) { - int cw=0; - if (style()->textIndent().isPercent()) - cw = containingBlock()->contentWidth(); - left += style()->textIndent().minWidth(cw); - } - - //kdDebug( 6040 ) << "leftOffset(" << y << ") = " << left << endl; - return left; -} - -int -RenderBlock::rightOffset() const -{ - int right = m_width - borderRight() - paddingRight(); - if (m_layer && scrollsOverflowY()) - right -= m_layer->verticalScrollbarWidth(); - return right; -} - -int -RenderBlock::rightRelOffset(int y, int fixedOffset, bool applyTextIndent, int *heightRemaining, bool *canClearLine ) const -{ - int right = fixedOffset; - if (canClearLine) *canClearLine = true; - - if (m_floatingObjects) { - if (heightRemaining) *heightRemaining = 1; - FloatingObject* r; - TQPtrListIterator it(*m_floatingObjects); - for ( ; (r = it.current()); ++it ) - { - //kdDebug( 6040 ) << "right: sy, ey, x, w " << r->startY << "," << r->endY << "," << r->left << "," << r->width << " " << endl; - if (r->startY <= y && r->endY > y && - r->type == FloatingObject::FloatRight && - r->left < right) { - right = r->left; - if ( heightRemaining ) *heightRemaining = r->endY - y; - if ( canClearLine ) *canClearLine = (r->node->style()->floating() != FRIGHT_ALIGN); - } - } - } - - if (applyTextIndent && m_firstLine && style()->direction() == RTL ) { - int cw=0; - if (style()->textIndent().isPercent()) - cw = containingBlock()->contentWidth(); - right -= style()->textIndent().minWidth(cw); - } - - //kdDebug( 6040 ) << "rightOffset(" << y << ") = " << right << endl; - return right; -} - -unsigned short -RenderBlock::lineWidth(int y, bool *canClearLine) const -{ - //kdDebug( 6040 ) << "lineWidth(" << y << ")=" << rightOffset(y) - leftOffset(y) << endl; - int result; - if (canClearLine) { - bool rightCanClearLine; - bool leftCanClearLine; - result = rightOffset(y, &rightCanClearLine) - leftOffset(y, &leftCanClearLine); - *canClearLine = rightCanClearLine && leftCanClearLine; - } else - result = rightOffset(y) - leftOffset(y); - return (result < 0) ? 0 : result; -} - -int -RenderBlock::nearestFloatBottom(int height) const -{ - if (!m_floatingObjects) return 0; - int bottom = 0; - FloatingObject* r; - TQPtrListIterator it(*m_floatingObjects); - for ( ; (r = it.current()); ++it ) - if (r->endY>height && (r->endYendY; - return kMax(bottom, height); -} - -int RenderBlock::floatBottom() const -{ - if (!m_floatingObjects) return 0; - int bottom=0; - FloatingObject* r; - TQPtrListIterator it(*m_floatingObjects); - for ( ; (r = it.current()); ++it ) - if (r->endY>bottom) - bottom=r->endY; - return bottom; -} - -int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf) const -{ - int bottom = RenderFlow::lowestPosition(includeOverflowInterior, includeSelf); - if (!includeOverflowInterior && hasOverflowClip()) - return bottom; - if (includeSelf && m_overflowHeight > bottom) - bottom = m_overflowHeight; - - if (m_floatingObjects) { - FloatingObject* r; - TQPtrListIterator it(*m_floatingObjects); - for ( ; (r = it.current()); ++it ) { - if (!r->noPaint) { - int lp = r->startY + r->node->marginTop() + r->node->lowestPosition(false); - bottom = kMax(bottom, lp); - } - } - } - bottom = kMax(bottom, lowestAbsolutePosition()); - - if (!includeSelf && lastLineBox()) { - int lp = lastLineBox()->yPos() + lastLineBox()->height(); - bottom = kMax(bottom, lp); - } - - return bottom; -} - -int RenderBlock::lowestAbsolutePosition() const -{ - if (!m_positionedObjects) - return 0; - - // Fixed positioned objects do not scroll and thus should not constitute - // part of the lowest position. - int bottom = 0; - RenderObject* r; - TQPtrListIterator it(*m_positionedObjects); - for ( ; (r = it.current()); ++it ) { - if (r->style()->position() == FIXED) - continue; - int lp = r->yPos() + r->lowestPosition(false); - bottom = kMax(bottom, lp); - } - return bottom; -} - -int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSelf) const -{ - int right = RenderFlow::rightmostPosition(includeOverflowInterior, includeSelf); - if (!includeOverflowInterior && hasOverflowClip()) - return right; - if (includeSelf && m_overflowWidth > right) - right = m_overflowWidth; - - if (m_floatingObjects) { - FloatingObject* r; - TQPtrListIterator it(*m_floatingObjects); - for ( ; (r = it.current()); ++it ) { - if (!r->noPaint) { - int rp = r->left + r->node->marginLeft() + r->node->rightmostPosition(false); - right = kMax(right, rp); - } - } - } - right = kMax(right, rightmostAbsolutePosition()); - - if (!includeSelf && firstLineBox()) { - for (InlineRunBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox()) { - int rp = currBox->xPos() + currBox->width(); - right = kMax(right, rp); - } - } - - return right; -} - -int RenderBlock::rightmostAbsolutePosition() const -{ - if (!m_positionedObjects) - return 0; - int right = 0; - RenderObject* r; - TQPtrListIterator it(*m_positionedObjects); - for ( ; (r = it.current()); ++it ) { - if (r->style()->position() == FIXED) - continue; - int rp = r->xPos() + r->rightmostPosition(false); - right = kMax(right, rp); - } - return right; -} - -int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf) const -{ - int left = RenderFlow::leftmostPosition(includeOverflowInterior, includeSelf); - if (!includeOverflowInterior && hasOverflowClip()) - return left; - - if (includeSelf && m_overflowLeft < left) - left = m_overflowLeft; - - if (m_floatingObjects) { - FloatingObject* r; - TQPtrListIterator it(*m_floatingObjects); - for ( ; (r = it.current()); ++it ) { - if (!r->noPaint) { - int lp = r->left + r->node->marginLeft() + r->node->leftmostPosition(false); - left = kMin(left, lp); - } - } - } - left = kMin(left, leftmostAbsolutePosition()); - - if (!includeSelf && firstLineBox()) { - for (InlineRunBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox()) - left = kMin(left, (int)currBox->xPos()); - } - - return left; -} - -int RenderBlock::leftmostAbsolutePosition() const -{ - if (!m_positionedObjects) - return 0; - int left = 0; - RenderObject* r; - TQPtrListIterator it(*m_positionedObjects); - for ( ; (r = it.current()); ++it ) { - if (r->style()->position() == FIXED) - continue; - int lp = r->xPos() + r->leftmostPosition(false); - left = kMin(left, lp); - } - return left; -} - -int RenderBlock::highestPosition(bool includeOverflowInterior, bool includeSelf) const -{ - int top = RenderFlow::highestPosition(includeOverflowInterior, includeSelf); - if (!includeOverflowInterior && hasOverflowClip()) - return top; - - if (includeSelf && m_overflowTop < top) - top = m_overflowTop; - - if (m_floatingObjects) { - FloatingObject* r; - TQPtrListIterator it(*m_floatingObjects); - for ( ; (r = it.current()); ++it ) { - if (!r->noPaint) { - int hp = r->startY + r->node->marginTop() + r->node->highestPosition(false); - top = kMin(top, hp); - } - } - } - top = kMin(top, highestAbsolutePosition()); - - if (!includeSelf && firstLineBox()) { - top = kMin(top, (int)firstLineBox()->yPos()); - } - - return top; -} - -int RenderBlock::highestAbsolutePosition() const -{ - if (!m_positionedObjects) - return 0; - int top = 0; - RenderObject* r; - TQPtrListIterator it(*m_positionedObjects); - for ( ; (r = it.current()); ++it ) { - if (r->style()->position() == FIXED) - continue; - int hp = r->yPos() + r->highestPosition(false); - hp = kMin(top, hp); - } - return top; -} - -int -RenderBlock::leftBottom() -{ - if (!m_floatingObjects) return 0; - int bottom=0; - FloatingObject* r; - TQPtrListIterator it(*m_floatingObjects); - for ( ; (r = it.current()); ++it ) - if (r->endY>bottom && r->type == FloatingObject::FloatLeft) - bottom=r->endY; - - return bottom; -} - -int -RenderBlock::rightBottom() -{ - if (!m_floatingObjects) return 0; - int bottom=0; - FloatingObject* r; - TQPtrListIterator it(*m_floatingObjects); - for ( ; (r = it.current()); ++it ) - if (r->endY>bottom && r->type == FloatingObject::FloatRight) - bottom=r->endY; - - return bottom; -} - -void -RenderBlock::clearFloats() -{ - if (m_floatingObjects) - m_floatingObjects->clear(); - - // we are done if the element defines a new block formatting context - if (flowAroundFloats() || isRoot() || isCanvas() || isFloatingOrPositioned() || isTableCell()) return; - - RenderObject *prev = previousSibling(); - - // find the element to copy the floats from - // pass non-flows - // pass fAF's - bool parentHasFloats = false; - while (prev) { - if (!prev->isRenderBlock() || prev->isFloatingOrPositioned() || prev->flowAroundFloats()) { - if ( prev->isFloating() && parent()->isRenderBlock() ) { - parentHasFloats = true; - } - prev = prev->previousSibling(); - } else - break; - } - - int offset = m_y; - if (parentHasFloats) - { - addOverHangingFloats( static_cast( parent() ), - parent()->borderLeft() + parent()->paddingLeft(), offset, false ); - } - - int xoffset = 0; - if (prev) { - if(prev->isTableCell()) return; - offset -= prev->yPos(); - } else { - prev = parent(); - if(!prev) return; - xoffset += prev->borderLeft() + prev->paddingLeft(); - } - //kdDebug() << "RenderBlock::clearFloats found previous "<< (void *)this << " prev=" << (void *)prev<< endl; - - // add overhanging special objects from the previous RenderBlock - if(!prev->isRenderBlock()) return; - RenderBlock * flow = static_cast(prev); - if(!flow->m_floatingObjects) return; - if(flow->floatBottom() > offset) - addOverHangingFloats( flow, xoffset, offset, false ); -} - -void RenderBlock::addOverHangingFloats( RenderBlock *flow, int xoff, int offset, bool child ) -{ -#ifdef DEBUG_LAYOUT - kdDebug( 6040 ) << (void *)this << ": adding overhanging floats xoff=" << xoff << " offset=" << offset << " child=" << child << endl; -#endif - - // Prevent floats from being added to the canvas by the root element, e.g., . - if ( !flow->m_floatingObjects || (child && flow->isRoot()) ) - return; - - // if I am clear of my floats, don't add them - // the CSS spec also mentions that child floats - // are not cleared. - if (!child && style()->clear() == CBOTH) - { - return; - } - - TQPtrListIterator it(*flow->m_floatingObjects); - FloatingObject *r; - for ( ; (r = it.current()); ++it ) { - - if (!child && r->type == FloatingObject::FloatLeft && style()->clear() == CLEFT ) - continue; - if (!child && r->type == FloatingObject::FloatRight && style()->clear() == CRIGHT ) - continue; - - if ( ( !child && r->endY > offset ) || - ( child && flow->yPos() + r->endY > height() ) ) { - if (child && !r->crossedLayer) { - if (flow->enclosingLayer() == enclosingLayer()) { - // Set noPaint to true only if we didn't cross layers. - r->noPaint = true; - } else { - r->crossedLayer = true; - } - } - - FloatingObject* f = 0; - // don't insert it twice! - if (m_floatingObjects) { - TQPtrListIterator it(*m_floatingObjects); - while ( (f = it.current()) ) { - if (f->node == r->node) break; - ++it; - } - } - if ( !f ) { - FloatingObject *floatingObj = new FloatingObject(r->type); - floatingObj->startY = r->startY - offset; - floatingObj->endY = r->endY - offset; - floatingObj->left = r->left - xoff; - // Applying the child's margin makes no sense in the case where the child was passed in. - // since his own margin was added already through the subtraction of the |xoff| variable - // above. |xoff| will equal -flow->marginLeft() in this case, so it's already been taken - // into account. Only apply this code if |child| is false, since otherwise the left margin - // will get applied twice. -dwh - if (!child && flow != parent()) - floatingObj->left += flow->marginLeft(); - if ( !child ) { - floatingObj->left -= marginLeft(); - floatingObj->noPaint = true; - } - else { - floatingObj->noPaint = (r->crossedLayer || !r->noPaint); - floatingObj->crossedLayer = r->crossedLayer; - } - - floatingObj->width = r->width; - floatingObj->node = r->node; - if (!m_floatingObjects) { - m_floatingObjects = new TQPtrList; - m_floatingObjects->setAutoDelete(true); - } - m_floatingObjects->append(floatingObj); -#ifdef DEBUG_LAYOUT - kdDebug( 6040 ) << "addOverHangingFloats x/y= (" << floatingObj->left << "/" << floatingObj->startY << "-" << floatingObj->width << "/" << floatingObj->endY - floatingObj->startY << ")" << endl; -#endif - } - } - } -} - -bool RenderBlock::containsFloat(RenderObject* o) const -{ - if (m_floatingObjects) { - TQPtrListIterator it(*m_floatingObjects); - while (it.current()) { - if (it.current()->node == o) - return true; - ++it; - } - } - return false; -} - -void RenderBlock::markAllDescendantsWithFloatsForLayout(RenderObject* floatToRemove) -{ - dirtyFormattingContext(false); - setChildNeedsLayout(true); - - if (floatToRemove) - removeFloatingObject(floatToRemove); - - // Iterate over our children and mark them as needed. - if (!childrenInline()) { - for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { - if (isBlockFlow() && !child->isFloatingOrPositioned() && - ((floatToRemove ? child->containsFloat(floatToRemove) : child->hasFloats()) || child->usesLineWidth())) - child->markAllDescendantsWithFloatsForLayout(floatToRemove); - } - } -} - -int RenderBlock::getClearDelta(RenderObject *child) -{ - if (!hasFloats()) - return 0; - - //kdDebug( 6040 ) << "getClearDelta on child " << child << " oldheight=" << m_height << endl; - bool clearSet = child->style()->clear() != CNONE; - int bottom = 0; - switch(child->style()->clear()) - { - case CNONE: - break; - case CLEFT: - bottom = leftBottom(); - break; - case CRIGHT: - bottom = rightBottom(); - break; - case CBOTH: - bottom = floatBottom(); - break; - } - - // We also clear floats if we are too big to sit on the same line as a float, and happen to flow around floats. - // FIXME: Note that the remaining space checks aren't quite accurate, since you should be able to clear only some floats (the minimum # needed - // to fit) and not all (we should be using nearestFloatBottom and looping). - - int result = clearSet ? kMax(0, bottom - child->yPos()) : 0; - if (!result && child->flowAroundFloats() && !style()->width().isVariable()) { - bool canClearLine; - int lw = lineWidth(child->yPos(), &canClearLine); - if (((child->style()->width().isPercent() && child->width() > lw) || - (child->style()->width().isFixed() && child->minWidth() > lw)) && - child->minWidth() <= contentWidth() && canClearLine) - result = kMax(0, floatBottom() - child->yPos()); - } - return result; -} - -bool RenderBlock::isPointInScrollbar(int _x, int _y, int _tx, int _ty) -{ - if (!scrollsOverflow() || !m_layer) - return false; - - if (m_layer->verticalScrollbarWidth()) { - TQRect vertRect(_tx + width() - borderRight() - m_layer->verticalScrollbarWidth(), - _ty + borderTop() - borderTopExtra(), - m_layer->verticalScrollbarWidth(), - height() + borderTopExtra() + borderBottomExtra()-borderTop()-borderBottom()); - if (vertRect.contains(_x, _y)) { -#ifdef APPLE_CHANGES - RenderLayer::gScrollBar = m_layer->verticalScrollbar(); -#endif - return true; - } - } - - if (m_layer->horizontalScrollbarHeight()) { - TQRect horizRect(_tx + borderLeft(), - _ty + height() + borderTop() + borderBottomExtra() - borderBottom() - m_layer->horizontalScrollbarHeight(), - width()-borderLeft()-borderRight(), - m_layer->horizontalScrollbarHeight()); - if (horizRect.contains(_x, _y)) { -#ifdef APPLE_CHANGES - RenderLayer::gScrollBar = m_layer->horizontalScrollbar(); -#endif - return true; - } - } - - return false; -} - -bool RenderBlock::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction, bool inBox) -{ - bool inScrollbar = isPointInScrollbar(_x, _y, _tx+xPos(), _ty+yPos()); - if (inScrollbar && hitTestAction != HitTestChildrenOnly) - inBox = true; - - if (hitTestAction != HitTestSelfOnly && m_floatingObjects && !inScrollbar) { - int stx = _tx + xPos(); - int sty = _ty + yPos(); - if (hasOverflowClip() && m_layer) - m_layer->subtractScrollOffset(stx, sty); - FloatingObject* o; - TQPtrListIterator it(*m_floatingObjects); - for (it.toLast(); (o = it.current()); --it) - if (!o->noPaint && !o->node->layer()) - inBox |= o->node->nodeAtPoint(info, _x, _y, - stx+o->left + o->node->marginLeft() - o->node->xPos(), - sty+o->startY + o->node->marginTop() - o->node->yPos(), HitTestAll ) ; - } - - inBox |= RenderFlow::nodeAtPoint(info, _x, _y, _tx, _ty, hitTestAction, inBox); - return inBox; -} - -void RenderBlock::calcMinMaxWidth() -{ - KHTMLAssert( !minMaxKnown() ); - -#ifdef DEBUG_LAYOUT - kdDebug( 6040 ) << renderName() << "(RenderBlock)::calcMinMaxWidth() this=" << this << endl; -#endif - - m_minWidth = 0; - m_maxWidth = 0; - - bool noWrap = !style()->autoWrap(); - if (childrenInline()) - calcInlineMinMaxWidth(); - else - calcBlockMinMaxWidth(); - - if(m_maxWidth < m_minWidth) m_maxWidth = m_minWidth; - - if (noWrap && childrenInline()) { - m_minWidth = m_maxWidth; - - // A horizontal marquee with inline children has no minimum width. - if (style()->overflowX() == OMARQUEE && m_layer && m_layer->marquee() && - m_layer->marquee()->isHorizontal() && !m_layer->marquee()->isUnfurlMarquee()) - m_minWidth = 0; - } - - if (isTableCell()) { - Length w = static_cast(this)->styleOrColWidth(); - if (w.isFixed() && w.value() > 0) - m_maxWidth = kMax((int)m_minWidth, calcContentWidth(w.value())); - } else if (style()->width().isFixed() && style()->width().value() > 0) - m_minWidth = m_maxWidth = calcContentWidth(style()->width().value()); - - if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) { - m_maxWidth = kMax(m_maxWidth, (int)calcContentWidth(style()->minWidth().value())); - m_minWidth = kMax(m_minWidth, (short)calcContentWidth(style()->minWidth().value())); - } - - if (style()->maxWidth().isFixed() && style()->maxWidth().value() != UNDEFINED) { - m_maxWidth = kMin(m_maxWidth, (int)calcContentWidth(style()->maxWidth().value())); - m_minWidth = kMin(m_minWidth, (short)calcContentWidth(style()->maxWidth().value())); - } - - int toAdd = 0; - toAdd = borderLeft() + borderRight() + paddingLeft() + paddingRight(); - - m_minWidth += toAdd; - m_maxWidth += toAdd; - - setMinMaxKnown(); - - //kdDebug( 6040 ) << "Text::calcMinMaxWidth(" << this << "): min = " << m_minWidth << " max = " << m_maxWidth << endl; - // ### compare with min/max width set in style sheet... -} - -// bidi.cpp defines the following functions too. -// Maybe these should not be static, after all... - -#ifndef KDE_USE_FINAL - -static int getBPMWidth(int childValue, Length cssUnit) -{ - if (!cssUnit.isVariable()) - return (cssUnit.isFixed() ? cssUnit.value() : childValue); - return 0; -} - -static int getBorderPaddingMargin(RenderObject* child, bool endOfInline) -{ - RenderStyle* cstyle = child->style(); - int result = 0; - bool leftSide = (cstyle->direction() == LTR) ? !endOfInline : endOfInline; - result += getBPMWidth((leftSide ? child->marginLeft() : child->marginRight()), - (leftSide ? cstyle->marginLeft() : - cstyle->marginRight())); - result += getBPMWidth((leftSide ? child->paddingLeft() : child->paddingRight()), - (leftSide ? cstyle->paddingLeft() : - cstyle->paddingRight())); - result += leftSide ? child->borderLeft() : child->borderRight(); - return result; -} -#endif - -static void stripTrailingSpace(bool preserveWS, - int& inlineMax, int& inlineMin, - RenderObject* trailingSpaceChild) -{ - if (!preserveWS && trailingSpaceChild && trailingSpaceChild->isText()) { - // Collapse away the trailing space at the end of a block. - RenderText* t = static_cast(trailingSpaceChild); - const Font *f = t->htmlFont( false ); - TQChar space[1]; space[0] = ' '; - int spaceWidth = f->width(space, 1, 0); - inlineMax -= spaceWidth; - if (inlineMin > inlineMax) - inlineMin = inlineMax; - } -} - -void RenderBlock::calcInlineMinMaxWidth() -{ - int inlineMax=0; - int inlineMin=0; - - int cw = containingBlock()->contentWidth(); - int floatMaxWidth = 0; - - // If we are at the start of a line, we want to ignore all white-space. - // Also strip spaces if we previously had text that ended in a trailing space. - bool stripFrontSpaces = true; - - bool isTcQuirk = isTableCell() && style()->htmlHacks() && style()->width().isVariable(); - - RenderObject* trailingSpaceChild = 0; - - bool autoWrap, oldAutoWrap; - autoWrap = oldAutoWrap = style()->autoWrap(); - - InlineMinMaxIterator childIterator(this, this); - bool addedTextIndent = false; // Only gets added in once. - RenderObject* prevFloat = 0; - while (RenderObject* child = childIterator.next()) - { - autoWrap = child->style()->autoWrap(); - - if( !child->isBR() ) - { - // Step One: determine whether or not we need to go ahead and - // terminate our current line. Each discrete chunk can become - // the new min-width, if it is the widest chunk seen so far, and - // it can also become the max-width. - - // Children fall into three categories: - // (1) An inline flow object. These objects always have a min/max of 0, - // and are included in the iteration solely so that their margins can - // be added in. - // - // (2) An inline non-text non-flow object, e.g., an inline replaced element. - // These objects can always be on a line by themselves, so in this situation - // we need to go ahead and break the current line, and then add in our own - // margins and min/max width on its own line, and then terminate the line. - // - // (3) A text object. Text runs can have breakable characters at the start, - // the middle or the end. They may also lose whitespace off the front if - // we're already ignoring whitespace. In order to compute accurate min-width - // information, we need three pieces of information. - // (a) the min-width of the first non-breakable run. Should be 0 if the text string - // starts with whitespace. - // (b) the min-width of the last non-breakable run. Should be 0 if the text string - // ends with whitespace. - // (c) the min/max width of the string (trimmed for whitespace). - // - // If the text string starts with whitespace, then we need to go ahead and - // terminate our current line (unless we're already in a whitespace stripping - // mode. - // - // If the text string has a breakable character in the middle, but didn't start - // with whitespace, then we add the width of the first non-breakable run and - // then end the current line. We then need to use the intermediate min/max width - // values (if any of them are larger than our current min/max). We then look at - // the width of the last non-breakable run and use that to start a new line - // (unless we end in whitespace). - RenderStyle* cstyle = child->style(); - short childMin = 0; - short childMax = 0; - - if (!child->isText()) { - // Case (1) and (2). Inline replaced and inline flow elements. - if (child->isInlineFlow()) { - // Add in padding/border/margin from the appropriate side of - // the element. - int bpm = getBorderPaddingMargin(child, childIterator.endOfInline); - childMin += bpm; - childMax += bpm; - - inlineMin += childMin; - inlineMax += childMax; - } - else { - // Inline replaced elements add in their margins to their min/max values. - int margins = 0; - LengthType type = cstyle->marginLeft().type(); - if ( type != Variable ) - margins += (type == Fixed ? cstyle->marginLeft().value() : child->marginLeft()); - type = cstyle->marginRight().type(); - if ( type != Variable ) - margins += (type == Fixed ? cstyle->marginRight().value() : child->marginRight()); - childMin += margins; - childMax += margins; - } - } - - if (!child->isRenderInline() && !child->isText()) { - - bool qBreak = isTcQuirk && !child->isFloatingOrPositioned(); - // Case (2). Inline replaced elements and floats. - // Go ahead and terminate the current line as far as - // minwidth is concerned. - childMin += child->minWidth(); - childMax += child->maxWidth(); - - if (!qBreak && (autoWrap || oldAutoWrap)) { - if(m_minWidth < inlineMin) m_minWidth = inlineMin; - inlineMin = 0; - } - - // Check our "clear" setting. If we're supposed to clear the previous float, then - // go ahead and terminate maxwidth as well. - if (child->isFloating()) { - if (prevFloat && - ((inlineMax + childMax > floatMaxWidth) || - ((prevFloat->style()->floating() & FLEFT) && (child->style()->clear() & CLEFT)) || - ((prevFloat->style()->floating() & FRIGHT) && (child->style()->clear() & CRIGHT)))) { - m_maxWidth = kMax(inlineMax, (int)m_maxWidth); - inlineMax = 0; - } - prevFloat = child; - if (!floatMaxWidth) - floatMaxWidth = availableWidth(); - } - - // Add in text-indent. This is added in only once. - int ti = 0; - if ( !addedTextIndent ) { - addedTextIndent = true; - ti = style()->textIndent().minWidth( cw ); - childMin+=ti; - childMax+=ti; - } - - // Add our width to the max. - inlineMax += childMax; - - if (!autoWrap||qBreak) - inlineMin += childMin; - else { - // Now check our line. - inlineMin = childMin; - if(m_minWidth < inlineMin) m_minWidth = inlineMin; - - // Now start a new line. - inlineMin = 0; - } - - // We are no longer stripping whitespace at the start of - // a line. - if (!child->isFloating()) { - stripFrontSpaces = false; - trailingSpaceChild = 0; - } - } - else if (child->isText()) - { - // Case (3). Text. - RenderText* t = static_cast(child); - - // Determine if we have a breakable character. Pass in - // whether or not we should ignore any spaces at the front - // of the string. If those are going to be stripped out, - // then they shouldn't be considered in the breakable char - // check. - bool hasBreakableChar, hasBreak; - short beginMin, endMin; - bool beginWS, endWS; - short beginMax, endMax; - t->trimmedMinMaxWidth(beginMin, beginWS, endMin, endWS, hasBreakableChar, - hasBreak, beginMax, endMax, - childMin, childMax, stripFrontSpaces); - - // This text object is insignificant and will not be rendered. Just - // continue. - if (!hasBreak && childMax == 0) continue; - - if (stripFrontSpaces) - trailingSpaceChild = child; - else - trailingSpaceChild = 0; - - // Add in text-indent. This is added in only once. - int ti = 0; - if (!addedTextIndent) { - addedTextIndent = true; - ti = style()->textIndent().minWidth(cw); - childMin+=ti; beginMin += ti; - childMax+=ti; beginMax += ti; - } - - // If we have no breakable characters at all, - // then this is the easy case. We add ourselves to the current - // min and max and continue. - if (!hasBreakableChar) { - inlineMin += childMin; - } - else { - // We have a breakable character. Now we need to know if - // we start and end with whitespace. - if (beginWS) { - // Go ahead and end the current line. - if(m_minWidth < inlineMin) m_minWidth = inlineMin; - } - else { - inlineMin += beginMin; - if(m_minWidth < inlineMin) m_minWidth = inlineMin; - childMin -= ti; - } - - inlineMin = childMin; - - if (endWS) { - // We end in whitespace, which means we can go ahead - // and end our current line. - if(m_minWidth < inlineMin) m_minWidth = inlineMin; - inlineMin = 0; - } - else { - if(m_minWidth < inlineMin) m_minWidth = inlineMin; - inlineMin = endMin; - } - } - - if (hasBreak) { - inlineMax += beginMax; - if (m_maxWidth < inlineMax) m_maxWidth = inlineMax; - if (m_maxWidth < childMax) m_maxWidth = childMax; - inlineMax = endMax; - } - else - inlineMax += childMax; - } - } - else - { - if(m_minWidth < inlineMin) m_minWidth = inlineMin; - if(m_maxWidth < inlineMax) m_maxWidth = inlineMax; - inlineMin = inlineMax = 0; - stripFrontSpaces = true; - trailingSpaceChild = 0; - } - - oldAutoWrap = autoWrap; - } - - stripTrailingSpace(style()->preserveWS(), inlineMax, inlineMin, trailingSpaceChild); - - if(m_minWidth < inlineMin) m_minWidth = inlineMin; - if(m_maxWidth < inlineMax) m_maxWidth = inlineMax; - // kdDebug( 6040 ) << "m_minWidth=" << m_minWidth - // << " m_maxWidth=" << m_maxWidth << endl; -} - -// Use a very large value (in effect infinite). -#define BLOCK_MAX_WIDTH 15000 - -void RenderBlock::calcBlockMinMaxWidth() -{ - bool nowrap = !style()->autoWrap(); - - RenderObject *child = firstChild(); - RenderObject* prevFloat = 0; - int floatWidths = 0; - int floatMaxWidth = 0; - - while(child != 0) - { - // positioned children don't affect the minmaxwidth - if (child->isPositioned()) { - child = child->nextSibling(); - continue; - } - - if (prevFloat && (!child->isFloating() || - ((prevFloat->style()->floating() & FLEFT) && (child->style()->clear() & CLEFT)) || - ((prevFloat->style()->floating() & FRIGHT) && (child->style()->clear() & CRIGHT)))) { - m_maxWidth = kMax(floatWidths, m_maxWidth); - floatWidths = 0; - } - - Length ml = child->style()->marginLeft(); - Length mr = child->style()->marginRight(); - - // Call calcWidth on the child to ensure that our margins are - // up to date. This method can be called before the child has actually - // calculated its margins (which are computed inside calcWidth). - if (ml.isPercent() || mr.isPercent()) - calcWidth(); - - // A margin basically has three types: fixed, percentage, and auto (variable). - // Auto margins simply become 0 when computing min/max width. - // Fixed margins can be added in as is. - // Percentage margins are computed as a percentage of the width we calculated in - // the calcWidth call above. In this case we use the actual cached margin values on - // the RenderObject itself. - int margin = 0; - if (ml.isFixed()) - margin += ml.value(); - else if (ml.isPercent()) - margin += child->marginLeft(); - - if (mr.isFixed()) - margin += mr.value(); - else if (mr.isPercent()) - margin += child->marginRight(); - - if (margin < 0) margin = 0; - - int w = child->minWidth() + margin; - if(m_minWidth < w) m_minWidth = w; - // IE ignores tables for calculation of nowrap. Makes some sense. - if ( nowrap && !child->isTable() && m_maxWidth < w ) - m_maxWidth = w; - - w = child->maxWidth() + margin; - - if(m_maxWidth < w) m_maxWidth = w; - - if (child->isFloating()) { - if (prevFloat && (floatWidths + w > floatMaxWidth)) { - m_maxWidth = kMax(floatWidths, m_maxWidth); - floatWidths = w; - } else - floatWidths += w; - } else if (m_maxWidth < w) - m_maxWidth = w; - - // A very specific WinIE quirk. - // Example: - /* -

-
-
-
-
- */ - // In the above example, the inner absolute positioned block should have a computed width - // of 100px because of the table. - // We can achieve this effect by making the maxwidth of blocks that contain tables - // with percentage widths be infinite (as long as they are not inside a table cell). - if (style()->htmlHacks() && child->style()->width().isPercent() && - !isTableCell() && child->isTable() && m_maxWidth < BLOCK_MAX_WIDTH) { - RenderBlock* cb = containingBlock(); - while (!cb->isCanvas() && !cb->isTableCell()) - cb = cb->containingBlock(); - if (!cb->isTableCell()) - m_maxWidth = BLOCK_MAX_WIDTH; - } - if (child->isFloating()) { - prevFloat = child; - if (!floatMaxWidth) - floatMaxWidth = availableWidth(); - } - child = child->nextSibling(); - } - m_maxWidth = kMax(floatWidths, m_maxWidth); -} - -void RenderBlock::close() -{ - if (lastChild() && lastChild()->isAnonymousBlock()) - lastChild()->close(); - updateFirstLetter(); - RenderFlow::close(); -} - -int RenderBlock::getBaselineOfFirstLineBox() -{ - if (m_firstLineBox) - return m_firstLineBox->yPos() + m_firstLineBox->baseline(); - - if (isInline()) - return -1; // We're inline and had no line box, so we have no baseline we can return. - - for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) { - int result = curr->getBaselineOfFirstLineBox(); - if (result != -1) - return curr->yPos() + result; // Translate to our coordinate space. - } - - return -1; -} - -InlineFlowBox* RenderBlock::getFirstLineBox() -{ - if (m_firstLineBox) - return m_firstLineBox; - - if (isInline()) - return 0; // We're inline and had no line box, so we have no baseline we can return. - - for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) { - InlineFlowBox* result = curr->getFirstLineBox(); - if (result) - return result; - } - - return 0; -} - -bool RenderBlock::inRootBlockContext() const -{ - if (isTableCell() || isFloatingOrPositioned() || hasOverflowClip()) - return false; - - if (isRoot() || isCanvas()) - return true; - - return containingBlock()->inRootBlockContext(); -} - -const char *RenderBlock::renderName() const -{ - if (isFloating()) - return "RenderBlock (floating)"; - if (isPositioned()) - return "RenderBlock (positioned)"; - if (isAnonymousBlock() && m_avoidPageBreak) - return "RenderBlock (avoidPageBreak)"; - if (isAnonymousBlock()) - return "RenderBlock (anonymous)"; - else if (isAnonymous()) - return "RenderBlock (generated)"; - if (isRelPositioned()) - return "RenderBlock (relative positioned)"; - if (style() && style()->display() == COMPACT) - return "RenderBlock (compact)"; - if (style() && style()->display() == RUN_IN) - return "RenderBlock (run-in)"; - return "RenderBlock"; -} - -#ifdef ENABLE_DUMP -void RenderBlock::printTree(int indent) const -{ - RenderFlow::printTree(indent); - - if (m_floatingObjects) - { - TQPtrListIterator it(*m_floatingObjects); - FloatingObject *r; - for ( ; (r = it.current()); ++it ) - { - TQString s; - s.fill(' ', indent); - kdDebug() << s << renderName() << ": " << - (r->type == FloatingObject::FloatLeft ? "FloatLeft" : "FloatRight" ) << - "[" << r->node->renderName() << ": " << (void*)r->node << "] (" << r->startY << " - " << r->endY << ")" << "width: " << r->width << - endl; - } - } -} - -void RenderBlock::dump(TQTextStream &stream, const TQString &ind) const -{ - RenderFlow::dump(stream,ind); - - if (m_childrenInline) { stream << " childrenInline"; } - // FIXME: currently only print pre to not mess up regression - if (style()->preserveWS()) { stream << " pre"; } - if (m_firstLine) { stream << " firstLine"; } - - if (m_floatingObjects && !m_floatingObjects->isEmpty()) - { - stream << " special("; - TQPtrListIterator it(*m_floatingObjects); - FloatingObject *r; - bool first = true; - for ( ; (r = it.current()); ++it ) - { - if (!first) - stream << ","; - stream << r->node->renderName(); - first = false; - } - stream << ")"; - } - - // ### EClear m_clearStatus -} -#endif - -#undef DEBUG -#undef DEBUG_LAYOUT -#undef BOX_DEBUG - -} // namespace khtml - diff --git a/khtml/rendering/render_block.h b/khtml/rendering/render_block.h deleted file mode 100644 index 2b0e49398..000000000 --- a/khtml/rendering/render_block.h +++ /dev/null @@ -1,378 +0,0 @@ -/* - * This file is part of the render object implementation for KHTML. - * - * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) - * (C) 1999-2003 Antti Koivisto (koivisto@kde.org) - * (C) 2002-2003 Dirk Mueller (mueller@kde.org) - * (C) 2003 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef RENDER_BLOCK_H -#define RENDER_BLOCK_H - -#include - -#include "render_flow.h" - -namespace khtml { - -class RenderBlock : public RenderFlow -{ -public: - RenderBlock(DOM::NodeImpl* node); - virtual ~RenderBlock(); - - virtual const char *renderName() const; - - virtual bool isRenderBlock() const { return true; } - virtual bool isBlockFlow() const { return !isInline() && !isTable(); } - virtual bool isInlineFlow() const { return isInline() && !isReplaced(); } - virtual bool isInlineBlockOrInlineTable() const { return isInline() && isReplaced(); } - - virtual bool childrenInline() const { return m_childrenInline; } - virtual void setChildrenInline(bool b) { m_childrenInline = b; } - void makeChildrenNonInline(RenderObject* insertionPoint = 0); - - void makePageBreakAvoidBlocks(); - - // The height (and width) of a block when you include overflow spillage out of the bottom - // of the block (e.g., a
that has a 100px tall image inside - // it would have an overflow height of borderTop() + paddingTop() + 100px. - virtual int overflowHeight() const { return m_overflowHeight; } - virtual int overflowWidth() const { return m_overflowWidth; } - virtual int overflowLeft() const { return m_overflowLeft; } - virtual int overflowTop() const { return m_overflowTop; } - virtual void setOverflowHeight(int h) { m_overflowHeight = h; } - virtual void setOverflowWidth(int w) { m_overflowWidth = w; } - virtual void setOverflowLeft(int l) { m_overflowLeft = l; } - virtual void setOverflowTop(int t) { m_overflowTop = t; } - - virtual bool isSelfCollapsingBlock() const; - virtual bool isTopMarginQuirk() const { return m_topMarginQuirk; } - virtual bool isBottomMarginQuirk() const { return m_bottomMarginQuirk; } - - virtual short maxTopMargin(bool positive) const { - if (positive) - return m_maxTopPosMargin; - else - return m_maxTopNegMargin; - } - virtual short maxBottomMargin(bool positive) const { - if (positive) - return m_maxBottomPosMargin; - else - return m_maxBottomNegMargin; - } - - void initMaxMarginValues() { - if (m_marginTop >= 0) - m_maxTopPosMargin = m_marginTop; - else - m_maxTopNegMargin = -m_marginTop; - if (m_marginBottom >= 0) - m_maxBottomPosMargin = m_marginBottom; - else - m_maxBottomNegMargin = -m_marginBottom; - } - - virtual void addChildToFlow(RenderObject* newChild, RenderObject* beforeChild); - virtual void removeChild(RenderObject *oldChild); - - virtual void setStyle(RenderStyle* _style); - virtual void attach(); - void updateFirstLetter(); - - virtual void layout(); - void layoutBlock( bool relayoutChildren ); - void layoutBlockChildren( bool relayoutChildren ); - void layoutInlineChildren( bool relayoutChildren, int breakBeforeLine = 0); - - void layoutPositionedObjects( bool relayoutChildren ); - void insertPositionedObject(RenderObject *o); - void removePositionedObject(RenderObject *o); - - // Called to lay out the legend for a fieldset. - virtual RenderObject* layoutLegend(bool /*relayoutChildren*/) { return 0; }; - - // the implementation of the following functions is in bidi.cpp - void bidiReorderLine(const BidiIterator &start, const BidiIterator &end, BidiState &bidi ); - BidiIterator findNextLineBreak(BidiIterator &start, BidiState &info ); - InlineFlowBox* constructLine(const BidiIterator& start, const BidiIterator& end); - InlineFlowBox* createLineBoxes(RenderObject* obj); - void computeHorizontalPositionsForLine(InlineFlowBox* lineBox, BidiState &bidi); - void computeVerticalPositionsForLine(InlineFlowBox* lineBox); - bool clearLineOfPageBreaks(InlineFlowBox* lineBox); - void checkLinesForOverflow(); - void deleteEllipsisLineBoxes(); - void checkLinesForTextOverflow(); - // end bidi.cpp functions - - virtual void paint(PaintInfo& i, int tx, int ty); - void paintObject(PaintInfo& i, int tx, int ty, bool paintOutline = true); - void paintFloats(PaintInfo& i, int _tx, int _ty, bool paintSelection = false); - - void insertFloatingObject(RenderObject *o); - void removeFloatingObject(RenderObject *o); - - // called from lineWidth, to position the floats added in the last line. - void positionNewFloats(); - void clearFloats(); - int getClearDelta(RenderObject *child); - virtual void markAllDescendantsWithFloatsForLayout(RenderObject* floatToRemove = 0); - - // FIXME: containsFloats() should not return true if the floating objects list - // is empty. However, layoutInlineChildren() relies on the current behavior. - // http://bugzilla.opendarwin.org/show_bug.cgi?id=7395#c3 - virtual bool hasFloats() const { return m_floatingObjects!=0; } - virtual bool containsFloat(RenderObject* o) const; - - virtual bool hasOverhangingFloats() const { return floatBottom() > m_height; } - void addOverHangingFloats( RenderBlock *block, int xoffset, int yoffset, bool child ); - - int nearestFloatBottom(int height) const; - int floatBottom() const; - inline int leftBottom(); - inline int rightBottom(); - - virtual unsigned short lineWidth(int y, bool *canClearLine = 0) const; - virtual int lowestPosition(bool includeOverflowInterior=true, bool includeSelf=true) const; - virtual int rightmostPosition(bool includeOverflowInterior=true, bool includeSelf=true) const; - virtual int leftmostPosition(bool includeOverflowInterior=true, bool includeSelf=true) const; - virtual int highestPosition(bool includeOverflowInterior, bool includeSelf) const; - int lowestAbsolutePosition() const; - int leftmostAbsolutePosition() const; - int rightmostAbsolutePosition() const; - int highestAbsolutePosition() const; - - int rightOffset() const; - int rightRelOffset(int y, int fixedOffset, bool applyTextIndent=true, int *heightRemaining = 0, bool *canClearLine = 0) const; - int rightOffset(int y, bool *canClearLine = 0) const { return rightRelOffset(y, rightOffset(), true, 0, canClearLine); } - - int leftOffset() const; - int leftRelOffset(int y, int fixedOffset, bool applyTextIndent=true, int *heightRemaining = 0, bool *canClearLine = 0) const; - int leftOffset(int y, bool *canClearLine = 0) const { return leftRelOffset(y, leftOffset(), true, 0, canClearLine); } - - virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int _tx, int _ty, HitTestAction hitTestAction = HitTestAll, bool inside=false); - - bool isPointInScrollbar(int x, int y, int tx, int ty); - - virtual void calcMinMaxWidth(); - void calcInlineMinMaxWidth(); - void calcBlockMinMaxWidth(); - - virtual void close(); - - virtual int getBaselineOfFirstLineBox(); - virtual InlineFlowBox* getFirstLineBox(); - - RootInlineBox* firstRootBox() { return static_cast(m_firstLineBox); } - RootInlineBox* lastRootBox() { return static_cast(m_lastLineBox); } - - bool inRootBlockContext() const; - -#ifdef ENABLE_DUMP - virtual void printTree(int indent=0) const; - virtual void dump(TQTextStream &stream, const TQString &ind) const; -#endif - -protected: - void newLine(); - -protected: - struct FloatingObject { - enum Type { - FloatLeft, - FloatRight - }; - - FloatingObject(Type _type) { - node = 0; - startY = 0; - endY = 0; - type = _type; - left = 0; - width = 0; - noPaint = false; - crossedLayer = false; - - } - RenderObject* node; - int startY; - int endY; - short left; - short width; - Type type : 1; // left or right aligned - bool noPaint : 1; - bool crossedLayer : 1; // lock noPaint flag - }; - - // The following helper functions and structs are used by layoutBlockChildren. - class CompactInfo { - // A compact child that needs to be collapsed into the margin of the following block. - RenderObject* m_compact; - - // The block with the open margin that the compact child is going to place itself within. - RenderObject* m_block; - bool m_treatAsBlock : 1; - - public: - RenderObject* compact() const { return m_compact; } - RenderObject* block() const { return m_block; } - void setTreatAsBlock(bool b) { m_treatAsBlock = b; } - bool treatAsBlock() const { return m_treatAsBlock; } - bool matches(RenderObject* child) const { return m_compact && m_block == child; } - - void clear() { set(0, 0); } - void set(RenderObject* c, RenderObject* b) { m_compact = c; m_block = b; } - - CompactInfo() { clear(); } - }; - - class MarginInfo { - // Collapsing flags for whether we can collapse our margins with our children's margins. - bool m_canCollapseWithChildren : 1; - bool m_canCollapseTopWithChildren : 1; - bool m_canCollapseBottomWithChildren : 1; - - // Whether or not we are a quirky container, i.e., do we collapse away top and bottom - // margins in our container. Table cells and the body are the common examples. We - // also have a custom style property for Safari RSS to deal with TypePad blog articles. - bool m_quirkContainer : 1; - - // This flag tracks whether we are still looking at child margins that can all collapse together at the beginning of a block. - // They may or may not collapse with the top margin of the block (|m_canCollapseTopWithChildren| tells us that), but they will - // always be collapsing with one another. This variable can remain set to true through multiple iterations - // as long as we keep encountering self-collapsing blocks. - bool m_atTopOfBlock : 1; - - // This flag is set when we know we're examining bottom margins and we know we're at the bottom of the block. - bool m_atBottomOfBlock : 1; - - // If our last normal flow child was a self-collapsing block that cleared a float, - // we track it in this variable. - bool m_selfCollapsingBlockClearedFloat : 1; - - // These variables are used to detect quirky margins that we need to collapse away (in table cells - // and in the body element). - bool m_topQuirk : 1; - bool m_bottomQuirk : 1; - bool m_determinedTopQuirk : 1; - - // These flags track the previous maximal positive and negative margins. - int m_posMargin; - int m_negMargin; - - public: - MarginInfo(RenderBlock* b, int top, int bottom); - - void setAtTopOfBlock(bool b) { m_atTopOfBlock = b; } - void setAtBottomOfBlock(bool b) { m_atBottomOfBlock = b; } - void clearMargin() { m_posMargin = m_negMargin = 0; } - void setSelfCollapsingBlockClearedFloat(bool b) { m_selfCollapsingBlockClearedFloat = b; } - void setTopQuirk(bool b) { m_topQuirk = b; } - void setBottomQuirk(bool b) { m_bottomQuirk = b; } - void setDeterminedTopQuirk(bool b) { m_determinedTopQuirk = b; } - void setPosMargin(int p) { m_posMargin = p; } - void setNegMargin(int n) { m_negMargin = n; } - void setPosMarginIfLarger(int p) { if (p > m_posMargin) m_posMargin = p; } - void setNegMarginIfLarger(int n) { if (n > m_negMargin) m_negMargin = n; } - - void setMargin(int p, int n) { m_posMargin = p; m_negMargin = n; } - - bool atTopOfBlock() const { return m_atTopOfBlock; } - bool canCollapseWithTop() const { return m_atTopOfBlock && m_canCollapseTopWithChildren; } - bool canCollapseWithBottom() const { return m_atBottomOfBlock && m_canCollapseBottomWithChildren; } - bool canCollapseTopWithChildren() const { return m_canCollapseTopWithChildren; } - bool canCollapseBottomWithChildren() const { return m_canCollapseBottomWithChildren; } - bool selfCollapsingBlockClearedFloat() const { return m_selfCollapsingBlockClearedFloat; } - bool quirkContainer() const { return m_quirkContainer; } - bool determinedTopQuirk() const { return m_determinedTopQuirk; } - bool topQuirk() const { return m_topQuirk; } - bool bottomQuirk() const { return m_bottomQuirk; } - int posMargin() const { return m_posMargin; } - int negMargin() const { return m_negMargin; } - int margin() const { return m_posMargin - m_negMargin; } - }; - - class PageBreakInfo { - int m_pageBottom; // Next calculated page-break - bool m_forcePageBreak : 1; // Must break before next block - // ### to do better "page-break-after/before: avoid" this struct - // should keep a pagebreakAvoid block and gather children in it - public: - PageBreakInfo(int pageBottom) : m_pageBottom(pageBottom), m_forcePageBreak(false) {}; - bool forcePageBreak() { return m_forcePageBreak; } - void setForcePageBreak(bool b) { m_forcePageBreak = b; } - int pageBottom() { return m_pageBottom; }; - void setPageBottom(int bottom) { m_pageBottom = bottom; } - }; - - virtual bool canClear(RenderObject *child, PageBreakLevel level); - void clearPageBreak(RenderObject* child, int pageBottom); - - void adjustPositionedBlock(RenderObject* child, const MarginInfo& marginInfo); - void adjustFloatingBlock(const MarginInfo& marginInfo); - RenderObject* handleSpecialChild(RenderObject* child, const MarginInfo& marginInfo, CompactInfo& compactInfo, bool& handled); - RenderObject* handleFloatingChild(RenderObject* child, const MarginInfo& marginInfo, bool& handled); - RenderObject* handlePositionedChild(RenderObject* child, const MarginInfo& marginInfo, bool& handled); - RenderObject* handleCompactChild(RenderObject* child, CompactInfo& compactInfo, const MarginInfo& marginInfo, bool& handled); - RenderObject* handleRunInChild(RenderObject* child, bool& handled); - void collapseMargins(RenderObject* child, MarginInfo& marginInfo, int yPosEstimate); - void clearFloatsIfNeeded(RenderObject* child, MarginInfo& marginInfo, int oldTopPosMargin, int oldTopNegMargin); - void adjustSizeForCompactIfNeeded(RenderObject* child, CompactInfo& compactInfo); - void insertCompactIfNeeded(RenderObject* child, CompactInfo& compactInfo); - int estimateVerticalPosition(RenderObject* child, const MarginInfo& info); - void determineHorizontalPosition(RenderObject* child); - void handleBottomOfBlock(int top, int bottom, MarginInfo& marginInfo); - void setCollapsedBottomMargin(const MarginInfo& marginInfo); - void clearChildOfPageBreaks(RenderObject* child, PageBreakInfo &pageBreakInfo, MarginInfo &marginInfo); - // End helper functions and structs used by layoutBlockChildren. - -protected: - // How much content overflows out of our block vertically or horizontally (all we support - // for now is spillage out of the bottom and the right, which are the common cases). - int m_overflowHeight; - int m_overflowWidth; - - // Left and top overflow. - int m_overflowTop; - int m_overflowLeft; - -private: - TQPtrList* m_floatingObjects; - TQPtrList* m_positionedObjects; - - bool m_childrenInline : 1; - bool m_firstLine : 1; // used in inline layouting - EClear m_clearStatus : 2; // used during layuting of paragraphs - bool m_avoidPageBreak : 1; // anonymous avoid page-break block - bool m_topMarginQuirk : 1; - bool m_bottomMarginQuirk : 1; - - short m_maxTopPosMargin; - short m_maxTopNegMargin; - short m_maxBottomPosMargin; - short m_maxBottomNegMargin; - -}; - -} // namespace - -#endif // RENDER_BLOCK_H - diff --git a/khtml/rendering/render_body.cpp b/khtml/rendering/render_body.cpp deleted file mode 100644 index 541c9676d..000000000 --- a/khtml/rendering/render_body.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/** - * This file is part of the html renderer for KDE. - * - * Copyright (C) 2000-2003 Lars Knoll (knoll@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#include "rendering/render_body.h" -#include "rendering/render_canvas.h" -#include "html/html_baseimpl.h" -#include "xml/dom_docimpl.h" -#include "khtmlview.h" - -#include -#include - -using namespace khtml; -using namespace DOM; - -RenderBody::RenderBody(HTMLBodyElementImpl* element) - : RenderBlock(element) -{ - scrollbarsStyled = false; -} - -RenderBody::~RenderBody() -{ -} - -void RenderBody::setStyle(RenderStyle* style) -{ -// tqDebug("RenderBody::setStyle()"); - // ignore position: fixed on body - if (style->htmlHacks() && style->position() == FIXED) - style->setPosition(STATIC); - - RenderBlock::setStyle(style); - document()->setTextColor( style->color() ); - scrollbarsStyled = false; -} - -void RenderBody::paintBoxDecorations(PaintInfo& paintInfo, int _tx, int _ty) -{ - //kdDebug( 6040 ) << renderName() << "::paintDecorations()" << endl; - TQColor bgColor; - const BackgroundLayer *bgLayer = 0; - - if( parent()->style()->hasBackground() ) { - // the root element already has a non-transparent background of its own - // so we must fork our own. (CSS2.1 - 14.2 §4) - bgColor = style()->backgroundColor(); - bgLayer = style()->backgroundLayers(); - } - - int w = width(); - int h = height() + borderTopExtra() + borderBottomExtra(); - _ty -= borderTopExtra(); - - int my = kMax(_ty, paintInfo.r.y()); - int end = kMin( paintInfo.r.y()+paintInfo.r.height(), _ty + h ); - int mh = end - my; - - paintBackgrounds(paintInfo.p, bgColor, bgLayer, my, mh, _tx, _ty, w, h); - - if(style()->hasBorder()) - paintBorder( paintInfo.p, _tx, _ty, w, h, style() ); - -} - -void RenderBody::repaint(Priority p) -{ - RenderObject *cb = containingBlock(); - if(cb) - cb->repaint(p); -} - -void RenderBody::layout() -{ - // in quirk mode, we'll need to have our margins determined - // for percentage height calculations - if (style()->htmlHacks()) - calcHeight(); - RenderBlock::layout(); - - if (!scrollbarsStyled) - { - RenderCanvas* canvas = this->canvas(); - if (canvas->view()) - { - canvas->view()->horizontalScrollBar()->setPalette(style()->palette()); - canvas->view()->verticalScrollBar()->setPalette(style()->palette()); - } - scrollbarsStyled=true; - } -} - -int RenderBody::availableHeight() const -{ - int h = RenderBlock::availableHeight(); - - if( style()->marginTop().isFixed() ) - h -= style()->marginTop().value(); - if( style()->marginBottom().isFixed() ) - h -= style()->marginBottom().value(); - - return kMax(0, h); -} diff --git a/khtml/rendering/render_body.h b/khtml/rendering/render_body.h deleted file mode 100644 index 7951f73e1..000000000 --- a/khtml/rendering/render_body.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of the html renderer for KDE. - * - * Copyright (C) 2000-2003 Lars Knoll (knoll@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#ifndef RENDER_BODY -#define RENDER_BODY - -#include "rendering/render_block.h" - -namespace DOM -{ - class HTMLBodyElementImpl; -} - -namespace khtml { - -class RenderBody : public RenderBlock -{ -public: - RenderBody(DOM::HTMLBodyElementImpl* node); - virtual ~RenderBody(); - - virtual bool isBody() const { return true; } - - virtual const char *renderName() const { return "RenderBody"; } - virtual void repaint(Priority p=NormalPriority); - - virtual void layout(); - virtual void setStyle(RenderStyle* style); - - virtual int availableHeight() const; - -protected: - virtual void paintBoxDecorations(PaintInfo&, int _tx, int _ty); - bool scrollbarsStyled; -}; - -} // end namespace -#endif diff --git a/khtml/rendering/render_box.cpp b/khtml/rendering/render_box.cpp deleted file mode 100644 index 7400752ac..000000000 --- a/khtml/rendering/render_box.cpp +++ /dev/null @@ -1,2325 +0,0 @@ -/** - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * (C) 2002-2003 Apple Computer, Inc. - * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) - * (C) 2006 Samuel Weinig (sam.weinig@gmail.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -// ------------------------------------------------------------------------- -//#define DEBUG_LAYOUT -//#define CLIP_DEBUG - - -#include - -#include "misc/loader.h" -#include "rendering/render_replaced.h" -#include "rendering/render_canvas.h" -#include "rendering/render_table.h" -#include "rendering/render_inline.h" -#include "rendering/render_block.h" -#include "rendering/render_line.h" -#include "rendering/render_layer.h" -#include "misc/htmlhashes.h" -#include "xml/dom_nodeimpl.h" -#include "xml/dom_docimpl.h" -#include "html/html_elementimpl.h" - -#include -#include -#include -#include - - -using namespace DOM; -using namespace khtml; - -#define TABLECELLMARGIN -0x4000 - -RenderBox::RenderBox(DOM::NodeImpl* node) - : RenderContainer(node) -{ - m_minWidth = -1; - m_maxWidth = -1; - m_width = m_height = 0; - m_x = 0; - m_y = 0; - m_marginTop = 0; - m_marginBottom = 0; - m_marginLeft = 0; - m_marginRight = 0; - m_staticX = 0; - m_staticY = 0; - - m_placeHolderBox = 0; - m_layer = 0; -} - -RenderBlock* RenderBox::createAnonymousBlock() -{ - RenderStyle *newStyle = new RenderStyle(); - newStyle->inheritFrom(style()); - newStyle->setDisplay(BLOCK); - - RenderBlock *newBox = new (renderArena()) RenderBlock(document() /* anonymous*/); - newBox->setStyle(newStyle); - return newBox; -} - -void RenderBox::restructureParentFlow() { - if (!parent() || parent()->childrenInline() == isInline()) - return; - // We have gone from not affecting the inline status of the parent flow to suddenly - // having an impact. See if there is a mismatch between the parent flow's - // childrenInline() state and our state. - if (!isInline()) { - if (parent()->isRenderInline()) { - // We have to split the parent flow. - RenderInline* parentInline = static_cast(parent()); - RenderBlock* newBox = parentInline->createAnonymousBlock(); - - RenderFlow* oldContinuation = parent()->continuation(); - parentInline->setContinuation(newBox); - - RenderObject* beforeChild = nextSibling(); - parent()->removeChildNode(this); - parentInline->splitFlow(beforeChild, newBox, this, oldContinuation); - } - else if (parent()->isRenderBlock()) - static_cast(parent())->makeChildrenNonInline(); - } - else { - // An anonymous block must be made to wrap this inline. - RenderBlock* box = createAnonymousBlock(); - parent()->insertChildNode(box, this); - box->appendChildNode(parent()->removeChildNode(this)); - } -} - -static inline bool overflowAppliesTo(RenderObject* o) -{ - // css 2.1-11.1.1 - // 1) overflow only applies to non-replaced block-level elements, table cells, and inline-block elements - if (o->isRenderBlock() || o->isTableRow() || o->isTableSection()) - // 2) overflow on root applies to the viewport (cf. KHTMLView::layout) - if (!o->isRoot()) - // 3) overflow on body may apply to the viewport... - if (!o->isBody() - // ...but only for HTML documents... - || !o->document()->isHTMLDocument() - // ...and only when the root has a visible overflow - || !o->document()->documentElement()->renderer() - || !o->document()->documentElement()->renderer()->style() - || o->document()->documentElement()->renderer()->style()->hidesOverflow()) - return true; - - return false; -} - -void RenderBox::setStyle(RenderStyle *_style) -{ - bool affectsParent = style() && isFloatingOrPositioned() && - (!_style->isFloating() && _style->position() != ABSOLUTE && _style->position() != FIXED) && - parent() && (parent()->isBlockFlow() || parent()->isInlineFlow()); - - RenderContainer::setStyle(_style); - - // The root always paints its background/border. - if (isRoot()) - setShouldPaintBackgroundOrBorder(true); - - switch(_style->display()) - { - case INLINE: - case INLINE_BLOCK: - case INLINE_TABLE: - setInline(true); - break; - case RUN_IN: - if (isInline() && parent() && parent()->childrenInline()) - break; - default: - setInline(false); - } - - switch(_style->position()) - { - case ABSOLUTE: - case FIXED: - setPositioned(true); - break; - default: - setPositioned(false); - if( !isTableCell() && _style->isFloating() ) - setFloating(true); - - if( _style->position() == RELATIVE ) - setRelPositioned(true); - } - - if (overflowAppliesTo(this) && _style->hidesOverflow()) - setHasOverflowClip(); - - if (requiresLayer()) { - if (!m_layer) { - m_layer = new (renderArena()) RenderLayer(this); - m_layer->insertOnlyThisLayer(); - if (parent() && containingBlock()) - m_layer->updateLayerPosition(); - } - } - else if (m_layer && !isCanvas()) { - m_layer->removeOnlyThisLayer(); - m_layer = 0; - } - - if (m_layer) - m_layer->styleChanged(); - - if (style()->outlineWidth() > 0 && style()->outlineSize() > maximalOutlineSize(PaintActionOutline)) - static_cast(document()->renderer())->setMaximalOutlineSize(style()->outlineSize()); - if (affectsParent) - restructureParentFlow(); -} - -RenderBox::~RenderBox() -{ - //kdDebug( 6040 ) << "Element destructor: this=" << nodeName().string() << endl; -} - -void RenderBox::detach() -{ - RenderLayer* layer = m_layer; - RenderArena* arena = renderArena(); - - RenderContainer::detach(); - - if (layer) - layer->detach(arena); -} - -InlineBox* RenderBox::createInlineBox(bool /*makePlaceHolderBox*/, bool /*isRootLineBox*/) -{ - if (m_placeHolderBox) - m_placeHolderBox->detach(renderArena()); - return (m_placeHolderBox = new (renderArena()) InlineBox(this)); -} - -void RenderBox::deleteInlineBoxes(RenderArena* arena) -{ - if (m_placeHolderBox) { - m_placeHolderBox->detach( arena ? arena : renderArena() ); - m_placeHolderBox = 0; - } -} - -short RenderBox::contentWidth() const -{ - short w = m_width - style()->borderLeftWidth() - style()->borderRightWidth(); - w -= paddingLeft() + paddingRight(); - - if (m_layer && scrollsOverflowY()) - w -= m_layer->verticalScrollbarWidth(); - - //kdDebug( 6040 ) << "RenderBox::contentWidth(2) = " << w << endl; - return w; -} - -int RenderBox::contentHeight() const -{ - int h = m_height - style()->borderTopWidth() - style()->borderBottomWidth(); - h -= paddingTop() + paddingBottom(); - - if (m_layer && scrollsOverflowX()) - h -= m_layer->horizontalScrollbarHeight(); - - return h; -} - -void RenderBox::setPos( int xPos, int yPos ) -{ - m_x = xPos; m_y = yPos; -} - -short RenderBox::width() const -{ - return m_width; -} - -int RenderBox::height() const -{ - return m_height; -} - -void RenderBox::setWidth( int width ) -{ - m_width = width; -} - -void RenderBox::setHeight( int height ) -{ - m_height = height; -} - -int RenderBox::calcBoxHeight(int h) const -{ - if (style()->boxSizing() == CONTENT_BOX) - h += borderTop() + borderBottom() + paddingTop() + paddingBottom(); - - return h; -} - -int RenderBox::calcBoxWidth(int w) const -{ - if (style()->boxSizing() == CONTENT_BOX) - w += borderLeft() + borderRight() + paddingLeft() + paddingRight(); - - return w; -} - -int RenderBox::calcContentHeight(int h) const -{ - if (style()->boxSizing() == BORDER_BOX) - h -= borderTop() + borderBottom() + paddingTop() + paddingBottom(); - - return kMax(0, h); -} - -int RenderBox::calcContentWidth(int w) const -{ - if (style()->boxSizing() == BORDER_BOX) - w -= borderLeft() + borderRight() + paddingLeft() + paddingRight(); - - return kMax(0, w); -} - -// --------------------- painting stuff ------------------------------- - -void RenderBox::paint(PaintInfo& i, int _tx, int _ty) -{ - _tx += m_x; - _ty += m_y; - - if (hasOverflowClip() && m_layer) - m_layer->subtractScrollOffset(_tx, _ty); - - // default implementation. Just pass things through to the children - for(RenderObject* child = firstChild(); child; child = child->nextSibling()) - child->paint(i, _tx, _ty); -} - -void RenderBox::paintRootBoxDecorations(PaintInfo& paintInfo, int _tx, int _ty) -{ - //kdDebug( 6040 ) << renderName() << "::paintRootBoxDecorations()" << _tx << "/" << _ty << endl; - const BackgroundLayer* bgLayer = style()->backgroundLayers(); - TQColor bgColor = style()->backgroundColor(); - if (document()->isHTMLDocument() && !style()->hasBackground()) { - // Locate the element using the DOM. This is easier than trying - // to crawl around a render tree with potential :before/:after content and - // anonymous blocks created by inline tags etc. We can locate the - // render object very easily via the DOM. - HTMLElementImpl* body = document()->body(); - RenderObject* bodyObject = (body && body->id() == ID_BODY) ? body->renderer() : 0; - - if (bodyObject) { - bgLayer = bodyObject->style()->backgroundLayers(); - bgColor = bodyObject->style()->backgroundColor(); - } - } - - if( !bgColor.isValid() && canvas()->view()) - bgColor = canvas()->view()->palette().active().color(TQColorGroup::Base); - - int w = width(); - int h = height(); - - // kdDebug(0) << "width = " << w <view()) { - rw = canvas()->view()->contentsWidth(); - rh = canvas()->view()->contentsHeight(); - } else { - rw = canvas()->docWidth(); - rh = canvas()->docHeight(); - } - - // kdDebug(0) << "rw = " << rw <hasBorder()) - paintBorder( paintInfo.p, _tx, _ty, w, h, style() ); -} - -void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, int _tx, int _ty) -{ - //kdDebug( 6040 ) << renderName() << "::paintDecorations()" << endl; - - if(isRoot()) - return paintRootBoxDecorations(paintInfo, _tx, _ty); - - int w = width(); - int h = height() + borderTopExtra() + borderBottomExtra(); - _ty -= borderTopExtra(); - - int my = kMax(_ty,paintInfo.r.y()); - int end = kMin( paintInfo.r.y() + paintInfo.r.height(), _ty + h ); - int mh = end - my; - - // The only paints its background if the root element has defined a background - // independent of the body. Go through the DOM to get to the root element's render object, - // since the root could be inline and wrapped in an anonymous block. - - if (!isBody() || !document()->isHTMLDocument() || document()->documentElement()->renderer()->style()->hasBackground()) - paintBackgrounds(paintInfo.p, style()->backgroundColor(), style()->backgroundLayers(), my, mh, _tx, _ty, w, h); - - if(style()->hasBorder()) { - paintBorder(paintInfo.p, _tx, _ty, w, h, style()); - } -} - -void RenderBox::paintBackgrounds(TQPainter *p, const TQColor& c, const BackgroundLayer* bgLayer, int clipy, int cliph, int _tx, int _ty, int w, int height) - { - if (!bgLayer) return; - paintBackgrounds(p, c, bgLayer->next(), clipy, cliph, _tx, _ty, w, height); - paintBackground(p, c, bgLayer, clipy, cliph, _tx, _ty, w, height); -} - -void RenderBox::paintBackground(TQPainter *p, const TQColor& c, const BackgroundLayer* bgLayer, int clipy, int cliph, int _tx, int _ty, int w, int height) -{ - paintBackgroundExtended(p, c, bgLayer, clipy, cliph, _tx, _ty, w, height, - borderLeft(), borderRight(), paddingLeft(), paddingRight()); -} - -static void calculateBackgroundSize(const BackgroundLayer* bgLayer, int& scaledWidth, int& scaledHeight) -{ - CachedImage* bg = bgLayer->backgroundImage(); - - if (bgLayer->isBackgroundSizeSet()) { - Length bgWidth = bgLayer->backgroundSize().width; - Length bgHeight = bgLayer->backgroundSize().height; - - if (bgWidth.isPercent()) - scaledWidth = scaledWidth * bgWidth.value() / 100; - else if (bgWidth.isFixed()) - scaledWidth = bgWidth.value(); - else if (bgWidth.isVariable()) { - // If the width is auto and the height is not, we have to use the appropriate - // scale to maintain our aspect ratio. - if (bgHeight.isPercent()) { - int scaledH = scaledHeight * bgHeight.value() / 100; - scaledWidth = bg->pixmap_size().width() * scaledH / bg->pixmap_size().height(); - } else if (bgHeight.isFixed()) - scaledWidth = bg->pixmap_size().width() * bgHeight.value() / bg->pixmap_size().height(); - } - - if (bgHeight.isPercent()) - scaledHeight = scaledHeight * bgHeight.value() / 100; - else if (bgHeight.isFixed()) - scaledHeight = bgHeight.value(); - else if (bgHeight.isVariable()) { - // If the height is auto and the width is not, we have to use the appropriate - // scale to maintain our aspect ratio. - if (bgWidth.isPercent()) - scaledHeight = bg->pixmap_size().height() * scaledWidth / bg->pixmap_size().width(); - else if (bgWidth.isFixed()) - scaledHeight = bg->pixmap_size().height() * bgWidth.value() / bg->pixmap_size().width(); - else if (bgWidth.isVariable()) { - // If both width and height are auto, we just want to use the image's - // intrinsic size. - scaledWidth = bg->pixmap_size().width(); - scaledHeight = bg->pixmap_size().height(); - } - } - } else { - scaledWidth = bg->pixmap_size().width(); - scaledHeight = bg->pixmap_size().height(); - } -} - -void RenderBox::paintBackgroundExtended(TQPainter *p, const TQColor &c, const BackgroundLayer* bgLayer, int clipy, int cliph, - int _tx, int _ty, int w, int h, - int bleft, int bright, int pleft, int pright) -{ - if ( cliph < 0 ) - return; - - if (bgLayer->backgroundClip() != BGBORDER) { - // Clip to the padding or content boxes as necessary. - bool includePadding = bgLayer->backgroundClip() == BGCONTENT; - int x = _tx + bleft + (includePadding ? pleft : 0); - int y = _ty + borderTop() + (includePadding ? paddingTop() : 0); - int width = w - bleft - bright - (includePadding ? pleft + pright : 0); - int height = h - borderTop() - borderBottom() - (includePadding ? paddingTop() + paddingBottom() : 0); - p->save(); - p->setClipRect(TQRect(x, y, width, height), TQPainter::CoordPainter); - } - - CachedImage* bg = bgLayer->backgroundImage(); - bool shouldPaintBackgroundImage = bg && bg->pixmap_size() == bg->valid_rect().size() && !bg->isTransparent() && !bg->isErrorImage(); - TQColor bgColor = c; - - // Paint the color first underneath all images. - if (!bgLayer->next() && bgColor.isValid() && tqAlpha(bgColor.rgb()) > 0) - p->fillRect(_tx, clipy, w, cliph, bgColor); - - // no progressive loading of the background image - if (shouldPaintBackgroundImage) { - int sx = 0; - int sy = 0; - int cw,ch; - int cx,cy; - int scaledImageWidth, scaledImageHeight; - - // CSS2 chapter 14.2.1 - - if (bgLayer->backgroundAttachment()) { - //scroll - int hpab = 0, vpab = 0, left = 0, top = 0; // Init to 0 for background-origin of 'border' - if (bgLayer->backgroundOrigin() != BGBORDER) { - hpab += bleft + bright; - vpab += borderTop() + borderBottom(); - left += bleft; - top += borderTop(); - if (bgLayer->backgroundOrigin() == BGCONTENT) { - hpab += pleft + pright; - vpab += paddingTop() + paddingBottom(); - left += pleft; - top += paddingTop(); - } - } - - int pw = w - hpab; - int ph = h - vpab; - scaledImageWidth = pw; - scaledImageHeight = ph; - calculateBackgroundSize(bgLayer, scaledImageWidth, scaledImageHeight); - - EBackgroundRepeat bgr = bgLayer->backgroundRepeat(); - if (bgr == NO_REPEAT || bgr == REPEAT_Y) { - cw = scaledImageWidth; - int xPosition = bgLayer->backgroundXPosition().minWidth(pw-scaledImageWidth); - if ( xPosition >= 0 ) { - cx = _tx + xPosition; - cw = kMin(scaledImageWidth, pw - xPosition); - } - else { - cx = _tx; - if (scaledImageWidth > 0) { - sx = -xPosition; - cw = kMin(scaledImageWidth+xPosition, pw); - } - } - cx += left; - } else { - // repeat over x - cw = w; - cx = _tx; - if (scaledImageWidth > 0) { - int xPosition = bgLayer->backgroundXPosition().minWidth(pw-scaledImageWidth); - sx = scaledImageWidth - (xPosition % scaledImageWidth); - sx -= left % scaledImageWidth; - } - } - if (bgr == NO_REPEAT || bgr == REPEAT_X) { - ch = scaledImageHeight; - int yPosition = bgLayer->backgroundYPosition().minWidth(ph - scaledImageHeight); - if ( yPosition >= 0 ) { - cy = _ty + yPosition; - ch = kMin(ch, ph - yPosition); - } - else { - cy = _ty; - if (scaledImageHeight > 0) { - sy = -yPosition; - ch = kMin(scaledImageHeight+yPosition, ph); - } - } - - cy += top; - } else { - // repeat over y - ch = h; - cy = _ty; - if (scaledImageHeight > 0) { - int yPosition = bgLayer->backgroundYPosition().minWidth(ph - scaledImageHeight); - sy = scaledImageHeight - (yPosition % scaledImageHeight); - sy -= top % scaledImageHeight; - } - } - if (layer()) - layer()->scrollOffset(sx, sy); - } - else - { - //fixed - TQRect vr = viewRect(); - int pw = vr.width(); - int ph = vr.height(); - scaledImageWidth = pw; - scaledImageHeight = ph; - calculateBackgroundSize(bgLayer, scaledImageWidth, scaledImageHeight); - EBackgroundRepeat bgr = bgLayer->backgroundRepeat(); - - int xPosition = bgLayer->backgroundXPosition().minWidth(pw-scaledImageWidth); - if (bgr == NO_REPEAT || bgr == REPEAT_Y) { - cw = kMin(scaledImageWidth, pw - xPosition); - cx = vr.x() + xPosition; - } else { - cw = pw; - cx = vr.x(); - if (scaledImageWidth > 0) - sx = scaledImageWidth - xPosition % scaledImageWidth; - } - - int yPosition = bgLayer->backgroundYPosition().minWidth(ph-scaledImageHeight); - if (bgr == NO_REPEAT || bgr == REPEAT_X) { - ch = kMin(scaledImageHeight, ph - yPosition); - cy = vr.y() + yPosition; - } else { - ch = ph; - cy = vr.y(); - if (scaledImageHeight > 0) - sy = scaledImageHeight - yPosition % scaledImageHeight; - } - - TQRect fix(cx, cy, cw, ch); - TQRect ele(_tx, _ty, w, h); - TQRect b = fix.intersect(ele); - - //kdDebug() <<" ele is " << ele << " b is " << b << " fix is " << fix << endl; - sx+=b.x()-cx; - sy+=b.y()-cy; - cx=b.x();cy=b.y();cw=b.width();ch=b.height(); - } - // restrict painting to repaint-clip - if (cy < clipy) { - ch -= (clipy - cy); - sy += (clipy - cy); - cy = clipy; - } - ch = kMin(ch, cliph); - -// kdDebug() << " clipy, cliph: " << clipy << ", " << cliph << endl; -// kdDebug() << " drawTiledPixmap(" << cx << ", " << cy << ", " << cw << ", " << ch << ", " << sx << ", " << sy << ")" << endl; - if (cw>0 && ch>0) - p->drawTiledPixmap(cx, cy, cw, ch, bg->tiled_pixmap(c, scaledImageWidth, scaledImageHeight), sx, sy); - - } - - if (bgLayer->backgroundClip() != BGBORDER) - p->restore(); // Undo the background clip - -} - -void RenderBox::outlineBox(TQPainter *p, int _tx, int _ty, const char *color) -{ - p->setPen(TQPen(TQColor(color), 1, Qt::DotLine)); - p->setBrush( Qt::NoBrush ); - p->drawRect(_tx, _ty, m_width, m_height); -} - -TQRect RenderBox::getOverflowClipRect(int tx, int ty) -{ - // XXX When overflow-clip (CSS3) is implemented, we'll obtain the property - // here. - int bl=borderLeft(),bt=borderTop(),bb=borderBottom(),br=borderRight(); - int clipx = tx+bl; - int clipy = ty+bt; - int clipw = m_width-bl-br; - int cliph = m_height-bt-bb+borderTopExtra()+borderBottomExtra(); - - // Substract out scrollbars if we have them. - if (m_layer) { - clipw -= m_layer->verticalScrollbarWidth(); - cliph -= m_layer->horizontalScrollbarHeight(); - } - - return TQRect(clipx,clipy,clipw,cliph); -} - -TQRect RenderBox::getClipRect(int tx, int ty) -{ - int bl=borderLeft(),bt=borderTop(),bb=borderBottom(),br=borderRight(); - // ### what about paddings? - int clipw = m_width-bl-br; - int cliph = m_height-bt-bb; - - bool rtl = (style()->direction() == RTL); - - int clipleft = 0; - int clipright = clipw; - int cliptop = 0; - int clipbottom = cliph; - - if ( style()->hasClip() && style()->position() == ABSOLUTE ) { - // the only case we use the clip property according to CSS 2.1 - if (!style()->clipLeft().isVariable()) { - int c = style()->clipLeft().width(clipw); - if ( rtl ) - clipleft = clipw - c; - else - clipleft = c; - } - if (!style()->clipRight().isVariable()) { - int w = style()->clipRight().width(clipw); - if ( rtl ) { - clipright = clipw - w; - } else { - clipright = w; - } - } - if (!style()->clipTop().isVariable()) - cliptop = style()->clipTop().width(cliph); - if (!style()->clipBottom().isVariable()) - clipbottom = style()->clipBottom().width(cliph); - } - int clipx = tx + clipleft; - int clipy = ty + cliptop; - clipw = clipright-clipleft; - cliph = clipbottom-cliptop; - - //kdDebug( 6040 ) << "setting clip("<view()) - { - if (canvas()->pagedMode()) - return canvas()->width(); - else - return canvas()->view()->visibleWidth(); - } - - RenderBlock* cb = containingBlock(); - if (isRenderBlock() && cb->isTable() && static_cast(cb)->caption() == this) { - //captions are not affected by table border or padding - return cb->width(); - } - if (usesLineWidth()) - return cb->lineWidth(m_y); - else - return cb->contentWidth(); -} - -bool RenderBox::absolutePosition(int &_xPos, int &_yPos, bool f) const -{ - if ( style()->position() == FIXED ) - f = true; - RenderObject *o = container(); - if( o && o->absolutePosition(_xPos, _yPos, f)) - { - if ( o->layer() ) { - if (o->hasOverflowClip()) - o->layer()->subtractScrollOffset( _xPos, _yPos ); - if (isPositioned()) - o->layer()->checkInlineRelOffset(this, _xPos, _yPos); - } - - if(!isInline() || isReplaced()) { - _xPos += xPos(), - _yPos += yPos(); - } - - if(isRelPositioned()) - relativePositionOffset(_xPos, _yPos); - return true; - } - else - { - _xPos = 0; - _yPos = 0; - return false; - } -} - -void RenderBox::position(InlineBox* box, int /*from*/, int /*len*/, bool /*reverse*/) -{ - if (isPositioned()) { - // Cache the x position only if we were an INLINE type originally. - bool wasInline = style()->isOriginalDisplayInlineType(); - - if (wasInline && hasStaticX()) { - // The value is cached in the xPos of the box. We only need this value if - // our object was inline originally, since otherwise it would have ended up underneath - // the inlines. - m_staticX = box->xPos(); - } - else if (!wasInline && hasStaticY()) { - // Our object was a block originally, so we make our normal flow position be - // just below the line box (as though all the inlines that came before us got - // wrapped in an anonymous block, which is what would have happened had we been - // in flow). This value was cached in the yPos() of the box. - m_staticY = box->yPos(); - } - } - else if (isReplaced()) - setPos( box->xPos(), box->yPos() ); -} - -void RenderBox::repaint(Priority prior) -{ - int ow = style() ? style()->outlineSize() : 0; - if( isInline() && !isReplaced() ) - { - RenderObject* p = parent(); - Q_ASSERT(p); - while( p->isInline() && !p->isReplaced() ) - p = p->parent(); - int xoff = p->hasOverflowClip() ? 0 : p->overflowLeft(); - int yoff = p->hasOverflowClip() ? 0 : p->overflowTop(); - p->repaintRectangle( -ow + xoff, -ow + yoff, p->effectiveWidth()+ow*2, p->effectiveHeight()+ow*2, prior); - } - else - { - int xoff = hasOverflowClip() ? 0 : overflowLeft(); - int yoff = hasOverflowClip() ? 0 : overflowTop(); - repaintRectangle( -ow + xoff, -ow + yoff, effectiveWidth()+ow*2, effectiveHeight()+ow*2, prior); - } -} - -void RenderBox::repaintRectangle(int x, int y, int w, int h, Priority p, bool f) -{ - x += m_x; - y += m_y; - - // Apply the relative position offset when invalidating a rectangle. The layer - // is translated, but the render box isn't, so we need to do this to get the - // right dirty rect. Since this is called from RenderObject::setStyle, the relative position - // flag on the RenderObject has been cleared, so use the one on the style(). - if (style()->position() == RELATIVE && m_layer) - relativePositionOffset(x,y); - - if (style()->position() == FIXED) f=true; - - // kdDebug( 6040 ) << "RenderBox(" <layer()) { - if (o->style()->hidesOverflow() && o->layer() && !o->isInlineFlow()) - o->layer()->subtractScrollOffset(x,y); // For overflow:auto/scroll/hidden. - if (style()->position() == ABSOLUTE) - o->layer()->checkInlineRelOffset(this,x,y); - } - o->repaintRectangle(x, y, w, h, p, f); - } -} - -void RenderBox::relativePositionOffset(int &tx, int &ty) const -{ - if(!style()->left().isVariable()) - tx += style()->left().width(containingBlockWidth()); - else if(!style()->right().isVariable()) - tx -= style()->right().width(containingBlockWidth()); - if(!style()->top().isVariable()) - { - if (!style()->top().isPercent() - || containingBlock()->style()->height().isFixed()) - ty += style()->top().width(containingBlockHeight()); - } - else if(!style()->bottom().isVariable()) - { - if (!style()->bottom().isPercent() - || containingBlock()->style()->height().isFixed()) - ty -= style()->bottom().width(containingBlockHeight()); - } -} - -void RenderBox::calcWidth() -{ -#ifdef DEBUG_LAYOUT - kdDebug( 6040 ) << "RenderBox("<width(); - - Length ml = style()->marginLeft(); - Length mr = style()->marginRight(); - - int cw = containingBlockWidth(); - if (cw<0) cw = 0; - - m_marginLeft = 0; - m_marginRight = 0; - - if (isInline() && !isInlineBlockOrInlineTable()) - { - // just calculate margins - m_marginLeft = ml.minWidth(cw); - m_marginRight = mr.minWidth(cw); - if (treatAsReplaced) - { - m_width = calcBoxWidth(w.width(cw)); - m_width = KMAX(m_width, m_minWidth); - } - - return; - } - else - { - LengthType widthType, minWidthType, maxWidthType; - if (treatAsReplaced) { - m_width = calcBoxWidth(w.width(cw)); - widthType = w.type(); - } else { - m_width = calcWidthUsing(Width, cw, widthType); - int minW = calcWidthUsing(MinWidth, cw, minWidthType); - int maxW = style()->maxWidth().value() == UNDEFINED ? - m_width : calcWidthUsing(MaxWidth, cw, maxWidthType); - - if (m_width > maxW) { - m_width = maxW; - widthType = maxWidthType; - } - if (m_width < minW) { - m_width = minW; - widthType = minWidthType; - } - } - - if (widthType == Variable) { - // kdDebug( 6040 ) << "variable" << endl; - m_marginLeft = ml.minWidth(cw); - m_marginRight = mr.minWidth(cw); - } - else - { -// kdDebug( 6040 ) << "non-variable " << w.type << ","<< w.value << endl; - calcHorizontalMargins(ml,mr,cw); - } - } - - if (cw && cw != m_width + m_marginLeft + m_marginRight && !isFloating() && !isInline()) - { - if (containingBlock()->style()->direction()==LTR) - m_marginRight = cw - m_width - m_marginLeft; - else - m_marginLeft = cw - m_width - m_marginRight; - } - } - -#ifdef DEBUG_LAYOUT - kdDebug( 6040 ) << "RenderBox::calcWidth(): m_width=" << m_width << " containingBlockWidth()=" << containingBlockWidth() << endl; - kdDebug( 6040 ) << "m_marginLeft=" << m_marginLeft << " m_marginRight=" << m_marginRight << endl; -#endif -} - -int RenderBox::calcWidthUsing(WidthType widthType, int cw, LengthType& lengthType) -{ - int width = m_width; - Length w; - if (widthType == Width) - w = style()->width(); - else if (widthType == MinWidth) - w = style()->minWidth(); - else - w = style()->maxWidth(); - - lengthType = w.type(); - - if (lengthType == Variable) { - int marginLeft = style()->marginLeft().minWidth(cw); - int marginRight = style()->marginRight().minWidth(cw); - if (cw) width = cw - marginLeft - marginRight; - - // size to max width? - if (sizesToMaxWidth()) { - width = KMAX(width, (int)m_minWidth); - width = KMIN(width, (int)m_maxWidth); - } - } - else - { - width = calcBoxWidth(w.width(cw)); - } - - return width; -} - -void RenderBox::calcHorizontalMargins(const Length& ml, const Length& mr, int cw) -{ - if (isFloating() || isInline()) // Inline blocks/tables and floats don't have their margins increased. - { - m_marginLeft = ml.minWidth(cw); - m_marginRight = mr.minWidth(cw); - } - else - { - if ( (ml.isVariable() && mr.isVariable() && m_widthstyle()->textAlign() == KHTML_CENTER) ) - { - m_marginLeft = (cw - m_width)/2; - if (m_marginLeft<0) m_marginLeft=0; - m_marginRight = cw - m_width - m_marginLeft; - } - else if ( (mr.isVariable() && m_widthstyle()->direction() == RTL && - containingBlock()->style()->textAlign() == KHTML_LEFT)) - { - m_marginLeft = ml.width(cw); - m_marginRight = cw - m_width - m_marginLeft; - } - else if ( (ml.isVariable() && m_widthstyle()->direction() == LTR && - containingBlock()->style()->textAlign() == KHTML_RIGHT)) - { - m_marginRight = mr.width(cw); - m_marginLeft = cw - m_width - m_marginRight; - } - else - { - // this makes auto margins 0 if we failed a m_widthheight(); - checkMinMaxHeight = true; - } - - int height; - if (checkMinMaxHeight) { - height = calcHeightUsing(style()->height()); - if (height == -1) - height = m_height; - int minH = calcHeightUsing(style()->minHeight()); // Leave as -1 if unset. - int maxH = style()->maxHeight().value() == UNDEFINED ? height : calcHeightUsing(style()->maxHeight()); - if (maxH == -1) - maxH = height; - height = kMin(maxH, height); - height = kMax(minH, height); - } - else { - // The only times we don't check min/max height are when a fixed length has - // been given as an override. Just use that. - height = calcBoxHeight(h.value()); - } - - if (heightoverflowX() == OMARQUEE && m_layer && m_layer->marquee() && - m_layer->marquee()->isUnfurlMarquee() && !m_layer->marquee()->isHorizontal()) { - m_layer->marquee()->setEnd(m_height); - m_height = kMin(m_height, m_layer->marquee()->unfurlPos()); - } - -} - -int RenderBox::calcHeightUsing(const Length& h) -{ - int height = -1; - if (!h.isVariable()) { - if (h.isFixed()) - height = h.value(); - else if (h.isPercent()) - height = calcPercentageHeight(h); - if (height != -1) { - height = calcBoxHeight(height); - return height; - } - } - return height; -} - -int RenderBox::calcImplicitHeight() const { - assert(hasImplicitHeight()); - - RenderBlock* cb = containingBlock(); - // padding-box height - int ch = cb->height() - cb->borderTop() + cb->borderBottom(); - int top = style()->top().width(ch); - int bottom = style()->bottom().width(ch); - - return ch - top - bottom; -} - -int RenderBox::calcPercentageHeight(const Length& height, bool treatAsReplaced) const -{ - int result = -1; - RenderBlock* cb = containingBlock(); - // In quirk mode, table cells violate what the CSS spec says to do with heights. - if (cb->isTableCell() && style()->htmlHacks()) { - result = static_cast(cb)->cellPercentageHeight(); - } - - // Otherwise we only use our percentage height if our containing block had a specified - // height. - else if (cb->style()->height().isFixed()) - result = cb->calcContentHeight(cb->style()->height().value()); - else if (cb->style()->height().isPercent()) { - // We need to recur and compute the percentage height for our containing block. - result = cb->calcPercentageHeight(cb->style()->height(), treatAsReplaced); - if (result != -1) - result = cb->calcContentHeight(result); - } - else if (cb->isCanvas()) { - if (!canvas()->pagedMode()) - result = static_cast(cb)->viewportHeight(); - else - result = static_cast(cb)->height(); - result -= cb->style()->borderTopWidth() - cb->style()->borderBottomWidth(); - result -= cb->paddingTop() + cb->paddingBottom(); - } - else if (cb->isBody() && style()->htmlHacks() && - cb->style()->height().isVariable() && !cb->isFloatingOrPositioned()) { - int margins = cb->collapsedMarginTop() + cb->collapsedMarginBottom(); - int visHeight = canvas()->viewportHeight(); - RenderObject* p = cb->parent(); - result = visHeight - (margins + p->marginTop() + p->marginBottom() + - p->borderTop() + p->borderBottom() + - p->paddingTop() + p->paddingBottom()); - } - else if (cb->isRoot() && style()->htmlHacks() && cb->style()->height().isVariable()) { - int visHeight = canvas()->viewportHeight(); - result = visHeight - (marginTop() + marginBottom() + - borderTop() + borderBottom() + - paddingTop() + paddingBottom()); - } - else if (cb->isAnonymousBlock() || treatAsReplaced && style()->htmlHacks()) { - // IE quirk. - result = cb->calcPercentageHeight(cb->style()->height(), treatAsReplaced); - } - else if (cb->hasImplicitHeight()) { - result = cb->calcImplicitHeight(); - } - - if (result != -1) { - result = height.width(result); - if (cb->isTableCell() && style()->boxSizing() != BORDER_BOX) { - result -= (borderTop() + paddingTop() + borderBottom() + paddingBottom()); - result = kMax(0, result); - } - } - return result; -} - -short RenderBox::calcReplacedWidth() const -{ - int width = calcReplacedWidthUsing(Width); - int minW = calcReplacedWidthUsing(MinWidth); - int maxW = style()->maxWidth().value() == UNDEFINED ? width : calcReplacedWidthUsing(MaxWidth); - - if (width > maxW) - width = maxW; - - if (width < minW) - width = minW; - - return width; -} - -int RenderBox::calcReplacedWidthUsing(WidthType widthType) const -{ - Length w; - if (widthType == Width) - w = style()->width(); - else if (widthType == MinWidth) - w = style()->minWidth(); - else - w = style()->maxWidth(); - - switch (w.type()) { - case Fixed: - return w.value(); - case Percent: - { - const int cw = containingBlockWidth(); - if (cw > 0) { - int result = w.minWidth(cw); - return result; - } - } - // fall through - default: - return intrinsicWidth(); - } -} - -int RenderBox::calcReplacedHeight() const -{ - int height = calcReplacedHeightUsing(Height); - int minH = calcReplacedHeightUsing(MinHeight); - int maxH = style()->maxHeight().value() == UNDEFINED ? height : calcReplacedHeightUsing(MaxHeight); - - if (height > maxH) - height = maxH; - - if (height < minH) - height = minH; - - return height; -} - -int RenderBox::calcReplacedHeightUsing(HeightType heightType) const -{ - Length h; - if (heightType == Height) - h = style()->height(); - else if (heightType == MinHeight) - h = style()->minHeight(); - else - h = style()->maxHeight(); - switch( h.type() ) { - case Fixed: - return h.value(); - case Percent: - { - int th = calcPercentageHeight(h, true); - if (th != -1) - return th; - // fall through - } - default: - return intrinsicHeight(); - }; -} - -int RenderBox::availableHeight() const -{ - return availableHeightUsing(style()->height()); -} - -int RenderBox::availableHeightUsing(const Length& h) const -{ - if (h.isFixed()) - return calcContentHeight(h.value()); - - if (isCanvas()) - if (static_cast(this)->pagedMode()) - return static_cast(this)->pageHeight(); - else - return static_cast(this)->viewportHeight(); - - // We need to stop here, since we don't want to increase the height of the table - // artificially. We're going to rely on this cell getting expanded to some new - // height, and then when we lay out again we'll use the calculation below. - if (isTableCell() && (h.isVariable() || h.isPercent())) { - const RenderTableCell* tableCell = static_cast(this); - return tableCell->cellPercentageHeight() - - (borderTop()+borderBottom()+paddingTop()+paddingBottom()); - } - - if (h.isPercent()) - return calcContentHeight(h.width(containingBlock()->availableHeight())); - - // Check for implicit height - if (hasImplicitHeight()) - return calcImplicitHeight(); - - return containingBlock()->availableHeight(); -} - -int RenderBox::availableWidth() const -{ - return availableWidthUsing(style()->width()); -} - -int RenderBox::availableWidthUsing(const Length& w) const -{ - if (w.isFixed()) - return calcContentWidth(w.value()); - - if (isCanvas()) - return static_cast(this)->viewportWidth(); - - if (w.isPercent()) - return calcContentWidth(w.width(containingBlock()->availableWidth())); - - return containingBlock()->availableWidth(); -} - -void RenderBox::calcVerticalMargins() -{ - if( isTableCell() ) { - // table margins are basically infinite - m_marginTop = TABLECELLMARGIN; - m_marginBottom = TABLECELLMARGIN; - return; - } - - Length tm = style()->marginTop(); - Length bm = style()->marginBottom(); - - // margins are calculated with respect to the _width_ of - // the containing block (8.3) - int cw = containingBlock()->contentWidth(); - - m_marginTop = tm.minWidth(cw); - m_marginBottom = bm.minWidth(cw); -} - -void RenderBox::setStaticX(short staticX) -{ - m_staticX = staticX; -} - -void RenderBox::setStaticY(int staticY) -{ - m_staticY = staticY; -} - -void RenderBox::calcAbsoluteHorizontal() -{ - if (isReplaced()) { - calcAbsoluteHorizontalReplaced(); - return; - } - - // QUESTIONS - // FIXME 1: Which RenderObject's 'direction' property should used: the - // containing block (cb) as the spec seems to imply, the parent (parent()) as - // was previously done in calculating the static distances, or ourself, which - // was also previously done for deciding what to override when you had - // over-constrained margins? Also note that the container block is used - // in similar situations in other parts of the RenderBox class (see calcWidth() - // and calcHorizontalMargins()). For now we are using the parent for quirks - // mode and the containing block for strict mode. - - // FIXME 2: Can perhaps optimize out cases when max-width/min-width are greater - // than or less than the computed m_width. Be careful of box-sizing and - // percentage issues. - - // The following is based off of the W3C Working Draft from April 11, 2006 of - // CSS 2.1: Section 10.3.7 "Absolutely positioned, non-replaced elements" - // - // (block-style-comments in this function and in calcAbsoluteHorizontalValues() - // correspond to text from the spec) - - - // We don't use containingBlock(), since we may be positioned by an enclosing - // relative positioned inline. - const RenderObject* containerBlock = container(); - - // FIXME: This is incorrect for cases where the container block is a relatively - // positioned inline. - const int containerWidth = containingBlockWidth() + containerBlock->paddingLeft() + containerBlock->paddingRight(); - - // To match WinIE, in quirks mode use the parent's 'direction' property - // instead of the the container block's. - EDirection containerDirection = (style()->htmlHacks()) ? parent()->style()->direction() : containerBlock->style()->direction(); - - const int bordersPlusPadding = borderLeft() + borderRight() + paddingLeft() + paddingRight(); - const Length marginLeft = style()->marginLeft(); - const Length marginRight = style()->marginRight(); - Length left = style()->left(); - Length right = style()->right(); - - /*---------------------------------------------------------------------------*\ - * For the purposes of this section and the next, the term "static position" - * (of an element) refers, roughly, to the position an element would have had - * in the normal flow. More precisely: - * - * * The static position for 'left' is the distance from the left edge of the - * containing block to the left margin edge of a hypothetical box that would - * have been the first box of the element if its 'position' property had - * been 'static' and 'float' had been 'none'. The value is negative if the - * hypothetical box is to the left of the containing block. - * * The static position for 'right' is the distance from the right edge of the - * containing block to the right margin edge of the same hypothetical box as - * above. The value is positive if the hypothetical box is to the left of the - * containing block's edge. - * - * But rather than actually calculating the dimensions of that hypothetical box, - * user agents are free to make a guess at its probable position. - * - * For the purposes of calculating the static position, the containing block of - * fixed positioned elements is the initial containing block instead of the - * viewport, and all scrollable boxes should be assumed to be scrolled to their - * origin. - \*---------------------------------------------------------------------------*/ - - // Calculate the static distance if needed. - if (left.isVariable() && right.isVariable()) { - if (containerDirection == LTR) { - // 'm_staticX' should already have been set through layout of the parent. - int staticPosition = m_staticX - containerBlock->borderLeft(); - for (RenderObject* po = parent(); po && po != containerBlock; po = po->parent()) - staticPosition += po->xPos(); - left = Length(staticPosition, Fixed); - } else { - RenderObject* po = parent(); - // 'm_staticX' should already have been set through layout of the parent. - int staticPosition = m_staticX + containerWidth + containerBlock->borderRight() - po->width(); - for (; po && po != containerBlock; po = po->parent()) - staticPosition -= po->xPos(); - right = Length(staticPosition, Fixed); - } - } - - // Calculate constraint equation values for 'width' case. - calcAbsoluteHorizontalValues(style()->width(), containerBlock, containerDirection, - containerWidth, bordersPlusPadding, - left, right, marginLeft, marginRight, - m_width, m_marginLeft, m_marginRight, m_x); - // Calculate constraint equation values for 'max-width' case.calcContentWidth(width.width(containerWidth)); - if (style()->maxWidth().value() != UNDEFINED) { - short maxWidth; - short maxMarginLeft; - short maxMarginRight; - short maxXPos; - - calcAbsoluteHorizontalValues(style()->maxWidth(), containerBlock, containerDirection, - containerWidth, bordersPlusPadding, - left, right, marginLeft, marginRight, - maxWidth, maxMarginLeft, maxMarginRight, maxXPos); - - if (m_width > maxWidth) { - m_width = maxWidth; - m_marginLeft = maxMarginLeft; - m_marginRight = maxMarginRight; - m_x = maxXPos; - } - } - - // Calculate constraint equation values for 'min-width' case. - if (style()->minWidth().value()) { - short minWidth; - short minMarginLeft; - short minMarginRight; - short minXPos; - - calcAbsoluteHorizontalValues(style()->minWidth(), containerBlock, containerDirection, - containerWidth, bordersPlusPadding, - left, right, marginLeft, marginRight, - minWidth, minMarginLeft, minMarginRight, minXPos); - - if (m_width < minWidth) { - m_width = minWidth; - m_marginLeft = minMarginLeft; - m_marginRight = minMarginRight; - m_x = minXPos; - } - } - - // Put m_width into correct form. - m_width += bordersPlusPadding; -} - -void RenderBox::calcAbsoluteHorizontalValues(Length width, const RenderObject* containerBlock, EDirection containerDirection, - const int containerWidth, const int bordersPlusPadding, - const Length left, const Length right, const Length marginLeft, const Length marginRight, - short& widthValue, short& marginLeftValue, short& marginRightValue, short& xPos) -{ - // 'left' and 'right' cannot both be 'auto' because one would of been - // converted to the static postion already - assert(!(left.isVariable() && right.isVariable())); - - int leftValue = 0; - - bool widthIsAuto = width.isVariable(); - bool leftIsAuto = left.isVariable(); - bool rightIsAuto = right.isVariable(); - - if (!leftIsAuto && !widthIsAuto && !rightIsAuto) { - /*-----------------------------------------------------------------------*\ - * If none of the three is 'auto': If both 'margin-left' and 'margin- - * right' are 'auto', solve the equation under the extra constraint that - * the two margins get equal values, unless this would make them negative, - * in which case when direction of the containing block is 'ltr' ('rtl'), - * set 'margin-left' ('margin-right') to zero and solve for 'margin-right' - * ('margin-left'). If one of 'margin-left' or 'margin-right' is 'auto', - * solve the equation for that value. If the values are over-constrained, - * ignore the value for 'left' (in case the 'direction' property of the - * containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') - * and solve for that value. - \*-----------------------------------------------------------------------*/ - // NOTE: It is not necessary to solve for 'right' in the over constrained - // case because the value is not used for any further calculations. - - leftValue = left.width(containerWidth); - widthValue = calcContentWidth(width.width(containerWidth)); - - const int availableSpace = containerWidth - (leftValue + widthValue + right.width(containerWidth) + bordersPlusPadding); - - // Margins are now the only unknown - if (marginLeft.isVariable() && marginRight.isVariable()) { - // Both margins auto, solve for equality - if (availableSpace >= 0) { - marginLeftValue = availableSpace / 2; // split the diference - marginRightValue = availableSpace - marginLeftValue; // account for odd valued differences - } else { - // see FIXME 1 - if (containerDirection == LTR) { - marginLeftValue = 0; - marginRightValue = availableSpace; // will be negative - } else { - marginLeftValue = availableSpace; // will be negative - marginRightValue = 0; - } - } - } else if (marginLeft.isVariable()) { - // Solve for left margin - marginRightValue = marginRight.width(containerWidth); - marginLeftValue = availableSpace - marginRightValue; - } else if (marginRight.isVariable()) { - // Solve for right margin - marginLeftValue = marginLeft.width(containerWidth); - marginRightValue = availableSpace - marginLeftValue; - } else { - // Over-constrained, solve for left if direction is RTL - marginLeftValue = marginLeft.width(containerWidth); - marginRightValue = marginRight.width(containerWidth); - - // see FIXME 1 -- used to be "this->style()->direction()" - if (containerDirection == RTL) - leftValue = (availableSpace + leftValue) - marginLeftValue - marginRightValue; - } - } else { - /*--------------------------------------------------------------------*\ - * Otherwise, set 'auto' values for 'margin-left' and 'margin-right' - * to 0, and pick the one of the following six rules that applies. - * - * 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the - * width is shrink-to-fit. Then solve for 'left' - * - * OMIT RULE 2 AS IT SHOULD NEVER BE HIT - * ------------------------------------------------------------------ - * 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if - * the 'direction' property of the containing block is 'ltr' set - * 'left' to the static position, otherwise set 'right' to the - * static position. Then solve for 'left' (if 'direction is 'rtl') - * or 'right' (if 'direction' is 'ltr'). - * ------------------------------------------------------------------ - * - * 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the - * width is shrink-to-fit . Then solve for 'right' - * 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve - * for 'left' - * 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve - * for 'width' - * 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve - * for 'right' - * - * Calculation of the shrink-to-fit width is similar to calculating the - * width of a table cell using the automatic table layout algorithm. - * Roughly: calculate the preferred width by formatting the content - * without breaking lines other than where explicit line breaks occur, - * and also calculate the preferred minimum width, e.g., by trying all - * possible line breaks. CSS 2.1 does not define the exact algorithm. - * Thirdly, calculate the available width: this is found by solving - * for 'width' after setting 'left' (in case 1) or 'right' (in case 3) - * to 0. - * - * Then the shrink-to-fit width is: - * kMin(kMax(preferred minimum width, available width), preferred width). - \*--------------------------------------------------------------------*/ - // NOTE: For rules 3 and 6 it is not necessary to solve for 'right' - // because the value is not used for any further calculations. - - // Calculate margins, 'auto' margins are ignored. - marginLeftValue = marginLeft.minWidth(containerWidth); - marginRightValue = marginRight.minWidth(containerWidth); - - const int availableSpace = containerWidth - (marginLeftValue + marginRightValue + bordersPlusPadding); - - // FIXME: Is there a faster way to find the correct case? - // Use rule/case that applies. - if (leftIsAuto && widthIsAuto && !rightIsAuto) { - // RULE 1: (use shrink-to-fit for width, and solve of left) - int rightValue = right.width(containerWidth); - - // FIXME: would it be better to have shrink-to-fit in one step? - int preferredWidth = m_maxWidth - bordersPlusPadding; - int preferredMinWidth = m_minWidth - bordersPlusPadding; - int availableWidth = availableSpace - rightValue; - widthValue = kMin(kMax(preferredMinWidth, availableWidth), preferredWidth); - leftValue = availableSpace - (widthValue + rightValue); - } else if (!leftIsAuto && widthIsAuto && rightIsAuto) { - // RULE 3: (use shrink-to-fit for width, and no need solve of right) - leftValue = left.width(containerWidth); - - // FIXME: would it be better to have shrink-to-fit in one step? - int preferredWidth = m_maxWidth - bordersPlusPadding; - int preferredMinWidth = m_minWidth - bordersPlusPadding; - int availableWidth = availableSpace - leftValue; - widthValue = kMin(kMax(preferredMinWidth, availableWidth), preferredWidth); - } else if (leftIsAuto && !width.isVariable() && !rightIsAuto) { - // RULE 4: (solve for left) - widthValue = calcContentWidth(width.width(containerWidth)); - leftValue = availableSpace - (widthValue + right.width(containerWidth)); - } else if (!leftIsAuto && widthIsAuto && !rightIsAuto) { - // RULE 5: (solve for width) - leftValue = left.width(containerWidth); - widthValue = availableSpace - (leftValue + right.width(containerWidth)); - } else if (!leftIsAuto&& !widthIsAuto && rightIsAuto) { - // RULE 6: (no need solve for right) - leftValue = left.width(containerWidth); - widthValue = calcContentWidth(width.width(containerWidth)); - } - } - - // Use computed values to calculate the horizontal position. - xPos = leftValue + marginLeftValue + containerBlock->borderLeft(); -} - - -void RenderBox::calcAbsoluteVertical() -{ - if (isReplaced()) { - calcAbsoluteVerticalReplaced(); - return; - } - - // The following is based off of the W3C Working Draft from April 11, 2006 of - // CSS 2.1: Section 10.6.4 "Absolutely positioned, non-replaced elements" - // - // (block-style-comments in this function and in calcAbsoluteVerticalValues() - // correspond to text from the spec) - - - // We don't use containingBlock(), since we may be positioned by an enclosing relpositioned inline. - const RenderObject* containerBlock = container(); - const int containerHeight = containerBlock->height() - containerBlock->borderTop() - containerBlock->borderBottom(); - - const int bordersPlusPadding = borderTop() + borderBottom() + paddingTop() + paddingBottom(); - const Length marginTop = style()->marginTop(); - const Length marginBottom = style()->marginBottom(); - Length top = style()->top(); - Length bottom = style()->bottom(); - - /*---------------------------------------------------------------------------*\ - * For the purposes of this section and the next, the term "static position" - * (of an element) refers, roughly, to the position an element would have had - * in the normal flow. More precisely, the static position for 'top' is the - * distance from the top edge of the containing block to the top margin edge - * of a hypothetical box that would have been the first box of the element if - * its 'position' property had been 'static' and 'float' had been 'none'. The - * value is negative if the hypothetical box is above the containing block. - * - * But rather than actually calculating the dimensions of that hypothetical - * box, user agents are free to make a guess at its probable position. - * - * For the purposes of calculating the static position, the containing block - * of fixed positioned elements is the initial containing block instead of - * the viewport. - \*---------------------------------------------------------------------------*/ - - // Calculate the static distance if needed. - if (top.isVariable() && bottom.isVariable()) { - // m_staticY should already have been set through layout of the parent() - int staticTop = m_staticY - containerBlock->borderTop(); - for (RenderObject* po = parent(); po && po != containerBlock; po = po->parent()) { - staticTop += po->yPos(); - } - top.setValue(Fixed, staticTop); - } - - - int height; // Needed to compute overflow. - - // Calculate constraint equation values for 'height' case. - calcAbsoluteVerticalValues(style()->height(), containerBlock, containerHeight, bordersPlusPadding, - top, bottom, marginTop, marginBottom, - height, m_marginTop, m_marginBottom, m_y); - - // Avoid doing any work in the common case (where the values of min-height and max-height are their defaults). - // see FIXME 2 - - // Calculate constraint equation values for 'max-height' case. - if (style()->maxHeight().value() != UNDEFINED) { - int maxHeight; - short maxMarginTop; - short maxMarginBottom; - int maxYPos; - - calcAbsoluteVerticalValues(style()->maxHeight(), containerBlock, containerHeight, bordersPlusPadding, - top, bottom, marginTop, marginBottom, - maxHeight, maxMarginTop, maxMarginBottom, maxYPos); - - if (height > maxHeight) { - height = maxHeight; - m_marginTop = maxMarginTop; - m_marginBottom = maxMarginBottom; - m_y = maxYPos; - } - } - - // Calculate constraint equation values for 'min-height' case. - if (style()->minHeight().value()) { - int minHeight; - short minMarginTop; - short minMarginBottom; - int minYPos; - - calcAbsoluteVerticalValues(style()->minHeight(), containerBlock, containerHeight, bordersPlusPadding, - top, bottom, marginTop, marginBottom, - minHeight, minMarginTop, minMarginBottom, minYPos); - - if (height < minHeight) { - height = minHeight; - m_marginTop = minMarginTop; - m_marginBottom = minMarginBottom; - m_y = minYPos; - } - } - - height += bordersPlusPadding; - - // Set final height value. - m_height = height; -} - -void RenderBox::calcAbsoluteVerticalValues(Length height, const RenderObject* containerBlock, - const int containerHeight, const int bordersPlusPadding, - const Length top, const Length bottom, const Length marginTop, const Length marginBottom, - int& heightValue, short& marginTopValue, short& marginBottomValue, int& yPos) -{ - // 'top' and 'bottom' cannot both be 'auto' because 'top would of been - // converted to the static position in calcAbsoluteVertical() - assert(!(top.isVariable() && bottom.isVariable())); - - int contentHeight = m_height - bordersPlusPadding; - - int topValue = 0; - - bool heightIsAuto = height.isVariable(); - bool topIsAuto = top.isVariable(); - bool bottomIsAuto = bottom.isVariable(); - - if (isTable() && heightIsAuto) { - // Height is never unsolved for tables. "auto" means shrink to fit. - // Use our height instead. - heightValue = contentHeight; - heightIsAuto = false; - } else if (!heightIsAuto) { - heightValue = calcContentHeight(height.width(containerHeight)); - if (contentHeight > heightValue) { - if (!isTable()) - contentHeight = heightValue; - else - heightValue = contentHeight; - } - } - - - if (!topIsAuto && !heightIsAuto && !bottomIsAuto) { - /*-----------------------------------------------------------------------*\ - * If none of the three are 'auto': If both 'margin-top' and 'margin- - * bottom' are 'auto', solve the equation under the extra constraint that - * the two margins get equal values. If one of 'margin-top' or 'margin- - * bottom' is 'auto', solve the equation for that value. If the values - * are over-constrained, ignore the value for 'bottom' and solve for that - * value. - \*-----------------------------------------------------------------------*/ - // NOTE: It is not necessary to solve for 'bottom' in the over constrained - // case because the value is not used for any further calculations. - - topValue = top.width(containerHeight); - - const int availableSpace = containerHeight - (topValue + heightValue + bottom.width(containerHeight) + bordersPlusPadding); - - // Margins are now the only unknown - if (marginTop.isVariable() && marginBottom.isVariable()) { - // Both margins auto, solve for equality - // NOTE: This may result in negative values. - marginTopValue = availableSpace / 2; // split the diference - marginBottomValue = availableSpace - marginTopValue; // account for odd valued differences - } else if (marginTop.isVariable()) { - // Solve for top margin - marginBottomValue = marginBottom.width(containerHeight); - marginTopValue = availableSpace - marginBottomValue; - } else if (marginBottom.isVariable()) { - // Solve for bottom margin - marginTopValue = marginTop.width(containerHeight); - marginBottomValue = availableSpace - marginTopValue; - } else { - // Over-constrained, (no need solve for bottom) - marginTopValue = marginTop.width(containerHeight); - marginBottomValue = marginBottom.width(containerHeight); - } - } else { - /*--------------------------------------------------------------------*\ - * Otherwise, set 'auto' values for 'margin-top' and 'margin-bottom' - * to 0, and pick the one of the following six rules that applies. - * - * 1. 'top' and 'height' are 'auto' and 'bottom' is not 'auto', then - * the height is based on the content, and solve for 'top'. - * - * OMIT RULE 2 AS IT SHOULD NEVER BE HIT - * ------------------------------------------------------------------ - * 2. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then - * set 'top' to the static position, and solve for 'bottom'. - * ------------------------------------------------------------------ - * - * 3. 'height' and 'bottom' are 'auto' and 'top' is not 'auto', then - * the height is based on the content, and solve for 'bottom'. - * 4. 'top' is 'auto', 'height' and 'bottom' are not 'auto', and - * solve for 'top'. - * 5. 'height' is 'auto', 'top' and 'bottom' are not 'auto', and - * solve for 'height'. - * 6. 'bottom' is 'auto', 'top' and 'height' are not 'auto', and - * solve for 'bottom'. - \*--------------------------------------------------------------------*/ - // NOTE: For rules 3 and 6 it is not necessary to solve for 'bottom' - // because the value is not used for any further calculations. - - // Calculate margins, 'auto' margins are ignored. - marginTopValue = marginTop.minWidth(containerHeight); - marginBottomValue = marginBottom.minWidth(containerHeight); - - const int availableSpace = containerHeight - (marginTopValue + marginBottomValue + bordersPlusPadding); - - // Use rule/case that applies. - if (topIsAuto && heightIsAuto && !bottomIsAuto) { - // RULE 1: (height is content based, solve of top) - heightValue = contentHeight; - topValue = availableSpace - (heightValue + bottom.width(containerHeight)); - } - else if (topIsAuto && !heightIsAuto && bottomIsAuto) { - // RULE 2: (shouldn't happen) - } - else if (!topIsAuto && heightIsAuto && bottomIsAuto) { - // RULE 3: (height is content based, no need solve of bottom) - heightValue = contentHeight; - topValue = top.width(containerHeight); - } else if (topIsAuto && !heightIsAuto && !bottomIsAuto) { - // RULE 4: (solve of top) - topValue = availableSpace - (heightValue + bottom.width(containerHeight)); - } else if (!topIsAuto && heightIsAuto && !bottomIsAuto) { - // RULE 5: (solve of height) - topValue = top.width(containerHeight); - heightValue = kMax(0, availableSpace - (topValue + bottom.width(containerHeight))); - } else if (!topIsAuto && !heightIsAuto && bottomIsAuto) { - // RULE 6: (no need solve of bottom) - topValue = top.width(containerHeight); - } - } - - // Use computed values to calculate the vertical position. - yPos = topValue + marginTopValue + containerBlock->borderTop(); -} - -void RenderBox::calcAbsoluteHorizontalReplaced() -{ - // The following is based off of the W3C Working Draft from April 11, 2006 of - // CSS 2.1: Section 10.3.8 "Absolutly positioned, replaced elements" - // - // (block-style-comments in this function correspond to text from the spec and - // the numbers correspond to numbers in spec) - - // We don't use containingBlock(), since we may be positioned by an enclosing relpositioned inline. - const RenderObject* containerBlock = container(); - - // FIXME: This is incorrect for cases where the container block is a relatively - // positioned inline. - const int containerWidth = containingBlockWidth() + containerBlock->paddingLeft() + containerBlock->paddingRight(); - - // To match WinIE, in quirks mode use the parent's 'direction' property - // instead of the the container block's. - EDirection containerDirection = (style()->htmlHacks()) ? parent()->style()->direction() : containerBlock->style()->direction(); - - // Variables to solve. - Length left = style()->left(); - Length right = style()->right(); - Length marginLeft = style()->marginLeft(); - Length marginRight = style()->marginRight(); - - - /*-----------------------------------------------------------------------*\ - * 1. The used value of 'width' is determined as for inline replaced - * elements. - \*-----------------------------------------------------------------------*/ - // NOTE: This value of width is FINAL in that the min/max width calculations - // are dealt with in calcReplacedWidth(). This means that the steps to produce - // correct max/min in the non-replaced version, are not necessary. - m_width = calcReplacedWidth() + borderLeft() + borderRight() + paddingLeft() + paddingRight(); - const int availableSpace = containerWidth - m_width; - - /*-----------------------------------------------------------------------*\ - * 2. If both 'left' and 'right' have the value 'auto', then if 'direction' - * of the containing block is 'ltr', set 'left' to the static position; - * else if 'direction' is 'rtl', set 'right' to the static position. - \*-----------------------------------------------------------------------*/ - if (left.isVariable() && right.isVariable()) { - // see FIXME 1 - if (containerDirection == LTR) { - // 'm_staticX' should already have been set through layout of the parent. - int staticPosition = m_staticX - containerBlock->borderLeft(); - for (RenderObject* po = parent(); po && po != containerBlock; po = po->parent()) - staticPosition += po->xPos(); - left.setValue(Fixed, staticPosition); - } else { - RenderObject* po = parent(); - // 'm_staticX' should already have been set through layout of the parent. - int staticPosition = m_staticX + containerWidth + containerBlock->borderRight() - po->width(); - for (; po && po != containerBlock; po = po->parent()) - staticPosition -= po->xPos(); - right.setValue(Fixed, staticPosition); - } - } - - /*-----------------------------------------------------------------------*\ - * 3. If 'left' or 'right' are 'auto', replace any 'auto' on 'margin-left' - * or 'margin-right' with '0'. - \*-----------------------------------------------------------------------*/ - if (left.isVariable() || right.isVariable()) { - if (marginLeft.isVariable()) - marginLeft.setValue(Fixed, 0); - if (marginRight.isVariable()) - marginRight.setValue(Fixed, 0); - } - - /*-----------------------------------------------------------------------*\ - * 4. If at this point both 'margin-left' and 'margin-right' are still - * 'auto', solve the equation under the extra constraint that the two - * margins must get equal values, unless this would make them negative, - * in which case when the direction of the containing block is 'ltr' - * ('rtl'), set 'margin-left' ('margin-right') to zero and solve for - * 'margin-right' ('margin-left'). - \*-----------------------------------------------------------------------*/ - int leftValue = 0; - int rightValue = 0; - - if (marginLeft.isVariable() && marginRight.isVariable()) { - // 'left' and 'right' cannot be 'auto' due to step 3 - assert(!(left.isVariable() && right.isVariable())); - - leftValue = left.width(containerWidth); - rightValue = right.width(containerWidth); - - int difference = availableSpace - (leftValue + rightValue); - if (difference > 0) { - m_marginLeft = difference / 2; // split the diference - m_marginRight = difference - m_marginLeft; // account for odd valued differences - } else { - // see FIXME 1 - if (containerDirection == LTR) { - m_marginLeft = 0; - m_marginRight = difference; // will be negative - } else { - m_marginLeft = difference; // will be negative - m_marginRight = 0; - } - } - - /*-----------------------------------------------------------------------*\ - * 5. If at this point there is an 'auto' left, solve the equation for - * that value. - \*-----------------------------------------------------------------------*/ - } else if (left.isVariable()) { - m_marginLeft = marginLeft.width(containerWidth); - m_marginRight = marginRight.width(containerWidth); - rightValue = right.width(containerWidth); - - // Solve for 'left' - leftValue = availableSpace - (rightValue + m_marginLeft + m_marginRight); - } else if (right.isVariable()) { - m_marginLeft = marginLeft.width(containerWidth); - m_marginRight = marginRight.width(containerWidth); - leftValue = left.width(containerWidth); - - // Solve for 'right' - rightValue = availableSpace - (leftValue + m_marginLeft + m_marginRight); - } else if (marginLeft.isVariable()) { - m_marginRight = marginRight.width(containerWidth); - leftValue = left.width(containerWidth); - rightValue = right.width(containerWidth); - - // Solve for 'margin-left' - m_marginLeft = availableSpace - (leftValue + rightValue + m_marginRight); - } else if (marginRight.isVariable()) { - m_marginLeft = marginLeft.width(containerWidth); - leftValue = left.width(containerWidth); - rightValue = right.width(containerWidth); - - // Solve for 'margin-right' - m_marginRight = availableSpace - (leftValue + rightValue + m_marginLeft); - } - - /*-----------------------------------------------------------------------*\ - * 6. If at this point the values are over-constrained, ignore the value - * for either 'left' (in case the 'direction' property of the - * containing block is 'rtl') or 'right' (in case 'direction' is - * 'ltr') and solve for that value. - \*-----------------------------------------------------------------------*/ - else { - m_marginLeft = marginLeft.width(containerWidth); - m_marginRight = marginRight.width(containerWidth); - if (containerDirection == LTR) { - leftValue = left.width(containerWidth); - rightValue = availableSpace - (leftValue + m_marginLeft + m_marginRight); - } - else { - rightValue = right.width(containerWidth); - leftValue = availableSpace - (rightValue + m_marginLeft + m_marginRight); - } - } - - int totalWidth = m_width + leftValue + rightValue + m_marginLeft + m_marginRight; - if (totalWidth > containerWidth && (containerDirection == RTL)) - leftValue = containerWidth - (totalWidth - leftValue); - - // Use computed values to calculate the horizontal position. - m_x = leftValue + m_marginLeft + containerBlock->borderLeft(); -} - -void RenderBox::calcAbsoluteVerticalReplaced() -{ - // The following is based off of the W3C Working Draft from April 11, 2006 of - // CSS 2.1: Section 10.6.5 "Absolutly positioned, replaced elements" - // - // (block-style-comments in this function correspond to text from the spec and - // the numbers correspond to numbers in spec) - - // We don't use containingBlock(), since we may be positioned by an enclosing relpositioned inline. - const RenderObject* containerBlock = container(); - const int containerHeight = containerBlock->height() - containerBlock->borderTop() - containerBlock->borderBottom(); - - // Variables to solve. - Length top = style()->top(); - Length bottom = style()->bottom(); - Length marginTop = style()->marginTop(); - Length marginBottom = style()->marginBottom(); - - - /*-----------------------------------------------------------------------*\ - * 1. The used value of 'height' is determined as for inline replaced - * elements. - \*-----------------------------------------------------------------------*/ - // NOTE: This value of height is FINAL in that the min/max height calculations - // are dealt with in calcReplacedHeight(). This means that the steps to produce - // correct max/min in the non-replaced version, are not necessary. - m_height = calcReplacedHeight() + borderTop() + borderBottom() + paddingTop() + paddingBottom(); - const int availableSpace = containerHeight - m_height; - - /*-----------------------------------------------------------------------*\ - * 2. If both 'top' and 'bottom' have the value 'auto', replace 'top' - * with the element's static position. - \*-----------------------------------------------------------------------*/ - if (top.isVariable() && bottom.isVariable()) { - // m_staticY should already have been set through layout of the parent(). - int staticTop = m_staticY - containerBlock->borderTop(); - for (RenderObject* po = parent(); po && po != containerBlock; po = po->parent()) { - staticTop += po->yPos(); - } - top.setValue(Fixed, staticTop); - } - - /*-----------------------------------------------------------------------*\ - * 3. If 'bottom' is 'auto', replace any 'auto' on 'margin-top' or - * 'margin-bottom' with '0'. - \*-----------------------------------------------------------------------*/ - // FIXME: The spec. says that this step should only be taken when bottom is - // auto, but if only top is auto, this makes step 4 impossible. - if (top.isVariable() || bottom.isVariable()) { - if (marginTop.isVariable()) - marginTop.setValue(Fixed, 0); - if (marginBottom.isVariable()) - marginBottom.setValue(Fixed, 0); - } - - /*-----------------------------------------------------------------------*\ - * 4. If at this point both 'margin-top' and 'margin-bottom' are still - * 'auto', solve the equation under the extra constraint that the two - * margins must get equal values. - \*-----------------------------------------------------------------------*/ - int topValue = 0; - int bottomValue = 0; - - if (marginTop.isVariable() && marginBottom.isVariable()) { - // 'top' and 'bottom' cannot be 'auto' due to step 2 and 3 combinded. - assert(!(top.isVariable() || bottom.isVariable())); - - topValue = top.width(containerHeight); - bottomValue = bottom.width(containerHeight); - - int difference = availableSpace - (topValue + bottomValue); - // NOTE: This may result in negative values. - m_marginTop = difference / 2; // split the difference - m_marginBottom = difference - m_marginTop; // account for odd valued differences - - /*-----------------------------------------------------------------------*\ - * 5. If at this point there is only one 'auto' left, solve the equation - * for that value. - \*-----------------------------------------------------------------------*/ - } else if (top.isVariable()) { - m_marginTop = marginTop.width(containerHeight); - m_marginBottom = marginBottom.width(containerHeight); - bottomValue = bottom.width(containerHeight); - - // Solve for 'top' - topValue = availableSpace - (bottomValue + m_marginTop + m_marginBottom); - } else if (bottom.isVariable()) { - m_marginTop = marginTop.width(containerHeight); - m_marginBottom = marginBottom.width(containerHeight); - topValue = top.width(containerHeight); - - // Solve for 'bottom' - // NOTE: It is not necessary to solve for 'bottom' because we don't ever - // use the value. - } else if (marginTop.isVariable()) { - m_marginBottom = marginBottom.width(containerHeight); - topValue = top.width(containerHeight); - bottomValue = bottom.width(containerHeight); - - // Solve for 'margin-top' - m_marginTop = availableSpace - (topValue + bottomValue + m_marginBottom); - } else if (marginBottom.isVariable()) { - m_marginTop = marginTop.width(containerHeight); - topValue = top.width(containerHeight); - bottomValue = bottom.width(containerHeight); - - // Solve for 'margin-bottom' - m_marginBottom = availableSpace - (topValue + bottomValue + m_marginTop); - } - - /*-----------------------------------------------------------------------*\ - * 6. If at this point the values are over-constrained, ignore the value - * for 'bottom' and solve for that value. - \*-----------------------------------------------------------------------*/ - else { - m_marginTop = marginTop.width(containerHeight); - m_marginBottom = marginBottom.width(containerHeight); - topValue = top.width(containerHeight); - - // Solve for 'bottom' - // NOTE: It is not necessary to solve for 'bottom' because we don't ever - // use the value. - } - - // Use computed values to calculate the vertical position. - m_y = topValue + m_marginTop + containerBlock->borderTop(); -} - -int RenderBox::highestPosition(bool /*includeOverflowInterior*/, bool includeSelf) const -{ - return includeSelf ? 0 : m_height; -} - -int RenderBox::lowestPosition(bool /*includeOverflowInterior*/, bool includeSelf) const -{ - return includeSelf ? m_height : 0; -} - -int RenderBox::rightmostPosition(bool /*includeOverflowInterior*/, bool includeSelf) const -{ - return includeSelf ? m_width : 0; -} - -int RenderBox::leftmostPosition(bool /*includeOverflowInterior*/, bool includeSelf) const -{ - return includeSelf ? 0 : m_width; -} - -int RenderBox::pageTopAfter(int y) const -{ - RenderObject* cb = container(); - if (cb) - return cb->pageTopAfter(y+yPos()) - yPos(); - else - return 0; -} - -int RenderBox::crossesPageBreak(int t, int b) const -{ - RenderObject* cb = container(); - if (cb) - return cb->crossesPageBreak(yPos()+t, yPos()+b); - else - return false; -} - -void RenderBox::caretPos(int /*offset*/, int flags, int &_x, int &_y, int &width, int &height) -{ -#if 0 - _x = -1; - - // propagate it downwards to its children, someone will feel responsible - RenderObject *child = firstChild(); -// if (child) kdDebug(6040) << "delegating caretPos to " << child->renderName() << endl; - if (child) child->caretPos(offset, override, _x, _y, width, height); - - // if not, use the extents of this box. offset 0 means left, offset 1 means - // right - if (_x == -1) { - //kdDebug(6040) << "no delegation" << endl; - _x = xPos() + (offset == 0 ? 0 : m_width); - _y = yPos(); - height = m_height; - width = override && offset == 0 ? m_width : 1; - - // If height of box is smaller than font height, use the latter one, - // otherwise the caret might become invisible. - // FIXME: ignoring :first-line, missing good reason to take care of - int fontHeight = style()->fontMetrics().height(); - if (fontHeight > height) - height = fontHeight; - - int absx, absy; - - RenderObject *cb = containingBlock(); - - if (cb && cb != this && cb->absolutePosition(absx,absy)) { - //kdDebug(6040) << "absx=" << absx << " absy=" << absy << endl; - _x += absx; - _y += absy; - } else { - // we don't know our absolute position, and there is no point returning - // just a relative one - _x = _y = -1; - } - } -#endif - - _x = xPos(); - _y = yPos(); -// kdDebug(6040) << "_x " << _x << " _y " << _y << endl; - width = 1; // no override is indicated in boxes - - RenderBlock *cb = containingBlock(); - - // Place caret outside the border - if (flags & CFOutside) { - - RenderStyle *s = element() && element()->parent() - && element()->parent()->renderer() - ? element()->parent()->renderer()->style() - : cb->style(); - - const TQFontMetrics &fm = s->fontMetrics(); - height = fm.height(); - - bool rtl = s->direction() == RTL; - bool outsideEnd = flags & CFOutsideEnd; - - if (outsideEnd) { - _x += this->width(); - } else { - _x--; - } - - int hl = fm.leading() / 2; - if (!isReplaced() || style()->display() == BLOCK) { - if (!outsideEnd ^ rtl) - _y -= hl; - else - _y += kMax(this->height() - fm.ascent() - hl, 0); - } else { - _y += baselinePosition(false) - fm.ascent() - hl; - } - - // Place caret inside the element - } else { - const TQFontMetrics &fm = style()->fontMetrics(); - height = fm.height(); - - RenderStyle *s = style(); - - _x += borderLeft() + paddingLeft(); - _y += borderTop() + paddingTop(); - - // ### regard direction - switch (s->textAlign()) { - case LEFT: - case KHTML_LEFT: - case TAAUTO: // ### find out what this does - case JUSTIFY: - break; - case CENTER: - case KHTML_CENTER: - _x += contentWidth() / 2; - break; - case KHTML_RIGHT: - case RIGHT: - _x += contentWidth(); - break; - } - } - - int absx, absy; - if (cb && cb != this && cb->absolutePosition(absx,absy)) { -// kdDebug(6040) << "absx=" << absx << " absy=" << absy << endl; - _x += absx; - _y += absy; - } else { - // we don't know our absolute position, and there is no point returning - // just a relative one - _x = _y = -1; - } -} - -#undef DEBUG_LAYOUT diff --git a/khtml/rendering/render_box.h b/khtml/rendering/render_box.h deleted file mode 100644 index c0c618d5c..000000000 --- a/khtml/rendering/render_box.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * (C) 2002-2003 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#ifndef RENDER_BOX_H -#define RENDER_BOX_H - -#include "render_container.h" - -namespace khtml { - -enum WidthType { Width, MinWidth, MaxWidth }; -enum HeightType { Height, MinHeight, MaxHeight }; - -class RenderBlock; - -class RenderBox : public RenderContainer -{ - - -// combines ElemImpl & PosElImpl (all rendering objects are positioned) -// should contain all border and padding handling - -public: - RenderBox(DOM::NodeImpl* node); - virtual ~RenderBox(); - - virtual const char *renderName() const { return "RenderBox"; } - virtual bool isBox() const { return true; } - - virtual void setStyle(RenderStyle *style); - virtual void paint(PaintInfo& i, int _tx, int _ty); - - virtual void close(); - - virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox); - virtual void deleteInlineBoxes(RenderArena* arena=0); - - virtual void detach(); - - virtual short minWidth() const { return m_minWidth; } - virtual int maxWidth() const { return m_maxWidth; } - - virtual short contentWidth() const; - virtual int contentHeight() const; - - virtual bool absolutePosition(int &xPos, int &yPos, bool f = false) const; - - virtual void setPos( int xPos, int yPos ); - - virtual int xPos() const { return m_x; } - virtual int yPos() const { return m_y; } - virtual short width() const; - virtual int height() const; - - virtual short marginTop() const { return m_marginTop; } - virtual short marginBottom() const { return m_marginBottom; } - virtual short marginLeft() const { return m_marginLeft; } - virtual short marginRight() const { return m_marginRight; } - - virtual void setWidth( int width ); - virtual void setHeight( int height ); - - virtual void position(InlineBox* box, int from, int len, bool reverse); - - virtual int highestPosition(bool includeOverflowInterior=true, bool includeSelf=true) const; - virtual int lowestPosition(bool includeOverflowInterior=true, bool includeSelf=true) const; - virtual int rightmostPosition(bool includeOverflowInterior=true, bool includeSelf=true) const; - virtual int leftmostPosition(bool includeOverflowInterior=true, bool includeSelf=true) const; - - virtual void repaint(Priority p=NormalPriority); - - virtual void repaintRectangle(int x, int y, int w, int h, Priority p=NormalPriority, bool f=false); - - virtual short containingBlockWidth() const; - void relativePositionOffset(int &tx, int &ty) const; - - virtual void calcWidth(); - virtual void calcHeight(); - - virtual short calcReplacedWidth() const; - virtual int calcReplacedHeight() const; - - virtual int availableHeight() const; - virtual int availableWidth() const; - - void calcVerticalMargins(); - - virtual RenderLayer* layer() const { return m_layer; } - - void setStaticX(short staticX); - void setStaticY(int staticY); - int staticX() const { return m_staticX; } - int staticY() const { return m_staticY; } - - virtual void caretPos(int offset, int flags, int &_x, int &_y, int &width, int &height); - - void calcHorizontalMargins(const Length& ml, const Length& mr, int cw); - RenderBlock* createAnonymousBlock(); - - virtual int pageTopAfter(int y) const; - virtual int crossesPageBreak(int t, int b) const; - - int calcBoxWidth(int w) const; - int calcBoxHeight(int h) const; - int calcContentWidth(int w) const; - int calcContentHeight(int h) const; - -protected: - int calcWidthUsing(WidthType widthType, int cw, LengthType& lengthType); - int calcHeightUsing(const Length& height); - int calcReplacedWidthUsing(WidthType widthType) const; - int calcReplacedHeightUsing(HeightType heightType) const; - int calcPercentageHeight(const Length& height, bool treatAsReplaced = false) const; - int availableHeightUsing(const Length& h) const; - int availableWidthUsing(const Length& w) const; - int calcImplicitHeight() const; - bool hasImplicitHeight() const { - return isPositioned() && !style()->top().isVariable() && !style()->bottom().isVariable(); - } - -protected: - virtual void paintBoxDecorations(PaintInfo& paintInfo, int _tx, int _ty); - void paintRootBoxDecorations( PaintInfo& paintInfo, int _tx, int _ty); - - void paintBackgrounds(TQPainter *p, const TQColor& c, const BackgroundLayer* bgLayer, int clipy, int cliph, int _tx, int _ty, int w, int h); - void paintBackground(TQPainter *p, const TQColor& c, const BackgroundLayer* bgLayer, int clipy, int cliph, int _tx, int _ty, int w, int h); - - virtual void paintBackgroundExtended(TQPainter* /*p*/, const TQColor& /*c*/, const BackgroundLayer* /*bgLayer*/, - int /*clipy*/, int /*cliph*/, int /*_tx*/, int /*_ty*/, - int /*w*/, int /*height*/, int /*bleft*/, int /*bright*/, int /*pleft*/, int /*pright*/ ); - - void outlineBox(TQPainter *p, int _tx, int _ty, const char *color = "red"); - - void calcAbsoluteHorizontal(); - void calcAbsoluteVertical(); - void calcAbsoluteHorizontalValues(Length width, const RenderObject* cb, EDirection containerDirection, - const int containerWidth, const int bordersPlusPadding, - const Length left, const Length right, const Length marginLeft, const Length marginRight, - short& widthValue, short& marginLeftValue, short& marginRightValue, short& xPos); - void calcAbsoluteVerticalValues(Length height, const RenderObject* cb, - const int containerHeight, const int bordersPlusPadding, - const Length top, const Length bottom, const Length marginTop, const Length marginBottom, - int& heightValue, short& marginTopValue, short& marginBottomValue, int& yPos); - - void calcAbsoluteVerticalReplaced(); - void calcAbsoluteHorizontalReplaced(); - - TQRect getOverflowClipRect(int tx, int ty); - TQRect getClipRect(int tx, int ty); - - void restructureParentFlow(); - - - // the actual height of the contents + borders + padding (border-box) - int m_height; - int m_y; - - short m_width; - short m_x; - - short m_marginTop; - short m_marginBottom; - - short m_marginLeft; - short m_marginRight; - - /* - * the minimum width the element needs, to be able to render - * its content without clipping - */ - short m_minWidth; - /* The maximum width the element can fill horizontally - * ( = the width of the element with line breaking disabled) - */ - int m_maxWidth; - - // Cached normal flow values for absolute positioned elements with static left/top values. - short m_staticX; - int m_staticY; - - RenderLayer *m_layer; - - /* A box used to represent this object on a line - * when its inner content isn't contextually relevant - * (e.g replaced or positioned elements) - */ - InlineBox *m_placeHolderBox; -}; - - -} //namespace - -#endif diff --git a/khtml/rendering/render_br.cpp b/khtml/rendering/render_br.cpp deleted file mode 100644 index 69984b760..000000000 --- a/khtml/rendering/render_br.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/** - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 2000 Lars Knoll (knoll@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#include "render_br.h" - -using namespace khtml; - - -RenderBR::RenderBR(DOM::NodeImpl* node) - : RenderText(node, new DOM::DOMStringImpl(TQChar('\n'))) -{ - m_hasReturn = true; -} - -RenderBR::~RenderBR() -{ -} - -#if 0 -void RenderBR::caretPos(int offset, int flags, int &_x, int &_y, int &width, int &height) -{ - RenderText::caretPos(offset,flags,_x,_y,width,height); - return; -#if 0 - if (previousSibling() && !previousSibling()->isBR() && !previousSibling()->isFloating()) { - int offset = 0; - if (previousSibling()->isText()) - offset = static_cast(previousSibling())->maxOffset(); - - // FIXME: this won't return a big width in override mode (LS) - previousSibling()->caretPos(offset,override,_x,_y,width,height); - return; - } - - int absx, absy; - absolutePosition(absx,absy); - if (absx == -1) { - // we don't know out absolute position, and there is no point returning - // just a relative one - _x = _y = -1; - } - else { - _x += absx; - _y += absy; - } - height = RenderText::verticalPositionHint( false ); - width = override ? height / 2 : 1; -#endif -} -#endif - -FindSelectionResult RenderBR::checkSelectionPoint(int _x, int _y, int _tx, int _ty, DOM::NodeImpl*& node, int &offset, SelPointState &state) -{ - // Simply take result of previous one - RenderText *prev = static_cast(previousSibling()); - if (!prev || !prev->isText() || !prev->inlineTextBoxCount() || prev->isBR()) - prev = this; - - //kdDebug(6040) << "delegated to " << prev->renderName() << "@" << prev << endl; - return prev->RenderText::checkSelectionPoint(_x, _y, _tx, _ty, node, offset, state); -} diff --git a/khtml/rendering/render_br.h b/khtml/rendering/render_br.h deleted file mode 100644 index f4175015f..000000000 --- a/khtml/rendering/render_br.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 2000 Lars Knoll (knoll@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#ifndef RENDER_BR_H -#define RENDER_BR_H - -#include "render_text.h" - -/* - * The whole class here is a hack to get
working, as long as we don't have support for - * CSS2 :before and :after pseudo elements - */ -namespace khtml { - -class RenderBR : public RenderText -{ -public: - RenderBR(DOM::NodeImpl* node); - virtual ~RenderBR(); - - virtual const char *renderName() const { return "RenderBR"; } - - virtual void paint( PaintInfo&, int, int) {} - - virtual unsigned int width(unsigned int, unsigned int, const Font *) const { return 0; } - virtual unsigned int width( unsigned int, unsigned int, bool) const { return 0; } - virtual short width() const { return RenderText::width(); } - - virtual int height() const { return 0; } - - // overrides - virtual void calcMinMaxWidth() {} - virtual short minWidth() const { return 0; } - virtual int maxWidth() const { return 0; } - - virtual FindSelectionResult checkSelectionPoint( int _x, int _y, int _tx, int _ty, - DOM::NodeImpl*& node, int & offset, - SelPointState & ); - - virtual bool isBR() const { return true; } -#if 0 - virtual void caretPos(int offset, int flags, int &_x, int &_y, int &width, int &height); -#endif - /** returns the lowest possible value the caret offset may have to - * still point to a valid position. - * - * Returns 0. - */ - virtual long minOffset() const { return 0; } - /** returns the highest possible value the caret offset may have to - * still point to a valid position. - * - * Returns also 0, as BRs have no width. - */ - virtual long maxOffset() const { return 0; } -}; - -} -#endif diff --git a/khtml/rendering/render_canvas.cpp b/khtml/rendering/render_canvas.cpp deleted file mode 100644 index e8540eba6..000000000 --- a/khtml/rendering/render_canvas.cpp +++ /dev/null @@ -1,780 +0,0 @@ -/** - * This file is part of the HTML widget for KDE. - * - * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) - * (C) 2003 Apple Computer, Inc. - * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - - -#include "rendering/render_canvas.h" -#include "rendering/render_layer.h" -#include "xml/dom_docimpl.h" - -#include "khtmlview.h" -#include "khtml_part.h" -#include -#include - -using namespace khtml; - -//#define BOX_DEBUG -//#define SPEED_DEBUG - -RenderCanvas::RenderCanvas(DOM::NodeImpl* node, KHTMLView *view) - : RenderBlock(node) -{ - // init RenderObject attributes - setInline(false); - setIsAnonymous(false); - - m_view = view; - // try to contrain the width to the views width - - m_minWidth = 0; - m_height = 0; - - m_width = m_minWidth; - m_maxWidth = m_minWidth; - - m_rootWidth = m_rootHeight = 0; - m_viewportWidth = m_viewportHeight = 0; - m_cachedDocWidth = m_cachedDocHeight = -1; - - setPositioned(true); // to 0,0 :) - - m_staticMode = false; - m_pagedMode = false; - m_printImages = true; - - m_pageTop = 0; - m_pageBottom = 0; - - m_page = 0; - - m_maximalOutlineSize = 0; - - m_selectionStart = 0; - m_selectionEnd = 0; - m_selectionStartPos = -1; - m_selectionEndPos = -1; - - m_needsWidgetMasks = false; - - // Create a new root layer for our layer hierarchy. - m_layer = new (node->getDocument()->renderArena()) RenderLayer(this); -} - -RenderCanvas::~RenderCanvas() -{ - delete m_page; -} - -void RenderCanvas::setStyle(RenderStyle* style) -{ - /* - if (m_pagedMode) - style->setOverflow(OHIDDEN); */ - RenderBlock::setStyle(style); -} - -void RenderCanvas::calcHeight() -{ - if (m_pagedMode || !m_view) - m_height = m_rootHeight; - else - m_height = m_view->visibleHeight(); -} - -void RenderCanvas::calcWidth() -{ - // the width gets set by KHTMLView::print when printing to a printer. - if(m_pagedMode || !m_view) - { - m_width = m_rootWidth; - return; - } - - m_width = m_view ? m_view->frameWidth() : m_minWidth; - - if (style()->marginLeft().isFixed()) - m_marginLeft = style()->marginLeft().value(); - else - m_marginLeft = 0; - - if (style()->marginRight().isFixed()) - m_marginRight = style()->marginRight().value(); - else - m_marginRight = 0; -} - -void RenderCanvas::calcMinMaxWidth() -{ - KHTMLAssert( !minMaxKnown() ); - - RenderBlock::calcMinMaxWidth(); - - m_maxWidth = m_minWidth; - - setMinMaxKnown(); -} - -//#define SPEED_DEBUG - -void RenderCanvas::layout() -{ - if (m_pagedMode) { - m_minWidth = m_width; -// m_maxWidth = m_width; - } - - m_needsFullRepaint = markedForRepaint() || !view() || view()->needsFullRepaint() || m_pagedMode; - - setChildNeedsLayout(true); - setMinMaxKnown(false); - for(RenderObject* c = firstChild(); c; c = c->nextSibling()) - c->setChildNeedsLayout(true); - - int oldWidth = m_width; - int oldHeight = m_height; - - m_cachedDocWidth = m_cachedDocHeight = -1; - - if (m_pagedMode || !m_view) { - m_width = m_rootWidth; - m_height = m_rootHeight; - } - else - { - m_viewportWidth = m_width = m_view->visibleWidth(); - m_viewportHeight = m_height = m_view->visibleHeight(); - } - -#ifdef SPEED_DEBUG - TQTime qt; - qt.start(); -#endif - - if ( recalcMinMax() ) - recalcMinMaxWidths(); - -#ifdef SPEED_DEBUG - kdDebug() << "RenderCanvas::calcMinMax time used=" << qt.elapsed() << endl; - qt.start(); -#endif - - bool relayoutChildren = (oldWidth != m_width) || (oldHeight != m_height); - - RenderBlock::layoutBlock( relayoutChildren ); - -#ifdef SPEED_DEBUG - kdDebug() << "RenderCanvas::layout time used=" << qt.elapsed() << endl; - qt.start(); -#endif - - updateDocumentSize(); - - layer()->updateLayerPositions( layer(), needsFullRepaint(), true ); - - if (!m_pagedMode && m_needsWidgetMasks) - layer()->updateWidgetMasks(layer()); - - scheduleDeferredRepaints(); - setNeedsLayout(false); - -#ifdef SPEED_DEBUG - kdDebug() << "RenderCanvas::end time used=" << qt.elapsed() << endl; -#endif -} - -void RenderCanvas::updateDocumentSize() -{ - // update our cached document size - int hDocH = m_cachedDocHeight = docHeight(); - int hDocW = m_cachedDocWidth = docWidth(); - - if (!m_pagedMode && m_view) { - - bool vss = m_view->verticalScrollBar()->isShown(); - bool hss = m_view->horizontalScrollBar()->isShown(); - TQSize s = m_view->viewportSize(m_cachedDocWidth, m_cachedDocHeight); - - // if we are about to show a scrollbar, and the document is sized to the viewport w or h, - // then reserve the scrollbar space so that it doesn't trigger the _other_ scrollbar - - if (!vss && m_width - m_view->verticalScrollBar()->sizeHint().width() == s.width() && - m_cachedDocWidth <= m_width) - hDocW = kMin( m_cachedDocWidth, s.width() ); - - if (!hss && m_height - m_view->horizontalScrollBar()->sizeHint().height() == s.height() && - m_cachedDocHeight <= m_height) - hDocH = kMin( m_cachedDocHeight, s.height() ); - - // likewise, if a scrollbar is shown, and we have a cunning plan to turn it off, - // think again if we are falling downright in the hysteresis zone - - if (vss && s.width() > m_cachedDocWidth && m_cachedDocWidth > m_view->visibleWidth()) - hDocW = s.width()+1; - - if (hss && s.height() > m_cachedDocHeight && m_cachedDocHeight > m_view->visibleHeight()) - hDocH = s.height()+1; - - m_view->resizeContents(hDocW, hDocH); - - setWidth( m_viewportWidth = s.width() ); - setHeight( m_viewportHeight = s.height() ); - } - layer()->resize( kMax( m_cachedDocWidth,int( m_width ) ), kMax( m_cachedDocHeight,m_height ) ); -} - -void RenderCanvas::updateDocSizeAfterLayerTranslation( RenderObject* o, bool posXOffset, bool posYOffset ) -{ - if (needsLayout()) - return; - int rightmost, lowest; - o->absolutePosition( rightmost, lowest ); - if (posXOffset) { - rightmost += o->rightmostPosition(false, true); - setCachedDocWidth( kMax(docWidth(), rightmost) ); - } else { - setCachedDocWidth( -1 ); - } - if (posYOffset) { - lowest += o->lowestPosition(false, true); - setCachedDocHeight( kMax(docHeight(), lowest) ); - } else { - setCachedDocHeight( -1 ); - } -// kdDebug() << " posXOffset: " << posXOffset << " posYOffset " << posYOffset << " m_cachedDocWidth " << m_cachedDocWidth << " m_cachedDocHeight " << m_cachedDocHeight << endl; - updateDocumentSize(); -} - -bool RenderCanvas::needsFullRepaint() const -{ - return m_needsFullRepaint || m_pagedMode; -} - -void RenderCanvas::repaintViewRectangle(int x, int y, int w, int h, bool asap) -{ - KHTMLAssert( view() ); - view()->scheduleRepaint( x, y, w, h, asap ); -} - -bool RenderCanvas::absolutePosition(int &xPos, int &yPos, bool f) const -{ - if ( f && m_pagedMode) { - xPos = 0; - yPos = m_pageTop; - } - else if ( f && m_view) { - xPos = m_view->contentsX(); - yPos = m_view->contentsY(); - } - else { - xPos = yPos = 0; - } - return true; -} - -void RenderCanvas::paint(PaintInfo& paintInfo, int _tx, int _ty) -{ -#ifdef DEBUG_LAYOUT - kdDebug( 6040 ) << renderName() << this << " ::paintObject() w/h = (" << width() << "/" << height() << ")" << endl; -#endif - - // 1. paint background, borders etc - if(paintInfo.phase == PaintActionElementBackground) { - paintBoxDecorations(paintInfo, _tx, _ty); - return; - } - - // 2. paint contents - for( RenderObject *child = firstChild(); child; child=child->nextSibling()) - if(!child->layer() && !child->isFloating()) - child->paint(paintInfo, _tx, _ty); - - // 3. paint floats. - if (paintInfo.phase == PaintActionFloat) - paintFloats(paintInfo, _tx, _ty); - -#ifdef BOX_DEBUG - if (m_view) - { - _tx += m_view->contentsX(); - _ty += m_view->contentsY(); - } - - outlineBox(p, _tx, _ty); -#endif - -} - -void RenderCanvas::paintBoxDecorations(PaintInfo& paintInfo, int /*_tx*/, int /*_ty*/) -{ - if ((firstChild() && firstChild()->style()->visibility() == VISIBLE) || !view()) - return; - - paintInfo.p->fillRect(paintInfo.r, view()->palette().active().color(TQColorGroup::Base)); -} - -void RenderCanvas::repaintRectangle(int x, int y, int w, int h, Priority p, bool f) -{ - if (m_staticMode) return; -// kdDebug( 6040 ) << "updating views contents (" << x << "/" << y << ") (" << w << "/" << h << ")" << endl; - - if (f && m_pagedMode) { - y += m_pageTop; - } else - if ( f && m_view ) { - x += m_view->contentsX(); - y += m_view->contentsY(); - } - - TQRect vr = viewRect(); - TQRect ur(x, y, w, h); - - if (m_view && ur.intersects(vr)) { - - if (p == RealtimePriority) - // ### KWQ's updateContents has an additional parameter "now". - // It's not clear what the difference between updateContents(...,true) - // and repaintContents(...) is. As Qt doesn't have this, I'm leaving it out. (LS) - m_view->updateContents(ur/*, true*/); - else if (p == HighPriority) - m_view->scheduleRepaint(x, y, w, h, true /*asap*/); - else - m_view->scheduleRepaint(x, y, w, h); - } -} - -void RenderCanvas::deferredRepaint( RenderObject* o ) -{ - m_dirtyChildren.append( o ); -} - -void RenderCanvas::scheduleDeferredRepaints() -{ - if (!needsFullRepaint()) { - TQValueList::const_iterator it; - for ( it = m_dirtyChildren.begin(); it != m_dirtyChildren.end(); ++it ) - (*it)->repaint(); - } - //kdDebug(6040) << "scheduled deferred repaints: " << m_dirtyChildren.count() << " needed full repaint: " << needsFullRepaint() << endl; - m_dirtyChildren.clear(); -} - -void RenderCanvas::repaint(Priority p) -{ - if (m_view && !m_staticMode) { - if (p == RealtimePriority) { - //m_view->resizeContents(docWidth(), docHeight()); - m_view->unscheduleRepaint(); - if (needsLayout()) { - m_view->scheduleRelayout(); - return; - } - // ### same as in repaintRectangle - m_view->updateContents(m_view->contentsX(), m_view->contentsY(), - m_view->visibleWidth(), m_view->visibleHeight()/*, true*/); - } - else if (p == HighPriority) - m_view->scheduleRepaint(m_view->contentsX(), m_view->contentsY(), - m_view->visibleWidth(), m_view->visibleHeight(), true /*asap*/); - else - m_view->scheduleRepaint(m_view->contentsX(), m_view->contentsY(), - m_view->visibleWidth(), m_view->visibleHeight()); - } -} - -static TQRect enclosingPositionedRect (RenderObject *n) -{ - RenderObject *enclosingParent = n->containingBlock(); - TQRect rect(0,0,0,0); - if (enclosingParent) { - int ox, oy; - enclosingParent->absolutePosition(ox, oy); - int off = 0; - if (!enclosingParent->hasOverflowClip()) { - ox += enclosingParent->overflowLeft(); - oy += enclosingParent->overflowTop(); - } - rect.setX(ox); - rect.setY(oy); - rect.setWidth(enclosingParent->effectiveWidth()); - rect.setHeight(enclosingParent->effectiveHeight()); - } - return rect; -} - -TQRect RenderCanvas::selectionRect() const -{ - RenderObject *r = m_selectionStart; - if (!r) - return TQRect(); - - TQRect selectionRect = enclosingPositionedRect(r); - - while (r && r != m_selectionEnd) - { - RenderObject* n; - if ( !(n = r->firstChild()) ){ - if ( !(n = r->nextSibling()) ) - { - n = r->parent(); - while (n && !n->nextSibling()) - n = n->parent(); - if (n) - n = n->nextSibling(); - } - } - r = n; - if (r) { - selectionRect = selectionRect.unite(enclosingPositionedRect(r)); - } - } - - return selectionRect; -} - -void RenderCanvas::setSelection(RenderObject *s, int sp, RenderObject *e, int ep) -{ - // Check we got valid renderobjects. www.msnbc.com and clicking - // around, to find the case where this happened. - if ( !s || !e ) - { - kdWarning(6040) << "RenderCanvas::setSelection() called with start=" << s << " end=" << e << endl; - return; - } -// kdDebug( 6040 ) << "RenderCanvas::setSelection(" << s << "," << sp << "," << e << "," << ep << ")" << endl; - - bool changedSelectionBorder = ( s != m_selectionStart || e != m_selectionEnd ); - - // Cut out early if the selection hasn't changed. - if ( !changedSelectionBorder && m_selectionStartPos == sp && m_selectionEndPos == ep ) - return; - - // Record the old selected objects. Will be used later - // to delta against the selected objects. - - RenderObject *oldStart = m_selectionStart; - int oldStartPos = m_selectionStartPos; - RenderObject *oldEnd = m_selectionEnd; - int oldEndPos = m_selectionEndPos; - TQPtrList oldSelectedInside; - TQPtrList newSelectedInside; - RenderObject *os = oldStart; - - while (os && os != oldEnd) - { - RenderObject* no; - if ( !(no = os->firstChild()) ){ - if ( !(no = os->nextSibling()) ) - { - no = os->parent(); - while (no && !no->nextSibling()) - no = no->parent(); - if (no) - no = no->nextSibling(); - } - } - if (os->selectionState() == SelectionInside && !oldSelectedInside.containsRef(os)) - oldSelectedInside.append(os); - - os = no; - } - if (changedSelectionBorder) - clearSelection(false); - - while (s->firstChild()) - s = s->firstChild(); - while (e->lastChild()) - e = e->lastChild(); - -#if 0 - bool changedSelectionBorder = ( s != m_selectionStart || e != m_selectionEnd ); - - if ( !changedSelectionBorder && m_selectionStartPos == sp && m_selectionEndPos = ep ) - return; -#endif - - // set selection start - if (m_selectionStart) - m_selectionStart->setIsSelectionBorder(false); - m_selectionStart = s; - if (m_selectionStart) - m_selectionStart->setIsSelectionBorder(true); - m_selectionStartPos = sp; - - // set selection end - if (m_selectionEnd) - m_selectionEnd->setIsSelectionBorder(false); - m_selectionEnd = e; - if (m_selectionEnd) - m_selectionEnd->setIsSelectionBorder(true); - m_selectionEndPos = ep; - -#if 0 - kdDebug( 6040 ) << "old selection (" << oldStart << "," << oldStartPos << "," << oldEnd << "," << oldEndPos << ")" << endl; - kdDebug( 6040 ) << "new selection (" << s << "," << sp << "," << e << "," << ep << ")" << endl; -#endif - - // update selection status of all objects between m_selectionStart and m_selectionEnd - RenderObject* o = s; - - while (o && o!=e) - { - o->setSelectionState(SelectionInside); -// kdDebug( 6040 ) << "setting selected " << o << ", " << o->isText() << endl; - RenderObject* no; - if ( !(no = o->firstChild()) ) - if ( !(no = o->nextSibling()) ) - { - no = o->parent(); - while (no && !no->nextSibling()) - no = no->parent(); - if (no) - no = no->nextSibling(); - } - if (o->selectionState() == SelectionInside && !newSelectedInside.containsRef(o)) - newSelectedInside.append(o); - - o=no; - } - s->setSelectionState(SelectionStart); - e->setSelectionState(SelectionEnd); - if(s == e) s->setSelectionState(SelectionBoth); - - if (!m_view) - return; - - newSelectedInside.removeRef(s); - newSelectedInside.removeRef(e); - - TQRect updateRect; - - // Don't use repaint() because it will cause all rects to - // be united (see khtmlview::scheduleRepaint()). Instead - // just draw damage rects for objects that have a change - // in selection state. - // ### for Qt, updateContents will unite them, too. This has to be - // circumvented somehow (LS) - - // Are any of the old fully selected objects not in the new selection? - // If so we have to draw them. - // Could be faster by building list of non-intersecting rectangles rather - // than unioning rectangles. - TQPtrListIterator oldIterator(oldSelectedInside); - bool firstRect = true; - for (; oldIterator.current(); ++oldIterator){ - if (!newSelectedInside.containsRef(oldIterator.current())){ - if (firstRect){ - updateRect = enclosingPositionedRect(oldIterator.current()); - firstRect = false; - } - else - updateRect = updateRect.unite(enclosingPositionedRect(oldIterator.current())); - } - } - if (!firstRect){ - m_view->updateContents( updateRect ); - } - - // Are any of the new fully selected objects not in the previous selection? - // If so we have to draw them. - // Could be faster by building list of non-intersecting rectangles rather - // than unioning rectangles. - TQPtrListIterator newIterator(newSelectedInside); - firstRect = true; - for (; newIterator.current(); ++newIterator){ - if (!oldSelectedInside.containsRef(newIterator.current())){ - if (firstRect){ - updateRect = enclosingPositionedRect(newIterator.current()); - firstRect = false; - } - else - updateRect = updateRect.unite(enclosingPositionedRect(newIterator.current())); - } - } - if (!firstRect) { - m_view->updateContents( updateRect ); - } - - // Is the new starting object different, or did the position in the starting - // element change? If so we have to draw it. - if (oldStart != m_selectionStart || - (oldStart == oldEnd && (oldStartPos != m_selectionStartPos || oldEndPos != m_selectionEndPos)) || - (oldStart == m_selectionStart && oldStartPos != m_selectionStartPos)){ - m_view->updateContents( enclosingPositionedRect(m_selectionStart) ); - } - - // Draw the old selection start object if it's different than the new selection - // start object. - if (oldStart && oldStart != m_selectionStart){ - m_view->updateContents( enclosingPositionedRect(oldStart) ); - } - - // Does the selection span objects and is the new end object different, or did the position - // in the end element change? If so we have to draw it. - if (/*(oldStart != oldEnd || !oldEnd) &&*/ - (oldEnd != m_selectionEnd || - (oldEnd == m_selectionEnd && oldEndPos != m_selectionEndPos))){ - m_view->updateContents( enclosingPositionedRect(m_selectionEnd) ); - } - - // Draw the old selection end object if it's different than the new selection - // end object. - if (oldEnd && oldEnd != m_selectionEnd){ - m_view->updateContents( enclosingPositionedRect(oldEnd) ); - } -} - -void RenderCanvas::clearSelection(bool doRepaint) -{ - // update selection status of all objects between m_selectionStart and m_selectionEnd - RenderObject* o = m_selectionStart; - while (o && o!=m_selectionEnd) - { - if (o->selectionState()!=SelectionNone) - if (doRepaint) - o->repaint(); - o->setSelectionState(SelectionNone); - o->repaint(); - RenderObject* no; - if ( !(no = o->firstChild()) ) - if ( !(no = o->nextSibling()) ) - { - no = o->parent(); - while (no && !no->nextSibling()) - no = no->parent(); - if (no) - no = no->nextSibling(); - } - o=no; - } - if (m_selectionEnd) { - m_selectionEnd->setSelectionState(SelectionNone); - if (doRepaint) - m_selectionEnd->repaint(); - } - - // set selection start & end to 0 - if (m_selectionStart) - m_selectionStart->setIsSelectionBorder(false); - m_selectionStart = 0; - m_selectionStartPos = -1; - - if (m_selectionEnd) - m_selectionEnd->setIsSelectionBorder(false); - m_selectionEnd = 0; - m_selectionEndPos = -1; -} - -void RenderCanvas::selectionStartEnd(int& spos, int& epos) -{ - spos = m_selectionStartPos; - epos = m_selectionEndPos; -} - -TQRect RenderCanvas::viewRect() const -{ - if (m_pagedMode) - if (m_pageTop == m_pageBottom) { - kdDebug(6040) << "viewRect: " << TQRect(0, m_pageTop, m_width, m_height) << endl; - return TQRect(0, m_pageTop, m_width, m_height); - } - else { - kdDebug(6040) << "viewRect: " << TQRect(0, m_pageTop, m_width, m_pageBottom - m_pageTop) << endl; - return TQRect(0, m_pageTop, m_width, m_pageBottom - m_pageTop); - } - else if (m_view) - return TQRect(m_view->contentsX(), - m_view->contentsY(), - m_view->visibleWidth(), - m_view->visibleHeight()); - else - return TQRect(0,0,m_rootWidth,m_rootHeight); -} - -int RenderCanvas::docHeight() const -{ - if (m_cachedDocHeight != -1) - return m_cachedDocHeight; - - int h; - if (m_pagedMode || !m_view) - h = m_height; - else - h = 0; - - RenderObject *fc = firstChild(); - if(fc) { - int dh = fc->overflowHeight() + fc->marginTop() + fc->marginBottom(); - int lowestPos = fc->lowestPosition(false); -// kdDebug(6040) << "h " << h << " lowestPos " << lowestPos << " dh " << dh << " fc->rh " << fc->effectiveHeight() << " fc->height() " << fc->height() << endl; - if( lowestPos > dh ) - dh = lowestPos; - lowestPos = lowestAbsolutePosition(); - if( lowestPos > dh ) - dh = lowestPos; - if( dh > h ) - h = dh; - } - - RenderLayer *layer = m_layer; - h = kMax( h, layer->yPos() + layer->height() ); -// kdDebug(6040) << "h " << h << " layer(" << layer->renderer()->renderName() << "@" << layer->renderer() << ")->height " << layer->height() << " lp " << (layer->yPos() + layer->height()) << " height() " << layer->renderer()->height() << " rh " << layer->renderer()->effectiveHeight() << endl; - return h; -} - -int RenderCanvas::docWidth() const -{ - if (m_cachedDocWidth != -1) - return m_cachedDocWidth; - - int w; - if (m_pagedMode || !m_view) - w = m_width; - else - w = 0; - - RenderObject *fc = firstChild(); - if(fc) { - // ow: like effectiveWidth() but without the negative - const int ow = fc->hasOverflowClip() ? fc->width() : fc->overflowWidth(); - int dw = ow + fc->marginLeft() + fc->marginRight(); - int rightmostPos = fc->rightmostPosition(false); -// kdDebug(6040) << "w " << w << " rightmostPos " << rightmostPos << " dw " << dw << " fc->rw " << fc->effectiveWidth() << " fc->width() " << fc->width() << endl; - if( rightmostPos > dw ) - dw = rightmostPos; - rightmostPos = rightmostAbsolutePosition(); - if ( rightmostPos > dw ) - dw = rightmostPos; - if( dw > w ) - w = dw; - } - - RenderLayer *layer = m_layer; - w = kMax( w, layer->xPos() + layer->width() ); -// kdDebug(6040) << "w " << w << " layer(" << layer->renderer()->renderName() << ")->width " << layer->width() << " rm " << (layer->xPos() + layer->width()) << " width() " << layer->renderer()->width() << " rw " << layer->renderer()->effectiveWidth() << endl; - return w; -} - -RenderPage* RenderCanvas::page() { - if (!m_page) m_page = new RenderPage(this); - return m_page; -} diff --git a/khtml/rendering/render_canvas.h b/khtml/rendering/render_canvas.h deleted file mode 100644 index 17f279d7b..000000000 --- a/khtml/rendering/render_canvas.h +++ /dev/null @@ -1,250 +0,0 @@ -/* - * This file is part of the HTML widget for KDE. - * - * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) - * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#ifndef render_canvas_h -#define render_canvas_h - -#include "render_block.h" - -class KHTMLView; -class TQScrollView; - -namespace khtml { - -class RenderPage; -class RenderStyle; - -enum CanvasMode { - CanvasViewPort, // Paints inside a viewport - CanvasPage, // Paints one page - CanvasDocument // Paints the whole document -}; - -class RenderCanvas : public RenderBlock -{ -public: - RenderCanvas(DOM::NodeImpl* node, KHTMLView *view); - ~RenderCanvas(); - - virtual const char *renderName() const { return "RenderCanvas"; } - - virtual bool isCanvas() const { return true; } - - virtual void setStyle(RenderStyle *style); - virtual void layout(); - virtual void calcWidth(); - virtual void calcHeight(); - virtual void calcMinMaxWidth(); - virtual bool absolutePosition(int &xPos, int&yPos, bool f = false) const; - - int docHeight() const; - int docWidth() const; - - KHTMLView *view() const { return m_view; } - - virtual void repaint(Priority p=NormalPriority); - virtual void repaintRectangle(int x, int y, int w, int h, Priority p=NormalPriority, bool f=false); - void repaintViewRectangle(int x, int y, int w, int h, bool asap=false); - bool needsFullRepaint() const; - void deferredRepaint( RenderObject* o ); - void scheduleDeferredRepaints(); - - virtual void paint(PaintInfo&, int tx, int ty); - virtual void paintBoxDecorations(PaintInfo& paintInfo, int _tx, int _ty); - virtual void setSelection(RenderObject *s, int sp, RenderObject *e, int ep); - virtual void clearSelection(bool doRepaint=true); - virtual RenderObject *selectionStart() const { return m_selectionStart; } - virtual RenderObject *selectionEnd() const { return m_selectionEnd; } - - void setPrintImages(bool enable) { m_printImages = enable; } - bool printImages() const { return m_printImages; } - - void setCanvasMode(CanvasMode mode) { m_canvasMode = mode; } - CanvasMode canvasMode() const { return m_canvasMode; } - - void setPagedMode(bool b) { m_pagedMode = b; } - void setStaticMode(bool b) { m_staticMode = b; } - - bool pagedMode() const { return m_pagedMode; } - bool staticMode() const { return m_staticMode; } - - void setPageTop(int top) { - m_pageTop = top; -// m_y = top; - } - void setPageBottom(int bottom) { m_pageBottom = bottom; } - int pageTop() const { return m_pageTop; } - int pageBottom() const { return m_pageBottom; } - - int pageTopAfter(int y) const { - if (pageHeight() == 0) return 0; - return (y / pageHeight() + 1) * pageHeight() ; - } - - int crossesPageBreak(int top, int bottom) const { - if (pageHeight() == 0) return false; - int pT = top / pageHeight(); - // bottom is actually the first line not in the box - int pB = (bottom-1) / pageHeight(); - return (pT == pB) ? 0 : (pB + 1); - } - - void setPageNumber(int number) { m_pageNr = number; } - int pageNumber() const { return m_pageNr; } - -public: - virtual void setWidth( int width ) { m_rootWidth = m_width = width; } - virtual void setHeight( int height ) { m_rootHeight = m_height = height; } - -// void setPageHeight( int height ) { m_viewportHeight = m_pageHeight = height; } - int pageHeight() const { return m_pageBottom - m_pageTop; } - - int viewportWidth() const { return m_viewportWidth; } - int viewportHeight() const { return m_viewportHeight; } - - RenderPage* page(); - - TQRect selectionRect() const; - - void setMaximalOutlineSize(int o) { m_maximalOutlineSize = o; } - int maximalOutlineSize() const { return m_maximalOutlineSize; } - - void setNeedsWidgetMasks( bool b=true) { m_needsWidgetMasks = b; } - bool needsWidgetMasks() const { return m_needsWidgetMasks; } - - void updateDocSizeAfterLayerTranslation( RenderObject* o, bool posXOffset, bool posYOffset ); -protected: - // makes sure document, scrollbars and viewport size are accurate - void updateDocumentSize(); - - // internal setters for cached values of document width/height - // Setting to -1/-1 invalidates the cache. - void setCachedDocWidth(int w ) { m_cachedDocWidth = w; } - void setCachedDocHeight(int h) { m_cachedDocHeight = h; } - - virtual void selectionStartEnd(int& spos, int& epos); - - virtual TQRect viewRect() const; - - KHTMLView *m_view; - - RenderObject* m_selectionStart; - RenderObject* m_selectionEnd; - int m_selectionStartPos; - int m_selectionEndPos; - - CanvasMode m_canvasMode; - - int m_rootWidth; - int m_rootHeight; - - int m_viewportWidth; - int m_viewportHeight; - - int m_cachedDocWidth; - int m_cachedDocHeight; - - bool m_printImages; - bool m_needsFullRepaint; - - // Canvas is not interactive - bool m_staticMode; - // Canvas is paged - bool m_pagedMode; - // Canvas contains overlaid widgets - bool m_needsWidgetMasks; - - short m_pageNr; - - int m_pageTop; - int m_pageBottom; - - RenderPage* m_page; - - int m_maximalOutlineSize; // Used to apply a fudge factor to dirty-rect checks on blocks/tables. - TQValueList m_dirtyChildren; -}; - -inline RenderCanvas* RenderObject::canvas() const -{ - return static_cast(document()->renderer()); -} - -// Represents the page-context of CSS -class RenderPage -{ -public: - RenderPage(RenderCanvas* canvas) : m_canvas(canvas), - m_marginTop(0), m_marginBottom(0), - m_marginLeft(0), m_marginRight(0), - m_pageWidth(0), m_pageHeight(0), - m_fixedSize(false) - { - m_style = new RenderPageStyle(); - } - virtual ~RenderPage() - { - delete m_style; - } - - int marginTop() const { return m_marginTop; } - int marginBottom() const { return m_marginBottom; } - int marginLeft() const { return m_marginLeft; } - int marginRight() const { return m_marginRight; } - - void setMarginTop(int margin) { m_marginTop = margin; } - void setMarginBottom(int margin) { m_marginBottom = margin; } - void setMarginLeft(int margin) { m_marginLeft = margin; } - void setMarginRight(int margin) { m_marginRight = margin; } - - int pageWidth() const { return m_pageWidth; } - int pageHeight() const { return m_pageHeight; } - - void setPageSize(int width, int height) { - m_pageWidth = width; - m_pageHeight = height; - } - - // Returns true if size was set by document, false if set by user-agent - bool fixedSize() const { return m_fixedSize; } - void setFixedSize(bool b) { m_fixedSize = b; } - - RenderPageStyle* style() { return m_style; } - const RenderPageStyle* style() const { return m_style; } - -protected: - RenderCanvas* m_canvas; - RenderPageStyle* m_style; - - int m_marginTop; - int m_marginBottom; - int m_marginLeft; - int m_marginRight; - - int m_pageWidth; - int m_pageHeight; - - bool m_fixedSize; -}; - -} -#endif diff --git a/khtml/rendering/render_container.cpp b/khtml/rendering/render_container.cpp deleted file mode 100644 index 69f987477..000000000 --- a/khtml/rendering/render_container.cpp +++ /dev/null @@ -1,597 +0,0 @@ -/** - * This file is part of the html renderer for KDE. - * - * Copyright (C) 2001-2003 Lars Knoll (knoll@kde.org) - * (C) 2001 Antti Koivisto (koivisto@kde.org) - * (C) 2000-2003 Dirk Mueller (mueller@kde.org) - * (C) 2002-2003 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -//#define DEBUG_LAYOUT - -#include "rendering/render_container.h" -#include "rendering/render_table.h" -#include "rendering/render_text.h" -#include "rendering/render_image.h" -#include "rendering/render_canvas.h" -#include "rendering/render_generated.h" -#include "rendering/render_inline.h" -#include "xml/dom_docimpl.h" -#include "css/css_valueimpl.h" - -#include -#include - -using namespace khtml; - -RenderContainer::RenderContainer(DOM::NodeImpl* node) - : RenderObject(node) -{ - m_first = 0; - m_last = 0; -} - -void RenderContainer::detach() -{ - if (continuation()) - continuation()->detach(); - - // We simulate removeNode calls for all our children - // and set parent to 0 to avoid removeNode from being called. - // First call removeLayers and removeFromObjectLists since they assume - // a valid render-tree - for(RenderObject* n = m_first; n; n = n->nextSibling() ) { - n->removeLayers(enclosingLayer()); - n->removeFromObjectLists(); - } - - RenderObject* next; - for(RenderObject* n = m_first; n; n = next ) { - n->setParent(0); - next = n->nextSibling(); - n->detach(); - } - m_first = 0; - m_last = 0; - - RenderObject::detach(); -} - -void RenderContainer::addChild(RenderObject *newChild, RenderObject *beforeChild) -{ -#ifdef DEBUG_LAYOUT - kdDebug( 6040 ) << this << ": " << renderName() << "(RenderObject)::addChild( " << newChild << ": " << - newChild->renderName() << ", " << (beforeChild ? beforeChild->renderName() : "0") << " )" << endl; -#endif - // protect ourselves from deletion - setDoNotDelete(true); - - bool needsTable = false; - - if(!newChild->isText() && !newChild->isReplaced()) { - switch(newChild->style()->display()) { - case INLINE: - case BLOCK: - case LIST_ITEM: - case RUN_IN: - case COMPACT: - case INLINE_BLOCK: - case TABLE: - case INLINE_TABLE: - break; - case TABLE_COLUMN: - if ( isTableCol() ) - break; - // nobreak - case TABLE_COLUMN_GROUP: - case TABLE_CAPTION: - case TABLE_ROW_GROUP: - case TABLE_HEADER_GROUP: - case TABLE_FOOTER_GROUP: - - //kdDebug( 6040 ) << "adding section" << endl; - if ( !isTable() ) - needsTable = true; - break; - case TABLE_ROW: - //kdDebug( 6040 ) << "adding row" << endl; - if ( !isTableSection() ) - needsTable = true; - break; - case TABLE_CELL: - //kdDebug( 6040 ) << "adding cell" << endl; - if ( !isTableRow() ) - needsTable = true; - // I'm not 100% sure this is the best way to fix this, but without this - // change we recurse infinitely when trying to render the CSS2 test page: - // http://www.bath.ac.uk/%7Epy8ieh/internet/eviltests/htmlbodyheadrendering2.html. - if ( isTableCell() && !firstChild() && !newChild->isTableCell() ) - needsTable = false; - - break; - case NONE: - // RenderHtml and some others can have display:none - // KHTMLAssert(false); - break; - } - } - - if ( needsTable ) { - RenderTable *table; - RenderObject *last = beforeChild ? beforeChild->previousSibling() : lastChild(); - if ( last && last->isTable() && last->isAnonymous() ) { - table = static_cast(last); - } else { - //kdDebug( 6040 ) << "creating anonymous table, before=" << beforeChild << endl; - table = new (renderArena()) RenderTable(document() /* is anonymous */); - RenderStyle *newStyle = new RenderStyle(); - newStyle->inheritFrom(style()); - newStyle->setDisplay( TABLE ); - newStyle->setFlowAroundFloats( true ); - table->setParent( this ); // so it finds the arena - table->setStyle(newStyle); - table->setParent( 0 ); - addChild(table, beforeChild); - } - table->addChild(newChild); - } else { - // just add it... - insertChildNode(newChild, beforeChild); - } - - if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE) { - DOM::DOMStringImpl* textToTransform = static_cast(newChild)->originalString(); - if (textToTransform) - static_cast(newChild)->setText(textToTransform, true); - } - newChild->attach(); - - setDoNotDelete(false); -} - -RenderObject* RenderContainer::removeChildNode(RenderObject* oldChild) -{ - KHTMLAssert(oldChild->parent() == this); - - // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or - // that a positioned child got yanked). We also repaint, so that the area exposed when the child - // disappears gets repainted properly. - if ( document()->renderer() ) { - oldChild->setNeedsLayoutAndMinMaxRecalc(); - oldChild->repaint(); - - // Keep our layer hierarchy updated. - oldChild->removeLayers(enclosingLayer()); - // remove the child from any special layout lists - oldChild->removeFromObjectLists(); - - // if oldChild is the start or end of the selection, then clear - // the selection to avoid problems of invalid pointers - - // ### This is not the "proper" solution... ideally the selection - // ### should be maintained based on DOM Nodes and a Range, which - // ### gets adjusted appropriately when nodes are deleted/inserted - // ### near etc. But this at least prevents crashes caused when - // ### the start or end of the selection is deleted and then - // ### accessed when the user next selects something. - - if (oldChild->isSelectionBorder()) { - RenderObject *root = oldChild; - while (root->parent()) - root = root->parent(); - if (root->isCanvas()) { - static_cast(root)->clearSelection(); - } - } - } - - // remove the child from the render-tree - if (oldChild->previousSibling()) - oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); - if (oldChild->nextSibling()) - oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling()); - - if (m_first == oldChild) - m_first = oldChild->nextSibling(); - if (m_last == oldChild) - m_last = oldChild->previousSibling(); - - oldChild->setPreviousSibling(0); - oldChild->setNextSibling(0); - oldChild->setParent(0); - - return oldChild; -} - -void RenderContainer::setStyle(RenderStyle* _style) -{ - RenderObject::setStyle(_style); - - // If we are a pseudo-container we need to restyle the children - if (style()->isGenerated()) - { - // ### we could save this call when the change only affected - // non inherited properties - RenderStyle *pseudoStyle = new RenderStyle(); - pseudoStyle->inheritFrom(style()); - pseudoStyle->ref(); - RenderObject *child = firstChild(); - while (child != 0) - { - child->setStyle(pseudoStyle); - child = child->nextSibling(); - } - pseudoStyle->deref(); - } -} - -void RenderContainer::updatePseudoChildren() -{ - // In CSS2, before/after pseudo-content cannot nest. Check this first. - // Remove when CSS 3 Generated Content becomes Candidate Recommendation - if (style()->styleType() == RenderStyle::BEFORE - || style()->styleType() == RenderStyle::AFTER) - return; - - updatePseudoChild(RenderStyle::BEFORE); - updatePseudoChild(RenderStyle::AFTER); - // updatePseudoChild(RenderStyle::MARKER, marker()); -} - -void RenderContainer::updatePseudoChild(RenderStyle::PseudoId type) -{ - // The head manages generated content for its continuations - if (isInlineContinuation()) return; - - RenderStyle* pseudo = style()->getPseudoStyle(type); - - RenderObject* child = pseudoContainer(type); - - // Whether or not we currently have generated content attached. - bool oldContentPresent = child && (child->style()->styleType() == type); - - // Whether or not we now want generated content. - bool newContentWanted = pseudo && pseudo->display() != NONE; - - // No generated content - if (!oldContentPresent && !newContentWanted) - return; - - bool movedContent = (type == RenderStyle::AFTER && isRenderInline() && continuation()); - - // Whether or not we want the same old content. - bool sameOldContent = oldContentPresent && newContentWanted && !movedContent - && (child->style()->contentDataEquivalent(pseudo)); - - // No change in content, update style - if( sameOldContent ) { - child->setStyle(pseudo); - return; - } - - // If we don't want generated content any longer, or if we have generated content, - // but it's no longer identical to the new content data we want to build - // render objects for, then we nuke all of the old generated content. - if (oldContentPresent && (!newContentWanted || !sameOldContent)) - { - // The child needs to be removed. - oldContentPresent = false; - child->detach(); - child = 0; - } - - // If we have no pseudo-style or if the pseudo's display type is NONE, then we - // have no generated content and can now return. - if (!newContentWanted) - return; - - // Generated content consists of a single container that houses multiple children (specified - // by the content property). This pseudo container gets the pseudo style set on it. - RenderContainer* pseudoContainer = 0; - pseudoContainer = RenderFlow::createFlow(element(), pseudo, renderArena()); - pseudoContainer->setIsAnonymous( true ); - pseudoContainer->createGeneratedContent(); - - // Only add the container if it had content - if (pseudoContainer->firstChild()) { - addPseudoContainer(pseudoContainer); - pseudoContainer->close(); - } -} - -void RenderContainer::createGeneratedContent() -{ - RenderStyle* pseudo = style(); - RenderStyle* style = new RenderStyle(); - style->ref(); - style->inheritFrom(pseudo); - - // Now walk our list of generated content and create render objects for every type - // we encounter. - for (ContentData* contentData = pseudo->contentData(); - contentData; contentData = contentData->_nextContent) - { - if (contentData->_contentType == CONTENT_TEXT) - { - RenderText* t = new (renderArena()) RenderText( node(), 0); - t->setIsAnonymous( true ); - t->setStyle(style); - t->setText(contentData->contentText()); - addChild(t); - } - else if (contentData->_contentType == CONTENT_OBJECT) - { - RenderImage* img = new (renderArena()) RenderImage(node()); - img->setIsAnonymous( true ); - img->setStyle(style); - img->setContentObject(contentData->contentObject()); - addChild(img); - } - else if (contentData->_contentType == CONTENT_COUNTER) - { - // really a counter or just a glyph? - EListStyleType type = (EListStyleType)contentData->contentCounter()->listStyle(); - RenderObject *t = 0; - if (isListStyleCounted(type)) { - t = new (renderArena()) RenderCounter( node(), contentData->contentCounter() ); - } - else { - t = new (renderArena()) RenderGlyph( node(), type ); - } - t->setIsAnonymous( true ); - t->setStyle(style); - addChild(t); - } - else if (contentData->_contentType == CONTENT_QUOTE) - { - RenderQuote* t = new (renderArena()) RenderQuote( node(), contentData->contentQuote() ); - t->setIsAnonymous( true ); - t->setStyle(style); - addChild(t); - } - } - style->deref(); -} - -RenderContainer* RenderContainer::pseudoContainer(RenderStyle::PseudoId type) const -{ - RenderObject *child = 0; - switch (type) { - case RenderStyle::AFTER: - child = lastChild(); - break; - case RenderStyle::BEFORE: - child = firstChild(); - break; - case RenderStyle::REPLACED: - child = lastChild(); - if (child && child->style()->styleType() == RenderStyle::AFTER) - child = child->previousSibling(); - break; - default: - child = 0; - } - - if (child && child->style()->styleType() == type) { - assert(child->isRenderBlock() || child->isRenderInline()); - return static_cast(child); - } - if (type == RenderStyle::AFTER) { - // check continuations - if (continuation()) - return continuation()->pseudoContainer(type); - } - if (child && child->isAnonymousBlock()) - return static_cast(child)->pseudoContainer(type); - return 0; -} - -void RenderContainer::addPseudoContainer(RenderObject* child) -{ - RenderStyle::PseudoId type = child->style()->styleType(); - switch (type) { - case RenderStyle::AFTER: { - RenderObject *o = this; - while (o->continuation()) o = o->continuation(); - - // Coalesce inlines - if (child->style()->display() == INLINE && o->lastChild() && o->lastChild()->isAnonymousBlock()) { - o->lastChild()->addChild(child, 0); - } else - o->addChild(child, 0); - break; - } - case RenderStyle::BEFORE: - // Coalesce inlines - if (child->style()->display() == INLINE && firstChild() && firstChild()->isAnonymousBlock()) { - firstChild()->addChild(child, firstChild()->firstChild()); - } else - addChild(child, firstChild()); - break; - case RenderStyle::REPLACED: - addChild(child, pseudoContainer(RenderStyle::AFTER)); - break; - default: - break; - } -} - -void RenderContainer::updateReplacedContent() -{ - // Only for normal elements - if (!style() || style()->styleType() != RenderStyle::NOPSEUDO) - return; - - // delete old generated content - RenderContainer *container = pseudoContainer(RenderStyle::REPLACED); - if (container) { - container->detach(); - } - - if (style()->useNormalContent()) return; - - // create generated content - RenderStyle* pseudo = style()->getPseudoStyle(RenderStyle::REPLACED); - if (!pseudo) { - pseudo = new RenderStyle(); - pseudo->inheritFrom(style()); - pseudo->setStyleType(RenderStyle::REPLACED); - } - if (pseudo->useNormalContent()) - pseudo->setContentData(style()->contentData()); - - container = RenderFlow::createFlow(node(), pseudo, renderArena()); - container->setIsAnonymous( true ); - container->createGeneratedContent(); - - addChild(container, pseudoContainer(RenderStyle::AFTER)); -} - -void RenderContainer::appendChildNode(RenderObject* newChild) -{ - KHTMLAssert(newChild->parent() == 0); - - newChild->setParent(this); - RenderObject* lChild = lastChild(); - - if(lChild) - { - newChild->setPreviousSibling(lChild); - lChild->setNextSibling(newChild); - } - else - setFirstChild(newChild); - - setLastChild(newChild); - - // Keep our layer hierarchy updated. Optimize for the common case where we don't have any children - // and don't have a layer attached to ourselves. - if (newChild->firstChild() || newChild->layer()) { - RenderLayer* layer = enclosingLayer(); - newChild->addLayers(layer, newChild); - } - - newChild->setNeedsLayoutAndMinMaxRecalc(); // Goes up the containing block hierarchy. - if (!normalChildNeedsLayout()) - setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child. -} - -void RenderContainer::insertChildNode(RenderObject* child, RenderObject* beforeChild) -{ - if(!beforeChild) { - appendChildNode(child); - return; - } - - KHTMLAssert(!child->parent()); - while ( beforeChild->parent() != this && beforeChild->parent()->isAnonymousBlock() ) - beforeChild = beforeChild->parent(); - KHTMLAssert(beforeChild->parent() == this); - - if(beforeChild == firstChild()) - setFirstChild(child); - - RenderObject* prev = beforeChild->previousSibling(); - child->setNextSibling(beforeChild); - beforeChild->setPreviousSibling(child); - if(prev) prev->setNextSibling(child); - child->setPreviousSibling(prev); - child->setParent(this); - - // Keep our layer hierarchy updated. - RenderLayer* layer = enclosingLayer(); - child->addLayers(layer, child); - - child->setNeedsLayoutAndMinMaxRecalc(); - if (!normalChildNeedsLayout()) - setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child. -} - - -void RenderContainer::layout() -{ - KHTMLAssert( needsLayout() ); - KHTMLAssert( minMaxKnown() ); - const bool pagedMode = canvas()->pagedMode(); - RenderObject *child = firstChild(); - while( child ) { - if (pagedMode) child->setNeedsLayout(true); - child->layoutIfNeeded(); - if (child->containsPageBreak()) setContainsPageBreak(true); - if (child->needsPageClear()) setNeedsPageClear(true); - child = child->nextSibling(); - } - setNeedsLayout(false); -} - -void RenderContainer::removeLeftoverAnonymousBoxes() -{ - // we have to go over all child nodes and remove anonymous boxes, that do _not_ - // have inline children to keep the tree flat - RenderObject *child = firstChild(); - while( child ) { - RenderObject *next = child->nextSibling(); - - if ( child->isRenderBlock() && child->isAnonymousBlock() && !child->continuation() && - !child->childrenInline() && !child->isTableCell() && !child->doNotDelete()) { - RenderObject *firstAnChild = child->firstChild(); - RenderObject *lastAnChild = child->lastChild(); - if ( firstAnChild ) { - RenderObject *o = firstAnChild; - while( o ) { - o->setParent( this ); - o = o->nextSibling(); - } - firstAnChild->setPreviousSibling( child->previousSibling() ); - lastAnChild->setNextSibling( child->nextSibling() ); - if ( child->previousSibling() ) - child->previousSibling()->setNextSibling( firstAnChild ); - if ( child->nextSibling() ) - child->nextSibling()->setPreviousSibling( lastAnChild ); - if ( child == firstChild() ) - m_first = firstAnChild; - if ( child == lastChild() ) - m_last = lastAnChild; - } else { - if ( child->previousSibling() ) - child->previousSibling()->setNextSibling( child->nextSibling() ); - if ( child->nextSibling() ) - child->nextSibling()->setPreviousSibling( child->previousSibling() ); - if ( child == firstChild() ) - m_first = child->nextSibling(); - if ( child == lastChild() ) - m_last = child->previousSibling(); - } - child->setParent( 0 ); - child->setPreviousSibling( 0 ); - child->setNextSibling( 0 ); - if ( !child->isText() ) { - RenderContainer *c = static_cast(child); - c->m_first = 0; - c->m_next = 0; - } - child->detach(); - } - child = next; - } - if ( parent() ) - parent()->removeLeftoverAnonymousBoxes(); -} - -#undef DEBUG_LAYOUT diff --git a/khtml/rendering/render_container.h b/khtml/rendering/render_container.h deleted file mode 100644 index 4cf386140..000000000 --- a/khtml/rendering/render_container.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file is part of the html renderer for KDE. - * - * Copyright (C) 2001 Antti Koivisto (koivisto@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#ifndef render_container_h -#define render_container_h - -#include "render_object.h" - -namespace khtml -{ - - -/** - * Base class for rendering objects that can have children - */ -class RenderContainer : public RenderObject -{ -public: - RenderContainer(DOM::NodeImpl* node); - - void detach(); - - RenderObject *firstChild() const { return m_first; } - RenderObject *lastChild() const { return m_last; } - - virtual bool childAllowed() const { - // Prevent normal children when we are replaced by generated content - if (style()) return style()->useNormalContent(); - return true; - } - - virtual void addChild(RenderObject *newChild, RenderObject *beforeChild = 0); - - virtual RenderObject* removeChildNode(RenderObject* child); - virtual void appendChildNode(RenderObject* child); - virtual void insertChildNode(RenderObject* child, RenderObject* before); - - virtual void layout(); - virtual void calcMinMaxWidth() { setMinMaxKnown( true ); } - - virtual void removeLeftoverAnonymousBoxes(); - - virtual void setStyle(RenderStyle* _style); - -protected: - // Generate CSS content - void createGeneratedContent(); - void updateReplacedContent(); - - void updatePseudoChildren(); - void updatePseudoChild(RenderStyle::PseudoId type); - - RenderContainer* pseudoContainer( RenderStyle::PseudoId type ) const; - void addPseudoContainer(RenderObject* child); -private: - - void setFirstChild(RenderObject *first) { m_first = first; } - void setLastChild(RenderObject *last) { m_last = last; } - -protected: - - RenderObject *m_first; - RenderObject *m_last; -}; - -} -#endif diff --git a/khtml/rendering/render_flow.cpp b/khtml/rendering/render_flow.cpp deleted file mode 100644 index ae579bd46..000000000 --- a/khtml/rendering/render_flow.cpp +++ /dev/null @@ -1,412 +0,0 @@ -/** - * This file is part of the html renderer for KDE. - * - * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) - * (C) 1999-2003 Antti Koivisto (koivisto@kde.org) - * (C) 2002-2003 Dirk Mueller (mueller@kde.org) - * (C) 2003-2006 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ -// ------------------------------------------------------------------------- - -#include -#include -#include -#include - -#include "rendering/render_flow.h" -#include "rendering/render_text.h" -#include "rendering/render_table.h" -#include "rendering/render_canvas.h" -#include "rendering/render_inline.h" -#include "rendering/render_block.h" -#include "rendering/render_arena.h" -#include "rendering/render_line.h" -#include "xml/dom_nodeimpl.h" -#include "xml/dom_docimpl.h" -#include "misc/htmltags.h" -#include "html/html_formimpl.h" - -#include "khtmlview.h" - -using namespace DOM; -using namespace khtml; - -RenderFlow* RenderFlow::createFlow(DOM::NodeImpl* node, RenderStyle* style, RenderArena* arena) -{ - RenderFlow* result; - if (style->display() == INLINE) - result = new (arena) RenderInline(node); - else - result = new (arena) RenderBlock(node); - result->setStyle(style); - return result; -} - -RenderFlow* RenderFlow::continuationBefore(RenderObject* beforeChild) -{ - if (beforeChild && beforeChild->parent() == this) - return this; - - RenderFlow* curr = continuation(); - RenderFlow* nextToLast = this; - RenderFlow* last = this; - while (curr) { - if (beforeChild && beforeChild->parent() == curr) { - if (curr->firstChild() == beforeChild) - return last; - return curr; - } - - nextToLast = last; - last = curr; - curr = curr->continuation(); - } - - if (!beforeChild && !last->firstChild()) - return nextToLast; - return last; -} - -void RenderFlow::addChildWithContinuation(RenderObject* newChild, RenderObject* beforeChild) -{ - RenderFlow* flow = continuationBefore(beforeChild); - while(beforeChild && beforeChild->parent() != flow && !beforeChild->parent()->isAnonymousBlock()) { - // skip implicit containers around beforeChild - beforeChild = beforeChild->parent(); - } - RenderFlow* beforeChildParent = beforeChild ? static_cast(beforeChild->parent()) : - (flow->continuation() ? flow->continuation() : flow); - - if (newChild->isFloatingOrPositioned()) - return beforeChildParent->addChildToFlow(newChild, beforeChild); - - // A continuation always consists of two potential candidates: an inline or an anonymous - // block box holding block children. - bool childInline = newChild->isInline(); - bool bcpInline = beforeChildParent->isInline(); - bool flowInline = flow->isInline(); - - if (flow == beforeChildParent) - return flow->addChildToFlow(newChild, beforeChild); - else { - // The goal here is to match up if we can, so that we can coalesce and create the - // minimal # of continuations needed for the inline. - if (childInline == bcpInline) - return beforeChildParent->addChildToFlow(newChild, beforeChild); - else if (flowInline == childInline) - return flow->addChildToFlow(newChild, 0); // Just treat like an append. - else - return beforeChildParent->addChildToFlow(newChild, beforeChild); - } -} - -void RenderFlow::addChild(RenderObject *newChild, RenderObject *beforeChild) -{ -#ifdef DEBUG_LAYOUT - kdDebug( 6040 ) << renderName() << "(RenderFlow)::addChild( " << newChild->renderName() << - ", " << (beforeChild ? beforeChild->renderName() : "0") << " )" << endl; - kdDebug( 6040 ) << "current height = " << m_height << endl; -#endif - - if (continuation()) - return addChildWithContinuation(newChild, beforeChild); - return addChildToFlow(newChild, beforeChild); -} - -void RenderFlow::deleteInlineBoxes(RenderArena* arena) -{ - RenderBox::deleteInlineBoxes(arena); //In case we upcalled - //during construction - if (m_firstLineBox) { - if (!arena) - arena = renderArena(); - InlineRunBox *curr=m_firstLineBox, *next=0; - while (curr) { - next = curr->nextLineBox(); - curr->detach(arena); - curr = next; - } - m_firstLineBox = 0; - m_lastLineBox = 0; - } -} - -void RenderFlow::deleteLastLineBox(RenderArena* arena) -{ - if (m_lastLineBox) { - if (!arena) - arena = renderArena(); - InlineRunBox *curr=m_lastLineBox, *prev = m_lastLineBox; - if (m_firstLineBox == m_lastLineBox) - m_firstLineBox = m_lastLineBox = 0; - else { - prev = curr->prevLineBox(); - while (!prev->isInlineFlowBox()) { - prev = prev->prevLineBox(); - prev->detach(arena); - } - m_lastLineBox = static_cast(prev); - prev->setNextLineBox(0); - } - if (curr->parent()) { - curr->parent()->removeFromLine(curr); - } - curr->detach(arena); - } -} - -InlineBox* RenderFlow::createInlineBox(bool makePlaceHolderBox, bool isRootLineBox) -{ - if ( !isRootLineBox && - (isReplaced() || makePlaceHolderBox) ) // Inline tables and inline blocks - return RenderBox::createInlineBox(false, false); // (or positioned element placeholders). - - InlineFlowBox* flowBox = 0; - if (isInlineFlow()) - flowBox = new (renderArena()) InlineFlowBox(this); - else - flowBox = new (renderArena()) RootInlineBox(this); - - if (!m_firstLineBox) { - m_firstLineBox = m_lastLineBox = flowBox; - } else { - m_lastLineBox->setNextLineBox(flowBox); - flowBox->setPreviousLineBox(m_lastLineBox); - m_lastLineBox = flowBox; - } - - return flowBox; -} - -void RenderFlow::paintLines(PaintInfo& i, int _tx, int _ty) -{ - // Only paint during the foreground/selection phases. - if (i.phase != PaintActionForeground && i.phase != PaintActionSelection && i.phase != PaintActionOutline) - return; - - if (!firstLineBox()) - return; - - // We can check the first box and last box and avoid painting if we don't - // intersect. This is a quick short-circuit that we can take to avoid walking any lines. - // FIXME: This check is flawed in two extremely obscure ways. - // (1) If some line in the middle has a huge overflow, it might actually extend below the last line. - // (2) The overflow from an inline block on a line is not reported to the line. - int maxOutlineSize = maximalOutlineSize(i.phase); - int yPos = firstLineBox()->root()->topOverflow() - maxOutlineSize; - int h = maxOutlineSize + lastLineBox()->root()->bottomOverflow() - yPos; - yPos += _ty; - if ((yPos >= i.r.y() + i.r.height()) || (yPos + h <= i.r.y())) - return; - for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextFlowBox()) { - yPos = curr->root()->topOverflow() - maxOutlineSize; - h = curr->root()->bottomOverflow() + maxOutlineSize - yPos; - yPos += _ty; - if ((yPos < i.r.y() + i.r.height()) && (yPos + h > i.r.y())) - curr->paint(i, _tx, _ty); - } - - if (i.phase == PaintActionOutline && i.outlineObjects) { - TQValueList::iterator it;; - for( it = (*i.outlineObjects).begin(); it != (*i.outlineObjects).end(); ++it ) - if ((*it)->isRenderInline()) - static_cast(*it)->paintOutlines(i.p, _tx, _ty); - i.outlineObjects->clear(); - } -} - - -bool RenderFlow::hitTestLines(NodeInfo& i, int x, int y, int tx, int ty, HitTestAction hitTestAction) -{ - (void) hitTestAction; - /* - if (hitTestAction != HitTestForeground) // ### port hitTest - return false; - */ - - if (!firstLineBox()) - return false; - - // We can check the first box and last box and avoid hit testing if we don't - // contain the point. This is a quick short-circuit that we can take to avoid walking any lines. - // FIXME: This check is flawed in two extremely obscure ways. - // (1) If some line in the middle has a huge overflow, it might actually extend below the last line. - // (2) The overflow from an inline block on a line is not reported to the line. - if ((y >= ty + lastLineBox()->root()->bottomOverflow()) || (y < ty + firstLineBox()->root()->topOverflow())) - return false; - - // See if our root lines contain the point. If so, then we hit test - // them further. Note that boxes can easily overlap, so we can't make any assumptions - // based off positions of our first line box or our last line box. - for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevFlowBox()) { - if (y >= ty + curr->root()->topOverflow() && y < ty + curr->root()->bottomOverflow()) { - bool inside = curr->nodeAtPoint(i, x, y, tx, ty); - if (inside) { - setInnerNode(i); - return true; - } - } - } - - return false; -} - - -void RenderFlow::repaint(Priority prior) -{ - if (isInlineFlow()) { - // Find our leftmost position. - int left = 0; - // root inline box not reliably availabe during relayout - int top = firstLineBox() ? ( - needsLayout() ? firstLineBox()->xPos() : firstLineBox()->root()->topOverflow() - ) : 0; - for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) - if (curr == firstLineBox() || curr->xPos() < left) - left = curr->xPos(); - - // Now invalidate a rectangle. - int ow = style() ? style()->outlineSize() : 0; - - // We need to add in the relative position offsets of any inlines (including us) up to our - // containing block. - RenderBlock* cb = containingBlock(); - for (RenderObject* inlineFlow = this; inlineFlow && inlineFlow->isInlineFlow() && inlineFlow != cb; - inlineFlow = inlineFlow->parent()) { - if (inlineFlow->style() && inlineFlow->style()->position() == RELATIVE && inlineFlow->layer()) { - KHTMLAssert(inlineFlow->isBox()); - static_cast(inlineFlow)->relativePositionOffset(left, top); - } - } - - RootInlineBox *lastRoot = lastLineBox() && !needsLayout() ? lastLineBox()->root() : 0; - containingBlock()->repaintRectangle(-ow+left, -ow+top, - width()+ow*2, - (lastRoot ? lastRoot->bottomOverflow() - top : height())+ow*2, prior); - } - else { - if (firstLineBox() && firstLineBox()->topOverflow() < 0) { - int ow = style() ? style()->outlineSize() : 0; - repaintRectangle(-ow, -ow+firstLineBox()->topOverflow(), - effectiveWidth()+ow*2, effectiveHeight()+ow*2, prior); - } - else - return RenderBox::repaint(prior); - } -} - -int -RenderFlow::lowestPosition(bool includeOverflowInterior, bool includeSelf) const -{ - int bottom = RenderBox::lowestPosition(includeOverflowInterior, includeSelf); - if (!includeOverflowInterior && hasOverflowClip()) - return bottom; - - // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids. - // For now, we have to descend into all the children, since we may have a huge abs div inside - // a tiny rel div buried somewhere deep in our child tree. In this case we have to get to - // the abs div. - for (RenderObject *c = firstChild(); c; c = c->nextSibling()) { - if (!c->isFloatingOrPositioned() && !c->isText() && !c->isInlineFlow()) { - int lp = c->yPos() + c->lowestPosition(false); - bottom = kMax(bottom, lp); - } - } - - if (isRelPositioned()) { - int x; - relativePositionOffset(x, bottom); - } - - return bottom; -} - -int RenderFlow::rightmostPosition(bool includeOverflowInterior, bool includeSelf) const -{ - int right = RenderBox::rightmostPosition(includeOverflowInterior, includeSelf); - if (!includeOverflowInterior && hasOverflowClip()) - return right; - - // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids. - // For now, we have to descend into all the children, since we may have a huge abs div inside - // a tiny rel div buried somewhere deep in our child tree. In this case we have to get to - // the abs div. - for (RenderObject *c = firstChild(); c; c = c->nextSibling()) { - if (!c->isFloatingOrPositioned() && !c->isText() && !c->isInlineFlow()) { - int rp = c->xPos() + c->rightmostPosition(false); - right = kMax(right, rp); - } - } - - if (isRelPositioned()) { - int y; - relativePositionOffset(right, y); - } - - return right; -} - -int RenderFlow::leftmostPosition(bool includeOverflowInterior, bool includeSelf) const -{ - int left = RenderBox::leftmostPosition(includeOverflowInterior, includeSelf); - if (!includeOverflowInterior && hasOverflowClip()) - return left; - - // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids. - // For now, we have to descend into all the children, since we may have a huge abs div inside - // a tiny rel div buried somewhere deep in our child tree. In this case we have to get to - // the abs div. - for (RenderObject *c = firstChild(); c; c = c->nextSibling()) { - if (!c->isFloatingOrPositioned() && !c->isText() && !c->isInlineFlow()) { - int lp = c->xPos() + c->leftmostPosition(false); - left = kMin(left, lp); - } - } - - if (isRelPositioned()) { - int y; - relativePositionOffset(left, y); - } - - return left; -} - -int RenderFlow::highestPosition(bool includeOverflowInterior, bool includeSelf) const -{ - int top = RenderBox::highestPosition(includeOverflowInterior, includeSelf); - if (!includeOverflowInterior && hasOverflowClip()) - return top; - - // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids. - // For now, we have to descend into all the children, since we may have a huge abs div inside - // a tiny rel div buried somewhere deep in our child tree. In this case we have to get to - // the abs div. - for (RenderObject *c = firstChild(); c; c = c->nextSibling()) { - if (!c->isFloatingOrPositioned() && !c->isText() && !c->isInlineFlow()) { - int hp = c->yPos() + c->highestPosition(false); - top = kMin(top, hp); - } - } - - if (isRelPositioned()) { - int x; - relativePositionOffset(x, top); - } - - return top; -} diff --git a/khtml/rendering/render_flow.h b/khtml/rendering/render_flow.h deleted file mode 100644 index 1e23822bb..000000000 --- a/khtml/rendering/render_flow.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) - * (C) 1999-2003 Antti Koivisto (koivisto@kde.org) - * (C) 2002-2003 Dirk Mueller (mueller@kde.org) - * (C) 2003 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#ifndef RENDER_FLOW_H -#define RENDER_FLOW_H - -#include "render_box.h" -#include "bidi.h" -#include "render_line.h" - -namespace khtml { - -/** - * all geometry managing stuff is only in the block elements. - * - * Inline elements don't layout themselves, but the whole paragraph - * gets flowed by the surrounding block element. This is, because - * one needs to know the whole paragraph to calculate bidirectional - * behaviour of text, so putting the layouting routines in the inline - * elements is impossible. - */ -class RenderFlow : public RenderBox -{ -public: - RenderFlow(DOM::NodeImpl* node) - : RenderBox(node) - { m_continuation = 0; m_firstLineBox = 0; m_lastLineBox = 0; } - - virtual RenderFlow* continuation() const { return m_continuation; } - void setContinuation(RenderFlow* c) { m_continuation = c; } - RenderFlow* continuationBefore(RenderObject* beforeChild); - - void addChildWithContinuation(RenderObject* newChild, RenderObject* beforeChild); - virtual void addChildToFlow(RenderObject* newChild, RenderObject* beforeChild) = 0; - virtual void addChild(RenderObject *newChild, RenderObject *beforeChild = 0); - - static RenderFlow* createFlow(DOM::NodeImpl* node, RenderStyle* style, RenderArena* arena); - - virtual void deleteLastLineBox(RenderArena* arena=0); - virtual void deleteInlineBoxes(RenderArena* arena=0); - - - InlineFlowBox* firstLineBox() const { return m_firstLineBox; } - InlineFlowBox* lastLineBox() const { return m_lastLineBox; } - - virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox); - - void paintLines(PaintInfo& i, int _tx, int _ty); - bool hitTestLines(NodeInfo& i, int x, int y, int tx, int ty, HitTestAction hitTestAction); - - virtual void repaint(Priority p=NormalPriority); - - virtual int highestPosition(bool includeOverflowInterior=true, bool includeSelf=true) const; - virtual int lowestPosition(bool includeOverflowInterior=true, bool includeSelf=true) const; - virtual int rightmostPosition(bool includeOverflowInterior=true, bool includeSelf=true) const; - virtual int leftmostPosition(bool includeOverflowInterior=true, bool includeSelf=true) const; - -protected: - // An inline can be split with blocks occurring in between the inline content. - // When this occurs we need a pointer to our next object. We can basically be - // split into a sequence of inlines and blocks. The continuation will either be - // an anonymous block (that houses other blocks) or it will be an inline flow. - RenderFlow* m_continuation; - - // For block flows, each box represents the root inline box for a line in the - // paragraph. - // For inline flows, each box represents a portion of that inline. - InlineFlowBox* m_firstLineBox; - InlineFlowBox* m_lastLineBox; -}; - - -} //namespace - -#endif diff --git a/khtml/rendering/render_form.cpp b/khtml/rendering/render_form.cpp deleted file mode 100644 index 81005de85..000000000 --- a/khtml/rendering/render_form.cpp +++ /dev/null @@ -1,1914 +0,0 @@ -/* - * This file is part of the DOM implementation for KDE. - * - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * (C) 2000 Dirk Mueller (mueller@kde.org) - * (C) 2006 Maksim Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "misc/helper.h" -#include "xml/dom2_eventsimpl.h" -#include "html/html_formimpl.h" -#include "misc/htmlhashes.h" - -#include "rendering/render_form.h" -#include - -#include "khtmlview.h" -#include "khtml_ext.h" -#include "xml/dom_docimpl.h" - -#include -#include - -using namespace khtml; - -RenderFormElement::RenderFormElement(HTMLGenericFormElementImpl *element) - : RenderWidget(element) -{ - // init RenderObject attributes - setInline(true); // our object is Inline - - m_state = 0; -} - -RenderFormElement::~RenderFormElement() -{ -} - -short RenderFormElement::baselinePosition( bool f ) const -{ - return RenderWidget::baselinePosition( f ) - 2 - style()->fontMetrics().descent(); -} - -void RenderFormElement::updateFromElement() -{ - m_widget->setEnabled(!element()->disabled()); - RenderWidget::updateFromElement(); -} - -void RenderFormElement::layout() -{ - KHTMLAssert( needsLayout() ); - KHTMLAssert( minMaxKnown() ); - - // minimum height - m_height = 0; - - calcWidth(); - calcHeight(); - - if ( m_widget ) - resizeWidget(m_width-borderLeft()-borderRight()-paddingLeft()-paddingRight(), - m_height-borderTop()-borderBottom()-paddingTop()-paddingBottom()); - - setNeedsLayout(false); -} - -TQ_Alignment RenderFormElement::textAlignment() const -{ - switch (style()->textAlign()) { - case LEFT: - case KHTML_LEFT: - return Qt::AlignLeft; - case RIGHT: - case KHTML_RIGHT: - return Qt::AlignRight; - case CENTER: - case KHTML_CENTER: - return Qt::AlignHCenter; - case JUSTIFY: - // Just fall into the auto code for justify. - case TAAUTO: - return style()->direction() == RTL ? Qt::AlignRight : Qt::AlignLeft; - } - assert(false); // Should never be reached. - return Qt::AlignLeft; -} - -// ------------------------------------------------------------------------- - -RenderButton::RenderButton(HTMLGenericFormElementImpl *element) - : RenderFormElement(element) -{ -} - -short RenderButton::baselinePosition( bool f ) const -{ - return RenderWidget::baselinePosition( f ) - 2; -} - -// ------------------------------------------------------------------------------- - - -RenderCheckBox::RenderCheckBox(HTMLInputElementImpl *element) - : RenderButton(element) -{ - TQCheckBox* b = new TQCheckBox(view()->viewport(), "__khtml"); - b->setAutoMask(true); - b->setMouseTracking(true); - setQWidget(b); - - // prevent firing toggled() signals on initialization - b->setChecked(element->checked()); - - connect(b,TQT_SIGNAL(stateChanged(int)),this,TQT_SLOT(slotStateChanged(int))); -} - - -void RenderCheckBox::calcMinMaxWidth() -{ - KHTMLAssert( !minMaxKnown() ); - - TQCheckBox *cb = static_cast( m_widget ); - TQSize s( cb->style().pixelMetric( TQStyle::PM_IndicatorWidth ), - cb->style().pixelMetric( TQStyle::PM_IndicatorHeight ) ); - setIntrinsicWidth( s.width() ); - setIntrinsicHeight( s.height() ); - - RenderButton::calcMinMaxWidth(); -} - -void RenderCheckBox::updateFromElement() -{ - widget()->setChecked(element()->checked()); - - RenderButton::updateFromElement(); -} - -void RenderCheckBox::slotStateChanged(int state) -{ - element()->setChecked(state == TQButton::On); - element()->setIndeterminate(state == TQButton::NoChange); - - ref(); - element()->onChange(); - deref(); -} - -// ------------------------------------------------------------------------------- - -RenderRadioButton::RenderRadioButton(HTMLInputElementImpl *element) - : RenderButton(element) -{ - TQRadioButton* b = new TQRadioButton(view()->viewport(), "__khtml"); - b->setMouseTracking(true); - setQWidget(b); - - // prevent firing toggled() signals on initialization - b->setChecked(element->checked()); - - connect(b,TQT_SIGNAL(toggled(bool)),this,TQT_SLOT(slotToggled(bool))); -} - -void RenderRadioButton::updateFromElement() -{ - widget()->setChecked(element()->checked()); - - RenderButton::updateFromElement(); -} - -void RenderRadioButton::calcMinMaxWidth() -{ - KHTMLAssert( !minMaxKnown() ); - - TQRadioButton *rb = static_cast( m_widget ); - TQSize s( rb->style().pixelMetric( TQStyle::PM_ExclusiveIndicatorWidth ), - rb->style().pixelMetric( TQStyle::PM_ExclusiveIndicatorHeight ) ); - setIntrinsicWidth( s.width() ); - setIntrinsicHeight( s.height() ); - - RenderButton::calcMinMaxWidth(); -} - -void RenderRadioButton::slotToggled(bool activated) -{ - if(activated) { - ref(); - element()->onChange(); - deref(); - } -} - -// ------------------------------------------------------------------------------- - - -RenderSubmitButton::RenderSubmitButton(HTMLInputElementImpl *element) - : RenderButton(element) -{ - TQPushButton* p = new TQPushButton(view()->viewport(), "__khtml"); - setQWidget(p); - p->setAutoMask(true); - p->setMouseTracking(true); -} - -TQString RenderSubmitButton::rawText() -{ - TQString value = element()->valueWithDefault().string(); - value = value.stripWhiteSpace(); - TQString raw; - for(unsigned int i = 0; i < value.length(); i++) { - raw += value[i]; - if(value[i] == '&') - raw += '&'; - } - return raw; -} - -void RenderSubmitButton::calcMinMaxWidth() -{ - KHTMLAssert( !minMaxKnown() ); - - TQString raw = rawText(); - TQPushButton* pb = static_cast(m_widget); - pb->setText(raw); - pb->setFont(style()->font()); - - bool empty = raw.isEmpty(); - if ( empty ) - raw = TQString::fromLatin1("X"); - TQFontMetrics fm = pb->fontMetrics(); - TQSize ts = fm.size( ShowPrefix, raw); - TQSize s(pb->style().tqsizeFromContents( TQStyle::CT_PushButton, pb, ts ) - .expandedTo(TQApplication::globalStrut())); - int margin = pb->style().pixelMetric( TQStyle::PM_ButtonMargin, pb) + - pb->style().pixelMetric( TQStyle::PM_DefaultFrameWidth, pb ) * 2; - int w = ts.width() + margin; - int h = s.height(); - if (pb->isDefault() || pb->autoDefault()) { - int dbw = pb->style().pixelMetric( TQStyle::PM_ButtonDefaultIndicator, pb ) * 2; - w += dbw; - } - - // add 30% margins to the width (heuristics to make it look similar to IE) - s = TQSize( w*13/10, h ).expandedTo(TQApplication::globalStrut()); - - setIntrinsicWidth( s.width() ); - setIntrinsicHeight( s.height() ); - - RenderButton::calcMinMaxWidth(); -} - -void RenderSubmitButton::updateFromElement() -{ - TQString oldText = static_cast(m_widget)->text(); - TQString newText = rawText(); - static_cast(m_widget)->setText(newText); - if ( oldText != newText ) - setNeedsLayoutAndMinMaxRecalc(); - RenderFormElement::updateFromElement(); -} - -short RenderSubmitButton::baselinePosition( bool f ) const -{ - return RenderFormElement::baselinePosition( f ); -} - -// ------------------------------------------------------------------------------- - -RenderResetButton::RenderResetButton(HTMLInputElementImpl *element) - : RenderSubmitButton(element) -{ -} - -// ------------------------------------------------------------------------------- - -LineEditWidget::LineEditWidget(DOM::HTMLInputElementImpl* input, KHTMLView* view, TQWidget* parent) - : KLineEdit(parent, "__khtml"), m_input(input), m_view(view), m_spell(0) -{ - setMouseTracking(true); - KActionCollection *ac = new KActionCollection(this); - m_spellAction = KStdAction::spelling( TQT_TQOBJECT(this), TQT_SLOT( slotCheckSpelling() ), ac ); -} - -LineEditWidget::~LineEditWidget() -{ - delete m_spell; - m_spell = 0L; -} - -void LineEditWidget::slotCheckSpelling() -{ - if ( text().isEmpty() ) { - return; - } - - delete m_spell; - m_spell = new KSpell( this, i18n( "Spell Checking" ), TQT_TQOBJECT(this), TQT_SLOT( slotSpellCheckReady( KSpell *) ), 0, true, true); - - connect( m_spell, TQT_SIGNAL( death() ),this, TQT_SLOT( spellCheckerFinished() ) ); - connect( m_spell, TQT_SIGNAL( misspelling( const TQString &, const TQStringList &, unsigned int ) ),this, TQT_SLOT( spellCheckerMisspelling( const TQString &, const TQStringList &, unsigned int ) ) ); - connect( m_spell, TQT_SIGNAL( corrected( const TQString &, const TQString &, unsigned int ) ),this, TQT_SLOT( spellCheckerCorrected( const TQString &, const TQString &, unsigned int ) ) ); -} - -void LineEditWidget::spellCheckerMisspelling( const TQString &_text, const TQStringList &, unsigned int pos) -{ - highLightWord( _text.length(),pos ); -} - -void LineEditWidget::highLightWord( unsigned int length, unsigned int pos ) -{ - setSelection ( pos, length ); -} - -void LineEditWidget::spellCheckerCorrected( const TQString &old, const TQString &corr, unsigned int pos ) -{ - if( old!= corr ) - { - setSelection ( pos, old.length() ); - insert( corr ); - setSelection ( pos, corr.length() ); - } -} - -void LineEditWidget::spellCheckerFinished() -{ -} - -void LineEditWidget::slotSpellCheckReady( KSpell *s ) -{ - s->check( text() ); - connect( s, TQT_SIGNAL( done( const TQString & ) ), this, TQT_SLOT( slotSpellCheckDone( const TQString & ) ) ); -} - -void LineEditWidget::slotSpellCheckDone( const TQString &s ) -{ - if( s != text() ) - setText( s ); -} - - -TQPopupMenu *LineEditWidget::createPopupMenu() -{ - TQPopupMenu *popup = KLineEdit::createPopupMenu(); - - if ( !popup ) { - return 0L; - } - - connect( popup, TQT_SIGNAL( activated( int ) ), - this, TQT_SLOT( extendedMenuActivated( int ) ) ); - - if (m_input->autoComplete()) { - popup->insertSeparator(); - int id = popup->insertItem( SmallIconSet("edit"), i18n("&Edit History..."), EditHistory ); - popup->setItemEnabled( id, (compObj() && !compObj()->isEmpty()) ); - id = popup->insertItem( SmallIconSet("history_clear"), i18n("Clear &History"), ClearHistory ); - popup->setItemEnabled( id, (compObj() && !compObj()->isEmpty()) ); - } - - if (echoMode() == TQLineEdit::Normal && - !isReadOnly()) { - popup->insertSeparator(); - - m_spellAction->plug(popup); - m_spellAction->setEnabled( !text().isEmpty() ); - } - - return popup; -} - - -void LineEditWidget::extendedMenuActivated( int id) -{ - switch ( id ) - { - case ClearHistory: - m_view->clearCompletionHistory(m_input->name().string()); - if (compObj()) - compObj()->clear(); - case EditHistory: - { - KHistoryComboEditor dlg( compObj() ? compObj()->items() : TQStringList(), this ); - connect( &dlg, TQT_SIGNAL( removeFromHistory(const TQString&) ), TQT_SLOT( slotRemoveFromHistory(const TQString&)) ); - dlg.exec(); - } - default: - break; - } -} - -void LineEditWidget::slotRemoveFromHistory(const TQString &entry) -{ - m_view->removeFormCompletionItem(m_input->name().string(), entry); - if (compObj()) - compObj()->removeItem(entry); -} - - -bool LineEditWidget::event( TQEvent *e ) -{ - if (KLineEdit::event(e)) - return true; - - if ( e->type() == TQEvent::AccelAvailable && isReadOnly() ) { - TQKeyEvent* ke = (TQKeyEvent*) e; - if ( ke->state() & ControlButton ) { - switch ( ke->key() ) { - case Key_Left: - case Key_Right: - case Key_Up: - case Key_Down: - case Key_Home: - case Key_End: - ke->accept(); - default: - break; - } - } - } - return false; -} - -void LineEditWidget::mouseMoveEvent(TQMouseEvent *e) -{ - // hack to prevent Qt from calling setCursor on the widget - setDragEnabled(false); - KLineEdit::mouseMoveEvent(e); - setDragEnabled(true); -} - - -// ----------------------------------------------------------------------------- - -RenderLineEdit::RenderLineEdit(HTMLInputElementImpl *element) - : RenderFormElement(element) -{ - LineEditWidget *edit = new LineEditWidget(element, view(), view()->viewport()); - connect(edit,TQT_SIGNAL(returnPressed()), this, TQT_SLOT(slotReturnPressed())); - connect(edit,TQT_SIGNAL(textChanged(const TQString &)),this,TQT_SLOT(slotTextChanged(const TQString &))); - - if(element->inputType() == HTMLInputElementImpl::PASSWORD) - edit->setEchoMode( TQLineEdit::Password ); - - if ( element->autoComplete() ) { - TQStringList completions = view()->formCompletionItems(element->name().string()); - if (completions.count()) { - edit->completionObject()->setItems(completions); - edit->setContextMenuEnabled(true); - edit->completionBox()->setTabHandling( false ); - } - } - - setQWidget(edit); -} - -void RenderLineEdit::setStyle(RenderStyle* _style) -{ - RenderFormElement::setStyle( _style ); - - widget()->setAlignment(textAlignment()); -} - -void RenderLineEdit::highLightWord( unsigned int length, unsigned int pos ) -{ - LineEditWidget* w = static_cast(m_widget); - if ( w ) - w->highLightWord( length, pos ); -} - - -void RenderLineEdit::slotReturnPressed() -{ - // don't submit the form when return was pressed in a completion-popup - KCompletionBox *box = widget()->completionBox(false); - - if ( box && box->isVisible() && box->currentItem() != -1 ) { - box->hide(); - return; - } - - // Emit onChange if necessary - // Works but might not be enough, dirk said he had another solution at - // hand (can't remember which) - David - handleFocusOut(); - - HTMLFormElementImpl* fe = element()->form(); - if ( fe ) - fe->submitFromKeyboard(); -} - -void RenderLineEdit::handleFocusOut() -{ - if ( widget() && widget()->edited() ) { - element()->onChange(); - widget()->setEdited( false ); - } -} - -void RenderLineEdit::calcMinMaxWidth() -{ - KHTMLAssert( !minMaxKnown() ); - - const TQFontMetrics &fm = style()->fontMetrics(); - TQSize s; - - int size = element()->size(); - - int h = fm.lineSpacing(); - int w = fm.width( 'x' ) * (size > 0 ? size+1 : 17); // "some" - s = TQSize(w + 2 + 2*widget()->frameWidth(), - kMax(h, 14) + 2 + 2*widget()->frameWidth()) - .expandedTo(TQApplication::globalStrut()); - - setIntrinsicWidth( s.width() ); - setIntrinsicHeight( s.height() ); - - RenderFormElement::calcMinMaxWidth(); -} - -void RenderLineEdit::updateFromElement() -{ - int ml = element()->maxLength(); - if ( ml < 0 ) - ml = 32767; - - if ( widget()->maxLength() != ml ) { - widget()->setMaxLength( ml ); - } - - if (element()->value().string() != widget()->text()) { - widget()->blockSignals(true); - int pos = widget()->cursorPosition(); - widget()->setText(element()->value().string()); - - widget()->setEdited( false ); - - widget()->setCursorPosition(pos); - widget()->blockSignals(false); - } - widget()->setReadOnly(element()->readOnly()); - - RenderFormElement::updateFromElement(); -} - -void RenderLineEdit::slotTextChanged(const TQString &string) -{ - // don't use setValue here! - element()->m_value = string; - element()->m_unsubmittedFormChange = true; -} - -void RenderLineEdit::select() -{ - static_cast(m_widget)->selectAll(); -} - -long RenderLineEdit::selectionStart() -{ - LineEditWidget* w = static_cast(m_widget); - if (w->hasSelectedText()) - return w->selectionStart(); - else - return w->cursorPosition(); -} - - -long RenderLineEdit::selectionEnd() -{ - LineEditWidget* w = static_cast(m_widget); - if (w->hasSelectedText()) - return w->selectionStart() + w->selectedText().length(); - else - return w->cursorPosition(); -} - -void RenderLineEdit::setSelectionStart(long pos) -{ - LineEditWidget* w = static_cast(m_widget); - //See whether we have a non-empty selection now. - long end = selectionEnd(); - if (end > pos) - w->setSelection(pos, end - pos); - w->setCursorPosition(pos); -} - -void RenderLineEdit::setSelectionEnd(long pos) -{ - LineEditWidget* w = static_cast(m_widget); - //See whether we have a non-empty selection now. - long start = selectionStart(); - if (start < pos) - w->setSelection(start, pos - start); - - w->setCursorPosition(pos); -} - -void RenderLineEdit::setSelectionRange(long start, long end) -{ - LineEditWidget* w = static_cast(m_widget); - w->setCursorPosition(end); - w->setSelection(start, end - start); -} - -// --------------------------------------------------------------------------- - -RenderFieldset::RenderFieldset(HTMLGenericFormElementImpl *element) - : RenderBlock(element) -{ -} - -RenderObject* RenderFieldset::layoutLegend(bool relayoutChildren) -{ - RenderObject* legend = findLegend(); - if (legend) { - if (relayoutChildren) - legend->setNeedsLayout(true); - legend->layoutIfNeeded(); - - int xPos = borderLeft() + paddingLeft() + legend->marginLeft(); - if (style()->direction() == RTL) - xPos = m_width - paddingRight() - borderRight() - legend->width() - legend->marginRight(); - int b = borderTop(); - int h = legend->height(); - legend->setPos(xPos, kMax((b-h)/2, 0)); - m_height = kMax(b,h) + paddingTop(); - } - return legend; -} - -RenderObject* RenderFieldset::findLegend() -{ - for (RenderObject* legend = firstChild(); legend; legend = legend->nextSibling()) { - if (!legend->isFloatingOrPositioned() && legend->element() && - legend->element()->id() == ID_LEGEND) - return legend; - } - return 0; -} - -void RenderFieldset::paintBoxDecorations(PaintInfo& pI, int _tx, int _ty) -{ - //kdDebug( 6040 ) << renderName() << "::paintDecorations()" << endl; - - RenderObject* legend = findLegend(); - if (!legend) - return RenderBlock::paintBoxDecorations(pI, _tx, _ty); - - int w = width(); - int h = height() + borderTopExtra() + borderBottomExtra(); - int yOff = (legend->yPos() > 0) ? 0 : (legend->height()-borderTop())/2; - h -= yOff; - _ty += yOff - borderTopExtra(); - - int my = kMax(_ty,pI.r.y()); - int end = kMin( pI.r.y() + pI.r.height(), _ty + h ); - int mh = end - my; - - paintBackground(pI.p, style()->backgroundColor(), style()->backgroundLayers(), my, mh, _tx, _ty, w, h); - - if ( style()->hasBorder() ) - paintBorderMinusLegend(pI.p, _tx, _ty, w, h, style(), legend->xPos(), legend->width()); -} - -void RenderFieldset::paintBorderMinusLegend(TQPainter *p, int _tx, int _ty, int w, int h, - const RenderStyle* style, int lx, int lw) -{ - - const TQColor& tc = style->borderTopColor(); - const TQColor& bc = style->borderBottomColor(); - - EBorderStyle ts = style->borderTopStyle(); - EBorderStyle bs = style->borderBottomStyle(); - EBorderStyle ls = style->borderLeftStyle(); - EBorderStyle rs = style->borderRightStyle(); - - bool render_t = ts > BHIDDEN; - bool render_l = ls > BHIDDEN; - bool render_r = rs > BHIDDEN; - bool render_b = bs > BHIDDEN; - - if(render_t) { - drawBorder(p, _tx, _ty, _tx + lx, _ty + style->borderTopWidth(), BSTop, tc, style->color(), ts, - (render_l && (ls == DOTTED || ls == DASHED || ls == DOUBLE)?style->borderLeftWidth():0), 0); - drawBorder(p, _tx+lx+lw, _ty, _tx + w, _ty + style->borderTopWidth(), BSTop, tc, style->color(), ts, - 0, (render_r && (rs == DOTTED || rs == DASHED || rs == DOUBLE)?style->borderRightWidth():0)); - } - - if(render_b) - drawBorder(p, _tx, _ty + h - style->borderBottomWidth(), _tx + w, _ty + h, BSBottom, bc, style->color(), bs, - (render_l && (ls == DOTTED || ls == DASHED || ls == DOUBLE)?style->borderLeftWidth():0), - (render_r && (rs == DOTTED || rs == DASHED || rs == DOUBLE)?style->borderRightWidth():0)); - - if(render_l) - { - const TQColor& lc = style->borderLeftColor(); - - bool ignore_top = - (tc == lc) && - (ls >= OUTSET) && - (ts == DOTTED || ts == DASHED || ts == SOLID || ts == OUTSET); - - bool ignore_bottom = - (bc == lc) && - (ls >= OUTSET) && - (bs == DOTTED || bs == DASHED || bs == SOLID || bs == INSET); - - drawBorder(p, _tx, _ty, _tx + style->borderLeftWidth(), _ty + h, BSLeft, lc, style->color(), ls, - ignore_top?0:style->borderTopWidth(), - ignore_bottom?0:style->borderBottomWidth()); - } - - if(render_r) - { - const TQColor& rc = style->borderRightColor(); - - bool ignore_top = - (tc == rc) && - (rs >= DOTTED || rs == INSET) && - (ts == DOTTED || ts == DASHED || ts == SOLID || ts == OUTSET); - - bool ignore_bottom = - (bc == rc) && - (rs >= DOTTED || rs == INSET) && - (bs == DOTTED || bs == DASHED || bs == SOLID || bs == INSET); - - drawBorder(p, _tx + w - style->borderRightWidth(), _ty, _tx + w, _ty + h, BSRight, rc, style->color(), rs, - ignore_top?0:style->borderTopWidth(), - ignore_bottom?0:style->borderBottomWidth()); - } -} - -void RenderFieldset::setStyle(RenderStyle* _style) -{ - RenderBlock::setStyle(_style); - - // WinIE renders fieldsets with display:inline like they're inline-blocks. For us, - // an inline-block is just a block element with replaced set to true and inline set - // to true. Ensure that if we ended up being inline that we set our replaced flag - // so that we're treated like an inline-block. - if (isInline()) - setReplaced(true); -} - -// ------------------------------------------------------------------------- - -RenderFileButton::RenderFileButton(HTMLInputElementImpl *element) - : RenderFormElement(element) -{ - KURLRequester* w = new KURLRequester( view()->viewport(), "__khtml" ); - - w->setMode(KFile::File | KFile::ExistingOnly); - w->completionObject()->setDir(TDEGlobalSettings::documentPath()); - - connect(w->lineEdit(), TQT_SIGNAL(returnPressed()), this, TQT_SLOT(slotReturnPressed())); - connect(w->lineEdit(), TQT_SIGNAL(textChanged(const TQString &)),this,TQT_SLOT(slotTextChanged(const TQString &))); - connect(w, TQT_SIGNAL(urlSelected(const TQString &)),this,TQT_SLOT(slotUrlSelected(const TQString &))); - - setQWidget(w); - m_haveFocus = false; -} - - - -void RenderFileButton::calcMinMaxWidth() -{ - KHTMLAssert( !minMaxKnown() ); - - const TQFontMetrics &fm = style()->fontMetrics(); - int size = element()->size(); - - int h = fm.lineSpacing(); - int w = fm.width( 'x' ) * (size > 0 ? size+1 : 17); // "some" - KLineEdit* edit = static_cast( m_widget )->lineEdit(); - TQSize s = edit->style().tqsizeFromContents(TQStyle::CT_LineEdit, - edit, - TQSize(w + 2 + 2*edit->frameWidth(), kMax(h, 14) + 2 + 2*edit->frameWidth())) - .expandedTo(TQApplication::globalStrut()); - TQSize bs = static_cast( m_widget )->minimumSizeHint() - edit->minimumSizeHint(); - - setIntrinsicWidth( s.width() + bs.width() ); - setIntrinsicHeight( kMax(s.height(), bs.height()) ); - - RenderFormElement::calcMinMaxWidth(); -} - -void RenderFileButton::handleFocusOut() -{ - if ( widget()->lineEdit() && widget()->lineEdit()->edited() ) { - element()->onChange(); - widget()->lineEdit()->setEdited( false ); - } -} - -void RenderFileButton::updateFromElement() -{ - KLineEdit* edit = widget()->lineEdit(); - edit->blockSignals(true); - edit->setText(element()->value().string()); - edit->blockSignals(false); - edit->setEdited( false ); - - RenderFormElement::updateFromElement(); -} - -void RenderFileButton::slotReturnPressed() -{ - handleFocusOut(); - - if (element()->form()) - element()->form()->submitFromKeyboard(); -} - -void RenderFileButton::slotTextChanged(const TQString &/*string*/) -{ - element()->m_value = KURL( widget()->url() ).prettyURL( 0, KURL::StripFileProtocol ); -} - -void RenderFileButton::slotUrlSelected(const TQString &) -{ - element()->onChange(); -} - -void RenderFileButton::select() -{ - widget()->lineEdit()->selectAll(); -} - -// ------------------------------------------------------------------------- - -RenderLabel::RenderLabel(HTMLGenericFormElementImpl *element) - : RenderFormElement(element) -{ - -} - -// ------------------------------------------------------------------------- - -RenderLegend::RenderLegend(HTMLGenericFormElementImpl *element) - : RenderBlock(element) -{ -} - -// ------------------------------------------------------------------------------- - -ComboBoxWidget::ComboBoxWidget(TQWidget *parent) - : KComboBox(false, parent, "__khtml") -{ - setAutoMask(true); - if (listBox()) listBox()->installEventFilter(this); - setMouseTracking(true); -} - -bool ComboBoxWidget::event(TQEvent *e) -{ - if (KComboBox::event(e)) - return true; - if (e->type()==TQEvent::KeyPress) - { - TQKeyEvent *ke = TQT_TQKEYEVENT(e); - switch(ke->key()) - { - case Key_Return: - case Key_Enter: - popup(); - ke->accept(); - return true; - default: - return false; - } - } - return false; -} - -bool ComboBoxWidget::eventFilter(TQObject *dest, TQEvent *e) -{ - if (TQT_BASE_OBJECT(dest)==TQT_BASE_OBJECT(listBox()) && e->type()==TQEvent::KeyPress) - { - TQKeyEvent *ke = TQT_TQKEYEVENT(e); - bool forward = false; - switch(ke->key()) - { - case Key_Tab: - forward=true; - case Key_BackTab: - // ugly hack. emulate popdownlistbox() (private in TQComboBox) - // we re-use ke here to store the reference to the generated event. - ke = new TQKeyEvent(TQEvent::KeyPress, Key_Escape, 0, 0); - TQApplication::sendEvent(dest,ke); - focusNextPrevChild(forward); - delete ke; - return true; - default: - return KComboBox::eventFilter(dest, e); - } - } - return KComboBox::eventFilter(dest, e); -} - -// ------------------------------------------------------------------------- - -RenderSelect::RenderSelect(HTMLSelectElementImpl *element) - : RenderFormElement(element) -{ - m_ignoreSelectEvents = false; - m_multiple = element->multiple(); - m_size = element->size(); - m_useListBox = (m_multiple || m_size > 1); - m_selectionChanged = true; - m_optionsChanged = true; - - if(m_useListBox) - setQWidget(createListBox()); - else - setQWidget(createComboBox()); -} - -void RenderSelect::updateFromElement() -{ - m_ignoreSelectEvents = true; - - // change widget type - bool oldMultiple = m_multiple; - unsigned oldSize = m_size; - bool oldListbox = m_useListBox; - - m_multiple = element()->multiple(); - m_size = element()->size(); - m_useListBox = (m_multiple || m_size > 1); - - if (oldMultiple != m_multiple || oldSize != m_size) { - if (m_useListBox != oldListbox) { - // type of select has changed - if(m_useListBox) - setQWidget(createListBox()); - else - setQWidget(createComboBox()); - } - - if (m_useListBox && oldMultiple != m_multiple) { - static_cast(m_widget)->setSelectionMode(m_multiple ? TQListBox::Extended : TQListBox::Single); - } - m_selectionChanged = true; - m_optionsChanged = true; - } - - // update contents listbox/combobox based on options in m_element - if ( m_optionsChanged ) { - if (element()->m_recalcListItems) - element()->recalcListItems(); - TQMemArray listItems = element()->listItems(); - int listIndex; - - if(m_useListBox) { - static_cast(m_widget)->clear(); - } - - else - static_cast(m_widget)->clear(); - - for (listIndex = 0; listIndex < int(listItems.size()); listIndex++) { - if (listItems[listIndex]->id() == ID_OPTGROUP) { - DOMString text = listItems[listIndex]->getAttribute(ATTR_LABEL); - if (text.isNull()) - text = ""; - - if(m_useListBox) { - TQListBoxText *item = new TQListBoxText(TQString(text.implementation()->s, text.implementation()->l)); - static_cast(m_widget) - ->insertItem(item, listIndex); - item->setSelectable(false); - } - else { - static_cast(m_widget) - ->insertItem(TQString(text.implementation()->s, text.implementation()->l), listIndex); - static_cast(m_widget)->listBox()->item(listIndex)->setSelectable(false); - } - } - else if (listItems[listIndex]->id() == ID_OPTION) { - HTMLOptionElementImpl* optElem = static_cast(listItems[listIndex]); - TQString text = optElem->text().string(); - if (optElem->parentNode()->id() == ID_OPTGROUP) - { - // Prefer label if set - DOMString label = optElem->getAttribute(ATTR_LABEL); - if (!label.isEmpty()) - text = label.string(); - text = TQString::fromLatin1(" ")+text; - } - - if(m_useListBox) { - KListBox *l = static_cast(m_widget); - l->insertItem(text, listIndex); - DOMString disabled = optElem->getAttribute(ATTR_DISABLED); - if (!disabled.isNull() && l->item( listIndex )) { - l->item( listIndex )->setSelectable( false ); - } - } else - static_cast(m_widget)->insertItem(text, listIndex); - } - else - KHTMLAssert(false); - m_selectionChanged = true; - } - - // TQComboBox caches the size hint unless you call setFont (ref: TT docu) - if(!m_useListBox) { - KComboBox *that = static_cast(m_widget); - that->setFont( that->font() ); - } - setNeedsLayoutAndMinMaxRecalc(); - m_optionsChanged = false; - } - - // update selection - if (m_selectionChanged) { - updateSelection(); - } - - - m_ignoreSelectEvents = false; - - RenderFormElement::updateFromElement(); -} - -void RenderSelect::calcMinMaxWidth() -{ - KHTMLAssert( !minMaxKnown() ); - - if (m_optionsChanged) - updateFromElement(); - - // ### ugly HACK FIXME!!! - setMinMaxKnown(); - layoutIfNeeded(); - setNeedsLayoutAndMinMaxRecalc(); - // ### end FIXME - - RenderFormElement::calcMinMaxWidth(); -} - -void RenderSelect::layout( ) -{ - KHTMLAssert(needsLayout()); - KHTMLAssert(minMaxKnown()); - - // ### maintain selection properly between type/size changes, and work - // out how to handle multiselect->singleselect (probably just select - // first selected one) - - // calculate size - if(m_useListBox) { - KListBox* w = static_cast(m_widget); - - TQListBoxItem* p = w->firstItem(); - int width = 0; - int height = 0; - while(p) { - width = kMax(width, p->width(p->listBox())); - height = kMax(height, p->height(p->listBox())); - p = p->next(); - } - if ( !height ) - height = w->fontMetrics().height(); - if ( !width ) - width = w->fontMetrics().width( 'x' ); - - int size = m_size; - // check if multiple and size was not given or invalid - // Internet Exploder sets size to kMin(number of elements, 4) - // Netscape seems to simply set it to "number of elements" - // the average of that is IMHO kMin(number of elements, 10) - // so I did that ;-) - if(size < 1) - size = kMin(static_cast(m_widget)->count(), 10u); - - width += 2*w->frameWidth() + w->verticalScrollBar()->sizeHint().width(); - height = size*height + 2*w->frameWidth(); - - setIntrinsicWidth( width ); - setIntrinsicHeight( height ); - } - else { - TQSize s(m_widget->sizeHint()); - setIntrinsicWidth( s.width() ); - setIntrinsicHeight( s.height() ); - } - - /// uuh, ignore the following line.. - setNeedsLayout(true); - RenderFormElement::layout(); - - // and now disable the widget in case there is no