home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / include / fonttext.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-11  |  11.5 KB  |  477 lines

  1. #pragma once
  2.  
  3. //-----------------------------------------------------------------------------------//
  4. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  5. //                             ISBN  0-13-086985-6                                   //
  6. //                                                                                   //
  7. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  8. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  9. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  10. //                                                                                   //
  11. //  FileName   : fonttext.h                                                             //
  12. //  Description: Font &  text routines and classes                                   //
  13. //  Version    : 1.00.000, May 31, 2000                                              //
  14. //-----------------------------------------------------------------------------------//
  15.  
  16. // convert point size to logical coordinate space size
  17. int PointSizetoLogical(HDC hDC, int points, int divisor=1);
  18.  
  19. // Create a font as large as EM square size for accurate metrics
  20. HFONT CreateReferenceFont(HFONT hFont, int & emsquare);
  21.  
  22. // justify text string within a left..right margin
  23. BOOL TextOutJust(HDC hDC, int left, int right, int y, LPCTSTR lpStr, int nCount, bool bAllowNegative=false, TCHAR cBreakChar=' ');
  24.  
  25.  
  26. // ABC extent of a text string
  27. // ( A0, B0, C0 ) + ( A1, B1, C1 ) = ( A0, B0+C0+A1+B1, C1 }
  28. BOOL GetTextABCExtent(HDC hDC, LPCTSTR lpString, int cbString, long * pHeight, ABC * pABC);
  29.  
  30. BOOL GetOpaqueBox(HDC hDC, LPCTSTR lpString, int cbString, RECT * pRect, int x, int y);
  31.  
  32. // Pixel-level precise text alignment
  33. BOOL PreciseTextOut(HDC hDC, int x, int y, LPCTSTR lpString, int cbString);
  34.  
  35.  
  36. class KLogFont
  37. {
  38. public:
  39.     LOGFONT m_lf;
  40.  
  41.     KLogFont(int height, const TCHAR * typeface=NULL)
  42.     {
  43.         m_lf.lfHeight         = height;
  44.         m_lf.lfWidth          = 0;
  45.         m_lf.lfEscapement     = 0;
  46.         m_lf.lfOrientation    = 0;
  47.         m_lf.lfWeight         = FW_NORMAL;
  48.         m_lf.lfItalic         = FALSE;
  49.         m_lf.lfUnderline      = FALSE;
  50.         m_lf.lfStrikeOut      = FALSE;
  51.         m_lf.lfCharSet        = ANSI_CHARSET;
  52.         m_lf.lfOutPrecision   = OUT_TT_PRECIS;
  53.         m_lf.lfClipPrecision  = CLIP_DEFAULT_PRECIS;
  54.         m_lf.lfQuality        = DEFAULT_QUALITY;
  55.         m_lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
  56.  
  57.         if ( typeface )
  58.             _tcsncpy(m_lf.lfFaceName, typeface, LF_FACESIZE-1);
  59.         else
  60.             m_lf.lfFaceName[0] = 0;
  61.     }
  62.  
  63.     HFONT CreateFont(void)
  64.     {
  65.         return ::CreateFontIndirect(& m_lf);
  66.     }
  67.  
  68.     int GetObject(HFONT hFont)
  69.     {
  70.         return ::GetObject(hFont, sizeof(m_lf), & m_lf);
  71.     }
  72. };
  73.  
  74.  
  75. template <int maxlength>
  76. class KPlacement
  77. {
  78. public:
  79.     GCP_RESULTS m_gcp;
  80.  
  81.     TCHAR        m_strOut[maxlength];
  82.     int            m_dx    [maxlength];
  83.     unsigned    m_order [maxlength];
  84.     int            m_caret [maxlength];
  85.     char        m_class [maxlength];
  86.     WORD        m_glyphs[maxlength];
  87.  
  88.     DWORD GetPlacement(HDC hDC, const TCHAR * mess, DWORD flags=0, int maxextent=0)
  89.     {
  90.         memset(&m_gcp, 0, sizeof(m_gcp));
  91.     
  92.         m_gcp.lStructSize = sizeof(GCP_RESULTS);
  93.         m_gcp.lpOutString = m_strOut;
  94.         m_gcp.lpOrder     = m_order;
  95.         m_gcp.lpDx        = m_dx;
  96.         m_gcp.lpCaretPos  = m_caret;
  97.         m_gcp.lpClass     = m_class;
  98.         m_gcp.lpGlyphs    = m_glyphs;
  99.         m_gcp.nGlyphs     = maxlength;
  100.  
  101.         return GetCharacterPlacement(hDC, mess, _tcslen(mess), maxextent, & m_gcp, flags);
  102.     }
  103.  
  104.     BOOL GlyphTextOut(HDC hDC, int x, int y)
  105.     {
  106.         return ExtTextOut(hDC, x, y, ETO_GLYPH_INDEX, NULL, (LPCTSTR) m_glyphs, m_gcp.nGlyphs, m_dx);
  107.     }
  108. };
  109.  
  110.  
  111. class KKerningPair
  112. {
  113. public:
  114.     KERNINGPAIR * m_pKerningPairs;
  115.     int              m_nPairs;
  116.  
  117.     KKerningPair(HDC hDC)
  118.     {
  119.         m_nPairs = GetKerningPairs(hDC, 0, NULL);
  120.  
  121.         if ( m_nPairs==0 )
  122.             m_pKerningPairs = NULL;
  123.         else
  124.         {
  125.             m_pKerningPairs = new KERNINGPAIR[m_nPairs];
  126.             assert(m_pKerningPairs);
  127.  
  128.             GetKerningPairs(hDC, m_nPairs, m_pKerningPairs);
  129.         }
  130.     }
  131.  
  132.     int GetKerning(TCHAR first, TCHAR second)
  133.     {
  134.         for (int i=0; i<m_nPairs; i++)
  135.             if ( (m_pKerningPairs[i].wFirst ==first) && 
  136.                  (m_pKerningPairs[i].wSecond==second) )
  137.                  return m_pKerningPairs[i].iKernAmount;
  138.  
  139.         return 0;
  140.     }
  141.  
  142.     ~KKerningPair(void)
  143.     {
  144.         if ( m_pKerningPairs )
  145.         {
  146.             delete m_pKerningPairs;
  147.             m_pKerningPairs = NULL;
  148.         }
  149.     }
  150. };
  151.  
  152.  
  153. class KGlyph
  154. {
  155. public:
  156.     GLYPHMETRICS  m_metrics;
  157.     BYTE *        m_pPixels;
  158.     DWORD          m_nAllocSize;
  159.     DWORD          m_nDataSize;
  160.     int              m_uFormat;
  161.  
  162.     KGlyph()
  163.     {
  164.         m_pPixels = NULL;
  165.     }
  166.  
  167.     ~KGlyph(void);
  168.  
  169.     DWORD GetGlyph(HDC hDC, UINT uChar, UINT uFormat, const MAT2 * pMat2=NULL);
  170.     
  171.     BOOL  DrawGlyphROP(HDC HDC, int x, int y, DWORD rop, COLORREF crBack, COLORREF crFore);
  172.     BOOL  DrawGlyph(HDC HDC, int x, int y, int & dx, int & dy);
  173. };
  174.  
  175.  
  176. template <int MAX_POINTS>
  177. class KGlyphOutline
  178. {
  179. public:
  180.     POINT m_Point[MAX_POINTS];
  181.     BYTE  m_Flag [MAX_POINTS];
  182.  
  183.     int   m_nPoints;
  184.  
  185. private:
  186.     void AddPoint(int x, int y, BYTE flag)
  187.     {
  188.         if ( m_nPoints < MAX_POINTS )
  189.         {
  190.             m_Point[m_nPoints].x = x;
  191.             m_Point[m_nPoints].y = y;
  192.             m_Flag [m_nPoints]   = flag;
  193.             m_nPoints ++;
  194.         }
  195.         else
  196.             assert(false);
  197.     }
  198.  
  199.     void AddQSpline(int x1, int y1, int x2, int y2)
  200.     {
  201.         assert(m_nPoints);
  202.  
  203.         // p0 p1 p2 -> p0 (p0+2p1)/3 (2p1+p2)/3, p2
  204.         int x0 = m_Point[m_nPoints-1].x;
  205.         int y0 = m_Point[m_nPoints-1].y;
  206.  
  207.         AddCSpline((x0+2*x1)/3, (y0+2*y1)/3, (2*x1+x2)/3, (2*y1+y2)/3, x2, y2);
  208.     }
  209.  
  210.     void AddCSpline(int x1, int y1, int x2, int y2, int x3, int y3)
  211.     {
  212.         assert(m_nPoints);
  213.  
  214.         AddPoint(x1, y1, PT_BEZIERTO);
  215.         AddPoint(x2, y2, PT_BEZIERTO);
  216.         AddPoint(x3, y3, PT_BEZIERTO);
  217.     }
  218.  
  219.     void MarkLast(BYTE flag)
  220.     {
  221.         assert(m_nPoints);
  222.         m_Flag[m_nPoints-1] |= flag;
  223.     }
  224.  
  225.     void Transform(int dx, int dy)
  226.     {
  227.         for (int i=0; i<m_nPoints; i++)
  228.         {
  229.             m_Point[i].x = (   m_Point[i].x + 32768 ) / 65536 + dx;
  230.             m_Point[i].y = ( - m_Point[i].y + 32768 ) / 65536 + dy;
  231.         }
  232.     }
  233.  
  234. public:
  235.     int DecodeTTPolygon(const TTPOLYGONHEADER * lpHeader, int size);
  236.  
  237.     BOOL Draw(HDC hDC, int x, int y)
  238.     {
  239.         Transform(x, y);
  240.     
  241.         return PolyDraw(hDC, m_Point, m_Flag, m_nPoints);
  242.     }
  243.  
  244.     int DecodeOutline(KGlyph & glyph)
  245.     {
  246.         if ( (glyph.m_uFormat==GGO_NATIVE) || (glyph.m_uFormat==GGO_BEZIER) )
  247.             return DecodeTTPolygon((const TTPOLYGONHEADER *) glyph.m_pPixels, glyph.m_nDataSize);
  248.         else
  249.             return 0;
  250.     }
  251.  
  252. };
  253.  
  254.  
  255. template <int MAX_POINTS>
  256. int KGlyphOutline<MAX_POINTS>::DecodeTTPolygon(const TTPOLYGONHEADER * pHeader, int size)
  257. {
  258.     m_nPoints = 0;
  259.  
  260.     while ( size>sizeof(TTPOLYGONHEADER) )
  261.     {
  262.         int curvesize = pHeader->cb;
  263.  
  264.         size -= curvesize;
  265.  
  266.         if ( size<0 )
  267.         {
  268.             assert(false);
  269.             break;
  270.         }
  271.  
  272.         if (pHeader->dwType != TT_POLYGON_TYPE)
  273.         {
  274.             assert(false);
  275.             break;
  276.         }
  277.  
  278.         const POINT * p = (const POINT *) & pHeader->pfxStart;
  279.  
  280.         AddPoint(p[0].x, p[0].y, PT_MOVETO);
  281.  
  282.         const TTPOLYCURVE * pCurve = (const TTPOLYCURVE *) & pHeader[1];
  283.         
  284.         while ( (unsigned) pCurve < ( ((unsigned) pHeader) + curvesize) )
  285.         {
  286.             int i;
  287.  
  288.             p = (const POINT *) pCurve->apfx;
  289.  
  290.             switch ( pCurve->wType )
  291.             {
  292.                 case TT_PRIM_LINE:        // polyline. 
  293.                     for (i=0; i<pCurve->cpfx; i++)
  294.                         AddPoint(p[i].x, p[i].y, PT_LINETO);
  295.                     break;
  296.  
  297.                 case TT_PRIM_QSPLINE:    // quadratic BΘzier spline.
  298.                     assert(pCurve->cpfx>=2);
  299.  
  300.                     for (i=0; i<(pCurve->cpfx-1); i++)
  301.                         if ( i==(pCurve->cpfx-2) )
  302.                             AddQSpline(p[i].x, p[i].y, p[i+1].x, p[i+1].y);
  303.                         else
  304.                             AddQSpline(
  305.                                 p[i].x, 
  306.                                 p[i].y, 
  307.                                 ( p[i].x + p[i+1].x ) / 2, 
  308.                                 ( p[i].y + p[i+1].y ) / 2);
  309.                     break;
  310.  
  311.                 case TT_PRIM_CSPLINE:    // cubic Bezier spline
  312.                     assert((pCurve->cpfx % 3) ==0);
  313.                     for (i=0; i<pCurve->cpfx; i+=3)
  314.                         AddCSpline(p[i].x, p[i].y, p[i+1].x, p[i+1].y, p[i+2].x, p[i+2].y);
  315.                     break;
  316.  
  317.                 default:
  318.                     assert(false);
  319.                     return 0;
  320.             }
  321.  
  322.             pCurve = (const TTPOLYCURVE *) & pCurve->apfx[pCurve->cpfx];
  323.         }
  324.  
  325.         MarkLast(PT_CLOSEFIGURE);
  326.  
  327.         pHeader = (const TTPOLYGONHEADER *) ((unsigned) pHeader + curvesize);
  328.     }
  329.  
  330.     return m_nPoints;
  331. }
  332.  
  333. BOOL BitmapTextOut(HDC hDC, int x, int y, const TCHAR * str, int count, int format = GGO_BITMAP);
  334. BOOL BitmapTextOutROP(HDC hDC, int x, int y, const TCHAR * str, int count, DWORD rop);
  335.  
  336. BOOL OutlineTextOut(HDC hDC, int x, int y, const TCHAR * str, int count);
  337.  
  338. ///////////////////////////////////////////////////////////
  339.  
  340. class KTextFormator
  341. {
  342.     typedef enum { MaxCharNo = 256 };
  343.  
  344.     float m_fCharWidth[MaxCharNo];
  345.     float m_fHeight;
  346.     float m_fLinespace;
  347.  
  348. public:
  349.  
  350.     BOOL  SetupPixel(HDC hDC, HFONT hFont, float pixelsize);
  351.     BOOL  Setup(HDC hDC, HFONT hFont, float pointsize);
  352.  
  353.     float GetLinespace(void) const
  354.     {
  355.         return m_fLinespace;
  356.     }
  357.  
  358.     BOOL  GetTextExtent(HDC hdc, LPCTSTR pString, int cbString, float & width, float & height);
  359.     BOOL  TextOut(HDC hDC, int x, int y, LPCTSTR pString, int nCount);
  360.     DWORD DrawText(HDC hDC, LPCTSTR pString, int nCount, const RECT * pRect, UINT uFormat);
  361. };
  362.  
  363.  
  364. BOOL ColorText(HDC hDC, int x, int y, LPCTSTR pString, int nCount, HBRUSH hFore);
  365.  BOOL BitmapText(HDC hDC, int x, int y, LPCTSTR pString, int nCount, HBITMAP hBmp);
  366. BOOL BitmapText2(HDC hDC, int x, int y, LPCTSTR pString, int nCount, HBITMAP hBmp);
  367. BOOL OffsetTextOut(HDC hDC, int x, int y, LPCTSTR pStr, int nCount, 
  368.                    int dx1, int dy1, COLORREF cr1,
  369.                    int dx2, int dy2, COLORREF cr2);
  370.  
  371. BOOL DrawChar(HDC hDC, double x0, double y0, double x1, double y1, TCHAR ch);
  372. void PathTextOut(HDC hDC, LPCTSTR pString, POINT point[], int no);
  373. BOOL PathTextOut(HDC hDC, LPCTSTR pString);
  374.  
  375.  
  376. // 3x3 average filter for any 8-bpp, 24-bpp, or 32-bpp frame buffer
  377. template <int bytepp>
  378. void Average(BYTE * pBits, int pitch, int width, int height)
  379. {
  380.     BYTE * buffer = new BYTE[pitch*2];
  381.  
  382.     for (int y=1; y<height; y++)
  383.     {
  384.         pBits += pitch; // first channel of pixel 0
  385.  
  386.         if ( y<(height-1) )
  387.         {
  388.             BYTE * P = pBits + bytepp;                // pixel 1
  389.             BYTE * B = buffer + pitch * (y & 1);    // pixel 1..n-2    
  390.  
  391.             for (int x=1; x<(width-1); x++)
  392.             {
  393.                 for (int b=0; b<bytepp; b++)
  394.                 {
  395.                     B[0] = ( P[-pitch-bytepp] + P[-pitch] + P[-pitch+bytepp] +
  396.                              P[      -bytepp] + P[     0] + P[       bytepp] +
  397.                              P[ pitch-bytepp] + P[ pitch] + P[ pitch+bytepp])/9;
  398.  
  399.                     P ++;
  400.                     B ++;
  401.                 }
  402.             }
  403.         }
  404.  
  405.         if ( y>=2 )
  406.         {
  407.             memcpy(pBits-pitch+bytepp, buffer + pitch * ( 1 - (y & 1)), (width-2) * bytepp);
  408.         }
  409.     }
  410.  
  411.     delete [] buffer;
  412. }
  413.  
  414.  
  415. // Conver text string to bitmap
  416. class KTextBitmap
  417. {
  418. public:
  419.     
  420.     HBITMAP        m_hBitmap;
  421.     HDC            m_hMemDC;
  422.     HGDIOBJ        m_hOldBmp;
  423.     int            m_width;
  424.     int            m_height;
  425.     int            m_dx;
  426.     int            m_dy;
  427.     BYTE *      m_pBits;
  428.  
  429.     BOOL Convert(HDC hDC, LPCTSTR pString, int nCount, int extra);
  430.  
  431.     void ReleaseBitmap(void)
  432.     {
  433.         if ( m_hOldBmp )
  434.         {
  435.             SelectObject(m_hMemDC, m_hOldBmp);
  436.             m_hOldBmp = NULL;
  437.         }
  438.  
  439.         if ( m_hBitmap )
  440.         {
  441.             DeleteObject(m_hBitmap);
  442.             m_hBitmap = NULL;
  443.         }
  444.     }
  445.  
  446.     KTextBitmap()
  447.     {
  448.         m_hBitmap = NULL;
  449.         m_hMemDC  = NULL;
  450.         m_hOldBmp = NULL;
  451.     }
  452.  
  453.     ~KTextBitmap()
  454.     {
  455.         if ( m_hMemDC )
  456.         {
  457.             DeleteObject(m_hMemDC);
  458.             m_hMemDC = NULL;
  459.         }
  460.     }
  461.  
  462.     void Blur(void);
  463.  
  464.     BOOL Draw(HDC hDC, int x, int y, int rop=SRCCOPY)
  465.     {
  466.         return BitBlt(hDC, x - m_dx, y - m_dy, m_width, m_height,
  467.                       m_hMemDC, 0, 0, rop);
  468.     }
  469.  
  470.     BOOL RenderText(HDC hDC, int x, int y, const TCHAR * pString, int nCount);
  471. };
  472.  
  473. // Embossing or Engraving by change edges only, good for non-solod background
  474. void TransparentEmboss(HDC hDC, const TCHAR * pString, int nCount, COLORREF crTL, COLORREF crBR, int offset, int x, int y);
  475.     
  476.  
  477.