2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
|
|
|
|
In this file we have GC level replacements for PolyText8/16,
|
|
|
|
ImageText8/16, ImageGlyphBlt and PolyGlyphBlt for TE (fixed) fonts.
|
|
|
|
The idea is that everything in this file is device independent.
|
|
|
|
The mentioned GCOps are merely wrappers for XAAGlyphBltTEColorExpansion
|
|
|
|
which calculates the boxes containing arbitrarily clipped text
|
|
|
|
and passes them to the TEGlyphRenderer which will usually be a lower
|
|
|
|
level XAA function which renders these clipped glyphs using
|
|
|
|
the basic color expansion functions exported by the chipset driver.
|
|
|
|
The TEGlyphRenderer itself may optionally be driver supplied to
|
|
|
|
facilitate work-arounds/optimizations at a higher level than usual.
|
|
|
|
|
|
|
|
v1.0 - Mark Vojkovich (mvojkovi@ucsd.edu)
|
|
|
|
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
#ifdef HAVE_XORG_CONFIG_H
|
|
|
|
#include <xorg-config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "misc.h"
|
|
|
|
#include "xf86.h"
|
|
|
|
#include "xf86_OSproc.h"
|
|
|
|
|
|
|
|
#include <X11/X.h>
|
|
|
|
#include <X11/fonts/font.h>
|
|
|
|
#include "scrnintstr.h"
|
|
|
|
#include "dixfontstr.h"
|
|
|
|
#include "xf86str.h"
|
|
|
|
#include "xaa.h"
|
|
|
|
#include "xaalocal.h"
|
|
|
|
#include "gcstruct.h"
|
|
|
|
#include "pixmapstr.h"
|
|
|
|
|
|
|
|
static void XAAGlyphBltTEColorExpansion(ScrnInfoPtr pScrn, int xInit,
|
2012-06-10 07:21:05 -06:00
|
|
|
int yInit, FontPtr font, int fg, int bg,
|
|
|
|
int rop, unsigned int planemask,
|
|
|
|
RegionPtr cclip, int nglyph,
|
|
|
|
unsigned char *gBase,
|
|
|
|
CharInfoPtr * ppci);
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
|
|
|
|
GC level replacements for PolyText8/16 and ImageText8/16
|
|
|
|
for TE fonts when using color expansion.
|
|
|
|
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
int
|
2012-06-10 07:21:05 -06:00
|
|
|
XAAPolyText8TEColorExpansion(DrawablePtr pDraw,
|
|
|
|
GCPtr pGC, int x, int y, int count, char *chars)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
|
|
|
|
unsigned long n;
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
(*pGC->font->get_glyphs) (pGC->font, (unsigned long) count,
|
|
|
|
(unsigned char *) chars, Linear8Bit, &n,
|
|
|
|
infoRec->CharInfo);
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
/* we have divorced XAAGlyphBltTEColorExpansion from the drawable */
|
2012-06-10 07:21:05 -06:00
|
|
|
if (n)
|
|
|
|
XAAGlyphBltTEColorExpansion(infoRec->pScrn, x + pDraw->x, y + pDraw->y,
|
|
|
|
pGC->font, pGC->fgPixel, -1, pGC->alu,
|
|
|
|
pGC->planemask, pGC->pCompositeClip, n,
|
|
|
|
FONTGLYPHS(pGC->font), infoRec->CharInfo);
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
return (x + (n * FONTMAXBOUNDS(pGC->font, characterWidth)));
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2012-06-10 07:21:05 -06:00
|
|
|
XAAPolyText16TEColorExpansion(DrawablePtr pDraw,
|
|
|
|
GCPtr pGC,
|
|
|
|
int x, int y, int count, unsigned short *chars)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
|
|
|
|
unsigned long n;
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
(*pGC->font->get_glyphs) (pGC->font, (unsigned long) count,
|
|
|
|
(unsigned char *) chars,
|
|
|
|
(FONTLASTROW(pGC->font) ==
|
|
|
|
0) ? Linear16Bit : TwoD16Bit, &n,
|
|
|
|
infoRec->CharInfo);
|
2006-11-26 11:13:41 -07:00
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
if (n)
|
|
|
|
XAAGlyphBltTEColorExpansion(infoRec->pScrn, x + pDraw->x, y + pDraw->y,
|
|
|
|
pGC->font, pGC->fgPixel, -1, pGC->alu,
|
|
|
|
pGC->planemask, pGC->pCompositeClip, n,
|
|
|
|
FONTGLYPHS(pGC->font), infoRec->CharInfo);
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
return (x + (n * FONTMAXBOUNDS(pGC->font, characterWidth)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-06-10 07:21:05 -06:00
|
|
|
XAAImageText8TEColorExpansion(DrawablePtr pDraw,
|
|
|
|
GCPtr pGC, int x, int y, int count, char *chars)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
|
|
|
|
unsigned long n;
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
if (!RegionNumRects(pGC->pCompositeClip))
|
|
|
|
return;
|
2006-11-26 11:13:41 -07:00
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
(*pGC->font->get_glyphs) (pGC->font, (unsigned long) count,
|
|
|
|
(unsigned char *) chars, Linear8Bit, &n,
|
|
|
|
infoRec->CharInfo);
|
2006-11-26 11:13:41 -07:00
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
if (n)
|
|
|
|
XAAGlyphBltTEColorExpansion(infoRec->pScrn, x + pDraw->x, y + pDraw->y,
|
|
|
|
pGC->font, pGC->fgPixel, pGC->bgPixel,
|
|
|
|
GXcopy, pGC->planemask, pGC->pCompositeClip,
|
|
|
|
n, FONTGLYPHS(pGC->font),
|
|
|
|
infoRec->CharInfo);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-06-10 07:21:05 -06:00
|
|
|
XAAImageText16TEColorExpansion(DrawablePtr pDraw,
|
|
|
|
GCPtr pGC,
|
|
|
|
int x, int y, int count, unsigned short *chars)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
|
|
|
|
unsigned long n;
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
if (!RegionNumRects(pGC->pCompositeClip))
|
|
|
|
return;
|
|
|
|
|
|
|
|
(*pGC->font->get_glyphs) (pGC->font, (unsigned long) count,
|
|
|
|
(unsigned char *) chars,
|
|
|
|
(FONTLASTROW(pGC->font) ==
|
|
|
|
0) ? Linear16Bit : TwoD16Bit, &n,
|
|
|
|
infoRec->CharInfo);
|
|
|
|
|
|
|
|
if (n)
|
|
|
|
XAAGlyphBltTEColorExpansion(infoRec->pScrn, x + pDraw->x, y + pDraw->y,
|
|
|
|
pGC->font, pGC->fgPixel, pGC->bgPixel,
|
|
|
|
GXcopy, pGC->planemask, pGC->pCompositeClip,
|
|
|
|
n, FONTGLYPHS(pGC->font),
|
|
|
|
infoRec->CharInfo);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
|
|
|
|
GC level replacements for ImageGlyphBlt and PolyGlyphBlt for
|
|
|
|
TE fonts when using color expansion.
|
|
|
|
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
void
|
2012-06-10 07:21:05 -06:00
|
|
|
XAAImageGlyphBltTEColorExpansion(DrawablePtr pDrawable,
|
|
|
|
GCPtr pGC,
|
|
|
|
int xInit, int yInit,
|
|
|
|
unsigned int nglyph,
|
|
|
|
CharInfoPtr * ppci, pointer pglyphBase)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
if (!RegionNumRects(pGC->pCompositeClip))
|
|
|
|
return;
|
2006-11-26 11:13:41 -07:00
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
XAAGlyphBltTEColorExpansion(infoRec->pScrn, xInit + pDrawable->x,
|
|
|
|
yInit + pDrawable->y, pGC->font, pGC->fgPixel,
|
|
|
|
pGC->bgPixel, GXcopy, pGC->planemask,
|
|
|
|
pGC->pCompositeClip, nglyph,
|
|
|
|
(unsigned char *) pglyphBase, ppci);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-06-10 07:21:05 -06:00
|
|
|
XAAPolyGlyphBltTEColorExpansion(DrawablePtr pDrawable,
|
|
|
|
GCPtr pGC,
|
|
|
|
int xInit, int yInit,
|
|
|
|
unsigned int nglyph,
|
|
|
|
CharInfoPtr * ppci, pointer pglyphBase)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
|
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
if (!RegionNumRects(pGC->pCompositeClip))
|
|
|
|
return;
|
2006-11-26 11:13:41 -07:00
|
|
|
|
2012-06-10 07:21:05 -06:00
|
|
|
XAAGlyphBltTEColorExpansion(infoRec->pScrn, xInit + pDrawable->x,
|
|
|
|
yInit + pDrawable->y, pGC->font, pGC->fgPixel,
|
|
|
|
-1, pGC->alu, pGC->planemask,
|
|
|
|
pGC->pCompositeClip, nglyph,
|
|
|
|
(unsigned char *) pglyphBase, ppci);
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
|
|
|
|
|
|
XAAGlyphBltTEColorExpansion -
|
|
|
|
|
|
|
|
This guy computes the clipped pieces of text and sends it to
|
|
|
|
the lower-level function which will handle acceleration of
|
|
|
|
arbitrarily clipped text.
|
|
|
|
|
|
|
|
********************************************************************/
|
|
|
|
|
|
|
|
static void
|
2012-06-10 07:21:05 -06:00
|
|
|
XAAGlyphBltTEColorExpansion(ScrnInfoPtr pScrn,
|
|
|
|
int xInit, int yInit,
|
|
|
|
FontPtr font,
|
|
|
|
int fg, int bg,
|
|
|
|
int rop,
|
|
|
|
unsigned int planemask,
|
|
|
|
RegionPtr cclip,
|
|
|
|
int nglyph,
|
|
|
|
unsigned char *gBase, CharInfoPtr * ppci)
|
2006-11-26 11:13:41 -07:00
|
|
|
{
|
|
|
|
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
|
|
|
|
int skippix, skipglyphs;
|
|
|
|
int Left, Right, Top, Bottom;
|
|
|
|
int LeftEdge, RightEdge, ytop, ybot;
|
2010-12-05 08:36:02 -07:00
|
|
|
int nbox = RegionNumRects(cclip);
|
|
|
|
BoxPtr pbox = RegionRects(cclip);
|
2012-06-10 07:21:05 -06:00
|
|
|
unsigned int **glyphs = NULL;
|
2006-11-26 11:13:41 -07:00
|
|
|
int glyphWidth = FONTMAXBOUNDS(font, characterWidth);
|
|
|
|
|
|
|
|
/* find the size of the box */
|
|
|
|
Left = xInit;
|
|
|
|
Right = Left + (glyphWidth * nglyph);
|
|
|
|
Top = yInit - FONTASCENT(font);
|
2012-06-10 07:21:05 -06:00
|
|
|
Bottom = yInit + FONTDESCENT(font);
|
2006-11-26 11:13:41 -07:00
|
|
|
|
|
|
|
/* get into the first band that may contain part of our string */
|
2012-06-10 07:21:05 -06:00
|
|
|
while (nbox && (Top >= pbox->y2)) {
|
|
|
|
pbox++;
|
|
|
|
nbox--;
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* stop when the lower edge of the box is beyond our string */
|
2012-06-10 07:21:05 -06:00
|
|
|
while (nbox && (Bottom > pbox->y1)) {
|
|
|
|
LeftEdge = max(Left, pbox->x1);
|
|
|
|
RightEdge = min(Right, pbox->x2);
|
|
|
|
|
|
|
|
if (RightEdge > LeftEdge) { /* we have something to draw */
|
|
|
|
unsigned int *fallbackBits = NULL;
|
|
|
|
|
|
|
|
ytop = max(Top, pbox->y1);
|
|
|
|
ybot = min(Bottom, pbox->y2);
|
|
|
|
|
|
|
|
if ((skippix = LeftEdge - Left)) {
|
|
|
|
skipglyphs = skippix / glyphWidth;
|
|
|
|
skippix %= glyphWidth;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
skipglyphs = 0;
|
|
|
|
|
|
|
|
if (!glyphs) {
|
|
|
|
int count;
|
|
|
|
|
|
|
|
glyphs = (unsigned int **) (infoRec->PreAllocMem);
|
|
|
|
|
|
|
|
for (count = 0; count < nglyph; count++) {
|
|
|
|
glyphs[count] = (unsigned int *)
|
|
|
|
FONTGLYPHBITS(gBase, *ppci++);
|
|
|
|
if (!glyphs[count]) {
|
|
|
|
/* Glyphs with NULL bits do exist in the wild.
|
|
|
|
Replace with blank bits in that case */
|
|
|
|
|
|
|
|
if (!fallbackBits) {
|
|
|
|
int fontHeight = Bottom - Top + 1;
|
|
|
|
|
|
|
|
fallbackBits = calloc(glyphWidth * fontHeight, 1);
|
|
|
|
if (!fallbackBits)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
glyphs[count] = fallbackBits;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* our new unrolled TE code only writes DWORDS at a time
|
|
|
|
so it can read up to 6 characters past the last one
|
|
|
|
we're displaying */
|
|
|
|
glyphs[count + 0] = glyphs[0];
|
|
|
|
glyphs[count + 1] = glyphs[0];
|
|
|
|
glyphs[count + 2] = glyphs[0];
|
|
|
|
glyphs[count + 3] = glyphs[0];
|
|
|
|
glyphs[count + 4] = glyphs[0];
|
|
|
|
glyphs[count + 5] = glyphs[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* x, y, w, h, skipleft, skiptop, glyphp, glyphWidth, fg, bg, rop, pm */
|
|
|
|
|
|
|
|
(*infoRec->TEGlyphRenderer) (pScrn,
|
|
|
|
LeftEdge, ytop, RightEdge - LeftEdge,
|
|
|
|
ybot - ytop, skippix, ytop - Top,
|
|
|
|
glyphs + skipglyphs, glyphWidth, fg,
|
|
|
|
bg, rop, planemask);
|
|
|
|
|
|
|
|
free(fallbackBits);
|
|
|
|
}
|
|
|
|
|
|
|
|
nbox--;
|
|
|
|
pbox++;
|
2006-11-26 11:13:41 -07:00
|
|
|
}
|
|
|
|
}
|