/* * Help Access Library * A Library to access the contents of Windows Help files. * * Copyright (C) 1995-2000 Bernd Herd, http://www.herdsoft.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* LDFONTS.C ------------------------------------------ * @doc * @module LDFONTS.C | * * Handling of FONTS-File * * Help Access Library Project. * *-----------------------------------------------------*/ #include #include #include #include #include #include "hlpacces.h" #include "top.h" void static near pascal nReadFontInfos(NPTOPIC topic, HIFSFILE hfont, FONTHEADER FAR *FontHdr); /* iFontsLoad * * Load the Table of font-Descriptors */ void iFontsLoad(NPTOPIC topic) /* Load Fonts-Table */ { HIFSFILE hfont = IFSOpenFile(topic->ifs, "|FONT"); FONTHEADER FontHdr; if (NULL!=hfont) { if (IFSReadFile(hfont, &FontHdr, sizeof(FontHdr))==sizeof(FontHdr) && NULL!=(topic->FontSelectors = (LPFONTSELECTORS) Hlpcalloc(sizeof(FONTSELECTORS) + leword(FontHdr.NumDescriptors) * sizeof(FONTINFO),1)) ) { topic->FontSelectors->FontCount = leword(FontHdr.NumDescriptors); nReadFontInfos(topic, hfont, &FontHdr); } IFSCloseFile(hfont); } } void static near pascal nReadFontInfos(NPTOPIC topic, HIFSFILE hfont, FONTHEADER FAR *FontHdr) { FONTDESCRIPTOR FontDesc; LONGFONTDESCRIPTOR LongFontDesc; LPFONTINFO lpfi; int FontsLength = IFSSeekFile(hfont,0,SEEK_END), FontNameLength = (leword(FontHdr->DescriptorsOffset)- sizeof(FontHdr)) / leword(FontHdr->NumFonts) > 20 ? 32 : 20, NameOffset = (leword(FontHdr->DescriptorsOffset)) - FontNameLength * leword(FontHdr->NumFonts), FontDescLength = (FontsLength-leword(FontHdr->DescriptorsOffset)) / leword(FontHdr->NumDescriptors) > 11 ? 42 : 11, counter; LPSTR FontNames, Separator; UINT uFontNameNumber; if (FontDescLength>11) topic->FontShowsItsMVCC=TRUE; // Currently the only point to find out about it, but There is a Factor of 10 in Left/Right Alignment... /* Read in the Names of the Fonts... */ IFSSeekFile(hfont, NameOffset, SEEK_SET); if (NULL!=(FontNames = (LPSTR) Hlpmalloc(leword(FontHdr->NumFonts) * FontNameLength+sizeof(LOGFONT)))) { IFSReadFile(hfont, FontNames, leword(FontHdr->NumFonts) * FontNameLength); /* Convert the font-Desciptors to a simpler format */ for (counter = 0; counter < leword(FontHdr->NumDescriptors); counter++) { /* Get Pointer to the LOGFONT structure for this Font. */ lpfi=topic->FontSelectors->Font+counter; switch (FontDescLength) { case 11: { /* Windows 3.x type font structure */ IFSReadFile(hfont, & FontDesc, sizeof( FontDesc)); lpfi->lf.lfHeight = FontDesc.HalfPoints; uFontNameNumber = FontDesc.FontName; if (FontDesc.Attributes & FONT_BOLD) lpfi->lf.lfWeight=FW_BOLD; if (FontDesc.Attributes & FONT_ITAL) lpfi->lf.lfItalic=TRUE; if (FontDesc.Attributes & FONT_UNDR) lpfi->lf.lfUnderline=TRUE; } break; case 42: { /* WIndows 4.x type font structure */ IFSReadFile(hfont, &LongFontDesc, sizeof(LongFontDesc)); memset(&FontDesc, 0, sizeof(FontDesc)); memcpy(&FontDesc.FGRGB, &LongFontDesc.FGRGB, 3); memcpy(&FontDesc.BGRGB, &LongFontDesc.BGRGB, 3); lpfi->lf.lfHeight = -2*ledword(LongFontDesc.NegHalfPoints); // FontDesc.HalfPoints = (short) (-2*LongFontDesc.NegHalfPoints); // FontDesc.FontName = (short) LongFontDesc.FontName; uFontNameNumber = ledword(LongFontDesc.FontName); switch (LongFontDesc.FontFamily) { case 0x10: FontDesc.FontFamily = FAM_ROMAN; break; case 0x20: FontDesc.FontFamily = FAM_SWISS; break; case 0x30: FontDesc.FontFamily = FAM_MODERN; break; case 0x40: FontDesc.FontFamily = FAM_SCRIPT; break; case 0x50: FontDesc.FontFamily = FAM_DECOR; break; default: FontDesc.FontFamily = FAM_MODERN; } lpfi->lf.lfWeight = ledword(LongFontDesc.lfWeight); lpfi->lf.lfItalic = LongFontDesc.lfItalic != 0; } } /* Translate data in the Font Descriptor into LOGFONT-Structure */ /* Get Face name */ memcpy(lpfi->lf.lfFaceName, FontNames + (FontNameLength * uFontNameNumber), sizeof(lpfi->lf.lfFaceName)); if (NULL!=(Separator = strrchr(lpfi->lf.lfFaceName, ','))) *Separator = 0; /* Get Font Family */ switch (FontDesc.FontFamily) { case FAM_MODERN: lpfi->lf.lfPitchAndFamily = FF_MODERN; break; case FAM_ROMAN: lpfi->lf.lfPitchAndFamily = FF_ROMAN; break; case FAM_SWISS: lpfi->lf.lfPitchAndFamily = FF_SWISS; break; case FAM_SCRIPT: lpfi->lf.lfPitchAndFamily = FF_SCRIPT; break; case FAM_DECOR: lpfi->lf.lfPitchAndFamily = FF_DECORATIVE;break; } /* Switch */ lpfi->FGcolor = RGB(FontDesc.FGRGB[0], FontDesc.FGRGB[1], FontDesc.FGRGB[2]); if (lpfi->FGcolor == 0xffffff) lpfi->FGcolor = 0x000000; lpfi->BGcolor = RGB(FontDesc.BGRGB[0], FontDesc.BGRGB[1], FontDesc.BGRGB[2]); // lpfi->lf.lfHeight=FontDesc.HalfPoints; } /* for counter */ Hlpfree(FontNames); } /* if malloc */ } /* iFontsFree * * Free up memory allocates for font-table */ void iFontsFree(NPTOPIC topic) /* Free Memory used by Fonts-Table */ { if (topic->FontSelectors) { Hlpfree(topic->FontSelectors); topic->FontSelectors=NULL; } } /* iFontsGetRtfSelection * * get an rtf-string that represents a given font based on the assumption, * that the colortable and fonttable has been created using iFontsGetRtfTable * * The memory-Block needs to be freed by the caller */ LPCSTR iFontsGetRtfSelection(NPTOPIC topic, int FontNum) /* Get a Font as an rtf-String */ { LPSTR str=NULL; LPFONTINFO lpfi; if (topic->FontSelectors && FontNum>=0 && FontNumFontSelectors->FontCount ) { str =(LPSTR) Hlpmalloc(100); lpfi=topic->FontSelectors->Font+FontNum; wsprintf(str, "\\f%d\\cf%d\\fs%d", FontNum, FontNum, lpfi->lf.lfHeight); strcat(str, lpfi->lf.lfWeight >= FW_NORMAL ? "\\b" : "\\b0"); strcat(str, lpfi->lf.lfItalic ? "\\i" : "\\i0"); strcat(str, lpfi->lf.lfUnderline ? "\\ul": "\\ul0"); } return str; } /* iFontsGetRtfTable * * Get a memory-Block with the Colortable and the fonttable */ LPCSTR iFontsGetRtfTable(NPTOPIC topic) /* Get RTF colortable */ { LPSTR str=NULL, dst; LPFONTINFO lpfi; int counter; LPCSTR type; if (topic->FontSelectors && topic->FontSelectors->FontCount && NULL!=(str = dst = (LPSTR) Hlpmalloc(topic->FontSelectors->FontCount * 100+100)) ) { strcpy(str, "{\\fonttbl\n"); /* Walk thru the available Fonts */ for (counter = 0; counter < topic->FontSelectors->FontCount; counter++) { dst=dst+strlen(dst); lpfi=topic->FontSelectors->Font + counter; switch (lpfi->lf.lfPitchAndFamily) { case FF_MODERN: type = "modern"; break; case FF_ROMAN: type = "roman"; break; case FF_SWISS: type = "swiss"; break; case FF_SCRIPT: type = "script"; break; case FF_DECORATIVE: type = "decor"; break; default: type="modern"; break; } /* Switch */ wsprintf(dst, "{\\f%d\\f%s %s;}\n", counter, type, lpfi->lf.lfFaceName); } /* Walk thru the available Font Colors */ strcat(dst, "}\n" "{\\colortbl\n"); for (counter = 0; counter < topic->FontSelectors->FontCount; counter++) { dst=dst+strlen(dst); lpfi=topic->FontSelectors->Font + counter; wsprintf(dst, "\\red%d\\green%d\\blue%d;\n", GetRValue(lpfi->FGcolor) , GetGValue(lpfi->FGcolor) , GetBValue(lpfi->FGcolor) ); } strcat(dst, "}\n"); } return str; } #ifdef OBSOLETE /*************************************************** Lists all of the fonts and font descriptors. Fonts are fixed length 20 followed by Font descriptors of Fixed Length 11 bytes. ****************************************************/ void LOCAL HlpFontDump(LPIFS ifs, FILE *rtf) { FILE * HelpFile = ifs->HelpFile; LONG FileStart= ifs->FontsOffset; // FILEHEADER FileHdr; FONTHEADER FontHdr; FONTDESCRIPTOR FontDesc; LONGFONTDESCRIPTOR LongFontDesc; char AFont[35], SelectString[30], *Separator; // int FontNameLength = ifs->V40 ? 32 : 20; int FontNameLength; # ifdef MVB int FontDescLength; # endif LONG FontStart, CurrLoc, NameOffset; short counter; char *type; LPFONTSELECTORS FontSelectors; PALETTEENTRY *RgbQuad, *NextRgbQuad; BOOL FirstCall; // On first Call get Font-Selection Strings DWORD OldFilePos = ftell(HelpFile); COLORREF FGColor; /* Go to the FONT file and get the headers */ fseek(HelpFile, FileStart, SEEK_SET); // fread(&FileHdr, sizeof(FileHdr), 1, HelpFile); fread(&FontHdr, sizeof(FontHdr), 1, HelpFile); FontNameLength = (FontHdr.DescriptorsOffset- sizeof(FontHdr)) / FontHdr.NumFonts > 20 ? 32 : 20; # ifdef MVB FontDescLength = (ifs->FontsLength-FontHdr.DescriptorsOffset) / FontHdr.NumDescriptors > 11 ? 42 : 11; if (FontDescLength>11) ifs->MVCC=TRUE; // Currently the only point to find out about it, but There is a Factor of 10 in Left/Right Alignment... # else # define FontDescLength 11 # endif HLPTRACE(("|FONTS\n\nData Offset:0x%08lX Number Fonts: %d\n", FileStart, FontHdr.NumFonts)); HLPTRACE(("Font # - Font Name\n")); /* Keep track of start of fonts */ FontStart = ftell(HelpFile); NameOffset = FontStart + (FontHdr.DescriptorsOffset- sizeof(FontHdr)) - FontNameLength * FontHdr.NumFonts; fseek(HelpFile, NameOffset, SEEK_SET); for (counter = 0; counter < FontHdr.NumFonts; counter++) { fread(AFont, FontNameLength, 1, HelpFile); HLPTRACE((" %3d - %s\n", counter, AFont)); } /* Go to Font Descriptors. Don't actually need this, because we're there, but wanted to show how to get there using the offset. */ fseek(HelpFile, FontStart + (LONG)(FontHdr.DescriptorsOffset) - sizeof(FontHdr), SEEK_SET); HLPTRACE(("\nNum Font Descriptors: %d\n", FontHdr.NumDescriptors)); HLPTRACE(("Default Descriptor: %d\n\n", FontHdr.DefDescriptor)); HLPTRACE(("Attributes: n=none b=bold i=ital u=undr s=strkout d=dblundr C=smallcaps\n\n")); HLPTRACE(("Font Name PointSize Family FG RGB BG RGB Attributes\n")); HLPTRACE(("--------------------------------------------------------------------------\n")); if (rtf) fprintf(rtf, "{\\fonttbl\n"); FirstCall = !ifs->FontSelectors; if (FirstCall) { ifs->FontSelectors= FontSelectors = (LPFONTSELECTORS) Hlpcalloc( sizeof(FONTSELECTORS) + FontHdr.NumDescriptors * sizeof(LPSTR), 1); FontSelectors->FontCount = FontHdr.NumDescriptors; } RgbQuad = NextRgbQuad = (LPPALETTEENTRY) Hlpmalloc( FontHdr.NumDescriptors * 2 * sizeof(PALETTEENTRY) ); for (counter = 0; counter < FontHdr.NumDescriptors; counter++) { switch (FontDescLength) { case 11: fread(&FontDesc, sizeof(FontDesc), 1, HelpFile); break; case 42: { fread(&LongFontDesc, sizeof(LongFontDesc), 1, HelpFile); memset(&FontDesc, 0, sizeof(FontDesc)); memcpy(&FontDesc.FGRGB, &LongFontDesc.FGRGB, 3); memcpy(&FontDesc.BGRGB, &LongFontDesc.BGRGB, 3); FontDesc.HalfPoints = -2*LongFontDesc.NegHalfPoints; FontDesc.FontName = LongFontDesc.FontName; switch (LongFontDesc.FontFamily) { case 0x10: FontDesc.FontFamily = FAM_ROMAN; break; case 0x20: FontDesc.FontFamily = FAM_SWISS; break; case 0x30: FontDesc.FontFamily = FAM_MODERN; break; case 0x40: FontDesc.FontFamily = FAM_SCRIPT; break; case 0x50: FontDesc.FontFamily = FAM_DECOR; break; default: FontDesc.FontFamily = FAM_MODERN; } if (LongFontDesc.lfWeight > 500) FontDesc.Attributes |= FONT_BOLD; if (LongFontDesc.lfItalic ) FontDesc.Attributes |= FONT_ITAL; } } CurrLoc = ftell(HelpFile); fseek(HelpFile, NameOffset + (FontNameLength * FontDesc.FontName), SEEK_SET); fread(AFont, FontNameLength, 1, HelpFile); fseek(HelpFile, CurrLoc, SEEK_SET); if (NULL!=(Separator = strrchr(AFont, ','))) *Separator = 0; /* write out info on Font descriptor */ HLPTRACE(("%-20s %4.1f ", AFont, (float)(FontDesc.HalfPoints / 2))); switch (FontDesc.FontFamily) { case FAM_MODERN: HLPTRACE(("Modern")); type = "modern"; break; case FAM_ROMAN: HLPTRACE(("Roman ")); type = "roman"; break; case FAM_SWISS: HLPTRACE(("Swiss ")); type = "swiss"; break; case FAM_SCRIPT: HLPTRACE(("Script")); type = "script"; break; case FAM_DECOR: HLPTRACE(("Decor ")); type = "decor"; break; default: HLPTRACE(("0X%02X ", FontDesc.FontFamily)); type = " "; break; } /* Switch */ if (rtf) fprintf(rtf, " {\\f%d\\f%s %s;}\n", counter, type, AFont); HLPTRACE((" 0X%08lX ",RGB(FontDesc.FGRGB[0], FontDesc.FGRGB[1], FontDesc.FGRGB[2]))); HLPTRACE(("0X%08lX ",RGB(FontDesc.BGRGB[0], FontDesc.BGRGB[1], FontDesc.BGRGB[2]))); FGColor = RGB(FontDesc.FGRGB[0], FontDesc.FGRGB[1], FontDesc.FGRGB[2]); if (FGColor == 0xffffff) { FGColor = 0x000000; HLPTRACE(("->Black")); } *((LONG *)NextRgbQuad++) = FGColor; sprintf(SelectString, "\\f%d\\cf%d\\fs%d", counter, counter, FontDesc.HalfPoints); if (FontDesc.Attributes & FONT_BOLD) { HLPTRACE(("b")); strcat(SelectString, "\\b"); } else strcat(SelectString, "\\b0"); if (FontDesc.Attributes & FONT_ITAL) { HLPTRACE(("i")); strcat(SelectString, "\\i"); } else strcat(SelectString, "\\i0"); if (FontDesc.Attributes & FONT_UNDR) { HLPTRACE(("u")); strcat(SelectString, "\\ul"); } else strcat(SelectString, "\\ul0"); # if DEBUG if (FontDesc.Attributes & FONT_STRK) HLPTRACE(("s")); if (FontDesc.Attributes & FONT_DBUN) HLPTRACE(("d")); if (FontDesc.Attributes & FONT_SMCP) HLPTRACE(("C")); # endif if (FirstCall) FontSelectors->FontSelectString[counter] = Hlpstrdup(SelectString); HLPTRACE(("\n")); } if (rtf) { fprintf(rtf, "}\n" "{\\colortbl\n"); for (counter = 0, NextRgbQuad = RgbQuad; counter < FontHdr.NumDescriptors; counter++, NextRgbQuad++) fprintf(rtf, " \\red%d\\green%d\\blue%d;\n", NextRgbQuad->peRed, NextRgbQuad->peGreen, NextRgbQuad->peBlue); fprintf(rtf, "}\n%s ", GetStringFromId(IDS_PAPERFORMAT)); # if defined(_Windows) && !defined(__CONSOLE__) if (ifs->Flags & RTF_NEEDWORD) { char szFileName[90], *p; extern HINSTANCE hInst; GetModuleFileName(hInst, szFileName, sizeof(szFileName)); if (NULL!=(p=strrchr(szFileName, '\\'))) strcpy(p+1, "HLP2RTF.DOT"); fprintf(rtf, "{\\*\\template "); p=szFileName; RtfTopicString(ifs, rtf, &p, NULL, TEXTTYPE_CONTROL); fputc('}', rtf); } # endif } Hlpfree(RgbQuad); fseek(HelpFile, OldFilePos, SEEK_SET); } #endif