From c46b7d89553209b8df4e9de392ee07ef711f092f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Lars=20Gullik=20Bj=C3=B8nnes?= Date: Sun, 13 Aug 2006 22:54:59 +0000 Subject: [PATCH] Merge the unicode branch into trunk. - src/support/unicode.[Ch]: new files with functions for converting to and fro ucs4, ucs2 and utf8. - src/support/docstring.h: specialization of basic_string that holds a uint32_t internally. - Several functions changed to use char_type instead of char or unsigned char. - Qt3 and Qt4 sends ucs2 on to core - Gtk sends ucs4 on to core - Read and write utf-8 .lyx files. - font_metrics and painter updated to handle ucs4 chars as input. - Quite a bit of ugly compability code, conversion string->docstring, etc. - Have fun... git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14661 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/BufferView_pimpl.C | 2 +- src/frontends/LyXKeySym.h | 9 +- src/frontends/Painter.C | 6 +- src/frontends/Painter.h | 8 +- src/frontends/WorkArea.C | 4 +- src/frontends/font_metrics.h | 22 ++- src/frontends/gtk/GLyXKeySym.C | 37 +--- src/frontends/gtk/GLyXKeySym.h | 3 +- src/frontends/gtk/GPainter.C | 51 +++--- src/frontends/gtk/GPainter.h | 6 +- src/frontends/gtk/GWorkArea.C | 22 +-- src/frontends/gtk/xftFontMetrics.C | 68 +++---- src/frontends/nullpainter.h | 12 +- src/frontends/qt3/QLPainter.C | 27 ++- src/frontends/qt3/QLPainter.h | 8 +- src/frontends/qt3/QLyXKeySym.C | 35 ++-- src/frontends/qt3/QLyXKeySym.h | 7 +- src/frontends/qt3/QWorkArea.C | 2 +- src/frontends/qt3/qfont_metrics.C | 135 +++++++------- src/frontends/qt4/GuiWorkArea.C | 2 +- src/frontends/qt4/QLPainter.C | 31 +++- src/frontends/qt4/QLPainter.h | 6 +- src/frontends/qt4/QLyXKeySym.C | 31 ++-- src/frontends/qt4/QLyXKeySym.h | 7 +- src/frontends/qt4/qfont_metrics.C | 113 ++++++------ src/insets/insetbibitem.C | 7 +- src/insets/insetcaption.C | 11 +- src/insets/insetcharstyle.C | 9 +- src/insets/insetcollapsable.C | 8 +- src/insets/insetlatexaccent.C | 26 ++- src/insets/insetlatexaccent.h | 3 +- src/insets/insetpagebreak.C | 6 +- src/insets/insetquotes.C | 4 +- src/insets/insetspace.C | 4 +- src/insets/insetspecialchar.C | 20 +- src/insets/insetvspace.C | 12 +- src/insets/render_button.C | 14 +- src/insets/render_graphic.C | 13 +- src/insets/render_preview.C | 12 +- src/lyxfunc.C | 7 +- src/lyxfunc.h | 4 +- src/lyxlex.C | 6 + src/lyxlex.h | 5 + src/lyxlex_pimpl.C | 10 + src/lyxlex_pimpl.h | 4 + src/lyxtext.h | 4 +- src/mathed/math_hullinset.C | 5 +- src/mathed/math_macro.C | 9 +- src/mathed/math_macrotemplate.C | 10 +- src/mathed/math_numberinset.C | 5 +- src/mathed/math_scriptinset.C | 4 +- src/mathed/math_stringinset.C | 4 +- src/mathed/math_support.C | 13 +- src/mathed/math_symbolinset.C | 5 +- src/metricsinfo.C | 7 +- src/metricsinfo.h | 4 +- src/paragraph.C | 12 +- src/paragraph.h | 6 +- src/rowpainter.C | 59 ++++-- src/support/Makefile.am | 2 + src/support/docstring.h | 28 +++ src/support/lstrings.h | 2 + src/support/types.h | 10 +- src/support/unicode.C | 285 +++++++++++++++++++++++++++++ src/support/unicode.h | 40 ++++ src/text.C | 116 ++++++++---- src/text2.C | 5 +- src/text3.C | 11 ++ 68 files changed, 1044 insertions(+), 441 deletions(-) create mode 100644 src/support/docstring.h create mode 100644 src/support/unicode.C create mode 100644 src/support/unicode.h diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index 527dc2693b..629ebee4fb 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -619,7 +619,7 @@ bool BufferView::Pimpl::update(Update::flags flags) bool const need_second_step = (flags & (Update::Force | Update::FitCursor | Update::MultiParSel)) && (fitCursor() || multiParSel()); - + return need_second_step; } diff --git a/src/frontends/LyXKeySym.h b/src/frontends/LyXKeySym.h index 11b0677c8e..4bad77316c 100644 --- a/src/frontends/LyXKeySym.h +++ b/src/frontends/LyXKeySym.h @@ -40,17 +40,16 @@ public: virtual bool isModifier() const = 0; /// Is this normal insertable text ? (last ditch attempt only) - virtual bool isText() const { return false; } + virtual bool isText() const = 0; /// What is the symbolic name of this key? F.ex. "Return" or "c" virtual std::string getSymbolName() const = 0; /** - * Return the value of the keysym into the local ISO encoding. - * This converts the LyXKeySym to a 8-bit encoded character. - * This relies on user to use the right encoding. + * Return the value of the keysym into the UCS-4 encoding. + * This converts the LyXKeySym to a 32-bit encoded character. */ - virtual char getISOEncoded(std::string const & encoding) const = 0; + virtual size_t getUCSEncoded() const = 0; /** * Return a string describing the KeySym with modifier mod. diff --git a/src/frontends/Painter.C b/src/frontends/Painter.C index a3b14ff624..757d851886 100644 --- a/src/frontends/Painter.C +++ b/src/frontends/Painter.C @@ -17,6 +17,8 @@ #include "LColor.h" #include "lyxfont.h" +using lyx::docstring; + using std::max; using std::string; @@ -48,7 +50,7 @@ void Painter::buttonFrame(int x, int y, int w, int h) void Painter::rectText(int x, int y, - string const & str, + docstring const & str, LyXFont const & font, LColor_color back, LColor_color frame) @@ -70,7 +72,7 @@ void Painter::rectText(int x, int y, } -void Painter::buttonText(int x, int y, string const & str, LyXFont const & font) +void Painter::buttonText(int x, int y, docstring const & str, LyXFont const & font) { int width; int ascent; diff --git a/src/frontends/Painter.h b/src/frontends/Painter.h index 3bf36843d6..1cca72c19b 100644 --- a/src/frontends/Painter.h +++ b/src/frontends/Painter.h @@ -135,14 +135,14 @@ public: /// draw a string at position x, y (y is the baseline) virtual void text(int x, int y, - std::string const & str, LyXFont const & f) = 0; + lyx::docstring const & str, LyXFont const & f) = 0; /** * Draw a string at position x, y (y is the baseline) * This is just for fast drawing */ virtual void text(int x, int y, - char const * str, size_t l, + lyx::char_type const * str, size_t l, LyXFont const & f) = 0; /// draw a char at position x, y (y is the baseline) @@ -156,14 +156,14 @@ public: * around the text with the given color. */ virtual void rectText(int x, int baseline, - std::string const & str, + lyx::docstring const & str, LyXFont const & font, LColor_color back, LColor_color frame); /// draw a string and enclose it inside a button frame virtual void buttonText(int x, - int baseline, std::string const & s, + int baseline, lyx::docstring const & s, LyXFont const & font); protected: diff --git a/src/frontends/WorkArea.C b/src/frontends/WorkArea.C index 5c789a8e0f..ba6a9625a3 100644 --- a/src/frontends/WorkArea.C +++ b/src/frontends/WorkArea.C @@ -269,7 +269,9 @@ void WorkArea::greyOut() x += 260; y += 265; - getPainter().text(x, y, splash.text(), splash.font()); + string stext = splash.text(); + docstring dstext(stext.begin(), stext.end()); + getPainter().text(x, y, dstext, splash.font()); } expose(0, 0, width(), height()); getPainter().end(); diff --git a/src/frontends/font_metrics.h b/src/frontends/font_metrics.h index 4d4a79b83a..a1bd2725c5 100644 --- a/src/frontends/font_metrics.h +++ b/src/frontends/font_metrics.h @@ -57,7 +57,8 @@ namespace font_metrics { /// return the descent of the char in the font int descent(lyx::char_type c, LyXFont const & f); /// return the descent of the char in the font - inline int height(lyx::char_type c, LyXFont const & f) { + inline int height(lyx::char_type c, LyXFont const & f) + { return ascent(c, f) + descent(c, f); } /// return the left bearing of the char in the font @@ -69,22 +70,25 @@ namespace font_metrics { return (rbearing(c, f) - lbearing(c, f)) / 2; } /// return the width of the string in the font - int width(char const * s, size_t n, LyXFont const & f); + int width(lyx::char_type const * s, size_t n, LyXFont const & f); /// return the width of the char in the font - inline int width(lyx::char_type c, LyXFont const & f) { - return width(&c, 1, f); + inline int width(lyx::char_type c, LyXFont const & f) + { + lyx::char_type tmp[2] = { c, L'\0'}; + return width(tmp, 1, f); } /// return the width of the string in the font - inline int width(std::string const & s, LyXFont const & f) { - return s.empty() ? 0 : width(s.data(), s.length(), f); + inline int width(lyx::docstring const & s, LyXFont const & f) + { + return s.empty() ? 0 : width(s.data(), s.length(), f); } /// FIXME ?? - int signedWidth(std::string const & s, LyXFont const & f); + int signedWidth(lyx::docstring const & s, LyXFont const & f); /** * fill in width,ascent,descent with the values for the * given string in the font. */ - void rectText(std::string const & str, LyXFont const & font, + void rectText(lyx::docstring const & str, LyXFont const & font, int & width, int & ascent, int & descent); @@ -92,7 +96,7 @@ namespace font_metrics { * fill in width,ascent,descent with the values for the * given string in the font for a button. */ - void buttonText(std::string const & str, LyXFont const & font, + void buttonText(lyx::docstring const & str, LyXFont const & font, int & width, int & ascent, int & descent); diff --git a/src/frontends/gtk/GLyXKeySym.C b/src/frontends/gtk/GLyXKeySym.C index 22c38fb104..2dbe883264 100644 --- a/src/frontends/gtk/GLyXKeySym.C +++ b/src/frontends/gtk/GLyXKeySym.C @@ -71,36 +71,9 @@ string GLyXKeySym::getSymbolName() const } -char GLyXKeySym::getISOEncoded(string const & /*encoding*/) const +size_t GLyXKeySym::getUCSEncoded() const { - if (keyval_ == GDK_VoidSymbol) - return 0; - - unsigned int c = keyval_; - - switch (c & 0x0000FF00) { - // latin 1 byte 3 = 0 - case 0x00000000: break; - // latin 2 byte 3 = 1 - case 0x00000100: - // latin 3 byte 3 = 2 - case 0x00000200: - // latin 4 byte 3 = 3 - case 0x00000300: - // cyrillic KOI8 & Co - case 0x00000600: - // greek - case 0x00000700: - // latin 8 byte 3 = 18 (0x12) - case 0x00001200: - // latin 9 byte 3 = 19 (0x13) - case 0x00001300: - c &= 0x000000FF; - break; - default: - c = 0; - } - return c; + return gdk_keyval_to_unicode(keyval_); } @@ -128,6 +101,12 @@ string const GLyXKeySym::print(key_modifier::state mod) const } +bool GLyXKeySym::isText() const +{ + return getUCSEncoded() != 0; +} + + bool operator==(LyXKeySym const & k1, LyXKeySym const & k2) { return static_cast(k1).getKeyval() diff --git a/src/frontends/gtk/GLyXKeySym.h b/src/frontends/gtk/GLyXKeySym.h index a0a8e82a80..3035871307 100644 --- a/src/frontends/gtk/GLyXKeySym.h +++ b/src/frontends/gtk/GLyXKeySym.h @@ -24,8 +24,9 @@ public: virtual ~GLyXKeySym() {} virtual bool isOK() const; virtual bool isModifier() const; + virtual bool isText() const; virtual std::string getSymbolName() const; - virtual char getISOEncoded(std::string const & encoding) const; + virtual size_t getUCSEncoded() const; virtual std::string const print(key_modifier::state mod) const; private: unsigned int keyval_; diff --git a/src/frontends/gtk/GPainter.C b/src/frontends/gtk/GPainter.C index 594cdf0565..96d5c5734c 100644 --- a/src/frontends/gtk/GPainter.C +++ b/src/frontends/gtk/GPainter.C @@ -43,13 +43,6 @@ using std::string; -namespace font_metrics { - -int width(wchar_t const * s, size_t n, LyXFont const & f); - -} // namespace font_metrics - - namespace lyx { namespace frontend { @@ -192,6 +185,7 @@ void GPainter::image(int x, int y, int w, int h, Gdk::RGB_DITHER_NONE, 0, 0); } +namespace { inline XftFont * getXftFont(LyXFont const & f) { @@ -199,34 +193,47 @@ inline XftFont * getXftFont(LyXFont const & f) f.realShape(), f.size()); } +} // anon namespace + -// ENCODING: we assume we've got 8-bit string in whatever format Xft -// wants. We should be finding out what the backend's giving us and -// then converting it before feeding it to Xft using XftDrawStringUtf8 -void GPainter::text(int x, int y, char const * s, size_t ls, LyXFont const & f) +void GPainter::text(int x, int y, + char_type const * s, size_t ls, + LyXFont const & f) { XftFont * font = getXftFont(f); XftColor * xftClr = owner_.getColorHandler(). getXftColor(f.realColor()); XftDraw * draw = owner_.getXftDraw(); if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) { - XftDrawString8(draw, xftClr, font, x, y, - reinterpret_cast(const_cast(s)), ls); + XftDrawString32(draw, + xftClr, + font, + x, y, + reinterpret_cast(s), + ls); } else { LyXFont smallfont(f); smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE); XftFont * fontS = getXftFont(smallfont); - char c; int tmpx = x; for (unsigned int i = 0; i < ls; ++i) { - c = lyx::support::uppercase(s[i]); + // Ok, this looks quite ugly... + char_type c = gdk_keyval_to_unicode(gdk_keyval_to_upper(gdk_unicode_to_keyval(s[i]))); if (c != s[i]) { - XftDrawString8(draw, xftClr, fontS, tmpx, y, - reinterpret_cast(const_cast(&c)), 1); + XftDrawString32(draw, + xftClr, + fontS, + tmpx, y, + reinterpret_cast(&c), + 1); tmpx += font_metrics::width(c, smallfont); } else { - XftDrawString8(draw, xftClr, font, tmpx, y, - reinterpret_cast(const_cast(&c)), 1); + XftDrawString32(draw, + xftClr, + font, + tmpx, y, + reinterpret_cast(&c), + 1); tmpx += font_metrics::width(c, f); } } @@ -236,13 +243,13 @@ void GPainter::text(int x, int y, char const * s, size_t ls, LyXFont const & f) } -void GPainter::text(int x, int y, std::string const & s, LyXFont const & f) +void GPainter::text(int x, int y, docstring const & s, LyXFont const & f) { - text (x, y, s.c_str(), s.size(), f); + text (x, y, reinterpret_cast(s.data()), s.size(), f); } -void GPainter::text(int x, int y, char c, LyXFont const & f) +void GPainter::text(int x, int y, char_type c, LyXFont const & f) { text (x, y, &c, 1, f); } diff --git a/src/frontends/gtk/GPainter.h b/src/frontends/gtk/GPainter.h index ff1eaba4fb..6201db57c8 100644 --- a/src/frontends/gtk/GPainter.h +++ b/src/frontends/gtk/GPainter.h @@ -98,16 +98,16 @@ public: /// draw a string at position x, y (y is the baseline) virtual void text(int x, int y, - std::string const & str, LyXFont const & f); + lyx::docstring const & str, LyXFont const & f); /// draw a string at position x, y (y is the baseline) virtual void text(int x, int y, - char const * str, size_t l, + lyx::char_type const * str, size_t l, LyXFont const & f); /// draw a char at position x, y (y is the baseline) virtual void text(int x, int y, - char c, LyXFont const & f); + lyx::char_type c, LyXFont const & f); void start(); diff --git a/src/frontends/gtk/GWorkArea.C b/src/frontends/gtk/GWorkArea.C index 35cbbc4499..3bb4e1f9e5 100644 --- a/src/frontends/gtk/GWorkArea.C +++ b/src/frontends/gtk/GWorkArea.C @@ -475,20 +475,20 @@ void GWorkArea::inputCommit(gchar * str) bool GWorkArea::onKeyPress(GdkEventKey * event) { -#ifdef I18N - inputCache_ = ""; - bool inputGet = gtk_im_context_filter_keypress(imContext_, event); - // cope with ascii - if ((inputGet && inputCache_.size() == 1 && inputCache_[0] < 128) || - !inputGet) { -#endif +// #ifdef I18N +// inputCache_ = ""; +// bool inputGet = gtk_im_context_filter_keypress(imContext_, event); +// // cope with ascii +// if ((inputGet && inputCache_.size() == 1 && inputCache_[0] < 128) || +// !inputGet) { +// #endif GLyXKeySym *glk = new GLyXKeySym(event->keyval); view_.workArea()->processKeySym(LyXKeySymPtr(glk), gtkKeyState(event->state)); -#ifdef I18N - } else if (!inputCache_.empty()) - workAreaCJK_IMprocess(inputCache_.size(), inputCache_.data()); -#endif +// #ifdef I18N +// } else if (!inputCache_.empty()) +// workAreaCJK_IMprocess(inputCache_.size(), inputCache_.data()); +// #endif return true; } diff --git a/src/frontends/gtk/xftFontMetrics.C b/src/frontends/gtk/xftFontMetrics.C index d2a4a6a3e5..5445660903 100644 --- a/src/frontends/gtk/xftFontMetrics.C +++ b/src/frontends/gtk/xftFontMetrics.C @@ -34,6 +34,9 @@ #include +using lyx::char_type; +using lyx::docstring; + using std::string; @@ -79,78 +82,78 @@ inline int XGlyphLogWidth(XGlyphInfo const & info) } // namespace anon -namespace font_metrics { - - -int maxAscent(LyXFont const & f) +int font_metrics::maxAscent(LyXFont const & f) { XftFont * font = getXftFont(f); return font->ascent; } -int maxDescent(LyXFont const & f) +int font_metrics::maxDescent(LyXFont const & f) { XftFont * font = getXftFont(f); return font->descent; } -int ascent(char c,LyXFont const & f) +int font_metrics::ascent(char_type c,LyXFont const & f) { XftFont * font = getXftFont(f); XGlyphInfo glyph; - XftTextExtents8(getDisplay(), font, - reinterpret_cast(&c), + XftTextExtents32(getDisplay(), font, + reinterpret_cast(&c), 1, &glyph); return XGlyphAscent(glyph); } -int descent(char c,LyXFont const & f) +int font_metrics::descent(char_type c,LyXFont const & f) { XftFont * font = getXftFont(f); XGlyphInfo glyph; - XftTextExtents8(getDisplay(), font, - reinterpret_cast(&c), + XftTextExtents32(getDisplay(), font, + reinterpret_cast(&c), 1, &glyph); return XGlyphDescent(glyph); } -int lbearing(char c,LyXFont const & f) +int font_metrics::lbearing(char_type c,LyXFont const & f) { XftFont * font = getXftFont(f); XGlyphInfo glyph; - XftTextExtents8(getDisplay(), font, - reinterpret_cast(&c), + XftTextExtents32(getDisplay(), font, + reinterpret_cast(&c), 1, &glyph); return XGlyphLbearing(glyph); } -int rbearing(char c,LyXFont const & f) +int font_metrics::rbearing(char_type c,LyXFont const & f) { XftFont * font = getXftFont(f); XGlyphInfo glyph; - XftTextExtents8(getDisplay(), font, - reinterpret_cast(&c), + XftTextExtents32(getDisplay(), font, + reinterpret_cast(&c), 1, &glyph); return XGlyphRbearing(glyph); } -int width(char const * s, size_t n, LyXFont const & f) +int font_metrics::width(char_type const * s, size_t n, LyXFont const & f) { XftFont * font = getXftFont(f); XGlyphInfo glyph; if (f.realShape() != LyXFont::SMALLCAPS_SHAPE){ - XftTextExtents8(getDisplay(), font, - reinterpret_cast(const_cast(s)), n, &glyph); + XftTextExtents32(getDisplay(), + font, + reinterpret_cast(s), + n, + &glyph); return XGlyphLogWidth(glyph); } else { int result = 0; @@ -158,16 +161,18 @@ int width(char const * s, size_t n, LyXFont const & f) smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE); XftFont * fontS = getXftFont(smallfont); for (size_t i = 0; i < n; ++i) { - char c = lyx::support::uppercase(s[i]); + char_type c = lyx::support::uppercase(s[i]); if (c != s[i]) { - XftTextExtents8(getDisplay(), fontS, - reinterpret_cast(&c), + XftTextExtents32(getDisplay(), + fontS, + reinterpret_cast(&c), 1, &glyph); result += XGlyphLogWidth(glyph); } else { - XftTextExtents8(getDisplay(), font, - reinterpret_cast(&c), + XftTextExtents32(getDisplay(), + font, + reinterpret_cast(&c), 1, &glyph); result += XGlyphLogWidth(glyph); @@ -178,18 +183,18 @@ int width(char const * s, size_t n, LyXFont const & f) } -int signedWidth(string const & s, LyXFont const & f) +int font_metrics::signedWidth(docstring const & s, LyXFont const & f) { if (s.empty()) return 0; if (s[0] == '-') - return width(s.c_str() + 1, s.size() - 1, f); + return width(s.substr(1, s.length() - 1), f); else - return width(s.c_str(), s.size(), f); + return width(s, f); } -void rectText(string const & str, LyXFont const & font, +void font_metrics::rectText(docstring const & str, LyXFont const & font, int & width, int & ascent, int & descent) @@ -201,7 +206,7 @@ void rectText(string const & str, LyXFont const & font, } -void buttonText(string const & str, LyXFont const & font, +void font_metrics::buttonText(docstring const & str, LyXFont const & font, int & width, int & ascent, int & descent) @@ -212,6 +217,3 @@ void buttonText(string const & str, LyXFont const & font, ascent = font_metrics::maxAscent(font) + d; descent = font_metrics::maxDescent(font) + d; } - - -} // namespace font_metrics diff --git a/src/frontends/nullpainter.h b/src/frontends/nullpainter.h index 2a5e5d6fd6..bb77976bca 100644 --- a/src/frontends/nullpainter.h +++ b/src/frontends/nullpainter.h @@ -57,16 +57,18 @@ public: /// void image(int, int, int, int, lyx::graphics::Image const &) {} /// - void text(int, int, std::string const &, LyXFont const &) {} + void text(int, int, lyx::docstring const &, LyXFont const &) {} +// /// +// void text(int, int, char const *, size_t, LyXFont const &) {} /// - void text(int, int, char const *, size_t, LyXFont const &) {} + void text(int, int, lyx::char_type const *, size_t, LyXFont const &) {} /// - void text(int, int, char, LyXFont const &) {} + void text(int, int, lyx::char_type, LyXFont const &) {} /// - void rectText(int, int, std::string const &, + void rectText(int, int, lyx::docstring const &, LyXFont const &, LColor_color, LColor_color) {} /// - void buttonText(int, int, std::string const &, LyXFont const &) {} + void buttonText(int, int, lyx::docstring const &, LyXFont const &) {} /// void underline(LyXFont const &, int, int, int) {} /// diff --git a/src/frontends/qt3/QLPainter.C b/src/frontends/qt3/QLPainter.C index dfb9e6f1c4..be335513b7 100644 --- a/src/frontends/qt3/QLPainter.C +++ b/src/frontends/qt3/QLPainter.C @@ -21,6 +21,8 @@ #include "language.h" #include "LColor.h" +#include "support/unicode.h" + #include "frontends/font_metrics.h" #include @@ -157,15 +159,16 @@ void QLPainter::image(int x, int y, int w, int h, } -void QLPainter::text(int x, int y, string const & s, LyXFont const & f) +void QLPainter::text(int x, int y, docstring const & s, LyXFont const & f) { - return text(x, y, s.data(), s.length(), f); + lyxerr << "Drawing string" << endl; + return text(x, y, reinterpret_cast(s.data()), s.length(), f); } void QLPainter::text(int x, int y, lyx::char_type c, LyXFont const & f) { - char s[2] = { c, '\0' }; + char_type s[2] = { c, L'\0' }; return text(x, y, s, 1, f); } @@ -199,23 +202,38 @@ void QLPainter::smallCapsText(int x, int y, } -void QLPainter::text(int x, int y, char const * s, size_t ls, +void QLPainter::text(int x, int y, lyx::char_type const * s, size_t ls, LyXFont const & f) { + lyxerr << "Drawing lyx::char_type const * s" << endl; setPen(f.realColor()); +#if 0 Encoding const * encoding = f.language()->encoding(); if (f.isSymbolFont()) encoding = encodings.symbol_encoding(); +#endif + +#if 0 QString str; str.setLength(ls); for (size_t i = 0; i < ls; ++i) // Brain-dead MSVC wants at(i) rather than operator[] str.at(i) = QChar(encoding->ucs(s[i])); +#else + //std::vector in(s, s + ls); + //std::vector ucs2 = ucs4_to_ucs2(in); + std::vector ucs2 = ucs4_to_ucs2(s, ls); + ucs2.push_back(0); + QString str = QString::fromUcs2(&ucs2[0]); +#endif + +#if 0 // HACK: QT3 refuses to show single compose characters if (ls == 1 && str[0].unicode() >= 0x05b0 && str[0].unicode() <= 0x05c2) str = ' ' + str; +#endif if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) { qp_->setFont(fontloader.get(f)); @@ -233,4 +251,3 @@ void QLPainter::text(int x, int y, char const * s, size_t ls, } // namespace frontend } // namespace lyx - diff --git a/src/frontends/qt3/QLPainter.h b/src/frontends/qt3/QLPainter.h index 19f1111d59..ade005a79c 100644 --- a/src/frontends/qt3/QLPainter.h +++ b/src/frontends/qt3/QLPainter.h @@ -99,18 +99,18 @@ public: /// draw a string at position x, y (y is the baseline) virtual void text(int x, int y, - std::string const & str, LyXFont const & f); + lyx::docstring const & str, LyXFont const & f); /** Draw a string at position x, y (y is the baseline) * This is just for fast drawing */ virtual void text(int x, int y, - char const * str, size_t l, - LyXFont const & f); + lyx::char_type const * str, size_t l, + LyXFont const & f); /// draw a char at position x, y (y is the baseline) virtual void text(int x, int y, - char c, LyXFont const & f); + lyx::char_type c, LyXFont const & f); private: /// draw small caps text void smallCapsText(int x, int y, diff --git a/src/frontends/qt3/QLyXKeySym.C b/src/frontends/qt3/QLyXKeySym.C index 1300e8d8b7..27ab911f86 100644 --- a/src/frontends/qt3/QLyXKeySym.C +++ b/src/frontends/qt3/QLyXKeySym.C @@ -24,6 +24,7 @@ #include #include "support/lstrings.h" #include "support/environment.h" +#include "support/unicode.h" #include "encoding.h" #include "language.h" @@ -75,6 +76,7 @@ char const encode(string const & encoding, QString const & str) void initEncodings() { +#if 0 //const char * c = QTextCodec::locale(); //string s = c ? c : ""; // In this order, see support/filetools.C @@ -131,7 +133,7 @@ void initEncodings() encoding_map[""] = defaultCodec; QTextCodec::setCodecForCStrings(defaultCodec); - +#endif } @@ -152,7 +154,10 @@ void QLyXKeySym::set(QKeyEvent * ev) } text_ = ev->text(); if (lyxerr.debugging()) - lyxerr[Debug::KEY] << "Setting key to " << key_ << ", " << fromqstr(text_) << endl; + lyxerr[Debug::KEY] << "Setting key to " + << key_ << ", " + << text_.utf8() + << endl; } @@ -195,14 +200,20 @@ string QLyXKeySym::getSymbolName() const } -char QLyXKeySym::getISOEncoded(string const & encoding) const +size_t QLyXKeySym::getUCSEncoded() const { - if (lyxerr.debugging()) - lyxerr[Debug::KEY] << "encoding is " << encoding << endl; - unsigned char const c = encode(encoding, text_); - if (lyxerr.debugging()) - lyxerr[Debug::KEY] << "ISOEncoded returning value " << int(c) << endl; - return c; + unsigned short const * ptr = text_.ucs2(); + std::vector tmp(ptr, ptr + text_.length()); + + //lyxerr << "Data is " << tmp << endl; + //lyxerr << "Length is " << text_.length() << endl; + + if (text_.isEmpty()) + return 0; + + //size_t res = utf8_to_ucs4(tmp, tmp.length()); + //lyxerr << "Res is " << res << endl; + return ucs2_to_ucs4(tmp)[0]; } @@ -235,11 +246,7 @@ bool QLyXKeySym::isText() const return false; } - QChar const c(text_[0]); - if (lyxerr.debugging()) - lyxerr[Debug::KEY] << "isText for key " << key_ - << " isPrint is " << c.isPrint() << endl; - return c.isPrint(); + return true; } diff --git a/src/frontends/qt3/QLyXKeySym.h b/src/frontends/qt3/QLyXKeySym.h index a0d18af290..85fea60c59 100644 --- a/src/frontends/qt3/QLyXKeySym.h +++ b/src/frontends/qt3/QLyXKeySym.h @@ -49,11 +49,10 @@ public: virtual bool isText() const; /** - * Return the value of the keysym into the local ISO encoding. - * This converts the LyXKeySym to a 8-bit encoded character. - * This relies on user to use the right encoding. + * Return the value of the keysym into the UCS-4 encoding. + * This converts the LyXKeySym to a 32-bit encoded character. */ - virtual char getISOEncoded(std::string const & encoding) const; + virtual size_t getUCSEncoded() const; /// Return a human-readable version of a key+modifier pair. virtual std::string const print(key_modifier::state mod) const; diff --git a/src/frontends/qt3/QWorkArea.C b/src/frontends/qt3/QWorkArea.C index 9fe3273d42..0f1610fa3e 100644 --- a/src/frontends/qt3/QWorkArea.C +++ b/src/frontends/qt3/QWorkArea.C @@ -55,7 +55,7 @@ namespace lyx { namespace frontend { QWorkArea::QWorkArea(LyXView & owner, int, int) - : QWidget(qApp->mainWidget()), owner_(owner), painter_(*this) + : QWidget(qApp->mainWidget()), owner_(owner), painter_(*this) { scrollbar_ = new QScrollBar(QScrollBar::Vertical, this); content_ = new QContentPane(this); diff --git a/src/frontends/qt3/qfont_metrics.C b/src/frontends/qt3/qfont_metrics.C index 1091636c71..135d55edb2 100644 --- a/src/frontends/qt3/qfont_metrics.C +++ b/src/frontends/qt3/qfont_metrics.C @@ -18,14 +18,46 @@ #include "language.h" +#include "support/unicode.h" + using lyx::char_type; +using lyx::docstring; using std::string; -namespace font_metrics { +namespace { -int maxAscent(LyXFont const & f) +int smallcapswidth(unsigned short const * s, size_t ls, LyXFont const & f) +{ + if (!lyx_gui::use_gui) + return 1; + // handle small caps ourselves ... + + LyXFont smallfont = f; + smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE); + + QFontMetrics const & qm = fontloader.metrics(f); + QFontMetrics const & qsmallm = fontloader.metrics(smallfont); + + int w = 0; + + for (size_t i = 0; i < ls; ++i) { + QChar const c = s[i]; + QChar const uc = c.upper(); + if (c != uc) + w += qsmallm.width(uc); + else + w += qm.width(c); + } + return w; +} + + +} // anon namespace + + +int font_metrics::maxAscent(LyXFont const & f) { if (!lyx_gui::use_gui) return 1; @@ -33,7 +65,7 @@ int maxAscent(LyXFont const & f) } -int maxDescent(LyXFont const & f) +int font_metrics::maxDescent(LyXFont const & f) { if (!lyx_gui::use_gui) return 1; @@ -43,11 +75,12 @@ int maxDescent(LyXFont const & f) } -int ascent(char_type c, LyXFont const & f) +int font_metrics::ascent(char_type c, LyXFont const & f) { if (!lyx_gui::use_gui) return 1; - QRect const & r = fontloader.metrics(f).boundingRect(c); + + QRect const & r = fontloader.metrics(f).boundingRect(ucs4_to_ucs2(c)); // Qt/Win 3.2.1nc (at least) corrects the GetGlyphOutlineA|W y // value by the height: (x, -y-height, width, height). // Other versions return: (x, -y, width, height) @@ -59,11 +92,12 @@ int ascent(char_type c, LyXFont const & f) } -int descent(char_type c, LyXFont const & f) +int font_metrics::descent(char_type c, LyXFont const & f) { if (!lyx_gui::use_gui) return 1; - QRect const & r = fontloader.metrics(f).boundingRect(c); + + QRect const & r = fontloader.metrics(f).boundingRect(ucs4_to_ucs2(c)); // Qt/Win 3.2.1nc (at least) corrects the GetGlyphOutlineA|W y // value by the height: (x, -y-height, width, height). // Other versions return: (x, -y, width, height) @@ -75,113 +109,78 @@ int descent(char_type c, LyXFont const & f) } -int lbearing(char_type c, LyXFont const & f) +int font_metrics::lbearing(char_type c, LyXFont const & f) { if (!lyx_gui::use_gui) return 1; - return fontloader.metrics(f).leftBearing(c); -} - -int rbearing(char_type c, LyXFont const & f) -{ - if (!lyx_gui::use_gui) - return 1; - QFontMetrics const & m = fontloader.metrics(f); - - // Qt rbearing is from the right edge of the char's width(). - return m.width(c) - m.rightBearing(c); + return fontloader.metrics(f).leftBearing(ucs4_to_ucs2(c)); } -Encoding const * fontencoding(LyXFont const & f) -{ - Encoding const * encoding = f.language()->encoding(); - if (f.isSymbolFont()) - encoding = encodings.symbol_encoding(); - return encoding; -} - - -int smallcapswidth(char const * s, size_t ls, LyXFont const & f) +int font_metrics::rbearing(char_type c, LyXFont const & f) { if (!lyx_gui::use_gui) return 1; - // handle small caps ourselves ... - - LyXFont smallfont = f; - smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE); - - QFontMetrics const & qm = fontloader.metrics(f); - QFontMetrics const & qsmallm = fontloader.metrics(smallfont); - - Encoding const * encoding = fontencoding(f); - int w = 0; + QFontMetrics const & m = fontloader.metrics(f); - for (size_t i = 0; i < ls; ++i) { - QChar const c = QChar(encoding->ucs(s[i])); - QChar const uc = c.upper(); - if (c != uc) - w += qsmallm.width(uc); - else - w += qm.width(c); - } - return w; + // Qt rbearing is from the right edge of the char's width(). + unsigned short sc = ucs4_to_ucs2(c); + return m.width(sc) - m.rightBearing(sc); } -int width(char const * s, size_t ls, LyXFont const & f) +int font_metrics::width(lyx::char_type const * str, size_t const ls, LyXFont const & f) { if (!lyx_gui::use_gui) return ls; + std::vector ucs2 = ucs4_to_ucs2(str, ls); + ucs2.push_back(0); + if (f.realShape() == LyXFont::SMALLCAPS_SHAPE) - return smallcapswidth(s, ls, f); + return smallcapswidth(&ucs2[0], ls, f); - Encoding const * encoding = fontencoding(f); QLFontInfo & fi = fontloader.fontinfo(f); if (ls == 1) - return fi.width(encoding->ucs(s[0])); + return fi.width(ucs2[0]); int w = 0; for (size_t i = 0; i < ls; ++i) - w += fi.width(encoding->ucs(s[i])); + w += fi.width(ucs2[i]); return w; } -int signedWidth(string const & s, LyXFont const & f) -{ - if (s[0] == '-') - return -width(s.substr(1, s.length() - 1), f); - else - return width(s, f); -} - - -void rectText(string const & str, LyXFont const & f, +void font_metrics::rectText(docstring const & str, LyXFont const & f, int & w, int & ascent, int & descent) { QFontMetrics const & m = fontloader.metrics(f); static int const d = 2; - w = width(str, f) + d * 2 + 2; + w = font_metrics::width(str, f) + d * 2 + 2; ascent = m.ascent() + d; descent = m.descent() + d; } - -void buttonText(string const & str, LyXFont const & f, +void font_metrics::buttonText(docstring const & str, LyXFont const & f, int & w, int & ascent, int & descent) { QFontMetrics const & m = fontloader.metrics(f); static int const d = 3; - w = width(str, f) + d * 2 + 2; + w = font_metrics::width(str, f) + d * 2 + 2; ascent = m.ascent() + d; descent = m.descent() + d; } -} // namespace font_metrics + +int font_metrics::signedWidth(docstring const & s, LyXFont const & f) +{ + if (s[0] == '-') + return -font_metrics::width(s.substr(1, s.length() - 1), f); + else + return font_metrics::width(s, f); +} diff --git a/src/frontends/qt4/GuiWorkArea.C b/src/frontends/qt4/GuiWorkArea.C index e6fe19a530..926477e381 100644 --- a/src/frontends/qt4/GuiWorkArea.C +++ b/src/frontends/qt4/GuiWorkArea.C @@ -339,7 +339,7 @@ void GuiWorkArea::wheelEvent(QWheelEvent * e) void GuiWorkArea::generateSyntheticMouseEvent() { - // Set things off to generate the _next_ 'pseudo' event. +// Set things off to generate the _next_ 'pseudo' event. if (synthetic_mouse_event_.restart_timeout) synthetic_mouse_event_.timeout.start(); diff --git a/src/frontends/qt4/QLPainter.C b/src/frontends/qt4/QLPainter.C index a8d5e30aa7..8b8bebac72 100644 --- a/src/frontends/qt4/QLPainter.C +++ b/src/frontends/qt4/QLPainter.C @@ -26,11 +26,16 @@ #include "frontends/font_metrics.h" +#include "support/unicode.h" + #include #include #include #include +using lyx::char_type; +using lyx::docstring; + using std::endl; using std::string; @@ -52,7 +57,7 @@ void QLPainter::start() { qp_.reset(new QPainter(qwa_->paintDevice())); // new QPainter has default QPen: - current_color_ = LColor::black; + current_color_ = LColor::black; current_ls_ = line_solid; current_lw_ = line_thin; } @@ -177,15 +182,15 @@ void QLPainter::image(int x, int y, int w, int h, } -void QLPainter::text(int x, int y, string const & s, LyXFont const & f) +void QLPainter::text(int x, int y, docstring const & s, LyXFont const & f) { - return text(x, y, s.data(), s.length(), f); + return text(x, y, reinterpret_cast(s.data()), s.length(), f); } -void QLPainter::text(int x, int y, char c, LyXFont const & f) +void QLPainter::text(int x, int y, char_type c, LyXFont const & f) { - char s[2] = { c, '\0' }; + char_type s[2] = { c, char_type('\0') }; return text(x, y, s, 1, f); } @@ -219,22 +224,34 @@ void QLPainter::smallCapsText(int x, int y, } -void QLPainter::text(int x, int y, char const * s, size_t ls, +void QLPainter::text(int x, int y, char_type const * s, size_t ls, LyXFont const & f) { +#if 0 Encoding const * encoding = f.language()->encoding(); if (f.isSymbolFont()) encoding = encodings.symbol_encoding(); +#endif +#if 0 QString str; str.setLength(ls); for (unsigned int i = 0; i < ls; ++i) str[i] = QChar(encoding->ucs(s[i])); - +#else + //std::vector in(s, s + ls); + //std::vector ucs2 = ucs4_to_ucs2(in); + std::vector ucs2 = ucs4_to_ucs2(s, ls); + ucs2.push_back(0); + QString str = QString::fromUcs2(&ucs2[0]); +#endif + +#if 0 // HACK: QT3 refuses to show single compose characters // Still needed with Qt4? if (ls == 1 && str[0].unicode() >= 0x05b0 && str[0].unicode() <= 0x05c2) str = ' ' + str; +#endif if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) { setQPainterPen(f.realColor()); diff --git a/src/frontends/qt4/QLPainter.h b/src/frontends/qt4/QLPainter.h index 6ba5ff6b4f..291b337f34 100644 --- a/src/frontends/qt4/QLPainter.h +++ b/src/frontends/qt4/QLPainter.h @@ -104,18 +104,18 @@ public: /// draw a string at position x, y (y is the baseline) virtual void text(int x, int y, - std::string const & str, LyXFont const & f); + lyx::docstring const & str, LyXFont const & f); /** Draw a string at position x, y (y is the baseline) * This is just for fast drawing */ virtual void text(int x, int y, - char const * str, size_t l, + lyx::char_type const * str, size_t l, LyXFont const & f); /// draw a char at position x, y (y is the baseline) virtual void text(int x, int y, - char c, LyXFont const & f); + lyx::char_type c, LyXFont const & f); /// draw a pixmap from the image cache virtual void drawPixmap(int x, int y, QPixmap const & pixmap); diff --git a/src/frontends/qt4/QLyXKeySym.C b/src/frontends/qt4/QLyXKeySym.C index 9fe0f98ccf..a391e52325 100644 --- a/src/frontends/qt4/QLyXKeySym.C +++ b/src/frontends/qt4/QLyXKeySym.C @@ -26,6 +26,8 @@ #include #include "support/lstrings.h" #include "support/environment.h" +#include "support/unicode.h" + #include "encoding.h" #include "language.h" @@ -75,6 +77,7 @@ char const encode(string const & encoding, QString const & str) void initEncodings() { +#if 0 //const char * c = QTextCodec::locale(); //string s = c ? c : ""; // In this order, see support/filetools.C @@ -131,7 +134,7 @@ void initEncodings() encoding_map[""] = defaultCodec; QTextCodec::setCodecForCStrings(defaultCodec); - +#endif } @@ -195,14 +198,20 @@ string QLyXKeySym::getSymbolName() const } -char QLyXKeySym::getISOEncoded(string const & encoding) const +size_t QLyXKeySym::getUCSEncoded() const { - if (lyxerr.debugging()) - lyxerr[Debug::KEY] << "encoding is " << encoding << endl; - unsigned char const c = encode(encoding, text_); - if (lyxerr.debugging()) - lyxerr[Debug::KEY] << "ISOEncoded returning value " << int(c) << endl; - return c; + unsigned short const * ptr = text_.ucs2(); + std::vector tmp(ptr, ptr + text_.length()); + + //lyxerr << "Data is " << tmp << endl; + lyxerr << "Length is " << text_.length() << endl; + + if (text_.isEmpty()) + return 0; + + //size_t res = utf8_to_ucs4(tmp, tmp.length()); + //lyxerr << "Res is " << res << endl; + return ucs2_to_ucs4(tmp)[0]; } @@ -235,11 +244,7 @@ bool QLyXKeySym::isText() const return false; } - QChar const c(text_[0]); - if (lyxerr.debugging()) - lyxerr[Debug::KEY] << "isText for key " << key_ - << " isPrint is " << c.isPrint() << endl; - return c.isPrint(); + return true; } diff --git a/src/frontends/qt4/QLyXKeySym.h b/src/frontends/qt4/QLyXKeySym.h index c9dcb9dfd9..61339cdcab 100644 --- a/src/frontends/qt4/QLyXKeySym.h +++ b/src/frontends/qt4/QLyXKeySym.h @@ -50,11 +50,10 @@ public: virtual bool isText() const; /** - * Return the value of the keysym into the local ISO encoding. - * This converts the LyXKeySym to a 8-bit encoded character. - * This relies on user to use the right encoding. + * Return the value of the keysym into the UCS-4 encoding. + * This converts the LyXKeySym to a 32-bit encoded character. */ - virtual char getISOEncoded(std::string const & encoding) const; + virtual size_t getUCSEncoded() const; /// Return a human-readable version of a key+modifier pair. virtual std::string const print(key_modifier::state mod) const; diff --git a/src/frontends/qt4/qfont_metrics.C b/src/frontends/qt4/qfont_metrics.C index c233a8d8f0..d58122e653 100644 --- a/src/frontends/qt4/qfont_metrics.C +++ b/src/frontends/qt4/qfont_metrics.C @@ -19,13 +19,46 @@ #include "language.h" +#include "support/unicode.h" + +using lyx::char_type; +using lyx::docstring; using std::string; -namespace font_metrics { +namespace { -int maxAscent(LyXFont const & f) +int smallcapswidth(unsigned short const * s, size_t ls, LyXFont const & f) +{ + if (!lyx_gui::use_gui) + return 1; + // handle small caps ourselves ... + + LyXFont smallfont = f; + smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE); + + QFontMetrics const & qm = theApp->fontLoader().metrics(f); + QFontMetrics const & qsmallm = theApp->fontLoader().metrics(smallfont); + + int w = 0; + + for (size_t i = 0; i < ls; ++i) { + QChar const c = s[i]; + QChar const uc = c.upper(); + if (c != uc) + w += qsmallm.width(uc); + else + w += qm.width(c); + } + return w; +} + + +} // anon namespace + + +int font_metrics::maxAscent(LyXFont const & f) { if (!lyx_gui::use_gui) return 1; @@ -33,7 +66,7 @@ int maxAscent(LyXFont const & f) } -int maxDescent(LyXFont const & f) +int font_metrics::maxDescent(LyXFont const & f) { if (!lyx_gui::use_gui) return 1; @@ -43,11 +76,11 @@ int maxDescent(LyXFont const & f) } -int ascent(char c, LyXFont const & f) +int font_metrics::ascent(char_type c, LyXFont const & f) { if (!lyx_gui::use_gui) return 1; - QRect const & r = theApp->fontLoader().metrics(f).boundingRect(c); + QRect const & r = theApp->fontLoader().metrics(f).boundingRect(ucs4_to_ucs2(c)); // Qt/Win 3.2.1nc (at least) corrects the GetGlyphOutlineA|W y // value by the height: (x, -y-height, width, height). // Other versions return: (x, -y, width, height) @@ -59,11 +92,11 @@ int ascent(char c, LyXFont const & f) } -int descent(char c, LyXFont const & f) +int font_metrics::descent(char_type c, LyXFont const & f) { if (!lyx_gui::use_gui) return 1; - QRect const & r = theApp->fontLoader().metrics(f).boundingRect(c); + QRect const & r = theApp->fontLoader().metrics(f).boundingRect(ucs4_to_ucs2(c)); // Qt/Win 3.2.1nc (at least) corrects the GetGlyphOutlineA|W y // value by the height: (x, -y-height, width, height). // Other versions return: (x, -y, width, height) @@ -75,85 +108,51 @@ int descent(char c, LyXFont const & f) } -int lbearing(char c, LyXFont const & f) +int font_metrics::lbearing(char_type c, LyXFont const & f) { if (!lyx_gui::use_gui) return 1; - return theApp->fontLoader().metrics(f).leftBearing(c); + return theApp->fontLoader().metrics(f).leftBearing(ucs4_to_ucs2(c)); } -int rbearing(char c, LyXFont const & f) +int font_metrics::rbearing(char_type c, LyXFont const & f) { if (!lyx_gui::use_gui) return 1; QFontMetrics const & m = theApp->fontLoader().metrics(f); // Qt rbearing is from the right edge of the char's width(). - return m.width(c) - m.rightBearing(c); -} - - -Encoding const * fontencoding(LyXFont const & f) -{ - Encoding const * encoding = f.language()->encoding(); - if (f.isSymbolFont()) - encoding = encodings.symbol_encoding(); - return encoding; + unsigned short sc = ucs4_to_ucs2(c); + return m.width(sc) - m.rightBearing(sc); } -int smallcapswidth(char const * s, size_t ls, LyXFont const & f) -{ - if (!lyx_gui::use_gui) - return 1; - // handle small caps ourselves ... - - LyXFont smallfont = f; - smallfont.decSize().decSize().setShape(LyXFont::UP_SHAPE); - - QFontMetrics const & qm = theApp->fontLoader().metrics(f); - QFontMetrics const & qsmallm = theApp->fontLoader().metrics(smallfont); - - Encoding const * encoding = fontencoding(f); - - int w = 0; - - for (size_t i = 0; i < ls; ++i) { - QChar const c = QChar(encoding->ucs(s[i])); - QChar const uc = c.upper(); - if (c != uc) - w += qsmallm.width(uc); - else - w += qm.width(c); - } - return w; -} - - -int width(char const * s, size_t ls, LyXFont const & f) +int font_metrics::width(char_type const * s, size_t ls, LyXFont const & f) { if (!lyx_gui::use_gui) return ls; + std::vector ucs2 = ucs4_to_ucs2(s, ls); + ucs2.push_back(0); + if (f.realShape() == LyXFont::SMALLCAPS_SHAPE) - return smallcapswidth(s, ls, f); + return smallcapswidth(&ucs2[0], ls, f); - Encoding const * encoding = fontencoding(f); QLFontInfo & fi = theApp->fontLoader().fontinfo(f); if (ls == 1) - return fi.width(encoding->ucs(s[0])); + return fi.width(ucs2[0]); int w = 0; for (size_t i = 0; i < ls; ++i) - w += fi.width(encoding->ucs(s[i])); + w += fi.width(ucs2[i]); return w; } -int signedWidth(string const & s, LyXFont const & f) +int font_metrics::signedWidth(docstring const & s, LyXFont const & f) { if (s[0] == '-') return -width(s.substr(1, s.length() - 1), f); @@ -162,7 +161,7 @@ int signedWidth(string const & s, LyXFont const & f) } -void rectText(string const & str, LyXFont const & f, +void font_metrics::rectText(docstring const & str, LyXFont const & f, int & w, int & ascent, int & descent) { QFontMetrics const & m = theApp->fontLoader().metrics(f); @@ -174,7 +173,7 @@ void rectText(string const & str, LyXFont const & f, -void buttonText(string const & str, LyXFont const & f, +void font_metrics::buttonText(docstring const & str, LyXFont const & f, int & w, int & ascent, int & descent) { QFontMetrics const & m = theApp->fontLoader().metrics(f); @@ -183,5 +182,3 @@ void buttonText(string const & str, LyXFont const & f, ascent = m.ascent() + d; descent = m.descent() + d; } - -} // namespace font_metrics diff --git a/src/insets/insetbibitem.C b/src/insets/insetbibitem.C index 4e1c5979f3..c582962ed6 100644 --- a/src/insets/insetbibitem.C +++ b/src/insets/insetbibitem.C @@ -27,6 +27,7 @@ #include "support/std_ostream.h" #include "support/convert.h" +using lyx::docstring; using lyx::support::prefixIs; using std::max; @@ -143,9 +144,11 @@ string const bibitemWidest(Buffer const & buffer) for (; it != end; ++it) { if (it->bibitem()) { + string const label = it->bibitem()->getBibLabel(); + docstring const dlab(label.begin(), label.end()); + int const wx = - font_metrics::width(it->bibitem()->getBibLabel(), - font); + font_metrics::width(dlab, font); if (wx > w) { w = wx; bitem = it->bibitem(); diff --git a/src/insets/insetcaption.C b/src/insets/insetcaption.C index c91d771b05..12ab885106 100644 --- a/src/insets/insetcaption.C +++ b/src/insets/insetcaption.C @@ -34,7 +34,7 @@ #include - +using lyx::docstring; using lyx::support::bformat; using std::auto_ptr; @@ -123,7 +123,8 @@ void InsetCaption::metrics(MetricsInfo & mi, Dimension & dim) const mi.base.textwidth -= 2 * TEXT_TO_INSET_OFFSET; LCursor cur = mi.base.bv->cursor(); setLabel(cur); - labelwidth_ = font_metrics::width(label, mi.base.font); + docstring dlab(label.begin(), label.end()); + labelwidth_ = font_metrics::width(dlab, mi.base.font); dim.wid = labelwidth_; Dimension textdim; InsetText::metrics(mi, textdim); @@ -150,9 +151,9 @@ void InsetCaption::draw(PainterInfo & pi, int x, int y) const // belongs to. LCursor cur = pi.base.bv->cursor(); setLabel(cur); - - labelwidth_ = font_metrics::width(label, pi.base.font); - pi.pain.text(x, y, label, pi.base.font); + docstring dlab(label.begin(), label.end()); + labelwidth_ = font_metrics::width(dlab, pi.base.font); + pi.pain.text(x, y, dlab, pi.base.font); InsetText::draw(pi, x + labelwidth_, y); setPosCache(pi, x, y); } diff --git a/src/insets/insetcharstyle.C b/src/insets/insetcharstyle.C index beb2b21357..9d34f5f642 100644 --- a/src/insets/insetcharstyle.C +++ b/src/insets/insetcharstyle.C @@ -36,6 +36,7 @@ #include +using lyx::docstring; using std::string; using std::auto_ptr; @@ -154,7 +155,8 @@ void InsetCharStyle::metrics(MetricsInfo & mi, Dimension & dim) const string s(params_.type); if (undefined()) s = _("Undef: ") + s; - font_metrics::rectText(s, font, w, a, d); + docstring ds(s.begin(), s.end()); + font_metrics::rectText(ds, font, w, a, d); dim.wid = max(dim.wid, w); } dim.asc += TEXT_TO_INSET_OFFSET; @@ -200,9 +202,10 @@ void InsetCharStyle::draw(PainterInfo & pi, int x, int y) const string s(params_.type); if (undefined()) s = _("Undef: ") + s; - font_metrics::rectText(s, font, w, a, d); + docstring ds(s.begin(), s.end()); + font_metrics::rectText(ds, font, w, a, d); pi.pain.rectText(x + (dim_.wid - w) / 2, y + desc + a, - s, font, LColor::none, LColor::none); + ds, font, LColor::none, LColor::none); } // a visual clue when the cursor is inside the inset diff --git a/src/insets/insetcollapsable.C b/src/insets/insetcollapsable.C index 5c2b3dee16..9b632078bb 100644 --- a/src/insets/insetcollapsable.C +++ b/src/insets/insetcollapsable.C @@ -30,7 +30,7 @@ #include "frontends/Painter.h" #include "frontends/LyXView.h" - +using lyx::docstring; using lyx::graphics::PreviewLoader; using std::endl; @@ -122,7 +122,8 @@ void InsetCollapsable::read(Buffer const & buf, LyXLex & lex) Dimension InsetCollapsable::dimensionCollapsed() const { Dimension dim; - font_metrics::buttonText(label, labelfont_, dim.wid, dim.asc, dim.des); + docstring dlab(label.begin(), label.end()); + font_metrics::buttonText(dlab, labelfont_, dim.wid, dim.asc, dim.des); return dim; } @@ -174,7 +175,8 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const button_dim.y1 = top; button_dim.y2 = top + dimc.height(); - pi.pain.buttonText(xx, top + dimc.asc, label, labelfont_); + docstring dlab(label.begin(), label.end()); + pi.pain.buttonText(xx, top + dimc.asc, dlab, labelfont_); if (status() == Open) { int textx, texty; diff --git a/src/insets/insetlatexaccent.C b/src/insets/insetlatexaccent.C index f5a9fac5ec..9f9d03c92f 100644 --- a/src/insets/insetlatexaccent.C +++ b/src/insets/insetlatexaccent.C @@ -24,6 +24,8 @@ #include "support/lstrings.h" +using lyx::char_type; +using lyx::docstring; using lyx::support::contains; using lyx::support::trim; @@ -265,7 +267,8 @@ void InsetLatexAccent::metrics(MetricsInfo & mi, Dimension & dim) const } else { dim.asc = font_metrics::maxAscent(font) + 4; dim.des = font_metrics::maxDescent(font) + 4; - dim.wid = font_metrics::width(contents, font) + 4; + docstring dcon(contents.begin(), contents.end()); + dim.wid = font_metrics::width(dcon, font) + 4; } dim_ = dim; } @@ -332,7 +335,7 @@ bool InsetLatexAccent::displayISO8859_9(PainterInfo & pi, int x, int y) const void InsetLatexAccent::drawAccent(PainterInfo const & pi, int x, int y, - char accent) const + char_type accent) const { LyXFont const & font = pi.base.font; x -= font_metrics::center(accent, font); @@ -407,15 +410,18 @@ void InsetLatexAccent::draw(PainterInfo & pi, int x, int baseline) const // now the rest - draw within (x, y, x + wid, y + hg) switch (modtype) { case ACUTE: - drawAccent(pi, x2, baseline, '\xB4'); + //drawAccent(pi, x2, baseline, '\xB4'); + drawAccent(pi, x2, baseline, 0xB4); break; case GRAVE: - drawAccent(pi, x2, baseline, '\x60'); + //drawAccent(pi, x2, baseline, '\x60'); + drawAccent(pi, x2, baseline, 0x60); break; case MACRON: - drawAccent(pi, x2, baseline, '\xAF'); + //drawAccent(pi, x2, baseline, '\xAF'); + drawAccent(pi, x2, baseline, 0xAF); break; case TILDE: @@ -423,14 +429,14 @@ void InsetLatexAccent::draw(PainterInfo & pi, int x, int baseline) const break; case UNDERBAR: { - char const underbar('\x5F'); + char_type const underbar = 0x5F; //('\x5F'); pi.pain.text(x2 - font_metrics::center(underbar, font), baseline, underbar, font); break; } case CEDILLA: { - char const cedilla('\xB8'); + char_type const cedilla = 0xB8; //('\xB8'); pi.pain.text(x2 - font_metrics::center(cedilla, font), baseline, cedilla, font); break; @@ -447,7 +453,8 @@ void InsetLatexAccent::draw(PainterInfo & pi, int x, int baseline) const break; case CIRCLE: - drawAccent(pi, x2, baseline, '\xB0'); + //drawAccent(pi, x2, baseline, '\xB0'); + drawAccent(pi, x2, baseline, 0xB0); break; case TIE: @@ -550,7 +557,8 @@ void InsetLatexAccent::draw(PainterInfo & pi, int x, int baseline) const pi.pain.rectangle(x + 1, baseline - dim_.asc + 1, dim_.wid - 2, dim_.asc + dim_.des - 2, LColor::foreground); - pi.pain.text(x + 2, baseline, contents, font); + docstring dcon(contents.begin(), contents.end()); + pi.pain.text(x + 2, baseline, dcon, font); } } diff --git a/src/insets/insetlatexaccent.h b/src/insets/insetlatexaccent.h index a44359f77a..5fb848120c 100644 --- a/src/insets/insetlatexaccent.h +++ b/src/insets/insetlatexaccent.h @@ -13,6 +13,7 @@ #define INSET_LATEX_ACCENT_H #include "inset.h" +#include "support/types.h" class Dimension; @@ -125,7 +126,7 @@ private: /// Check if we know the modifier and can display it ok on screen. void checkContents(); /// - void drawAccent(PainterInfo const & pi, int x, int y, char accent) const; + void drawAccent(PainterInfo const & pi, int x, int y, lyx::char_type accent) const; /// std::string contents; /// can display as proper char diff --git a/src/insets/insetpagebreak.C b/src/insets/insetpagebreak.C index cb417630c7..ff11d0f367 100644 --- a/src/insets/insetpagebreak.C +++ b/src/insets/insetpagebreak.C @@ -21,6 +21,7 @@ #include "frontends/Painter.h" #include "frontends/font_metrics.h" +using lyx::docstring; using lyx::frontend::Painter; using std::endl; @@ -59,12 +60,13 @@ void InsetPagebreak::draw(PainterInfo & pi, int x, int y) const int w = 0; int a = 0; int d = 0; - font_metrics::rectText(label, font, w, a, d); + docstring dlab(label.begin(), label.end()); + font_metrics::rectText(dlab, font, w, a, d); int const text_start = int(x + (dim_.wid - w) / 2); int const text_end = text_start + w; - pi.pain.rectText(text_start, y + d, label, font, + pi.pain.rectText(text_start, y + d, dlab, font, LColor::none, LColor::none); pi.pain.line(x, y, text_start, y, diff --git a/src/insets/insetquotes.C b/src/insets/insetquotes.C index 7a85306c6d..4eaee5b506 100644 --- a/src/insets/insetquotes.C +++ b/src/insets/insetquotes.C @@ -30,6 +30,7 @@ #include "support/lstrings.h" +using lyx::docstring; using lyx::support::prefixIs; using std::endl; @@ -237,7 +238,8 @@ void InsetQuotes::draw(PainterInfo & pi, int x, int y) const int const t = font_metrics::width(',', pi.base.font); pi.pain.text(x + t, y, text[0], pi.base.font); } else { - pi.pain.text(x, y, text, pi.base.font); + docstring dtext(text.begin(), text.end()); + pi.pain.text(x, y, dtext, pi.base.font); } } diff --git a/src/insets/insetspace.C b/src/insets/insetspace.C index 0ca675b1bb..d97ad6602f 100644 --- a/src/insets/insetspace.C +++ b/src/insets/insetspace.C @@ -55,11 +55,11 @@ void InsetSpace::metrics(MetricsInfo & mi, Dimension & dim) const switch (kind_) { case THIN: case NEGTHIN: - dim.wid = font_metrics::width("x", font) / 3; + dim.wid = font_metrics::width(lyx::char_type('x'), font) / 3; break; case PROTECTED: case NORMAL: - dim.wid = font_metrics::width("x", font); + dim.wid = font_metrics::width(lyx::char_type('x'), font); break; case QUAD: dim.wid = 20; diff --git a/src/insets/insetspecialchar.C b/src/insets/insetspecialchar.C index c79eeb735d..eecfe288f2 100644 --- a/src/insets/insetspecialchar.C +++ b/src/insets/insetspecialchar.C @@ -23,6 +23,7 @@ #include "frontends/font_metrics.h" #include "frontends/Painter.h" +using lyx::docstring; using std::string; using std::auto_ptr; @@ -54,7 +55,8 @@ void InsetSpecialChar::metrics(MetricsInfo & mi, Dimension & dim) const case MENU_SEPARATOR: s = " x "; break; case HYPHENATION: s = "-"; break; } - dim.wid = font_metrics::width(s, font); + docstring ds(s.begin(), s.end()); + dim.wid = font_metrics::width(ds, font); if (kind_ == HYPHENATION && dim.wid > 5) dim.wid -= 2; // to make it look shorter dim_ = dim; @@ -69,33 +71,35 @@ void InsetSpecialChar::draw(PainterInfo & pi, int x, int y) const case HYPHENATION: { font.setColor(LColor::special); - pi.pain.text(x, y, '-', font); + pi.pain.text(x, y, lyx::char_type('-'), font); break; } case LIGATURE_BREAK: { font.setColor(LColor::special); - pi.pain.text(x, y, '|', font); + pi.pain.text(x, y, lyx::char_type('|'), font); break; } case END_OF_SENTENCE: { font.setColor(LColor::special); - pi.pain.text(x, y, '.', font); + pi.pain.text(x, y, lyx::char_type('.'), font); break; } case LDOTS: { font.setColor(LColor::special); - pi.pain.text(x, y, ". . .", font); + string ell = ". . . "; + docstring dell(ell.begin(), ell.end()); + pi.pain.text(x, y, dell, font); break; } case MENU_SEPARATOR: { // A triangle the width and height of an 'x' - int w = font_metrics::width('x', font); - int ox = font_metrics::width(' ', font) + x; - int h = font_metrics::ascent('x', font); + int w = font_metrics::width(lyx::char_type('x'), font); + int ox = font_metrics::width(lyx::char_type(' '), font) + x; + int h = font_metrics::ascent(lyx::char_type('x'), font); int xp[4], yp[4]; xp[0] = ox; yp[0] = y; diff --git a/src/insets/insetvspace.C b/src/insets/insetvspace.C index 31c40bf9dd..d9c9772ff0 100644 --- a/src/insets/insetvspace.C +++ b/src/insets/insetvspace.C @@ -29,6 +29,8 @@ #include +using lyx::docstring; + using std::istringstream; using std::ostream; using std::ostringstream; @@ -127,7 +129,9 @@ void InsetVSpace::metrics(MetricsInfo & mi, Dimension & dim) const int w = 0; int a = 0; int d = 0; - font_metrics::rectText(label(), font, w, a, d); + string lab = label(); + docstring dlab(lab.begin(), lab.end()); + font_metrics::rectText(dlab, font, w, a, d); height = max(height, a + d); @@ -177,11 +181,13 @@ void InsetVSpace::draw(PainterInfo & pi, int x, int y) const font.setColor(LColor::added_space); font.decSize(); font.decSize(); - font_metrics::rectText(label(), font, w, a, d); + string lab = label(); + docstring dlab(lab.begin(), lab.end()); + font_metrics::rectText(dlab, font, w, a, d); pi.pain.rectText(x + 2 * arrow_size + 5, start + (end - start) / 2 + (a - d) / 2, - label(), font, LColor::none, LColor::none); + dlab, font, LColor::none, LColor::none); // top arrow pi.pain.line(x, ty1, midx, ty2, LColor::added_space); diff --git a/src/insets/render_button.C b/src/insets/render_button.C index 9bff2efc1b..1537ecf14c 100644 --- a/src/insets/render_button.C +++ b/src/insets/render_button.C @@ -18,6 +18,8 @@ #include "frontends/font_metrics.h" #include "frontends/Painter.h" +using lyx::docstring; + using std::string; using std::auto_ptr; @@ -45,10 +47,12 @@ void RenderButton::metrics(MetricsInfo &, Dimension & dim) const LyXFont font(LyXFont::ALL_SANE); font.decSize(); + docstring dtext(text_.begin(), text_.end()); + if (editable_) - font_metrics::buttonText(text_, font, dim.wid, dim.asc, dim.des); + font_metrics::buttonText(dtext, font, dim.wid, dim.asc, dim.des); else - font_metrics::rectText(text_, font, dim.wid, dim.asc, dim.des); + font_metrics::rectText(dtext, font, dim.wid, dim.asc, dim.des); dim.wid += 4; } @@ -61,10 +65,12 @@ void RenderButton::draw(PainterInfo & pi, int x, int y) const font.setColor(LColor::command); font.decSize(); + docstring dtext(text_.begin(), text_.end()); + if (editable_) { - pi.pain.buttonText(x + 2, y, text_, font); + pi.pain.buttonText(x + 2, y, dtext, font); } else { - pi.pain.rectText(x + 2, y, text_, font, + pi.pain.rectText(x + 2, y, dtext, font, LColor::commandbg, LColor::commandframe); } } diff --git a/src/insets/render_graphic.C b/src/insets/render_graphic.C index dcd6f705cd..a7e2bcb7e4 100644 --- a/src/insets/render_graphic.C +++ b/src/insets/render_graphic.C @@ -31,6 +31,7 @@ namespace graphics = lyx::graphics; +using lyx::docstring; using lyx::support::absolutePath; using lyx::support::onlyFilename; @@ -143,16 +144,18 @@ void RenderGraphic::metrics(MetricsInfo & mi, Dimension & dim) const msgFont.setFamily(LyXFont::SANS_FAMILY); string const justname = onlyFilename(params_.filename); + docstring djust(justname.begin(), justname.end()); if (!justname.empty()) { msgFont.setSize(LyXFont::SIZE_FOOTNOTE); - font_width = font_metrics::width(justname, msgFont); + font_width = font_metrics::width(djust, msgFont); } string const msg = statusMessage(params_, loader_.status()); if (!msg.empty()) { + docstring dmsg(msg.begin(), msg.end()); msgFont.setSize(LyXFont::SIZE_TINY); font_width = std::max(font_width, - font_metrics::width(msg, msgFont)); + font_metrics::width(dmsg, msgFont)); } dim.wid = std::max(50, font_width + 15); @@ -194,18 +197,20 @@ void RenderGraphic::draw(PainterInfo & pi, int x, int y) const string const justname = onlyFilename(params_.filename); if (!justname.empty()) { + docstring djust(justname.begin(), justname.end()); msgFont.setSize(LyXFont::SIZE_FOOTNOTE); pi.pain.text(x + InsetOld::TEXT_TO_INSET_OFFSET + 6, y - font_metrics::maxAscent(msgFont) - 4, - justname, msgFont); + djust, msgFont); } // Print the message. string const msg = statusMessage(params_, loader_.status()); if (!msg.empty()) { + docstring dmsg(msg.begin(), msg.end()); msgFont.setSize(LyXFont::SIZE_TINY); pi.pain.text(x + InsetOld::TEXT_TO_INSET_OFFSET + 6, - y - 4, msg, msgFont); + y - 4, dmsg, msgFont); } } } diff --git a/src/insets/render_preview.C b/src/insets/render_preview.C index d91551ecb8..21b4d43d8f 100644 --- a/src/insets/render_preview.C +++ b/src/insets/render_preview.C @@ -32,6 +32,8 @@ #include +using lyx::docstring; + using std::string; using std::auto_ptr; @@ -128,9 +130,9 @@ void RenderPreview::metrics(MetricsInfo & mi, Dimension & dim) const LyXFont font(mi.base.font); font.setFamily(LyXFont::SANS_FAMILY); font.setSize(LyXFont::SIZE_FOOTNOTE); - dim.wid = 15 + - font_metrics::width(statusMessage(mi.base.bv, snippet_), - font); + string stat = statusMessage(mi.base.bv, snippet_); + docstring dstat(stat.begin(), stat.end()); + dim.wid = 15 + font_metrics::width(dstat, font); } dim_ = dim; @@ -162,9 +164,11 @@ void RenderPreview::draw(PainterInfo & pi, int x, int y) const font.setFamily(LyXFont::SANS_FAMILY); font.setSize(LyXFont::SIZE_FOOTNOTE); + string stat = statusMessage(pi.base.bv, snippet_); + docstring dstat(stat.begin(), stat.end()); pi.pain.text(x + offset + 6, y - font_metrics::maxAscent(font) - 4, - statusMessage(pi.base.bv, snippet_), font); + dstat, font); } } diff --git a/src/lyxfunc.C b/src/lyxfunc.C index fbce9de95a..6cc001266b 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -92,6 +92,7 @@ #include "support/systemcall.h" #include "support/convert.h" #include "support/os.h" +#include "support/unicode.h" #include #include @@ -248,7 +249,8 @@ void LyXFunc::processKeySym(LyXKeySymPtr keysym, key_modifier::state state) Encoding const * encoding = view()->cursor().getEncoding(); - encoded_last_key = keysym->getISOEncoded(encoding ? encoding->name() : ""); + //encoded_last_key = keysym->getISOEncoded(encoding ? encoding->name() : ""); + size_t encoded_last_key = keysym->getUCSEncoded(); // Do a one-deep top-level lookup for // cancel and meta-fake keys. RVDK_PATCH_5 @@ -321,7 +323,8 @@ void LyXFunc::processKeySym(LyXKeySymPtr keysym, key_modifier::state state) if (func.action == LFUN_SELF_INSERT) { if (encoded_last_key != 0) { - string const arg(1, encoded_last_key); + std::vector tmp = ucs4_to_utf8(encoded_last_key); + string const arg(tmp.begin(), tmp.end()); dispatch(FuncRequest(LFUN_SELF_INSERT, arg, FuncRequest::KEYBOARD)); lyxerr[Debug::KEY] diff --git a/src/lyxfunc.h b/src/lyxfunc.h index c018192176..7a1e63370d 100644 --- a/src/lyxfunc.h +++ b/src/lyxfunc.h @@ -18,6 +18,8 @@ #include "kbsequence.h" #include "lfuns.h" +#include "support/types.h" + #include #include @@ -75,7 +77,7 @@ private: LyXView * owner; /// the last character added to the key sequence, in ISO encoded form - char encoded_last_key; + lyx::char_type encoded_last_key; /// kb_sequence keyseq; diff --git a/src/lyxlex.C b/src/lyxlex.C index 4a84d7fcbe..3ad334d38f 100644 --- a/src/lyxlex.C +++ b/src/lyxlex.C @@ -147,6 +147,12 @@ string const LyXLex::getString() const } +lyx::docstring const LyXLex::getDocString() const +{ + return pimpl_->getDocString(); +} + + // I would prefer to give a tag number instead of an explicit token // here, but it is not possible because Buffer::readDocument uses // explicit tokens (JMarc) diff --git a/src/lyxlex.h b/src/lyxlex.h index 384a03b4ad..3dd942eea8 100644 --- a/src/lyxlex.h +++ b/src/lyxlex.h @@ -17,6 +17,8 @@ #ifndef LYXLEX_H #define LYXLEX_H +#include "support/types.h" + #include #include @@ -100,6 +102,9 @@ public: /// std::string const getString() const; + /// + lyx::docstring const getDocString() const; + /** Get a long string, ended by the tag `endtag'. This string can span several lines. The first line serves as a template for how many spaces the lines diff --git a/src/lyxlex_pimpl.C b/src/lyxlex_pimpl.C index 481c579c9b..3d66b7efd1 100644 --- a/src/lyxlex_pimpl.C +++ b/src/lyxlex_pimpl.C @@ -19,6 +19,8 @@ #include "support/filetools.h" #include "support/lyxalgo.h" #include "support/lstrings.h" +#include "support/types.h" +#include "support/unicode.h" #include @@ -69,6 +71,14 @@ string const LyXLex::Pimpl::getString() const } +lyx::docstring const LyXLex::Pimpl::getDocString() const +{ + std::vector res = utf8_to_ucs4(buff); + lyx::docstring dstr(res.begin(), res.end()); + return dstr; +} + + void LyXLex::Pimpl::printError(string const & message) const { string const tmpmsg = subst(message, "$$Token", getString()); diff --git a/src/lyxlex_pimpl.h b/src/lyxlex_pimpl.h index 1a9a06c89c..55f9e8c596 100644 --- a/src/lyxlex_pimpl.h +++ b/src/lyxlex_pimpl.h @@ -14,6 +14,8 @@ #include "lyxlex.h" +#include "support/types.h" + # include # include # include @@ -34,6 +36,8 @@ public: /// std::string const getString() const; /// + lyx::docstring const getDocString() const; + /// void printError(std::string const & message) const; /// void printTable(std::ostream & os); diff --git a/src/lyxtext.h b/src/lyxtext.h index 118d832d66..4ec3824e00 100644 --- a/src/lyxtext.h +++ b/src/lyxtext.h @@ -51,6 +51,8 @@ public: /// typedef lyx::pos_type pos_type; /// + typedef lyx::char_type char_type; + /// typedef lyx::pit_type pit_type; /// constructor @@ -275,7 +277,7 @@ public: int singleWidth(Paragraph const & par, pos_type pos) const; /// int singleWidth(Paragraph const & par, - pos_type pos, char c, LyXFont const & Font) const; + pos_type pos, char_type c, LyXFont const & Font) const; /// return the color of the canvas LColor_color backgroundColor() const; diff --git a/src/mathed/math_hullinset.C b/src/mathed/math_hullinset.C index 89fd9b8520..3a7491e433 100644 --- a/src/mathed/math_hullinset.C +++ b/src/mathed/math_hullinset.C @@ -54,6 +54,7 @@ #include +using lyx::docstring; using lyx::cap::grabAndEraseSelection; using lyx::support::bformat; using lyx::support::subst; @@ -326,7 +327,9 @@ void MathHullInset::draw(PainterInfo & pi, int x, int y) const for (row_type row = 0; row < nrows(); ++row) { int const yy = y + rowinfo_[row].offset_; FontSetChanger dummy(pi.base, "mathrm"); - pi.draw(xx, yy, nicelabel(row)); + string const nl = nicelabel(row); + docstring const dnl(nl.begin(), nl.end()); + pi.draw(xx, yy, dnl); } } setPosCache(pi, x, y); diff --git a/src/mathed/math_macro.C b/src/mathed/math_macro.C index a403edfc9c..a424d252e2 100644 --- a/src/mathed/math_macro.C +++ b/src/mathed/math_macro.C @@ -23,6 +23,8 @@ #include "LaTeXFeatures.h" #include "frontends/Painter.h" +using lyx::docstring; + using std::string; using std::max; using std::auto_ptr; @@ -89,7 +91,8 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const LyXFont font = pi.base.font; augmentFont(font, "lyxtex"); int h = y - dim_.ascent() + 2 + tmpl_.ascent(); - pi.pain.text(x + 3, h, name(), font); + docstring dn(name().begin(), name().end()); + pi.pain.text(x + 3, h, dn, font); int const w = mathed_string_width(font, name()); tmpl_.draw(pi, x + w + 12, h); h += tmpl_.descent(); @@ -99,8 +102,8 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const MathArray const & c = cell(i); h += max(c.ascent(), ldim.asc) + 5; c.draw(pi, x + ldim.wid, h); - char str[] = "#1:"; - str[1] += static_cast(i); + lyx::char_type str[] = { '#', '1', ':', '\0' }; + str[1] += static_cast(i); pi.pain.text(x + 3, h, str, font); h += max(c.descent(), ldim.des) + 5; } diff --git a/src/mathed/math_macrotemplate.C b/src/mathed/math_macrotemplate.C index c02ad4c18c..44ad9f7f26 100644 --- a/src/mathed/math_macrotemplate.C +++ b/src/mathed/math_macrotemplate.C @@ -26,6 +26,7 @@ #include "support/lstrings.h" +using lyx::docstring; using lyx::support::bformat; using std::string; @@ -111,8 +112,9 @@ void MathMacroTemplate::metrics(MetricsInfo & mi, Dimension & dim) const { cell(0).metrics(mi); cell(1).metrics(mi); + docstring dp(prefix().begin(), prefix().end()); dim.wid = cell(0).width() + cell(1).width() + 20 - + font_metrics::width(prefix(), mi.base.font); + + font_metrics::width(dp, mi.base.font); dim.asc = std::max(cell(0).ascent(), cell(1).ascent()) + 7; dim.des = std::max(cell(0).descent(), cell(1).descent()) + 7; dim_ = dim; @@ -148,9 +150,9 @@ void MathMacroTemplate::draw(PainterInfo & p, int x, int y) const if (cur.isInside(this)) cur.drawSelection(pi); #endif - - pi.pain.text(x + 2, y, prefix(), font); - x += font_metrics::width(prefix(), pi.base.font) + 6; + docstring dp(prefix().begin(), prefix().end()); + pi.pain.text(x + 2, y, dp, font); + x += font_metrics::width(dp, pi.base.font) + 6; int const w0 = cell(0).width(); int const w1 = cell(1).width(); diff --git a/src/mathed/math_numberinset.C b/src/mathed/math_numberinset.C index acf4302c25..0b4a64d89e 100644 --- a/src/mathed/math_numberinset.C +++ b/src/mathed/math_numberinset.C @@ -15,6 +15,8 @@ #include "math_streamstr.h" #include "math_support.h" +using lyx::docstring; + using std::string; using std::auto_ptr; @@ -38,7 +40,8 @@ void MathNumberInset::metrics(MetricsInfo & mi, Dimension & dim) const void MathNumberInset::draw(PainterInfo & pi, int x, int y) const { - pi.draw(x, y, str_); + docstring const dstr(str_.begin(), str_.end()); + pi.draw(x, y, dstr); } diff --git a/src/mathed/math_scriptinset.C b/src/mathed/math_scriptinset.C index 252540ea42..39fef44309 100644 --- a/src/mathed/math_scriptinset.C +++ b/src/mathed/math_scriptinset.C @@ -22,6 +22,8 @@ #include +using lyx::char_type; + using std::string; using std::max; using std::auto_ptr; @@ -245,7 +247,7 @@ void MathScriptInset::draw(PainterInfo & pi, int x, int y) const else { nuc().setXY(x + dxx(), y); if (editing(pi.base.bv)) - pi.draw(x + dxx(), y, "."); + pi.draw(x + dxx(), y, char_type('.')); } ScriptChanger dummy(pi.base); if (hasUp()) diff --git a/src/mathed/math_stringinset.C b/src/mathed/math_stringinset.C index 8b157df513..79373f18ce 100644 --- a/src/mathed/math_stringinset.C +++ b/src/mathed/math_stringinset.C @@ -15,6 +15,7 @@ #include "math_streamstr.h" #include "math_support.h" +using lyx::docstring; using std::string; using std::auto_ptr; @@ -40,7 +41,8 @@ void MathStringInset::metrics(MetricsInfo & mi, Dimension & dim) const void MathStringInset::draw(PainterInfo & pi, int x, int y) const { //lyxerr << "drawing '" << str_ << "' code: " << code_ << endl; - pi.draw(x, y, str_); + docstring dstr(str_.begin(), str_.end()); + pi.draw(x, y, dstr); } diff --git a/src/mathed/math_support.C b/src/mathed/math_support.C index 7832135bc7..c4d02a7986 100644 --- a/src/mathed/math_support.C +++ b/src/mathed/math_support.C @@ -27,6 +27,7 @@ #include #include +using lyx::docstring; using lyx::frontend::Painter; using std::string; @@ -403,13 +404,15 @@ void mathed_string_dim(LyXFont const & font, string const & s, Dimension & dim) dim.asc = font_metrics::maxAscent(font); dim.des = font_metrics::maxDescent(font); #endif - dim.wid = font_metrics::width(s, font); + docstring ds(s.begin(), s.end()); + dim.wid = font_metrics::width(ds, font); } int mathed_string_width(LyXFont const & font, string const & s) { - return font_metrics::width(s, font); + docstring ds(s.begin(), s.end()); + return font_metrics::width(ds, font); } @@ -487,7 +490,8 @@ void drawStrRed(PainterInfo & pi, int x, int y, string const & str) { LyXFont f = pi.base.font; f.setColor(LColor::latex); - pi.pain.text(x, y, str, f); + docstring dstr(str.begin(), str.end()); + pi.pain.text(x, y, dstr, f); } @@ -495,7 +499,8 @@ void drawStrBlack(PainterInfo & pi, int x, int y, string const & str) { LyXFont f = pi.base.font; f.setColor(LColor::foreground); - pi.pain.text(x, y, str, f); + docstring dstr(str.begin(), str.end()); + pi.pain.text(x, y, dstr, f); } diff --git a/src/mathed/math_symbolinset.C b/src/mathed/math_symbolinset.C index 2c5dd8ec32..4159d2da30 100644 --- a/src/mathed/math_symbolinset.C +++ b/src/mathed/math_symbolinset.C @@ -20,6 +20,7 @@ #include "LaTeXFeatures.h" #include "debug.h" +using lyx::docstring; using std::string; using std::auto_ptr; @@ -109,7 +110,9 @@ void MathSymbolInset::draw(PainterInfo & pi, int x, int y) const x += static_cast(0.0833*em+0.5); FontSetChanger dummy(pi.base, sym_->inset.c_str()); - pi.draw(x, y - h_, sym_->draw); + string const sym = sym_->draw; + docstring const dsym(sym.begin(), sym.end()); + pi.draw(x, y - h_, dsym); } diff --git a/src/metricsinfo.C b/src/metricsinfo.C index 63d6f2eae3..bb14576342 100644 --- a/src/metricsinfo.C +++ b/src/metricsinfo.C @@ -20,6 +20,9 @@ #include +using lyx::char_type; +using lyx::docstring; + using std::string; @@ -53,13 +56,13 @@ PainterInfo::PainterInfo(BufferView * bv, lyx::frontend::Painter & painter) } -void PainterInfo::draw(int x, int y, char c) +void PainterInfo::draw(int x, int y, char_type c) { pain.text(x, y, c, base.font); } -void PainterInfo::draw(int x, int y, std::string const & str) +void PainterInfo::draw(int x, int y, docstring const & str) { pain.text(x, y, str, base.font); } diff --git a/src/metricsinfo.h b/src/metricsinfo.h index b2366783f6..d55c3f4e4e 100644 --- a/src/metricsinfo.h +++ b/src/metricsinfo.h @@ -87,9 +87,9 @@ public: /// PainterInfo(BufferView * bv, lyx::frontend::Painter & pain); /// - void draw(int x, int y, char c); + void draw(int x, int y, lyx::char_type c); /// - void draw(int x, int y, std::string const & str); + void draw(int x, int y, lyx::docstring const & str); /// MetricsBase base; diff --git a/src/paragraph.C b/src/paragraph.C index 20e7817237..bc2b6ad538 100644 --- a/src/paragraph.C +++ b/src/paragraph.C @@ -44,6 +44,7 @@ #include "support/lstrings.h" #include "support/textutils.h" #include "support/convert.h" +#include "support/unicode.h" #include #include @@ -54,6 +55,7 @@ #include using lyx::pos_type; +using lyx::char_type; using lyx::support::subst; @@ -212,9 +214,11 @@ void Paragraph::write(Buffer const & buf, ostream & os, } // this check is to amend a bug. LyX sometimes // inserts '\0' this could cause problems. - if (c != '\0') - os << c; - else + if (c != '\0') { + std::vector tmp = ucs4_to_utf8(c); + tmp.push_back('\0'); + os << &tmp[0]; + } else lyxerr << "ERROR (Paragraph::writeFile):" " NULL char in structure." << endl; ++column; @@ -1801,7 +1805,7 @@ size_t Paragraph::pos2row(pos_type pos) const } -unsigned char Paragraph::transformChar(unsigned char c, pos_type pos) const +char_type Paragraph::transformChar(char_type c, pos_type pos) const { if (!Encodings::is_arabic(c)) if (lyxrc.font_norm_type == LyXRC::ISO_8859_6_8 && isDigit(c)) diff --git a/src/paragraph.h b/src/paragraph.h index 98e909257b..bab6fb3ce6 100644 --- a/src/paragraph.h +++ b/src/paragraph.h @@ -69,8 +69,8 @@ public: /// (returning 0) - if this was 0, then we'd /// try getInset() and crash. We should fix /// all these places. - META_INSET = 1 - //META_INSET = 0x200001 // above 0x10ffff, for ucs-4 + //META_INSET = 1 // as in trunk + META_INSET = 0x200001 // above 0x10ffff, for ucs-4 }; enum ChangeTracking { @@ -376,7 +376,7 @@ public: /// return true if we allow this par to stay empty bool allowEmpty() const; /// - unsigned char transformChar(unsigned char c, lyx::pos_type pos) const; + lyx::char_type transformChar(lyx::char_type c, lyx::pos_type pos) const; /// ParagraphParameters & params(); /// diff --git a/src/rowpainter.C b/src/rowpainter.C index 46aa7beb86..45bae7438c 100644 --- a/src/rowpainter.C +++ b/src/rowpainter.C @@ -44,6 +44,7 @@ #include +using lyx::docstring; using lyx::frontend::Painter; using lyx::frontend::NullPainter; using lyx::char_type; @@ -218,7 +219,8 @@ void RowPainter::paintHebrewComposeChar(pos_type & vpos, LyXFont const & font) } // Draw nikud - pain_.text(int(x_) + dx, yo_, str, font); + docstring dstr(str.begin(), str.end()); + pain_.text(int(x_) + dx, yo_, dstr, font); } @@ -248,7 +250,8 @@ void RowPainter::paintArabicComposeChar(pos_type & vpos, LyXFont const & font) } } // Draw nikud - pain_.text(int(x_) + dx, yo_, str, font); + docstring dstr(str.begin(), str.end()); + pain_.text(int(x_) + dx, yo_, dstr, font); } @@ -261,10 +264,15 @@ void RowPainter::paintChars(pos_type & vpos, LyXFont font, Change::Type const prev_change = par_.lookupChange(pos).type; // first character +#if 0 string str; str += par_.getChar(pos); +#else + std::vector str; + str.push_back(par_.getChar(pos)); +#endif if (arabic) { - unsigned char c = str[0]; + char_type c = str[0]; str[0] = par_.transformChar(c, pos); } @@ -291,7 +299,11 @@ void RowPainter::paintChars(pos_type & vpos, LyXFont font, if (arabic) c = par_.transformChar(c, pos); +#if 0 str += c; +#else + str.push_back(c); +#endif } if (prev_change == Change::DELETED) @@ -301,8 +313,13 @@ void RowPainter::paintChars(pos_type & vpos, LyXFont font, // Draw text and set the new x position //lyxerr << "paint row: yo_ " << yo_ << "\n"; +#if 0 pain_.text(int(x_), yo_, str, font); x_ += font_metrics::width(str, font); +#else + pain_.text(int(x_), yo_, &str[0], str.size(), font); + x_ += font_metrics::width(&str[0], str.size(), font); +#endif } @@ -444,12 +461,13 @@ int RowPainter::paintAppendixStart(int y) int w = 0; int a = 0; int d = 0; - font_metrics::rectText(label, pb_font, w, a, d); + docstring dlab(label.begin(), label.end()); + font_metrics::rectText(dlab, pb_font, w, a, d); int const text_start = int(xo_ + (width_ - w) / 2); int const text_end = text_start + w; - pain_.rectText(text_start, y + d, label, pb_font, LColor::none, LColor::none); + pain_.rectText(text_start, y + d, dlab, pb_font, LColor::none, LColor::none); pain_.line(int(xo_ + 1), y, text_start, y, LColor::appendix); pain_.line(text_end, y, int(xo_ + width_ - 2), y, LColor::appendix); @@ -502,6 +520,7 @@ void RowPainter::paintFirst() string const str = par_.getLabelstring(); if (!str.empty()) { double x = x_; + docstring dstr(str.begin(), str.end()); // this is special code for the chapter layout. This is // printed in an extra row and has a pagebreak at @@ -521,20 +540,22 @@ void RowPainter::paintFirst() if (is_rtl) { x = width_ - leftMargin() - - font_metrics::width(str, font); + font_metrics::width(dstr, font); } - pain_.text(int(x), yo_ - maxdesc - labeladdon, str, font); + pain_.text(int(x), yo_ - maxdesc - labeladdon, dstr, font); } else { + string lab = layout->labelsep; + docstring dlab(lab.begin(), lab.end()); if (is_rtl) { x = width_ - leftMargin() - + font_metrics::width(layout->labelsep, font); + + font_metrics::width(dlab, font); } else { - x = x_ - font_metrics::width(layout->labelsep, font) - - font_metrics::width(str, font); + x = x_ - font_metrics::width(dlab, font) + - font_metrics::width(dstr, font); } - pain_.text(int(x), yo_, str, font); + pain_.text(int(x), yo_, dstr, font); } } @@ -547,6 +568,7 @@ void RowPainter::paintFirst() LyXFont font = getLabelFont(); if (!par_.getLabelstring().empty()) { string const str = par_.getLabelstring(); + docstring dstr(str.begin(), str.end()); double spacing_val = 1.0; if (!parparams.spacing().isDefault()) spacing_val = parparams.spacing().getValue(); @@ -564,12 +586,12 @@ void RowPainter::paintFirst() if (is_rtl) x = leftMargin(); x += (width_ - text_.rightMargin(par_) - leftMargin()) / 2; - x -= font_metrics::width(str, font) / 2; + x -= font_metrics::width(dstr, font) / 2; } else if (is_rtl) { x = width_ - leftMargin() - - font_metrics::width(str, font); + font_metrics::width(dstr, font); } - pain_.text(int(x), yo_ - maxdesc - labeladdon, str, font); + pain_.text(int(x), yo_ - maxdesc - labeladdon, dstr, font); } } } @@ -602,10 +624,11 @@ void RowPainter::paintLast() case END_LABEL_STATIC: { LyXFont font = getLabelFont(); string const & str = par_.layout()->endlabelstring(); + docstring dstr(str.begin(), str.end()); double const x = is_rtl ? - x_ - font_metrics::width(str, font) + x_ - font_metrics::width(dstr, font) : - text_.rightMargin(par_) - row_.width(); - pain_.text(int(x), yo_, str, font); + pain_.text(int(x), yo_, dstr, font); break; } @@ -683,7 +706,9 @@ void RowPainter::paintText() } if (body_pos > 0 && pos == body_pos - 1) { - int const lwidth = font_metrics::width(layout->labelsep, + string lab = layout->labelsep; + docstring dlab(lab.begin(), lab.end()); + int const lwidth = font_metrics::width(dlab, getLabelFont()); x_ += label_hfill_ + lwidth - width_pos; diff --git a/src/support/Makefile.am b/src/support/Makefile.am index da297d11bf..6ef5eec4d0 100644 --- a/src/support/Makefile.am +++ b/src/support/Makefile.am @@ -74,6 +74,8 @@ libsupport_la_SOURCES = \ types.h \ userinfo.C \ userinfo.h \ + unicode.C \ + unicode.h \ unlink.C diff --git a/src/support/docstring.h b/src/support/docstring.h new file mode 100644 index 0000000000..9f54f0eaaa --- /dev/null +++ b/src/support/docstring.h @@ -0,0 +1,28 @@ +// -*- C++ -*- +/** + * \file docstring.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * Provide a set of typedefs for commonly used things like sizes and + * indices wile trying to stay compatible with types used + * by the standard containers. + * + * \author André Pönitz + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef LYX_DOCSTRING_H +#define LYX_DOCSTRING_H + +#include +#include + +namespace lyx { + +typedef std::basic_string docstring; + +} + +#endif diff --git a/src/support/lstrings.h b/src/support/lstrings.h index 2b03e42b78..c873d47268 100644 --- a/src/support/lstrings.h +++ b/src/support/lstrings.h @@ -16,6 +16,8 @@ #ifndef LSTRINGS_H #define LSTRINGS_H +#include "support/types.h" + #include #include diff --git a/src/support/types.h b/src/support/types.h index 48fc219e8f..65928821c3 100644 --- a/src/support/types.h +++ b/src/support/types.h @@ -16,15 +16,21 @@ #ifndef LYX_TYPES_H #define LYX_TYPES_H +#include "docstring.h" + +#include + #include +#include namespace lyx { // The type used to hold characters in paragraphs - //typedef uint32_t char_type; // Possibly the ucs-4 type we will use + typedef boost::uint32_t char_type; // Possibly the ucs-4 type we will use //typedef wchar_t char_type; // The wide char type CJK-LyX uses - typedef char char_type; // Current narrow char type in use + //typedef char char_type; // Current narrow char type in use + //typedef std::wstring docstring; /// a type for positions used in paragraphs // needs to be signed for a while to hold the special value -1 that is diff --git a/src/support/unicode.C b/src/support/unicode.C new file mode 100644 index 0000000000..d32c204b20 --- /dev/null +++ b/src/support/unicode.C @@ -0,0 +1,285 @@ +/** + * \file unicode.C + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Lars Gullik Bjønnes + * + * Full author contact details are available in file CREDITS. + * + * A collection of unicode conversion functions, using iconv. + */ + +#include + +#include "unicode.h" + +#include "debug.h" + +#include +#include +#include + +using std::endl; +using std::string; + +namespace { + +std::vector +iconv_convert(std::string const & tocode, std::string const & fromcode, + std::vector const & buf) +{ + iconv_t cd = iconv_open(tocode.c_str(), fromcode.c_str()); + if (cd == (iconv_t)(-1)) { + lyxerr << "Error returned from iconv_open" << endl; + switch (errno) { + case EINVAL: + lyxerr << "EINVAL The conversion from " << fromcode + << " to " << tocode + << " is not supported by the implementation." + << endl; + break; + default: + lyxerr << "\tSome other error: " << errno << endl; + break; + } + } + + char * inbuf = const_cast(&buf[0]); + size_t inbytesleft = buf.size(); + char out[1000] = { 0 }; + char * outbuf = out; + size_t outbytesleft = 1000; + + size_t res = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); + + if (res == (size_t)(-1)) { + lyxerr << "Error returned from iconv" << endl; + switch (errno) { + case E2BIG: + lyxerr << "E2BIG There is not sufficient room at *outbuf." << endl; + break; + case EILSEQ: + lyxerr << "EILSEQ An invalid multibyte sequence" + << " has been encountered in the input.\n" + << "When converting from " << fromcode + << " to " << tocode << ".\n"; + lyxerr << "Input: " << std::hex; + for (size_t i = 0; i < buf.size(); ++i) { + unsigned char const b = buf[i]; + lyxerr << "0x" << int(b) << " "; + } + lyxerr << endl; + break; + case EINVAL: + lyxerr << "EINVAL An incomplete multibyte sequence" + << " has been encountered in the input.\n" + << "When converting from " << fromcode + << " to " << tocode << ".\n"; + lyxerr << "Input: " << std::hex; + for (size_t i = 0; i < buf.size(); ++i) { + unsigned char const b = buf[i]; + lyxerr << "0x" << int(b) << " "; + } + lyxerr << endl; + break; + default: + lyxerr << "\tSome other error: " << errno << endl; + break; + } + } + + if (iconv_close(cd) == -1) { + lyxerr << "Error returned from iconv_close(" + << errno << ")" << endl; + } + + //lyxerr << std::dec; + //lyxerr << "Inbytesleft: " << inbytesleft << endl; + //lyxerr << "Outbytesleft: " << outbytesleft << endl; + int bytes = 1000 - outbytesleft; + + std::vector outvec(out, out + bytes); + return outvec; +} + + +std::vector bytes_to_ucs4(std::vector const & bytes) +{ + //lyxerr << "Outbuf =" << std::hex; + + std::vector ucs4; + for (size_t i = 0; i < bytes.size(); i += 4) { + unsigned char const b1 = bytes[i ]; + unsigned char const b2 = bytes[i + 1]; + unsigned char const b3 = bytes[i + 2]; + unsigned char const b4 = bytes[i + 3]; + + boost::uint32_t c; + char * cc = reinterpret_cast(&c); + cc[3] = b1; + cc[2] = b2; + cc[1] = b3; + cc[0] = b4; + + if (c > 0xffff) { + lyxerr << "Strange ucs4 value encountered\n"; + lyxerr << "0x" + << std::setw(2) << std::setfill('0') << int(b1) + << std::setw(2) << std::setfill('0') << int(b2) + << std::setw(2) << std::setfill('0') << int(b3) + << std::setw(2) << std::setfill('0') << int(b4) + << ' ' + << "(0x" + << c + << ") "; + } + + ucs4.push_back(c); + } + //lyxerr << endl; + return ucs4; +} + + +std::vector bytes_to_ucs2(std::vector const & bytes) +{ + //lyxerr << "Outbuf =" << std::hex; + + std::vector ucs2; + for (size_t i = 0; i < bytes.size(); i += 2) { + unsigned char const b1 = bytes[i ]; + unsigned char const b2 = bytes[i + 1]; + + unsigned short c; + char * cc = reinterpret_cast(&c); + cc[0] = b1; + cc[1] = b2; + + //lyxerr << "0x" + // << std::setw(2) << std::setfill('0') << int(b2) + // << std::setw(2) << std::setfill('0') << int(b1) + // << ' ' + // << "(0x" + // << c + // << ") "; + + ucs2.push_back(c); + } + //lyxerr << endl; + return ucs2; +} + +} // anon namespace + + +std::vector utf8_to_ucs4(std::vector const & utf8str) +{ + //lyxerr << "Buff = " << string(utf8str.begin(), utf8str.end()) + // << " (" << utf8str.size() << ")" << endl; + //lyxerr << "Res = " << string(res.begin(), res.end()) + // << " (" << res.size() << ")" << endl; + + std::vector res = iconv_convert("UCS-4", "UTF-8", utf8str); + return bytes_to_ucs4(res); +} + + +std::vector +ucs2_to_ucs4(std::vector const & ucs2str) +{ + // TODO: Simplify and speed up. + std::vector in; + std::vector::const_iterator cit = ucs2str.begin(); + std::vector::const_iterator end = ucs2str.end(); + //lyxerr << std::hex; + for (; cit != end; ++cit) { + unsigned short s = *cit; + in.push_back(static_cast(s & 0x00ff)); + in.push_back(static_cast((s & 0xff00) >> 8)); + lyxerr << std::setw(2) << std::setfill('0') << (s & 0x00ff) << endl; + lyxerr << std::setw(2) << std::setfill('0') << ((s & 0xff00) >> 8) << endl; + } + + std::vector res = iconv_convert("UCS-4", "UCS-2", in); + return bytes_to_ucs4(res); +} + + +std::vector +ucs4_to_ucs2(std::vector const & ucs4str) +{ + std::vector in; + std::vector::const_iterator cit = ucs4str.begin(); + std::vector::const_iterator end = ucs4str.end(); + for (; cit != end; ++cit) { + boost::uint32_t s = *cit; + in.push_back(static_cast((s & 0xff000000) >> 24)); + in.push_back(static_cast((s & 0x00ff0000) >> 16)); + in.push_back(static_cast((s & 0x0000ff00) >> 8)); + in.push_back(static_cast(s & 0x000000ff)); + } + std::vector res = iconv_convert("UCS-2", "UCS-4", in); + return bytes_to_ucs2(res); +} + + +std::vector +ucs4_to_ucs2(boost::uint32_t const * s, size_t ls) +{ + std::vector in; + for (size_t i = 0; i < ls; ++i) { + in.push_back(static_cast((s[i] & 0xff000000) >> 24)); + in.push_back(static_cast((s[i] & 0x00ff0000) >> 16)); + in.push_back(static_cast((s[i] & 0x0000ff00) >> 8)); + in.push_back(static_cast(s[i] & 0x000000ff)); + } + std::vector res = iconv_convert("UCS-2", "UCS-4", in); + return bytes_to_ucs2(res); +} + + +unsigned short +ucs4_to_ucs2(boost::uint32_t c) +{ + std::vector in; + in.push_back(static_cast((c & 0xff000000) >> 24)); + in.push_back(static_cast((c & 0x00ff0000) >> 16)); + in.push_back(static_cast((c & 0x0000ff00) >> 8)); + in.push_back(static_cast(c & 0x000000ff)); + std::vector res = iconv_convert("UCS-2", "UCS-4", in); + std::vector us = bytes_to_ucs2(res); + if (!us.empty()) + return us[0]; + else + return 0xfffd; // unknown character +} + + +std::vector ucs4_to_utf8(std::vector const & ucs4str) +{ + std::vector in; + std::vector::const_iterator cit = ucs4str.begin(); + std::vector::const_iterator end = ucs4str.end(); + for (; cit != end; ++cit) { + boost::uint32_t s = *cit; + in.push_back(static_cast((s & 0xff000000) >> 24)); + in.push_back(static_cast((s & 0x00ff0000) >> 16)); + in.push_back(static_cast((s & 0x0000ff00) >> 8)); + in.push_back(static_cast(s & 0x000000ff)); + } + std::vector res = iconv_convert("UTF-8", "UCS-4", in); + return res; +} + + +std::vector ucs4_to_utf8(boost::uint32_t c) +{ + std::vector in; + in.push_back(static_cast((c & 0xff000000) >> 24)); + in.push_back(static_cast((c & 0x00ff0000) >> 16)); + in.push_back(static_cast((c & 0x0000ff00) >> 8)); + in.push_back(static_cast(c & 0x000000ff)); + std::vector res = iconv_convert("UTF-8", "UCS-4", in); + return res; +} diff --git a/src/support/unicode.h b/src/support/unicode.h new file mode 100644 index 0000000000..21ff21afb5 --- /dev/null +++ b/src/support/unicode.h @@ -0,0 +1,40 @@ +/** + * \file unicode.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Lars Gullik Bjønnes + * + * Full author contact details are available in file CREDITS. + * + * A collection of unicode conversion functions, using iconv. + */ + +#ifndef LYX_SUPPORT_UNICODE_H +#define LYX_SUPPORT_UNICODE_H + +#include +#include + +std::vector +utf8_to_ucs4(std::vector const & utf8str); + +std::vector +ucs2_to_ucs4(std::vector const & ucs2str); + +std::vector +ucs4_to_ucs2(std::vector const & ucs4str); + +std::vector +ucs4_to_ucs2(boost::uint32_t const * s, size_t ls); + +unsigned short +ucs4_to_ucs2(boost::uint32_t c); + +std::vector +ucs4_to_utf8(std::vector const & ucs4str); + +std::vector +ucs4_to_utf8(boost::uint32_t c); + +#endif diff --git a/src/text.C b/src/text.C index a29c214577..0493c1416c 100644 --- a/src/text.C +++ b/src/text.C @@ -75,6 +75,7 @@ #include +using lyx::docstring; using lyx::char_type; using lyx::pit_type; using lyx::pos_type; @@ -161,9 +162,17 @@ void readParToken(Buffer const & buf, Paragraph & par, LyXLex & lex, BufferParams const & bp = buf.params(); if (token[0] != '\\') { +#if 0 string::const_iterator cit = token.begin(); for (; cit != token.end(); ++cit) par.insertChar(par.size(), (*cit), font, change); +#else + lyx::docstring dstr = lex.getDocString(); + lyx::docstring::const_iterator cit = dstr.begin(); + lyx::docstring::const_iterator cend = dstr.end(); + for (; cit != cend; ++cit) + par.insertChar(par.size(), *cit, font, change); +#endif } else if (token == "\\begin_layout") { lex.eatLine(); string layoutname = lex.getString(); @@ -492,7 +501,9 @@ int LyXText::leftMargin(pit_type const pit, pos_type const pos) const if (isMainText()) l_margin += changebarMargin(); - l_margin += font_metrics::signedWidth(tclass.leftmargin(), params.getFont()); + string leftm = tclass.leftmargin(); + docstring dleft(leftm.begin(), leftm.end()); + l_margin += font_metrics::signedWidth(dleft, params.getFont()); if (par.getDepth() != 0) { // find the next level paragraph @@ -520,42 +531,65 @@ int LyXText::leftMargin(pit_type const pit, pos_type const pos) const LyXFont const labelfont = getLabelFont(par); switch (layout->margintype) { case MARGIN_DYNAMIC: - if (!layout->leftmargin.empty()) - l_margin += font_metrics::signedWidth(layout->leftmargin, - params.getFont()); - if (!par.getLabelstring().empty()) { - l_margin += font_metrics::signedWidth(layout->labelindent, + if (!layout->leftmargin.empty()) { + string leftm = layout->leftmargin; + docstring dleft(leftm.begin(), leftm.end()); + l_margin += font_metrics::signedWidth(dleft, + params.getFont()); + } + if (!par.getLabelstring().empty()) { + string labin = layout->labelindent; + docstring dlabin(labin.begin(), labin.end()); + l_margin += font_metrics::signedWidth(dlabin, labelfont); - l_margin += font_metrics::width(par.getLabelstring(), + string labstr = par.getLabelstring(); + docstring dlabstr(labstr.begin(), labstr.end()); + l_margin += font_metrics::width(dlabstr, labelfont); - l_margin += font_metrics::width(layout->labelsep, labelfont); + string labsep = layout->labelsep; + docstring dlabsep(labsep.begin(), labsep.end()); + l_margin += font_metrics::width(dlabsep, labelfont); } break; - case MARGIN_MANUAL: - l_margin += font_metrics::signedWidth(layout->labelindent, labelfont); + case MARGIN_MANUAL: { + string labin = layout->labelindent; + docstring dlabin(labin.begin(), labin.end()); + l_margin += font_metrics::signedWidth(dlabin, labelfont); // The width of an empty par, even with manual label, should be 0 if (!par.empty() && pos >= par.beginOfBody()) { if (!par.getLabelWidthString().empty()) { - l_margin += font_metrics::width(par.getLabelWidthString(), + string labstr = par.getLabelWidthString(); + docstring dlabstr(labstr.begin(), labstr.end()); + l_margin += font_metrics::width(dlabstr, labelfont); - l_margin += font_metrics::width(layout->labelsep, labelfont); + string labsep = layout->labelsep; + docstring dlabsep(labsep.begin(), labsep.end()); + l_margin += font_metrics::width(dlabsep, labelfont); } } break; - - case MARGIN_STATIC: - l_margin += font_metrics::signedWidth(layout->leftmargin, params.getFont()) * 4 + } + + case MARGIN_STATIC: { + string leftm = layout->leftmargin; + docstring dleft(leftm.begin(), leftm.end()); + l_margin += font_metrics::signedWidth(dleft, params.getFont()) * 4 / (par.getDepth() + 4); break; + } case MARGIN_FIRST_DYNAMIC: if (layout->labeltype == LABEL_MANUAL) { if (pos >= par.beginOfBody()) { - l_margin += font_metrics::signedWidth(layout->leftmargin, + string leftm = layout->leftmargin; + docstring dleft(leftm.begin(), leftm.end()); + l_margin += font_metrics::signedWidth(dleft, labelfont); } else { - l_margin += font_metrics::signedWidth(layout->labelindent, + string labin = layout->labelindent; + docstring dlabin(labin.begin(), labin.end()); + l_margin += font_metrics::signedWidth(dlabin, labelfont); } } else if (pos != 0 @@ -564,17 +598,24 @@ int LyXText::leftMargin(pit_type const pit, pos_type const pos) const || (layout->labeltype == LABEL_STATIC && layout->latextype == LATEX_ENVIRONMENT && !isFirstInSequence(pit, pars_))) { - l_margin += font_metrics::signedWidth(layout->leftmargin, + string leftm = layout->leftmargin; + docstring dleft(leftm.begin(), leftm.end()); + l_margin += font_metrics::signedWidth(dleft, labelfont); } else if (layout->labeltype != LABEL_TOP_ENVIRONMENT && layout->labeltype != LABEL_BIBLIO && layout->labeltype != LABEL_CENTERED_TOP_ENVIRONMENT) { - l_margin += font_metrics::signedWidth(layout->labelindent, + string labin = layout->labelindent; + docstring dlabin(labin.begin(), labin.end()); + l_margin += font_metrics::signedWidth(dlabin, labelfont); - l_margin += font_metrics::width(layout->labelsep, labelfont); - l_margin += font_metrics::width(par.getLabelstring(), - labelfont); + string labsep = layout->labelsep; + docstring dlabsep(labsep.begin(), labsep.end()); + l_margin += font_metrics::width(dlabsep, labelfont); + string labstr = par.getLabelstring(); + docstring dlabstr(labstr.begin(), labstr.end()); + l_margin += font_metrics::width(dlabstr, labelfont); } break; @@ -631,7 +672,8 @@ int LyXText::leftMargin(pit_type const pit, pos_type const pos) const || bv()->buffer()->params().paragraph_separation == BufferParams::PARSEP_INDENT)) { - l_margin += font_metrics::signedWidth(parindent, params.getFont()); + docstring din(parindent.begin(), parindent.end()); + l_margin += font_metrics::signedWidth(din, params.getFont()); } return l_margin; @@ -646,11 +688,15 @@ int LyXText::rightMargin(Paragraph const & par) const BufferParams const & params = bv()->buffer()->params(); LyXTextClass const & tclass = params.getLyXTextClass(); + string trmarg = tclass.rightmargin(); + docstring dtrmarg(trmarg.begin(), trmarg.end()); + string lrmarg = par.layout()->rightmargin; + docstring dlrmarg(lrmarg.begin(), lrmarg.end()); int const r_margin = ::rightMargin() - + font_metrics::signedWidth(tclass.rightmargin(), + + font_metrics::signedWidth(dtrmarg, params.getFont()) - + font_metrics::signedWidth(par.layout()->rightmargin, + + font_metrics::signedWidth(dlrmarg, params.getFont()) * 4 / (par.getDepth() + 4); @@ -731,7 +777,9 @@ void LyXText::rowBreakPoint(pit_type const pit, Row & row) const // add the auto-hfill from label end to the body if (body_pos && i == body_pos) { - int add = font_metrics::width(layout->labelsep, getLabelFont(par)); + string lsep = layout->labelsep; + docstring dlsep(lsep.begin(), lsep.end()); + int add = font_metrics::width(dlsep, getLabelFont(par)); if (par.isLineSeparator(i - 1)) add -= singleWidth(par, i - 1); @@ -805,6 +853,7 @@ void LyXText::setRowWidth(pit_type const pit, Row & row) const Paragraph const & par = pars_[pit]; string const & labelsep = par.layout()->labelsep; + docstring dlsep(labelsep.begin(), labelsep.end()); int w = leftMargin(pit, row.pos()); pos_type const body_pos = par.beginOfBody(); @@ -814,7 +863,7 @@ void LyXText::setRowWidth(pit_type const pit, Row & row) const FontIterator fi = FontIterator(*this, par, i); for ( ; i < end; ++i, ++fi) { if (body_pos > 0 && i == body_pos) { - w += font_metrics::width(labelsep, getLabelFont(par)); + w += font_metrics::width(dlsep, getLabelFont(par)); if (par.isLineSeparator(i - 1)) w -= singleWidth(par, i - 1); w = max(w, labelEnd(pit)); @@ -825,7 +874,7 @@ void LyXText::setRowWidth(pit_type const pit, Row & row) const } if (body_pos > 0 && body_pos >= end) { - w += font_metrics::width(labelsep, getLabelFont(par)); + w += font_metrics::width(dlsep, getLabelFont(par)); if (end > 0 && par.isLineSeparator(end - 1)) w -= singleWidth(par, end - 1); w = max(w, labelEnd(pit)); @@ -857,7 +906,8 @@ int LyXText::labelFill(Paragraph const & par, Row const & row) const if (label.empty()) return 0; - return max(0, font_metrics::width(label, getLabelFont(par)) - w); + docstring dlab(label.begin(), label.end()); + return max(0, font_metrics::width(dlab, getLabelFont(par)) - w); } @@ -1332,7 +1382,9 @@ LyXText::computeRowMetrics(pit_type const pit, Row const & row) const if (body_pos > 0 && (body_pos > end || !par.isLineSeparator(body_pos - 1))) { - result.x += font_metrics::width(layout->labelsep, getLabelFont(par)); + string lsep = layout->labelsep; + docstring dlsep(lsep.begin(), lsep.end()); + result.x += font_metrics::width(dlsep, getLabelFont(par)); if (body_pos <= end) result.x += result.label_hfill; } @@ -2201,8 +2253,10 @@ int LyXText::cursorX(CursorSlice const & sl, bool boundary) const for (pos_type vpos = row_pos; vpos < cursor_vpos; ++vpos) { pos_type pos = bidi.vis2log(vpos); if (body_pos > 0 && pos == body_pos - 1) { + string lsep = par.layout()->labelsep; + docstring dlsep(lsep.begin(), lsep.end()); x += m.label_hfill - + font_metrics::width(par.layout()->labelsep, + + font_metrics::width(dlsep, getLabelFont(par)); if (par.isLineSeparator(body_pos - 1)) x -= singleWidth(par, body_pos - 1); diff --git a/src/text2.C b/src/text2.C index 68d04bd112..cc1cda40c5 100644 --- a/src/text2.C +++ b/src/text2.C @@ -57,6 +57,7 @@ #include +using lyx::docstring; using lyx::pit_type; using lyx::pos_type; @@ -797,8 +798,10 @@ pos_type LyXText::getColumnNearX(pit_type const pit, c = bidi.vis2log(vc); last_tmpx = tmpx; if (body_pos > 0 && c == body_pos - 1) { + string lsep = layout->labelsep; + docstring dlsep(lsep.begin(), lsep.end()); tmpx += r.label_hfill + - font_metrics::width(layout->labelsep, getLabelFont(par)); + font_metrics::width(dlsep, getLabelFont(par)); if (par.isLineSeparator(body_pos - 1)) tmpx -= singleWidth(par, body_pos - 1); } diff --git a/src/text3.C b/src/text3.C index 027343eb4b..28a1002480 100644 --- a/src/text3.C +++ b/src/text3.C @@ -64,6 +64,7 @@ #include "support/lyxlib.h" #include "support/convert.h" #include "support/lyxtime.h" +#include "support/unicode.h" #include "mathed/math_hullinset.h" #include "mathed/math_macrotemplate.h" @@ -73,6 +74,7 @@ #include #include +using lyx::char_type; using lyx::pos_type; using lyx::cap::copySelection; @@ -1100,11 +1102,20 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) cur.clearSelection(); LyXFont const old_font = real_current_font; +#if 0 string::const_iterator cit = cmd.argument.begin(); string::const_iterator end = cmd.argument.end(); for (; cit != end; ++cit) bv->owner()->getIntl().getTransManager(). translateAndInsert(*cit, this); +#else + std::vector in(cmd.argument.begin(), cmd.argument.end()); + std::vector const res = utf8_to_ucs4(in); + std::vector::const_iterator cit = res.begin(); + std::vector::const_iterator end = res.end(); + for (; cit != end; ++cit) + insertChar(bv->cursor(), *cit); +#endif cur.resetAnchor(); moveCursor(cur, false); -- 2.39.5