home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / odtlktv4.zip / ODTLKT / TOOLKIT / SAMPLES / OPENDOC / PARTS / TTAPE1 / TEXTDATA.CPP < prev    next >
Text File  |  1995-12-15  |  14KB  |  481 lines

  1. /***********************************************************************
  2. *
  3. *  File Name   : TEXTDATA.CPP
  4. *
  5. *  Description : Implementation of the TextData class.  This class both
  6. *                maintains and displays the Ticker Tape text.
  7. *
  8. *  Notes       : N/A
  9. *
  10. *  Entry Points: DefaultOutlineFont
  11. *                TextData::TextData
  12. *                TextData::DrawTape
  13. *                TextData::GetTextBuffer
  14. *                TextData::GetTextArea
  15. *                TextData::SetSize
  16. *                TextData::SetTextBuffer
  17. *                TextData::SetTextArea
  18. *
  19. *    (C) COPYRIGHT International Business Machines Corp. 1995
  20. *    All Rights Reserved
  21. *    Licensed Materials - Property of IBM
  22. *
  23. *    US Government Users Restricted Rights - Use, duplication or
  24. *    disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  25. *
  26. *    DISCLAIMER OF WARRANTIES.  The following [enclosed] code is
  27. *    sample code created by IBM Corporation. This sample code is not
  28. *    part of any standard or IBM product and is provided to you solely
  29. *    for the purpose of assisting you in the development of your
  30. *    applications.  The code is provided "AS IS", without
  31. *    warranty of any kind.  IBM shall not be liable for any damages
  32. *    arising out of your use of the sample code, even if they have been
  33. *    advised of the possibility of such damages.
  34. *
  35. ***********************************************************************/
  36. #include "textdata.hpp"
  37.  
  38. #include <stdio.h>
  39. #include <memory.h>
  40. #include <string.h>
  41.  
  42. /*
  43.  *
  44.  *    Method(s) :  DefaultOutlineFont
  45.  *
  46.  *  Description :  A utility routine which finds an outline font.  The
  47.  *                 font must be proportional so it can be resized in the
  48.  *                 text box and also demonstrate proportional support.
  49.  *
  50.  *                 The routine initially attempts to install the "Helv"
  51.  *                 outline font in the Font record within the textArea
  52.  *                 text-maintenance structure.
  53.  *
  54.  *   Parameters :  TEXTAREA *textArea - the text maintenance record.
  55.  *
  56.  *      Returns :  VOID
  57.  *
  58.  *        Notes :  N/A
  59.  */
  60. void DefaultOutlineFont(TEXTAREA *textarea)
  61. {
  62.     static FONTMETRICS fm[80]; /* The Font metrics information. */
  63.     LONG ltemp  = 0;
  64.     LONG cFonts = 0;
  65.     int     i;
  66.  
  67.     /*
  68.      *  Clear the text area's Font attributes record.
  69.      */
  70.     memset(&textarea->fAttr, 0 ,sizeof(FATTRS));
  71.  
  72.     /*
  73.      *  Load all fonts from the font resource file "helv.fon".
  74.      */
  75.     GpiLoadFonts(WinQueryAnchorBlock(HWND_DESKTOP), "helv");
  76.  
  77.     /*
  78.      *  Retrieve the number of fonts loaded by GpiLoadFonts,
  79.      *  which have the "helv" typeface name.
  80.      */
  81.     cFonts = GpiQueryFonts(textarea->hps, QF_PUBLIC|QF_PRIVATE, "Helv",
  82.                          <emp, sizeof(FONTMETRICS), (PFONTMETRICS)0);
  83.  
  84.     /*
  85.      *  Limit the number of fonts retrieved to the number which can
  86.      *  be stored in the "fm" local variable.
  87.      */
  88.     if (cFonts > sizeof(fm)/sizeof(FONTMETRICS))
  89.         cFonts = sizeof(fm)/sizeof(FONTMETRICS);
  90.  
  91.     /*
  92.      *  Retrieve the font metrics for all private fonts having the
  93.      *  "Helv" typeface name.
  94.      */
  95.     GpiQueryFonts(textarea->hps, QF_PUBLIC|QF_PRIVATE, "Helv", &cFonts,
  96.                   sizeof(FONTMETRICS), fm);
  97.  
  98.     /*
  99.      *  Find an outline font which is also kerned from the retrieved
  100.      *  font metrics.
  101.      */
  102.     for (i = 0; (!(fm[i].fsDefn&FM_DEFN_OUTLINE)) &&
  103.               (!(fm[i].fsType&FM_TYPE_KERNING)) && (i<cFonts); i++);
  104.  
  105.     /*
  106.      *  Find at least an outline font, if can't find one which is
  107.      *  both an outline and a kerned font.
  108.      */
  109.     if (i == cFonts)
  110.         for (i=0; (!(fm[i].fsDefn&FM_DEFN_OUTLINE))&& (i<cFonts); i++);
  111.  
  112.     /*
  113.      *  If can't find an outline font, use the first font found.
  114.      */
  115.     if (i == cFonts)
  116.         i = 0;
  117.  
  118.     /*
  119.      *  Initialize the text area's font metrics record and font
  120.      *  attributes record with the font information found above.
  121.      */
  122.     textarea->fmFont               = fm[i];
  123.     textarea->fAttr.usRecordLength = sizeof(FATTRS);
  124.     textarea->fAttr.lMatch         = fm[i].lMatch;
  125.     textarea->fAttr.lMatch         = 0;
  126.     textarea->fAttr.fsFontUse      = FATTR_FONTUSE_OUTLINE;
  127.     strcpy(textarea->fAttr.szFacename, fm[i].szFacename);
  128. }
  129.  
  130. /*
  131.  *
  132.  *    Method(s) :  TextData::TextData
  133.  *
  134.  *  Description :  TextData class constructor.  Create and initialize
  135.  *                 the textArea data structure.  Initialize the TextData
  136.  *                 class variables.
  137.  *
  138.  *   Parameters :  None.
  139.  *
  140.  *      Returns :  N/A
  141.  *
  142.  *        Notes :  N/A
  143.  */
  144. TextData::TextData (TextData *initData)
  145. {
  146.  
  147.     if (initData != NULL)
  148.     {
  149.         textBuffer    = initData->textBuffer;
  150.         sTextFileSize = initData->GetTextFileSize();
  151.         textArea      = initData->textArea;
  152.         sScrollPos    = initData->GetScrollPos();
  153.         sGap          = initData->GetGap();
  154.     }
  155.     else
  156.     {
  157.         textBuffer    = NULL;
  158.         textArea      = NULL;
  159.         sTextFileSize = 0;
  160.         sGap          = 0;
  161.         sScrollPos    = MAXSIZETEXTFILE +1;
  162.     }
  163.  
  164.     /*
  165.      *  Clear the text area data structure.
  166.      */
  167.     if (textArea == NULL)
  168.     {
  169.         textArea = new TEXTAREA;
  170.  
  171.         /*
  172.          *  Set the text attributes within the text area.
  173.          */
  174.         textArea->hps           = WinGetScreenPS(HWND_DESKTOP);
  175.         textArea->lColorText    = CLR_BLACK;
  176.         textArea->lBackText     = CLR_RED;
  177.         textArea->lScrollRate   = RATE;
  178.         textArea->sNeedToScroll = 1;
  179.  
  180.         /*
  181.          *  Install an outline font in the text data area.
  182.          */
  183.         DefaultOutlineFont(textArea);
  184.         WinReleasePS(textArea->hps);
  185.     }
  186. }
  187.  
  188. /*
  189.  *
  190.  *    Method(s) :  TextData::SetSize
  191.  *
  192.  *  Description :  Set the size of the textArea's rectlBox.
  193.  *
  194.  *   Parameters :  RECTL *rclFrame - new rectangle box size.
  195.  *
  196.  *      Returns :  VOID
  197.  *
  198.  *        Notes :  N/A
  199.  */
  200. void TextData::SetSize(RECTL *rclFrame)
  201. {
  202.     memcpy(&textArea->rectlBox, rclFrame, sizeof(RECTL));
  203. }
  204.  
  205. /*
  206.  *
  207.  *    Method(s) :  TextData::DrawTape
  208.  *
  209.  *  Description :  Draw the text within the textArea's rectangle box.
  210.  *                 Draw the text so that the height of the text fills
  211.  *                 the height of the box.
  212.  *
  213.  *   Parameters    HPS hps   - PM presentation screen handle.
  214.  *
  215.  *      Returns :  VOID
  216.  *
  217.  *        Notes :  N/A
  218.  */
  219. void TextData::DrawTape(HPS hps)
  220. {
  221.     SIZEF size;      /* Character-box size in world coordinates. */
  222.     LONG  lcid = 1;  /* Identifier for font.                     */
  223.     POINTL ptl;
  224.  
  225.     /*
  226.      *  The number of characters which can fit within the text
  227.      *  area's rectangle.  This is recalculated to get the number
  228.      *  of characters to write with GpiStringAt.
  229.      */
  230.     short sNumCharInBox = 0;
  231.  
  232.     /*
  233.      *  Create the logical font identifed by lcid and the contents
  234.      *  of the text area's FATTRS structure.
  235.      */
  236.     GpiCreateLogFont(hps, (PSTR8)0, lcid, &textArea->fAttr);
  237.  
  238.     /*
  239.      *  The size values are shifted to make them FIXED.
  240.      */
  241.     size.cy = MAKEFIXED(textArea->rectlBox.yTop, 0);  /* Height. */
  242.     size.cx = MAKEFIXED(textArea->rectlBox.yTop, 0);  /* Width.  */
  243.  
  244.     /*
  245.      *  Set the size of character-box to the specified size value.
  246.      *  Set the logical font identified by lcid.
  247.      */
  248.     GpiSetCharBox(hps, &size);
  249.     GpiSetCharSet(hps, lcid);
  250.  
  251.     /*
  252.      *  Get the font metrics for the set character-box size and
  253.      *  logical font.
  254.      */
  255.     GpiQueryFontMetrics(hps, sizeof(textArea->fmFont), &textArea->fmFont);
  256.  
  257.     /*
  258.      *  If the text is to displayed at a new scroll position then do
  259.      *  the following - which updates the "Gap" and "Scroll Position."
  260.      */
  261.     if (textArea->sNeedToScroll || (sScrollPos > MAXSIZETEXTFILE))
  262.     {
  263.         if (textArea->sNeedToScroll)
  264.         {
  265.  
  266.             /*
  267.              * Set color to background color for erasing previous text.
  268.              */
  269.             GpiSetColor(hps, textArea->lBackText);
  270.  
  271.             /*
  272.              * Erase previous text by filling box with background color.
  273.              */
  274.             POINTL drawPtl;
  275.  
  276.             drawPtl.x = 0L;
  277.             drawPtl.y = 0L;
  278.             GpiMove(hps, &drawPtl);
  279.  
  280.             drawPtl.x = textArea->rectlBox.xRight;
  281.             drawPtl.y = textArea->rectlBox.yTop;
  282.             GpiBox(hps, DRO_FILL, &drawPtl, 0L, 0L);
  283.         }
  284.  
  285.         /*
  286.          *  If the Scroll Position is past the end of the text then
  287.          *  set the Scroll Position to the first character in the
  288.          *  text, and the starting text position to past the right
  289.          *  end of the text area's rectangle.
  290.          */
  291.         if (sScrollPos >= sTextFileSize)
  292.         {
  293.             sScrollPos = 0;
  294.             sGap = textArea->rectlBox.xRight - textArea->fmFont.lAveCharWidth;
  295.         }
  296.  
  297.         /*
  298.          *  If starting text position, or "Gap", is past the left side
  299.          *  of the text area's rectangle, decrease "Gap" by the average
  300.          *  width of one character.  The "Gap" can't be negative.
  301.          */
  302.         if (sGap > -textArea->fmFont.lAveCharWidth)
  303.         {
  304.             sGap -= textArea->fmFont.lAveCharWidth;
  305.         }
  306.         else
  307.         {
  308.            /*
  309.             *  Otherwise, the text is scrolling past the left end
  310.             *  of the rectangle.  Increase the "Scroll Position",
  311.             *  or postion of first character of text to display.
  312.             */
  313.             ++ sScrollPos;
  314.         }
  315.  
  316.         /*
  317.          *  Make sure the text is not written to the left of origin.
  318.          */
  319.         if (sGap < -textArea->fmFont.lAveCharWidth)
  320.             sGap = -textArea->fmFont.lAveCharWidth;
  321.     }
  322.  
  323.     /*
  324.      *  Get the total number of characters that can fit in the box.
  325.      */
  326.     sNumCharInBox = ((textArea->rectlBox.xRight - sGap)/
  327.                                     textArea->fmFont.lAveCharWidth) + 2;
  328.  
  329.     /*
  330.      *  Decrement the result above by the number of characters in the
  331.      *  text from scroll position to the end of the string.
  332.      */
  333.     if (sNumCharInBox > (sTextFileSize - sScrollPos))
  334.         sNumCharInBox = sTextFileSize - sScrollPos;
  335.  
  336.     /*
  337.      *  Center the text vertically.
  338.      */
  339.     ptl.y = textArea->fmFont.lLowerCaseDescent;
  340.  
  341.     /*
  342.      *  Set the starting position of text within the Ticker Tape window.
  343.      */
  344.     ptl.x = sGap;
  345.  
  346.     /*
  347.      *  Set the foreground color for writing the current text.
  348.      */
  349.     GpiSetColor(hps, textArea->lColorText);
  350.  
  351.     /*
  352.      *  Write the Ticker Tape text to the presentation screen.
  353.      */
  354.     GpiCharStringAt(hps,
  355.                     (PPOINTL)&ptl,
  356.                     (SHORT)sNumCharInBox,
  357.                     textBuffer +sScrollPos);
  358. }
  359.  
  360. /*
  361.  *
  362.  *    Method(s) :  TextData::GetTextBuffer
  363.  *
  364.  *  Description :  Get the Ticker Tape text stored in the text buffer.
  365.  *
  366.  *   Parameters :  int bufferIndex - starting position within buffer.
  367.  *
  368.  *      Returns :  char * - reference to the textBuffer string.
  369.  *
  370.  *        Notes :  N/A
  371.  */
  372. CHAR *TextData::GetTextBuffer(int bufferIndex) const
  373. {
  374.     if (textBuffer != NULL)
  375.         return &textBuffer[bufferIndex];
  376.     else
  377.         return NULL;
  378. }
  379.  
  380. /*
  381.  *
  382.  *    Method(s) :  TextData::SetTextBuffer
  383.  *
  384.  *  Description :  Set the text buffer to the new Ticker Tape text.
  385.  *
  386.  *   Parameters :  CHAR *text - reference to the new text.
  387.  *                 SHORT sInitGap - Initial position of text within the
  388.  *                                  Ticker Tape window.
  389.  *                 SHORT sInitScrollPos - Position of first character of
  390.  *                                        text to display within the
  391.  *                                        Ticker Tape window.
  392.  *
  393.  *      Returns :  SHORT - 1, if text buffer set successful.
  394.  *                       - 0, if text buffer set failed.
  395.  *
  396.  *        Notes :  N/A
  397.  */
  398. SHORT TextData::SetTextBuffer(CHAR *text, SHORT sInitGap,
  399.                                           SHORT sInitScrollPos)
  400. {
  401.     SHORT success;  /* temporary boolean for returning success of */
  402.                     /* setting the textBuffer to the new text.    */
  403.  
  404.     /*
  405.      *  Delete the previous text stored in textBuffer.
  406.      */
  407.     if (textBuffer != NULL) delete [] textBuffer;
  408.     sTextFileSize = strlen(text);
  409.  
  410.     /*
  411.      *  Re-create a new textBuffer and copy the new text into it.
  412.      */
  413.     textBuffer = new CHAR [sTextFileSize+1];
  414.     if (textBuffer != NULL)
  415.     {
  416.         strcpy(textBuffer, text);
  417.  
  418.         /*
  419.          *  Initialize the location of the text, and the location of the
  420.          *  first character to display, within the Ticker Tape window.
  421.          */
  422.         sGap       = sInitGap;
  423.         sScrollPos = sInitScrollPos;
  424.         success = 1;
  425.     }
  426.     else
  427.     {
  428.         /*
  429.          *  Failed to allocate enough memory for the text buffer.
  430.          *  Reset text buffer, buffer length, and scroll parameters.
  431.          */
  432.         textBuffer = new CHAR [1];
  433.         textBuffer[0] = 0;
  434.         sTextFileSize = 0;
  435.  
  436.         sGap       = 0;
  437.         sScrollPos = 0;
  438.         success    = 0;
  439.     }
  440.  
  441.     return success;
  442. }
  443.  
  444. /*
  445.  *
  446.  *    Method(s) :  TextData::GetTextArea
  447.  *
  448.  *  Description :  Get the Ticker Tape text attributes stored in the
  449.  *                 text area.
  450.  *
  451.  *   Parameters :  TEXTAREA &textOut - the text attributes stored in
  452.  *                                     the text area.
  453.  *
  454.  *      Returns :  VOID
  455.  *
  456.  *        Notes :  N/A
  457.  */
  458. void TextData::GetTextArea(TEXTAREA &textOut)
  459. {
  460.     memcpy(&textOut, textArea, sizeof(TEXTAREA));
  461. }
  462.  
  463. /*
  464.  *
  465.  *    Method(s) :  TextData::SetTextArea
  466.  *
  467.  *  Description :  Set the Ticker Tape text attributes stored in the
  468.  *                 text area.
  469.  *
  470.  *   Parameters :  TEXTAREA textIn - the new text attributes.
  471.  *
  472.  *      Returns :  VOID
  473.  *
  474.  *        Notes :  N/A
  475.  */
  476. void TextData::SetTextArea(TEXTAREA textIn)
  477. {
  478.     memcpy(textArea, &textIn, sizeof(TEXTAREA));
  479. }
  480.  
  481.