forked from mirrors/gecko-dev
Bug 1483566 - Update Graphite2 to version 1.3.12. r=jfkthame
Differential Revision: https://phabricator.services.mozilla.com/D3426 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
203aa92dca
commit
9966e32859
80 changed files with 1034 additions and 2330 deletions
18
gfx/graphite2/ChangeLog
Executable file → Normal file
18
gfx/graphite2/ChangeLog
Executable file → Normal file
|
|
@ -1,3 +1,21 @@
|
|||
1.3.12
|
||||
. Graphite no longer does dumb rendering for fonts with no smarts
|
||||
. Segment caching code removed. Anything attempting to use the segment cache gets given a regular face instead
|
||||
. Add libfuzzer support
|
||||
. Builds now require C++11
|
||||
. Improvements to Windows 64 bit builds
|
||||
. Support different versions of python including 32 bit and python 3
|
||||
. Various minor bug fixes
|
||||
|
||||
1.3.11
|
||||
. Fixes due to security review
|
||||
. Minor collision avoidance fixes
|
||||
. Fix LZ4 decompressor against high compression
|
||||
|
||||
1.3.10
|
||||
. Address floating point build parameters to give consistent positioning results across platforms
|
||||
. Various bug fixes
|
||||
|
||||
1.3.9
|
||||
. Add Collision COLL_ISSPACE to allow for visible spaces in collision avoidance
|
||||
. Add segment and pass direction information to tracing output
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
# Graphite engine
|
||||
|
||||
## Project CI status
|
||||
Linux -- Intel 64bit:[](http://build.palaso.org/viewType.html?buildTypeId=bt124&guest=1)
|
||||
Intel 32bit:[](http://build.palaso.org/viewType.html?buildTypeId=bt123&guest=1)
|
||||
ARM 32bit:[](http://build.palaso.org/viewType.html?buildTypeId=Graphite_Linux32bitArm&guest=1)
|
||||
|
||||
Windows -- Intel 64bit:[](http://build.palaso.org/viewType.html?buildTypeId=Graphite_Windows64bitProduction&guest=1)
|
||||
| OS | Intel 64 bit | Intel 32 bit | Arm 32 bit |
|
||||
|---------|:------------:|:------------:|:----------:|
|
||||
| Linux | [](http://build.palaso.org/viewType.html?buildTypeId=bt124&guest=1) | [](http://build.palaso.org/viewType.html?buildTypeId=bt123&guest=1) | [](http://build.palaso.org/viewType.html?buildTypeId=Graphite_Linux32bitArm&guest=1) |
|
||||
| Windows | [](http://build.palaso.org/viewType.html?buildTypeId=Graphite_Windows64bitProduction&guest=1) | [](http://build.palaso.org/viewType.html?buildTypeId=bt91&guest=1)| |
|
||||
|
||||
## What is Graphite?
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,3 @@
|
|||
This directory contains the Graphite2 library release 1.3.11 from
|
||||
https://github.com/silnrsi/graphite/releases/download/1.3.11/graphite2-minimal-1.3.11.tgz
|
||||
This directory contains the Graphite2 library release 1.3.12 from
|
||||
https://github.com/silnrsi/graphite/releases/download/1.3.12/graphite2-minimal-1.3.12.tgz
|
||||
See ./gfx/graphite2/moz-gr-update.sh for update procedure.
|
||||
|
||||
Note (2018-03-10):
|
||||
Cherry-picked 6e24eb7edbd0872b46441d7397e8b87cccfede73 from upstream to fix memory leak
|
||||
as noted in bug https://bugzilla.mozilla.org/show_bug.cgi?id=1443095.
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#define GR2_VERSION_MAJOR 1
|
||||
#define GR2_VERSION_MINOR 3
|
||||
#define GR2_VERSION_BUGFIX 11
|
||||
#define GR2_VERSION_BUGFIX 12
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
|
@ -56,7 +56,7 @@ GR2_API void gr_engine_version(int *nMajor, int *nMinor, int *nBugFix);
|
|||
enum gr_face_options {
|
||||
/** No preload, no cmap caching, fail if the graphite tables are invalid */
|
||||
gr_face_default = 0,
|
||||
/** Dumb rendering will be enabled if the graphite tables are invalid */
|
||||
/** Dumb rendering will be enabled if the graphite tables are invalid. @deprecated Since 1.311 */
|
||||
gr_face_dumbRendering = 1,
|
||||
/** preload glyphs at construction time */
|
||||
gr_face_preloadGlyphs = 2,
|
||||
|
|
@ -130,8 +130,8 @@ typedef struct gr_face_ops gr_face_ops;
|
|||
*/
|
||||
GR2_API gr_face* gr_make_face_with_ops(const void* appFaceHandle/*non-NULL*/, const gr_face_ops *face_ops, unsigned int faceOptions);
|
||||
|
||||
/** Create a gr_face object given application information and a getTable function. This function is deprecated as of v1.2.0 in
|
||||
* favour of gr_make_face_with_ops.
|
||||
/** @deprecated Since v1.2.0 in favour of gr_make_face_with_ops.
|
||||
* Create a gr_face object given application information and a getTable function.
|
||||
*
|
||||
* @return gr_face or NULL if the font fails to load for some reason.
|
||||
* @param appFaceHandle This is application specific information that is passed
|
||||
|
|
@ -140,22 +140,25 @@ GR2_API gr_face* gr_make_face_with_ops(const void* appFaceHandle/*non-NULL*/, co
|
|||
* @param getTable Callback function to get table data.
|
||||
* @param faceOptions Bitfield describing various options. See enum gr_face_options for details.
|
||||
*/
|
||||
GR2_API gr_face* gr_make_face(const void* appFaceHandle/*non-NULL*/, gr_get_table_fn getTable, unsigned int faceOptions);
|
||||
GR2_DEPRECATED_API gr_face* gr_make_face(const void* appFaceHandle/*non-NULL*/, gr_get_table_fn getTable, unsigned int faceOptions);
|
||||
|
||||
//#ifndef GRAPHITE2_NSEGCACHE
|
||||
/** Create a gr_face object given application information, with subsegmental caching support
|
||||
/** @deprecated Since 1.3.7 this function is now an alias for gr_make_face_with_ops().
|
||||
*
|
||||
* Create a gr_face object given application information, with subsegmental caching support
|
||||
*
|
||||
* @return gr_face or NULL if the font fails to load.
|
||||
* @param appFaceHandle is a pointer to application specific information that is passed to getTable.
|
||||
* This may not be NULL and must stay alive as long as the gr_face is alive.
|
||||
* @param face_ops Pointer to face specific callback structure for table management. Must stay
|
||||
* alive for the duration of the call only.
|
||||
* @param segCacheMaxSize How large the segment cache is.
|
||||
* @param segCacheMaxSize Unused.
|
||||
* @param faceOptions Bitfield of values from enum gr_face_options
|
||||
*/
|
||||
GR2_API gr_face* gr_make_face_with_seg_cache_and_ops(const void* appFaceHandle, const gr_face_ops *face_ops, unsigned int segCacheMaxSize, unsigned int faceOptions);
|
||||
GR2_DEPRECATED_API gr_face* gr_make_face_with_seg_cache_and_ops(const void* appFaceHandle, const gr_face_ops *face_ops, unsigned int segCacheMaxSize, unsigned int faceOptions);
|
||||
|
||||
/** Create a gr_face object given application information, with subsegmental caching support.
|
||||
/** @deprecated Since 1.3.7 this function is now an alias for gr_make_face().
|
||||
*
|
||||
* Create a gr_face object given application information, with subsegmental caching support.
|
||||
* This function is deprecated as of v1.2.0 in favour of gr_make_face_with_seg_cache_and_ops.
|
||||
*
|
||||
* @return gr_face or NULL if the font fails to load.
|
||||
|
|
@ -165,8 +168,7 @@ GR2_API gr_face* gr_make_face_with_seg_cache_and_ops(const void* appFaceHandle,
|
|||
* @param segCacheMaxSize How large the segment cache is.
|
||||
* @param faceOptions Bitfield of values from enum gr_face_options
|
||||
*/
|
||||
GR2_API gr_face* gr_make_face_with_seg_cache(const void* appFaceHandle, gr_get_table_fn getTable, unsigned int segCacheMaxSize, unsigned int faceOptions);
|
||||
//#endif
|
||||
GR2_DEPRECATED_API gr_face* gr_make_face_with_seg_cache(const void* appFaceHandle, gr_get_table_fn getTable, unsigned int segCacheMaxSize, unsigned int faceOptions);
|
||||
|
||||
/** Convert a tag in a string into a gr_uint32
|
||||
*
|
||||
|
|
@ -243,16 +245,16 @@ GR2_API int gr_face_is_char_supported(const gr_face *pFace, gr_uint32 usv, gr_ui
|
|||
*/
|
||||
GR2_API gr_face* gr_make_file_face(const char *filename, unsigned int faceOptions);
|
||||
|
||||
//#ifndef GRAPHITE2_NSEGCACHE
|
||||
/** Create gr_face from a font file, with subsegment caching support.
|
||||
/** @deprecated Since 1.3.7. This function is now an alias for gr_make_file_face().
|
||||
*
|
||||
* Create gr_face from a font file, with subsegment caching support.
|
||||
*
|
||||
* @return gr_face that accesses a font file directly. Returns NULL on failure.
|
||||
* @param filename Full path and filename to font file
|
||||
* @param segCacheMaxSize Specifies how big to make the cache in segments.
|
||||
* @param faceOptions Bitfield from enum gr_face_options to control face options.
|
||||
*/
|
||||
GR2_API gr_face* gr_make_file_face_with_seg_cache(const char *filename, unsigned int segCacheMaxSize, unsigned int faceOptions);
|
||||
//#endif
|
||||
GR2_DEPRECATED_API gr_face* gr_make_file_face_with_seg_cache(const char *filename, unsigned int segCacheMaxSize, unsigned int faceOptions);
|
||||
#endif // !GRAPHITE2_NFILEFACE
|
||||
|
||||
/** Create a font from a face
|
||||
|
|
@ -385,4 +387,3 @@ GR2_API void gr_featureval_destroy(gr_feature_val *pfeatures);
|
|||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -40,33 +40,40 @@ enum gr_encform {
|
|||
gr_utf8 = 1/*sizeof(uint8)*/, gr_utf16 = 2/*sizeof(uint16)*/, gr_utf32 = 4/*sizeof(uint32)*/
|
||||
};
|
||||
|
||||
// Definitions for library publicly exported symbols
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
#if defined GRAPHITE2_STATIC
|
||||
#define GR2_API
|
||||
#elif defined GRAPHITE2_EXPORTING
|
||||
#if defined __GNUC__
|
||||
#define GR2_API __attribute__((dllexport))
|
||||
#else
|
||||
#define GR2_API __declspec(dllexport)
|
||||
#endif
|
||||
#else
|
||||
#if defined __GNUC__
|
||||
#define GR2_API __attribute__((dllimport))
|
||||
#else
|
||||
#define GR2_API __declspec(dllimport)
|
||||
#endif
|
||||
#endif
|
||||
#define GR2_LOCAL
|
||||
#elif __GNUC__ >= 4
|
||||
#if defined GRAPHITE2_STATIC
|
||||
#define GR2_API __attribute__ ((visibility("hidden")))
|
||||
#else
|
||||
#define GR2_API __attribute__ ((visibility("default")))
|
||||
#endif
|
||||
#define GR2_LOCAL __attribute__ ((visibility("hidden")))
|
||||
#else
|
||||
#define GR2_API
|
||||
#define GR2_LOCAL
|
||||
|
||||
// Define API function declspec/attributes and how each supported compiler or OS
|
||||
// allows us to specify them.
|
||||
#if defined __GNUC__
|
||||
#define _gr2_and ,
|
||||
#define _gr2_tag_fn(a) __attribute__((a))
|
||||
#define _gr2_deprecated_flag deprecated
|
||||
#define _gr2_export_flag visibility("default")
|
||||
#define _gr2_import_flag visibility("default")
|
||||
#define _gr2_static_flag visibility("hidden")
|
||||
#endif
|
||||
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
#if defined __GNUC__ // These three will be redefined for Windows
|
||||
#undef _gr2_export_flag
|
||||
#undef _gr2_import_flag
|
||||
#undef _gr2_static_flag
|
||||
#else // How MSVC sepcifies function level attributes adn deprecation
|
||||
#define _gr2_and
|
||||
#define _gr2_tag_fn(a) __declspec(a)
|
||||
#define _gr2_deprecated_flag deprecated
|
||||
#endif
|
||||
#define _gr2_export_flag dllexport
|
||||
#define _gr2_import_flag dllimport
|
||||
#define _gr2_static_flag
|
||||
#endif
|
||||
|
||||
#if defined GRAPHITE2_STATIC
|
||||
#define GR2_API _gr2_tag_fn(_gr2_static_flag)
|
||||
#define GR2_DEPRECATED_API _gr2_tag_fn(_gr2_deprecated_flag _gr2_and _gr2_static_flag)
|
||||
#elif defined GRAPHITE2_EXPORTING
|
||||
#define GR2_API _gr2_tag_fn(_gr2_export_flag)
|
||||
#define GR2_DEPRECATED_API _gr2_tag_fn(_gr2_deprecated_flag _gr2_and _gr2_export_flag)
|
||||
#else
|
||||
#define GR2_API _gr2_tag_fn(_gr2_import_flag)
|
||||
#define GR2_DEPRECATED_API _gr2_tag_fn(_gr2_deprecated_flag _gr2_and _gr2_import_flag)
|
||||
#endif
|
||||
|
|
|
|||
2
gfx/graphite2/moz-gr-update.sh
Normal file → Executable file
2
gfx/graphite2/moz-gr-update.sh
Normal file → Executable file
|
|
@ -22,7 +22,7 @@ fi
|
|||
TARBALL="https://github.com/silnrsi/graphite/releases/download/$RELEASE/graphite2-minimal-$RELEASE.tgz"
|
||||
|
||||
foo=`basename $0`
|
||||
TMPFILE=`mktemp -t ${foo}` || exit 1
|
||||
TMPFILE=`mktemp -t ${foo}.XXX` || exit 1
|
||||
|
||||
curl -L "$TARBALL" -o "$TMPFILE"
|
||||
tar -x -z -C gfx/graphite2/ --strip-components 1 -f "$TMPFILE" || exit 1
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ cmake_policy(SET CMP0012 NEW)
|
|||
INCLUDE(CheckCXXSourceCompiles)
|
||||
|
||||
set(GRAPHITE_API_CURRENT 3)
|
||||
set(GRAPHITE_API_REVISION 0)
|
||||
set(GRAPHITE_API_REVISION 2)
|
||||
set(GRAPHITE_API_AGE 1)
|
||||
set(GRAPHITE_VERSION ${GRAPHITE_API_CURRENT}.${GRAPHITE_API_REVISION}.${GRAPHITE_API_AGE})
|
||||
set(GRAPHITE_SO_VERSION ${GRAPHITE_API_CURRENT})
|
||||
|
|
@ -34,12 +34,6 @@ include(TestBigEndian)
|
|||
|
||||
include_directories(${PROJECT_SOURCE_DIR})
|
||||
|
||||
set(SEGCACHE SegCache.cpp SegCacheEntry.cpp SegCacheStore.cpp)
|
||||
if (GRAPHITE2_NSEGCACHE)
|
||||
add_definitions(-DGRAPHITE2_NSEGCACHE)
|
||||
set(SEGCACHE)
|
||||
endif (GRAPHITE2_NSEGCACHE)
|
||||
|
||||
set(FILEFACE FileFace.cpp)
|
||||
if (GRAPHITE2_NFILEFACE)
|
||||
add_definitions(-DGRAPHITE2_NFILEFACE)
|
||||
|
|
@ -78,7 +72,6 @@ add_library(graphite2
|
|||
gr_logging.cpp
|
||||
gr_segment.cpp
|
||||
gr_slot.cpp
|
||||
CachedFace.cpp
|
||||
CmapCache.cpp
|
||||
Code.cpp
|
||||
Collider.cpp
|
||||
|
|
@ -100,7 +93,6 @@ add_library(graphite2
|
|||
TtfUtil.cpp
|
||||
UtfCodec.cpp
|
||||
${FILEFACE}
|
||||
${SEGCACHE}
|
||||
${TRACING})
|
||||
|
||||
set_target_properties(graphite2 PROPERTIES PUBLIC_HEADER "${GRAPHITE_HEADERS}"
|
||||
|
|
@ -123,21 +115,21 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
|||
endif (CMAKE_COMPILER_IS_GNUCXX)
|
||||
message(STATUS "Compiler ID is: ${CMAKE_CXX_COMPILER_ID}")
|
||||
if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
|
||||
add_definitions(-Wimplicit-fallthrough)
|
||||
add_definitions(-Wimplicit-fallthrough -Wshorten-64-to-32)
|
||||
endif (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
|
||||
if (${CMAKE_CXX_COMPILER} MATCHES ".*mingw.*")
|
||||
target_link_libraries(graphite2 kernel32 msvcr90 mingw32 gcc user32)
|
||||
else (${CMAKE_CXX_COMPILER} MATCHES ".*mingw.*")
|
||||
if (GRAPHITE2_ASAN)
|
||||
if (GRAPHITE2_SANITIZERS)
|
||||
target_link_libraries(graphite2 c gcc_s)
|
||||
else (GRAPHITE2_ASAN)
|
||||
else ()
|
||||
target_link_libraries(graphite2 c gcc)
|
||||
endif (GRAPHITE2_ASAN)
|
||||
endif ()
|
||||
endif (${CMAKE_CXX_COMPILER} MATCHES ".*mingw.*")
|
||||
include(Graphite)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
nolib_test(stdc++ $<TARGET_SONAME_FILE:graphite2>)
|
||||
endif (BUILD_SHARED_LIBS)
|
||||
endif (${CMAKE_CXX_COMPILER} MATCHES ".*mingw.*")
|
||||
endif ()
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
|
||||
CREATE_LIBTOOL_FILE(graphite2 "/lib${LIB_SUFFIX}")
|
||||
endif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
|
|
|
|||
|
|
@ -1,127 +0,0 @@
|
|||
/* GRAPHITE2 LICENSING
|
||||
|
||||
Copyright 2010, SIL International
|
||||
All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should also have received a copy of the GNU Lesser General Public
|
||||
License along with this library in the file named "LICENSE".
|
||||
If not, write to the Free Software Foundation, 51 Franklin Street,
|
||||
Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
|
||||
internet at http://www.fsf.org/licenses/lgpl.html.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of the
|
||||
Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
|
||||
License, as published by the Free Software Foundation, either version 2
|
||||
of the License or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef GRAPHITE2_NSEGCACHE
|
||||
|
||||
#include <graphite2/Segment.h>
|
||||
#include "inc/CachedFace.h"
|
||||
#include "inc/SegCacheStore.h"
|
||||
|
||||
|
||||
using namespace graphite2;
|
||||
|
||||
CachedFace::CachedFace(const void* appFaceHandle/*non-NULL*/, const gr_face_ops & ops)
|
||||
: Face(appFaceHandle, ops), m_cacheStore(0)
|
||||
{
|
||||
}
|
||||
|
||||
CachedFace::~CachedFace()
|
||||
{
|
||||
delete m_cacheStore;
|
||||
}
|
||||
|
||||
bool CachedFace::setupCache(unsigned int cacheSize)
|
||||
{
|
||||
m_cacheStore = new SegCacheStore(*this, m_numSilf, cacheSize);
|
||||
return bool(m_cacheStore);
|
||||
}
|
||||
|
||||
|
||||
bool CachedFace::runGraphite(Segment *seg, const Silf *pSilf) const
|
||||
{
|
||||
assert(pSilf);
|
||||
pSilf->runGraphite(seg, 0, pSilf->substitutionPass());
|
||||
|
||||
unsigned int silfIndex = 0;
|
||||
for (; silfIndex < m_numSilf && &(m_silfs[silfIndex]) != pSilf; ++silfIndex);
|
||||
if (silfIndex == m_numSilf) return false;
|
||||
SegCache * const segCache = m_cacheStore->getOrCreate(silfIndex, seg->getFeatures(0));
|
||||
if (!segCache)
|
||||
return false;
|
||||
|
||||
assert(m_cacheStore);
|
||||
// find where the segment can be broken
|
||||
Slot * subSegStartSlot = seg->first();
|
||||
Slot * subSegEndSlot = subSegStartSlot;
|
||||
uint16 cmapGlyphs[eMaxSpliceSize];
|
||||
int subSegStart = 0;
|
||||
for (unsigned int i = 0; i < seg->charInfoCount() && subSegEndSlot; ++i)
|
||||
{
|
||||
const unsigned int length = i - subSegStart + 1;
|
||||
if (length < eMaxSpliceSize && subSegEndSlot->gid() < m_cacheStore->maxCmapGid())
|
||||
cmapGlyphs[length-1] = subSegEndSlot->gid();
|
||||
else return false;
|
||||
const bool spaceOnly = m_cacheStore->isSpaceGlyph(subSegEndSlot->gid());
|
||||
// at this stage the character to slot mapping is still 1 to 1
|
||||
const int breakWeight = seg->charinfo(i)->breakWeight(),
|
||||
nextBreakWeight = (i + 1 < seg->charInfoCount())?
|
||||
seg->charinfo(i+1)->breakWeight() : 0;
|
||||
const uint8 f = seg->charinfo(i)->flags();
|
||||
if (((spaceOnly
|
||||
|| (breakWeight > 0 && breakWeight <= gr_breakWord)
|
||||
|| i + 1 == seg->charInfoCount()
|
||||
|| ((nextBreakWeight < 0 && nextBreakWeight >= gr_breakBeforeWord)
|
||||
|| (subSegEndSlot->next() && m_cacheStore->isSpaceGlyph(subSegEndSlot->next()->gid()))))
|
||||
&& f != 1)
|
||||
|| f == 2)
|
||||
{
|
||||
// record the next slot before any splicing
|
||||
Slot * nextSlot = subSegEndSlot->next();
|
||||
// spaces should be left untouched by graphite rules in any sane font
|
||||
if (!spaceOnly)
|
||||
{
|
||||
// found a break position, check for a cache of the sub sequence
|
||||
const SegCacheEntry * entry = segCache->find(cmapGlyphs, length);
|
||||
// TODO disable cache for words at start/end of line with contextuals
|
||||
if (!entry)
|
||||
{
|
||||
SegmentScopeState scopeState = seg->setScope(subSegStartSlot, subSegEndSlot, length);
|
||||
pSilf->runGraphite(seg, pSilf->substitutionPass(), pSilf->numPasses());
|
||||
if (length < eMaxSpliceSize)
|
||||
{
|
||||
seg->associateChars(subSegStart, length);
|
||||
segCache->cache(m_cacheStore, cmapGlyphs, length, seg, subSegStart);
|
||||
}
|
||||
seg->removeScope(scopeState);
|
||||
}
|
||||
else
|
||||
seg->splice(subSegStart, length, subSegStartSlot, subSegEndSlot,
|
||||
entry->first(), entry->glyphLength());
|
||||
}
|
||||
subSegStartSlot = subSegEndSlot = nextSlot;
|
||||
subSegStart = i + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
subSegEndSlot = subSegEndSlot->next();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -275,7 +275,7 @@ opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
|
|||
// Do some basic sanity checks based on what we know about the opcode
|
||||
if (!validate_opcode(opc, bc)) return MAX_OPCODE;
|
||||
|
||||
// And check it's arguments as far as possible
|
||||
// And check its arguments as far as possible
|
||||
switch (opcode(opc))
|
||||
{
|
||||
case NOP :
|
||||
|
|
@ -509,7 +509,7 @@ void Machine::Code::decoder::analyse_opcode(const opcode opc, const int8 * arg)
|
|||
case NEXT :
|
||||
case COPY_NEXT :
|
||||
++_slotref;
|
||||
_contexts[_slotref] = context(_code._instr_count+1);
|
||||
_contexts[_slotref] = context(uint8(_code._instr_count+1));
|
||||
// if (_analysis.slotref > _analysis.max_ref) _analysis.max_ref = _analysis.slotref;
|
||||
break;
|
||||
case INSERT :
|
||||
|
|
@ -589,8 +589,8 @@ bool Machine::Code::decoder::emit_opcode(opcode opc, const byte * & bc)
|
|||
if (load(bc, bc + instr_skip))
|
||||
{
|
||||
bc += instr_skip;
|
||||
data_skip = instr_skip - (_code._instr_count - ctxt_start);
|
||||
instr_skip = _code._instr_count - ctxt_start;
|
||||
data_skip = instr_skip - byte(_code._instr_count - ctxt_start);
|
||||
instr_skip = byte(_code._instr_count - ctxt_start);
|
||||
_max.bytecode = curr_end;
|
||||
|
||||
_out_length = 1;
|
||||
|
|
@ -750,4 +750,3 @@ int32 Machine::Code::run(Machine & m, slotref * & map) const
|
|||
|
||||
return m.run(_code, _data, map);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -877,7 +877,7 @@ bool KernCollider::initSlot(Segment *seg, Slot *aSlot, const Rect &limit, float
|
|||
}
|
||||
goto done;
|
||||
}
|
||||
numSlices = _edges.size();
|
||||
numSlices = int(_edges.size());
|
||||
|
||||
#if !defined GRAPHITE2_NTRACING
|
||||
// Debugging
|
||||
|
|
|
|||
|
|
@ -121,6 +121,5 @@ int lz4::decompress(void const *in, size_t in_size, void *out, size_t out_size)
|
|||
return -1;
|
||||
dst = fast_copy(dst, literal, literal_len);
|
||||
|
||||
return dst - (u8*)out;
|
||||
return int(dst - (u8*)out);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ of the License or (at your option) any later version.
|
|||
#include "inc/FileFace.h"
|
||||
#include "inc/GlyphFace.h"
|
||||
#include "inc/json.h"
|
||||
#include "inc/SegCacheStore.h"
|
||||
#include "inc/Segment.h"
|
||||
#include "inc/NameTable.h"
|
||||
#include "inc/Error.h"
|
||||
|
|
@ -142,7 +141,7 @@ bool Face::readGraphite(const Table & silf)
|
|||
{
|
||||
error_context(EC_ASILF + (i << 8));
|
||||
const uint32 offset = be::read<uint32>(p),
|
||||
next = i == m_numSilf - 1 ? silf.size() : be::peek<uint32>(p);
|
||||
next = i == m_numSilf - 1 ? uint32(silf.size()) : be::peek<uint32>(p);
|
||||
if (e.test(next > silf.size() || offset >= next, E_BADSIZE))
|
||||
return error(e);
|
||||
|
||||
|
|
@ -201,7 +200,7 @@ bool Face::runGraphite(Segment *seg, const Silf *aSilf) const
|
|||
<< "advance" << seg->advance()
|
||||
<< "chars" << json::array;
|
||||
for(size_t i = 0, n = seg->charInfoCount(); i != n; ++i)
|
||||
*dbgout << json::flat << *seg->charinfo(i);
|
||||
*dbgout << json::flat << *seg->charinfo(int(i));
|
||||
*dbgout << json::close // Close up the chars array
|
||||
<< json::close; // Close up the segment object
|
||||
}
|
||||
|
|
@ -276,15 +275,13 @@ uint16 Face::languageForLocale(const char * locale) const
|
|||
|
||||
|
||||
Face::Table::Table(const Face & face, const Tag n, uint32 version) throw()
|
||||
: _f(&face), _compressed(false)
|
||||
: _f(&face), _sz(0), _compressed(false)
|
||||
{
|
||||
size_t sz = 0;
|
||||
_p = static_cast<const byte *>((*_f->m_ops.get_table)(_f->m_appFaceHandle, n, &sz));
|
||||
_sz = uint32(sz);
|
||||
_p = static_cast<const byte *>((*_f->m_ops.get_table)(_f->m_appFaceHandle, n, &_sz));
|
||||
|
||||
if (!TtfUtil::CheckTable(n, _p, _sz))
|
||||
{
|
||||
releaseBuffers(); // Make sure we release the table buffer even if the table failed it's checks
|
||||
release(); // Make sure we release the table buffer even if the table failed its checks
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -292,7 +289,7 @@ Face::Table::Table(const Face & face, const Tag n, uint32 version) throw()
|
|||
decompress();
|
||||
}
|
||||
|
||||
void Face::Table::releaseBuffers()
|
||||
void Face::Table::release()
|
||||
{
|
||||
if (_compressed)
|
||||
free(const_cast<byte *>(_p));
|
||||
|
|
@ -301,12 +298,11 @@ void Face::Table::releaseBuffers()
|
|||
_p = 0; _sz = 0;
|
||||
}
|
||||
|
||||
Face::Table & Face::Table::operator = (const Table & rhs) throw()
|
||||
Face::Table & Face::Table::operator = (const Table && rhs) throw()
|
||||
{
|
||||
if (_p == rhs._p) return *this;
|
||||
|
||||
this->~Table();
|
||||
new (this) Table(rhs);
|
||||
if (this == &rhs) return *this;
|
||||
release();
|
||||
new (this) Table(std::move(rhs));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -353,7 +349,7 @@ Error Face::Table::decompress()
|
|||
|
||||
// Tell the provider to release the compressed form since were replacing
|
||||
// it anyway.
|
||||
releaseBuffers();
|
||||
release();
|
||||
|
||||
if (e)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ FileFace::FileFace(const char *filename)
|
|||
|
||||
// Get the header.
|
||||
if (!TtfUtil::GetHeaderInfo(tbl_offset, tbl_len)) return;
|
||||
if (fseek(_file, tbl_offset, SEEK_SET)) return;
|
||||
if (fseek(_file, long(tbl_offset), SEEK_SET)) return;
|
||||
_header_tbl = (TtfUtil::Sfnt::OffsetSubTable*)gralloc<char>(tbl_len);
|
||||
if (_header_tbl)
|
||||
{
|
||||
|
|
@ -59,7 +59,7 @@ FileFace::FileFace(const char *filename)
|
|||
// Get the table directory
|
||||
if (!TtfUtil::GetTableDirInfo(_header_tbl, tbl_offset, tbl_len)) return;
|
||||
_table_dir = (TtfUtil::Sfnt::OffsetSubTable::Entry*)gralloc<char>(tbl_len);
|
||||
if (fseek(_file, tbl_offset, SEEK_SET)) return;
|
||||
if (fseek(_file, long(tbl_offset), SEEK_SET)) return;
|
||||
if (_table_dir && fread(_table_dir, 1, tbl_len, _file) != tbl_len)
|
||||
{
|
||||
free(_table_dir);
|
||||
|
|
@ -88,7 +88,7 @@ const void *FileFace::get_table_fn(const void* appFaceHandle, unsigned int name,
|
|||
return 0;
|
||||
|
||||
if (tbl_offset > file_face._file_len || tbl_len > file_face._file_len - tbl_offset
|
||||
|| fseek(file_face._file, tbl_offset, SEEK_SET) != 0)
|
||||
|| fseek(file_face._file, long(tbl_offset), SEEK_SET) != 0)
|
||||
return 0;
|
||||
|
||||
tbl = malloc(tbl_len);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,3 @@ Font::Font(float ppm, const Face & f, const void * appFontHandle, const gr_font_
|
|||
{
|
||||
free(m_advances);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace
|
|||
template<typename W>
|
||||
class _glat_iterator : public std::iterator<std::input_iterator_tag, std::pair<sparse::key_type, sparse::mapped_type> >
|
||||
{
|
||||
unsigned short key() const { return be::peek<W>(_e) + _n; }
|
||||
unsigned short key() const { return uint16(be::peek<W>(_e) + _n); }
|
||||
unsigned int run() const { return be::peek<W>(_e+sizeof(W)); }
|
||||
void advance_entry() { _n = 0; _e = _v; be::skip<W>(_v,2); }
|
||||
public:
|
||||
|
|
@ -84,7 +84,7 @@ const SlantBox SlantBox::empty = {0,0,0,0};
|
|||
class GlyphCache::Loader
|
||||
{
|
||||
public:
|
||||
Loader(const Face & face, const bool dumb_font); //return result indicates success. Do not use if failed.
|
||||
Loader(const Face & face); //return result indicates success. Do not use if failed.
|
||||
|
||||
operator bool () const throw();
|
||||
unsigned short int units_per_em() const throw();
|
||||
|
|
@ -115,7 +115,7 @@ private:
|
|||
|
||||
|
||||
GlyphCache::GlyphCache(const Face & face, const uint32 face_options)
|
||||
: _glyph_loader(new Loader(face, bool(face_options & gr_face_dumbRendering))),
|
||||
: _glyph_loader(new Loader(face)),
|
||||
_glyphs(_glyph_loader && *_glyph_loader && _glyph_loader->num_glyphs()
|
||||
? grzeroalloc<const GlyphFace *>(_glyph_loader->num_glyphs()) : 0),
|
||||
_boxes(_glyph_loader && _glyph_loader->has_boxes() && _glyph_loader->num_glyphs()
|
||||
|
|
@ -239,7 +239,7 @@ const GlyphFace *GlyphCache::glyph(unsigned short glyphid) const //result m
|
|||
|
||||
|
||||
|
||||
GlyphCache::Loader::Loader(const Face & face, const bool dumb_font)
|
||||
GlyphCache::Loader::Loader(const Face & face)
|
||||
: _head(face, Tag::head),
|
||||
_hhea(face, Tag::hhea),
|
||||
_hmtx(face, Tag::hmtx),
|
||||
|
|
@ -257,7 +257,7 @@ GlyphCache::Loader::Loader(const Face & face, const bool dumb_font)
|
|||
const Face::Table maxp = Face::Table(face, Tag::maxp);
|
||||
if (!maxp) { _head = Face::Table(); return; }
|
||||
|
||||
_num_glyphs_graphics = TtfUtil::GlyphCount(maxp);
|
||||
_num_glyphs_graphics = static_cast<unsigned short>(TtfUtil::GlyphCount(maxp));
|
||||
// This will fail if the number of glyphs is wildly out of range.
|
||||
if (_glyf && TtfUtil::LocaLookup(_num_glyphs_graphics-1, _loca, _loca.size(), _head) == size_t(-2))
|
||||
{
|
||||
|
|
@ -265,8 +265,6 @@ GlyphCache::Loader::Loader(const Face & face, const bool dumb_font)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!dumb_font)
|
||||
{
|
||||
if ((m_pGlat = Face::Table(face, Tag::Glat, 0x00030000)) == NULL
|
||||
|| (m_pGloc = Face::Table(face, Tag::Gloc)) == NULL
|
||||
|| m_pGloc.size() < 8)
|
||||
|
|
@ -282,7 +280,7 @@ GlyphCache::Loader::Loader(const Face & face, const bool dumb_font)
|
|||
// subtracting the length of the attribids array (numAttribs long if present)
|
||||
// and dividing by either 2 or 4 depending on shor or lonf format
|
||||
_long_fmt = flags & 1;
|
||||
int tmpnumgattrs = (m_pGloc.size()
|
||||
ptrdiff_t tmpnumgattrs = (m_pGloc.size()
|
||||
- (p - m_pGloc)
|
||||
- sizeof(uint16)*(flags & 0x2 ? _num_attrs : 0))
|
||||
/ (_long_fmt ? sizeof(uint32) : sizeof(uint16)) - 1;
|
||||
|
|
@ -311,7 +309,6 @@ GlyphCache::Loader::Loader(const Face & face, const bool dumb_font)
|
|||
// delete this once the compiler is fixed
|
||||
_has_boxes = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
|
|
@ -489,4 +486,3 @@ GlyphBox * GlyphCache::Loader::read_box(uint16 gid, GlyphBox *curr, const GlyphF
|
|||
}
|
||||
return (GlyphBox *)((char *)(curr) + sizeof(GlyphBox) + 2 * num * sizeof(Rect));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,16 +33,16 @@ int32 GlyphFace::getMetric(uint8 metric) const
|
|||
{
|
||||
switch (metrics(metric))
|
||||
{
|
||||
case kgmetLsb : return m_bbox.bl.x;
|
||||
case kgmetRsb : return m_advance.x - m_bbox.tr.x;
|
||||
case kgmetBbTop : return m_bbox.tr.y;
|
||||
case kgmetBbBottom : return m_bbox.bl.y;
|
||||
case kgmetBbLeft : return m_bbox.bl.x;
|
||||
case kgmetBbRight : return m_bbox.tr.x;
|
||||
case kgmetBbHeight : return m_bbox.tr.y - m_bbox.bl.y;
|
||||
case kgmetBbWidth : return m_bbox.tr.x - m_bbox.bl.x;
|
||||
case kgmetAdvWidth : return m_advance.x;
|
||||
case kgmetAdvHeight : return m_advance.y;
|
||||
case kgmetLsb : return int32(m_bbox.bl.x);
|
||||
case kgmetRsb : return int32(m_advance.x - m_bbox.tr.x);
|
||||
case kgmetBbTop : return int32(m_bbox.tr.y);
|
||||
case kgmetBbBottom : return int32(m_bbox.bl.y);
|
||||
case kgmetBbLeft : return int32(m_bbox.bl.x);
|
||||
case kgmetBbRight : return int32(m_bbox.tr.x);
|
||||
case kgmetBbHeight : return int32(m_bbox.tr.y - m_bbox.bl.y);
|
||||
case kgmetBbWidth : return int32(m_bbox.tr.x - m_bbox.bl.x);
|
||||
case kgmetAdvWidth : return int32(m_advance.x);
|
||||
case kgmetAdvHeight : return int32(m_advance.y);
|
||||
default : return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,11 +183,11 @@ void Zones::remove(float x, float xm)
|
|||
|
||||
Zones::const_iterator Zones::find_exclusion_under(float x) const
|
||||
{
|
||||
int l = 0, h = _exclusions.size();
|
||||
size_t l = 0, h = _exclusions.size();
|
||||
|
||||
while (l < h)
|
||||
{
|
||||
int const p = (l+h) >> 1;
|
||||
size_t const p = (l+h) >> 1;
|
||||
switch (_exclusions[p].outcode(x))
|
||||
{
|
||||
case 0 : return _exclusions.begin()+p;
|
||||
|
|
@ -296,4 +296,3 @@ void Zones::jsonDbgOut(Segment *seg) const {
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ void JustifyTotal::accumulate(Slot *s, Segment *seg, int level)
|
|||
|
||||
float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUSED justFlags jflags, Slot *pFirst, Slot *pLast)
|
||||
{
|
||||
Slot *s, *end;
|
||||
Slot *end = last();
|
||||
float currWidth = 0.0;
|
||||
const float scale = font ? font->scale() : 1.0f;
|
||||
Position res;
|
||||
|
|
@ -73,9 +73,7 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
|
|||
if ((m_dir & 1) != m_silf->dir() && m_silf->bidiPass() != m_silf->numPasses())
|
||||
{
|
||||
reverseSlots();
|
||||
s = pFirst;
|
||||
pFirst = pLast;
|
||||
pLast = s;
|
||||
std::swap(pFirst, pLast);
|
||||
}
|
||||
if (!pFirst) pFirst = pSlot;
|
||||
while (!pFirst->isBase()) pFirst = pFirst->attachedTo();
|
||||
|
|
@ -85,22 +83,25 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
|
|||
width = width / scale;
|
||||
if ((jflags & gr_justEndInline) == 0)
|
||||
{
|
||||
do {
|
||||
while (pLast != pFirst && pLast)
|
||||
{
|
||||
Rect bbox = theGlyphBBoxTemporary(pLast->glyph());
|
||||
if (bbox.bl.x != 0.f || bbox.bl.y != 0.f || bbox.tr.x != 0.f || bbox.tr.y == 0.f)
|
||||
break;
|
||||
pLast = pLast->prev();
|
||||
} while (pLast != pFirst);
|
||||
}
|
||||
}
|
||||
|
||||
if (pLast)
|
||||
end = pLast->nextSibling();
|
||||
if (pFirst)
|
||||
pFirst = pFirst->nextSibling();
|
||||
|
||||
int icount = 0;
|
||||
int numLevels = silf()->numJustLevels();
|
||||
if (!numLevels)
|
||||
{
|
||||
for (s = pSlot; s && s != end; s = s->nextSibling())
|
||||
for (Slot *s = pSlot; s && s != end; s = s->nextSibling())
|
||||
{
|
||||
CharInfo *c = charinfo(s->before());
|
||||
if (isWhitespace(c->unicodeChar()))
|
||||
|
|
@ -113,7 +114,7 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
|
|||
}
|
||||
if (!icount)
|
||||
{
|
||||
for (s = pSlot; s && s != end; s = s->nextSibling())
|
||||
for (Slot *s = pSlot; s && s != end; s = s->nextSibling())
|
||||
{
|
||||
s->setJustify(this, 0, 3, 1);
|
||||
s->setJustify(this, 0, 2, 1);
|
||||
|
|
@ -124,7 +125,7 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
|
|||
}
|
||||
|
||||
Vector<JustifyTotal> stats(numLevels);
|
||||
for (s = pFirst; s && s != end; s = s->nextSibling())
|
||||
for (Slot *s = pFirst; s && s != end; s = s->nextSibling())
|
||||
{
|
||||
float w = s->origin().x / scale + s->advance() - base;
|
||||
if (w > currWidth) currWidth = w;
|
||||
|
|
@ -146,7 +147,7 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
|
|||
diff = width - currWidth;
|
||||
diffpw = diff / tWeight;
|
||||
tWeight = 0;
|
||||
for (s = pFirst; s && s != end; s = s->nextSibling()) // don't include final glyph
|
||||
for (Slot *s = pFirst; s && s != end; s = s->nextSibling()) // don't include final glyph
|
||||
{
|
||||
int w = s->getJustify(this, i, 3);
|
||||
float pref = diffpw * w + error;
|
||||
|
|
@ -224,7 +225,9 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
|
|||
|
||||
if (silf()->flags() & 1)
|
||||
{
|
||||
if (m_first)
|
||||
delLineEnd(m_first);
|
||||
if (m_last)
|
||||
delLineEnd(m_last);
|
||||
}
|
||||
m_first = oldFirst;
|
||||
|
|
@ -277,4 +280,3 @@ void Segment::delLineEnd(Slot *s)
|
|||
s->prev()->next(NULL);
|
||||
freeSlot(s);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ NameTable::NameTable(const void* data, size_t length, uint16 platformId, uint16
|
|||
{
|
||||
m_nameData = reinterpret_cast<const uint8*>(pdata) + offset;
|
||||
setPlatformEncoding(platformId, encodingID);
|
||||
m_nameDataLength = length - offset;
|
||||
m_nameDataLength = uint16(length - offset);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -180,7 +180,7 @@ void* NameTable::getName(uint16& languageId, uint16 nameId, gr_encform enc, uint
|
|||
utf8::iterator d = uniBuffer;
|
||||
for (utf16::const_iterator s = utf16Name, e = utf16Name + utf16Length; s != e; ++s, ++d)
|
||||
*d = *s;
|
||||
length = d - uniBuffer;
|
||||
length = uint32(d - uniBuffer);
|
||||
uniBuffer[length] = 0;
|
||||
free(utf16Name);
|
||||
return uniBuffer;
|
||||
|
|
@ -201,7 +201,7 @@ void* NameTable::getName(uint16& languageId, uint16 nameId, gr_encform enc, uint
|
|||
utf32::iterator d = uniBuffer;
|
||||
for (utf16::const_iterator s = utf16Name, e = utf16Name + utf16Length; s != e; ++s, ++d)
|
||||
*d = *s;
|
||||
length = d - uniBuffer;
|
||||
length = uint32(d - uniBuffer);
|
||||
uniBuffer[length] = 0;
|
||||
free(utf16Name);
|
||||
return uniBuffer;
|
||||
|
|
@ -252,4 +252,3 @@ uint16 NameTable::getLanguageId(const char * bcp47Locale)
|
|||
}
|
||||
return localeId;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -246,11 +246,11 @@ bool Pass::readRules(const byte * rule_map, const size_t num_entries,
|
|||
Rule * r = m_rules + m_numRules - 1;
|
||||
for (size_t n = m_numRules; r >= m_rules; --n, --r, ac_end = ac_begin, rc_end = rc_begin)
|
||||
{
|
||||
face.error_context((face.error_context() & 0xFFFF00) + EC_ARULE + ((n - 1) << 24));
|
||||
face.error_context((face.error_context() & 0xFFFF00) + EC_ARULE + int((n - 1) << 24));
|
||||
r->preContext = *--precontext;
|
||||
r->sort = be::peek<uint16>(--sort_key);
|
||||
#ifndef NDEBUG
|
||||
r->rule_idx = n - 1;
|
||||
r->rule_idx = uint16(n - 1);
|
||||
#endif
|
||||
if (r->sort > 63 || r->preContext >= r->sort || r->preContext > m_maxPreCtxt || r->preContext < m_minPreCtxt)
|
||||
return false;
|
||||
|
|
@ -291,7 +291,7 @@ bool Pass::readRules(const byte * rule_map, const size_t num_entries,
|
|||
|
||||
// Load the rule entries map
|
||||
face.error_context((face.error_context() & 0xFFFF00) + EC_APASS);
|
||||
//TODO: Coverty: 1315804: FORWARD_NULL
|
||||
//TODO: Coverity: 1315804: FORWARD_NULL
|
||||
RuleEntry * re = m_ruleMap = gralloc<RuleEntry>(num_entries);
|
||||
if (e.test(!re, E_OUTOFMEM)) return face.error(e);
|
||||
for (size_t n = num_entries; n; --n, ++re)
|
||||
|
|
@ -330,7 +330,7 @@ bool Pass::readStates(const byte * starts, const byte *states, const byte * o_ru
|
|||
*s = be::read<uint16>(starts);
|
||||
if (e.test(*s >= m_numStates, E_BADSTATE))
|
||||
{
|
||||
face.error_context((face.error_context() & 0xFFFF00) + EC_ASTARTS + ((s - m_startStates) << 24));
|
||||
face.error_context((face.error_context() & 0xFFFF00) + EC_ASTARTS + int((s - m_startStates) << 24));
|
||||
return face.error(e); // true;
|
||||
}
|
||||
}
|
||||
|
|
@ -342,7 +342,7 @@ bool Pass::readStates(const byte * starts, const byte *states, const byte * o_ru
|
|||
*t = be::read<uint16>(states);
|
||||
if (e.test(*t >= m_numStates, E_BADSTATE))
|
||||
{
|
||||
face.error_context((face.error_context() & 0xFFFF00) + EC_ATRANS + (((t - m_transitions) / m_numColumns) << 8));
|
||||
face.error_context((face.error_context() & 0xFFFF00) + EC_ATRANS + int(((t - m_transitions) / m_numColumns) << 8));
|
||||
return face.error(e);
|
||||
}
|
||||
}
|
||||
|
|
@ -357,7 +357,7 @@ bool Pass::readStates(const byte * starts, const byte *states, const byte * o_ru
|
|||
|
||||
if (e.test(begin >= rule_map_end || end > rule_map_end || begin > end, E_BADRULEMAPPING))
|
||||
{
|
||||
face.error_context((face.error_context() & 0xFFFF00) + EC_ARULEMAP + (n << 24));
|
||||
face.error_context((face.error_context() & 0xFFFF00) + EC_ARULEMAP + int(n << 24));
|
||||
return face.error(e);
|
||||
}
|
||||
s->rules = begin;
|
||||
|
|
@ -1105,4 +1105,3 @@ float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start
|
|||
}
|
||||
return 0.;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,4 +95,3 @@ Position Rect::constrainedAvoid(Position &offset, Rect &box, Rect &sdbox, Positi
|
|||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,224 +0,0 @@
|
|||
/* GRAPHITE2 LICENSING
|
||||
|
||||
Copyright 2010, SIL International
|
||||
All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should also have received a copy of the GNU Lesser General Public
|
||||
License along with this library in the file named "LICENSE".
|
||||
If not, write to the Free Software Foundation, 51 Franklin Street,
|
||||
Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
|
||||
internet at http://www.fsf.org/licenses/lgpl.html.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of the
|
||||
Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
|
||||
License, as published by the Free Software Foundation, either version 2
|
||||
of the License or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include "inc/Main.h"
|
||||
#include "inc/TtfTypes.h"
|
||||
#include "inc/TtfUtil.h"
|
||||
#include "inc/SegCache.h"
|
||||
#include "inc/SegCacheEntry.h"
|
||||
#include "inc/SegCacheStore.h"
|
||||
#include "inc/CmapCache.h"
|
||||
|
||||
|
||||
using namespace graphite2;
|
||||
|
||||
#ifndef GRAPHITE2_NSEGCACHE
|
||||
|
||||
SegCache::SegCache(const SegCacheStore * store, const Features & feats)
|
||||
: m_prefixLength(ePrefixLength),
|
||||
// m_maxCachedSegLength(eMaxSpliceSize),
|
||||
m_segmentCount(0),
|
||||
m_features(feats),
|
||||
m_totalAccessCount(0l), m_totalMisses(0l),
|
||||
m_purgeFactor(1.0f / (ePurgeFactor * store->maxSegmentCount()))
|
||||
{
|
||||
m_prefixes.raw = grzeroalloc<void*>(store->maxCmapGid() + 2);
|
||||
m_prefixes.range[SEG_CACHE_MIN_INDEX] = SEG_CACHE_UNSET_INDEX;
|
||||
m_prefixes.range[SEG_CACHE_MAX_INDEX] = SEG_CACHE_UNSET_INDEX;
|
||||
}
|
||||
|
||||
void SegCache::freeLevel(SegCacheStore * store, SegCachePrefixArray prefixes, size_t level)
|
||||
{
|
||||
for (size_t i = 0; i < store->maxCmapGid(); i++)
|
||||
{
|
||||
if (prefixes.array[i].raw)
|
||||
{
|
||||
if (level + 1 < ePrefixLength)
|
||||
freeLevel(store, prefixes.array[i], level + 1);
|
||||
else
|
||||
{
|
||||
SegCachePrefixEntry * prefixEntry = prefixes.prefixEntries[i];
|
||||
delete prefixEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(prefixes.raw);
|
||||
}
|
||||
|
||||
void SegCache::clear(SegCacheStore * store)
|
||||
{
|
||||
freeLevel(store, m_prefixes, 0);
|
||||
m_prefixes.raw = NULL;
|
||||
}
|
||||
|
||||
SegCache::~SegCache()
|
||||
{
|
||||
assert(m_prefixes.raw == NULL);
|
||||
}
|
||||
|
||||
SegCacheEntry* SegCache::cache(SegCacheStore * store, const uint16* cmapGlyphs, size_t length, Segment * seg, size_t charOffset)
|
||||
{
|
||||
uint16 pos = 0;
|
||||
if (!length) return NULL;
|
||||
// assert(length < m_maxCachedSegLength);
|
||||
SegCachePrefixArray pArray = m_prefixes;
|
||||
while (pos + 1 < m_prefixLength)
|
||||
{
|
||||
uint16 gid = (pos < length)? cmapGlyphs[pos] : 0;
|
||||
if (!pArray.array[gid].raw)
|
||||
{
|
||||
pArray.array[gid].raw = grzeroalloc<void*>(store->maxCmapGid() + 2);
|
||||
if (!pArray.array[gid].raw)
|
||||
return NULL; // malloc failed
|
||||
if (pArray.range[SEG_CACHE_MIN_INDEX] == SEG_CACHE_UNSET_INDEX)
|
||||
{
|
||||
pArray.range[SEG_CACHE_MIN_INDEX] = gid;
|
||||
pArray.range[SEG_CACHE_MAX_INDEX] = gid;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gid < pArray.range[SEG_CACHE_MIN_INDEX])
|
||||
pArray.range[SEG_CACHE_MIN_INDEX] = gid;
|
||||
else if (gid > pArray.range[SEG_CACHE_MAX_INDEX])
|
||||
pArray.range[SEG_CACHE_MAX_INDEX] = gid;
|
||||
}
|
||||
}
|
||||
pArray = pArray.array[gid];
|
||||
++pos;
|
||||
}
|
||||
uint16 gid = (pos < length)? cmapGlyphs[pos] : 0;
|
||||
SegCachePrefixEntry * prefixEntry = pArray.prefixEntries[gid];
|
||||
if (!prefixEntry)
|
||||
{
|
||||
prefixEntry = new SegCachePrefixEntry();
|
||||
pArray.prefixEntries[gid] = prefixEntry;
|
||||
if (pArray.range[SEG_CACHE_MIN_INDEX] == SEG_CACHE_UNSET_INDEX)
|
||||
{
|
||||
pArray.range[SEG_CACHE_MIN_INDEX] = gid;
|
||||
pArray.range[SEG_CACHE_MAX_INDEX] = gid;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gid < pArray.range[SEG_CACHE_MIN_INDEX])
|
||||
pArray.range[SEG_CACHE_MIN_INDEX] = gid;
|
||||
else if (gid > pArray.range[SEG_CACHE_MAX_INDEX])
|
||||
pArray.range[SEG_CACHE_MAX_INDEX] = gid;
|
||||
}
|
||||
}
|
||||
if (!prefixEntry) return NULL;
|
||||
// if the cache is full run a purge - this is slow, since it walks the tree
|
||||
if (m_segmentCount + 1 > store->maxSegmentCount())
|
||||
{
|
||||
purge(store);
|
||||
assert(m_segmentCount < store->maxSegmentCount());
|
||||
}
|
||||
SegCacheEntry * pEntry = prefixEntry->cache(cmapGlyphs, length, seg, charOffset, m_totalAccessCount);
|
||||
if (pEntry) ++m_segmentCount;
|
||||
return pEntry;
|
||||
}
|
||||
|
||||
void SegCache::purge(SegCacheStore * store)
|
||||
{
|
||||
unsigned long long minAccessCount = static_cast<unsigned long long>(m_totalAccessCount * m_purgeFactor + 1);
|
||||
if (minAccessCount < 2) minAccessCount = 2;
|
||||
unsigned long long oldAccessTime = m_totalAccessCount - store->maxSegmentCount() / eAgeFactor;
|
||||
purgeLevel(store, m_prefixes, 0, minAccessCount, oldAccessTime);
|
||||
}
|
||||
|
||||
void SegCache::purgeLevel(SegCacheStore * store, SegCachePrefixArray prefixes, size_t level,
|
||||
unsigned long long minAccessCount, unsigned long long oldAccessTime)
|
||||
{
|
||||
if (prefixes.range[SEG_CACHE_MIN_INDEX] == SEG_CACHE_UNSET_INDEX) return;
|
||||
size_t maxGlyphCached = prefixes.range[SEG_CACHE_MAX_INDEX];
|
||||
for (size_t i = prefixes.range[SEG_CACHE_MIN_INDEX]; i <= maxGlyphCached; i++)
|
||||
{
|
||||
if (prefixes.array[i].raw)
|
||||
{
|
||||
if (level + 1 < ePrefixLength)
|
||||
purgeLevel(store, prefixes.array[i], level + 1, minAccessCount, oldAccessTime);
|
||||
else
|
||||
{
|
||||
SegCachePrefixEntry * prefixEntry = prefixes.prefixEntries[i];
|
||||
m_segmentCount -= prefixEntry->purge(minAccessCount,
|
||||
oldAccessTime, m_totalAccessCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SegCachePrefixEntry::purge(unsigned long long minAccessCount,
|
||||
unsigned long long oldAccessTime,
|
||||
unsigned long long currentTime)
|
||||
{
|
||||
// ignore the purge request if another has been done recently
|
||||
//if (m_lastPurge > oldAccessTime)
|
||||
// return 0;
|
||||
|
||||
uint32 totalPurged = 0;
|
||||
// real length is length + 1 in this loop
|
||||
for (uint16 length = 0; length < eMaxSpliceSize; length++)
|
||||
{
|
||||
if (m_entryCounts[length] == 0)
|
||||
continue;
|
||||
uint16 purgeCount = 0;
|
||||
uint16 newIndex = 0;
|
||||
for (uint16 j = 0; j < m_entryCounts[length]; j++)
|
||||
{
|
||||
SegCacheEntry & tempEntry = m_entries[length][j];
|
||||
// purge entries with a low access count which haven't been
|
||||
// accessed recently
|
||||
if (tempEntry.accessCount() <= minAccessCount &&
|
||||
tempEntry.lastAccess() <= oldAccessTime)
|
||||
{
|
||||
tempEntry.clear();
|
||||
++purgeCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(m_entries[length] + newIndex++, m_entries[length] + j, sizeof(SegCacheEntry));
|
||||
}
|
||||
}
|
||||
if (purgeCount == m_entryCounts[length])
|
||||
{
|
||||
assert(newIndex == 0);
|
||||
m_entryCounts[length] = 0;
|
||||
m_entryBSIndex[length] = 0;
|
||||
free(m_entries[length]);
|
||||
m_entries[length] = NULL;
|
||||
}
|
||||
else if (purgeCount > 0)
|
||||
{
|
||||
assert(m_entryCounts[length] == newIndex + purgeCount);
|
||||
m_entryCounts[length] = newIndex;
|
||||
}
|
||||
totalPurged += purgeCount;
|
||||
}
|
||||
m_lastPurge = currentTime;
|
||||
return totalPurged;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
/* GRAPHITE2 LICENSING
|
||||
|
||||
Copyright 2010, SIL International
|
||||
All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should also have received a copy of the GNU Lesser General Public
|
||||
License along with this library in the file named "LICENSE".
|
||||
If not, write to the Free Software Foundation, 51 Franklin Street,
|
||||
Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
|
||||
internet at http://www.fsf.org/licenses/lgpl.html.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of the
|
||||
Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
|
||||
License, as published by the Free Software Foundation, either version 2
|
||||
of the License or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef GRAPHITE2_NSEGCACHE
|
||||
|
||||
#include "inc/Main.h"
|
||||
#include "inc/Slot.h"
|
||||
#include "inc/Segment.h"
|
||||
#include "inc/SegCache.h"
|
||||
#include "inc/SegCacheEntry.h"
|
||||
|
||||
|
||||
using namespace graphite2;
|
||||
|
||||
SegCacheEntry::SegCacheEntry(const uint16* cmapGlyphs, size_t length, Segment * seg, size_t charOffset, long long cacheTime)
|
||||
: m_glyphLength(0), m_unicode(gralloc<uint16>(length)), m_glyph(NULL),
|
||||
m_attr(NULL), m_justs(NULL),
|
||||
m_accessCount(0), m_lastAccess(cacheTime)
|
||||
{
|
||||
if (m_unicode)
|
||||
for (size_t i = 0; i < length; i++)
|
||||
m_unicode[i] = cmapGlyphs[i];
|
||||
|
||||
const size_t glyphCount = seg->slotCount(),
|
||||
sizeof_sjust = SlotJustify::size_of(seg->silf()->numJustLevels());
|
||||
if (!glyphCount) return;
|
||||
size_t num_justs = 0,
|
||||
justs_pos = 0;
|
||||
if (seg->hasJustification())
|
||||
{
|
||||
for (const Slot * s = seg->first(); s; s = s->next())
|
||||
{
|
||||
if (s->m_justs == 0) continue;
|
||||
++num_justs;
|
||||
}
|
||||
m_justs = gralloc<byte>(sizeof_sjust * num_justs);
|
||||
}
|
||||
const Slot * slot = seg->first();
|
||||
m_glyph = new Slot[glyphCount];
|
||||
m_attr = gralloc<int16>(glyphCount * seg->numAttrs());
|
||||
if (!m_glyph || (!m_attr && seg->numAttrs())) return;
|
||||
m_glyphLength = glyphCount;
|
||||
Slot * slotCopy = m_glyph;
|
||||
m_glyph->prev(NULL);
|
||||
|
||||
uint16 pos = 0;
|
||||
while (slot)
|
||||
{
|
||||
slotCopy->userAttrs(m_attr + pos * seg->numAttrs());
|
||||
slotCopy->m_justs = m_justs ? reinterpret_cast<SlotJustify *>(m_justs + justs_pos++ * sizeof_sjust) : 0;
|
||||
slotCopy->set(*slot, -static_cast<int32>(charOffset), seg->numAttrs(), seg->silf()->numJustLevels(), length);
|
||||
slotCopy->index(pos);
|
||||
if (slot->firstChild())
|
||||
slotCopy->m_child = m_glyph + slot->firstChild()->index();
|
||||
if (slot->attachedTo())
|
||||
slotCopy->attachTo(m_glyph + slot->attachedTo()->index());
|
||||
if (slot->nextSibling())
|
||||
slotCopy->m_sibling = m_glyph + slot->nextSibling()->index();
|
||||
slot = slot->next();
|
||||
++slotCopy;
|
||||
++pos;
|
||||
if (slot)
|
||||
{
|
||||
slotCopy->prev(slotCopy-1);
|
||||
(slotCopy-1)->next(slotCopy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SegCacheEntry::clear()
|
||||
{
|
||||
free(m_unicode);
|
||||
free(m_attr);
|
||||
free(m_justs);
|
||||
delete [] m_glyph;
|
||||
m_unicode = NULL;
|
||||
m_glyph = NULL;
|
||||
m_glyphLength = 0;
|
||||
m_attr = NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/* GRAPHITE2 LICENSING
|
||||
|
||||
Copyright 2010, SIL International
|
||||
All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should also have received a copy of the GNU Lesser General Public
|
||||
License along with this library in the file named "LICENSE".
|
||||
If not, write to the Free Software Foundation, 51 Franklin Street,
|
||||
Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
|
||||
internet at http://www.fsf.org/licenses/lgpl.html.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of the
|
||||
Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
|
||||
License, as published by the Free Software Foundation, either version 2
|
||||
of the License or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef GRAPHITE2_NSEGCACHE
|
||||
|
||||
#include "inc/SegCacheStore.h"
|
||||
#include "inc/Face.h"
|
||||
|
||||
|
||||
using namespace graphite2;
|
||||
|
||||
SegCacheStore::SegCacheStore(const Face & face, unsigned int numSilf, size_t maxSegments)
|
||||
: m_caches(new SilfSegCache[numSilf]),
|
||||
m_numSilf(numSilf),
|
||||
m_maxSegments(maxSegments),
|
||||
m_maxCmapGid(face.glyphs().numGlyphs()),
|
||||
m_spaceGid(face.cmap()[0x20]),
|
||||
m_zwspGid(face.cmap()[0x200B])
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ of the License or (at your option) any later version.
|
|||
|
||||
using namespace graphite2;
|
||||
|
||||
Segment::Segment(unsigned int numchars, const Face* face, uint32 script, int textDir)
|
||||
Segment::Segment(size_t numchars, const Face* face, uint32 script, int textDir)
|
||||
: m_freeSlots(NULL),
|
||||
m_freeJustifies(NULL),
|
||||
m_charinfo(new CharInfo[numchars]),
|
||||
|
|
@ -54,14 +54,12 @@ Segment::Segment(unsigned int numchars, const Face* face, uint32 script, int tex
|
|||
m_bufSize(numchars + 10),
|
||||
m_numGlyphs(numchars),
|
||||
m_numCharinfo(numchars),
|
||||
m_passBits(m_silf->aPassBits() ? -1 : 0),
|
||||
m_defaultOriginal(0),
|
||||
m_dir(textDir),
|
||||
m_flags(((m_silf->flags() & 0x20) != 0) << 1)
|
||||
m_flags(((m_silf->flags() & 0x20) != 0) << 1),
|
||||
m_passBits(m_silf->aPassBits() ? -1 : 0)
|
||||
{
|
||||
Slot *s = newSlot();
|
||||
if (s)
|
||||
freeSlot(s);
|
||||
freeSlot(newSlot());
|
||||
m_bufSize = log_binary(numchars)+1;
|
||||
}
|
||||
|
||||
|
|
@ -77,71 +75,6 @@ Segment::~Segment()
|
|||
free(m_collisions);
|
||||
}
|
||||
|
||||
#ifndef GRAPHITE2_NSEGCACHE
|
||||
SegmentScopeState Segment::setScope(Slot * firstSlot, Slot * lastSlot, size_t subLength)
|
||||
{
|
||||
SegmentScopeState state;
|
||||
state.numGlyphsOutsideScope = m_numGlyphs - subLength;
|
||||
state.realFirstSlot = m_first;
|
||||
state.slotBeforeScope = firstSlot->prev();
|
||||
state.slotAfterScope = lastSlot->next();
|
||||
state.realLastSlot = m_last;
|
||||
firstSlot->prev(NULL);
|
||||
lastSlot->next(NULL);
|
||||
assert(m_defaultOriginal == 0);
|
||||
m_defaultOriginal = firstSlot->original();
|
||||
m_numGlyphs = subLength;
|
||||
m_first = firstSlot;
|
||||
m_last = lastSlot;
|
||||
return state;
|
||||
}
|
||||
|
||||
void Segment::removeScope(SegmentScopeState & state)
|
||||
{
|
||||
m_numGlyphs = state.numGlyphsOutsideScope + m_numGlyphs;
|
||||
if (state.slotBeforeScope)
|
||||
{
|
||||
state.slotBeforeScope->next(m_first);
|
||||
m_first->prev(state.slotBeforeScope);
|
||||
m_first = state.realFirstSlot;
|
||||
}
|
||||
if (state.slotAfterScope)
|
||||
{
|
||||
state.slotAfterScope->prev(m_last);
|
||||
m_last->next(state.slotAfterScope);
|
||||
m_last = state.realLastSlot;
|
||||
}
|
||||
m_defaultOriginal = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void Segment::append(const Segment &other)
|
||||
{
|
||||
Rect bbox = other.m_bbox + m_advance;
|
||||
|
||||
m_slots.insert(m_slots.end(), other.m_slots.begin(), other.m_slots.end());
|
||||
CharInfo* pNewCharInfo = new CharInfo[m_numCharinfo+other.m_numCharinfo]; //since CharInfo has no constructor, this doesn't do much
|
||||
for (unsigned int i=0 ; i<m_numCharinfo ; ++i)
|
||||
pNewCharInfo[i] = m_charinfo[i];
|
||||
m_last->next(other.m_first);
|
||||
other.m_last->prev(m_last);
|
||||
m_userAttrs.insert(m_userAttrs.end(), other.m_userAttrs.begin(), other.m_userAttrs.end());
|
||||
|
||||
delete[] m_charinfo;
|
||||
m_charinfo = pNewCharInfo;
|
||||
pNewCharInfo += m_numCharinfo ;
|
||||
for (unsigned int i=0 ; i<m_numCharinfo ; ++i)
|
||||
pNewCharInfo[i] = other.m_charinfo[i];
|
||||
|
||||
m_numCharinfo += other.m_numCharinfo;
|
||||
m_numGlyphs += other.m_numGlyphs;
|
||||
m_advance = m_advance + other.m_advance;
|
||||
m_bbox = m_bbox.widen(bbox);
|
||||
m_passBits &= other.passBits();
|
||||
}
|
||||
#endif
|
||||
#endif // GRAPHITE2_NSEGCACHE
|
||||
|
||||
void Segment::appendSlot(int id, int cid, int gid, int iFeats, size_t coffset)
|
||||
{
|
||||
Slot *aSlot = newSlot();
|
||||
|
|
@ -206,6 +139,7 @@ Slot *Segment::newSlot()
|
|||
|
||||
void Segment::freeSlot(Slot *aSlot)
|
||||
{
|
||||
if (aSlot == nullptr) return;
|
||||
if (m_last == aSlot) m_last = aSlot->prev();
|
||||
if (m_first == aSlot) m_first = aSlot->next();
|
||||
if (aSlot->attachedTo())
|
||||
|
|
@ -214,11 +148,11 @@ void Segment::freeSlot(Slot *aSlot)
|
|||
{
|
||||
if (aSlot->firstChild()->attachedTo() == aSlot)
|
||||
{
|
||||
aSlot->firstChild()->attachTo(NULL);
|
||||
aSlot->firstChild()->attachTo(nullptr);
|
||||
aSlot->removeChild(aSlot->firstChild());
|
||||
}
|
||||
else
|
||||
aSlot->firstChild(NULL);
|
||||
aSlot->firstChild(nullptr);
|
||||
}
|
||||
// reset the slot incase it is reused
|
||||
::new (aSlot) Slot(aSlot->userAttrs());
|
||||
|
|
@ -230,7 +164,7 @@ void Segment::freeSlot(Slot *aSlot)
|
|||
#endif
|
||||
// update next pointer
|
||||
if (!m_freeSlots)
|
||||
aSlot->next(NULL);
|
||||
aSlot->next(nullptr);
|
||||
else
|
||||
aSlot->next(m_freeSlots);
|
||||
m_freeSlots = aSlot;
|
||||
|
|
@ -243,7 +177,7 @@ SlotJustify *Segment::newJustify()
|
|||
const size_t justSize = SlotJustify::size_of(m_silf->numJustLevels());
|
||||
byte *justs = grzeroalloc<byte>(justSize * m_bufSize);
|
||||
if (!justs) return NULL;
|
||||
for (int i = m_bufSize - 2; i >= 0; --i)
|
||||
for (ptrdiff_t i = m_bufSize - 2; i >= 0; --i)
|
||||
{
|
||||
SlotJustify *p = reinterpret_cast<SlotJustify *>(justs + justSize * i);
|
||||
SlotJustify *next = reinterpret_cast<SlotJustify *>(justs + justSize * (i + 1));
|
||||
|
|
@ -267,64 +201,6 @@ void Segment::freeJustify(SlotJustify *aJustify)
|
|||
m_freeJustifies = aJustify;
|
||||
}
|
||||
|
||||
#ifndef GRAPHITE2_NSEGCACHE
|
||||
void Segment::splice(size_t offset, size_t length, Slot * const startSlot,
|
||||
Slot * endSlot, const Slot * srcSlot,
|
||||
const size_t numGlyphs)
|
||||
{
|
||||
size_t numChars = length;
|
||||
extendLength(numGlyphs - length);
|
||||
// remove any extra
|
||||
if (numGlyphs < length)
|
||||
{
|
||||
Slot * end = endSlot->next();
|
||||
do
|
||||
{
|
||||
endSlot = endSlot->prev();
|
||||
freeSlot(endSlot->next());
|
||||
} while (numGlyphs < --length);
|
||||
endSlot->next(end);
|
||||
if (end)
|
||||
end->prev(endSlot);
|
||||
}
|
||||
else
|
||||
{
|
||||
// insert extra slots if needed
|
||||
while (numGlyphs > length)
|
||||
{
|
||||
Slot * extra = newSlot();
|
||||
if (!extra) return;
|
||||
extra->prev(endSlot);
|
||||
extra->next(endSlot->next());
|
||||
endSlot->next(extra);
|
||||
if (extra->next())
|
||||
extra->next()->prev(extra);
|
||||
if (m_last == endSlot)
|
||||
m_last = extra;
|
||||
endSlot = extra;
|
||||
++length;
|
||||
}
|
||||
}
|
||||
|
||||
endSlot = endSlot->next();
|
||||
assert(numGlyphs == length);
|
||||
assert(offset + numChars <= m_numCharinfo);
|
||||
Slot * indexmap[eMaxSpliceSize*3];
|
||||
assert(numGlyphs < sizeof indexmap/sizeof *indexmap);
|
||||
Slot * slot = startSlot;
|
||||
for (uint16 i=0; i < numGlyphs; slot = slot->next(), ++i)
|
||||
indexmap[i] = slot;
|
||||
|
||||
for (slot = startSlot; slot != endSlot; slot = slot->next(), srcSlot = srcSlot->next())
|
||||
{
|
||||
slot->set(*srcSlot, offset, m_silf->numUser(), m_silf->numJustLevels(), numChars);
|
||||
if (srcSlot->attachedTo()) slot->attachTo(indexmap[srcSlot->attachedTo()->index()]);
|
||||
if (srcSlot->nextSibling()) slot->m_sibling = indexmap[srcSlot->nextSibling()->index()];
|
||||
if (srcSlot->firstChild()) slot->m_child = indexmap[srcSlot->firstChild()->index()];
|
||||
}
|
||||
}
|
||||
#endif // GRAPHITE2_NSEGCACHE
|
||||
|
||||
// reverse the slots but keep diacritics in their same position after their bases
|
||||
void Segment::reverseSlots()
|
||||
{
|
||||
|
|
@ -452,7 +328,7 @@ Position Segment::positionSlots(const Font *font, Slot * iStart, Slot * iEnd, bo
|
|||
}
|
||||
|
||||
|
||||
void Segment::associateChars(int offset, int numChars)
|
||||
void Segment::associateChars(int offset, size_t numChars)
|
||||
{
|
||||
int i = 0, j = 0;
|
||||
CharInfo *c, *cend;
|
||||
|
|
@ -476,7 +352,7 @@ void Segment::associateChars(int offset, int numChars)
|
|||
for (Slot *s = m_first; s; s = s->next())
|
||||
{
|
||||
int a;
|
||||
for (a = s->after() + 1; a < offset + numChars && charinfo(a)->after() < 0; ++a)
|
||||
for (a = s->after() + 1; a < offset + int(numChars) && charinfo(a)->after() < 0; ++a)
|
||||
{ charinfo(a)->after(s->index()); }
|
||||
--a;
|
||||
s->after(a);
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ bool Silf::readGraphite(const byte * const silf_start, size_t lSilf, Face& face,
|
|||
{
|
||||
uint32 pass_start = be::read<uint32>(o_passes);
|
||||
uint32 pass_end = be::peek<uint32>(o_passes);
|
||||
face.error_context((face.error_context() & 0xFF00) + EC_ASILF + (i << 16));
|
||||
face.error_context((face.error_context() & 0xFF00) + EC_ASILF + unsigned(i << 16));
|
||||
if (e.test(pass_start > pass_end, E_BADPASSSTART)
|
||||
|| e.test(pass_start < passes_start, E_BADPASSSTART)
|
||||
|| e.test(pass_end > lSilf, E_BADPASSEND)) {
|
||||
|
|
@ -233,7 +233,7 @@ bool Silf::readGraphite(const byte * const silf_start, size_t lSilf, Face& face,
|
|||
template<typename T> inline uint32 Silf::readClassOffsets(const byte *&p, size_t data_len, Error &e)
|
||||
{
|
||||
const T cls_off = 2*sizeof(uint16) + sizeof(T)*(m_nClass+1);
|
||||
const size_t max_off = (be::peek<T>(p + sizeof(T)*m_nClass) - cls_off)/sizeof(uint16);
|
||||
const uint32 max_off = (be::peek<T>(p + sizeof(T)*m_nClass) - cls_off)/sizeof(uint16);
|
||||
// Check that the last+1 offset is less than or equal to the class map length.
|
||||
if (e.test(be::peek<T>(p) != cls_off, E_MISALIGNEDCLASSES)
|
||||
|| e.test(max_off > (data_len - cls_off)/sizeof(uint16), E_HIGHCLASSOFFSET))
|
||||
|
|
@ -357,7 +357,7 @@ uint16 Silf::getClassGlyph(uint16 cid, unsigned int index) const
|
|||
bool Silf::runGraphite(Segment *seg, uint8 firstPass, uint8 lastPass, int dobidi) const
|
||||
{
|
||||
assert(seg != 0);
|
||||
unsigned int maxSize = seg->slotCount() * MAX_SEG_GROWTH_FACTOR;
|
||||
size_t maxSize = seg->slotCount() * MAX_SEG_GROWTH_FACTOR;
|
||||
SlotMap map(*seg, m_dir, maxSize);
|
||||
FiniteStateMachine fsm(map, seg->getFace()->logger());
|
||||
vm::Machine m(map);
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ void Slot::set(const Slot & orig, int charOffset, size_t sizeAttr, size_t justLe
|
|||
else
|
||||
m_before = orig.m_before + charOffset;
|
||||
if (charOffset <= 0 && orig.m_after + charOffset >= numChars)
|
||||
m_after = numChars - 1;
|
||||
m_after = int(numChars) - 1;
|
||||
else
|
||||
m_after = orig.m_after + charOffset;
|
||||
m_parent = NULL;
|
||||
|
|
@ -165,25 +165,25 @@ int32 Slot::clusterMetric(const Segment *seg, uint8 metric, uint8 attrLevel, boo
|
|||
switch (metrics(metric))
|
||||
{
|
||||
case kgmetLsb :
|
||||
return bbox.bl.x;
|
||||
return int32(bbox.bl.x);
|
||||
case kgmetRsb :
|
||||
return res.x - bbox.tr.x;
|
||||
return int32(res.x - bbox.tr.x);
|
||||
case kgmetBbTop :
|
||||
return bbox.tr.y;
|
||||
return int32(bbox.tr.y);
|
||||
case kgmetBbBottom :
|
||||
return bbox.bl.y;
|
||||
return int32(bbox.bl.y);
|
||||
case kgmetBbLeft :
|
||||
return bbox.bl.x;
|
||||
return int32(bbox.bl.x);
|
||||
case kgmetBbRight :
|
||||
return bbox.tr.x;
|
||||
return int32(bbox.tr.x);
|
||||
case kgmetBbWidth :
|
||||
return bbox.tr.x - bbox.bl.x;
|
||||
return int32(bbox.tr.x - bbox.bl.x);
|
||||
case kgmetBbHeight :
|
||||
return bbox.tr.y - bbox.bl.y;
|
||||
return int32(bbox.tr.y - bbox.bl.y);
|
||||
case kgmetAdvWidth :
|
||||
return res.x;
|
||||
return int32(res.x);
|
||||
case kgmetAdvHeight :
|
||||
return res.y;
|
||||
return int32(res.y);
|
||||
default :
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -193,14 +193,7 @@ int32 Slot::clusterMetric(const Segment *seg, uint8 metric, uint8 attrLevel, boo
|
|||
|
||||
int Slot::getAttr(const Segment *seg, attrCode ind, uint8 subindex) const
|
||||
{
|
||||
if (ind == gr_slatUserDefnV1)
|
||||
{
|
||||
ind = gr_slatUserDefn;
|
||||
subindex = 0;
|
||||
if (seg->numAttrs() == 0)
|
||||
return 0;
|
||||
}
|
||||
else if (ind >= gr_slatJStretch && ind < gr_slatJStretch + 20 && ind != gr_slatJWidth)
|
||||
if (ind >= gr_slatJStretch && ind < gr_slatJStretch + 20 && ind != gr_slatJWidth)
|
||||
{
|
||||
int indx = ind - gr_slatJStretch;
|
||||
return getJustify(seg, indx / 5, indx % 5);
|
||||
|
|
@ -231,30 +224,32 @@ int Slot::getAttr(const Segment *seg, attrCode ind, uint8 subindex) const
|
|||
case gr_slatMeasureSol: return -1; // err what's this?
|
||||
case gr_slatMeasureEol: return -1;
|
||||
case gr_slatJWidth: return int(m_just);
|
||||
case gr_slatUserDefn : return m_userAttr[subindex];
|
||||
case gr_slatUserDefnV1: subindex = 0; GR_FALLTHROUGH;
|
||||
// no break
|
||||
case gr_slatUserDefn : return subindex < seg->numAttrs() ? m_userAttr[subindex] : 0;
|
||||
case gr_slatSegSplit : return seg->charinfo(m_original)->flags() & 3;
|
||||
case gr_slatBidiLevel: return m_bidiLevel;
|
||||
case gr_slatColFlags : { SlotCollision *c = seg->collisionInfo(this); return c ? c->flags() : 0; }
|
||||
case gr_slatColLimitblx : SLOTGETCOLATTR(limit().bl.x)
|
||||
case gr_slatColLimitbly : SLOTGETCOLATTR(limit().bl.y)
|
||||
case gr_slatColLimittrx : SLOTGETCOLATTR(limit().tr.x)
|
||||
case gr_slatColLimittry : SLOTGETCOLATTR(limit().tr.y)
|
||||
case gr_slatColLimitblx:SLOTGETCOLATTR(limit().bl.x)
|
||||
case gr_slatColLimitbly:SLOTGETCOLATTR(limit().bl.y)
|
||||
case gr_slatColLimittrx:SLOTGETCOLATTR(limit().tr.x)
|
||||
case gr_slatColLimittry:SLOTGETCOLATTR(limit().tr.y)
|
||||
case gr_slatColShiftx : SLOTGETCOLATTR(offset().x)
|
||||
case gr_slatColShifty : SLOTGETCOLATTR(offset().y)
|
||||
case gr_slatColMargin : SLOTGETCOLATTR(margin())
|
||||
case gr_slatColMarginWt : SLOTGETCOLATTR(marginWt())
|
||||
case gr_slatColExclGlyph : SLOTGETCOLATTR(exclGlyph())
|
||||
case gr_slatColExclOffx : SLOTGETCOLATTR(exclOffset().x)
|
||||
case gr_slatColExclOffy : SLOTGETCOLATTR(exclOffset().y)
|
||||
case gr_slatColMarginWt:SLOTGETCOLATTR(marginWt())
|
||||
case gr_slatColExclGlyph:SLOTGETCOLATTR(exclGlyph())
|
||||
case gr_slatColExclOffx:SLOTGETCOLATTR(exclOffset().x)
|
||||
case gr_slatColExclOffy:SLOTGETCOLATTR(exclOffset().y)
|
||||
case gr_slatSeqClass : SLOTGETCOLATTR(seqClass())
|
||||
case gr_slatSeqProxClass : SLOTGETCOLATTR(seqProxClass())
|
||||
case gr_slatSeqProxClass:SLOTGETCOLATTR(seqProxClass())
|
||||
case gr_slatSeqOrder : SLOTGETCOLATTR(seqOrder())
|
||||
case gr_slatSeqAboveXoff : SLOTGETCOLATTR(seqAboveXoff())
|
||||
case gr_slatSeqAboveWt : SLOTGETCOLATTR(seqAboveWt())
|
||||
case gr_slatSeqBelowXlim : SLOTGETCOLATTR(seqBelowXlim())
|
||||
case gr_slatSeqBelowWt : SLOTGETCOLATTR(seqBelowWt())
|
||||
case gr_slatSeqValignHt : SLOTGETCOLATTR(seqValignHt())
|
||||
case gr_slatSeqValignWt : SLOTGETCOLATTR(seqValignWt())
|
||||
case gr_slatSeqAboveXoff:SLOTGETCOLATTR(seqAboveXoff())
|
||||
case gr_slatSeqAboveWt: SLOTGETCOLATTR(seqAboveWt())
|
||||
case gr_slatSeqBelowXlim:SLOTGETCOLATTR(seqBelowXlim())
|
||||
case gr_slatSeqBelowWt: SLOTGETCOLATTR(seqBelowWt())
|
||||
case gr_slatSeqValignHt:SLOTGETCOLATTR(seqValignHt())
|
||||
case gr_slatSeqValignWt:SLOTGETCOLATTR(seqValignWt())
|
||||
default : return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -480,7 +475,7 @@ void Slot::setGlyph(Segment *seg, uint16 glyphid, const GlyphFace * theGlyph)
|
|||
m_advance = Position(aGlyph->theAdvance().x, 0.);
|
||||
if (seg->silf()->aPassBits())
|
||||
{
|
||||
seg->mergePassBits(theGlyph->attrs()[seg->silf()->aPassBits()]);
|
||||
seg->mergePassBits(uint8(theGlyph->attrs()[seg->silf()->aPassBits()]));
|
||||
if (seg->silf()->numPasses() > 16)
|
||||
seg->mergePassBits(theGlyph->attrs()[seg->silf()->aPassBits()+1] << 16);
|
||||
}
|
||||
|
|
@ -532,4 +527,3 @@ bool Slot::isChildOf(const Slot *base) const
|
|||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1252,7 +1252,7 @@ size_t LocaLookup(gid16 nGlyphId,
|
|||
void * GlyfLookup(const void * pGlyf, size_t nGlyfOffset, size_t nTableLen)
|
||||
{
|
||||
const uint8 * pByte = reinterpret_cast<const uint8 *>(pGlyf);
|
||||
if (nGlyfOffset + pByte < pByte || nGlyfOffset >= nTableLen - sizeof(Sfnt::Glyph))
|
||||
if (OVERFLOW_OFFSET_CHECK(pByte, nGlyfOffset) || nGlyfOffset >= nTableLen - sizeof(Sfnt::Glyph))
|
||||
return NULL;
|
||||
return const_cast<uint8 *>(pByte + nGlyfOffset);
|
||||
}
|
||||
|
|
@ -1670,7 +1670,7 @@ void * GlyfLookup(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
|
|||
}
|
||||
}
|
||||
|
||||
long lGlyfOffset = LocaLookup(nGlyphId, pLoca, lLocaSize, pHead);
|
||||
size_t lGlyfOffset = LocaLookup(nGlyphId, pLoca, lLocaSize, pHead);
|
||||
void * pSimpleGlyf = GlyfLookup(pGlyf, lGlyfOffset, lGlyfSize); // invalid loca offset returns null
|
||||
return pSimpleGlyf;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,5 +136,3 @@ const opcode_t * Machine::getOpcodeTable() throw()
|
|||
{
|
||||
return opcode_table;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -118,4 +118,3 @@ Machine::stack_t Machine::run(const instr * program,
|
|||
check_final_stack(sp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,9 +63,6 @@ $(_NS)_SOURCES = \
|
|||
$($(_NS)_BASE)/src/NameTable.cpp \
|
||||
$($(_NS)_BASE)/src/Pass.cpp \
|
||||
$($(_NS)_BASE)/src/Position.cpp \
|
||||
$($(_NS)_BASE)/src/SegCache.cpp \
|
||||
$($(_NS)_BASE)/src/SegCacheEntry.cpp \
|
||||
$($(_NS)_BASE)/src/SegCacheStore.cpp \
|
||||
$($(_NS)_BASE)/src/Segment.cpp \
|
||||
$($(_NS)_BASE)/src/Silf.cpp \
|
||||
$($(_NS)_BASE)/src/Slot.cpp \
|
||||
|
|
@ -104,9 +101,6 @@ $(_NS)_PRIVATE_HEADERS = \
|
|||
$($(_NS)_BASE)/src/inc/Pass.h \
|
||||
$($(_NS)_BASE)/src/inc/Position.h \
|
||||
$($(_NS)_BASE)/src/inc/Rule.h \
|
||||
$($(_NS)_BASE)/src/inc/SegCache.h \
|
||||
$($(_NS)_BASE)/src/inc/SegCacheEntry.h \
|
||||
$($(_NS)_BASE)/src/inc/SegCacheStore.h \
|
||||
$($(_NS)_BASE)/src/inc/Segment.h \
|
||||
$($(_NS)_BASE)/src/inc/Silf.h \
|
||||
$($(_NS)_BASE)/src/inc/Slot.h \
|
||||
|
|
@ -120,4 +114,3 @@ $(_NS)_PUBLIC_HEADERS = \
|
|||
$($(_NS)_BASE)/include/graphite2/Log.h \
|
||||
$($(_NS)_BASE)/include/graphite2/Segment.h \
|
||||
$($(_NS)_BASE)/include/graphite2/Types.h
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ of the License or (at your option) any later version.
|
|||
#include "inc/Face.h"
|
||||
#include "inc/FileFace.h"
|
||||
#include "inc/GlyphCache.h"
|
||||
#include "inc/CachedFace.h"
|
||||
#include "inc/CmapCache.h"
|
||||
#include "inc/Silf.h"
|
||||
#include "inc/json.h"
|
||||
|
|
@ -47,8 +46,7 @@ namespace
|
|||
telemetry::category _misc_cat(face.tele.misc);
|
||||
#endif
|
||||
Face::Table silf(face, Tag::Silf, 0x00050000);
|
||||
if (silf) options &= ~gr_face_dumbRendering;
|
||||
else if (!(options & gr_face_dumbRendering))
|
||||
if (!silf)
|
||||
return false;
|
||||
|
||||
if (!face.readGlyphs(options))
|
||||
|
|
@ -74,7 +72,17 @@ namespace
|
|||
return true;
|
||||
}
|
||||
else
|
||||
return options & gr_face_dumbRendering;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline
|
||||
uint32 zeropad(const uint32 x)
|
||||
{
|
||||
if (x == 0x20202020) return 0;
|
||||
if ((x & 0x00FFFFFF) == 0x00202020) return x & 0xFF000000;
|
||||
if ((x & 0x0000FFFF) == 0x00002020) return x & 0xFFFF0000;
|
||||
if ((x & 0x000000FF) == 0x00000020) return x & 0xFFFFFF00;
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -99,56 +107,41 @@ gr_face* gr_make_face(const void* appFaceHandle/*non-NULL*/, gr_get_table_fn tab
|
|||
return gr_make_face_with_ops(appFaceHandle, &ops, faceOptions);
|
||||
}
|
||||
|
||||
#ifndef GRAPHITE2_NSEGCACHE
|
||||
gr_face* gr_make_face_with_seg_cache_and_ops(const void* appFaceHandle/*non-NULL*/, const gr_face_ops *ops, unsigned int cacheSize, unsigned int faceOptions)
|
||||
//the appFaceHandle must stay alive all the time when the GrFace is alive. When finished with the GrFace, call destroy_face
|
||||
|
||||
gr_face* gr_make_face_with_seg_cache_and_ops(const void* appFaceHandle/*non-NULL*/, const gr_face_ops *ops, unsigned int , unsigned int faceOptions)
|
||||
{
|
||||
if (ops == 0) return 0;
|
||||
|
||||
CachedFace *res = new CachedFace(appFaceHandle, *ops);
|
||||
if (res && load_face(*res, faceOptions)
|
||||
&& res->setupCache(cacheSize))
|
||||
return static_cast<gr_face *>(static_cast<Face *>(res));
|
||||
|
||||
delete res;
|
||||
return 0;
|
||||
return gr_make_face_with_ops(appFaceHandle, ops, faceOptions);
|
||||
}
|
||||
|
||||
gr_face* gr_make_face_with_seg_cache(const void* appFaceHandle/*non-NULL*/, gr_get_table_fn getTable, unsigned int cacheSize, unsigned int faceOptions)
|
||||
gr_face* gr_make_face_with_seg_cache(const void* appFaceHandle/*non-NULL*/, gr_get_table_fn tablefn, unsigned int, unsigned int faceOptions)
|
||||
{
|
||||
const gr_face_ops ops = {sizeof(gr_face_ops), getTable, NULL};
|
||||
return gr_make_face_with_seg_cache_and_ops(appFaceHandle, &ops, cacheSize, faceOptions);
|
||||
const gr_face_ops ops = {sizeof(gr_face_ops), tablefn, NULL};
|
||||
return gr_make_face_with_ops(appFaceHandle, &ops, faceOptions);
|
||||
}
|
||||
#endif
|
||||
|
||||
gr_uint32 gr_str_to_tag(const char *str)
|
||||
{
|
||||
uint32 res = 0;
|
||||
int i = strlen(str);
|
||||
if (i > 4) i = 4;
|
||||
while (--i >= 0)
|
||||
res = (res >> 8) + (str[i] << 24);
|
||||
switch(max(strlen(str),size_t(4)))
|
||||
{
|
||||
case 4: res |= str[3]; GR_FALLTHROUGH;
|
||||
case 3: res |= str[2] << 8; GR_FALLTHROUGH;
|
||||
case 2: res |= str[1] << 16; GR_FALLTHROUGH;
|
||||
case 1: res |= str[0] << 24; GR_FALLTHROUGH;
|
||||
default: break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void gr_tag_to_str(gr_uint32 tag, char *str)
|
||||
{
|
||||
int i = 4;
|
||||
while (--i >= 0)
|
||||
{
|
||||
str[i] = tag & 0xFF;
|
||||
tag >>= 8;
|
||||
}
|
||||
}
|
||||
if (!str) return;
|
||||
|
||||
inline
|
||||
uint32 zeropad(const uint32 x)
|
||||
{
|
||||
if (x == 0x20202020) return 0;
|
||||
if ((x & 0x00FFFFFF) == 0x00202020) return x & 0xFF000000;
|
||||
if ((x & 0x0000FFFF) == 0x00002020) return x & 0xFFFF0000;
|
||||
if ((x & 0x000000FF) == 0x00000020) return x & 0xFFFFFF00;
|
||||
return x;
|
||||
*str++ = char(tag >> 24);
|
||||
*str++ = char(tag >> 16);
|
||||
*str++ = char(tag >> 8);
|
||||
*str++ = char(tag);
|
||||
*str = '\0';
|
||||
}
|
||||
|
||||
gr_feature_val* gr_face_featureval_for_lang(const gr_face* pFace, gr_uint32 langname/*0 means clone default*/) //clones the features. if none for language, clones the default
|
||||
|
|
@ -253,30 +246,11 @@ gr_face* gr_make_file_face(const char *filename, unsigned int faceOptions)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef GRAPHITE2_NSEGCACHE
|
||||
gr_face* gr_make_file_face_with_seg_cache(const char* filename, unsigned int segCacheMaxSize, unsigned int faceOptions) //returns NULL on failure. //TBD better error handling
|
||||
gr_face* gr_make_file_face_with_seg_cache(const char* filename, unsigned int, unsigned int faceOptions) //returns NULL on failure. //TBD better error handling
|
||||
//when finished with, call destroy_face
|
||||
{
|
||||
FileFace* pFileFace = new FileFace(filename);
|
||||
if (*pFileFace)
|
||||
{
|
||||
gr_face * pRes = gr_make_face_with_seg_cache_and_ops(pFileFace, &FileFace::ops, segCacheMaxSize, faceOptions);
|
||||
if (pRes)
|
||||
{
|
||||
pRes->takeFileFace(pFileFace); //takes ownership
|
||||
return pRes;
|
||||
}
|
||||
}
|
||||
|
||||
//error when loading
|
||||
|
||||
delete pFileFace;
|
||||
return NULL;
|
||||
return gr_make_file_face(filename, faceOptions);
|
||||
}
|
||||
#endif
|
||||
#endif //!GRAPHITE2_NFILEFACE
|
||||
|
||||
|
||||
} // extern "C"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,3 @@ void gr_font_destroy(gr_font *font)
|
|||
|
||||
|
||||
} // extern "C"
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -252,14 +252,14 @@ json & graphite2::operator << (json & j, const dslot & ds) throw()
|
|||
graphite2::objectid::objectid(const dslot & ds) throw()
|
||||
{
|
||||
const Slot * const p = ds.second;
|
||||
uint32 s = reinterpret_cast<size_t>(p);
|
||||
uint32 s = uint32(reinterpret_cast<size_t>(p));
|
||||
sprintf(name, "%.4x-%.2x-%.4hx", uint16(s >> 16), uint16(p ? p->userAttrs()[ds.first->silf()->numUser()] : 0), uint16(s));
|
||||
name[sizeof name-1] = 0;
|
||||
}
|
||||
|
||||
graphite2::objectid::objectid(const Segment * const p) throw()
|
||||
{
|
||||
uint32 s = reinterpret_cast<size_t>(p);
|
||||
uint32 s = uint32(reinterpret_cast<size_t>(p));
|
||||
sprintf(name, "%.4x-%.2x-%.4hx", uint16(s >> 16), 0, uint16(s));
|
||||
name[sizeof name-1] = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,18 +53,19 @@ namespace
|
|||
return static_cast<gr_segment*>(pRes);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
template <typename utf_iter>
|
||||
inline size_t count_unicode_chars(utf_iter first, const utf_iter last, const void **error)
|
||||
{
|
||||
template <typename utf_iter>
|
||||
inline size_t count_unicode_chars(utf_iter first, const utf_iter last, const void **error)
|
||||
{
|
||||
size_t n_chars = 0;
|
||||
uint32 usv = 0;
|
||||
|
||||
if (last)
|
||||
{
|
||||
if (!first.validate(last))
|
||||
{
|
||||
if (error) *error = last - 1;
|
||||
return 0;
|
||||
}
|
||||
for (;first != last; ++first, ++n_chars)
|
||||
if ((usv = *first) == 0 || first.error()) break;
|
||||
}
|
||||
|
|
@ -79,8 +80,10 @@ inline size_t count_unicode_chars(utf_iter first, const utf_iter last, const voi
|
|||
|
||||
if (error) *error = first.error() ? first : 0;
|
||||
return n_chars;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
size_t gr_count_unicode_characters(gr_encform enc, const void* buffer_begin, const void* buffer_end/*don't go on or past end, If NULL then ignored*/, const void** pError) //Also stops on nul. Any nul is not in the count
|
||||
|
|
@ -99,6 +102,8 @@ size_t gr_count_unicode_characters(gr_encform enc, const void* buffer_begin, con
|
|||
|
||||
gr_segment* gr_make_seg(const gr_font *font, const gr_face *face, gr_uint32 script, const gr_feature_val* pFeats, gr_encform enc, const void* pStart, size_t nChars, int dir)
|
||||
{
|
||||
if (!face) return nullptr;
|
||||
|
||||
const gr_feature_val * tmp_feats = 0;
|
||||
if (pFeats == 0)
|
||||
pFeats = tmp_feats = static_cast<const gr_feature_val*>(face->theSill().cloneFeatures(0));
|
||||
|
|
@ -132,7 +137,7 @@ float gr_seg_advance_Y(const gr_segment* pSeg/*not NULL*/)
|
|||
unsigned int gr_seg_n_cinfo(const gr_segment* pSeg/*not NULL*/)
|
||||
{
|
||||
assert(pSeg);
|
||||
return pSeg->charInfoCount();
|
||||
return static_cast<unsigned int>(pSeg->charInfoCount());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -145,7 +150,7 @@ const gr_char_info* gr_seg_cinfo(const gr_segment* pSeg/*not NULL*/, unsigned in
|
|||
unsigned int gr_seg_n_slots(const gr_segment* pSeg/*not NULL*/)
|
||||
{
|
||||
assert(pSeg);
|
||||
return pSeg->slotCount();
|
||||
return static_cast<unsigned int>(pSeg->slotCount());
|
||||
}
|
||||
|
||||
const gr_slot* gr_seg_first_slot(gr_segment* pSeg/*not NULL*/)
|
||||
|
|
|
|||
|
|
@ -170,4 +170,3 @@ size_t id(const gr_slot* p/*not NULL*/)
|
|||
|
||||
|
||||
} // extern "C"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,56 +0,0 @@
|
|||
/* GRAPHITE2 LICENSING
|
||||
|
||||
Copyright 2010, SIL International
|
||||
All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should also have received a copy of the GNU Lesser General Public
|
||||
License along with this library in the file named "LICENSE".
|
||||
If not, write to the Free Software Foundation, 51 Franklin Street,
|
||||
Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
|
||||
internet at http://www.fsf.org/licenses/lgpl.html.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of the
|
||||
Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
|
||||
License, as published by the Free Software Foundation, either version 2
|
||||
of the License or (at your option) any later version.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef GRAPHITE2_NSEGCACHE
|
||||
|
||||
#include "inc/Face.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class SegCacheStore;
|
||||
class SegCache;
|
||||
|
||||
class CachedFace : public Face
|
||||
{
|
||||
CachedFace(const CachedFace &);
|
||||
CachedFace & operator = (const CachedFace &);
|
||||
|
||||
public:
|
||||
CachedFace(const void* appFaceHandle/*non-NULL*/, const gr_face_ops & ops);
|
||||
bool setupCache(unsigned int cacheSize);
|
||||
virtual ~CachedFace();
|
||||
virtual bool runGraphite(Segment *seg, const Silf *silf) const;
|
||||
SegCacheStore * cacheStore() { return m_cacheStore; }
|
||||
private:
|
||||
SegCacheStore * m_cacheStore;
|
||||
};
|
||||
|
||||
} // namespace graphite2
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -64,4 +64,3 @@ private:
|
|||
} // namespace graphite2
|
||||
|
||||
struct gr_char_info : public graphite2::CharInfo {};
|
||||
|
||||
|
|
|
|||
|
|
@ -243,4 +243,3 @@ KernCollider::KernCollider(GR_MAYBE_UNUSED json *dbg)
|
|||
};
|
||||
|
||||
}; // end of namespace graphite2
|
||||
|
||||
|
|
|
|||
|
|
@ -102,5 +102,3 @@ u8 * fast_copy(u8 * d, u8 const * s, size_t n) {
|
|||
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -52,5 +52,3 @@ namespace lz4
|
|||
int decompress(void const *in, size_t in_size, void *out, size_t out_size);
|
||||
|
||||
} // end of namespace shrinker
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -109,4 +109,3 @@ public:
|
|||
|
||||
template<>
|
||||
inline unsigned long int le::_peek<1>(const unsigned char * p) { return *p; }
|
||||
|
||||
|
|
|
|||
|
|
@ -132,4 +132,3 @@ enum errors {
|
|||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -170,23 +170,23 @@ class Face::Table
|
|||
{
|
||||
const Face * _f;
|
||||
mutable const byte * _p;
|
||||
uint32 _sz;
|
||||
size_t _sz;
|
||||
bool _compressed;
|
||||
|
||||
Error decompress();
|
||||
|
||||
void releaseBuffers();
|
||||
void release();
|
||||
|
||||
public:
|
||||
Table() throw();
|
||||
Table(const Face & face, const Tag n, uint32 version=0xffffffff) throw();
|
||||
Table(const Table & rhs) throw();
|
||||
~Table() throw();
|
||||
Table(const Table && rhs) throw();
|
||||
|
||||
operator const byte * () const throw();
|
||||
|
||||
Table & operator = (const Table & rhs) throw();
|
||||
size_t size() const throw();
|
||||
Table & operator = (const Table && rhs) throw();
|
||||
};
|
||||
|
||||
inline
|
||||
|
|
@ -196,7 +196,7 @@ Face::Table::Table() throw()
|
|||
}
|
||||
|
||||
inline
|
||||
Face::Table::Table(const Table & rhs) throw()
|
||||
Face::Table::Table(const Table && rhs) throw()
|
||||
: _f(rhs._f), _p(rhs._p), _sz(rhs._sz), _compressed(rhs._compressed)
|
||||
{
|
||||
rhs._p = 0;
|
||||
|
|
@ -205,7 +205,7 @@ Face::Table::Table(const Table & rhs) throw()
|
|||
inline
|
||||
Face::Table::~Table() throw()
|
||||
{
|
||||
releaseBuffers();
|
||||
release();
|
||||
}
|
||||
|
||||
inline
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ struct telemetry {};
|
|||
#define HAVE_BUILTIN_OVERFLOW
|
||||
#endif
|
||||
#if defined(__has_include)
|
||||
#if __has_include(<intsafe.h>)
|
||||
#if __has_include(<intsafe.h>) && !defined(__CYGWIN__)
|
||||
#define HAVE_INTSAFE_H
|
||||
#endif
|
||||
#elif defined(_WIN32)
|
||||
|
|
@ -172,9 +172,14 @@ inline T max(const T a, const T b)
|
|||
#define GR_MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
#if defined(__clang__) && __cplusplus >= 201103L
|
||||
/* clang's fallthrough annotations are only available starting in C++11. */
|
||||
#define GR_FALLTHROUGH [[fallthrough]]
|
||||
#ifndef __has_cpp_attribute
|
||||
# define __has_cpp_attribute(x) 0
|
||||
#endif
|
||||
|
||||
#if __has_cpp_attribute(clang::fallthrough)
|
||||
# define GR_FALLTHROUGH [[clang::fallthrough]]
|
||||
#elif __has_cpp_attribute(gnu::fallthrough)
|
||||
# define GR_FALLTHROUGH [[gnu::fallthrough]]
|
||||
#elif defined(_MSC_VER)
|
||||
/*
|
||||
* MSVC's __fallthrough annotations are checked by /analyze (Code Analysis):
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ class SlotMap
|
|||
{
|
||||
public:
|
||||
enum {MAX_SLOTS=64};
|
||||
SlotMap(Segment & seg, uint8 direction, int maxSize);
|
||||
SlotMap(Segment & seg, uint8 direction, size_t maxSize);
|
||||
|
||||
Slot * * begin();
|
||||
Slot * * end();
|
||||
|
|
@ -244,9 +244,9 @@ void FiniteStateMachine::Rules::accumulate_rules(const State &state)
|
|||
}
|
||||
|
||||
inline
|
||||
SlotMap::SlotMap(Segment & seg, uint8 direction, int maxSize)
|
||||
SlotMap::SlotMap(Segment & seg, uint8 direction, size_t maxSize)
|
||||
: segment(seg), m_size(0), m_precontext(0), m_highwater(0),
|
||||
m_maxSize(maxSize), m_dir(direction), m_highpassed(false)
|
||||
m_maxSize(int(maxSize)), m_dir(direction), m_highpassed(false)
|
||||
{
|
||||
m_slot_map[0] = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,316 +0,0 @@
|
|||
/* GRAPHITE2 LICENSING
|
||||
|
||||
Copyright 2010, SIL International
|
||||
All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should also have received a copy of the GNU Lesser General Public
|
||||
License along with this library in the file named "LICENSE".
|
||||
If not, write to the Free Software Foundation, 51 Franklin Street,
|
||||
Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
|
||||
internet at http://www.fsf.org/licenses/lgpl.html.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of the
|
||||
Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
|
||||
License, as published by the Free Software Foundation, either version 2
|
||||
of the License or (at your option) any later version.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef GRAPHITE2_NSEGCACHE
|
||||
|
||||
#include <graphite2/Segment.h>
|
||||
#include "inc/Main.h"
|
||||
#include "inc/Slot.h"
|
||||
#include "inc/FeatureVal.h"
|
||||
#include "inc/SegCacheEntry.h"
|
||||
#include "inc/Segment.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class SegCache;
|
||||
class SegCacheEntry;
|
||||
class SegCacheStore;
|
||||
|
||||
/**
|
||||
* SegPrefixEntry stores lists of word/syllable segments
|
||||
* with one list for each word length. The prefix size should be chosen so that
|
||||
* these list sizes stay small since they will be searched iteratively.
|
||||
*/
|
||||
class SegCachePrefixEntry
|
||||
{
|
||||
SegCachePrefixEntry(const SegCachePrefixEntry &);
|
||||
SegCachePrefixEntry & operator = (const SegCachePrefixEntry &);
|
||||
|
||||
public:
|
||||
SegCachePrefixEntry() : m_lastPurge(0)
|
||||
{
|
||||
memset(m_entryCounts, 0, sizeof m_entryCounts);
|
||||
memset(m_entryBSIndex, 0, sizeof m_entryBSIndex);
|
||||
memset(m_entries, 0, sizeof m_entries);
|
||||
}
|
||||
|
||||
~SegCachePrefixEntry()
|
||||
{
|
||||
for (size_t j = 0; j < eMaxSpliceSize; j++)
|
||||
{
|
||||
if (m_entryCounts[j])
|
||||
{
|
||||
assert(m_entries[j]);
|
||||
for (size_t k = 0; k < m_entryCounts[j]; k++)
|
||||
m_entries[j][k].clear();
|
||||
|
||||
free(m_entries[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
const SegCacheEntry * find(const uint16 * cmapGlyphs, size_t length) const
|
||||
{
|
||||
if (length <= ePrefixLength)
|
||||
{
|
||||
assert(m_entryCounts[length-1] <= 1);
|
||||
if (m_entries[length-1])
|
||||
return m_entries[length-1];
|
||||
return NULL;
|
||||
}
|
||||
SegCacheEntry * entry = NULL;
|
||||
findPosition(cmapGlyphs, length, &entry);
|
||||
return entry;
|
||||
}
|
||||
SegCacheEntry * cache(const uint16* cmapGlyphs, size_t length, Segment * seg, size_t charOffset, unsigned long long totalAccessCount)
|
||||
{
|
||||
size_t listSize = m_entryBSIndex[length-1]? (m_entryBSIndex[length-1] << 1) - 1 : 0;
|
||||
SegCacheEntry * newEntries = NULL;
|
||||
if (m_entryCounts[length-1] + 1u > listSize)
|
||||
{
|
||||
if (m_entryCounts[length-1] == 0)
|
||||
listSize = 1;
|
||||
else
|
||||
{
|
||||
// the problem comes when you get incremental numeric ids in a large doc
|
||||
if (listSize >= eMaxSuffixCount)
|
||||
return NULL;
|
||||
listSize = (m_entryBSIndex[length-1] << 2) - 1;
|
||||
}
|
||||
newEntries = gralloc<SegCacheEntry>(listSize);
|
||||
if (!newEntries)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint16 insertPos = 0;
|
||||
if (m_entryCounts[length-1] > 0)
|
||||
{
|
||||
insertPos = findPosition(cmapGlyphs, length, NULL);
|
||||
if (!newEntries)
|
||||
{
|
||||
// same buffer, shift entries up
|
||||
memmove(m_entries[length-1] + insertPos + 1, m_entries[length-1] + insertPos,
|
||||
sizeof(SegCacheEntry) * (m_entryCounts[length-1] - insertPos));
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(newEntries, m_entries[length-1], sizeof(SegCacheEntry) * (insertPos));
|
||||
memcpy(newEntries + insertPos + 1, m_entries[length-1] + insertPos,
|
||||
sizeof(SegCacheEntry) * (m_entryCounts[length-1] - insertPos));
|
||||
|
||||
free(m_entries[length-1]);
|
||||
m_entries[length-1] = newEntries;
|
||||
assert (m_entryBSIndex[length-1]);
|
||||
m_entryBSIndex[length-1] <<= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_entryBSIndex[length-1] = 1;
|
||||
m_entries[length-1] = newEntries;
|
||||
}
|
||||
m_entryCounts[length-1] += 1;
|
||||
new (m_entries[length-1] + insertPos)
|
||||
SegCacheEntry(cmapGlyphs, length, seg, charOffset, totalAccessCount);
|
||||
return m_entries[length-1] + insertPos;
|
||||
}
|
||||
uint32 purge(unsigned long long minAccessCount, unsigned long long oldAccessTime,
|
||||
unsigned long long currentTime);
|
||||
CLASS_NEW_DELETE
|
||||
private:
|
||||
uint16 findPosition(const uint16 * cmapGlyphs, uint16 length, SegCacheEntry ** entry) const
|
||||
{
|
||||
int dir = 0;
|
||||
if (m_entryCounts[length-1] == 0)
|
||||
{
|
||||
if (entry) *entry = NULL;
|
||||
return 0;
|
||||
}
|
||||
else if (m_entryCounts[length-1] == 1)
|
||||
{
|
||||
// optimize single entry case
|
||||
for (int i = ePrefixLength; i < length; i++)
|
||||
{
|
||||
if (cmapGlyphs[i] > m_entries[length-1][0].m_unicode[i])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (cmapGlyphs[i] < m_entries[length-1][0].m_unicode[i])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (entry)
|
||||
*entry = m_entries[length-1];
|
||||
return 0;
|
||||
}
|
||||
uint16 searchIndex = m_entryBSIndex[length-1] - 1;
|
||||
uint16 stepSize = m_entryBSIndex[length-1] >> 1;
|
||||
size_t prevIndex = searchIndex;
|
||||
do
|
||||
{
|
||||
dir = 0;
|
||||
if (searchIndex >= m_entryCounts[length-1])
|
||||
{
|
||||
dir = -1;
|
||||
searchIndex -= stepSize;
|
||||
stepSize >>= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = ePrefixLength; i < length; i++)
|
||||
{
|
||||
if (cmapGlyphs[i] > m_entries[length-1][searchIndex].m_unicode[i])
|
||||
{
|
||||
dir = 1;
|
||||
searchIndex += stepSize;
|
||||
stepSize >>= 1;
|
||||
break;
|
||||
}
|
||||
else if (cmapGlyphs[i] < m_entries[length-1][searchIndex].m_unicode[i])
|
||||
{
|
||||
dir = -1;
|
||||
searchIndex -= stepSize;
|
||||
stepSize >>= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (prevIndex == searchIndex)
|
||||
break;
|
||||
prevIndex = searchIndex;
|
||||
} while (dir != 0);
|
||||
if (entry)
|
||||
{
|
||||
if (dir == 0)
|
||||
*entry = m_entries[length-1] + searchIndex;
|
||||
else
|
||||
*entry = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if entry is null, then this is for inserting a new value, which
|
||||
// shouldn't already be in the cache
|
||||
assert(dir != 0);
|
||||
if (dir > 0)
|
||||
++searchIndex;
|
||||
}
|
||||
return searchIndex;
|
||||
}
|
||||
/** m_entries is a null terminated list of entries */
|
||||
uint16 m_entryCounts[eMaxSpliceSize];
|
||||
uint16 m_entryBSIndex[eMaxSpliceSize];
|
||||
SegCacheEntry * m_entries[eMaxSpliceSize];
|
||||
unsigned long long m_lastPurge;
|
||||
};
|
||||
|
||||
|
||||
#define SEG_CACHE_MIN_INDEX (store->maxCmapGid())
|
||||
#define SEG_CACHE_MAX_INDEX (store->maxCmapGid()+1u)
|
||||
#define SEG_CACHE_UNSET_INDEX (store->maxCmapGid()+2u)
|
||||
|
||||
union SegCachePrefixArray
|
||||
{
|
||||
void ** raw;
|
||||
SegCachePrefixArray * array;
|
||||
SegCachePrefixEntry ** prefixEntries;
|
||||
uintptr * range;
|
||||
};
|
||||
|
||||
class SegCache
|
||||
{
|
||||
public:
|
||||
SegCache(const SegCacheStore * store, const Features& features);
|
||||
~SegCache();
|
||||
|
||||
const SegCacheEntry * find(const uint16 * cmapGlyphs, size_t length) const;
|
||||
SegCacheEntry * cache(SegCacheStore * store, const uint16 * cmapGlyphs, size_t length, Segment * seg, size_t charOffset);
|
||||
void purge(SegCacheStore * store);
|
||||
|
||||
long long totalAccessCount() const { return m_totalAccessCount; }
|
||||
size_t segmentCount() const { return m_segmentCount; }
|
||||
const Features & features() const { return m_features; }
|
||||
void clear(SegCacheStore * store);
|
||||
|
||||
CLASS_NEW_DELETE
|
||||
private:
|
||||
void freeLevel(SegCacheStore * store, SegCachePrefixArray prefixes, size_t level);
|
||||
void purgeLevel(SegCacheStore * store, SegCachePrefixArray prefixes, size_t level,
|
||||
unsigned long long minAccessCount, unsigned long long oldAccessTime);
|
||||
|
||||
uint16 m_prefixLength;
|
||||
// uint16 m_maxCachedSegLength;
|
||||
size_t m_segmentCount;
|
||||
SegCachePrefixArray m_prefixes;
|
||||
Features m_features;
|
||||
mutable unsigned long long m_totalAccessCount;
|
||||
mutable unsigned long long m_totalMisses;
|
||||
float m_purgeFactor;
|
||||
};
|
||||
|
||||
inline const SegCacheEntry * SegCache::find(const uint16 * cmapGlyphs, size_t length) const
|
||||
{
|
||||
uint16 pos = 0;
|
||||
if (!length || length > eMaxSpliceSize) return NULL;
|
||||
SegCachePrefixArray pEntry = m_prefixes.array[cmapGlyphs[0]];
|
||||
while (++pos < m_prefixLength - 1)
|
||||
{
|
||||
if (!pEntry.raw)
|
||||
{
|
||||
++m_totalMisses;
|
||||
return NULL;
|
||||
}
|
||||
pEntry = pEntry.array[(pos < length)? cmapGlyphs[pos] : 0];
|
||||
}
|
||||
if (!pEntry.raw)
|
||||
{
|
||||
++m_totalMisses;
|
||||
return NULL;
|
||||
}
|
||||
SegCachePrefixEntry * prefixEntry = pEntry.prefixEntries[(pos < length)? cmapGlyphs[pos] : 0];
|
||||
if (!prefixEntry)
|
||||
{
|
||||
++m_totalMisses;
|
||||
return NULL;
|
||||
}
|
||||
const SegCacheEntry * entry = prefixEntry->find(cmapGlyphs, length);
|
||||
if (entry)
|
||||
{
|
||||
++m_totalAccessCount;
|
||||
entry->accessed(m_totalAccessCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
++m_totalMisses;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
} // namespace graphite2
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
/* GRAPHITE2 LICENSING
|
||||
|
||||
Copyright 2010, SIL International
|
||||
All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should also have received a copy of the GNU Lesser General Public
|
||||
License along with this library in the file named "LICENSE".
|
||||
If not, write to the Free Software Foundation, 51 Franklin Street,
|
||||
Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
|
||||
internet at http://www.fsf.org/licenses/lgpl.html.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of the
|
||||
Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
|
||||
License, as published by the Free Software Foundation, either version 2
|
||||
of the License or (at your option) any later version.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef GRAPHITE2_NSEGCACHE
|
||||
|
||||
#include "inc/Main.h"
|
||||
#include "inc/Slot.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class Segment;
|
||||
class Slot;
|
||||
class SegCacheEntry;
|
||||
class SegCachePrefixEntry;
|
||||
|
||||
enum SegCacheParameters {
|
||||
/** number of characters used in initial prefix tree */
|
||||
ePrefixLength = 2,
|
||||
/** Segments more recent than maxSegmentCount() / eAgeFactor are kept */
|
||||
eAgeFactor = 4,
|
||||
/** Segments are purged according to the formular:
|
||||
* accessCount < (totalAccesses)/(ePurgeFactor * maxSegments) */
|
||||
ePurgeFactor = 5,
|
||||
/** Maximum number of Segments to store which have the same
|
||||
* prefix. Needed to prevent unique identifiers flooding the cache */
|
||||
eMaxSuffixCount = 15
|
||||
|
||||
};
|
||||
|
||||
class SegCacheCharInfo
|
||||
{
|
||||
public:
|
||||
uint16 m_unicode;
|
||||
uint16 m_before;
|
||||
uint16 m_after;
|
||||
};
|
||||
|
||||
/**
|
||||
* SegCacheEntry stores the result of running the engine for specific unicode
|
||||
* code points in the typical mid-line situation.
|
||||
*/
|
||||
class SegCacheEntry
|
||||
{
|
||||
// Prevent any implict copying;
|
||||
SegCacheEntry(const SegCacheEntry &);
|
||||
SegCacheEntry & operator = (const SegCacheEntry &);
|
||||
|
||||
friend class SegCachePrefixEntry;
|
||||
public:
|
||||
SegCacheEntry() :
|
||||
m_glyphLength(0), m_unicode(NULL), m_glyph(NULL), m_attr(NULL), m_justs(0),
|
||||
m_accessCount(0), m_lastAccess(0)
|
||||
{}
|
||||
SegCacheEntry(const uint16 * cmapGlyphs, size_t length, Segment * seg, size_t charOffset, long long cacheTime);
|
||||
~SegCacheEntry() { clear(); };
|
||||
void clear();
|
||||
size_t glyphLength() const { return m_glyphLength; }
|
||||
const Slot * first() const { return m_glyph; }
|
||||
const Slot * last() const { return m_glyph + (m_glyphLength - 1); }
|
||||
|
||||
/** Total number of times this entry has been accessed since creation */
|
||||
unsigned long long accessCount() const { return m_accessCount; }
|
||||
/** "time" of last access where "time" is measured in accesses to the cache owning this entry */
|
||||
void accessed(unsigned long long cacheTime) const
|
||||
{
|
||||
m_lastAccess = cacheTime; ++m_accessCount;
|
||||
};
|
||||
|
||||
int compareRank(const SegCacheEntry & entry) const
|
||||
{
|
||||
if (m_accessCount > entry.m_accessCount) return 1;
|
||||
else if (m_accessCount < entry.m_accessCount) return 1;
|
||||
else if (m_lastAccess > entry.m_lastAccess) return 1;
|
||||
else if (m_lastAccess < entry.m_lastAccess) return -1;
|
||||
return 0;
|
||||
}
|
||||
unsigned long long lastAccess() const { return m_lastAccess; };
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
private:
|
||||
|
||||
size_t m_glyphLength;
|
||||
/** glyph ids resulting from cmap mapping from unicode to glyph before substitution
|
||||
* the length of this array is determined by the position in the SegCachePrefixEntry */
|
||||
uint16 * m_unicode;
|
||||
/** slots after shapping and positioning */
|
||||
Slot * m_glyph;
|
||||
int16 * m_attr;
|
||||
byte * m_justs;
|
||||
mutable unsigned long long m_accessCount;
|
||||
mutable unsigned long long m_lastAccess;
|
||||
};
|
||||
|
||||
} // namespace graphite2
|
||||
|
||||
#endif
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
/* GRAPHITE2 LICENSING
|
||||
|
||||
Copyright 2010, SIL International
|
||||
All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should also have received a copy of the GNU Lesser General Public
|
||||
License along with this library in the file named "LICENSE".
|
||||
If not, write to the Free Software Foundation, 51 Franklin Street,
|
||||
Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
|
||||
internet at http://www.fsf.org/licenses/lgpl.html.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of the
|
||||
Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
|
||||
License, as published by the Free Software Foundation, either version 2
|
||||
of the License or (at your option) any later version.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef GRAPHITE2_NSEGCACHE
|
||||
|
||||
#include "inc/Main.h"
|
||||
#include "inc/CmapCache.h"
|
||||
#include "inc/SegCache.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
class SegCache;
|
||||
class Face;
|
||||
|
||||
class SilfSegCache
|
||||
{
|
||||
SilfSegCache(const SilfSegCache &);
|
||||
SilfSegCache & operator = (const SilfSegCache &);
|
||||
|
||||
public:
|
||||
SilfSegCache() : m_caches(NULL), m_cacheCount(0) {};
|
||||
~SilfSegCache()
|
||||
{
|
||||
assert(m_caches == NULL);
|
||||
}
|
||||
void clear(SegCacheStore * cacheStore)
|
||||
{
|
||||
for (size_t i = 0; i < m_cacheCount; i++)
|
||||
{
|
||||
m_caches[i]->clear(cacheStore);
|
||||
delete m_caches[i];
|
||||
}
|
||||
free(m_caches);
|
||||
m_caches = NULL;
|
||||
m_cacheCount = 0;
|
||||
}
|
||||
SegCache * getOrCreate(SegCacheStore * cacheStore, const Features & features)
|
||||
{
|
||||
for (size_t i = 0; i < m_cacheCount; i++)
|
||||
{
|
||||
if (m_caches[i]->features() == features)
|
||||
return m_caches[i];
|
||||
}
|
||||
SegCache ** newData = gralloc<SegCache*>(m_cacheCount+1);
|
||||
if (newData)
|
||||
{
|
||||
if (m_cacheCount > 0)
|
||||
{
|
||||
memcpy(newData, m_caches, sizeof(SegCache*) * m_cacheCount);
|
||||
free(m_caches);
|
||||
}
|
||||
m_caches = newData;
|
||||
m_caches[m_cacheCount] = new SegCache(cacheStore, features);
|
||||
m_cacheCount++;
|
||||
return m_caches[m_cacheCount - 1];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
CLASS_NEW_DELETE
|
||||
private:
|
||||
SegCache ** m_caches;
|
||||
size_t m_cacheCount;
|
||||
};
|
||||
|
||||
class SegCacheStore
|
||||
{
|
||||
SegCacheStore(const SegCacheStore &);
|
||||
SegCacheStore & operator = (const SegCacheStore &);
|
||||
|
||||
public:
|
||||
SegCacheStore(const Face & face, unsigned int numSilf, size_t maxSegments);
|
||||
~SegCacheStore()
|
||||
{
|
||||
for (size_t i = 0; i < m_numSilf; i++)
|
||||
{
|
||||
m_caches[i].clear(this);
|
||||
}
|
||||
delete [] m_caches;
|
||||
m_caches = NULL;
|
||||
}
|
||||
SegCache * getOrCreate(unsigned int i, const Features & features)
|
||||
{
|
||||
return m_caches[i].getOrCreate(this, features);
|
||||
}
|
||||
bool isSpaceGlyph(uint16 gid) const { return (gid == m_spaceGid) || (gid == m_zwspGid); }
|
||||
uint16 maxCmapGid() const { return m_maxCmapGid; }
|
||||
uint32 maxSegmentCount() const { return m_maxSegments; };
|
||||
|
||||
CLASS_NEW_DELETE
|
||||
private:
|
||||
SilfSegCache * m_caches;
|
||||
uint8 m_numSilf;
|
||||
uint32 m_maxSegments;
|
||||
uint16 m_maxCmapGid;
|
||||
uint16 m_spaceGid;
|
||||
uint16 m_zwspGid;
|
||||
};
|
||||
|
||||
} // namespace graphite2
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -49,9 +49,6 @@ typedef Vector<Slot *> SlotRope;
|
|||
typedef Vector<int16 *> AttributeRope;
|
||||
typedef Vector<SlotJustify *> JustifyRope;
|
||||
|
||||
#ifndef GRAPHITE2_NSEGCACHE
|
||||
class SegmentScopeState;
|
||||
#endif
|
||||
class Font;
|
||||
class Segment;
|
||||
class Silf;
|
||||
|
|
@ -91,26 +88,18 @@ public:
|
|||
SEG_HASCOLLISIONS = 2
|
||||
};
|
||||
|
||||
unsigned int slotCount() const { return m_numGlyphs; } //one slot per glyph
|
||||
void extendLength(int num) { m_numGlyphs += num; }
|
||||
size_t slotCount() const { return m_numGlyphs; } //one slot per glyph
|
||||
void extendLength(ptrdiff_t num) { m_numGlyphs += num; }
|
||||
Position advance() const { return m_advance; }
|
||||
bool runGraphite() { if (m_silf) return m_face->runGraphite(this, m_silf); else return true;};
|
||||
void chooseSilf(uint32 script) { m_silf = m_face->chooseSilf(script); }
|
||||
const Silf *silf() const { return m_silf; }
|
||||
unsigned int charInfoCount() const { return m_numCharinfo; }
|
||||
size_t charInfoCount() const { return m_numCharinfo; }
|
||||
const CharInfo *charinfo(unsigned int index) const { return index < m_numCharinfo ? m_charinfo + index : NULL; }
|
||||
CharInfo *charinfo(unsigned int index) { return index < m_numCharinfo ? m_charinfo + index : NULL; }
|
||||
|
||||
Segment(unsigned int numchars, const Face* face, uint32 script, int dir);
|
||||
Segment(size_t numchars, const Face* face, uint32 script, int dir);
|
||||
~Segment();
|
||||
#ifndef GRAPHITE2_NSEGCACHE
|
||||
SegmentScopeState setScope(Slot * firstSlot, Slot * lastSlot, size_t subLength);
|
||||
void removeScope(SegmentScopeState & state);
|
||||
void append(const Segment &other);
|
||||
void splice(size_t offset, size_t length, Slot * const startSlot,
|
||||
Slot * endSlot, const Slot * srcSlot,
|
||||
const size_t numGlyphs);
|
||||
#endif
|
||||
uint8 flags() const { return m_flags; }
|
||||
void flags(uint8 f) { m_flags = f; }
|
||||
Slot *first() { return m_first; }
|
||||
|
|
@ -123,11 +112,11 @@ public:
|
|||
SlotJustify *newJustify();
|
||||
void freeJustify(SlotJustify *aJustify);
|
||||
Position positionSlots(const Font *font=0, Slot *first=0, Slot *last=0, bool isRtl = false, bool isFinal = true);
|
||||
void associateChars(int offset, int num);
|
||||
void associateChars(int offset, size_t num);
|
||||
void linkClusters(Slot *first, Slot *last);
|
||||
uint16 getClassGlyph(uint16 cid, uint16 offset) const { return m_silf->getClassGlyph(cid, offset); }
|
||||
uint16 findClassIndex(uint16 cid, uint16 gid) const { return m_silf->findClassIndex(cid, gid); }
|
||||
int addFeatures(const Features& feats) { m_feats.push_back(feats); return m_feats.size() - 1; }
|
||||
int addFeatures(const Features& feats) { m_feats.push_back(feats); return int(m_feats.size()) - 1; }
|
||||
uint32 getFeature(int index, uint8 findex) const { const FeatureRef* pFR=m_face->theSill().theFeatureMap().featureRef(findex); if (!pFR) return 0; else return pFR->getFeatureVal(m_feats[index]); }
|
||||
void setFeature(int index, uint8 findex, uint32 val) {
|
||||
const FeatureRef* pFR=m_face->theSill().theFeatureMap().featureRef(findex);
|
||||
|
|
@ -139,8 +128,8 @@ public:
|
|||
int8 dir() const { return m_dir; }
|
||||
void dir(int8 val) { m_dir = val; }
|
||||
bool currdir() const { return ((m_dir >> 6) ^ m_dir) & 1; }
|
||||
unsigned int passBits() const { return m_passBits; }
|
||||
void mergePassBits(const unsigned int val) { m_passBits &= val; }
|
||||
uint8 passBits() const { return m_passBits; }
|
||||
void mergePassBits(const uint8 val) { m_passBits &= val; }
|
||||
int16 glyphAttr(uint16 gid, uint16 gattr) const { const GlyphFace * p = m_face->glyphs().glyphSafe(gid); return p ? p->attrs()[gattr] : 0; }
|
||||
int32 getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel, bool rtl) const;
|
||||
float glyphAdvance(uint16 gid) const { return m_face->glyphs().glyph(gid)->theAdvance().x; }
|
||||
|
|
@ -183,13 +172,13 @@ private:
|
|||
const Silf * m_silf;
|
||||
Slot * m_first; // first slot in segment
|
||||
Slot * m_last; // last slot in segment
|
||||
unsigned int m_bufSize, // how big a buffer to create when need more slots
|
||||
size_t m_bufSize, // how big a buffer to create when need more slots
|
||||
m_numGlyphs,
|
||||
m_numCharinfo, // size of the array and number of input characters
|
||||
m_passBits; // if bit set then skip pass
|
||||
m_numCharinfo; // size of the array and number of input characters
|
||||
int m_defaultOriginal; // number of whitespace chars in the string
|
||||
int8 m_dir;
|
||||
uint8 m_flags; // General purpose flags
|
||||
uint8 m_flags, // General purpose flags
|
||||
m_passBits; // if bit set then skip pass
|
||||
};
|
||||
|
||||
inline
|
||||
|
|
@ -245,4 +234,3 @@ bool Segment::isWhitespace(const int cid) const
|
|||
} // namespace graphite2
|
||||
|
||||
struct gr_segment : public graphite2::Segment {};
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ namespace graphite2 {
|
|||
typedef gr_attrCode attrCode;
|
||||
|
||||
class GlyphFace;
|
||||
class SegCacheEntry;
|
||||
class Segment;
|
||||
|
||||
struct SlotJustify
|
||||
|
|
@ -163,7 +162,6 @@ private:
|
|||
int16 *m_userAttr; // pointer to user attributes
|
||||
SlotJustify *m_justs; // pointer to justification parameters
|
||||
|
||||
friend class SegCacheEntry;
|
||||
friend class Segment;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ sparse::sparse(I attr, const I last)
|
|||
if (ci != ci_)
|
||||
{
|
||||
ci = ci_;
|
||||
ci->offset = vi - m_array.values;
|
||||
ci->offset = key_type(vi - m_array.values);
|
||||
}
|
||||
|
||||
ci->mask |= 1UL << (SIZEOF_CHUNK - 1 - (v.first % SIZEOF_CHUNK));
|
||||
|
|
|
|||
|
|
@ -79,9 +79,9 @@ enum
|
|||
//**********************************************************************************************
|
||||
namespace Sfnt
|
||||
{
|
||||
#pragma pack(1) // We need this or the structure members aren't alligned
|
||||
#pragma pack(1) // We need this or the structure members aren't aligned
|
||||
// correctly. Fortunately this form of pragma is supposed
|
||||
// to be recongnised by VS C++ too (at least according to
|
||||
// to be recognised by VS C++ too (at least according to
|
||||
// MSDN).
|
||||
|
||||
struct OffsetSubTable
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ namespace graphite2
|
|||
namespace TtfUtil
|
||||
{
|
||||
|
||||
#define OVERFLOW_OFFSET_CHECK(p, o) (o + reinterpret_cast<size_t>(p) < reinterpret_cast<size_t>(p))
|
||||
|
||||
typedef long fontTableId32;
|
||||
typedef unsigned short gid16;
|
||||
|
||||
|
|
@ -51,12 +53,12 @@ typedef unsigned short gid16;
|
|||
// Enumeration used to specify a table in a TTF file
|
||||
class Tag
|
||||
{
|
||||
unsigned long _v;
|
||||
unsigned int _v;
|
||||
public:
|
||||
Tag(const char n[5]) throw() : _v(TTF_TAG(n[0],n[1],n[2],n[3])) {}
|
||||
Tag(const unsigned long tag) throw() : _v(tag) {}
|
||||
Tag(const unsigned int tag) throw() : _v(tag) {}
|
||||
|
||||
operator unsigned long () const throw () { return _v; }
|
||||
operator unsigned int () const throw () { return _v; }
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ struct _utf_codec
|
|||
|
||||
static void put(codeunit_t * cp, const uchar_t , int8 & len) throw();
|
||||
static uchar_t get(const codeunit_t * cp, int8 & len) throw();
|
||||
static bool validate(const codeunit_t * s, const codeunit_t * e) throw();
|
||||
static bool validate(const codeunit_t * s, const codeunit_t * const e) throw();
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -66,9 +66,9 @@ public:
|
|||
}
|
||||
|
||||
inline
|
||||
static bool validate(codeunit_t * s, codeunit_t * e) throw()
|
||||
static bool validate(const codeunit_t * s, const codeunit_t * const e) throw()
|
||||
{
|
||||
return e > s;
|
||||
return s <= e;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -101,18 +101,19 @@ public:
|
|||
l = 1;
|
||||
|
||||
if (uh < 0xD800|| uh > 0xDFFF) { return uh; }
|
||||
if (uh > 0xDBFF) { l = -1; return 0xFFFD; }
|
||||
const uint32 ul = cp[1];
|
||||
if (uh > 0xDBFF || ul < 0xDC00 || ul > 0xDFFF) { l = -1; return 0xFFFD; }
|
||||
if (ul < 0xDC00 || ul > 0xDFFF) { l = -1; return 0xFFFD; }
|
||||
++l;
|
||||
return (uh<<10) + ul + surrogate_offset;
|
||||
}
|
||||
|
||||
inline
|
||||
static bool validate(codeunit_t * s, codeunit_t * e) throw()
|
||||
static bool validate(const codeunit_t * s, const codeunit_t * const e) throw()
|
||||
{
|
||||
const ptrdiff_t n = e-s;
|
||||
if (n <= 0) return n == 0;
|
||||
const uint32 u = *(s+(n-1)); // Get the last codepoint
|
||||
const uint32 u = *(e-1); // Get the last codepoint
|
||||
return (u < 0xD800 || u > 0xDBFF);
|
||||
}
|
||||
};
|
||||
|
|
@ -166,7 +167,7 @@ public:
|
|||
}
|
||||
|
||||
inline
|
||||
static bool validate(codeunit_t * s, codeunit_t * e) throw()
|
||||
static bool validate(const codeunit_t * s, const codeunit_t * const e) throw()
|
||||
{
|
||||
const ptrdiff_t n = e-s;
|
||||
if (n <= 0) return n == 0;
|
||||
|
|
@ -175,7 +176,7 @@ public:
|
|||
if (*s >= 0xC0) return false;
|
||||
if (n == 1) return true;
|
||||
if (*--s < 0x80) return true;
|
||||
if (*s >= 0xe0) return false;
|
||||
if (*s >= 0xE0) return false;
|
||||
if (n == 2 || *s >= 0xC0) return true;
|
||||
if (*--s < 0x80) return true;
|
||||
if (*s >= 0xF0) return false;
|
||||
|
|
@ -225,6 +226,7 @@ public:
|
|||
operator codeunit_type * () const throw() { return cp; }
|
||||
|
||||
bool error() const throw() { return sl < 1; }
|
||||
bool validate(const _utf_iterator & e) { return codec::validate(cp, e.cp); }
|
||||
};
|
||||
|
||||
template <typename C>
|
||||
|
|
|
|||
|
|
@ -73,30 +73,34 @@ inline unsigned int bit_set_count(signed long long v)
|
|||
{
|
||||
return __builtin_popcountll(v);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<typename T>
|
||||
inline unsigned int bit_set_count(T v)
|
||||
{
|
||||
v = v - ((v >> 1) & T(~(0UL)/3)); // temp
|
||||
v = (v & T(~(0UL)/15*3)) + ((v >> 2) & T(~(0UL)/15*3)); // temp
|
||||
v = (v + (v >> 4)) & T(~(0UL)/255*15); // temp
|
||||
return (T)(v * T(~(0UL)/255)) >> (sizeof(T)-1)*8; // count
|
||||
static size_t const ONES = ~0;
|
||||
|
||||
v = v - ((v >> 1) & T(ONES/3)); // temp
|
||||
v = (v & T(ONES/15*3)) + ((v >> 2) & T(ONES/15*3)); // temp
|
||||
v = (v + (v >> 4)) & T(ONES/255*15); // temp
|
||||
return (T)(v * T(ONES/255)) >> (sizeof(T)-1)*8; // count
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//TODO: Changed these to uintmax_t when we go to C++11
|
||||
template<int S>
|
||||
inline unsigned long _mask_over_val(unsigned long v)
|
||||
inline size_t _mask_over_val(size_t v)
|
||||
{
|
||||
v = _mask_over_val<S/2>(v);
|
||||
v |= v >> S*4;
|
||||
return v;
|
||||
}
|
||||
|
||||
//TODO: Changed these to uintmax_t when we go to C++11
|
||||
template<>
|
||||
inline unsigned long _mask_over_val<1>(unsigned long v)
|
||||
inline size_t _mask_over_val<1>(size_t v)
|
||||
{
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
|
|
@ -107,7 +111,7 @@ inline unsigned long _mask_over_val<1>(unsigned long v)
|
|||
template<typename T>
|
||||
inline T mask_over_val(T v)
|
||||
{
|
||||
return _mask_over_val<sizeof(T)>(v);
|
||||
return T(_mask_over_val<sizeof(T)>(v));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ of the License or (at your option) any later version.
|
|||
#include "inc/Main.h"
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include "inc/List.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
|
@ -44,7 +45,6 @@ class json
|
|||
json & operator = (const json &);
|
||||
|
||||
typedef void (*_context_t)(json &);
|
||||
class _null_t {};
|
||||
|
||||
FILE * const _stream;
|
||||
char _contexts[128], // context stack
|
||||
|
|
@ -61,11 +61,12 @@ class json
|
|||
public:
|
||||
class closer;
|
||||
|
||||
typedef const char * string;
|
||||
typedef double number;
|
||||
typedef long signed int integer;
|
||||
typedef bool boolean;
|
||||
static const _null_t null;
|
||||
using string = const char *;
|
||||
using number = double;
|
||||
enum class integer : std::intmax_t {};
|
||||
enum class integer_u : std::uintmax_t {};
|
||||
using boolean = bool;
|
||||
static const std::nullptr_t null;
|
||||
|
||||
void setenv(unsigned int index, void *val) { _env.reserve(index + 1); if (index >= _env.size()) _env.insert(_env.end(), _env.size() - index + 1, 0); _env[index] = val; }
|
||||
void *getenv(unsigned int index) const { return _env[index]; }
|
||||
|
|
@ -85,9 +86,9 @@ public:
|
|||
json & operator << (string) throw();
|
||||
json & operator << (number) throw();
|
||||
json & operator << (integer) throw();
|
||||
json & operator << (long unsigned int d) throw();
|
||||
json & operator << (integer_u) throw();
|
||||
json & operator << (boolean) throw();
|
||||
json & operator << (_null_t) throw();
|
||||
json & operator << (std::nullptr_t) throw();
|
||||
json & operator << (_context_t) throw();
|
||||
|
||||
operator bool() const throw();
|
||||
|
|
@ -139,26 +140,31 @@ inline
|
|||
json & operator << (json & j, signed char d) throw() { return j << json::integer(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, short signed int d) throw() { return j << json::integer(d); }
|
||||
json & operator << (json & j, unsigned char d) throw() { return j << json::integer_u(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, signed int d) throw() { return j << json::integer(d); }
|
||||
json & operator << (json & j, short int d) throw() { return j << json::integer(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, unsigned char d) throw() { return j << json::integer(d); }
|
||||
json & operator << (json & j, unsigned short int d) throw() { return j << json::integer_u(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, short unsigned int d) throw() { return j << json::integer(d); }
|
||||
json & operator << (json & j, int d) throw() { return j << json::integer(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, unsigned int d) throw() { return j << json::integer(d); }
|
||||
json & operator << (json & j, unsigned int d) throw() { return j << json::integer_u(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, char c) throw ()
|
||||
{
|
||||
const char str[2] = {c,0};
|
||||
return j << str;
|
||||
}
|
||||
json & operator << (json & j, long int d) throw() { return j << json::integer(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, unsigned long int d) throw() { return j << json::integer_u(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, long long int d) throw() { return j << json::integer(d); }
|
||||
|
||||
inline
|
||||
json & operator << (json & j, unsigned long long int d) throw() { return j << json::integer_u(d); }
|
||||
|
||||
inline
|
||||
json::operator bool() const throw() { return good(); }
|
||||
|
|
|
|||
|
|
@ -122,4 +122,3 @@ static const opcode_t opcode_table[] =
|
|||
// private opcodes for internal use only, comes after all other on disk opcodes.
|
||||
{{do_(temp_copy), NILOP}, 0, "TEMP_COPY"}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -387,49 +387,49 @@ ENDOP
|
|||
STARTOP(attr_set)
|
||||
declare_params(1);
|
||||
const attrCode slat = attrCode(uint8(*param));
|
||||
const int val = int(pop());
|
||||
const int val = pop();
|
||||
is->setAttr(&seg, slat, 0, val, smap);
|
||||
ENDOP
|
||||
|
||||
STARTOP(attr_add)
|
||||
declare_params(1);
|
||||
const attrCode slat = attrCode(uint8(*param));
|
||||
const int val = int(pop());
|
||||
const uint32_t val = pop();
|
||||
if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
|
||||
{
|
||||
seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
|
||||
flags |= POSITIONED;
|
||||
}
|
||||
int res = is->getAttr(&seg, slat, 0);
|
||||
is->setAttr(&seg, slat, 0, val + res, smap);
|
||||
uint32_t res = uint32_t(is->getAttr(&seg, slat, 0));
|
||||
is->setAttr(&seg, slat, 0, int32_t(val + res), smap);
|
||||
ENDOP
|
||||
|
||||
STARTOP(attr_sub)
|
||||
declare_params(1);
|
||||
const attrCode slat = attrCode(uint8(*param));
|
||||
const int val = int(pop());
|
||||
const uint32_t val = pop();
|
||||
if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
|
||||
{
|
||||
seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
|
||||
flags |= POSITIONED;
|
||||
}
|
||||
int res = is->getAttr(&seg, slat, 0);
|
||||
is->setAttr(&seg, slat, 0, res - val, smap);
|
||||
uint32_t res = uint32_t(is->getAttr(&seg, slat, 0));
|
||||
is->setAttr(&seg, slat, 0, int32_t(res - val), smap);
|
||||
ENDOP
|
||||
|
||||
STARTOP(attr_set_slot)
|
||||
declare_params(1);
|
||||
const attrCode slat = attrCode(uint8(*param));
|
||||
const int offset = (map - smap.begin())*int(slat == gr_slatAttTo);
|
||||
const int val = int(pop()) + offset;
|
||||
const int offset = int(map - smap.begin())*int(slat == gr_slatAttTo);
|
||||
const int val = pop() + offset;
|
||||
is->setAttr(&seg, slat, offset, val, smap);
|
||||
ENDOP
|
||||
|
||||
STARTOP(iattr_set_slot)
|
||||
declare_params(2);
|
||||
const attrCode slat = attrCode(uint8(param[0]));
|
||||
const size_t idx = uint8(param[1]);
|
||||
const int val = int(pop()) + (map - smap.begin())*int(slat == gr_slatAttTo);
|
||||
const uint8 idx = uint8(param[1]);
|
||||
const int val = int(pop() + (map - smap.begin())*int(slat == gr_slatAttTo));
|
||||
is->setAttr(&seg, slat, idx, val, smap);
|
||||
ENDOP
|
||||
|
||||
|
|
@ -548,37 +548,37 @@ ENDOP
|
|||
STARTOP(iattr_set)
|
||||
declare_params(2);
|
||||
const attrCode slat = attrCode(uint8(param[0]));
|
||||
const size_t idx = uint8(param[1]);
|
||||
const int val = int(pop());
|
||||
const uint8 idx = uint8(param[1]);
|
||||
const int val = pop();
|
||||
is->setAttr(&seg, slat, idx, val, smap);
|
||||
ENDOP
|
||||
|
||||
STARTOP(iattr_add)
|
||||
declare_params(2);
|
||||
const attrCode slat = attrCode(uint8(param[0]));
|
||||
const size_t idx = uint8(param[1]);
|
||||
const int val = int(pop());
|
||||
const uint8 idx = uint8(param[1]);
|
||||
const uint32_t val = pop();
|
||||
if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
|
||||
{
|
||||
seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
|
||||
flags |= POSITIONED;
|
||||
}
|
||||
int res = is->getAttr(&seg, slat, idx);
|
||||
is->setAttr(&seg, slat, idx, val + res, smap);
|
||||
uint32_t res = uint32_t(is->getAttr(&seg, slat, idx));
|
||||
is->setAttr(&seg, slat, idx, int32_t(val + res), smap);
|
||||
ENDOP
|
||||
|
||||
STARTOP(iattr_sub)
|
||||
declare_params(2);
|
||||
const attrCode slat = attrCode(uint8(param[0]));
|
||||
const size_t idx = uint8(param[1]);
|
||||
const int val = int(pop());
|
||||
const uint8 idx = uint8(param[1]);
|
||||
const uint32_t val = pop();
|
||||
if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
|
||||
{
|
||||
seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
|
||||
flags |= POSITIONED;
|
||||
}
|
||||
int res = is->getAttr(&seg, slat, idx);
|
||||
is->setAttr(&seg, slat, idx, res - val, smap);
|
||||
uint32_t res = uint32_t(is->getAttr(&seg, slat, idx));
|
||||
is->setAttr(&seg, slat, idx, int32_t(res - val), smap);
|
||||
ENDOP
|
||||
|
||||
STARTOP(push_proc_state)
|
||||
|
|
@ -689,4 +689,3 @@ STARTOP(set_feat)
|
|||
seg.setFeature(fid, feat, pop());
|
||||
}
|
||||
ENDOP
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,14 @@ of the License or (at your option) any later version.
|
|||
#include <limits>
|
||||
#include "inc/json.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define FORMAT_INTMAX "%lli"
|
||||
#define FORMAT_UINTMAX "%llu"
|
||||
#else
|
||||
#define FORMAT_INTMAX "%ji"
|
||||
#define FORMAT_UINTMAX "%ju"
|
||||
#endif
|
||||
|
||||
using namespace graphite2;
|
||||
|
||||
namespace
|
||||
|
|
@ -45,7 +53,7 @@ namespace
|
|||
};
|
||||
}
|
||||
|
||||
const json::_null_t json::null = {};
|
||||
const std::nullptr_t json::null = nullptr;
|
||||
|
||||
inline
|
||||
void json::context(const char current) throw()
|
||||
|
|
@ -131,10 +139,9 @@ json & json::operator << (json::number f) throw()
|
|||
fprintf(_stream, "%g", f);
|
||||
return *this;
|
||||
}
|
||||
json & json::operator << (json::integer d) throw() { context(seq); fprintf(_stream, "%ld", d); return *this; }
|
||||
json & json::operator << (long unsigned d) throw() { context(seq); fprintf(_stream, "%ld", d); return *this; }
|
||||
json & json::operator << (json::integer d) throw() { context(seq); fprintf(_stream, FORMAT_INTMAX, intmax_t(d)); return *this; }
|
||||
json & json::operator << (json::integer_u d) throw() { context(seq); fprintf(_stream, FORMAT_UINTMAX, uintmax_t(d)); return *this; }
|
||||
json & json::operator << (json::boolean b) throw() { context(seq); fputs(b ? "true" : "false", _stream); return *this; }
|
||||
json & json::operator << (json::_null_t) throw() { context(seq); fputs("null",_stream); return *this; }
|
||||
json & json::operator << (std::nullptr_t) throw() { context(seq); fputs("null",_stream); return *this; }
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ else:
|
|||
|
||||
# This should contain all of the _SOURCES from files.mk, except *_machine.cpp
|
||||
UNIFIED_SOURCES += [
|
||||
'CachedFace.cpp',
|
||||
'CmapCache.cpp',
|
||||
'Code.cpp',
|
||||
'Collider.cpp',
|
||||
|
|
@ -46,9 +45,6 @@ UNIFIED_SOURCES += [
|
|||
'Justifier.cpp',
|
||||
'Pass.cpp',
|
||||
'Position.cpp',
|
||||
'SegCache.cpp',
|
||||
'SegCacheEntry.cpp',
|
||||
'SegCacheStore.cpp',
|
||||
'Segment.cpp',
|
||||
'Silf.cpp',
|
||||
'Slot.cpp',
|
||||
|
|
|
|||
Loading…
Reference in a new issue