/* ** Make a single GL bitmap from a single X glyph */ static int __glXMakeBitmapFromGlyph(FontPtr font, CharInfoPtr pci) { int i, j; int widthPadded; /* width of glyph in bytes, as padded by X */ int allocBytes; /* bytes to allocate to store bitmap */ int w; /* width of glyph in bits */ int h; /* height of glyph */ register unsigned char *pglyph; register unsigned char *p; unsigned char *allocbuf; #define __GL_CHAR_BUF_SIZE 2048 unsigned char buf[__GL_CHAR_BUF_SIZE]; w = GLYPHWIDTHPIXELS(pci); h = GLYPHHEIGHTPIXELS(pci); widthPadded = GLYPHWIDTHBYTESPADDED(pci); /* ** Use the local buf if possible, otherwise malloc. */ allocBytes = widthPadded * h; if (allocBytes <= __GL_CHAR_BUF_SIZE) { p = buf; allocbuf = 0; } else { p = (unsigned char *) malloc(allocBytes); if (!p) return BadAlloc; allocbuf = p; } /* ** We have to reverse the picture, top to bottom */ pglyph = FONTGLYPHBITS(FONTGLYPHS(font), pci) + (h - 1) * widthPadded; for (j = 0; j < h; j++) { for (i = 0; i < widthPadded; i++) { p[i] = pglyph[i]; } pglyph -= widthPadded; p += widthPadded; } CALL_Bitmap(GET_DISPATCH(), (w, h, -pci->metrics.leftSideBearing, pci->metrics.descent, pci->metrics.characterWidth, 0, allocbuf ? allocbuf : buf)); free(allocbuf); return Success; #undef __GL_CHAR_BUF_SIZE }
void fbImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppciInit, pointer pglyphBase) { FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); CharInfoPtr *ppci; CharInfoPtr pci; unsigned char *pglyph; /* pointer bits in glyph */ int gWidth, gHeight; /* width and height of glyph */ FbStride gStride; /* stride of glyph */ Bool opaque; int n; int gx, gy; void (*glyph) (FbBits *, FbStride, int, FbStip *, FbBits, int, int); FbBits *dst = 0; FbStride dstStride = 0; int dstBpp = 0; int dstXoff = 0, dstYoff = 0; glyph = 0; if (pPriv->and == 0) { fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); switch (dstBpp) { case 8: glyph = fbGlyph8; break; case 16: glyph = fbGlyph16; break; case 24: glyph = fbGlyph24; break; case 32: glyph = fbGlyph32; break; } } x += pDrawable->x; y += pDrawable->y; if (TERMINALFONT(pGC->font) && !glyph ) { opaque = TRUE; } else { int xBack, widthBack; int yBack, heightBack; ppci = ppciInit; n = nglyph; widthBack = 0; while (n--) widthBack += (*ppci++)->metrics.characterWidth; xBack = x; if (widthBack < 0) { xBack += widthBack; widthBack = -widthBack; } yBack = y - FONTASCENT(pGC->font); heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font); fbSolidBoxClipped(pDrawable, fbGetCompositeClip(pGC), xBack, yBack, xBack + widthBack, yBack + heightBack, fbAnd(GXcopy, pPriv->bg, pPriv->pm), fbXor(GXcopy, pPriv->bg, pPriv->pm)); opaque = FALSE; } ppci = ppciInit; while (nglyph--) { pci = *ppci++; pglyph = FONTGLYPHBITS(pglyphBase, pci); gWidth = GLYPHWIDTHPIXELS(pci); gHeight = GLYPHHEIGHTPIXELS(pci); if (gWidth && gHeight) { gx = x + pci->metrics.leftSideBearing; gy = y - pci->metrics.ascent; if (glyph && gWidth <= sizeof(FbStip) * 8 && fbGlyphIn(fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) { (*glyph) (dst + (gy + dstYoff) * dstStride, dstStride, dstBpp, (FbStip *) pglyph, pPriv->fg, gx + dstXoff, gHeight); } else { gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip); fbPutXYImage(pDrawable, fbGetCompositeClip(pGC), pPriv->fg, pPriv->bg, pPriv->pm, GXcopy, opaque, gx, gy, gWidth, gHeight, (FbStip *) pglyph, gStride, 0); } } x += pci->metrics.characterWidth; } }
void fbPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase) { FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); CharInfoPtr pci; unsigned char *pglyph; /* pointer bits in glyph */ int gx, gy; int gWidth, gHeight; /* width and height of glyph */ FbStride gStride; /* stride of glyph */ void (*glyph) (FbBits *, FbStride, int, FbStip *, FbBits, int, int); FbBits *dst = 0; FbStride dstStride = 0; int dstBpp = 0; int dstXoff = 0, dstYoff = 0; glyph = 0; if (pGC->fillStyle == FillSolid && pPriv->and == 0) { fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); switch (dstBpp) { case 8: glyph = fbGlyph8; break; case 16: glyph = fbGlyph16; break; case 24: glyph = fbGlyph24; break; case 32: glyph = fbGlyph32; break; } } x += pDrawable->x; y += pDrawable->y; while (nglyph--) { pci = *ppci++; pglyph = FONTGLYPHBITS(pglyphBase, pci); gWidth = GLYPHWIDTHPIXELS(pci); gHeight = GLYPHHEIGHTPIXELS(pci); if (gWidth && gHeight) { gx = x + pci->metrics.leftSideBearing; gy = y - pci->metrics.ascent; if (glyph && gWidth <= sizeof(FbStip) * 8 && fbGlyphIn(fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) { (*glyph) (dst + (gy + dstYoff) * dstStride, dstStride, dstBpp, (FbStip *) pglyph, pPriv->xor, gx + dstXoff, gHeight); } else { gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip); fbPushImage(pDrawable, pGC, (FbStip *) pglyph, gStride, 0, gx, gy, gWidth, gHeight); } } x += pci->metrics.characterWidth; } }
void miPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase) { int width, height; PixmapPtr pPixmap; int nbyLine; /* bytes per line of padded pixmap */ FontPtr pfont; GCPtr pGCtmp; int i; int j; unsigned char *pbits; /* buffer for PutImage */ unsigned char *pb; /* temp pointer into buffer */ CharInfoPtr pci; /* currect char info */ unsigned char *pglyph; /* pointer bits in glyph */ int gWidth, gHeight; /* width and height of glyph */ int nbyGlyphWidth; /* bytes per scanline of glyph */ int nbyPadGlyph; /* server padded line of glyph */ XID gcvals[3]; if (pGC->miTranslate) { x += pDrawable->x; y += pDrawable->y; } pfont = pGC->font; width = FONTMAXBOUNDS(pfont,rightSideBearing) - FONTMINBOUNDS(pfont,leftSideBearing); height = FONTMAXBOUNDS(pfont,ascent) + FONTMAXBOUNDS(pfont,descent); pPixmap = (*pDrawable->pScreen->CreatePixmap)(pDrawable->pScreen, width, height, 1); if (!pPixmap) return; pGCtmp = GetScratchGC(1, pDrawable->pScreen); if (!pGCtmp) { (*pDrawable->pScreen->DestroyPixmap)(pPixmap); return; } gcvals[0] = GXcopy; gcvals[1] = 1; gcvals[2] = 0; DoChangeGC(pGCtmp, GCFunction|GCForeground|GCBackground, gcvals, 0); nbyLine = BitmapBytePad(width); pbits = (unsigned char *)ALLOCATE_LOCAL(height*nbyLine); if (!pbits) { (*pDrawable->pScreen->DestroyPixmap)(pPixmap); FreeScratchGC(pGCtmp); return; } while(nglyph--) { pci = *ppci++; pglyph = FONTGLYPHBITS(pglyphBase, pci); gWidth = GLYPHWIDTHPIXELS(pci); gHeight = GLYPHHEIGHTPIXELS(pci); if (gWidth && gHeight) { nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci); nbyPadGlyph = BitmapBytePad(gWidth); if (nbyGlyphWidth == nbyPadGlyph #if GLYPHPADBYTES != 4 && (((int) pglyph) & 3) == 0 #endif ) { pb = pglyph; } else { for (i=0, pb = pbits; i<gHeight; i++, pb = pbits+(i*nbyPadGlyph)) for (j = 0; j < nbyGlyphWidth; j++) *pb++ = *pglyph++; pb = pbits; } if ((pGCtmp->serialNumber) != (pPixmap->drawable.serialNumber)) ValidateGC((DrawablePtr)pPixmap, pGCtmp); (*pGCtmp->ops->PutImage)((DrawablePtr)pPixmap, pGCtmp, pPixmap->drawable.depth, 0, 0, gWidth, gHeight, 0, XYBitmap, (char *)pb); if ((pGC->serialNumber) != (pDrawable->serialNumber)) ValidateGC(pDrawable, pGC); (*pGC->ops->PushPixels)(pGC, pPixmap, pDrawable, gWidth, gHeight, x + pci->metrics.leftSideBearing, y - pci->metrics.ascent); } x += pci->metrics.characterWidth; } (*pDrawable->pScreen->DestroyPixmap)(pPixmap); DEALLOCATE_LOCAL(pbits); FreeScratchGC(pGCtmp); }
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); } }
static Bool glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc, int start_x, int y, unsigned int nglyph, CharInfoPtr *ppci, void *pglyph_base) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv; glamor_program *prog; RegionPtr clip = gc->pCompositeClip; int box_index; pixmap_priv = glamor_get_pixmap_private(pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; glamor_make_current(glamor_priv); prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_glyph_blt_progs, &glamor_facet_poly_glyph_blt); if (!prog) goto bail; glEnableVertexAttribArray(GLAMOR_VERTEX_POS); start_x += drawable->x; y += drawable->y; glamor_pixmap_loop(pixmap_priv, box_index) { int x; int n; int num_points, max_points; INT16 *points = NULL; int off_x, off_y; char *vbo_offset; glamor_set_destination_drawable(drawable, box_index, FALSE, TRUE, prog->matrix_uniform, &off_x, &off_y); max_points = 500; num_points = 0; x = start_x; for (n = 0; n < nglyph; n++) { CharInfoPtr charinfo = ppci[n]; int w = GLYPHWIDTHPIXELS(charinfo); int h = GLYPHHEIGHTPIXELS(charinfo); uint8_t *glyphbits = FONTGLYPHBITS(NULL, charinfo); if (w && h) { int glyph_x = x + charinfo->metrics.leftSideBearing; int glyph_y = y - charinfo->metrics.ascent; int glyph_stride = GLYPHWIDTHBYTESPADDED(charinfo); int xx, yy; for (yy = 0; yy < h; yy++) { uint8_t *glyph = glyphbits; for (xx = 0; xx < w; glyph += ((xx&7) == 7), xx++) { int pt_x_i = glyph_x + xx; int pt_y_i = glyph_y + yy; if (!(*glyph & (1 << (xx & 7)))) continue; if (!RegionContainsPoint(clip, pt_x_i, pt_y_i, NULL)) continue; if (!num_points) { points = glamor_get_vbo_space(screen, max_points * (2 * sizeof (INT16)), &vbo_offset); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, 0, vbo_offset); } *points++ = pt_x_i; *points++ = pt_y_i; num_points++; if (num_points == max_points) { glamor_put_vbo_space(screen); glDrawArrays(GL_POINTS, 0, num_points); num_points = 0; } } glyphbits += glyph_stride; } } x += charinfo->metrics.characterWidth; } if (num_points) { glamor_put_vbo_space(screen); glDrawArrays(GL_POINTS, 0, num_points); } }
void LeoPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pGlyphBase) { LeoPtr pLeo = LeoGetScreenPrivate (pGC->pScreen); LeoCommand0 *lc0 = pLeo->lc0; LeoDraw *ld0 = pLeo->ld0; RegionPtr clip; CharInfoPtr pci; int w, h, x0, y0, i; unsigned int *bits; BoxRec box; int curw = -1; unsigned int *fbf; unsigned char *fb; int height, width; clip = cfbGetCompositeClip(pGC); /* compute an approximate (but covering) bounding box */ box.x1 = 0; if (ppci[0]->metrics.leftSideBearing < 0) box.x1 = ppci[0]->metrics.leftSideBearing; h = nglyph - 1; w = ppci[h]->metrics.rightSideBearing; while (--h >= 0) w += ppci[h]->metrics.characterWidth; box.x2 = w; box.y1 = -FONTMAXBOUNDS(pGC->font,ascent); box.y2 = FONTMAXBOUNDS(pGC->font,descent); box.x1 += pDrawable->x + x; box.x2 += pDrawable->x + x; box.y1 += pDrawable->y + y; box.y2 += pDrawable->y + y; switch (RECT_IN_REGION(pGC->pScreen, clip, &box)) { case rgnPART: if (REGION_NUM_RECTS(clip) == 1) { ld0->vclipmin = (clip->extents.y1 << 16) | clip->extents.x1; ld0->vclipmax = ((clip->extents.y2 - 1) << 16) | (clip->extents.x2 - 1); break; } cfbPolyGlyphBlt8 (pDrawable, pGC, x, y, nglyph, ppci, pGlyphBase); case rgnOUT: return; default: clip = NULL; break; } x += pDrawable->x; y += pDrawable->y; lc0->fontt = 1; lc0->addrspace = LEO_ADDRSPC_FONT_OBGR; ld0->fg = pGC->fgPixel; if (pGC->alu != GXcopy) ld0->rop = leoRopTable[pGC->alu]; if (pGC->planemask != 0xffffff) ld0->planemask = pGC->planemask; height = pLeo->height; width = pLeo->width; fb = (unsigned char *)pLeo->fb; while (nglyph--) { pci = *ppci++; w = GLYPHWIDTHPIXELS (pci); h = GLYPHHEIGHTPIXELS (pci); if (!w || !h) goto next_glyph; x0 = x + pci->metrics.leftSideBearing; y0 = y - pci->metrics.ascent; /* We're off the screen to the left, making our way * back onto the screen. */ if((x0 >> 31) == -1) goto next_glyph; /* We walked off the screen (to the right or downwards) * or we started there, we're never going to work our * way back so stop now. */ if(x0 >= width || y0 >= height) break; bits = (unsigned int *) pci->bits; if (w != curw) { curw = w; if (w) lc0->fontmsk = 0xffffffff << (32 - w); else lc0->fontmsk = 0; } fbf = (unsigned *)(fb + (y0 << 13) + (x0 << 2)); if (y0 + h <= height) for (i = 0; i < h; i++) { *fbf = *bits++; fbf += 2048; } else for (i = 0; i < h && y0 + i < height; i++) { *fbf = *bits++; fbf += 2048; } next_glyph: x += pci->metrics.characterWidth; } lc0->addrspace = LEO_ADDRSPC_OBGR; if (pGC->alu != GXcopy) ld0->rop = LEO_ATTR_RGBE_ENABLE|LEO_ROP_NEW; if (pGC->planemask != 0xffffff) ld0->planemask = 0xffffff; if (clip) { ld0->vclipmin = 0; ld0->vclipmax = pLeo->vclipmax; } }
void fbImageGlyphBlt(DrawablePtr drawable, GCPtr gc, int x, int y, unsigned int nglyph, CharInfoPtr * ppciInit, pointer glyphs) { FbGCPrivPtr pgc = fb_gc(gc); CharInfoPtr *ppci; CharInfoPtr pci; unsigned char *pglyph; /* pointer bits in glyph */ int gWidth, gHeight; /* width and height of glyph */ FbStride gStride; /* stride of glyph */ bool opaque; int n; int gx, gy; void (*raster)(FbBits *, FbStride, int, FbStip *, FbBits, int, int); FbBits *dst = 0; FbStride dstStride = 0; int dstBpp = 0; int dstXoff = 0, dstYoff = 0; DBG(("%s x %d\n", __FUNCTION__, nglyph)); raster = 0; if (pgc->and == 0) { dstBpp = drawable->bitsPerPixel; switch (dstBpp) { case 8: raster = fbGlyph8; break; case 16: raster = fbGlyph16; break; case 32: raster = fbGlyph32; break; } } x += drawable->x; y += drawable->y; if (TERMINALFONT(gc->font) && !raster) { opaque = TRUE; } else { int xBack, widthBack; int yBack, heightBack; ppci = ppciInit; n = nglyph; widthBack = 0; while (n--) widthBack += (*ppci++)->metrics.characterWidth; xBack = x; if (widthBack < 0) { xBack += widthBack; widthBack = -widthBack; } yBack = y - FONTASCENT(gc->font); heightBack = FONTASCENT(gc->font) + FONTDESCENT(gc->font); fbSolidBoxClipped(drawable, gc, xBack, yBack, xBack + widthBack, yBack + heightBack); opaque = FALSE; } ppci = ppciInit; while (nglyph--) { pci = *ppci++; pglyph = FONTGLYPHBITS(glyphs, pci); gWidth = GLYPHWIDTHPIXELS(pci); gHeight = GLYPHHEIGHTPIXELS(pci); if (gWidth && gHeight) { gx = x + pci->metrics.leftSideBearing; gy = y - pci->metrics.ascent; if (raster && gWidth <= sizeof(FbStip) * 8 && fbGlyphIn(gc, gx, gy, gWidth, gHeight)) { fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); raster(dst + (gy + dstYoff) * dstStride, dstStride, dstBpp, (FbStip *) pglyph, pgc->fg, gx + dstXoff, gHeight); } else { gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip); fbPutXYImage(drawable, gc, pgc->fg, pgc->bg, pgc->pm, GXcopy, opaque, gx, gy, gWidth, gHeight, (FbStip *) pglyph, gStride, 0); } } x += pci->metrics.characterWidth; } }
void fbPolyGlyphBlt(DrawablePtr drawable, GCPtr gc, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, pointer glyphs) { FbGCPrivPtr pgc = fb_gc(gc); CharInfoPtr pci; unsigned char *pglyph; /* pointer bits in glyph */ int gx, gy; int gWidth, gHeight; /* width and height of glyph */ FbStride gStride; /* stride of glyph */ void (*raster) (FbBits *, FbStride, int, FbStip *, FbBits, int, int); FbBits *dst = 0; FbStride dstStride = 0; int dstBpp = 0; int dstXoff = 0, dstYoff = 0; DBG(("%s x %d\n", __FUNCTION__, nglyph)); raster = 0; if (gc->fillStyle == FillSolid && pgc->and == 0) { dstBpp = drawable->bitsPerPixel; switch (dstBpp) { case 8: raster = fbGlyph8; break; case 16: raster = fbGlyph16; break; case 32: raster = fbGlyph32; break; } } x += drawable->x; y += drawable->y; while (nglyph--) { pci = *ppci++; pglyph = FONTGLYPHBITS(glyphs, pci); gWidth = GLYPHWIDTHPIXELS(pci); gHeight = GLYPHHEIGHTPIXELS(pci); if (gWidth && gHeight) { gx = x + pci->metrics.leftSideBearing; gy = y - pci->metrics.ascent; if (raster && gWidth <= sizeof(FbStip) * 8 && fbGlyphIn(gc, gx, gy, gWidth, gHeight)) { fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); raster(dst + (gy + dstYoff) * dstStride, dstStride, dstBpp, (FbStip *) pglyph, pgc->xor, gx + dstXoff, gHeight); } else { gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip); fbPushImage(drawable, gc, (FbStip *)pglyph, gStride, 0, gx, gy, gWidth, gHeight); } } x += pci->metrics.characterWidth; } }