From 03339b3565fdb900590682cbbc1d2f45d61b72a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Wed, 30 Mar 2005 22:10:42 +0000 Subject: [PATCH] added Adis changes, started to return BRect in Painter drawing functions, this will be the area enclosing all pixels that were touched by an operation, so that the DisplayDriverPainter knows exactly what region to copy from back to front buffer, it calculates that by itself for all other functions, which is not as robust. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12170 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../app/drawing/DisplayDriverPainter.cpp | 20 +- src/servers/app/drawing/Painter/Painter.cpp | 43 ++-- .../Painter/font_support/AGGTextRenderer.cpp | 203 ++++++------------ .../Painter/font_support/AGGTextRenderer.h | 7 +- .../Painter/font_support/TextRenderer.cpp | 2 +- .../Painter/font_support/TextRenderer.h | 4 +- 6 files changed, 105 insertions(+), 174 deletions(-) diff --git a/src/servers/app/drawing/DisplayDriverPainter.cpp b/src/servers/app/drawing/DisplayDriverPainter.cpp index d5253ed7e5..ced5daa4ed 100644 --- a/src/servers/app/drawing/DisplayDriverPainter.cpp +++ b/src/servers/app/drawing/DisplayDriverPainter.cpp @@ -887,10 +887,7 @@ DisplayDriverPainter::DrawString(const char *string, const int32 &length, if (Lock()) { fPainter->SetDrawData(d); - BRect boundingBox = fPainter->BoundingBox(string, length, pt); - - fPainter->DrawString(string, length, pt); - + BRect boundingBox = fPainter->DrawString(string, length, pt); fGraphicsCard->Invalidate(boundingBox); Unlock(); @@ -1232,8 +1229,19 @@ void DisplayDriverPainter::Invalidate(const BRect &r) // ConstrainClippingRegion void DisplayDriverPainter::ConstrainClippingRegion(BRegion *region) { - if (region && Lock()) { - fPainter->ConstrainClipping(*region); + if (Lock()) { + if (!region || !region->Frame().IsValid()) { +// BRegion empty; +// fPainter->ConstrainClipping(empty); + if (RenderingBuffer* buffer = fGraphicsCard->BackBuffer()) { + BRegion all; + all.Include(BRect(0, 0, buffer->Width() - 1, + buffer->Height() - 1)); + fPainter->ConstrainClipping(all); + } + } else { + fPainter->ConstrainClipping(*region); + } Unlock(); } } diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index 8ba8a4d266..9661390ede 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -729,38 +729,39 @@ Painter::FillArc(BPoint center, float xRadius, float yRadius, // #pragma mark - // DrawChar -void +BRect Painter::DrawChar(char aChar) { // TODO: to be moved elsewhere - DrawChar(aChar, fPenLocation); + return DrawChar(aChar, fPenLocation); } // DrawChar -void +BRect Painter::DrawChar(char aChar, BPoint baseLine) { // TODO: to be moved elsewhere char wrapper[2]; wrapper[0] = aChar; wrapper[1] = 0; - DrawString(wrapper, 1, baseLine); + return DrawString(wrapper, 1, baseLine); } // DrawString -void +BRect Painter::DrawString(const char* utf8String, uint32 length, const escapement_delta* delta) { // TODO: to be moved elsewhere - DrawString(utf8String, length, fPenLocation, delta); + return DrawString(utf8String, length, fPenLocation, delta); } // DrawString -void +BRect Painter::DrawString(const char* utf8String, uint32 length, BPoint baseLine, const escapement_delta* delta) { + BRect bounds(0.0, 0.0, -1.0, -1.0); fPatternHandler->SetPattern(B_SOLID_HIGH); if (fBuffer) { @@ -773,12 +774,12 @@ Painter::DrawString(const char* utf8String, uint32 length, transform.ScaleBy(B_ORIGIN, fScale, fScale); transform.TranslateBy(fOrigin); - fTextRenderer->RenderString(utf8String, - length, - fFontRendererSolid, - fFontRendererBin, - transform, - &fPenLocation); + bounds = fTextRenderer->RenderString(utf8String, + length, + fFontRendererSolid, + fFontRendererBin, + transform, false, + &fPenLocation); // pen location is not transformed in quite the same way, // or transformations would add up transform.Reset(); @@ -786,23 +787,24 @@ Painter::DrawString(const char* utf8String, uint32 length, transform.TranslateBy(baseLine); transform.Transform(&fPenLocation); } + return bounds; } // DrawString -void +BRect Painter::DrawString(const char* utf8String, const escapement_delta* delta) { // TODO: to be moved elsewhere - DrawString(utf8String, strlen(utf8String), fPenLocation, delta); + return DrawString(utf8String, strlen(utf8String), fPenLocation, delta); } // DrawString -void +BRect Painter::DrawString(const char* utf8String, BPoint baseLine, const escapement_delta* delta) { // TODO: to be moved elsewhere - DrawString(utf8String, strlen(utf8String), baseLine, delta); + return DrawString(utf8String, strlen(utf8String), baseLine, delta); } // #pragma mark - @@ -883,7 +885,12 @@ Painter::BoundingBox(const char* utf8String, uint32 length, { Transformable transform; transform.TranslateBy(baseLine); - return fTextRenderer->Bounds(utf8String, length, transform); + + return fTextRenderer->RenderString(utf8String, + length, + fFontRendererSolid, + fFontRendererBin, + transform, true); } // #pragma mark - diff --git a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp index 6ff7c9b9bd..de9968d9b5 100644 --- a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp +++ b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp @@ -192,18 +192,21 @@ AGGTextRenderer::PostScriptName() const } // RenderString -void +BRect AGGTextRenderer::RenderString(const char* string, uint32 length, font_renderer_solid_type* solidRenderer, font_renderer_bin_type* binRenderer, const Transformable& transform, + bool dryRun, BPoint* nextCharPos) { - fFontEngine.hinting(false); + fFontEngine.hinting(fHinted); fFontEngine.height((int32)(fPtSize)); fFontEngine.width((int32)(fPtSize)); + BRect bounds(0.0, 0.0, -1.0, -1.0); + typedef agg::conv_curve conv_font_curve_type; // typedef agg::conv_segmentator conv_font_segm_type; // typedef agg::conv_transform conv_font_trans_type; @@ -271,51 +274,78 @@ AGGTextRenderer::RenderString(const char* string, y += advanceY; fFontManager.init_embedded_adaptors(glyph, x, y); - + + double left = 0.0; + double top = 0.0; + double right = -1.0; + double bottom = -1.0; + uint32 pathID[1]; + pathID[0] = 0; + + const agg::rect& r = fFontEngine.bounds(); + switch(glyph->data_type) { case agg::glyph_data_mono: -// binRenderer->color(agg::gray8(fOpacity)); - agg::render_scanlines(fFontManager.mono_adaptor(), - fFontManager.mono_scanline(), - *binRenderer); + left = r.x1 + x; + right = r.x2 + x; + top = r.y1 + y; + bottom = r.y2 + y; + if (!dryRun) { + agg::render_scanlines(fFontManager.mono_adaptor(), + fFontManager.mono_scanline(), + *binRenderer); + } break; - + case agg::glyph_data_gray8: -// solidRenderer->color(agg::gray8(fOpacity)); - agg::render_scanlines(fFontManager.gray8_adaptor(), - fFontManager.gray8_scanline(), - *solidRenderer); + left = r.x1 + x; + right = r.x2 + x; + top = r.y1 + y; + bottom = r.y2 + y; + if (!dryRun) { + agg::render_scanlines(fFontManager.gray8_adaptor(), + fFontManager.gray8_scanline(), + *solidRenderer); + } break; - + case agg::glyph_data_outline: ras.reset(); if(fabs(0.0) <= 0.01) { // For the sake of efficiency skip the // contour converter if the weight is about zero. //----------------------- -// ras.add_path(fCurves); - ras.add_path(ftrans); + agg::bounding_rect(ftrans, pathID, 0, 1, + &left, &top, &right, &bottom); + if (!dryRun) + // ras.add_path(fCurves); + ras.add_path(ftrans); } else { -// ras.add_path(fContour); - ras.add_path(ftrans); + if (!dryRun) + // ras.add_path(fContour); + ras.add_path(ftrans); + agg::bounding_rect(ftrans, pathID, 0, 1, + &left, &top, &right, &bottom); } - if (fAntialias) { -// solidRenderer->color(agg::gray8(fOpacity)); - agg::render_scanlines(ras, sl, *solidRenderer); - } else { -// binRenderer->color(agg::gray8(fOpacity)); - agg::render_scanlines(ras, sl, *binRenderer); + if (!dryRun) { + if (fAntialias) { + agg::render_scanlines(ras, sl, *solidRenderer); + } else { + agg::render_scanlines(ras, sl, *binRenderer); + } } break; default: break; } - + // calculate bounds + BRect t(left, top, right, bottom); + if (t.IsValid()) + 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; + advanceX = fHinted ? floorf(glyph->advance_x + 0.5) : glyph->advance_x; + advanceY = fHinted ? floorf(glyph->advance_y + 0.5) : glyph->advance_y; } ++p; } @@ -331,119 +361,8 @@ AGGTextRenderer::RenderString(const char* string, fprintf(stderr, "UTF8 -> Unicode conversion failed: %s\n", strerror(ret)); } delete[] buffer; -} - -// Bounds -BRect -AGGTextRenderer::Bounds(const char* string, uint32 length, - const Transformable& transform) -{ - fFontEngine.hinting(false); - fFontEngine.height((int32)(fPtSize)); - fFontEngine.width((int32)(fPtSize)); - - BRect bounds(0.0, 0.0, -1.0, -1.0); - - // do a UTF8 -> Unicode conversion - if (string) { - - int32 srcLength = min_c(strlen(string), length); - if (srcLength > 0) { - - int32 dstLength = srcLength * 4; - - char* buffer = new char[dstLength]; - - int32 state = 0; - status_t ret; - if ((ret = convert_from_utf8(B_UNICODE_CONVERSION, - string, &srcLength, - buffer, &dstLength, - &state, B_SUBSTITUTE)) >= B_OK - && (ret = swap_data(B_INT16_TYPE, buffer, dstLength, - B_SWAP_BENDIAN_TO_HOST)) >= B_OK) { - - uint16* p = (uint16*)buffer; - - double x = 0.0; - double y0 = 0.0; - double y = y0; - - double advanceX = 0.0; - double advanceY = 0.0; - - for (int32 i = 0; i < dstLength / 2; i++) { - - // line break - if (*p == '\n') { - y0 +=LineOffset(); - x = 0.0; - y = y0; - advanceX = 0.0; - advanceY = 0.0; - ++p; - continue; - } - - const agg::glyph_cache* glyph = fFontManager.glyph(*p); - - if (glyph) { - - if (fKerning) { - fFontManager.add_kerning(&advanceX, &advanceY); - } - - x += fAdvanceScale * advanceX; - if (advanceX > 0.0 && fAdvanceScale > 1.0) - x += (fAdvanceScale - 1.0) * fFontEngine.height(); - y += advanceY; - - double left = 0.0; - double top = 0.0; - double right = -1.0; - double bottom = -1.0; - uint32 pathID[1]; - pathID[0] = 0; - - fFontManager.init_embedded_adaptors(glyph, x, y); - - switch(glyph->data_type) { - case agg::glyph_data_mono: - break; - - case agg::glyph_data_gray8: - break; - - case agg::glyph_data_outline: - if (fabs(0.0) <= 0.01) { - // For the sake of efficiency skip the - // contour converter if the weight is about zero. - //----------------------- - agg::bounding_rect(fContour, pathID, 0, 1, &left, &top, &right, &bottom); - } else { - agg::bounding_rect(fCurves, pathID, 0, 1, &left, &top, &right, &bottom); - } - break; - default: - break; - } - BRect t(left, top, right, bottom); - if (t.IsValid()) - bounds = bounds.IsValid() ? bounds | t : t; - - // increment pen position - advanceX = glyph->advance_x; - advanceY = glyph->advance_y; - } - ++p; - } - delete[] buffer; - } else { - fprintf(stderr, "UTF8 -> Unicode conversion failed: %s\n", strerror(ret)); - } - } - } - - return transform.TransformBounds(bounds); + +// return transform.TransformBounds(bounds); + return bounds; } diff --git a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.h b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.h index f75d58009a..db6a48e71d 100644 --- a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.h +++ b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.h @@ -29,17 +29,14 @@ class AGGTextRenderer : public TextRenderer { virtual const char* Style() const; virtual const char* PostScriptName() const; - virtual void RenderString(const char* utf8String, + virtual BRect RenderString(const char* utf8String, uint32 length, font_renderer_solid_type* solidRenderer, font_renderer_bin_type* binRenderer, const Transformable& transform, + bool dryRun = false, BPoint* nextCharPos = NULL); - virtual BRect Bounds(const char* utf8String, - uint32 length, - const Transformable& transform); - private: typedef agg::font_engine_freetype_int32 font_engine_type; diff --git a/src/servers/app/drawing/Painter/font_support/TextRenderer.cpp b/src/servers/app/drawing/Painter/font_support/TextRenderer.cpp index 15ff8e722a..71bd4ff7bf 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(true), + fHinted(false), fAntialias(true), fKerning(true), fOpacity(255), diff --git a/src/servers/app/drawing/Painter/font_support/TextRenderer.h b/src/servers/app/drawing/Painter/font_support/TextRenderer.h index e654747f2b..439ff70d1f 100644 --- a/src/servers/app/drawing/Painter/font_support/TextRenderer.h +++ b/src/servers/app/drawing/Painter/font_support/TextRenderer.h @@ -58,10 +58,10 @@ class TextRenderer : public BArchivable { /* virtual void RenderString(const char* utf8String, BBitmap* bitmap, BRect constrainRect, - const Transformable& transform) = 0;*/ + const Transformable& transform) = 0; virtual BRect Bounds(const char* utf8String, uint32 length, - const Transformable& transform) = 0; + const Transformable& transform) = 0;*/ virtual void Update() {};