int main(int, char* argv[]) { FT_Library library; if (FT_Init_FreeType(&library)) { qDebug("init free type library failed"); exit(-1); } FT_Face face; int error = FT_New_Face(library, argv[1], 0, &face); if (error) { qDebug("open font failed <%s>", argv[1]); exit(-2); } FT_Select_Charmap(face, FT_ENCODING_UNICODE); FT_ULong charcode; FT_UInt gindex; for (charcode = FT_Get_First_Char(face, &gindex); gindex; charcode = FT_Get_Next_Char(face, charcode, &gindex)) { char name[256]; FT_Get_Glyph_Name(face, gindex, name, 256); codemap[gindex] = charcode; namemap[name] = gindex; } // char* p = getTable((char*)"LILC", face); // parseLILC(p); // p = getTable("LILY", face); // global values, not used // p = getTable("LILF", face); // subfont table, not used genJson(); return 0; }
std::vector<int> Glyphs::Codepoints(std::string fontstack) { std::vector<int> points; mapnik_fontnik::freetype_engine font_engine_; mapnik_fontnik::face_manager_freetype font_manager(font_engine_); mapnik_fontnik::font_set font_set(fontstack); std::stringstream stream(fontstack); std::string face_name; while (std::getline(stream, face_name, ',')) { font_set.add_face_name(Trim(face_name, " \t")); } mapnik_fontnik::face_set_ptr face_set; // This may throw. face_set = font_manager.get_face_set(font_set); for (auto const& face : *face_set) { FT_Face ft_face = face->get_face(); FT_ULong charcode; FT_UInt gindex; charcode = FT_Get_First_Char(ft_face, &gindex); while (gindex != 0) { charcode = FT_Get_Next_Char(ft_face, charcode, &gindex); if (charcode != 0) points.push_back(charcode); } break; } return points; }
bool ScFace_ttf::glyphNames(ScFace::FaceEncoding& GList) const { FT_ULong charcode; FT_UInt gindex = 0; FT_Face face = ftFace(); if (!face) return false; // The glyph name table embedded in Truetype fonts is not reliable. // For those fonts we consequently use Adobe Glyph names whenever possible. const bool avoidFntNames = (formatCode != ScFace::TYPE42 && typeCode == ScFace::TTF) && hasMicrosoftUnicodeCmap(face); if (!avoidFntNames) return FtFace::glyphNames(GList); // qDebug() << "reading metrics for" << face->family_name << face->style_name; charcode = FT_Get_First_Char(face, &gindex); while (gindex != 0) { GList.insert(gindex, std::make_pair(static_cast<ScFace::ucs4_type>(charcode), adobeGlyphName(charcode))); charcode = FT_Get_Next_Char(face, charcode, &gindex ); } return true; }
// load and store charsmaps static void LoadCharsMaps(GFont2D& Font, const FT_Face Face) { GUInt32 i, numMaps; FT_ULong charCode; FT_UInt glyphIndex; FT_Error err; FT_CharMap *maps; FT_CharMap map; GEncodedChar encodedChar; GCharMap tmpMap; numMaps = Face->num_charmaps; maps = Face->charmaps; for (i = 0; i < numMaps; i++) { map = maps[i]; err = FT_Set_Charmap(Face, map); if (err == 0) { // get first (valid) char code charCode = FT_Get_First_Char(Face, &glyphIndex); // if glyphIndex is 0, it means that charmap is empty if (glyphIndex != 0) { tmpMap.CharMap.clear(); // store encoding informations tmpMap.PlatformID = map->platform_id; tmpMap.EncodingID = map->encoding_id; switch (map->encoding) { case FT_ENCODING_MS_SYMBOL: tmpMap.Encoding = G_ENCODING_MS_SYMBOL; case FT_ENCODING_UNICODE: tmpMap.Encoding = G_ENCODING_UNICODE; case FT_ENCODING_SJIS: tmpMap.Encoding = G_ENCODING_SJIS; case FT_ENCODING_GB2312: tmpMap.Encoding = G_ENCODING_GB2312; case FT_ENCODING_BIG5: tmpMap.Encoding = G_ENCODING_BIG5; case FT_ENCODING_WANSUNG: tmpMap.Encoding = G_ENCODING_WANSUNG; case FT_ENCODING_JOHAB: tmpMap.Encoding = G_ENCODING_JOHAB; case FT_ENCODING_ADOBE_STANDARD: tmpMap.Encoding = G_ENCODING_ADOBE_STANDARD; case FT_ENCODING_ADOBE_EXPERT: tmpMap.Encoding = G_ENCODING_ADOBE_EXPERT; case FT_ENCODING_ADOBE_CUSTOM: tmpMap.Encoding = G_ENCODING_ADOBE_CUSTOM; case FT_ENCODING_ADOBE_LATIN_1: tmpMap.Encoding = G_ENCODING_ADOBE_LATIN_1; case FT_ENCODING_OLD_LATIN_2: tmpMap.Encoding = G_ENCODING_OLD_LATIN_2; case FT_ENCODING_APPLE_ROMAN: tmpMap.Encoding = G_ENCODING_APPLE_ROMAN; default: tmpMap.Encoding = G_ENCODING_NONE; } while (glyphIndex != 0) { encodedChar.CharCode = (GUInt32)charCode; encodedChar.GlyphIndex = (GUInt32)(glyphIndex - 0); tmpMap.CharMap.push_back(encodedChar); charCode = FT_Get_Next_Char(Face, charCode, &glyphIndex); } // add the loaded charmap to the font Font.AddCharMap(tmpMap); } } } }
LEUnicode32 XeTeXFontInst_FT2::getFirstCharCode() { if (!fFreeTypeOnly) return XeTeXFontInst::getFirstCharCode(); else { FT_UInt gindex; return FT_Get_First_Char(face, &gindex); } }
UChar32 XeTeXFontInst::getLastCharCode() { FT_UInt gindex; UChar32 ch = FT_Get_First_Char(m_ftFace, &gindex); UChar32 prev = ch; while (gindex != 0) { prev = ch; ch = FT_Get_Next_Char(m_ftFace, ch, &gindex); } return prev; }
value ftIterateKerningPairs( value font, value callback ) { if( !val_is_object(font) ) { ft_failure_v("not a freetype font face: ", font ); } value __f = val_field( font, val_id("__f") ); if( __f == NULL || !val_is_abstract( __f ) || !val_is_kind( __f, k_ft_face ) ) { ft_failure_v("not a freetype font face: ", font ); } FT_Face *face = val_data( __f ); if( !FT_HAS_KERNING((*face)) ) { return val_null; } FT_UInt left_index, right_index; FT_ULong left, right; FT_Vector vec; left = FT_Get_First_Char( *face, &left_index ); while( left != 0 ) { right = FT_Get_First_Char( *face, &right_index ); while( right != 0 ) { if( !FT_Get_Kerning( *face, left_index, right_index, FT_KERNING_UNFITTED, &vec ) && vec.x ) { // printf("KERNING %c_%c: %f\n", left, right, vec.x ); val_call3( callback, alloc_int( (int)left ), alloc_int( (int)right ), alloc_float( vec.x ) ); } right = FT_Get_Next_Char( *face, right, &right_index ); } left = FT_Get_Next_Char( *face, left, &left_index ); } return val_true; }
// // _getUnicodeValues() covered in this font // unsigned int FontFace::_getUnicodeValues(void){ FT_ULong characterCode; FT_UInt glyphIndex; characterCode = FT_Get_First_Char(_face, &glyphIndex); while(glyphIndex !=0 ){ characterCode = FT_Get_Next_Char(_face,characterCode,&glyphIndex); _unicodeValues.insert(characterCode); } return _unicodeValues.size(); }
LEUnicode32 XeTeXFontInst_FT2::getLastCharCode() { if (!fFreeTypeOnly) return XeTeXFontInst::getLastCharCode(); else { FT_UInt gindex; LEUnicode32 ch = FT_Get_First_Char(face, &gindex); LEUnicode32 prev = ch; while (gindex != 0) { prev = ch; ch = FT_Get_Next_Char(face, ch, &gindex); } return prev; } }
Py::Object FT2Font::get_charmap(const Py::Tuple & args) { _VERBOSE("FT2Font::get_charmap"); args.verify_length(0); FT_UInt index; Py::Dict charmap; FT_ULong code = FT_Get_First_Char(face, &index); while (code != 0) { //charmap[Py::Long((long) code)] = Py::Int((int) index); charmap[Py::Int((int) index)] = Py::Long((long) code); code = FT_Get_Next_Char(face, code, &index); } return charmap; }
VCOS_STATUS_T vgft_font_convert_glyphs(VGFT_FONT_T *font, unsigned int char_height, unsigned int dpi_x, unsigned int dpi_y) { FT_UInt glyph_index; FT_ULong ch; if (FT_Set_Char_Size(font->ft_face, 0, char_height, dpi_x, dpi_y)) { FT_Done_Face(font->ft_face); vgDestroyFont(font->vg_font); return VCOS_EINVAL; } ch = FT_Get_First_Char(font->ft_face, &glyph_index); while (ch != 0) { if (FT_Load_Glyph(font->ft_face, glyph_index, FT_LOAD_DEFAULT)) { FT_Done_Face(font->ft_face); vgDestroyFont(font->vg_font); return VCOS_ENOMEM; } VGPath vg_path; FT_Outline *outline = &font->ft_face->glyph->outline; if (outline->n_contours != 0) { vg_path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 0, 0, VG_PATH_CAPABILITY_ALL); assert(vg_path != VG_INVALID_HANDLE); convert_outline(outline->points, outline->tags, outline->contours, outline->n_contours, outline->n_points); vgAppendPathData(vg_path, segments_count, segments, coords); } else { vg_path = VG_INVALID_HANDLE; } VGfloat origin[] = { 0.0f, 0.0f }; VGfloat escapement[] = { float_from_26_6(font->ft_face->glyph->advance.x), float_from_26_6(font->ft_face->glyph->advance.y) }; vgSetGlyphToPath(font->vg_font, glyph_index, vg_path, VG_FALSE, origin, escapement); if (vg_path != VG_INVALID_HANDLE) { vgDestroyPath(vg_path); } ch = FT_Get_Next_Char(font->ft_face, ch, &glyph_index); } return VCOS_SUCCESS; }
SkUnichar SkScalerContext_CairoFT::generateGlyphToChar(uint16_t glyph) { SkASSERT(fScaledFont != NULL); CairoLockedFTFace faceLock(fScaledFont); FT_Face face = faceLock.getFace(); FT_UInt glyphIndex; SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex); while (glyphIndex != 0) { if (glyphIndex == glyph) { return charCode; } charCode = FT_Get_Next_Char(face, charCode, &glyphIndex); } return 0; }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_font_options_t *font_options; cairo_scaled_font_t *scaled_font; FT_Face face; FT_ULong charcode; FT_UInt idx; int i = 0; cairo_glyph_t glyphs[NUM_GLYPHS]; /* paint white so we don't need separate ref images for * RGB24 and ARGB32 */ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); cairo_paint (cr); cairo_select_font_face (cr, "Bitstream Vera Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (cr, TEXT_SIZE); font_options = cairo_font_options_create (); cairo_get_font_options (cr, font_options); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF); cairo_set_font_options (cr, font_options); cairo_font_options_destroy (font_options); cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); scaled_font = cairo_get_scaled_font (cr); face = cairo_ft_scaled_font_lock_face (scaled_font); { charcode = FT_Get_First_Char(face, &idx); while (idx && (i < NUM_GLYPHS)) { glyphs[i] = (cairo_glyph_t) {idx, PAD + GRID_SIZE * (i/GRID_ROWS), PAD + TEXT_SIZE + GRID_SIZE * (i%GRID_ROWS)}; i++; charcode = FT_Get_Next_Char(face, charcode, &idx); } } cairo_ft_scaled_font_unlock_face (scaled_font); cairo_show_glyphs(cr, glyphs, i); return CAIRO_TEST_SUCCESS; }
CAMLprim value Wrapper_FT_Get_First_Char(value face) { CAMLparam1(face); CAMLlocal1(block); FT_Face f; FT_ULong char_code; FT_UInt glyph; f = *(FT_Face *)Data_custom_val(face); char_code = FT_Get_First_Char (f, &glyph); block = alloc_tuple(2); Store_field(block, 0, Val_int(char_code)); Store_field(block, 1, Val_int(glyph)); CAMLreturn(block); };
static PyObject * Py_CharIter_next(Py_CharIter *self) { Py_Face *face = (Py_Face *)self->base.owner; if (self->started) { self->charcode = FT_Get_Next_Char( face->x, self->charcode, &self->glyph_index); } else { self->charcode = FT_Get_First_Char( face->x, &self->glyph_index); self->started = 1; } if (self->glyph_index) { return Py_BuildValue("kI", self->charcode, self->glyph_index); } return NULL; }
int test_cmap_iter( btimer_t* timer, FT_Face face, void* user_data ) { FT_UInt idx; FT_ULong charcode; FT_UNUSED( user_data ); TIMER_START( timer ); charcode = FT_Get_First_Char( face, &idx ); while ( idx != 0 ) charcode = FT_Get_Next_Char( face, charcode, &idx ); TIMER_STOP( timer ); return 1; }
void Print_Charmaps( FT_Face face ) { int i, active = -1; if ( face->charmap ) active = FT_Get_Charmap_Index( face->charmap ); /* CharMaps */ printf( "charmaps\n" ); for( i = 0; i < face->num_charmaps; i++ ) { printf( " %d: platform %d, encoding %d", i, face->charmaps[i]->platform_id, face->charmaps[i]->encoding_id ); if ( i == active ) printf( " (active)" ); printf ( "\n" ); if ( verbose ) { FT_ULong charcode; FT_UInt gindex; FT_Set_Charmap( face, face->charmaps[i] ); charcode = FT_Get_First_Char( face, &gindex ); while ( gindex ) { printf( " 0x%04lx => %d\n", charcode, gindex ); charcode = FT_Get_Next_Char( face, charcode, &gindex ); } printf( "\n" ); } } }
void get_charset( FT_Face face, bcharset_t* charset ) { FT_ULong charcode; FT_UInt gindex; int i; charset->code = (FT_ULong*)calloc( face->num_glyphs, sizeof( FT_ULong ) ); if ( !charset->code ) return; if ( face->charmap ) { i = 0; charcode = FT_Get_First_Char(face, &gindex); /* certain fonts contain a broken charmap that will map character codes */ /* to out-of-bounds glyph indices. Take care of that here !! */ /* */ while ( gindex && i < face->num_glyphs ) { charset->code[i++] = charcode; charcode = FT_Get_Next_Char(face, charcode, &gindex); } } else { /* no charmap, do an identity mapping */ for ( i = 0; i < face->num_glyphs; i++ ) charset->code[i] = i; } charset->size = i; }
static gchar * check_for_ascii_glyph_numbers (FT_Face face, gboolean *found_ascii) { GString *ascii_string, *string; gulong c; guint glyph, found = 0; string = g_string_new (NULL); ascii_string = g_string_new (NULL); *found_ascii = FALSE; c = FT_Get_First_Char (face, &glyph); do { if (glyph == 65 || glyph == 97) { g_string_append_unichar (ascii_string, (gunichar) c); found++; } if (found == 2) break; g_string_append_unichar (string, (gunichar) c); c = FT_Get_Next_Char (face, c, &glyph); } while (glyph != 0); if (found == 2) { *found_ascii = TRUE; g_string_free (string, TRUE); return g_string_free (ascii_string, FALSE); } else { g_string_free (ascii_string, TRUE); return g_string_free (string, FALSE); } }
static gchar * build_charlist_for_face (FT_Face face, gint *length) { GString *string; gulong c; guint glyph; gint total_chars = 0; string = g_string_new (NULL); c = FT_Get_First_Char (face, &glyph); while (glyph != 0) { g_string_append_unichar (string, (gunichar) c); c = FT_Get_Next_Char (face, c, &glyph); total_chars++; } if (length) *length = total_chars; return g_string_free (string, FALSE); }
PVOID APIENTRY FtfdQueryFontTree( DHPDEV dhpdev, ULONG_PTR iFile, ULONG iFace, ULONG iMode, ULONG_PTR *pid) { PFTFD_FILE pfile = (PFTFD_FILE)iFile; FT_Face ftface; FT_Error fterror; FTFD_CHARPAIR *pcp; FD_GLYPHSET *pGlyphSet; FT_ULong charcode; ULONG i, j, cGlyphs, cRuns, cjSize; WCRUN *pwcrun; HGLYPH * phglyphs; DbgPrint("FtfdQueryFontTree()\n"); fterror = FT_New_Memory_Face(gftlibrary, pfile->pvView, pfile->cjView, iFace - 1, &ftface); if (fterror) { DbgPrint("FT_New_Memory_Face() failed.\n"); return NULL; } /* Get initial value for cGlyphs from ftface */ cGlyphs = ftface->num_glyphs + 1; /* Allocate a buffer for the char codes and glyph indexes */ pcp = EngAllocMem(0, cGlyphs * sizeof(FTFD_CHARPAIR), 'pcp '); if (!pcp) { DbgPrint("EngAllocMem() failed.\n"); return NULL; } /* Gather char codes and indexes and count WCRUNs */ pcp[0].code = FT_Get_First_Char(ftface, &pcp[0].index); charcode = pcp[0].code; for (i = 1, cRuns = 1; charcode && i < cGlyphs; i++) { charcode = FT_Get_Next_Char(ftface, charcode, &pcp[i].index); DbgPrint("charcode=0x%lx, index=0x%lx\n", charcode, pcp[i].index); pcp[i].code = charcode; if (charcode != pcp[i - 1].code + 1) { cRuns++; } } /* Update cGlyphs to real value */ cGlyphs = i - 1; /* Calculate FD_GLYPHSET size */ cjSize = sizeof(FD_GLYPHSET) + (cRuns - 1) * sizeof(WCRUN) + cGlyphs * sizeof(HGLYPH); /* Allocate the FD_GLYPHSET structure */ pGlyphSet = EngAllocMem(0, cjSize, TAG_GLYPHSET); if (!pGlyphSet) { DbgPrint("EngAllocMem() failed.\n"); return NULL; } /* Initialize FD_GLYPHSET */ pGlyphSet->cjThis = cjSize; pGlyphSet->flAccel = 0; pGlyphSet->cGlyphsSupported = cGlyphs; pGlyphSet->cRuns = cRuns; /* Initialize 1st WCRUN */ pwcrun = pGlyphSet->awcrun; phglyphs = (PHGLYPH)&pGlyphSet->awcrun[cRuns]; pwcrun[0].wcLow = pcp[0].code; pwcrun[0].cGlyphs = 1; pwcrun[0].phg = &phglyphs[0]; phglyphs[0] = pcp[0].index; DbgPrint("pcp[0].index = 0x%lx\n", pcp[0].index); /* Walk through all supported chars */ for (i = 1, j = 0; i < cGlyphs; i++) { /* Use glyph index as HGLYPH */ phglyphs[i] = pcp[i].index; /* Check whether we can append the wchar to a run */ if (pcp[i].code == pcp[i - 1].code + 1) { /* Append to current WCRUN */ pwcrun[j].cGlyphs++; } else { /* Add a new WCRUN */ DbgPrint("adding new run\n"); j++; pwcrun[j].wcLow = pcp[i].code; pwcrun[j].cGlyphs = 1; pwcrun[j].phg = &phglyphs[i]; } } /* Free the temporary buffer */ EngFreeMem(pcp); /* Set *pid to the allocated structure for use in FtfdFree */ *pid = (ULONG_PTR)pGlyphSet; DbgPrint("pGlyphSet=%p\n", pGlyphSet); __debugbreak(); return pGlyphSet; }
void freeTypeFont_t :: dump() const { debugPrint( "num_faces %ld\n", face_->num_faces ); debugPrint( "face_index %ld\n", face_->face_index ); debugPrint( "face_flags %ld:\n", face_->face_flags ); for( int mask = 1, idx = 0 ; mask <= FT_FACE_FLAG_GLYPH_NAMES ; mask <<= 1, idx++ ) { if( (unsigned)idx < numFaceFlags_ ) { if( 0 != ( face_->face_flags & mask ) ) debugPrint( " " ); else debugPrint( " !" ); debugPrint( "%s\n", faceFlagNames_[idx] ); } else fprintf( stderr, "How did we get here!\n" ); } debugPrint( "style_flags %ld\n", face_->style_flags ); debugPrint( "num_glyphs %ld\n", face_->num_glyphs ); debugPrint( "family_name %s\n", face_->family_name ); debugPrint( "style_name %s\n", face_->style_name ); debugPrint( "num_fixed_sizes %d\n", face_->num_fixed_sizes ); for( int fs = 0 ; fs < face_->num_fixed_sizes ; fs++ ) { debugPrint( " %d/%d\n", face_->available_sizes[fs].width, face_->available_sizes[fs].height ); } debugPrint( "num_charmaps %d\n", face_->num_charmaps ); // the following are only relevant to scalable outlines // FT_BBox bbox; debugPrint( "bbox %d/%d, %d/%d\n", face_->bbox.xMin, face_->bbox.xMax, face_->bbox.yMin, face_->bbox.yMax ); debugPrint( "units_per_EM %d\n", face_->units_per_EM ); debugPrint( "ascender; %d\n", face_->ascender ); debugPrint( "descender %d\n", face_->descender ); debugPrint( "height %d\n", face_->height ); debugPrint( "max_advance_width %d\n", face_->max_advance_width ); debugPrint( "max_advance_height %d\n", face_->max_advance_height ); debugPrint( "underline_position %d\n", face_->underline_position ); debugPrint( "underline_thickness %d\n", face_->underline_thickness ); // FT_GlyphSlot glyph; // FT_Size size; // FT_CharMap charmap; for( int cm = 0; cm < face_->num_charmaps; cm++ ) { FT_CharMap charmap = face_->charmaps[cm]; debugPrint( "charmap %d =>\n", cm ); debugPrint( " encoding 0x%08x\n", charmap->encoding ); debugPrint( " platform 0x%02x\n", charmap->platform_id ); debugPrint( " encodeId 0x%02x\n", charmap->encoding_id ); unsigned long numCharCodes = 0 ; #define BADCHARCODE 0xFFFFaaaa FT_ULong startCharCode = BADCHARCODE ; FT_ULong prevCharCode = BADCHARCODE ; FT_UInt gindex; FT_ULong charcode = FT_Get_First_Char( face_, &gindex ); while( gindex != 0 ) { if( charcode != prevCharCode + 1 ) { if( BADCHARCODE != prevCharCode ) { numCharCodes += ( prevCharCode-startCharCode ) + 1 ; } startCharCode = prevCharCode = charcode ; } else prevCharCode = charcode ; charcode = FT_Get_Next_Char( face_, charcode, &gindex ); } if( BADCHARCODE != prevCharCode ) numCharCodes += ( prevCharCode-startCharCode ) + 1 ; debugPrint( " -> %lu charcodes\n", numCharCodes ); } for( int fs = 0 ; fs < face_->num_fixed_sizes ; fs++ ) { FT_Bitmap_Size const *bms = face_->available_sizes + fs; debugPrint( "fixed bitmap size %d =>\n", fs ); debugPrint( " height %d\n", bms->height ); debugPrint( " width %d\n", bms->width ); } }
static VFontData *objfnt_to_ftvfontdata(PackedFile *pf) { /* Variables */ FT_Face face; const FT_ULong charcode_reserve = 256; FT_ULong charcode = 0, lcode; FT_UInt glyph_index; const char *fontname; VFontData *vfd; #if 0 FT_CharMap found = 0; FT_CharMap charmap; FT_UShort my_platform_id = TT_PLATFORM_MICROSOFT; FT_UShort my_encoding_id = TT_MS_ID_UNICODE_CS; int n; #endif /* load the freetype font */ err = FT_New_Memory_Face(library, pf->data, pf->size, 0, &face); if (err) return NULL; #if 0 for (n = 0; n < face->num_charmaps; n++) { charmap = face->charmaps[n]; if (charmap->platform_id == my_platform_id && charmap->encoding_id == my_encoding_id) { found = charmap; break; } } if (!found) { return NULL; } /* now, select the charmap for the face object */ err = FT_Set_Charmap(face, found); if (err) { return NULL; } #endif /* allocate blender font */ vfd = MEM_callocN(sizeof(*vfd), "FTVFontData"); /* get the name */ fontname = FT_Get_Postscript_Name(face); BLI_strncpy(vfd->name, (fontname == NULL) ? "" : fontname, sizeof(vfd->name)); /* Extract the first 256 character from TTF */ lcode = charcode = FT_Get_First_Char(face, &glyph_index); /* No charmap found from the ttf so we need to figure it out */ if (glyph_index == 0) { FT_CharMap found = NULL; FT_CharMap charmap; int n; for (n = 0; n < face->num_charmaps; n++) { charmap = face->charmaps[n]; if (charmap->encoding == FT_ENCODING_APPLE_ROMAN) { found = charmap; break; } } err = FT_Set_Charmap(face, found); if (err) return NULL; lcode = charcode = FT_Get_First_Char(face, &glyph_index); } /* Adjust font size */ if (face->bbox.yMax != face->bbox.yMin) { vfd->scale = (float)(1.0 / (double)(face->bbox.yMax - face->bbox.yMin)); } else { vfd->scale = 1.0f / 1000.0f; } /* Load characters */ vfd->characters = BLI_ghash_int_new_ex(__func__, charcode_reserve); while (charcode < charcode_reserve) { /* Generate the font data */ freetypechar_to_vchar(face, charcode, vfd); /* Next glyph */ charcode = FT_Get_Next_Char(face, charcode, &glyph_index); /* Check that we won't start infinite loop */ if (charcode <= lcode) break; lcode = charcode; } return vfd; }
boost::optional<unsigned> getFirstChar() { unsigned agindex = 0; unsigned charcode = FT_Get_First_Char(handle_, &agindex); return boost::make_optional(agindex != 0, charcode); }
/** * Main. */ int main(int argc, char* argv[]) { FT_Error error; std::string fTtf; std::string fCxf; // init: fpCxf = NULL; nodes = 4; name = "Unknown"; letterSpacing = 3.0; wordSpacing = 6.75; lineSpacingFactor = 1.0; author = "Unknown"; // handle arguments: if (argc<2) { std::cout << "Usage: ttf2cxf <options> <ttf file> <cxf file>\n"; std::cout << " ttf file: An existing True Type Font file\n"; std::cout << " cxf file: The CXF font file to create\n"; std::cout << "options are:\n"; std::cout << " -n nodes Number of nodes for quadratic and cubic splines (int)\n"; std::cout << " -a author Author of the font. Preferably full name and e-mail address\n"; std::cout << " -l letter spacing Letter spacing (float)\n"; std::cout << " -w word spacing Word spacing (float)\n"; std::cout << " -f line spacing factor Default is 1.0 (float)\n"; exit(1); } for (int i=1; i<argc; ++i) { if (!strcmp(argv[i], "-n")) { ++i; nodes = atoi(argv[i]); } else if (!strcmp(argv[i], "-a")) { ++i; author = argv[i]; } else if (!strcmp(argv[i], "-l")) { ++i; letterSpacing = atof(argv[i]); } else if (!strcmp(argv[i], "-w")) { ++i; wordSpacing = atof(argv[i]); } else if (!strcmp(argv[i], "-f")) { ++i; lineSpacingFactor = atof(argv[i]); } } fTtf = argv[argc-2]; fCxf = argv[argc-1]; std::cout << "TTF file: " << fTtf.c_str() << "\n"; std::cout << "CXF file: " << fCxf.c_str() << "\n"; // init freetype error = FT_Init_FreeType(&library); if (error) { std::cerr << "Error: FT_Init_FreeType\n"; } // load ttf font error = FT_New_Face(library, fTtf.c_str(), 0, &face); if (error==FT_Err_Unknown_File_Format) { std::cerr << "FT_New_Face: Unknown format\n"; } else if (error) { std::cerr << "FT_New_Face: Unknown error\n"; } std::cout << "family: " << face->family_name << "\n"; name = face->family_name; std::cout << "height: " << face->height << "\n"; std::cout << "ascender: " << face->ascender << "\n"; std::cout << "descender: " << face->descender << "\n"; // find out height by tracing 'A' yMax = -1000; convertGlyph(65); factor = 1.0/(1.0/9.0*yMax); std::cout << "factor: " << factor << "\n"; // write font file: fpCxf = fopen(fCxf.c_str(), "wt"); if (fpCxf==NULL) { std::cerr << "Cannot open file " << fCxf.c_str() << " for writing.\n"; exit(2); } // write font header fprintf(fpCxf, "# Format: QCad 2 Font\n"); fprintf(fpCxf, "# Creator: ttf2cxf\n"); fprintf(fpCxf, "# Version: 1\n"); fprintf(fpCxf, "# Name: %s\n", name.c_str()); fprintf(fpCxf, "# LetterSpacing: %f\n", letterSpacing); fprintf(fpCxf, "# WordSpacing: %f\n", wordSpacing); fprintf(fpCxf, "# LineSpacingFactor: %f\n", lineSpacingFactor); fprintf(fpCxf, "# Author: %s\n", author.c_str()); fprintf(fpCxf, "\n"); uint first; FT_Get_First_Char(face, &first); FT_ULong charcode; FT_UInt gindex; // iterate through glyphs charcode = FT_Get_First_Char( face, &gindex ); while (gindex != 0) { convertGlyph(charcode); charcode = FT_Get_Next_Char(face, charcode, &gindex); } return 0; }
void PdfFontCID::CreateCMap( PdfObject* pUnicode ) const { PdfFontMetricsFreetype* pFreetype = dynamic_cast<PdfFontMetricsFreetype*>(m_pMetrics); if (!pFreetype) return; int nFirstChar = m_pEncoding->GetFirstChar(); int nLastChar = m_pEncoding->GetLastChar(); std::ostringstream oss; FT_Face face = pFreetype->GetFace(); FT_ULong charcode; FT_UInt gindex; TBFRange curRange; curRange.srcCode = -1; std::vector<TBFRange> vecRanges; // Only 255 sequent characters are allowed to be in one range! const unsigned int MAX_CHARS_IN_RANGE = 255; charcode = FT_Get_First_Char( face, &gindex ); while ( gindex != 0 ) { if( static_cast<int>(charcode) > nLastChar ) { break; } else if( static_cast<int>(charcode) >= nFirstChar ) { if( curRange.vecDest.size() == 0 ) { curRange.srcCode = gindex; curRange.vecDest.push_back( charcode ); } else if( (curRange.srcCode + curRange.vecDest.size() == gindex) && ((gindex - curRange.srcCode + curRange.vecDest.size()) < MAX_CHARS_IN_RANGE) ) { curRange.vecDest.push_back( charcode ); } else { // Create a new bfrange vecRanges.push_back( curRange ); curRange.srcCode = gindex; curRange.vecDest.clear(); curRange.vecDest.push_back( charcode ); } } charcode = FT_Get_Next_Char( face, charcode, &gindex ); } if( curRange.vecDest.size() ) vecRanges.push_back( curRange ); // Now transform it into a string // Make sure each bfrange section has a maximum of // 100 entries. If there are more Acrobat Reader might crash std::ostringstream range; int numberOfEntries = 0; std::vector<TBFRange>::const_iterator it = vecRanges.begin(); const int BUFFER_LEN = 5; char buffer[BUFFER_LEN]; // buffer of the format "XXXX\0" while( it != vecRanges.end() ) { if( numberOfEntries == 99 ) { oss << numberOfEntries << " beginbfrange" << std::endl; oss << range.str(); oss << "endbfrange" << std::endl; numberOfEntries = 0; range.str(""); } pdf_long iStart = (*it).srcCode; pdf_long iEnd = (*it).srcCode + (*it).vecDest.size() - 1; snprintf( buffer, BUFFER_LEN, "%04X", static_cast<unsigned int>(iStart) ); range << "<" << buffer << "> <"; snprintf( buffer, BUFFER_LEN, "%04X", static_cast<unsigned int>(iEnd) ); range << buffer << "> [ "; std::vector<int>::const_iterator it2 = (*it).vecDest.begin(); while( it2 != (*it).vecDest.end() ) { snprintf( buffer, BUFFER_LEN, "%04X", *it2 ); range << "<" << buffer << "> "; ++it2; } range << "]" << std::endl; ++it; ++numberOfEntries; } if( numberOfEntries > 0 ) { oss << numberOfEntries << " beginbfrange" << std::endl; oss << range.str(); oss << "endbfrange" << std::endl; } /* // Create the beginbfchar section std::ostringstream oss; std::ostringstream tmp; const int BUFFER_LEN = 14; char buffer[BUFFER_LEN]; // buffer of the format "<XXXX> <XXXX>\0" bool bLittle = podofo_is_little_endian(); int nCount = 1; while( nFirstChar <= nLastChar ) { lGlyph = m_pMetrics->GetGlyphId( nFirstChar ); if( lGlyph && lGlyph <= 0xffff) { if( bLittle ) snprintf( buffer, BUFFER_LEN, "<%04X> <%04X>", static_cast<unsigned int>(lGlyph), ((nFirstChar & 0xff00) >> 8) | ((nFirstChar & 0x00ff) << 8) ); else snprintf( buffer, BUFFER_LEN, "<%04X> <%04X>", static_cast<unsigned int>(lGlyph), nFirstChar ); tmp << buffer << std::endl; if( nCount % 100 == 0 ) { // There can be at maximum 100 lines in a bfchar section oss << nCount - 1 << " beginbfchar" << std::endl << tmp.str() << "endbfchar" << std::endl; tmp.str(""); // clear the stream nCount = 0; } ++nCount; } ++nFirstChar; } if( nCount > 1 ) oss << nCount - 1 << " beginbfchar" << std::endl << tmp.str() << "endbfchar" << std::endl; */ // Create the CMap pUnicode->GetStream()->BeginAppend(); pUnicode->GetStream()->Append("/CIDInit /ProcSet findresource begin\n"); pUnicode->GetStream()->Append("10000 dict begin\n"); pUnicode->GetStream()->Append("begincmap\n"); pUnicode->GetStream()->Append("/CIDSystemInfo\n"); pUnicode->GetStream()->Append("<< /Registry (Adobe)\n"); pUnicode->GetStream()->Append("/Ordering (UCS)\n"); pUnicode->GetStream()->Append("/Supplement 0\n"); pUnicode->GetStream()->Append(">> def\n"); pUnicode->GetStream()->Append("/CMapName /Adobe-Identity-UCS def\n"); pUnicode->GetStream()->Append("/CMapType 2 def\n"); pUnicode->GetStream()->Append("1 begincodespacerange\n"); pUnicode->GetStream()->Append("<0000> <FFFF>\n"); pUnicode->GetStream()->Append("endcodespacerange\n"); pUnicode->GetStream()->Append( oss.str().c_str() ); pUnicode->GetStream()->Append("endcmap\n"); pUnicode->GetStream()->Append("CMapName currentdict /CMap defineresource pop\n"); pUnicode->GetStream()->Append("end\n"); pUnicode->GetStream()->Append("end\n"); pUnicode->GetStream()->EndAppend(); }
static VFontData *objfnt_to_ftvfontdata(PackedFile * pf) { // Variables FT_Face face; FT_ULong charcode = 0, lcode; FT_UInt glyph_index; const char *fontname; VFontData *vfd; /* FT_CharMap found = 0; FT_CharMap charmap; FT_UShort my_platform_id = TT_PLATFORM_MICROSOFT; FT_UShort my_encoding_id = TT_MS_ID_UNICODE_CS; int n; */ // load the freetype font err = FT_New_Memory_Face( library, pf->data, pf->size, 0, &face ); if(err) return NULL; /* for ( n = 0; n < face->num_charmaps; n++ ) { charmap = face->charmaps[n]; if ( charmap->platform_id == my_platform_id && charmap->encoding_id == my_encoding_id ) { found = charmap; break; } } if ( !found ) { return NULL; } // now, select the charmap for the face object err = FT_Set_Charmap( face, found ); if ( err ) { return NULL; } */ // allocate blender font vfd= MEM_callocN(sizeof(*vfd), "FTVFontData"); // get the name fontname = FT_Get_Postscript_Name(face); strcpy(vfd->name, (fontname == NULL) ? "" : fontname); // Extract the first 256 character from TTF lcode= charcode= FT_Get_First_Char(face, &glyph_index); // No charmap found from the ttf so we need to figure it out if(glyph_index == 0) { FT_CharMap found = NULL; FT_CharMap charmap; int n; for ( n = 0; n < face->num_charmaps; n++ ) { charmap = face->charmaps[n]; if (charmap->encoding == FT_ENCODING_APPLE_ROMAN) { found = charmap; break; } } err = FT_Set_Charmap( face, found ); if( err ) return NULL; lcode= charcode= FT_Get_First_Char(face, &glyph_index); } // Load characters while(charcode < 256) { // Generate the font data freetypechar_to_vchar(face, charcode, vfd); // Next glyph charcode = FT_Get_Next_Char(face, charcode, &glyph_index); // Check that we won't start infinite loop if(charcode <= lcode) break; lcode = charcode; } return vfd; }
UChar32 XeTeXFontInst::getFirstCharCode() { FT_UInt gindex; return FT_Get_First_Char(m_ftFace, &gindex); }
void importDefineFont2( DefineFont2 *tag, const char *filename, xmlNodePtr node ) { FT_Library swfft_library; FT_Face face; int error; FT_UInt glyph_index; FT_ULong character; FT_Outline *outline; xmlChar *glyphs_xml = xmlGetProp( node, (const xmlChar *)"glyphs" ); const char *glyphs = (const char *)glyphs_xml; GlyphList *glyphList = tag->getglyphs(); List<Short>* advance = tag->getadvance(); List<Rectangle>* bounds = tag->getbounds(); // NYI: kerning Shape *shape; int glyph_n; int n, ofs; if( FT_Init_FreeType( &swfft_library ) ) { fprintf( stderr, "WARNING: could not initialize FreeType\n" ); goto fail; } error = FT_New_Face( swfft_library, filename, 0, &face ); if( error ) { fprintf( stderr, "WARNING: FreeType does not like %s\n", filename ); goto fail; } if( face->num_faces > 1 ) { fprintf( stderr, "WARNING: %s contains %i faces, but only the first is imported.\n", filename, face->num_faces ); } if( face->charmap == 0 ) { fprintf( stderr, "WARNING: %s doesn't seem to contain a unicode charmap.\n", filename ); } FT_Set_Char_Size(face, 1024<<6, 1024<<6, 75, 75); // we should only import @glyphs, lets do all for now. // count availably glyphs n = 0; if( (character = FT_Get_First_Char( face, &glyph_index )) != 0 ) n++; while( (character = FT_Get_Next_Char( face, character, &glyph_index )) != 0 ) n++; if( n>255 ) n=255; // FIXME ofs = 0; n-=ofs; fprintf( stderr, "importing %s: %i glyphs\n", filename, n ); glyphList->allocate( n ); tag->setglyphCount( n ); tag->setname( "helvetica" ); // FIXME tag->sethasLayout( 1 ); tag->setascent( face->ascender * 1024 / face->units_per_EM ); tag->setdescent( labs(face->descender)* 1024 / face->units_per_EM ); tag->setleading( face->height* 1024 / face->units_per_EM ); tag->setwideGlyphOffsets( 1 ); tag->setwideMap( 1 ); character = FT_Get_First_Char( face, &glyph_index ); for( int i=0; i<ofs; i++ ) character=FT_Get_Next_Char( face, character, &glyph_index ); for( int glyph_n=0; character && glyph_n<n; glyph_n++ ) { // glyph_index = FT_Get_Char_Index( face, character ); if( FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_BITMAP ) ) { fprintf( stderr, "WARNING: couldnt load glyph %i (%c) from %s.\n", character, character, filename ); } if( face->glyph->format != FT_GLYPH_FORMAT_OUTLINE ) { fprintf( stderr, "WARNING: %s seems to be a bitmap font.\n", filename ); goto fail; } outline = &face->glyph->outline; // fprintf(stderr,"importing glyph %i ('%c') of %s (advance %i, %i points)\n", character, character, filename, face->glyph->advance.x, outline->n_points ); { Short *adv = new Short(); adv->setvalue( (short)(face->glyph->advance.x * (1.0/64)) ); advance->append(adv); Rectangle *r = new Rectangle(); /* r->settop( -face->bbox.yMax * 1024 / face->units_per_EM ); r->setright( face->bbox.xMax - face->bbox.xMin ); r->setbottom( -face->bbox.yMin * 1024 / face->units_per_EM ); */ r->setbits( SWFMaxBitsNeeded( true, 3, r->gettop(), r->getright(), r->getbottom() ) ); bounds->append(r); glyphList->setMapN(glyph_n, character); shape = glyphList->getShapeN(glyph_n); ShapeMaker shaper( shape->getedges(), (1.0/64), -(1.0/64), 0, 0 ); // set fillBits shape->setfillBits(1); int start = 0, end; bool control, cubic; int n; for( int contour = 0; contour < outline->n_contours; contour++ ) { end = outline->contours[contour]; // fprintf(stderr," contour %i: %i-%i\n", contour, start, end ); n=0; for( int p = start; p<=end; p++ ) { control = !(outline->tags[p] & 0x01); cubic = outline->tags[p] & 0x02; /* if( character == 'h' ) fprintf( stderr, " point %i: %s%s %i %i\n", p, control?(cubic?"third-order ":"second-order "):"", control?"control":"on-curve", outline->points[p].x, outline->points[p].y); */ if( p==start ) { shaper.setup( outline->points[p-n].x, outline->points[p-n].y, 1 ); } if( !control && n > 0 ) { importGlyphPoints( &(outline->points[(p-n)+1]), n-1, shaper, cubic ); n=1; } else { n++; } } if( n ) { // special case: repeat first point FT_Vector points[n+1]; int s=(end-n)+2; for( int i=0; i<n-1; i++ ) { points[i].x = outline->points[s+i].x; points[i].y = outline->points[s+i].y; } points[n-1].x = outline->points[start].x; points[n-1].y = outline->points[start].y; importGlyphPoints( points, n-1, shaper, false ); } shaper.close(); start = end+1; } shaper.finish(); } character = FT_Get_Next_Char( face, character, &glyph_index ); } return; fail: fprintf( stderr, "WARNING: could not import %s\n", filename ); return; }
/** * Main. */ int main(int argc, char* argv[]) { FT_Error error; std::string fTtf; std::string fLff; // init: fpLff = NULL; nodes = 4; std::string name = "Unknown"; double letterSpacing = 3.0; double wordSpacing = 6.75; double lineSpacingFactor = 1.0; std::string author = "Unknown"; std::string license = "Unknown"; precision = 6; // handle arguments: if (argc<2) { std::cout << "Usage: ttf2cxf <options> <ttf file> <cxf file>\n"; std::cout << " ttf file: An existing True Type Font file\n"; std::cout << " lff file: The LFF font file to create\n"; std::cout << "options are:\n"; std::cout << " -n nodes Number of nodes for quadratic and cubic splines (int)\n"; std::cout << " -a author Author of the font. Preferably full name and e-mail address\n"; std::cout << " -l letter spacing Letter spacing (float)\n"; std::cout << " -w word spacing Word spacing (float)\n"; std::cout << " -f line spacing factor Default is 1.0 (float)\n"; std::cout << " -d precision Number of decimal digits (int)\n"; std::cout << " -L license license of the font.\n"; exit(1); } for (int i=1; i<argc; ++i) { if (!strcmp(argv[i], "-n")) { ++i; nodes = atoi(argv[i]); } else if (!strcmp(argv[i], "-a")) { ++i; author = argv[i]; } else if (!strcmp(argv[i], "-l")) { ++i; letterSpacing = atof(argv[i]); } else if (!strcmp(argv[i], "-w")) { ++i; wordSpacing = atof(argv[i]); } else if (!strcmp(argv[i], "-d")) { ++i; precision = atoi(argv[i]); } else if (!strcmp(argv[i], "-f")) { ++i; lineSpacingFactor = atof(argv[i]); } else if (!strcmp(argv[i], "-L")) { ++i; license = argv[i]; } } fTtf = argv[argc-2]; fLff = argv[argc-1]; std::cout << "TTF file: " << fTtf.c_str() << "\n"; std::cout << "LFF file: " << fLff.c_str() << "\n"; // init freetype error = FT_Init_FreeType(&library); if (error) { std::cerr << "Error: FT_Init_FreeType\n"; } // load ttf font error = FT_New_Face(library, fTtf.c_str(), 0, &face); if (error==FT_Err_Unknown_File_Format) { std::cerr << "FT_New_Face: Unknown format\n"; } else if (error) { std::cerr << "FT_New_Face: Unknown error\n"; } std::cout << "family: " << face->family_name << "\n"; name = face->family_name; std::cout << "height: " << face->height << "\n"; std::cout << "ascender: " << face->ascender << "\n"; std::cout << "descender: " << face->descender << "\n"; // find out height by tracing 'A' yMax = -1000; convertGlyph(65); factor = 1.0/(1.0/9.0*yMax); std::cout << "factor: " << factor << "\n"; // write font file: fpLff = fopen(fLff.c_str(), "wt"); if (fpLff==NULL) { std::cerr << "Cannot open file " << fLff.c_str() << " for writing.\n"; exit(2); } sprintf(numFormat,"%%.%if", precision); // write font header fprintf(fpLff, "# Format: LibreCAD Font 1\n"); fprintf(fpLff, "# Creator: ttf2lff\n"); fprintf(fpLff, "# Version: 1\n"); fprintf(fpLff, "# Name: %s\n", name.c_str()); fprintf(fpLff, "# LetterSpacing: %s\n", clearZeros(letterSpacing).c_str()); fprintf(fpLff, "# WordSpacing: %s\n", clearZeros(wordSpacing).c_str()); fprintf(fpLff, "# LineSpacingFactor: %s\n", clearZeros(lineSpacingFactor).c_str()); time_t rawtime; struct tm * timeinfo; char buffer [12]; time ( &rawtime ); timeinfo = localtime ( &rawtime ); strftime (buffer,80,"%Y-%m-%d",timeinfo); fprintf(fpLff, "# Created: %s\n", buffer); fprintf(fpLff, "# Last modified: %s\n", buffer); fprintf(fpLff, "# Author: %s\n", author.c_str()); fprintf(fpLff, "# License: %s\n", license.c_str()); fprintf(fpLff, "\n"); uint first; FT_Get_First_Char(face, &first); FT_ULong charcode; FT_UInt gindex; // iterate through glyphs charcode = FT_Get_First_Char( face, &gindex ); while (gindex != 0) { convertGlyph(charcode); charcode = FT_Get_Next_Char(face, charcode, &gindex); } return 0; }