diff --git a/src/servers/app/server/DisplayDriver.cpp b/src/servers/app/server/DisplayDriver.cpp index 7f2f79e9ba..c4207b213b 100644 --- a/src/servers/app/server/DisplayDriver.cpp +++ b/src/servers/app/server/DisplayDriver.cpp @@ -27,6 +27,8 @@ // //------------------------------------------------------------------------------ #include +#include "Angle.h" +#include "FontFamily.h" #include #include "DisplayDriver.h" #include "ServerCursor.h" @@ -329,6 +331,365 @@ void DisplayDriver::DrawBitmap(ServerBitmap *bmp, const BRect &src, const BRect \param d Data structure containing any other data necessary for the call. Always non-NULL. */ void DisplayDriver::DrawString(const char *string, const int32 &length, const BPoint &pt, const DrawData *d) +{ + if(!string || !d) + return; + + Lock(); + + BPoint point(pt); + + point.y--; // because of Be's backward compatibility hack + + const ServerFont *font=&(d->font); + FontStyle *style=font->Style(); + + if(!style) + { + Unlock(); + return; + } + + FT_Face face; + FT_GlyphSlot slot; + FT_Matrix rmatrix,smatrix; + FT_UInt glyph_index=0, previous=0; + FT_Vector pen,delta,space,nonspace; + int16 error=0; + int32 strlength,i; + Angle rotation(font->Rotation()), shear(font->Shear()); + + bool antialias=( (font->Size()<18 && font->Flags()& B_DISABLE_ANTIALIASING==0) + || font->Flags()& B_FORCE_ANTIALIASING)?true:false; + + // Originally, I thought to do this shear checking here, but it really should be + // done in BFont::SetShear() + float shearangle=shear.Value(); + if(shearangle>135) + shearangle=135; + if(shearangle<45) + shearangle=45; + + if(shearangle>90) + shear=90+((180-shearangle)*2); + else + shear=90-(90-shearangle)*2; + + error=FT_New_Face(ftlib, style->GetPath(), 0, &face); + if(error) + { + Unlock(); + return; + } + + slot=face->glyph; + + bool use_kerning=FT_HAS_KERNING(face) && font->Spacing()==B_STRING_SPACING; + + error=FT_Set_Char_Size(face, 0,int32(font->Size())*64,72,72); + if(error) + { + Unlock(); + return; + } + + // if we do any transformation, we do a call to FT_Set_Transform() here + + // First, rotate + rmatrix.xx = (FT_Fixed)( rotation.Cosine()*0x10000); + rmatrix.xy = (FT_Fixed)(-rotation.Sine()*0x10000); + rmatrix.yx = (FT_Fixed)( rotation.Sine()*0x10000); + rmatrix.yy = (FT_Fixed)( rotation.Cosine()*0x10000); + + // Next, shear + smatrix.xx = (FT_Fixed)(0x10000); + smatrix.xy = (FT_Fixed)(-shear.Cosine()*0x10000); + smatrix.yx = (FT_Fixed)(0); + smatrix.yy = (FT_Fixed)(0x10000); + + FT_Matrix_Multiply(&rmatrix,&smatrix); + + // Set up the increment value for escapement padding + space.x=int32(d->edelta.space * rotation.Cosine()*64); + space.y=int32(d->edelta.space * rotation.Sine()*64); + nonspace.x=int32(d->edelta.nonspace * rotation.Cosine()*64); + nonspace.y=int32(d->edelta.nonspace * rotation.Sine()*64); + + // set the pen position in 26.6 cartesian space coordinates + pen.x=(int32)point.x * 64; + pen.y=(int32)point.y * 64; + + slot=face->glyph; + + + strlength=strlen(string); + if(lengthbitmap, + BPoint(slot->bitmap_left,point.y-(slot->bitmap_top-point.y)), d); + else + BlitMono2RGB32(&slot->bitmap, + BPoint(slot->bitmap_left,point.y-(slot->bitmap_top-point.y)), d); + } + + // increment pen position + pen.x+=slot->advance.x; + pen.y+=slot->advance.y; + previous=glyph_index; + } + + // TODO: implement properly + // calculate the invalid rectangle + BRect r; + r.left=MIN(point.x,pen.x>>6); + r.right=MAX(point.x,pen.x>>6); + r.top=point.y-face->height; + r.bottom=point.y+face->height; + + FT_Done_Face(face); + + Unlock(); + +} + +void DisplayDriver::BlitMono2RGB32(FT_Bitmap *src, const BPoint &pt, const DrawData *d) +{ +/* rgb_color color=d->highcolor.GetColor32(); + + // pointers to the top left corner of the area to be copied in each bitmap + uint8 *srcbuffer, *destbuffer; + + // index pointers which are incremented during the course of the blit + uint8 *srcindex, *destindex, *rowptr, value; + + // increment values for the index pointers + int32 srcinc=src->pitch, destinc=framebuffer->BytesPerRow(); + + int16 i,j,k, srcwidth=src->pitch, srcheight=src->rows; + int32 x=(int32)pt.x,y=(int32)pt.y; + + // starting point in source bitmap + srcbuffer=(uint8*)src->buffer; + + if(y<0) + { + if(yframebuffer->Bounds().IntegerHeight()) + { + if(y>pt.y) + y--; + srcheight-=(y+srcheight-1)-framebuffer->Bounds().IntegerHeight(); + } + + if(x+srcwidth>framebuffer->Bounds().IntegerWidth()) + { + if(x>pt.x) + x--; + srcwidth-=(x+srcwidth-1)-framebuffer->Bounds().IntegerWidth(); + } + + if(x<0) + { + if(x>3; + srcwidth-=0-x; + destbuffer+=(0-x)*4; + } + + // starting point in destination bitmap + destbuffer=(uint8*)framebuffer->Bits()+int32( (pt.y*framebuffer->BytesPerRow())+(pt.x*4) ); + + srcindex=srcbuffer; + destindex=destbuffer; + + for(i=0; ihighcolor.GetColor32(), lowcolor=d->lowcolor.GetColor32(); float rstep,gstep,bstep,astep; + + rstep=float(highcolor.red-lowcolor.red)/255.0; + gstep=float(highcolor.green-lowcolor.green)/255.0; + bstep=float(highcolor.blue-lowcolor.blue)/255.0; + astep=float(highcolor.alpha-lowcolor.alpha)/255.0; + + // increment values for the index pointers + int32 x=(int32)pt.x, + y=(int32)pt.y, + srcinc=src->pitch, +// destinc=dest->BytesPerRow(), + destinc=framebuffer->BytesPerRow(), + srcwidth=src->width, + srcheight=src->rows, + incval=0; + + int16 i,j; + + // starting point in source bitmap + srcbuffer=(uint8*)src->buffer; + + // starting point in destination bitmap +// destbuffer=(uint8*)dest->Bits()+(y*dest->BytesPerRow()+(x*4)); + destbuffer=(uint8*)framebuffer->Bits()+(y*framebuffer->BytesPerRow()+(x*4)); + + + if(y<0) + { + if(yframebuffer->Bounds().IntegerHeight()) + { + if(y>pt.y) + y--; + srcheight-=(y+srcheight-1)-framebuffer->Bounds().IntegerHeight(); + } + + if(x+srcwidth>framebuffer->Bounds().IntegerWidth()) + { + if(x>pt.x) + x--; + srcwidth-=(x+srcwidth-1)-framebuffer->Bounds().IntegerWidth(); + } + + if(x<0) + { + if(xdraw_mode==B_OP_COPY) + { + rowptr[0]=uint8(highcolor.blue-(value*bstep)); + rowptr[1]=uint8(highcolor.green-(value*gstep)); + rowptr[2]=uint8(highcolor.red-(value*rstep)); + rowptr[3]=255; + } + else + if(d->draw_mode==B_OP_OVER) + { + if(highcolor.alpha>127) + { + rowptr[0]=uint8(highcolor.blue-(value*(float(highcolor.blue-rowptr[0])/255.0))); + rowptr[1]=uint8(highcolor.green-(value*(float(highcolor.green-rowptr[1])/255.0))); + rowptr[2]=uint8(highcolor.red-(value*(float(highcolor.red-rowptr[2])/255.0))); + rowptr[3]=255; + } + } + } + rowptr+=4; + + } + + srcindex+=srcinc; + destindex+=destinc; + } +*/ +} + +bool DisplayDriver::AcquireBuffer(FBBitmap *bmp) +{ + return false; +} + +void DisplayDriver::ReleaseBuffer(void) { } @@ -905,12 +1266,10 @@ void DisplayDriver::FillPolygon(BPoint *ptlist, int32 numpts, DisplayDriver* dri horizontal line, second intersection is end of horizontal line. Continue for all pairs of intersections. Watch out for horizontal line segments. */ - Lock(); if ( !ptlist || (numpts < 3) ) - { - Unlock(); return; - } + + Lock(); BPoint *currentPoint, *nextPoint; BPoint tempNextPoint; @@ -929,6 +1288,7 @@ void DisplayDriver::FillPolygon(BPoint *ptlist, int32 numpts, DisplayDriver* dri { printf("ERROR: Insufficient memory allocated to segment array\n"); delete[] segmentArray; + Unlock(); return; } @@ -1050,7 +1410,7 @@ void DisplayDriver::FillRegion(BRegion& r, RGBColor &color) Lock(); for(int32 i=0; iUnlock(); } +void ViewDriver::FillSolidRect(const BRect &rect, RGBColor &color) +{ + if(!is_initialized) + return; + + screenwin->Lock(); + framebuffer->Lock(); + drawview->SetHighColor(color.GetColor32()); + drawview->FillRect(rect); + drawview->Sync(); + screenwin->view->Invalidate(rect); + framebuffer->Unlock(); + screenwin->Unlock(); +} + +void ViewDriver::FillPatternRect(const BRect &rect, const DrawData *d) +{ + if(!d) + return; + + if(!is_initialized) + return; + + screenwin->Lock(); + framebuffer->Lock(); + drawview->SetHighColor(d->highcolor.GetColor32()); + drawview->SetLowColor(d->lowcolor.GetColor32()); + drawview->FillRect(rect,*((pattern*)d->patt.GetInt8())); + drawview->Sync(); + screenwin->view->Invalidate(rect); + framebuffer->Unlock(); + screenwin->Unlock(); +} + +void ViewDriver::StrokePatternLine(const BPoint &start, const BPoint &end, const DrawData *d) +{ + if(!d) + return; + + if(!is_initialized) + return; + + screenwin->Lock(); + framebuffer->Lock(); + drawview->SetHighColor(d->highcolor.GetColor32()); + drawview->SetLowColor(d->lowcolor.GetColor32()); + drawview->StrokeLine(start,end,*((pattern*)d->patt.GetInt8())); + drawview->Sync(); + screenwin->view->Invalidate(BRect(start,end)); + framebuffer->Unlock(); + screenwin->Unlock(); +} + +void ViewDriver::StrokeSolidLine(const BPoint &start, const BPoint &end, RGBColor &color) +{ + if(!is_initialized) + return; + + screenwin->Lock(); + framebuffer->Lock(); + drawview->SetHighColor(color.GetColor32()); + drawview->StrokeLine(start,end); + drawview->Sync(); + screenwin->view->Invalidate(BRect(start,end)); + framebuffer->Unlock(); + screenwin->Unlock(); +} + +void ViewDriver::StrokeSolidRect(const BRect &rect, RGBColor &color) +{ + if(!is_initialized) + return; + + screenwin->Lock(); + framebuffer->Lock(); + drawview->SetHighColor(color.GetColor32()); + drawview->StrokeRect(rect); + drawview->Sync(); + screenwin->view->Invalidate(rect); + framebuffer->Unlock(); + screenwin->Unlock(); +} + void ViewDriver::SetLayerData(LayerData *d, bool set_font_data) { if(!is_initialized) @@ -1663,4 +1746,3 @@ status_t ViewDriver::WaitForRetrace(bigtime_t timeout=B_INFINITE_TIMEOUT) BScreen screen; return screen.WaitForRetrace(timeout); } - diff --git a/src/servers/app/server/ViewDriver.h b/src/servers/app/server/ViewDriver.h index 27b45372ff..f9b26a36b9 100644 --- a/src/servers/app/server/ViewDriver.h +++ b/src/servers/app/server/ViewDriver.h @@ -130,7 +130,13 @@ public: virtual status_t WaitForRetrace(bigtime_t timeout=B_INFINITE_TIMEOUT); protected: + void FillSolidRect(const BRect &rect, RGBColor &color); + void FillPatternRect(const BRect &rect, const DrawData *d); + void StrokeSolidRect(const BRect &rect, RGBColor &color); + void StrokeSolidLine(const BPoint &start, const BPoint &end, RGBColor &color); void SetLayerData(LayerData *d, bool set_font_data=false); + void StrokePatternLine(const BPoint &start, const BPoint &end, const DrawData *d); + void BlitMono2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d); void BlitGray2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d); rgb_color GetBlitColor(rgb_color src, rgb_color dest, LayerData *d, bool use_high=true);