hlpfile.c
来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C语言 代码 · 共 2,066 行 · 第 1/5 页
C
2,066 行
/* FIXME: should build a string table for the attributes.link.lpszPath * they are reallocated for each link */ link = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_LINK) + strlen(str) + 1); if (!link) return NULL; link->cookie = cookie; link->lpszString = link_str = (char*)link + sizeof(HLPFILE_LINK); strcpy(link_str, str); link->lHash = hash; link->bClrChange = clrChange ? 1 : 0; link->window = wnd; link->wRefCount = 1; WINE_TRACE("Link[%d] to %s@%08x:%d\n", link->cookie, link->lpszString, link->lHash, link->window); return link;}/*********************************************************************** * * HLPFILE_AddParagraph */static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned* len){ HLPFILE_PAGE *page; HLPFILE_PARAGRAPH *paragraph, **paragraphptr; UINT textsize; BYTE *format, *format_end; char *text, *text_end; long size; unsigned short bits; unsigned nc, ncol = 1; if (!hlpfile->first_page) {WINE_WARN("no page\n"); return FALSE;}; for (page = hlpfile->first_page; page->next; page = page->next) /* Nothing */; for (paragraphptr = &page->first_paragraph; *paragraphptr; paragraphptr = &(*paragraphptr)->next) /* Nothing */; if (buf + 0x19 > end) {WINE_WARN("header too small\n"); return FALSE;}; size = GET_UINT(buf, 0x4); text = HeapAlloc(GetProcessHeap(), 0, size); if (!text) return FALSE; if (hlpfile->hasPhrases) { HLPFILE_Uncompress2(buf + GET_UINT(buf, 0x10), end, (BYTE*)text, (BYTE*)text + size); } else { if (GET_UINT(buf, 0x4) > GET_UINT(buf, 0) - GET_UINT(buf, 0x10)) { /* block is compressed */ HLPFILE_Uncompress3(text, text + size, buf + GET_UINT(buf, 0x10), end); } else { text = (char*)buf + GET_UINT(buf, 0x10); } } text_end = text + size; format = buf + 0x15; format_end = buf + GET_UINT(buf, 0x10); fetch_long(&format); *len = fetch_ushort(&format); if (buf[0x14] == 0x23) { char type; ncol = *format++; WINE_TRACE("#cols %u\n", ncol); type = *format++; if (type == 0 || type == 2) format += 2; format += ncol * 4; } for (nc = 0; nc < ncol; nc++) { WINE_TRACE("looking for format at offset %u for column %d\n", format - (buf + 0x15), nc); if (buf[0x14] == 0x23) format += 5; format += 4; bits = GET_USHORT(format, 0); format += 2; if (bits & 0x0001) fetch_long(&format); if (bits & 0x0002) fetch_short(&format); if (bits & 0x0004) fetch_short(&format); if (bits & 0x0008) fetch_short(&format); if (bits & 0x0010) fetch_short(&format); if (bits & 0x0020) fetch_short(&format); if (bits & 0x0040) fetch_short(&format); if (bits & 0x0100) format += 3; if (bits & 0x0200) { int ntab = fetch_short(&format); unsigned short ts; while (ntab-- > 0) { ts = fetch_ushort(&format); if (ts & 0x4000) fetch_ushort(&format); } } /* 0x0400, 0x0800 and 0x1000 don't need space */ if ((bits & 0xE080) != 0) WINE_FIXME("Unsupported bits %04x, potential trouble ahead\n", bits); while (text < text_end && format < format_end) { //WINE_TRACE("Got text: %s (%p/%p - %p/%p)\n", wine_dbgstr_a(text), text, text_end, format, format_end); textsize = strlen(text) + 1; if (textsize > 1) { paragraph = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_PARAGRAPH) + textsize); if (!paragraph) return FALSE; *paragraphptr = paragraph; paragraphptr = ¶graph->next; paragraph->next = NULL; paragraph->link = attributes.link; if (paragraph->link) paragraph->link->wRefCount++; paragraph->cookie = para_normal_text; paragraph->u.text.wFont = attributes.wFont; paragraph->u.text.wVSpace = attributes.wVSpace; paragraph->u.text.wHSpace = attributes.wHSpace; paragraph->u.text.wIndent = attributes.wIndent; paragraph->u.text.lpszText = (char*)paragraph + sizeof(HLPFILE_PARAGRAPH); strcpy(paragraph->u.text.lpszText, text); attributes.wVSpace = 0; attributes.wHSpace = 0; } /* else: null text, keep on storing attributes */ text += textsize; if (*format == 0xff) { format++; break; } WINE_TRACE("format=%02x\n", *format); switch (*format) { case 0x20: WINE_FIXME("NIY20\n"); format += 5; break; case 0x21: WINE_FIXME("NIY21\n"); format += 3; break; case 0x80: attributes.wFont = GET_USHORT(format, 1); WINE_TRACE("Changing font to %d\n", attributes.wFont); format += 3; break; case 0x81: attributes.wVSpace++; format += 1; break; case 0x82: attributes.wVSpace++; attributes.wIndent = 0; format += 1; break; case 0x83: attributes.wIndent++; format += 1; break;#if 0 case 0x84: format += 3; break;#endif case 0x86: case 0x87: case 0x88: { BYTE pos = (*format - 0x86); BYTE type = format[1]; long size; format += 2; size = fetch_long(&format); paragraph = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_PARAGRAPH) + textsize); if (!paragraph) return FALSE; *paragraphptr = paragraph; paragraphptr = ¶graph->next; paragraph->next = NULL; paragraph->link = attributes.link; if (paragraph->link) paragraph->link->wRefCount++; paragraph->cookie = para_bitmap; paragraph->u.gfx.pos = pos; switch (type) { case 0x22: fetch_ushort(&format); /* hot spot */ /* fall thru */ case 0x03: switch (GET_SHORT(format, 0)) { case 0: HLPFILE_LoadGfxByIndex(hlpfile, GET_SHORT(format, 2), paragraph); break; case 1: WINE_FIXME("does it work ??? %x<%lu>#%u\n", GET_SHORT(format, 0), size, GET_SHORT(format, 2)); HLPFILE_LoadGfxByAddr(hlpfile, format + 2, size - 4, paragraph); break; default: WINE_FIXME("??? %u\n", GET_SHORT(format, 0)); break; } break; case 0x05: WINE_FIXME("Got an embedded element %s\n", format + 6); break; default: WINE_FIXME("Got a type %d picture\n", type); break; } if (attributes.wVSpace) paragraph->u.gfx.pos |= 0x8000; format += size; } break; case 0x89: HLPFILE_FreeLink(attributes.link); attributes.link = NULL; format += 1; break; case 0x8B: case 0x8C: WINE_FIXME("NIY non-break space/hyphen\n"); format += 1; break;#if 0 case 0xA9: format += 2; break;#endif case 0xC8: case 0xCC: WINE_TRACE("macro => %s\n", format + 3); HLPFILE_FreeLink(attributes.link); attributes.link = HLPFILE_AllocLink(hlp_link_macro, (const char*)format + 3, 0, !(*format & 4), -1); format += 3 + GET_USHORT(format, 1); break; case 0xE0: case 0xE1: WINE_WARN("jump topic 1 => %u\n", GET_UINT(format, 1)); format += 5; break; case 0xE2: case 0xE3: case 0xE6: case 0xE7: HLPFILE_FreeLink(attributes.link); attributes.link = HLPFILE_AllocLink((*format & 1) ? hlp_link_link : hlp_link_popup, hlpfile->lpszPath, GET_UINT(format, 1), !(*format & 4), -1); format += 5; break; case 0xEA: case 0xEB: case 0xEE: case 0xEF: { char* ptr = (char*) format + 8; BYTE type = format[3]; int wnd = -1; char* str; if (type == 1) wnd = *ptr++; if (type == 4 || type == 6) { str = ptr; ptr += strlen(ptr) + 1; } else str = hlpfile->lpszPath; if (type == 6) { for (wnd = hlpfile->numWindows - 1; wnd >= 0; wnd--) { if (!strcmp(ptr, hlpfile->windows[wnd].name)) break; } if (wnd == -1) WINE_WARN("Couldn't find window info for %s\n", ptr); } HLPFILE_FreeLink(attributes.link); attributes.link = HLPFILE_AllocLink((*format & 4) ? hlp_link_link : hlp_link_popup, str, GET_UINT(format, 4), !(*format & 1), wnd); } format += 3 + GET_USHORT(format, 1); break; default: WINE_WARN("format %02x\n", *format); format++; } } } if (text_end != (char*)buf + GET_UINT(buf, 0x10) + size) HeapFree(GetProcessHeap(), 0, text_end - size); return TRUE;}/****************************************************************** * HLPFILE_ReadFont * * */static BOOL HLPFILE_ReadFont(HLPFILE* hlpfile){ BYTE *ref, *end; unsigned i, len, idx; unsigned face_num, dscr_num, face_offset, dscr_offset; BYTE flag, family; if (!HLPFILE_FindSubFile("|FONT", &ref, &end)) { WINE_WARN("no subfile FONT\n"); hlpfile->numFonts = 0; hlpfile->fonts = NULL; return FALSE; } ref += 9; face_num = GET_USHORT(ref, 0); dscr_num = GET_USHORT(ref, 2); face_offset = GET_USHORT(ref, 4); dscr_offset = GET_USHORT(ref, 6); WINE_TRACE("Got NumFacenames=%u@%u NumDesc=%u@%u\n", face_num, face_offset, dscr_num, dscr_offset); hlpfile->numFonts = dscr_num; hlpfile->fonts = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_FONT) * dscr_num); len = (dscr_offset - face_offset) / face_num;/* EPP for (i = face_offset; i < dscr_offset; i += len) *//* EPP WINE_FIXME("[%d]: %*s\n", i / len, len, ref + i); */ for (i = 0; i < dscr_num; i++) { flag = ref[dscr_offset + i * 11 + 0]; family = ref[dscr_offset + i * 11 + 2]; hlpfile->fonts[i].LogFont.lfHeight = -ref[dscr_offset + i * 11 + 1] / 2; hlpfile->fonts[i].LogFont.lfWidth = 0; hlpfile->fonts[i].LogFont.lfEscapement = 0; hlpfile->fonts[i].LogFont.lfOrientation = 0; hlpfile->fonts[i].LogFont.lfWeight = (flag & 1) ? 700 : 400; hlpfile->fonts[i].LogFont.lfItalic = (flag & 2) ? TRUE : FALSE; hlpfile->fonts[i].LogFont.lfUnderline = (flag & 4) ? TRUE : FALSE; hlpfile->fonts[i].LogFont.lfStrikeOut = (flag & 8) ? TRUE : FALSE; hlpfile->fonts[i].LogFont.lfCharSet = ANSI_CHARSET; hlpfile->fonts[i].LogFont.lfOutPrecision = OUT_DEFAULT_PRECIS; hlpfile->fonts[i].LogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; hlpfile->fonts[i].LogFont.lfQuality = DEFAULT_QUALITY; hlpfile->fonts[i].LogFont.lfPitchAndFamily = DEFAULT_PITCH; switch (family) { case 0x01: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_MODERN; break; case 0x02: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_ROMAN; break; case 0x03: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_SWISS; break; case 0x04: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_SCRIPT; break; case 0x05: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_DECORATIVE; break; default: WINE_FIXME("Unknown family %u\n", family); } idx = GET_USHORT(ref, dscr_offset + i * 11 + 3); if (idx < face_num) { memcpy(hlpfile->fonts[i].LogFont.lfFaceName, ref + face_offset + idx * len, min(len, LF_FACESIZE - 1)); hlpfile->fonts[i].LogFont.lfFaceName[min(len, LF_FACESIZE - 1)] = '\0'; } else { WINE_FIXME("Too high face ref (%u/%u)\n", idx, face_num); strcpy(hlpfile->fonts[i].LogFont.lfFaceName, "Helv");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?