Пример #1
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;
    }
}
Пример #2
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;
}
Пример #3
0
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;
}