📄 pdf_fontfilems.c.svn-base
字号:
ttRecord.uNameID = SWAPWORD(ttRecord.uNameID); ttRecord.uLanguageID = SWAPWORD(ttRecord.uLanguageID); // Full Name if (ttRecord.uNameID == 6) { ttRecord.uPlatformID = SWAPWORD(ttRecord.uPlatformID); ttRecord.uEncodingID = SWAPWORD(ttRecord.uEncodingID); ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength); ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset); fz_seek(file, tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset, 0); SAFE_FZ_READ(file, szTemp, ttRecord.uStringLength); switch(ttRecord.uPlatformID) { case PLATFORM_UNICODE: err = decodeunicodeplatform(szTemp, ttRecord.uStringLength, szTemp, sizeof(szTemp), ttRecord.uEncodingID); break; case PLATFORM_MACINTOSH: err = decodemacintoshplatform(szTemp, ttRecord.uStringLength, szTemp, sizeof(szTemp), ttRecord.uEncodingID); break; case PLATFORM_ISO: err = fz_throw("fonterror : unsupported platform"); break; case PLATFORM_MICROSOFT: err = decodemicrosoftplatform(szTemp, ttRecord.uStringLength, szTemp, sizeof(szTemp), ttRecord.uEncodingID); break; } if (err == nil) err = insertmapping(&fontlistMS, szTemp, path, index); } } }cleanup: return err;}static fz_error *parseTTFs(char *path){ fz_error *err = nil; fz_stream *file = nil; err = fz_openrfile(&file, path); if (err) goto cleanup; err = parseTTF(file,0,0,path); if (err) goto cleanup;cleanup: if (file) fz_dropstream(file); return err;}static fz_error *parseTTCs(char *path){ fz_error *err = nil; int byteread; fz_stream *file = nil; FONT_COLLECTION fontcollectioin; ULONG i; err = fz_openrfile(&file, path); if (err) goto cleanup; SAFE_FZ_READ(file, &fontcollectioin, sizeof(FONT_COLLECTION)); if (memcmp(fontcollectioin.Tag,"ttcf",sizeof(fontcollectioin.Tag)) == 0) { fontcollectioin.Version = SWAPLONG(fontcollectioin.Version); fontcollectioin.NumFonts = SWAPLONG(fontcollectioin.NumFonts); if (fontcollectioin.Version == TTC_VERSION1 || fontcollectioin.Version == TTC_VERSION2 ) { ULONG *offsettable = fz_malloc(sizeof(ULONG)*fontcollectioin.NumFonts); if (offsettable == nil) { err = fz_outofmem; goto cleanup; } SAFE_FZ_READ(file, offsettable, sizeof(ULONG)*fontcollectioin.NumFonts); for (i = 0; i < fontcollectioin.NumFonts; ++i) { offsettable[i] = SWAPLONG(offsettable[i]); parseTTF(file,offsettable[i],i,path); } fz_free(offsettable); } else { err = fz_throw("fonterror : invalid version"); goto cleanup; } } else { err = fz_throw("fonterror: wrong format"); goto cleanup; }cleanup: if (file) fz_dropstream(file); return err;}static fz_error*pdf_createfontlistMS(){ char szFontDir[MAX_PATH*2]; char szSearch[MAX_PATH*2]; char szFile[MAX_PATH*2]; BOOL fFinished; HANDLE hList; WIN32_FIND_DATA FileData; fz_error *err; if (fontlistMS.len != 0) return fz_okay; GetWindowsDirectory(szFontDir, sizeof(szFontDir)); // Get the proper directory path strcat(szFontDir,"\\Fonts\\"); sprintf(szSearch,"%s*.tt?",szFontDir); // Get the first file hList = FindFirstFile(szSearch, &FileData); if (hList == INVALID_HANDLE_VALUE) { /* Don't complain about missing directories */ if (errno == ENOENT) return fz_throw("fonterror : can't find system fonts dir"); return fz_throw("ioerror"); } // Traverse through the directory structure fFinished = FALSE; while (!fFinished) { if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { // Get the full path for sub directory sprintf(szFile,"%s%s", szFontDir, FileData.cFileName); if (szFile[strlen(szFile)-1] == 'c' || szFile[strlen(szFile)-1] == 'C') { err = parseTTCs(szFile); // ignore error parsing a given font file } else if (szFile[strlen(szFile)-1] == 'f'|| szFile[strlen(szFile)-1] == 'F') { err = parseTTFs(szFile); // ignore error parsing a given font file } } if (!FindNextFile(hList, &FileData)) { if (GetLastError() == ERROR_NO_MORE_FILES) { fFinished = TRUE; } } } // Let go of find handle FindClose(hList); removeredundancy(&fontlistMS); finddefaultsubstitutes(&fontlistMS); return fz_okay;}static voidfindsubstitute(char *fontname, char **fontpath, int *index){ // TODO: do something more clever *fontpath = defaultSubstitute.fontpath; *index = defaultSubstitute.index;}voidpdf_destoryfontlistMS(){ if (fontlistMS.fontmap != nil) fz_free(fontlistMS.fontmap); fontlistMS.len = 0; fontlistMS.cap = 0;}static fz_error *pdf_lookupfontMS2(char *fontname, char **fontpath, int *index, int *didfind){ pdf_fontmapMS fontmap; pdf_fontmapMS *found = nil; char *pattern; int i; if (fontlistMS.len == 0) return fz_throw("fonterror : no fonts in the system"); pattern = fontname; for (i = 0; i < ARRAY_SIZE(basenames); i++) { if (0 == strcmp(fontname, basenames[i])) { pattern = basepatterns[i]; break; } } strlcpy(fontmap.fontface,pattern, sizeof(fontmap.fontface)); found = localbsearch(&fontmap, fontlistMS.fontmap, fontlistMS.len, sizeof(pdf_fontmapMS), lookupcompare);#if 0 if (!found) found = findlinear(&fontlistMS, &fontmap);#endif if (found) { *fontpath = found->fontpath; *index = found->index; } else { findsubstitute(fontname, fontpath, index); } *didfind = 0; if (found) *didfind = 1; return fz_okay;}static FT_Library ftlib = nil;static fz_error *initfontlibs(void){ int fterr; int maj, min, pat; fz_error *err; if (ftlib) return fz_okay; fterr = FT_Init_FreeType(&ftlib); if (fterr) return fz_throw("freetype failed initialisation: %s", ft_errstr(fterr)); FT_Library_Version(ftlib, &maj, &min, &pat); if (maj == 2 && min == 1 && pat < 7) return fz_throw("freetype version too old: %d.%d.%d", maj, min, pat); err = pdf_createfontlistMS(); if (err) return err; return fz_okay;}static fz_error *pdf_lookupfontMS(pdf_font *font, char *fontname, char *collection, char **fontpath, int *index){ fz_error *error; int found; char *fontname2 = font->super.name; error = initfontlibs(); if (error) return error; error = pdf_lookupfontMS2(fontname, fontpath, index, &found); if (error) return error; if (!found && fontname2) { error = pdf_lookupfontMS2(fontname2, fontpath, index, &found); if (error) return error; } if (!found && collection) { if ((!strcmp(collection, "Adobe-Japan1")) || (!strcmp(collection, "Adobe-Japan2"))) { if (!strcmp(fontname, "GothicBBB-Medium")) { error = pdf_lookupfontMS2("MS-Gothic", fontpath, index, &found); if (error) return error; } else if (!strcmp(fontname, "Ryumin-Light")) { error = pdf_lookupfontMS2("MS-Mincho", fontpath, index, &found); if (error) return error; } else if (font->flags & FD_FIXED) { if (font->flags & FD_SERIF) { error = pdf_lookupfontMS2("MS-Mincho", fontpath, index, &found); if (error) return error; } else { error = pdf_lookupfontMS2("MS-Gothic", fontpath, index, &found); if (error) return error; } } else { if (font->flags & FD_SERIF) { error = pdf_lookupfontMS2("MS-PMincho", fontpath, index, &found); if (error) return error; } else { error = pdf_lookupfontMS2("MS-PGothic", fontpath, index, &found); if (error) return error; } } font->substitute = 1; } } return fz_okay;}#ifdef USE_BUILTIN_FONTS/* based on (and duplicates lots of) pdf_fontfile.c */static const struct{ const char *name; const unsigned char *cff; const unsigned int *len;} basefonts[15] = { { "Courier", fonts_NimbusMonL_Regu_cff, &fonts_NimbusMonL_Regu_cff_len }, { "Courier-Bold", fonts_NimbusMonL_Bold_cff, &fonts_NimbusMonL_Bold_cff_len }, { "Courier-Oblique", fonts_NimbusMonL_ReguObli_cff, &fonts_NimbusMonL_ReguObli_cff_len }, { "Courier-BoldOblique", fonts_NimbusMonL_BoldObli_cff, &fonts_NimbusMonL_BoldObli_cff_len }, { "Helvetica", fonts_NimbusSanL_Regu_cff, &fonts_NimbusSanL_Regu_cff_len }, { "Helvetica-Bold", fonts_NimbusSanL_Bold_cff, &fonts_NimbusSanL_Bold_cff_len }, { "Helvetica-Oblique", fonts_NimbusSanL_ReguItal_cff, &fonts_NimbusSanL_ReguItal_cff_len }, { "Helvetica-BoldOblique", fonts_NimbusSanL_BoldItal_cff, &fonts_NimbusSanL_BoldItal_cff_len }, { "Times-Roman", fonts_NimbusRomNo9L_Regu_cff, &fonts_NimbusRomNo9L_Regu_cff_len }, { "Times-Bold", fonts_NimbusRomNo9L_Medi_cff, &fonts_NimbusRomNo9L_Medi_cff_len }, { "Times-Italic", fonts_NimbusRomNo9L_ReguItal_cff, &fonts_NimbusRomNo9L_ReguItal_cff_len }, { "Times-BoldItalic", fonts_NimbusRomNo9L_MediItal_cff, &fonts_NimbusRomNo9L_MediItal_cff_len }, { "Symbol", fonts_StandardSymL_cff, &fonts_StandardSymL_cff_len }, { "ZapfDingbats", fonts_Dingbats_cff, &fonts_Dingbats_cff_len }, { "Chancery", fonts_URWChanceryL_MediItal_cff, &fonts_URWChanceryL_MediItal_cff_len }};#endiffz_error *pdf_loadbuiltinfont(pdf_font *font, char *basefont){ fz_error *error; int fterr; FT_Face face; char *file; int index;#ifdef USE_BUILTIN_FONTS /* try built-in fonts first */ int i; unsigned char *data; unsigned int len; int found = 0; for (i = 0; i < 15; i++) { if (!strcmp(basefont, basefonts[i].name)) { found = 1; break; } } if (found) { pdf_logfont("load builtin font %s\n", basefont); data = (unsigned char *) basefonts[i].cff; len = *basefonts[i].len; fterr = FT_New_Memory_Face(ftlib, data, len, 0, (FT_Face*)&font->ftface); /* TODO: fails on "Helvetica" */#if 0 if (fterr) return fz_throw("freetype: cannot load font: %s", ft_errstr(fterr)); return fz_okay;#else if (!fterr) return fz_okay;#endif }#endif error = pdf_lookupfontMS(font, basefont, NULL, &file, &index); if (error) return error; fterr = FT_New_Face(ftlib, file, index, &face); if (fterr) return fz_throw("freetype could not load font file '%s': %s", file, ft_errstr(fterr)); font->ftface = face; return fz_okay;}fz_error *pdf_loadsystemfont(pdf_font *font, char *basefont, char *collection){ fz_error *error; int fterr; FT_Face face; char *file; int index; error = pdf_lookupfontMS(font, basefont, collection, &file, &index); if (error) goto cleanup; fterr = FT_New_Face(ftlib, file, index, &face); if (fterr) { return fz_throw("freetype could not load font file '%s': %s", file, ft_errstr(fterr)); } font->ftface = face; return fz_okay;cleanup: return error;}fz_error *pdf_loadembeddedfont(pdf_font *font, pdf_xref *xref, fz_obj *stmref){ fz_error *error; int fterr; FT_Face face; fz_buffer *buf; error = initfontlibs(); if (error) return error; error = pdf_loadstream(&buf, xref, fz_tonum(stmref), fz_togen(stmref)); if (error) return error; fterr = FT_New_Memory_Face(ftlib, buf->rp, buf->wp - buf->rp, 0, &face); if (fterr) { fz_free(buf); return fz_throw("freetype could not load embedded font: %s", ft_errstr(fterr)); } font->ftface = face; font->fontdata = buf; return fz_okay;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -