1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-1999 The LyX Team.
9 * ====================================================== */
15 #pragma implementation "lyxfont.h"
26 #include "FontLoader.h"
27 #include "support/lstrings.h"
31 // The global fontloader
32 FontLoader fontloader;
38 string const GUIFamilyNames[6] =
39 { N_("Roman"), N_("Sans serif"), N_("Typewriter"), N_("Symbol"), N_("Inherit"),
42 string const GUISeriesNames[4] =
43 { N_("Medium"), N_("Bold"), N_("Inherit"), N_("Ignore") };
45 string const GUIShapeNames[6] =
46 { N_("Upright"), N_("Italic"), N_("Slanted"), N_("Smallcaps"), N_("Inherit"),
49 string const GUISizeNames[14] =
50 { N_("Tiny"), N_("Smallest"), N_("Smaller"), N_("Small"), N_("Normal"), N_("Large"),
51 N_("Larger"), N_("Largest"), N_("Huge"), N_("Huger"), N_("Increase"), N_("Decrease"),
52 N_("Inherit"), N_("Ignore") };
54 string const lGUISizeNames[15] =
55 { N_("tiny"), N_("smallest"), N_("smaller"), N_("small"), N_("normal"), N_("large"),
56 N_("larger"), N_("largest"), N_("huge"), N_("huger"), N_("increase"), N_("decrease"),
57 N_("inherit"), N_("ignore"), string() };
59 string const GUIMiscNames[5] =
60 { N_("Off"), N_("On"), N_("Toggle"), N_("Inherit"), N_("Ignore") };
62 string const GUIDirectionNames[5] =
63 { N_("LTR"), N_("RTL"), N_("Toggle"), N_("Inherit"), N_("Ignore") };
67 string const GUIColorNames[13] =
68 { N_("None"), N_("Black"), N_("White"), N_("Red"), N_("Green"), N_("Blue"),
69 N_("Cyan"), N_("Magenta"),
70 N_("Yellow"), N_("Math"), N_("Inset"), N_("Inherit"), N_("Ignore") };
74 // Strings used to read and write .lyx format files
76 string const LyXFamilyNames[6] =
77 { "roman", "sans", "typewriter", "symbol", "default", "error" };
79 string const LyXSeriesNames[4] =
80 { "medium", "bold", "default", "error" };
82 string const LyXShapeNames[6] =
83 { "up", "italic", "slanted", "smallcaps", "default", "error" };
85 string const LyXSizeNames[14] =
86 { "tiny", "scriptsize", "footnotesize", "small", "normal", "large",
87 "larger", "largest", "huge", "giant",
88 "increase-error", "decrease-error", "default", "error" };
90 string const LyXMiscNames[12] =
91 { "off", "on", "toggle", "default", "error" };
94 string const LyXColorNames[13] =
95 { "none", "black", "white", "red", "green", "blue", "cyan", "magenta",
96 "yellow", "matherror", "inseterror", "default", "error" };
100 // Strings used to write LaTeX files
103 string const LaTeXFamilyNames[6] =
104 { "textrm", "textsf", "texttt", "error1", "error2", "error3" };
106 string const LaTeXSeriesNames[4] =
107 { "textmd", "textbf", "error4", "error5" };
109 string const LaTeXShapeNames[6] =
110 { "textup", "textit", "textsl", "textsc", "error6", "error7" };
112 string const LaTeXSizeNames[14] =
113 { "tiny", "scriptsize", "footnotesize", "small", "normalsize", "large",
114 "Large", "LARGE", "huge", "Huge", "error8", "error9", "error10", "error11" };
117 string const LaTeXColorNames[13] =
118 { "none", "black", "white", "red", "green", "blue", "cyan", "magenta",
119 "yellow", "error12", "error13", "error14", "error15" };
123 LyXFont::FontBits LyXFont::sane = { ROMAN_FAMILY,
138 LyXFont::FontBits LyXFont::inherit = { INHERIT_FAMILY,
153 LyXFont::FontBits LyXFont::ignore = { IGNORE_FAMILY,
169 /// Decreases font size by one
170 LyXFont & LyXFont::decSize()
173 case SIZE_HUGER: setSize(SIZE_HUGE); break;
174 case SIZE_HUGE: setSize(SIZE_LARGEST); break;
175 case SIZE_LARGEST: setSize(SIZE_LARGER); break;
176 case SIZE_LARGER: setSize(SIZE_LARGE); break;
177 case SIZE_LARGE: setSize(SIZE_NORMAL); break;
178 case SIZE_NORMAL: setSize(SIZE_SMALL); break;
179 case SIZE_SMALL: setSize(SIZE_FOOTNOTE); break;
180 case SIZE_FOOTNOTE: setSize(SIZE_SCRIPT); break;
181 case SIZE_SCRIPT: setSize(SIZE_TINY); break;
182 case SIZE_TINY: break;
184 lyxerr << "Can't LyXFont::decSize on INCREASE_SIZE" << endl;
187 lyxerr <<"Can't LyXFont::decSize on DECREASE_SIZE" << endl;
190 lyxerr <<"Can't LyXFont::decSize on INHERIT_SIZE" << endl;
193 lyxerr <<"Can't LyXFont::decSize on IGNORE_SIZE" << endl;
200 /// Increases font size by one
201 LyXFont & LyXFont::incSize()
204 case SIZE_HUGER: break;
205 case SIZE_HUGE: setSize(SIZE_HUGER); break;
206 case SIZE_LARGEST: setSize(SIZE_HUGE); break;
207 case SIZE_LARGER: setSize(SIZE_LARGEST); break;
208 case SIZE_LARGE: setSize(SIZE_LARGER); break;
209 case SIZE_NORMAL: setSize(SIZE_LARGE); break;
210 case SIZE_SMALL: setSize(SIZE_NORMAL); break;
211 case SIZE_FOOTNOTE: setSize(SIZE_SMALL); break;
212 case SIZE_SCRIPT: setSize(SIZE_FOOTNOTE); break;
213 case SIZE_TINY: setSize(SIZE_SCRIPT); break;
215 lyxerr <<"Can't LyXFont::incSize on INCREASE_SIZE" << endl;
218 lyxerr <<"Can't LyXFont::incSize on DECREASE_SIZE" << endl;
221 lyxerr <<"Can't LyXFont::incSize on INHERIT_SIZE" << endl;
224 lyxerr <<"Can't LyXFont::incSize on IGNORE_SIZE" << endl;
231 /// Updates a misc setting according to request
232 LyXFont::FONT_MISC_STATE LyXFont::setMisc(FONT_MISC_STATE newfont,
235 if (newfont == TOGGLE) {
241 lyxerr <<"LyXFont::setMisc: Need state"
242 " ON or OFF to toggle. Setting to ON" << endl;
245 } else if (newfont == IGNORE)
252 /// Updates font settings according to request
253 void LyXFont::update(LyXFont const & newfont, bool toggleall)
255 if(newfont.family() == family() && toggleall)
256 setFamily(INHERIT_FAMILY); // toggle 'back'
257 else if (newfont.family() != IGNORE_FAMILY)
258 setFamily(newfont.family());
259 // else it's IGNORE_SHAPE
261 // "Old" behaviour: "Setting" bold will toggle bold on/off.
262 switch (newfont.series()) {
265 if (series() == BOLD_SERIES && toggleall)
266 setSeries(MEDIUM_SERIES);
268 setSeries(BOLD_SERIES);
272 setSeries(newfont.series());
278 if(newfont.shape() == shape() && toggleall)
279 setShape(INHERIT_SHAPE); // toggle 'back'
280 else if (newfont.shape() != IGNORE_SHAPE)
281 setShape(newfont.shape());
282 // else it's IGNORE_SHAPE
284 if (newfont.size() != IGNORE_SIZE) {
285 if (newfont.size() == INCREASE_SIZE)
287 else if (newfont.size() == DECREASE_SIZE)
289 else if (newfont.size() == size() && toggleall)
290 setSize(INHERIT_SIZE); // toggle 'back'
292 setSize(newfont.size());
295 setEmph(setMisc(newfont.emph(), emph()));
296 setUnderbar(setMisc(newfont.underbar(), underbar()));
297 setNoun(setMisc(newfont.noun(), noun()));
298 setLatex(setMisc(newfont.latex(), latex()));
300 switch(newfont.direction()) {
302 if (direction() == LTR_DIR)
303 setDirection(RTL_DIR);
305 setDirection(LTR_DIR);
310 setDirection(newfont.direction());
314 if(newfont.color() == color() && toggleall)
315 setColor(LColor::inherit); // toggle 'back'
316 else if (newfont.color() != LColor::ignore)
317 setColor(newfont.color());
319 if(newfont.color() == color() && toggleall)
320 setColor(LyXFont::INHERIT_COLOR); // toggle 'back'
321 else if (newfont.color() != LyXFont::IGNORE_COLOR)
322 setColor(newfont.color());
327 /// Reduce font to fall back to template where possible
328 void LyXFont::reduce(LyXFont const & tmplt)
330 if (family() == tmplt.family())
331 setFamily(INHERIT_FAMILY);
332 if (series() == tmplt.series())
333 setSeries(INHERIT_SERIES);
334 if (shape() == tmplt.shape())
335 setShape(INHERIT_SHAPE);
336 if (size() == tmplt.size())
337 setSize(INHERIT_SIZE);
338 if (emph() == tmplt.emph())
340 if (underbar() == tmplt.underbar())
341 setUnderbar(INHERIT);
342 if (noun() == tmplt.noun())
344 if (latex() == tmplt.latex())
347 if (color() == tmplt.color())
348 setColor(LColor::inherit);
350 if (color() == tmplt.color())
351 setColor(LyXFont::INHERIT_COLOR);
353 if (direction() == tmplt.direction())
354 setDirection(INHERIT_DIR);
358 /// Realize font from a template
359 // This one is not pretty, but it's extremely fast (Asger)
361 LyXFont & LyXFont::realize(LyXFont const & tmplt)
363 if (bits == inherit) {
368 if (bits.family == INHERIT_FAMILY) {
369 bits.family = tmplt.bits.family;
371 if (bits.series == INHERIT_SERIES) {
372 bits.series = tmplt.bits.series;
374 if (bits.shape == INHERIT_SHAPE) {
375 bits.shape = tmplt.bits.shape;
377 if (bits.size == INHERIT_SIZE) {
378 bits.size = tmplt.bits.size;
380 if (bits.emph == INHERIT) {
381 bits.emph = tmplt.bits.emph;
383 if (bits.underbar == INHERIT) {
384 bits.underbar = tmplt.bits.underbar;
386 if (bits.noun == INHERIT) {
387 bits.noun = tmplt.bits.noun;
389 if (bits.latex == INHERIT) {
390 bits.latex = tmplt.bits.latex;
393 if (bits.color == LColor::inherit) {
394 bits.color = tmplt.bits.color;
397 if (bits.color == INHERIT_COLOR) {
398 bits.color = tmplt.bits.color;
401 if (bits.direction == INHERIT_DIR) {
402 bits.direction = tmplt.bits.direction;
408 LyXFont & LyXFont::realize(LyXFont const & tmplt)
410 if (bits == inherit) {
415 if ((bits & (Fam_Mask<<Fam_Pos)) == (ui32(INHERIT_FAMILY)<<Fam_Pos))
417 bits &= ~(Fam_Mask << Fam_Pos);
418 bits |= (tmplt.bits & Fam_Mask << Fam_Pos);
420 if ((bits & (Ser_Mask<<Ser_Pos)) == (ui32(INHERIT_SERIES)<<Ser_Pos))
422 bits &= ~(Ser_Mask << Ser_Pos);
423 bits |= (tmplt.bits & Ser_Mask << Ser_Pos);
425 if ((bits & (Sha_Mask << Sha_Pos)) == ui32(INHERIT_SHAPE) << Sha_Pos)
427 bits &= ~(Sha_Mask << Sha_Pos);
428 bits |= (tmplt.bits & Sha_Mask << Sha_Pos);
430 if ((bits & (Siz_Mask << Siz_Pos)) == ui32(INHERIT_SIZE) << Siz_Pos)
432 bits &= ~(Siz_Mask << Siz_Pos);
433 bits |= (tmplt.bits & Siz_Mask << Siz_Pos);
435 if ((bits & (Misc_Mask << Emp_Pos)) == ui32(INHERIT) << Emp_Pos)
437 bits &= ~(Misc_Mask << Emp_Pos);
438 bits |= (tmplt.bits & Misc_Mask << Emp_Pos);
440 if ((bits & (Misc_Mask << Und_Pos)) == ui32(INHERIT) << Und_Pos)
442 bits &= ~(Misc_Mask << Und_Pos);
443 bits |= (tmplt.bits & Misc_Mask << Und_Pos);
445 if ((bits & (Misc_Mask << Nou_Pos)) == ui32(INHERIT) << Nou_Pos)
447 bits &= ~(Misc_Mask << Nou_Pos);
448 bits |= (tmplt.bits & Misc_Mask << Nou_Pos);
450 if ((bits & (Misc_Mask << Lat_Pos)) == ui32(INHERIT) << Lat_Pos)
452 bits &= ~(Misc_Mask << Lat_Pos);
453 bits |= (tmplt.bits & Misc_Mask << Lat_Pos);
456 if ((bits & (Col_Mask << Col_Pos)) == ui32(LColor::inherit) << Col_Pos)
458 bits &= ~(Col_Mask << Col_Pos);
459 bits |= (tmplt.bits & Col_Mask << Col_Pos);
462 if ((bits & (Col_Mask << Col_Pos)) == ui32(INHERIT_COLOR) << Col_Pos)
464 bits &= ~(Col_Mask << Col_Pos);
465 bits |= (tmplt.bits & Col_Mask << Col_Pos);
468 if ((bits & (Dir_Mask << Dir_Pos)) == ui32(INHERIT_DIR) << Dir_Pos)
470 bits &= ~(Dir_Mask << Dir_Pos);
471 bits |= (tmplt.bits & Dir_Mask << Dir_Pos);
479 /// Is font resolved?
481 bool LyXFont::resolved() const
483 return (family() != INHERIT_FAMILY && series() != INHERIT_SERIES &&
484 shape() != INHERIT_SHAPE && size() != INHERIT_SIZE &&
485 emph() != INHERIT && underbar() != INHERIT &&
486 noun() != INHERIT && latex() != INHERIT &&
487 color() != LColor::inherit &&
488 direction() != INHERIT_DIR);
491 bool LyXFont::resolved() const
493 return (family() != INHERIT_FAMILY && series() != INHERIT_SERIES &&
494 shape() != INHERIT_SHAPE && size() != INHERIT_SIZE &&
495 emph() != INHERIT && underbar() != INHERIT &&
496 noun() != INHERIT && latex() != INHERIT &&
497 color() != INHERIT_COLOR &&
498 direction() != INHERIT_DIR);
503 /// Build GUI description of font state
504 string LyXFont::stateText() const
507 if (family() != INHERIT_FAMILY)
508 buf += string(_(GUIFamilyNames[family()].c_str())) + ", ";
509 if (series() != INHERIT_SERIES)
510 buf += string(_(GUISeriesNames[series()].c_str())) + ", ";
511 if (shape() != INHERIT_SHAPE)
512 buf += string(_(GUIShapeNames[shape()].c_str())) + ", ";
513 if (size() != INHERIT_SIZE)
514 buf += string(_(GUISizeNames[size()].c_str())) + ", ";
516 if (color() != LColor::inherit)
517 buf += lcolor.getGUIName(color()) + ", ";
519 if (color() != INHERIT_COLOR)
520 buf += string(_(GUIColorNames[color()].c_str())) + ", ";
522 if (emph() != INHERIT)
523 buf += string(_("Emphasis ")) + _(GUIMiscNames[emph()].c_str()) + ", ";
524 if (underbar() != INHERIT)
525 buf += string(_("Underline ")) + _(GUIMiscNames[underbar()].c_str()) + ", ";
526 if (noun() != INHERIT)
527 buf += string(_("Noun ")) + _(GUIMiscNames[noun()].c_str()) + ", ";
528 if (latex() != INHERIT)
529 buf += string(_("Latex ")) + _(GUIMiscNames[latex()].c_str()) + ", ";
530 if (direction() != INHERIT_DIR)
531 buf += string(_("Direction ")) + _(GUIDirectionNames[direction()].c_str()) + ", ";
534 buf = strip(buf, ' ');
535 buf = strip(buf, ',');
540 // Set family according to lyx format string
541 LyXFont & LyXFont::setLyXFamily(string const & fam)
543 string s = lowercase(fam);
546 while (s != LyXFamilyNames[i] && LyXFamilyNames[i] != "error") ++i;
547 if (s == LyXFamilyNames[i]) {
548 setFamily(LyXFont::FONT_FAMILY(i));
550 lyxerr << "LyXFont::setLyXFamily: Unknown family `"
551 << s << '\'' << endl;
556 // Set series according to lyx format string
557 LyXFont & LyXFont::setLyXSeries(string const & ser)
559 string s = lowercase(ser);
562 while (s != LyXSeriesNames[i] && LyXSeriesNames[i] != "error") ++i;
563 if (s == LyXSeriesNames[i]) {
564 setSeries(LyXFont::FONT_SERIES(i));
566 lyxerr << "LyXFont::setLyXSeries: Unknown series `"
567 << s << '\'' << endl;
572 // Set shape according to lyx format string
573 LyXFont & LyXFont::setLyXShape(string const & sha)
575 string s = lowercase(sha);
578 while (s != LyXShapeNames[i] && LyXShapeNames[i] != "error") ++i;
579 if (s == LyXShapeNames[i]) {
580 setShape(LyXFont::FONT_SHAPE(i));
582 lyxerr << "LyXFont::setLyXShape: Unknown shape `"
583 << s << '\'' << endl;
588 // Set size according to lyx format string
589 LyXFont & LyXFont::setLyXSize(string const & siz)
591 string s = lowercase(siz);
593 while (s != LyXSizeNames[i] && LyXSizeNames[i] != "error") ++i;
594 if (s == LyXSizeNames[i]) {
595 setSize(LyXFont::FONT_SIZE(i));
597 lyxerr << "LyXFont::setLyXSize: Unknown size `"
598 << s << '\'' << endl;
602 // Set size according to lyx format string
603 LyXFont::FONT_MISC_STATE LyXFont::setLyXMisc(string const & siz)
605 string s = lowercase(siz);
607 while (s != LyXMiscNames[i] && LyXMiscNames[i] != "error") ++i;
608 if (s == LyXMiscNames[i])
609 return FONT_MISC_STATE(i);
610 lyxerr << "LyXFont::setLyXMisc: Unknown misc flag `"
611 << s << '\'' << endl;
615 /// Sets color after LyX text format
616 LyXFont & LyXFont::setLyXColor(string const & col)
619 setColor(lcolor.getFromLyXName(col));
621 string s = lowercase(col);
623 while (s != LyXColorNames[i] && LyXColorNames[i] != "error") ++i;
624 if (s == LyXColorNames[i]) {
625 setColor(LyXFont::FONT_COLOR(i));
627 lyxerr << "LyXFont::setLyXColor: Unknown Color `"
628 << s << '\'' << endl;
634 /// Sets size after GUI name
635 LyXFont & LyXFont::setGUISize(string const & siz)
639 // this is how it was how it was done in the lyx repository...
640 // but this does not make sense.
641 setColor(lcolor.getFromGUIName(siz));
643 string s = lowercase(siz);
645 while (!lGUISizeNames[i].empty() &&
646 s != _(lGUISizeNames[i].c_str()))
648 if (s == _(lGUISizeNames[i].c_str())) {
649 setSize(LyXFont::FONT_SIZE(i));
651 lyxerr << "LyXFont::setGUISize: Unknown Size `"
652 << s << '\'' << endl;
658 // Returns size in latex format
659 string LyXFont::latexSize() const
661 return LaTeXSizeNames[size()];
665 // Read a font definition from given file in lyx format
667 LyXFont & LyXFont::lyxRead(LyXLex & lex)
670 bool finished = false;
671 while (!finished && lex.IsOK() && !error) {
673 string tok = lowercase(lex.GetString());
677 } else if (tok == "endfont") {
679 } else if (tok == "family") {
681 string tok = lex.GetString();
683 } else if (tok == "series") {
685 string tok = lex.GetString();
687 } else if (tok == "shape") {
689 string tok = lex.GetString();
691 } else if (tok == "size") {
693 string tok = lex.GetString();
695 } else if (tok == "latex") {
697 string tok = lowercase(lex.GetString());
699 if (tok == "no_latex") {
701 } else if (tok == "latex") {
704 lex.printError("Illegal LaTeX type`$$Token'");
706 } else if (tok == "misc") {
708 string tok = lowercase(lex.GetString());
710 if (tok == "no_bar") {
712 } else if (tok == "no_emph") {
714 } else if (tok == "no_noun") {
716 } else if (tok == "emph") {
718 } else if (tok == "underbar") {
720 } else if (tok == "noun") {
723 lex.printError("Illegal misc type `$$Token´");
725 } else if (tok == "color") {
727 string tok = lex.GetString();
729 } else if (tok == "direction") {
731 string tok = lowercase(lex.GetString());
734 setDirection(LTR_DIR);
735 } else if (tok == "rtl") {
736 setDirection(RTL_DIR);
738 lex.printError("Illegal type`$$Token'");
741 lex.printError("Unknown tag `$$Token'");
749 /// Writes the changes from this font to orgfont in .lyx format in file
750 void LyXFont::lyxWriteChanges(LyXFont const & orgfont, ostream & os) const
753 if (orgfont.family() != family()) {
754 os << "\\family " << LyXFamilyNames[family()] << " \n";
756 if (orgfont.series() != series()) {
757 os << "\\series " << LyXSeriesNames[series()] << " \n";
759 if (orgfont.shape() != shape()) {
760 os << "\\shape " << LyXShapeNames[shape()] << " \n";
762 if (orgfont.size() != size()) {
763 os << "\\size " << LyXSizeNames[size()] << " \n";
765 if (orgfont.emph() != emph()) {
766 os << "\\emph " << LyXMiscNames[emph()] << " \n";
768 if (orgfont.underbar() != underbar()) {
769 // This is only for backwards compatibility
770 switch (underbar()) {
771 case OFF: os << "\\bar no \n"; break;
772 case ON: os << "\\bar under \n"; break;
773 case TOGGLE: lyxerr << "LyXFont::lyxWriteFontChanges: "
774 "TOGGLE should not appear here!"
777 case INHERIT: os << "\\bar default \n"; break;
778 case IGNORE: lyxerr << "LyXFont::lyxWriteFontChanges: "
779 "IGNORE should not appear here!"
784 if (orgfont.noun() != noun()) {
785 os << "\\noun " << LyXMiscNames[noun()] << " \n";
787 if (orgfont.latex() != latex()) {
788 // This is only for backwards compatibility
790 case OFF: os << "\\latex no_latex \n"; break;
791 case ON: os << "\\latex latex \n"; break;
792 case TOGGLE: lyxerr << "LyXFont::lyxWriteFontChanges: "
793 "TOGGLE should not appear here!"
796 case INHERIT: os << "\\latex default \n"; break;
797 case IGNORE: lyxerr << "LyXFont::lyxWriteFontChanges: "
798 "IGNORE should not appear here!"
804 if (orgfont.color() != color()) {
805 os << "\\color " << lcolor.getLyXName(color()) << "\n";
808 if (orgfont.color() != color()) {
809 os << "\\color " << LyXColorNames[color()] << "\n";
812 if (orgfont.direction() != direction()) {
813 switch (direction()) {
814 case RTL_DIR: os << "\\direction rtl \n"; break;
815 case LTR_DIR: os << "\\direction ltr\n"; break;
816 case TOGGLE_DIR: lyxerr << "LyXFont::lyxWriteFontChanges: "
817 "TOGGLE should not appear here!"
819 case INHERIT_DIR: os << "\\direction default \n"; break;
820 case IGNORE_DIR: lyxerr << "LyXFont::lyxWriteFontChanges: "
821 "IGNORE should not appear here!"
829 /// Writes the head of the LaTeX needed to impose this font
830 // Returns number of chars written.
831 int LyXFont::latexWriteStartChanges(string & file, LyXFont const & base,
832 LyXFont const & prev) const
837 if (f.bits == inherit)
843 FONT_DIRECTION direction = f.direction();
844 if (direction != prev.direction()) {
845 if (direction == LTR_DIR) {
848 env = true; //We have opened a new environment
850 if (direction == RTL_DIR) {
853 env = true; //We have opened a new environment
857 if (f.family() != INHERIT_FAMILY) {
859 file += LaTeXFamilyNames[f.family()];
861 count += LaTeXFamilyNames[f.family()].length() + 2;
862 env = true; //We have opened a new environment
864 if (f.series() != INHERIT_SERIES) {
866 file += LaTeXSeriesNames[f.series()];
868 count += LaTeXSeriesNames[f.series()].length() + 2;
869 env = true; //We have opened a new environment
871 if (f.shape() != INHERIT_SHAPE) {
873 file += LaTeXShapeNames[f.shape()];
875 count += LaTeXShapeNames[f.shape()].length() + 2;
876 env = true; //We have opened a new environment
879 if (f.color() != LColor::inherit) {
880 file += "\\textcolor{";
881 file += lcolor.getLaTeXName(f.color());
883 count += lcolor.getLaTeXName(f.color()).length() + 13;
884 env = true; //We have opened a new environment
887 if (f.color() != INHERIT_COLOR) {
888 file += "\\textcolor{";
889 file += LaTeXColorNames[f.color()];
891 count += LaTeXColorNames[f.color()].length() + 13;
892 env = true; //We have opened a new environment
895 if (f.emph() == ON) {
898 env = true; //We have opened a new environment
900 if (f.underbar() == ON) {
901 file += "\\underbar{";
903 env = true; //We have opened a new environment
905 // \noun{} is a LyX special macro
906 if (f.noun() == ON) {
909 env = true; //We have opened a new environment
911 if (f.size() != INHERIT_SIZE) {
912 // If we didn't open an environment above, we open one here
918 file += LaTeXSizeNames[f.size()];
920 count += LaTeXSizeNames[f.size()].length() + 2;
926 /// Writes ending block of LaTeX needed to close use of this font
927 // Returns number of chars written
928 // This one corresponds to latexWriteStartChanges(). (Asger)
929 int LyXFont::latexWriteEndChanges(string & file, LyXFont const & base,
930 LyXFont const & next) const
932 LyXFont f = *this; // why do you need this?
933 f.reduce(base); // why isn't this just "reduce(base);" (Lgb)
934 // Because this function is const. Everything breaks if this
935 // method changes the font it represents. There is no speed penalty
936 // by using the temporary. (Asger)
938 if (f.bits == inherit)
944 FONT_DIRECTION direction = f.direction();
945 if ( direction != next.direction()
946 && (direction == RTL_DIR || direction == LTR_DIR) ) {
949 env = true; // Size change need not bother about closing env.
952 if (f.family() != INHERIT_FAMILY) {
955 env = true; // Size change need not bother about closing env.
957 if (f.series() != INHERIT_SERIES) {
960 env = true; // Size change need not bother about closing env.
962 if (f.shape() != INHERIT_SHAPE) {
965 env = true; // Size change need not bother about closing env.
968 if (f.color() != LColor::inherit) {
971 env = true; // Size change need not bother about closing env.
974 if (f.color() != INHERIT_COLOR) {
977 env = true; // Size change need not bother about closing env.
980 if (f.emph() == ON) {
983 env = true; // Size change need not bother about closing env.
985 if (f.underbar() == ON) {
988 env = true; // Size change need not bother about closing env.
990 if (f.noun() == ON) {
993 env = true; // Size change need not bother about closing env.
995 if (f.size() != INHERIT_SIZE) {
996 // We only have to close if only size changed
1008 LColor::color LyXFont::realColor() const
1011 return LColor::latex;
1012 if (color() == LColor::none)
1013 return LColor::foreground;
1019 // Convert logical attributes to concrete shape attribute
1020 LyXFont::FONT_SHAPE LyXFont::realShape() const
1022 register FONT_SHAPE s = shape();
1031 s = SMALLCAPS_SHAPE;
1037 GC LyXFont::getGC() const
1041 gc = ::getGC(gc_latex);
1043 if (color() == NONE)
1044 gc = ::getGC(gc_copy);
1045 else if (color() == MATH)
1046 gc = ::getGC(gc_math);
1047 else if (color() == INSET)
1048 gc = ::getGC(gc_foot);
1050 gc = ::GetColorGC(color());
1053 XSetFont(fl_display, gc, getXFontstruct()->fid);
1059 XFontStruct * LyXFont::getXFontstruct() const
1061 return fontloader.load(family(), series(), realShape(), size());
1065 int LyXFont::maxAscent() const
1067 return getXFontstruct()->ascent;
1071 int LyXFont::maxDescent() const
1073 return getXFontstruct()->descent;
1077 int LyXFont::ascent(char c) const
1079 XFontStruct * finfo = getXFontstruct();
1080 unsigned int uc = static_cast<unsigned char>(c);
1082 && uc >= finfo->min_char_or_byte2
1083 && uc <= finfo->max_char_or_byte2)
1084 return finfo->per_char[uc - finfo->min_char_or_byte2].ascent;
1086 return finfo->ascent;
1090 int LyXFont::descent(char c) const
1092 XFontStruct * finfo = getXFontstruct();
1093 unsigned int uc = static_cast<unsigned char>(c);
1095 && uc >= finfo->min_char_or_byte2
1096 && uc <= finfo->max_char_or_byte2)
1097 return finfo->per_char[uc - finfo->min_char_or_byte2].descent;
1099 return finfo->descent;
1103 // Specialized after profiling. (Asger)
1104 int LyXFont::width(char c) const
1106 if (realShape() != LyXFont::SMALLCAPS_SHAPE){
1107 return XTextWidth(getXFontstruct(), &c, 1);
1109 return textWidth(&c, 1);
1114 int LyXFont::lbearing(char c) const
1116 XFontStruct * finfo = getXFontstruct();
1117 unsigned int uc = static_cast<unsigned char>(c);
1119 && uc >= finfo->min_char_or_byte2
1120 && uc <= finfo->max_char_or_byte2)
1121 return finfo->per_char[uc - finfo->min_char_or_byte2].lbearing;
1127 int LyXFont::rbearing(char c) const
1129 XFontStruct * finfo = getXFontstruct();
1130 unsigned int uc = static_cast<unsigned char>(c);
1132 && uc >= finfo->min_char_or_byte2
1133 && uc <= finfo->max_char_or_byte2)
1134 return finfo->per_char[uc - finfo->min_char_or_byte2].rbearing;
1140 int LyXFont::textWidth(char const * s, int n) const
1142 if (realShape() != LyXFont::SMALLCAPS_SHAPE){
1143 return XTextWidth(getXFontstruct(), s, n);
1145 // emulate smallcaps since X doesn't support this
1146 unsigned int result = 0;
1148 LyXFont smallfont = *this;
1149 smallfont.decSize();
1150 smallfont.decSize();
1151 smallfont.setShape(LyXFont::UP_SHAPE);
1152 for (int i = 0; i < n; ++i) {
1154 // when islower is a macro, the cast is needed (JMarc)
1155 if (islower(static_cast<unsigned char>(c))){
1157 result += XTextWidth(smallfont.getXFontstruct(), &c, 1);
1159 result += XTextWidth(getXFontstruct(), &c, 1);
1167 int LyXFont::stringWidth(string const & s) const
1169 if (s.empty()) return 0;
1170 return textWidth(s.c_str(), s.length());
1174 int LyXFont::signedStringWidth(string const & s) const
1176 if (s.empty()) return 0;
1177 if (s.c_str()[0] == '-')
1178 return -textWidth(s.c_str()+1, s.length()-1);
1180 return textWidth(s.c_str(), s.length());
1185 int LyXFont::drawText(char const * s, int n, Pixmap,
1188 if (realShape() != LyXFont::SMALLCAPS_SHAPE) {
1189 /* XDrawString(fl_display,
1194 XFlush(fl_display); */
1195 return XTextWidth(getXFontstruct(), s, n);
1198 // emulate smallcaps since X doesn't support this
1201 LyXFont smallfont = *this;
1202 smallfont.decSize();
1203 smallfont.decSize();
1204 smallfont.setShape(LyXFont::UP_SHAPE);
1205 for (int i = 0; i < n; ++i) {
1207 if (islower(static_cast<unsigned char>(c))){
1209 /* XDrawString(fl_display,
1214 x += XTextWidth(smallfont.getXFontstruct(),
1216 //XFlush(fl_display);
1218 /* XDrawString(fl_display,
1223 x += XTextWidth(getXFontstruct(), &c, 1);
1224 //XFlush(fl_display);
1231 int LyXFont::drawText(char const * s, int n, Pixmap pm,
1232 int baseline, int x) const
1234 if (realShape() != LyXFont::SMALLCAPS_SHAPE) {
1235 XDrawString(fl_display,
1241 return XTextWidth(getXFontstruct(), s, n);
1244 // emulate smallcaps since X doesn't support this
1247 LyXFont smallfont = *this;
1248 smallfont.decSize();
1249 smallfont.decSize();
1250 smallfont.setShape(LyXFont::UP_SHAPE);
1251 for (int i = 0; i < n; ++i) {
1253 if (islower(static_cast<unsigned char>(c))){
1255 XDrawString(fl_display,
1260 x += XTextWidth(smallfont.getXFontstruct(),
1264 XDrawString(fl_display,
1269 x += XTextWidth(getXFontstruct(), &c, 1);
1279 int LyXFont::drawString(string const & s, Pixmap pm, int baseline, int x) const
1281 return drawText(s.c_str(), s.length(), pm, baseline, x);
1285 bool LyXFont::equalExceptLatex(LyXFont const & f) const
1288 f1.setLatex(f.latex());
1293 ostream & operator<<(ostream & o, LyXFont::FONT_MISC_STATE fms)
1295 return o << int(fms);