diff options
Diffstat (limited to 'Bug_1584000___Migrate_glyph_to_character_association_code.patch')
-rw-r--r-- | Bug_1584000___Migrate_glyph_to_character_association_code.patch | 380 |
1 files changed, 0 insertions, 380 deletions
diff --git a/Bug_1584000___Migrate_glyph_to_character_association_code.patch b/Bug_1584000___Migrate_glyph_to_character_association_code.patch deleted file mode 100644 index 32e1e52651bd..000000000000 --- a/Bug_1584000___Migrate_glyph_to_character_association_code.patch +++ /dev/null @@ -1,380 +0,0 @@ -# HG changeset patch -# User shravanrn@gmail.com <shravanrn@gmail.com> -# Date 1572421705 0 -# Wed Oct 30 07:48:25 2019 +0000 -# Node ID 1b90fe16b26aaa175ed963b4cb1610e87cbac410 -# Parent f67361bfb377d12c0ee1f26f710833f20641bb77 -Bug 1584000 - Migrate glyph to character association code from libThebes to graphite for sandboxed libGraphite performance r=jfkthame,froydnj - -Differential Revision: https://phabricator.services.mozilla.com/D47388 - -diff -r f67361bfb377 -r 1b90fe16b26a gfx/graphite2/geckoextra/include/GraphiteExtra.h ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/gfx/graphite2/geckoextra/include/GraphiteExtra.h Wed Oct 30 07:48:25 2019 +0000 -@@ -0,0 +1,42 @@ -+// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- -+// vim: set ts=2 et sw=2 tw=80: -+// This Source Code is subject to the terms of the Mozilla Public License -+// version 2.0 (the "License"). You can obtain a copy of the License at -+// http://mozilla.org/MPL/2.0/. -+ -+#ifndef GraphiteExtra_h__ -+#define GraphiteExtra_h__ -+ -+#include <stdint.h> -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#include "graphite2/Segment.h" -+ -+typedef struct { -+ uint32_t baseChar; // in UTF16 code units, not Unicode character indices -+ uint32_t baseGlyph; -+ uint32_t nChars; // UTF16 code units -+ uint32_t nGlyphs; -+} gr_glyph_to_char_cluster; -+ -+typedef struct { -+ gr_glyph_to_char_cluster* clusters; -+ uint16_t* gids; -+ float* xLocs; -+ float* yLocs; -+ uint32_t cIndex; -+} gr_glyph_to_char_association; -+ -+gr_glyph_to_char_association* gr_get_glyph_to_char_association( -+ gr_segment* aSegment, uint32_t aLength, const char16_t* aText); -+ -+void gr_free_char_association(gr_glyph_to_char_association* aData); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif -\ No newline at end of file -diff -r f67361bfb377 -r 1b90fe16b26a gfx/graphite2/geckoextra/src/GraphiteExtra.cpp ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/gfx/graphite2/geckoextra/src/GraphiteExtra.cpp Wed Oct 30 07:48:25 2019 +0000 -@@ -0,0 +1,167 @@ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -+/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -+/* 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/. */ -+ -+#include "graphite2/Font.h" -+#include "graphite2/Segment.h" -+#include "graphite2/GraphiteExtra.h" -+ -+#include <stdlib.h> -+#include <memory> -+#include <limits> -+ -+#define CHECK(cond, str) \ -+ do { \ -+ if (!(cond)) { \ -+ return false; \ -+ } \ -+ } while (false) -+ -+// High surrogates are in the range 0xD800 -- OxDBFF -+#define NS_IS_HIGH_SURROGATE(u) ((uint32_t(u) & 0xFFFFFC00) == 0xD800) -+// Low surrogates are in the range 0xDC00 -- 0xDFFF -+#define NS_IS_LOW_SURROGATE(u) ((uint32_t(u) & 0xFFFFFC00) == 0xDC00) -+ -+#define IS_POWER_OF_2(n) (n & (n - 1)) == 0 -+ -+typedef gr_glyph_to_char_cluster Cluster; -+ -+// returns whether successful -+static bool LoopThrough(gr_segment* aSegment, const uint32_t aLength, -+ const uint32_t aGlyphCount, const char16_t* aText, -+ uint32_t& aCIndex, Cluster* aClusters, uint16_t* aGids, -+ float* aXLocs, float* aYLocs) { -+ // walk through the glyph slots and check which original character -+ // each is associated with -+ uint32_t gIndex = 0; // glyph slot index -+ for (const gr_slot* slot = gr_seg_first_slot(aSegment); slot != nullptr; -+ slot = gr_slot_next_in_segment(slot), gIndex++) { -+ CHECK(gIndex < aGlyphCount, "iterating past glyphcount"); -+ uint32_t before = -+ gr_cinfo_base(gr_seg_cinfo(aSegment, gr_slot_before(slot))); -+ uint32_t after = gr_cinfo_base(gr_seg_cinfo(aSegment, gr_slot_after(slot))); -+ aGids[gIndex] = gr_slot_gid(slot); -+ aXLocs[gIndex] = gr_slot_origin_X(slot); -+ aYLocs[gIndex] = gr_slot_origin_Y(slot); -+ -+ // if this glyph has a "before" character index that precedes the -+ // current cluster's char index, we need to merge preceding -+ // aClusters until it gets included -+ while (before < aClusters[aCIndex].baseChar && aCIndex > 0) { -+ aClusters[aCIndex - 1].nChars += aClusters[aCIndex].nChars; -+ aClusters[aCIndex - 1].nGlyphs += aClusters[aCIndex].nGlyphs; -+ --aCIndex; -+ } -+ -+ // if there's a gap between the current cluster's base character and -+ // this glyph's, extend the cluster to include the intervening chars -+ if (gr_slot_can_insert_before(slot) && aClusters[aCIndex].nChars && -+ before >= aClusters[aCIndex].baseChar + aClusters[aCIndex].nChars) { -+ CHECK(aCIndex < aLength - 1, "aCIndex at end of word"); -+ Cluster& c = aClusters[aCIndex + 1]; -+ c.baseChar = aClusters[aCIndex].baseChar + aClusters[aCIndex].nChars; -+ c.nChars = before - c.baseChar; -+ c.baseGlyph = gIndex; -+ c.nGlyphs = 0; -+ ++aCIndex; -+ } -+ -+ // increment cluster's glyph count to include current slot -+ CHECK(aCIndex < aLength, "aCIndex beyond word length"); -+ ++aClusters[aCIndex].nGlyphs; -+ -+ // bump |after| index if it falls in the middle of a surrogate pair -+ if (NS_IS_HIGH_SURROGATE(aText[after]) && after < aLength - 1 && -+ NS_IS_LOW_SURROGATE(aText[after + 1])) { -+ after++; -+ } -+ -+ // extend cluster if necessary to reach the glyph's "after" index -+ if (aClusters[aCIndex].baseChar + aClusters[aCIndex].nChars < after + 1) { -+ aClusters[aCIndex].nChars = after + 1 - aClusters[aCIndex].baseChar; -+ } -+ } -+ -+ // Succeeded -+ return true; -+} -+ -+static gr_glyph_to_char_association* calloc_glyph_to_char_association( -+ uint32_t aGlyphCount, uint32_t aLength) { -+ using Type1 = gr_glyph_to_char_association; -+ using Type2 = gr_glyph_to_char_cluster; -+ using Type3 = float; -+ using Type4 = float; -+ using Type5 = uint16_t; -+ -+ // We are allocating memory in a pool. To avoid dealing with thorny alignment -+ // issues, we allocate from most to least aligned -+ static_assert( -+ alignof(Type1) >= alignof(Type2) && alignof(Type2) >= alignof(Type3) && -+ alignof(Type3) >= alignof(Type4) && alignof(Type4) >= alignof(Type5), -+ "Unexpected alignments of types"); -+ -+ const uint64_t size1 = sizeof(Type1) * static_cast<uint64_t>(1); -+ const uint64_t size2 = sizeof(Type2) * static_cast<uint64_t>(aLength); -+ const uint64_t size3 = sizeof(Type3) * static_cast<uint64_t>(aGlyphCount); -+ const uint64_t size4 = sizeof(Type4) * static_cast<uint64_t>(aGlyphCount); -+ const uint64_t size5 = sizeof(Type5) * static_cast<uint64_t>(aGlyphCount); -+ -+ uint64_t totalSize = size1 + size2 + size3 + size4 + size5; -+ -+ if (totalSize > std::numeric_limits<uint32_t>::max()) { -+ // allocation request got too large -+ return nullptr; -+ } -+ -+ char* const memoryPool = static_cast<char*>(calloc(1, totalSize)); -+ if (!memoryPool) { -+ return nullptr; -+ } -+ -+ char* currentPoolFront = memoryPool; -+ -+ auto data = reinterpret_cast<Type1*>(currentPoolFront); -+ currentPoolFront += size1; -+ data->clusters = reinterpret_cast<Type2*>(currentPoolFront); -+ currentPoolFront += size2; -+ data->xLocs = reinterpret_cast<Type3*>(currentPoolFront); -+ currentPoolFront += size3; -+ data->yLocs = reinterpret_cast<Type4*>(currentPoolFront); -+ currentPoolFront += size4; -+ data->gids = reinterpret_cast<Type5*>(currentPoolFront); -+ -+ return data; -+} -+ -+// returns nullptr on failure and the glyph to char association on success -+gr_glyph_to_char_association* gr_get_glyph_to_char_association( -+ gr_segment* aSegment, uint32_t aLength, const char16_t* aText) { -+ uint32_t glyphCount = gr_seg_n_slots(aSegment); -+ -+ gr_glyph_to_char_association* data = -+ calloc_glyph_to_char_association(glyphCount, aLength); -+ if (!data) { -+ return nullptr; -+ } -+ -+ bool succeeded = -+ LoopThrough(aSegment, aLength, glyphCount, aText, data->cIndex, -+ data->clusters, data->gids, data->xLocs, data->yLocs); -+ if (!succeeded) { -+ gr_free_char_association(data); -+ return nullptr; -+ } -+ return data; -+} -+ -+void gr_free_char_association(gr_glyph_to_char_association* aData) { -+ free(aData); -+} -+ -+#undef CHECK -+#undef NS_IS_HIGH_SURROGATE -+#undef NS_IS_LOW_SURROGATE -+#undef IS_POWER_OF_2 -diff -r f67361bfb377 -r 1b90fe16b26a gfx/graphite2/src/moz.build ---- a/gfx/graphite2/src/moz.build Wed Oct 30 11:00:40 2019 +0000 -+++ b/gfx/graphite2/src/moz.build Wed Oct 30 07:48:25 2019 +0000 -@@ -6,6 +6,7 @@ - - # This should contain all of the _PUBLIC_HEADERS from files.mk - EXPORTS.graphite2 += [ -+ '../geckoextra/include/GraphiteExtra.h', - '../include/graphite2/Font.h', - '../include/graphite2/Log.h', - '../include/graphite2/Segment.h', -@@ -23,6 +24,7 @@ - - # This should contain all of the _SOURCES from files.mk, except *_machine.cpp - UNIFIED_SOURCES += [ -+ '../geckoextra/src/GraphiteExtra.cpp', - 'CmapCache.cpp', - 'Code.cpp', - 'Collider.cpp', -diff -r f67361bfb377 -r 1b90fe16b26a gfx/thebes/gfxGraphiteShaper.cpp ---- a/gfx/thebes/gfxGraphiteShaper.cpp Wed Oct 30 11:00:40 2019 +0000 -+++ b/gfx/thebes/gfxGraphiteShaper.cpp Wed Oct 30 07:48:25 2019 +0000 -@@ -10,6 +10,7 @@ - #include "gfxTextRun.h" - - #include "graphite2/Font.h" -+#include "graphite2/GraphiteExtra.h" - #include "graphite2/Segment.h" - - #include "harfbuzz/hb.h" -@@ -191,18 +192,6 @@ - return NS_SUCCEEDED(rv); - } - --#define SMALL_GLYPH_RUN \ -- 256 // avoid heap allocation of per-glyph data arrays -- // for short (typical) runs up to this length -- --struct Cluster { -- uint32_t baseChar; // in UTF16 code units, not Unicode character indices -- uint32_t baseGlyph; -- uint32_t nChars; // UTF16 code units -- uint32_t nGlyphs; -- Cluster() : baseChar(0), baseGlyph(0), nChars(0), nGlyphs(0) {} --}; -- - nsresult gfxGraphiteShaper::SetGlyphsFromSegment( - gfxShapedText* aShapedText, uint32_t aOffset, uint32_t aLength, - const char16_t* aText, gr_segment* aSegment, RoundingFlags aRounding) { -@@ -211,70 +200,19 @@ - int32_t dev2appUnits = aShapedText->GetAppUnitsPerDevUnit(); - bool rtl = aShapedText->IsRightToLeft(); - -- uint32_t glyphCount = gr_seg_n_slots(aSegment); -+ // identify clusters; graphite may have reordered/expanded/ligated glyphs. -+ gr_glyph_to_char_association* data = -+ gr_get_glyph_to_char_association(aSegment, aLength, aText); - -- // identify clusters; graphite may have reordered/expanded/ligated glyphs. -- AutoTArray<Cluster, SMALL_GLYPH_RUN> clusters; -- AutoTArray<uint16_t, SMALL_GLYPH_RUN> gids; -- AutoTArray<float, SMALL_GLYPH_RUN> xLocs; -- AutoTArray<float, SMALL_GLYPH_RUN> yLocs; -- -- if (!clusters.SetLength(aLength, fallible) || -- !gids.SetLength(glyphCount, fallible) || -- !xLocs.SetLength(glyphCount, fallible) || -- !yLocs.SetLength(glyphCount, fallible)) { -- return NS_ERROR_OUT_OF_MEMORY; -+ if (!data) { -+ return NS_ERROR_FAILURE; - } - -- // walk through the glyph slots and check which original character -- // each is associated with -- uint32_t gIndex = 0; // glyph slot index -- uint32_t cIndex = 0; // current cluster index -- for (const gr_slot* slot = gr_seg_first_slot(aSegment); slot != nullptr; -- slot = gr_slot_next_in_segment(slot), gIndex++) { -- uint32_t before = -- gr_cinfo_base(gr_seg_cinfo(aSegment, gr_slot_before(slot))); -- uint32_t after = gr_cinfo_base(gr_seg_cinfo(aSegment, gr_slot_after(slot))); -- gids[gIndex] = gr_slot_gid(slot); -- xLocs[gIndex] = gr_slot_origin_X(slot); -- yLocs[gIndex] = gr_slot_origin_Y(slot); -- -- // if this glyph has a "before" character index that precedes the -- // current cluster's char index, we need to merge preceding -- // clusters until it gets included -- while (before < clusters[cIndex].baseChar && cIndex > 0) { -- clusters[cIndex - 1].nChars += clusters[cIndex].nChars; -- clusters[cIndex - 1].nGlyphs += clusters[cIndex].nGlyphs; -- --cIndex; -- } -- -- // if there's a gap between the current cluster's base character and -- // this glyph's, extend the cluster to include the intervening chars -- if (gr_slot_can_insert_before(slot) && clusters[cIndex].nChars && -- before >= clusters[cIndex].baseChar + clusters[cIndex].nChars) { -- NS_ASSERTION(cIndex < aLength - 1, "cIndex at end of word"); -- Cluster& c = clusters[cIndex + 1]; -- c.baseChar = clusters[cIndex].baseChar + clusters[cIndex].nChars; -- c.nChars = before - c.baseChar; -- c.baseGlyph = gIndex; -- c.nGlyphs = 0; -- ++cIndex; -- } -- -- // increment cluster's glyph count to include current slot -- NS_ASSERTION(cIndex < aLength, "cIndex beyond word length"); -- ++clusters[cIndex].nGlyphs; -- -- // bump |after| index if it falls in the middle of a surrogate pair -- if (NS_IS_HIGH_SURROGATE(aText[after]) && after < aLength - 1 && -- NS_IS_LOW_SURROGATE(aText[after + 1])) { -- after++; -- } -- // extend cluster if necessary to reach the glyph's "after" index -- if (clusters[cIndex].baseChar + clusters[cIndex].nChars < after + 1) { -- clusters[cIndex].nChars = after + 1 - clusters[cIndex].baseChar; -- } -- } -+ uint32_t cIndex = data->cIndex; -+ gr_glyph_to_char_cluster* clusters = data->clusters; -+ uint16_t* gids = data->gids; -+ float* xLocs = data->xLocs; -+ float* yLocs = data->yLocs; - - CompressedGlyph* charGlyphs = aShapedText->GetCharacterGlyphs() + aOffset; - -@@ -283,7 +221,7 @@ - - // now put glyphs into the textrun, one cluster at a time - for (uint32_t i = 0; i <= cIndex; ++i) { -- const Cluster& c = clusters[i]; -+ const gr_glyph_to_char_cluster& c = clusters[i]; - - float adv; // total advance of the cluster - if (rtl) { -@@ -350,11 +288,10 @@ - } - } - -+ gr_free_char_association(data); - return NS_OK; - } - --#undef SMALL_GLYPH_RUN -- - // for language tag validation - include list of tags from the IANA registry - #include "gfxLanguageTagList.cpp" - |