Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
b6ecac9f
Kaydet (Commit)
b6ecac9f
authored
May 13, 2013
tarafından
Khaled Hosny
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Bye Bye ICU Layout Engine
Change-Id: I0f887ba378f9dac45a3736e4d1789585651148d1
üst
7aa42913
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
5 additions
and
677 deletions
+5
-677
gcach_layout.cxx
vcl/generic/glyphs/gcach_layout.cxx
+4
-676
glyphcache.hxx
vcl/inc/generic/glyphcache.hxx
+1
-1
No files found.
vcl/generic/glyphs/gcach_layout.cxx
Dosyayı görüntüle @
b6ecac9f
...
...
@@ -33,13 +33,7 @@
#include <hb-icu.h>
#include <hb-ot.h>
#include <layout/LayoutEngine.h>
#include <layout/LEFontInstance.h>
#include <layout/LELanguages.h>
#include <layout/LEScripts.h>
#include <unicode/uscript.h>
#include <unicode/ubidi.h>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/i18n/CharacterIteratorMode.hpp>
...
...
@@ -51,9 +45,7 @@
ServerFontLayout
::
ServerFontLayout
(
ServerFont
&
rFont
)
:
mrServerFont
(
rFont
)
{
bUseHarfBuzz
=
(
getenv
(
"SAL_USE_ICULE"
)
==
NULL
);
}
{
}
void
ServerFontLayout
::
DrawText
(
SalGraphics
&
rSalGraphics
)
const
{
...
...
@@ -64,7 +56,7 @@ void ServerFontLayout::DrawText( SalGraphics& rSalGraphics ) const
bool
ServerFontLayout
::
LayoutText
(
ImplLayoutArgs
&
rArgs
)
{
ServerFontLayoutEngine
*
pLE
=
mrServerFont
.
GetLayoutEngine
(
bUseHarfBuzz
);
ServerFontLayoutEngine
*
pLE
=
mrServerFont
.
GetLayoutEngine
();
assert
(
pLE
);
bool
bRet
=
pLE
?
pLE
->
layout
(
*
this
,
rArgs
)
:
false
;
return
bRet
;
...
...
@@ -501,677 +493,13 @@ bool HbLayoutEngine::layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs)
return
true
;
}
// =======================================================================
// bridge to ICU LayoutEngine
// =======================================================================
using
namespace
U_ICU_NAMESPACE
;
static
const
LEGlyphID
ICU_DELETED_GLYPH
=
0xFFFF
;
static
const
LEGlyphID
ICU_MARKED_GLYPH
=
0xFFFE
;
// -----------------------------------------------------------------------
class
IcuFontFromServerFont
:
public
LEFontInstance
{
private
:
ServerFont
&
mrServerFont
;
public
:
IcuFontFromServerFont
(
ServerFont
&
rFont
)
:
mrServerFont
(
rFont
)
{}
virtual
const
void
*
getFontTable
(
LETag
tableTag
,
size_t
&
length
)
const
;
virtual
const
void
*
getFontTable
(
LETag
tableTag
)
const
;
virtual
le_int32
getUnitsPerEM
()
const
;
virtual
float
getXPixelsPerEm
()
const
;
virtual
float
getYPixelsPerEm
()
const
;
virtual
float
getScaleFactorX
()
const
;
virtual
float
getScaleFactorY
()
const
;
using
LEFontInstance
::
mapCharToGlyph
;
virtual
LEGlyphID
mapCharToGlyph
(
LEUnicode32
ch
)
const
;
virtual
LEGlyphID
mapCharToGlyph
(
LEUnicode32
ch
,
const
LECharMapper
*
mapper
,
le_bool
filterZeroWidth
)
const
;
virtual
le_int32
getAscent
()
const
;
virtual
le_int32
getDescent
()
const
;
virtual
le_int32
getLeading
()
const
;
virtual
void
getGlyphAdvance
(
LEGlyphID
glyph
,
LEPoint
&
advance
)
const
;
virtual
le_bool
getGlyphPoint
(
LEGlyphID
glyph
,
le_int32
pointNumber
,
LEPoint
&
point
)
const
;
};
// -----------------------------------------------------------------------
const
void
*
IcuFontFromServerFont
::
getFontTable
(
LETag
nICUTableTag
,
size_t
&
rLength
)
const
{
char
pTagName
[
5
];
pTagName
[
0
]
=
(
char
)(
nICUTableTag
>>
24
);
pTagName
[
1
]
=
(
char
)(
nICUTableTag
>>
16
);
pTagName
[
2
]
=
(
char
)(
nICUTableTag
>>
8
);
pTagName
[
3
]
=
(
char
)(
nICUTableTag
);
pTagName
[
4
]
=
0
;
sal_uLong
nLength
=
0
;
const
unsigned
char
*
pBuffer
=
mrServerFont
.
GetTable
(
pTagName
,
&
nLength
);
rLength
=
static_cast
<
size_t
>
(
nLength
);
SAL_INFO
(
"vcl"
,
"IcuGetTable(
\"
"
<<
pTagName
<<
"
\"
) => "
<<
pBuffer
<<
", len="
<<
rLength
);
SAL_INFO
(
"vcl"
,
"font( h="
<<
mrServerFont
.
GetFontSelData
().
mnHeight
<<
",
\"
"
<<
mrServerFont
.
GetFontFileName
()
->
getStr
()
<<
"
\"
)"
);
return
pBuffer
;
}
const
void
*
IcuFontFromServerFont
::
getFontTable
(
LETag
nICUTableTag
)
const
{
size_t
nLength
=
0
;
return
getFontTable
(
nICUTableTag
,
nLength
);
}
// -----------------------------------------------------------------------
le_int32
IcuFontFromServerFont
::
getUnitsPerEM
()
const
{
return
mrServerFont
.
GetEmUnits
();
}
// -----------------------------------------------------------------------
float
IcuFontFromServerFont
::
getXPixelsPerEm
()
const
{
const
FontSelectPattern
&
r
=
mrServerFont
.
GetFontSelData
();
float
fX
=
r
.
mnWidth
?
r
.
mnWidth
:
r
.
mnHeight
;
return
fX
;
}
// -----------------------------------------------------------------------
float
IcuFontFromServerFont
::
getYPixelsPerEm
()
const
{
float
fY
=
mrServerFont
.
GetFontSelData
().
mnHeight
;
return
fY
;
}
// -----------------------------------------------------------------------
float
IcuFontFromServerFont
::
getScaleFactorX
()
const
{
return
1.0
;
}
// -----------------------------------------------------------------------
float
IcuFontFromServerFont
::
getScaleFactorY
()
const
{
return
1.0
;
}
// -----------------------------------------------------------------------
LEGlyphID
IcuFontFromServerFont
::
mapCharToGlyph
(
LEUnicode32
ch
)
const
{
LEGlyphID
nGlyphIndex
=
mrServerFont
.
GetRawGlyphIndex
(
ch
);
return
nGlyphIndex
;
}
LEGlyphID
IcuFontFromServerFont
::
mapCharToGlyph
(
LEUnicode32
ch
,
const
LECharMapper
*
mapper
,
le_bool
/*filterZeroWidth*/
)
const
{
/*
fdo#31821, icu has...
>│93 if (filterZeroWidth && (mappedChar == 0x200C || mappedChar == 0x200D)) { │
│94 return canDisplay(mappedChar) ? 0x0001 : 0xFFFF; │
│95 }
so only the Indic layouts allow the joiners to get mapped to glyphs
*/
return
LEFontInstance
::
mapCharToGlyph
(
ch
,
mapper
,
false
);
}
// -----------------------------------------------------------------------
le_int32
IcuFontFromServerFont
::
getAscent
()
const
{
const
FT_Size_Metrics
&
rMetrics
=
mrServerFont
.
GetMetricsFT
();
le_int32
nAscent
=
(
+
rMetrics
.
ascender
+
32
)
>>
6
;
return
nAscent
;
}
// -----------------------------------------------------------------------
le_int32
IcuFontFromServerFont
::
getDescent
()
const
{
const
FT_Size_Metrics
&
rMetrics
=
mrServerFont
.
GetMetricsFT
();
le_int32
nDescent
=
(
-
rMetrics
.
descender
+
32
)
>>
6
;
return
nDescent
;
}
// -----------------------------------------------------------------------
le_int32
IcuFontFromServerFont
::
getLeading
()
const
{
const
FT_Size_Metrics
&
rMetrics
=
mrServerFont
.
GetMetricsFT
();
le_int32
nLeading
=
((
rMetrics
.
height
-
rMetrics
.
ascender
+
rMetrics
.
descender
)
+
32
)
>>
6
;
return
nLeading
;
}
// -----------------------------------------------------------------------
void
IcuFontFromServerFont
::
getGlyphAdvance
(
LEGlyphID
nGlyphIndex
,
LEPoint
&
advance
)
const
{
if
(
(
nGlyphIndex
==
ICU_MARKED_GLYPH
)
||
(
nGlyphIndex
==
ICU_DELETED_GLYPH
)
)
{
// deleted glyph or mark glyph has not advance
advance
.
fX
=
0
;
}
else
{
const
GlyphMetric
&
rGM
=
mrServerFont
.
GetGlyphMetric
(
nGlyphIndex
);
advance
.
fX
=
rGM
.
GetCharWidth
();
}
advance
.
fY
=
0
;
}
// -----------------------------------------------------------------------
le_bool
IcuFontFromServerFont
::
getGlyphPoint
(
LEGlyphID
,
le_int32
pointNumber
,
LEPoint
&
)
const
{
//TODO: replace dummy implementation
SAL_INFO
(
"vcl"
,
"getGlyphPoint("
<<
pointNumber
<<
")"
);
return
false
;
}
// =======================================================================
class
IcuLayoutEngine
:
public
ServerFontLayoutEngine
{
private
:
IcuFontFromServerFont
maIcuFont
;
LanguageCodes
meLanguageCode
;
le_int32
meScriptCode
;
le_int32
mnLayoutFlags
;
LayoutEngine
*
mpIcuLE
;
public
:
IcuLayoutEngine
(
ServerFont
&
);
virtual
~
IcuLayoutEngine
();
virtual
bool
layout
(
ServerFontLayout
&
,
ImplLayoutArgs
&
);
};
// -----------------------------------------------------------------------
IcuLayoutEngine
::
IcuLayoutEngine
(
ServerFont
&
rServerFont
)
:
maIcuFont
(
rServerFont
),
meLanguageCode
(
nullLanguageCode
),
meScriptCode
(
USCRIPT_INVALID_CODE
),
mnLayoutFlags
(
0
),
mpIcuLE
(
NULL
)
{}
// -----------------------------------------------------------------------
IcuLayoutEngine
::~
IcuLayoutEngine
()
{
delete
mpIcuLE
;
}
// -----------------------------------------------------------------------
namespace
{
LanguageCodes
mapLanguageTypetoICU
(
LanguageType
eLangCode
)
{
LanguageTag
aLangTag
(
eLangCode
);
OUString
sLanguage
=
aLangTag
.
getLanguage
();
if
(
sLanguage
==
"af"
)
// Afrikaans
return
afkLanguageCode
;
else
if
(
sLanguage
==
"ar"
)
// Arabic
return
araLanguageCode
;
else
if
(
sLanguage
==
"as"
)
// Assamese
return
asmLanguageCode
;
else
if
(
sLanguage
==
"be"
)
// Belarussian
return
belLanguageCode
;
else
if
(
sLanguage
==
"bn"
)
// Bengali
return
benLanguageCode
;
else
if
(
sLanguage
==
"bo"
)
// Tibetan
return
tibLanguageCode
;
else
if
(
sLanguage
==
"bu"
)
// Bulgarian
return
bgrLanguageCode
;
else
if
(
sLanguage
==
"ca"
)
// Catalan
return
catLanguageCode
;
else
if
(
sLanguage
==
"cs"
)
// Czech
return
csyLanguageCode
;
else
if
(
sLanguage
==
"ch"
)
// Chechen
return
cheLanguageCode
;
else
if
(
sLanguage
==
"co"
)
// Coptic
return
copLanguageCode
;
else
if
(
sLanguage
==
"cy"
)
// Welsh
return
welLanguageCode
;
else
if
(
sLanguage
==
"da"
)
// Danish
return
danLanguageCode
;
else
if
(
sLanguage
==
"de"
)
// German
return
deuLanguageCode
;
else
if
(
sLanguage
==
"dz"
)
// Dzongkha
return
dznLanguageCode
;
else
if
(
sLanguage
==
"el"
)
// Greek
return
ellLanguageCode
;
else
if
(
sLanguage
==
"en"
)
// English
return
engLanguageCode
;
else
if
(
sLanguage
==
"et"
)
// Estonian
return
etiLanguageCode
;
else
if
(
sLanguage
==
"eu"
)
// Basque
return
euqLanguageCode
;
else
if
(
sLanguage
==
"fa"
)
// Farsi
return
farLanguageCode
;
else
if
(
sLanguage
==
"fi"
)
// Finnish
return
finLanguageCode
;
else
if
(
sLanguage
==
"fr"
)
// French
return
fraLanguageCode
;
else
if
(
sLanguage
==
"ga"
)
// Irish Gaelic
return
gaeLanguageCode
;
else
if
(
sLanguage
==
"gu"
)
// Gujarati
return
gujLanguageCode
;
else
if
(
sLanguage
==
"ha"
)
// Hausa
return
hauLanguageCode
;
else
if
(
sLanguage
==
"he"
)
// Hebrew
return
iwrLanguageCode
;
else
if
(
sLanguage
==
"hi"
)
// Hindi
return
hinLanguageCode
;
else
if
(
sLanguage
==
"hr"
)
// Croatian
return
hrvLanguageCode
;
else
if
(
sLanguage
==
"hu"
)
// Hungarian
return
hunLanguageCode
;
else
if
(
sLanguage
==
"hy"
)
// Armenian
return
hyeLanguageCode
;
else
if
(
sLanguage
==
"id"
)
// Indonesian
return
indLanguageCode
;
else
if
(
sLanguage
==
"it"
)
// Italian
return
itaLanguageCode
;
else
if
(
sLanguage
==
"ja"
)
// Japanese
return
janLanguageCode
;
else
if
(
sLanguage
==
"kn"
)
// Kannada
return
kanLanguageCode
;
else
if
(
sLanguage
==
"ks"
)
// Kashmiri
return
kshLanguageCode
;
else
if
(
sLanguage
==
"kh"
)
// Khmer
return
khmLanguageCode
;
else
if
(
sLanguage
==
"kok"
)
// Konkani
return
kokLanguageCode
;
else
if
(
sLanguage
==
"ko"
)
// Korean
return
korLanguageCode
;
else
if
(
sLanguage
==
"ml"
)
// Malayalam - Reformed (should there be some bcp47 tag for Traditional Malayalam)
return
mlrLanguageCode
;
else
if
(
sLanguage
==
"mr"
)
// Marathi
return
marLanguageCode
;
else
if
(
sLanguage
==
"mt"
)
// Maltese
return
mtsLanguageCode
;
else
if
(
sLanguage
==
"mni"
)
// Manipuri
return
mniLanguageCode
;
else
if
(
sLanguage
==
"mn"
)
// Mongolian
return
mngLanguageCode
;
else
if
(
sLanguage
==
"ne"
)
// Nepali
return
nepLanguageCode
;
else
if
(
sLanguage
==
"or"
)
// Oriya
return
oriLanguageCode
;
else
if
(
sLanguage
==
"pl"
)
// Polish
return
plkLanguageCode
;
else
if
(
sLanguage
==
"po"
)
// Portuguese
return
ptgLanguageCode
;
else
if
(
sLanguage
==
"ps"
)
// Pashto
return
pasLanguageCode
;
else
if
(
sLanguage
==
"ro"
)
// Romanian
return
romLanguageCode
;
else
if
(
sLanguage
==
"ru"
)
// Russian
return
rusLanguageCode
;
else
if
(
sLanguage
==
"sa"
)
// Sanskrit
return
sanLanguageCode
;
else
if
(
sLanguage
==
"si"
)
// Sinhalese
return
snhLanguageCode
;
else
if
(
sLanguage
==
"sk"
)
// Slovak
return
skyLanguageCode
;
else
if
(
sLanguage
==
"sd"
)
// Sindhi
return
sndLanguageCode
;
else
if
(
sLanguage
==
"sl"
)
// Slovenian
return
slvLanguageCode
;
else
if
(
sLanguage
==
"es"
)
// Spanish
return
espLanguageCode
;
else
if
(
sLanguage
==
"sq"
)
// Albanian
return
sqiLanguageCode
;
else
if
(
sLanguage
==
"sr"
)
// Serbian
return
srbLanguageCode
;
else
if
(
sLanguage
==
"sv"
)
// Swedish
return
sveLanguageCode
;
else
if
(
sLanguage
==
"syr"
)
// Syriac
return
syrLanguageCode
;
else
if
(
sLanguage
==
"ta"
)
// Tamil
return
tamLanguageCode
;
else
if
(
sLanguage
==
"te"
)
// Telugu
return
telLanguageCode
;
else
if
(
sLanguage
==
"th"
)
// Thai
return
thaLanguageCode
;
else
if
(
sLanguage
==
"tu"
)
// Turkish
return
trkLanguageCode
;
else
if
(
sLanguage
==
"ur"
)
// Urdu
return
urdLanguageCode
;
else
if
(
sLanguage
==
"yi"
)
// Yiddish
return
jiiLanguageCode
;
else
if
(
sLanguage
==
"zh"
)
// Chinese
{
OUString
sScript
=
aLangTag
.
getScript
();
if
(
sScript
.
isEmpty
())
{
if
(
MsLangId
::
isTraditionalChinese
(
eLangCode
))
sScript
=
"Hant"
;
else
sScript
=
"Hans"
;
}
if
(
sScript
==
"Latn"
)
return
zhpLanguageCode
;
else
if
(
sScript
==
"Hans"
)
return
zhsLanguageCode
;
else
if
(
sScript
==
"Hant"
)
return
zhtLanguageCode
;
}
//if there are new ones, please reexamine the mapping list for the new ones
BOOST_STATIC_ASSERT
(
languageCodeCount
==
72
);
return
nullLanguageCode
;
}
}
//See https://bugs.freedesktop.org/show_bug.cgi?id=31016
#define ARABIC_BANDAID
bool
IcuLayoutEngine
::
layout
(
ServerFontLayout
&
rLayout
,
ImplLayoutArgs
&
rArgs
)
{
le_int32
nLayoutFlags
=
0
;
#if (U_ICU_VERSION_MAJOR_NUM > 4)
if
(
rArgs
.
mnFlags
&
SAL_LAYOUT_KERNING_PAIRS
)
nLayoutFlags
|=
LayoutEngine
::
kTypoFlagKern
;
if
(
rArgs
.
mnFlags
&
SAL_LAYOUT_ENABLE_LIGATURES
)
nLayoutFlags
|=
LayoutEngine
::
kTypoFlagLiga
;
#else
if
(
rArgs
.
mnFlags
&
SAL_LAYOUT_KERNING_PAIRS
)
nLayoutFlags
|=
0x01
;
if
(
rArgs
.
mnFlags
&
SAL_LAYOUT_ENABLE_LIGATURES
)
nLayoutFlags
|=
0x10
;
#endif
LEUnicode
*
pIcuChars
;
if
(
sizeof
(
LEUnicode
)
==
sizeof
(
*
rArgs
.
mpStr
)
)
pIcuChars
=
(
LEUnicode
*
)
rArgs
.
mpStr
;
else
{
// this conversion will only be needed when either
// ICU's or OOo's unicodes stop being unsigned shorts
// TODO: watch out for surrogates!
pIcuChars
=
(
LEUnicode
*
)
alloca
(
rArgs
.
mnLength
*
sizeof
(
LEUnicode
)
);
for
(
xub_StrLen
ic
=
0
;
ic
<
rArgs
.
mnLength
;
++
ic
)
pIcuChars
[
ic
]
=
static_cast
<
LEUnicode
>
(
rArgs
.
mpStr
[
ic
]
);
}
// allocate temporary arrays, note: round to even
int
nGlyphCapacity
=
(
3
*
(
rArgs
.
mnEndCharPos
-
rArgs
.
mnMinCharPos
)
|
15
)
+
1
;
rLayout
.
Reserve
(
nGlyphCapacity
);
struct
IcuPosition
{
float
fX
,
fY
;
};
const
int
nAllocSize
=
sizeof
(
LEGlyphID
)
+
sizeof
(
le_int32
)
+
sizeof
(
IcuPosition
);
LEGlyphID
*
pIcuGlyphs
=
(
LEGlyphID
*
)
alloca
(
(
nGlyphCapacity
*
nAllocSize
)
+
sizeof
(
IcuPosition
)
);
le_int32
*
pCharIndices
=
(
le_int32
*
)((
char
*
)
pIcuGlyphs
+
nGlyphCapacity
*
sizeof
(
LEGlyphID
)
);
IcuPosition
*
pGlyphPositions
=
(
IcuPosition
*
)((
char
*
)
pCharIndices
+
nGlyphCapacity
*
sizeof
(
le_int32
)
);
ServerFont
&
rFont
=
rLayout
.
GetServerFont
();
UErrorCode
rcI18n
=
U_ZERO_ERROR
;
LEErrorCode
rcIcu
=
LE_NO_ERROR
;
Point
aNewPos
(
0
,
0
);
for
(
int
nGlyphCount
=
0
;;
)
{
int
nMinRunPos
,
nEndRunPos
;
bool
bRightToLeft
;
if
(
!
rArgs
.
GetNextRun
(
&
nMinRunPos
,
&
nEndRunPos
,
&
bRightToLeft
)
)
break
;
// find matching script
// TODO: split up bidi run into script runs
le_int32
eScriptCode
=
-
1
;
for
(
int
i
=
nMinRunPos
;
i
<
nEndRunPos
;
++
i
)
{
le_int32
eNextScriptCode
=
uscript_getScript
(
pIcuChars
[
i
],
&
rcI18n
);
if
(
(
eNextScriptCode
>
USCRIPT_INHERITED
)
)
{
eScriptCode
=
eNextScriptCode
;
if
(
eNextScriptCode
!=
latnScriptCode
)
break
;
}
}
if
(
eScriptCode
<
0
)
// TODO: handle errors better
eScriptCode
=
latnScriptCode
;
LanguageCodes
eLanguageCode
=
mapLanguageTypetoICU
(
rArgs
.
meLanguage
);
// get layout engine matching to this script and ligature/kerning combination
// no engine change necessary if script is latin
if
(
!
mpIcuLE
||
((
eScriptCode
!=
meScriptCode
)
&&
(
eScriptCode
>
USCRIPT_INHERITED
))
||
(
mnLayoutFlags
!=
nLayoutFlags
)
||
(
meLanguageCode
!=
eLanguageCode
)
)
{
// TODO: cache multiple layout engines when multiple scripts are used
delete
mpIcuLE
;
meLanguageCode
=
eLanguageCode
;
meScriptCode
=
eScriptCode
;
mnLayoutFlags
=
nLayoutFlags
;
mpIcuLE
=
LayoutEngine
::
layoutEngineFactory
(
&
maIcuFont
,
eScriptCode
,
eLanguageCode
,
nLayoutFlags
,
rcIcu
);
if
(
LE_FAILURE
(
rcIcu
)
)
{
delete
mpIcuLE
;
mpIcuLE
=
NULL
;
}
}
// fall back to default layout if needed
if
(
!
mpIcuLE
)
break
;
// run ICU layout engine
// TODO: get enough context, remove extra glyps below
int
nRawRunGlyphCount
=
mpIcuLE
->
layoutChars
(
pIcuChars
,
nMinRunPos
,
nEndRunPos
-
nMinRunPos
,
rArgs
.
mnLength
,
bRightToLeft
,
aNewPos
.
X
(),
aNewPos
.
Y
(),
rcIcu
);
if
(
LE_FAILURE
(
rcIcu
)
)
return
false
;
// import layout info from icu
mpIcuLE
->
getGlyphs
(
pIcuGlyphs
,
rcIcu
);
mpIcuLE
->
getCharIndices
(
pCharIndices
,
rcIcu
);
mpIcuLE
->
getGlyphPositions
(
&
pGlyphPositions
->
fX
,
rcIcu
);
if
(
LE_FAILURE
(
rcIcu
)
)
return
false
;
// 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
)
{
LEGlyphID
nGlyphIndex
=
pIcuGlyphs
[
i
];
// ignore glyphs which were marked or deleted by ICU
if
(
(
nGlyphIndex
==
ICU_MARKED_GLYPH
)
||
(
nGlyphIndex
==
ICU_DELETED_GLYPH
)
)
continue
;
// adjust the relative char pos
int
nCharPos
=
pCharIndices
[
i
];
if
(
nCharPos
>=
0
)
{
nCharPos
+=
nMinRunPos
;
// ICU seems to return bad pCharIndices
// for some combinations of ICU+font+text
// => better give up now than crash later
if
(
nCharPos
>=
nEndRunPos
)
continue
;
}
// if needed request glyph fallback by updating LayoutArgs
if
(
!
nGlyphIndex
)
{
rLayout
.
setNeedFallback
(
rArgs
,
nCharPos
,
bRightToLeft
);
if
(
SAL_LAYOUT_FOR_FALLBACK
&
rArgs
.
mnFlags
)
continue
;
}
// apply vertical flags, etc.
bool
bDiacritic
=
false
;
if
(
nCharPos
>=
0
)
{
sal_UCS4
aChar
=
rArgs
.
mpStr
[
nCharPos
];
nGlyphIndex
=
rFont
.
FixupGlyphIndex
(
nGlyphIndex
,
aChar
);
// i#99367# HACK: try to detect all diacritics
if
(
aChar
>=
0x0300
&&
aChar
<
0x2100
)
bDiacritic
=
IsDiacritic
(
aChar
);
}
// get glyph position and its metrics
aNewPos
=
Point
(
(
int
)(
pPos
->
fX
+
0.5
),
(
int
)(
pPos
->
fY
+
0.5
)
);
const
GlyphMetric
&
rGM
=
rFont
.
GetGlyphMetric
(
nGlyphIndex
);
int
nGlyphWidth
=
rGM
.
GetCharWidth
();
int
nNewWidth
=
nGlyphWidth
;
if
(
nGlyphWidth
<=
0
)
bDiacritic
|=
true
;
// i#99367# force all diacritics to zero width
// TODO: we need mnOrigWidth/mnLogicWidth/mnNewWidth
else
if
(
bDiacritic
)
nGlyphWidth
=
nNewWidth
=
0
;
else
{
// Hack, find next +ve width glyph and calculate current
// glyph width by substracting the two posituons
const
IcuPosition
*
pNextPos
=
pPos
+
1
;
for
(
int
j
=
i
+
1
;
j
<=
nRawRunGlyphCount
;
++
j
,
++
pNextPos
)
{
if
(
j
==
nRawRunGlyphCount
)
{
nNewWidth
=
static_cast
<
int
>
(
pNextPos
->
fX
-
pPos
->
fX
);
break
;
}
LEGlyphID
nNextGlyphIndex
=
pIcuGlyphs
[
j
];
if
(
(
nNextGlyphIndex
==
ICU_MARKED_GLYPH
)
||
(
nNextGlyphIndex
==
ICU_DELETED_GLYPH
)
)
continue
;
const
GlyphMetric
&
rNextGM
=
rFont
.
GetGlyphMetric
(
nNextGlyphIndex
);
int
nNextGlyphWidth
=
rNextGM
.
GetCharWidth
();
if
(
nNextGlyphWidth
>
0
)
{
nNewWidth
=
static_cast
<
int
>
(
pNextPos
->
fX
-
pPos
->
fX
);
break
;
}
}
}
// 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
(
bDiacritic
)
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
(
bDiacritic
)
{
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
(
bInCluster
)
nGlyphFlags
|=
GlyphItem
::
IS_IN_CLUSTER
;
if
(
bRightToLeft
)
nGlyphFlags
|=
GlyphItem
::
IS_RTL_GLYPH
;
if
(
bDiacritic
)
nGlyphFlags
|=
GlyphItem
::
IS_DIACRITIC
;
// add resulting glyph item to layout
GlyphItem
aGI
(
nCharPos
,
nGlyphIndex
,
aNewPos
,
nGlyphFlags
,
nGlyphWidth
);
#ifdef ARABIC_BANDAID
aGI
.
mnNewWidth
=
nNewWidth
;
#endif
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
if
(
(
rArgs
.
mpDXArray
||
rArgs
.
mnLayoutWidth
)
&&
((
meScriptCode
==
arabScriptCode
)
||
(
meScriptCode
==
syrcScriptCode
))
)
rArgs
.
mnFlags
|=
SAL_LAYOUT_KASHIDA_JUSTIFICATON
;
return
true
;
}
// =======================================================================
ServerFontLayoutEngine
*
ServerFont
::
GetLayoutEngine
(
bool
bUseHarfBuzz
)
ServerFontLayoutEngine
*
ServerFont
::
GetLayoutEngine
()
{
// find best layout engine for font, platform, script and language
if
(
!
mpLayoutEngine
)
{
if
(
bUseHarfBuzz
)
mpLayoutEngine
=
new
HbLayoutEngine
(
*
this
);
else
mpLayoutEngine
=
new
IcuLayoutEngine
(
*
this
);
mpLayoutEngine
=
new
HbLayoutEngine
(
*
this
);
}
return
mpLayoutEngine
;
}
...
...
vcl/inc/generic/glyphcache.hxx
Dosyayı görüntüle @
b6ecac9f
...
...
@@ -241,7 +241,7 @@ private:
int
ApplyGlyphTransform
(
int
nGlyphFlags
,
FT_GlyphRec_
*
,
bool
)
const
;
bool
ApplyGSUB
(
const
FontSelectPattern
&
);
ServerFontLayoutEngine
*
GetLayoutEngine
(
bool
);
ServerFontLayoutEngine
*
GetLayoutEngine
();
typedef
::
boost
::
unordered_map
<
int
,
GlyphData
>
GlyphList
;
mutable
GlyphList
maGlyphList
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment