float EDFBFont::StringWidth(const char *string, float size, float spacing, float shear, bool bold, eint32 length) const { if(fEngine == NULL) return 0; if((int)size <= 0 || string == NULL || *string == 0 || length == 0 || !IsAttached()) return 0; EAutolock <EDFBGraphicsEngine> autolock(fEngine); if(autolock.IsLocked() == false || fEngine->InitCheck() != E_OK) return 0; int height = 0; fDFBFont->GetHeight(fDFBFont, &height); if(size != (float)height) return 0; float width = 0; if(length < 0 || (size_t)length > strlen(string)) length = (eint32)strlen(string); float delta = (float)ceil((double)(spacing * size)); 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); width += (float)(bWidth > 0 ? bWidth : height) + (tmp == str ? 0.f : delta); tmp = e_utf8_next(tmp, &bytes); } return width; }
LOCAL void dfb_drawtext(DFBDISPLAY *mod, struct TVRequest *req) { DFBWINDOW *v = req->tvr_Op.Text.Window; TSTRPTR text = req->tvr_Op.Text.Text; TINT len = req->tvr_Op.Text.Length; TUINT x = req->tvr_Op.Text.X; TUINT y = req->tvr_Op.Text.Y; TINT w; /*TINT h = ((struct FontNode *) v->curfont)->height;*/ struct DFBPen *fgpen = (struct DFBPen *) req->tvr_Op.Text.FgPen; TINT ascent = ((struct FontNode *) v->curfont)->ascent; IDirectFBFont *f = ((struct FontNode *) v->curfont)->font; f->GetStringWidth(f, text, len, &w); setfgpen(mod, v, (TVPEN) fgpen); v->winsurface->DrawString(v->winsurface, text, len, x, y + ascent, DSTF_LEFT); }
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; }