Beispiel #1
0
CAMLprim value has_ps_glyph_names(value f)
{
  CAMLparam1(f);
  FT_Face face;

  face = *(FT_Face *)Data_custom_val(f);

  CAMLreturn(Val_bool(FT_Has_PS_Glyph_Names(face) != 0));
};
static int
checkExtraEncoding(FT_Face face, char *encoding_name, int found)
{
    int c;

    if(strcasecmp(encoding_name, "iso10646-1") == 0) {
        if(doISO10646_1_encoding && find_cmap(FONT_ENCODING_UNICODE, -1, -1, face)) {
            int found = 0;
             /* Export as Unicode if there are at least 15 BMP
               characters that are not a space or ignored. */
            for(c = 0x21; c < 0x10000; c++) {
                if(CODE_IGNORED(c))
                    continue;
                if(FT_Get_Char_Index(face, c) > 0)
                    found++;
                if(found >= 15)
                    return 1;
            }
            return 0;
        } else
            return 0;
    } else if(strcasecmp(encoding_name, "microsoft-symbol") == 0) {
        if(find_cmap(FONT_ENCODING_TRUETYPE,
                     TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS,
                     face))
            return 1;
        else
            return 0;
    } else if(strcasecmp(encoding_name, "adobe-fontspecific") == 0) {
        if(!found) {
            if(FT_Has_PS_Glyph_Names(face))
                return 1;
            else
                return 0;
        } else
            return 0;
    } else {
        fprintf(stderr, "Unknown extra encoding %s\n", encoding_name);
        return 0;
    }
}
Beispiel #3
0
int
FTPickMapping(char *xlfd, int length, char *filename, FT_Face face,
              FTMappingPtr tm)
{
    FontEncPtr encoding;
    FontMapPtr mapping;
    FT_CharMap cmap;
    int ftrc;
    int symbol = 0;
    const char *enc, *reg;
    char *encoding_name = 0;
    char buf[20];

    if(xlfd)
      encoding_name = FontEncFromXLFD(xlfd, length);
    if(!encoding_name)
        encoding_name = "iso8859-1";

    symbol = FTEncFontSpecific(encoding_name);

#if XFONT_BDFFORMAT
    ftrc = FT_Get_BDF_Charset_ID(face, &enc, &reg);
#else
    ftrc = -1;
#endif
    if(ftrc == 0) {
        /* Disable reencoding for non-Unicode fonts.  This will
           currently only work for BDFs. */
        if(strlen(enc) + strlen(reg) > 18)
            goto native;
        strcpy(buf, enc);
        strcat(buf, "-");
        strcat(buf, reg);
        ErrorF("%s %s\n", buf, encoding_name);
        if(strcasecmp(buf, "iso10646-1") != 0) {
            if(strcasecmp(buf, encoding_name) == 0)
                goto native;
            return BadFontFormat;
        }
    } else if(symbol) {
        ftrc = FT_Select_Charmap(face, ft_encoding_adobe_custom);
        if(ftrc == 0)
            goto native;
    }

    encoding = FontEncFind(encoding_name, filename);
    if(symbol && encoding == NULL)
        encoding = FontEncFind("microsoft-symbol", filename);
    if(encoding == NULL) {
        ErrorF("FreeType: couldn't find encoding '%s' for '%s'\n",
               encoding_name, filename);
        return BadFontName;
    }

    if(FT_Has_PS_Glyph_Names(face)) {
        for(mapping = encoding->mappings; mapping; mapping = mapping->next) {
            if(mapping->type == FONT_ENCODING_POSTSCRIPT) {
                tm->named = 1;
                tm->base = 0;
                tm->mapping = mapping;
                return Successful;
            }
        }
    }
    
    for(mapping = encoding->mappings; mapping; mapping = mapping->next) {
        if(find_cmap(mapping->type, mapping->pid, mapping->eid, face, 
                     &cmap)) {
            tm->named = 0;
            tm->cmap = cmap;
            if(symbol) {
                /* deal with an undocumented ``feature'' of the
                   Microsft-Symbol cmap */
                TT_OS2 *os2;
                os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
                if(os2)
                    tm->base = os2->usFirstCharIndex - 0x20;
                else
                    tm->base = 0;
            } else
                tm->base = 0;
            tm->mapping = mapping;
            return Successful;
        }
    }
    
    return BadFontFormat;

  native:
    tm->named = 0;
    tm->cmap = face->charmap;
    tm->base = 0;
    tm->mapping = NULL;
    return Successful;
}
Beispiel #4
0
static int
glnames(
	GLYPH *glyph_list
)
{
#define MAX_NAMELEN	1024

#ifdef XP_PSTEXT
	char          buf[1024];
	long          i;
    FT_Error      error;

#ifdef XP_ONLY_BLOCKS
    extern unsigned long xp_font_block_offset;
    extern FTFontPtr     xp_xtf;
    int                  bc; /* block counter */
    
    
    /* FixMe: This code should use PsOut_Get_FreeType_Glyph_Name() instead of
     * duplicating the code
     */
    for( bc = xp_font_block_offset ; bc < (xp_font_block_offset+256) ; bc++ ) {
        /* Remap X11 font index to FreeType font index */
        i = FTRemap(face, &xp_xtf->mapping, bc);
        
        if( i >= face->num_glyphs )
          continue;
#else
	for(i=0; i < face->num_glyphs; i++) {
#endif /* XP_ONLY_BLOCKS */
        if( FT_Has_PS_Glyph_Names(face) ) {
          error = FT_Get_Glyph_Name(face, i, buf, MAX_NAMELEN);
        }
        else
        {
          error = -1;
        }
    
		if( error ) {
          /* Check for unicode mapping
           * See Adobe document "Unicode and Glyph Names"
           * (http://partners.adobe.com/asn/tech/type/unicodegn.jsp)
           */
          if( (xp_xtf->mapping.mapping->type == FONT_ENCODING_UNICODE) &&
              (i < 0xFFFE) )
          {
            sprintf(buf, "uni%04lx", i);
          }
          else
          {
            sprintf(buf, "ch%02lx", i);
          }
		}
		glyph_list[i].name = strdup(buf);
		if(ISDBG(FT)) fprintf(stderr, "%d has name %s\n", i, buf);
		if (glyph_list[i].name == NULL) {
			fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
			exit(255);
		}
	}

	return 0;
#else
	char bf[1024];
	long i;

	if( ! FT_HAS_GLYPH_NAMES(face) ) {
		WARNING_1 fprintf(stderr, "Font has no glyph names\n");
		return 1;
	}

	for(i=0; i < face->num_glyphs; i++) {
		if( FT_Get_Glyph_Name(face, i, bf, MAX_NAMELEN) || bf[0]==0 ) {
			sprintf(bf, "_g_%d", i);
			WARNING_2 fprintf(stderr,
				"Glyph No. %d has no postscript name, becomes %s\n", i, bf);
		}
		glyph_list[i].name = strdup(bf);
		if(ISDBG(FT)) fprintf(stderr, "%d has name %s\n", i, bf);
		if (glyph_list[i].name == NULL) {
			fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
			exit(255);
		}
	}

	return 0;
#endif /* XP_PSTEXT */
}

/*
 * Get the metrics of the glyphs.
 */

static void
glmetrics(
	GLYPH *glyph_list
)
{
	GLYPH          *g;
	int i;
	FT_Glyph_Metrics *met;
	FT_BBox bbox;
	FT_Glyph gly;

#ifdef XP_ONLY_BLOCKS
    extern unsigned long xp_font_block_offset;
    extern FTFontPtr     xp_xtf;
    int                  bc; /* block counter */
    
    for( bc = xp_font_block_offset ; bc < (xp_font_block_offset+256) ; bc++ ) {
        /* Remap X11 font index to FreeType font index */
        i = FTRemap(face, &xp_xtf->mapping, bc);
        
        if( i >= face->num_glyphs )
          continue;
        
#else
	for(i=0; i < face->num_glyphs; i++) {
#endif /* XP_ONLY_BLOCKS */
		g = &(glyph_list[i]);

		if( FT_Load_Glyph(face, i, FT_LOAD_NO_BITMAP|FT_LOAD_NO_SCALE) ) {
			fprintf(stderr, "Can't load glyph %s, skipped\n", g->name);
			continue;
		}

		met = &face->glyph->metrics;

		if(FT_HAS_HORIZONTAL(face)) {
			g->width = met->horiAdvance;
			g->lsb = met->horiBearingX;
		} else {
			WARNING_2 fprintf(stderr, "Glyph %s has no horizontal metrics, guessed them\n", g->name);
			g->width = met->width;
			g->lsb = 0;
		}

		if( FT_Get_Glyph(face->glyph, &gly) ) {
			fprintf(stderr, "Can't access glyph %s bbox, skipped\n", g->name);
			continue;
		}

		FT_Glyph_Get_CBox(gly, ft_glyph_bbox_unscaled, &bbox);
		g->xMin = bbox.xMin;
		g->yMin = bbox.yMin;
		g->xMax = bbox.xMax;
		g->yMax = bbox.yMax;

		g->ttf_pathlen = face->glyph->outline.n_points;
	}
}

/*
 * Get the original encoding of the font. 
 * Returns 1 for if the original encoding is Unicode, 2 if the
 * original encoding is other 16-bit, 0 if 8-bit.
 */

static int
glenc(
	GLYPH *glyph_list,
	int *encoding,
	int *unimap
)
{
#ifdef XP_PSTEXT
	int                  i,
                         e;
	unsigned             code;
    extern FTFontPtr     xp_xtf;
    extern unsigned long xp_font_block_offset;
        
    enc_found = 1;
    enc_type  = 0;
    
	for(i=0; i<ENCTABSZ; i++) {
		if(encoding[i] != -1)
			continue;

        /* Remap X11 font index to FreeType font index */
        code = FTRemap(face, &xp_xtf->mapping, xp_font_block_offset+i);

		if(code == 0)
			continue; /* .notdef */

		encoding[i] = code;
	}
        
	return enc_type;
#else
	int i, e;
	unsigned code;

	if(ISDBG(FT)) 
		for(e=0; e < face->num_charmaps; e++) {
			fprintf(stderr, "found encoding pid=%d eid=%d\n", 
				face->charmaps[e]->platform_id,
				face->charmaps[e]->encoding_id);
		}

	if(enc_found)
		goto populate_map;

	enc_type = 0;

	/* first check for an explicit PID/EID */

	if(force_pid != -1) {
		for(e=0; e < face->num_charmaps; e++) {
			if(face->charmaps[e]->platform_id == force_pid
			&& face->charmaps[e]->encoding_id == force_eid) {
				WARNING_1 fprintf(stderr, "Found Encoding PID=%d/EID=%d\n", 
					force_pid, force_eid);
				if( FT_Set_Charmap(face, face->charmaps[e]) ) {
					fprintf(stderr, "**** Cannot set charmap in FreeType ****\n");
					exit(1);
				}
				enc_type = 1;
				goto populate_map;
			}
		}
		fprintf(stderr, "*** TTF encoding table PID=%d/EID=%d not found\n", 
			force_pid, force_eid);
		exit(1);
	}

	/* next check for a direct Adobe mapping */

	if(!forcemap) {
		for(e=0; e < face->num_charmaps; e++) {
			if(face->charmaps[e]->encoding == ft_encoding_adobe_custom) {
				WARNING_1 fputs("Found Adobe Custom Encoding\n", stderr);
				if( FT_Set_Charmap(face, face->charmaps[e]) ) {
					fprintf(stderr, "**** Cannot set charmap in FreeType ****\n");
					exit(1);
				}
				goto populate_map;
			}
		}
	}

	for(e=0; e < face->num_charmaps; e++) {
		if(face->charmaps[e]->platform_id == 3) {
			switch(face->charmaps[e]->encoding_id) {
			case 0:
				WARNING_1 fputs("Found Symbol Encoding\n", stderr);
				break;
			case 1:
				WARNING_1 fputs("Found Unicode Encoding\n", stderr);
				enc_type = 1;
				break;
			default:
				WARNING_1 {
					fprintf(stderr,
					"****MS Encoding ID %d not supported****\n",
						face->charmaps[e]->encoding_id);
					fputs("Treating it like Symbol encoding\n", stderr);
				}
				break;
			}
			break;
		}
	}
	if(e >= face->num_charmaps) {
		WARNING_1 fputs("No Microsoft encoding, using first encoding available\n", stderr);
		e = 0;
	}
	
	if( FT_Set_Charmap(face, face->charmaps[e]) ) {
		fprintf(stderr, "**** Cannot set charmap in FreeType ****\n");
		exit(1);
	}

populate_map:
	enc_found = 1;
	for(i=0; i<ENCTABSZ; i++) {
		if(encoding[i] != -1)
			continue;
		if(enc_type == 1 || forcemap) {
			code = unimap[i];
			if(code == (unsigned) -1)
				continue;
		} else
			code = i;

		code = FT_Get_Char_Index(face, code);
		if(0 && ISDBG(FT)) fprintf(stderr, "code of %3d is %3d\n", i, code);
		if(code == 0)
			continue; /* .notdef */
		encoding[i] = code;
	}

	return enc_type;
#endif /* XP_PSTEXT */
}
static int
checkEncoding(FT_Face face, char *encoding_name)
{
    FontEncPtr encoding;
    FontMapPtr mapping;
    int i, j, c, koi8;
    char *n;

    encoding = FontEncFind(encoding_name, NULL);
    if(!encoding)
        return 0;

    /* An encoding is ``small'' if one of the following is true:
         - it is linear and has no more than 256 codepoints; or
         - it is a matrix encoding and has no more than one column.

       For small encodings using Unicode indices, we require perfect
       coverage except for CODE_IGNORED and KOI-8 IBM-PC compatibility.

       For large encodings, we require coverage up to bigEncodingFuzz.

       For encodings using PS names (currently Adobe Standard and
       Adobe Symbol only), we require perfect coverage. */


    if(FT_Has_PS_Glyph_Names(face)) {
        for(mapping = encoding->mappings; mapping; mapping = mapping->next) {
            if(mapping->type == FONT_ENCODING_POSTSCRIPT) {
                if(encoding->row_size > 0) {
                    for(i = encoding->first; i < encoding->size; i++) {
                        for(j = encoding->first_col;
                            j < encoding->row_size;
                            j++) {
                            n = FontEncName((i<<8) | j, mapping);
                            if(n && FT_Get_Name_Index(face, n) == 0) {
                                return 0;
                            }
                        }
                    }
                    return 1;
                } else {
                    for(i = encoding->first; i < encoding->size; i++) {
                        n = FontEncName(i, mapping);
                        if(n && FT_Get_Name_Index(face, n) == 0) {
                            return 0;
                        }
                    }
                    return 1;
                }
            }
        }
    }

    for(mapping = encoding->mappings; mapping; mapping = mapping->next) {
        if(find_cmap(mapping->type, mapping->pid, mapping->eid, face)) {
            int total = 0, failed = 0;
            if(encoding->row_size > 0) {
                int estimate =
                    (encoding->size - encoding->first) *
                    (encoding->row_size - encoding->first_col);
                for(i = encoding->first; i < encoding->size; i++) {
                    for(j = encoding->first_col;
                        j < encoding->row_size;
                        j++) {
                        c = FontEncRecode((i<<8) | j, mapping);
                        if(CODE_IGNORED(c)) {
                            continue;
                        } else {
                            if(FT_Get_Char_Index(face, c) == 0) {
                                failed++;
                            }
                            total++;
                            if((encoding->size <= 1 && failed > 0) ||
                               ((float)failed >= bigEncodingFuzz * estimate)) {
                                return 0;
                            }
                        }
                    }
                }
                if((float)failed >= total * bigEncodingFuzz)
                    return 0;
                else
                    return 1;
            } else {
                int estimate = encoding->size - encoding->first;
                /* For the KOI8 encodings, we ignore the lack of
                   linedrawing and pseudo-math characters */
                if(strncmp(encoding->name, "koi8-", 5) == 0)
                    koi8 = 1;
                else
                    koi8 = 0;
                for(i = encoding->first; i < encoding->size; i++) {
                    c = FontEncRecode(i, mapping);
                    if(CODE_IGNORED(c) ||
                       (koi8 && ((c >= 0x2200 && c < 0x2600) || c == 0x00b2))) {
                        continue;
                    } else {
                        if(FT_Get_Char_Index(face, c) == 0) {
                            failed++;
                        }
                        total++;
                        if((encoding->size <= 256 && failed > 0) ||
                           ((float)failed >= bigEncodingFuzz * estimate)) {
                            return 0;
                        }
                    }
                }
                if((float)failed >= total * bigEncodingFuzz)
                    return 0;
                else
                    return 1;
            }
        }
    }
    return 0;
}