2 * Copyright © 2009 Intel Corporation
3 * Copyright © 1998 Keith Packard
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * Zhigang Gong <zhigang.gong@gmail.com>
29 #include "glamor_priv.h"
30 #include <dixfontstr.h>
31 #include "glamor_transform.h"
33 static const glamor_facet glamor_facet_poly_glyph_blt
= {
34 .name
= "poly_glyph_blt",
35 .vs_vars
= "in vec2 primitive;\n",
36 .vs_exec
= (" vec2 pos = vec2(0,0);\n"
37 GLAMOR_DEFAULT_POINT_SIZE
38 GLAMOR_POS(gl_Position
, primitive
)),
42 glamor_poly_glyph_blt_gl(DrawablePtr drawable
, GCPtr gc
,
43 int start_x
, int y
, unsigned int nglyph
,
44 CharInfoPtr
*ppci
, void *pglyph_base
)
46 ScreenPtr screen
= drawable
->pScreen
;
47 glamor_screen_private
*glamor_priv
= glamor_get_screen_private(screen
);
48 PixmapPtr pixmap
= glamor_get_drawable_pixmap(drawable
);
49 glamor_pixmap_private
*pixmap_priv
;
51 RegionPtr clip
= gc
->pCompositeClip
;
55 pixmap_priv
= glamor_get_pixmap_private(pixmap
);
56 if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv
))
59 glamor_make_current(glamor_priv
);
61 prog
= glamor_use_program_fill(drawable
, gc
,
62 &glamor_priv
->poly_glyph_blt_progs
,
63 &glamor_facet_poly_glyph_blt
);
67 glEnableVertexAttribArray(GLAMOR_VERTEX_POS
);
69 start_x
+= drawable
->x
;
72 glamor_pixmap_loop(pixmap_priv
, box_index
) {
75 int num_points
, max_points
;
80 if (!glamor_set_destination_drawable(drawable
, box_index
, FALSE
, TRUE
,
81 prog
->matrix_uniform
, &off_x
, &off_y
))
87 for (n
= 0; n
< nglyph
; n
++) {
88 CharInfoPtr charinfo
= ppci
[n
];
89 int w
= GLYPHWIDTHPIXELS(charinfo
);
90 int h
= GLYPHHEIGHTPIXELS(charinfo
);
91 uint8_t *glyphbits
= FONTGLYPHBITS(NULL
, charinfo
);
94 int glyph_x
= x
+ charinfo
->metrics
.leftSideBearing
;
95 int glyph_y
= y
- charinfo
->metrics
.ascent
;
96 int glyph_stride
= GLYPHWIDTHBYTESPADDED(charinfo
);
99 for (yy
= 0; yy
< h
; yy
++) {
100 uint8_t *glyph
= glyphbits
;
101 for (xx
= 0; xx
< w
; glyph
+= ((xx
&7) == 7), xx
++) {
102 int pt_x_i
= glyph_x
+ xx
;
103 int pt_y_i
= glyph_y
+ yy
;
105 #if BITMAP_BIT_ORDER == MSBFirst
106 if (!(*glyph
& (128 >> (xx
& 7))))
108 if (!(*glyph
& (1 << (xx
& 7))))
112 if (!RegionContainsPoint(clip
, pt_x_i
, pt_y_i
, NULL
))
116 points
= glamor_get_vbo_space(screen
,
118 (2 * sizeof (INT16
)),
121 glVertexAttribPointer(GLAMOR_VERTEX_POS
,
123 GL_FALSE
, 0, vbo_offset
);
130 if (num_points
== max_points
) {
131 glamor_put_vbo_space(screen
);
132 glDrawArrays(GL_POINTS
, 0, num_points
);
136 glyphbits
+= glyph_stride
;
139 x
+= charinfo
->metrics
.characterWidth
;
143 glamor_put_vbo_space(screen
);
144 glDrawArrays(GL_POINTS
, 0, num_points
);
151 glDisableVertexAttribArray(GLAMOR_VERTEX_POS
);
157 glamor_poly_glyph_blt(DrawablePtr drawable
, GCPtr gc
,
158 int start_x
, int y
, unsigned int nglyph
,
159 CharInfoPtr
*ppci
, void *pglyph_base
)
161 if (glamor_poly_glyph_blt_gl(drawable
, gc
, start_x
, y
, nglyph
, ppci
,
164 miPolyGlyphBlt(drawable
, gc
, start_x
, y
, nglyph
,
169 glamor_push_pixels_gl(GCPtr gc
, PixmapPtr bitmap
,
170 DrawablePtr drawable
, int w
, int h
, int x
, int y
)
172 ScreenPtr screen
= drawable
->pScreen
;
173 glamor_screen_private
*glamor_priv
= glamor_get_screen_private(screen
);
174 PixmapPtr pixmap
= glamor_get_drawable_pixmap(drawable
);
175 glamor_pixmap_private
*pixmap_priv
;
176 uint8_t *bitmap_data
= bitmap
->devPrivate
.ptr
;
177 int bitmap_stride
= bitmap
->devKind
;
178 glamor_program
*prog
;
179 RegionPtr clip
= gc
->pCompositeClip
;
183 INT16
*points
= NULL
;
187 if (w
* h
> MAXINT
/ (2 * sizeof(float)))
190 pixmap_priv
= glamor_get_pixmap_private(pixmap
);
191 if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv
))
194 glamor_make_current(glamor_priv
);
196 prog
= glamor_use_program_fill(drawable
, gc
,
197 &glamor_priv
->poly_glyph_blt_progs
,
198 &glamor_facet_poly_glyph_blt
);
202 glEnableVertexAttribArray(GLAMOR_VERTEX_POS
);
204 points
= glamor_get_vbo_space(screen
, w
* h
* sizeof(INT16
) * 2,
208 /* Note that because fb sets miTranslate in the GC, our incoming X
209 * and Y are in screen coordinate space (same for spans, but not
213 for (yy
= 0; yy
< h
; yy
++) {
214 uint8_t *bitmap_row
= bitmap_data
+ yy
* bitmap_stride
;
215 for (xx
= 0; xx
< w
; xx
++) {
216 #if BITMAP_BIT_ORDER == MSBFirst
217 if (bitmap_row
[xx
/ 8] & (128 >> xx
% 8) &&
219 if (bitmap_row
[xx
/ 8] & (1 << xx
% 8) &&
221 RegionContainsPoint(clip
,
231 glVertexAttribPointer(GLAMOR_VERTEX_POS
, 2, GL_SHORT
,
232 GL_FALSE
, 0, vbo_offset
);
234 glamor_put_vbo_space(screen
);
236 glamor_pixmap_loop(pixmap_priv
, box_index
) {
237 if (!glamor_set_destination_drawable(drawable
, box_index
, FALSE
, TRUE
,
238 prog
->matrix_uniform
, NULL
, NULL
))
241 glDrawArrays(GL_POINTS
, 0, num_points
);
247 glDisableVertexAttribArray(GLAMOR_VERTEX_POS
);
253 glamor_push_pixels(GCPtr pGC
, PixmapPtr pBitmap
,
254 DrawablePtr pDrawable
, int w
, int h
, int x
, int y
)
256 if (glamor_push_pixels_gl(pGC
, pBitmap
, pDrawable
, w
, h
, x
, y
))
259 miPushPixels(pGC
, pBitmap
, pDrawable
, w
, h
, x
, y
);