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
This commit is contained in:
Stephan Aßmus 2005-03-30 22:10:42 +00:00
parent e18f9c5e67
commit 03339b3565
6 changed files with 105 additions and 174 deletions

View File

@ -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();
}
}

View File

@ -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 -

View File

@ -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<font_manager_type::path_adaptor_type> conv_font_curve_type;
// typedef agg::conv_segmentator<conv_font_curve_type> conv_font_segm_type;
// typedef agg::conv_transform<conv_font_segm_type, agg::trans_affine> 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;
}

View File

@ -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;

View File

@ -15,7 +15,7 @@
// constructor
TextRenderer::TextRenderer()
: fPtSize(12.0),
fHinted(true),
fHinted(false),
fAntialias(true),
fKerning(true),
fOpacity(255),

View File

@ -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() {};