diff options
24 files changed, 14 insertions, 2508 deletions
diff --git a/bin/findunusedcode b/bin/findunusedcode index 9758ed408139..526b2f706859 100755 --- a/bin/findunusedcode +++ b/bin/findunusedcode @@ -15,7 +15,6 @@ echo "--without-doxygen --enable-gio --enable-packagekit --enable-extension-integration ---enable-graphite --enable-evolution2 --enable-online-update --enable-dbgutil diff --git a/config_host.mk.in b/config_host.mk.in index 3d39dcddde94..13c0b25a6938 100644 --- a/config_host.mk.in +++ b/config_host.mk.in @@ -132,7 +132,6 @@ export ENABLE_EVOAB2=@ENABLE_EVOAB2@ export ENABLE_FIREBIRD_SDBC=@ENABLE_FIREBIRD_SDBC@ export ENABLE_FORMULA_LOGGER=@ENABLE_FORMULA_LOGGER@ export ENABLE_GIO=@ENABLE_GIO@ -export ENABLE_GRAPHITE=@ENABLE_GRAPHITE@ export ENABLE_ORCUS=@ENABLE_ORCUS@ export ENABLE_GLTF=@ENABLE_GLTF@ export SYSTEM_LIBGLTF=@SYSTEM_LIBGLTF@ diff --git a/config_host/config_graphite.h.in b/config_host/config_graphite.h.in deleted file mode 100644 index 46e624dc01a1..000000000000 --- a/config_host/config_graphite.h.in +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef CONFIG_GRAPHITE_H -#define CONFIG_GRAPHITE_H - -#define ENABLE_GRAPHITE 0 - -#endif diff --git a/configure.ac b/configure.ac index 62f0b0f339ca..731e9035bd08 100644 --- a/configure.ac +++ b/configure.ac @@ -1039,11 +1039,6 @@ AC_ARG_ENABLE(mergelibs, for Linux any more. This will link a core set of libraries into libmerged.]) ) -AC_ARG_ENABLE(graphite, - AS_HELP_STRING([--disable-graphite], - [Disables the compilation of Graphite smart font rendering.]) -) - AC_ARG_ENABLE(breakpad, AS_HELP_STRING([--enable-breakpad], [Enables breakpad for crash reporting.]) @@ -4593,7 +4588,6 @@ if test "$cross_compiling" = "yes"; then # Don't bother having configure look for stuff not needed for the build platform anyway ./configure \ --disable-cups \ - --disable-graphite \ --disable-gtk3 \ --disable-pdfimport \ --disable-postgresql-sdbc \ @@ -9183,29 +9177,6 @@ AC_SUBST(ICU_RECLASSIFIED_HEBREW_LETTER) AC_SUBST(ICU_CFLAGS) AC_SUBST(ICU_LIBS) -dnl =================================================================== -dnl Graphite -dnl =================================================================== -libo_CHECK_SYSTEM_MODULE([graphite],[GRAPHITE],[graphite2 >= 0.9.3],["-I${WORKDIR}/UnpackedTarball/graphite/include -DGRAPHITE2_STATIC"],["-L${WORKDIR}/LinkTarget/StaticLibrary -lgraphite"]) -if test "$with_system_graphite" = "yes"; then - libo_MINGW_CHECK_DLL([libgraphite2]) -fi -if test "$COM" = "MSC"; then # override the above - GRAPHITE_LIBS="${WORKDIR}/LinkTarget/StaticLibrary/graphite.lib" -fi - -# This is the old Graphite support that will eventually be removed -AC_MSG_CHECKING([whether to enable graphite support]) -if test $_os != Darwin -a $_os != Android -a $_os != iOS -a \( -z "$enable_graphite" -o "$enable_graphite" != no \); then - AC_MSG_RESULT([yes]) - ENABLE_GRAPHITE="TRUE" - AC_DEFINE(ENABLE_GRAPHITE) - -else - AC_MSG_RESULT([no]) -fi -AC_SUBST(ENABLE_GRAPHITE) - dnl ================================================================== dnl Breakpad dnl ================================================================== @@ -9281,10 +9252,19 @@ AC_SUBST(ENABLE_ORCUS) dnl =================================================================== dnl HarfBuzz dnl =================================================================== -libo_CHECK_SYSTEM_MODULE([harfbuzz],[HARFBUZZ],[harfbuzz-icu >= 0.9.18],["-I${WORKDIR}/UnpackedTarball/harfbuzz/src"],["-L${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs -lharfbuzz"]) +libo_CHECK_SYSTEM_MODULE([graphite],[GRAPHITE],[graphite2 >= 0.9.3], + ["-I${WORKDIR}/UnpackedTarball/graphite/include -DGRAPHITE2_STATIC"], + ["-L${WORKDIR}/LinkTarget/StaticLibrary -lgraphite"]) + +libo_CHECK_SYSTEM_MODULE([harfbuzz],[HARFBUZZ],[harfbuzz-icu >= 0.9.18], + ["-I${WORKDIR}/UnpackedTarball/harfbuzz/src"], + ["-L${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs -lharfbuzz"]) + if test "$COM" = "MSC"; then # override the above + GRAPHITE_LIBS="${WORKDIR}/LinkTarget/StaticLibrary/graphite.lib" HARFBUZZ_LIBS="${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs/libharfbuzz.lib" fi + if test "$with_system_harfbuzz" = "yes"; then if test "$with_system_graphite" = "no"; then AC_MSG_ERROR([--with-system-graphite must be used when --with-system-harfbuzz is used]) @@ -12877,7 +12857,6 @@ AC_CONFIG_HEADERS([config_host/config_firebird.h]) AC_CONFIG_HEADERS([config_host/config_folders.h]) AC_CONFIG_HEADERS([config_host/config_gio.h]) AC_CONFIG_HEADERS([config_host/config_global.h]) -AC_CONFIG_HEADERS([config_host/config_graphite.h]) AC_CONFIG_HEADERS([config_host/config_java.h]) AC_CONFIG_HEADERS([config_host/config_lgpl.h]) AC_CONFIG_HEADERS([config_host/config_liblangtag.h]) diff --git a/distro-configs/LibreOfficeEmscripten.conf b/distro-configs/LibreOfficeEmscripten.conf index 3ca706efc3c5..a72a25204b58 100644 --- a/distro-configs/LibreOfficeEmscripten.conf +++ b/distro-configs/LibreOfficeEmscripten.conf @@ -25,7 +25,6 @@ --disable-report-builder --disable-lpsolve --disable-coinmp ---disable-graphite --disable-orcus --disable-liblangtag --without-fonts diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index b8cb25748d3f..90650adcebcd 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -417,23 +417,6 @@ $(eval $(call gb_Library_add_cobjects,vcl,\ # optional parts -## handle Graphite -ifeq ($(ENABLE_GRAPHITE),TRUE) -# add graphite sources for all platforms -$(eval $(call gb_Library_add_exception_objects,vcl,\ - vcl/source/glyphs/graphite_features \ - vcl/source/glyphs/graphite_layout \ -)) - -# handle X11 platforms, which have additional files and possibly system graphite -ifneq (,$(or $(USING_X11),$(ENABLE_HEADLESS))) -$(eval $(call gb_Library_add_exception_objects,vcl,\ - vcl/unx/generic/glyphs/graphite_serverfont \ -)) -endif - -endif - vcl_quartz_code= \ vcl/quartz/salbmp \ vcl/quartz/utils \ diff --git a/vcl/inc/graphite_features.hxx b/vcl/inc/graphite_features.hxx deleted file mode 100644 index 3caa3ec2789c..000000000000 --- a/vcl/inc/graphite_features.hxx +++ /dev/null @@ -1,65 +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 . - */ - -// Description: -// Parse a string of features specified as ; separated pairs. -// e.g. -// 1001=1&2002=2&fav1=0 - -#ifndef INCLUDED_VCL_INC_GRAPHITE_FEATURES_HXX -#define INCLUDED_VCL_INC_GRAPHITE_FEATURES_HXX - -#include <sal/types.h> -#include <rtl/ustring.hxx> -#include <graphite_static.hxx> -#include <graphite2/Font.h> - -namespace grutils -{ - union FeatId - { - gr_uint32 num; - unsigned char label[5]; - }; - - class GrFeatureParser - { - public: - enum { MAX_FEATURES = 64 }; - static const char FEAT_ID_VALUE_SEPARATOR; - GrFeatureParser(const gr_face * face, const OString& features, const OString& lang); - GrFeatureParser(const gr_face * face, const OString& lang); - ~GrFeatureParser(); - gr_feature_val * values() const { return mpSettings; }; - private: - GrFeatureParser(const GrFeatureParser & copy) = delete; - void setLang(const gr_face * face, const OString & lang); - static bool isCharId(const OString & id, size_t offset, size_t length); - static gr_uint32 getCharId(const OString & id, size_t offset, size_t length); - size_t mnNumSettings; - FeatId maLang; - sal_uInt32 mnHash; - gr_feature_val * mpSettings; - }; - -} - -#endif // INCLUDED_VCL_INC_GRAPHITE_FEATURES_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/graphite_layout.hxx b/vcl/inc/graphite_layout.hxx deleted file mode 100644 index 7aacf4351ef2..000000000000 --- a/vcl/inc/graphite_layout.hxx +++ /dev/null @@ -1,159 +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 . - */ - -#ifndef INCLUDED_VCL_INC_GRAPHITE_LAYOUT_HXX -#define INCLUDED_VCL_INC_GRAPHITE_LAYOUT_HXX -// Description: An implementation of the SalLayout interface that uses the -// Graphite engine. - -// We need this to enable namespace support in libgrengine headers. -#define GR_NAMESPACE - -#include <memory> -#include <vector> -#include <map> -#include <utility> - -#include <graphite_static.hxx> -#include <graphite2/Font.h> -#include <graphite2/Segment.h> - -#include <vcl/dllapi.h> - -#include "sallayout.hxx" - -class FreetypeFont; -class PhysicalFontFace; - -namespace grutils { class GrFeatureParser; } - -class GraphiteFaceWrapper -{ -public: - typedef std::map<std::pair<int, int>, gr_font*> GrFontMap; - GraphiteFaceWrapper(gr_face * pFace) : m_pFace(pFace) {} - ~GraphiteFaceWrapper() - { - GrFontMap::iterator i = m_fonts.begin(); - while (i != m_fonts.end()) - gr_font_destroy((*i++).second); - m_fonts.clear(); - gr_face_destroy(m_pFace); - } - const gr_face * face() const { return m_pFace; } - gr_font * font(int ppm, bool isBold, bool isItalic) const - { - int styleKey = int(isBold) | (int(isItalic) << 1); - GrFontMap::const_iterator i = m_fonts.find(std::pair<int, int>(ppm, styleKey)); - if (i != m_fonts.end()) - return i->second; - return nullptr; - }; - void addFont(int ppm, gr_font * pFont, bool isBold, bool isItalic) - { - int styleKey = int(isBold) | (int(isItalic) << 1); - std::pair<int, int> key(ppm, styleKey); - if (m_fonts[key]) - gr_font_destroy(m_fonts[key]); - m_fonts[key] = pFont; - } -private: - gr_face * m_pFace; - GrFontMap m_fonts; -}; - -// This class uses the SIL Graphite engine to provide complex text layout services to the VCL -// @author tse - -class VCL_PLUGIN_PUBLIC GraphiteLayout : public SalLayout -{ -public: - typedef std::vector<GlyphItem> Glyphs; - - mutable Glyphs mvGlyphs; - void clear(); - -private: - const gr_face * mpFace; // not owned by layout - gr_font * mpFont; // not owned by layout - unsigned int mnSegCharOffset; // relative to ImplLayoutArgs::mpStr - long mnWidth; - std::vector<int> mvChar2BaseGlyph; - std::vector<int> mvChar2Glyph; - std::vector<int> mvGlyph2Char; - std::vector<int> mvCharDxs; - std::vector<int> mvCharBreaks; - float mfScaling; - const grutils::GrFeatureParser * mpFeatures; - -public: - GraphiteLayout(const gr_face * pFace) throw(); - - // used by upper layers - virtual bool LayoutText( ImplLayoutArgs& ) override; // first step of layout - // split into two stages to allow dc to be restored on the segment - - virtual void AdjustLayout( ImplLayoutArgs& ) override; // adjusting positions - - // methods using string indexing - virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const override; - virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const override; - void ApplyDXArray(ImplLayoutArgs &rArgs, std::vector<int> & rDeltaWidth); - - virtual void GetCaretPositions( int nArraySize, long* pCaretXArray ) const override; - - // methods using glyph indexing - virtual int GetNextGlyphs(int nLen, sal_GlyphId* pGlyphIdxAry, ::Point & rPos, int&, - long* pGlyphAdvAry = nullptr, int* pCharPosAry = nullptr, - const PhysicalFontFace** pFallbackFonts = nullptr ) const override; - - // used by glyph+font+script fallback - virtual void MoveGlyph( int nStart, long nNewXPos ) override; - virtual void DropGlyph( int nStart ) override; - virtual void Simplify( bool bIsBase ) override; - - // Dummy implementation so layout can be shared between Linux/Windows - virtual void DrawText(SalGraphics&) const override {}; - - virtual ~GraphiteLayout() throw() override; - void SetFont(gr_font * pFont) { mpFont = pFont; } -#ifdef _WIN32 - gr_font * GetFont() { return mpFont; } - void SetFontScale(float s) { mfScaling = s; }; -#endif - void SetFeatures(grutils::GrFeatureParser * aFeature) { mpFeatures = aFeature; } - virtual sal_GlyphId getKashidaGlyph(int & width) = 0; - void kashidaJustify(std::vector<int> & rDeltaWidth, sal_GlyphId, int width); - - static const int EXTRA_CONTEXT_LENGTH; -private: - void expandOrCondense(ImplLayoutArgs &rArgs); - void fillFrom(gr_segment * rSeg, ImplLayoutArgs & rArgs, float fScaling, bool bRtl, int firstCharOffset); - - float append(gr_segment * pSeg, - ImplLayoutArgs & rArgs, - const gr_slot * pSlot, float gOrigin, - float nextGlyphOrigin, float fScaling, - long & rDXOffset, bool bIsBase, int baseChar, int baseGlyph, bool bRtl); - unsigned int ScanFwdForChar(int &findChar, bool fallback) const; -}; - -#endif // INCLUDED_VCL_INC_GRAPHITE_LAYOUT_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/graphite_serverfont.hxx b/vcl/inc/graphite_serverfont.hxx deleted file mode 100644 index 9e43bf7a6224..000000000000 --- a/vcl/inc/graphite_serverfont.hxx +++ /dev/null @@ -1,110 +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 . - */ - -#ifndef INCLUDED_VCL_INC_GRAPHITE_SERVERFONT_HXX -#define INCLUDED_VCL_INC_GRAPHITE_SERVERFONT_HXX - -// We need this to enable namespace support in libgrengine headers. -#define GR_NAMESPACE - -#ifndef _MSC_VER -#include <graphite_layout.hxx> - -#include "unx/glyphcache.hxx" - -class PhysicalFontFace; - -// Modules - -class VCL_PLUGIN_PUBLIC GraphiteLayoutImpl : public GraphiteLayout -{ -public: - GraphiteLayoutImpl(const gr_face * pFace, - FreetypeFont & rFreetypeFont) throw() - : GraphiteLayout(pFace), mrFreetypeFont(rFreetypeFont) {}; - virtual ~GraphiteLayoutImpl() throw() override {}; - virtual sal_GlyphId getKashidaGlyph(int & width) override; -private: - FreetypeFont & mrFreetypeFont; -}; - -// This class implments the server font specific parts. -// @author tse - -class VCL_PLUGIN_PUBLIC GraphiteServerFontLayout : public ServerFontLayout -{ -private: - // mutable so that the DrawOffset/DrawBase can be set - mutable GraphiteLayoutImpl maImpl; - grutils::GrFeatureParser * mpFeatures; -public: - GraphiteServerFontLayout(FreetypeFont& pFreetypeFont) throw(); - - virtual bool LayoutText( ImplLayoutArgs& rArgs) override - { - SalLayout::AdjustLayout(rArgs); - return maImpl.LayoutText(rArgs); - }; // first step of layout - virtual void AdjustLayout( ImplLayoutArgs& rArgs) override - { - SalLayout::AdjustLayout(rArgs); - maImpl.DrawBase() = maDrawBase; - maImpl.DrawOffset() = maDrawOffset; - maImpl.AdjustLayout(rArgs); - }; - virtual DeviceCoordinate GetTextWidth() const override - { - return maImpl.GetTextWidth(); - } - virtual DeviceCoordinate FillDXArray( DeviceCoordinate* dxa ) const override - { - return maImpl.FillDXArray(dxa); - } - virtual sal_Int32 GetTextBreak(DeviceCoordinate max_width, DeviceCoordinate extra=0, int factor=1) const override - { - return maImpl.GetTextBreak(max_width, extra, factor); - } - virtual void GetCaretPositions( int as, long* cxa ) const override - { - maImpl.GetCaretPositions(as, cxa); - } - - // used by display layers - virtual int GetNextGlyphs( int l, sal_GlyphId* gia, Point& p, int& s, - long* gaa = nullptr, int* cpa = nullptr, - const PhysicalFontFace** pFallbackFonts = nullptr ) const override - { - maImpl.DrawBase() = maDrawBase; - maImpl.DrawOffset() = maDrawOffset; - return maImpl.GetNextGlyphs(l, gia, p, s, gaa, cpa, pFallbackFonts); - } - - virtual void MoveGlyph( int nStart, long nNewXPos ) override { maImpl.MoveGlyph(nStart, nNewXPos); }; - virtual void DropGlyph( int nStart ) override { maImpl.DropGlyph(nStart); }; - virtual void Simplify( bool bIsBase ) override { maImpl.Simplify(bIsBase); }; - - virtual ~GraphiteServerFontLayout() throw() override; - - static bool IsGraphiteEnabledFont(FreetypeFont& rFreetypeFont); -}; - -#endif -#endif // INCLUDED_VCL_INC_GRAPHITE_SERVERFONT_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/graphite_static.hxx b/vcl/inc/graphite_static.hxx deleted file mode 100644 index c13333150a56..000000000000 --- a/vcl/inc/graphite_static.hxx +++ /dev/null @@ -1,21 +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/. - */ - -#ifndef INCLUDED_VCL_INC_GRAPHITE_STATIC_HXX -#define INCLUDED_VCL_INC_GRAPHITE_STATIC_HXX - -#ifdef _WIN32 -# ifndef GRAPHITE2_STATIC -# define GRAPHITE2_STATIC 1 -# endif -#endif - -#endif // INCLUDED_VCL_INC_GRAPHITE_STATIC_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/pch/precompiled_vcl.hxx b/vcl/inc/pch/precompiled_vcl.hxx index e283e036bc45..235bb911218f 100644 --- a/vcl/inc/pch/precompiled_vcl.hxx +++ b/vcl/inc/pch/precompiled_vcl.hxx @@ -27,7 +27,6 @@ #include <config_features.h> #include <config_folders.h> #include <config_global.h> -#include <config_graphite.h> #include <cstddef> #include <cstdlib> #include <cstring> diff --git a/vcl/inc/unx/cairotextrender.hxx b/vcl/inc/unx/cairotextrender.hxx index 1aeaf06ae474..008cb158dce2 100644 --- a/vcl/inc/unx/cairotextrender.hxx +++ b/vcl/inc/unx/cairotextrender.hxx @@ -36,8 +36,6 @@ class VCL_DLLPUBLIC CairoTextRender : public TextRenderImpl SalColor mnTextColor; - bool bDisableGraphite_; - protected: virtual GlyphCache& getPlatformGlyphCache() = 0; virtual cairo_t* getCairoContext() = 0; diff --git a/vcl/inc/unx/freetype_glyphcache.hxx b/vcl/inc/unx/freetype_glyphcache.hxx index 119dcda7d1fc..bbd606dc4515 100644 --- a/vcl/inc/unx/freetype_glyphcache.hxx +++ b/vcl/inc/unx/freetype_glyphcache.hxx @@ -23,11 +23,6 @@ #include "unx/glyphcache.hxx" #include "PhysicalFontFace.hxx" -#include <config_graphite.h> -#if ENABLE_GRAPHITE -class GraphiteFaceWrapper; -#endif - // FreetypeFontFile has the responsibility that a font file is only mapped once. // (#86621#) the old directly ft-managed solution caused it to be mapped // in up to nTTC*nSizes*nOrientation*nSynthetic times @@ -66,9 +61,6 @@ public: const unsigned char* GetTable( const char*, sal_uLong* pLength=nullptr ) const; FT_FaceRec_* GetFaceFT(); -#if ENABLE_GRAPHITE - GraphiteFaceWrapper* GetGraphiteFace(); -#endif void ReleaseFaceFT(); const OString& GetFontFileName() const { return mpFontFile->GetFileName(); } @@ -90,10 +82,6 @@ private: FreetypeFontFile* mpFontFile; const int mnFaceNum; int mnRefCount; -#if ENABLE_GRAPHITE - bool mbCheckedGraphite; - GraphiteFaceWrapper * mpGraphiteFace; -#endif sal_IntPtr mnFontId; FontAttributes maDevFontAttributes; diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx index ac52a6a0d9a0..ce5dd1f30885 100644 --- a/vcl/inc/unx/glyphcache.hxx +++ b/vcl/inc/unx/glyphcache.hxx @@ -20,8 +20,6 @@ #ifndef INCLUDED_VCL_INC_GENERIC_GLYPHCACHE_HXX #define INCLUDED_VCL_INC_GENERIC_GLYPHCACHE_HXX -#include <config_graphite.h> - #include <ft2build.h> #include FT_FREETYPE_H #include FT_GLYPH_H @@ -42,7 +40,6 @@ class FreetypeManager; class FreetypeFontInfo; class GlyphData; -class GraphiteFaceWrapper; class FontConfigFontOptions; class PhysicalFontCollection; class FreetypeFont; @@ -171,10 +168,6 @@ public: const GlyphMetric& GetGlyphMetric(sal_GlyphId aGlyphId); -#if ENABLE_GRAPHITE - GraphiteFaceWrapper* GetGraphiteFace() const; -#endif - sal_GlyphId GetGlyphIndex( sal_UCS4 ) const; sal_GlyphId GetRawGlyphIndex( sal_UCS4, sal_UCS4 = 0 ) const; sal_GlyphId FixupGlyphIndex( sal_GlyphId aGlyphId, sal_UCS4 ) const; diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 305005540841..5e1978c892f3 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -33,11 +33,6 @@ #include <memory> #include <unordered_set> -#include <config_graphite.h> -#if ENABLE_GRAPHITE -# include <graphite_static.hxx> -# include <graphite2/Font.h> -#endif #ifndef INCLUDED_PRE_POST_WIN_H #define INCLUDED_PRE_POST_WIN_H # include "prewin.h" @@ -60,26 +55,6 @@ class CommonSalLayout; #define RGB_TO_PALRGB(nRGB) ((nRGB)|0x02000000) #define PALRGB_TO_RGB(nPalRGB) ((nPalRGB)&0x00ffffff) -#if ENABLE_GRAPHITE -class RawFontData; -class GrFontData -{ -public: - GrFontData(HDC hDC); - ~GrFontData(); - const void * getTable(unsigned int name, size_t *len) const; - const gr_face * getFace() const { return mpFace; } - void AddReference() { ++mnRefCount; } - void DeReference() { if (--mnRefCount == 0) delete this; } -private: - GrFontData(GrFontData &) {}; - HDC mhDC; - mutable std::vector<RawFontData*> mvData; - gr_face * mpFace; - unsigned int mnRefCount; -}; -#endif - // win32 specific physically available font face class WinFontFace : public PhysicalFontFace { @@ -101,10 +76,6 @@ public: BYTE GetPitchAndFamily() const { return mnPitchAndFamily; } bool SupportsCJK() const { return mbHasCJKSupport; } bool SupportsArabic() const { return mbHasArabicSupport; } -#if ENABLE_GRAPHITE - bool SupportsGraphite() const { return mbHasGraphiteSupport; } - const gr_face* GraphiteFace() const; -#endif FontCharMapRef GetFontCharMap() const; bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const; @@ -120,10 +91,6 @@ private: // some members that are initalized lazily when the font gets selected into a HDC mutable bool mbHasCJKSupport; -#if ENABLE_GRAPHITE - mutable GrFontData* mpGraphiteData; - mutable bool mbHasGraphiteSupport; -#endif mutable bool mbHasArabicSupport; mutable bool mbFontCapabilitiesRead; mutable FontCharMapRef mxUnicodeMap; diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx index 7b15e7e4f5f3..ff57506420a0 100644 --- a/vcl/inc/win/winlayout.hxx +++ b/vcl/inc/win/winlayout.hxx @@ -34,14 +34,6 @@ typedef std::unordered_map<int,int> IntMap; -// Graphite headers -#include <config_graphite.h> -#if ENABLE_GRAPHITE -#include <graphite_layout.hxx> -#include <i18nlangtag/languagetag.hxx> -#include <graphite_features.hxx> -#endif - class WinFontInstance; struct VisualItem; @@ -350,57 +342,6 @@ private: bool mbDisableGlyphInjection; }; -#if ENABLE_GRAPHITE - -class GraphiteLayoutWinImpl : public GraphiteLayout -{ -public: - GraphiteLayoutWinImpl(const gr_face * pFace, WinFontInstance & rFont) - throw() - : GraphiteLayout(pFace), mrFont(rFont) {}; - virtual ~GraphiteLayoutWinImpl() throw() override {}; - virtual sal_GlyphId getKashidaGlyph(int & rWidth) override; -private: - WinFontInstance & mrFont; -}; - -/// This class uses the SIL Graphite engine to provide complex text layout services to the VCL -class GraphiteWinLayout : public WinLayout -{ -private: - gr_font * mpFont; - grutils::GrFeatureParser * mpFeatures; - mutable GraphiteLayoutWinImpl maImpl; -public: - GraphiteWinLayout(HDC hDC, const WinFontFace& rWFD, WinFontInstance& rWFE, bool bUseOpenGL) throw(); - virtual ~GraphiteWinLayout() override; - - // used by upper layers - virtual bool LayoutText( ImplLayoutArgs& ) override; // first step of layout - virtual void AdjustLayout( ImplLayoutArgs& ) override; // adjusting after fallback etc. - virtual bool DrawTextImpl(HDC hDC, const Rectangle* pRectToErase, Point* pPos, int* pGetNextGlypInfo) const override; - virtual bool CacheGlyphs(SalGraphics& rGraphics) const override; - virtual bool DrawCachedGlyphs(SalGraphics& rGraphics) const override; - - // methods using string indexing - virtual sal_Int32 GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const override; - virtual DeviceCoordinate FillDXArray( DeviceCoordinate* pDXArray ) const override; - - virtual void GetCaretPositions( int nArraySize, long* pCaretXArray ) const override; - - // methods using glyph indexing - virtual int GetNextGlyphs(int nLen, sal_GlyphId* pGlyphIdxAry, ::Point & rPos, int&, - DeviceCoordinate* pGlyphAdvAry = nullptr, int* pCharPosAry = nullptr, - const PhysicalFontFace** pFallbackFonts = nullptr ) const override; - - // used by glyph+font+script fallback - virtual void MoveGlyph( int nStart, long nNewXPos ) override; - virtual void DropGlyph( int nStart ) override; - virtual void Simplify( bool bIsBase ) override; -}; - -#endif // ENABLE_GRAPHITE - class TextOutRenderer { protected: diff --git a/vcl/source/glyphs/graphite_features.cxx b/vcl/source/glyphs/graphite_features.cxx deleted file mode 100644 index a8ad4dd25c94..000000000000 --- a/vcl/source/glyphs/graphite_features.cxx +++ /dev/null @@ -1,265 +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 . - */ - -// Description: -// Parse a string of features specified as & separated pairs. -// e.g. -// 1001=1&2002=2&fav1=0 - -#include <sal/types.h> -#include <osl/endian.h> - -#include <fontselect.hxx> -#include <graphite_features.hxx> - -using namespace grutils; - -namespace { - -short getIntValue(const OString & id, size_t offset, size_t length) -{ - short value = 0; - int sign = 1; - for (size_t i = 0; i < length; i++) - { - switch (id[offset + i]) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - value *= 10; - if (sign < 0) - { - value = -(id[offset + i] - '0'); - sign = 1; - } - value += (id[offset + i] - '0'); - break; - case '-': - if (i == 0) - sign = -1; - break; - default: - break; - } - } - return value; -} - -} - -const char GrFeatureParser::FEAT_ID_VALUE_SEPARATOR = '='; - -GrFeatureParser::GrFeatureParser(const gr_face * pFace, const OString& lang) - : mnNumSettings(0), mpSettings(nullptr) -{ - maLang.label[0] = maLang.label[1] = maLang.label[2] = maLang.label[3] = '\0'; - setLang(pFace, lang); -} - -GrFeatureParser::GrFeatureParser(const gr_face * pFace, const OString& features, const OString& lang) - : mnNumSettings(0), mpSettings(nullptr) -{ - sal_Int32 nEquals = 0; - sal_Int32 nFeatEnd = 0; - sal_Int32 pos = 0; - maLang.num = 0u; - setLang(pFace, lang); - while ((pos < features.getLength()) && (mnNumSettings < MAX_FEATURES)) - { - nEquals = features.indexOf(FEAT_ID_VALUE_SEPARATOR, pos); - if (nEquals == -1) - { - break; - } - // check for a lang=xxx specification - const OString aLangPrefix("lang"); - if (features.match(aLangPrefix, pos )) - { - pos = nEquals + 1; - nFeatEnd = features.indexOf(FontSelectPatternAttributes::FEAT_SEPARATOR, pos); - if (nFeatEnd == -1) - { - nFeatEnd = features.getLength(); - } - if (nFeatEnd - pos <= 3) - { - FeatId aLang = maLang; - aLang.num = 0; - for (sal_Int32 i = pos; i < nFeatEnd; i++) - aLang.label[i-pos] = features[i]; - - //ext_std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported - // = font.getSupportedLanguages(); - //gr::LanguageIterator iL = aSupported.first; - unsigned short i = 0; - for (; i < gr_face_n_languages(pFace); i++) - { - gr_uint32 nFaceLang = gr_face_lang_by_index(pFace, i); - FeatId aSupportedLang; - aSupportedLang.num = nFaceLang; -#ifdef OSL_BIGENDIAN - // here we only expect full 3 letter codes - if (aLang.label[0] == aSupportedLang.label[0] && - aLang.label[1] == aSupportedLang.label[1] && - aLang.label[2] == aSupportedLang.label[2] && - aLang.label[3] == aSupportedLang.label[3]) -#else - if (aLang.label[0] == aSupportedLang.label[3] && - aLang.label[1] == aSupportedLang.label[2] && - aLang.label[2] == aSupportedLang.label[1] && - aLang.label[3] == aSupportedLang.label[0]) -#endif - { - maLang = aSupportedLang; - break; - } - } - if (i != gr_face_n_languages(pFace)) - { - mnHash = maLang.num; - mpSettings = gr_face_featureval_for_lang(pFace, maLang.num); - } - } - } - else - { - sal_uInt32 featId = 0; - if (isCharId(features, pos, nEquals - pos)) - { - featId = getCharId(features, pos, nEquals - pos); - } - else - { - featId = getIntValue(features, pos, nEquals - pos); - } - const gr_feature_ref * pFref = gr_face_find_fref(pFace, featId); - pos = nEquals + 1; - nFeatEnd = features.indexOf(FontSelectPatternAttributes::FEAT_SEPARATOR, pos); - if (nFeatEnd == -1) - { - nFeatEnd = features.getLength(); - } - sal_Int16 featValue = 0; - featValue = getIntValue(features, pos, nFeatEnd - pos); - if (pFref && gr_fref_set_feature_value(pFref, featValue, mpSettings)) - { - mnHash = (mnHash << 16) ^ ((featId << 8) | featValue); - mnNumSettings++; - } - } - pos = nFeatEnd + 1; - } -} - -void GrFeatureParser::setLang(const gr_face * pFace, const OString & lang) -{ - FeatId aLang; - aLang.num = 0; - if (lang.getLength() >= 2) - { - for (sal_Int32 i = 0; i < lang.getLength() && i < 3; i++) - { - if (lang[i] == '-') break; - aLang.label[i] = lang[i]; - } - unsigned short i = 0; - for (; i < gr_face_n_languages(pFace); i++) - { - gr_uint32 nFaceLang = gr_face_lang_by_index(pFace, i); - FeatId aSupportedLang; - aSupportedLang.num = nFaceLang; - // here we only expect full 2 & 3 letter codes -#ifdef OSL_BIGENDIAN - if (aLang.label[0] == aSupportedLang.label[0] && - aLang.label[1] == aSupportedLang.label[1] && - aLang.label[2] == aSupportedLang.label[2] && - aLang.label[3] == aSupportedLang.label[3]) -#else - if (aLang.label[0] == aSupportedLang.label[3] && - aLang.label[1] == aSupportedLang.label[2] && - aLang.label[2] == aSupportedLang.label[1] && - aLang.label[3] == aSupportedLang.label[0]) -#endif - { - maLang = aSupportedLang; - break; - } - } - if (i != gr_face_n_languages(pFace)) - { - if (mpSettings) - gr_featureval_destroy(mpSettings); - mpSettings = gr_face_featureval_for_lang(pFace, maLang.num); - mnHash = maLang.num; - } - } - if (!mpSettings) - mpSettings = gr_face_featureval_for_lang(pFace, 0); -} - -GrFeatureParser::~GrFeatureParser() -{ - if (mpSettings) - { - gr_featureval_destroy(mpSettings); - mpSettings = nullptr; - } -} - -bool GrFeatureParser::isCharId(const OString & id, size_t offset, size_t length) -{ - if (length > 4) return false; - for (size_t i = 0; i < length; i++) - { - if (i > 0 && id[offset+i] == '\0') continue; - if (id[offset+i] < 0x20 || static_cast<signed char>(id[offset+i]) < 0) - return false; - if (i==0 && (id[offset+i] < 0x41)) - return false; - } - return true; -} - -gr_uint32 GrFeatureParser::getCharId(const OString & id, size_t offset, size_t length) -{ - FeatId charId; - charId.num = 0; -#ifdef OSL_BIGENDIAN - for (size_t i = 0; i < length; i++) - { - charId.label[i] = id[offset+i]; - } -#else - for (size_t i = 0; i < length; i++) - { - charId.label[3-i] = id[offset+i]; - } -#endif - return charId.num; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx deleted file mode 100644 index 188ee727d82f..000000000000 --- a/vcl/source/glyphs/graphite_layout.cxx +++ /dev/null @@ -1,1143 +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 . - */ - -// Description: An implementation of the SalLayout interface that uses the -// Graphite engine. - -// Enable lots of debug info -#if OSL_DEBUG_LEVEL > 1 -#include <cstdio> -#define GRLAYOUT_DEBUG 1 -#endif - -//#define GRLAYOUT_DEBUG 1 - -#include <algorithm> -#include <cassert> -#include <functional> -#include <limits> -#include <numeric> -#include <deque> - -#include <config_global.h> - -#include <svsys.h> - -#include <salgdi.hxx> - -#include <unicode/uchar.h> -#include <unicode/ubidi.h> -#include <unicode/uscript.h> - -#include <vcl/unohelp.hxx> -#include <com/sun/star/i18n/XCharacterClassification.hpp> -#include <com/sun/star/i18n/UnicodeType.hpp> - -// Graphite Libraries (must be after vcl headers on windows) -#include <graphite_static.hxx> -#include <graphite2/Segment.h> - -#include <graphite_layout.hxx> -#include <graphite_features.hxx> - -#ifdef GRLAYOUT_DEBUG -static FILE * grLog() -{ -#ifdef _WIN32 - static FILE * grLogFile = NULL; - if (grLogFile == NULL) - { - std::string logFileName(getenv("TEMP")); - logFileName.append("/graphitelayout.log"); - grLogFile = fopen(logFileName.c_str(),"w"); - } - else - fflush(grLogFile); - return grLogFile; -#else - fflush(stdout); - return stdout; -#endif -} -#endif - -namespace -{ - inline long round_to_long(const float n) { - return long(n + (n < 0 ? -0.5 : 0.5)); - } - - template<typename T> - inline bool in_range(const T i, const T b, const T e) { - return !(b > i) && i < e; - } - - template <typename T> - T maximum(T a, T b) - { - return (a > b)? a : b; - } - template <typename T> - T minimum(T a, T b) - { - return (a < b)? a : b; - } - -} // namespace - -// Impementation of the GraphiteLayout::Glyphs container class. -// This is an extended vector class with methods added to enable -// o Correctly filling with glyphs. -// o Querying clustering relationships. -// o manipulations that affect neighbouring glyphs. - -const int GraphiteLayout::EXTRA_CONTEXT_LENGTH = 32; - -const gr_slot *get_next_base(const gr_slot *slot, bool bRtl) -{ - for ( ; slot; slot = bRtl ? gr_slot_prev_in_segment(slot) : gr_slot_next_in_segment(slot)) - if (!gr_slot_attached_to(slot) || gr_slot_can_insert_before(slot)) - break; - return slot; -} - -bool isWhite(sal_Unicode nChar) -{ - if (nChar <= 0x0020 || nChar == 0x00A0 || (nChar >= 0x2000 && nChar <= 0x200F) || nChar == 0x3000) - return true; - return false; -} - -// The Graphite glyph stream is really a sequence of glyph attachment trees -// each rooted at a non-attached base glyph. fill_from walks the glyph stream, -// finds each non-attached base glyph and calls append to record them as a -// sequence of clusters. -void -GraphiteLayout::fillFrom(gr_segment * pSegment, ImplLayoutArgs &rArgs, float fScaling, bool bRtl, int lastCharPos) -{ - float fMinX = gr_seg_advance_X(pSegment); - float fMaxX = 0.0f; - long nDxOffset = 0; // from dropped glyphs - int origNumGlyphs = mvGlyphs.size(); - unsigned int nGlyphs = gr_seg_n_slots(pSegment); - mvGlyph2Char.resize(mvGlyph2Char.size() + nGlyphs, -1); - mvGlyphs.reserve(mvGlyphs.size() + nGlyphs); - int clusterStart = -1; - int clusterFirstChar = -1; - const gr_slot *nextBaseSlot; - const sal_Unicode *pStr = rArgs.mrStr.getStr(); - int firstChar; - - if (!nGlyphs || lastCharPos - mnSegCharOffset == 0) return; - const gr_slot* baseSlot = bRtl ? gr_seg_last_slot(pSegment) : gr_seg_first_slot(pSegment); - // find first base - while (baseSlot && gr_slot_attached_to(baseSlot) != nullptr && !gr_slot_can_insert_before(baseSlot)) - baseSlot = bRtl ? gr_slot_prev_in_segment(baseSlot) : gr_slot_next_in_segment(baseSlot); - assert(baseSlot); - int nextChar = gr_cinfo_base(gr_seg_cinfo(pSegment, gr_slot_before(baseSlot))) + mnSegCharOffset; - float thisBoundary = 0.; - float nextBoundary = gr_slot_origin_X(baseSlot); - // now loop over bases - for ( ; baseSlot; baseSlot = nextBaseSlot) - { - firstChar = nextChar; - thisBoundary = nextBoundary; - nextBaseSlot = get_next_base(bRtl ? gr_slot_prev_in_segment(baseSlot) : gr_slot_next_in_segment(baseSlot), bRtl); - nextChar = nextBaseSlot ? gr_cinfo_base(gr_seg_cinfo(pSegment, gr_slot_before(nextBaseSlot))) + mnSegCharOffset : -1; - nextBoundary = nextBaseSlot ? gr_slot_origin_X(nextBaseSlot) : gr_seg_advance_X(pSegment); - - if (firstChar < mnMinCharPos || firstChar >= mnEndCharPos) - { - // handle clipping of diacritic from base - nextBaseSlot = bRtl ? gr_slot_prev_in_segment(baseSlot) : gr_slot_next_in_segment(baseSlot); - nextBoundary = nextBaseSlot ? gr_slot_origin_X(nextBaseSlot) : gr_seg_advance_X(pSegment); - nextChar = nextBaseSlot ? gr_cinfo_base(gr_seg_cinfo(pSegment, gr_slot_before(nextBaseSlot))) + mnSegCharOffset : -1; - continue; - } - // handle reordered clusters. Presumes reordered glyphs have monotonic opposite char index until the cluster base. - bool isReordered = (nextBaseSlot && ((bRtl != (gr_cinfo_base(gr_seg_cinfo(pSegment, gr_slot_before(nextBaseSlot))) < firstChar - mnSegCharOffset)) - || gr_cinfo_base(gr_seg_cinfo(pSegment, gr_slot_before(nextBaseSlot))) == firstChar - mnSegCharOffset)); - if (clusterStart >= 0 && !isReordered) // we hit the base (end) of a reordered cluster - { - int clusterEnd = mvGlyphs.size(); - for (int i = clusterStart; i < clusterEnd; ++i) - mvGlyph2Char[i] = firstChar; - if (bRtl) - { - for ( ; clusterFirstChar < firstChar; ++clusterFirstChar) - if (clusterFirstChar >= mnMinCharPos && clusterFirstChar < mnEndCharPos) - { - mvChar2BaseGlyph[clusterFirstChar - mnMinCharPos] = clusterStart; // lowest glyphItem index - mvCharDxs[clusterFirstChar - mnMinCharPos] = static_cast<int>(thisBoundary * fScaling) + mnWidth + nDxOffset; - } - } - else - { - for ( ; clusterFirstChar > firstChar; --clusterFirstChar) - if (clusterFirstChar < mnEndCharPos && clusterFirstChar >= mnMinCharPos) - { - mvChar2BaseGlyph[clusterFirstChar - mnMinCharPos] = clusterStart; - mvCharDxs[clusterFirstChar - mnMinCharPos] = static_cast<int>(nextBoundary * fScaling) + mnWidth + nDxOffset; - } - } - clusterStart = -1; - clusterFirstChar = -1; - } - else if (clusterStart < 0 && isReordered) // we hit the start of a reordered cluster - { - clusterStart = mvGlyphs.size(); - clusterFirstChar = firstChar; - } - - int baseGlyph = mvGlyphs.size(); - int scaledGlyphPos = round_to_long(gr_slot_origin_X(baseSlot) * fScaling) + mnWidth + nDxOffset; - if (mvChar2Glyph[firstChar - mnMinCharPos] == -1 || mvGlyphs[mvChar2Glyph[firstChar - mnMinCharPos]].maLinearPos.X() < scaledGlyphPos) - { - mvChar2Glyph[firstChar - mnMinCharPos] = mvGlyphs.size(); - mvCharDxs[firstChar - mnMinCharPos] = static_cast<int>((bRtl ? thisBoundary : nextBoundary) * fScaling) + mnWidth + nDxOffset; - mvChar2BaseGlyph[firstChar - mnMinCharPos] = baseGlyph; - mvCharBreaks[firstChar - mnMinCharPos] = gr_cinfo_break_weight(gr_seg_cinfo(pSegment, gr_slot_before(baseSlot))); - } - mvGlyph2Char[baseGlyph] = firstChar; - append(pSegment, rArgs, baseSlot, thisBoundary, nextBoundary, fScaling, nDxOffset, true, firstChar, baseGlyph, bRtl); - if (thisBoundary < fMinX) fMinX = thisBoundary; - if (nextBoundary > fMaxX && (nextChar < mnMinCharPos || nextChar >= mnEndCharPos || !isWhite(pStr[nextChar]) || fMaxX <= 0.0f)) - fMaxX = nextBoundary; - } - - long nXOffset = round_to_long(fMinX * fScaling); - long nXEnd = round_to_long(fMaxX * fScaling); - int nCharRequested = minimum<int>(lastCharPos, mnEndCharPos) - mnMinCharPos; - int firstCharOffset = maximum<int>(mnSegCharOffset, mnMinCharPos) - mnMinCharPos; - // fill up non-base char dx with cluster widths from previous base glyph - if (bRtl) - { - if (mvCharDxs[nCharRequested-1] == -1) - mvCharDxs[nCharRequested-1] = nXEnd - nXOffset + mnWidth + nDxOffset; - else - mvCharDxs[nCharRequested-1] = nXEnd - mvCharDxs[nCharRequested-1] + 2 * (mnWidth + nDxOffset); -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"%d,%d ", nCharRequested - 1, (int)mvCharDxs[nCharRequested-1]); -#endif - for (int i = nCharRequested - 2; i >= firstCharOffset; i--) - { - if (mvCharDxs[i] == -1) mvCharDxs[i] = mvCharDxs[i+1]; - else mvCharDxs[i] = nXEnd - mvCharDxs[i] + 2 * (mnWidth + nDxOffset); -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"%d,%d ", (int)i, (int)mvCharDxs[i]); -#endif - } - } - else - { - if (mvCharDxs[firstCharOffset] == -1) - mvCharDxs[firstCharOffset] = 0; - else - mvCharDxs[firstCharOffset] -= nXOffset; -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"%d,%d ", firstCharOffset, (int)mvCharDxs[firstCharOffset]); -#endif - for (int i = firstCharOffset + 1; i < nCharRequested; i++) - { - if (mvCharDxs[i] == -1) mvCharDxs[i] = mvCharDxs[i-1]; - else mvCharDxs[i] -= nXOffset; -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"%d,%d ", (int)i, (int)mvCharDxs[i]); -#endif - } - } - // remove offset due to context if there is one - if (nXOffset != 0) - { - for (size_t i = origNumGlyphs; i < mvGlyphs.size(); i++) - mvGlyphs[i].maLinearPos.X() -= nXOffset; - } - mnWidth += nXEnd - nXOffset + nDxOffset; - if (mnWidth < 0) - { - // This can happen when there was no base inside the range - mnWidth = 0; - } -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(), "fillFrom %" SAL_PRI_SIZET "u glyphs offset %ld width %ld for %d\n", mvGlyphs.size(), nXOffset, mnWidth, nCharRequested); -#endif -} - -// append walks an attachment tree, flattening it, and converting it into a -// sequence of GlyphItem objects which we can later manipulate. -float -GraphiteLayout::append(gr_segment *pSeg, ImplLayoutArgs &rArgs, - const gr_slot * gi, float gOrigin, float nextGlyphOrigin, float scaling, long & rDXOffset, - bool bIsBase, int baseChar, int baseGlyph, bool bRtl) -{ - assert(gi); - // assert(gr_slot_before(gi) <= gr_slot_after(gi)); - int firstChar = gr_cinfo_base(gr_seg_cinfo(pSeg, gr_slot_before(gi))) + mnSegCharOffset; - assert(mvGlyphs.size() < mvGlyph2Char.size()); - if (firstChar < mnMinCharPos || firstChar >= mnEndCharPos) - return nextGlyphOrigin; - - long glyphId = gr_slot_gid(gi); - long deltaOffset = 0; - int scaledGlyphPos = round_to_long(gr_slot_origin_X(gi) * scaling) + mnWidth + rDXOffset; - int glyphWidth = round_to_long((nextGlyphOrigin - gOrigin) * scaling); - if (!bIsBase) - { - mvChar2BaseGlyph[firstChar - mnMinCharPos] = baseGlyph; - mvCharDxs[firstChar - mnMinCharPos] = mvCharDxs[baseChar - mnMinCharPos]; - mvCharBreaks[firstChar - mnMinCharPos] = gr_cinfo_break_weight(gr_seg_cinfo(pSeg, gr_slot_before(gi))); - } - -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"c%d g%ld,X%d W%d nX%f @%d=%d ", firstChar, glyphId, - scaledGlyphPos, glyphWidth, nextGlyphOrigin * scaling, mvChar2Glyph[firstChar-mnMinCharPos], mvCharDxs[firstChar-mnMinCharPos]); -#endif - if (glyphId == 0) - { - rArgs.NeedFallback(firstChar, bRtl); - if( (SalLayoutFlags::ForFallback & rArgs.mnFlags )) - { - glyphId = GF_DROPPED; - deltaOffset -= glyphWidth; - glyphWidth = 0; - } - } - else if(rArgs.mnFlags & SalLayoutFlags::ForFallback) - { -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"fallback c%d %x in run %d\n", firstChar, rArgs.mrStr[firstChar], - rArgs.maRuns.PosIsInAnyRun(firstChar)); -#endif - // glyphs that aren't requested for fallback will be taken from base - // layout, so mark them as dropped (should this wait until Simplify(false) is called?) - if (!rArgs.maRuns.PosIsInAnyRun(firstChar) && - in_range(firstChar, rArgs.mnMinCharPos, rArgs.mnEndCharPos)) - { - glyphId = GF_DROPPED; - deltaOffset -= glyphWidth; - glyphWidth = 0; - } - } - // append this glyph. Set the cluster flag if this glyph is attached to another - long nGlyphFlags = bIsBase ? 0 : GlyphItem::IS_IN_CLUSTER; - if (gr_slot_attached_to(gi)) - nGlyphFlags |= GlyphItem::IS_DIACRITIC; - nGlyphFlags |= (bRtl)? GlyphItem::IS_RTL_GLYPH : 0; - GlyphItem aGlyphItem(mvGlyphs.size(), - glyphId, - Point(scaledGlyphPos, round_to_long((-gr_slot_origin_Y(gi) * scaling))), - nGlyphFlags, - glyphWidth); - if (glyphId != static_cast<long>(GF_DROPPED)) - aGlyphItem.mnOrigWidth = round_to_long(gr_slot_advance_X(gi, mpFace, mpFont) * scaling); - mvGlyphs.push_back(aGlyphItem); - - // update the offset if this glyph was dropped - rDXOffset += deltaOffset; - - // Recursively append all the attached glyphs. - float cOrigin = nextGlyphOrigin; - for (const gr_slot * agi = gr_slot_first_attachment(gi); agi != nullptr; agi = gr_slot_next_sibling_attachment(agi)) - if (!gr_slot_can_insert_before(agi)) - cOrigin = append(pSeg, rArgs, agi, cOrigin, nextGlyphOrigin, scaling, rDXOffset, false, baseChar, baseGlyph, bRtl); - - return cOrigin; -} - -// An implementation of the SalLayout interface to enable Graphite enabled fonts to be used. - -GraphiteLayout::GraphiteLayout(const gr_face * face) throw() - : mpFace(face) - , mpFont(nullptr) - , mnSegCharOffset(0) - , mnWidth(0) - , mfScaling(1.0) - , mpFeatures(nullptr) -{ - -} - -GraphiteLayout::~GraphiteLayout() throw() -{ - clear(); - // the features and font are owned by the platform layers - mpFeatures = nullptr; - mpFont = nullptr; -} - -void GraphiteLayout::clear() -{ - // Destroy the segment and text source from any previous invocation of - // LayoutText - mvGlyphs.clear(); - mvCharDxs.clear(); - mvChar2BaseGlyph.clear(); - mvChar2Glyph.clear(); - mvGlyph2Char.clear(); - - // Reset the state to the empty state. - mnWidth = 0; - // Don't reset the scaling, because it is set before LayoutText -} - -// This method shouldn't be called on windows, since it needs the dc reset -bool GraphiteLayout::LayoutText(ImplLayoutArgs & rArgs) -{ - clear(); - bool success = true; - if (rArgs.mnMinCharPos >= rArgs.mnEndCharPos) - return success; - // Set the SalLayouts values to be the initial ones. - SalLayout::AdjustLayout(rArgs); - // TODO check if this is needed - if (mnUnitsPerPixel > 1) - mfScaling = 1.0f / mnUnitsPerPixel; - mvCharDxs.assign(mnEndCharPos - mnMinCharPos, -1); - mvChar2BaseGlyph.assign(mnEndCharPos - mnMinCharPos, -1); - mvChar2Glyph.assign(mnEndCharPos - mnMinCharPos, -1); - mvCharBreaks.assign(mnEndCharPos - mnMinCharPos, 0); - -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(), "New Graphite LayoutText\n"); -#endif - success = false; - const int nLength = rArgs.mrStr.getLength(); - while (true) - { - int nBidiMinRunPos, nBidiEndRunPos; - bool bRightToLeft; - if (!rArgs.GetNextRun(&nBidiMinRunPos, &nBidiEndRunPos, &bRightToLeft)) - break; - - if (nBidiEndRunPos < mnMinCharPos || nBidiMinRunPos >= mnEndCharPos) - continue; - - if (nBidiMinRunPos == mnMinCharPos) - nBidiMinRunPos = maximum<int>(0, nBidiMinRunPos - EXTRA_CONTEXT_LENGTH); - if (nBidiEndRunPos == mnEndCharPos) - nBidiEndRunPos = minimum<int>(nLength, nBidiEndRunPos + EXTRA_CONTEXT_LENGTH); - const sal_Unicode *pStr = rArgs.mrStr.getStr(); - size_t numchars = gr_count_unicode_characters(gr_utf16, pStr + nBidiMinRunPos, - pStr + nBidiEndRunPos, nullptr); - gr_segment * pSegment = gr_make_seg(mpFont, mpFace, 0, mpFeatures ? mpFeatures->values() : nullptr, - gr_utf16, pStr + nBidiMinRunPos, numchars, 2 | int(bRightToLeft)); - - if (pSegment != nullptr) - { - success = true; - mnSegCharOffset = nBidiMinRunPos; -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"Gr::LayoutText %d-%d, context %d-%d, len %d, numchars %" SAL_PRI_SIZET "u, rtl %d scaling %f:", - rArgs.mnMinCharPos, rArgs.mnEndCharPos, - nBidiMinRunPos, nBidiEndRunPos, - nLength, numchars, bRightToLeft, mfScaling); - for (int i = mnSegCharOffset; i < nBidiEndRunPos; ++i) - fprintf(grLog(), " %04X", rArgs.mrStr[i]); - fprintf(grLog(), "\n"); -#endif - fillFrom(pSegment, rArgs, mfScaling, bRightToLeft, nBidiEndRunPos); - gr_seg_destroy(pSegment); - } - } - return success; -} - -sal_Int32 GraphiteLayout::GetTextBreak(DeviceCoordinate maxmnWidth, DeviceCoordinate char_extra, int factor) const -{ -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"Gr::GetTextBreak c[%d-%d) maxWidth %ld char extra %ld factor %d\n", - mnMinCharPos, mnEndCharPos, maxmnWidth, char_extra, factor); -#endif - - // return quickly if this segment is narrower than the target width - if (maxmnWidth > mnWidth * factor + char_extra * (mnEndCharPos - mnMinCharPos - 1)) - return -1; - - DeviceCoordinate nWidth = mvCharDxs[0] * factor; - long wLastBreak = 0; - int nLastBreak = -1; - int nEmergency = -1; - for (size_t i = 1; i < mvCharDxs.size(); i++) - { - nWidth += char_extra; - if (nWidth > maxmnWidth) break; - int gi = mvChar2BaseGlyph[i]; - if (gi != -1) - { - if (!mvGlyphs[gi].IsDiacritic() && - (mvCharBreaks[i] > -35 || (mvCharBreaks[i-1] > 0 && mvCharBreaks[i-1] < 35)) && - (mvCharBreaks[i-1] < 35 || (mvCharBreaks[i] < 0 && mvCharBreaks[i] > -35))) - { - nLastBreak = static_cast<int>(i); - wLastBreak = nWidth; - } - nEmergency = static_cast<int>(i); - } - nWidth += (mvCharDxs[i] - mvCharDxs[i-1]) * factor; - } - int nBreak = mnMinCharPos; - if (wLastBreak > 9 * maxmnWidth / 10) - nBreak += nLastBreak; - else - if (nEmergency > -1) - nBreak += nEmergency; - -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(), "Gr::GetTextBreak break after %d, weights(%d, %d)\n", nBreak - mnMinCharPos, mvCharBreaks[nBreak - mnMinCharPos], mvCharBreaks[nBreak - mnMinCharPos - 1]); -#endif - - if (nBreak > mnEndCharPos) - nBreak = -1; - else if (nBreak < mnMinCharPos) - nBreak = mnMinCharPos; - return nBreak; -} - -DeviceCoordinate GraphiteLayout::FillDXArray( DeviceCoordinate* pDXArray ) const -{ - if (mnEndCharPos == mnMinCharPos) - // Then we must be zero width! - return 0; - - if (pDXArray) - { - for (size_t i = 0; i < mvCharDxs.size(); i++) - { - assert( (mvChar2BaseGlyph[i] == -1) || - ((signed)(mvChar2BaseGlyph[i]) < (signed)mvGlyphs.size())); - if (mvChar2BaseGlyph[i] != -1 && - mvGlyphs[mvChar2BaseGlyph[i]].maGlyphId == GF_DROPPED) - { - // when used in MultiSalLayout::GetTextBreak dropped glyphs - // must have zero width - pDXArray[i] = 0; - } - else - { - pDXArray[i] = mvCharDxs[i]; - if (i > 0) pDXArray[i] -= mvCharDxs[i-1]; - } -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"%d,%d,%ld ", (int)i, (int)mvCharDxs[i], pDXArray[i]); -#endif - } - } -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"FillDXArray %d-%d=%g\n", mnMinCharPos, mnEndCharPos, (double)mnWidth); -#endif - return mnWidth; -} - -void GraphiteLayout::AdjustLayout(ImplLayoutArgs& rArgs) -{ - SalLayout::AdjustLayout(rArgs); - if(rArgs.mpDXArray && mvGlyphs.size()) - { - std::vector<int> vDeltaWidths(mvGlyphs.size(), 0); - ApplyDXArray(rArgs, vDeltaWidths); - - if( (mnLayoutFlags & SalLayoutFlags::BiDiRtl) && - !(rArgs.mnFlags & SalLayoutFlags::ForFallback) ) - { - // check if this is a kashida script - bool bKashidaScript = false; - for (int i = rArgs.mnMinCharPos; i < rArgs.mnEndCharPos; i++) - { - UErrorCode aStatus = U_ZERO_ERROR; - UScriptCode scriptCode = uscript_getScript(rArgs.mrStr[i], &aStatus); - if (scriptCode == USCRIPT_ARABIC || scriptCode == USCRIPT_SYRIAC) - { - bKashidaScript = true; - break; - } - } - int nKashidaWidth = 0; - int nKashidaIndex = getKashidaGlyph(nKashidaWidth); - if( nKashidaIndex != 0 && bKashidaScript) - { - kashidaJustify( vDeltaWidths, nKashidaIndex, nKashidaWidth ); - } - } - } - else if (rArgs.mnLayoutWidth > 0) - { -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(), "AdjustLayout width %ld=>%ld\n", mnWidth, rArgs.mnLayoutWidth); -#endif - expandOrCondense(rArgs); - } -} - -void GraphiteLayout::expandOrCondense(ImplLayoutArgs &rArgs) -{ - int nDeltaWidth = rArgs.mnLayoutWidth - mnWidth; - if (nDeltaWidth > 0) // expand, just expand between clusters - { - // NOTE: for expansion we can use base glyphs (which have IsClusterStart set) - // even though they may have been reordered in which case they will have - // been placed in a bigger cluster for other purposes. - int nClusterCount = 0; - for (GlyphItem & i : mvGlyphs) - { - if (i.IsClusterStart() && !i.IsDiacritic()) - { - ++nClusterCount; - } - } -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(), "Expand by width %f for %ld clusters\n", nDeltaWidth, nClusterCount); -#endif - if (nClusterCount > 1) - { - float fExtraPerCluster = static_cast<float>(nDeltaWidth) / static_cast<float>(nClusterCount - 1); - int nCluster = 0; - int nOffset = 0; - for (size_t i = 0; i < mvGlyphs.size(); i++) - { - if (mvGlyphs[i].IsClusterStart() && !mvGlyphs[i].IsDiacritic()) - { - nOffset = static_cast<int>(fExtraPerCluster * nCluster); - int nCharIndex = mvGlyph2Char[i]; - assert(nCharIndex > -1); - if (nCharIndex < mnMinCharPos || - static_cast<size_t>(nCharIndex-mnMinCharPos) - >= mvCharDxs.size()) - { - continue; - } - mvCharDxs[nCharIndex-mnMinCharPos] += nOffset; - // adjust char dxs for rest of characters in cluster - while (++nCharIndex - mnMinCharPos < static_cast<int>(mvChar2BaseGlyph.size())) - { - int nChar2Base = mvChar2BaseGlyph[nCharIndex-mnMinCharPos]; - if (nChar2Base == -1 || nChar2Base == static_cast<int>(i)) - mvCharDxs[nCharIndex-mnMinCharPos] += nOffset; - else - break; - } - ++nCluster; - } - mvGlyphs[i].maLinearPos.X() += nOffset; - } - } - } - else if (nDeltaWidth < 0)// condense - apply a factor to all glyph positions - { - if (mvGlyphs.empty()) return; - Glyphs::iterator iLastGlyph = mvGlyphs.begin() + (mvGlyphs.size() - 1); - // position last glyph using original width - float fXFactor = static_cast<float>(rArgs.mnLayoutWidth - iLastGlyph->mnOrigWidth) / static_cast<float>(iLastGlyph->maLinearPos.X()); -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(), "Condense by factor %f last x%ld\n", fXFactor, iLastGlyph->maLinearPos.X()); -#endif - if (fXFactor < 0) - return; // probably a bad mnOrigWidth value - iLastGlyph->maLinearPos.X() = rArgs.mnLayoutWidth - iLastGlyph->mnOrigWidth; - Glyphs::iterator iGlyph = mvGlyphs.begin(); - while (iGlyph != iLastGlyph) - { - iGlyph->maLinearPos.X() = static_cast<int>(static_cast<float>(iGlyph->maLinearPos.X()) * fXFactor); - ++iGlyph; - } - for (int & rDx : mvCharDxs) - { - rDx = static_cast<int>(fXFactor * static_cast<float>(rDx)); - } - } - mnWidth = rArgs.mnLayoutWidth; -} - -unsigned int GraphiteLayout::ScanFwdForChar(int &findChar, bool fallback) const -{ - int res = mvChar2Glyph[findChar - mnMinCharPos]; - if (res >= 0) - return unsigned(res); - if (fallback) - { - for (++findChar; findChar - mnMinCharPos < int(mvChar2Glyph.size()); ++findChar) - if ((res = mvChar2Glyph[findChar - mnMinCharPos]) != -1) - return res; - --findChar; - return mvGlyphs.size() - 1; - } - else - { - for (--findChar; findChar >= mnMinCharPos; --findChar) - if ((res = mvChar2Glyph[findChar - mnMinCharPos]) != -1) - return res; - ++findChar; - return 0; - } -} - -void GraphiteLayout::ApplyDXArray(ImplLayoutArgs &args, std::vector<int> & rDeltaWidth) -{ - bool bRtl(mnLayoutFlags & SalLayoutFlags::BiDiRtl); - int startChar = args.mnMinCharPos < mnMinCharPos ? mnMinCharPos : args.mnMinCharPos; - int endChar = args.mnEndCharPos >= mnEndCharPos ? mnEndCharPos - 1 : args.mnEndCharPos; - unsigned int startGi = ScanFwdForChar(startChar, bRtl); - unsigned int endGi = ScanFwdForChar(endChar, !bRtl); - int nChars = endChar - startChar + 1; - if (nChars <= 0) return; - if (startGi > endGi) - { - unsigned int temp = endGi; - endGi = startGi; - startGi = temp; - } - ++endGi; - -#ifdef GRLAYOUT_DEBUG - for (size_t iDx = 0; iDx < mvCharDxs.size(); iDx++) - fprintf(grLog(),"%d,%d,%ld ", (int)iDx, (int)mvCharDxs[iDx], args.mpDXArray[iDx]); - fprintf(grLog(),"ApplyDx %d-%d=%d-%d\n", startChar, endChar, startGi, endGi); -#endif - - for (unsigned int i = startGi; i < endGi; ++i) - { - // calculate visual cluster bounds - int firstChar = mvGlyph2Char[i]; - unsigned int nBaseGlyph = mvChar2BaseGlyph[firstChar - mnMinCharPos]; - while (nBaseGlyph == ~0U && i < endGi) - { - ++i; - firstChar = mvGlyph2Char[i]; - nBaseGlyph = unsigned(mvChar2BaseGlyph[firstChar - mnMinCharPos]); - } - int lastChar = firstChar; - unsigned int nLastGlyph = i; - // firstGlyph = i - for ( ; nLastGlyph < endGi; nLastGlyph++) - { - int thisChar = mvGlyph2Char[nLastGlyph]; - if (thisChar == -1) continue; - if (unsigned(mvChar2BaseGlyph[thisChar - mnMinCharPos]) != nBaseGlyph) - { - if (!mvGlyphs[nLastGlyph].IsDiacritic()) - break; - else - nBaseGlyph = mvChar2BaseGlyph[thisChar - mnMinCharPos]; - } - if (thisChar > lastChar) lastChar = thisChar; - if (thisChar < firstChar) firstChar = thisChar; - } - - // calculate visual cluster widths - if (lastChar > args.mnEndCharPos) lastChar = args.mnEndCharPos; - if (firstChar < args.mnMinCharPos) firstChar = args.mnMinCharPos; - long nOrigClusterWidth = mvCharDxs[lastChar - mnMinCharPos]; - long nNewClusterWidth = args.mpDXArray[lastChar - args.mnMinCharPos]; - long nDGlyphOrigin = 0; - if (firstChar > args.mnMinCharPos) - { - //nNewClusterWidth -= args.mpDXArray[firstChar - args.mnMinCharPos]; - //nOrigClusterWidth -= mvCharDxs[firstChar - mnMinCharPos]; - nDGlyphOrigin = args.mpDXArray[firstChar - args.mnMinCharPos - 1] - - mvCharDxs[firstChar - mnMinCharPos - 1]; - } - - // update visual cluster - long nDWidth = nNewClusterWidth - nOrigClusterWidth; - if (firstChar >= args.mnMinCharPos) - for (int n = firstChar; n <= lastChar; ++n) - if (n > mnMinCharPos && mvCharDxs[n - mnMinCharPos - 1] != -1) - mvCharDxs[n - mnMinCharPos - 1] += nDGlyphOrigin; // + nDWidth; - for (unsigned int n = i; n < nLastGlyph; n++) - //mvGlyphs[n].maLinearPos.X() += (nDGlyphOrigin + nDWidth) * (bRtl ? -1 : 1); - mvGlyphs[n].maLinearPos.X() += nDGlyphOrigin * (bRtl ? -1 : 1); - - rDeltaWidth[nBaseGlyph] = nDWidth; -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"c%d=%d g%d-%d dW%ld-%ld=%ld dX%ld x%ld @%d=%d\n", firstChar, lastChar, i, nLastGlyph, nNewClusterWidth, nOrigClusterWidth, nDWidth, nDGlyphOrigin, mvGlyphs[i].maLinearPos.X(), mvCharDxs[lastChar - mnMinCharPos], args.mpDXArray[lastChar - args.mnMinCharPos]); -#endif - i = nLastGlyph - 1; - if (i >= endGi - 1) - mnWidth += nDGlyphOrigin + nDWidth; - } - // Update the dx vector with the new values. - std::copy(args.mpDXArray, args.mpDXArray + nChars, - mvCharDxs.begin() + (args.mnMinCharPos - mnMinCharPos)); - //args.mpDXArray[0] = 0; -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"ApplyDx %ld(%ld)\n", args.mpDXArray[nChars - 1], mnWidth); -#endif - if (bRtl) - { - int diff = mvGlyphs[0].maLinearPos.X(); - for (GlyphItem & i : mvGlyphs) - i.maLinearPos.X() -= diff; - } -} - -void GraphiteLayout::kashidaJustify(std::vector<int>& rDeltaWidths, sal_GlyphId nKashidaIndex, int nKashidaWidth) -{ - // skip if the kashida glyph in the font looks suspicious - if( nKashidaWidth <= 0 ) - return; - - // calculate max number of needed kashidas - Glyphs::iterator i = mvGlyphs.begin(); - int nKashidaCount = 0; - int nOrigGlyphIndex = -1; - int nGlyphIndex = -1; - while (i != mvGlyphs.end()) - { - nOrigGlyphIndex++; - nGlyphIndex++; - // only inject kashidas in RTL contexts - if( !(*i).IsRTLGlyph() ) - { - ++i; - continue; - } - // no kashida-injection for blank justified expansion either - if( IsSpacingGlyph( (*i).maGlyphId ) ) - { - ++i; - continue; - } - // calculate gap, ignore if too small - int nGapWidth = rDeltaWidths[nOrigGlyphIndex]; - // worst case is one kashida even for mini-gaps - if( 3 * nGapWidth < nKashidaWidth ) - { - ++i; - continue; - } - nKashidaCount = 1 + (nGapWidth / nKashidaWidth); -#ifdef GRLAYOUT_DEBUG - printf("inserting %d kashidas at %u\n", nKashidaCount, (*i).maGlyphId); -#endif - GlyphItem glyphItem = *i; - Point aPos(0, 0); - aPos.X() = (*i).maLinearPos.X(); - GlyphItem newGi(glyphItem.mnCharPos, nKashidaIndex, aPos, - GlyphItem::IS_IN_CLUSTER|GlyphItem::IS_RTL_GLYPH, nKashidaWidth); - mvGlyphs.reserve(mvGlyphs.size() + nKashidaCount); - i = mvGlyphs.begin() + nGlyphIndex; - mvGlyphs.insert(i, nKashidaCount, newGi); - i = mvGlyphs.begin() + nGlyphIndex; - nGlyphIndex += nKashidaCount; - // now fix up the kashida positions - for (int j = 0; j < nKashidaCount; j++) - { - (*(i)).maLinearPos.X() -= nGapWidth; - nGapWidth -= nKashidaWidth; - ++i; - } - - // fixup rightmost kashida for gap remainder - if( nGapWidth < 0 ) - { - if( nKashidaCount <= 1 ) - nGapWidth /= 2; // for small gap move kashida to middle - (*(i-1)).mnNewWidth += nGapWidth; // adjust kashida width to gap width - (*(i-1)).maLinearPos.X() += nGapWidth; - } - - (*i).mnNewWidth = (*i).mnOrigWidth; - ++i; - } - -} - -void GraphiteLayout::GetCaretPositions( int nArraySize, long* pCaretXArray ) const -{ - // For each character except the last discover the caret positions - // immediately before and after that character. - // This is used for underlines in the GUI amongst other things. - // It may be used from MultiSalLayout, in which case it must take into account - // glyphs that have been moved. - std::fill(pCaretXArray, pCaretXArray + nArraySize, -1); - // the layout method doesn't modify the layout even though it isn't - // const in the interface - bool bRtl(mnLayoutFlags & SalLayoutFlags::BiDiRtl);//const_cast<GraphiteLayout*>(this)->maLayout.rightToLeft(); - int prevBase = -1; - long prevClusterWidth = 0; - for (int i = 0, nCharSlot = 0; i < nArraySize && nCharSlot < static_cast<int>(mvCharDxs.size()); ++nCharSlot, i+=2) - { - if (mvChar2BaseGlyph[nCharSlot] != -1) - { - int nChar2Base = mvChar2BaseGlyph[nCharSlot]; - assert((nChar2Base > -1) && (nChar2Base < (signed)mvGlyphs.size())); - GlyphItem gi = mvGlyphs[nChar2Base]; - if (gi.maGlyphId == GF_DROPPED) - { - continue; - } - int nCluster = nChar2Base; - long origClusterWidth = gi.mnNewWidth; - long nMin = gi.maLinearPos.X(); - long nMax = gi.maLinearPos.X() + gi.mnNewWidth; - // attached glyphs are always stored after their base rtl or ltr - while (++nCluster < static_cast<int>(mvGlyphs.size()) && - !mvGlyphs[nCluster].IsClusterStart()) - { - origClusterWidth += mvGlyphs[nCluster].mnNewWidth; - if (mvGlyph2Char[nCluster] == nCharSlot) - { - nMin = minimum(nMin, mvGlyphs[nCluster].maLinearPos.X()); - nMax = maximum(nMax, mvGlyphs[nCluster].maLinearPos.X() + mvGlyphs[nCluster].mnNewWidth); - } - } - if (bRtl) - { - pCaretXArray[i+1] = nMin; - pCaretXArray[i] = nMax; - } - else - { - pCaretXArray[i] = nMin; - pCaretXArray[i+1] = nMax; - } - prevBase = nChar2Base; - prevClusterWidth = origClusterWidth; - } - else if (prevBase > -1) - { - // this could probably be improved - assert((prevBase > -1) && (prevBase < (signed)mvGlyphs.size())); - GlyphItem gi = mvGlyphs[prevBase]; - int nGlyph = prevBase + 1; - // try to find a better match, otherwise default to complete cluster - for (; nGlyph < static_cast<int>(mvGlyphs.size()) && - !mvGlyphs[nGlyph].IsClusterStart(); nGlyph++) - { - if (mvGlyph2Char[nGlyph] == nCharSlot) - { - gi = mvGlyphs[nGlyph]; - break; - } - } - // if no match position at end of cluster - if (nGlyph == static_cast<int>(mvGlyphs.size()) || - mvGlyphs[nGlyph].IsClusterStart()) - { - if (bRtl) - { - pCaretXArray[i+1] = gi.maLinearPos.X(); - pCaretXArray[i] = gi.maLinearPos.X(); - } - else - { - pCaretXArray[i] = gi.maLinearPos.X() + prevClusterWidth; - pCaretXArray[i+1] = gi.maLinearPos.X() + prevClusterWidth; - } - } - else - { - if (bRtl) - { - pCaretXArray[i+1] = gi.maLinearPos.X(); - pCaretXArray[i] = gi.maLinearPos.X() + gi.mnNewWidth; - } - else - { - pCaretXArray[i] = gi.maLinearPos.X(); - pCaretXArray[i+1] = gi.maLinearPos.X() + gi.mnNewWidth; - } - } - } - else - { - pCaretXArray[i] = pCaretXArray[i+1] = 0; - } -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"%d,%ld-%ld\t", nCharSlot, pCaretXArray[i], pCaretXArray[i+1]); -#endif - } -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"\n"); -#endif -} - -// GetNextGlyphs returns a contiguous sequence of glyphs that can be -// rendered together. It should never return a dropped glyph. -// The glyph_slot returned should be the index of the next visible -// glyph after the last glyph returned by this call. -// The char_index array should be filled with the characters corresponding -// to each glyph returned. -// glyph_adv array should be a virtual width such that if successive -// glyphs returned by this method are added one after the other they -// have the correct spacing. -// The logic in this method must match that expected in MultiSalLayout which -// is used when glyph fallback is in operation. -int GraphiteLayout::GetNextGlyphs( int length, sal_GlyphId * glyph_out, - ::Point & aPosOut, int &glyph_slot, DeviceCoordinate* glyph_adv, int *char_index, - const PhysicalFontFace** /*pFallbackFonts*/ ) const -{ - // Sanity check on the slot index. - if (glyph_slot >= signed(mvGlyphs.size())) - { - glyph_slot = mvGlyphs.size(); - return 0; - } - assert(glyph_slot >= 0); - // Find the first glyph in the substring. - for (; glyph_slot < signed(mvGlyphs.size()) && - ((mvGlyphs.begin() + glyph_slot)->maGlyphId == GF_DROPPED); - ++glyph_slot) {}; - - // Update the length - const int nGlyphSlotEnd = minimum(size_t(glyph_slot + length), mvGlyphs.size()); - - // We're all out of glyphs here. - if (glyph_slot == nGlyphSlotEnd) - { - return 0; - } - - // Find as many glyphs as we can which can be drawn in one go. - Glyphs::const_iterator glyph_itr = mvGlyphs.begin() + glyph_slot; - const int glyph_slot_begin = glyph_slot; - const int initial_y_pos = glyph_itr->maLinearPos.Y(); - - // Set the position to the position of the start glyph. - ::Point aStartPos = glyph_itr->maLinearPos; - //aPosOut = glyph_itr->maLinearPos; - aPosOut = GetDrawPosition(aStartPos); - - for (;;) // Forever - { - // last index of the range from glyph_to_chars does not include this glyph - if (char_index) - { - if (glyph_slot >= (signed)mvGlyph2Char.size()) - { - *char_index++ = mnMinCharPos + mvCharDxs.size(); - } - else - { - assert(glyph_slot > -1); - if (mvGlyph2Char[glyph_slot] == -1) - *char_index++ = mnMinCharPos + mvCharDxs.size(); - else - *char_index++ = mvGlyph2Char[glyph_slot]; - } - } - // Copy out this glyphs data. - ++glyph_slot; - *glyph_out++ = glyph_itr->maGlyphId; - - // Find the actual advance - this must be correct if called from - // MultiSalLayout::AdjustLayout which requests one glyph at a time. - const long nGlyphAdvance = (glyph_slot == static_cast<int>(mvGlyphs.size()))? - glyph_itr->mnNewWidth : - ((glyph_itr+1)->maLinearPos.X() - glyph_itr->maLinearPos.X()); - -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"GetNextGlyphs g%d gid%d c%d x%ld,%ld adv%ld, pos %ld,%ld\n", - glyph_slot - 1, glyph_itr->maGlyphId, - mvGlyph2Char[glyph_slot-1], glyph_itr->maLinearPos.X(), glyph_itr->maLinearPos.Y(), (long)nGlyphAdvance, - aPosOut.X(), aPosOut.Y()); -#endif - - if (glyph_adv) // If we are returning advance store it. - *glyph_adv++ = nGlyphAdvance; - else // Stop when next advance is unexpected. - if (glyph_itr->mnOrigWidth != nGlyphAdvance) break; - - // Have fetched all the glyphs we need to - if (glyph_slot == nGlyphSlotEnd) - break; - - ++glyph_itr; - // Stop when next y position is unexpected. - if (initial_y_pos != glyph_itr->maLinearPos.Y()) - break; - - // Stop if glyph dropped - if (glyph_itr->maGlyphId == GF_DROPPED) - break; - } - int numGlyphs = glyph_slot - glyph_slot_begin; - // move the next glyph_slot to a glyph that hasn't been dropped - while (glyph_slot < static_cast<int>(mvGlyphs.size()) && - (mvGlyphs.begin() + glyph_slot)->maGlyphId == GF_DROPPED) - ++glyph_slot; - return numGlyphs; -} - -void GraphiteLayout::MoveGlyph( int nGlyphIndex, long nNewPos ) -{ - // TODO it might be better to actually implement simplify properly, but this - // needs to be done carefully so the glyph/char maps are maintained - // If a glyph has been dropped then it wasn't returned by GetNextGlyphs, so - // the index here may be wrong - while ((mvGlyphs[nGlyphIndex].maGlyphId == GF_DROPPED) && - (nGlyphIndex < (signed)mvGlyphs.size())) - { - nGlyphIndex++; - } - const long dx = nNewPos - mvGlyphs[nGlyphIndex].maLinearPos.X(); - - if (dx == 0) return; - // GenericSalLayout only changes maLinearPos, mvCharDxs doesn't change -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"Move %d (%ld,%ld) c%d by %ld\n", nGlyphIndex, mvGlyphs[nGlyphIndex].maLinearPos.X(), nNewPos, mvGlyph2Char[nGlyphIndex], dx); -#endif - for (size_t gi = nGlyphIndex; gi < mvGlyphs.size(); gi++) - { - mvGlyphs[gi].maLinearPos.X() += dx; - } - // width does need to be updated for correct fallback - mnWidth += dx; -} - -void GraphiteLayout::DropGlyph( int nGlyphIndex ) -{ - if(nGlyphIndex >= signed(mvGlyphs.size())) - return; - - GlyphItem & glyph = mvGlyphs[nGlyphIndex]; - glyph.maGlyphId = GF_DROPPED; -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"Dropped %d\n", nGlyphIndex); -#endif -} - -void GraphiteLayout::Simplify( bool isBaseLayout ) -{ - const sal_GlyphId dropMarker = isBaseLayout ? GF_DROPPED : 0; - - Glyphs::iterator gi = mvGlyphs.begin(); - // TODO check whether we need to adjust positions here - // MultiSalLayout seems to move the glyphs itself, so it may not be needed. - long deltaX = 0; - while (gi != mvGlyphs.end()) - { - if (gi->maGlyphId == dropMarker) - { - deltaX += gi->mnNewWidth; - gi->mnNewWidth = 0; - } - else - { - deltaX = 0; - } - ++gi; - } -#ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"Simplify base%d dx=%ld newW=%ld\n", isBaseLayout, deltaX, mnWidth - deltaX); -#endif - // discard width from trailing dropped glyphs, but not those in the middle - mnWidth -= deltaX; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx index eb941e2b384c..289a066cf878 100644 --- a/vcl/unx/generic/gdi/cairotextrender.cxx +++ b/vcl/unx/generic/gdi/cairotextrender.cxx @@ -34,12 +34,6 @@ #include "impfont.hxx" #include "impfontmetricdata.hxx" -#include <config_graphite.h> -#if ENABLE_GRAPHITE -#include <graphite_layout.hxx> -#include <graphite_serverfont.hxx> -#endif - #include <cairo.h> #include <cairo-ft.h> #include "CommonSalLayout.hxx" @@ -95,12 +89,6 @@ CairoTextRender::CairoTextRender() { for(FreetypeFont* & rp : mpFreetypeFont) rp = nullptr; - -#if ENABLE_GRAPHITE - // check if graphite fonts have been disabled - static const char* pDisableGraphiteStr = getenv( "SAL_DISABLE_GRAPHITE" ); - bDisableGraphite_ = pDisableGraphiteStr && (pDisableGraphiteStr[0]!='0'); -#endif } bool CairoTextRender::setFont( const FontSelectPattern *pEntry, int nFallbackLevel ) @@ -519,22 +507,9 @@ SalLayout* CairoTextRender::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackL && !(rArgs.mnFlags & SalLayoutFlags::DisableGlyphProcessing) ) { if (SalLayout::UseCommonLayout()) - { pLayout = new CommonSalLayout(*mpFreetypeFont[nFallbackLevel]); - } else - { -#if ENABLE_GRAPHITE - // Is this a Graphite font? - if (!bDisableGraphite_ && - GraphiteServerFontLayout::IsGraphiteEnabledFont(*mpFreetypeFont[nFallbackLevel])) - { - pLayout = new GraphiteServerFontLayout(*mpFreetypeFont[nFallbackLevel]); - } - else -#endif - pLayout = new ServerFontLayout( *mpFreetypeFont[ nFallbackLevel ] ); - } + pLayout = new ServerFontLayout( *mpFreetypeFont[ nFallbackLevel ] ); } return pLayout; diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx index 6df2bba7269a..409972619201 100644 --- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx +++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx @@ -28,12 +28,6 @@ #include "fontattributes.hxx" #include <config_features.h> -#include <config_graphite.h> -#if ENABLE_GRAPHITE -# include <graphite_static.hxx> -# include <graphite2/Font.h> -# include <graphite_layout.hxx> -#endif #include <unotools/fontdefs.hxx> #include "tools/poly.hxx" @@ -170,33 +164,6 @@ void FreetypeFontFile::Unmap() mpFileMap = nullptr; } -#if ENABLE_GRAPHITE -// wrap FreetypeFontInfo's table function -const void * graphiteFontTable(const void* appFaceHandle, unsigned int name, size_t *len) -{ - const FreetypeFontInfo * pFontInfo = static_cast<const FreetypeFontInfo*>(appFaceHandle); - typedef union { - char m_c[5]; - unsigned int m_id; - } TableId; - TableId tableId; - tableId.m_id = name; -#ifndef OSL_BIGENDIAN - TableId swapped; - swapped.m_c[3] = tableId.m_c[0]; - swapped.m_c[2] = tableId.m_c[1]; - swapped.m_c[1] = tableId.m_c[2]; - swapped.m_c[0] = tableId.m_c[3]; - tableId.m_id = swapped.m_id; -#endif - tableId.m_c[4] = '\0'; - sal_uLong nLength = 0; - const void * pTable = static_cast<const void*>(pFontInfo->GetTable(tableId.m_c, &nLength)); - if (len) *len = static_cast<size_t>(nLength); - return pTable; -} -#endif - FreetypeFontInfo::FreetypeFontInfo( const FontAttributes& rDevFontAttributes, const OString& rNativeFileName, int nFaceNum, sal_IntPtr nFontId) : @@ -204,10 +171,6 @@ FreetypeFontInfo::FreetypeFontInfo( const FontAttributes& rDevFontAttributes, mpFontFile( FreetypeFontFile::FindFontFile( rNativeFileName ) ), mnFaceNum( nFaceNum ), mnRefCount( 0 ), -#if ENABLE_GRAPHITE - mbCheckedGraphite(false), - mpGraphiteFace(nullptr), -#endif mnFontId( nFontId ), maDevFontAttributes( rDevFontAttributes ), mxFontCharMap( nullptr ), @@ -226,9 +189,6 @@ FreetypeFontInfo::~FreetypeFontInfo() mxFontCharMap.Clear(); delete mpChar2Glyph; delete mpGlyph2Char; -#if ENABLE_GRAPHITE - delete mpGraphiteFace; -#endif } void FreetypeFontInfo::InitHashes() const @@ -253,29 +213,6 @@ FT_FaceRec_* FreetypeFontInfo::GetFaceFT() return maFaceFT; } -#if ENABLE_GRAPHITE -GraphiteFaceWrapper * FreetypeFontInfo::GetGraphiteFace() -{ - if (mbCheckedGraphite) - return mpGraphiteFace; - // test for graphite here so that it is cached most efficiently - if (GetTable("Silf")) - { - static const char* pGraphiteCacheStr = getenv( "SAL_GRAPHITE_CACHE_SIZE" ); - int graphiteSegCacheSize = pGraphiteCacheStr ? (atoi(pGraphiteCacheStr)) : 0; - gr_face * pGraphiteFace; - if (graphiteSegCacheSize > 500) - pGraphiteFace = gr_make_face_with_seg_cache(this, graphiteFontTable, graphiteSegCacheSize, gr_face_cacheCmap); - else - pGraphiteFace = gr_make_face(this, graphiteFontTable, gr_face_cacheCmap); - if (pGraphiteFace) - mpGraphiteFace = new GraphiteFaceWrapper(pGraphiteFace); - } - mbCheckedGraphite = true; - return mpGraphiteFace; -} -#endif - void FreetypeFontInfo::ReleaseFaceFT() { if (--mnRefCount <= 0) @@ -1507,11 +1444,4 @@ const unsigned char* FreetypeFont::GetTable(const char* pName, sal_uLong* pLengt return mpFontInfo->GetTable( pName, pLength ); } -#if ENABLE_GRAPHITE -GraphiteFaceWrapper* FreetypeFont::GetGraphiteFace() const -{ - return mpFontInfo->GetGraphiteFace(); -} -#endif - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/glyphs/graphite_serverfont.cxx b/vcl/unx/generic/glyphs/graphite_serverfont.cxx deleted file mode 100644 index af57ded6d861..000000000000 --- a/vcl/unx/generic/glyphs/graphite_serverfont.cxx +++ /dev/null @@ -1,134 +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 "unx/glyphcache.hxx" -#include <graphite_features.hxx> -#include <graphite_serverfont.hxx> - -float freetypeServerFontAdvance(const void* appFontHandle, gr_uint16 glyphId) -{ - FreetypeFont * pFreetypeFont = - const_cast<FreetypeFont*> - (static_cast<const FreetypeFont*>(appFontHandle)); - if (pFreetypeFont) - { - return static_cast<float>(pFreetypeFont->GetGlyphMetric(glyphId).GetCharWidth()); - } - return .0f; -} - -// An implementation of the GraphiteLayout interface to enable Graphite enabled fonts to be used. - -GraphiteServerFontLayout::GraphiteServerFontLayout(FreetypeFont& rFreetypeFont) throw() - : ServerFontLayout(rFreetypeFont), - maImpl(rFreetypeFont.GetGraphiteFace()->face(), rFreetypeFont) - , mpFeatures(nullptr) -{ - gr_font * pFont = rFreetypeFont.GetGraphiteFace()->font(rFreetypeFont.GetFontSelData().mnHeight, rFreetypeFont.NeedsArtificialBold(), rFreetypeFont.NeedsArtificialItalic()); - if (!pFont) - { - pFont = gr_make_font_with_advance_fn( - // need to use mnHeight here, mfExactHeight can give wrong values - static_cast<float>(rFreetypeFont.GetFontSelData().mnHeight), - &rFreetypeFont, - freetypeServerFontAdvance, - rFreetypeFont.GetGraphiteFace()->face()); - rFreetypeFont.GetGraphiteFace()->addFont(rFreetypeFont.GetFontSelData().mnHeight, pFont, rFreetypeFont.NeedsArtificialBold(), rFreetypeFont.NeedsArtificialItalic()); - } - maImpl.SetFont(pFont); - OString aLang(""); - if (rFreetypeFont.GetFontSelData().meLanguage != LANGUAGE_DONTKNOW) - { - aLang = OUStringToOString( LanguageTag( rFreetypeFont.GetFontSelData().meLanguage ).getBcp47(), - RTL_TEXTENCODING_UTF8 ); - } - OString name = OUStringToOString( - rFreetypeFont.GetFontSelData().maTargetName, RTL_TEXTENCODING_UTF8 ); -#ifdef DEBUG - printf("GraphiteServerFontLayout %lx %s size %d %f\n", (long unsigned int)this, name.getStr(), - rFreetypeFont.GetFtFace()->size->metrics.x_ppem, - rFreetypeFont.GetFontSelData().mfExactHeight); -#endif - sal_Int32 nFeat = name.indexOf(FontSelectPatternAttributes::FEAT_PREFIX) + 1; - if (nFeat > 0) - { - OString aFeat = name.copy(nFeat, name.getLength() - nFeat); - mpFeatures = new grutils::GrFeatureParser( - rFreetypeFont.GetGraphiteFace()->face(), aFeat, aLang); -#ifdef DEBUG - if (mpFeatures) - printf("GraphiteServerFontLayout %s/%s/%s %x language\n", - OUStringToOString( rFreetypeFont.GetFontSelData().GetFamilyName(), - RTL_TEXTENCODING_UTF8 ).getStr(), - OUStringToOString( rFreetypeFont.GetFontSelData().maTargetName, - RTL_TEXTENCODING_UTF8 ).getStr(), - OUStringToOString( rFreetypeFont.GetFontSelData().maSearchName, - RTL_TEXTENCODING_UTF8 ).getStr(), - rFreetypeFont.GetFontSelData().meLanguage); -#endif - } - else - { - mpFeatures = new grutils::GrFeatureParser( - rFreetypeFont.GetGraphiteFace()->face(), aLang); - } - maImpl.SetFeatures(mpFeatures); -} - -GraphiteServerFontLayout::~GraphiteServerFontLayout() throw() -{ - delete mpFeatures; - mpFeatures = nullptr; -} - -bool GraphiteServerFontLayout::IsGraphiteEnabledFont(FreetypeFont& rFreetypeFont) -{ - if (rFreetypeFont.GetGraphiteFace()) - { -#ifdef DEBUG - printf("IsGraphiteEnabledFont\n"); -#endif - return true; - } - return false; -} - -sal_GlyphId GraphiteLayoutImpl::getKashidaGlyph(int & width) -{ - int nKashidaIndex = mrFreetypeFont.GetGlyphIndex( 0x0640 ); - if( nKashidaIndex != 0 ) - { - const GlyphMetric& rGM = mrFreetypeFont.GetGlyphMetric( nKashidaIndex ); - width = rGM.GetCharWidth(); - } - else - { - width = 0; - } - return nKashidaIndex; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/print/genpspgraphics.cxx b/vcl/unx/generic/print/genpspgraphics.cxx index 6bd871b89049..ee605546dc5f 100644 --- a/vcl/unx/generic/print/genpspgraphics.cxx +++ b/vcl/unx/generic/print/genpspgraphics.cxx @@ -56,12 +56,6 @@ #include "salprn.hxx" #include "CommonSalLayout.hxx" -#include <config_graphite.h> -#if ENABLE_GRAPHITE -#include <graphite_layout.hxx> -#include <graphite_serverfont.hxx> -#endif - using namespace psp; // ----- Implementation of PrinterBmp by means of SalBitmap/BitmapBuffer --------------- @@ -741,20 +735,12 @@ static void DrawPrinterLayout( const SalLayout& rLayout, ::psp::PrinterGfx& rGfx if (bIsPspServerFontLayout) { const PspServerFontLayout * pPspLayout = dynamic_cast<const PspServerFontLayout*>(&rLayout); -#if ENABLE_GRAPHITE - const GraphiteServerFontLayout * pGrLayout = dynamic_cast<const GraphiteServerFontLayout*>(&rLayout); -#endif if (pPspLayout) { pText = pPspLayout->getTextPtr(); nMinCharPos = pPspLayout->getMinCharPos(); nMaxCharPos = pPspLayout->getMaxCharPos(); } -#if ENABLE_GRAPHITE - else if (pGrLayout) - { - } -#endif } for( int nStart = 0;; ) { @@ -1027,21 +1013,9 @@ SalLayout* GenPspGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe && !(rArgs.mnFlags & SalLayoutFlags::DisableGlyphProcessing) ) { if (SalLayout::UseCommonLayout()) - { - pLayout = new PspCommonSalLayout(*m_pPrinterGfx, *m_pFreetypeFont[nFallbackLevel]); - } + pLayout = new PspCommonSalLayout(*m_pPrinterGfx, *m_pFreetypeFont[nFallbackLevel]); else - { -#if ENABLE_GRAPHITE - // Is this a Graphite font? - if (GraphiteServerFontLayout::IsGraphiteEnabledFont(*m_pFreetypeFont[nFallbackLevel])) - { - pLayout = new GraphiteServerFontLayout(*m_pFreetypeFont[nFallbackLevel]); - } - else -#endif - pLayout = new PspServerFontLayout( *m_pPrinterGfx, *m_pFreetypeFont[nFallbackLevel], rArgs ); - } + pLayout = new PspServerFontLayout( *m_pPrinterGfx, *m_pFreetypeFont[nFallbackLevel], rArgs ); } else pLayout = new PspFontLayout( *m_pPrinterGfx ); diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index d2d964d47f4b..1c2cfe4289da 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -642,107 +642,11 @@ void ImplSalLogFontToFontW( HDC hDC, const LOGFONTW& rLogFont, Font& rFont ) } } -#if ENABLE_GRAPHITE - -#ifdef DEBUG -static FILE * grLogFile = NULL; -static FILE * grLog() -{ - std::string logFileName(getenv("TEMP")); - logFileName.append("\\grface.log"); - if (grLogFile == NULL) grLogFile = fopen(logFileName.c_str(),"w"); - else fflush(grLogFile); - return grLogFile; -} -#endif - -const void * getGrTable(const void* appFaceHandle, unsigned int name, size_t *len) -{ - const GrFontData * fontTables = static_cast<const GrFontData*>(appFaceHandle); - return fontTables->getTable(name, len); -} - -GrFontData::GrFontData(HDC hDC) : - mhDC(hDC), mpFace(nullptr), mnRefCount(1) -{ - // The face options ensure that the tables are all read at construction - // time so there is no need to keep the hDC uptodate - static const char* pGraphiteCacheStr = getenv( "SAL_GRAPHITE_CACHE_SIZE" ); - unsigned long graphiteSegCacheSize = pGraphiteCacheStr ? (atoi(pGraphiteCacheStr)) : 0; - if (graphiteSegCacheSize > 500) - mpFace = gr_make_face_with_seg_cache(this, getGrTable, - graphiteSegCacheSize, gr_face_preloadGlyphs | gr_face_cacheCmap); - else - mpFace = gr_make_face(this, getGrTable, - gr_face_preloadGlyphs | gr_face_cacheCmap); -#ifdef DEBUG - fprintf(grLog(), "gr_make_face %lx for WinFontData %lx\n", (unsigned long)mpFace, - (unsigned long)this); -#endif - mhDC = nullptr; -} - -GrFontData::~GrFontData() -{ - if (mpFace) - { -#ifdef DEBUG - fprintf(grLog(), "gr_face_destroy %lx for WinFontData %lx\n", (unsigned long)mpFace, - (unsigned long)this); -#endif - gr_face_destroy(mpFace); - mpFace = nullptr; - } - std::vector<RawFontData*>::iterator i = mvData.begin(); - while (i != mvData.end()) - { - delete *i; - ++i; - } - mvData.clear(); -} - -const void * GrFontData::getTable(unsigned int name, size_t *len) const -{ - assert(mhDC); - // swap the bytes - union TtfTag { - unsigned int i; - unsigned char c[4]; - }; - TtfTag littleEndianTag; - littleEndianTag.i = name; - TtfTag bigEndianTag; - bigEndianTag.c[0] = littleEndianTag.c[3]; - bigEndianTag.c[1] = littleEndianTag.c[2]; - bigEndianTag.c[2] = littleEndianTag.c[1]; - bigEndianTag.c[3] = littleEndianTag.c[0]; - mvData.push_back(new RawFontData(mhDC, bigEndianTag.i)); - const RawFontData * data = mvData[mvData.size()-1]; - if (data && (data->size() > 0)) - { - if (len) - *len = data->size(); - return static_cast<const void *>(data->get()); - } - else - { - if (len) - *len = 0; - return nullptr; - } -} -#endif - WinFontFace::WinFontFace( const FontAttributes& rDFS, int nHeight, BYTE eWinCharSet, BYTE nPitchAndFamily ) : PhysicalFontFace( rDFS ), mnId( 0 ), mbHasCJKSupport( false ), -#if ENABLE_GRAPHITE - mpGraphiteData(nullptr), - mbHasGraphiteSupport( false ), -#endif mbHasArabicSupport ( false ), mbFontCapabilitiesRead( false ), mxUnicodeMap( nullptr ), @@ -785,13 +689,7 @@ WinFontFace::~WinFontFace() { if( mxUnicodeMap.Is() ) mxUnicodeMap = nullptr; -#if ENABLE_GRAPHITE - if (mpGraphiteData) - mpGraphiteData->DeReference(); -#ifdef DEBUG - fprintf(grLog(), "WinFontFace::~WinFontFace %lx\n", (unsigned long)this); -#endif -#endif // ENABLE_GRAPHITE + delete mpEncodingVector; if( mpHbFont ) @@ -814,45 +712,8 @@ void WinFontFace::UpdateFromHDC( HDC hDC ) const ReadCmapTable( hDC ); GetFontCapabilities( hDC ); -#if ENABLE_GRAPHITE - static const char* pDisableGraphiteText = getenv( "SAL_DISABLE_GRAPHITE" ); - if( !pDisableGraphiteText || (pDisableGraphiteText[0] == '0') ) - { - const DWORD nSilfTag = CalcTag("Silf"); - const RawFontData aRawFontData( hDC, nSilfTag ); - mbHasGraphiteSupport = (aRawFontData.size() > 0); - if (mbHasGraphiteSupport) - { -#ifdef DEBUG - fprintf(grLog(), "WinFontFace::UpdateFromHDC %lx\n", - (unsigned long)this); -#endif - if (mpGraphiteData == nullptr) - { - mpGraphiteData = new GrFontData(hDC); - if (!mpGraphiteData->getFace()) - { - mbHasGraphiteSupport = false; - delete mpGraphiteData; - mpGraphiteData = nullptr; - } - } - } - } -#endif } -#if ENABLE_GRAPHITE -const gr_face* WinFontFace::GraphiteFace() const -{ -#ifdef DEBUG - fprintf(grLog(), "WinFontFace::GraphiteFace %lx has face %lx\n", - (unsigned long)this, mpGraphiteData? mpGraphiteData->getFace(): 0); -#endif - return (mpGraphiteData)? mpGraphiteData->getFace() : nullptr; -} -#endif - bool WinFontFace::HasGSUBstitutions( HDC hDC ) const { if( !mbGsubRead ) diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx index 4941ac7cad3a..1cb227bc85d4 100644 --- a/vcl/win/gdi/winlayout.cxx +++ b/vcl/win/gdi/winlayout.cxx @@ -3430,164 +3430,6 @@ bool D2DWriteTextOutRenderer::GetDWriteInkBox(SalLayout const &rLayout, Rectangl return true; } -#if ENABLE_GRAPHITE - -sal_GlyphId GraphiteLayoutWinImpl::getKashidaGlyph(int & rWidth) -{ - rWidth = mrFont.GetMinKashidaWidth(); - return mrFont.GetMinKashidaGlyph(); -} - -float gr_fontAdvance(const void* appFontHandle, gr_uint16 glyphId) -{ - HDC hDC = static_cast<HDC>(const_cast<void*>(appFontHandle)); - GLYPHMETRICS gm; - const MAT2 mat2 = {{0,1}, {0,0}, {0,0}, {0,1}}; - if (GDI_ERROR == GetGlyphOutlineW(hDC, glyphId, GGO_GLYPH_INDEX | GGO_METRICS, - &gm, 0, nullptr, &mat2)) - { - return .0f; - } - return gm.gmCellIncX; -} - -GraphiteWinLayout::GraphiteWinLayout(HDC hDC, const WinFontFace& rWFD, WinFontInstance& rWFE, bool bUseOpenGL) throw() - : WinLayout(hDC, rWFD, rWFE, bUseOpenGL), mpFont(nullptr), - maImpl(rWFD.GraphiteFace(), rWFE) -{ - // the log font size may differ from the font entry size if scaling is used for large fonts - LOGFONTW aLogFont; - GetObjectW( mhFont, sizeof(LOGFONTW), &aLogFont); - mpFont = gr_make_font_with_advance_fn(static_cast<float>(-aLogFont.lfHeight), - hDC, gr_fontAdvance, rWFD.GraphiteFace()); - maImpl.SetFont(mpFont); - const OString aLang = OUStringToOString( LanguageTag::convertToBcp47( rWFE.maFontSelData.meLanguage ), - RTL_TEXTENCODING_ASCII_US); - OString name = OUStringToOString( - rWFE.maFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 ); - sal_Int32 nFeat = name.indexOf(FontSelectPatternAttributes::FEAT_PREFIX) + 1; - if (nFeat > 0) - { - OString aFeat = name.copy(nFeat, name.getLength() - nFeat); - mpFeatures = new grutils::GrFeatureParser(rWFD.GraphiteFace(), aFeat.getStr(), aLang.getStr()); - } - else - { - mpFeatures = new grutils::GrFeatureParser(rWFD.GraphiteFace(), aLang.getStr()); - } - maImpl.SetFeatures(mpFeatures); -} - -GraphiteWinLayout::~GraphiteWinLayout() -{ - delete mpFeatures; - gr_font_destroy(maImpl.GetFont()); -} - -bool GraphiteWinLayout::LayoutText(ImplLayoutArgs & args) -{ - HFONT hUnRotatedFont = nullptr; - if (args.mnOrientation) - { - // Graphite gets very confused if the font is rotated - LOGFONTW aLogFont; - GetObjectW( mhFont, sizeof(LOGFONTW), &aLogFont); - aLogFont.lfEscapement = 0; - aLogFont.lfOrientation = 0; - hUnRotatedFont = CreateFontIndirectW( &aLogFont); - SelectFont(mhDC, hUnRotatedFont); - } - WinLayout::AdjustLayout(args); - maImpl.SetFontScale(WinLayout::mfFontScale); - bool bSucceeded = maImpl.LayoutText(args); - if (args.mnOrientation) - { - // restore the rotated font - SelectFont(mhDC, mhFont); - DeleteObject(hUnRotatedFont); - } - return bSucceeded; -} - -void GraphiteWinLayout::AdjustLayout(ImplLayoutArgs& rArgs) -{ - WinLayout::AdjustLayout(rArgs); - maImpl.DrawBase() = WinLayout::maDrawBase; - maImpl.DrawOffset() = WinLayout::maDrawOffset; - if ( (rArgs.mnFlags & SalLayoutFlags::BiDiRtl) && rArgs.mpDXArray) - { - mrWinFontEntry.InitKashidaHandling(mhDC); - } - maImpl.AdjustLayout(rArgs); -} - -bool GraphiteWinLayout::DrawTextImpl(HDC hDC, - const Rectangle* pRectToErase, - Point* pPos, - int* pGetNextGlypInfo) const -{ - HFONT hOrigFont = DisableFontScaling(); - maImpl.DrawBase() = WinLayout::maDrawBase; - maImpl.DrawOffset() = WinLayout::maDrawOffset; - - TextOutRenderer & render = TextOutRenderer::get(true); - bool const ok = render(*this, hDC, pRectToErase, pPos, pGetNextGlypInfo); - if( hOrigFont ) - DeleteFont(SelectFont(hDC, hOrigFont)); - return ok; -} - -bool GraphiteWinLayout::CacheGlyphs(SalGraphics& /*rGraphics*/) const -{ - return false; -} - -bool GraphiteWinLayout::DrawCachedGlyphs(SalGraphics& /*rGraphics*/) const -{ - return false; -} - -sal_Int32 GraphiteWinLayout::GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate nCharExtra, int nFactor) const -{ - sal_Int32 nBreak = maImpl.GetTextBreak(nMaxWidth, nCharExtra, nFactor); - return nBreak; -} - -DeviceCoordinate GraphiteWinLayout::FillDXArray( DeviceCoordinate* pDXArray ) const -{ - return maImpl.FillDXArray(pDXArray); -} - -void GraphiteWinLayout::GetCaretPositions( int nArraySize, long* pCaretXArray ) const -{ - maImpl.GetCaretPositions(nArraySize, pCaretXArray); -} - -int GraphiteWinLayout::GetNextGlyphs( int length, sal_GlyphId* glyph_out, - Point& pos_out, int& glyph_slot, DeviceCoordinate* glyph_adv, int* char_index, - const PhysicalFontFace** pFallbackFonts ) const -{ - maImpl.DrawBase() = WinLayout::maDrawBase; - maImpl.DrawOffset() = WinLayout::maDrawOffset; - return maImpl.GetNextGlyphs(length, glyph_out, pos_out, glyph_slot, glyph_adv, char_index, pFallbackFonts); -} - -void GraphiteWinLayout::MoveGlyph( int glyph_idx, long new_x_pos ) -{ - maImpl.MoveGlyph(glyph_idx, new_x_pos); -} - -void GraphiteWinLayout::DropGlyph( int glyph_idx ) -{ - maImpl.DropGlyph(glyph_idx); -} - -void GraphiteWinLayout::Simplify( bool is_base ) -{ - maImpl.Simplify(is_base); -} -#endif // ENABLE_GRAPHITE - SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel ) { if (!mpWinFontEntry[nFallbackLevel]) return nullptr; @@ -3612,13 +3454,6 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe if( !(rArgs.mnFlags & SalLayoutFlags::ComplexDisabled) ) { -#if ENABLE_GRAPHITE - if (rFontFace.SupportsGraphite()) - { - pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); - } - else -#endif // ENABLE_GRAPHITE { // script complexity is determined in upper layers pWinLayout = new UniscribeLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); @@ -3629,13 +3464,6 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe } else { -#if ENABLE_GRAPHITE - if (rFontFace.SupportsGraphite()) - { - pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); - } - else -#endif // ENABLE_GRAPHITE { static bool bAvoidSimpleWinLayout = (std::getenv("VCL_NO_SIMPLEWINLAYOUT") != nullptr); @@ -3756,10 +3584,6 @@ bool WinFontInstance::InitKashidaHandling( HDC hDC ) PhysicalFontFace* WinFontFace::Clone() const { -#if ENABLE_GRAPHITE - if ( mpGraphiteData ) - mpGraphiteData->AddReference(); -#endif if( mpHbFont ) hb_font_reference( mpHbFont ); |