static int GDI_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, int count) { GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; int i; COLORREF color; if (data->makedirty) { /* Get the smallest rectangle that contains everything */ SDL_Window *window = renderer->window; SDL_Rect rect; rect.x = 0; rect.y = 0; rect.w = window->w; rect.h = window->h; if (!SDL_EnclosePoints(points, count, &rect, &rect)) { /* Nothing to draw */ return 0; } SDL_AddDirtyRect(&data->dirty, &rect); } color = RGB(renderer->r, renderer->g, renderer->b); for (i = 0; i < count; ++i) { SetPixel(data->current_hdc, points[i].x, points[i].y, color); } return 0; }
static int DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, int markDirty, void **pixels, int *pitch) { DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata; DFBResult ret; if (markDirty) { SDL_AddDirtyRect(&texturedata->dirty, rect); } if (texturedata->display) { void *fdata; int fpitch; SDL_DFB_CHECKERR(texturedata->surface->Lock(texturedata->surface, DSLF_WRITE | DSLF_READ, &fdata, &fpitch)); *pitch = fpitch; *pixels = fdata; } else { *pixels = (void *) ((Uint8 *) texturedata->pixels + rect->y * texturedata->pitch + rect->x * SDL_BYTESPERPIXEL(texture->format)); *pitch = texturedata->pitch; } return 0; error: return -1; }
static int GDI_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) { GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; HPEN pen; POINT vertices[5]; int i, status = 1; if (data->makedirty) { SDL_Window *window = renderer->window; SDL_Rect clip, rect; clip.x = 0; clip.y = 0; clip.w = window->w; clip.h = window->h; for (i = 0; i < count; ++i) { if (SDL_IntersectRect(rects[i], &clip, &rect)) { SDL_AddDirtyRect(&data->dirty, &rect); } } } /* Should we cache the pen? .. it looks like GDI does for us. :) */ pen = CreatePen(PS_SOLID, 1, RGB(renderer->r, renderer->g, renderer->b)); SelectObject(data->current_hdc, pen); for (i = 0; i < count; ++i) { const SDL_Rect *rect = rects[i]; vertices[0].x = rect->x; vertices[0].y = rect->y; vertices[1].x = rect->x+rect->w-1; vertices[1].y = rect->y; vertices[2].x = rect->x+rect->w-1; vertices[2].y = rect->y+rect->h-1; vertices[3].x = rect->x; vertices[3].y = rect->y+rect->h-1; vertices[4].x = rect->x; vertices[4].y = rect->y; status &= Polyline(data->current_hdc, vertices, 5); } DeleteObject(pen); if (!status) { WIN_SetError("Polyline()"); return -1; } return 0; }
static int GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect) { GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; GDI_TextureData *texturedata = (GDI_TextureData *) texture->driverdata; if (data->makedirty) { SDL_AddDirtyRect(&data->dirty, dstrect); } SelectObject(data->memory_hdc, texturedata->hbm); if (texturedata->hpal) { SelectPalette(data->memory_hdc, texturedata->hpal, TRUE); RealizePalette(data->memory_hdc); } if (texture->blendMode & (SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND)) { #ifdef _WIN32_WCE SDL_SetError("Texture has blendmode not supported under WinCE"); return -1; #else BLENDFUNCTION blendFunc = { AC_SRC_OVER, 0, texture->a, AC_SRC_NO_PREMULT_ALPHA/*AC_SRC_ALPHA*/ }; if (!AlphaBlend (data->current_hdc, dstrect->x, dstrect->y, dstrect->w, dstrect->h, data->memory_hdc, srcrect->x, srcrect->y, srcrect->w, srcrect->h, blendFunc)) { WIN_SetError("AlphaBlend()"); return -1; } #endif } else { if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) { if (!BitBlt (data->current_hdc, dstrect->x, dstrect->y, dstrect->w, srcrect->h, data->memory_hdc, srcrect->x, srcrect->y, SRCCOPY)) { WIN_SetError("BitBlt()"); return -1; } } else { if (!StretchBlt (data->current_hdc, dstrect->x, dstrect->y, dstrect->w, dstrect->h, data->memory_hdc, srcrect->x, srcrect->y, srcrect->w, srcrect->h, SRCCOPY)) { WIN_SetError("StretchBlt()"); return -1; } } } return 0; }
static int GDI_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, int count) { GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; HPEN pen; BOOL status; if (data->makedirty) { /* Get the smallest rectangle that contains everything */ SDL_Window *window = renderer->window; SDL_Rect clip, rect; clip.x = 0; clip.y = 0; clip.w = window->w; clip.h = window->h; SDL_EnclosePoints(points, count, NULL, &rect); if (!SDL_IntersectRect(&rect, &clip, &rect)) { /* Nothing to draw */ return 0; } SDL_AddDirtyRect(&data->dirty, &rect); } /* Should we cache the pen? .. it looks like GDI does for us. :) */ pen = CreatePen(PS_SOLID, 1, RGB(renderer->r, renderer->g, renderer->b)); SelectObject(data->current_hdc, pen); { LPPOINT p = SDL_stack_alloc(POINT, count); int i; for (i = 0; i < count; ++i) { p[i].x = points[i].x; p[i].y = points[i].y; } status = Polyline(data->current_hdc, p, count); SDL_stack_free(p); } DeleteObject(pen); /* Need to close the endpoint of the line */ if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) { SetPixel(data->current_hdc, points[count-1].x, points[count-1].y, RGB(renderer->r, renderer->g, renderer->b)); } if (!status) { WIN_SetError("Polyline()"); return -1; } return 0; }
static void GLES_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects, const SDL_Rect * rects) { GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; int i; for (i = 0; i < numrects; ++i) { SDL_AddDirtyRect(&data->dirty, &rects[i]); } }
static int X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, int count) { X11_RenderData *data = (X11_RenderData *) renderer->driverdata; SDL_Window *window = renderer->window; unsigned long foreground; XPoint *xpoints, *xpoint; int i, xcount; if (data->makedirty) { SDL_Rect rect; /* Get the smallest rectangle that contains everything */ rect.x = 0; rect.y = 0; rect.w = window->w; rect.h = window->h; if (!SDL_EnclosePoints(points, count, &rect, &rect)) { /* Nothing to draw */ return 0; } SDL_AddDirtyRect(&data->dirty, &rect); } foreground = renderdrawcolor(renderer, 1); XSetForeground(data->display, data->gc, foreground); xpoint = xpoints = SDL_stack_alloc(XPoint, count); xcount = 0; for (i = 0; i < count; ++i) { int x = points[i].x; int y = points[i].y; if (x < 0 || x >= window->w || y < 0 || y >= window->h) { continue; } xpoint->x = (short)x; xpoint->y = (short)y; ++xpoint; ++xcount; } if (xcount > 0) { XDrawPoints(data->display, data->drawable, data->gc, xpoints, xcount, CoordModeOrigin); } SDL_stack_free(xpoints); return 0; }
static int SW_RenderPoint(SDL_Renderer * renderer, int x, int y) { SW_RenderData *data = (SW_RenderData *) renderer->driverdata; SDL_Rect rect; int status; rect.x = x; rect.y = y; rect.w = 1; rect.h = 1; if (data->renderer->info.flags & SDL_RENDERER_PRESENTCOPY) { SDL_AddDirtyRect(&data->dirty, &rect); } if (data->renderer->LockTexture(data->renderer, data->texture[data->current_texture], &rect, 1, &data->surface.pixels, &data->surface.pitch) < 0) { return -1; } data->surface.w = 1; data->surface.h = 1; data->surface.clip_rect.w = 1; data->surface.clip_rect.h = 1; if (renderer->blendMode == SDL_BLENDMODE_NONE || renderer->blendMode == SDL_BLENDMODE_MASK) { Uint32 color = SDL_MapRGBA(data->surface.format, renderer->r, renderer->g, renderer->b, renderer->a); status = SDL_DrawPoint(&data->surface, 0, 0, color); } else { status = SDL_BlendPoint(&data->surface, 0, 0, renderer->blendMode, renderer->r, renderer->g, renderer->b, renderer->a); } data->renderer->UnlockTexture(data->renderer, data->texture[data->current_texture]); return status; }
static int GLES_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, int markDirty, void **pixels, int *pitch) { GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; if (markDirty) { SDL_AddDirtyRect(&data->dirty, rect); } *pixels = (void *) ((Uint8 *) data->pixels + rect->y * data->pitch + rect->x * SDL_BYTESPERPIXEL(texture->format)); *pitch = data->pitch; return 0; }
static int GDI_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) { GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; RECT rc; HBRUSH brush; int i, status = 1; if (data->makedirty) { SDL_Window *window = renderer->window; SDL_Rect clip, rect; clip.x = 0; clip.y = 0; clip.w = window->w; clip.h = window->h; for (i = 0; i < count; ++i) { if (SDL_IntersectRect(rects[i], &clip, &rect)) { SDL_AddDirtyRect(&data->dirty, &rect); } } } /* Should we cache the brushes? .. it looks like GDI does for us. :) */ brush = CreateSolidBrush(RGB(renderer->r, renderer->g, renderer->b)); SelectObject(data->current_hdc, brush); for (i = 0; i < count; ++i) { const SDL_Rect *rect = rects[i]; rc.left = rect->x; rc.top = rect->y; rc.right = rect->x + rect->w; rc.bottom = rect->y + rect->h; status &= FillRect(data->current_hdc, &rc, brush); } DeleteObject(brush); if (!status) { WIN_SetError("FillRect()"); return -1; } return 0; }
static int X11_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) { X11_RenderData *data = (X11_RenderData *) renderer->driverdata; SDL_Window *window = renderer->window; SDL_Rect clip, rect; unsigned long foreground; XRectangle *xrects, *xrect; int i, xcount; clip.x = 0; clip.y = 0; clip.w = window->w; clip.h = window->h; foreground = renderdrawcolor(renderer, 1); XSetForeground(data->display, data->gc, foreground); xrect = xrects = SDL_stack_alloc(XRectangle, count); xcount = 0; for (i = 0; i < count; ++i) { if (!SDL_IntersectRect(rects[i], &clip, &rect)) { continue; } xrect->x = (short)rect.x; xrect->y = (short)rect.y; xrect->width = (unsigned short)rect.w; xrect->height = (unsigned short)rect.h; ++xrect; ++xcount; if (data->makedirty) { SDL_AddDirtyRect(&data->dirty, &rect); } } if (xcount > 0) { XFillRectangles(data->display, data->drawable, data->gc, xrects, xcount); } SDL_stack_free(xpoints); return 0; }
static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect) { SW_RenderData *data = (SW_RenderData *) renderer->driverdata; //SDL_Window *window = SDL_GetWindowFromID(renderer->window); int status; if (data->renderer->info.flags & SDL_RENDERER_PRESENTCOPY) { SDL_AddDirtyRect(&data->dirty, dstrect); } if (data->renderer->LockTexture(data->renderer, data->texture[data->current_texture], dstrect, 1, &data->surface.pixels, &data->surface.pitch) < 0) { return -1; } if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { status = SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata, srcrect, data->format, dstrect->w, dstrect->h, data->surface.pixels, data->surface.pitch); } else { SDL_Surface *surface = (SDL_Surface *) texture->driverdata; SDL_Rect real_srcrect = *srcrect; SDL_Rect real_dstrect; data->surface.w = dstrect->w; data->surface.h = dstrect->h; data->surface.clip_rect.w = dstrect->w; data->surface.clip_rect.h = dstrect->h; real_dstrect = data->surface.clip_rect; status = SDL_LowerBlit(surface, &real_srcrect, &data->surface, &real_dstrect); } data->renderer->UnlockTexture(data->renderer, data->texture[data->current_texture]); return status; }
static int SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect) { SW_RenderData *data = (SW_RenderData *) renderer->driverdata; SDL_Rect real_rect; int status; if (data->renderer->info.flags & SDL_RENDERER_PRESENTCOPY) { SDL_AddDirtyRect(&data->dirty, rect); } if (data->renderer->LockTexture(data->renderer, data->texture[data->current_texture], rect, 1, &data->surface.pixels, &data->surface.pitch) < 0) { return -1; } data->surface.w = rect->w; data->surface.h = rect->h; data->surface.clip_rect.w = rect->w; data->surface.clip_rect.h = rect->h; real_rect = data->surface.clip_rect; if (renderer->blendMode == SDL_BLENDMODE_NONE) { Uint32 color = SDL_MapRGBA(data->surface.format, renderer->r, renderer->g, renderer->b, renderer->a); status = SDL_FillRect(&data->surface, &real_rect, color); } else { status = SDL_BlendRect(&data->surface, &real_rect, renderer->blendMode, renderer->r, renderer->g, renderer->b, renderer->a); } data->renderer->UnlockTexture(data->renderer, data->texture[data->current_texture]); return status; }
static int DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, void **pixels, int *pitch) { DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata; DirectFB_ActivateRenderer(renderer); #if 0 if (markDirty) { SDL_AddDirtyRect(&texturedata->dirty, rect); } #endif if (texturedata->display) { void *fdata; int fpitch; SDL_DFB_CHECKERR(texturedata->surface->Lock(texturedata->surface, DSLF_WRITE | DSLF_READ, &fdata, &fpitch)); *pitch = fpitch; *pixels = fdata; } else { *pixels = (void *) ((Uint8 *) texturedata->pixels + rect->y * texturedata->pitch + rect->x * DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format))); *pitch = texturedata->pitch; texturedata->isDirty = 1; } return 0; error: return -1; }
static int X11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect) { X11_RenderData *data = (X11_RenderData *) renderer->driverdata; X11_TextureData *texturedata = (X11_TextureData *) texture->driverdata; if (data->makedirty) { SDL_AddDirtyRect(&data->dirty, dstrect); } if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) { #ifndef NO_SHARED_MEMORY if (texturedata->shminfo.shmaddr) { XShmPutImage(data->display, data->drawable, data->gc, texturedata->image, srcrect->x, srcrect->y, dstrect->x, dstrect->y, srcrect->w, srcrect->h, False); } else #endif if (texturedata->pixels) { XPutImage(data->display, data->drawable, data->gc, texturedata->image, srcrect->x, srcrect->y, dstrect->x, dstrect->y, srcrect->w, srcrect->h); } else { XCopyArea(data->display, texturedata->pixmap, data->drawable, data->gc, srcrect->x, srcrect->y, dstrect->w, dstrect->h, dstrect->x, dstrect->y); } } else if (texturedata->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING) { SDL_Surface src, dst; SDL_PixelFormat fmt; SDL_Rect rect; XImage *image = texturedata->scaling_image; if (!image) { int depth; void *pixels; int pitch; pitch = dstrect->w * SDL_BYTESPERPIXEL(texturedata->format); pixels = SDL_malloc(dstrect->h * pitch); if (!pixels) { SDL_OutOfMemory(); return -1; } image = XCreateImage(data->display, data->visual, data->depth, ZPixmap, 0, pixels, dstrect->w, dstrect->h, SDL_BYTESPERPIXEL(texturedata->format) * 8, pitch); if (!image) { SDL_SetError("XCreateImage() failed"); return -1; } texturedata->scaling_image = image; } else if (image->width != dstrect->w || image->height != dstrect->h || !image->data) { image->width = dstrect->w; image->height = dstrect->h; image->bytes_per_line = image->width * SDL_BYTESPERPIXEL(texturedata->format); image->data = (char *) SDL_realloc(image->data, image->height * image->bytes_per_line); if (!image->data) { SDL_OutOfMemory(); return -1; } } /* Set up fake surfaces for SDL_SoftStretch() */ SDL_zero(src); src.format = &fmt; src.w = texture->w; src.h = texture->h; #ifndef NO_SHARED_MEMORY if (texturedata->shminfo.shmaddr) { src.pixels = texturedata->shminfo.shmaddr; } else #endif src.pixels = texturedata->pixels; src.pitch = texturedata->pitch; SDL_zero(dst); dst.format = &fmt; dst.w = image->width; dst.h = image->height; dst.pixels = image->data; dst.pitch = image->bytes_per_line; fmt.BytesPerPixel = SDL_BYTESPERPIXEL(texturedata->format); rect.x = 0; rect.y = 0; rect.w = dstrect->w; rect.h = dstrect->h; if (SDL_SoftStretch(&src, srcrect, &dst, &rect) < 0) { return -1; } XPutImage(data->display, data->drawable, data->gc, image, 0, 0, dstrect->x, dstrect->y, dstrect->w, dstrect->h); } else { XCopyArea(data->display, texturedata->pixmap, data->drawable, data->gc, srcrect->x, srcrect->y, dstrect->w, dstrect->h, srcrect->x, srcrect->y); } return 0; }
static int X11_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, int count) { X11_RenderData *data = (X11_RenderData *) renderer->driverdata; SDL_Window *window = renderer->window; SDL_Rect clip, rect; unsigned long foreground; XPoint *xpoints, *xpoint; int i, xcount; int minx, miny; int maxx, maxy; clip.x = 0; clip.y = 0; clip.w = window->w; clip.h = window->h; foreground = renderdrawcolor(renderer, 1); XSetForeground(data->display, data->gc, foreground); xpoint = xpoints = SDL_stack_alloc(XPoint, count); xcount = 0; minx = INT_MAX; miny = INT_MAX; maxx = INT_MIN; maxy = INT_MIN; for (i = 0; i < count; ++i) { int x = points[i].x; int y = points[i].y; /* If the point is inside the window, add it to the list */ if (x >= 0 && x < window->w && y >= 0 && y < window->h) { if (x < minx) { minx = x; } else if (x > maxx) { maxx = x; } if (y < miny) { miny = y; } else if (y > maxy) { maxy = y; } xpoint->x = (short)x; xpoint->y = (short)y; ++xpoint; ++xcount; continue; } /* We need to clip the line segments joined by this point */ if (xcount > 0) { int x1 = xpoint[-1].x; int y1 = xpoint[-1].y; int x2 = x; int y2 = y; if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) { if (x2 < minx) { minx = x2; } else if (x2 > maxx) { maxx = x2; } if (y2 < miny) { miny = y2; } else if (y2 > maxy) { maxy = y2; } xpoint->x = (short)x2; xpoint->y = (short)y2; ++xpoint; ++xcount; } XDrawLines(data->display, data->drawable, data->gc, xpoints, xcount, CoordModeOrigin); if (xpoints[0].x != x2 || xpoints[0].y != y2) { XDrawPoint(data->display, data->drawable, data->gc, x2, y2); } if (data->makedirty) { SDL_Rect rect; rect.x = minx; rect.y = miny; rect.w = (maxx - minx) + 1; rect.h = (maxy - miny) + 1; SDL_AddDirtyRect(&data->dirty, &rect); } xpoint = xpoints; xcount = 0; minx = INT_MAX; miny = INT_MAX; maxx = INT_MIN; maxy = INT_MIN; } if (i < (count-1)) { int x1 = x; int y1 = y; int x2 = points[i+1].x; int y2 = points[i+1].y; if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) { if (x1 < minx) { minx = x1; } else if (x1 > maxx) { maxx = x1; } if (y1 < miny) { miny = y1; } else if (y1 > maxy) { maxy = y1; } xpoint->x = (short)x1; xpoint->y = (short)y1; ++xpoint; ++xcount; } } } if (xcount > 1) { int x2 = xpoint[-1].x; int y2 = xpoint[-1].y; XDrawLines(data->display, data->drawable, data->gc, xpoints, xcount, CoordModeOrigin); if (xpoints[0].x != x2 || xpoints[0].y != y2) { XDrawPoint(data->display, data->drawable, data->gc, x2, y2); } if (data->makedirty) { SDL_Rect rect; rect.x = minx; rect.y = miny; rect.w = (maxx - minx) + 1; rect.h = (maxy - miny) + 1; SDL_AddDirtyRect(&data->dirty, &rect); } } SDL_stack_free(xpoints); return 0; }
static int SW_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2) { SW_RenderData *data = (SW_RenderData *) renderer->driverdata; SDL_Rect rect; int status; if (x1 < x2) { rect.x = x1; rect.w = (x2 - x1) + 1; x2 -= x1; x1 = 0; } else { rect.x = x2; rect.w = (x1 - x2) + 1; x1 -= x2; x2 = 0; } if (y1 < y2) { rect.y = y1; rect.h = (y2 - y1) + 1; y2 -= y1; y1 = 0; } else { rect.y = y2; rect.h = (y1 - y2) + 1; y1 -= y2; y2 = 0; } if (data->renderer->info.flags & SDL_RENDERER_PRESENTCOPY) { SDL_AddDirtyRect(&data->dirty, &rect); } if (data->renderer->LockTexture(data->renderer, data->texture[data->current_texture], &rect, 1, &data->surface.pixels, &data->surface.pitch) < 0) { return -1; } data->surface.w = rect.w; data->surface.h = rect.h; data->surface.clip_rect.w = rect.w; data->surface.clip_rect.h = rect.h; if (renderer->blendMode == SDL_BLENDMODE_NONE || renderer->blendMode == SDL_BLENDMODE_MASK) { Uint32 color = SDL_MapRGBA(data->surface.format, renderer->r, renderer->g, renderer->b, renderer->a); status = SDL_DrawLine(&data->surface, x1, y1, x2, y2, color); } else { status = SDL_BlendLine(&data->surface, x1, y1, x2, y2, renderer->blendMode, renderer->r, renderer->g, renderer->b, renderer->a); } data->renderer->UnlockTexture(data->renderer, data->texture[data->current_texture]); return status; }