Beispiel #1
0
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);
	
}
Beispiel #4
0
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);
    }
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);
}
Beispiel #7
0
Datei: ugView.c Projekt: rolk/ug
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);
}
Beispiel #8
0
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);
	}	
}
Beispiel #11
0
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;
}
Beispiel #12
0
/******************************************************
 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();
}
Beispiel #13
0
	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);
}
Beispiel #16
0
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);
}
Beispiel #17
0
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);
}
Beispiel #18
0
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);
}
Beispiel #19
0
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);
}
Beispiel #20
0
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);
}
Beispiel #21
0
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 ();

}
Beispiel #22
0
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/
	 */
    }
}
Beispiel #23
0
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;
}
Beispiel #24
0
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;
}
Beispiel #25
0
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 );
	}
}
Beispiel #26
0
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);
}
Beispiel #29
0
Datei: ugView.c Projekt: rolk/ug
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(&region);
				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(&region);
				fOffscreen->UnlockLooper();
				Invalidate(&region);
				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(&region, pattern);
				else {
					BGradient *gradient;
					if (message.ReadGradient(&gradient) != B_OK)
						continue;

					offscreen->FillRegion(&region, *gradient);
					delete gradient;
				}

				invalidRegion.Include(&region);
				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);
		}
	}
}