home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / lyx-0.13.2.tar.gz / lyx-0.13.2.tar / lyx-0.13.2 / src / insetlatexaccent.C < prev    next >
C/C++ Source or Header  |  1998-04-23  |  16KB  |  655 lines

  1. /* This file is part of
  2.  * ======================================================
  3.  * 
  4.  *           LyX, The Document Processor
  5.  *      
  6.  *        Copyright (C) 1995 Matthias Ettrich
  7.  *          Copyright (C) 1995-1998 The LyX Team.
  8.  *
  9.  *======================================================*/
  10.  
  11. #include <config.h>
  12.  
  13. #ifdef __GNUG__
  14. #pragma implementation
  15. #endif
  16.  
  17. #include "insetlatexaccent.h"
  18. #include "error.h"
  19. #include "lyxrc.h"
  20. #include "lyxdraw.h"
  21.  
  22. extern LyXRC * lyxrc;
  23.  
  24. //     $Id: insetlatexaccent.C,v 1.1.1.1 1998/04/23 16:02:51 larsbj Exp $    
  25.  
  26. #if !defined(lint) && !defined(WITH_WARNINGS)
  27. static char vcid[] = "$Id: insetlatexaccent.C,v 1.1.1.1 1998/04/23 16:02:51 larsbj Exp $";
  28. #endif /* lint */
  29.  
  30. /* LatexAccent. Proper handling of accented characters */
  31. /* This part is done by Ivan Schreter, schreter@ccsun.tuke.sk */
  32. /* Later modified by Lars G. Bjonnes, larsbj@ifi.uio.no */
  33.  
  34. InsetLatexAccent::InsetLatexAccent()
  35. {
  36.     candisp = false;
  37. }
  38.  
  39.  
  40. InsetLatexAccent::InsetLatexAccent(InsetLatexAccent const & other)
  41.     :contents(other.contents),
  42.      candisp(other.candisp),
  43.      modtype(other.modtype),
  44.      remdot(other.remdot),
  45.      plusasc(other.plusasc),
  46.      plusdesc(other.plusdesc),
  47.      ic(other.ic)
  48. {}
  49.  
  50.  
  51. InsetLatexAccent::InsetLatexAccent(LString const & string)
  52.     : contents(string)
  53. {
  54.     checkContents();
  55. }
  56.  
  57.  
  58. InsetLatexAccent::~InsetLatexAccent()
  59. {
  60. }
  61.  
  62.  
  63. void InsetLatexAccent::checkContents()
  64.         // check, if we know the modifier and can display it ok on screen
  65. {
  66.         candisp = false;
  67.  
  68.     if (contents.empty() || contents.length()<2) return;
  69.  
  70.     // REMOVE IN 0.13
  71.     // Dirty Hack for backward compability. remove in 0.13 (Lgb)
  72.     // ok, let's see if that work...
  73.     //contents.strip();
  74.     //contents.frontStrip();
  75.     //if (!contents.contains("{") && !contents.contains("}")) {
  76.     //    if (contents.length() == 2) {
  77.     //        LString tmp;
  78.     //        tmp += contents[0];
  79.     //        tmp += contents[1];
  80.     //        tmp += "{}";
  81.     //        contents = tmp;
  82.     //    } else if (contents.length() == 3) {
  83.     //        LString tmp;
  84.     //        tmp += contents[0];
  85.     //        tmp += contents[1];
  86.     //        tmp += '{';
  87.     //        tmp += contents[2];
  88.     //        tmp += '}';
  89.     //        contents = tmp;
  90.     //    } else if (contents.length()==4 && contents[2] == ' ') {
  91.     //        LString tmp;
  92.     //        tmp += contents[0];
  93.     //        tmp += contents[1];
  94.     //        tmp += '{';
  95.     //        tmp += contents[3];
  96.     //        tmp += '}';
  97.     //        contents = tmp;
  98.     //    } else if  (contents.length()==4 && contents[2] == '\\'
  99.     //            && (contents[3]== 'i' || contents[3]== 'j')) {
  100.     //        LString tmp;
  101.     //        tmp += contents[0];
  102.     //        tmp += contents[1];
  103.     //        tmp += '{';
  104.     //        tmp += contents[2];
  105.     //        tmp += contents[3];
  106.     //        tmp += '}';
  107.     //        contents = tmp;
  108.     //    }
  109.     //}
  110.         if (contents[0] != '\\') return; // demand that first char is a '\\'
  111.  
  112.     lyxerr.debug("Decode: " + contents);
  113.  
  114.         remdot = false; plusasc = false; plusdesc = false;
  115.  
  116.         switch (contents[1]) { // second char should be one of these
  117.     case '\'':  // acute
  118.                 modtype = ACUTE;    // acute
  119.                 plusasc = true;    // at the top of character
  120.                 break;
  121.     case '`':   // grave
  122.                 modtype = GRAVE;    // grave
  123.                 plusasc = true;    // at the top
  124.                 break;
  125.     case '=':   // macron
  126.                 modtype = MACRON;    // macron
  127.                 plusasc = true;    // at the top
  128.                 break;
  129.     case '~':   // tilde
  130.                 modtype = TILDE;    // tilde
  131.                 plusasc = true;    // at the top
  132.                 break;
  133.     case 'b':   // underbar
  134.                 modtype = UNDERBAR;    // underbar
  135.                 plusdesc = true;   // at the bottom
  136.                 break;
  137.     case 'c':   // cedilla
  138.                 modtype = CEDILLA;    // cedilla
  139.                 plusdesc = true;   // at the bottom
  140.                 break;
  141.     case 'd':   // underdot
  142.                 modtype = UNDERDOT;    // underdot
  143.                 plusdesc = true;   // at the bottom
  144.                 break;
  145.     case 'r':   // circle
  146.                 modtype = CIRCLE;    // circle
  147.                 plusasc = true;    // at the top
  148.                 break;
  149.     case 't':   // tie
  150.                 modtype = TIE;    // tie
  151.                 plusasc = true;    // at the top
  152.                 break;
  153.     case 'u':   // breve
  154.                 modtype = BREVE;    // breve
  155.                 plusasc = true;    // at the top
  156.                 break;
  157.     case 'v':   // caron
  158.                 modtype = CARON;   // caron
  159.                 plusasc = true;    // at the top
  160.                 break;
  161.     case 'q':   // special caron
  162.                 modtype = SPECIAL_CARON;   // special caron
  163.                 plusasc = true;    // at the top
  164.                 break;
  165.     case 'H':   // hungarian umlaut
  166.                 modtype = HUNGARIAN_UMLAUT;   // hungarian umlaut
  167.                 plusasc = true;    // at the top
  168.                 break;
  169.     case '"':   // umlaut
  170.                 modtype = UMLAUT;   // umlaut
  171.                 plusasc = true;    // at the top
  172.                 break;
  173.     case '.':   // dot
  174.                 modtype = DOT;   // dot
  175.                 plusasc = true;    // at the top
  176.                 break;
  177.     case '^':   // circumflex
  178.                 modtype = CIRCUMFLEX;   // circumflex
  179.                 plusasc = true;    // at the top
  180.                 break;
  181.     case 'k':   // ogonek
  182.         modtype = OGONEK;  // ogonek
  183.         plusdesc = true;
  184.         break;
  185.     case 'i': // dot-less-i
  186.         modtype = DOT_LESS_I;  // dot-less-i
  187.         plusasc = true; // at the top (not really needed)
  188.         remdot = true;
  189.         break;
  190.     case 'j': // dot-less-j
  191.         modtype = DOT_LESS_J; // dot-less-j
  192.         plusasc = true; // at the top (not really needed)
  193.         remdot = true;
  194.         break;
  195.      case 'l': // lslash
  196.          modtype = lSLASH;
  197.          plusasc = true; // at the top (not really needed)
  198.          break;
  199.      case 'L': // lslash
  200.          modtype = LSLASH;
  201.          plusasc = true; // at the top (not really needed)
  202.          break;
  203.     default:
  204.              printf ("Default\n");
  205.         // unknow accent (or something else)
  206.                 return;
  207.         }
  208.  
  209.     // we demand that third char is a '{' (Lgb)
  210.     if (contents[2] != '{') return;
  211.  
  212.     // special clause for \i{}, \j{} \l{} and \L{}
  213.     if ((modtype == DOT_LESS_I || modtype == DOT_LESS_J
  214.         || modtype == lSLASH || modtype == LSLASH)
  215.         && contents[3] == '}' ) {
  216.         switch (modtype) {
  217.         case DOT_LESS_I: ic = 'i'; break;
  218.         case DOT_LESS_J: ic = 'j'; break;
  219.         case lSLASH:     ic = 'l'; break;
  220.         case LSLASH:     ic = 'L'; break;
  221.         default:
  222.             // if this happens something is really wrong
  223.             lyxerr.print("InsetLaTexAccent: weird error.");
  224.             break;
  225.         }
  226.         //ic = (modtype == DOT_LESS_J ? 'j' : 'i');
  227.         lyxerr.debug("Contents: [" + contents + "], ic: " + ic + 
  228.                   ", top: " + plusasc + ", bot: " + plusdesc + 
  229.                   ", dot: " + remdot + ", mod: " + modtype);
  230.     // Special case for space
  231.     } else if (contents[3] == '}') {
  232.         ic = ' ';
  233.     } else {
  234.         int i = 3;
  235.         
  236.         // now get the char
  237.         ic = contents[3]; // i will always be 3 here
  238.  
  239.         // ic should now be a alfa-char or '\\'
  240.         if (ic == '\\') {
  241.             ic = contents[++i]; // will only allow \<foo>{\i} and \<foo>{\j}
  242.             if (ic == 'i' || ic == 'j')
  243.                 remdot = true;
  244.             else
  245.                 return;
  246.         } else if ( (ic=='i'|| ic=='j') && contents[4]=='}') {
  247.             // Do a rewrite: \<foo>{i} --> \<foo>{\i}
  248.             LString temp=contents;
  249.             temp.substring(0,2);
  250.             temp+='\\';
  251.             temp+=char(ic);
  252.             for(int j=4;j<contents.length();j++)
  253.                 temp+=contents[j];
  254.             contents=temp;
  255.             i++;
  256.             remdot=true;
  257.         }    
  258.  
  259.         // demand a '}' at the end
  260.         if (contents[++i] != '}' && contents[++i]) return;
  261.                        
  262.         // fine, the char is properly decoded now (hopefully)
  263.         lyxerr.debug("Contents: [" + contents + "], ic: " + ic + 
  264.                   ", top: " + plusasc + ", bot: " + plusdesc + 
  265.                   ", dot: " + remdot + ", mod: " + modtype);
  266.     }
  267.         candisp = true;
  268. }
  269.  
  270.  
  271. int InsetLatexAccent::Ascent(LyXFont const &font) const
  272. {
  273.     int max;
  274.     if (candisp) {
  275.         if (ic == ' ')
  276.             max = font.ascent('a');
  277.         else
  278.             max = font.ascent(ic);
  279.         if (plusasc) 
  280.             max += (font.maxAscent()+3) / 3;
  281.     } else
  282.         max = font.maxAscent()+4;
  283.     return max;
  284. }
  285.  
  286.  
  287. int InsetLatexAccent::Descent(LyXFont const &font) const
  288. {
  289.     int max;
  290.     if (candisp) {
  291.         if (ic==' ') 
  292.             max = font.descent('a');
  293.                 else 
  294.                     max = font.descent(ic);
  295.                 if (plusdesc)
  296.                     max += 3;
  297.     } else
  298.         max = font.maxDescent() + 4;
  299.     return max;
  300. }
  301.  
  302.  
  303. int InsetLatexAccent::Width(LyXFont const &font) const
  304. {
  305.     if (candisp)
  306.         return font.textWidth(&ic, 1);
  307.         else
  308.                 return font.stringWidth(contents) + 4;
  309. }
  310.  
  311.  
  312.  
  313. bool InsetLatexAccent::DisplayISO8859_9(LyXFont font,
  314.                 LyXScreen &scr,
  315.                 int baseline, 
  316.                 float &x)
  317. {
  318.     unsigned char tmpic = ic;
  319.     
  320.     switch (modtype) {
  321.     case CEDILLA:
  322.     {
  323.         if (ic == 'c') tmpic = 0xe7;
  324.         if (ic == 'C') tmpic = 0xc7;
  325.         if (ic == 's') tmpic = 0xfe;
  326.         if (ic == 'S') tmpic = 0xde;
  327.         break;
  328.     }
  329.     case BREVE:
  330.     {    if (ic == 'g') tmpic = 0xf0;
  331.         if (ic == 'G') tmpic = 0xd0;
  332.         break;
  333.     }
  334.     case UMLAUT:
  335.     {
  336.         if (ic == 'o') tmpic = 0xf6;
  337.         if (ic == 'O') tmpic = 0xd6;
  338.         if (ic == 'u') tmpic = 0xfc;
  339.         if (ic == 'U') tmpic = 0xdc;
  340.         break;
  341.     }
  342.     case DOT:      if (ic == 'I') tmpic = 0xdd; break;
  343.     case DOT_LESS_I: tmpic = 0xfd; break;
  344.     default:     return false;
  345.     }
  346.     if (tmpic != ic) {
  347.         char ch = char(tmpic);
  348.         scr.drawText(font, &ch, 1, baseline, int(x));
  349.         x += Width (font);
  350.         return true;
  351.     }
  352.     else
  353.         return false;
  354. }
  355.  
  356.  
  357. void InsetLatexAccent::Draw(LyXFont font,
  358.                 LyXScreen &scr,
  359.                 int baseline, 
  360.                 float &x)
  361. {
  362.     if (lyxrc->font_norm=="iso8859-9")
  363.         if (DisplayISO8859_9 (font, scr, baseline, x))    
  364.             return;
  365.     
  366.     /* draw it! */ 
  367.   
  368.     if (candisp) {
  369.         int asc = Ascent(font);
  370.         int desc = Descent(font);
  371.         int wid = Width(font);
  372.         float x2 = x+(float(wid)/2);
  373.         float hg35;
  374.         int hg, y;
  375.         if (plusasc) {
  376.             // mark at the top
  377.             hg = font.maxDescent();
  378.             y = baseline - asc;
  379.  
  380.             if (font.shape() == LyXFont::ITALIC_SHAPE) x2 += (4*hg)/5; // italic
  381.         } else {
  382.             // at the bottom
  383.             hg = desc;
  384.             y = baseline;
  385.         }
  386.  
  387.         hg35 = float(hg*3)/5;
  388.  
  389.         // display with proper accent mark
  390.         // first the letter
  391.         scr.drawText(font, &ic, 1, baseline, int(x));
  392.  
  393.         GC pgc = GetAccentGC(font, (hg+3)/5);
  394.  
  395.         if (remdot) {
  396.             int tmpvar = baseline - font.ascent('i');
  397.             float tmpx = 0;
  398.             if (font.shape() == LyXFont::ITALIC_SHAPE) tmpx += (8*hg)/10; // italic
  399.             lyxerr.debug("Removing dot.", Error::ANY);
  400.             // remove the dot first
  401.             scr.fillRectangle(gc_clear, int(x + tmpx),
  402.                       tmpvar, wid,
  403.                       font.ascent('i') -
  404.                       font.ascent('x')-1);
  405.             
  406.         }
  407.         // now the rest - draw within (x,y, x+wid, y+hg)
  408.         switch (modtype) {
  409.         case ACUTE:     // acute
  410.          {
  411.             scr.drawLine(pgc, int(x2), int(y+hg35),
  412.                      int(x2+hg35), y);
  413.             break;
  414.         }
  415.         case GRAVE:     // grave
  416.         {
  417.             scr.drawLine(pgc,int(x2), int(y+hg35),
  418.                      int(x2-hg35), y); 
  419.             break;
  420.         }
  421.         case MACRON:     // macron
  422.         {
  423.             scr.drawLine(pgc,
  424.                      int(x2-(3*wid/7)), int(y+(hg/2) + hg35),
  425.                      int(x2+(3*wid/7)), int(y+(hg/2) + hg35));
  426.             break;
  427.         }
  428.         case TILDE:     // tilde
  429.         {
  430.             if (hg35 > 2) --hg35;
  431.             x2 += (hg35/2);
  432.             XPoint p[4];
  433.             p[0].x = int(x2 - 2*hg35); p[0].y = int(y + hg);
  434.             p[1].x = int(x2 - hg35);   p[1].y = int(y + hg35);
  435.             p[2].x = int(x2);          p[2].y = int(y + hg);
  436.             p[3].x = int(x2 + hg35);   p[3].y = int(y + hg35);
  437.             scr.drawLines(pgc, p, 4);
  438.             break;
  439.         }
  440.         case UNDERBAR:     // underbar
  441.         {
  442.             scr.drawLine(pgc,
  443.                      int(x2-(3*wid/7)), y+(hg/2),
  444.                      int(x2+(3*wid/7)), y+(hg/2));
  445.             break;
  446.         }
  447.         case CEDILLA:     // cedilla
  448.         {
  449.             XPoint p[4];
  450.             p[0].x = int(x2);          p[0].y = y;
  451.             p[1].x = int(x2);          p[1].y = y + (hg/3);
  452.             p[2].x = int(x2 + (hg/3)); p[2].y = y + (hg/2);
  453.             p[3].x = int(x2 - (hg/4)); p[3].y = y + hg;
  454.             scr.drawLines(pgc, p, 4);
  455.             break;
  456.         }
  457.         case UNDERDOT:     // underdot
  458.         case DOT:    // dot
  459.         {
  460.             scr.drawArc(pgc,int(x2), y+(hg/2),
  461.                     1, 1, 0, 360*64); 
  462.             break;
  463.         }
  464.         case CIRCLE:     // circle
  465.         {
  466.             scr.drawArc(pgc, int(x2-(hg/2)), y, hg, hg, 0,
  467.                     360*64);
  468.             break;
  469.         }
  470.         case TIE:     // tie
  471.         {
  472.             scr.drawArc(pgc,
  473.                     int(x2), y+(hg/4),
  474.                     hg, hg, 0, 11519);
  475.             break;
  476.         }
  477.         case BREVE:     // breve
  478.         {
  479.             scr.drawArc(pgc,
  480.                     int(x2-(hg/2)), y-(hg/4),
  481.                     hg, hg, 0, -11519);
  482.             break;
  483.         }
  484.         case CARON:    // caron
  485.         {
  486.             XPoint p[3];
  487.             p[0].x = int(x2 - hg35); p[0].y = y;
  488.             p[1].x = int(x2);        p[1].y = int(y+hg35);
  489.             p[2].x = int(x2 + hg35); p[2].y = y;
  490.             scr.drawLines(pgc, p, 3);
  491.             break;
  492.         }
  493.         case SPECIAL_CARON:    // special caron
  494.         {
  495.             switch (ic) {
  496.             case 'L': wid = 4*wid/5; break;
  497.             case 't': y -= int(hg35/2); break;
  498.             }
  499.             XPoint p[3];
  500.             p[0].x = int(x+wid);          p[0].y = int(y+hg35+hg);
  501.             p[1].x = int(x+wid+(hg35/2)); p[1].y = int(y+ hg+(hg35/2));
  502.             p[2].x = int(x+wid+(hg35/2)); p[2].y = y + hg;
  503.             scr.drawLines(pgc, p, 3);
  504.             break;
  505.         }
  506.         case HUNGARIAN_UMLAUT:    // hung. umlaut
  507.         {
  508.             XSegment s[2];
  509.             s[0].x1= int(x2-(hg/2));      s[0].y1 = int(y + hg35);
  510.             s[0].x2= int(x2+hg35-(hg/2)); s[0].y2 = y;
  511.             s[1].x1= int(x2+(hg/2));      s[1].y1 = int(y + hg35);
  512.             s[1].x2= int(x2+hg35+(hg/2)); s[1].y2 = y;
  513.  
  514.             scr.drawSegments(pgc, s, 2);
  515.             break;
  516.         }
  517.         case UMLAUT:    // umlaut
  518.         {
  519.             int tmpadd = y;
  520.             tmpadd += (remdot) ? ((19*hg)/10) : ((20*hg)/27); // if (remdot) -> i or j
  521.             int rad = ((hg*4)/8);
  522.             if (rad <= 1) {
  523.                 scr.drawPoint(pgc, int(x2-((4*hg)/7)), tmpadd);
  524.                 scr.drawPoint(pgc, int(x2+((4*hg)/7)), tmpadd);
  525.             } else {
  526.                 scr.drawArc(pgc, int(x2-((2*hg)/4)), tmpadd,
  527.                         rad-1, rad-1, 0, 360*64);
  528.                 scr.drawArc(pgc, int(x2+((2*hg)/4)), tmpadd,
  529.                         rad-1, rad-1, 0, 360*64);
  530.             }
  531.             break;
  532.         }
  533.         case CIRCUMFLEX:    // circumflex
  534.         {
  535.             XPoint p[3];
  536.             p[0].x = int(x2 - hg35); p[0].y = y + hg;
  537.             p[1].x = int(x2);        p[1].y = int(y + hg35);
  538.             p[2].x = int(x2 + hg35); p[2].y = y + hg;
  539.             scr.drawLines(pgc, p, 3);
  540.             break;
  541.         }
  542.         case OGONEK:    // ogonek
  543.         {
  544.             // this does probably not look like an ogonek, so
  545.             // it should certainly be refined
  546.             XPoint p[4];
  547.             p[0].x = int(x2);          p[0].y = y;
  548.             p[1].x = int(x2);          p[1].y = y + (hg/3);
  549.             p[2].x = int(x2 - (hg/3)); p[2].y = y + (hg/2);
  550.             p[3].x = int(x2 + (hg/4)); p[3].y = y + hg;
  551.             scr.drawLines(pgc, p, 4);
  552.             break;
  553.         }
  554.         case lSLASH:
  555.         case LSLASH:
  556.         {
  557.              XPoint p[2];
  558.              p[0].x = int(x);                p[0].y = y+3*hg;
  559.              p[1].x = int(x+float(wid)*.75); p[1].y = y+hg;
  560.              scr.drawLines(pgc, p, 2);
  561.              break;
  562.         }
  563.         case DOT_LESS_I: // dotless-i
  564.         case DOT_LESS_J: // dotless-j
  565.         {
  566.             // nothing to do for these
  567.             break;
  568.         }
  569.         }
  570.     } else {
  571.         //scr.drawFilledRectangle(int(x+1), baseline - Ascent(font)+1,
  572.         //            Width(font)-2,
  573.         //            Ascent(font)+Descent(font)-2,
  574.         //            FL_GRAY80);
  575.         scr.fillRectangle(gc_lighted,
  576.                   int(x+1), baseline - Ascent(font)+1,
  577.                   Width(font)-2,
  578.                   Ascent(font)+Descent(font)-2);
  579.         
  580.         //scr.drawRectangle(int(x), baseline - Ascent(font),
  581.         //          Width(font)-1,
  582.         //          Ascent(font)+Descent(font)-1,
  583.         //          FL_GRAY80);
  584.         scr.drawRectangle(gc_lighted,
  585.                   int(x), baseline - Ascent(font),
  586.                   Width(font)-1,
  587.                   Ascent(font)+Descent(font)-1);
  588.         scr.drawString(font, contents, baseline, int(x+2));
  589.     }
  590.     x +=  Width(font);
  591. }
  592.  
  593.  
  594. void InsetLatexAccent::Write(FILE *file)
  595. {
  596.     fprintf(file, "\\i %s\n", contents.c_str());
  597. }
  598.  
  599.  
  600. void InsetLatexAccent::Read(LyXLex &lex)
  601. {
  602.     lex.EatLine();
  603.     contents = lex.GetString();
  604.     checkContents();
  605. }
  606.  
  607.  
  608. int InsetLatexAccent::Latex(FILE *file, signed char /*fragile*/)
  609. {
  610.     fprintf(file, "%s", contents.c_str());
  611.     return 0;
  612. }
  613.  
  614.  
  615. int InsetLatexAccent::Latex(LString &file, signed char /*fragile*/)
  616. {
  617.     file += contents;
  618.     return 0;
  619. }
  620.  
  621.  
  622. bool InsetLatexAccent::Deletable() const
  623. {
  624.     return true;
  625. }
  626.  
  627.  
  628. bool InsetLatexAccent::DirectWrite() const
  629. {
  630.     return true;
  631. }
  632.  
  633.  
  634. Inset* InsetLatexAccent::Clone()
  635. {
  636.     InsetLatexAccent *result = new InsetLatexAccent(contents);
  637.     return result;
  638. }
  639.  
  640.  
  641. Inset::Code InsetLatexAccent::LyxCode() const
  642. {
  643.     return Inset::ACCENT_CODE;
  644. }
  645.  
  646.  
  647. bool InsetLatexAccent::IsEqual(Inset* other)
  648. {
  649.     if (other && other->LyxCode() == Inset::ACCENT_CODE){
  650.         InsetLatexAccent* otheraccent = (InsetLatexAccent*) other;
  651.         return (contents == otheraccent->contents);
  652.     }
  653.     return false;
  654. }
  655.