From 45c0cd28d8e7f49683dd8f180eba5385b16591dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Wed, 30 Mar 2005 16:05:05 +0000 Subject: [PATCH] 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 --- src/servers/app/Layer.cpp | 5 +- .../app/drawing/AccelerantHWInterface.cpp | 4 +- .../app/drawing/DisplayDriverPainter.cpp | 271 +++++++++++++++++- .../app/drawing/DisplayDriverPainter.h | 4 + .../Painter/font_support/AGGTextRenderer.cpp | 23 +- .../Painter/font_support/FontManager.cpp | 3 +- .../Painter/font_support/TextRenderer.cpp | 2 +- 7 files changed, 285 insertions(+), 27 deletions(-) diff --git a/src/servers/app/Layer.cpp b/src/servers/app/Layer.cpp index 158883db6a..d0c3b1d133 100644 --- a/src/servers/app/Layer.cpp +++ b/src/servers/app/Layer.cpp @@ -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(); diff --git a/src/servers/app/drawing/AccelerantHWInterface.cpp b/src/servers/app/drawing/AccelerantHWInterface.cpp index e46a0b3ef7..70a33ea135 100644 --- a/src/servers/app/drawing/AccelerantHWInterface.cpp +++ b/src/servers/app/drawing/AccelerantHWInterface.cpp @@ -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 + } diff --git a/src/servers/app/drawing/DisplayDriverPainter.cpp b/src/servers/app/drawing/DisplayDriverPainter.cpp index e8371323a5..d5253ed7e5 100644 --- a/src/servers/app/drawing/DisplayDriverPainter.cpp +++ b/src/servers/app/drawing/DisplayDriverPainter.cpp @@ -25,11 +25,19 @@ // //------------------------------------------------------------------------------ #include +#include #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; + } +} + diff --git a/src/servers/app/drawing/DisplayDriverPainter.h b/src/servers/app/drawing/DisplayDriverPainter.h index d9d7f5917e..40596733d9 100644 --- a/src/servers/app/drawing/DisplayDriverPainter.h +++ b/src/servers/app/drawing/DisplayDriverPainter.h @@ -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; }; diff --git a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp index 6cc045243c..6ff7c9b9bd 100644 --- a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp +++ b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp @@ -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 conv_font_curve_type; // typedef agg::conv_segmentator 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; } diff --git a/src/servers/app/drawing/Painter/font_support/FontManager.cpp b/src/servers/app/drawing/Painter/font_support/FontManager.cpp index 6bbbe6a1e0..87515b8a89 100644 --- a/src/servers/app/drawing/Painter/font_support/FontManager.cpp +++ b/src/servers/app/drawing/Painter/font_support/FontManager.cpp @@ -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(); } diff --git a/src/servers/app/drawing/Painter/font_support/TextRenderer.cpp b/src/servers/app/drawing/Painter/font_support/TextRenderer.cpp index 71bd4ff7bf..15ff8e722a 100644 --- a/src/servers/app/drawing/Painter/font_support/TextRenderer.cpp +++ b/src/servers/app/drawing/Painter/font_support/TextRenderer.cpp @@ -15,7 +15,7 @@ // constructor TextRenderer::TextRenderer() : fPtSize(12.0), - fHinted(false), + fHinted(true), fAntialias(true), fKerning(true), fOpacity(255),