void
EDFBFont::GetHeight(e_font_height *height, float size, float shear, bool bold) const
{
	if(fEngine == NULL || height == NULL) return;

	bzero(height, sizeof(e_font_height));

	EAutolock <EDFBGraphicsEngine> autolock(fEngine);
	if(autolock.IsLocked() == false || fEngine->InitCheck() != E_OK) return;

	int dfbHeight = 0;
	fDFBFont->GetHeight(fDFBFont, &dfbHeight);

	if(size != (float)dfbHeight) return;

	int ascent = 0, descent = 0;
	fDFBFont->GetAscender(fDFBFont, &ascent);
	fDFBFont->GetDescender(fDFBFont, &descent);

	height->ascent = (float)(dfbHeight - ascent + descent) / 2.f + (float)ascent;
	height->descent = (float)dfbHeight - height->ascent;
	height->leading = 0;

	return;
}
ERect
EDFBFont::RenderString(EHandler *_view, const char *string, float size, float spacing, float shear, bool bold, eint32 length)
{
	if(fEngine == NULL || (int)size <= 0 || string == NULL || *string == 0 || length == 0) return ERect();

	EView *view = e_cast_as(_view, EView);
	if(view == NULL || view->Window() == NULL || view->IsPrinting()) return ERect();

	ERegion viewClipping;
	view->GetClippingRegion(&viewClipping);
	if(viewClipping.CountRects() <= 0) return ERect();

	EAutolock <EDFBGraphicsEngine> autolock(fEngine);
	if(autolock.IsLocked() == false || fEngine->InitCheck() != E_OK) return ERect();

	EDFBGraphicsDrawable *pix = e_cast_as(EGraphicsEngine::GetPixmap(view->Window()), EDFBGraphicsDrawable);
	EGraphicsContext *dc = EGraphicsEngine::GetContext(view);
	if(pix == NULL || pix->dfbSurface == NULL || dc == NULL) return ERect();

	if(!IsAttached()) return ERect();

	int height = 0, ascent = 0, descent = 0;
	fDFBFont->GetHeight(fDFBFont, &height);
	fDFBFont->GetAscender(fDFBFont, &ascent);
	fDFBFont->GetDescender(fDFBFont, &descent);

	if(size != (float)height) return ERect();

	float width = 0;
	if(length < 0 || (size_t)length > strlen(string)) length = (eint32)strlen(string);
	float delta = (float)ceil((double)(spacing * size));

	EPoint pt = view->ConvertToWindow(view->PenLocation());
	pt.y -= (float)(ascent + 1);

	e_rgb_color c = dc->HighColor();
	pix->dfbSurface->SetColor(pix->dfbSurface, c.red, c.green, c.blue, 255);
	pix->dfbSurface->SetDrawingFlags(pix->dfbSurface, DSDRAW_NOFX);
	pix->dfbSurface->SetFont(pix->dfbSurface, fDFBFont);

	euint8 bytes = 0;
	const char *str = e_utf8_at(string, 0, &bytes);
	const char *tmp = str;
	while(!(tmp == NULL || bytes == 0 || (size_t)(tmp - string) > (size_t)length - (size_t)bytes))
	{
		EString aStr(tmp, (eint32)bytes);

		int bWidth = -1;
		fDFBFont->GetStringWidth(fDFBFont, aStr.String(), aStr.Length(), &bWidth);

		for(eint32 i = 0; i < dc->Clipping()->CountRects(); i++)
		{
			ERect rect = dc->Clipping()->RectAt(i).FloorCopy();

			DFBRegion clipping;
			clipping.x1 = (int)rect.left;
			clipping.y1 = (int)rect.top;
			clipping.x2 = (int)rect.right;
			clipping.y2 = (int)rect.bottom;

			pix->dfbSurface->SetClip(pix->dfbSurface, &clipping);

			if(bWidth > 0)
				pix->dfbSurface->DrawString(pix->dfbSurface, aStr.String(), aStr.Length(),
							    (int)pt.x, (int)pt.y, (DFBSurfaceTextFlags)(DSTF_LEFT | DSTF_TOP));
//			else
//				pix->dfbSurface->FillRectangle(pix->dfbSurface, (int)pt.x + 3, (int)pt.y + 3, height - 6, height - 6);
		}

		pt.x += (float)(bWidth > 0 ? bWidth : height) + delta;
		width += (float)(bWidth > 0 ? bWidth : height) + (tmp == str ? 0.f : delta);

		tmp = e_utf8_next(tmp, &bytes);
	}

	pix->dfbSurface->SetFont(pix->dfbSurface, NULL);

	ERect updateRect;
	updateRect.left = pt.x;
	updateRect.right = pt.x + width;
	updateRect.top = pt.y;
	updateRect.bottom = updateRect.top + (float)height;
	view->ConvertFromWindow(&updateRect);
	updateRect &= viewClipping.Frame();

	return updateRect;
}