[prev in list] [next in list] [prev in thread] [next in thread] 

List:       koffice-devel
Subject:    stuff that's not intended for anyone to commit ever (weird line
From:       Jaymz Julian <jaymz () dspaudio ! com>
Date:       2002-09-19 14:45:38
[Download RAW message or body]

just figured it might be itneresting for people to see what I came up with
to make kword work on our systems.  Basically, it stores prerendered lines
into a QPicture, which seems to be happy with everything we've thrown at
it so far.  But who knows.  I'm on crack

	- Jaymz

-- 
Jaymz Julian aka A Life in Hell
Coder, Visionary, Fat Ass.
Ralph:  Lisa, you have no tits and a awful tight pussy.
Lisa:   Ralph... get off my back!!

["line-caching-1.patch" (TEXT/PLAIN)]

Index: qrichtext_p.h
===================================================================
RCS file: /home/kde/koffice/lib/kotext/qrichtext_p.h,v
retrieving revision 1.40
diff -u -3 -p -r1.40 qrichtext_p.h
--- qrichtext_p.h	14 Sep 2002 09:52:38 -0000	1.40
+++ qrichtext_p.h	18 Sep 2002 11:43:59 -0000
@@ -68,6 +68,7 @@
 #include "qcolor.h"
 #include "qsize.h"
 #include "qvaluelist.h"
+#include "qvaluevector.h"
 #include "qvaluestack.h"
 #include "qobject.h"
 #include "qdict.h"
@@ -81,6 +82,7 @@
 #include <limits.h>
 #include "qcomplextext_p.h"
 #include "qapplication.h"
+#include "qpicture.h"
 #endif // QT_H
 
 class KoTextParag;
@@ -108,6 +110,34 @@ class KoTextDocCommand;
 #include "korichtext.h"
 ////
 
+typedef struct
+{
+   // clipping
+   int clipx;
+   int clipy;
+   int clipw;
+   int cliph;
+
+   // line height and positions
+   int cy;
+   int h;
+
+   // line flags
+   bool drawSelections;
+   bool rightToLeft;
+
+   QMemArray<int> selections;
+
+   // line contents and formatting
+   QString contents;
+   KoTextFormat *lastFormat;
+
+   // and finally the picture
+   QPicture *cachedPicture;
+} paragCacheInfo;
+
+typedef QValueVector<paragCacheInfo> paragCacheVector;
+
 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  
 class Q_EXPORT KoTextStringChar
@@ -1401,6 +1431,9 @@ private:
     KoTextDocCommandHistory *commandHistory;
     int list_val;
     QColor *bgcol;
+    
+    // info for redraw cache
+    paragCacheVector cacheData;
 };
 
 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                
Index: qrichtext.cpp
===================================================================
RCS file: /home/kde/koffice/lib/kotext/qrichtext.cpp,v
retrieving revision 1.91
diff -u -3 -p -r1.91 qrichtext.cpp
--- qrichtext.cpp	16 Sep 2002 14:26:24 -0000	1.91
+++ qrichtext.cpp	18 Sep 2002 11:44:03 -0000
@@ -3760,6 +3760,10 @@ KoTextParag::~KoTextParag()
     {
         emit document()->paragraphDeleted( this );
     }
+
+    for(int i=0;i<(int)cacheData.size();i++)
+	    if(!cacheData[i].cachedPicture)
+		    delete cacheData[i].cachedPicture;
     //kdDebug(32500) << "KoTextParag::~KoTextParag " << this << endl;
     ////
 }
@@ -4318,17 +4322,21 @@ void KoTextParag::paintDefault( QPainter
     if(line<0) line=0;
     
     int numLines=lines();
+    int cursorLine;
+    if(cursor) 
+	    lineStartOfChar( cursor->index(), 0, &cursorLine );
+    else
+	    cursorLine = -1;
     for(;line<numLines;line++)
     {
 	// get the start and length of the line
-	int lineLen;
 	int nextLine;
     	lineStartOfLine(line, &startOfLine);
 	if(line==(numLines-1))
 		nextLine=length();
 	else
 		lineStartOfLine(line+1, &nextLine);
-	lineLen=(nextLine-startOfLine);
+	int lineLen=nextLine-startOfLine;
 	
 	// init this line
 	lineInfo( line, cy, h, baseLine );
@@ -4339,8 +4347,7 @@ void KoTextParag::paintDefault( QPainter
 	lastBaseLine = baseLine;
 
     	// initialise the line
-	int paintStart = startOfLine;
-	paintEnd = startOfLine;
+	int paintStart = paintEnd = startOfLine;
 	lastY = cy;
 	chr = at(startOfLine);
 	startX=chr->x;
@@ -4350,100 +4357,187 @@ void KoTextParag::paintDefault( QPainter
 	if(!lastFormat)
 		lastFormat = chr->format();
 
-	// okay, paint the line!
-	for(i=startOfLine;i<nextLine;i++)
+	// make sure that we can fit this line
+	if(cacheData.size()<=line)
 	{
-		chr = at( i );
-	        cw = chr->width;
-			// check for cursor mark
-		if ( cursor && this == cursor->parag() && i == cursor->index() ) {
-		    curx = cursor->x();
-		    curline = line;
-	            KoTextStringChar *c = chr;
-	            if ( i > 0 )
-	                --c;
-	            curh = c->height();
-	            cury = cy + baseLine - c->ascent();
-		}
-			// test for end of line
-		bool endOfLine=false;
-		if(i==((startOfLine+lineLen)-1))
-			endOfLine=true;
-			// check if selection state changed
-		bool selectionChange = FALSE;
-		if ( drawSelections ) {
-		    for ( int j = 0; j < nSels; ++j ) {
-			selectionChange = selectionStarts[ j ] == i || selectionEnds[ j ] == i;
-			if ( selectionChange )
-			    break;
-		    }
-		}
-		//if something (format, etc.) changed, draw what we have so far
-		if ( ( (alignment() & Qt::AlignJustify) == Qt::AlignJustify && paintEnd != -1 &&  \
                at(paintEnd)->c.isSpace() ) ||
-	#ifdef CHECK_PIXELXADJ
-	            lastXAdj != chr->pixelxadj ||
-	#endif
-		    endOfLine ||
-		    lastDirection != (bool)chr->rightToLeft ||
-		    chr->startOfRun ||
-		    lastY != cy || chr->format() != lastFormat ||
-		    ( paintEnd != -1 && at( paintEnd )->c =='\t' ) || chr->c == '\t' ||
-		    ( paintEnd != -1 && at( paintEnd )->c.unicode() == 0xad ) || chr->c.unicode() \
                == 0xad ||
-		    selectionChange || 
-		    chr->isCustom() 
-		   ) 
-		   {
-	
-		   if ( paintStart <= paintEnd ) {
-			if ( chr->isCustom() && chr->customItem()->placement() == \
                KoTextCustomItem::PlaceInline ) {
-			    qstr.replace(i,1," ");
+		cacheData.resize(line+1);
+		cacheData[line].cachedPicture=NULL;
+		cacheData[line].lastFormat=NULL;
+	}
+
+	// check if we need a redraw on this line or not
+	// NOTE: only redraw for clipping if the new clipping area is 
+	// LARGER than the old clipping area - this is inefficient, but is required
+	// for the algorythm to work until the cursor blinking code is modified take all
+	// of this into account
+	bool needRedraw;
+	if(cacheData[line].cachedPicture==NULL ||
+	   cacheData[line].clipx > clipx ||
+	   cacheData[line].clipy > clipy ||
+	   cacheData[line].clipw < clipw ||
+	   cacheData[line].cliph < cliph ||
+	   cacheData[line].cy != cy ||
+	   cacheData[line].h != h ||
+	   cacheData[line].drawSelections != drawSelections ||
+	   cacheData[line].rightToLeft != lastDirection ||
+	   cacheData[line].contents != qstr.mid(startOfLine, lineLen) ||
+	   cacheData[line].lastFormat != lastFormat ||
+	   cursorLine == line)
+		needRedraw=true;
+	else
+	{
+		needRedraw=false;
+		// check selections - do this here, because it takes some CPU
+		if(cacheData[line].drawSelections)
+			if((int)cacheData[line].selections.size()==lineLen)
+			{
+				for(i=0;i<lineLen;i++)
+					if(cacheData[line].selections[i]!=hasSelection(i+startOfLine))
+						needRedraw=true;
 			}
+			else
+			{
+				// This condition should never happen, but test it just incase I'm an idiot ^_^
+				needRedraw=true;
+			}
+	}
 
-  		    drawParagString( painter, qstr, paintStart, paintEnd - paintStart + 1, \
                startX, lastY,
-				 lastBaseLine, bw, lasth, drawSelections,
-				 lastFormat, i, selectionStarts, selectionEnds, cg, lastDirection );
-		    }
-		    if ( !chr->isCustom() ) {
-			paintStart = i;
-			paintEnd = i;
-			lastFormat = chr->format();
-			lastY = cy;
-			startX = chr->x;
-			bw = cw;
-		    } else {
-			if ( chr->customItem()->placement() == KoTextCustomItem::PlaceInline ) {
-	       	            chr->customItem()->draw( &painter, chr->x, cy + baseLine - \
                chr->customItem()->ascent(), clipx - r.x(), clipy - r.y(), clipw, \
                cliph, cg,
-						     drawSelections && nSels && selectionStarts[ 0 ] <= i && selectionEnds[ 0 \
                ] > i );
-			    paintStart = i+1;
-			    paintEnd = -1;
-			    lastFormat = chr->format();
-			    lastY = cy;
-			    startX = chr->x + chr->width;
-			    bw = 0;
+	if(needRedraw)
+	{
+		//kdDebug() << "Miss: " << line << "\n";
+		// update the cache *first*, before the data is modified!
+		cacheData[line].clipx=clipx;
+		cacheData[line].clipy=clipy;
+		cacheData[line].cliph=cliph;
+		cacheData[line].clipw=clipw;
+		cacheData[line].cy=cy;
+		cacheData[line].h=h;
+		cacheData[line].drawSelections=drawSelections;
+		cacheData[line].rightToLeft=lastDirection;
+		cacheData[line].contents=qstr.mid(startOfLine, lineLen);
+		cacheData[line].lastFormat=lastFormat;
+		
+		if(drawSelections)
+		{
+			cacheData[line].selections.resize(lineLen);
+			for(i=0;i<lineLen;i++)
+				cacheData[line].selections[i]=hasSelection(i+startOfLine);
+		}
+
+		// allocate
+		QPicture *myPicture=new QPicture();
+		QPainter myPainter(myPicture);
+
+		// draw the line
+		for(i=startOfLine;i<nextLine;i++)
+		{
+			chr = at( i );
+		        cw = chr->width;
+				// check for cursor mark
+			if ( cursor && this == cursor->parag() && i == cursor->index() ) {
+			    curx = cursor->x();
+			    curline = line;
+		            KoTextStringChar *c = chr;
+		            if ( i > 0 )
+		                --c;
+		            curh = c->height();
+		            cury = cy + baseLine - c->ascent();
+			}
+				// test for end of line
+			bool endOfLine=false;
+			if(i==(nextLine-1))
+				endOfLine=true;
+				// check if selection state changed
+			bool selectionChange = FALSE;
+			if ( drawSelections ) {
+			    for ( int j = 0; j < nSels; ++j ) {
+				selectionChange = selectionStarts[ j ] == i || selectionEnds[ j ] == i;
+				if ( selectionChange )
+				    break;
+			    }
+			}
+				//if something (format, etc.) changed, draw what we have so far
+			if ( ( (alignment() & Qt::AlignJustify) == Qt::AlignJustify && paintEnd != -1 &&  \
at(paintEnd)->c.isSpace() ) || +		#ifdef CHECK_PIXELXADJ
+		            lastXAdj != chr->pixelxadj ||
+		#endif
+			    endOfLine ||
+			    lastDirection != (bool)chr->rightToLeft ||
+			    chr->startOfRun ||
+			    lastY != cy || chr->format() != lastFormat ||
+			    ( paintEnd != -1 && at( paintEnd )->c =='\t' ) || chr->c == '\t' ||
+			    ( paintEnd != -1 && at( paintEnd )->c.unicode() == 0xad ) || chr->c.unicode() \
== 0xad || +			    selectionChange || 
+			    chr->isCustom() 
+			   ) 
+			   {
+		
+			   if ( paintStart <= paintEnd ) {
+				if ( chr->isCustom() && chr->customItem()->placement() == \
KoTextCustomItem::PlaceInline ) { +				    qstr.replace(i,1," ");
+				}
+	
+	  		    drawParagString( myPainter, qstr, paintStart, paintEnd - paintStart + 1, \
startX, lastY, +					 lastBaseLine, bw, lasth, drawSelections,
+					 lastFormat, i, selectionStarts, selectionEnds, cg, lastDirection );
+			    }
+			    if ( !chr->isCustom() ) {
+				paintStart = i;
+				paintEnd = i;
+				lastFormat = chr->format();
+				lastY = cy;
+				startX = chr->x;
+				bw = cw;
+			    } else {
+				if ( chr->customItem()->placement() == KoTextCustomItem::PlaceInline ) {
+		       	            chr->customItem()->draw( &myPainter, chr->x, cy + baseLine - \
chr->customItem()->ascent(), clipx - r.x(), clipy - r.y(), clipw, cliph, cg, +							 \
drawSelections && nSels && selectionStarts[ 0 ] <= i && selectionEnds[ 0 ] > i ); \
+				    paintStart = i+1; +				    paintEnd = -1;
+				    lastFormat = chr->format();
+				    lastY = cy;
+				    startX = chr->x + chr->width;
+				    bw = 0;
+				} else {
+				    chr->customItem()->resize( pntr, chr->customItem()->width );
+				    paintStart = i+1;
+				    paintEnd = -1;
+				    lastFormat = chr->format();
+				    lastY = cy;
+				    startX = chr->x + chr->width;
+				    bw = 0;
+				}
+			    }
 			} else {
-			    chr->customItem()->resize( pntr, chr->customItem()->width );
-			    paintStart = i+1;
-			    paintEnd = -1;
-			    lastFormat = chr->format();
-			    lastY = cy;
-			    startX = chr->x + chr->width;
-			    bw = 0;
+			    if( chr->rightToLeft ) {
+				startX = chr->x;
+			    }
+			    paintEnd = i;
+			    bw += cw;
 			}
-		    }
-		} else {
-		    if( chr->rightToLeft ) {
-			startX = chr->x;
-		    }
-		    paintEnd = i;
-		    bw += cw;
-		}
-		lastBaseLine = baseLine;
-		lasth = h;
-		lastDirection = chr->rightToLeft;
-	#ifdef CHECK_PIXELXADJ
-	        lastXAdj = chr->pixelxadj;
-	#endif
-	} // end of charecter loop
+			lastBaseLine = baseLine;
+			lasth = h;
+			lastDirection = chr->rightToLeft;
+		#ifdef CHECK_PIXELXADJ
+		        lastXAdj = chr->pixelxadj;
+		#endif
+		} // end of charecter loop
+
+		// draw it, bitch!
+		myPainter.end();
+		painter.drawPicture(*myPicture);
+
+		// free any picture that we had from before
+		if(!cacheData[line].cachedPicture)
+			free(cacheData[line].cachedPicture);
+	
+		cacheData[line].cachedPicture=myPicture;
+	}
+	else
+	{
+		// just redraw what we drew last time!
+		painter.drawPicture(*(cacheData[line].cachedPicture));
+	}
     }
 
     // if we should draw a cursor, draw it now


_______________________________________________
koffice-devel mailing list
koffice-devel@mail.kde.org
http://mail.kde.org/mailman/listinfo/koffice-devel

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic