summaryrefslogtreecommitdiff
path: root/vcl/generic
diff options
context:
space:
mode:
authorChris Sherlock <chris.sherlock79@gmail.com>2016-01-11 13:41:05 +1100
committerChris Sherlock <chris.sherlock79@gmail.com>2016-01-11 03:30:42 +0000
commit09a1566bf18cdf98b111d4979e4f4ad52ce65b07 (patch)
tree8ae3d9283dacd2c94214f3aeda853b73f403f511 /vcl/generic
parent557a6d20080e6f4d95db9e5b4dff87f3e51ac054 (diff)
vcl: move all glyph files from generic to unx
All the files in glyph are only used by Unix based systems, with the exception of OS X. Therefore, it's not really "generic" as in "used across all platforms" but is generic as in "used in all Unix-based systems". Change-Id: Id89c09df74f0ddafee5c88c55bac4c35f9b23ef8 Reviewed-on: https://gerrit.libreoffice.org/21312 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Chris Sherlock <chris.sherlock79@gmail.com>
Diffstat (limited to 'vcl/generic')
-rw-r--r--vcl/generic/fontmanager/fontsubst.cxx2
-rw-r--r--vcl/generic/glyphs/gcach_layout.cxx621
-rw-r--r--vcl/generic/glyphs/glyphcache.cxx379
-rw-r--r--vcl/generic/glyphs/graphite_serverfont.cxx135
-rw-r--r--vcl/generic/glyphs/scrptrun.cxx234
-rw-r--r--vcl/generic/glyphs/scrptrun.h173
-rw-r--r--vcl/generic/print/genpspgraphics.cxx2
7 files changed, 2 insertions, 1544 deletions
diff --git a/vcl/generic/fontmanager/fontsubst.cxx b/vcl/generic/fontmanager/fontsubst.cxx
index 5f7bfb361d46..f88944504764 100644
--- a/vcl/generic/fontmanager/fontsubst.cxx
+++ b/vcl/generic/fontmanager/fontsubst.cxx
@@ -19,7 +19,7 @@
#include "generic/geninst.h"
#include "generic/genpspgraphics.h"
-#include "generic/glyphcache.hxx"
+#include "unx/glyphcache.hxx"
#include "vcl/sysdata.hxx"
#include "fontinstance.hxx"
diff --git a/vcl/generic/glyphs/gcach_layout.cxx b/vcl/generic/glyphs/gcach_layout.cxx
deleted file mode 100644
index 70ac1901f09d..000000000000
--- a/vcl/generic/glyphs/gcach_layout.cxx
+++ /dev/null
@@ -1,621 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include "unx/freetype_glyphcache.hxx"
-#include <sallayout.hxx>
-#include <salgdi.hxx>
-#include <scrptrun.h>
-
-#include <i18nlangtag/mslangid.hxx>
-
-#include <vcl/svapp.hxx>
-#include <vcl/unohelp.hxx>
-
-#include <rtl/instance.hxx>
-
-#include <hb-icu.h>
-#include <hb-ot.h>
-
-#include <com/sun/star/i18n/CharacterIteratorMode.hpp>
-
-#ifndef HB_VERSION_ATLEAST
-#define HB_VERSION_ATLEAST(a,b,c) 0
-#endif
-
-// layout implementation for ServerFont
-ServerFontLayout::ServerFontLayout( ServerFont& rFont )
-: mrServerFont( rFont )
-{
-}
-
-void ServerFontLayout::DrawText( SalGraphics& rSalGraphics ) const
-{
- rSalGraphics.DrawServerFontLayout( *this );
-}
-
-bool ServerFontLayout::LayoutText( ImplLayoutArgs& rArgs )
-{
- return mrServerFont.GetLayoutEngine()->Layout(*this, rArgs);
-}
-
-void ServerFontLayout::AdjustLayout( ImplLayoutArgs& rArgs )
-{
- GenericSalLayout::AdjustLayout( rArgs );
-
- // apply asian kerning if the glyphs are not already formatted
- if( (rArgs.mnFlags & SalLayoutFlags::KerningAsian)
- && !(rArgs.mnFlags & SalLayoutFlags::Vertical) )
- if( (rArgs.mpDXArray != nullptr) || (rArgs.mnLayoutWidth != 0) )
- ApplyAsianKerning(rArgs.mrStr);
-
- // insert kashidas where requested by the formatting array
- if( (rArgs.mnFlags & SalLayoutFlags::KashidaJustification) && rArgs.mpDXArray )
- {
- int nKashidaIndex = mrServerFont.GetGlyphIndex( 0x0640 );
- if( nKashidaIndex != 0 )
- {
- const GlyphMetric& rGM = mrServerFont.GetGlyphMetric( nKashidaIndex );
- KashidaJustify( nKashidaIndex, rGM.GetCharWidth() );
- // TODO: kashida-GSUB/GPOS
- }
- }
-}
-
-void ServerFontLayout::SetNeedFallback(ImplLayoutArgs& rArgs, sal_Int32 nCharPos,
- bool bRightToLeft)
-{
- if (nCharPos < 0)
- return;
-
- using namespace ::com::sun::star;
-
- if (!mxBreak.is())
- mxBreak = vcl::unohelper::CreateBreakIterator();
-
- lang::Locale aLocale(rArgs.maLanguageTag.getLocale());
-
- //if position nCharPos is missing in the font, grab the entire grapheme and
- //mark all glyphs as missing so the whole thing is rendered with the same
- //font
- sal_Int32 nDone;
- sal_Int32 nGraphemeStartPos =
- mxBreak->previousCharacters(rArgs.mrStr, nCharPos+1, aLocale,
- i18n::CharacterIteratorMode::SKIPCELL, 1, nDone);
- sal_Int32 nGraphemeEndPos =
- mxBreak->nextCharacters(rArgs.mrStr, nCharPos, aLocale,
- i18n::CharacterIteratorMode::SKIPCELL, 1, nDone);
-
- rArgs.NeedFallback(nGraphemeStartPos, nGraphemeEndPos, bRightToLeft);
-}
-
-std::ostream &operator <<(std::ostream& s, ServerFont* pFont)
-{
-#ifndef SAL_LOG_INFO
- (void) pFont;
-#else
- FT_Face aFace = pFont->GetFtFace();
- const char* pName = FT_Get_Postscript_Name(aFace);
- if (pName)
- s << pName;
- else
- s << pFont->GetFontFileName();
-#endif
- return s;
-}
-
-static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pUserData)
-{
- char pTagName[5];
- pTagName[0] = (char)(nTableTag >> 24);
- pTagName[1] = (char)(nTableTag >> 16);
- pTagName[2] = (char)(nTableTag >> 8);
- pTagName[3] = (char)(nTableTag);
- pTagName[4] = 0;
-
- ServerFont* pFont = static_cast<ServerFont*>(pUserData);
-
- SAL_INFO("vcl.harfbuzz", "getFontTable(" << pFont << ", " << pTagName << ")");
-
- sal_uLong nLength;
- const unsigned char* pBuffer = pFont->GetTable(pTagName, &nLength);
-
- hb_blob_t* pBlob = nullptr;
- if (pBuffer != nullptr)
- pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY, const_cast<unsigned char *>(pBuffer), nullptr);
-
- return pBlob;
-}
-
-static hb_bool_t getFontGlyph(hb_font_t* /*font*/, void* pFontData,
- hb_codepoint_t ch, hb_codepoint_t vs,
- hb_codepoint_t* nGlyphIndex,
- void* /*pUserData*/)
-{
- ServerFont* pFont = static_cast<ServerFont*>(pFontData);
- *nGlyphIndex = pFont->GetRawGlyphIndex(ch, vs);
-
- // tdf#89231 if the font is missing non-breaking space, then use a normal space
- if (*nGlyphIndex == 0 && ch == 0x202F && !vs)
- *nGlyphIndex = pFont->GetRawGlyphIndex(' ');
-
- return *nGlyphIndex != 0;
-}
-
-static hb_position_t getGlyphAdvanceH(hb_font_t* /*font*/, void* pFontData,
- hb_codepoint_t nGlyphIndex,
- void* /*pUserData*/)
-{
- ServerFont* pFont = static_cast<ServerFont*>(pFontData);
- const GlyphMetric& rGM = pFont->GetGlyphMetric(nGlyphIndex);
- return rGM.GetCharWidth() << 6;
-}
-
-#if !HB_VERSION_ATLEAST(1, 1, 2)
-static hb_position_t getGlyphAdvanceV(hb_font_t* /*font*/, void* /*pFontData*/,
- hb_codepoint_t /*nGlyphIndex*/,
- void* /*pUserData*/)
-{
- // XXX: vertical metrics
- return 0;
-}
-
-static hb_bool_t getGlyphOriginH(hb_font_t* /*font*/, void* /*pFontData*/,
- hb_codepoint_t /*nGlyphIndex*/,
- hb_position_t* /*x*/, hb_position_t* /*y*/,
- void* /*pUserData*/)
-{
- // the horizontal origin is always (0, 0)
- return true;
-}
-
-static hb_bool_t getGlyphOriginV(hb_font_t* /*font*/, void* /*pFontData*/,
- hb_codepoint_t /*nGlyphIndex*/,
- hb_position_t* /*x*/, hb_position_t* /*y*/,
- void* /*pUserData*/)
-{
- // XXX: vertical origin
- return true;
-}
-#endif
-
-static hb_position_t getGlyphKerningH(hb_font_t* /*font*/, void* pFontData,
- hb_codepoint_t nGlyphIndex1, hb_codepoint_t nGlyphIndex2,
- void* /*pUserData*/)
-{
- // This callback is for old style 'kern' table, GPOS kerning is handled by HarfBuzz directly
-
- ServerFont* pFont = static_cast<ServerFont*>(pFontData);
- FT_Face aFace = pFont->GetFtFace();
-
- SAL_INFO("vcl.harfbuzz", "getGlyphKerningH(" << pFont << ", " << nGlyphIndex1 << ", " << nGlyphIndex2 << ")");
-
- FT_Error error;
- FT_Vector kerning;
- hb_position_t ret;
-
- error = FT_Get_Kerning(aFace, nGlyphIndex1, nGlyphIndex2, FT_KERNING_DEFAULT, &kerning);
- if (error)
- ret = 0;
- else
- ret = kerning.x;
-
- return ret;
-}
-
-#if !HB_VERSION_ATLEAST(1, 1, 2)
-static hb_position_t getGlyphKerningV(hb_font_t* /*font*/, void* /*pFontData*/,
- hb_codepoint_t /*nGlyphIndex1*/, hb_codepoint_t /*nGlyphIndex2*/,
- void* /*pUserData*/)
-{
- // XXX vertical kerning
- return 0;
-}
-#endif
-
-static hb_bool_t getGlyphExtents(hb_font_t* /*font*/, void* pFontData,
- hb_codepoint_t nGlyphIndex,
- hb_glyph_extents_t* pExtents,
- void* /*pUserData*/)
-{
- ServerFont* pFont = static_cast<ServerFont*>(pFontData);
- FT_Face aFace = pFont->GetFtFace();
-
- SAL_INFO("vcl.harfbuzz", "getGlyphExtents(" << pFont << ", " << nGlyphIndex << ")");
-
- FT_Error error;
- error = FT_Load_Glyph(aFace, nGlyphIndex, FT_LOAD_DEFAULT);
- if (!error)
- {
- pExtents->x_bearing = aFace->glyph->metrics.horiBearingX;
- pExtents->y_bearing = aFace->glyph->metrics.horiBearingY;
- pExtents->width = aFace->glyph->metrics.width;
- pExtents->height = -aFace->glyph->metrics.height;
- }
-
- return !error;
-}
-
-static hb_bool_t getGlyphContourPoint(hb_font_t* /*font*/, void* pFontData,
- hb_codepoint_t nGlyphIndex, unsigned int nPointIndex,
- hb_position_t *x, hb_position_t *y,
- void* /*pUserData*/)
-{
- bool ret = false;
- ServerFont* pFont = static_cast<ServerFont*>(pFontData);
- FT_Face aFace = pFont->GetFtFace();
-
- SAL_INFO("vcl.harfbuzz", "getGlyphContourPoint(" << pFont << ", " << nGlyphIndex << ", " << nPointIndex << ")");
-
- FT_Error error;
- error = FT_Load_Glyph(aFace, nGlyphIndex, FT_LOAD_DEFAULT);
- if (!error)
- {
- if (aFace->glyph->format == FT_GLYPH_FORMAT_OUTLINE)
- {
- if (nPointIndex < (unsigned int) aFace->glyph->outline.n_points)
- {
- *x = aFace->glyph->outline.points[nPointIndex].x;
- *y = aFace->glyph->outline.points[nPointIndex].y;
- ret = true;
- }
- }
- }
-
- return ret;
-}
-
-static hb_font_funcs_t* getFontFuncs()
-{
- static hb_font_funcs_t* funcs = hb_font_funcs_create();
-
- hb_font_funcs_set_glyph_func (funcs, getFontGlyph, nullptr, nullptr);
- hb_font_funcs_set_glyph_h_advance_func (funcs, getGlyphAdvanceH, nullptr, nullptr);
- hb_font_funcs_set_glyph_h_kerning_func (funcs, getGlyphKerningH, nullptr, nullptr);
- hb_font_funcs_set_glyph_extents_func (funcs, getGlyphExtents, nullptr, nullptr);
- hb_font_funcs_set_glyph_contour_point_func (funcs, getGlyphContourPoint, nullptr, nullptr);
-#if !HB_VERSION_ATLEAST(1, 1, 2)
- hb_font_funcs_set_glyph_v_advance_func (funcs, getGlyphAdvanceV, nullptr, nullptr);
- hb_font_funcs_set_glyph_h_origin_func (funcs, getGlyphOriginH, nullptr, nullptr);
- hb_font_funcs_set_glyph_v_origin_func (funcs, getGlyphOriginV, nullptr, nullptr);
- hb_font_funcs_set_glyph_v_kerning_func (funcs, getGlyphKerningV, nullptr, nullptr);
-#endif
-
- return funcs;
-}
-
-#if !HB_VERSION_ATLEAST(1, 1, 0)
-// Disabled Unicode compatibility decomposition, see fdo#66715
-static unsigned int unicodeDecomposeCompatibility(hb_unicode_funcs_t* /*ufuncs*/,
- hb_codepoint_t /*u*/,
- hb_codepoint_t* /*decomposed*/,
- void* /*user_data*/)
-{
- return 0;
-}
-
-static hb_unicode_funcs_t* getUnicodeFuncs()
-{
- static hb_unicode_funcs_t* ufuncs = hb_unicode_funcs_create(hb_icu_get_unicode_funcs());
- hb_unicode_funcs_set_decompose_compatibility_func(ufuncs, unicodeDecomposeCompatibility, nullptr, nullptr);
- return ufuncs;
-}
-#endif
-
-class HbLayoutEngine : public ServerFontLayoutEngine
-{
-private:
- hb_script_t maHbScript;
- hb_face_t* mpHbFace;
- int mnUnitsPerEM;
-
-public:
- explicit HbLayoutEngine(ServerFont&);
- virtual ~HbLayoutEngine();
-
- virtual bool Layout(ServerFontLayout&, ImplLayoutArgs&) override;
-};
-
-HbLayoutEngine::HbLayoutEngine(ServerFont& rServerFont)
-: maHbScript(HB_SCRIPT_INVALID),
- mpHbFace(nullptr),
- mnUnitsPerEM(0)
-{
- FT_Face aFtFace = rServerFont.GetFtFace();
- mnUnitsPerEM = rServerFont.GetEmUnits();
-
- mpHbFace = hb_face_create_for_tables(getFontTable, &rServerFont, nullptr);
- hb_face_set_index(mpHbFace, aFtFace->face_index);
- hb_face_set_upem(mpHbFace, mnUnitsPerEM);
-}
-
-HbLayoutEngine::~HbLayoutEngine()
-{
- hb_face_destroy(mpHbFace);
-}
-
-struct HbScriptRun
-{
- int32_t mnMin;
- int32_t mnEnd;
- hb_script_t maScript;
-
- HbScriptRun(int32_t nMin, int32_t nEnd, UScriptCode aScript)
- : mnMin(nMin), mnEnd(nEnd),
- maScript(hb_icu_script_to_script(aScript))
- {}
-};
-
-typedef std::vector<HbScriptRun> HbScriptRuns;
-
-namespace vcl {
- struct Run
- {
- int32_t nStart;
- int32_t nEnd;
- UScriptCode nCode;
- Run(int32_t nStart_, int32_t nEnd_, UScriptCode nCode_)
- : nStart(nStart_), nEnd(nEnd_), nCode(nCode_)
- {}
- };
-
- class TextLayoutCache
- {
- public:
- std::vector<vcl::Run> runs;
- TextLayoutCache(sal_Unicode const* pStr, sal_Int32 const nEnd)
- {
- vcl::ScriptRun aScriptRun(
- reinterpret_cast<const UChar *>(pStr),
- nEnd);
- while (aScriptRun.next())
- {
- runs.push_back(Run(aScriptRun.getScriptStart(),
- aScriptRun.getScriptEnd(), aScriptRun.getScriptCode()));
- }
- }
- };
-}
-
-std::shared_ptr<vcl::TextLayoutCache> ServerFontLayout::CreateTextLayoutCache(
- OUString const& rString) const
-{
- return std::make_shared<vcl::TextLayoutCache>(rString.getStr(), rString.getLength());
-}
-
-bool HbLayoutEngine::Layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs)
-{
- ServerFont& rFont = rLayout.GetServerFont();
- FT_Face aFtFace = rFont.GetFtFace();
-
- SAL_INFO("vcl.harfbuzz", "layout(" << this << ",rArgs=" << rArgs << ")");
-
- static hb_font_funcs_t* pHbFontFuncs = getFontFuncs();
-
- hb_font_t *pHbFont = hb_font_create(mpHbFace);
- hb_font_set_funcs(pHbFont, pHbFontFuncs, &rFont, nullptr);
- hb_font_set_scale(pHbFont,
- ((uint64_t) aFtFace->size->metrics.x_scale * (uint64_t) mnUnitsPerEM) >> 16,
- ((uint64_t) aFtFace->size->metrics.y_scale * (uint64_t) mnUnitsPerEM) >> 16);
- hb_font_set_ppem(pHbFont, aFtFace->size->metrics.x_ppem, aFtFace->size->metrics.y_ppem);
-
- // allocate temporary arrays, note: round to even
- int nGlyphCapacity = (3 * (rArgs.mnEndCharPos - rArgs.mnMinCharPos) | 15) + 1;
- int32_t nVirtAdv = int32_t(aFtFace->size->metrics.height*rFont.GetStretch())>>6;
-
- rLayout.Reserve(nGlyphCapacity);
-
- const int nLength = rArgs.mrStr.getLength();
- const sal_Unicode *pStr = rArgs.mrStr.getStr();
-
- std::unique_ptr<vcl::TextLayoutCache> pNewScriptRun;
- vcl::TextLayoutCache const* pTextLayout;
- if (rArgs.m_pTextLayoutCache)
- {
- pTextLayout = rArgs.m_pTextLayoutCache; // use cache!
- }
- else
- {
- pNewScriptRun.reset(new vcl::TextLayoutCache(pStr, rArgs.mnEndCharPos));
- pTextLayout = pNewScriptRun.get();
- }
-
- Point aCurrPos(0, 0);
- while (true)
- {
- int nBidiMinRunPos, nBidiEndRunPos;
- bool bRightToLeft;
- if (!rArgs.GetNextRun(&nBidiMinRunPos, &nBidiEndRunPos, &bRightToLeft))
- break;
-
- // Find script subruns.
- int nCurrentPos = nBidiMinRunPos;
- HbScriptRuns aScriptSubRuns;
- size_t k = 0;
- for (; k < pTextLayout->runs.size(); ++k)
- {
- vcl::Run const& rRun(pTextLayout->runs[k]);
- if (rRun.nStart <= nCurrentPos && nCurrentPos < rRun.nEnd)
- {
- break;
- }
- }
-
- while (nCurrentPos < nBidiEndRunPos && k < pTextLayout->runs.size())
- {
- int32_t nMinRunPos = nCurrentPos;
- int32_t nEndRunPos = std::min(pTextLayout->runs[k].nEnd, nBidiEndRunPos);
- HbScriptRun aRun(nMinRunPos, nEndRunPos, pTextLayout->runs[k].nCode);
- aScriptSubRuns.push_back(aRun);
-
- nCurrentPos = nEndRunPos;
- ++k;
- }
-
- // RTL subruns should be reversed to ensure that final glyph order is
- // correct.
- if (bRightToLeft)
- std::reverse(aScriptSubRuns.begin(), aScriptSubRuns.end());
-
- for (HbScriptRuns::iterator it = aScriptSubRuns.begin(); it != aScriptSubRuns.end(); ++it)
- {
- int nMinRunPos = it->mnMin;
- int nEndRunPos = it->mnEnd;
- int nRunLen = nEndRunPos - nMinRunPos;
- maHbScript = it->maScript;
- // hb_language_from_string() accept ISO639-3 language tag except for Chinese.
- LanguageTag &rTag = rArgs.maLanguageTag;
- OString sLanguage = OUStringToOString( MsLangId::isChinese(rTag.getLanguageType()) ? rTag.getBcp47():rTag.getLanguage() , RTL_TEXTENCODING_UTF8 );
-
- int nHbFlags = HB_BUFFER_FLAGS_DEFAULT;
- if (nMinRunPos == 0)
- nHbFlags |= HB_BUFFER_FLAG_BOT; /* Beginning-of-text */
- if (nEndRunPos == nLength)
- nHbFlags |= HB_BUFFER_FLAG_EOT; /* End-of-text */
-
- hb_buffer_t *pHbBuffer = hb_buffer_create();
-#if !HB_VERSION_ATLEAST(1, 1, 0)
- static hb_unicode_funcs_t* pHbUnicodeFuncs = getUnicodeFuncs();
- hb_buffer_set_unicode_funcs(pHbBuffer, pHbUnicodeFuncs);
-#endif
- hb_buffer_set_direction(pHbBuffer, bRightToLeft ? HB_DIRECTION_RTL: HB_DIRECTION_LTR);
- hb_buffer_set_script(pHbBuffer, maHbScript);
- hb_buffer_set_language(pHbBuffer, hb_language_from_string(sLanguage.getStr(), -1));
- hb_buffer_set_flags(pHbBuffer, (hb_buffer_flags_t) nHbFlags);
- hb_buffer_add_utf16(
- pHbBuffer, reinterpret_cast<uint16_t const *>(pStr), nLength,
- nMinRunPos, nRunLen);
- hb_shape(pHbFont, pHbBuffer, nullptr, 0);
-
- int nRunGlyphCount = hb_buffer_get_length(pHbBuffer);
- hb_glyph_info_t *pHbGlyphInfos = hb_buffer_get_glyph_infos(pHbBuffer, nullptr);
- hb_glyph_position_t *pHbPositions = hb_buffer_get_glyph_positions(pHbBuffer, nullptr);
-
- for (int i = 0; i < nRunGlyphCount; ++i) {
- int32_t nGlyphIndex = pHbGlyphInfos[i].codepoint;
- int32_t nCharPos = pHbGlyphInfos[i].cluster;
-
- // if needed request glyph fallback by updating LayoutArgs
- if (!nGlyphIndex)
- {
- rLayout.SetNeedFallback(rArgs, nCharPos, bRightToLeft);
- if (SalLayoutFlags::ForFallback & rArgs.mnFlags)
- continue;
- }
-
- // apply vertical flags and glyph substitution
- // XXX: Use HB_DIRECTION_TTB above and apply whatever flags magic
- // FixupGlyphIndex() is doing, minus the GSUB part.
- if (nCharPos >= 0)
- {
- sal_UCS4 aChar = rArgs.mrStr[nCharPos];
- nGlyphIndex = rFont.FixupGlyphIndex(nGlyphIndex, aChar);
- }
-
- bool bInCluster = false;
- if (i > 0 && pHbGlyphInfos[i].cluster == pHbGlyphInfos[i - 1].cluster)
- bInCluster = true;
-
- long nGlyphFlags = 0;
- if (bRightToLeft)
- nGlyphFlags |= GlyphItem::IS_RTL_GLYPH;
-
- if (bInCluster)
- nGlyphFlags |= GlyphItem::IS_IN_CLUSTER;
-
- // The whole IS_DIACRITIC concept is a stupid hack that was
- // introduced ages ago to work around the utter brokenness of the
- // way justification adjustments are applied (the DXArray fiasco).
- // Since it is such a stupid hack, there is no sane way to directly
- // map to concepts of the "outside" world, so we do some rather
- // ugly hacks:
- // * If the font has a GDEF table, we check for glyphs with mark
- // glyph class which is sensible, except that some fonts
- // (fdo#70968) assign mark class to spacing marks (which is wrong
- // but usually harmless), so we try to sniff what HarfBuzz thinks
- // about this glyph by checking if it gives it a zero advance
- // width.
- // * If the font has no GDEF table, we just check if the glyph has
- // zero advance width, but this is stupid and can be wrong. A
- // better way would to check the character's Unicode combining
- // class, but unfortunately glyph gives combining marks the
- // cluster value of its base character, so nCharPos will be
- // pointing to the wrong character (but HarfBuzz might change
- // this in the future).
- bool bDiacritic = false;
- if (hb_ot_layout_has_glyph_classes(mpHbFace))
- {
- // the font has GDEF table
- bool bMark = hb_ot_layout_get_glyph_class(mpHbFace, nGlyphIndex) == HB_OT_LAYOUT_GLYPH_CLASS_MARK;
- if (bMark && pHbPositions[i].x_advance == 0)
- bDiacritic = true;
- }
- else
- {
- // the font lacks GDEF table
- if (pHbPositions[i].x_advance == 0)
- bDiacritic = true;
- }
-
- if (bDiacritic)
- nGlyphFlags |= GlyphItem::IS_DIACRITIC;
-
- int32_t nXOffset = pHbPositions[i].x_offset >> 6;
- int32_t nYOffset = pHbPositions[i].y_offset >> 6;
- int32_t nXAdvance = pHbPositions[i].x_advance >> 6;
- int32_t nYAdvance = pHbPositions[i].y_advance >> 6;
- if ( nGlyphIndex & GF_ROTMASK )
- nXAdvance = nVirtAdv;
-
- Point aNewPos = Point(aCurrPos.X() + nXOffset, -(aCurrPos.Y() + nYOffset));
- const GlyphItem aGI(nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nXAdvance, nXOffset, nYOffset);
- rLayout.AppendGlyph(aGI);
-
- aCurrPos.X() += nXAdvance;
- aCurrPos.Y() += nYAdvance;
- }
-
- hb_buffer_destroy(pHbBuffer);
- }
- }
-
- hb_font_destroy(pHbFont);
-
- // sort glyphs in visual order
- // and then in logical order (e.g. diacritics after cluster start)
- // XXX: why?
- rLayout.SortGlyphItems();
-
- // determine need for kashida justification
- if((rArgs.mpDXArray || rArgs.mnLayoutWidth)
- && ((maHbScript == HB_SCRIPT_ARABIC) || (maHbScript == HB_SCRIPT_SYRIAC)))
- rArgs.mnFlags |= SalLayoutFlags::KashidaJustification;
-
- return true;
-}
-
-ServerFontLayoutEngine* ServerFont::GetLayoutEngine()
-{
- // find best layout engine for font, platform, script and language
- if (!mpLayoutEngine) {
- mpLayoutEngine = new HbLayoutEngine(*this);
- }
- return mpLayoutEngine;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/generic/glyphs/glyphcache.cxx b/vcl/generic/glyphs/glyphcache.cxx
deleted file mode 100644
index 33f06df2faab..000000000000
--- a/vcl/generic/glyphs/glyphcache.cxx
+++ /dev/null
@@ -1,379 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include <stdlib.h>
-#include <math.h>
-#include "unx/freetype_glyphcache.hxx"
-
-#include <vcl/svapp.hxx>
-#include <vcl/bitmap.hxx>
-#include <fontinstance.hxx>
-#include <fontattributes.hxx>
-
-#include <config_graphite.h>
-#if ENABLE_GRAPHITE
-#include <graphite_features.hxx>
-#endif
-
-#include <rtl/ustring.hxx>
-#include <osl/file.hxx>
-#include <tools/debug.hxx>
-
-static GlyphCache* pInstance = nullptr;
-
-GlyphCache::GlyphCache()
-: mnMaxSize( 1500000 ),
- mnBytesUsed(sizeof(GlyphCache)),
- mnLruIndex(0),
- mnGlyphCount(0),
- mpCurrentGCFont(nullptr),
- mpFtManager(nullptr)
-{
- pInstance = this;
- mpFtManager = new FreetypeManager;
-}
-
-GlyphCache::~GlyphCache()
-{
- InvalidateAllGlyphs();
- delete mpFtManager;
-}
-
-void GlyphCache::InvalidateAllGlyphs()
-{
- for( FontList::iterator it = maFontList.begin(), end = maFontList.end(); it != end; ++it )
- {
- ServerFont* pServerFont = it->second;
- // free all pServerFont related data
- pServerFont->GarbageCollect( mnLruIndex+0x10000000 );
- delete pServerFont;
- }
-
- maFontList.clear();
- mpCurrentGCFont = nullptr;
-}
-
-inline
-size_t GlyphCache::IFSD_Hash::operator()( const FontSelectPattern& rFontSelData ) const
-{
- // TODO: is it worth to improve this hash function?
- sal_IntPtr nFontId = reinterpret_cast<sal_IntPtr>( rFontSelData.mpFontData );
-#if ENABLE_GRAPHITE
- if (rFontSelData.maTargetName.indexOf(grutils::GrFeatureParser::FEAT_PREFIX)
- != -1)
- {
- OString aFeatName = OUStringToOString( rFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 );
- nFontId ^= aFeatName.hashCode();
- }
-#endif
- size_t nHash = nFontId << 8;
- nHash += rFontSelData.mnHeight;
- nHash += rFontSelData.mnOrientation;
- nHash += size_t(rFontSelData.mbVertical);
- nHash += rFontSelData.GetSlantType();
- nHash += rFontSelData.GetWeight();
-#if ENABLE_GRAPHITE
- nHash += rFontSelData.meLanguage;
-#endif
- return nHash;
-}
-
-bool GlyphCache::IFSD_Equal::operator()( const FontSelectPattern& rA, const FontSelectPattern& rB) const
-{
- // check font ids
- sal_IntPtr nFontIdA = reinterpret_cast<sal_IntPtr>( rA.mpFontData );
- sal_IntPtr nFontIdB = reinterpret_cast<sal_IntPtr>( rB.mpFontData );
- if( nFontIdA != nFontIdB )
- return false;
-
- // compare with the requested metrics
- if( (rA.mnHeight != rB.mnHeight)
- || (rA.mnOrientation != rB.mnOrientation)
- || (rA.mbVertical != rB.mbVertical)
- || (rA.mbNonAntialiased != rB.mbNonAntialiased) )
- return false;
-
- if( (rA.GetSlantType() != rB.GetSlantType())
- || (rA.GetWeight() != rB.GetWeight()) )
- return false;
-
- // NOTE: ignoring meFamily deliberately
-
- // compare with the requested width, allow default width
- int nAWidth = rA.mnWidth != 0 ? rA.mnWidth : rA.mnHeight;
- int nBWidth = rB.mnWidth != 0 ? rB.mnWidth : rB.mnHeight;
- if( nAWidth != nBWidth )
- return false;
-
-#if ENABLE_GRAPHITE
- if (rA.meLanguage != rB.meLanguage)
- return false;
- // check for features
- if ((rA.maTargetName.indexOf(grutils::GrFeatureParser::FEAT_PREFIX)
- != -1 ||
- rB.maTargetName.indexOf(grutils::GrFeatureParser::FEAT_PREFIX)
- != -1) && rA.maTargetName != rB.maTargetName)
- return false;
-#endif
-
- if (rA.mbEmbolden != rB.mbEmbolden)
- return false;
-
- if (rA.maItalicMatrix != rB.maItalicMatrix)
- return false;
-
- return true;
-}
-
-GlyphCache& GlyphCache::GetInstance()
-{
- return *pInstance;
-}
-
-void GlyphCache::AddFontFile( const OString& rNormalizedName, int nFaceNum,
- sal_IntPtr nFontId, const FontAttributes& rDFA)
-{
- if( mpFtManager )
- mpFtManager->AddFontFile( rNormalizedName, nFaceNum, nFontId, rDFA);
-}
-
-void GlyphCache::AnnounceFonts( PhysicalFontCollection* pFontCollection ) const
-{
- if( mpFtManager )
- mpFtManager->AnnounceFonts( pFontCollection );
-}
-
-void GlyphCache::ClearFontCache()
-{
- InvalidateAllGlyphs();
- if (mpFtManager)
- mpFtManager->ClearFontList();
-}
-
-ServerFont* GlyphCache::CacheFont( const FontSelectPattern& rFontSelData )
-{
- // a serverfont request has pFontData
- if( rFontSelData.mpFontData == nullptr )
- return nullptr;
- // a serverfont request has a fontid > 0
- sal_IntPtr nFontId = rFontSelData.mpFontData->GetFontId();
- if( nFontId <= 0 )
- return nullptr;
-
- // the FontList's key mpFontData member is reinterpreted as font id
- FontSelectPattern aFontSelData = rFontSelData;
- aFontSelData.mpFontData = reinterpret_cast<PhysicalFontFace*>( nFontId );
- FontList::iterator it = maFontList.find( aFontSelData );
- if( it != maFontList.end() )
- {
- ServerFont* pFound = it->second;
- if( pFound )
- pFound->AddRef();
- return pFound;
- }
-
- // font not cached yet => create new font item
- ServerFont* pNew = nullptr;
- if( mpFtManager )
- pNew = mpFtManager->CreateFont( aFontSelData );
-
- if( pNew )
- {
- maFontList[ aFontSelData ] = pNew;
- mnBytesUsed += pNew->GetByteCount();
-
- // enable garbage collection for new font
- if( !mpCurrentGCFont )
- {
- mpCurrentGCFont = pNew;
- pNew->mpNextGCFont = pNew;
- pNew->mpPrevGCFont = pNew;
- }
- else
- {
- pNew->mpNextGCFont = mpCurrentGCFont;
- pNew->mpPrevGCFont = mpCurrentGCFont->mpPrevGCFont;
- pNew->mpPrevGCFont->mpNextGCFont = pNew;
- mpCurrentGCFont->mpPrevGCFont = pNew;
- }
- }
-
- return pNew;
-}
-
-void GlyphCache::UncacheFont( ServerFont& rServerFont )
-{
- if( (rServerFont.Release() <= 0) && (mnMaxSize <= mnBytesUsed) )
- {
- mpCurrentGCFont = &rServerFont;
- GarbageCollect();
- }
-}
-
-void GlyphCache::GarbageCollect()
-{
- // when current GC font has been destroyed get another one
- if( !mpCurrentGCFont )
- {
- FontList::iterator it = maFontList.begin();
- if( it != maFontList.end() )
- mpCurrentGCFont = it->second;
- }
-
- // unless there is no other font to collect
- if( !mpCurrentGCFont )
- return;
-
- // prepare advance to next font for garbage collection
- ServerFont* const pServerFont = mpCurrentGCFont;
- mpCurrentGCFont = pServerFont->mpNextGCFont;
-
- if( (pServerFont == mpCurrentGCFont) // no other fonts
- || (pServerFont->GetRefCount() > 0) ) // font still used
- {
- // try to garbage collect at least a few bytes
- pServerFont->GarbageCollect( mnLruIndex - mnGlyphCount/2 );
- }
- else // current GC font is unreferenced
- {
- DBG_ASSERT( (pServerFont->GetRefCount() == 0),
- "GlyphCache::GC detected RefCount underflow" );
-
- // free all pServerFont related data
- pServerFont->GarbageCollect( mnLruIndex+0x10000000 );
- if( pServerFont == mpCurrentGCFont )
- mpCurrentGCFont = nullptr;
- const FontSelectPattern& rIFSD = pServerFont->GetFontSelData();
- maFontList.erase( rIFSD );
- mnBytesUsed -= pServerFont->GetByteCount();
-
- // remove font from list of garbage collected fonts
- if( pServerFont->mpPrevGCFont )
- pServerFont->mpPrevGCFont->mpNextGCFont = pServerFont->mpNextGCFont;
- if( pServerFont->mpNextGCFont )
- pServerFont->mpNextGCFont->mpPrevGCFont = pServerFont->mpPrevGCFont;
- if( pServerFont == mpCurrentGCFont )
- mpCurrentGCFont = nullptr;
-
- delete pServerFont;
- }
-}
-
-inline void GlyphCache::UsingGlyph( ServerFont&, GlyphData& rGlyphData )
-{
- rGlyphData.SetLruValue( mnLruIndex++ );
-}
-
-inline void GlyphCache::AddedGlyph( ServerFont& rServerFont, GlyphData& rGlyphData )
-{
- ++mnGlyphCount;
- mnBytesUsed += sizeof( rGlyphData );
- UsingGlyph( rServerFont, rGlyphData );
- GrowNotify();
-}
-
-void GlyphCache::GrowNotify()
-{
- if( mnBytesUsed > mnMaxSize )
- GarbageCollect();
-}
-
-inline void GlyphCache::RemovingGlyph()
-{
- mnBytesUsed -= sizeof( GlyphData );
- --mnGlyphCount;
-}
-
-void ServerFont::ReleaseFromGarbageCollect()
-{
- // remove from GC list
- ServerFont* pPrev = mpPrevGCFont;
- ServerFont* pNext = mpNextGCFont;
- if( pPrev ) pPrev->mpNextGCFont = pNext;
- if( pNext ) pNext->mpPrevGCFont = pPrev;
- mpPrevGCFont = nullptr;
- mpNextGCFont = nullptr;
-}
-
-long ServerFont::Release() const
-{
- DBG_ASSERT( mnRefCount > 0, "ServerFont: RefCount underflow" );
- return --mnRefCount;
-}
-
-GlyphData& ServerFont::GetGlyphData( sal_GlyphId aGlyphId )
-{
- // usually the GlyphData is cached
- GlyphList::iterator it = maGlyphList.find( aGlyphId );
- if( it != maGlyphList.end() ) {
- GlyphData& rGlyphData = it->second;
- GlyphCache::GetInstance().UsingGlyph( *this, rGlyphData );
- return rGlyphData;
- }
-
- // sometimes not => we need to create and initialize it ourselves
- GlyphData& rGlyphData = maGlyphList[ aGlyphId ];
- mnBytesUsed += sizeof( GlyphData );
- InitGlyphData( aGlyphId, rGlyphData );
- GlyphCache::GetInstance().AddedGlyph( *this, rGlyphData );
- return rGlyphData;
-}
-
-void ServerFont::GarbageCollect( long nMinLruIndex )
-{
- GlyphList::iterator it = maGlyphList.begin();
- while( it != maGlyphList.end() )
- {
- GlyphData& rGD = it->second;
- if( (nMinLruIndex - rGD.GetLruValue()) > 0 )
- {
- OSL_ASSERT( mnBytesUsed >= sizeof(GlyphData) );
- mnBytesUsed -= sizeof( GlyphData );
- GlyphCache::GetInstance().RemovingGlyph();
- it = maGlyphList.erase( it );
- }
- else
- ++it;
- }
-}
-
-ServerFontInstance::ServerFontInstance( FontSelectPattern& rFSD )
-: LogicalFontInstance( rFSD )
-, mpServerFont( nullptr )
-, mbGotFontOptions( false )
-{}
-
-void ServerFontInstance::SetServerFont(ServerFont* p)
-{
- if (p == mpServerFont)
- return;
- if (mpServerFont)
- mpServerFont->Release();
- mpServerFont = p;
- if (mpServerFont)
- mpServerFont->AddRef();
-}
-
-ServerFontInstance::~ServerFontInstance()
-{
- // TODO: remove the ServerFont here instead of in the GlyphCache
- if (mpServerFont)
- mpServerFont->Release();
-}
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/generic/glyphs/graphite_serverfont.cxx b/vcl/generic/glyphs/graphite_serverfont.cxx
deleted file mode 100644
index 623df7b3fb8d..000000000000
--- a/vcl/generic/glyphs/graphite_serverfont.cxx
+++ /dev/null
@@ -1,135 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-// Header files
-
-// Platform
-#include <i18nlangtag/languagetag.hxx>
-#include <sallayout.hxx>
-// Module
-#include "unx/freetype_glyphcache.hxx"
-#include "generic/glyphcache.hxx"
-#include <graphite_features.hxx>
-#include <graphite_serverfont.hxx>
-
-float freetypeServerFontAdvance(const void* appFontHandle, gr_uint16 glyphId)
-{
- ServerFont * pServerFont =
- const_cast<ServerFont*>
- (static_cast<const ServerFont*>(appFontHandle));
- if (pServerFont)
- {
- return static_cast<float>(pServerFont->GetGlyphMetric(glyphId).GetCharWidth());
- }
- return .0f;
-}
-
-// An implementation of the GraphiteLayout interface to enable Graphite enabled fonts to be used.
-
-GraphiteServerFontLayout::GraphiteServerFontLayout(ServerFont& rServerFont) throw()
- : ServerFontLayout(rServerFont),
- maImpl(rServerFont.GetGraphiteFace()->face(), rServerFont)
- , mpFeatures(nullptr)
-{
- gr_font * pFont = rServerFont.GetGraphiteFace()->font(rServerFont.GetFontSelData().mnHeight, rServerFont.NeedsArtificialBold(), rServerFont.NeedsArtificialItalic());
- if (!pFont)
- {
- pFont = gr_make_font_with_advance_fn(
- // need to use mnHeight here, mfExactHeight can give wrong values
- static_cast<float>(rServerFont.GetFontSelData().mnHeight),
- &rServerFont,
- freetypeServerFontAdvance,
- rServerFont.GetGraphiteFace()->face());
- rServerFont.GetGraphiteFace()->addFont(rServerFont.GetFontSelData().mnHeight, pFont, rServerFont.NeedsArtificialBold(), rServerFont.NeedsArtificialItalic());
- }
- maImpl.SetFont(pFont);
- OString aLang("");
- if (rServerFont.GetFontSelData().meLanguage != LANGUAGE_DONTKNOW)
- {
- aLang = OUStringToOString( LanguageTag( rServerFont.GetFontSelData().meLanguage ).getBcp47(),
- RTL_TEXTENCODING_UTF8 );
- }
- OString name = OUStringToOString(
- rServerFont.GetFontSelData().maTargetName, RTL_TEXTENCODING_UTF8 );
-#ifdef DEBUG
- printf("GraphiteServerFontLayout %lx %s size %d %f\n", (long unsigned int)this, name.getStr(),
- rServerFont.GetMetricsFT().x_ppem,
- rServerFont.GetFontSelData().mfExactHeight);
-#endif
- sal_Int32 nFeat = name.indexOf(grutils::GrFeatureParser::FEAT_PREFIX) + 1;
- if (nFeat > 0)
- {
- OString aFeat = name.copy(nFeat, name.getLength() - nFeat);
- mpFeatures = new grutils::GrFeatureParser(
- rServerFont.GetGraphiteFace()->face(), aFeat, aLang);
-#ifdef DEBUG
- if (mpFeatures)
- printf("GraphiteServerFontLayout %s/%s/%s %x language %d features %d errors\n",
- OUStringToOString( rServerFont.GetFontSelData().GetFamilyName(),
- RTL_TEXTENCODING_UTF8 ).getStr(),
- OUStringToOString( rServerFont.GetFontSelData().maTargetName,
- RTL_TEXTENCODING_UTF8 ).getStr(),
- OUStringToOString( rServerFont.GetFontSelData().maSearchName,
- RTL_TEXTENCODING_UTF8 ).getStr(),
- rServerFont.GetFontSelData().meLanguage,
- (int)mpFeatures->numFeatures(), mpFeatures->parseErrors());
-#endif
- }
- else
- {
- mpFeatures = new grutils::GrFeatureParser(
- rServerFont.GetGraphiteFace()->face(), aLang);
- }
- maImpl.SetFeatures(mpFeatures);
-}
-
-GraphiteServerFontLayout::~GraphiteServerFontLayout() throw()
-{
- delete mpFeatures;
- mpFeatures = nullptr;
-}
-
-bool GraphiteServerFontLayout::IsGraphiteEnabledFont(ServerFont& rServerFont)
-{
- if (rServerFont.GetGraphiteFace())
- {
-#ifdef DEBUG
- printf("IsGraphiteEnabledFont\n");
-#endif
- return true;
- }
- return false;
-}
-
-sal_GlyphId GraphiteLayoutImpl::getKashidaGlyph(int & width)
-{
- int nKashidaIndex = mrServerFont.GetGlyphIndex( 0x0640 );
- if( nKashidaIndex != 0 )
- {
- const GlyphMetric& rGM = mrServerFont.GetGlyphMetric( nKashidaIndex );
- width = rGM.GetCharWidth();
- }
- else
- {
- width = 0;
- }
- return nKashidaIndex;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/generic/glyphs/scrptrun.cxx b/vcl/generic/glyphs/scrptrun.cxx
deleted file mode 100644
index d6557d79a894..000000000000
--- a/vcl/generic/glyphs/scrptrun.cxx
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- *******************************************************************************
- *
- * Copyright (c) 1995-2013 International Business Machines Corporation and others
- *
- * All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, and/or sell copies of the
- * Software, and to permit persons to whom the Software is furnished to do so,
- * provided that the above copyright notice(s) and this permission notice appear
- * in all copies of the Software and that both the above copyright notice(s) and
- * this permission notice appear in supporting documentation.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
- * NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE
- * LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY
- * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Except as contained in this notice, the name of a copyright holder shall not be
- * used in advertising or otherwise to promote the sale, use or other dealings in
- * this Software without prior written authorization of the copyright holder.
- *
- *******************************************************************************
- * file name: scrptrun.cpp
- *
- * created on: 10/17/2001
- * created by: Eric R. Mader
- */
-/**
- * This file is largely copied from the ICU project,
- * under folder source/extra/scrptrun/scrptrun.cpp
- */
-#include "unicode/utypes.h"
-#include "unicode/uscript.h"
-
-#include "scrptrun.h"
-#include <algorithm>
-
-namespace {
-
-struct PairIndices
-{
- int8_t ma00[0xff];
- int8_t ma20[0x7f];
- int8_t ma30[0x7f];
-
- PairIndices()
- {
- std::fill_n(ma00, 0xff, -1);
- std::fill_n(ma20, 0x7f, -1);
- std::fill_n(ma30, 0x7f, -1);
-
- // characters in the range 0x0000 - 0x007e (inclusive)
- // ascii paired punctuation
- ma00[0x28] = 0;
- ma00[0x29] = 1;
- ma00[0x3c] = 2;
- ma00[0x3e] = 3;
- ma00[0x5b] = 4;
- ma00[0x5d] = 5;
- ma00[0x7b] = 6;
- ma00[0x7d] = 7;
- // guillemets
- ma00[0xab] = 8;
- ma00[0xbb] = 9;
-
- // characters in the range 0x2000 - 0x207e (inclusive)
- // general punctuation
- ma20[0x18] = 10;
- ma20[0x19] = 11;
- ma20[0x1c] = 12;
- ma20[0x1d] = 13;
- ma20[0x39] = 14;
- ma20[0x3a] = 15;
-
- // characters in the range 0x3000 - 0x307e (inclusive)
- // chinese paired punctuation
- ma30[0x08] = 16;
- ma30[0x09] = 17;
- ma30[0x0a] = 18;
- ma30[0x0b] = 19;
- ma30[0x0c] = 20;
- ma30[0x0d] = 21;
- ma30[0x0e] = 22;
- ma30[0x0f] = 23;
- ma30[0x10] = 24;
- ma30[0x11] = 25;
- ma30[0x14] = 26;
- ma30[0x15] = 27;
- ma30[0x16] = 28;
- ma30[0x17] = 29;
- ma30[0x18] = 30;
- ma30[0x19] = 31;
- ma30[0x1a] = 32;
- ma30[0x1b] = 33;
- }
-
- inline int32_t getPairIndex(UChar32 ch) const
- {
- if (ch < 0xff)
- return ma00[ch];
- if (ch >= 0x2000 && ch < 0x207f)
- return ma20[ch - 0x2000];
- if (ch >= 0x3000 && ch < 0x307f)
- return ma30[ch - 0x3000];
- return -1;
- }
-
-};
-
-}
-
-static const PairIndices gPairIndices;
-
-
-namespace vcl {
-
-const char ScriptRun::fgClassID=0;
-
-static inline UBool sameScript(int32_t scriptOne, int32_t scriptTwo)
-{
- return scriptOne <= USCRIPT_INHERITED || scriptTwo <= USCRIPT_INHERITED || scriptOne == scriptTwo;
-}
-
-UBool ScriptRun::next()
-{
- int32_t startSP = parenSP; // used to find the first new open character
- UErrorCode error = U_ZERO_ERROR;
-
- // if we've fallen off the end of the text, we're done
- if (scriptEnd >= charLimit) {
- return false;
- }
-
- scriptCode = USCRIPT_COMMON;
-
- for (scriptStart = scriptEnd; scriptEnd < charLimit; scriptEnd += 1) {
- UChar high = charArray[scriptEnd];
- UChar32 ch = high;
-
- // if the character is a high surrogate and it's not the last one
- // in the text, see if it's followed by a low surrogate
- if (high >= 0xD800 && high <= 0xDBFF && scriptEnd < charLimit - 1)
- {
- UChar low = charArray[scriptEnd + 1];
-
- // if it is followed by a low surrogate,
- // consume it and form the full character
- if (low >= 0xDC00 && low <= 0xDFFF) {
- ch = (high - 0xD800) * 0x0400 + low - 0xDC00 + 0x10000;
- scriptEnd += 1;
- }
- }
-
- UScriptCode sc = uscript_getScript(ch, &error);
- int32_t pairIndex = gPairIndices.getPairIndex(ch);
-
- // Paired character handling:
-
- // if it's an open character, push it onto the stack.
- // if it's a close character, find the matching open on the
- // stack, and use that script code. Any non-matching open
- // characters above it on the stack will be poped.
- if (pairIndex >= 0) {
- if ((pairIndex & 1) == 0) {
- ++parenSP;
- int32_t nVecSize = parenStack.size();
- if (parenSP == nVecSize)
- parenStack.resize(nVecSize + 128);
- parenStack[parenSP].pairIndex = pairIndex;
- parenStack[parenSP].scriptCode = scriptCode;
- } else if (parenSP >= 0) {
- int32_t pi = pairIndex & ~1;
-
- while (parenSP >= 0 && parenStack[parenSP].pairIndex != pi) {
- parenSP -= 1;
- }
-
- if (parenSP < startSP) {
- startSP = parenSP;
- }
-
- if (parenSP >= 0) {
- sc = parenStack[parenSP].scriptCode;
- }
- }
- }
-
- if (sameScript(scriptCode, sc)) {
- if (scriptCode <= USCRIPT_INHERITED && sc > USCRIPT_INHERITED) {
- scriptCode = sc;
-
- // now that we have a final script code, fix any open
- // characters we pushed before we knew the script code.
- while (startSP < parenSP) {
- parenStack[++startSP].scriptCode = scriptCode;
- }
- }
-
- // if this character is a close paired character,
- // pop it from the stack
- if (pairIndex >= 0 && (pairIndex & 1) != 0 && parenSP >= 0) {
- parenSP -= 1;
- /* decrement startSP only if it is >= 0,
- decrementing it unnecessarily will lead to memory corruption
- while processing the above while block.
- e.g. startSP = -4 , parenSP = -1
- */
- if (startSP >= 0) {
- startSP -= 1;
- }
- }
- } else {
- // if the run broke on a surrogate pair,
- // end it before the high surrogate
- if (ch >= 0x10000) {
- scriptEnd -= 1;
- }
-
- break;
- }
- }
-
- return true;
-}
-
-}
diff --git a/vcl/generic/glyphs/scrptrun.h b/vcl/generic/glyphs/scrptrun.h
deleted file mode 100644
index 2efcff4110ba..000000000000
--- a/vcl/generic/glyphs/scrptrun.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- *******************************************************************************
- *
- * Copyright (c) 1995-2013 International Business Machines Corporation and others
- *
- * All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, and/or sell copies of the
- * Software, and to permit persons to whom the Software is furnished to do so,
- * provided that the above copyright notice(s) and this permission notice appear
- * in all copies of the Software and that both the above copyright notice(s) and
- * this permission notice appear in supporting documentation.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
- * NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE
- * LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY
- * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Except as contained in this notice, the name of a copyright holder shall not be
- * used in advertising or otherwise to promote the sale, use or other dealings in
- * this Software without prior written authorization of the copyright holder.
- *
- *******************************************************************************
- * file name: scrptrun.h
- *
- * created on: 10/17/2001
- * created by: Eric R. Mader
- */
-
-#ifndef INCLUDED_VCL_GENERIC_GLYPHS_SCRPTRUN_H
-#define INCLUDED_VCL_GENERIC_GLYPHS_SCRPTRUN_H
-
-#include <sal/config.h>
-
-#include <sal/types.h>
-#include "unicode/utypes.h"
-#include "unicode/uobject.h"
-#include "unicode/uscript.h"
-#include <vector>
-
-namespace vcl {
-
-struct ParenStackEntry
-{
- int32_t pairIndex;
- UScriptCode scriptCode;
- ParenStackEntry()
- : pairIndex(0)
- , scriptCode(USCRIPT_INVALID_CODE)
- {
- }
-};
-
-class ScriptRun : public UObject {
-public:
- ScriptRun();
-
- ScriptRun(const UChar chars[], int32_t length);
-
- ScriptRun(const UChar chars[], int32_t start, int32_t length);
-
- void reset();
-
- void reset(int32_t start, int32_t count);
-
- void reset(const UChar chars[], int32_t start, int32_t length);
-
- int32_t getScriptStart();
-
- int32_t getScriptEnd();
-
- UScriptCode getScriptCode();
-
- UBool next();
-
- /**
-s * ICU "poor man's RTTI", returns a UClassID for the actual class.
- *
- * @stable ICU 2.2
- */
- virtual inline UClassID getDynamicClassID() const override { return getStaticClassID(); }
-
- /**
- * ICU "poor man's RTTI", returns a UClassID for this class.
- *
- * @stable ICU 2.2
- */
- static inline UClassID getStaticClassID() { return static_cast<UClassID>(const_cast<char *>(&fgClassID)); }
-
-private:
-
- int32_t charStart;
- int32_t charLimit;
- const UChar *charArray;
-
- int32_t scriptStart;
- int32_t scriptEnd;
- UScriptCode scriptCode;
-
- std::vector<ParenStackEntry> parenStack;
- int32_t parenSP;
-
- /**
- * The address of this static class variable serves as this class's ID
- * for ICU "poor man's RTTI".
- */
- static const char fgClassID;
-};
-
-inline ScriptRun::ScriptRun()
-{
- reset(NULL, 0, 0);
-}
-
-inline ScriptRun::ScriptRun(const UChar chars[], int32_t length)
-{
- reset(chars, 0, length);
-}
-
-inline ScriptRun::ScriptRun(const UChar chars[], int32_t start, int32_t length)
-{
- reset(chars, start, length);
-}
-
-inline int32_t ScriptRun::getScriptStart()
-{
- return scriptStart;
-}
-
-inline int32_t ScriptRun::getScriptEnd()
-{
- return scriptEnd;
-}
-
-inline UScriptCode ScriptRun::getScriptCode()
-{
- return scriptCode;
-}
-
-inline void ScriptRun::reset()
-{
- scriptStart = charStart;
- scriptEnd = charStart;
- scriptCode = USCRIPT_INVALID_CODE;
- parenSP = -1;
- parenStack.resize(128);
-}
-
-inline void ScriptRun::reset(int32_t start, int32_t length)
-{
- charStart = start;
- charLimit = start + length;
-
- reset();
-}
-
-inline void ScriptRun::reset(const UChar chars[], int32_t start, int32_t length)
-{
- charArray = chars;
-
- reset(start, length);
-}
-
-}
-
-#endif
diff --git a/vcl/generic/print/genpspgraphics.cxx b/vcl/generic/print/genpspgraphics.cxx
index 145bf7dc18e6..d3cc75c1466b 100644
--- a/vcl/generic/print/genpspgraphics.cxx
+++ b/vcl/generic/print/genpspgraphics.cxx
@@ -46,7 +46,7 @@
#include "fontsubset.hxx"
#include "generic/geninst.h"
#include "generic/genpspgraphics.h"
-#include "generic/glyphcache.hxx"
+#include "unx/glyphcache.hxx"
#include "generic/printergfx.hxx"
#include "impfont.hxx"
#include "langboost.hxx"