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:
parent
e18f9c5e67
commit
03339b3565
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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 -
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -15,7 +15,7 @@
|
||||
// constructor
|
||||
TextRenderer::TextRenderer()
|
||||
: fPtSize(12.0),
|
||||
fHinted(true),
|
||||
fHinted(false),
|
||||
fAntialias(true),
|
||||
fKerning(true),
|
||||
fOpacity(255),
|
||||
|
@ -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() {};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user