summaryrefslogtreecommitdiff
path: root/vcl/source/glyphs
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/glyphs')
-rw-r--r--vcl/source/glyphs/gcach_ftyp.cxx11
-rwxr-xr-xvcl/source/glyphs/gcach_layout.cxx67
2 files changed, 63 insertions, 15 deletions
diff --git a/vcl/source/glyphs/gcach_ftyp.cxx b/vcl/source/glyphs/gcach_ftyp.cxx
index f6d93963540b..3fe2f7cd0ec2 100644
--- a/vcl/source/glyphs/gcach_ftyp.cxx
+++ b/vcl/source/glyphs/gcach_ftyp.cxx
@@ -1031,6 +1031,17 @@ void FreetypeServerFont::FetchFontMetric( ImplFontMetricData& rTo, long& rFactor
rTo.mnDescent += nOtherHalfTmpExtLeading;
}
}
+
+ // initialize kashida width
+ // TODO: what if there are different versions of this glyph available
+ rTo.mnMinKashida = rTo.mnAscent / 4; // a reasonable default
+ const int nKashidaGlyphId = GetRawGlyphIndex( 0x0640 );
+ if( nKashidaGlyphId )
+ {
+ GlyphData aGlyphData;
+ InitGlyphData( nKashidaGlyphId, aGlyphData );
+ rTo.mnMinKashida = aGlyphData.GetMetric().GetCharWidth();
+ }
}
// -----------------------------------------------------------------------
diff --git a/vcl/source/glyphs/gcach_layout.cxx b/vcl/source/glyphs/gcach_layout.cxx
index bdd2444013c0..1e2f83f5f128 100755
--- a/vcl/source/glyphs/gcach_layout.cxx
+++ b/vcl/source/glyphs/gcach_layout.cxx
@@ -60,8 +60,6 @@ void ServerFontLayout::DrawText( SalGraphics& rSalGraphics ) const
rSalGraphics.DrawServerFontLayout( *this );
}
-//--------------------------------------------------------------------------
-
// -----------------------------------------------------------------------
bool ServerFontLayout::LayoutText( ImplLayoutArgs& rArgs )
@@ -481,6 +479,9 @@ bool IcuLayoutEngine::operator()( ServerFontLayout& rLayout, ImplLayoutArgs& rAr
// layout bidi/script runs and export them to a ServerFontLayout
// convert results to GlyphItems
int nLastCharPos = -1;
+ int nClusterMinPos = -1;
+ int nClusterMaxPos = -1;
+ bool bClusterStart = true;
int nFilteredRunGlyphCount = 0;
const IcuPosition* pPos = pGlyphPositions;
for( int i = 0; i < nRawRunGlyphCount; ++i, ++pPos )
@@ -518,14 +519,6 @@ bool IcuLayoutEngine::operator()( ServerFontLayout& rLayout, ImplLayoutArgs& rAr
continue;
}
- // if ICU feeds us a character index sequence like [1,0,1] (which
- // is completely valid), smooth out the sequence so that our cluster
- // detection routines work better. The best knowledge where the
- // cluster boundaries are should be provided by the layout engine...
- if( nLastCharPos != -1 )
- if( (nCharPos < nLastCharPos) ^ bRightToLeft )
- nCharPos = nLastCharPos;
-
// apply vertical flags, etc.
if( nCharPos >= 0 )
{
@@ -549,25 +542,68 @@ bool IcuLayoutEngine::operator()( ServerFontLayout& rLayout, ImplLayoutArgs& rAr
const GlyphMetric& rGM = rFont.GetGlyphMetric( nGlyphIndex );
int nGlyphWidth = rGM.GetCharWidth();
- // heuristic to detect group clusters using "smoothed" char positions
+ // heuristic to detect glyph clusters
+ bool bInCluster = true;
+ if( nLastCharPos == -1 )
+ {
+ nClusterMinPos = nClusterMaxPos = nCharPos;
+ bInCluster = false;
+ }
+ else if( !bRightToLeft )
+ {
+ // left-to-right case
+ if( nClusterMinPos > nCharPos )
+ nClusterMinPos = nCharPos; // extend cluster
+ else if( nCharPos <= nClusterMaxPos )
+ /*NOTHING*/; // inside cluster
+ else if( nGlyphWidth <= 0 )
+ nClusterMaxPos = nCharPos; // add diacritic to cluster
+ else {
+ nClusterMinPos = nClusterMaxPos = nCharPos; // new cluster
+ bInCluster = false;
+ }
+ }
+ else
+ {
+ // right-to-left case
+ if( nClusterMaxPos < nCharPos )
+ nClusterMaxPos = nCharPos; // extend cluster
+ else if( nCharPos >= nClusterMinPos )
+ /*NOTHING*/; // inside cluster
+ else if( nGlyphWidth <= 0 )
+ {
+ nClusterMinPos = nCharPos; // ICU often has [diacritic* baseglyph*]
+ if( bClusterStart ) {
+ nClusterMaxPos = nCharPos;
+ bInCluster = false;
+ }
+ }
+ else
+ {
+ nClusterMinPos = nClusterMaxPos = nCharPos; // new cluster
+ bInCluster = !bClusterStart;
+ }
+ }
+
long nGlyphFlags = 0;
- if( nLastCharPos != -1 )
- if( (nCharPos == nLastCharPos) || (nGlyphWidth <= 0) )
- nGlyphFlags = GlyphItem::IS_IN_CLUSTER;
+ if( bInCluster )
+ nGlyphFlags |= GlyphItem::IS_IN_CLUSTER;
if( bRightToLeft )
nGlyphFlags |= GlyphItem::IS_RTL_GLYPH;
// add resulting glyph item to layout
- GlyphItem aGI( nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nGlyphWidth );
+ const GlyphItem aGI( nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nGlyphWidth );
rLayout.AppendGlyph( aGI );
++nFilteredRunGlyphCount;
nLastCharPos = nCharPos;
+ bClusterStart = !aGI.IsDiacritic(); // TODO: only needed in RTL-codepath
}
aNewPos = Point( (int)(pPos->fX+0.5), (int)(pPos->fY+0.5) );
nGlyphCount += nFilteredRunGlyphCount;
}
// sort glyphs in visual order
+ // and then in logical order (e.g. diacritics after cluster start)
rLayout.SortGlyphItems();
// determine need for kashida justification
@@ -594,3 +630,4 @@ ServerFontLayoutEngine* FreetypeServerFont::GetLayoutEngine()
}
// =======================================================================
+