mirror of
https://github.com/Stichting-MINIX-Research-Foundation/xsrc.git
synced 2025-09-16 08:05:30 -04:00
331 lines
9.1 KiB
C
331 lines
9.1 KiB
C
/* $XConsortium: xf86fcache.c,v 1.4 95/01/05 20:25:04 kaleb Exp $ */
|
|
/* $XFree86: xc/programs/Xserver/hw/xfree86/accel/cache/xf86fcache.c,v 3.8 1995/07/07 15:38:25 dawes Exp $ */
|
|
/*
|
|
* Copyright 1992 by Kevin E. Martin, Chapel Hill, North Carolina.
|
|
*
|
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
* documentation for any purpose is hereby granted without fee, provided that
|
|
* the above copyright notice appear in all copies and that both that
|
|
* copyright notice and this permission notice appear in supporting
|
|
* documentation, and that the name of Kevin E. Martin not be used in
|
|
* advertising or publicity pertaining to distribution of the software
|
|
* without specific, written prior permission. Kevin E. Martin makes no
|
|
* representations about the suitability of this software for any purpose. It
|
|
* is provided "as is" without express or implied warranty.
|
|
*
|
|
* KEVIN E. MARTIN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
* EVENT SHALL KEVIN E. MARTIN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* Extracted from s3fcach.c and adapted to XFree86 in X11R6 by
|
|
* Hans Nasten. ( nasten@everyware.se ).
|
|
*/
|
|
|
|
/*
|
|
* Modified for the CyberVision 64 by Michael Teske
|
|
*/
|
|
|
|
#include "amiga.h"
|
|
#include "X.h"
|
|
#include "Xmd.h"
|
|
#include "Xproto.h"
|
|
#include "cfb.h"
|
|
#include "misc.h"
|
|
#include "windowstr.h"
|
|
#include "gcstruct.h"
|
|
#include "fontstruct.h"
|
|
#include "dixfontstr.h"
|
|
#include "xf86bcache.h"
|
|
#include "xf86fcache.h"
|
|
#include "amigaCV.h"
|
|
|
|
static CacheFont8Ptr xf86HeadFont = NULL;
|
|
static CachePool xf86FontPool = NULL;
|
|
static int xf86MaxWidth;
|
|
static int xf86MaxHeight;
|
|
static void (*xf86FontOpStippleFunc)(
|
|
#if NeedFunctionPrototypes
|
|
int, int, int, int, unsigned char *, int, Pixel
|
|
#endif
|
|
);
|
|
|
|
/*
|
|
* Init the font cache.
|
|
* The Cache Pool pointer is stored together with various other information
|
|
*/
|
|
|
|
void
|
|
xf86InitFontCache(
|
|
CachePool FontCache,
|
|
int MaxWidth,
|
|
int MaxHeight,
|
|
void (*FontOpStippleFunc)(
|
|
int, int, int, int, unsigned char *, int, Pixel
|
|
)
|
|
)
|
|
{
|
|
xf86FontPool = FontCache;
|
|
xf86MaxWidth = MaxWidth / 32;
|
|
xf86MaxHeight = MaxHeight;
|
|
xf86HeadFont = (CacheFont8Ptr) Xcalloc(sizeof(CacheFont8Rec));
|
|
xf86FontOpStippleFunc = FontOpStippleFunc;
|
|
}
|
|
|
|
/*
|
|
* Release all cache blocks to the block allocator.
|
|
*/
|
|
void xf86ReleaseFontCache(void)
|
|
{
|
|
CacheFont8Ptr CFptr;
|
|
int i;
|
|
|
|
/*
|
|
* The screen has been destroyed so we must go through
|
|
* all cached font blocks and return them to the cache
|
|
*/
|
|
ERROR_F(("Releasing font cache.\n"));
|
|
for (CFptr = xf86HeadFont; CFptr != NULL; CFptr=CFptr->next) {
|
|
if (CFptr->font) {
|
|
for (i = 0; i < 8; i++) {
|
|
if (CFptr->fblock[i] != NULL)
|
|
xf86ReleaseToCachePool( xf86FontPool, CFptr->fblock[i] );
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
* Remove a font from the font cache.
|
|
*/
|
|
void
|
|
xf86UnCacheFont8(FontPtr font)
|
|
{
|
|
int i;
|
|
CacheFont8Ptr ptr, last;
|
|
|
|
ERROR_F(("UnCach %d\n", font));
|
|
last = xf86HeadFont;
|
|
for (ptr = xf86HeadFont; ptr != NULL; ptr = ptr->next) {
|
|
if (ptr->font == font) {
|
|
for (i = 0; i < 8; i++)
|
|
if (ptr->fblock[i] != NULL)
|
|
xf86ReleaseToCachePool( xf86FontPool, ptr->fblock[i] );
|
|
|
|
if (ptr != xf86HeadFont) {
|
|
last->next = ptr->next;
|
|
xfree(ptr);
|
|
} else {
|
|
if (ptr->next != NULL) { /* move the head down */
|
|
xf86HeadFont=ptr->next;
|
|
xfree(ptr);
|
|
} else { /* one and only entry */
|
|
xf86HeadFont->font = NULL;
|
|
}
|
|
}
|
|
#ifdef DEBUG_FCACHE
|
|
for (ptr = xf86HeadFont; ptr != NULL; ptr = ptr->next)
|
|
__dolog("fonts %d\n", ptr->font);
|
|
#endif
|
|
return;
|
|
}
|
|
last=ptr;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Add a new font to the font cache.
|
|
*/
|
|
CacheFont8Ptr
|
|
xf86CacheFont8(FontPtr font)
|
|
{
|
|
int c;
|
|
unsigned long n;
|
|
unsigned char chr;
|
|
int width, height;
|
|
CharInfoPtr pci;
|
|
CacheFont8Ptr last, ret = xf86HeadFont;
|
|
|
|
|
|
if( !xf86FontPool ) /* No font cache available */
|
|
return( NULL );
|
|
|
|
/* XXX*/
|
|
/* font->refcnt++;*/
|
|
|
|
while (ret != NULL) {
|
|
if (ret->font == font) {
|
|
return ret;
|
|
}
|
|
last = ret;
|
|
ret = ret->next;
|
|
}
|
|
|
|
width = FONTMAXBOUNDS(font, rightSideBearing) -
|
|
FONTMINBOUNDS(font, leftSideBearing);
|
|
height = FONTMAXBOUNDS(font, ascent) + FONTMAXBOUNDS(font, descent);
|
|
|
|
if ((width > xf86MaxWidth) || (height > xf86MaxHeight) ||
|
|
(FONTFIRSTROW(font) != 0) || (FONTLASTROW(font) != 0) ||
|
|
(FONTLASTCOL(font) > 255))
|
|
return NULL;
|
|
|
|
if (xf86HeadFont->font == NULL)
|
|
ret = xf86HeadFont;
|
|
else
|
|
ret = (CacheFont8Ptr) Xcalloc(sizeof(CacheFont8Rec));
|
|
|
|
if (ret == NULL) {
|
|
return NULL;
|
|
}
|
|
ret->w = width;
|
|
ret->h = height;
|
|
ret->font = font;
|
|
|
|
/*
|
|
* We load all the font infos now, and the fonts themselves are demand
|
|
* loaded into the cache as 32 font bitmaps. This way we can load alot
|
|
* more things into cache at the expense of the cache management.
|
|
*/
|
|
|
|
for (c = 0; c < 256; c++) {
|
|
chr = (unsigned char)c;
|
|
GetGlyphs(font, 1, &chr, Linear8Bit, &n, &pci);
|
|
if (n == 0) {
|
|
ret->pci[c] = NULL;
|
|
|
|
} else {
|
|
ret->pci[c] = pci;
|
|
}
|
|
}
|
|
if (ret != xf86HeadFont)
|
|
last->next = ret;
|
|
|
|
/* test: */
|
|
ret->next = NULL;
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Load a block of 32 glyphs into a cache block requested
|
|
* from the block allocator.
|
|
*/
|
|
void
|
|
xf86loadFontBlock(CacheFont8Ptr fentry, int block)
|
|
{
|
|
int i, j, c;
|
|
unsigned char chr;
|
|
int nbyLine;
|
|
unsigned char *pb, *pbits;
|
|
unsigned char *pglyph;
|
|
int gWidth, gHeight;
|
|
int nbyGlyphWidth;
|
|
int nbyPadGlyph;
|
|
|
|
nbyLine = PixmapBytePad(fentry->w, 1);
|
|
|
|
__dolog("loading %d (%d) %d\n", fentry->font, block, fentry->fblock[block]);
|
|
|
|
pbits = (unsigned char *)ALLOCATE_LOCAL(nbyLine * fentry->h);
|
|
if (pbits != NULL &&
|
|
(fentry->fblock[block] = xf86AllocFromCachePool( xf86FontPool,
|
|
32 * fentry->w,
|
|
fentry->h )) != NULL) {
|
|
fentry->fblock[block]->reference = (pointer *) &(fentry->fblock[block]);
|
|
fentry->fblock[block]->lru = 0x7fffffff;
|
|
for (c = block * 32; c < (block * 32) + 32; c++) {
|
|
|
|
if (fentry->pci[c] != NULL) {
|
|
chr = (unsigned char)c;
|
|
|
|
pglyph = FONTGLYPHBITS(pglyphBase, fentry->pci[c]);
|
|
gWidth = GLYPHWIDTHPIXELS(fentry->pci[c]);
|
|
gHeight = GLYPHHEIGHTPIXELS(fentry->pci[c]);
|
|
if (gWidth && gHeight) {
|
|
nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(fentry->pci[c]);
|
|
nbyPadGlyph = PixmapBytePad(gWidth, 1);
|
|
|
|
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;
|
|
}
|
|
(xf86FontOpStippleFunc)( fentry->fblock[block]->x +
|
|
(c % 32) * fentry->w,
|
|
fentry->fblock[block]->y,
|
|
gWidth, gHeight,
|
|
pb, nbyGlyphWidth,
|
|
fentry->fblock[block]->id);
|
|
}
|
|
}
|
|
}
|
|
DEALLOCATE_LOCAL(pbits);
|
|
} else {
|
|
CacheFont8Ptr fptr;
|
|
Bool found = FALSE;
|
|
/*
|
|
* If we get here we are in deep trouble, half way through printing a
|
|
* string we have been unable to load a font block into the cache, the
|
|
* get Block function found no block of the right size, this is probably
|
|
* impossible but just to stop potential core dumps we shall do something
|
|
* stupid about it anyway we just throw away the font blocks of another
|
|
* font. Or even ourselves in desperate times!
|
|
* Unfortunatly this doesn't work if we use the preload code so the
|
|
* demand load makes more sense.
|
|
*/
|
|
if (pbits) DEALLOCATE_LOCAL(pbits);
|
|
__dolog("Time to write new font cache management\n");
|
|
for (fptr = xf86HeadFont; fptr != NULL; fptr= fptr->next)
|
|
if (fptr != fentry) {
|
|
for (i = 0; i < 8; i++)
|
|
if (fptr->fblock[i] != NULL) {
|
|
xf86ReleaseToCachePool( xf86FontPool, fptr->fblock[i] );
|
|
fptr->fblock[i] = NULL;
|
|
found = TRUE;
|
|
}
|
|
if (found)
|
|
break;
|
|
}
|
|
|
|
|
|
/* getting real desperate - this doesn't work with pre-loading */
|
|
if (!found) {
|
|
for (i = 0; i < 8; i++)
|
|
if (fentry->fblock[i] != NULL) {
|
|
xf86ReleaseToCachePool( xf86FontPool, fentry->fblock[i] );
|
|
fentry->fblock[i] = NULL;
|
|
}
|
|
}
|
|
xf86loadFontBlock(fentry, block);
|
|
return;
|
|
}
|
|
#ifdef DEBUG_FCACHE
|
|
for(fentry=xf86HeadFont;fentry != NULL;fentry=fentry->next)
|
|
if( fentry->font != NULL )
|
|
for (i = 0; i < 8; i++)
|
|
__dolog(("got %d (%d) %d x=%d y=%d w=%d h=%d\n",
|
|
fentry->font, i, fentry->fblock[i],
|
|
fentry->fblock[i] != NULL ? fentry->fblock[i]->x : 0,
|
|
fentry->fblock[i] != NULL ? fentry->fblock[i]->y : 0,
|
|
fentry->fblock[i] != NULL ? fentry->fblock[i]->w : 0,
|
|
fentry->fblock[i] != NULL ? fentry->fblock[i]->h : 0));
|
|
#endif
|
|
}
|