Merge commit 'origin/gallium-0.1' into gallium-0.2
[mesa.git] / src / mesa / swrast / s_bitmap.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.1
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file swrast/s_bitmap.c
27 * \brief glBitmap rendering.
28 * \author Brian Paul
29 */
30
31 #include "main/glheader.h"
32 #include "main/bufferobj.h"
33 #include "main/image.h"
34 #include "main/macros.h"
35 #include "main/pixel.h"
36
37 #include "s_context.h"
38 #include "s_span.h"
39
40
41
42 /**
43 * Render a bitmap.
44 * Called via ctx->Driver.Bitmap()
45 * All parameter error checking will have been done before this is called.
46 */
47 void
48 _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
49 GLsizei width, GLsizei height,
50 const struct gl_pixelstore_attrib *unpack,
51 const GLubyte *bitmap )
52 {
53 SWcontext *swrast = SWRAST_CONTEXT(ctx);
54 GLint row, col;
55 GLuint count = 0;
56 SWspan span;
57
58 ASSERT(ctx->RenderMode == GL_RENDER);
59
60 bitmap = _mesa_map_bitmap_pbo(ctx, unpack, bitmap);
61 if (!bitmap)
62 return;
63
64 RENDER_START(swrast,ctx);
65
66 if (SWRAST_CONTEXT(ctx)->NewState)
67 _swrast_validate_derived( ctx );
68
69 INIT_SPAN(span, GL_BITMAP);
70 span.end = width;
71 span.arrayMask = SPAN_XY;
72 _swrast_span_default_attribs(ctx, &span);
73
74 for (row = 0; row < height; row++) {
75 const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
76 bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
77
78 if (unpack->LsbFirst) {
79 /* Lsb first */
80 GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
81 for (col = 0; col < width; col++) {
82 if (*src & mask) {
83 span.array->x[count] = px + col;
84 span.array->y[count] = py + row;
85 count++;
86 }
87 if (mask == 128U) {
88 src++;
89 mask = 1U;
90 }
91 else {
92 mask = mask << 1;
93 }
94 }
95
96 /* get ready for next row */
97 if (mask != 1)
98 src++;
99 }
100 else {
101 /* Msb first */
102 GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
103 for (col = 0; col < width; col++) {
104 if (*src & mask) {
105 span.array->x[count] = px + col;
106 span.array->y[count] = py + row;
107 count++;
108 }
109 if (mask == 1U) {
110 src++;
111 mask = 128U;
112 }
113 else {
114 mask = mask >> 1;
115 }
116 }
117
118 /* get ready for next row */
119 if (mask != 128)
120 src++;
121 }
122
123 if (count + width >= MAX_WIDTH || row + 1 == height) {
124 /* flush the span */
125 span.end = count;
126 if (ctx->Visual.rgbMode)
127 _swrast_write_rgba_span(ctx, &span);
128 else
129 _swrast_write_index_span(ctx, &span);
130 span.end = 0;
131 count = 0;
132 }
133 }
134
135 RENDER_FINISH(swrast,ctx);
136
137 _mesa_unmap_bitmap_pbo(ctx, unpack);
138 }
139
140
141 #if 0
142 /*
143 * XXX this is another way to implement Bitmap. Use horizontal runs of
144 * fragments, initializing the mask array to indicate which fragments to
145 * draw or skip.
146 */
147 void
148 _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
149 GLsizei width, GLsizei height,
150 const struct gl_pixelstore_attrib *unpack,
151 const GLubyte *bitmap )
152 {
153 SWcontext *swrast = SWRAST_CONTEXT(ctx);
154 GLint row, col;
155 SWspan span;
156
157 ASSERT(ctx->RenderMode == GL_RENDER);
158 ASSERT(bitmap);
159
160 RENDER_START(swrast,ctx);
161
162 if (SWRAST_CONTEXT(ctx)->NewState)
163 _swrast_validate_derived( ctx );
164
165 INIT_SPAN(span, GL_BITMAP);
166 span.end = width;
167 span.arrayMask = SPAN_MASK;
168 _swrast_span_default_attribs(ctx, &span);
169
170 /*span.arrayMask |= SPAN_MASK;*/ /* we'll init span.mask[] */
171 span.x = px;
172 span.y = py;
173 /*span.end = width;*/
174
175 for (row=0; row<height; row++, span.y++) {
176 const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
177 bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
178
179 if (unpack->LsbFirst) {
180 /* Lsb first */
181 GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
182 for (col=0; col<width; col++) {
183 span.array->mask[col] = (*src & mask) ? GL_TRUE : GL_FALSE;
184 if (mask == 128U) {
185 src++;
186 mask = 1U;
187 }
188 else {
189 mask = mask << 1;
190 }
191 }
192
193 if (ctx->Visual.rgbMode)
194 _swrast_write_rgba_span(ctx, &span);
195 else
196 _swrast_write_index_span(ctx, &span);
197
198 /* get ready for next row */
199 if (mask != 1)
200 src++;
201 }
202 else {
203 /* Msb first */
204 GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
205 for (col=0; col<width; col++) {
206 span.array->mask[col] = (*src & mask) ? GL_TRUE : GL_FALSE;
207 if (mask == 1U) {
208 src++;
209 mask = 128U;
210 }
211 else {
212 mask = mask >> 1;
213 }
214 }
215
216 if (ctx->Visual.rgbMode)
217 _swrast_write_rgba_span(ctx, &span);
218 else
219 _swrast_write_index_span(ctx, &span);
220
221 /* get ready for next row */
222 if (mask != 128)
223 src++;
224 }
225 }
226
227 RENDER_FINISH(swrast,ctx);
228 }
229 #endif