[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