[Libreoffice-commits] .: Branch 'libreoffice-3-3' - 3 commits - canvas/source vcl/inc vcl/source
Caolán McNamara
caolan at kemper.freedesktop.org
Fri Dec 3 03:18:00 PST 2010
canvas/source/cairo/cairo_textlayout.cxx | 320 +++++++++++++++++--------------
vcl/inc/vcl/sysdata.hxx | 9
vcl/source/gdi/outdev3.cxx | 8
vcl/source/gdi/pdfwriter_impl.cxx | 28 ++
4 files changed, 209 insertions(+), 156 deletions(-)
New commits:
commit f3dd48059efe1321c58718b4d7a220b94fbc4a2e
Author: Caolán McNamara <caolanm at redhat.com>
Date: Fri Dec 3 11:06:13 2010 +0000
Related: fdo#31243 remove shadowed variable names
(cherry picked from commit 4a95223e49e5967472ff6ee68659c4ff87298e4d)
diff --git a/canvas/source/cairo/cairo_textlayout.cxx b/canvas/source/cairo/cairo_textlayout.cxx
index 934bb91..d8de6c5 100644
--- a/canvas/source/cairo/cairo_textlayout.cxx
+++ b/canvas/source/cairo/cairo_textlayout.cxx
@@ -417,14 +417,14 @@ namespace cairocanvas
typedef std::pair<SystemFontData,int> FontLevel;
typedef std::vector<FontLevel> FontLevelVector;
FontLevelVector aFontData;
- SystemGlyphDataVector::const_iterator aIter=aSysLayoutData.rGlyphData.begin();
- const SystemGlyphDataVector::const_iterator aEnd=aSysLayoutData.rGlyphData.end();
- for( ; aIter != aEnd; ++aIter )
+ SystemGlyphDataVector::const_iterator aGlyphIter=aSysLayoutData.rGlyphData.begin();
+ const SystemGlyphDataVector::const_iterator aGlyphEnd=aSysLayoutData.rGlyphData.end();
+ for( ; aGlyphIter != aGlyphEnd; ++aGlyphIter )
{
- if( aFontData.empty() || aIter->fallbacklevel != aFontData.back().second )
+ if( aFontData.empty() || aGlyphIter->fallbacklevel != aFontData.back().second )
{
- aFontData.push_back(FontLevel(rOutDev.GetSysFontData(aIter->fallbacklevel),
- aIter->fallbacklevel));
+ aFontData.push_back(FontLevel(rOutDev.GetSysFontData(aGlyphIter->fallbacklevel),
+ aGlyphIter->fallbacklevel));
if( !isCairoRenderable(aFontData.back().first) )
{
bCairoRenderable = false;
@@ -477,11 +477,10 @@ namespace cairocanvas
std::vector<cairo_glyph_t> cairo_glyphs;
cairo_glyphs.reserve( 256 );
- SystemGlyphDataVector::const_iterator aIter=aSysLayoutData.rGlyphData.begin();
- const SystemGlyphDataVector::const_iterator aEnd=aSysLayoutData.rGlyphData.end();
- for( ; aIter != aEnd; ++aIter )
+ aGlyphIter=aSysLayoutData.rGlyphData.begin();
+ for( ; aGlyphIter != aGlyphEnd; ++aGlyphIter )
{
- SystemGlyphData systemGlyph = *aIter;
+ SystemGlyphData systemGlyph = *aGlyphIter;
if( systemGlyph.fallbacklevel != aFontDataIter->second )
continue;
commit 1fada0bf264d7c5e37087c31bbfe11955ed5b782
Author: Caolán McNamara <caolanm at redhat.com>
Date: Fri Dec 3 11:00:01 2010 +0000
Resolves: fdo#31243 glyph fallback for cairo-canvas
(cherry picked from commit cbd99e3bdd8a2bb887fb3eeb1e8d0a90f7576234)
diff --git a/canvas/source/cairo/cairo_textlayout.cxx b/canvas/source/cairo/cairo_textlayout.cxx
index d8b8126..934bb91 100644
--- a/canvas/source/cairo/cairo_textlayout.cxx
+++ b/canvas/source/cairo/cairo_textlayout.cxx
@@ -106,6 +106,11 @@ namespace cairocanvas
// as required at the API spec
rOutDev.SetLayoutMode( nLayoutMode | TEXT_LAYOUT_TEXTORIGIN_LEFT );
}
+
+ bool compareFallbacks(const SystemGlyphData&rA, const SystemGlyphData &rB)
+ {
+ return rA.fallbacklevel < rB.fallbacklevel;
+ }
}
TextLayout::TextLayout( const rendering::StringContext& aText,
@@ -364,7 +369,6 @@ namespace cairocanvas
return true;
}
-
/**
* TextLayout::draw
*
@@ -405,18 +409,41 @@ namespace cairocanvas
::canvas::tools::numeric_cast<USHORT>(maText.Length),
maLogicalAdvancements.getLength() ? aOffsets.get() : NULL);
+ // Sort them so that all glyphs on the same glyph fallback level are consecutive
+ std::sort(aSysLayoutData.rGlyphData.begin(), aSysLayoutData.rGlyphData.end(), compareFallbacks);
+ bool bCairoRenderable = true;
+
+ //Pull all the fonts we need to render the text
+ typedef std::pair<SystemFontData,int> FontLevel;
+ typedef std::vector<FontLevel> FontLevelVector;
+ FontLevelVector aFontData;
+ SystemGlyphDataVector::const_iterator aIter=aSysLayoutData.rGlyphData.begin();
+ const SystemGlyphDataVector::const_iterator aEnd=aSysLayoutData.rGlyphData.end();
+ for( ; aIter != aEnd; ++aIter )
+ {
+ if( aFontData.empty() || aIter->fallbacklevel != aFontData.back().second )
+ {
+ aFontData.push_back(FontLevel(rOutDev.GetSysFontData(aIter->fallbacklevel),
+ aIter->fallbacklevel));
+ if( !isCairoRenderable(aFontData.back().first) )
+ {
+ bCairoRenderable = false;
+ OSL_TRACE(":cairocanvas::TextLayout::draw(S,O,p,v,r): VCL FALLBACK %s%s%s%s - %s",
+ maLogicalAdvancements.getLength() ? "ADV " : "",
+ aFontData.back().first.bAntialias ? "AA " : "",
+ aFontData.back().first.bFakeBold ? "FB " : "",
+ aFontData.back().first.bFakeItalic ? "FI " : "",
+ ::rtl::OUStringToOString( maText.Text.copy( maText.StartPosition, maText.Length ),
+ RTL_TEXTENCODING_UTF8 ).getStr());
+ break;
+ }
+ }
+ }
+
// The ::GetSysTextLayoutData(), i.e. layouting of text to glyphs can change the font being used.
// The fallback checks need to be done after final font is known.
- if (!isCairoRenderable(aSysLayoutData.aSysFontData)) // VCL FALLBACKS
+ if (!bCairoRenderable) // VCL FALLBACKS
{
- OSL_TRACE(":cairocanvas::TextLayout::draw(S,O,p,v,r): VCL FALLBACK %s%s%s%s - %s",
- maLogicalAdvancements.getLength() ? "ADV " : "",
- aSysLayoutData.aSysFontData.bAntialias ? "AA " : "",
- aSysLayoutData.aSysFontData.bFakeBold ? "FB " : "",
- aSysLayoutData.aSysFontData.bFakeItalic ? "FI " : "",
- ::rtl::OUStringToOString( maText.Text.copy( maText.StartPosition, maText.Length ),
- RTL_TEXTENCODING_UTF8 ).getStr());
-
if (maLogicalAdvancements.getLength()) // VCL FALLBACK - with glyph advances
{
rOutDev.DrawTextArray( rOutpos, maText.Text, aOffsets.get(),
@@ -438,145 +465,159 @@ namespace cairocanvas
/**
* Setup platform independent glyph vector into cairo-based glyphs vector.
**/
-
- // setup glyphs
- std::vector<cairo_glyph_t> cairo_glyphs;
- cairo_glyphs.reserve( 256 );
-
- for( int nStart = 0; nStart < (int) aSysLayoutData.rGlyphData.size(); nStart++ )
+
+ // Loop through the fonts used and render the matching glyphs for each
+ FontLevelVector::const_iterator aFontDataIter = aFontData.begin();
+ const FontLevelVector::const_iterator aFontDataEnd = aFontData.end();
+ for( ; aFontDataIter != aFontDataEnd; ++aFontDataIter )
{
- cairo_glyph_t aGlyph;
- SystemGlyphData systemGlyph = aSysLayoutData.rGlyphData.at(nStart);
- aGlyph.index = systemGlyph.index;
-#ifdef CAIRO_HAS_WIN32_SURFACE
- // Cairo requires standard glyph indexes (ETO_GLYPH_INDEX), while vcl/win/* uses ucs4 chars.
- // Convert to standard indexes
- aGlyph.index = cairo::ucs4toindex((unsigned int) aGlyph.index, aSysLayoutData.aSysFontData.hFont);
-#endif
- aGlyph.x = systemGlyph.x;
- aGlyph.y = systemGlyph.y;
- cairo_glyphs.push_back(aGlyph);
- }
+ const SystemFontData &rSysFontData = aFontDataIter->first;
- if (cairo_glyphs.empty()) return true; //true or false??
-
- /**
- * Setup font
- **/
- cairo_font_face_t* font_face = NULL;
+ // setup glyphs
+ std::vector<cairo_glyph_t> cairo_glyphs;
+ cairo_glyphs.reserve( 256 );
-#ifdef CAIRO_HAS_QUARTZ_SURFACE
- // TODO: use cairo_quartz_font_face_create_for_cgfont(cgFont)
- // when CGFont (Mac OS X 10.5 API) is provided by the AQUA VCL backend.
- font_face = cairo_quartz_font_face_create_for_atsu_font_id((ATSUFontID) aSysLayoutData.aSysFontData.aATSUFontID);
-
-#elif defined CAIRO_HAS_WIN32_SURFACE
- #if (OSL_DEBUG_LEVEL > 1)
- GetObjectW( aSysLayoutData.aSysFontData.hFont, sizeof(logfont), &logfont );
- #endif
- // Note: cairo library uses logfont fallbacks when lfEscapement, lfOrientation and lfWidth are not zero.
- // VCL always has non-zero value for lfWidth
- font_face = cairo_win32_font_face_create_for_hfont(aSysLayoutData.aSysFontData.hFont);
-
-#elif defined CAIRO_HAS_XLIB_SURFACE
- font_face = cairo_ft_font_face_create_for_ft_face((FT_Face)aSysLayoutData.aSysFontData.nFontId,
- aSysLayoutData.aSysFontData.nFontFlags);
-#else
-# error Native API needed.
-#endif
+ SystemGlyphDataVector::const_iterator aIter=aSysLayoutData.rGlyphData.begin();
+ const SystemGlyphDataVector::const_iterator aEnd=aSysLayoutData.rGlyphData.end();
+ for( ; aIter != aEnd; ++aIter )
+ {
+ SystemGlyphData systemGlyph = *aIter;
+ if( systemGlyph.fallbacklevel != aFontDataIter->second )
+ continue;
+
+ cairo_glyph_t aGlyph;
+ aGlyph.index = systemGlyph.index;
+ #ifdef CAIRO_HAS_WIN32_SURFACE
+ // Cairo requires standard glyph indexes (ETO_GLYPH_INDEX), while vcl/win/* uses ucs4 chars.
+ // Convert to standard indexes
+ aGlyph.index = cairo::ucs4toindex((unsigned int) aGlyph.index, rSysFontData.hFont);
+ #endif
+ aGlyph.x = systemGlyph.x;
+ aGlyph.y = systemGlyph.y;
+ cairo_glyphs.push_back(aGlyph);
+ }
- CairoSharedPtr pSCairo = pSurface->getCairo();
-
- cairo_set_font_face( pSCairo.get(), font_face);
-
- // create default font options. cairo_get_font_options() does not retrieve the surface defaults,
- // only what has been set before with cairo_set_font_options()
- cairo_font_options_t* options = cairo_font_options_create();
- if (aSysLayoutData.aSysFontData.bAntialias) {
- // CAIRO_ANTIALIAS_GRAY provides more similar result to VCL Canvas,
- // so we're not using CAIRO_ANTIALIAS_SUBPIXEL
- cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_GRAY);
- }
- cairo_set_font_options( pSCairo.get(), options);
-
- // Font color
- Color mTextColor = rOutDev.GetTextColor();
- cairo_set_source_rgb(pSCairo.get(),
- mTextColor.GetRed()/255.0,
- mTextColor.GetGreen()/255.0,
- mTextColor.GetBlue()/255.0);
-
- // Font rotation and scaling
- cairo_matrix_t m;
- Font aFont = rOutDev.GetFont();
- FontMetric aMetric( rOutDev.GetFontMetric(aFont) );
- long nWidth = 0;
-
- // width calculation is deep magic and platform/font dependant.
- // width == 0 means no scaling, and usually width == height means the same.
- // Other values mean horizontal scaling (narrow or stretching)
- // see issue #101566
-
- //proper scale calculation across platforms
- if (aFont.GetWidth() == 0) {
- nWidth = aFont.GetHeight();
- } else {
- // any scaling needs to be relative to the platform-dependent definition
- // of height of the font
- nWidth = aFont.GetWidth() * aFont.GetHeight() / aMetric.GetHeight();
- }
-
- cairo_matrix_init_identity(&m);
-
- if (aSysLayoutData.orientation) cairo_matrix_rotate(&m, (3600 - aSysLayoutData.orientation) * M_PI / 1800.0);
-
- cairo_matrix_scale(&m, nWidth, aFont.GetHeight());
+ if (cairo_glyphs.empty())
+ continue;
+
+ /**
+ * Setup font
+ **/
+ cairo_font_face_t* font_face = NULL;
+
+ #ifdef CAIRO_HAS_QUARTZ_SURFACE
+ // TODO: use cairo_quartz_font_face_create_for_cgfont(cgFont)
+ // when CGFont (Mac OS X 10.5 API) is provided by the AQUA VCL backend.
+ font_face = cairo_quartz_font_face_create_for_atsu_font_id((ATSUFontID) rSysFontData.aATSUFontID);
+
+ #elif defined CAIRO_HAS_WIN32_SURFACE
+ #if (OSL_DEBUG_LEVEL > 1)
+ GetObjectW( rSysFontData.hFont, sizeof(logfont), &logfont );
+ #endif
+ // Note: cairo library uses logfont fallbacks when lfEscapement, lfOrientation and lfWidth are not zero.
+ // VCL always has non-zero value for lfWidth
+ font_face = cairo_win32_font_face_create_for_hfont(rSysFontData.hFont);
+
+ #elif defined CAIRO_HAS_XLIB_SURFACE
+ font_face = cairo_ft_font_face_create_for_ft_face((FT_Face)rSysFontData.nFontId,
+ rSysFontData.nFontFlags);
+ #else
+ # error Native API needed.
+ #endif
+
+ CairoSharedPtr pSCairo = pSurface->getCairo();
+
+ cairo_set_font_face( pSCairo.get(), font_face);
+
+ // create default font options. cairo_get_font_options() does not retrieve the surface defaults,
+ // only what has been set before with cairo_set_font_options()
+ cairo_font_options_t* options = cairo_font_options_create();
+ if (rSysFontData.bAntialias) {
+ // CAIRO_ANTIALIAS_GRAY provides more similar result to VCL Canvas,
+ // so we're not using CAIRO_ANTIALIAS_SUBPIXEL
+ cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_GRAY);
+ }
+ cairo_set_font_options( pSCairo.get(), options);
+
+ // Font color
+ Color mTextColor = rOutDev.GetTextColor();
+ cairo_set_source_rgb(pSCairo.get(),
+ mTextColor.GetRed()/255.0,
+ mTextColor.GetGreen()/255.0,
+ mTextColor.GetBlue()/255.0);
+
+ // Font rotation and scaling
+ cairo_matrix_t m;
+ Font aFont = rOutDev.GetFont();
+ FontMetric aMetric( rOutDev.GetFontMetric(aFont) );
+ long nWidth = 0;
+
+ // width calculation is deep magic and platform/font dependant.
+ // width == 0 means no scaling, and usually width == height means the same.
+ // Other values mean horizontal scaling (narrow or stretching)
+ // see issue #101566
+
+ //proper scale calculation across platforms
+ if (aFont.GetWidth() == 0) {
+ nWidth = aFont.GetHeight();
+ } else {
+ // any scaling needs to be relative to the platform-dependent definition
+ // of height of the font
+ nWidth = aFont.GetWidth() * aFont.GetHeight() / aMetric.GetHeight();
+ }
- //faux italics
- if (aSysLayoutData.aSysFontData.bFakeItalic) m.xy = -m.xx * 0x6000L / 0x10000L;
-
- cairo_set_font_matrix(pSCairo.get(), &m);
-
- OSL_TRACE("\r\n:cairocanvas::TextLayout::draw(S,O,p,v,r): Size:(%d,%d), W:%d->%d, Pos (%d,%d), G(%d,%d,%d) %s%s%s%s || Name:%s - %s",
- aFont.GetWidth(),
- aFont.GetHeight(),
- aMetric.GetWidth(),
- nWidth,
- (int) rOutpos.X(),
- (int) rOutpos.Y(),
- cairo_glyphs[0].index, cairo_glyphs[1].index, cairo_glyphs[2].index,
- maLogicalAdvancements.getLength() ? "ADV " : "",
- aSysLayoutData.aSysFontData.bAntialias ? "AA " : "",
- aSysLayoutData.aSysFontData.bFakeBold ? "FB " : "",
- aSysLayoutData.aSysFontData.bFakeItalic ? "FI " : "",
-#if (defined CAIRO_HAS_WIN32_SURFACE) && (OSL_DEBUG_LEVEL > 1)
- ::rtl::OUStringToOString( reinterpret_cast<const sal_Unicode*> (logfont.lfFaceName), RTL_TEXTENCODING_UTF8 ).getStr(),
-#else
- ::rtl::OUStringToOString( aFont.GetName(), RTL_TEXTENCODING_UTF8 ).getStr(),
-#endif
- ::rtl::OUStringToOString( maText.Text.copy( maText.StartPosition, maText.Length ),
- RTL_TEXTENCODING_UTF8 ).getStr()
- );
-
- cairo_show_glyphs(pSCairo.get(), &cairo_glyphs[0], cairo_glyphs.size());
-
- //faux bold
- if (aSysLayoutData.aSysFontData.bFakeBold) {
- double bold_dx = 0.5 * sqrt( 0.7 * aFont.GetHeight() );
- int total_steps = 2 * ((int) (bold_dx + 0.5));
+ cairo_matrix_init_identity(&m);
+
+ if (aSysLayoutData.orientation) cairo_matrix_rotate(&m, (3600 - aSysLayoutData.orientation) * M_PI / 1800.0);
+
+ cairo_matrix_scale(&m, nWidth, aFont.GetHeight());
+
+ //faux italics
+ if (rSysFontData.bFakeItalic) m.xy = -m.xx * 0x6000L / 0x10000L;
+
+ cairo_set_font_matrix(pSCairo.get(), &m);
+
+ OSL_TRACE("\r\n:cairocanvas::TextLayout::draw(S,O,p,v,r): Size:(%d,%d), W:%d->%d, Pos (%d,%d), G(%d,%d,%d) %s%s%s%s || Name:%s - %s",
+ aFont.GetWidth(),
+ aFont.GetHeight(),
+ aMetric.GetWidth(),
+ nWidth,
+ (int) rOutpos.X(),
+ (int) rOutpos.Y(),
+ cairo_glyphs[0].index, cairo_glyphs[1].index, cairo_glyphs[2].index,
+ maLogicalAdvancements.getLength() ? "ADV " : "",
+ rSysFontData.bAntialias ? "AA " : "",
+ rSysFontData.bFakeBold ? "FB " : "",
+ rSysFontData.bFakeItalic ? "FI " : "",
+ #if (defined CAIRO_HAS_WIN32_SURFACE) && (OSL_DEBUG_LEVEL > 1)
+ ::rtl::OUStringToOString( reinterpret_cast<const sal_Unicode*> (logfont.lfFaceName), RTL_TEXTENCODING_UTF8 ).getStr(),
+ #else
+ ::rtl::OUStringToOString( aFont.GetName(), RTL_TEXTENCODING_UTF8 ).getStr(),
+ #endif
+ ::rtl::OUStringToOString( maText.Text.copy( maText.StartPosition, maText.Length ),
+ RTL_TEXTENCODING_UTF8 ).getStr()
+ );
+
+ cairo_show_glyphs(pSCairo.get(), &cairo_glyphs[0], cairo_glyphs.size());
- // loop to draw the text for every half pixel of displacement
- for (int nSteps = 0; nSteps < total_steps; nSteps++) {
- for(int nGlyphIdx = 0; nGlyphIdx < (int) cairo_glyphs.size(); nGlyphIdx++) {
- cairo_glyphs[nGlyphIdx].x += bold_dx * nSteps / total_steps;
+ //faux bold
+ if (rSysFontData.bFakeBold) {
+ double bold_dx = 0.5 * sqrt( 0.7 * aFont.GetHeight() );
+ int total_steps = 2 * ((int) (bold_dx + 0.5));
+
+ // loop to draw the text for every half pixel of displacement
+ for (int nSteps = 0; nSteps < total_steps; nSteps++) {
+ for(int nGlyphIdx = 0; nGlyphIdx < (int) cairo_glyphs.size(); nGlyphIdx++) {
+ cairo_glyphs[nGlyphIdx].x += bold_dx * nSteps / total_steps;
+ }
+ cairo_show_glyphs(pSCairo.get(), &cairo_glyphs[0], cairo_glyphs.size());
}
- cairo_show_glyphs(pSCairo.get(), &cairo_glyphs[0], cairo_glyphs.size());
+ OSL_TRACE(":cairocanvas::TextLayout::draw(S,O,p,v,r): FAKEBOLD - dx:%d", (int) bold_dx);
}
- OSL_TRACE(":cairocanvas::TextLayout::draw(S,O,p,v,r): FAKEBOLD - dx:%d", (int) bold_dx);
+
+ cairo_restore( pSCairo.get() );
+ cairo_font_face_destroy(font_face);
}
-
- cairo_restore( pSCairo.get() );
- cairo_font_face_destroy(font_face);
return true;
}
diff --git a/vcl/inc/vcl/sysdata.hxx b/vcl/inc/vcl/sysdata.hxx
index 018872b..1a8f56d 100644
--- a/vcl/inc/vcl/sysdata.hxx
+++ b/vcl/inc/vcl/sysdata.hxx
@@ -151,6 +151,7 @@ struct SystemGlyphData
unsigned long index;
double x;
double y;
+ int fallbacklevel;
};
@@ -179,12 +180,12 @@ struct SystemFontData
// - SystemTextLayoutData -
// --------------------
+typedef std::vector<SystemGlyphData> SystemGlyphDataVector;
struct SystemTextLayoutData
{
- unsigned long nSize; // size in bytes of this structure
- std::vector<SystemGlyphData> rGlyphData; // glyph data
- int orientation; // Text orientation
- SystemFontData aSysFontData; // Font data for the text layout
+ unsigned long nSize; // size in bytes of this structure
+ SystemGlyphDataVector rGlyphData; // glyph data
+ int orientation; // Text orientation
};
#endif // _SV_SYSDATA_HXX
diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx
index b898258..96bfab5 100644
--- a/vcl/source/gdi/outdev3.cxx
+++ b/vcl/source/gdi/outdev3.cxx
@@ -7339,7 +7339,6 @@ SystemTextLayoutData OutputDevice::GetSysTextLayoutData(const Point& rStartPt, c
// setup glyphs
Point aPos;
sal_GlyphId aGlyphId;
- int nFallbacklevel = 0;
for( int nStart = 0; rLayout->GetNextGlyphs( 1, &aGlyphId, aPos, nStart ); )
{
// NOTE: Windows backend is producing unicode chars (ucs4), so on windows,
@@ -7349,15 +7348,12 @@ SystemTextLayoutData OutputDevice::GetSysTextLayoutData(const Point& rStartPt, c
aGlyph.index = static_cast<unsigned long> (aGlyphId & GF_IDXMASK);
aGlyph.x = aPos.X();
aGlyph.y = aPos.Y();
- aSysLayoutData.rGlyphData.push_back(aGlyph);
-
int nLevel = (aGlyphId & GF_FONTMASK) >> GF_FONTSHIFT;
- if (nLevel > nFallbacklevel && nLevel < MAX_FALLBACK)
- nFallbacklevel = nLevel;
+ aGlyph.fallbacklevel = nLevel < MAX_FALLBACK ? nLevel : 0;
+ aSysLayoutData.rGlyphData.push_back(aGlyph);
}
// Get font data
- aSysLayoutData.aSysFontData = GetSysFontData(nFallbacklevel);
aSysLayoutData.orientation = rLayout->GetOrientation();
rLayout->Release();
commit 9f79f618431af939efbb2cc223d38227dbce692f
Author: Caolán McNamara <caolanm at redhat.com>
Date: Thu Dec 2 11:18:12 2010 +0000
Resolves: #i115788# URIs must be exported as 7bit ASCII
(cherry picked from commit 8b074d17a7e81f075dfe30236dfcd1b0e9f36ad2)
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index c4816bc..2285fed 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -4614,6 +4614,7 @@ we check in the following sequence:
nSetRelative++;
rtl::OUString aFragment = aTargetURL.GetMark( INetURLObject::NO_DECODE /*DECODE_WITH_CHARSET*/ ); //fragment as is,
+ bool bIsURI=false; //URI: 12.6.4.7, URI Actions, URI must be encoded in 7-bit-ASCII
if( nSetGoToRMode == 0 )
switch( m_aContext.DefaultLinkAction )
{
@@ -4621,6 +4622,7 @@ we check in the following sequence:
case PDFWriter::URIAction :
case PDFWriter::URIActionDestination :
aLine.append( "/URI/URI" );
+ bIsURI=true;
break;
case PDFWriter::LaunchAction:
// now:
@@ -4632,7 +4634,10 @@ we check in the following sequence:
// and will force the use of URI when the protocol is not file://
if( (aFragment.getLength() > 0 && !bTargetHasPDFExtension) ||
eTargetProtocol != INET_PROT_FILE )
+ {
aLine.append( "/URI/URI" );
+ bIsURI=true;
+ }
else
aLine.append( "/Launch/F" );
break;
@@ -4640,7 +4645,8 @@ we check in the following sequence:
//fragment are encoded in the same way as in the named destination processing
rtl::OUString aURLNoMark = aTargetURL.GetURLNoMark( INetURLObject::DECODE_WITH_CHARSET );
if( nSetGoToRMode )
- {//add the fragment
+ {
+ //add the fragment
aLine.append("/GoToR");
aLine.append("/F");
appendLiteralStringEncrypt( nSetRelative ? INetURLObject::GetRelURL( m_aContext.BaseURL, aURLNoMark,
@@ -4665,13 +4671,23 @@ we check in the following sequence:
//substitute the fragment
aTargetURL.SetMark( aLineLoc.getStr() );
}
- rtl::OUString aURL = aTargetURL.GetMainURL( (nSetRelative || eTargetProtocol == INET_PROT_FILE) ? INetURLObject::DECODE_WITH_CHARSET : INetURLObject::NO_DECODE );
-// check if we have a URL available, if the string is empty, set it as the original one
-// if( aURL.getLength() == 0 )
-// appendLiteralStringEncrypt( rLink.m_aURL , rLink.m_nObject, aLine );
-// else
+ if (bIsURI)
+ {
+ //If we're writing to URI/URI we must e in 7-bit ASCII, so encode anything else as %XX
+ rtl::OUString aURL = aTargetURL.GetMainURL(INetURLObject::NO_DECODE);
+ appendLiteralStringEncrypt( nSetRelative ? INetURLObject::GetRelURL(m_aContext.BaseURL, aURL) :
+ aURL , rLink.m_nObject, aLine );
+ }
+ else
+ {
+ //TO-DO: Depending on the interpretation of 12.6.4.5 we
+ //may be able to use appendUnicodeTextStringEncrypt
+ //here for the INetURLObject::DECODE_WITH_CHARSET case
+ //to ensure that the string doesn't get mangled
+ rtl::OUString aURL = aTargetURL.GetMainURL( (nSetRelative || eTargetProtocol == INET_PROT_FILE) ? INetURLObject::DECODE_WITH_CHARSET : INetURLObject::NO_DECODE );
appendLiteralStringEncrypt( nSetRelative ? INetURLObject::GetRelURL( m_aContext.BaseURL, aURL ) :
aURL , rLink.m_nObject, aLine );
+ }
}
//<--- i56629
}
More information about the Libreoffice-commits
mailing list