예제 #1
0
static PyObject*
validate_dict_key( Member* keymember, PyObject* owner, PyObject* dict )
{
    PyObject* key;
    PyObject* value;
    Py_ssize_t pos = 0;
    PyDictPtr newptr( PyDict_New() );
    if( !newptr )
        return 0;
    while( PyDict_Next( dict, &pos, &key, &value ) )
    {
        PyObjectPtr keyptr( member_validate( keymember, owner, _py_null, key ) );
        if( !keyptr )
            return 0;
        PyObjectPtr valptr( newref( value ) );
        if( !newptr.set_item( keyptr, valptr ) )
            return 0;
    }
    return newptr.release();
}
예제 #2
0
파일: ttf.c 프로젝트: goblinhack/MundusMeus
font *
ttf_write_tga (char *name, int32_t pointsize)
{
    uint32_t rmask, gmask, bmask, amask;
    double glyph_per_row;
    char filename[200];
    SDL_Surface *dst;
    uint32_t height;
    uint32_t width;
    double maxx;
    double maxy[TTF_GLYPH_MAX];
    uint32_t c;
    int x;
    int y;
    double h;
    font *f;

    snprintf(filename, sizeof(filename), "%s_pointsize%u.tga",
             name, pointsize);

    if (tex_find(filename)) {
        return (0);
    }

    /*
     * x glyphs horizontally and y vertically.
     */
    glyph_per_row = 16;

    f = ttf_new(name, pointsize, TTF_STYLE_NORMAL);
    if (!f) {
        ERR("could not create font %s", name);
    }

    maxx = 0;
    memset(maxy, 0, sizeof(maxy));

    /*
     * Find the largest font glyph pointsize.
     */
    x = 0;
    y = 0;
    height = 0;

    for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) {

        if (f->tex[c].image) {
            maxx = max(maxx, f->tex[c].image->w);
            maxy[y] = max(maxy[y], f->tex[c].image->h);
        }

        if (++x >= glyph_per_row) {
            x = 0;
            height += maxy[y];
            y++;
        }
    }

    if (!maxx) {
        ERR("no glyphs in font %s", name);
    }

    width = glyph_per_row * maxx;

    if (MULTIPLE_BITS(width)) {
        width = nextpoweroftwo(width);
    }

    height += 40;

    if (MULTIPLE_BITS(height)) {
        height = nextpoweroftwo(height);
    }

    /*
     * Make a large surface for all glyphs.
     */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
    rmask = 0xff000000;
    gmask = 0x00ff0000;
    bmask = 0x0000ff00;
    amask = 0x000000ff;
#else
    rmask = 0x000000ff;
    gmask = 0x0000ff00;
    bmask = 0x00ff0000;
    amask = 0xff000000;
#endif

    dst = SDL_CreateRGBSurface(0, width, height, 32,
                               rmask, gmask, bmask, amask);
    if (!dst) {
        ERR("no surface created for size %dx%d font %s", width, height, name);
    }

    newptr(dst, "SDL_CreateRGBSurface");

    /*
     * Blit each glyph to the large surface.
     */
    x = 0;
    y = 0;
    h = 0;

    for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) {

        if (f->tex[c].image) {
            SDL_Rect dstrect = { maxx * x, h, maxx, maxy[y] };

            SDL_BlitSurface(f->tex[c].image, 0, dst, &dstrect);
        }

        if (++x >= glyph_per_row) {
            x = 0;
            h += maxy[y];
            y++;
        }
    }

    /*
     * Convert the black border smoothing that ttf adds into alpha.
     */
    {
        double x;
        double y;

        for (x = 0; x < dst->w; x++) {
            for (y = 0; y < dst->h; y++) {

                color c;

                c = getPixel(dst, x, y);

                if ((c.a == 255) &&
                    (c.r == 255) &&
                    (c.g == 255) &&
                    (c.b == 255)) {
                    /*
                     * Do nothing.
                     */
                } else if ((c.a == 0) &&
                    (c.r == 0) &&
                    (c.g == 0) &&
                    (c.b == 0)) {
                    /*
                     * Do nothing.
                     */
                } else {
                    /*
                     * Convery gray to white with alpha.
                     */
                    c.a = (c.r + c.g + c.b) / 3;
                    c.r = 255;
                    c.g = 255;
                    c.b = 255;
                }

                putPixel(dst, x, y, c);
            }
        }
    }

#define MAX_TEXTURE_HEIGHT 4096

    if (dst->h > MAX_TEXTURE_HEIGHT) {
        ERR("ttf is too large");
    }

    uint8_t filled_pixel_row[MAX_TEXTURE_HEIGHT] = {0};

    /*
     * What the hell am I doing here? The ttf library returns incorrect
     * boounds for the top and bottom of glyphs, so I'm looking for a line of
     * no pixels above and below each glyph so I can really find the texture
     * bounds of a glyph. This allows squeezing of text together.
     */
    {
        int x;
        int y;

        for (y = 0; y < dst->h; y++) {
            for (x = 0; x < dst->w; x++) {
                color c;
                c = getPixel(dst, x, y);
                if (c.r || c.g || c.b || c.a) {
                    filled_pixel_row[y] = true;
                    break;
                }
            }
        }
    }

    /*
     * Work our the tex co-ords for each glyph in the large tex.
     */
    x = 0;
    y = 0;
    h = 0;

    int d1_max = 0;
    int d2_max = 0;

    for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) {

        {
            int y = (h + (h + f->glyphs[c].height)) / 2;

            int miny = y;
            int maxy = y;

            for (;;) {
                if (!filled_pixel_row[miny]) {
                    break;
                }

                miny--;
                if (miny <= 0) {
                    break;
                }
            }

            for (;;) {
                if (!filled_pixel_row[maxy]) {
                    break;
                }

                maxy++;
                if (maxy >= MAX_TEXTURE_HEIGHT - 1) {
                    break;
                }
            }

            int d1 = y - miny;
            if (d1 > d1_max) {
                d1_max = d1;
            }

            int d2 = maxy - y;
            if (d2 > d2_max) {
                d2_max = d2;
            }
        }

        if (++x >= glyph_per_row) {
            x = 0;
            h += maxy[y];
            y++;
        }
    }

    x = 0;
    y = 0;
    h = 0;

    for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) {

        f->glyphs[c].texMinX =
                        (double)(x * maxx) / (double)dst->w;
        f->glyphs[c].texMaxX =
                        (double)((x * maxx) + f->glyphs[c].width) /
                        (double)dst->w;

        {
            int y = (h + (h + f->glyphs[c].height)) / 2;

            int y1 = y - d1_max;
            int y2 = y + d2_max;

            if (y1 < 0) {
                y1 = 0;
            }

            f->glyphs[c].texMinY =
                            (double)(y1) /
                            (double)dst->h;
            f->glyphs[c].texMaxY =
                            (double)(y2) /
                            (double)dst->h;
        }

        if (++x >= glyph_per_row) {
            x = 0;
            h += maxy[y];
            y++;
        }
    }

    SDL_LockSurface(dst);
    stbi_write_tga(filename, dst->w, dst->h, STBI_rgb_alpha, dst->pixels);
    SDL_UnlockSurface(dst);

    texp tex;
    tex = tex_from_surface(dst, filename, filename);
    if (!tex) {
        ERR("could not convert %s to tex", filename);
    }

    /*
     * Work our the tex co-ords for each glyph in the large tex.
     */
    x = 0;
    y = 0;
    h = 0;

    for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) {

        f->tex[c].image = dst;
        f->tex[c].tex = tex_get_gl_binding(tex);
    }

    /*
     * Save the glyph data.
     */
    snprintf(filename, sizeof(filename), "%s_pointsize%u.data",
             name, pointsize);

    FILE *out = fopen(filename, "w");

    fwrite(f->glyphs, sizeof(f->glyphs), 1, out);

    fclose(out);

    printf("wrote %s\n",filename);
    return (f);
}
예제 #3
0
파일: update.c 프로젝트: sharugupta/OpenUH
static int
_elf_update_pointers(Elf *elf, char *outbuf, size_t len) {
    Elf_Scn *scn;
    Scn_Data *sd;
    char *data, *rawdata;

    elf_assert(elf);
    elf_assert(elf->e_data);
    elf_assert(!elf->e_parent);
    elf_assert(!elf->e_unmap_data);
    elf_assert(elf->e_kind == ELF_K_ELF);
    elf_assert(len >= EI_NIDENT);

    /* resize memory images */
    if (len <= elf->e_dsize) {
	/* don't shorten the memory image */
	data = elf->e_data;
    }
    else if ((data = (char*)realloc(elf->e_data, len))) {
	elf->e_dsize = len;
    }
    else {
	seterr(ERROR_IO_2BIG);
	return -1;
    }
    if (elf->e_rawdata == elf->e_data) {
	/* update frozen raw image */
	memcpy(data, outbuf, len);
	elf->e_data = elf->e_rawdata = data;
	/* cooked data is stored outside the raw image */
	return 0;
    }
    if (elf->e_rawdata) {
	/* update raw image */
	if (!(rawdata = (char*)realloc(elf->e_rawdata, len))) {
	    seterr(ERROR_IO_2BIG);
	    return -1;
	}
	memcpy(rawdata, outbuf, len);
	elf->e_rawdata = rawdata;
    }
    if (data == elf->e_data) {
	/* nothing more to do */
	return 0;
    }
    /* adjust internal pointers */
    if (elf->e_ehdr && !elf->e_free_ehdr) {
	elf_assert(ptrinside(elf->e_ehdr, elf->e_data, elf->e_dsize));
	newptr(elf->e_ehdr, elf->e_data, data);
    }
    if (elf->e_phdr && !elf->e_free_phdr) {
	elf_assert(ptrinside(elf->e_phdr, elf->e_data, elf->e_dsize));
	newptr(elf->e_phdr, elf->e_data, data);
    }
    for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
	elf_assert(scn->s_magic == SCN_MAGIC);
	elf_assert(scn->s_elf == elf);
	if ((sd = scn->s_data_1)) {
	    elf_assert(sd->sd_magic == DATA_MAGIC);
	    elf_assert(sd->sd_scn == scn);
	    if (sd->sd_memdata && !sd->sd_free_data) {
		elf_assert(ptrinside(sd->sd_memdata, elf->e_data, elf->e_dsize));
		if (sd->sd_data.d_buf == sd->sd_memdata) {
		    newptr(sd->sd_memdata, elf->e_data, data);
		    sd->sd_data.d_buf = sd->sd_memdata;
		}
		else {
		    newptr(sd->sd_memdata, elf->e_data, data);
		}
	    }
	}
	if ((sd = scn->s_rawdata)) {
	    elf_assert(sd->sd_magic == DATA_MAGIC);
	    elf_assert(sd->sd_scn == scn);
	    if (sd->sd_memdata && sd->sd_free_data) {
		size_t off, len;

		if (elf->e_class == ELFCLASS32) {
		    off = scn->s_shdr32.sh_offset;
		    len = scn->s_shdr32.sh_size;
		}
#if __LIBELF64
		else if (elf->e_class == ELFCLASS64) {
		    off = scn->s_shdr64.sh_offset;
		    len = scn->s_shdr64.sh_size;
		}
#endif /* __LIBELF64 */
		else {
		    seterr(ERROR_UNIMPLEMENTED);
		    return -1;
		}
		if (!(rawdata = (char*)realloc(sd->sd_memdata, len))) {
		    seterr(ERROR_IO_2BIG);
		    return -1;
		}
		memcpy(rawdata, outbuf + off, len);
		if (sd->sd_data.d_buf == sd->sd_memdata) {
		    sd->sd_data.d_buf = rawdata;
		}
		sd->sd_memdata = rawdata;
	    }
	}
    }
    elf->e_data = data;
    return 0;
}
예제 #4
0
파일: ttf.c 프로젝트: goblinhack/MundusMeus
static void
ttf_set_color_key (SDL_Surface *glyph_surface,
                   GLfloat *texcoord,
                   uint8_t ckr,
                   uint8_t ckg,
                   uint8_t ckb,
                   double *width,
                   double *height)
{
    SDL_Surface *tmp;
    uint32_t colorkey;

    /*
     * Use the surface width and height expanded to powers of 2
     */
    *width = glyph_surface->w;
    *height = glyph_surface->h;

    texcoord[0] = 0; // Min X
    texcoord[1] = 0; // Min Y
    texcoord[2] =
        (GLfloat)(((double)glyph_surface->w) / ((double)*width));  // Max X
    texcoord[3] =
        (GLfloat)(((double)glyph_surface->h) / ((double)*height)); // Max Y

    tmp = SDL_CreateRGBSurface(glyph_surface->flags,
                               *width, *height, 32,
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
                               0xFF000000,
                               0x00FF0000,
                               0x0000FF00,
                               0x000000FF
#else
                               0x000000FF,
                               0x0000FF00,
                               0x00FF0000,
                               0xFF000000
#endif
                            );

    if (!tmp) {
        ERR("Failed to make RGB surface size %f %f: %s",
            *width, *height, SDL_GetError());
        SDL_ClearError();
        return;
    }

    newptr(tmp, "SDL_CreateRGBSurface");

    /*
     * Set up so that colorkey pixels become transparent
     */
    colorkey = SDL_MapRGBA(tmp->format, 0, 0, 0, 0);
    SDL_FillRect(tmp, 0, colorkey);

    colorkey = SDL_MapRGBA(glyph_surface->format, ckr, ckg, ckb, 0);
#if (SDL_MAJOR_VERSION == 2)
    SDL_SetColorKey(glyph_surface, SDL_TRUE, colorkey);
#else
    SDL_SetColorKey(glyph_surface, SDL_SRCCOLORKEY, colorkey);
#endif

    SDL_FreeSurface(tmp);
    oldptr(tmp);
}