home *** CD-ROM | disk | FTP | other *** search
/ NEXT Generation 27 / NEXT27.iso / pc / demos / emperor / dx3.exe / SDK / SAMPLES / IKLOWNS / CGTEXT.CPP < prev    next >
C/C++ Source or Header  |  1996-08-28  |  8KB  |  279 lines

  1. /*===========================================================================*\
  2. |
  3. |  File:        cgtext.cpp
  4. |
  5. |  Description: 
  6. |   Object class to manage lines of text to be displayed over a bitmap.
  7. |   The text may have an optional drop shadow and may be scrolled
  8. |   vertically.
  9. |       
  10. |-----------------------------------------------------------------------------
  11. |
  12. |  Copyright (C) 1995-1996 Microsoft Corporation.  All Rights Reserved.
  13. |
  14. |  Written by Moss Bay Engineering, Inc. under contract to Microsoft Corporation
  15. |
  16. \*===========================================================================*/
  17.  
  18. /**************************************************************************
  19.  
  20.     (C) Copyright 1995-1996 Microsoft Corp.  All rights reserved.
  21.  
  22.     You have a royalty-free right to use, modify, reproduce and 
  23.     distribute the Sample Files (and/or any modified version) in 
  24.     any way you find useful, provided that you agree that 
  25.     Microsoft has no warranty obligations or liability for any 
  26.     Sample Application Files which are modified. 
  27.  
  28.     we do not recomend you base your game on IKlowns, start with one of
  29.     the other simpler sample apps in the GDK
  30.  
  31.  **************************************************************************/
  32.  
  33. //** include files **
  34. #include <windows.h>
  35. #include <windowsx.h>
  36. #include "cgtext.h"
  37.  
  38. //** local definitions **
  39. typedef struct {
  40.     LPSTR       text;       // actual text string
  41.     int     nChars;     // number of characters in string
  42.     int     X;      // location of text in rectangle
  43.     int     Y;
  44.     COLORREF    color;      // color of text
  45.     COLORREF    dropColor;  // color of shadow
  46.     int     shadowX;    // horizontal offset of shaadow
  47.     int     shadowY;    // vertical offset of shadow
  48. } LINE_INFO;
  49.  
  50. #define DEFAULT_SHADOWX 2
  51. #define DEFAULT_SHADOWY 1
  52.  
  53. #define MAX(x,y)    (((x) > (y)) ? (x) : (y))
  54.  
  55. //** external functions **
  56. //** external data **
  57. //** public data **
  58. //** private data **
  59. //** public functions **
  60. //** private functions **
  61.  
  62. // ----------------------------------------------------------
  63. // CGameText contructor - 
  64. // ----------------------------------------------------------
  65. CGameText::CGameText(
  66.     HDC     hdc,        // hdc to blit to
  67.     LPRECT      pRect,      // rectangle to center text
  68.     int     screenLines,    // max lines on screen at once
  69.     int     linespacing // 1=single, 2=double 
  70. ) : hOldFont( NULL )
  71. {
  72.     nLines = 0;
  73.     maxLines = screenLines;
  74.     maxWidth = 0;
  75.     maxHeight = 0;
  76.     hdcText = hdc;
  77.     spacing = linespacing;
  78.     hFont = NULL;
  79.     memcpy(&rect, pRect, sizeof(RECT));
  80.     pLines = new CLinkedList;
  81.  
  82.     SetBkMode(hdc, TRANSPARENT);
  83. }
  84.  
  85. // ----------------------------------------------------------
  86. // CGameText destructor - 
  87. // ----------------------------------------------------------
  88. CGameText::~CGameText()
  89. {
  90.     LINE_INFO   *pCur;
  91.  
  92.     // remove all the text and delete entry in list
  93.     while ((pCur = (LINE_INFO *)pLines->RemoveFirst()) != NULL)
  94.     {
  95.         delete pCur->text;  // hope caller alloced these with new!
  96.         delete pCur;
  97.     }
  98.  
  99.     delete pLines;
  100.  
  101.     if (hOldFont)
  102.         SelectObject( hdcText, hOldFont );
  103.  
  104.     if (hFont)
  105.         DeleteObject(hFont);
  106. }
  107.  
  108. // ----------------------------------------------------------
  109. // AddLine - add a new line of text to the list
  110. // ----------------------------------------------------------
  111. int CGameText::AddLine(LPSTR NewLine, COLORREF Color, COLORREF DropShadow)
  112. {
  113.     LINE_INFO   *pCur = new LINE_INFO;
  114.  
  115.     pCur->text = NewLine;
  116.     pCur->nChars = lstrlen(NewLine);
  117.     pCur->X = -1;
  118.     pCur->Y = -1;
  119.     pCur->color = Color;
  120.     pCur->shadowX = 0;
  121.     pCur->shadowY = 0;
  122.     pCur->dropColor = DropShadow;
  123.     if (DropShadow != NO_SHADOW)
  124.     {
  125.         pCur->shadowX = DEFAULT_SHADOWX;
  126.         pCur->shadowY = DEFAULT_SHADOWY;
  127.     } else {
  128.         pCur->shadowX = 0;
  129.         pCur->shadowY = 0;
  130.     }
  131.  
  132.     pLines->Append(pCur);
  133.     return (++nLines);
  134. }
  135.  
  136. // ----------------------------------------------------------
  137. // ChangeColor - change the color of a particular string in
  138. //  the display list.  The text is repainted onto the DC.
  139. // ----------------------------------------------------------
  140. void CGameText::ChangeColor(
  141.     int     LineIndex,  // index of string to recolor
  142.     COLORREF    NewColor,   // color to make string
  143.     COLORREF    DropColor   // color of drop shadow
  144. )
  145. {
  146.     LINE_INFO   *pCur;
  147.  
  148.     if ((LineIndex <= 0) || (LineIndex > nLines))
  149.     {
  150.         return;
  151.     }
  152.  
  153.     // Find the line in list
  154.     pCur = (LINE_INFO *)pLines->GetFirst();
  155.     for (int ii=1; ii < LineIndex; ii++)
  156.     {
  157.         pCur = (LINE_INFO *)pLines->GetNext();
  158.     }
  159.  
  160.     // Change the color of the entry
  161.     pCur->color = NewColor;
  162.     pCur->dropColor = DropColor;
  163.  
  164.     // Display drop shadow if any
  165.     if (pCur->shadowX || pCur->shadowY)
  166.     {
  167.         SetTextColor(hdcText, pCur->dropColor);
  168.         TextOut(hdcText, pCur->X+pCur->shadowX, pCur->Y+pCur->shadowY
  169.         , pCur->text, pCur->nChars);
  170.     }
  171.  
  172.     // Display text
  173.     SetTextColor(hdcText, pCur->color);
  174.     TextOut(hdcText, pCur->X, pCur->Y, pCur->text, pCur->nChars);
  175. }
  176.  
  177. // ----------------------------------------------------------
  178. // GetText - retrieve text assoicated with a particular index
  179. // ----------------------------------------------------------
  180. LPSTR CGameText::GetText(
  181.     int LineIndex
  182. )
  183. {
  184.     LINE_INFO   *pCur;
  185.  
  186.     if ((LineIndex <= 0) || (LineIndex > nLines))
  187.     {
  188.         return(NULL);
  189.     }
  190.  
  191.     pCur = (LINE_INFO *)pLines->GetFirst();
  192.     for (int ii=1; ii < LineIndex; ii++)
  193.     {
  194.         pCur = (LINE_INFO *)pLines->GetNext();
  195.     }
  196.     
  197.     return(pCur->text);
  198. }
  199.  
  200. // ----------------------------------------------------------
  201. // TextBlt - draw text to DC
  202. // ----------------------------------------------------------
  203. int CGameText::TextBlt(
  204.     int ScrollPos       // offset using for scrolling the data
  205. )
  206. {
  207.     LINE_INFO   *pCur;
  208.     int     TextX, TextY;
  209.     int         totalLines;
  210.     int     nDisplayed=0;
  211.  
  212.     // Figure out how many lines are displayed and how tall each line is
  213.  
  214.     if (maxLines <= 2)
  215.         maxLines = nLines;
  216.  
  217. //  totalLines = nLines < maxLines ? nLines : maxLines;
  218.     totalLines = maxLines;
  219.     if (totalLines < 2)
  220.         totalLines = 2;
  221.  
  222.     maxHeight = (rect.bottom - rect.top) / ((totalLines * spacing) - 1);
  223.  
  224.     // figure out starting point (may be off screen if we are scrolling)
  225.     TextY = rect.top+ScrollPos; 
  226.     TextX = rect.left;
  227.  
  228.     // If we don't have a font yet -- figure out how big of a font to use
  229.     // and create it.
  230.     if (hFont == NULL)
  231.     {
  232.         LOGFONT logFont;
  233.         memset(&logFont, 0, sizeof(LOGFONT));
  234.         logFont.lfHeight = maxHeight;
  235.         logFont.lfPitchAndFamily = FF_ROMAN;
  236.         hFont = CreateFontIndirect(&logFont);
  237.                 hOldFont = (HFONT)SelectObject(hdcText, hFont);
  238.     }
  239.  
  240.  
  241.     // Go through each line of text and display it to the screen.
  242.     pCur = (LINE_INFO *)pLines->GetFirst();
  243.     while (pCur != NULL)
  244.     {
  245.  
  246.         // Don't bother if text won't be visible
  247.         if ((TextY+maxHeight > rect.top) && (TextY <rect.bottom))
  248.         {
  249.  
  250.             // paint shadow of text
  251.             if (pCur->shadowX || pCur->shadowY)
  252.             {
  253.                 SetTextColor(hdcText, pCur->dropColor);
  254.                 ExtTextOut(hdcText, TextX+pCur->shadowX
  255.                 , TextY+pCur->shadowY
  256.                 , ETO_CLIPPED, &rect
  257.                 , pCur->text, pCur->nChars, NULL);
  258.             }
  259.  
  260.             // paint text
  261.             SetTextColor(hdcText, pCur->color);
  262.             ExtTextOut(hdcText, TextX, TextY
  263.             , ETO_CLIPPED, &rect
  264.             , pCur->text, pCur->nChars, NULL);
  265.  
  266.             nDisplayed++;
  267.         }
  268.  
  269.         // save position of text
  270.         pCur->X = TextX;
  271.         pCur->Y = TextY;
  272.         TextY += maxHeight * spacing;
  273.  
  274.         pCur = (LINE_INFO *)pLines->GetNext();
  275.     }
  276.  
  277.     return(nDisplayed);
  278. }
  279.