Esempio n. 1
0
/** Render string of 16-bit \a chars (foreground only) in \a pDrawable
 *  on the back-end server associated with \a pDrawable's screen.  If
 *  the offscreen optimization is enabled, only draw when \a pDrawable
 *  is at least partially visible. */
int dmxPolyText16(DrawablePtr pDrawable, GCPtr pGC,
		  int x, int y, int count, unsigned short *chars)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
    unsigned long  n, i;
    int            w;
    CharInfoPtr    charinfo[255];
    Drawable       draw;

    GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
	      (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
	      &n, charinfo);

    /* Calculate text width */
    w = 0;
    for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth;

    if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
	DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);

	XDrawString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
		      x, y, (XChar2b *)chars, count);
	dmxSync(dmxScreen, FALSE);
    }

    return x+w;
}
Esempio n. 2
0
static void
glamor_get_glyphs(FontPtr font, glamor_font_t *glamor_font,
                  int count, char *chars, Bool sixteen, CharInfoPtr *charinfo)
{
    unsigned long nglyphs;
    FontEncoding encoding;
    int char_step;
    int c;

    if (sixteen) {
        char_step = 2;
        if (FONTLASTROW(font) == 0)
            encoding = Linear16Bit;
        else
            encoding = TwoD16Bit;
    } else {
        char_step = 1;
        encoding = Linear8Bit;
    }

    /* If the font has a default character, then we shouldn't have to
     * worry about missing glyphs, so just get the whole string all at
     * once. Otherwise, we have to fetch chars one at a time to notice
     * missing ones.
     */
    if (glamor_font->default_char) {
        GetGlyphs(font, (unsigned long) count, (unsigned char *) chars,
                  encoding, &nglyphs, charinfo);

        /* Make sure it worked. There's a bug in libXfont through
         * version 1.4.7 which would cause it to fail when the font is
         * a 2D font without a first row, and the application sends a
         * 1-d request. In this case, libXfont would return zero
         * glyphs, even when the font had a default character.
         *
         * It's easy enough for us to work around that bug here by
         * simply checking the returned nglyphs and falling through to
         * the one-at-a-time code below. Not doing this check would
         * result in uninitialized memory accesses in the rendering code.
         */
        if (nglyphs == count)
            return;
    }

    for (c = 0; c < count; c++) {
        GetGlyphs(font, 1, (unsigned char *) chars,
                  encoding, &nglyphs, &charinfo[c]);
        if (!nglyphs)
            charinfo[c] = NULL;
        chars += char_step;
    }
}
Esempio n. 3
0
static void
glamor_get_glyphs(FontPtr font, glamor_font_t *glamor_font,
                  int count, char *chars, Bool sixteen, CharInfoPtr *charinfo)
{
    unsigned long nglyphs;
    FontEncoding encoding;
    int char_step;

    if (sixteen) {
        char_step = 2;
        if (FONTLASTROW(font) == 0)
            encoding = Linear16Bit;
        else
            encoding = TwoD16Bit;
    } else {
        char_step = 1;
        encoding = Linear8Bit;
    }

    /* If the font has a default character, then we don't have to
     * worry about missing glyphs, so just get the whole string all at
     * once. Otherwise, we have to fetch chars one at a time to notice
     * missing ones.
     */
    if (glamor_font->default_char) {
        GetGlyphs(font, (unsigned long) count, (unsigned char *) chars,
                  encoding, &nglyphs, charinfo);
    } else {
        int c;
        for (c = 0; c < count; c++) {
            GetGlyphs(font, 1, (unsigned char *) chars,
                      encoding, &nglyphs, &charinfo[c]);
            if (!nglyphs)
                charinfo[c] = NULL;
            chars += char_step;
        }
    }
}
Esempio n. 4
0
static int
MakeBitmapsFromFont(FontPtr pFont, int first, int count, int list_base)
{
    unsigned long i, nglyphs;
    CARD8 chs[2];               /* the font index we are going after */
    CharInfoPtr pci;
    int rv;                     /* return value */
    int encoding = (FONTLASTROW(pFont) == 0) ? Linear16Bit : TwoD16Bit;

    CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, FALSE));
    CALL_PixelStorei(GET_DISPATCH(),
                     (GL_UNPACK_LSB_FIRST, BITMAP_BIT_ORDER == LSBFirst));
    CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH, 0));
    CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, 0));
    CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, 0));
    CALL_PixelStorei(GET_DISPATCH(), (GL_UNPACK_ALIGNMENT, GLYPHPADBYTES));
    for (i = 0; i < count; i++) {
        chs[0] = (first + i) >> 8;      /* high byte is first byte */
        chs[1] = first + i;

        (*pFont->get_glyphs) (pFont, 1, chs, (FontEncoding) encoding,
                              &nglyphs, &pci);

        /*
         ** Define a display list containing just a glBitmap() call.
         */
        CALL_NewList(GET_DISPATCH(), (list_base + i, GL_COMPILE));
        if (nglyphs) {
            rv = __glXMakeBitmapFromGlyph(pFont, pci);
            if (rv) {
                return rv;
            }
        }
        CALL_EndList(GET_DISPATCH(), ());
    }
    return Success;
}
Esempio n. 5
0
static int
glamor_text(DrawablePtr drawable, GCPtr gc,
            glamor_font_t *glamor_font,
            glamor_program *prog,
            int x, int y,
            int count, char *s_chars, CharInfoPtr *charinfo,
            Bool sixteen)
{
    unsigned char *chars = (unsigned char *) s_chars;
    FontPtr font = gc->font;
    int off_x, off_y;
    int c;
    int nglyph;
    GLshort *v;
    char *vbo_offset;
    CharInfoPtr ci;
    int firstRow = font->info.firstRow;
    int firstCol = font->info.firstCol;
    int glyph_spacing_x = glamor_font->glyph_width_bytes * 8;
    int glyph_spacing_y = glamor_font->glyph_height;
    int box_x, box_y;
    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);

    /* Set the font as texture 1 */

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, glamor_font->texture_id);
    glUniform1i(prog->font_uniform, 1);

    /* Set up the vertex buffers for the font and destination */

    v = glamor_get_vbo_space(drawable->pScreen, count * (6 * sizeof (GLshort)), &vbo_offset);

    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
    glVertexAttribDivisor(GLAMOR_VERTEX_POS, 1);
    glVertexAttribPointer(GLAMOR_VERTEX_POS, 4, GL_SHORT, GL_FALSE,
                          6 * sizeof (GLshort), vbo_offset);

    glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
    glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 1);
    glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_SHORT, GL_FALSE,
                          6 * sizeof (GLshort), vbo_offset + 4 * sizeof (GLshort));

    /* Set the vertex coordinates */
    nglyph = 0;

    for (c = 0; c < count; c++) {
        if ((ci = *charinfo++)) {
            int     x1 = x + ci->metrics.leftSideBearing;
            int     y1 = y - ci->metrics.ascent;
            int     width = GLYPHWIDTHPIXELS(ci);
            int     height = GLYPHHEIGHTPIXELS(ci);
            int     tx, ty = 0;
            int     row = 0, col;

            x += ci->metrics.characterWidth;

            if (sixteen) {
                if (ci == glamor_font->default_char) {
                    row = glamor_font->default_row;
                    col = glamor_font->default_col;
                } else {
                    row = chars[0];
                    col = chars[1];
                }
                if (FONTLASTROW(font) != 0)
                    ty = (row - firstRow) * glyph_spacing_y;
                else
                    col += row << 8;
            } else {
                if (ci == glamor_font->default_char)
                    col = glamor_font->default_col;
                else
                    col = chars[0];
            }

            tx = (col - firstCol) * glyph_spacing_x;

            v[ 0] = x1;
            v[ 1] = y1;
            v[ 2] = width;
            v[ 3] = height;
            v[ 4] = tx;
            v[ 5] = ty;

            v += 6;
            nglyph++;
        }
        chars += 1 + sixteen;
    }
    glamor_put_vbo_space(drawable->pScreen);

    if (nglyph != 0) {

        glEnable(GL_SCISSOR_TEST);

        glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
            BoxPtr box = RegionRects(gc->pCompositeClip);
            int nbox = RegionNumRects(gc->pCompositeClip);

            glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y);

            /* Run over the clip list, drawing the glyphs
             * in each box
             */

            while (nbox--) {
                glScissor(box->x1 + off_x,
                          box->y1 + off_y,
                          box->x2 - box->x1,
                          box->y2 - box->y1);
                box++;
                glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nglyph);
            }
        }