PageRenderTime 15ms CodeModel.GetById 2ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/project/jni/sdl-1.3/src/render/software/SDL_drawline.c

https://github.com/aichunyu/FFPlayer
C | 214 lines | 165 code | 22 blank | 27 comment | 57 complexity | 9a82bfb4dde8867bf4ef37fd7498896a MD5 | raw file
  1/*
  2  Simple DirectMedia Layer
  3  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
  4
  5  This software is provided 'as-is', without any express or implied
  6  warranty.  In no event will the authors be held liable for any damages
  7  arising from the use of this software.
  8
  9  Permission is granted to anyone to use this software for any purpose,
 10  including commercial applications, and to alter it and redistribute it
 11  freely, subject to the following restrictions:
 12
 13  1. The origin of this software must not be misrepresented; you must not
 14     claim that you wrote the original software. If you use this software
 15     in a product, an acknowledgment in the product documentation would be
 16     appreciated but is not required.
 17  2. Altered source versions must be plainly marked as such, and must not be
 18     misrepresented as being the original software.
 19  3. This notice may not be removed or altered from any source distribution.
 20*/
 21#include "SDL_config.h"
 22
 23#if !SDL_RENDER_DISABLED
 24
 25#include "SDL_draw.h"
 26#include "SDL_drawline.h"
 27#include "SDL_drawpoint.h"
 28
 29
 30static void
 31SDL_DrawLine1(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color,
 32              SDL_bool draw_end)
 33{
 34    if (y1 == y2) {
 35        //HLINE(Uint8, DRAW_FASTSETPIXEL1, draw_end);
 36        int length;
 37        int pitch = (dst->pitch / dst->format->BytesPerPixel);
 38        Uint8 *pixel;
 39        if (x1 <= x2) {
 40            pixel = (Uint8 *)dst->pixels + y1 * pitch + x1;
 41            length = draw_end ? (x2-x1+1) : (x2-x1);
 42        } else {
 43            pixel = (Uint8 *)dst->pixels + y1 * pitch + x2;
 44            if (!draw_end) {
 45                ++pixel;
 46            }
 47            length = draw_end ? (x1-x2+1) : (x1-x2);
 48        }
 49        SDL_memset(pixel, color, length);
 50    } else if (x1 == x2) {
 51        VLINE(Uint8, DRAW_FASTSETPIXEL1, draw_end);
 52    } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
 53        DLINE(Uint8, DRAW_FASTSETPIXEL1, draw_end);
 54    } else {
 55        BLINE(x1, y1, x2, y2, DRAW_FASTSETPIXELXY1, draw_end);
 56    }
 57}
 58
 59static void
 60SDL_DrawLine2(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color,
 61              SDL_bool draw_end)
 62{
 63    if (y1 == y2) {
 64        HLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end);
 65    } else if (x1 == x2) {
 66        VLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end);
 67    } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
 68        DLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end);
 69    } else {
 70        Uint8 _r, _g, _b, _a;
 71        const SDL_PixelFormat * fmt = dst->format;
 72        SDL_GetRGBA(color, fmt, &_r, &_g, &_b, &_a);
 73        if (fmt->Rmask == 0x7C00) {
 74            AALINE(x1, y1, x2, y2,
 75                   DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY_BLEND_RGB555,
 76                   draw_end);
 77        } else if (fmt->Rmask == 0xF800) {
 78            AALINE(x1, y1, x2, y2,
 79                   DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY_BLEND_RGB565,
 80                   draw_end);
 81        } else {
 82            AALINE(x1, y1, x2, y2,
 83                   DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY2_BLEND_RGB,
 84                   draw_end);
 85        }
 86    }
 87}
 88
 89static void
 90SDL_DrawLine4(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color,
 91              SDL_bool draw_end)
 92{
 93    if (y1 == y2) {
 94        HLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end);
 95    } else if (x1 == x2) {
 96        VLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end);
 97    } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
 98        DLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end);
 99    } else {
100        Uint8 _r, _g, _b, _a;
101        const SDL_PixelFormat * fmt = dst->format;
102        SDL_GetRGBA(color, fmt, &_r, &_g, &_b, &_a);
103        if (fmt->Rmask == 0x00FF0000) {
104            if (!fmt->Amask) {
105                AALINE(x1, y1, x2, y2,
106                       DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_RGB888,
107                       draw_end);
108            } else {
109                AALINE(x1, y1, x2, y2,
110                       DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_ARGB8888,
111                       draw_end);
112            }
113        } else {
114            AALINE(x1, y1, x2, y2,
115                   DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY4_BLEND_RGB,
116                   draw_end);
117        }
118    }
119}
120
121typedef void (*DrawLineFunc) (SDL_Surface * dst,
122                              int x1, int y1, int x2, int y2,
123                              Uint32 color, SDL_bool draw_end);
124
125static DrawLineFunc
126SDL_CalculateDrawLineFunc(const SDL_PixelFormat * fmt)
127{
128    switch (fmt->BytesPerPixel) {
129    case 1:
130        if (fmt->BitsPerPixel < 8) {
131            break;
132        }
133        return SDL_DrawLine1;
134    case 2:
135        return SDL_DrawLine2;
136    case 4:
137        return SDL_DrawLine4;
138    }
139    return NULL;
140}
141
142int
143SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color)
144{
145    DrawLineFunc func;
146
147    if (!dst) {
148        SDL_SetError("SDL_DrawLine(): Passed NULL destination surface");
149        return -1;
150    }
151
152    func = SDL_CalculateDrawLineFunc(dst->format);
153    if (!func) {
154        SDL_SetError("SDL_DrawLine(): Unsupported surface format");
155        return -1;
156    }
157
158    /* Perform clipping */
159    /* FIXME: We don't actually want to clip, as it may change line slope */
160    if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
161        return 0;
162    }
163
164    func(dst, x1, y1, x2, y2, color, SDL_TRUE);
165    return 0;
166}
167
168int
169SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count,
170              Uint32 color)
171{
172    int i;
173    int x1, y1;
174    int x2, y2;
175    SDL_bool draw_end;
176    DrawLineFunc func;
177
178    if (!dst) {
179        SDL_SetError("SDL_DrawLines(): Passed NULL destination surface");
180        return -1;
181    }
182
183    func = SDL_CalculateDrawLineFunc(dst->format);
184    if (!func) {
185        SDL_SetError("SDL_DrawLines(): Unsupported surface format");
186        return -1;
187    }
188
189    for (i = 1; i < count; ++i) {
190        x1 = points[i-1].x;
191        y1 = points[i-1].y;
192        x2 = points[i].x;
193        y2 = points[i].y;
194
195        /* Perform clipping */
196        /* FIXME: We don't actually want to clip, as it may change line slope */
197        if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
198            continue;
199        }
200
201        /* Draw the end if it was clipped */
202        draw_end = (x2 != points[i].x || y2 != points[i].y);
203
204        func(dst, x1, y1, x2, y2, color, draw_end);
205    }
206    if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
207        SDL_DrawPoint(dst, points[count-1].x, points[count-1].y, color);
208    }
209    return 0;
210}
211
212#endif /* !SDL_RENDER_DISABLED */
213
214/* vi: set ts=4 sw=4 expandtab: */