home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / flash078.zip / flashsource-r0_7_8.zip / FlashFontObj.cpp < prev    next >
C/C++ Source or Header  |  2001-07-26  |  9KB  |  350 lines

  1. #include "FlashFontObj.h"
  2. #include "FFont.h"
  3. #include "FDisplay.h"
  4. #include <iostream>
  5. #include <windows.h>
  6. #include <math.h>
  7. #include <hash_map>
  8.  
  9. SWORD SWORDFromFixed(FIXED f)
  10. {
  11.     SWORD ret = f.value;
  12.     if(f.fract > 0x8000) ret+=1;
  13.     return (SWORD)ret;
  14. }
  15.  
  16. bool FlashFontFactory::GetGlyphShape(const char *font, UWORD charindex, FlashShape & s, bool bold, bool italic, bool uLine)
  17. {
  18.  
  19.     unsigned int fWeight=400;
  20.     if(bold==true)fWeight=700;
  21.  
  22.     FlashShape &r=s;
  23.     FlashShapeRecordChange c;
  24.     c.ChangeFillStyle0(1);
  25.     c.ChangeLineStyle(0);
  26.     s.AddRecord(c);
  27.     HDC tmphdc = CreateDC("DISPLAY", NULL, NULL, NULL); 
  28.     HDC hdcScreen = CreateCompatibleDC(tmphdc); 
  29.         
  30.     long base = 1300;
  31.     HFONT myfont = CreateFont(-base,0,0,0,fWeight,italic ? TRUE : FALSE,uLine ? TRUE : FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,DEFAULT_PITCH,font);    
  32.     HGDIOBJ obj = SelectObject(hdcScreen,myfont);
  33.     
  34.     unsigned int c2=charindex;
  35.     
  36.     GLYPHMETRICS gm;
  37.     DWORD size;
  38.     MAT2 matrix;
  39.     FIXED f1;
  40.     f1.value = 1;
  41.     f1.fract = 0;
  42.     FIXED f0;
  43.     f0.value = 0;
  44.     f0.fract = 0;
  45.     matrix.eM11 = f1;
  46.     matrix.eM12 = f0;
  47.     matrix.eM21 = f0;
  48.     matrix.eM22 = f1;
  49.     
  50.     SWORD lastx=0;
  51.     SWORD lasty=0;
  52.     if(c2 != ' ')
  53.     {
  54.         if((size = GetGlyphOutline(hdcScreen,c2,GGO_NATIVE,&gm,0,NULL,&matrix)) != GDI_ERROR)
  55.         { 
  56.             
  57.             char *buffer = new char[size+1];
  58.             if((size = GetGlyphOutline(hdcScreen,c2,GGO_NATIVE,&gm,size,buffer,&matrix)) != GDI_ERROR)
  59.             {
  60.                 if(uLine==true)
  61.                 {
  62.                     INT charWidth=0;
  63.                     GetCharWidth(hdcScreen,charindex,charindex,&charWidth);
  64.           
  65.                     r.AddRecord(FlashShapeRecordChange(0,1536));
  66.                     r.AddRecord(FlashShapeRecordStraight(charWidth,0));
  67.                     r.AddRecord(FlashShapeRecordStraight(0,-100));
  68.                     r.AddRecord(FlashShapeRecordStraight(-charWidth,0));
  69.                     r.AddRecord(FlashShapeRecordStraight(0,100)); 
  70.                     r.AddRecord(FlashShapeRecordChange(0,-1536));       
  71.                 }
  72.                 
  73.                 char *pos = (char*)buffer;
  74.                 while(pos < buffer+size)
  75.                 {
  76.                     TTPOLYGONHEADER *header = (TTPOLYGONHEADER *)pos;
  77.                     pos+=sizeof(TTPOLYGONHEADER);
  78.     
  79.                     SWORD hx = SWORDFromFixed(header->pfxStart.x);
  80.                     SWORD hy = 1024-SWORDFromFixed(header->pfxStart.y);
  81.                     r.AddRecord(FlashShapeRecordChange(hx,hy));
  82.                     lastx = hx;
  83.                     lasty = hy;
  84.                     while(pos < (char*)header+(header->cb))
  85.                     {            
  86.                         
  87.                         TTPOLYCURVE *curve = (TTPOLYCURVE *)pos;
  88.                         // handle polylines
  89.                         if(curve->wType == TT_PRIM_LINE)
  90.                         {
  91.  
  92.                             for(WORD i=0; i < curve->cpfx; i++)
  93.                             {
  94.                                 SWORD x = SWORDFromFixed(curve->apfx[i].x);
  95.                                 SWORD y = 1024-SWORDFromFixed(curve->apfx[i].y);
  96.                                 r.AddRecord(FlashShapeRecordStraight(x-lastx,y-lasty));
  97.                                 lastx += x-lastx;
  98.                                 lasty += y-lasty;
  99.                             }
  100.                         }
  101.                         
  102.                         // handle lines
  103.                         else
  104.                         {
  105.                             POINTFX pfxB,pfxC;
  106.                             for (int u = 0; u < curve->cpfx - 1; u++) // Walk through points in spline 
  107.                             {
  108.                                 pfxB = curve->apfx[u];                // B is always the current point
  109.                                
  110.                                SWORD cx_;
  111.                                SWORD cy_;
  112.                                SWORD ax_;
  113.                                SWORD ay_;
  114.  
  115.                                cx_ = SWORDFromFixed(pfxB.x);
  116.                                cy_ = SWORDFromFixed(pfxB.y);
  117.  
  118.                                if (u < curve->cpfx - 2)            // If not on last spline, compute C
  119.                                {                      
  120.                                   ax_ = (cx_ + SWORDFromFixed(curve->apfx[u+1].x)) / 2;  // x midpoint
  121.                                   ay_ = (cy_ + SWORDFromFixed(curve->apfx[u+1].y)) / 2;  // y midpoint
  122.                                }
  123.                                else 
  124.                                {
  125.                                   pfxC = curve->apfx[u+1];
  126.                                   
  127.                                   ax_ = SWORDFromFixed(pfxC.x);
  128.                                   ay_ = SWORDFromFixed(pfxC.y);
  129.                                }
  130.  
  131.                                cy_=1024-cy_;
  132.                                ay_=1024-ay_;
  133.                                SWORD cx = cx_-lastx;
  134.                                SWORD cy = cy_-lasty;
  135.                                SWORD rx = ax_-cx_;
  136.                                SWORD ry = ay_-cy_;
  137.                                lastx += ax_-lastx;
  138.                                lasty += ay_-lasty;
  139.                                r.AddRecord(FlashShapeRecordCurved(cx,cy,rx,ry));
  140.                            }
  141.                         }
  142.                         pos+=(sizeof(WORD)*2) + (sizeof(POINTFX)*curve->cpfx);
  143.                     }
  144.                     r.AddRecord(FlashShapeRecordStraight(hx-lastx, hy-lasty));
  145.                     lastx = hx;
  146.                     lasty = hy;
  147.                 }            
  148.             }
  149.             else 
  150.             {
  151.                 return false; // ERROR
  152.             }
  153.             delete[] buffer;
  154.         }
  155.         else 
  156.         {
  157.             return false; // ERROR
  158.         } 
  159.     }
  160.  
  161.     SelectObject(hdcScreen,obj);
  162.     DeleteObject(myfont);
  163.     DeleteObject(hdcScreen);
  164.     return true;
  165. }
  166.  
  167.  
  168. int FlashFontFactory::GetGlyphAdvance(const char *fontname, UWORD charindex, int pointsize)
  169. {
  170.     HDC tmphdc = CreateDC("DISPLAY", NULL, NULL, NULL); 
  171.     HDC hdcScreen = CreateCompatibleDC(tmphdc); 
  172.      
  173.     OUTLINETEXTMETRIC om;
  174.     GetOutlineTextMetrics(hdcScreen,sizeof(om),&om);
  175.  
  176.     HFONT myfont = CreateFont(-1300/50*pointsize,0,0,0,FW_REGULAR,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,fontname);
  177.     HGDIOBJ obj = SelectObject(hdcScreen,myfont);
  178.  
  179.     INT i=0;
  180.     BOOL ret=::GetCharWidth(hdcScreen,charindex,charindex,&i);
  181.  
  182.     SelectObject(hdcScreen,obj);
  183.     DeleteObject(myfont);
  184.     DeleteObject(hdcScreen);
  185.  
  186.     if(ret == 0) return -1;
  187.     else return i;
  188.  
  189. }
  190.  
  191. UWORD FlashFontFactory::WriteText(std::ostream &out, const char *fontname, const char *text, int x, int y, FlashRGB color, int pointsize, int depth, int extraspacing, bool bold, bool italic, bool uLine)
  192. {
  193.     FlashRect textBounds;
  194.  
  195.     std::hash_map<int,FlashShape> shapes;
  196.     std::hash_map<int,int> shapes_lookup;
  197.     
  198.     FlashTagDefineFont df;
  199.         
  200.     FlashTextRecordStyle* trs1 = new FlashTextRecordStyle(1,1,1,1,df.GetID(), pointsize*20, color, x, y);
  201.     FlashTextRecordGlyph* trs2 = new FlashTextRecordGlyph();
  202.  
  203.     FlashRect bounds(x,y,x,y);
  204.     int index = 0;
  205.     int width = 0;
  206.  
  207.     UWORD uCode;
  208.     bool bDBCS;
  209.     textBounds.SetRect(x,y,x,y);
  210.     for(int i=0; text[i] != 0; )
  211.     {
  212.         //Added=2001.7.16
  213.         //if (text[i] & 0x80) {
  214.         if (IsDBCSLeadByte(text[i])) {
  215.             bDBCS = true;
  216.             uCode = ((text[i]<<8)&0xff00) | (text[i+1]&0x00ff);
  217.         }
  218.         else {
  219.             bDBCS = false;
  220.             uCode = text[i];
  221.         }
  222.         
  223.         if(shapes.find(uCode) == shapes.end())
  224.         {
  225.             shapes[uCode] = FlashShape();
  226.             if(!GetGlyphShape(fontname,(UWORD)uCode,shapes[uCode],bold,italic,uLine)) return false; 
  227.             df.AddShape(shapes[uCode]);
  228.             shapes_lookup[uCode]=index;
  229.             index++;
  230.         }        
  231.         int advance = GetGlyphAdvance(fontname,uCode,pointsize)+extraspacing;
  232.         trs2->AddGlyph(FlashGlyphEntry(shapes_lookup[uCode],advance));
  233.  
  234.         FlashRect r = shapes[uCode].GetBounds();
  235.         FlashRect b(r.GetX1() / 50 * pointsize+width+x+extraspacing*i, 
  236.                     r.GetY1() / 50 * pointsize+y, 
  237.                     r.GetX2() / 50 * pointsize+width+x+extraspacing*i,
  238.                     r.GetY2() / 50 * pointsize+y);
  239.  
  240.         if(index == 0) bounds = b;
  241.         else bounds.BoundWith(b);
  242.         width+=advance;    
  243.  
  244.         //cout << "index " << index << " ----------------\n";
  245.         //cout << bounds.GetX1() << "   " << bounds.GetY1() << "   " << bounds.GetX2() << "   " << bounds.GetY2() << "\n";
  246.  
  247.         //Added=2001.7.16
  248.         if (bDBCS) i += 2;
  249.         else i++;
  250.         textBounds.SetRect(x,y,
  251.                         textBounds.GetX2()+r.GetX2()-r.GetX1(), 
  252.                         max(textBounds.GetY2(),y+r.GetY2()-r.GetY1()));
  253.     }
  254.     //FlashTagDefineText dt(bounds,FlashMatrix());
  255.     //Modified=2001.7.16
  256.     FlashTagDefineText dt(textBounds,FlashMatrix());
  257.     
  258.     dt.AddTextRecord(trs1);
  259.     dt.AddTextRecord(trs2);
  260.     
  261.     out << df;
  262.     out << dt;
  263.     
  264.     delete trs1;
  265.     delete trs2;
  266.  
  267.     out << FlashTagPlaceObject2(depth,dt.GetID());
  268.  
  269.     return dt.GetID();
  270. }
  271.  
  272. UWORD FlashFontFactory::WriteText(std::ostream &out, const char *fontname, const char *text, int x, int y, FlashRGB color, int pointsize, int depth, FlashRect& textBounds, int extraspacing, bool bold, bool italic, bool uLine)
  273. {
  274.     std::hash_map<int,FlashShape> shapes;
  275.     std::hash_map<int,int> shapes_lookup;
  276.     
  277.     FlashTagDefineFont df;
  278.         
  279.     FlashTextRecordStyle* trs1 = new FlashTextRecordStyle(1,1,1,1,df.GetID(), pointsize*20, color, x, y);
  280.     FlashTextRecordGlyph* trs2 = new FlashTextRecordGlyph();
  281.  
  282.     FlashRect bounds(x,y,x,y);
  283.     int index = 0;
  284.     int width = 0;
  285.  
  286.     UWORD uCode;
  287.     bool bDBCS;
  288.     textBounds.SetRect(x,y,x,y);
  289.     for(int i=0; text[i] != 0; )
  290.     {
  291.         //Added=2001.7.16
  292.         //if (text[i] & 0x80) {
  293.         if (IsDBCSLeadByte(text[i])) {
  294.             bDBCS = true;
  295.             uCode = ((text[i]<<8)&0xff00) | (text[i+1]&0x00ff);
  296.         }
  297.         else {
  298.             bDBCS = false;
  299.             uCode = text[i];
  300.         }
  301.         
  302.         if(shapes.find(uCode) == shapes.end())
  303.         {
  304.             shapes[uCode] = FlashShape();
  305.             if(!GetGlyphShape(fontname,(UWORD)uCode,shapes[uCode],bold,italic,uLine)) return false;
  306.             df.AddShape(shapes[uCode]);
  307.             shapes_lookup[uCode]=index;
  308.             index++;
  309.         }        
  310.         int advance = GetGlyphAdvance(fontname,uCode,pointsize)+extraspacing;
  311.         trs2->AddGlyph(FlashGlyphEntry(shapes_lookup[uCode],advance));
  312.  
  313.         FlashRect r = shapes[uCode].GetBounds();
  314.         FlashRect b(r.GetX1() / 50 * pointsize+width+x+extraspacing*i, 
  315.                     r.GetY1() / 50 * pointsize+y, 
  316.                     r.GetX2() / 50 * pointsize+width+x+extraspacing*i,
  317.                     r.GetY2() / 50 * pointsize+y);
  318.  
  319.         if(index == 0) bounds = b;
  320.         else bounds.BoundWith(b);
  321.         width+=advance;    
  322.  
  323.         //cout << "index " << index << " ----------------\n";
  324.         //cout << bounds.GetX1() << "   " << bounds.GetY1() << "   " << bounds.GetX2() << "   " << bounds.GetY2() << "\n";
  325.  
  326.         //Added=2001.7.16
  327.         if (bDBCS) i += 2;
  328.         else i++;
  329.         textBounds.SetRect(x,y,
  330.                         textBounds.GetX2()+r.GetX2()-r.GetX1(), 
  331.                         max(textBounds.GetY2(),y+r.GetY2()-r.GetY1()));
  332.     }
  333.     //FlashTagDefineText dt(bounds,FlashMatrix());
  334.     //Modified=2001.7.16
  335.     FlashTagDefineText dt(textBounds,FlashMatrix());
  336.     
  337.     dt.AddTextRecord(trs1);
  338.     dt.AddTextRecord(trs2);
  339.     
  340.     out << df;
  341.     out << dt;
  342.     
  343.     delete trs1;
  344.     delete trs2;
  345.  
  346.     out << FlashTagPlaceObject2(depth,dt.GetID());
  347.  
  348.     return dt.GetID();
  349. }
  350.