scrolling BViews now works, tested with MiniTerminal, added lots of TODO stuff, maybe Adi or DarkWyrm should have a look, maybe they can clear some stuff up for me.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12161 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2005-03-30 16:05:05 +00:00
parent 6283b1c6dd
commit 45c0cd28d8
7 changed files with 285 additions and 27 deletions
+4 -1
View File
@@ -1134,7 +1134,10 @@ void Layer::move_layer(float x, float y)
BRect rect(fFull.Frame().OffsetByCopy(pt));
fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_MOVE, pt);
fDriver->CopyRegionList(&fRootLayer->fCopyRegList, &fRootLayer->fCopyList, fRootLayer->fCopyRegList.CountItems(), &fFullVisible);
fDriver->CopyRegionList(&fRootLayer->fCopyRegList,
&fRootLayer->fCopyList,
fRootLayer->fCopyRegList.CountItems(),
&fFullVisible);
fParent->Redraw(fRootLayer->fRedrawReg, this);
EmptyGlobals();
@@ -518,7 +518,7 @@ AccelerantHWInterface::BackBuffer() const
void
AccelerantHWInterface::_DrawCursor(BRect area) const
{
#if 0
BRect cf = _CursorFrame();
if (cf.IsValid() && area.Intersects(cf)) {
// clip to common area
@@ -580,6 +580,6 @@ AccelerantHWInterface::_DrawCursor(BRect area) const
delete[] buffer;
}
#endif
}
+258 -13
View File
@@ -25,11 +25,19 @@
//
//------------------------------------------------------------------------------
#include <stdio.h>
#include <algo.h>
#include "Painter.h"
#include "RenderingBuffer.h"
#ifdef __HAIKU__
#define USE_ACCELERANT 1
#else
#define USE_ACCELERANT 0
#endif
#if USE_ACCELERANT
#include "AccelerantHWInterface.h"
#else
#include "ViewHWInterface.h"
@@ -46,7 +54,7 @@
DisplayDriverPainter::DisplayDriverPainter()
: DisplayDriver(),
fPainter(new Painter()),
#ifdef __HAIKU__
#if USE_ACCELERANT
fGraphicsCard(new AccelerantHWInterface())
#else
fGraphicsCard(new ViewHWInterface())
@@ -81,25 +89,53 @@ DisplayDriverPainter::Shutdown()
// CopyBits
void
DisplayDriverPainter::CopyBits(const BRect &src, const BRect &dest,
DisplayDriverPainter::CopyBits(const BRect &src, const BRect &dst,
const DrawData *d)
{
/* if(!d)
return;
if (Lock()) {
// TODO: handle clipping to d->clipreg here?
RenderingBuffer* backBuffer = fGraphicsCard->BackBuffer();
BRect valid(0, 0, backBuffer->Width() - 1, backBuffer->Height() - 1);
if (valid.Intersects(src) && valid.Intersects(dst)) {
// calculate offset before any clipping
int32 xOffset = (int32)(dst.left - src.left);
int32 yOffset = (int32)(dst.top - src.top);
// clip src and dest
BRect a = src & valid;
BRect b = dst & valid;
a = a & b.OffsetByCopy(BPoint(-xOffset, -yOffset));
b = b & a.OffsetByCopy(BPoint(xOffset, yOffset));
Lock();
uint8* bits = (uint8*)backBuffer->Bits();
uint32 bpr = backBuffer->BytesPerRow();
if(fCursorHandler.IntersectsCursor(dest))
fCursorHandler.DriverHide();
Blit(src,dest,d);
fCursorHandler.DriverShow();
Unlock();*/
uint32 width = a.IntegerWidth() + 1;
uint32 height = a.IntegerHeight() + 1;
int32 left = (int32)a.left;
int32 top = (int32)a.top;
// offset to left top of src rect
bits += top * bpr + left * 4;
_MoveRect(bits, width, height, bpr, xOffset, yOffset);
fGraphicsCard->Invalidate(dst);
}
Unlock();
}
}
// CopyRegion
void
DisplayDriverPainter::CopyRegion(BRegion *src, const BPoint &lefttop)
{
printf("DisplayDriverPainter::CopyRegion()\n");
}
// InvertRect
@@ -137,6 +173,102 @@ DisplayDriverPainter::DrawBitmap(BRegion *region, ServerBitmap *bitmap,
}
}
/*
inline int
compare_left_right_top_bottom(BRect* a, BRect* b)
{
if (b->right < a->left || b->bottom < a->top)
return 1;
else
return -1;
return 0;
}
inline int
compare_right_left_top_bottom(BRect* a, BRect* b)
{
if (b->right > a->left || b->bottom < a->top)
return 1;
else
return -1;
return 0;
}
inline int
compare_left_right_bottom_top(BRect* a, BRect* b)
{
if (b->right < a->left || b->bottom > a->top)
return 1;
else
return -1;
return 0;
}
inline int
compare_right_left_bottom_top(BRect* a, BRect* b)
{
if (b->right > a->left || b->bottom > a->top)
return 1;
else
return -1;
return 0;
}
*/
// TODO: the commented out code is completely broken
// what needs to be done is a topological sort of the rectangles
// in a given BRegion.
// For example, let's suppose these rects are in a BRegion:
// ************
// * B *
// ************* ************
// * *
// * A ***************
// * * *
// ************* *
// * C *
// * *
// * *
// ***************
// When moving stuff from LEFT TO RIGHT, TOP TO BOTTOM, the
// result of the sort should be C, B, A, ie, you take an unsorted
// list of rects, and you go look for the one that has no neighbors
// to the right and to the bottom, that's the first one you want
// to move. If you move from RIGHT TO LEFT, BOTTOM TO TOP, you
// go look for the one that has no neighbors to the top and left.
//
// Here I draw some rays to illustrate LEFT TO RIGHT, TOP TO BOTTOM:
// ************
// * B *
// ************* ************
// * *
// * A ***************-----------------
// * * *
// ************* *
// * C *
// * *
// * *
// ***************
// |
// |
// |
// |
// There are no rects in the area defined by the rays to the right
// and bottom of rect C, so that's the one we want to copy first
// (for positive x and y offsets). If the sorting of rects can
// be implemented, the speed-up of the CopyRegionList() function
// will be about 300% (I tested that) with "in-place" copying.
//
// Of course, the usage of the funcion is completely obscure to me.
// First of all, why is there a list of points? I checked and it
// is indeed always the same point (the same offset used for all rects).
// Second, if the Regions provided in the list somehow overlap, then
// an in-place copy cannot be performed, so this all makes no sense.
// However during my tests, the usage of the function
// (from Layer::move_to() btw) was only with a *single* BRegion in
// the list. Which makes most sense, but it doesn't make sense to pass
// a BList then.
// used to move windows arround on screen
//
// CopyRegionList
@@ -146,14 +278,84 @@ DisplayDriverPainter::CopyRegionList(BList* list, BList* pList,
{
if (!clipReg || !Lock())
return;
// This is the same implementation as in DisplayDriverPainter for now
/*
// This is the same implementation as in DisplayDriverImpl for now
// since we're not using painter.... this won't do much good, will it?
// fPainter->ConstrainClipping(*clipReg);
//bigtime_t now = system_time();
BRect updateRect;
RenderingBuffer* backBuffer = fGraphicsCard->BackBuffer();
uint8* bits = (uint8*)backBuffer->Bits();
uint32 bpr = backBuffer->BytesPerRow();
// TODO: it's always the same point, no?
BPoint offset = *((BPoint*)pList->ItemAt(0));
// iterate over regions (and points)
for (int32 i = 0; i < rCount; i++) {
BRegion* region = (BRegion*)list->ItemAt(i);
// copy rects into a list
int32 rectCount = region->CountRects();
BList rects(rectCount);
for (int32 j = 0; j < rectCount; j++) {
BRect* r = new BRect(region->RectAt(j));
rects.AddItem((void*)r);
}
// sort the rects according to offset
BRect** first = (BRect**)rects.Items();
BRect** behindLast = (BRect**)rects.Items() + rects.CountItems();
int32 xOffset = (int32)offset.x;
int32 yOffset = (int32)offset.y;
if (xOffset >= 0) {
if (yOffset >= 0)
sort(first, behindLast, compare_left_right_top_bottom);
else
sort(first, behindLast, compare_left_right_bottom_top);
} else {
if (yOffset >= 0)
sort(first, behindLast, compare_right_left_top_bottom);
else
sort(first, behindLast, compare_right_left_bottom_top);
}
// iterate over rects in region
for (int32 j = 0; j < rectCount; j++) {
BRect* r = (BRect*)rects.ItemAt(j);
uint32 width = r->IntegerWidth() + 1;
uint32 height = r->IntegerHeight() + 1;
int32 left = (int32)r->left;
int32 top = (int32)r->top;
// TODO: out of bounds checking!
// BPoint offset = *((BPoint*)pList->ItemAt(j % rCount));
// keep track of dirty rect
r->OffsetBy(offset);
updateRect = updateRect.IsValid() ? updateRect | *r : *r;
printf("region: %ld, rect: %ld, offset(%ld, %ld)\n", i, j, xOffset, yOffset);
// offset to left top of src rect
uint8* src = bits + top * bpr + left * 4;
_MoveRect(src, width, height, bpr, xOffset, yOffset);
delete r;
}
}
*/
RenderingBuffer* bmp = fGraphicsCard->BackBuffer();
uint32 bytesPerPixel = bmp->BytesPerRow() / bmp->Width();
BList rectList;
int32 i, k;
@@ -258,6 +460,7 @@ DisplayDriverPainter::CopyRegionList(BList* list, BList* pList,
if (void* rectCopy = rectList.ItemAt(i))
free(rectCopy);
}
//printf("CopyRegionList(): %lld\n", system_time() - now);
fGraphicsCard->Invalidate(updateRect);
@@ -1034,3 +1237,45 @@ void DisplayDriverPainter::ConstrainClippingRegion(BRegion *region)
Unlock();
}
}
// _MoveRect
void
DisplayDriverPainter::_MoveRect(uint8* src, uint32 width, uint32 height,
uint32 bpr, int32 xOffset, int32 yOffset) const
{
int32 xIncrement;
int32 yIncrement;
if (xOffset > 0) {
// copy from right to left
xIncrement = -1;
src += width * 4;
} else {
// copy from left to right
xIncrement = 1;
}
if (yOffset > 0) {
// copy from bottom to top
yIncrement = -bpr;
src += height * bpr;
} else {
// copy from top to bottom
yIncrement = bpr;
}
uint8* dst = src + yOffset * bpr + xOffset * 4;
for (uint32 y = 0; y < height; y++) {
uint32* srcHandle = (uint32*)src;
uint32* dstHandle = (uint32*)dst;
for (uint32 x = 0; x < width; x++) {
*dstHandle = *srcHandle;
srcHandle += xIncrement;
dstHandle += xIncrement;
}
src += yIncrement;
dst += yIncrement;
}
}
@@ -281,6 +281,10 @@ class DisplayDriverPainter : public DisplayDriver {
virtual void ConstrainClippingRegion(BRegion *reg);
private:
void _MoveRect(uint8* bits,
uint32 width, uint32 height, uint32 bpr,
int32 xOffset, int32 yOffset) const;
Painter* fPainter;
HWInterface* fGraphicsCard;
};
@@ -120,7 +120,8 @@ AGGTextRenderer::SetFont(const char* pathToFontFile)
{
if (pathToFontFile) {
if (fFontEngine.load_font(pathToFontFile, 0, agg::glyph_ren_outline)) {
// if (fFontEngine.load_font(pathToFontFile, 0, agg::glyph_ren_native_gray8)) {
return TextRenderer::SetFont(pathToFontFile);
} else {
fprintf(stderr, "%s : is not a font file or could not be opened\n",
@@ -199,8 +200,9 @@ AGGTextRenderer::RenderString(const char* string,
const Transformable& transform,
BPoint* nextCharPos)
{
fFontEngine.hinting(fHinted);
fFontEngine.height((int32)(fPtSize/* * 16.0*/));
fFontEngine.hinting(false);
fFontEngine.height((int32)(fPtSize));
fFontEngine.width((int32)(fPtSize));
typedef agg::conv_curve<font_manager_type::path_adaptor_type> conv_font_curve_type;
// typedef agg::conv_segmentator<conv_font_curve_type> conv_font_segm_type;
@@ -310,8 +312,10 @@ AGGTextRenderer::RenderString(const char* string,
}
// increment pen position
advanceX = fHinted ? floorf(glyph->advance_x + 0.5) : glyph->advance_x;
advanceY = fHinted ? floorf(glyph->advance_y + 0.5) : glyph->advance_y;
// advanceX = fHinted ? floorf(glyph->advance_x + 0.5) : glyph->advance_x;
// advanceY = fHinted ? floorf(glyph->advance_y + 0.5) : glyph->advance_y;
advanceX = glyph->advance_x;
advanceY = glyph->advance_y;
}
++p;
}
@@ -334,8 +338,9 @@ BRect
AGGTextRenderer::Bounds(const char* string, uint32 length,
const Transformable& transform)
{
fFontEngine.hinting(fHinted);
fFontEngine.height((int32)(fPtSize/* * 16.0*/));
fFontEngine.hinting(false);
fFontEngine.height((int32)(fPtSize));
fFontEngine.width((int32)(fPtSize));
BRect bounds(0.0, 0.0, -1.0, -1.0);
@@ -427,8 +432,8 @@ AGGTextRenderer::Bounds(const char* string, uint32 length,
bounds = bounds.IsValid() ? bounds | t : t;
// increment pen position
advanceX = fHinted ? floorf(glyph->advance_x + 0.5) : glyph->advance_x;
advanceY = fHinted ? floorf(glyph->advance_y + 0.5) : glyph->advance_y;
advanceX = glyph->advance_x;
advanceY = glyph->advance_y;
}
++p;
}
@@ -35,6 +35,7 @@ FontManager::FontManager(bool scanFontsInline)
if (error)
fprintf(stderr, "Could not initialise FreeType library\n");
/*
if (scanFontsInline) {
_update((void*)this);
} else {
@@ -43,7 +44,7 @@ FontManager::FontManager(bool scanFontsInline)
B_LOW_PRIORITY, this);
if (fontScanner >= B_OK)
resume_thread(fontScanner);
}
}*/
Run();
}
@@ -15,7 +15,7 @@
// constructor
TextRenderer::TextRenderer()
: fPtSize(12.0),
fHinted(false),
fHinted(true),
fAntialias(true),
fKerning(true),
fOpacity(255),