Annotation of ntddk/src/video/displays/jz484/text.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1991-1992  Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:    Text.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     This module attempts to cache fonts on the VXL video board and draw glyphs
                     12:     using hardware acceleration,
                     13:     If the font cannot be cached the Engine is called to draw the glyphs.
                     14: 
                     15: Environment:
                     16: 
                     17: 
                     18: Revision History:
                     19: 
                     20: --*/
                     21: 
                     22: #include "driver.h"
                     23: #include "jzvxl484.h"
                     24: 
                     25: //
                     26: // The following macro is the hash function for computing the cache
                     27: // index from a Glyph Handle and  FontId.
                     28: //
                     29: 
                     30: #define HASH_FUNCTION(GlyphHandle,FontId) \
                     31:     ((GlyphHandle & 0x7FF) << 1) + \
                     32:     FontId + \
                     33:     (FontId << 7)
                     34: 
                     35: 
                     36: 
                     37: //#define CACHE_STATS
                     38: 
                     39: //
                     40: // Define string object accelerator masks.
                     41: //
                     42: 
                     43: #define SO_MASK \
                     44:     (SO_FLAG_DEFAULT_PLACEMENT | SO_ZERO_BEARINGS | \
                     45:      SO_CHAR_INC_EQUAL_BM_BASE | SO_MAXEXT_EQUAL_BM_SIDE)
                     46: 
                     47: #define SO_LTOR (SO_MASK | SO_HORIZONTAL)
                     48: #define SO_RTOL (SO_LTOR | SO_REVERSED)
                     49: #define SO_TTOB (SO_MASK | SO_VERTICAL)
                     50: #define SO_BTOT (SO_TTOB | SO_REVERSED)
                     51: 
                     52: static ULONG TextForegroundColor = 0xFFFFFFFF;
                     53: static ULONG TextBackgroundColor = 0xFFFFFFFF;
                     54: 
                     55: #ifdef CACHE_STATS
                     56: static ULONG CacheUnused = Vxl.CacheSize;
                     57: static ULONG CharCount = 0;
                     58: static ULONG CacheMisses = 0;
                     59: static ULONG CacheReplacement = 0;
                     60: static ULONG ReplacementTotal = 0;
                     61: static ULONG CharTotal = 0;
                     62: static ULONG MissTotal = 0;
                     63: static ULONG HigherFontId = 0;
                     64: static ULONG HigherGlyphHandle = 0;
                     65: #endif
                     66: 
                     67: static UCHAR ToBigEndian[256] = {
                     68:     0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
                     69:     0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
                     70:     0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
                     71:     0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
                     72:     0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
                     73:     0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
                     74:     0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
                     75:     0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
                     76:     0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
                     77:     0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
                     78:     0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
                     79:     0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
                     80:     0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
                     81:     0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
                     82:     0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
                     83:     0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
                     84:     };
                     85: 
                     86: 
                     87: 
                     88: BOOL
                     89: DrvTextOut
                     90: (
                     91:     IN SURFOBJ  *pso,
                     92:     IN STROBJ   *pstro,
                     93:     IN FONTOBJ  *pfo,
                     94:     IN CLIPOBJ  *pco,
                     95:     IN RECTL    *prclExtra,
                     96:     IN RECTL    *prclOpaque,
                     97:     IN BRUSHOBJ *pboFore,
                     98:     IN BRUSHOBJ *pboOpaque,
                     99:     IN POINTL   *pptlOrg,
                    100:     IN MIX       mix
                    101: )
                    102: /*++
                    103: 
                    104: Routine Description:
                    105: 
                    106:     This function will cache fonts on the VXL video board and use accelerator
                    107:     hardware to draw each glyph. An attemp is made to use opaque mode
                    108:     text output to draw text and background color at the same time. If this
                    109:     cannot be done then glyph forground and backgrounds are drawn spearately.
                    110: 
                    111: Arguments:
                    112: 
                    113:     MIX is not checked. Since the GCAPS_ARBMIXTEXT capability bit is not
                    114:     set, mix mode is always R2_COPYPEN.
                    115: 
                    116: Return Value:
                    117: 
                    118: 
                    119: --*/
                    120: 
                    121: {
                    122:     BOOL         bMoreGlyphs;
                    123:     LONG         LineIndex;
                    124:     ULONG        ByteIndex;
                    125:     PGLYPHPOS    GlyphPosList;
                    126:     ULONG        GlyphCount;
                    127:     ULONG        GlyphHandle;
                    128:     ULONG        CacheIndex;
                    129:     ULONG        FontId;
                    130:     GLYPHBITS    *FontBitMap;
                    131:     PBYTE        BitMapPtr;
                    132:     ULONG        X,Y;
                    133:     BOOL         Allocate;
                    134:     PULONG       CacheData;
                    135:     ULONG        BitMapData;
                    136:     ULONG        SrcAdr,DstAdr,XYCmd,Cmd;
                    137:     PGLYPHPOS    GlyphEnd;
                    138:     PGLYPHPOS    GlyphStart;
                    139:     LONG         GlyphStride;
                    140:     RECTL        OpaqueRectl;
                    141:     ULONG        GlyphBytesPerScan,ShiftAmount;
                    142: 
                    143:     //
                    144:     //  Make sure the surface is the screen.
                    145:     //
                    146: 
                    147:     if (pso->pvBits != (PVOID)Vxl.ScreenBase) {
                    148:         goto DevFailTextOut;
                    149:     }
                    150: 
                    151:     //
                    152:     // If the width of the glyph is bigger than what the accelerator supports
                    153:     //    The font is non cacheable
                    154:     //    Clipping is not trivial OR
                    155:     //    SolidColor is a brush.
                    156:     // call GDI to draw the text.
                    157:     //
                    158: 
                    159: 
                    160:     if ((pfo->cxMax > 32) ||
                    161:         (pfo->flFontType & DEVICE_FONTTYPE) ||
                    162:         (pco->iDComplexity != DC_TRIVIAL) ||
                    163:         (pboFore->iSolidColor == 0xFFFFFFFFL)) {
                    164: 
                    165:         goto DevFailTextOut;
                    166:     }
                    167: 
                    168:     //
                    169:     // Set Jaguar foreground color only if it changed since the
                    170:     // previous call. Changing Foreground/Background color requires
                    171:     // synchronization.
                    172:     //
                    173: 
                    174:     if (TextForegroundColor != pboFore->iSolidColor) {
                    175:         TextForegroundColor =  pboFore->iSolidColor;
                    176:         DevSetFgColor(TextForegroundColor);
                    177:     }
                    178: 
                    179:     //
                    180:     // Check that the Background color is solid.
                    181:     // Set Jaguar Background color if it changed.
                    182:     //
                    183: 
                    184:     if (prclOpaque != (PRECTL) NULL) {
                    185:         if (pboOpaque->iSolidColor == 0xFFFFFFFFL) {
                    186:             goto DevFailTextOut;
                    187:         }
                    188:         if (TextBackgroundColor != pboOpaque->iSolidColor) {
                    189:             TextBackgroundColor = pboOpaque->iSolidColor;
                    190:             DevSetBgColor(TextBackgroundColor);
                    191:         }
                    192:     }
                    193: 
                    194:     //
                    195:     //  enumerate the string psto into glyphs (GLYPHPOS), then send a draw
                    196:     //  command for each. Deal with clipping later.
                    197:     //
                    198: 
                    199:     FontId = pfo->iUniq;
                    200: #ifdef CACHE_STATS
                    201:     if (FontId > HigherFontId) {
                    202:         HigherFontId = FontId;
                    203:     }
                    204: #endif
                    205:     if (((pstro->flAccel == SO_LTOR) || (pstro->flAccel == SO_RTOL) ||
                    206:         (pstro->flAccel == SO_TTOB) || (pstro->flAccel == SO_BTOT)) &&
                    207:         (prclOpaque != NULL)) {
                    208: 
                    209:         //
                    210:         // If the top of the opaque rectangle is less than the top of the
                    211:         // background rectangle, then fill the region between the top of
                    212:         // opaque rectangle and the top of the background rectangle and
                    213:         // reduce the size of the opaque rectangle.
                    214:         //
                    215: 
                    216:         OpaqueRectl = *prclOpaque;
                    217:         if (OpaqueRectl.top < pstro->rclBkGround.top) {
                    218:             OpaqueRectl.bottom = pstro->rclBkGround.top;
                    219:             DrvpFillRectangle(&OpaqueRectl, pboOpaque->iSolidColor);
                    220:             OpaqueRectl.top = pstro->rclBkGround.top;
                    221:             OpaqueRectl.bottom = prclOpaque->bottom;
                    222:         }
                    223: 
                    224:         //
                    225:         // If the bottom of the opaque rectangle is greater than the bottom
                    226:         // of the background rectangle, then fill the region between the
                    227:         // bottom of the background rectangle and the bottom of the opaque
                    228:         // rectangle and reduce the size of the opaque rectangle.
                    229:         //
                    230: 
                    231:         if (OpaqueRectl.bottom > pstro->rclBkGround.bottom) {
                    232:             OpaqueRectl.top = pstro->rclBkGround.bottom;
                    233:             DrvpFillRectangle(&OpaqueRectl, pboOpaque->iSolidColor);
                    234:             OpaqueRectl.top = pstro->rclBkGround.top;
                    235:             OpaqueRectl.bottom = pstro->rclBkGround.bottom;
                    236:         }
                    237: 
                    238:         //
                    239:         // If the left of the opaque rectangle is less than the left of
                    240:         // the background rectangle, then fill the region between the
                    241:         // left of the opaque rectangle and the left of the background
                    242:         // rectangle.
                    243:         //
                    244: 
                    245:         if (OpaqueRectl.left < pstro->rclBkGround.left) {
                    246:             OpaqueRectl.right = pstro->rclBkGround.left;
                    247:             DrvpFillRectangle(&OpaqueRectl, pboOpaque->iSolidColor);
                    248:             OpaqueRectl.right = prclOpaque->right;
                    249:         }
                    250: 
                    251:         //
                    252:         // If the right of the opaque rectangle is greater than the right
                    253:         // of the background rectangle, then fill the region between the
                    254:         // right of the opaque rectangle and the right of the background
                    255:         // rectangle.
                    256:         //
                    257: 
                    258:         if (OpaqueRectl.right > pstro->rclBkGround.right) {
                    259:             OpaqueRectl.left = pstro->rclBkGround.right;
                    260:             DrvpFillRectangle(&OpaqueRectl, pboOpaque->iSolidColor);
                    261:         }
                    262: 
                    263:         Cmd = JAGUAR_TEXT_OPAQUE << XYCMD_CMD_SHIFT;
                    264: 
                    265:     } else {
                    266: 
                    267:         //
                    268:         //  We now have a cacheable font and drawable rectangles, first clip and draw
                    269:         //  all opaque rectangles.
                    270:         //
                    271: 
                    272:         if (prclOpaque != (PRECTL)NULL) {
                    273: 
                    274:             DrvpFillRectangle(prclOpaque,pboOpaque->iSolidColor);
                    275: 
                    276:         }
                    277:         Cmd = JAGUAR_TEXT_TRANSPARENT << XYCMD_CMD_SHIFT;
                    278:     }
                    279: 
                    280:     //
                    281:     // If the font is fixed pitch, then optimize the computation of
                    282:     // x and y coordinate values. Otherwise, compute the x and y values
                    283:     // for each glyph.
                    284:     //
                    285: 
                    286:     if (pstro->ulCharInc != 0) {
                    287: 
                    288:         //
                    289:         // The font is fixed pitch. Capture the glyph dimensions and
                    290:         // compute the starting display address.
                    291:         //
                    292: 
                    293:         if (pstro->pgp == NULL) {
                    294:             bMoreGlyphs = STROBJ_bEnum(pstro, &GlyphCount, &GlyphPosList);
                    295: 
                    296:         } else {
                    297:             GlyphCount = pstro->cGlyphs;
                    298:             GlyphPosList = pstro->pgp;
                    299:             bMoreGlyphs = FALSE;
                    300:         }
                    301: 
                    302: #ifdef CACHE_STATS
                    303:     CharCount += GlyphCount;
                    304: #endif
                    305: 
                    306:         FontBitMap = GlyphPosList->pgdf->pgb;
                    307:         X = FontBitMap->sizlBitmap.cx;
                    308:         Y = FontBitMap->sizlBitmap.cy;
                    309: 
                    310:         DstAdr = ((GlyphPosList->ptl.y + FontBitMap->ptlOrigin.y) * Vxl.JaguarScreenX) +
                    311:                  ((GlyphPosList->ptl.x + FontBitMap->ptlOrigin.x) << Vxl.ColorModeShift) ;
                    312: 
                    313:         //
                    314:         // Compute the glyph stride.
                    315:         //
                    316: 
                    317:         GlyphStride = ((pstro->ulCharInc) << Vxl.ColorModeShift);
                    318:         if ((pstro->flAccel & SO_VERTICAL) != 0) {
                    319:             GlyphStride *= Vxl.JaguarScreenX;
                    320:         }
                    321: 
                    322:         //
                    323:         // If the direction of drawing is reversed, then the stride is
                    324:         // negative.
                    325:         //
                    326: 
                    327:         if ((pstro->flAccel & SO_REVERSED) != 0) {
                    328:             GlyphStride = -GlyphStride;
                    329:         }
                    330: 
                    331:         //
                    332:         // Output the set of glyphs.
                    333:         //
                    334: 
                    335:         do {
                    336:             GlyphEnd = &GlyphPosList[GlyphCount];
                    337:             GlyphStart = GlyphPosList;
                    338:             do {
                    339: 
                    340:                 GlyphHandle = (ULONG) (GlyphStart->hg);
                    341: 
                    342:                 CacheIndex = HASH_FUNCTION(GlyphHandle,FontId);
                    343: 
                    344:                 CacheIndex &= Vxl.CacheIndexMask;
                    345: 
                    346:                 //
                    347:                 // Get glyph info
                    348:                 //
                    349: 
                    350:                 FontBitMap = GlyphStart->pgdf->pgb;
                    351: 
                    352:                 //
                    353:                 // If FontId or GlyphHandle don't match, cache this glyph.
                    354:                 //
                    355: 
                    356:                 if (Vxl.CacheTag[CacheIndex].FontId != FontId) {
                    357:                     Allocate = TRUE;
                    358:                 } else {
                    359:                     if (Vxl.CacheTag[CacheIndex].GlyphHandle != GlyphHandle) {
                    360:                         Allocate = TRUE;
                    361:                     } else {
                    362:                         Allocate = FALSE;
                    363:                     }
                    364:                 }
                    365:                 if (Allocate) {
                    366: 
                    367:                     //
                    368:                     // Wait for the accelerator to be idle to ensure
                    369:                     // that the glyph being replaced is not in use.
                    370:                     //
                    371: 
                    372:                     WaitForJaguarIdle();
                    373: 
                    374: #ifdef CACHE_STATS
                    375:                     CacheMisses++;
                    376: 
                    377:                     if (Vxl.CacheTag[CacheIndex].FontId == FreeTag) {
                    378:                         CacheUnused--;
                    379:                     } else {
                    380:                         CacheReplacement++;
                    381:                     }
                    382: 
                    383:                     if (Vxl.CacheTag[CacheIndex].FontId == FontId) {
                    384:                         DISPDBG((3, "Replacing same font Glyph %x with glyph %x\n",
                    385:                         Vxl.CacheTag[CacheIndex].FontId,
                    386:                         FontId));
                    387:                     }
                    388: 
                    389:                     if (Vxl.CacheTag[CacheIndex].GlyphHandle == GlyphHandle) {
                    390:                         DISPDBG((3, "Replacing same Glyph %x font %x with font %x\n",
                    391:                         GlyphHandle,
                    392:                         Vxl.CacheTag[CacheIndex].FontId,
                    393:                         FontId));
                    394:                     }
                    395: 
                    396:                     if (GlyphHandle > HigherGlyphHandle) {
                    397:                         HigherGlyphHandle = GlyphHandle;
                    398:                     }
                    399: #endif
                    400:                     //
                    401:                     // if the entry that needs to be replaced
                    402:                     // is used as extension for a glyph > 32 lines
                    403:                     // go backwards and clear the Id so that if the
                    404:                     // glyph > 32 is used again it'll miss in the cache
                    405:                     //
                    406:                     //
                    407: 
                    408:                     LineIndex = CacheIndex;
                    409:                     while (Vxl.CacheTag[LineIndex].FontId == GlyphExtended) {
                    410:                         LineIndex--;
                    411:                         Vxl.CacheTag[LineIndex].FontId = FreeTag;
                    412:                     }
                    413: 
                    414:                     //
                    415:                     // Clear the entries used by the big glyph that follows the one
                    416:                     // that needs to be replaced
                    417:                     //
                    418: 
                    419:                     LineIndex = CacheIndex+1;
                    420:                     while (Vxl.CacheTag[LineIndex].FontId == GlyphExtended) {
                    421:                         Vxl.CacheTag[LineIndex].FontId = FreeTag;
                    422:                         LineIndex++;
                    423:                     }
                    424: 
                    425:                     //
                    426:                     //  Store the tag for the current glyph.
                    427:                     //
                    428: 
                    429:                     Vxl.CacheTag[CacheIndex].FontId = FontId;
                    430:                     Vxl.CacheTag[CacheIndex].GlyphHandle = GlyphHandle;
                    431: 
                    432:                     CacheData = Vxl.FontCacheBase + (CacheIndex << 5);
                    433: 
                    434:                     //
                    435:                     // Fix the bit ordering and store the bitmap
                    436:                     // in off screen video memory.
                    437:                     //
                    438: 
                    439:                     BitMapPtr = FontBitMap->aj;
                    440:                     GlyphBytesPerScan = (X+7) >> 3;
                    441:                     ShiftAmount  = (GlyphBytesPerScan-1) << 3;
                    442: 
                    443: 
                    444:                     for (LineIndex=0;LineIndex < Y; LineIndex ++) {
                    445:                         BitMapData = 0;
                    446: 
                    447: 
                    448:                         for (ByteIndex = 0; ByteIndex < GlyphBytesPerScan; ByteIndex++) {
                    449:                             BitMapData >>= 8;
                    450:                             BitMapData |= ToBigEndian[*BitMapPtr++] << ShiftAmount;
                    451:                         }
                    452:                         *CacheData++ = BitMapData;
                    453:                     }
                    454: 
                    455:                     //
                    456:                     // If Y is bigger than 32 lines, the glyph that was just cached
                    457:                     // took more than one entry. Fix the CacheTags.
                    458:                     //
                    459: 
                    460:                     for (ByteIndex = 1; LineIndex > 32 ;ByteIndex++) {
                    461:                         Vxl.CacheTag[CacheIndex+ByteIndex].FontId = GlyphExtended;
                    462:                         LineIndex -=32;
                    463:                     }
                    464:                 }
                    465: 
                    466:                 //
                    467:                 // Find out where to draw the glyph and the glyph's starting address
                    468:                 //
                    469: 
                    470:                 SrcAdr = Vxl.FontCacheOffset + (CacheIndex << 7);
                    471: 
                    472:                 XYCmd = Cmd | (Y << XYCMD_Y_SHIFT) | X;
                    473: 
                    474:                 FifoWrite(DstAdr,SrcAdr,XYCmd);
                    475: 
                    476:                 DstAdr += GlyphStride;
                    477:                 GlyphStart += 1;
                    478:             } while (GlyphStart != GlyphEnd);
                    479: 
                    480:             if (bMoreGlyphs) {
                    481:                 bMoreGlyphs = STROBJ_bEnum(pstro, &GlyphCount, &GlyphPosList);
                    482: #ifdef CACHE_STATS
                    483:                 CharCount += GlyphCount;
                    484: #endif
                    485: 
                    486:             } else {
                    487:                 break;
                    488:             }
                    489:         } while (TRUE);
                    490: 
                    491:     } else {
                    492: 
                    493:         //
                    494:         // The font is not fixed pitch. Compute the x and y values for
                    495:         // each glyph individually.
                    496:         //
                    497: 
                    498:         do {
                    499: 
                    500:             //
                    501:             //  Get each glyph handle, find the physical address and send the
                    502:             //  draw command to the accelerator. Don't worry about clipping yet.
                    503:             //
                    504: 
                    505:             bMoreGlyphs = STROBJ_bEnum(pstro, &GlyphCount,&GlyphPosList);
                    506: 
                    507: #ifdef CACHE_STATS
                    508:             CharCount += GlyphCount;
                    509: #endif
                    510: 
                    511:             GlyphEnd = &GlyphPosList[GlyphCount];
                    512:             GlyphStart = GlyphPosList;
                    513:             do {
                    514: 
                    515:                 GlyphHandle = (ULONG) (GlyphStart->hg);
                    516: 
                    517:                 CacheIndex = HASH_FUNCTION(GlyphHandle,FontId);
                    518: 
                    519:                 CacheIndex &= Vxl.CacheIndexMask;
                    520: 
                    521:                 //
                    522:                 // Get glyph info
                    523:                 //
                    524: 
                    525:                 FontBitMap = GlyphStart->pgdf->pgb;
                    526:                 X = FontBitMap->sizlBitmap.cx;
                    527:                 Y = FontBitMap->sizlBitmap.cy;
                    528: 
                    529:                 //
                    530:                 // If FontId or GlyphHandle don't match, cache this glyph.
                    531:                 //
                    532: 
                    533: 
                    534:                 if (Vxl.CacheTag[CacheIndex].FontId != FontId) {
                    535:                     Allocate = TRUE;
                    536:                 } else {
                    537:                     if (Vxl.CacheTag[CacheIndex].GlyphHandle != GlyphHandle) {
                    538:                         Allocate = TRUE;
                    539:                     } else {
                    540:                         Allocate = FALSE;
                    541:                     }
                    542:                 }
                    543: 
                    544:                 if (Allocate) {
                    545: 
                    546:                     //
                    547:                     // Wait for the accelerator to be idle to ensure
                    548:                     // that the glyph being replaced is not in use.
                    549:                     //
                    550:                     WaitForJaguarIdle();
                    551: 
                    552: #ifdef CACHE_STATS
                    553:                     CacheMisses++;
                    554: #endif
                    555: 
                    556:                     //
                    557:                     // The Glyph that has to be replaced is from the same font,
                    558:                     // wait for the accelerator to be idle before caching the
                    559:                     // glyph.
                    560:                     //
                    561: 
                    562: #ifdef CACHE_STATS
                    563:                     if (Vxl.CacheTag[CacheIndex].FontId == FreeTag) {
                    564:                         CacheUnused--;
                    565:                     } else {
                    566:                         CacheReplacement++;
                    567:                     }
                    568: 
                    569:                     if (Vxl.CacheTag[CacheIndex].FontId == FontId) {
                    570:                         DISPDBG((3, "Replacing same font Glyph %x with glyph %x\n",
                    571:                         Vxl.CacheTag[CacheIndex].FontId,
                    572:                         FontId));
                    573:                     }
                    574: 
                    575:                     if (Vxl.CacheTag[CacheIndex].GlyphHandle == GlyphHandle) {
                    576:                         DISPDBG((3, "Replacing same Glyph %x font %x with font %x\n",
                    577:                             GlyphHandle,
                    578:                             Vxl.CacheTag[CacheIndex].FontId,
                    579:                             FontId));
                    580:                     }
                    581: 
                    582:                     if (GlyphHandle > HigherGlyphHandle) {
                    583:                         HigherGlyphHandle = GlyphHandle;
                    584:                     }
                    585: #endif
                    586: 
                    587:                     //
                    588:                     // if the entry that needs to be replaced
                    589:                     // is used as extension for a glyph > 32 lines
                    590:                     // go backwards and clear the Id so that if the
                    591:                     // glyph > 32 is used again it'll miss in the cache
                    592:                     //
                    593: 
                    594:                     LineIndex = CacheIndex;
                    595:                     while (Vxl.CacheTag[LineIndex].FontId == GlyphExtended) {
                    596:                         LineIndex--;
                    597:                         Vxl.CacheTag[LineIndex].FontId = FreeTag;
                    598:                     }
                    599: 
                    600:                     //
                    601:                     // Clear the entries used by the big glyph that follows the one
                    602:                     // that needs to be replaced
                    603:                     //
                    604: 
                    605:                     LineIndex = CacheIndex+1;
                    606:                     while (Vxl.CacheTag[LineIndex].FontId == GlyphExtended) {
                    607:                         Vxl.CacheTag[LineIndex].FontId = FreeTag;
                    608:                         LineIndex++;
                    609:                     }
                    610: 
                    611:                     //
                    612:                     //  Store the tag for the current glyph.
                    613:                     //
                    614: 
                    615:                     Vxl.CacheTag[CacheIndex].FontId = FontId;
                    616:                     Vxl.CacheTag[CacheIndex].GlyphHandle = GlyphHandle;
                    617: 
                    618:                     CacheData = Vxl.FontCacheBase + (CacheIndex << 5);
                    619: 
                    620:                     BitMapPtr = FontBitMap->aj;
                    621:                     GlyphBytesPerScan = (X+7) >> 3;
                    622:                     ShiftAmount  = (GlyphBytesPerScan-1) << 3;
                    623: 
                    624:                     for (LineIndex=0;LineIndex < Y; LineIndex ++) {
                    625:                         BitMapData = 0;
                    626:                         for (ByteIndex = 0; ByteIndex < GlyphBytesPerScan; ByteIndex++) {
                    627: 
                    628:                             BitMapData >>= 8;
                    629:                             BitMapData |= ToBigEndian[*BitMapPtr++] << ShiftAmount;
                    630:                         }
                    631:                         *CacheData++ = BitMapData;
                    632:                     }
                    633: 
                    634:                     //
                    635:                     // If Y is bigger than 32 lines, the glyph we just cached
                    636:                     // took more than one entry. Fix the CacheTags.
                    637:                     //
                    638: 
                    639:                     for (ByteIndex = 1; LineIndex > 32 ;ByteIndex++) {
                    640:                         Vxl.CacheTag[CacheIndex+ByteIndex].FontId = GlyphExtended;
                    641:                         LineIndex -=32;
                    642:                     }
                    643: 
                    644:                 }
                    645: 
                    646:                 SrcAdr = Vxl.FontCacheOffset + (CacheIndex << 7);
                    647: 
                    648:                 DstAdr = Vxl.JaguarScreenX * (GlyphStart->ptl.y + FontBitMap->ptlOrigin.y) +
                    649:                          ((GlyphStart->ptl.x + FontBitMap->ptlOrigin.x) << Vxl.ColorModeShift);
                    650: 
                    651:                 XYCmd = Cmd | (Y << XYCMD_Y_SHIFT) | X;
                    652: 
                    653:                 FifoWrite(DstAdr,SrcAdr,XYCmd);
                    654:                 GlyphStart += 1;
                    655:             } while (GlyphStart != GlyphEnd);
                    656:         } while (bMoreGlyphs);
                    657:     }
                    658: 
                    659:     //
                    660:     //  Draw extra rectangles using foreground brush
                    661:     //
                    662: 
                    663:     if (prclExtra != (PRECTL)NULL) {
                    664:         DrvpFillRectangle(prclExtra,pboFore->iSolidColor);
                    665:     }
                    666: 
                    667: #ifdef CACHE_STATS
                    668:     if (CharCount >= 10000) {
                    669:         ReplacementTotal += CacheReplacement;
                    670:         CharTotal += CharCount;
                    671:         MissTotal += CacheMisses;
                    672:         DISPDBG((3, "Cache Statistics for last %ld chars\n",CharCount));
                    673:         DISPDBG((3, "Misses = %ld Rate = %ld Replacements %ld\n",
                    674:               CacheMisses,
                    675:               (CacheMisses*100)/CharCount,
                    676:               CacheReplacement));
                    677: 
                    678:         DISPDBG((3, "Cache Statistics since begining. Total of %ld chars\n",CharTotal));
                    679:         DISPDBG((3, "Misses = %ld Rate = %ld Replacements %ld Unused entries = %ld\n",
                    680:               MissTotal,
                    681:               (MissTotal*100)/CharTotal,
                    682:               ReplacementTotal,
                    683:               CacheUnused));
                    684:         DISPDBG((3, "HigherFontId = %x HigherGlyphHandle = %x\n",HigherFontId,HigherGlyphHandle));
                    685:         CharCount = 0;
                    686:         CacheMisses = 0;
                    687:         CacheReplacement = 0;
                    688:     }
                    689: 
                    690: #endif
                    691: 
                    692:     //
                    693:     //  Done with call, return
                    694:     //
                    695: 
                    696:     return(TRUE);
                    697: 
                    698:     //
                    699:     // Could not execute this TextOut call, pass to engine.
                    700:     // No need to synchronize here since Eng routine will call DrvSynchronize.
                    701:     //
                    702: 
                    703: 
                    704: DevFailTextOut:
                    705: 
                    706:     return(EngTextOut(pso,
                    707:                       pstro,
                    708:                       pfo,
                    709:                       pco,
                    710:                       prclExtra,
                    711:                       prclOpaque,
                    712:                       pboFore,
                    713:                       pboOpaque,
                    714:                       pptlOrg,
                    715:                       mix));
                    716: 
                    717: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.