hlpfile.c
来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C语言 代码 · 共 2,066 行 · 第 1/5 页
C
2,066 行
} } page->lpszTitle[titlesize] = '\0'; if (hlpfile->first_page) { HLPFILE_PAGE *p; for (p = hlpfile->first_page; p->next; p = p->next); page->prev = p; p->next = page; } else { hlpfile->first_page = page; page->prev = NULL; } page->file = hlpfile; page->next = NULL; page->first_paragraph = NULL; page->first_macro = NULL; page->wNumber = GET_UINT(buf, 0x21); page->offset = offset; page->browse_bwd = GET_UINT(buf, 0x19); page->browse_fwd = GET_UINT(buf, 0x1D); WINE_TRACE("Added page[%d]: title='%s' %08x << %08x >> %08x\n", page->wNumber, page->lpszTitle, page->browse_bwd, page->offset, page->browse_fwd); memset(&attributes, 0, sizeof(attributes)); /* now load macros */ ptr = page->lpszTitle + strlen(page->lpszTitle) + 1; while (ptr < page->lpszTitle + titlesize) { unsigned len = strlen(ptr); char* macro_str; WINE_TRACE("macro: %s\n", ptr); macro = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_MACRO) + len + 1); macro->lpszMacro = macro_str = (char*)(macro + 1); memcpy(macro_str, ptr, len + 1); /* FIXME: shall we really link macro in reverse order ?? * may produce strange results when played at page opening */ macro->next = page->first_macro; page->first_macro = macro; ptr += len + 1; } return TRUE;}static long fetch_long(BYTE** ptr){ long ret; if (*(*ptr) & 1) { ret = (*(unsigned long*)(*ptr) - 0x80000000L) / 2; (*ptr) += 4; } else { ret = (*(unsigned short*)(*ptr) - 0x8000) / 2; (*ptr) += 2; } return ret;}static unsigned long fetch_ulong(BYTE** ptr){ unsigned long ret; if (*(*ptr) & 1) { ret = *(unsigned long*)(*ptr) / 2; (*ptr) += 4; } else { ret = *(unsigned short*)(*ptr) / 2; (*ptr) += 2; } return ret;} static short fetch_short(BYTE** ptr){ short ret; if (*(*ptr) & 1) { ret = (*(unsigned short*)(*ptr) - 0x8000) / 2; (*ptr) += 2; } else { ret = (*(unsigned char*)(*ptr) - 0x80) / 2; (*ptr)++; } return ret;}static unsigned short fetch_ushort(BYTE** ptr){ unsigned short ret; if (*(*ptr) & 1) { ret = *(unsigned short*)(*ptr) / 2; (*ptr) += 2; } else { ret = *(unsigned char*)(*ptr) / 2; (*ptr)++; } return ret;}/****************************************************************** * HLPFILE_DecompressGfx * * Decompress the data part of a bitmap or a metafile */static BYTE* HLPFILE_DecompressGfx(BYTE* src, unsigned csz, unsigned sz, BYTE packing){ BYTE* dst; BYTE* tmp; BYTE* tmp2; unsigned sz77; WINE_TRACE("Unpacking (%d) from %u bytes to %u bytes\n", packing, csz, sz); switch (packing) { case 0: /* uncompressed */ if (sz != csz) WINE_WARN("Bogus gfx sizes (uncompressed): %u / %u\n", sz, csz); dst = src; break; case 1: /* RunLen */ tmp = dst = HeapAlloc(GetProcessHeap(), 0, sz); if (!dst) return NULL; HLPFILE_UncompressRLE(src, src + csz, &tmp, sz); if (tmp - dst != sz) WINE_WARN("Bogus gfx sizes (RunLen): %u/%u\n", tmp - dst, sz); break; case 2: /* LZ77 */ sz77 = HLPFILE_UncompressedLZ77_Size(src, src + csz); dst = HeapAlloc(GetProcessHeap(), 0, sz77); if (!dst) return NULL; HLPFILE_UncompressLZ77(src, src + csz, dst); if (sz77 != sz) WINE_WARN("Bogus gfx sizes (LZ77): %u / %u\n", sz77, sz); break; case 3: /* LZ77 then RLE */ sz77 = HLPFILE_UncompressedLZ77_Size(src, src + csz); tmp = HeapAlloc(GetProcessHeap(), 0, sz77); if (!tmp) return FALSE; HLPFILE_UncompressLZ77(src, src + csz, tmp); dst = tmp2 = HeapAlloc(GetProcessHeap(), 0, sz); if (!dst) return FALSE; HLPFILE_UncompressRLE(tmp, tmp + sz77, &tmp2, sz); if (tmp2 - dst != sz) WINE_WARN("Bogus gfx sizes (LZ77+RunLen): %u / %u\n", tmp2 - dst, sz); HeapFree(GetProcessHeap(), 0, tmp); break; default: WINE_FIXME("Unsupported packing %u\n", packing); return NULL; } return dst;}/****************************************************************** * HLPFILE_LoadBitmap * * */static BOOL HLPFILE_LoadBitmap(BYTE* beg, BYTE type, BYTE pack, HLPFILE_PARAGRAPH* paragraph){ BYTE* ptr; BYTE* pict_beg; BITMAPINFO* bi; unsigned long off, csz; HDC hdc; bi = HeapAlloc(GetProcessHeap(), 0, sizeof(*bi)); if (!bi) return FALSE; ptr = beg + 2; /* for type and pack */ bi->bmiHeader.biSize = sizeof(bi->bmiHeader); bi->bmiHeader.biXPelsPerMeter = fetch_ulong(&ptr); bi->bmiHeader.biYPelsPerMeter = fetch_ulong(&ptr); bi->bmiHeader.biPlanes = fetch_ushort(&ptr); bi->bmiHeader.biBitCount = fetch_ushort(&ptr); bi->bmiHeader.biWidth = fetch_ulong(&ptr); bi->bmiHeader.biHeight = fetch_ulong(&ptr); bi->bmiHeader.biClrUsed = fetch_ulong(&ptr); bi->bmiHeader.biClrImportant = fetch_ulong(&ptr); bi->bmiHeader.biCompression = BI_RGB; if (bi->bmiHeader.biBitCount > 32) WINE_FIXME("Unknown bit count %u\n", bi->bmiHeader.biBitCount); if (bi->bmiHeader.biPlanes != 1) WINE_FIXME("Unsupported planes %u\n", bi->bmiHeader.biPlanes); bi->bmiHeader.biSizeImage = (((bi->bmiHeader.biWidth * bi->bmiHeader.biBitCount + 31) & ~31) / 8) * bi->bmiHeader.biHeight; WINE_TRACE("planes=%d bc=%d size=(%d,%d)\n", bi->bmiHeader.biPlanes, bi->bmiHeader.biBitCount, bi->bmiHeader.biWidth, bi->bmiHeader.biHeight); csz = fetch_ulong(&ptr); fetch_ulong(&ptr); /* hotspot size */ off = GET_UINT(ptr, 0); ptr += 4; /* GET_UINT(ptr, 0); hotspot offset */ ptr += 4; /* now read palette info */ if (type == 0x06) { unsigned nc = bi->bmiHeader.biClrUsed; unsigned i; /* not quite right, especially for bitfields type of compression */ if (!nc && bi->bmiHeader.biBitCount <= 8) nc = 1 << bi->bmiHeader.biBitCount; bi = HeapReAlloc(GetProcessHeap(), 0, bi, sizeof(*bi) + nc * sizeof(RGBQUAD)); if (!bi) return FALSE; for (i = 0; i < nc; i++) { bi->bmiColors[i].rgbBlue = ptr[0]; bi->bmiColors[i].rgbGreen = ptr[1]; bi->bmiColors[i].rgbRed = ptr[2]; bi->bmiColors[i].rgbReserved = 0; ptr += 4; } } pict_beg = HLPFILE_DecompressGfx(beg + off, csz, bi->bmiHeader.biSizeImage, pack); paragraph->u.gfx.u.bmp.hBitmap = CreateDIBitmap(hdc = GetDC(0), &bi->bmiHeader, CBM_INIT, pict_beg, bi, DIB_RGB_COLORS); ReleaseDC(0, hdc); if (!paragraph->u.gfx.u.bmp.hBitmap) WINE_ERR("Couldn't create bitmap\n"); HeapFree(GetProcessHeap(), 0, bi); if (pict_beg != beg + off) HeapFree(GetProcessHeap(), 0, pict_beg); return TRUE;}/****************************************************************** * HLPFILE_LoadMetaFile * * */static BOOL HLPFILE_LoadMetaFile(BYTE* beg, BYTE pack, HLPFILE_PARAGRAPH* paragraph){ BYTE* ptr; unsigned long size, csize; unsigned long off, hsoff; BYTE* bits; LPMETAFILEPICT lpmfp; WINE_TRACE("Loading metafile\n"); ptr = beg + 2; /* for type and pack */ lpmfp = ¶graph->u.gfx.u.mfp; lpmfp->mm = fetch_ushort(&ptr); /* mapping mode */ lpmfp->xExt = GET_USHORT(ptr, 0); lpmfp->yExt = GET_USHORT(ptr, 2); ptr += 4; size = fetch_ulong(&ptr); /* decompressed size */ csize = fetch_ulong(&ptr); /* compressed size */ fetch_ulong(&ptr); /* hotspot size */ off = GET_UINT(ptr, 0); hsoff = GET_UINT(ptr, 4); ptr += 8; WINE_TRACE("sz=%lu csz=%lu (%d,%d) offs=%lu/%u,%lu\n", size, csize, lpmfp->xExt, lpmfp->yExt, off, ptr - beg, hsoff); bits = HLPFILE_DecompressGfx(beg + off, csize, size, pack); if (!bits) return FALSE; paragraph->cookie = para_metafile; lpmfp->hMF = SetMetaFileBitsEx(size, bits); if (!lpmfp->hMF) WINE_FIXME("Couldn't load metafile\n"); if (bits != beg + off) HeapFree(GetProcessHeap(), 0, bits); return TRUE;}/****************************************************************** * HLPFILE_LoadGfxByAddr * * */static BOOL HLPFILE_LoadGfxByAddr(HLPFILE *hlpfile, BYTE* ref, unsigned long size, HLPFILE_PARAGRAPH* paragraph){ unsigned i, numpict; numpict = GET_USHORT(ref, 2); WINE_TRACE("Got picture magic=%04x #=%d\n", GET_USHORT(ref, 0), numpict); for (i = 0; i < numpict; i++) { BYTE* beg; BYTE* ptr; BYTE type, pack; WINE_TRACE("Offset[%d] = %x\n", i, GET_UINT(ref, (1 + i) * 4)); beg = ptr = ref + GET_UINT(ref, (1 + i) * 4); type = *ptr++; pack = *ptr++; switch (type) { case 5: /* device dependent bmp */ case 6: /* device independent bmp */ HLPFILE_LoadBitmap(beg, type, pack, paragraph); break; case 8: HLPFILE_LoadMetaFile(beg, pack, paragraph); break; default: WINE_FIXME("Unknown type %u\n", type); return FALSE; } /* FIXME: hotspots */ /* FIXME: implement support for multiple picture format */ if (numpict != 1) WINE_FIXME("Supporting only one bitmap format per logical bitmap (for now). Using first format\n"); break; } return TRUE;}/****************************************************************** * HLPFILE_LoadGfxByIndex * * */static BOOL HLPFILE_LoadGfxByIndex(HLPFILE *hlpfile, unsigned index, HLPFILE_PARAGRAPH* paragraph){ char tmp[16]; BYTE *ref, *end; BOOL ret; WINE_TRACE("Loading picture #%d\n", index); if (index < hlpfile->numBmps && hlpfile->bmps[index] != NULL) { paragraph->u.gfx.u.bmp.hBitmap = hlpfile->bmps[index]; return TRUE; } sprintf(tmp, "|bm%u", index); if (!HLPFILE_FindSubFile(tmp, &ref, &end)) {WINE_WARN("no sub file\n"); return FALSE;} ref += 9; ret = HLPFILE_LoadGfxByAddr(hlpfile, ref, end - ref, paragraph); /* cache bitmap */ if (ret && paragraph->cookie == para_bitmap) { if (index >= hlpfile->numBmps) { hlpfile->numBmps = index + 1; if (hlpfile->bmps) hlpfile->bmps = HeapReAlloc(GetProcessHeap(), 0, hlpfile->bmps, hlpfile->numBmps * sizeof(hlpfile->bmps[0])); else hlpfile->bmps = HeapAlloc(GetProcessHeap(), 0, hlpfile->numBmps * sizeof(hlpfile->bmps[0])); } hlpfile->bmps[index] = paragraph->u.gfx.u.bmp.hBitmap; } return ret;}/****************************************************************** * HLPFILE_AllocLink * * */static HLPFILE_LINK* HLPFILE_AllocLink(int cookie, const char* str, LONG hash, BOOL clrChange, unsigned wnd){ HLPFILE_LINK* link; char* link_str;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?