Beispiel #1
0
fz_pixmap *
fz_render_stroked_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *stroke, const fz_irect *scissor)
{
	if (font->ft_face)
	{
		fz_matrix subpix_trm;
		unsigned char qe, qf;

		if (stroke->dash_len > 0)
			return NULL;
		(void)fz_subpixel_adjust(ctx, trm, &subpix_trm, &qe, &qf);
		return fz_render_ft_stroked_glyph_pixmap(ctx, font, gid, &subpix_trm, ctm, stroke);
	}
	return fz_render_glyph_pixmap(ctx, font, gid, trm, scissor);
}
Beispiel #2
0
static struct glyph *lookup_glyph(fz_font *font, int gid, float *xp, float *yp)
{
    fz_matrix trm, subpix_trm;
    unsigned char subx, suby;
    fz_pixmap *pixmap;
    struct key key;
    unsigned int pos;
    int w, h;

    /* match fitz's glyph cache quantization */
    fz_scale(&trm, g_font_size, -g_font_size);
    trm.e = *xp;
    trm.f = *yp;
    fz_subpixel_adjust(ctx, &trm, &subpix_trm, &subx, &suby);
    *xp = trm.e;
    *yp = trm.f;

    /*
     * Look it up in the table
     */

    memset(&key, 0, sizeof key);
    key.font = font;
    key.gid = gid;
    key.subx = subx;
    key.suby = suby;

    pos = lookup_table(&key);
    if (g_table[pos].key.font)
        return &g_table[pos].glyph;

    /*
     * Render the bitmap
     */

    glEnd();

    pixmap = fz_render_glyph_pixmap(ctx, font, gid, &subpix_trm, NULL);
    w = pixmap->w;
    h = pixmap->h;

    /*
     * Find an empty slot in the texture
     */

    if (g_table_load == (MAXGLYPHS * 3) / 4)
    {
        puts("font cache table full, clearing cache");
        clear_font_cache();
        pos = lookup_table(&key);
    }

    if (h + PADDING > g_cache_h || w + PADDING > g_cache_w)
        return NULL;

    if (g_cache_row_x + w + PADDING > g_cache_w)
    {
        g_cache_row_y += g_cache_row_h + PADDING;
        g_cache_row_x = PADDING;
        g_cache_row_h = 0;
    }
    if (g_cache_row_y + h + PADDING > g_cache_h)
    {
        puts("font cache texture full, clearing cache");
        clear_font_cache();
        pos = lookup_table(&key);
    }

    /*
     * Copy bitmap into texture
     */

    memcpy(&g_table[pos].key, &key, sizeof(struct key));
    g_table[pos].glyph.w = pixmap->w;
    g_table[pos].glyph.h = pixmap->h;
    g_table[pos].glyph.lsb = pixmap->x;
    g_table[pos].glyph.top = -pixmap->y;
    g_table[pos].glyph.s = g_cache_row_x;
    g_table[pos].glyph.t = g_cache_row_y;
    g_table_load ++;

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glPixelStorei(GL_UNPACK_ROW_LENGTH, pixmap->w);
    glTexSubImage2D(GL_TEXTURE_2D, 0, g_cache_row_x, g_cache_row_y, w, h,
                    GL_ALPHA, GL_UNSIGNED_BYTE, pixmap->samples);
    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);

    fz_drop_pixmap(ctx, pixmap);

    glBegin(GL_QUADS);

    g_cache_row_x += w + PADDING;
    if (g_cache_row_h < h + PADDING)
        g_cache_row_h = h + PADDING;

    return &g_table[pos].glyph;
}