Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

xyrtext.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /* Módulo: xyrtext.cpp                                                       */
00003 /* Autores: Carlos Henrique Levy e Jaudênia Cavalcante                       */
00004 /* Data: 20 jun 97                                                           */
00005 /* Comentário:                                                               */
00006 /*    Implementação de métodos da classe que desenha textos raster.          */
00007 /*****************************************************************************/
00008 
00009 #include "xyrtext.h"
00010 #include "cdimage.h"
00011 #include "xymath.h"
00012 
00013 const char* xy_id_xyrtext_cpp="$Id: xyrtext.cpp,v 1.12 2000/06/13 13:35:51 camilo Exp $";                                                               
00014 
00015 XYRasterText::XYRasterText (const char* text,   
00016                             XYCoordinate x,     
00017                             XYCoordinate y,     
00018                             long color,                 
00019                             int size,           
00020                             Typeface font,              
00021                             Style style,                
00022                             Alignment alignment,        
00023                             Orientation orientation,
00024                             xybool underline,
00025                             xybool visible)     
00026                                   : XYText(text, x, y, color, font, style, alignment,
00027                                            orientation, underline, visible),
00028                                     _size(size)
00029 {
00030 }
00031 
00032 XYRasterText::XYRasterText (const char* text,   
00033                             XYCoordinate x,
00034                             XYCoordinate y,
00035                             xybool visible)     
00036                                   : XYText(text, x, y, visible),
00037                                     _size(XYRasterText::xystandard)
00038 {
00039 }
00040 
00041 XYRasterText::XYRasterText (const char* text,
00042                                   long color,
00043                                   int size,
00044                                     Typeface font,                      
00045                                     Style style,                        
00046                                     Alignment alignment,        
00047                                     Orientation orientation,
00048                                   xybool underline,
00049                                   xybool visible)
00050                                   : XYText(text, color, font, style, alignment,
00051                                            orientation, underline, visible),
00052                                     _size(size)
00053 {
00054 }
00055 
00056 XYRasterText::XYRasterText (long color,
00057                                   int size,
00058                                     Typeface font,                      
00059                                     Style style,                        
00060                                     Alignment alignment,        
00061                                     Orientation orientation,
00062                                   xybool underline,
00063                                   xybool visible)
00064                                   : XYText(color, font, style, alignment, orientation,
00065                                            underline, visible),
00066                                     _size(size)
00067 {
00068 }
00069 
00070 XYRasterText::~XYRasterText (void)
00071 {
00072 }
00073 
00074 extern "C"
00075 {
00076    extern cdCanvas* cdActiveCanvas(void);
00077 }
00078 
00079 void XYRasterText::size (int s)
00080 {
00081    _size = s;
00082 }
00083 
00084 int XYRasterText::size (void) const
00085 {
00086    return _size;
00087 }
00088 
00089 #if 0
00090 static void  mycdFont(int font, int style, int size)
00091 {
00092    static int old_font  = 9999;
00093    static int old_style = 9999;
00094    static int old_size  = 9999;
00095 
00096    if ((font != old_font) || (style!=old_style) || (size != old_size))
00097    {
00098       cdFont (font, style, size);
00099 
00100       old_font  = font;
00101       old_style = style;
00102       old_size  = size;
00103    }
00104 }
00105 #endif
00106 
00107 void XYRasterText::draw (void)
00108 {
00109    draw (_xmin, _ymin, _xmax, _ymax);
00110 }
00111 
00112 void XYRasterText::draw (int xmin, int ymin, int xmax, int ymax) const
00113 {
00114    // teste de inconsistência
00115    if (text() == NULL) return;
00116 
00117    if (visible() == xyfalse) return;  // invisível!!!
00118 
00119    double oldOrientation =  cdTextOrientation(CD_QUERY);
00120 
00121    int mode = cdClip(CD_CLIPON);
00122 
00123    // guarda a região de clip corrente
00124    int oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax;
00125    cdGetClipArea (&oldclip_xmin, &oldclip_xmax, &oldclip_ymin, &oldclip_ymax);
00126    // define nova região de clip
00127    cdClipArea(xmin, xmax, ymin, ymax);
00128 
00129    cdFont(font(), style(), size());
00130    cdTextAlignment(align());
00131    cdForeground(color());
00132    cdBackOpacity(CD_TRANSPARENT);
00133 
00134    if (orientation() == horizontal)  // orientação default
00135    {
00136       int xd, yd;
00137       position (&xd, &yd);
00138       cdTextOrientation(0.0);
00139 
00140       cdText(xd, yd, text());
00141 
00142       cdTextOrientation(oldOrientation);
00143    }
00144    else if (orientation() == vertBotTop)
00145    {
00146       int xd, yd;
00147       position (&xd, &yd);
00148       cdTextOrientation(90.0);
00149 
00150       cdText(xd, yd, text());
00151 
00152       cdTextOrientation(oldOrientation);
00153    }
00154    else if (orientation() == vertTopBot)
00155    {
00156       int xd, yd;
00157       position (&xd, &yd);
00158       cdTextOrientation(-90.0);
00159 
00160       cdText(xd, yd, text());
00161 
00162       cdTextOrientation(oldOrientation);
00163    }
00164    else                            // com orientação
00165    {
00166       // limites da menor caixa que contém um texto
00167       int x1, y1, x2, y2;
00168       boundingBox (x1, y1, x2, y2);
00169 
00170       int m = y2 - y1;             // largura da caixa do texto horizontal
00171       int n = x2 - x1;             // altura da caixa do texto horizontal
00172         
00173       // salva canvas atual para tratar imagem onde a própria imagem é usada
00174       // como canvas do CD
00175       cdCanvas* OldCanvas = cdActiveCanvas();
00176       // consulta cor do canvas
00177       long bc = cdBackground(CD_QUERY);
00178         
00179       // cria uma imagem
00180       void *image = cdCreateImage (m, n);
00181 
00182       // faz de uma imagem um canvas do CD
00183       if (image)
00184       {
00185          cdCanvas* imagecv = cdCreateCanvas (CD_IMAGE, image);
00186 
00187          // r,g,b -> imagem do texto
00188          unsigned char *r = new unsigned char[m * n];
00189          unsigned char *g = new unsigned char[m * n];
00190          unsigned char *b = new unsigned char[m * n];
00191         
00192          // nr,ng,nb -> imagem do texto rotacionado
00193          unsigned char *nr = new unsigned char[m * n];
00194          unsigned char *ng = new unsigned char[m * n];
00195          unsigned char *nb = new unsigned char[m * n];
00196         
00197          // ativa imagem a ser tratada  
00198          if (imagecv)
00199          {
00200             cdGetImageRGB(nr, ng, nb, x1, y1, n, m);
00201 
00202             cdActivate (imagecv);
00203             cdBackground(bc);
00204 
00205             // limpa a imagem
00206             //cdClear();
00207             cdFont(font(), style(), size());
00208             cdTextAlignment(CD_SOUTH_WEST);
00209             cdForeground(color());
00210             cdBackOpacity(CD_TRANSPARENT);
00211 
00212             if (orientation() == vertBotTop)            
00213               for (int i = 0; i < m; ++i)               
00214                 for (int j = 0; j < n; ++j)
00215                 {
00216                       r[(n - j - 1) * m + i] = nr[i * n + j];
00217                       g[(n - j - 1) * m + i] = ng[i * n + j];
00218                       b[(n - j - 1) * m + i] = nb[i * n + j];
00219                     }
00220             else        // orientação: vertical de cima para baixo (-90 graus)
00221               for (int i = 0; i < m; ++i)
00222                 for (int j = 0; j < n; ++j)
00223                     {
00224                       r[j * m + m - i - 1] = nr[i * n + j];
00225                       g[j * m + m - i - 1] = ng[i * n + j];
00226                       b[j * m + m - i - 1] = nb[i * n + j];
00227                     }
00228 
00229             cdPutImageRGB(m, n, r, g, b, 0, 0, m, n);           
00230 
00231             // desenha um texto
00232             cdText(0, 0, text());
00233           
00234             // converte imagem para o formato RGB
00235             cdGetImageRGB(r, g, b, 0, 0, m, n);
00236 
00237             // ativa canvas que estava sendo usado anteriormente
00238             cdActivate(OldCanvas);              
00239 
00240             // libera uma imagem                                
00241             cdKillImage (image);
00242             cdKillCanvas (imagecv);
00243          }
00244                             
00245          // rotaciona texto com orientação: vertical de baixo para cima (90 graus)
00246          if (orientation() == vertBotTop)               
00247            for (int i = 0; i < n; ++i)          
00248              for (int j = 0; j < m; ++j)
00249              {
00250                    nr[j * n + n - i - 1] = r[i * m + j];
00251                    ng[j * n + n - i - 1] = g[i * m + j];
00252                    nb[j * n + n - i - 1] = b[i * m + j];
00253                  }
00254          else   // orientação: vertical de cima para baixo (-90 graus)
00255            for (int i = 0; i < n; ++i)
00256              for (int j = 0; j < m; ++j)
00257                  {
00258                      nr[(m - j - 1) * n + i] = r[i * m + j];
00259                      ng[(m - j - 1) * n + i] = g[i * m + j];
00260                      nb[(m - j - 1) * n + i] = b[i * m + j];
00261                    }
00262 
00263          // libera memória não mais usada
00264          delete r;
00265          delete g;
00266          delete b;
00267         
00268          // exibe texto rotacionado
00269          cdPutImageRGB(n, m, nr, ng, nb, x1, y1, n, m);         
00270         
00271          // libera memória não mais usada
00272          delete nr;                                                                                     
00273          delete ng;
00274          delete nb;
00275       }
00276    }
00277 
00278    // acrescenta o sublinhado, se houver
00279    if (underline())
00280    {
00281       int descent;
00282       cdFontDim(0, 0, 0, &descent);
00283       cdLineStyle(CD_SOLID);
00284       cdLineWidth((style() == bold || style() == boldItalic) ? 2 : 1);
00285 
00286       int bxmin, bxmax, bymin, bymax;
00287       boundingBox(bxmin, bymin, bxmax, bymax);
00288 
00289       if (orientation() == horizontal)
00290          cdLine(bxmin, bymin + descent, bxmax, bymin + descent);
00291       else if (orientation() == vertBotTop)
00292          cdLine(bxmax - descent, bymin, bxmax - descent, bymax);
00293       else
00294          cdLine(bxmin + descent, bymin, bxmin + descent, bymax);
00295    }
00296 
00297    cdClip(mode);
00298    // restaura a região de clip anterior
00299    cdClipArea(oldclip_xmin, oldclip_xmax, oldclip_ymin, oldclip_ymax);
00300 }
00301 
00302 void XYRasterText::boundingBox (int& xmin, int& ymin, int& xmax, int& ymax)
00303                                 const
00304 {
00305    // teste de inconsistência
00306    if (text() == NULL) return;
00307 
00308    if (visible() == xyfalse) return;  // invisível!!!
00309 
00310    int xi, yi;
00311    position (&xi, &yi);
00312 
00313    cdFont(font(), style(), size());
00314    cdTextAlignment(align());
00315 
00316    if (orientation() == horizontal)  // orientação default
00317     cdTextOrientation(0.0);
00318    else if (orientation() == vertBotTop)
00319     cdTextOrientation(90.0);
00320    else if (orientation() == vertTopBot)
00321     cdTextOrientation(-90.0);
00322 
00323    int width, height;
00324    cdTextSize(text(), &width, &height);
00325 
00326    int xd, yd, xmn, xmx, ymn, ymx;
00327    position (&xd, &yd);
00328    cdTextBox(xi, yi, text(), &xmn, &xmx, &ymn, &ymx);
00329    xmin = xmn; ymin = ymn;
00330    xmax = xmx; ymax = ymx;
00331    if ( xmin>xmax ) { xmin = xmx; xmax = xmn; }
00332    if ( ymin>ymax ) { ymin = ymx; ymax = ymn; }
00333 
00334 #if 0
00335    if (orientation() == horizontal)  // orientação default
00336    {
00337       xmax = width;
00338       ymax = height;
00339    }
00340    else
00341    {
00342       xmax = height;
00343       ymax = width;
00344    }
00345 
00346    // testa alinhamento e decide os valores mínimos do boundingBox
00347    switch (align())
00348    {
00349       case north:     xmin = xi - xmax / 2; ymin = yi - ymax;     break;
00350       case south:     xmin = xi - xmax / 2; ymin = yi;            break;
00351       case east:      xmin = xi - xmax;     ymin = yi - ymax / 2; break;
00352       case west:      xmin = xi;                  ymin = yi - ymax / 2; break;
00353       case northEast: xmin = xi - xmax;     ymin = yi - ymax;     break;
00354       case northWest: xmin = xi;                  ymin = yi - ymax;     break;
00355       case southEast: xmin = xi - xmax;     ymin = yi;            break;
00356       case southWest: xmin = xi;                  ymin = yi;                    break;
00357       case center:    xmin = xi - xmax / 2; ymin = yi - ymax / 2; break;
00358 
00359       case baseLeft:
00360          int descent;
00361          cdFontDim(0, 0, 0, &descent);
00362 
00363          xmin = xi;
00364          ymin = yi - descent;
00365          break;
00366 
00367       case baseCenter:
00368          cdFontDim(0, 0, 0, &descent);
00369 
00370          xmin = xi - xmax / 2;
00371          ymin = yi - descent;
00372          break;
00373 
00374       case baseRight:
00375          cdFontDim(0, 0, 0, &descent);
00376 
00377          xmin = xi - xmax;
00378          ymin = yi - descent;
00379          break;
00380    }
00381 
00382    xmax += xmin;
00383    ymax += ymin;
00384 #endif
00385 }
00386 

XY
Tecgraf / PUC-Rio - Computer Graphics Technology Group