Esempio n. 1
0
SDL_Surface *btext_render(bfont *f, const char *text, Uint32 bgval, Uint32 fgval, SDL_Rect *rect, Uint32 flags) {
	Uint32 length, width;
	Uint32 c, x, y;
	Uint32 start, lstart, blitoffset;
	Uint32 dataoffset;
	unsigned char *utext;
	SDL_Surface *surface;

	if(rect == NULL) {
		length = strlen(text);
		width = btext_calcWidth(f, text);
	} else {
		length = btext_clipTextToWidth(f, text, rect->w, 1);
		width = rect->w;
	}
	if(length == 0)
		return(NULL);

	surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, f->height, 32, RMASK, GMASK, BMASK, AMASK);
	if(surface == NULL)
		return(NULL);

	if(SDL_LockSurface(surface) < 0)
		return(NULL);

	utext = (unsigned char *)text;
	start = 0;
	for(c = 0; c < length; c++) {
		lstart = start;
		dataoffset = 0;
		if(utext[c] >= ' ' && utext[c] <= '\x7f') {
			for(y = 0; y < f->height; y++) {
				blitoffset = lstart;
				for(x = 0; x < (f->widths)[utext[c] - 32]; x++) {
					if((f->fontData)[utext[c] - 32][dataoffset] == 0) {
						if(!(flags & BTEXT_BGTRANSPARENT))
							PIXELS(surface)[blitoffset] = bgval;
					} else {
						if(!(flags & BTEXT_FGTRANSPARENT))
							PIXELS(surface)[blitoffset] = fgval;
					}
					blitoffset++;
					dataoffset++;
				}
				lstart += surface->w;
			}
			start += (f->widths)[text[c] - 32];
		}
	}

	SDL_UnlockSurface(surface);

	return(surface);
}
Esempio n. 2
0
GLYPH* font_getglyph(FONT *f, uint32_t ch)
{
    uint32_t hash = ch % 128;
    GLYPH *g = f->glyphs[hash], *s = g;
    if(g) {
        while(g->ucs4 != ~0) {
            if(g->ucs4 == ch) {
                return g;
            }
            g++;
        }

        uint32_t count = (uint32_t)(g - s);
        g = realloc(s, (count + 2) * sizeof(GLYPH));
        if(!g) {
            return NULL;
        }

        f->glyphs[hash] = g;
        g += count;
    } else {
        g = malloc(sizeof(GLYPH) * 2);
        if(!g) {
            return NULL;
        }

        f->glyphs[hash] = g;
    }

    g[1].ucs4 = ~0;
    FT_UInt index = FT_Get_Char_Index(f->face, ch);
    FT_Load_Glyph(f->face, index, FT_LOAD_RENDER);
    FT_GlyphSlotRec *p = f->face->glyph;

    g->ucs4 = ch;
    g->x = p->bitmap_left;
    g->y = PIXELS(f->face->size->metrics.ascender) - p->bitmap_top;
    g->width = p->bitmap.width;
    g->height = p->bitmap.rows;
    g->xadvance = (p->advance.x + (1 << 5)) >> 6;

    if(f->x + g->width > 512) {
        f->x = 0;
        f->y = f->my;
    }

    g->mx = f->x;
    g->my = f->y;

    glBindTexture(GL_TEXTURE_2D, f->texture);
    glTexSubImage2D(GL_TEXTURE_2D, 0, f->x, f->y, g->width, g->height, GL_ALPHA, GL_UNSIGNED_BYTE, p->bitmap.buffer);

    f->x += g->width;

    if(f->y + g->height > f->my) {
        f->my = f->y + g->height;
    }

    return g;
}
Esempio n. 3
0
int btext_renderToSurface(bfont *f, const char *text, Uint32 bgval, Uint32 fgval, SDL_Surface *surface, SDL_Rect *rect, Uint32 flags) {
	Uint32 length;
	Uint32 c, x, y;
	Uint32 start, lstart, blitoffset;
	Uint32 dataoffset;
	unsigned char *utext;

	if(rect->w == 0 || rect->w > surface->w - rect->x)
		rect->w = surface->w - rect->x; /* clip to surface dimensions */
	length = btext_clipTextToWidth(f, text, rect->w, 1);
	if(length == 0)
		return(-1);

	if(SDL_LockSurface(surface) < 0)
		return(-1);

	utext = (unsigned char *)text;
	start = (rect->y * surface->w) + rect->x;
	for(c = 0; c < length; c++) {
		lstart = start;
		dataoffset = 0;
		if(utext[c] >= ' ' && utext[c] <= '\x7f') {
			for(y = 0; y < f->height; y++) {
				blitoffset = lstart;
				for(x = 0; x < (f->widths)[utext[c] - 32]; x++) {
					if((f->fontData)[utext[c] - 32][dataoffset] == 0) {
						if(!(flags & BTEXT_BGTRANSPARENT))
							PIXELS(surface)[blitoffset] = bgval;
					} else {
						if(!(flags & BTEXT_FGTRANSPARENT))
							PIXELS(surface)[blitoffset] = fgval;
					}
					blitoffset++;
					dataoffset++;
				}
				lstart += surface->w;
			}
			start += (f->widths)[text[c] - 32];
		}
	}

	SDL_UnlockSurface(surface);

	return(0);
}
Esempio n. 4
0
bfont *btext_loadFromSurface(SDL_Surface *fontsurface) {
	bfont *f;
	Uint32 black;
	Uint32 x, y, c;
	Uint8 *data;
	Uint32 offsets[96];
	Uint32 pix, lstart, cpix;

	SDL_Surface *surface, *surface32;

	if(fontsurface->h < 2)
		return(NULL);

	/* convert surface to 32 bit for easier operation */
	surface32 = SDL_CreateRGBSurface(SDL_SWSURFACE, 1, 1, 32, RMASK, GMASK, BMASK, AMASK);
	if(surface32 == NULL)
		return(NULL);
	surface = SDL_ConvertSurface(fontsurface, surface32->format, SDL_SWSURFACE);
	SDL_FreeSurface(surface32);
	if(surface == NULL)
		return(NULL);

	f = malloc(sizeof(bfont));
	if(f == NULL) {
		SDL_FreeSurface(surface);
		return(NULL);
	}

	f->height = surface->h - 1;

	black = SDL_MapRGB(surface->format, 0, 0, 0);

	if(SDL_LockSurface(surface) < 0) {
		free(f);
		SDL_FreeSurface(surface);
		return(NULL);
	}
/* ----- Find Widths ----- */
	for(c = 0; c < 96; c++)
		(f->widths)[c] = 1;
	c = 0;
	offsets[0] = 0;
	for(x = 0; (int)x < surface->w; x++) {
		if(PIXELS(surface)[x] == black)
			((f->widths)[c])++;
		else {
			c++;
			if(c == 96)
				break;
			offsets[c] = offsets[c - 1] + (f->widths)[c - 1];
		}
	}
	if(c != 96) {
		free(f);
		return(NULL);
	}

	data = malloc(sizeof(Uint8) * (x + 1) * f->height);
	if(data == NULL) {
		free(f);
		return(NULL);
	}

/* ----- Convert data -----
 * Format:
 * fontdata[character][pixel data offset]
 * Pixel data is stored starting at each char's top left corner and goes to the right for width, then down for height
 * Pixel value is 0 for background and 1 for foreground
 */
	for(c = 0; c < 96; c++) {
		lstart = pix = surface->w + offsets[c]; /* skip top line and set pointer to top left pixel of char and set line start pointer */
		cpix = 0; /* set font data pointer to start */
		(f->fontData)[c] = &(data[offsets[c] * f->height]); /* allocate memory for glyph */
		for(y = 0; y < f->height; y++) {
			for(x = 0; x < (f->widths)[c]; x++) {
				if(PIXELS(surface)[pix] == black) {
					(f->fontData)[c][cpix] = 0;
					cpix++;
				} else {
					(f->fontData)[c][cpix] = 1;
					cpix++;
				}
				pix++; /* next pixel */
			}
			lstart = pix = lstart + surface->w; /* next line and update line start pointer */
		}
	}

	SDL_UnlockSurface(surface);
	SDL_FreeSurface(surface);

	return(f);
}