void BBox::Draw(BRect updateRect) { if (!IsVisible() || fBorder == B_NO_BORDER) return; e_theme_engine *theme = get_current_theme_engine(); if (theme == NULL || theme->get_border_margins == NULL || theme->draw_border == NULL) return; float l = 0, t = 0, r = 0, b = 0; theme->get_border_margins(theme, this, &l, &t, &r, &b, fBorder, PenSize()); BRect rect = Frame().OffsetToSelf(B_ORIGIN); if (!(fLabelView == NULL || fLabelView->Frame().Width() <= 0 || fLabelView->Frame().Height() < t)) rect.top += (fLabelView->Frame().Height() - t) / 2.f; PushState(); BRegion clipping(updateRect); if (!(fLabelView == NULL || fLabelView->Frame().IsValid() == false)) clipping.Exclude(fLabelView->Frame()); ConstrainClippingRegion(&clipping); if (clipping.CountRects() > 0) theme->draw_border(theme, this, rect, fBorder, PenSize()); PopState(); }
static pascal void drawProc(ControlRef inControl, SInt16 inPart) { #pragma unused(inControl, inPart) int i; RGBColor saveForeColor; RGBColor saveBackColor; PenState savePenState; GetForeColor(&saveForeColor); GetBackColor(&saveBackColor); GetPenState(&savePenState); RGBForeColor(&rgbBlack); RGBBackColor(&rgbWhite); PenNormal(); for (i = 0; i < sNumMonitors; i++) { RGBForeColor(&rgbGray); PaintRect(&sMonitors[i].scaledRect); if (sMonitors[i].isMain) { Rect r = sMonitors[i].scaledRect; InsetRect(&r, 1, 1); r.bottom = r.top + 6; RGBForeColor(&rgbWhite); PaintRect(&r); RGBForeColor(&rgbBlack); PenSize(1,1); MoveTo(r.left, r.bottom); LineTo(r.right, r.bottom); } if (sMonitors[i].device == sSelectedDevice) { PenSize(3,3); RGBForeColor(&rgbBlack); FrameRect(&sMonitors[i].scaledRect); } else { PenSize(1,1); RGBForeColor(&rgbBlack); FrameRect(&sMonitors[i].scaledRect); } } // restore the original pen state and colors RGBForeColor(&saveForeColor); RGBBackColor(&saveBackColor); SetPenState(&savePenState); }
void _HYPlatformGraphicPane::_DrawArc (_HYRect rectDesc, int s, int f) { PenSize (rectDesc.width, rectDesc.width); Rect r= HYRect2Rect (rectDesc); FrameArc (&r,s,f); }
static void fillarea(int n, double *px, double *py) { int fl_inter, fl_style, fl_color; fl_inter = gkss->asf[10] ? gkss->ints : predef_ints[gkss->findex - 1]; fl_style = gkss->asf[11] ? gkss->styli : predef_styli[gkss->findex - 1]; fl_color = gkss->asf[12] ? gkss->facoli : 1; p->pat = NULL; if (fl_inter == GKS_K_INTSTYLE_HOLLOW) { PenSize(1, 1); set_color(fl_color); line_routine(n, px, py, DrawBorder, gkss->cntnr); } else if (fl_inter == GKS_K_INTSTYLE_SOLID) { set_color(fl_color); fill_routine(n, px, py, gkss->cntnr); } else if (fl_inter == GKS_K_INTSTYLE_PATTERN || fl_inter == GKS_K_INTSTYLE_HATCH) { set_color(fl_color); if (fl_inter == GKS_K_INTSTYLE_HATCH) fl_style += HATCH_STYLE; if (fl_style >= PATTERNS) fl_style = 1; p->pat = p->pattern + fl_style; fill_routine(n, px, py, gkss->cntnr); } }
static void text(double px, double py, int nchars, char *chars) { int tx_font, tx_prec, tx_color; double x, y; tx_font = gkss->asf[6] ? gkss->txfont : predef_font[gkss->tindex - 1]; tx_prec = gkss->asf[6] ? gkss->txprec : predef_prec[gkss->tindex - 1]; tx_color = gkss->asf[9] ? gkss->txcoli : 1; PenSize(1, 1); set_color(tx_color); if (tx_prec == GKS_K_TEXT_PRECISION_STRING) { set_font(tx_font); WC_to_NDC(px, py, gkss->cntnr, x, y); seg_xform(&x, &y); text_routine(x, y, nchars, chars); } else gks_emul_text(px, py, nchars, chars, line_routine, fill_routine); }
void TextDiffView::Draw(BRect updateRect) { rgb_color oldHighColor = HighColor(); float oldPenSize = PenSize(); BRect bounds = Bounds(); float leftWidth = floor((bounds.Width() + 1 - B_H_SCROLL_BAR_HEIGHT - PANE_SPLITTER_WIDTH) / 2); if (updateRect.left <= leftWidth + 1) { SetPenSize(0); SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_2_TINT)); StrokeLine(BPoint(leftWidth, updateRect.top), BPoint(leftWidth, updateRect.bottom), B_SOLID_HIGH); SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_1_TINT)); StrokeLine(BPoint(leftWidth + 1, updateRect.top), BPoint(leftWidth + 1, updateRect.bottom), B_SOLID_HIGH); } if (updateRect.right >= leftWidth + PANE_SPLITTER_WIDTH - 2) { SetPenSize(0); SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_1_TINT)); StrokeLine(BPoint(leftWidth + PANE_SPLITTER_WIDTH - 2, updateRect.top), BPoint(leftWidth + PANE_SPLITTER_WIDTH - 2, updateRect.bottom), B_SOLID_HIGH); SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_2_TINT)); StrokeLine(BPoint(leftWidth + PANE_SPLITTER_WIDTH - 1, updateRect.top), BPoint(leftWidth + PANE_SPLITTER_WIDTH - 1, updateRect.bottom), B_SOLID_HIGH); } SetPenSize(oldPenSize); SetHighColor(oldHighColor); }
static int OneButtonBox (char *text, char *button1) { DialogPtr theDialog; short itemHit,itemType; Handle item; Rect box; char buffer[256]; theDialog = GetNewDialog(oneButtonDialog,NULL,(WindowPtr) -1); /* draw OK Button */ GetDialogItem(theDialog,OKButton,&itemType,&item,&box); SetPort((GrafPtr) theDialog); PenSize(3,3); InsetRect(&box,-4,-4); FrameRoundRect(&box,16,16); /* change text of button 1 */ strcpy(buffer,button1); SetControlTitle((ControlHandle) item,c2pstr(buffer)); GetDialogItem(theDialog,2,&itemType,&item,&box); strcpy(buffer,text); SetDialogItemText(item,c2pstr(buffer)); itemHit=0; while (itemHit!=OKButton) { ModalDialog(NULL,&itemHit); } DisposeDialog(theDialog); return(itemHit); }
static void MyDrawUserItem(DialogRef theDialog, DialogItemIndex itemNo) { DialogItemType itemType; Handle itemHandle; Rect itemBox; GetDialogItem(theDialog, itemNo, &itemType, &itemHandle, &itemBox); CGrafPtr savePort; GetPort(&savePort); SetPortDialogPort(theDialog); PenState penState; GetPenState(&penState); PenSize(3, 3); if (itemType & itemDisable) { Pattern gray; PenPat(GetQDGlobalsGray(&gray)); } FrameRect(&itemBox); Rect userRect = {gUserV-4, gUserH-4, gUserV+4, gUserH+4}; PaintRect(&userRect); SetPenState(&penState); SetPort(savePort); }
void _HYPlatformGraphicPane::_DrawOval (_HYRect rectDesc) { PenSize (rectDesc.width, rectDesc.width); Rect r= HYRect2Rect (rectDesc); FrameOval (&r); }
void _HYPlatformGraphicPane::_DrawPolygon (Ptr rgn, long width) { if (rgn) { PenSize (width, width); FramePoly ((PolyHandle)rgn); } }
static void draw_device_area( GDSpecPtr device_spec, GDHandle selected_device, Rect *frame) { Point offset; GDHandle device; get_device_area_offset(frame, &offset); EraseRect(frame); FrameRect(frame); for (device= GetDeviceList(); device; device= GetNextDevice(device)) { if (TestDeviceAttribute(device, screenDevice) && TestDeviceAttribute(device, screenActive)) { GDSpec spec; Rect bounds; BuildExplicitGDSpec(&spec, device, device_spec->flags, device_spec->bit_depth, 0, 0); get_device_area_frame(device, &bounds, offset); RGBForeColor(HasDepthGDSpec(&spec) ? &rgb_dark_gray : &rgb_white); PaintRect(&bounds); RGBForeColor(&rgb_black); if (device==selected_device) PenSize(2, 2); FrameRect(&bounds); PenSize(1, 1); if (device==GetMainDevice()) { bounds.bottom= bounds.top + DEVICE_AREA_MENU_BAR_HEIGHT; EraseRect(&bounds); FrameRect(&bounds); } } } return; }
/****************************************************** DrawCheck() - This subroutine draws a check mark at the chosen item. *****************************************************/ void DrawCheck(RECTPTR r) { PenSize(1, 2); MoveTo(r->left + 2, (r->top + r->bottom)/2); Line(2, 2); Line(6, -6); PenNormal(); }
static bool openPostScript (void) { PenState pen; /* * Flush GrafPort state. */ SetPort ((GrafPtr) theMacPort); /* Some warning message could have drawn ThePort away... */ GetPenState (& pen); PenSize (0, 0); Line (0, 0); PenSize (pen. pnSize.h, pen. pnSize.v); /* * Send direct PostScript commands. */ if (PMSessionPostScriptBegin (theMacPrintSession)) { return Melder_error1 (L"Cannot begin PostScript."); } initPostScriptPage (); return true; }
static pascal void outline_hook(DialogRef dptr, short theItem){ short itemType; Handle itemHdl; Rect itemRect; PenState oldpen; GetDialogItem( dptr, theItem, &itemType, &itemHdl, &itemRect); GetPenState( &oldpen); PenSize( 3, 3); FrameRoundRect( &itemRect, 16, 16); SetPenState( &oldpen); }
void _HYPlatformGraphicPane::_DrawHatchedLine (_HYRect lineDesc) { PenState savePen; GetPenState (&savePen); if (abs(lineDesc.left-lineDesc.right)>5) PenPat (&penHatchPattern); else PenPat (&vertPenHatchPattern); PenSize (lineDesc.width, lineDesc.width); MoveTo (lineDesc.left, lineDesc.top); LineTo (lineDesc.right,lineDesc.bottom); SetPenState (&savePen); }
void TestView::Draw(BRect updateRect) { printf("Draw(BRect(%.1f, %.1f, %.1f, %.1f))\n", updateRect.left, updateRect.top, updateRect.right, updateRect.bottom); printf("pensize: %.2f\n", PenSize()); SetHighColor(0, 0, 255); StrokeLine(Bounds().LeftBottom(), Bounds().RightTop()); SetPenSize(5); }
void setUpPalette(Lcd *x, RGBColor *oldColor, PaletteHandle *oldPalette) { if (hasColorQD) { if (numPaletteColors>2){ GetForeColor(oldColor); *oldPalette = GetPalette(&x->lcd_box.b_patcher->p_wind->w_gp); SetPalette(&x->lcd_box.b_patcher->p_wind->w_gp,x->lcd_palette,FALSE); PmForeColor(x->lcd_pIndex); } } GetPenState(&x->lcd_penState); PenMode(x->lcd_penMode); PenSize(1,1); }
void TestView::DrawAfterChildren(BRect updateRect) { printf("DrawAfterChildren(BRect(%.1f, %.1f, %.1f, %.1f))\n", updateRect.left, updateRect.top, updateRect.right, updateRect.bottom); printf("pensize: %.2f\n", PenSize()); SetHighColor(255, 0, 0); StrokeLine(Bounds().LeftTop(), Bounds().RightBottom()); Sync(); SetPenSize(7); }
static void polymarker(int n, double *px, double *py) { int mk_type, mk_color; double mk_size; mk_type = gkss->asf[3] ? gkss->mtype : gkss->mindex; mk_size = gkss->asf[4] ? gkss->mszsc : 1; mk_color = gkss->asf[5] ? gkss->pmcoli : 1; PenSize(1, 1); set_color(mk_color); marker_routine(n, px, py, mk_type, mk_size, mk_color); }
static void MyUserPaneDrawProc(ControlRef control, SInt16 part) { // we now use a User Pane Control instead of a dialog user item // the draw, hit test, and track are more separated Rect bounds; GetControlBounds(control, &bounds); PenSize(3, 3); if (!IsControlActive(control)) { RGBColor gray = {32767, 32767, 32767}; RGBForeColor(&gray); } FrameRect(&bounds); Rect userRect = {gUserV-4, gUserH-4, gUserV+4, gUserH+4}; PaintRect(&userRect); }
void box_d_item(DialogPtr dp, short item) { Rect r; Handle h; short itemType; GetDItem (dp, item, &itemType, &h, &r); PenNormal (); PenSize (2, 2); InsetRect (&r, -2, -2); FrameRect (&r); PenNormal (); }
void TkMacSetUpGraphicsPort( GC gc) /* GC to apply to current port. */ { RGBColor macColor; if (gPenPat == NULL) { gPenPat = NewPixPat(); } if (TkSetMacColor(gc->foreground, &macColor) == true) { /* TODO: cache RGBPats for preformace - measure gains... */ MakeRGBPat(gPenPat, &macColor); } PenNormal(); if(gc->function == GXxor) { PenMode(patXor); } if (gc->line_width > 1) { PenSize(gc->line_width, gc->line_width); } if (gc->line_style != LineSolid) { unsigned char *p = (unsigned char *) &(gc->dashes); /* * Here the dash pattern should be set in the drawing, * environment, but I don't know how to do that for the Mac. * * p[] is an array of unsigned chars containing the dash list. * A '\0' indicates the end of this list. * * Someone knows how to implement this? If you have a more * complete implementation of SetUpGraphicsPort() for * the Mac (or for Windows), please let me know. * * Jan Nijtmans * CMG Arnhem, B.V. * email: [email protected] (private) * [email protected] (work) * url: http://purl.oclc.org/net/nijtmans/ */ } }
BRect BBox::ContentBounds() const { e_theme_engine *theme = get_current_theme_engine(); float l = 0, t = 0, r = 0, b = 0; if (!(theme == NULL || theme->get_border_margins == NULL)) theme->get_border_margins(theme, this, &l, &t, &r, &b, fBorder, PenSize()); float labelHeight = ((fLabelView == NULL || fLabelView->Frame().Width() <= 0) ? 0.f : fLabelView->Frame().Height()); BRect bounds = Frame().OffsetToSelf(B_ORIGIN); bounds.left += l; bounds.top += max_c(t, labelHeight); bounds.right -= r; bounds.bottom -= b; return bounds; }
void BBox::GetPreferredSize(float *width, float *height) { if (!width && !height) return; float w = 0, h = 0; if (fLabelView) fLabelView->GetPreferredSize(&w, &h); e_theme_engine *theme = get_current_theme_engine(); float l = 0, t = 0, r = 0, b = 0; if (!(theme == NULL || theme->get_border_margins == NULL)) theme->get_border_margins(theme, this, &l, &t, &r, &b, fBorder, PenSize()); w += (l + r) + 2.f; if (h < t) h = t; h += b + 2.f; if (width) *width = w; if (height) *height = h; }
void ArpBox::ComputeIndents(void) { float fw = BasicFont()->StringWidth("W"); font_height fhs; BasicFont()->GetHeight(&fhs); float fh = fhs.ascent+fhs.descent+fhs.leading; float ps = PenSize(); if( ps < 1 ) ps = 1; indent_l = indent_r = floor( (fw/2) + (ps*2) + .5 ); indent_b = floor( (fh/2) + (ps*2) + .5 ); const char* lab = Label(); min_w = 0; if( lab && *lab ) { min_w = BasicFont()->StringWidth(lab) + indent_l + indent_r; indent_t = floor( fh + ps*2 + .5 ); } else { indent_t = floor( (fh/2) + ps*2 + .5 ); } }
static void polyline(int n, double *px, double *py) { int ln_type, ln_color; double ln_width; int width; ln_type = gkss->asf[0] ? gkss->ltype : gkss->lindex; ln_width = gkss->asf[1] ? gkss->lwidth : 1; ln_color = gkss->asf[2] ? gkss->plcoli : 1; if (gkss->version > 4) width = nint(ln_width * p->height / 500.0); else width = nint(ln_width); if (width < 1) width = 1; PenSize(width, width); set_color(ln_color); gks_set_dev_xform(gkss, p->window, p->viewport); gks_emul_polyline(n, px, py, ln_type, gkss->cntnr, move, draw); }
// Will draw in center of view rectangle in the current QD graphics context; // modeled after fps display. // It won't try to clip the ends of the lines. bool Crosshairs_Render(Rect &ViewRect) { if (!_Crosshairs_IsActive) return _Crosshairs_IsActive; // Get the crosshair data CrosshairData &Crosshairs = GetCrosshairData(); // Push previous state PenState OldPen; RGBColor OldBackColor, OldForeColor; GetPenState(&OldPen); GetBackColor(&OldBackColor); GetForeColor(&OldForeColor); // Get ready to draw the crosshairs PenNormal(); // Drawing color RGBForeColor(&Crosshairs.Color); // Get the center location from the view rectangle // Shift it down one, so that even line widths can come out right. short XCen = ((ViewRect.left + ViewRect.right) >> 1) - 1; short YCen = ((ViewRect.top + ViewRect.bottom) >> 1) - 1; // Separate for X and Y; the points are three on top/left and three on top/right: // Line-split position // Octagon vertex (half-way) // Farthest extent short OctaPoints[2][6]; short Len; switch(Crosshairs.Shape) { case CHShape_RealCrosshairs: PenSize(1,Crosshairs.Thickness); // Left MoveTo(XCen-Crosshairs.FromCenter+Crosshairs.Thickness-1,YCen); Line(-Crosshairs.Length,0); // Right MoveTo(XCen+Crosshairs.FromCenter,YCen); Line(Crosshairs.Length,0); PenSize(Crosshairs.Thickness,1); // Top MoveTo(XCen,YCen-Crosshairs.FromCenter+Crosshairs.Thickness-1); Line(0,-Crosshairs.Length); // Bottom MoveTo(XCen,YCen+Crosshairs.FromCenter); Line(0,Crosshairs.Length); break; case CHShape_Circle: // This will really be an octagon, for OpenGL-rendering convenience // Precalculate the line endpoints, for convenience Len = Crosshairs.Length; OctaPoints[0][0] = XCen - Len; OctaPoints[0][5] = XCen + Len; OctaPoints[1][0] = YCen - Len; OctaPoints[1][5] = YCen + Len; Len = Len/2; OctaPoints[0][1] = XCen - Len; OctaPoints[0][4] = XCen + Len; OctaPoints[1][1] = YCen - Len; OctaPoints[1][4] = YCen + Len; Len = MIN(Len,Crosshairs.FromCenter); OctaPoints[0][2] = XCen - Len; OctaPoints[0][3] = XCen + Len; OctaPoints[1][2] = YCen - Len; OctaPoints[1][3] = YCen + Len; // We need to do 12 line segments, so we do them in 2*2*3 fashion for (int ix=0; ix<2; ix++) { int ixi = (ix > 0) ? 5 : 0; int ixid = (ix > 0) ? -1 : 1; for (int iy=0; iy<2; iy++) { int iyi = (iy > 0) ? 5 : 0; int iyid = (iy > 0) ? -1 : 1; // Vertical PenSize(Crosshairs.Thickness,1); MoveTo(OctaPoints[0][ixi],OctaPoints[1][iyi+2*iyid]); LineTo(OctaPoints[0][ixi],OctaPoints[1][iyi+iyid]); // Diagonal PenSize(Crosshairs.Thickness,Crosshairs.Thickness); LineTo(OctaPoints[0][ixi+ixid],OctaPoints[1][iyi]); // Horizontal PenSize(1,Crosshairs.Thickness); LineTo(OctaPoints[0][ixi+2*ixid],OctaPoints[1][iyi]); } } break; } // Pop previous state SetPenState(&OldPen); RGBBackColor(&OldBackColor); RGBForeColor(&OldForeColor); return _Crosshairs_IsActive; }
/* ------------ Local code */ static void add_overhead_thumbnail( FileSpecifier &File) { PicHandle picture; PicHandle preview; RgnHandle clip_region; FontInfo info; short text_x, text_y; short text_length; Str255 temporary; GWorldPtr old_gworld; GDHandle old_device; struct overhead_map_data overhead_data; Rect bounds; AEDesc aeFileSpec; FSSpec *SpecPtr; // Skip all this if there's no nav services to install the preview if(!machine_has_nav_services() || NavLibraryVersion() < kNavServicesVersion_2_0) return; GetGWorld(&old_gworld, &old_device); SetGWorld(world_pixels, (GDHandle) NULL); // Note well. We're using world_pixels to create our thumbnail pict within. // If world_pixels is runing as a postage stamp (low-res + small display space) // Then it is actually smaller than the size we're looking to build a thumbnail // within. But seeing as we're generating pict images and using drawing commands // instead of bit-wise operations. It all works out. /* Create the bounding rectangle */ SetRect(&bounds, 0, 0, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT); /* Start recording.. */ picture= OpenPicture(&bounds); PaintRect(&bounds); overhead_data.scale= OVERHEAD_MAP_MINIMUM_SCALE; overhead_data.origin.x= local_player->location.x; overhead_data.origin.y= local_player->location.y; overhead_data.half_width= RECTANGLE_WIDTH(&bounds)/2; overhead_data.half_height= RECTANGLE_HEIGHT(&bounds)/2; overhead_data.width= RECTANGLE_WIDTH(&bounds); overhead_data.height= RECTANGLE_HEIGHT(&bounds); overhead_data.mode= _rendering_saved_game_preview; _render_overhead_map(&overhead_data); RGBForeColor(&rgb_black); PenSize(1, 1); TextFont(0); TextFace(normal); TextSize(0); ClosePicture(); // JTP: Add Nav Services style preview SetRect(&bounds, 0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT); preview= OpenPicture(&bounds); SetRect(&bounds, PREVIEW_IMAGE_X, PREVIEW_IMAGE_Y, THUMBNAIL_WIDTH + PREVIEW_IMAGE_X, THUMBNAIL_HEIGHT + PREVIEW_IMAGE_Y); clip_region= NewRgn(); GetClip(clip_region); ClipRect(&bounds); DrawPicture(picture, &bounds); SetClip(clip_region); /* Center the text in the rectangle */ // LP: Classic doesn't have this function #ifdef TARGET_API_MAC_CARBON CopyCStringToPascal(static_world->level_name, temporary); #else strncpy((char *)temporary,static_world->level_name,LEVEL_NAME_LENGTH); c2pstr((char *)temporary); #endif // LP: fix to allow lengths more than 127 bytes (not really necessary, but...) text_length = *ptemporary; TruncText(PREVIEW_WIDTH, (char *)temporary+1, &text_length, smTruncEnd); *ptemporary = text_length; GetFontInfo(&info); text_y= PREVIEW_HEIGHT - info.descent; text_x= PREVIEW_LABEL_X + (PREVIEW_WIDTH-StringWidth(temporary))/2; MoveTo(text_x, text_y); DrawString(temporary); ClosePicture(); // This requires NavServices 2.0, what's the inline check? // From FSS get a AEDesc OSStatus err; SpecPtr = &File.GetSpec(); err = AECreateDesc(typeFSS, SpecPtr, sizeof(FSSpec), &aeFileSpec); HLock((Handle)preview); err = NavCreatePreview(&aeFileSpec, 'PICT', *preview, GetHandleSize((Handle)preview)); HUnlock((Handle)preview); AEDisposeDesc(&aeFileSpec); KillPicture(preview); KillPicture(picture); DisposeRgn(clip_region); SetGWorld(old_gworld, old_device); }
static int RasterizeFile (FILE *stream, AWindowRecord *myWindow, short wx, short wy) { char *buffer; /* input buffer */ long blockSize; /* METABUFFERSIZE */ long blockUsed; /* actual buffer size used */ long itemCounter; /* number of commands in buffer */ char *data; /* data pointer in buffer */ short fx,fy; /* file screen size */ Fixed sx,sy; /* scaling factors */ int i,error,j,size; char opCode; short x,y,r,g,b,n,lw,ts,m,ms,w; short x1,y1,x2,y2; short xx[SIZE],yy[SIZE]; PolyHandle myPoly; char s[CSIZE]; unsigned char c; RGBColor newColor; PaletteHandle myPalette; long l; /* get file parameters */ rewind(stream); error = fread(&blockSize,4,1,stream); if (error!=1) return(1); /* block size */ error = fread(&fx,2,1,stream); if (error!=1) return(1); /* x size */ error = fread(&fy,2,1,stream); if (error!=1) return(1); /* y size */ /* compute scaling factors */ sx = FixRatio(wx-1,fx-1); sy = FixRatio(wy-1,fy-1); /* default values */ lw = 1; ts = 12; m = 0; ms = 6; /* allocate input buffer */ buffer = malloc(blockSize); if (buffer==NULL) return(1); SetPort((GrafPtr)(myWindow->theWindow)); EraseRect(&(myWindow->usableRect)); /* loop through the blocks */ while (!feof(stream)) { /* read block parameters */ error = fread(&blockUsed,4,1,stream); if (error!=1) {free(buffer); return(1);} error = fread(&itemCounter,4,1,stream); if (error!=1) {free(buffer); return(1);} error = fread(buffer,blockUsed,1,stream);if (error!=1) {free(buffer); return(1);} /* init pointer to next item */ data = buffer; /* for all items */ for (i=0; i<itemCounter; i++) { /* get op code */ opCode = *(data++); switch (opCode) { case opMove : x = *((short *)data); data += 2; y = *((short *)data); data += 2; TRFMX(x); TRFMY(y); MoveTo(x,y); break; case opDraw : x = *((short *)data); data += 2; y = *((short *)data); data += 2; TRFMX(x); TRFMY(y); LineTo(x,y); break; case opPolyline : n = *((short *)data); data += 2; if (n>=SIZE) {free(buffer); return(2);} size = n<<1; memcpy(xx,data,size); data += size; memcpy(yy,data,size); data += size; for (j=0; j<n; j++) { TRFMX(xx[j]); TRFMY(yy[j]); } MoveTo(xx[0],yy[0]); for (j=1; j<n; j++) LineTo(xx[j],yy[j]); break; case opPolygon : n = *((short *)data); data += 2; if (n>=SIZE) {free(buffer); return(2);} size = n<<1; memcpy(xx,data,size); data += size; memcpy(yy,data,size); data += size; for (j=0; j<n; j++) { TRFMX(xx[j]); TRFMY(yy[j]); } if (n<3) break; myPoly = OpenPoly(); MoveTo(xx[0],yy[0]); for (j=1; j<n; j++) LineTo(xx[j],yy[j]); LineTo(xx[0],yy[0]); ClosePoly(); PaintPoly(myPoly); FramePoly(myPoly); KillPoly(myPoly); break; case opPolymark : n = *((short *)data); data += 2; if (n>=SIZE) {free(buffer); return(2);} size = n<<1; memcpy(xx,data,size); data += size; memcpy(yy,data,size); data += size; for (j=0; j<n; j++) { TRFMX(xx[j]); TRFMY(yy[j]); } for (j=0; j<n; j++) Marker(m,ms,xx[j],yy[j]); break; case opText : n = *((short *)data); data += 2; if (n>=CSIZE-1) {free(buffer); return(2);} memcpy(s,data,n); s[n] = 0; data += n; DrawString((ConstStr255Param)c2pstr(s)); break; case opCenteredText : x = *((short *)data); data += 2; y = *((short *)data); data += 2; TRFMX(x); TRFMY(y); n = *((short *)data); data += 2; if (n>=CSIZE-1) {free(buffer); return(2);} memcpy(s,data,n); s[n] = 0; data += n; c2pstr(s); w = StringWidth((ConstStr255Param)s); MoveTo(x-w/2,y+ts/2); DrawString((ConstStr255Param)s); break; case opSetLineWidth : n = *((short *)data); data += 2; lw = n; PenSize(n,n); break; case opSetTextSize : n = *((short *)data); data += 2; ts = n; TextSize(n); break; case opSetMarker : n = *((short *)data); data += 2; m = n; break; case opSetMarkerSize : n = *((short *)data); data += 2; ms = n; break; case opSetColor : c = *((unsigned char *)data); data++; PmForeColor((short)c); break; case opSetEntry : c = *((unsigned char *)data); data++; r = (short) (*((unsigned char *)data)); data++; g = (short) (*((unsigned char *)data)); data++; b = (short) (*((unsigned char *)data)); data++; myPalette = GetPalette(myWindow->theWindow); myWindow->red[c] = newColor.red = r<<8; myWindow->green[c] = newColor.green = g<<8; myWindow->blue[c] = newColor.blue = b<<8; SetEntryColor(myPalette,(short) c,&newColor); ActivatePalette(myWindow->theWindow); break; case opSetPalette : x = (short) (*((unsigned char *)data)); data++; y = (short) (*((unsigned char *)data)); data++; myPalette = GetPalette(myWindow->theWindow); for (j=x; j<=y; j++) { r = (short) (*((unsigned char *)data)); data++; g = (short) (*((unsigned char *)data)); data++; b = (short) (*((unsigned char *)data)); data++; myWindow->red[j] = newColor.red = r<<8; myWindow->green[j] = newColor.green = g<<8; myWindow->blue[j] = newColor.blue = b<<8; SetEntryColor(myPalette,(short) j,&newColor); } ActivatePalette(myWindow->theWindow); break; case opNewLine : lw = *((unsigned char *)data); data++; c = *((unsigned char *)data); data++; x1 = *((short *)data); data += 2; y1 = *((short *)data); data += 2; x2 = *((short *)data); data += 2; y2 = *((short *)data); data += 2; TRFMX(x1); TRFMY(y1); TRFMX(x2); TRFMY(y2); PenSize(lw,lw); PmForeColor((short)c); MoveTo(x1,y1); LineTo(x2,y2); break; case opNewPolyline : lw = *((unsigned char *)data); data++; c = *((unsigned char *)data); data++; n = *((short *)data); data += 2; if (n>=SIZE) {free(buffer); return(2);} size = n<<1; memcpy(xx,data,size); data += size; memcpy(yy,data,size); data += size; for (j=0; j<n; j++) { TRFMX(xx[j]); TRFMY(yy[j]); } PenSize(lw,lw); PmForeColor((short)c); MoveTo(xx[0],yy[0]); for (j=1; j<n; j++) LineTo(xx[j],yy[j]); break; case opNewPolygon : c = *((unsigned char *)data); data++; n = *((short *)data); data += 2; if (n>=SIZE) {free(buffer); return(2);} size = n<<1; memcpy(xx,data,size); data += size; memcpy(yy,data,size); data += size; for (j=0; j<n; j++) { TRFMX(xx[j]); TRFMY(yy[j]); } if (n<3) break; PmForeColor((short)c); myPoly = OpenPoly(); MoveTo(xx[0],yy[0]); for (j=1; j<n; j++) LineTo(xx[j],yy[j]); LineTo(xx[0],yy[0]); ClosePoly(); PaintPoly(myPoly); FramePoly(myPoly); KillPoly(myPoly); break; case opNewPolymark : m = *((unsigned char *)data); data++; ms = *((unsigned char *)data); data++; c = *((unsigned char *)data); data++; n = *((short *)data); data += 2; if (n>=SIZE) {free(buffer); return(2);} size = n<<1; memcpy(xx,data,size); data += size; memcpy(yy,data,size); data += size; for (j=0; j<n; j++) { TRFMX(xx[j]); TRFMY(yy[j]); } PmForeColor((short)c); for (j=0; j<n; j++) Marker(m,ms,xx[j],yy[j]); break; case opNewText : ts = *((unsigned char *)data); data++; c = *((unsigned char *)data); data++; x = *((short *)data); data += 2; y = *((short *)data); data += 2; TRFMX(x); TRFMY(y); n = *((short *)data); data += 2; if (n>=CSIZE-1) {free(buffer); return(2);} memcpy(s,data,n); s[n] = 0; data += n; MoveTo(x,y); TextSize(ts); PmForeColor((short)c); DrawString((ConstStr255Param)c2pstr(s)); break; case opNewCenteredText : ts = *((unsigned char *)data); data++; c = *((unsigned char *)data); data++; x = *((short *)data); data += 2; y = *((short *)data); data += 2; TRFMX(x); TRFMY(y); n = *((short *)data); data += 2; if (n>=CSIZE-1) {free(buffer); return(2);} memcpy(s,data,n); s[n] = 0; data += n; c2pstr(s); w = StringWidth((ConstStr255Param)s); TextSize(ts); PmForeColor((short)c); MoveTo(x-w/2,y+ts/2); DrawString((ConstStr255Param)c2pstr(s)); break; default : break; } } } return(0); }
void RemoteView::_DrawThread() { RemoteMessage reply(NULL, fSendBuffer); RemoteMessage message(fReceiveBuffer, NULL); // cursor BPoint cursorHotSpot(0, 0); while (!fStopThread) { uint16 code; status_t status = message.NextMessage(code); if (status != B_OK) { TRACE_ERROR("failed to read message from receiver\n"); break; } TRACE("code %u with %ld bytes data\n", code, message.DataLeft()); BAutolock locker(this->Looper()); if (!locker.IsLocked()) break; // handle stuff that doesn't go to a specicifc engine switch (code) { case RP_INIT_CONNECTION: { uint16 port; status_t result = message.Read(port); if (result != B_OK) { TRACE_ERROR("failed to read remote port\n"); continue; } BNetEndpoint *endpoint = fReceiver->Endpoint(); if (endpoint == NULL) { TRACE_ERROR("receiver not connected anymore\n"); continue; } in_addr remoteHost; char hostName[MAXHOSTNAMELEN + 1]; BNetAddress address(endpoint->RemoteAddr()); address.GetAddr(remoteHost); address.GetAddr(hostName, NULL); address.SetTo(remoteHost, port); TRACE("connecting to host \"%s\" port %u\n", hostName, port); result = fSendEndpoint->Connect(address); if (result != B_OK) { TRACE_ERROR("failed to connect to host \"%s\" port %u\n", hostName, port); continue; } BRect bounds = fOffscreenBitmap->Bounds(); reply.Start(RP_UPDATE_DISPLAY_MODE); reply.Add(bounds.IntegerWidth() + 1); reply.Add(bounds.IntegerHeight() + 1); if (reply.Flush() == B_OK) fIsConnected = true; continue; } case RP_CLOSE_CONNECTION: { be_app->PostMessage(B_QUIT_REQUESTED); continue; } case RP_CREATE_STATE: case RP_DELETE_STATE: { uint32 token; message.Read(token); if (code == RP_CREATE_STATE) _CreateState(token); else _DeleteState(token); continue; } case RP_SET_CURSOR: { BBitmap *bitmap; BPoint oldHotSpot = cursorHotSpot; message.Read(cursorHotSpot); if (message.ReadBitmap(&bitmap) != B_OK) continue; delete fCursorBitmap; fCursorBitmap = bitmap; Invalidate(fCursorFrame); BRect bounds = fCursorBitmap->Bounds(); fCursorFrame.right = fCursorFrame.left + bounds.IntegerWidth() + 1; fCursorFrame.bottom = fCursorFrame.bottom + bounds.IntegerHeight() + 1; fCursorFrame.OffsetBy(oldHotSpot - cursorHotSpot); Invalidate(fCursorFrame); continue; } case RP_SET_CURSOR_VISIBLE: { bool wasVisible = fCursorVisible; message.Read(fCursorVisible); if (wasVisible != fCursorVisible) Invalidate(fCursorFrame); continue; } case RP_MOVE_CURSOR_TO: { BPoint position; message.Read(position); if (fCursorVisible) Invalidate(fCursorFrame); fCursorFrame.OffsetTo(position - cursorHotSpot); Invalidate(fCursorFrame); continue; } case RP_INVALIDATE_RECT: { BRect rect; if (message.Read(rect) != B_OK) continue; Invalidate(rect); continue; } case RP_INVALIDATE_REGION: { BRegion region; if (message.ReadRegion(region) != B_OK) continue; Invalidate(®ion); continue; } case RP_FILL_REGION_COLOR_NO_CLIPPING: { BRegion region; rgb_color color; message.ReadRegion(region); if (message.Read(color) != B_OK) continue; fOffscreen->LockLooper(); fOffscreen->SetHighColor(color); fOffscreen->FillRegion(®ion); fOffscreen->UnlockLooper(); Invalidate(®ion); continue; } case RP_COPY_RECT_NO_CLIPPING: { int32 xOffset, yOffset; BRect rect; message.Read(xOffset); message.Read(yOffset); if (message.Read(rect) != B_OK) continue; BRect dest = rect.OffsetByCopy(xOffset, yOffset); fOffscreen->LockLooper(); fOffscreen->CopyBits(rect, dest); fOffscreen->UnlockLooper(); continue; } } uint32 token; message.Read(token); engine_state *state = _FindState(token); if (state == NULL) { TRACE_ERROR("didn't find state for token %lu\n", token); continue; } BView *offscreen = state->view; ::pattern &pattern = state->pattern; BRegion &clippingRegion = state->clipping_region; float &penSize = state->pen_size; bool &syncDrawing = state->sync_drawing; BRegion invalidRegion; BAutolock offscreenLocker(offscreen->Looper()); if (!offscreenLocker.IsLocked()) break; switch (code) { case RP_ENABLE_SYNC_DRAWING: syncDrawing = true; continue; case RP_DISABLE_SYNC_DRAWING: syncDrawing = false; continue; case RP_SET_OFFSETS: { int32 xOffset, yOffset; message.Read(xOffset); if (message.Read(yOffset) != B_OK) continue; offscreen->MovePenTo(xOffset, yOffset); break; } case RP_SET_HIGH_COLOR: case RP_SET_LOW_COLOR: { rgb_color color; if (message.Read(color) != B_OK) continue; if (code == RP_SET_HIGH_COLOR) offscreen->SetHighColor(color); else offscreen->SetLowColor(color); break; } case RP_SET_PEN_SIZE: { float newPenSize; if (message.Read(newPenSize) != B_OK) continue; offscreen->SetPenSize(newPenSize); penSize = newPenSize / 2; break; } case RP_SET_STROKE_MODE: { cap_mode capMode; join_mode joinMode; float miterLimit; message.Read(capMode); message.Read(joinMode); if (message.Read(miterLimit) != B_OK) continue; offscreen->SetLineMode(capMode, joinMode, miterLimit); break; } case RP_SET_BLENDING_MODE: { source_alpha sourceAlpha; alpha_function alphaFunction; message.Read(sourceAlpha); if (message.Read(alphaFunction) != B_OK) continue; offscreen->SetBlendingMode(sourceAlpha, alphaFunction); break; } case RP_SET_PATTERN: { if (message.Read(pattern) != B_OK) continue; break; } case RP_SET_DRAWING_MODE: { drawing_mode drawingMode; if (message.Read(drawingMode) != B_OK) continue; offscreen->SetDrawingMode(drawingMode); break; } case RP_SET_FONT: { BFont font; if (message.ReadFontState(font) != B_OK) continue; offscreen->SetFont(&font); break; } case RP_CONSTRAIN_CLIPPING_REGION: { if (message.ReadRegion(clippingRegion) != B_OK) continue; offscreen->ConstrainClippingRegion(&clippingRegion); break; } case RP_INVERT_RECT: { BRect rect; if (message.Read(rect) != B_OK) continue; offscreen->InvertRect(rect); invalidRegion.Include(rect); break; } case RP_DRAW_BITMAP: { BBitmap *bitmap; BRect bitmapRect, viewRect; uint32 options; message.Read(bitmapRect); message.Read(viewRect); message.Read(options); if (message.ReadBitmap(&bitmap) != B_OK || bitmap == NULL) continue; offscreen->DrawBitmap(bitmap, bitmapRect, viewRect, options); invalidRegion.Include(viewRect); delete bitmap; break; } case RP_DRAW_BITMAP_RECTS: { color_space colorSpace; int32 rectCount; uint32 flags, options; message.Read(options); message.Read(colorSpace); message.Read(flags); message.Read(rectCount); for (int32 i = 0; i < rectCount; i++) { BBitmap *bitmap; BRect viewRect; message.Read(viewRect); if (message.ReadBitmap(&bitmap, true, colorSpace, flags) != B_OK || bitmap == NULL) { continue; } offscreen->DrawBitmap(bitmap, bitmap->Bounds(), viewRect, options); invalidRegion.Include(viewRect); delete bitmap; } break; } case RP_STROKE_ARC: case RP_FILL_ARC: case RP_FILL_ARC_GRADIENT: { BRect rect; float angle, span; message.Read(rect); message.Read(angle); if (message.Read(span) != B_OK) continue; if (code == RP_STROKE_ARC) { offscreen->StrokeArc(rect, angle, span, pattern); rect.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_ARC) offscreen->FillArc(rect, angle, span, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillArc(rect, angle, span, *gradient); delete gradient; } invalidRegion.Include(rect); break; } case RP_STROKE_BEZIER: case RP_FILL_BEZIER: case RP_FILL_BEZIER_GRADIENT: { BPoint points[4]; if (message.ReadList(points, 4) != B_OK) continue; BRect bounds = _BuildInvalidateRect(points, 4); if (code == RP_STROKE_BEZIER) { offscreen->StrokeBezier(points, pattern); bounds.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_BEZIER) offscreen->FillBezier(points, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillBezier(points, *gradient); delete gradient; } invalidRegion.Include(bounds); break; } case RP_STROKE_ELLIPSE: case RP_FILL_ELLIPSE: case RP_FILL_ELLIPSE_GRADIENT: { BRect rect; if (message.Read(rect) != B_OK) continue; if (code == RP_STROKE_ELLIPSE) { offscreen->StrokeEllipse(rect, pattern); rect.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_ELLIPSE) offscreen->FillEllipse(rect, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillEllipse(rect, *gradient); delete gradient; } invalidRegion.Include(rect); break; } case RP_STROKE_POLYGON: case RP_FILL_POLYGON: case RP_FILL_POLYGON_GRADIENT: { BRect bounds; bool closed; int32 numPoints; message.Read(bounds); message.Read(closed); if (message.Read(numPoints) != B_OK) continue; BPoint points[numPoints]; for (int32 i = 0; i < numPoints; i++) message.Read(points[i]); if (code == RP_STROKE_POLYGON) { offscreen->StrokePolygon(points, numPoints, bounds, closed, pattern); bounds.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_POLYGON) offscreen->FillPolygon(points, numPoints, bounds, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillPolygon(points, numPoints, bounds, *gradient); delete gradient; } invalidRegion.Include(bounds); break; } case RP_STROKE_RECT: case RP_FILL_RECT: case RP_FILL_RECT_GRADIENT: { BRect rect; if (message.Read(rect) != B_OK) continue; if (code == RP_STROKE_RECT) { offscreen->StrokeRect(rect, pattern); rect.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_RECT) offscreen->FillRect(rect, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillRect(rect, *gradient); delete gradient; } invalidRegion.Include(rect); break; } case RP_STROKE_ROUND_RECT: case RP_FILL_ROUND_RECT: case RP_FILL_ROUND_RECT_GRADIENT: { BRect rect; float xRadius, yRadius; message.Read(rect); message.Read(xRadius); if (message.Read(yRadius) != B_OK) continue; if (code == RP_STROKE_ROUND_RECT) { offscreen->StrokeRoundRect(rect, xRadius, yRadius, pattern); rect.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_ROUND_RECT) offscreen->FillRoundRect(rect, xRadius, yRadius, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillRoundRect(rect, xRadius, yRadius, *gradient); delete gradient; } invalidRegion.Include(rect); break; } case RP_STROKE_SHAPE: case RP_FILL_SHAPE: case RP_FILL_SHAPE_GRADIENT: { BRect bounds; int32 opCount, pointCount; message.Read(bounds); if (message.Read(opCount) != B_OK) continue; BMessage archive; for (int32 i = 0; i < opCount; i++) { int32 op; message.Read(op); archive.AddInt32("ops", op); } if (message.Read(pointCount) != B_OK) continue; for (int32 i = 0; i < pointCount; i++) { BPoint point; message.Read(point); archive.AddPoint("pts", point); } BPoint offset; message.Read(offset); float scale; if (message.Read(scale) != B_OK) continue; offscreen->PushState(); offscreen->MovePenTo(offset); offscreen->SetScale(scale); BShape shape(&archive); if (code == RP_STROKE_SHAPE) { offscreen->StrokeShape(&shape, pattern); bounds.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_SHAPE) offscreen->FillShape(&shape, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) { offscreen->PopState(); continue; } offscreen->FillShape(&shape, *gradient); delete gradient; } offscreen->PopState(); invalidRegion.Include(bounds); break; } case RP_STROKE_TRIANGLE: case RP_FILL_TRIANGLE: case RP_FILL_TRIANGLE_GRADIENT: { BRect bounds; BPoint points[3]; message.ReadList(points, 3); if (message.Read(bounds) != B_OK) continue; if (code == RP_STROKE_TRIANGLE) { offscreen->StrokeTriangle(points[0], points[1], points[2], bounds, pattern); bounds.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_TRIANGLE) { offscreen->FillTriangle(points[0], points[1], points[2], bounds, pattern); } else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillTriangle(points[0], points[1], points[2], bounds, *gradient); delete gradient; } invalidRegion.Include(bounds); break; } case RP_STROKE_LINE: { BPoint points[2]; if (message.ReadList(points, 2) != B_OK) continue; offscreen->StrokeLine(points[0], points[1], pattern); BRect bounds = _BuildInvalidateRect(points, 2); invalidRegion.Include(bounds.InsetBySelf(-penSize, -penSize)); break; } case RP_STROKE_LINE_ARRAY: { int32 numLines; if (message.Read(numLines) != B_OK) continue; BRect bounds; offscreen->BeginLineArray(numLines); for (int32 i = 0; i < numLines; i++) { rgb_color color; BPoint start, end; message.ReadArrayLine(start, end, color); offscreen->AddLine(start, end, color); bounds.left = min_c(bounds.left, min_c(start.x, end.x)); bounds.top = min_c(bounds.top, min_c(start.y, end.y)); bounds.right = max_c(bounds.right, max_c(start.x, end.x)); bounds.bottom = max_c(bounds.bottom, max_c(start.y, end.y)); } offscreen->EndLineArray(); invalidRegion.Include(bounds); break; } case RP_FILL_REGION: case RP_FILL_REGION_GRADIENT: { BRegion region; if (message.ReadRegion(region) != B_OK) continue; if (code == RP_FILL_REGION) offscreen->FillRegion(®ion, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillRegion(®ion, *gradient); delete gradient; } invalidRegion.Include(®ion); break; } case RP_STROKE_POINT_COLOR: { BPoint point; rgb_color color; message.Read(point); if (message.Read(color) != B_OK) continue; rgb_color oldColor = offscreen->HighColor(); offscreen->SetHighColor(color); offscreen->StrokeLine(point, point); offscreen->SetHighColor(oldColor); invalidRegion.Include( BRect(point, point).InsetBySelf(-penSize, -penSize)); break; } case RP_STROKE_LINE_1PX_COLOR: { BPoint points[2]; rgb_color color; message.ReadList(points, 2); if (message.Read(color) != B_OK) continue; float oldSize = offscreen->PenSize(); rgb_color oldColor = offscreen->HighColor(); drawing_mode oldMode = offscreen->DrawingMode(); offscreen->SetPenSize(1); offscreen->SetHighColor(color); offscreen->SetDrawingMode(B_OP_OVER); offscreen->StrokeLine(points[0], points[1]); offscreen->SetDrawingMode(oldMode); offscreen->SetHighColor(oldColor); offscreen->SetPenSize(oldSize); invalidRegion.Include(_BuildInvalidateRect(points, 2)); break; } case RP_STROKE_RECT_1PX_COLOR: case RP_FILL_RECT_COLOR: { BRect rect; rgb_color color; message.Read(rect); if (message.Read(color) != B_OK) continue; rgb_color oldColor = offscreen->HighColor(); offscreen->SetHighColor(color); if (code == RP_STROKE_RECT_1PX_COLOR) { float oldSize = PenSize(); offscreen->SetPenSize(1); offscreen->StrokeRect(rect); offscreen->SetPenSize(oldSize); } else offscreen->FillRect(rect); offscreen->SetHighColor(oldColor); invalidRegion.Include(rect); break; } case RP_DRAW_STRING: { BPoint point; size_t length; char *string; bool hasDelta; message.Read(point); message.ReadString(&string, length); if (message.Read(hasDelta) != B_OK) { free(string); continue; } if (hasDelta) { escapement_delta delta[length]; message.ReadList(delta, length); offscreen->DrawString(string, point, delta); } else offscreen->DrawString(string, point); free(string); reply.Start(RP_DRAW_STRING_RESULT); reply.Add(token); reply.Add(offscreen->PenLocation()); reply.Flush(); font_height height; offscreen->GetFontHeight(&height); BRect bounds(point, offscreen->PenLocation()); bounds.top -= height.ascent; bounds.bottom += height.descent; invalidRegion.Include(bounds); break; } case RP_DRAW_STRING_WITH_OFFSETS: { size_t length; char *string; message.ReadString(&string, length); int32 count = UTF8CountChars(string, length); BPoint offsets[count]; if (message.ReadList(offsets, count) != B_OK) { free(string); continue; } offscreen->DrawString(string, offsets, count); free(string); reply.Start(RP_DRAW_STRING_RESULT); reply.Add(token); reply.Add(offscreen->PenLocation()); reply.Flush(); BFont font; offscreen->GetFont(&font); BRect boxes[count]; font.GetBoundingBoxesAsGlyphs(string, count, B_SCREEN_METRIC, boxes); font_height height; offscreen->GetFontHeight(&height); for (int32 i = 0; i < count; i++) { // TODO: validate boxes[i].OffsetBy(offsets[i] + BPoint(0, -height.ascent)); invalidRegion.Include(boxes[i]); } break; } case RP_READ_BITMAP: { BRect bounds; bool drawCursor; message.Read(bounds); if (message.Read(drawCursor) != B_OK) continue; // TODO: support the drawCursor flag BBitmap bitmap(bounds, B_BITMAP_NO_SERVER_LINK, B_RGB32); bitmap.ImportBits(fOffscreenBitmap, bounds.LeftTop(), BPoint(0, 0), bounds.IntegerWidth() + 1, bounds.IntegerHeight() + 1); reply.Start(RP_READ_BITMAP_RESULT); reply.Add(token); reply.AddBitmap(&bitmap); reply.Flush(); break; } default: TRACE_ERROR("unknown protocol code: %u\n", code); break; } if (syncDrawing) { offscreen->Sync(); Invalidate(&invalidRegion); } } }