/* * Copyright (c) 1995 FirePower Systems, Inc. * DO NOT DISTRIBUTE without permission * * $RCSfile: debug.c $ * $Revision: 1.1 $ * $Date: 1996/03/08 01:19:00 $ * $Locker: $ */ /******************************Module*Header*******************************\ * Module Name: debug.c * * debug helpers routine * * Copyright (c) 1992-1995 Microsoft Corporation * * Copyright (c) 1994 FirePower Systems, Inc. * Modified for FirePower display model by Neil Ogura (9-7-1994) * \**************************************************************************/ #include "driver.h" #if DBG || INVESTIGATE #include #endif #if DBG #define DUMP_PARAM_LEVEL 0 ULONG DebugLevel = 0; #endif #if INVESTIGATE #include #define MEMMAXBANDWIDTH FALSE #define MEMCPYPERFORM FALSE #define MEMCPYVERIFY FALSE #define SMP_TRACE FALSE static char *bittable[256] = { "........",".......*","......*.","......**",".....*..",".....*.*",".....**.",".....***", "....*...","....*..*","....*.*.","....*.**","....**..","....**.*","....***.","....****", "...*....","...*...*","...*..*.","...*..**","...*.*..","...*.*.*","...*.**.","...*.***", "...**...","...**..*","...**.*.","...**.**","...***..","...***.*","...****.","...*****", "..*.....","..*....*","..*...*.","..*...**","..*..*..","..*..*.*","..*..**.","..*..***", "..*.*...","..*.*..*","..*.*.*.","..*.*.**","..*.**..","..*.**.*","..*.***.","..*.****", "..**....","..**...*","..**..*.","..**..**","..**.*..","..**.*.*","..**.**.","..**.***", "..***...","..***..*","..***.*.","..***.**","..****..","..****.*","..*****.","..******", ".*......",".*.....*",".*....*.",".*....**",".*...*..",".*...*.*",".*...**.",".*...***", ".*..*...",".*..*..*",".*..*.*.",".*..*.**",".*..**..",".*..**.*",".*..***.",".*..****", ".*.*....",".*.*...*",".*.*..*.",".*.*..**",".*.*.*..",".*.*.*.*",".*.*.**.",".*.*.***", ".*.**...",".*.**..*",".*.**.*.",".*.**.**",".*.***..",".*.***.*",".*.****.",".*.*****", ".**.....",".**....*",".**...*.",".**...**",".**..*..",".**..*.*",".**..**.",".**..***", ".**.*...",".**.*..*",".**.*.*.",".**.*.**",".**.**..",".**.**.*",".**.***.",".**.****", ".***....",".***...*",".***..*.",".***..**",".***.*..",".***.*.*",".***.**.",".***.***", ".****...",".****..*",".****.*.",".****.**",".*****..",".*****.*",".******.",".*******", "*.......","*......*","*.....*.","*.....**","*....*..","*....*.*","*....**.","*....***", "*...*...","*...*..*","*...*.*.","*...*.**","*...**..","*...**.*","*...***.","*...****", "*..*....","*..*...*","*..*..*.","*..*..**","*..*.*..","*..*.*.*","*..*.**.","*..*.***", "*..**...","*..**..*","*..**.*.","*..**.**","*..***..","*..***.*","*..****.","*..*****", "*.*.....","*.*....*","*.*...*.","*.*...**","*.*..*..","*.*..*.*","*.*..**.","*.*..***", "*.*.*...","*.*.*..*","*.*.*.*.","*.*.*.**","*.*.**..","*.*.**.*","*.*.***.","*.*.****", "*.**....","*.**...*","*.**..*.","*.**..**","*.**.*..","*.**.*.*","*.**.**.","*.**.***", "*.***...","*.***..*","*.***.*.","*.***.**","*.****..","*.****.*","*.*****.","*.******", "**......","**.....*","**....*.","**....**","**...*..","**...*.*","**...**.","**...***", "**..*...","**..*..*","**..*.*.","**..*.**","**..**..","**..**.*","**..***.","**..****", "**.*....","**.*...*","**.*..*.","**.*..**","**.*.*..","**.*.*.*","**.*.**.","**.*.***", "**.**...","**.**..*","**.**.*.","**.**.**","**.***..","**.***.*","**.****.","**.*****", "***.....","***....*","***...*.","***...**","***..*..","***..*.*","***..**.","***..***", "***.*...","***.*..*","***.*.*.","***.*.**","***.**..","***.**.*","***.***.","***.****", "****....","****...*","****..*.","****..**","****.*..","****.*.*","****.**.","****.***", "*****...","*****..*","*****.*.","*****.**","******..","******.*","*******.","********" }; static CHAR dbgbuf[1024]; #define MAX_CRITICAL 6 // Number of maximum critical sections where CPU switch shouldn't happen #define MAX_STEP 100 #define RECORDINTERVAL 30000000 // Measure and out statistics every INTERVAL * 0.01 ms #define INITIALINTERVAL 12000000 // Initial addtion to the interval #define MAX_HOOKED_OPS 20 // Number of hooked operations by DrbBitBlt static ULONG FileId = 0; static FILE *stream = NULL; static ULONG startsec[MAX_TRAP], activated = 0, timercount=0, clockoverhead = 0; static ULONG numcalled[MAX_TRAP]; static ULONG totalelapse[MAX_TRAP]; static ULONG distribution[MAX_TRAP][MAX_STEP]; static ULONG enterCPU[MAX_TRAP]; static ULONG CPUSwitch[MAX_TRAP][4]; static ULONG SwitchDuringCritical[MAX_CRITICAL]; static ULONG TotalCritical[MAX_CRITICAL]; static UCHAR EnterCriticalCPU[MAX_CRITICAL]; static CHAR *TrapName[MAX_TRAP] = { "BITBLT","COPYBITS","STRETCHBLT","PLGBLT", "FILLPATH","STROKENFIL","TEXTOUT","PAINT","STROKEPATH","REALIZE_BRUSH", "DRV_BITBLT","DRV_COPYBITS","DRV_STRETCHBLT","DRV_PLGBLT", "DRV_FILLPATH","DRV_STROKENFIL","DRV_TEXTOUT","DRV_PAINT","DRV_STROKEPATH","DRV_REALIZE_BRUSH", "DITHER","SETPOINTERSHAPE","SETPALETTE","SAVESCREEN","DESTROYFONT" }; static CHAR *TextPerfCtgry[4] = {"Opaque no clipping", "Opaque with clipping", "Transparent no clipping", "Transparent with clipping" }; static CHAR *CriticalNames[MAX_CRITICAL] = { "RectFill", "RectOp", "RectCopy", "OpTgt", "PatFill", "EntireText" }; static CHAR *PaintCatNames[MAX_PAINT_CATEGORY] = { "SolidFill", "PatFill", "SolidOp", "PatOp", "NotSupported" }; static CHAR *PaintOpNames[MAX_PAINT_OPS] = { "ff", "00", "05", "0a", "0f", "50", "55", "5a", "5f", "a0", "a5", "aa", "af", "f0", "f5", "fa", "Pat-5a", "Pat-f0", "Pat-0f", "Pat-a5" }; static ULONG HookedBitBltOp[MAX_HOOKED_OPS] = {0x00000000, 0x0000ffff, 0x1111f0f0, 0xfffff0f0, 0x11110f0f, 0x00005555, 0x11115a5a, 0x1111a5a5, 0xffff5a5a, 0xffffa5a5, 0xffff0a0a, 0xffffa0a0, 0x1111b8b8, 0x00006666, 0x00008888, 0x0000eeee, 0x0000bbbb, 0x00004444, 0x00001111, 0x00003333 }; LONG TimesToMeasure = 1; ULONG Interval = INITIALINTERVAL; ULONG spentindrv; BOOL InitTable; ULONG FontTblMax, GlyphTblMax, CacheTblMax; ULONG CopyBitsHist[MAX_CATEGORY]; ULONG BitBltHist[MAX_CATEGORY]; ULONG TextOutHist[MAX_TEXT_CATEGORY]; ULONG fontSize[MAX_FONT_SIZE]; ULONG GlyphCountTable[MAX_GLYPH_COUNT]; ULONG FontAccl[MAX_CATEGORY]; ULONG TextRect[MAX_TEXT_RECT]; ULONG TextClip[MAX_CLIP_CONDITION]; ULONG TextWidthHist[6][MAX_WIDTH_STEP]; ULONG TextHeightHist[6][MAX_HEIGHT_STEP]; ULONG FontWidth[MAX_FONT_SIZE]; ULONG FontHeight[MAX_FONT_SIZE]; ULONG StrObjCountTable[MAX_STROBJ_COUNT]; ULONG FontIDTable[MAX_FONT_ENTRY][2]; ULONG GlyphHndlTable[MAX_GLYPH_HNDL_ENTRY][2]; ULONG CacheTable[MAX_CACHE_ENTRY][3]; ULONG CopyBitWidthHist[4][MAX_WIDTH_STEP]; ULONG CopyBitHeightHist[4][MAX_HEIGHT_STEP]; ULONG BitBltWidthHist[6][MAX_WIDTH_STEP]; ULONG BitBltHeightHist[6][MAX_HEIGHT_STEP]; ULONG BitBltRop[37][MAX_ROP_ENTRY]; ULONG BitBltBrush[2][MAX_BRUSH_ENTRY]; ULONG TextPerfByCtgry[4][2]; ULONG TextSubEntryCalled[MAX_TEXT_SUB_ENTRY]; ULONG TextSubEntryDCBZCalled[MAX_TEXT_SUB_ENTRY]; ULONG TextSubEntryTransCalled[MAX_TEXT_SUB_ENTRY]; ULONG PaintOp[MAX_PAINT_OPS]; ULONG PaintCategories[MAX_PAINT_CATEGORY]; ULONG PaintClips[MAX_PAINT_CATEGORY-1][MAX_PAINT_CLIP_ENTRY]; ULONG PaintHeight[MAX_PAINT_CATEGORY-1][MAX_PAINT_HEIGHT_ENTRY]; ULONG PaintWidth[MAX_PAINT_CATEGORY-1][MAX_PAINT_WIDTH_ENTRY]; ULONG PaintBounds[MAX_PAINT_CATEGORY-1][MAX_PAINT_BOUNDS_ENTRY]; VOID DisplayPDEV(); VOID PerformCheck( ULONG start, ULONG end, ULONG step, ULONG height); VOID VramAccess(); ULONG GetTime(); LONG SaveScreenMem( ULONG FileCategory, ULONG FileNumber ); LONG RestoreScreenMem( ULONG FileCategory, ULONG FileNumber ); VOID InitializeTable() { ULONG ui, uj; // Initialize table for(ui=0; ui= 10) DISPDBG((1, "BitBlt category: %u %u %u %u %u %u %u %u %u %u\n", BitBltHist[0], BitBltHist[1], BitBltHist[2], BitBltHist[3], BitBltHist[4], BitBltHist[5], BitBltHist[6], BitBltHist[7], BitBltHist[8], BitBltHist[9])); DISPDBG((1, "BitBlt ROP table count ave-width\n")); for(ui=0; ui0]: %d, [0->1]: %d, [1->0]: %d, [1->1]: %d\n", CPUSwitch[ui][0], CPUSwitch[ui][1], CPUSwitch[ui][2], CPUSwitch[ui][3]); fwrite(dbgbuf, 1, length, stream); #endif } #if SMP_TRACE length = sprintf(dbgbuf, "\nCPU Switch dring critical section\n"); fwrite(dbgbuf, 1, length, stream); for(ui=0; uiD, D->V, V->D, V->V"); fwrite(dbgbuf, 1, length, stream); for(ui=0; ui<4; ++ui) { length = sprintf(dbgbuf, "\nWidth Distribution\n"); fwrite(dbgbuf, 1, length, stream); for(uj=0; ujD, N->V, D->D, D->V, V->D, V->V"); fwrite(dbgbuf, 1, length, stream); for(ui=0; ui<6; ++ui) { length = sprintf(dbgbuf, "\nWidth Distribution\n"); fwrite(dbgbuf, 1, length, stream); for(uj=0; uj= 0) { #if DBG // EngDebugBreak(); #endif if(TimesToMeasure) { SaveScreenMem(0, 9999); #if MEMMAXBANDWIDTH VramAccess(); #endif #if MEMCPYPERFORM PerformCheck(1, 64, 1, 300); PerformCheck(250, 350, 7, 400); PerformCheck(650, 750, 31, 600); #endif RestoreScreenMem(0, 9999); } TimesToMeasure -= 1; } #endif } VOID ReportNesting( IN ULONG FunctionID ) { ULONG i; DISPDBG((0,"### Nesting function call: %s is called while executing", TrapName[FunctionID])); for(i=0; iTscStatusReg && SectionID < MAX_CRITICAL) { tscReg = *(myPDEV->TscStatusReg + 7); EnterCriticalCPU[SectionID] = tscReg & 0x40; } } VOID ExitCritical( IN ULONG SectionID ) { UCHAR tscReg; if(myPDEV->TscStatusReg && SectionID < MAX_CRITICAL) { tscReg = *(myPDEV->TscStatusReg + 7); if((tscReg & 0x40) != EnterCriticalCPU[SectionID]) { SwitchDuringCritical[SectionID] += 1; } TotalCritical[SectionID] += 1; } } VOID ClockStart( IN ULONG FunctionID ) { ULONG i; UCHAR tscReg; if(myPDEV->TscStatusReg) { tscReg = *(myPDEV->TscStatusReg + 7); if(tscReg & 0x40) enterCPU[FunctionID] = 1; else enterCPU[FunctionID] = 0; } if(timercount) { // There are some other functions nesting if(FunctionID == TRAP_PAINT || FunctionID == DRV_TRAP_PAINT || FunctionID == TRAP_BITBLT || FunctionID == TRAP_DITHER || FunctionID == DRV_TRAP_BITBLT || FunctionID == DRV_REALIZE_BRUSH) { for(i=0; i= MAX_STEP) index = MAX_STEP-1; distribution[FunctionID][index] += 1; timercount -= 1; startsec[FunctionID] = 0; if(timercount < 0) { DISPDBG((0,"### Timer Count Becomes Negative ###\n", TrapName[FunctionID])); } if(activated == 0) activated = time2; else { if(time2 > activated + Interval && timercount == 0) { // statistics out every INTERVAL seconds activated = 0; // reset acivated counter RecordPerformance(); } } if(myPDEV->TscStatusReg) { tscReg = *(myPDEV->TscStatusReg + 7); if(tscReg & 0x40) { if(enterCPU[FunctionID]) { CPUSwitch[FunctionID][3] += 1; } else { CPUSwitch[FunctionID][2] += 1; } } else { if(enterCPU[FunctionID]) { CPUSwitch[FunctionID][1] += 1; } else { CPUSwitch[FunctionID][0] += 1; } } } } VOID CountUp( IN ULONG FunctionID ) { numcalled[FunctionID] += 1; } VOID CountBreak() { if(breakcnt) { // break point counting mode? if(--breakcnt == 0) { EngDebugBreak(); } } else { if(dbgflg) EngDebugBreak(); } } #endif // INVESTIGATE /***************************************************************************** * * Routine Description: * * This function is variable-argument, level-sensitive debug print * routine. * If the specified debug level for the print statement is lower or equal * to the current debug level, the message will be printed. * * Arguments: * * DebugPrintLevel - Specifies at which debugging level the string should * be printed * * DebugMessage - Variable argument ascii c string * * Return Value: * * None. * ***************************************************************************/ VOID DebugPrint( ULONG DebugPrintLevel, PCHAR DebugMessage, ... ) { #if DBG va_list ap; va_start(ap, DebugMessage); #endif #if DBG if (DebugPrintLevel <= DebugLevel) { EngDebugPrint(STANDARD_DEBUG_PREFIX, DebugMessage, ap); } #endif #if DBG va_end(ap); #endif } // DebugPrint() #if INVESTIGATE LONG DumpSurfObj( char *title, SURFOBJ *pso ) { #define STYPE_MAX 9 #define ITYPE_MAX 4 char *StypeString[STYPE_MAX] = {"DEVICE", "1BPP", "4BPP", "8BPP", "16BPP", "24BPP", "32BPP", "4RLE", "8RLE" }; char *ItypeString[ITYPE_MAX] = {"BITMAP", "DEVICE", "JOURNAL", "DEVBITMAP"}; if(pso == NULL) { DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title)); return (0); } DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title)); DumpHex(" device handle", (ULONG) pso->dhsurf); DumpHex(" logical handle for the surface", (ULONG) pso->hsurf); DumpHex(" pdev handle", (ULONG) pso->dhpdev); DumpHex(" logical handle for the pdev", (ULONG) pso->hdev); DumpSizel(" bitmap size", &(pso->sizlBitmap)); DumpCombo(" buffer size", pso->cjBits); DumpHex(" bitmap address", (ULONG) pso->pvBits); DumpHex(" first scan line address", (ULONG) pso->pvScan0); DumpDecimal(" bytes per line", pso->lDelta); DumpCombo(" status", pso->iUniq); DumpTable(" bitmap format", pso->iBitmapFormat, StypeString, STYPE_MAX); DumpTable(" surface type", pso->iType, ItypeString, ITYPE_MAX); return(DumpDecimal(" bitmap style (direction)", pso->fjBitmap)); } LONG DumpClipObj( char *title, CLIPOBJ *pco ) { #define DCOMP_MAX 4 #define FCOMP_MAX 4 char *DcompString[DCOMP_MAX] = {"TRIVIAL", "RECT", "#INVALID#", "COMPLEX"}; char *FcompString[FCOMP_MAX] = {"#INVALID#", "RECT", "RECT4", "COMPLEX"}; if(pco == NULL) { DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title)); return(0); } DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title)); DumpCombo(" clip region ID", pco->iUniq); DumpRectl(" bounding rectangle", &(pco->rclBounds)); DumpTable(" complexity", pco->iDComplexity, DcompString, DCOMP_MAX); DumpTable(" whole region complexity", pco->iFComplexity, FcompString, FCOMP_MAX); DumpCombo(" mode", pco->iMode); return(DumpCombo(" options", pco->fjOptions)); } LONG DumpXlateObj( char *title, XLATEOBJ *pxlo ) { #define XLATFL_MAX 3 #define XLATST_MAX 4 FLTABLE xlatfltbl[XLATFL_MAX] = { {XO_TRIVIAL, "TRIVIAL"}, {XO_TABLE, "TABLE"}, {XO_TO_MONO, "TO_MONO"} }; KEYTABLE xlatsttbl[XLATST_MAX] = { {PAL_INDEXED, "PAL_INDEXED"}, {PAL_BITFIELDS, "PAL_BITFIELDS"}, {PAL_RGB, "PAL_RGB"}, {PAL_BGR, "PAL_BGR"} }; ULONG i; if(pxlo == NULL) { DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title)); return(0); } DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title)); DumpCombo(" xlate object ID", pxlo->iUniq); DumpFlong(" hints for translation", pxlo->flXlate, xlatfltbl, XLATFL_MAX); DumpKeyTable(" source palette type", pxlo->iSrcType, xlatsttbl, XLATST_MAX); DumpKeyTable(" target palette type", pxlo->iDstType, xlatsttbl, XLATST_MAX); DumpDecimal(" number of translation entries", pxlo->cEntries); for(i=0; icEntries; ++i) { DumpCombo(" translation", pxlo->pulXlate[i]); } return(0); } LONG DumpRectl( char *title, RECTL *prect ) { if(prect == NULL) { DISPDBG((DUMP_PARAM_LEVEL, "%s: NULL\n", title)); return(0); } DISPDBG((DUMP_PARAM_LEVEL, "%s: (%d, %d) - (%d, %d)\n", title, prect->left, prect->top, prect->right, prect->bottom)); return(0); } LONG DumpPointl( char *title, POINTL *pptl ) { if(pptl == NULL) { DISPDBG((DUMP_PARAM_LEVEL, "%s: NULL\n", title)); return(0); } DISPDBG((DUMP_PARAM_LEVEL, "%s: (%d, %d)\n", title, pptl->x, pptl->y)); return(0); } LONG DumpBrushObj( char *title, BRUSHOBJ *pbo ) { if(pbo == NULL) { DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title)); return(0); } DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title)); DumpDecimal(" solid brush color index", pbo->iSolidColor); return(DumpHex(" realization of the brush", (ULONG) pbo->pvRbrush)); } LONG DumpColorAdjustment( char *title, COLORADJUSTMENT *pca ) { #define CAFLG_MAX 2 static FLTABLE cafltbl[CAFLG_MAX] = {{CA_NEGATIVE, "NEGATIVE"}, {CA_LOG_FILTER, "LOG_FILTER"}}; #define CAILL_MAX 9 static char *cailltbl[CAILL_MAX] = {"DEFAULT", "A", "B", "C", "D50", "D55", "D65", "D75", "F2"}; if(pca == NULL) { DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title)); return(0); } DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title)); DumpDecimal(" size of the structure", pca->caSize); DumpFlong(" color flags", pca->caFlags, cafltbl, CAFLG_MAX); DumpTable(" illuminant", pca->caIlluminantIndex, cailltbl, CAILL_MAX); DumpDecimal(" RedGamma", pca->caRedGamma); DumpDecimal(" GreenGamma", pca->caGreenGamma); DumpDecimal(" BlueGamma", pca->caBlueGamma); DumpDecimal(" ReferenceBlack", pca->caReferenceBlack); DumpDecimal(" ReferenceWhite", pca->caReferenceWhite); DumpDecimal(" Contrast", pca->caContrast); DumpDecimal(" Brightness", pca->caBrightness); DumpDecimal(" Colorfulness", pca->caColorfulness); return(DumpDecimal(" RedGreenTint", pca->caRedGreenTint)); } LONG DumpPointFix( char *title, POINTFIX *pptfx ) { if(pptfx == NULL) { DISPDBG((DUMP_PARAM_LEVEL, "%s: NULL\n", title)); return(0); } DISPDBG((DUMP_PARAM_LEVEL, "%s: (%d, %d)\n", title, pptfx->x, pptfx->y)); return(0); } LONG DumpSizel( char *title, SIZEL *sizep ) { if(sizep == NULL) { DISPDBG((DUMP_PARAM_LEVEL, "%s: NULL\n", title)); return(0); } DISPDBG((DUMP_PARAM_LEVEL, "%s: (%d, %d)\n", title, sizep->cx, sizep->cy)); return(0); } LONG DumpStrObj( char *title, STROBJ *pstro ) { ULONG i; #define STRFL_MAX 7 static FLTABLE strfltbl[STRFL_MAX] = { {SO_FLAG_DEFAULT_PLACEMENT, "DEFAULT"}, {SO_HORIZONTAL, "HORIZONTAL"}, {SO_VERTICAL, "VERTICAL"}, {SO_REVERSED, "REVERSED"}, {SO_ZERO_BEARINGS, "ZERO_BEARINGS"}, {SO_CHAR_INC_EQUAL_BM_BASE, "BM_BASE"}, {SO_MAXEXT_EQUAL_BM_SIDE, "BM_SIZE"}}; if(pstro == NULL) { DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title)); return(0); } DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title)); DumpDecimal(" number of glyphs", pstro->cGlyphs); DumpFlong(" accelerator flag", pstro->flAccel, strfltbl, STRFL_MAX); DumpDecimal(" fixed pitch width", pstro->ulCharInc); DumpRectl(" bounding box", &(pstro->rclBkGround)); if(pstro->pgp) { // Has glyph DumpString(" glyphs\n"); for(i=0; icGlyphs; ++i) { DumpGlyphpos("glyphpos", &(pstro->pgp[i])); } } else { DumpString(" no glyphs\n"); } if(pstro->pwszOrg) DISPDBG((DUMP_PARAM_LEVEL, " unicode string: %S\n", pstro->pwszOrg)); else DISPDBG((DUMP_PARAM_LEVEL, " unicode string: NULL\n")); return(0); } LONG DumpGlyphpos( char *title, GLYPHPOS *pgp ) { if(pgp == NULL) { DISPDBG((DUMP_PARAM_LEVEL, " %s: NULL\n", title)); return(0); } DISPDBG((DUMP_PARAM_LEVEL, " -- %s dump --\n", title)); DumpCombo(" handle for the glyph", pgp->hg); if(pgp->pgdf != NULL) { DumpPointl(" character origin", &(pgp->pgdf->pgb->ptlOrigin)); DumpSizel(" glyph size", &(pgp->pgdf->pgb->sizlBitmap)); /******* printing gryph pattern is not practical using DISPDBG ****** { LONG i, j; BYTE *bp; bp = pgp->pgdf->pgb->aj; for(i=0; ipgdf->pgb->sizlBitmap.cy; ++i) { for(j=0; j<(pgp->pgdf->pgb->sizlBitmap.cx + 7)/8; ++j) { DumpString(bittable[*bp++]); } DumpString("\n"); } } ********************************************************************/ } return(DumpPointl(" position on device space", &(pgp->ptl))); } LONG DumpFontObj( char *title, FONTOBJ *pfo ) { #define FNTFL_MAX 6 FLTABLE fntfltbl[FNTFL_MAX] = { {FO_TYPE_RASTER, "RASTER"}, {FO_TYPE_DEVICE, "DEVICE"}, {FO_TYPE_TRUETYPE, "TRUETYPE"}, {FO_SIM_BOLD, "BOLD"}, {FO_SIM_ITALIC, "ITALIC"}, {FO_EM_HEIGHT, "EM_HEIGHT"}}; if(pfo == NULL) { DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title)); return(0); } DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title)); DumpCombo(" font ID", pfo->iUniq); DumpDecimal(" index to the device font", pfo->iFace); DumpDecimal(" maximum width", pfo->cxMax); DumpFlong(" font type", pfo->flFontType, fntfltbl, FNTFL_MAX); DumpCombo(" ID for true type font", pfo->iTTUniq); DumpCombo(" ID for device font", pfo->iFile); DumpSizel(" resolution", &(pfo->sizLogResPpi)); DumpDecimal(" size in point", pfo->ulStyleSize); DumpHex(" consumer", (ULONG) pfo->pvConsumer); return(DumpHex(" producer", (ULONG) pfo->pvProducer)); } LONG DumpMix( char *title, MIX mix ) { #define OP_MAX 17 static char *optbl[OP_MAX] = { "NULL", "BLACK (0)", "NOTMERGEPEN (DPon)", "MASKNOTPEN (DPna)", "NOTCOPYPEN (PN)", "MASKPENNOT (PDna)", "NOT (Dn)", "XORPEN (DPx)", "NOTMASKPEN (DPan)", "MASKPEN (DPa)", "NOTXORPEN (DPxn)", "NOP (D)", "MERGENOTPEN (DPno)", "COPYPEN (P)", "MERGEPENNOT (PDno)", "MERGEPEN (DPo)", "WHITE (1)" }; DumpTable(title, (mix & 0xff00) >> 8, optbl, OP_MAX); return(DumpTable(title, (mix & 0xff), optbl, OP_MAX)); } LONG DumpPathObj( char *title, PATHOBJ *ppo ) { #define PATHFL_MAX 2 FLTABLE pathfltbl[PATHFL_MAX] = {{PO_BEZIERS, "BEZIERS"} , {PO_ELLIPSE, "ELLIPSE"}}; if(ppo == NULL) { DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title)); return(0); } DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title)); DumpFlong(" hint flags", ppo->fl, pathfltbl, PATHFL_MAX); return(DumpDecimal(" number of curves", ppo->cCurves)); } LONG DumpXformObj( char *title, XFORMOBJ *pxo ) { if(pxo == NULL) { DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title)); return(0); } DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title)); return(0); } LONG DumpLineAttrs( char *title, LINEATTRS *plineattrs ) { #define LINEFL_MAX 3 FLTABLE linefltbl[LINEFL_MAX] = {{LA_GEOMETRIC, "Geometric"}, {LA_ALTERNATE, "Alternate"}, {LA_STARTGAP, "StartGap"}}; #define LINEJOIN_MAX 3 char *linejointbl[LINEJOIN_MAX] = {"Round", "Bevel", "Mitter"}; #define LINEEND_MAX 3 char *linenedtbl[LINEEND_MAX] = {"Round", "Square", "Butt"}; if(plineattrs == NULL) { DISPDBG((DUMP_PARAM_LEVEL, " %s: NULL\n", title)); return(0); } DISPDBG((DUMP_PARAM_LEVEL, " -- %s dump --\n", title)); DumpFlong(" option flag", plineattrs->fl, linefltbl, LINEFL_MAX); DumpTable(" join style", plineattrs->iJoin, linejointbl, LINEJOIN_MAX); DumpTable(" end style", plineattrs->iEndCap, linenedtbl, LINEEND_MAX); return(DumpDecimal(" number of style array", plineattrs->cstyle)); } LONG DumpDecimal( char *title, ULONG value ) { DISPDBG((DUMP_PARAM_LEVEL, "%s: %d\n", title, value)); return(0); } LONG DumpHex( char *title, ULONG value ) { DISPDBG((DUMP_PARAM_LEVEL, "%s: 0x%08x)\n", title, value)); return(0); } LONG DumpCombo( char *title, ULONG value ) { DISPDBG((DUMP_PARAM_LEVEL, "%s: %d (0x%x)\n", title, value, value)); return(0); } LONG DumpFlong( char *title, FLONG value, FLTABLE *fltblp, ULONG numentry ) { ULONG i; DISPDBG((DUMP_PARAM_LEVEL, "%s\n", title)); for(i=0; i