/* internal version of ExtTextOut, passed flags for text data type*/ static BOOL MwExtTextOut(HDC hdc, int x, int y, UINT fuOptions, CONST RECT *lprc, LPCVOID lpszString, UINT cbCount, CONST INT *lpDx, int flags) { HWND hwnd; POINT pt; RECT rc; hwnd = MwPrepareDC(hdc); if(!hwnd) return FALSE; pt.x = x; pt.y = y; if(MwIsClientDC(hdc)) ClientToScreen(hwnd, &pt); /* optionally fill passed rectangle*/ if(lprc && (fuOptions&ETO_OPAQUE)) { rc = *lprc; if(MwIsClientDC(hdc)) MapWindowPoints(hwnd, NULL, (LPPOINT)&rc, 2); /* fill rectangle with current background color*/ GdSetForegroundColor(hdc->psd, hdc->bkcolor); GdFillRect(hdc->psd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); GdSetUseBackground(FALSE); } else { /* use current background mode for text background draw*/ GdSetUseBackground(hdc->bkmode == OPAQUE? TRUE: FALSE); /* always set background color in case GdArea is * used to draw, which compares gr_foreground != gr_background * if gr_usebg is false... */ /*if(hdc->bkmode == OPAQUE)*/ GdSetBackgroundColor(hdc->psd, hdc->bkcolor); } if (cbCount == 0) { /* Special case - no text. Used to fill rectangle. */ return TRUE; } /* nyi: lpDx*/ /* draw text in current text foreground and background color*/ GdSetForegroundColor(hdc->psd, hdc->textcolor); //GdSetFont(hdc->font->pfont); /* this whole text alignment thing needs rewriting*/ if((hdc->textalign & TA_BASELINE) == TA_BASELINE) { /* this is not right... changed for kaffe port flags |= MWTF_TOP; */ flags |= MWTF_BASELINE; } else if(hdc->textalign & TA_BOTTOM) { MWCOORD ph, pw, pb; if(lprc) pt.y += lprc->bottom - lprc->top; else { GdGetTextSize(hdc->font->pfont, lpszString, cbCount, &pw, &ph, &pb, flags); pt.y += ph; } flags |= MWTF_BOTTOM; } else flags |= MWTF_TOP; if((hdc->textalign & TA_CENTER) == TA_CENTER) { MWCOORD ph, pw, pb; GdGetTextSize(hdc->font->pfont, lpszString, cbCount, &pw, &ph, &pb, flags); pt.x -= pw/2; } else if(hdc->textalign & TA_RIGHT) { MWCOORD ph, pw, pb; GdGetTextSize(hdc->font->pfont, lpszString, cbCount, &pw, &ph, &pb, flags); pt.x -= pw; } GdText(hdc->psd, hdc->font->pfont, pt.x, pt.y, lpszString, cbCount, flags); return TRUE; }
/* * Prepare to do drawing in a window or pixmap using the specified * graphics context. Returns the drawable pointer if successful, * and the type of drawing id that was supplied. Returns the special value * GR_DRAW_TYPE_NONE if an error is generated, or if drawing is useless. */ GR_DRAW_TYPE GsPrepareDrawing(GR_DRAW_ID id, GR_GC_ID gcid, GR_DRAWABLE **retdp) { GR_WINDOW *wp; /* found window */ GR_PIXMAP *pp; /* found pixmap */ GR_GC *gcp; /* found graphics context */ GR_REGION *regionp; /* user clipping region */ MWCLIPREGION*reg; *retdp = NULL; gcp = GsFindGC(gcid); if (gcp == NULL) return GR_DRAW_TYPE_NONE; /* * If the graphics context is not the current one, then * make it the current one and remember to update it. */ if (gcp != curgcp) { curgcp = gcp; gcp->changed = GR_TRUE; } /* * Look for window or pixmap id */ pp = NULL; wp = GsFindWindow(id); if (wp == NULL) { pp = GsFindPixmap(id); if (pp == NULL) return GR_DRAW_TYPE_NONE; havepixmap: #if DYNAMICREGIONS reg = GdAllocRectRegion(0, 0, pp->psd->xvirtres, pp->psd->yvirtres); /* intersect with user region if any*/ if (gcp->regionid) { regionp = GsFindRegion(gcp->regionid); if (regionp) { /* handle pixmap offsets*/ if (gcp->xoff || gcp->yoff) { MWCLIPREGION *local = GdAllocRegion(); GdCopyRegion(local, regionp->rgn); GdOffsetRegion(local, gcp->xoff, gcp->yoff); GdIntersectRegion(reg, reg, local); GdDestroyRegion(local); } else GdIntersectRegion(reg, reg, regionp->rgn); } } GdSetClipRegion(pp->psd, reg); #else { MWCLIPRECT cliprect; /* FIXME: setup pixmap clipping, different from windows*/ cliprect.x = 0; cliprect.y = 0; cliprect.width = pp->psd->xvirtres; cliprect.height = pp->psd->yvirtres; GdSetClipRects(pp->psd, 1, &cliprect); } #endif /* reset clip cache for next window draw*/ clipwp = NULL; } else { if (!wp->output) { GsError(GR_ERROR_INPUT_ONLY_WINDOW, id); return GR_DRAW_TYPE_NONE; } /* check if buffered window*/ if (wp->props & GR_WM_PROPS_BUFFERED) { pp = wp->buffer; wp = NULL; goto havepixmap; /* draw into pixmap buffer*/ } if (!wp->realized) return GR_DRAW_TYPE_NONE; /* * If the window is not the currently clipped one, * then make it the current one and define its clip rectangles. */ if (wp != clipwp || gcp->changed) { #if DYNAMICREGIONS /* find user region for intersect*/ regionp = gcp->regionid? GsFindRegion(gcp->regionid): NULL; /* Special handling if user region is not at offset 0,0*/ if (regionp && (gcp->xoff || gcp->yoff)) { MWCLIPREGION *local = GdAllocRegion(); GdCopyRegion(local, regionp->rgn); GdOffsetRegion(local, gcp->xoff, gcp->yoff); GsSetClipWindow(wp, local, gcp->mode & ~GR_MODE_DRAWMASK); GdDestroyRegion(local); } else GsSetClipWindow(wp, regionp? regionp->rgn: NULL, gcp->mode & ~GR_MODE_DRAWMASK); #else GsSetClipWindow(wp, NULL, gcp->mode & ~GR_MODE_DRAWMASK); #endif /* DYNAMICREGIONS*/ } } /* * If the graphics context has been changed, then tell the * device driver about it. */ if (gcp->changed) { PSD psd = (wp ? wp->psd : pp->psd); uint32_t mask; int count; if (gcp->linestyle == GR_LINE_SOLID) { mask = 0; count = 0; } else { mask = gcp->dashmask; count = gcp->dashcount; } if (gcp->fgispixelval) GdSetForegroundPixelVal(psd, gcp->foreground); else GdSetForegroundColor(psd, gcp->foreground); if (gcp->bgispixelval) GdSetBackgroundPixelVal(psd, gcp->background); else GdSetBackgroundColor(psd, gcp->background); GdSetMode(gcp->mode & GR_MODE_DRAWMASK); GdSetUseBackground(gcp->usebackground); #if MW_FEATURE_SHAPES GdSetDash(&mask, &count); GdSetFillMode(gcp->fillmode); GdSetTSOffset(gcp->ts_offset.x, gcp->ts_offset.y); switch(gcp->fillmode) { case GR_FILL_STIPPLE: case GR_FILL_OPAQUE_STIPPLE: GdSetStippleBitmap(gcp->stipple.bitmap, gcp->stipple.width, gcp->stipple.height); break; case GR_FILL_TILE: GdSetTilePixmap(gcp->tile.psd, gcp->tile.width, gcp->tile.height); break; } #endif gcp->changed = GR_FALSE; } *retdp = wp? (GR_DRAWABLE *)wp: (GR_DRAWABLE *)pp; return wp? GR_DRAW_TYPE_WINDOW: GR_DRAW_TYPE_PIXMAP; }
/** * Open low level graphics driver. * * @return The screen drawing surface. */ PSD GdOpenScreen(void) { PSD psd; MWPALENTRY * stdpal; psd = scrdev.Open(&scrdev); if (!psd) return NULL; /* assume no user changable palette entries*/ gr_firstuserpalentry = (int)psd->ncolors; /* set palette according to system colors and devpalX.c*/ switch((int)psd->ncolors) { #if !defined(NOSTDPAL1) /* don't require stdpal1 if not needed */ case 2: /* 1bpp*/ { extern MWPALENTRY mwstdpal1[2]; stdpal = mwstdpal1; } break; #endif #if !defined(NOSTDPAL2) /* don't require stdpal2 if not needed */ case 4: /* 2bpp*/ { extern MWPALENTRY mwstdpal2[4]; stdpal = mwstdpal2; } break; #endif #if !defined(NOSTDPAL4) /* don't require stdpal4 if not needed */ case 8: /* 3bpp - not fully supported*/ case 16: /* 4bpp*/ { extern MWPALENTRY mwstdpal4[16]; stdpal = mwstdpal4; } break; #endif #if !defined(NOSTDPAL8) /* don't require large stdpal8 if not needed */ case 256: /* 8bpp*/ { extern MWPALENTRY mwstdpal8[256]; #if UNIFORMPALETTE /* don't change uniform palette if alpha blending*/ gr_firstuserpalentry = 256; #else /* start after last system-reserved color*/ gr_firstuserpalentry = FIRSTUSERPALENTRY; #endif stdpal = mwstdpal8; } break; #endif /* !defined(NOSTDPAL8)*/ default: /* truecolor*/ /* no palette*/ gr_firstuserpalentry = 0; stdpal = NULL; } /* reset next user palette entry, write hardware palette*/ GdResetPalette(); GdSetPalette(psd, 0, (int)psd->ncolors, stdpal); /* init local vars*/ GdSetMode(MWROP_COPY); GdSetFillMode(MWFILL_SOLID); /* Set the fill mode to solid */ GdSetForegroundColor(psd, MWRGB(255, 255, 255)); /* WHITE*/ GdSetBackgroundColor(psd, MWRGB(0, 0, 0)); /* BLACK*/ GdSetUseBackground(TRUE); /* select first builtin font (usually MWFONT_SYSTEM_VAR)*/ //GdSetFont(GdCreateFont(psd, NULL, 0, 0, NULL)); GdSetDash(0, 0); /* No dashing to start */ GdSetStippleBitmap(0,0,0); /* No stipple to start */ #if !NOCLIPPING #if DYNAMICREGIONS GdSetClipRegion(psd, GdAllocRectRegion(0, 0, psd->xvirtres, psd->yvirtres)); #else GdSetClipRects(psd, 0, NULL); #endif /* DYNAMICREGIONS*/ #endif /* NOCLIPPING*/ /* fill black (actually fill to first palette entry or truecolor 0*/ psd->FillRect(psd, 0, 0, psd->xvirtres-1, psd->yvirtres-1, 0); return psd; }