[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