[Libreoffice-commits] .: 9 commits - comphelper/qa i18npool/source vcl/inc vcl/source vcl/unx vcl/util vcl/win

Martin Hosken mhosken at kemper.freedesktop.org
Thu Mar 10 07:44:00 PST 2011


 comphelper/qa/weakbag/test_weakbag_noadditional.cxx |    2 
 i18npool/source/breakiterator/breakiteratorImpl.cxx |   62 -
 i18npool/source/breakiterator/data/char.txt         |  118 ++
 vcl/inc/vcl/graphite_adaptors.hxx                   |  145 ---
 vcl/inc/vcl/graphite_cache.hxx                      |  290 ------
 vcl/inc/vcl/graphite_features.hxx                   |   47 
 vcl/inc/vcl/graphite_layout.hxx                     |  116 +-
 vcl/inc/vcl/graphite_serverfont.hxx                 |   25 
 vcl/source/glyphs/gcach_ftyp.cxx                    |   65 +
 vcl/source/glyphs/gcach_ftyp.hxx                    |   15 
 vcl/source/glyphs/graphite_adaptors.cxx             |  339 -------
 vcl/source/glyphs/graphite_cache.cxx                |  201 ----
 vcl/source/glyphs/graphite_features.cxx             |  231 ++--
 vcl/source/glyphs/graphite_layout.cxx               |  958 +++++++-------------
 vcl/source/glyphs/graphite_serverfont.cxx           |  100 +-
 vcl/source/glyphs/makefile.mk                       |    8 
 vcl/unx/source/gdi/pspgraphics.cxx                  |    8 
 vcl/unx/source/gdi/salgdi3.cxx                      |   11 
 vcl/util/makefile.mk                                |    7 
 vcl/win/inc/salgdi.h                                |   29 
 vcl/win/source/gdi/salgdi.cxx                       |    3 
 vcl/win/source/gdi/salgdi3.cxx                      |  201 +++-
 vcl/win/source/gdi/winlayout.cxx                    |  133 +-
 23 files changed, 1204 insertions(+), 1910 deletions(-)

New commits:
commit b5984e292401e87f68343e1bf8a565b622c3b4b7
Author: Martin Hosken <martin_hosken at sil.org>
Date:   Fri Feb 25 16:10:55 2011 +0700

    graphite2 consolidated patch

diff --git a/comphelper/qa/weakbag/test_weakbag_noadditional.cxx b/comphelper/qa/weakbag/test_weakbag_noadditional.cxx
index 1abcc82..7449e3f 100644
--- a/comphelper/qa/weakbag/test_weakbag_noadditional.cxx
+++ b/comphelper/qa/weakbag/test_weakbag_noadditional.cxx
@@ -28,6 +28,6 @@
 
 #include <cppunit/plugin/TestPlugIn.h>
 
-CPPUNIT_PLUGIN_IMPLEMENT();
+// CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 722cf17fcf43a54d600809edc8b52c43fc487e0a
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Mar 9 14:22:35 2011 +0000

    enable fontcapabilities under windows

diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx
index bd83a0a..c7337a8 100644
--- a/vcl/win/source/gdi/salgdi3.cxx
+++ b/vcl/win/source/gdi/salgdi3.cxx
@@ -1393,7 +1393,6 @@ void ImplWinFontData::ReadOs2Table( HDC hDC ) const
         mbHasArabicSupport = (ulUnicodeRange1 & 0x00002000);
    }
 }
-
 // -----------------------------------------------------------------------
 
 void ImplWinFontData::ReadGsubTable( HDC hDC ) const
commit 5d8f056cacb31b7b324b6154f120b8dcfc5820e3
Author: Martin Hosken <martin_hosken at sil.org>
Date:   Wed Mar 9 14:46:09 2011 +0700

    Do SMP properly for ICU. No bug thankfully

diff --git a/i18npool/source/breakiterator/data/char.txt b/i18npool/source/breakiterator/data/char.txt
index b2772db..8e49a56 100644
--- a/i18npool/source/breakiterator/data/char.txt
+++ b/i18npool/source/breakiterator/data/char.txt
@@ -23,7 +23,7 @@ $SpacingMark = [\p{Grapheme_Cluster_Break = SpacingMark}];
 # In effect it is [\p{Grapheme_Cluster_Break = SpacingMark} - \u0E30 \u0E32 \u0E45 \u0EB0 \u0EB2 \u102B \u102C \u1038
 #       \u1062-\u1064 \u1067-\u106D \u1083 \u1087-\u108C \u108F \u109A-\u109C \u19B0-\u19B4 \u19B8-\u19C0 \u19C8 \u19C9
 #       \u1A61 \u1A63 \u1A64 \u1BE7 \u1BEA-\u1BEC \u1BEE \u1BF2 \u1BF3 \uAA7B
-$IndicSpacing = [\u0903 \u093B \u093E-\u0940 \u0949-\u094C \u094E \u094F \u0982 \u0983 \u09BF \u09C0 \u09C7 \u09C8 \u09CB \u09CC \u0A03 \u0A3E-\u0A40 \u0A83 \u0ABE-\u0AC0 \u0AC9 \u0ACB \u0ACC \u0B02 \u0B03 \u0B40 \u0B47 \u0B48 \u0B4B-\u0B4C \u0BBF \u0BC1 \u0BC2 \u0BC6-\u0BC8 \u0BCA-\u0BCC \u0C01-\u0C03 \u0C41-\u0C44 \u0C82 \u0C83 \u0CBE \u0CC0 \u0CC1 \u0CC3 \u0CC4 \u0CC7 \u0CC8 \u0CCA \u0CCB \u0D02 \u0D03 \u0D3F \u0D40 \u0D46-\u0D48 \u0D4A-\u0D4C \u0D82 \u0D83 \u0DD0 \u0DD1 \u0DD8-\u0DDE \u0F3E \u0F3F \u0F7F \u1923-\u1926 \u1929-\u192B \u1930 \u1931 \u1933-\u1938 \u1A19-\u1A1B \u1B04 \u1B35 \u1B3B \u1B3D-\u1B41 \u1B43 \u1B44 \u1B82 \u1BA1 \u1BA6 \u1BA7 \u1BAA \u1C24-\u1C2B \u1C34 \u1C35 \u1CE1 \u1CF2 \uA880 \uA881 \uA8B4-\uA8C3 \uA952 \uA953 \uA983 \uA9B4 \uA9B5 \uA9BA \uA9BB \uA9BD-\uA9C0 \uAA2F \uAA30 \uAA33 \uAA34 \uABE3 \uABE4 \uABE6 \uABE7 \uABE9 \uABEA \uABEC \u11000 \u11002 \u11082 \u110B0 \u110B1 \u110B2 \u110B7 \u100B8 \u1D166 \u1D16D];
+$IndicSpacing = [\u0903 \u093B \u093E-\u0940 \u0949-\u094C \u094E \u094F \u0982 \u0983 \u09BF \u09C0 \u09C7 \u09C8 \u09CB \u09CC \u0A03 \u0A3E-\u0A40 \u0A83 \u0ABE-\u0AC0 \u0AC9 \u0ACB \u0ACC \u0B02 \u0B03 \u0B40 \u0B47 \u0B48 \u0B4B-\u0B4C \u0BBF \u0BC1 \u0BC2 \u0BC6-\u0BC8 \u0BCA-\u0BCC \u0C01-\u0C03 \u0C41-\u0C44 \u0C82 \u0C83 \u0CBE \u0CC0 \u0CC1 \u0CC3 \u0CC4 \u0CC7 \u0CC8 \u0CCA \u0CCB \u0D02 \u0D03 \u0D3F \u0D40 \u0D46-\u0D48 \u0D4A-\u0D4C \u0D82 \u0D83 \u0DD0 \u0DD1 \u0DD8-\u0DDE \u0F3E \u0F3F \u0F7F \u1923-\u1926 \u1929-\u192B \u1930 \u1931 \u1933-\u1938 \u1A19-\u1A1B \u1B04 \u1B35 \u1B3B \u1B3D-\u1B41 \u1B43 \u1B44 \u1B82 \u1BA1 \u1BA6 \u1BA7 \u1BAA \u1C24-\u1C2B \u1C34 \u1C35 \u1CE1 \u1CF2 \uA880 \uA881 \uA8B4-\uA8C3 \uA952 \uA953 \uA983 \uA9B4 \uA9B5 \uA9BA \uA9BB \uA9BD-\uA9C0 \uAA2F \uAA30 \uAA33 \uAA34 \uABE3 \uABE4 \uABE6 \uABE7 \uABE9 \uABEA \uABEC \U00011000 \U00011002 \U00011082 \U000110B0-\U000110B2 \U000110B7 \U000100B8 \U0001D166 \U0001D16D];
 # SEAsian (Thai, Lao, Burmese, Tai Lue, Tai Tham, Batak) are cluster based not syllable based
 $SEASpacing = [\u0E33 \u0EB3 \u1031 \u103B \u103C \u1056 \u1057 \u1084 \u17B6 \u17BE-\u17C5 \u17C7 \u17C8 \u19B5-\u19B7 \u19BA \u1A55 \u1A57 \u1A6D-\u1A72 \uA823 \uA824 \uA827 \uAA4D];
 $BengaliLetter = [\u0985-\u09B9 \u09CE \u09DC-\u09E1 \u09F0-\u09F1];
commit 20594d17cdb367ba81183a5c3847efa2e90531c8
Author: Martin Hosken <martin_hosken at sil.org>
Date:   Wed Mar 9 14:29:05 2011 +0700

    Work around ICU bug regarding SMP ranges not working, so expand them

diff --git a/i18npool/source/breakiterator/data/char.txt b/i18npool/source/breakiterator/data/char.txt
index c298b73..b2772db 100644
--- a/i18npool/source/breakiterator/data/char.txt
+++ b/i18npool/source/breakiterator/data/char.txt
@@ -23,7 +23,7 @@ $SpacingMark = [\p{Grapheme_Cluster_Break = SpacingMark}];
 # In effect it is [\p{Grapheme_Cluster_Break = SpacingMark} - \u0E30 \u0E32 \u0E45 \u0EB0 \u0EB2 \u102B \u102C \u1038
 #       \u1062-\u1064 \u1067-\u106D \u1083 \u1087-\u108C \u108F \u109A-\u109C \u19B0-\u19B4 \u19B8-\u19C0 \u19C8 \u19C9
 #       \u1A61 \u1A63 \u1A64 \u1BE7 \u1BEA-\u1BEC \u1BEE \u1BF2 \u1BF3 \uAA7B
-$IndicSpacing = [\u0903 \u093B \u093E-\u0940 \u0949-\u094C \u094E \u094F \u0982 \u0983 \u09BF \u09C0 \u09C7 \u09C8 \u09CB \u09CC \u0A03 \u0A3E-\u0A40 \u0A83 \u0ABE-\u0AC0 \u0AC9 \u0ACB \u0ACC \u0B02 \u0B03 \u0B40 \u0B47 \u0B48 \u0B4B-\u0B4C \u0BBF \u0BC1 \u0BC2 \u0BC6-\u0BC8 \u0BCA-\u0BCC \u0C01-\u0C03 \u0C41-\u0C44 \u0C82 \u0C83 \u0CBE \u0CC0 \u0CC1 \u0CC3 \u0CC4 \u0CC7 \u0CC8 \u0CCA \u0CCB \u0D02 \u0D03 \u0D3F \u0D40 \u0D46-\u0D48 \u0D4A-\u0D4C \u0D82 \u0D83 \u0DD0 \u0DD1 \u0DD8-\u0DDE \u0F3E \u0F3F \u0F7F \u1923-\u1926 \u1929-\u192B \u1930 \u1931 \u1933-\u1938 \u1A19-\u1A1B \u1B04 \u1B35 \u1B3B \u1B3D-\u1B41 \u1B43 \u1B44 \u1B82 \u1BA1 \u1BA6 \u1BA7 \u1BAA \u1C24-\u1C2B \u1C34 \u1C35 \u1CE1 \u1CF2 \uA880 \uA881 \uA8B4-\uA8C3 \uA952 \uA953 \uA983 \uA9B4 \uA9B5 \uA9BA \uA9BB \uA9BD-\uA9C0 \uAA2F \uAA30 \uAA33 \uAA34 \uABE3 \uABE4 \uABE6 \uABE7 \uABE9 \uABEA \uABEC \u11000 \u11002 \u11082 \u110B0-\u110B2 \u110B7 \u100B8 \u1D166 \u1D16D];
+$IndicSpacing = [\u0903 \u093B \u093E-\u0940 \u0949-\u094C \u094E \u094F \u0982 \u0983 \u09BF \u09C0 \u09C7 \u09C8 \u09CB \u09CC \u0A03 \u0A3E-\u0A40 \u0A83 \u0ABE-\u0AC0 \u0AC9 \u0ACB \u0ACC \u0B02 \u0B03 \u0B40 \u0B47 \u0B48 \u0B4B-\u0B4C \u0BBF \u0BC1 \u0BC2 \u0BC6-\u0BC8 \u0BCA-\u0BCC \u0C01-\u0C03 \u0C41-\u0C44 \u0C82 \u0C83 \u0CBE \u0CC0 \u0CC1 \u0CC3 \u0CC4 \u0CC7 \u0CC8 \u0CCA \u0CCB \u0D02 \u0D03 \u0D3F \u0D40 \u0D46-\u0D48 \u0D4A-\u0D4C \u0D82 \u0D83 \u0DD0 \u0DD1 \u0DD8-\u0DDE \u0F3E \u0F3F \u0F7F \u1923-\u1926 \u1929-\u192B \u1930 \u1931 \u1933-\u1938 \u1A19-\u1A1B \u1B04 \u1B35 \u1B3B \u1B3D-\u1B41 \u1B43 \u1B44 \u1B82 \u1BA1 \u1BA6 \u1BA7 \u1BAA \u1C24-\u1C2B \u1C34 \u1C35 \u1CE1 \u1CF2 \uA880 \uA881 \uA8B4-\uA8C3 \uA952 \uA953 \uA983 \uA9B4 \uA9B5 \uA9BA \uA9BB \uA9BD-\uA9C0 \uAA2F \uAA30 \uAA33 \uAA34 \uABE3 \uABE4 \uABE6 \uABE7 \uABE9 \uABEA \uABEC \u11000 \u11002 \u11082 \u110B0 \u110B1 \u110B2 \u110B7 \u100B8 \u1D166 \u1D16D];
 # SEAsian (Thai, Lao, Burmese, Tai Lue, Tai Tham, Batak) are cluster based not syllable based
 $SEASpacing = [\u0E33 \u0EB3 \u1031 \u103B \u103C \u1056 \u1057 \u1084 \u17B6 \u17BE-\u17C5 \u17C7 \u17C8 \u19B5-\u19B7 \u19BA \u1A55 \u1A57 \u1A6D-\u1A72 \uA823 \uA824 \uA827 \uAA4D];
 $BengaliLetter = [\u0985-\u09B9 \u09CE \u09DC-\u09E1 \u09F0-\u09F1];
@@ -79,8 +79,7 @@ $L ($L | $V | $LV | $LVT);
 
 [^$Control $CR $LF] $Extend;
 
-[^$Control $CR $LF] $IndicSpacing;
-[^$Control $CR $LF] $SEASpacing;
+[^$Control $CR $LF] ($IndicSpacing | $SEASpacing);
 #[^$Control $CR $LF] $SpacingMark;
 # $Prepend [^$Control $CR $LF];
 
@@ -103,8 +102,7 @@ $LF $CR;
 $T ($LVT | $T);
 
 $Extend      [^$Control $CR $LF];
-$IndicSpacing [^$Control $CR $LF];
-$SEASpacing [^$Control $CR $LF];
+($IndicSpacing | $SEASpacing) [^$Control $CR $LF];
 #$SpacingMark [^$Control $CR $LF];
 # [^$Control $CR $LF] $Prepend;
 
commit 1ae0df1c597f7c55ed411707018fd56884d08531
Author: Martin Hosken <martin_hosken at sil.org>
Date:   Tue Mar 8 11:45:16 2011 +0700

    Attempt to fix winlayout memory leak

diff --git a/vcl/inc/vcl/graphite_layout.hxx b/vcl/inc/vcl/graphite_layout.hxx
index 1c8900f..2012e2b 100644
--- a/vcl/inc/vcl/graphite_layout.hxx
+++ b/vcl/inc/vcl/graphite_layout.hxx
@@ -81,6 +81,8 @@ public:
     };
     void addFont(int ppm, gr_font * pFont)
     {
+        if (m_fonts[ppm])
+            gr_font_destroy(m_fonts[ppm]);
         m_fonts[ppm] = pFont;
     }
 private:
@@ -107,7 +109,7 @@ public:
 
 private:
     const gr_face *         mpFace; // not owned by layout
-    gr_font *               mpFont; // owned by layout
+    gr_font *               mpFont; // not owned by layout
     int                     mnSegCharOffset; // relative to ImplLayoutArgs::mpStr
     long                    mnWidth;
     std::vector<int>        mvChar2BaseGlyph;
@@ -150,6 +152,7 @@ public:
 
     virtual ~GraphiteLayout() throw();
     void SetFont(gr_font * pFont) { mpFont = pFont; }
+    gr_font * GetFont() { return mpFont; }
     void SetFeatures(grutils::GrFeatureParser * aFeature) { mpFeatures = aFeature; }
     void SetFontScale(float s) { mfScaling = s; };
     virtual sal_GlyphId getKashidaGlyph(int & width) = 0;
diff --git a/vcl/source/glyphs/graphite_features.cxx b/vcl/source/glyphs/graphite_features.cxx
index 6445765..dabb11f 100644
--- a/vcl/source/glyphs/graphite_features.cxx
+++ b/vcl/source/glyphs/graphite_features.cxx
@@ -161,7 +161,7 @@ void GrFeatureParser::setLang(const gr_face * pFace, const rtl::OString & lang)
 {
     FeatId aLang;
     aLang.num = 0;
-    if (lang.getLength() > 2)
+    if (lang.getLength() >= 2)
     {
         for (sal_Int32 i = 0; i < lang.getLength() && i < 3; i++)
         {
@@ -194,17 +194,13 @@ void GrFeatureParser::setLang(const gr_face * pFace, const rtl::OString & lang)
         if (i != gr_face_n_languages(pFace))
         {
             if (mpSettings)
-            {
                 gr_featureval_destroy(mpSettings);
-            }
             mpSettings = gr_face_featureval_for_lang(pFace, maLang.num);
             mnHash = maLang.num;
         }
     }
     if (!mpSettings)
-    {
         mpSettings = gr_face_featureval_for_lang(pFace, 0);
-    }
 }
 
 GrFeatureParser::~GrFeatureParser()
diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx
index 48aa477..683fa00 100644
--- a/vcl/win/source/gdi/winlayout.cxx
+++ b/vcl/win/source/gdi/winlayout.cxx
@@ -2805,6 +2805,7 @@ private:
 public:
     GraphiteWinLayout(HDC hDC, const ImplWinFontData& rWFD, ImplWinFontEntry& rWFE);
 
+    ~GraphiteWinLayout() { gr_font_destroy(maImpl.getFont()); }
     // used by upper layers
     virtual bool  LayoutText( ImplLayoutArgs& );    // first step of layout
     virtual void  AdjustLayout( ImplLayoutArgs& );  // adjusting after fallback etc.
commit c0ee5f3da6b8ac0c27950a1715a6bf80f1ecacb6
Author: Martin Hosken <martin_hosken at sil.org>
Date:   Fri Mar 4 19:57:29 2011 +0700

    break graphemes on new uax#29 updates, use ICU for script identification

diff --git a/i18npool/source/breakiterator/breakiteratorImpl.cxx b/i18npool/source/breakiterator/breakiteratorImpl.cxx
index c072bfc..1f2acc7 100644
--- a/i18npool/source/breakiterator/breakiteratorImpl.cxx
+++ b/i18npool/source/breakiterator/breakiteratorImpl.cxx
@@ -473,31 +473,61 @@ static UBlock2Script scriptList[] = {
 
 #define scriptListCount sizeof (scriptList) / sizeof (UBlock2Script)
 
+static sal_Int16 scriptTypes[] = {
+    ScriptType::WEAK, ScriptType::WEAK, ScriptType::COMPLEX, ScriptType::LATIN, ScriptType::COMPLEX,
+    ScriptType::ASIAN, ScriptType::LATIN, ScriptType::LATIN, ScriptType::LATIN, ScriptType::COMPLEX,
+    ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::LATIN, ScriptType::LATIN, ScriptType::LATIN,
+// 15
+    ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::ASIAN, ScriptType::ASIAN, ScriptType::COMPLEX,
+    ScriptType::ASIAN, ScriptType::COMPLEX, ScriptType::ASIAN, ScriptType::COMPLEX, ScriptType::COMPLEX,
+    ScriptType::LATIN, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::LATIN,
+// 30
+    ScriptType::LATIN, ScriptType::COMPLEX, ScriptType::LATIN, ScriptType::COMPLEX, ScriptType::COMPLEX,
+    ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX,
+    ScriptType::LATIN, ScriptType::ASIAN, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX,
+// 45
+    ScriptType::COMPLEX, ScriptType::LATIN, ScriptType::LATIN, ScriptType::COMPLEX, ScriptType::COMPLEX,
+    ScriptType::LATIN, ScriptType::LATIN, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::LATIN,
+    ScriptType::COMPLEX, ScriptType::LATIN, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX,
+// 60
+    ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX,
+    ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::LATIN, ScriptType::LATIN, ScriptType::COMPLEX,
+    ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::ASIAN, ScriptType::ASIAN,
+// 75
+    ScriptType::COMPLEX, ScriptType::LATIN, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX,
+    ScriptType::LATIN, ScriptType::LATIN, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX,
+    ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX,
+// 90
+    ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX,
+    ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX,
+    ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::WEAK, ScriptType::WEAK, ScriptType::COMPLEX,
+// 105
+    ScriptType::ASIAN, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX,
+    ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX,
+    ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::ASIAN,
+// 120
+    ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX,
+    ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::COMPLEX, ScriptType::LATIN, ScriptType::LATIN,
+    ScriptType::WEAK};
+
+#define scriptTypesCount sizeof(scriptTypes) / sizeof(sal_Int16)
+
 sal_Int16  BreakIteratorImpl::getScriptClass(sal_uInt32 currentChar)
 {
         static sal_uInt32 lastChar = 0;
         static sal_Int16 nRet = 0;
+        sal_uInt32 script;
 
         if (currentChar != lastChar) {
             lastChar = currentChar;
 
-            //JP 21.9.2001: handle specific characters - always as weak
-            //                  definition of 1 - this breaks a word
-            //                  2 - this can be inside a word
-            //                  0x20 & 0xA0 - Bug 102975, declare western space and non-break space as WEAK char.
-            if( 1 == currentChar || 2 == currentChar || 0x20 == currentChar || 0xA0 == currentChar)
+            script = u_getIntPropertyValue(currentChar, UCHAR_SCRIPT);
+            if (script < 0)
                 nRet = ScriptType::WEAK;
-            // workaround for Coptic
-            else if ( 0x2C80 <= currentChar && 0x2CE3 >= currentChar)
-                nRet = ScriptType::LATIN;            
-            else {
-                UBlockCode block=ublock_getCode(currentChar);
-                sal_uInt16 i;
-                for ( i = 0; i < scriptListCount; i++) {
-                    if (block <= scriptList[i].to) break;
-                }
-                nRet=(i < scriptListCount && block >= scriptList[i].from) ? scriptList[i].script : ScriptType::WEAK;
-            }
+            else if (script >= scriptTypesCount)
+                nRet = ScriptType::COMPLEX;         // anything new is going to be pretty wild
+            else
+                nRet = scriptTypes[script];
         }
         return nRet;
 }
diff --git a/i18npool/source/breakiterator/data/char.txt b/i18npool/source/breakiterator/data/char.txt
new file mode 100644
index 0000000..c298b73
--- /dev/null
+++ b/i18npool/source/breakiterator/data/char.txt
@@ -0,0 +1,120 @@
+#
+#   Copyright (C) 2002-2009, International Business Machines Corporation and others.
+#       All Rights Reserved.
+#
+#   file:  char.txt 
+#
+#   ICU Character Break Rules, also known as Grapheme Cluster Boundaries
+#      See Unicode Standard Annex #29.
+#      These rules are based on TR29 Revision 13, for Unicode Version 5.1
+#   Modifications to SpacingMark and Prepend by M. Hosken.
+#
+
+#
+#  Character Class Definitions.
+#
+$CR          = [\p{Grapheme_Cluster_Break = CR}];
+$LF          = [\p{Grapheme_Cluster_Break = LF}];
+$Control     = [\p{Grapheme_Cluster_Break = Control}];
+$Prepend     = [\p{Grapheme_Cluster_Break = Prepend}];
+$Extend      = [\p{Grapheme_Cluster_Break = Extend}];
+$SpacingMark = [\p{Grapheme_Cluster_Break = SpacingMark}];
+# True Indic wants to move by syllables. Break up SpacingMark. This based on Unicode 6.0 data
+# In effect it is [\p{Grapheme_Cluster_Break = SpacingMark} - \u0E30 \u0E32 \u0E45 \u0EB0 \u0EB2 \u102B \u102C \u1038
+#       \u1062-\u1064 \u1067-\u106D \u1083 \u1087-\u108C \u108F \u109A-\u109C \u19B0-\u19B4 \u19B8-\u19C0 \u19C8 \u19C9
+#       \u1A61 \u1A63 \u1A64 \u1BE7 \u1BEA-\u1BEC \u1BEE \u1BF2 \u1BF3 \uAA7B
+$IndicSpacing = [\u0903 \u093B \u093E-\u0940 \u0949-\u094C \u094E \u094F \u0982 \u0983 \u09BF \u09C0 \u09C7 \u09C8 \u09CB \u09CC \u0A03 \u0A3E-\u0A40 \u0A83 \u0ABE-\u0AC0 \u0AC9 \u0ACB \u0ACC \u0B02 \u0B03 \u0B40 \u0B47 \u0B48 \u0B4B-\u0B4C \u0BBF \u0BC1 \u0BC2 \u0BC6-\u0BC8 \u0BCA-\u0BCC \u0C01-\u0C03 \u0C41-\u0C44 \u0C82 \u0C83 \u0CBE \u0CC0 \u0CC1 \u0CC3 \u0CC4 \u0CC7 \u0CC8 \u0CCA \u0CCB \u0D02 \u0D03 \u0D3F \u0D40 \u0D46-\u0D48 \u0D4A-\u0D4C \u0D82 \u0D83 \u0DD0 \u0DD1 \u0DD8-\u0DDE \u0F3E \u0F3F \u0F7F \u1923-\u1926 \u1929-\u192B \u1930 \u1931 \u1933-\u1938 \u1A19-\u1A1B \u1B04 \u1B35 \u1B3B \u1B3D-\u1B41 \u1B43 \u1B44 \u1B82 \u1BA1 \u1BA6 \u1BA7 \u1BAA \u1C24-\u1C2B \u1C34 \u1C35 \u1CE1 \u1CF2 \uA880 \uA881 \uA8B4-\uA8C3 \uA952 \uA953 \uA983 \uA9B4 \uA9B5 \uA9BA \uA9BB \uA9BD-\uA9C0 \uAA2F \uAA30 \uAA33 \uAA34 \uABE3 \uABE4 \uABE6 \uABE7 \uABE9 \uABEA \uABEC \u11000 \u11002 \u11082 \u110B0-\u110B2 \u110B7 \u100B8 \u1D166 \u1D16D];
+# SEAsian (Thai, Lao, Burmese, Tai Lue, Tai Tham, Batak) are cluster based not syllable based
+$SEASpacing = [\u0E33 \u0EB3 \u1031 \u103B \u103C \u1056 \u1057 \u1084 \u17B6 \u17BE-\u17C5 \u17C7 \u17C8 \u19B5-\u19B7 \u19BA \u1A55 \u1A57 \u1A6D-\u1A72 \uA823 \uA824 \uA827 \uAA4D];
+$BengaliLetter = [\u0985-\u09B9 \u09CE \u09DC-\u09E1 \u09F0-\u09F1];
+$BengaliSignVirama = \u09CD;
+$GujaratiLetter = [\u0A85-\u0A8C \u0A8F-\u0A90 \u0A93-\u0AB9 \u0AE0-\u0AE1];
+$GujaratiSignVirama = \u0ACD;
+$DevanagariLetter = [\u0904-\u0939 \u0958-\u0961 \u0972-\u097F];
+$DevanagariSignVirama = \u094D;
+$KannadaLetter = [\u0C85-\u0CB9 \u0CDE-\u0CE1];
+$KannadaSignVirama = \u0CCD;
+$MalayalamLetter = [\u0D05-\u0D39 \u0D60-\u0D61 \u0D7A-\u0D7F];
+$MalayalamSignVirama = \u0D4D;
+$OriyaLetter = [\u0B05-\u0B39 \u0B5C-\u0B61 \u0B71];
+$OriyaSignVirama = \u0B4D;
+$GurmukhiLetter = [\u0A05-\u0A39 \u0A59-\u0A5E];
+$GurmukhiSignVirama = \u0A4D;
+$TamilLetter = [\u0B85-\u0BB9];
+$TamilSignVirama = \u0BCD;
+$TeluguLetter = [\u0C05-\u0C39 \u0C58-\u0C61];
+$TeluguSignVirama = \u0C4D;
+
+#
+# Korean Syllable Definitions
+#
+$L       = [\p{Grapheme_Cluster_Break = L}];
+$V       = [\p{Grapheme_Cluster_Break = V}];
+$T       = [\p{Grapheme_Cluster_Break = T}];
+
+$LV      = [\p{Grapheme_Cluster_Break = LV}];
+$LVT     = [\p{Grapheme_Cluster_Break = LVT}];
+
+
+## -------------------------------------------------
+!!chain;
+
+!!forward;
+
+$CR $LF;
+
+$BengaliLetter ($BengaliSignVirama $BengaliLetter?)+;
+$GujaratiLetter ($GujaratiSignVirama $GujaratiLetter?)+;
+$DevanagariLetter ($DevanagariSignVirama $DevanagariLetter?)+;
+$KannadaLetter ($KannadaSignVirama $KannadaLetter?)+;
+$MalayalamLetter ($MalayalamSignVirama $MalayalamLetter?)+;
+$OriyaLetter ($OriyaSignVirama $OriyaLetter?)+;
+$GurmukhiLetter ($GurmukhiSignVirama $GurmukhiLetter?)+;
+$TamilLetter ($TamilSignVirama $TamilLetter?)+;
+$TeluguLetter ($TeluguSignVirama $TeluguLetter?)+;
+
+$L ($L | $V | $LV | $LVT);
+($LV | $V) ($V | $T);
+($LVT | $T) $T;
+
+[^$Control $CR $LF] $Extend;
+
+[^$Control $CR $LF] $IndicSpacing;
+[^$Control $CR $LF] $SEASpacing;
+#[^$Control $CR $LF] $SpacingMark;
+# $Prepend [^$Control $CR $LF];
+
+
+## -------------------------------------------------
+
+!!reverse;
+$LF $CR;
+($BengaliLetter? $BengaliSignVirama)+ $BengaliLetter;
+($GujaratiLetter? $GujaratiSignVirama)+ $GujaratiLetter;
+($DevanagariLetter? $DevanagariSignVirama)+ $DevanagariLetter;
+($KannadaLetter? $KannadaSignVirama)+ $KannadaLetter;
+($MalayalamLetter? $MalayalamSignVirama)+ $MalayalamLetter;
+($OriyaLetter? $OriyaSignVirama)+ $OriyaLetter;
+($GurmukhiLetter? $GurmukhiSignVirama)+ $GurmukhiLetter;
+($TamilLetter? $TamilSignVirama)+ $TamilLetter;
+($TeluguLetter? $TeluguSignVirama)+ $TeluguLetter;
+($L | $V | $LV | $LVT) $L;
+($V | $T) ($LV | $V);
+$T ($LVT | $T);
+
+$Extend      [^$Control $CR $LF];
+$IndicSpacing [^$Control $CR $LF];
+$SEASpacing [^$Control $CR $LF];
+#$SpacingMark [^$Control $CR $LF];
+# [^$Control $CR $LF] $Prepend;
+
+
+## -------------------------------------------------
+
+!!safe_reverse;
+
+
+## -------------------------------------------------
+
+!!safe_forward;
+
commit 0ba940b307b67aef2a8090f7d55384f8818f317f
Author: Martin Hosken <martin_hosken at sil.org>
Date:   Fri Mar 4 19:53:12 2011 +0700

    Use statically built graphite library

diff --git a/vcl/util/makefile.mk b/vcl/util/makefile.mk
index 6e75f09..a67095f 100755
--- a/vcl/util/makefile.mk
+++ b/vcl/util/makefile.mk
@@ -187,7 +187,7 @@ SHL1STDLIBS+=\
 .IF "$(SYSTEM_GRAPHITE)" == "YES"
 SHL1STDLIBS+= $(GRAPHITE_LIBS)
 .ELSE
-SHL1STDLIBS+= -lgraphite2
+SHL1STDLIBS+= -lgraphite2_off
 .ENDIF
 .ENDIF
 .ENDIF
@@ -232,9 +232,10 @@ DEFLIB1NAME =vcl
 
 .IF "$(ENABLE_GRAPHITE)" == "TRUE"
 .IF "$(COM)" == "GCC"
-SHL1STDLIBS += -lgraphite2
+SHL1STDLIBS += -Wl,-Bstatic -lgraphite2_off -Wl,-Bdynamic
+#SHL1STDLIBS += -lgraphite2_off
 .ELSE
-SHL1STDLIBS += graphite2.lib
+SHL1STDLIBS += graphite2_off.lib
 .ENDIF
 .ENDIF
 
diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx
index 3f28cfc..48aa477 100644
--- a/vcl/win/source/gdi/winlayout.cxx
+++ b/vcl/win/source/gdi/winlayout.cxx
@@ -2849,7 +2849,7 @@ GraphiteWinLayout::GraphiteWinLayout(HDC hDC, const ImplWinFontData& rWFD, ImplW
     ::GetObjectW( mhFont, sizeof(LOGFONTW), &aLogFont);
     mpFont = gr_make_font_with_advance_fn(static_cast<float>(-aLogFont.lfHeight),
         hDC, gr_fontAdvance, rWFD.GraphiteFace());
-    maImpl.TakeFont(mpFont);
+    maImpl.SetFont(mpFont);
     const rtl::OString aLang = MsLangId::convertLanguageToIsoByteString( rWFE.maFontSelData.meLanguage );
     rtl::OString name = rtl::OUStringToOString(
         rWFE.maFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 );
commit f098d34fa7000ed690130bccda68797211a2e0b9
Author: Martin Hosken <martin_hosken at sil.org>
Date:   Wed Mar 2 16:21:57 2011 +0700

    revert bad patch in graphite consolidated patch

diff --git a/comphelper/qa/weakbag/test_weakbag_noadditional.cxx b/comphelper/qa/weakbag/test_weakbag_noadditional.cxx
index 7449e3f..1abcc82 100644
--- a/comphelper/qa/weakbag/test_weakbag_noadditional.cxx
+++ b/comphelper/qa/weakbag/test_weakbag_noadditional.cxx
@@ -28,6 +28,6 @@
 
 #include <cppunit/plugin/TestPlugIn.h>
 
-// CPPUNIT_PLUGIN_IMPLEMENT();
+CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 85dc00b157fb97b70ff5fa20bf9e6355404aba30
Author: Martin Hosken <martin_hosken at sil.org>
Date:   Fri Feb 25 16:10:55 2011 +0700

    graphite2 consolidated patch

diff --git a/comphelper/qa/weakbag/test_weakbag_noadditional.cxx b/comphelper/qa/weakbag/test_weakbag_noadditional.cxx
index 1abcc82..7449e3f 100644
--- a/comphelper/qa/weakbag/test_weakbag_noadditional.cxx
+++ b/comphelper/qa/weakbag/test_weakbag_noadditional.cxx
@@ -28,6 +28,6 @@
 
 #include <cppunit/plugin/TestPlugIn.h>
 
-CPPUNIT_PLUGIN_IMPLEMENT();
+// CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/vcl/graphite_adaptors.hxx b/vcl/inc/vcl/graphite_adaptors.hxx
deleted file mode 100644
index 2b95fd4..0000000
--- a/vcl/inc/vcl/graphite_adaptors.hxx
+++ /dev/null
@@ -1,145 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org.  If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-#ifndef _SV_GRAPHITEADAPTORS_HXX
-#define _SV_GRAPHITEADAPTORS_HXX
-
-// We need this to enable namespace support in libgrengine headers.
-#define GR_NAMESPACE
-
-// Standard Library
-#include <stdexcept>
-// Platform
-
-#include <tools/svwin.h>
-
-#include <svsys.h>
-
-#include <vcl/salgdi.hxx>
-
-#include <vcl/sallayout.hxx>
-
-// Module
-#include "vcl/dllapi.h"
-
-// Libraries
-#include <graphite/GrClient.h>
-#include <graphite/Font.h>
-#include <graphite/ITextSource.h>
-
-// Module type definitions and forward declarations.
-//
-#ifndef MSC
-// SAL/VCL types
-class ServerFont;
-class FreetypeServerFont;
-
-// Graphite types
-
-struct FontProperties : gr::FontProps
-{
-    FontProperties(const FreetypeServerFont & font) throw();
-};
-
-namespace grutils
-{
-    class GrFeatureParser;
-}
-
-// This class adapts the Sal font and graphics services to form required by
-// the Graphite engine.
-// @author tse
-//
-class VCL_DLLPUBLIC GraphiteFontAdaptor : public gr::Font
-{
-    typedef std::map<const gr::gid16, std::pair<gr::Rect, gr::Point> > GlyphMetricMap;
-    friend class GrFontHasher;
-public:
-    static bool    IsGraphiteEnabledFont(ServerFont &) throw();
-
-    GraphiteFontAdaptor(ServerFont & font, const sal_Int32 dpi_x, const sal_Int32 dpi_y);
-    GraphiteFontAdaptor(const GraphiteFontAdaptor &) throw();
-    ~GraphiteFontAdaptor() throw();
-
-     gr::Font    * copyThis();
-
-    // Basic attribute accessors.
-    virtual float        ascent();
-    virtual float        descent();
-    virtual bool        bold();
-    virtual bool        italic();
-    virtual float        height();
-    virtual unsigned int    getDPIx();
-    virtual unsigned int    getDPIy();
-
-    // Font access methods.
-    virtual const void    * getTable(gr::fontTableId32 tableID, size_t * pcbSize);
-    virtual void          getFontMetrics(float * ascent_out, float * descent_out = 0, float * em_square_out = 0);
-
-    // Glyph metrics.
-    virtual void      getGlyphMetrics(gr::gid16 glyphID, gr::Rect & boundingBox, gr::Point & advances);
-
-    // Adaptor attributes.
-    const FontProperties    & fontProperties() const throw();
-    FreetypeServerFont        & font() const throw();
-    const grutils::GrFeatureParser * features() const { return mpFeatures; };
-
-private:
-    virtual void UniqueCacheInfo(std::wstring &, bool &, bool &);
-
-    FreetypeServerFont& mrFont;
-    FontProperties        maFontProperties;
-    const unsigned int    mnDpiX, mnDpiY;
-    const float           mfAscent,
-                    mfDescent,
-                    mfEmUnits;
-    grutils::GrFeatureParser * mpFeatures;
-    GlyphMetricMap maGlyphMetricMap;
-};
-
-// Partial implementation of class GraphiteFontAdaptor.
-//
-inline const FontProperties & GraphiteFontAdaptor::fontProperties() const throw() {
-    return maFontProperties;
-}
-
-inline FreetypeServerFont & GraphiteFontAdaptor::font() const throw() {
-    return mrFont;
-}
-#endif // not MFC
-
-// Partial implementation of class TextSourceAdaptor.
-//
-//inline const ImplLayoutArgs & TextSourceAdaptor::layoutArgs() const throw() {
-//  return _layout_args;
-//}
-
-
-#endif // _SV_GRAPHITEADAPTORS_HXX
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/vcl/graphite_cache.hxx b/vcl/inc/vcl/graphite_cache.hxx
deleted file mode 100644
index 3fbb963..0000000
--- a/vcl/inc/vcl/graphite_cache.hxx
+++ /dev/null
@@ -1,290 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org.  If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// Description: Classes to cache Graphite Segments to try to improve
-//              rendering performance.
-
-#ifndef GraphiteSegmentCache_h
-#define GraphiteSegmentCache_h
-
-#include <tools/solar.h>
-#include <rtl/ustring.h>
-
-#define GRCACHE_REUSE_VECTORS 1
-
-#include <boost/unordered_map.hpp>
-
-class TextSourceAdaptor;
-/**
-* GrSegRecord stores a Graphite Segment and its associated text
-*/
-class GrSegRecord {
-public:
-    GrSegRecord(rtl::OUString * rope, TextSourceAdaptor * textSrc, gr::Segment * seg, bool bIsRtl);
-
-    ~GrSegRecord();
-
-    void reuse(rtl::OUString * rope, TextSourceAdaptor * textSrc, gr::Segment * seg, bool bIsRtl);
-
-    void clearVectors();
-    void clear();
-#ifdef GRCACHE_REUSE_VECTORS
-    void setGlyphVectors(long nWidth, GraphiteLayout::Glyphs & vGlyphs, std::vector<int> vCharDxs,
-                         std::vector<int> & vChar2Base, std::vector<int> & vGlyph2Char, float fScale)
-    {
-        clearVectors();
-        mnWidth = nWidth;
-        m_fontScale = fScale;
-        mvGlyphs.insert(mvGlyphs.begin(), vGlyphs.begin(), vGlyphs.end());
-        mvCharDxs.insert(mvCharDxs.begin(),vCharDxs.begin(),vCharDxs.end());
-        mvChar2BaseGlyph.insert(mvChar2BaseGlyph.begin(),vChar2Base.begin(),vChar2Base.end());
-        mvGlyph2Char.insert(mvGlyph2Char.begin(),vGlyph2Char.begin(),vGlyph2Char.end());
-    }
-#endif
-    gr::Segment * getSegment() { return m_seg; }
-    TextSourceAdaptor * getTextSrc() { return m_text; }
-    void unlock() { --m_lockCount; }
-    bool isRtl() const { return mbIsRtl; }
-#ifdef GRCACHE_REUSE_VECTORS
-    const long & width() const { return mnWidth; }
-    const GraphiteLayout::Glyphs & glyphs() const { return mvGlyphs; }
-    const std::vector<int> & charDxs() const { return mvCharDxs; }
-    const std::vector<int> & char2BaseGlyph() const { return mvChar2BaseGlyph; }
-    const std::vector<int> & glyph2Char() const { return mvGlyph2Char; }
-    float & fontScale() { return m_fontScale; }
-#endif
-private:
-    rtl::OUString * m_rope;
-    TextSourceAdaptor * m_text;
-    gr::Segment * m_seg;
-    const xub_Unicode * m_nextKey;
-    const xub_Unicode*  m_pStr;
-    size_t m_startChar;
-    float m_fontScale;
-    long mnWidth;
-    GraphiteLayout::Glyphs mvGlyphs; // glyphs in display order
-    std::vector<int> mvCharDxs; // right hand side x offset of each glyph
-    std::vector<int> mvChar2BaseGlyph;
-    std::vector<int> mvGlyph2Char;
-    bool mbIsRtl;
-    int m_lockCount;
-    friend class GraphiteSegmentCache;
-};
-
-typedef boost::unordered_map<long, GrSegRecord*, boost::hash<long> > GraphiteSegMap;
-typedef boost::unordered_multimap<size_t, GrSegRecord*> GraphiteRopeMap;
-typedef std::pair<GraphiteRopeMap::iterator, GraphiteRopeMap::iterator> GrRMEntry;
-
-/**
-* GraphiteSegmentCache contains the cached Segments for one particular font size
-*/
-class GraphiteSegmentCache
-{
-public:
-  enum {
-    // not really sure what good values are here,
-    // bucket size should be >> cache size
-    SEG_BUCKET_FACTOR = 4,
-    SEG_DEFAULT_CACHE_SIZE = 2047
-  };
-  GraphiteSegmentCache(sal_uInt32 nSegCacheSize)
-    : m_segMap(nSegCacheSize * SEG_BUCKET_FACTOR),
-    m_nSegCacheSize(nSegCacheSize),
-    m_oldestKey(NULL) {};
-  ~GraphiteSegmentCache()
-  {
-    m_ropeMap.clear();
-    GraphiteSegMap::iterator i = m_segMap.begin();
-    while (i != m_segMap.end())
-    {
-      GrSegRecord *r = i->second;
-      delete r;
-      ++i;
-    }
-    m_segMap.clear();
-  };
-  GrSegRecord * getSegment(ImplLayoutArgs & layoutArgs, bool bIsRtl, int segCharLimit)
-  {
-    GrSegRecord * found = NULL;
-    // try to find a segment starting at correct place, if not, try to find a
-    //  match for the complete buffer
-    GraphiteSegMap::iterator iMap =
-      m_segMap.find(reinterpret_cast<long>(layoutArgs.mpStr +
-                                           layoutArgs.mnMinCharPos));
-    if (iMap != m_segMap.end())
-    {
-      found = iMap->second;
-    }
-    else
-    {
-      iMap = m_segMap.find(reinterpret_cast<long>(layoutArgs.mpStr));
-      if (iMap != m_segMap.end())
-      {
-        found = iMap->second;
-      }
-    }
-    if (found)
-    {
-      if (found->m_seg->startCharacter() <= layoutArgs.mnMinCharPos &&
-          found->m_seg->stopCharacter() >= layoutArgs.mnEndCharPos)
-      {
-        DBG_ASSERT(found && found->m_seg, "null entry in GraphiteSegmentCache");
-        // restore original start character, in case it has changed
-        found->m_seg->setTextSourceOffset(found->m_startChar);
-        // check that characters are the same, at least in the range of
-        // interest
-        // We could use substr and ==, but substr does a copy,
-        // so its probably faster to do it like this
-        for (int i = layoutArgs.mnMinCharPos; i < segCharLimit; i++)
-        {
-          //if (!found->m_rope->match(rtl::OUString(layoutArgs.mpStr[i], layoutArgs.mnLength), i - found->m_seg->startCharacter()))
-          if (found->m_rope->getStr()[i-found->m_seg->startCharacter()] != layoutArgs.mpStr[i])
-            return NULL;
-        }
-        if (found->isRtl() != bIsRtl)
-        {
-            return NULL;
-        }
-        if (found->m_seg->stopCharacter() > layoutArgs.mnEndCharPos &&
-            static_cast<int>(found->char2BaseGlyph().size()) > layoutArgs.mnEndCharPos)
-        {
-            // check that the requested end character isn't mid cluster
-            if (found->char2BaseGlyph()[layoutArgs.mnEndCharPos-layoutArgs.mnMinCharPos] == -1)
-            {
-                return NULL;
-            }
-        }
-//        if (found->m_lockCount != 0)
-//          OutputDebugString("Multple users of SegRecord!");
-        found->m_lockCount++;
-      }
-      else found = NULL;
-    }
-    else
-    {
-      // the pointers aren't the same, but we might still have the same text in a segment
-      // this is expecially needed when editing a large paragraph
-      // each edit changes the pointers, but if we don't reuse any segments it gets very
-      // slow.
-      rtl::OUString * rope = new rtl::OUString(layoutArgs.mpStr + layoutArgs.mnMinCharPos,
-                                         segCharLimit - layoutArgs.mnMinCharPos);
-      if (!rope) return NULL;
-      size_t nHash = (*(rope)).hashCode();
-      GrRMEntry range = m_ropeMap.equal_range(nHash);
-      while (range.first != range.second)
-      {
-        found = range.first->second;
-        if (found->m_lockCount == 0)
-        {
-          if(rope->match(*(found->m_rope)))
-          {
-            // found, but the pointers are all wrong
-            found->m_seg->setTextSourceOffset(layoutArgs.mnMinCharPos);
-            // the switch is done in graphite_layout.cxx
-            //found->m_text->switchLayoutArgs(layoutArgs);
-            found->m_lockCount++;
-            break;
-          }
-          else
-            found = NULL;
-        }
-        else
-          found = NULL;
-        ++(range.first);
-      }
-      delete rope;
-    }
-    return found;
-  };
-  GrSegRecord * cacheSegment(TextSourceAdaptor * adapter, gr::Segment * seg, bool bIsRtl);
-private:
-  GraphiteSegMap m_segMap;
-  GraphiteRopeMap m_ropeMap;
-  sal_uInt32 m_nSegCacheSize;
-  const xub_Unicode * m_oldestKey;
-  const xub_Unicode * m_prevKey;
-};
-
-typedef boost::unordered_map<int, GraphiteSegmentCache *, boost::hash<int> > GraphiteCacheMap;
-
-/**
-* GraphiteCacheHandler maps a particular font, style, size to a GraphiteSegmentCache
-*/
-class GraphiteCacheHandler
-{
-public:
-  GraphiteCacheHandler() : m_cacheMap(255)
-  {
-    const char * pEnvCache = getenv( "SAL_GRAPHITE_CACHE_SIZE" );
-    if (pEnvCache != NULL)
-    {
-        int envCacheSize = atoi(pEnvCache);
-        if (envCacheSize <= 0)
-            m_nSegCacheSize = GraphiteSegmentCache::SEG_DEFAULT_CACHE_SIZE;
-        else
-        {
-            m_nSegCacheSize = envCacheSize;
-        }
-    }
-    else
-    {
-        m_nSegCacheSize = GraphiteSegmentCache::SEG_DEFAULT_CACHE_SIZE;
-    }
-  };
-  ~GraphiteCacheHandler()
-  {
-    GraphiteCacheMap::iterator i = m_cacheMap.begin();
-    while (i != m_cacheMap.end())
-    {
-      GraphiteSegmentCache *r = i->second;
-      delete r;
-      ++i;
-    }
-    m_cacheMap.clear();
-  };
-
-  static GraphiteCacheHandler instance;
-
-  GraphiteSegmentCache * getCache(sal_Int32 & fontHash)
-  {
-    if (m_cacheMap.count(fontHash) > 0)
-    {
-      return m_cacheMap.find(fontHash)->second;
-    }
-    GraphiteSegmentCache *pCache = new GraphiteSegmentCache(m_nSegCacheSize);
-    m_cacheMap[fontHash] = pCache;
-    return pCache;
-  }
-private:
-  GraphiteCacheMap m_cacheMap;
-  sal_uInt32 m_nSegCacheSize;
-};
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/vcl/graphite_features.hxx b/vcl/inc/vcl/graphite_features.hxx
index d02e5e6..e88009b 100644
--- a/vcl/inc/vcl/graphite_features.hxx
+++ b/vcl/inc/vcl/graphite_features.hxx
@@ -30,12 +30,17 @@
 // Parse a string of features specified as ; separated pairs.
 // e.g.
 // 1001=1&2002=2&fav1=0
-#include <graphite/GrClient.h>
-#include <graphite/Font.h>
-#include <graphite/GrFeature.h>
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+#include <graphite2/Font.h>
 
 namespace grutils
 {
+    union FeatId
+    {
+        gr_uint32 num;
+        unsigned char label[5];
+    };
 
     class GrFeatureParser
     {
@@ -44,32 +49,30 @@ namespace grutils
         static const char FEAT_PREFIX;
         static const char FEAT_SEPARATOR;
         static const char FEAT_ID_VALUE_SEPARATOR;
-        GrFeatureParser(gr::Font & font, const std::string features, const std::string lang);
-        GrFeatureParser(gr::Font & font, const std::string lang);
-        GrFeatureParser(const GrFeatureParser & copy);
+        GrFeatureParser(const gr_face * face, const ::rtl::OString features, const ::rtl::OString lang);
+        GrFeatureParser(const gr_face * face, const ::rtl::OString lang);
         ~GrFeatureParser();
-        size_t getFontFeatures(gr::FeatureSetting settings[MAX_FEATURES]) const;
+        //size_t getFontFeatures(gr::FeatureSetting settings[MAX_FEATURES]) const;
         bool parseErrors() { return mbErrors; };
-        static bool isValid(gr::Font & font, gr::FeatureSetting & setting);
-        gr::isocode getLanguage() const { return maLang; };
-        bool hasLanguage() const { return (maLang.rgch[0] != '\0'); }
-        sal_Int32 hashCode() const;
+        //static bool isValid(gr::Font & font, gr::FeatureSetting & setting);
+        gr_uint32 getLanguage() const { return maLang.num; };
+        bool hasLanguage() const { return (maLang.label[0] != '\0'); }
+        sal_Int32 hashCode() const { return mnHash; }
+        size_t numFeatures() const { return mnNumSettings; }
+        gr_feature_val * values() const { return mpSettings; };
     private:
-        void setLang(gr::Font & font, const std::string & lang);
-        bool isCharId(const std::string & id, size_t offset, size_t length);
-        int getCharId(const std::string & id, size_t offset, size_t length);
-        int getIntValue(const std::string & id, size_t offset, size_t length);
+        GrFeatureParser(const GrFeatureParser & copy);
+        void setLang(const gr_face * face, const ::rtl::OString & lang);
+        bool isCharId(const ::rtl::OString & id, size_t offset, size_t length);
+        gr_uint32 getCharId(const ::rtl::OString & id, size_t offset, size_t length);
+        short getIntValue(const ::rtl::OString & id, size_t offset, size_t length);
         size_t mnNumSettings;
-        gr::isocode maLang;
+        FeatId maLang;
         bool mbErrors;
-        gr::FeatureSetting maSettings[64];
+        sal_uInt32 mnHash;
+        gr_feature_val * mpSettings;
     };
 
-    union FeatId
-    {
-        gr::featid num;
-        unsigned char label[5];
-    };
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/vcl/graphite_layout.hxx b/vcl/inc/vcl/graphite_layout.hxx
index dde9461..1c8900f 100644
--- a/vcl/inc/vcl/graphite_layout.hxx
+++ b/vcl/inc/vcl/graphite_layout.hxx
@@ -34,29 +34,19 @@
 // We need this to enable namespace support in libgrengine headers.
 #define GR_NAMESPACE
 
-#define GRCACHE 1
-
 // Standard Library
 #include <memory>
 #include <vector>
+#include <map>
 #include <utility>
 // Libraries
-#include <graphite/GrClient.h>
-#include <graphite/Font.h>
-#include <graphite/GrConstants.h>
-#include <graphite/GrAppData.h>
-#include <graphite/SegmentAux.h>
+#include <graphite2/Font.h>
+#include <graphite2/Segment.h>
 // Platform
 #include <vcl/sallayout.hxx>
 #include <vcl/dllapi.h>
 // Module
 
-// For backwards compatibility with 2.4.x
-#if (SUPD == 680)
-typedef sal_Int32 sal_GlyphId;
-#endif
-
-
 // Module type definitions and forward declarations.
 //
 class TextSourceAdaptor;
@@ -65,21 +55,38 @@ class GrSegRecord;
 // SAL/VCL types
 class ServerFont;
 
-#ifdef WNT
-// The GraphiteWinFont is just a wrapper to enable GrFontHasher to be a friend
-// so that UniqueCacheInfo can be called.
-#include <graphite/WinFont.h>
-class GraphiteWinFont : public gr::WinFont
+// Graphite types
+namespace grutils { class GrFeatureParser; }
+
+class GraphiteFaceWrapper
 {
-    friend class GrFontHasher;
 public:
-    GraphiteWinFont(HDC hdc) : gr::WinFont(hdc) {};
-    virtual ~GraphiteWinFont() {};
+    typedef std::map<int, gr_font*> GrFontMap;
+    GraphiteFaceWrapper(gr_face * pFace) : m_pFace(pFace) {}
+    ~GraphiteFaceWrapper()
+    {
+        GrFontMap::iterator i = m_fonts.begin();
+        while (i != m_fonts.end())
+            gr_font_destroy((*i++).second);
+        m_fonts.clear();
+        gr_face_destroy(m_pFace);
+    }
+    const gr_face * face() const { return m_pFace; }
+    gr_font * font(int ppm) const
+    {
+        GrFontMap::const_iterator i = m_fonts.find(ppm);
+        if (i != m_fonts.end())
+            return i->second;
+        return NULL;
+    };
+    void addFont(int ppm, gr_font * pFont)
+    {
+        m_fonts[ppm] = pFont;
+    }
+private:
+    gr_face * m_pFace;
+    GrFontMap m_fonts;
 };
-#endif
-// Graphite types
-namespace gr { class Segment; class GlyphIterator; }
-namespace grutils { class GrFeatureParser; }
 
 // This class uses the SIL Graphite engine to provide complex text layout services to the VCL
 // @author tse
@@ -87,63 +94,38 @@ namespace grutils { class GrFeatureParser; }
 class VCL_DLLPUBLIC GraphiteLayout : public SalLayout
 {
 public:
-    // Mask to allow Word break status to be stored within mvChar2BaseGlyph
-    enum {
-        WORD_BREAK_BEFORE   = 0x40000000,
-        HYPHEN_BREAK_BEFORE = 0x80000000,
-        BREAK_MASK          = 0xC0000000,
-        GLYPH_INDEX_MASK    = 0x3FFFFFFF
-    } LineBreakMask;
 
     class Glyphs : public std::vector<GlyphItem>
     {
     public:
         typedef std::pair<Glyphs::const_iterator, Glyphs::const_iterator> iterator_pair_t;
 
-        void    fill_from(gr::Segment & rSeg, ImplLayoutArgs & rArgs,
-            bool bRtl, long &rWidth, float fScaling,
-            std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char,
-            std::vector<int> & rCharDxs);
-        void    move_glyph(Glyphs::iterator, long dx);
-
-        const_iterator    cluster_base(const_iterator) const;
-        iterator_pair_t    neighbour_clusters(const_iterator) const;
-    private:
-        std::pair<float,float> appendCluster(gr::Segment & rSeg, ImplLayoutArgs & rArgs,
-            bool bRtl, float fSegmentAdvance, int nFirstCharInCluster, int nNextChar,
-            int nFirstGlyphInCluster, int nNextGlyph, float fScaling,
-            std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char,
-            std::vector<int> & rCharDxs, long & rDXOffset);
-        void         append(gr::Segment & rSeg, ImplLayoutArgs & rArgs, gr::GlyphInfo & rGi, float nextGlyphOrigin, float fScaling, std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char, std::vector<int> & rCharDxs, long & rDXOffset, bool bIsBase);
     };
 
     mutable Glyphs          mvGlyphs;
     void clear();
 
 private:
-    TextSourceAdaptor     * mpTextSrc; // Text source.
-    gr::LayoutEnvironment   maLayout;
-    const gr::Font         &mrFont;
+    const gr_face *         mpFace; // not owned by layout
+    gr_font *               mpFont; // owned by layout
+    int                     mnSegCharOffset; // relative to ImplLayoutArgs::mpStr
     long                    mnWidth;
-    std::vector<int>        mvCharDxs;
     std::vector<int>        mvChar2BaseGlyph;
     std::vector<int>        mvGlyph2Char;
+    std::vector<int>        mvCharDxs;
+    std::vector<int>        mvCharBreaks;
     float                   mfScaling;
     const grutils::GrFeatureParser * mpFeatures;
 
 public:
-    GraphiteLayout(const gr::Font & font, const grutils::GrFeatureParser * features = NULL) throw();
+    GraphiteLayout(const gr_face * pFace, gr_font * pFont = NULL,
+        const grutils::GrFeatureParser * features = NULL) throw();
 
     // used by upper layers
     virtual bool  LayoutText( ImplLayoutArgs& );    // first step of layout
     // split into two stages to allow dc to be restored on the segment
-#ifdef GRCACHE
-    gr::Segment * CreateSegment(ImplLayoutArgs& rArgs, GrSegRecord ** pRecord = NULL);
-    bool LayoutGlyphs(ImplLayoutArgs& rArgs, gr::Segment * pSegment, GrSegRecord * pSegRecord);
-#else
-    gr::Segment * CreateSegment(ImplLayoutArgs& rArgs);
-    bool LayoutGlyphs(ImplLayoutArgs& rArgs, gr::Segment * pSegment);
-#endif
+    gr_segment * CreateSegment(ImplLayoutArgs& rArgs);
+    bool LayoutGlyphs(ImplLayoutArgs& rArgs, gr_segment * pSegment);
 
     virtual void  AdjustLayout( ImplLayoutArgs& );  // adjusting positions
 
@@ -167,19 +149,22 @@ public:
     virtual void    DrawText(SalGraphics&) const {};
 
     virtual ~GraphiteLayout() throw();
+    void SetFont(gr_font * pFont) { mpFont = pFont; }
     void SetFeatures(grutils::GrFeatureParser * aFeature) { mpFeatures = aFeature; }
     void SetFontScale(float s) { mfScaling = s; };
-    const TextSourceAdaptor * textSrc() const { return mpTextSrc; };
     virtual sal_GlyphId getKashidaGlyph(int & width) = 0;
     void kashidaJustify(std::vector<int> & rDeltaWidth, sal_GlyphId, int width);
 
     static const int EXTRA_CONTEXT_LENGTH;
 private:
-    int                   glyph_to_char(Glyphs::iterator);
-    std::pair<int,int>    glyph_to_chars(const GlyphItem &) const;
-
-    std::pair<long,long>  caret_positions(size_t) const;
     void expandOrCondense(ImplLayoutArgs &rArgs);
+    void    fillFrom(gr_segment * rSeg, ImplLayoutArgs & rArgs, float fScaling);
+
+    void append(gr_segment * pSeg,
+                ImplLayoutArgs & rArgs,
+                const gr_slot * pSlot,
+                float nextGlyphOrigin, float fScaling,
+                long & rDXOffset, bool bIsBase, int baseChar);
 };
 
 
diff --git a/vcl/inc/vcl/graphite_serverfont.hxx b/vcl/inc/vcl/graphite_serverfont.hxx
index 21873e0..93f588e 100644
--- a/vcl/inc/vcl/graphite_serverfont.hxx
+++ b/vcl/inc/vcl/graphite_serverfont.hxx
@@ -33,20 +33,20 @@
 #define GR_NAMESPACE
 
 #ifndef MSC
-#include <vcl/graphite_layout.hxx>
-#include <vcl/graphite_adaptors.hxx>
+#include "vcl/graphite_layout.hxx"
 
 // Modules
 
 class VCL_DLLPUBLIC GraphiteLayoutImpl : public GraphiteLayout
 {
 public:
-    GraphiteLayoutImpl(const gr::Font & font, const grutils::GrFeatureParser * features, GraphiteFontAdaptor * pFont) throw()
-    : GraphiteLayout(font, features), mpFont(pFont) {};
+    GraphiteLayoutImpl(const gr_face * pFace,
+                       ServerFont & rServerFont) throw()
+    : GraphiteLayout(pFace), mrServerFont(rServerFont) {};
     virtual ~GraphiteLayoutImpl() throw() {};
     virtual sal_GlyphId getKashidaGlyph(int & width);
 private:
-    GraphiteFontAdaptor * mpFont;
+    ServerFont & mrServerFont;
 };
 
 // This class implments the server font specific parts.
@@ -55,13 +55,19 @@ private:
 class VCL_DLLPUBLIC GraphiteServerFontLayout : public ServerFontLayout
 {
 private:
-        mutable GraphiteFontAdaptor * mpFont;
         // mutable so that the DrawOffset/DrawBase can be set
         mutable GraphiteLayoutImpl maImpl;
+        grutils::GrFeatureParser * mpFeatures;
+        const sal_Unicode * mpStr;
 public:
-        GraphiteServerFontLayout(GraphiteFontAdaptor * font) throw();
+        GraphiteServerFontLayout(ServerFont& pServerFont) throw();
 
-        virtual bool  LayoutText( ImplLayoutArgs& rArgs) { SalLayout::AdjustLayout(rArgs); return maImpl.LayoutText(rArgs); };    // first step of layout
+        virtual bool  LayoutText( ImplLayoutArgs& rArgs)
+        {
+            mpStr = rArgs.mpStr;
+            SalLayout::AdjustLayout(rArgs);
+            return maImpl.LayoutText(rArgs);
+        };    // first step of layout
         virtual void  AdjustLayout( ImplLayoutArgs& rArgs)
         {
             SalLayout::AdjustLayout(rArgs);
@@ -89,8 +95,9 @@ public:
 
         virtual ~GraphiteServerFontLayout() throw();
 
+        static bool IsGraphiteEnabledFont(ServerFont * pServerFont);
 // For use with PspGraphics
-        const sal_Unicode* getTextPtr() const;
+        const sal_Unicode* getTextPtr() const { return mpStr; };
         int getMinCharPos() const { return mnMinCharPos; }
         int getMaxCharPos() const { return mnEndCharPos; }
 };
diff --git a/vcl/source/glyphs/gcach_ftyp.cxx b/vcl/source/glyphs/gcach_ftyp.cxx
index b2e2f29..2db53a5 100644
--- a/vcl/source/glyphs/gcach_ftyp.cxx
+++ b/vcl/source/glyphs/gcach_ftyp.cxx
@@ -39,6 +39,10 @@
 #include "vcl/svapp.hxx"
 #include "vcl/outfont.hxx"
 #include "vcl/impfont.hxx"
+#ifdef ENABLE_GRAPHITE
+#include <graphite2/Font.h>
+#include "vcl/graphite_layout.hxx"
+#endif
 
 #include "tools/poly.hxx"
 #include "basegfx/matrix/b2dhommatrix.hxx"
@@ -290,6 +294,33 @@ void FtFontFile::Unmap()
     mpFileMap = NULL;
 }
 
+#ifdef ENABLE_GRAPHITE
+// wrap FtFontInfo's table function
+const void * graphiteFontTable(const void* appFaceHandle, unsigned int name, size_t *len)
+{
+    const FtFontInfo * pFontInfo = reinterpret_cast<const FtFontInfo*>(appFaceHandle);
+    typedef union {
+        char m_c[5];
+        unsigned int m_id;
+    } TableId;
+    TableId tableId;
+    tableId.m_id = name;
+#ifndef WORDS_BIGENDIAN
+    TableId swapped;
+    swapped.m_c[3] = tableId.m_c[0];
+    swapped.m_c[2] = tableId.m_c[1];
+    swapped.m_c[1] = tableId.m_c[2];
+    swapped.m_c[0] = tableId.m_c[3];
+    tableId.m_id = swapped.m_id;
+#endif
+    tableId.m_c[4] = '\0';
+    ULONG nLength = 0;
+    const void * pTable = static_cast<const void*>(pFontInfo->GetTable(tableId.m_c, &nLength));
+    if (len) *len = static_cast<size_t>(nLength);
+    return pTable;
+}
+#endif
+
 // =======================================================================
 
 FtFontInfo::FtFontInfo( const ImplDevFontAttributes& rDevFontAttributes,
@@ -298,9 +329,15 @@ FtFontInfo::FtFontInfo( const ImplDevFontAttributes& rDevFontAttributes,
 :
     maFaceFT( NULL ),
     mpFontFile( FtFontFile::FindFontFile( rNativeFileName ) ),
+#ifdef ENABLE_GRAPHITE
+    mpGraphiteFace(NULL),
+#endif
     mnFaceNum( nFaceNum ),
     mnRefCount( 0 ),
     mnSynthetic( nSynthetic ),
+#ifdef ENABLE_GRAPHITE
+    mbCheckedGraphite(false),
+#endif
     mnFontId( nFontId ),
     maDevFontAttributes( rDevFontAttributes ),
     mpChar2Glyph( NULL ),
@@ -323,6 +360,10 @@ FtFontInfo::~FtFontInfo()
     delete mpExtraKernInfo;
     delete mpChar2Glyph;
     delete mpGlyph2Char;
+#ifdef ENABLE_GRAPHITE
+    if (mpGraphiteFace)
+        delete mpGraphiteFace;
+#endif
 }
 
 void FtFontInfo::InitHashes() const
@@ -351,6 +392,30 @@ FT_FaceRec_* FtFontInfo::GetFaceFT()
    return maFaceFT;
 }
 
+#ifdef ENABLE_GRAPHITE
+GraphiteFaceWrapper * FtFontInfo::GetGraphiteFace()
+{
+    if (mbCheckedGraphite)
+        return mpGraphiteFace;
+    // test for graphite here so that it is cached most efficiently
+    if (GetTable("Silf", 0))
+    {
+        int graphiteSegCacheSize = 10000;
+        static const char* pGraphiteCacheStr = getenv( "SAL_GRAPHITE_CACHE_SIZE" );
+        graphiteSegCacheSize = pGraphiteCacheStr ? (atoi(pGraphiteCacheStr)) : 0;
+        gr_face * pGraphiteFace;
+        if (graphiteSegCacheSize > 500)
+            pGraphiteFace = gr_make_face_with_seg_cache(this, graphiteFontTable, graphiteSegCacheSize, gr_face_cacheCmap);
+        else
+            pGraphiteFace = gr_make_face(this, graphiteFontTable, gr_face_cacheCmap);
+        if (pGraphiteFace)
+            mpGraphiteFace = new GraphiteFaceWrapper(pGraphiteFace);
+    }
+    mbCheckedGraphite = true;
+    return mpGraphiteFace;
+}
+#endif
+
 // -----------------------------------------------------------------------
 
 void FtFontInfo::ReleaseFaceFT( FT_FaceRec_* pFaceFT )
diff --git a/vcl/source/glyphs/gcach_ftyp.hxx b/vcl/source/glyphs/gcach_ftyp.hxx
index 3f2b890..cf2284c 100644
--- a/vcl/source/glyphs/gcach_ftyp.hxx
+++ b/vcl/source/glyphs/gcach_ftyp.hxx
@@ -36,6 +36,10 @@
 #include FT_FREETYPE_H
 
 class FreetypeServerFont;
+#ifdef ENABLE_GRAPHITE
+class GraphiteFaceWrapper;
+#endif
+
 struct FT_GlyphRec_;
 
 // -----------------------------------------------------------------------
@@ -81,6 +85,9 @@ public:
     const unsigned char*  GetTable( const char*, ULONG* pLength=0 ) const;
 
     FT_FaceRec_*          GetFaceFT();
+#ifdef ENABLE_GRAPHITE
+    GraphiteFaceWrapper*  GetGraphiteFace();
+#endif
     void                  ReleaseFaceFT( FT_FaceRec_* );
 
     const ::rtl::OString* GetFontFileName() const   { return mpFontFile->GetFileName(); }
@@ -105,7 +112,10 @@ private:
     const int       mnFaceNum;
     int             mnRefCount;
     const int       mnSynthetic;
-
+#ifdef ENABLE_GRAPHITE
+    bool            mbCheckedGraphite;
+    GraphiteFaceWrapper * mpGraphiteFace;
+#endif
     sal_IntPtr      mnFontId;
     ImplDevFontAttributes maDevFontAttributes;
 
@@ -198,6 +208,9 @@ public:
                                 { return mpFontInfo->GetTable( pName, pLength ); }
     int                         GetEmUnits() const;
     const FT_Size_Metrics&      GetMetricsFT() const { return maSizeFT->metrics; }
+#ifdef ENABLE_GRAPHITE
+    GraphiteFaceWrapper*        GetGraphiteFace() const { return mpFontInfo->GetGraphiteFace(); }
+#endif
 
 protected:
     friend class GlyphCache;
diff --git a/vcl/source/glyphs/graphite_adaptors.cxx b/vcl/source/glyphs/graphite_adaptors.cxx
deleted file mode 100644
index f559254..0000000
--- a/vcl/source/glyphs/graphite_adaptors.cxx
+++ /dev/null
@@ -1,339 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org.  If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// Description: Implements the Graphite interfaces with access to the
-//              platform's font and graphics systems.
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_vcl.hxx"
-
-// We need this to enable namespace support in libgrengine headers.
-#define GR_NAMESPACE
-
-// Header files
-//
-// Standard Library
-#include <string>
-#include <cassert>
-// Libraries
-#include <rtl/string.hxx>
-#include <rtl/ustring.hxx>
-#include <i18npool/mslangid.hxx>
-// Platform
-#ifndef WNT
-#include <saldisp.hxx>
-
-#include <vcl/salgdi.hxx>
-
-#include <freetype/ftsynth.h>
-
-// Module
-#include "gcach_ftyp.hxx"
-
-#include <vcl/graphite_features.hxx>
-#include <vcl/graphite_adaptors.hxx>
-
-// Module private type definitions and forward declarations.
-//
-using gr::GrResult;
-namespace
-{
-    inline float from_hinted(const int x) {
-        return static_cast<float>(x + 32) / 64.0;
-    }
-    typedef boost::unordered_map<long,bool> SilfMap;
-}
-extern FT_Error (*pFTEmbolden)(FT_GlyphSlot);
-extern FT_Error (*pFTOblique)(FT_GlyphSlot);
-
-// class CharacterRenderProperties implentation.
-//
-FontProperties::FontProperties(const FreetypeServerFont &font) throw()
-{
-    clrFore = gr::kclrBlack;
-    clrBack = gr::kclrTransparent;
-
-    pixHeight = from_hinted(font.GetMetricsFT().height);
-
-    switch (font.GetFontSelData().meWeight)
-    {
-        case WEIGHT_SEMIBOLD: case WEIGHT_BOLD:
-        case WEIGHT_ULTRABOLD: case WEIGHT_BLACK:
-            fBold = true;
-            break;
-        default :
-            fBold = false;
-    }
-
-    switch (font.GetFontSelData().meItalic)
-    {
-        case ITALIC_NORMAL: case ITALIC_OBLIQUE:
-            fItalic = true;
-            break;
-        default :
-            fItalic = false;
-    }
-
-    // Get the font name, but prefix with file name hash in case
-    // there are 2 fonts on the system with the same face name
-    sal_Int32 nHashCode = font.GetFontFileName()->hashCode();
-    ::rtl::OUStringBuffer nHashFaceName;
-    nHashFaceName.append(nHashCode, 16);
-    const sal_Unicode    * name = font.GetFontSelData().maName.GetBuffer();
-    nHashFaceName.append(name);
-
-    const size_t name_sz = std::min(sizeof szFaceName/sizeof(wchar_t)-1,
-                    static_cast<size_t>(nHashFaceName.getLength()));
-
-    std::copy(nHashFaceName.getStr(), nHashFaceName.getStr() + name_sz, szFaceName);
-    szFaceName[name_sz] = '\0';
-}
-
-// class GraphiteFontAdaptor implementaion.
-//
-GraphiteFontAdaptor::GraphiteFontAdaptor(ServerFont & sfont, const sal_Int32 dpiX, const sal_Int32 dpiY)
-  :    mrFont(static_cast<FreetypeServerFont &>(sfont)),
-    maFontProperties(static_cast<FreetypeServerFont &>(sfont)),
-    mnDpiX(dpiX),
-    mnDpiY(dpiY),
-    mfAscent(from_hinted(static_cast<FreetypeServerFont &>(sfont).GetMetricsFT().ascender)),
-    mfDescent(from_hinted(static_cast<FreetypeServerFont &>(sfont).GetMetricsFT().descender)),
-    mfEmUnits(static_cast<FreetypeServerFont &>(sfont).GetMetricsFT().y_ppem),
-    mpFeatures(NULL)
-{
-    const rtl::OString aLang = MsLangId::convertLanguageToIsoByteString( sfont.GetFontSelData().meLanguage );
-    rtl::OString name = rtl::OUStringToOString(
-        sfont.GetFontSelData().maTargetName, RTL_TEXTENCODING_UTF8 );
-#ifdef DEBUG
-    printf("GraphiteFontAdaptor %lx %s italic=%u bold=%u\n", (long)this, name.getStr(),
-           maFontProperties.fItalic, maFontProperties.fBold);
-#endif
-    sal_Int32 nFeat = name.indexOf(grutils::GrFeatureParser::FEAT_PREFIX) + 1;
-    if (nFeat > 0)
-    {
-        rtl::OString aFeat = name.copy(nFeat, name.getLength() - nFeat);
-        mpFeatures = new grutils::GrFeatureParser(*this, aFeat.getStr(), aLang.getStr());
-#ifdef DEBUG
-        printf("GraphiteFontAdaptor %s/%s/%s %x language %d features %d errors\n",
-            rtl::OUStringToOString( sfont.GetFontSelData().maName,
-            RTL_TEXTENCODING_UTF8 ).getStr(),
-            rtl::OUStringToOString( sfont.GetFontSelData().maTargetName,
-            RTL_TEXTENCODING_UTF8 ).getStr(),
-            rtl::OUStringToOString( sfont.GetFontSelData().maSearchName,
-            RTL_TEXTENCODING_UTF8 ).getStr(),
-            sfont.GetFontSelData().meLanguage,
-            (int)mpFeatures->getFontFeatures(NULL), mpFeatures->parseErrors());
-#endif
-    }
-    else
-    {
-        mpFeatures = new grutils::GrFeatureParser(*this, aLang.getStr());
-    }
-}
-
-GraphiteFontAdaptor::GraphiteFontAdaptor(const GraphiteFontAdaptor &rhs) throw()
- :    Font(rhs),
-     mrFont (rhs.mrFont), maFontProperties(rhs.maFontProperties),
-    mnDpiX(rhs.mnDpiX), mnDpiY(rhs.mnDpiY),
-    mfAscent(rhs.mfAscent), mfDescent(rhs.mfDescent), mfEmUnits(rhs.mfEmUnits),
-    mpFeatures(NULL)
-{
-    if (rhs.mpFeatures) mpFeatures = new grutils::GrFeatureParser(*(rhs.mpFeatures));
-}
-
-
-GraphiteFontAdaptor::~GraphiteFontAdaptor() throw()
-{
-    maGlyphMetricMap.clear();
-    if (mpFeatures) delete mpFeatures;
-    mpFeatures = NULL;
-}
-
-void GraphiteFontAdaptor::UniqueCacheInfo(std::wstring & face_name_out, bool & bold_out, bool & italic_out)
-{
-    face_name_out = maFontProperties.szFaceName;
-    bold_out = maFontProperties.fBold;
-    italic_out = maFontProperties.fItalic;
-}
-
-bool GraphiteFontAdaptor::IsGraphiteEnabledFont(ServerFont & font) throw()
-{
-    static SilfMap sSilfMap;
-    // NOTE: this assumes that the same FTFace pointer won't be reused,
-    // so FtFontInfo::ReleaseFaceFT must only be called at shutdown.
-    FreetypeServerFont & aFtFont = dynamic_cast<FreetypeServerFont &>(font);
-    FT_Face aFace = reinterpret_cast<FT_FaceRec_*>(aFtFont.GetFtFace());
-    SilfMap::iterator i = sSilfMap.find(reinterpret_cast<long>(aFace));
-    if (i != sSilfMap.end())
-    {
-#ifdef DEBUG
-        if (static_cast<bool>(aFtFont.GetTable("Silf", 0)) != (*i).second)
-            printf("Silf cache font mismatch\n");
-#endif
-        return (*i).second;
-    }
-    bool bHasSilf = aFtFont.GetTable("Silf", 0);
-    sSilfMap[reinterpret_cast<long>(aFace)] = bHasSilf;
-    return bHasSilf;
-}
-
-
-gr::Font * GraphiteFontAdaptor::copyThis() {
-    return new GraphiteFontAdaptor(*this);
-}
-
-
-unsigned int GraphiteFontAdaptor::getDPIx() {
-    return mnDpiX;
-}
-
-
-unsigned int GraphiteFontAdaptor::getDPIy() {
-    return mnDpiY;
-}
-
-
-float GraphiteFontAdaptor::ascent() {
-    return mfAscent;
-}
-
-
-float GraphiteFontAdaptor::descent() {
-    return mfDescent;
-}
-
-
-bool GraphiteFontAdaptor::bold() {
-    return maFontProperties.fBold;
-}
-
-
-bool GraphiteFontAdaptor::italic() {
-    return maFontProperties.fItalic;
-}
-
-
-float GraphiteFontAdaptor::height() {
-    return maFontProperties.pixHeight;
-}
-
-
-void GraphiteFontAdaptor::getFontMetrics(float * ascent_out, float * descent_out, float * em_square_out) {
-    if (ascent_out)        *ascent_out    = mfAscent;
-    if (descent_out)    *descent_out   = mfDescent;
-    if (em_square_out)    *em_square_out = mfEmUnits;
-}
-
-
-const void * GraphiteFontAdaptor::getTable(gr::fontTableId32 table_id, size_t * buffer_sz)
-{
-    char tag_name[5] = {char(table_id >> 24), char(table_id >> 16), char(table_id >> 8), char(table_id), 0};
-    ULONG temp = *buffer_sz;
-
-    const void * const tbl_buf = static_cast<FreetypeServerFont &>(mrFont).GetTable(tag_name, &temp);
-    *buffer_sz = temp;
-
-    return tbl_buf;
-}
-
-#define fix26_6(x) (x >> 6) + (x & 32 ? (x > 0 ? 1 : 0) : (x < 0 ? -1 : 0))
-
-// Return the glyph's metrics in pixels.
-void GraphiteFontAdaptor::getGlyphMetrics(gr::gid16 nGlyphId, gr::Rect & aBounding, gr::Point & advances)
-{
-    // There used to be problems when orientation was set however, this no
-    // longer seems to be the case and the Glyph Metric cache in
-    // FreetypeServerFont is more efficient since it lasts between calls to VCL
-#if 1
-    const GlyphMetric & metric = mrFont.GetGlyphMetric(nGlyphId);
-
-    aBounding.right  = aBounding.left = metric.GetOffset().X();
-    aBounding.bottom = aBounding.top  = -metric.GetOffset().Y();
-    aBounding.right  += metric.GetSize().Width();
-    aBounding.bottom -= metric.GetSize().Height();
-
-    advances.x = metric.GetDelta().X();
-    advances.y = -metric.GetDelta().Y();
-
-#else
-    // The problem with the code below is that the cache only lasts
-    // as long as the life time of the GraphiteFontAdaptor, which
-    // is created once per call to X11SalGraphics::GetTextLayout
-    GlyphMetricMap::const_iterator gm_itr = maGlyphMetricMap.find(nGlyphId);
-    if (gm_itr != maGlyphMetricMap.end())
-    {
-        // We've cached the results from last time.
-        aBounding = gm_itr->second.first;
-        advances    = gm_itr->second.second;
-    }
-    else
-    {
-        // We need to look up the glyph.
-        FT_Int nLoadFlags = mrFont.GetLoadFlags();
-
-        FT_Face aFace = reinterpret_cast<FT_Face>(mrFont.GetFtFace());
-        if (!aFace)
-        {
-            aBounding.top = aBounding.bottom = aBounding.left = aBounding.right = 0;
-            advances.x = advances.y = 0;
-            return;
-        }
-        FT_Error aStatus = -1;
-        aStatus = FT_Load_Glyph(aFace, nGlyphId, nLoadFlags);
-        if( aStatus != FT_Err_Ok || (!aFace->glyph))
-        {
-            aBounding.top = aBounding.bottom = aBounding.left = aBounding.right = 0;
-            advances.x = advances.y = 0;
-            return;
-        }
-        // check whether we need synthetic bold/italic otherwise metric is wrong
-        if (mrFont.NeedsArtificialBold() && pFTEmbolden)
-            (*pFTEmbolden)(aFace->glyph);
-
-        if (mrFont.NeedsArtificialItalic() && pFTOblique)
-            (*pFTOblique)(aFace->glyph);
-
-        const FT_Glyph_Metrics &gm = aFace->glyph->metrics;
-
-        // Fill out the bounding box an advances.
-        aBounding.top = aBounding.bottom = fix26_6(gm.horiBearingY);
-        aBounding.bottom -= fix26_6(gm.height);
-        aBounding.left = aBounding.right = fix26_6(gm.horiBearingX);
-        aBounding.right += fix26_6(gm.width);
-        advances.x = fix26_6(gm.horiAdvance);
-        advances.y = 0;
-
-        // Now add an entry to our metrics map.
-        maGlyphMetricMap[nGlyphId] = std::make_pair(aBounding, advances);
-    }
-#endif
-}
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/glyphs/graphite_cache.cxx b/vcl/source/glyphs/graphite_cache.cxx
deleted file mode 100644
index 76450a2..0000000
--- a/vcl/source/glyphs/graphite_cache.cxx
+++ /dev/null
@@ -1,201 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org.  If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_vcl.hxx"
-
-#ifdef WNT
-#include <tools/svwin.h>
-#include <svsys.h>
-#endif
-
-#include <tools/debug.hxx>
-#include <vcl/sallayout.hxx>
-
-#include <graphite/GrClient.h>
-#include <graphite/Segment.h>
-
-#include <rtl/ustring.hxx>
-#include <vcl/graphite_layout.hxx>
-#include <vcl/graphite_cache.hxx>
-
-#include "graphite_textsrc.hxx"
-
-GrSegRecord::GrSegRecord(rtl::OUString * rope, TextSourceAdaptor * textSrc, gr::Segment * seg, bool bIsRtl)
-    : m_rope(rope), m_text(textSrc), m_seg(seg), m_nextKey(NULL),
-    m_fontScale(0.0f), mbIsRtl(bIsRtl), m_lockCount(0)
-{
-    m_pStr = textSrc->getLayoutArgs().mpStr + seg->startCharacter();
-    m_startChar = seg->startCharacter();
-}
-
-GrSegRecord::~GrSegRecord()
-{
-    clear();
-}
-
-void GrSegRecord::reuse(rtl::OUString * rope, TextSourceAdaptor * textSrc, gr::Segment * seg, bool bIsRtl)
-{
-    clear();
-    mnWidth = 0;
-    m_rope = rope;
-    m_text = textSrc;
-    m_seg = seg;
-    m_nextKey = NULL;
-    m_pStr = textSrc->getLayoutArgs().mpStr + seg->startCharacter();
-    m_startChar = seg->startCharacter();
-    mbIsRtl = bIsRtl;
-}
-
-void GrSegRecord::clearVectors()
-{
-    mvGlyphs.clear();
-    mvCharDxs.clear();
-    mvChar2BaseGlyph.clear();
-    mvGlyph2Char.clear();
-}
-
-void GrSegRecord::clear()
-{
-#ifdef GR_DEBUG_TEXT
-    if (m_lockCount != 0)
-      OutputDebugString("GrSegRecord locked!");
-#endif
-    clearVectors();
-    delete m_rope;
-    delete m_seg;
-    delete m_text;
-    m_rope = NULL;
-    m_seg = NULL;
-    m_text = NULL;
-    m_fontScale = 0.0f;
-    m_lockCount = 0;
-}
-
-GrSegRecord * GraphiteSegmentCache::cacheSegment(TextSourceAdaptor * adapter, gr::Segment * seg, bool bIsRtl)
-{
-    GrSegRecord * record = NULL;
-    // We keep a record of the oldest key and the last key added
-    // when the next key is added, the record for the prevKey's m_nextKey field
-    // is updated to the newest key so that m_oldestKey can be updated to the
-    // next oldest key when the record for m_oldestKey is deleted
-    if (m_segMap.size() > m_nSegCacheSize)
-    {
-      GraphiteSegMap::iterator oldestPair = m_segMap.find(reinterpret_cast<long>(m_oldestKey));
-      // oldest record may no longer exist if a buffer was changed
-      if (oldestPair != m_segMap.end())
-      {
-        record = oldestPair->second;
-        m_segMap.erase(reinterpret_cast<long>(m_oldestKey));
-        GrRMEntry range = m_ropeMap.equal_range((*(record->m_rope)).hashCode());
-        while (range.first != range.second)
-        {
-          if (range.first->second == record)
-          {
-            m_ropeMap.erase(range.first);
-            break;
-          }
-          ++range.first;
-        }
-        m_oldestKey = record->m_nextKey;
-        // record will be reused, so don't delete
-      }
-    }
-
-
-//    const int seg_char_limit = min(adapter->maLayoutArgs().mnLength,
-//      adapter->maLayoutArgs().mnEndCharPos
-//      + GraphiteLayout::EXTRA_CONTEXT_LENGTH);
-//    if (seg->stopCharacter() - seg->startCharacter() <= 0)
-//      OutputDebugString("Invalid seg indices\n");
-    rtl::OUString * pRope = new rtl::OUString(adapter->getLayoutArgs().mpStr + seg->startCharacter(),
-       seg->stopCharacter() - seg->startCharacter());
-    if (!pRope) return NULL;
-    bool reuse = false;
-    if (record)
-      record->reuse(pRope, adapter, seg, bIsRtl);
-    else
-      record = new GrSegRecord(pRope, adapter, seg, bIsRtl);
-    if (!record)
-    {
-      delete pRope;
-      return NULL;
-    }
-    GraphiteSegMap::iterator iMap =
-      m_segMap.find(reinterpret_cast<long>(record->m_pStr));
-    if (iMap != m_segMap.end())
-    {
-      // the buffer has changed, so the old cached Segment is useless
-      reuse = true;
-      GrSegRecord * found = iMap->second;
-      // Note: we reuse the old next key to avoid breaking our history
-      // chain. This means it will be prematurely deleted, but this is
-      // unlikely to happen very often.
-      record->m_nextKey = found->m_nextKey;
-      // overwrite the old record
-      m_segMap[reinterpret_cast<long>(record->m_pStr)] = record;
-      // erase the old rope key and save the new one
-      GrRMEntry range = m_ropeMap.equal_range((*(found->m_rope)).hashCode());
-      while (range.first != range.second)
-      {
-        if (range.first->second == found)
-        {
-          m_ropeMap.erase(range.first);
-          break;
-        }
-        ++range.first;
-      }
-      GraphiteRopeMap::value_type mapEntry(record->m_rope->hashCode(), record);
-      m_ropeMap.insert(mapEntry);
-      // remove the old record
-      delete found;
-      record->m_lockCount++;
-      return record;
-    }
-    m_segMap[reinterpret_cast<long>(record->m_pStr)] = record;
-    GraphiteRopeMap::value_type mapEntry((*(record->m_rope)).hashCode(), record);
-    m_ropeMap.insert(mapEntry);
-
-    if (m_oldestKey == NULL)
-    {
-      m_oldestKey = record->m_pStr;
-      m_prevKey = record->m_pStr;
-    }
-    else if (reuse == false)
-    {
-      DBG_ASSERT(m_segMap.count(reinterpret_cast<long>(m_prevKey)),
-        "Previous key got lost somehow!");
-      m_segMap.find(reinterpret_cast<long>(m_prevKey))
-        ->second->m_nextKey = record->m_pStr;
-      m_prevKey = record->m_pStr;
-    }
-    record->m_lockCount++;
-    return record;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/glyphs/graphite_features.cxx b/vcl/source/glyphs/graphite_features.cxx
index f5e6aa9..6445765 100644
--- a/vcl/source/glyphs/graphite_features.cxx
+++ b/vcl/source/glyphs/graphite_features.cxx
@@ -49,79 +49,107 @@ const char GrFeatureParser::FEAT_PREFIX = ':';
 const char GrFeatureParser::FEAT_SEPARATOR = '&';
 const char GrFeatureParser::FEAT_ID_VALUE_SEPARATOR = '=';
 
-GrFeatureParser::GrFeatureParser(gr::Font & font, const std::string lang)
-    : mnNumSettings(0), mbErrors(false)
+GrFeatureParser::GrFeatureParser(const gr_face * pFace, const ::rtl::OString lang)
+    : mnNumSettings(0), mbErrors(false), mpSettings(NULL)
 {
-    maLang.rgch[0] = maLang.rgch[1] = maLang.rgch[2] = maLang.rgch[3] = '\0';
-    setLang(font, lang);
+    maLang.label[0] = maLang.label[1] = maLang.label[2] = maLang.label[3] = '\0';
+    setLang(pFace, lang);
 }
 
-GrFeatureParser::GrFeatureParser(gr::Font & font, const std::string features, const std::string lang)
-    : mnNumSettings(0), mbErrors(false)
+GrFeatureParser::GrFeatureParser(const gr_face * pFace, const ::rtl::OString features, const ::rtl::OString lang)
+    : mnNumSettings(0), mbErrors(false), mpSettings(NULL)
 {
-    size_t nEquals = 0;
-    size_t nFeatEnd = 0;
-    size_t pos = 0;
-    maLang.rgch[0] = maLang.rgch[1] = maLang.rgch[2] = maLang.rgch[3] = '\0';
-    setLang(font, lang);
-    while (pos < features.length() && mnNumSettings < MAX_FEATURES)
+    sal_Int32 nEquals = 0;
+    sal_Int32 nFeatEnd = 0;
+    sal_Int32 pos = 0;
+    maLang.num = 0u;
+    setLang(pFace, lang);
+    while ((pos < features.getLength()) && (mnNumSettings < MAX_FEATURES))
     {
-        nEquals = features.find(FEAT_ID_VALUE_SEPARATOR,pos);
-        if (nEquals == std::string::npos)
+        nEquals = features.indexOf(FEAT_ID_VALUE_SEPARATOR, pos);
+        if (nEquals == -1)
         {
             mbErrors = true;
             break;
         }
         // check for a lang=xxx specification
-        if (features.compare(pos, nEquals - pos, "lang") == 0)
+        const ::rtl::OString aLangPrefix("lang");
+        if (features.match(aLangPrefix, pos ))
         {
             pos = nEquals + 1;
-            nFeatEnd = features.find(FEAT_SEPARATOR, pos);
-            if (nFeatEnd == std::string::npos)
+            nFeatEnd = features.indexOf(FEAT_SEPARATOR, pos);
+            if (nFeatEnd == -1)
             {
-                nFeatEnd = features.length();
+                nFeatEnd = features.getLength();
             }
             if (nFeatEnd - pos > 3)
                 mbErrors = true;
             else
             {
-                gr::isocode aLang = maLang;
-                for (size_t i = pos; i < nFeatEnd; i++)
-                    aLang.rgch[i-pos] = features[i];
-                std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported
-                    = font.getSupportedLanguages();
-                gr::LanguageIterator iL = aSupported.first;
-                while (iL != aSupported.second)
+                FeatId aLang = maLang;
+                aLang.num = 0;
+                for (sal_Int32 i = pos; i < nFeatEnd; i++)
+                    aLang.label[i-pos] = features[i];
+
+                //ext_std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported
+                //    = font.getSupportedLanguages();
+                //gr::LanguageIterator iL = aSupported.first;
+                unsigned short i = 0;
+                for (; i < gr_face_n_languages(pFace); i++)
                 {
-                    gr::isocode aSupportedLang = *iL;
+                    gr_uint32 nFaceLang = gr_face_lang_by_index(pFace, i);
+                    FeatId aSupportedLang;
+                    aSupportedLang.num = nFaceLang;
+#ifdef __BIG_ENDIAN__
                     // here we only expect full 3 letter codes
-                    if (aLang.rgch[0] == aSupportedLang.rgch[0] &&
-                        aLang.rgch[1] == aSupportedLang.rgch[1] &&
-                        aLang.rgch[2] == aSupportedLang.rgch[2] &&
-                        aLang.rgch[3] == aSupportedLang.rgch[3]) break;
-                    ++iL;
+                    if (aLang.label[0] == aSupportedLang.label[0] &&
+                        aLang.label[1] == aSupportedLang.label[1] &&
+                        aLang.label[2] == aSupportedLang.label[2] &&
+                        aLang.label[3] == aSupportedLang.label[3])
+#else
+                    if (aLang.label[0] == aSupportedLang.label[3] &&
+                        aLang.label[1] == aSupportedLang.label[2] &&
+                        aLang.label[2] == aSupportedLang.label[1] &&
+                        aLang.label[3] == aSupportedLang.label[0])
+#endif
+                    {
+                        maLang = aSupportedLang;
+                        break;
+                    }
+                }
+                if (i == gr_face_n_languages(pFace)) mbErrors = true;
+                else
+                {
+                    mnHash = maLang.num;
+                    mpSettings = gr_face_featureval_for_lang(pFace, maLang.num);
                 }
-                if (iL == aSupported.second) mbErrors = true;
-                else maLang = aLang;
             }
         }
         else
         {
+            sal_uInt32 featId = 0;
             if (isCharId(features, pos, nEquals - pos))
-                maSettings[mnNumSettings].id = getCharId(features, pos, nEquals - pos);
-            else maSettings[mnNumSettings].id = getIntValue(features, pos, nEquals - pos);
-            pos = nEquals + 1;
-            nFeatEnd = features.find(FEAT_SEPARATOR, pos);
-            if (nFeatEnd == std::string::npos)
             {
-                nFeatEnd = features.length();
+                featId = getCharId(features, pos, nEquals - pos);
             }
-            if (isCharId(features, pos, nFeatEnd - pos))
-                maSettings[mnNumSettings].value = getCharId(features, pos, nFeatEnd - pos);
             else
-                maSettings[mnNumSettings].value= getIntValue(features, pos, nFeatEnd - pos);
-            if (isValid(font, maSettings[mnNumSettings]))
+            {
+                featId = getIntValue(features, pos, nEquals - pos);
+            }
+            const gr_feature_ref * pFref = gr_face_find_fref(pFace, featId);
+            pos = nEquals + 1;
+            nFeatEnd = features.indexOf(FEAT_SEPARATOR, pos);
+            if (nFeatEnd == -1)
+            {
+                nFeatEnd = features.getLength();
+            }
+            sal_Int16 featValue = 0;
+            featValue = getIntValue(features, pos, nFeatEnd - pos);
+            if (pFref && gr_fref_set_feature_value(pFref, featValue, mpSettings))
+            {
+                mnHash = (mnHash << 16) ^ ((featId << 8) | featValue);
                 mnNumSettings++;
+            }
             else
                 mbErrors = true;
         }
@@ -129,89 +157,80 @@ GrFeatureParser::GrFeatureParser(gr::Font & font, const std::string features, co
     }
 }
 
-void GrFeatureParser::setLang(gr::Font & font, const std::string & lang)
+void GrFeatureParser::setLang(const gr_face * pFace, const rtl::OString & lang)
 {
-    gr::isocode aLang = {{0,0,0,0}};
-    if (lang.length() > 2)
+    FeatId aLang;
+    aLang.num = 0;
+    if (lang.getLength() > 2)
     {
-        for (size_t i = 0; i < lang.length() && i < 3; i++)
+        for (sal_Int32 i = 0; i < lang.getLength() && i < 3; i++)
         {
             if (lang[i] == '-') break;
-            aLang.rgch[i] = lang[i];
+            aLang.label[i] = lang[i];
         }
-        std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported
-                    = font.getSupportedLanguages();
-        gr::LanguageIterator iL = aSupported.first;
-        while (iL != aSupported.second)
+        unsigned short i = 0;
+        for (; i < gr_face_n_languages(pFace); i++)
         {
-            gr::isocode aSupportedLang = *iL;
-            if (aLang.rgch[0] == aSupportedLang.rgch[0] &&
-                aLang.rgch[1] == aSupportedLang.rgch[1] &&
-                aLang.rgch[2] == aSupportedLang.rgch[2] &&
-                aLang.rgch[3] == aSupportedLang.rgch[3]) break;
-            ++iL;
-        }
-        if (iL != aSupported.second)
-            maLang = aLang;
-#ifdef DEBUG
-        else
-            printf("%s has no features\n", aLang.rgch);
+            gr_uint32 nFaceLang = gr_face_lang_by_index(pFace, i);
+            FeatId aSupportedLang;
+            aSupportedLang.num = nFaceLang;
+            // here we only expect full 2 & 3 letter codes
+#ifdef __BIG_ENDIAN__
+            if (aLang.label[0] == aSupportedLang.label[0] &&
+                aLang.label[1] == aSupportedLang.label[1] &&
+                aLang.label[2] == aSupportedLang.label[2] &&
+                aLang.label[3] == aSupportedLang.label[3])
+#else
+            if (aLang.label[0] == aSupportedLang.label[3] &&
+                aLang.label[1] == aSupportedLang.label[2] &&
+                aLang.label[2] == aSupportedLang.label[1] &&
+                aLang.label[3] == aSupportedLang.label[0])
 #endif
+            {
+                maLang = aSupportedLang;
+                break;
+            }
+        }
+        if (i != gr_face_n_languages(pFace))
+        {
+            if (mpSettings)
+            {
+                gr_featureval_destroy(mpSettings);
+            }
+            mpSettings = gr_face_featureval_for_lang(pFace, maLang.num);
+            mnHash = maLang.num;
+        }
     }
-}
-
-GrFeatureParser::GrFeatureParser(const GrFeatureParser & aCopy)
- : maLang(aCopy.maLang), mbErrors(aCopy.mbErrors)
-{
-    mnNumSettings = aCopy.getFontFeatures(maSettings);
-}
-
-GrFeatureParser::~GrFeatureParser()
-{
-}
-
-size_t GrFeatureParser::getFontFeatures(gr::FeatureSetting settings[64]) const
-{
-    if (settings)
+    if (!mpSettings)
     {
-        std::copy(maSettings, maSettings + mnNumSettings, settings);
+        mpSettings = gr_face_featureval_for_lang(pFace, 0);
     }
-    return mnNumSettings;
 }
 
-bool GrFeatureParser::isValid(gr::Font & font, gr::FeatureSetting & setting)
+GrFeatureParser::~GrFeatureParser()
 {
-    gr::FeatureIterator i = font.featureWithID(setting.id);
-    if (font.getFeatures().second == i)
+    if (mpSettings)
     {
-        return false;
+        gr_featureval_destroy(mpSettings);
+        mpSettings = NULL;
     }
-    std::pair< gr::FeatureSettingIterator, gr::FeatureSettingIterator >
-        validValues = font.getFeatureSettings(i);
-    gr::FeatureSettingIterator j = validValues.first;
-    while (j != validValues.second)
-    {
-        if (*j == setting.value) return true;
-        ++j;
-    }
-    return false;
 }
 
-bool GrFeatureParser::isCharId(const std::string & id, size_t offset, size_t length)
+bool GrFeatureParser::isCharId(const rtl::OString & id, size_t offset, size_t length)
 {
     if (length > 4) return false;
     for (size_t i = 0; i < length; i++)
     {
         if (i > 0 && id[offset+i] == '\0') continue;
-        if ((id[offset+i]) < 0x20 || (id[offset+i]) < 0)
+        if ((id[offset+i] < 0x20) || (id[offset+i] < 0))
             return false;
-        if (i==0 && id[offset+i] < 0x41)
+        if (i==0 && (id[offset+i] < 0x41))
             return false;
     }
     return true;
 }
 
-int GrFeatureParser::getCharId(const std::string & id, size_t offset, size_t length)
+gr_uint32 GrFeatureParser::getCharId(const rtl::OString & id, size_t offset, size_t length)
 {
     FeatId charId;
     charId.num = 0;
@@ -229,9 +248,9 @@ int GrFeatureParser::getCharId(const std::string & id, size_t offset, size_t len
     return charId.num;
 }
 
-int GrFeatureParser::getIntValue(const std::string & id, size_t offset, size_t length)
+short GrFeatureParser::getIntValue(const rtl::OString & id, size_t offset, size_t length)
 {
-    int value = 0;
+    short value = 0;
     int sign = 1;
     for (size_t i = 0; i < length; i++)
     {
@@ -271,18 +290,4 @@ int GrFeatureParser::getIntValue(const std::string & id, size_t offset, size_t l
     return value;
 }
 
-
-sal_Int32 GrFeatureParser::hashCode() const
-{
-    union IsoHash { sal_Int32 mInt; gr::isocode mCode; };
-    IsoHash isoHash;
-    isoHash.mCode = maLang;
-    sal_Int32 hash = isoHash.mInt;
-    for (size_t i = 0; i < mnNumSettings; i++)
-    {
-        hash = (hash << 16) ^ ((maSettings[i].id << 8) | maSettings[i].value);
-    }
-    return hash;
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx
index 80a300a..c4053c2 100644
--- a/vcl/source/glyphs/graphite_layout.cxx
+++ b/vcl/source/glyphs/graphite_layout.cxx
@@ -37,8 +37,9 @@
 
 // Enable lots of debug info
 #ifdef DEBUG
+#include <cstdio>
 //#define GRLAYOUT_DEBUG 1
-//#undef NDEBUG
+#undef NDEBUG
 #endif
 
 // Header files
@@ -57,10 +58,6 @@
 #include <svsys.h>
 #endif
 
-#ifdef UNX
-#include <vcl/graphite_adaptors.hxx>
-#endif
-
 #include <vcl/salgdi.hxx>
 
 #include <unicode/uchar.h>
@@ -68,16 +65,10 @@
 #include <unicode/uscript.h>
 
 // Graphite Libraries (must be after vcl headers on windows)
-#include <graphite/GrClient.h>
-#include <graphite/Font.h>
-#include <graphite/ITextSource.h>
-#include <graphite/Segment.h>
-#include <graphite/SegmentPainter.h>
-
-#include <vcl/graphite_layout.hxx>
-#include <vcl/graphite_features.hxx>
-#include "graphite_textsrc.hxx"
+#include <graphite2/Segment.h>
 
+#include "vcl/graphite_layout.hxx"
+#include "vcl/graphite_features.hxx"
 
 // Module private type definitions and forward declarations.
 //
@@ -85,48 +76,38 @@
 //
 
 #ifdef GRLAYOUT_DEBUG
-FILE * grLogFile = NULL;
-FILE * grLog()
+static FILE * grLogFile = NULL;
+static FILE * grLog()
 {
 #ifdef WNT
     std::string logFileName(getenv("TEMP"));
-    logFileName.append("\\graphitelayout.log");
+    logFileName.append("/graphitelayout.log");
     if (grLogFile == NULL) grLogFile = fopen(logFileName.c_str(),"w");
     else fflush(grLogFile);
     return grLogFile;
 #else
+    fflush(stdout);
     return stdout;
 #endif
 }
 #endif
 
-#ifdef GRCACHE
-#include <vcl/graphite_cache.hxx>
-#endif
-
-
 namespace
 {
-    typedef std::pair<gr::GlyphIterator, gr::GlyphIterator>       glyph_range_t;
-    typedef std::pair<gr::GlyphSetIterator, gr::GlyphSetIterator> glyph_set_range_t;
-
     inline long round(const float n) {
         return long(n + (n < 0 ? -0.5 : 0.5));
     }
 
-
     template<typename T>
     inline bool in_range(const T i, const T b, const T e) {
         return !(b > i) && i < e;
     }
 
-
     template<typename T>
     inline bool is_subrange(const T sb, const T se, const T b, const T e) {
         return !(b > sb || se > e);
     }
 
-
     template<typename T>
     inline bool is_subrange(const std::pair<T, T> &s, const T b, const T e) {
         return is_subrange(s.first, s.second, b, e);
@@ -149,9 +130,18 @@ namespace
         return limit;
     }
 
-} // namespace
-
+    template <typename T>
+    T maximum(T a, T b)
+    {
+        return (a > b)? a : b;
+    }
+    template <typename T>
+    T minimum(T a, T b)
+    {
+        return (a < b)? a : b;
+    }
 
+} // namespace
 
 // Impementation of the GraphiteLayout::Glyphs container class.
 //    This is an extended vector class with methods added to enable
@@ -160,412 +150,364 @@ namespace
 //        o manipulations that affect neighouring glyphs.
 
 const int GraphiteLayout::EXTRA_CONTEXT_LENGTH = 10;
-#ifdef GRCACHE
-GraphiteCacheHandler GraphiteCacheHandler::instance;
-#endif
+
+// find first slot of cluster and first slot of subsequent cluster
+static void findFirstClusterSlot(const gr_slot* base, gr_slot const** first, gr_slot const** after, int * firstChar, int * lastChar, bool bRtl)
+{
+    if (gr_slot_attached_to(base) == NULL)
+    {
+        *first = base;
+        *after = (bRtl)? gr_slot_prev_in_segment(base) :
+            gr_slot_next_in_segment(base);
+        *firstChar = gr_slot_before(base);
+        *lastChar = gr_slot_after(base);
+    }
+    const gr_slot * attachment = gr_slot_first_attachment(base);
+    while (attachment)
+    {
+        if (gr_slot_origin_X(*first) > gr_slot_origin_X(attachment))
+            *first = attachment;
+        const gr_slot* attachmentNext = (bRtl)?
+            gr_slot_prev_in_segment(attachment) : gr_slot_next_in_segment(attachment);
+        if (attachmentNext)
+        {
+            if (*after && (gr_slot_origin_X(*after) < gr_slot_origin_X(attachmentNext)))
+                *after = attachmentNext;
+        }
+        else
+        {
+            *after = NULL;
+        }
+        if (gr_slot_before(attachment) < *firstChar)
+            *firstChar = gr_slot_before(attachment);
+        if (gr_slot_after(attachment) > *lastChar)
+            *lastChar = gr_slot_after(attachment);
+        if (gr_slot_first_attachment(attachment))
+            findFirstClusterSlot(attachment, first, after, firstChar, lastChar, bRtl);
+        attachment = gr_slot_next_sibling_attachment(attachment);
+    }
+}
 
 // The Graphite glyph stream is really a sequence of glyph attachment trees
-//  each rooted at a non-attached base glyph.  fill_from walks the glyph stream
-//  find each non-attached base glyph and calls append to record them as a
+//  each rooted at a non-attached base glyph.  fill_from walks the glyph stream,
+//  finds each non-attached base glyph and calls append to record them as a
 //  sequence of clusters.
 void
-GraphiteLayout::Glyphs::fill_from(gr::Segment & rSegment, ImplLayoutArgs &rArgs,
-    bool bRtl, long &rWidth, float fScaling, std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char, std::vector<int> & rCharDxs)
+GraphiteLayout::fillFrom(gr_segment * pSegment, ImplLayoutArgs &rArgs, float fScaling)
 {
-    // Create a glyph item for each of the glyph and append it to the base class glyph list.
-    typedef std::pair< gr::GlyphSetIterator, gr::GlyphSetIterator > GrGlyphSet;
-    int nChar = rArgs.mnEndCharPos - rArgs.mnMinCharPos;
-    glyph_range_t iGlyphs = rSegment.glyphs();
-    int nGlyphs = iGlyphs.second - iGlyphs.first;
-    float fSegmentAdvance = rSegment.advanceWidth();
-    float fMinX = fSegmentAdvance;
+    bool bRtl = (rArgs.mnFlags & SAL_LAYOUT_BIDI_RTL);
+    int nCharRequested = rArgs.mnEndCharPos - rArgs.mnMinCharPos;
+    int nChar = gr_seg_n_cinfo(pSegment);
+    float fMinX = gr_seg_advance_X(pSegment);
     float fMaxX = 0.0f;
-    rGlyph2Char.assign(nGlyphs, -1);
-    long nDxOffset = 0;
-    int nGlyphIndex = (bRtl)? (nGlyphs - 1) : 0;
-    // OOo always expects the glyphs in ltr order
-    int nDelta = (bRtl)? -1 : 1;
-
-    int nLastGlyph = (bRtl)? nGlyphs - 1: 0;
-    int nNextChar = (bRtl)? (rSegment.stopCharacter() - 1) : rSegment.startCharacter();//rArgs.mnMinCharPos;
-    // current glyph number (Graphite glyphs)
-    //int currGlyph = 0;
-    int nFirstCharInCluster = nNextChar;
-    int nFirstGlyphInCluster = nLastGlyph;
-
-    // ltr first char in cluster is lowest, same is true for rtl
-    // ltr first glyph in cluster is lowest, rtl first glyph is highest
-
-    // loop over the glyphs determining which characters are linked to them
-    gr::GlyphIterator gi;
-    for (gi = iGlyphs.first + nGlyphIndex;
-         nGlyphIndex >= 0 && nGlyphIndex < nGlyphs;
-         nGlyphIndex+= nDelta, gi = iGlyphs.first + nGlyphIndex)
+    long nDxOffset = 0; // from dropped glyphs
+    int nFirstCharInCluster = 0;
+    int nLastCharInCluster = 0;
+    unsigned int nGlyphs = gr_seg_n_slots(pSegment);
+    mvGlyph2Char.assign(nGlyphs, -1);
+    mvGlyphs.reserve(nGlyphs);
+
+    if (bRtl)
     {
-        gr::GlyphInfo info = (*gi);
-#ifdef GRLAYOUT_DEBUG
-        fprintf(grLog(),"Glyph %d %f,%f\n", (int)info.logicalIndex(), info.origin(), info.yOffset());
-#endif
-        // the last character associated with this glyph is after
-        // our current cluster buffer position
-        if ((bRtl && ((signed)info.firstChar() <= nNextChar)) ||
-            (!bRtl && ((signed)info.lastChar() >= nNextChar)))
+        const gr_slot* prevBase = NULL;
+        const gr_slot* baseSlot = gr_seg_last_slot(pSegment);
+        // find first base
+        while (baseSlot && (gr_slot_attached_to(baseSlot) != NULL))
+            baseSlot = gr_slot_prev_in_segment(baseSlot);
+        int iChar = nChar - 1;
+        int iNextChar = nChar - 1;
+        bool reordered = false;
+        int nBaseGlyphIndex = 0;
+        // now loop over bases
+        while (baseSlot)
         {
-            if ((bRtl && nGlyphIndex < nLastGlyph) ||
-                (!bRtl && nGlyphIndex > nLastGlyph))
+            bool bCluster = !reordered;
+            const gr_slot * clusterFirst = NULL;
+            const gr_slot * clusterAfter = NULL;
+            int firstChar = -1;
+            int lastChar = -1;
+            findFirstClusterSlot(baseSlot, &clusterFirst, &clusterAfter, &firstChar, &lastChar, bRtl);
+            iNextChar = minimum<int>(firstChar, iNextChar);
+            if (bCluster)
             {
-                // this glyph is after the previous one left->right
-                // if insertion is allowed before it then we are in a
-                // new cluster
-                int nAttachedBase = (*(info.attachedClusterBase())).logicalIndex();
-                if (!info.isAttached() ||
-                    !in_range(nAttachedBase, nFirstGlyphInCluster, nGlyphIndex))
+                nBaseGlyphIndex = mvGlyphs.size();
+                mvGlyph2Char[nBaseGlyphIndex] = iChar + mnSegCharOffset;
+                nFirstCharInCluster = firstChar;
+                nLastCharInCluster = lastChar;
+            }
+            else
+            {
+                mvGlyph2Char[mvGlyphs.size()] = firstChar + mnSegCharOffset;
+                nFirstCharInCluster = minimum<int>(firstChar, nFirstCharInCluster);
+                nLastCharInCluster = maximum<int>(firstChar, nLastCharInCluster);
+            }
+            float leftBoundary = gr_slot_origin_X(clusterFirst);
+            float rightBoundary = (clusterAfter)?
+                gr_slot_origin_X(clusterAfter) : gr_seg_advance_X(pSegment);
+            if (lastChar < iChar && gr_cinfo_after(gr_seg_cinfo(pSegment, iChar)) > gr_slot_index(clusterAfter))
+            {
+                reordered = true;
+            }
+            else
+            {
+                reordered = false;
+                iChar = iNextChar - 1;
+            }
+            if (mnSegCharOffset + nFirstCharInCluster >= mnMinCharPos &&
+                mnSegCharOffset + nFirstCharInCluster < mnEndCharPos)
+            {
+                fMinX = minimum<float>(fMinX, leftBoundary);
+                fMaxX = maximum<float>(fMaxX, rightBoundary);
+                if (!reordered)
                 {
-                    if (in_range(nFirstCharInCluster, rArgs.mnMinCharPos, rArgs.mnEndCharPos) &&
-                        nFirstGlyphInCluster != nGlyphIndex)
+                    for (int i = nFirstCharInCluster; i <= nLastCharInCluster; i++)
                     {
-                        std::pair <float,float> aBounds =
-                            appendCluster(rSegment, rArgs, bRtl,
-                            fSegmentAdvance, nFirstCharInCluster,
-                            nNextChar, nFirstGlyphInCluster, nGlyphIndex, fScaling,
-                            rChar2Base, rGlyph2Char, rCharDxs, nDxOffset);
-                        fMinX = std::min(aBounds.first, fMinX);
-                        fMaxX = std::max(aBounds.second, fMaxX);
+                        if (mnSegCharOffset + i >= mnEndCharPos)
+                            break;
+                        // from the point of view of the dx array, the xpos is
+                        // the origin of the first glyph of the cluster rtl
+                        mvCharDxs[mnSegCharOffset + i - mnMinCharPos] =
+                            static_cast<int>(leftBoundary * fScaling) + nDxOffset;
+                        mvCharBreaks[mnSegCharOffset + i - mnMinCharPos] = gr_cinfo_break_weight(gr_seg_cinfo(pSegment, i));
                     }

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list