home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / Kasumi / source / text.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  5.2 KB  |  156 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    Graphics support library
  3. //    Copyright (C) 1998-2007 Avery Lee
  4. //
  5. //    This program is free software; you can redistribute it and/or modify
  6. //    it under the terms of the GNU General Public License as published by
  7. //    the Free Software Foundation; either version 2 of the License, or
  8. //    (at your option) any later version.
  9. //
  10. //    This program is distributed in the hope that it will be useful,
  11. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. //    GNU General Public License for more details.
  14. //
  15. //    You should have received a copy of the GNU General Public License
  16. //    along with this program; if not, write to the Free Software
  17. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include <vd2/system/math.h>
  20. #include <vd2/Kasumi/region.h>
  21. #include <vd2/Kasumi/text.h>
  22.  
  23. #include "defaultfont.inl"
  24.  
  25. void VDPixmapGetTextExtents(const VDOutlineFontInfo *font, float size, const char *pText, VDTextLayoutMetrics& out_Metrics) {
  26.     if (!font)
  27.         font = &g_VDDefaultFont_FontInfo;
  28.  
  29.     float invEmSquare = 1.0f / (float)font->mEmSquare;
  30.     float scale = 1.0f / (255.0f * 65536.0f);
  31.     float xscale = (float)(font->mMaxX - font->mMinX) * scale;
  32.     float yscale = (float)(font->mMaxY - font->mMinY) * scale;
  33.  
  34.     float xinitstep = font->mMinX * 255.0f * scale;
  35.     float yinitstep = -(font->mMaxY * scale + font->mDescent);
  36.  
  37.     float xoffset = xinitstep;
  38.     float yoffset = yinitstep;
  39.  
  40.     vdrect32f bounds;
  41.     bounds.invalidate();
  42.  
  43.     while(const char c = *pText++) {
  44.         int index = (unsigned char)c - font->mStartGlyph;
  45.  
  46.         if ((unsigned)index >= (unsigned)(font->mEndGlyph - font->mStartGlyph))
  47.             continue;
  48.  
  49.         const VDOutlineFontGlyphInfo& glyph = font->mpGlyphArray[index];
  50.         const VDOutlineFontGlyphInfo& glyphNext = font->mpGlyphArray[index + 1];
  51.         int nPoints = glyphNext.mPointArrayStart - glyph.mPointArrayStart;
  52.  
  53.         if (nPoints) {
  54.             vdrect32 localBounds;
  55.             localBounds.invalidate();
  56.  
  57.             const uint16 *pPoints = font->mpPointArray + glyph.mPointArrayStart;
  58.             for(int i=0; i<nPoints; ++i) {
  59.                 uint16 pt = *pPoints++;
  60.  
  61.                 localBounds.add(pt & 255, pt >> 8);
  62.             }
  63.  
  64.             vdrect32f localBoundsF((float)localBounds.left, -(float)localBounds.bottom, (float)localBounds.right, -(float)localBounds.top);
  65.             localBoundsF.scale(xscale, yscale);
  66.             localBoundsF.translate(xoffset, yoffset);
  67.             bounds.add(localBoundsF);
  68.         }
  69.  
  70.         xoffset += glyph.mAWidth + glyph.mBWidth + glyph.mCWidth;
  71.     }
  72.  
  73.     if (bounds.valid())
  74.         bounds.scale(size * invEmSquare, size * invEmSquare);
  75.  
  76.     out_Metrics.mExtents = bounds;
  77.     out_Metrics.mAdvance = (xoffset - xinitstep) * size * invEmSquare;
  78. }
  79.  
  80. void VDPixmapConvertTextToPath(VDPixmapPathRasterizer& rast, const VDOutlineFontInfo *pFont, float size, float x, float y, const char *pText, const float transform[2][2]) {
  81.     if (!pFont)
  82.         pFont = &g_VDDefaultFont_FontInfo;
  83.  
  84.     vdfastfixedvector<vdint2, 256> points;
  85.  
  86.     float scale = size / ((float)pFont->mEmSquare * 255.0f * 65536.0f);
  87.     float xscale = (float)(pFont->mMaxX - pFont->mMinX) * scale;
  88.     float yscale = -(float)(pFont->mMaxY - pFont->mMinY) * scale;
  89.  
  90.     float xinitstep = pFont->mMinX * 255.0f * scale;
  91.     float yinitstep = -pFont->mMaxY * scale - pFont->mDescent * size / (float)pFont->mEmSquare;
  92.  
  93.     static const float kIdentity[2][2]={1,0,0,1};
  94.  
  95.     if (!transform)
  96.         transform = kIdentity;
  97.  
  98.     float xoffset = x + xinitstep * transform[0][0] + yinitstep * transform[0][1];
  99.     float yoffset = y + xinitstep * transform[1][0] + yinitstep * transform[1][1];
  100.  
  101.     while(const char c = *pText++) {
  102.         int index = (unsigned char)c - pFont->mStartGlyph;
  103.  
  104.         if ((unsigned)index >= (unsigned)(pFont->mEndGlyph - pFont->mStartGlyph))
  105.             continue;
  106.  
  107.         const VDOutlineFontGlyphInfo& glyph = pFont->mpGlyphArray[index];
  108.         const VDOutlineFontGlyphInfo& glyphNext = pFont->mpGlyphArray[index + 1];
  109.         const uint16 *pPoints = pFont->mpPointArray + glyph.mPointArrayStart;
  110.         const uint8 *pCommands = pFont->mpCommandArray + glyph.mCommandArrayStart;
  111.         int nPoints = glyphNext.mPointArrayStart - glyph.mPointArrayStart;
  112.         int nCommands = glyphNext.mCommandArrayStart - glyph.mCommandArrayStart;
  113.  
  114.         points.clear();
  115.         points.resize(nPoints);
  116.  
  117.         for(int i=0; i<nPoints; ++i) {
  118.             uint16 pt = *pPoints++;
  119.             float fx1 = (pt & 255) * xscale;
  120.             float fy1 = (pt >> 8) * yscale;
  121.             points[i].set(VDRoundToInt(fx1*transform[0][0] + fy1*transform[0][1] + xoffset), VDRoundToInt(fx1*transform[1][0] + fy1*transform[1][1] + yoffset));
  122.         }
  123.  
  124.         const vdint2 *srcpt = points.data();
  125.         const vdint2 *startpt = points.data();
  126.  
  127.         while(nCommands--) {
  128.             uint8 cmd = *pCommands++;
  129.             int countm1 = (cmd & 0x7f) >> 2;
  130.  
  131.             for(int i=0; i<=countm1; ++i) {
  132.                 switch(cmd & 3) {
  133.                 case 2:
  134.                     rast.Line(srcpt[0], srcpt[1]);
  135.                     ++srcpt;
  136.                     break;
  137.  
  138.                 case 3:
  139.                     rast.QuadraticBezier(srcpt);
  140.                     srcpt += 2;
  141.                     break;
  142.                 }
  143.             }
  144.  
  145.             if (cmd & 0x80) {
  146.                 rast.Line(*srcpt, *startpt);
  147.                 startpt = ++srcpt;
  148.             }
  149.         }
  150.  
  151.         float step = (glyph.mAWidth + glyph.mBWidth + glyph.mCWidth) * (size / (float)pFont->mEmSquare);
  152.         xoffset += step * transform[0][0];
  153.         yoffset += step * transform[1][0];
  154.     }
  155. }
  156.