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:
Ryan VanderMeulen 2018-08-21 13:58:42 +00:00
parent 203aa92dca
commit 9966e32859
80 changed files with 1034 additions and 2330 deletions

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, you may use this library under the terms of the Mozilla Alternatively, you may use this library under the terms of the Mozilla

18
gfx/graphite2/ChangeLog Executable file → Normal file
View 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 1.3.9
. Add Collision COLL_ISSPACE to allow for visible spaces in collision avoidance . Add Collision COLL_ISSPACE to allow for visible spaces in collision avoidance
. Add segment and pass direction information to tracing output . Add segment and pass direction information to tracing output

View file

@ -1,11 +1,10 @@
# Graphite engine # Graphite engine
## Project CI status ## Project CI status
Linux -- Intel 64bit:[![Build Status](http://build.palaso.org/app/rest/builds/buildType:bt124/statusIcon)](http://build.palaso.org/viewType.html?buildTypeId=bt124&guest=1) | OS | Intel 64 bit | Intel 32 bit | Arm 32 bit |
Intel 32bit:[![Build Status](http://build.palaso.org/app/rest/builds/buildType:bt123/statusIcon)](http://build.palaso.org/viewType.html?buildTypeId=bt123&guest=1) |---------|:------------:|:------------:|:----------:|
ARM 32bit:[![Build Status](http://build.palaso.org/app/rest/builds/buildType:Graphite_Linux32bitArm/statusIcon)](http://build.palaso.org/viewType.html?buildTypeId=Graphite_Linux32bitArm&guest=1) | Linux | [![Build Status](http://build.palaso.org/app/rest/builds/buildType:bt124/statusIcon)](http://build.palaso.org/viewType.html?buildTypeId=bt124&guest=1) | [![Build Status](http://build.palaso.org/app/rest/builds/buildType:bt123/statusIcon)](http://build.palaso.org/viewType.html?buildTypeId=bt123&guest=1) | [![Build Status](http://build.palaso.org/app/rest/builds/buildType:Graphite_Linux32bitArm/statusIcon)](http://build.palaso.org/viewType.html?buildTypeId=Graphite_Linux32bitArm&guest=1) |
| Windows | [![Build Status](http://build.palaso.org/app/rest/builds/buildType:Graphite_Windows64bitProduction/statusIcon)](http://build.palaso.org/viewType.html?buildTypeId=Graphite_Windows64bitProduction&guest=1) | [![Build Status](http://build.palaso.org/app/rest/builds/buildType:bt91/statusIcon)](http://build.palaso.org/viewType.html?buildTypeId=bt91&guest=1)| |
Windows -- Intel 64bit:[![Build Status](http://build.palaso.org/app/rest/builds/buildType:Graphite_Windows64bitProduction/statusIcon)](http://build.palaso.org/viewType.html?buildTypeId=Graphite_Windows64bitProduction&guest=1)
## What is Graphite? ## What is Graphite?

View file

@ -1,7 +1,3 @@
This directory contains the Graphite2 library release 1.3.11 from This directory contains the Graphite2 library release 1.3.12 from
https://github.com/silnrsi/graphite/releases/download/1.3.11/graphite2-minimal-1.3.11.tgz 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. 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.

View file

@ -30,7 +30,7 @@
#define GR2_VERSION_MAJOR 1 #define GR2_VERSION_MAJOR 1
#define GR2_VERSION_MINOR 3 #define GR2_VERSION_MINOR 3
#define GR2_VERSION_BUGFIX 11 #define GR2_VERSION_BUGFIX 12
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
@ -51,12 +51,12 @@ GR2_API void gr_engine_version(int *nMajor, int *nMinor, int *nBugFix);
* The Face Options allow the application to require that certain tables are * The Face Options allow the application to require that certain tables are
* read during face construction. This may be of concern if the appFaceHandle * read during face construction. This may be of concern if the appFaceHandle
* used in the gr_get_table_fn may change. * used in the gr_get_table_fn may change.
* The values can be combined * The values can be combined
*/ */
enum gr_face_options { enum gr_face_options {
/** No preload, no cmap caching, fail if the graphite tables are invalid */ /** No preload, no cmap caching, fail if the graphite tables are invalid */
gr_face_default = 0, 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, gr_face_dumbRendering = 1,
/** preload glyphs at construction time */ /** preload glyphs at construction time */
gr_face_preloadGlyphs = 2, gr_face_preloadGlyphs = 2,
@ -113,7 +113,7 @@ struct gr_face_ops
gr_get_table_fn get_table; gr_get_table_fn get_table;
/** is a pointer to a function to notify the client the a table can be released. /** is a pointer to a function to notify the client the a table can be released.
* This can be NULL to signify that the client does not wish to do any release handling. */ * This can be NULL to signify that the client does not wish to do any release handling. */
gr_release_table_fn release_table; gr_release_table_fn release_table;
}; };
typedef struct gr_face_ops gr_face_ops; typedef struct gr_face_ops gr_face_ops;
@ -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); 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 /** @deprecated Since v1.2.0 in favour of gr_make_face_with_ops.
* 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. * @return gr_face or NULL if the font fails to load for some reason.
* @param appFaceHandle This is application specific information that is passed * @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 getTable Callback function to get table data.
* @param faceOptions Bitfield describing various options. See enum gr_face_options for details. * @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 /** @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 *
* Create a gr_face object given application information, with subsegmental caching support
* *
* @return gr_face or NULL if the font fails to load. * @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. * @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. * 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 * @param face_ops Pointer to face specific callback structure for table management. Must stay
* alive for the duration of the call only. * 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 * @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. * 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. * @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 segCacheMaxSize How large the segment cache is.
* @param faceOptions Bitfield of values from enum gr_face_options * @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); 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);
//#endif
/** Convert a tag in a string into a gr_uint32 /** 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); GR2_API gr_face* gr_make_file_face(const char *filename, unsigned int faceOptions);
//#ifndef GRAPHITE2_NSEGCACHE /** @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. *
* Create gr_face from a font file, with subsegment caching support.
* *
* @return gr_face that accesses a font file directly. Returns NULL on failure. * @return gr_face that accesses a font file directly. Returns NULL on failure.
* @param filename Full path and filename to font file * @param filename Full path and filename to font file
* @param segCacheMaxSize Specifies how big to make the cache in segments. * @param segCacheMaxSize Specifies how big to make the cache in segments.
* @param faceOptions Bitfield from enum gr_face_options to control face options. * @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); GR2_DEPRECATED_API gr_face* gr_make_file_face_with_seg_cache(const char *filename, unsigned int segCacheMaxSize, unsigned int faceOptions);
//#endif
#endif // !GRAPHITE2_NFILEFACE #endif // !GRAPHITE2_NFILEFACE
/** Create a font from a face /** Create a font from a face
@ -347,7 +349,7 @@ GR2_API gr_uint16 gr_fref_n_values(const gr_feature_ref* pfeatureref);
* @param pfeatureref gr_feature_ref of the feature of interest * @param pfeatureref gr_feature_ref of the feature of interest
* @param settingno Index up to the return value of gr_fref_n_values() of the value * @param settingno Index up to the return value of gr_fref_n_values() of the value
*/ */
GR2_API gr_int16 gr_fref_value(const gr_feature_ref* pfeatureref, gr_uint16 settingno); GR2_API gr_int16 gr_fref_value(const gr_feature_ref* pfeatureref, gr_uint16 settingno);
/** Returns a string of the UI name of a feature /** Returns a string of the UI name of a feature
* *
@ -385,4 +387,3 @@ GR2_API void gr_featureval_destroy(gr_feature_val *pfeatures);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -42,7 +42,7 @@ typedef enum {
GRLOG_SEGMENT = 0x02, GRLOG_SEGMENT = 0x02,
GRLOG_PASS = 0x04, GRLOG_PASS = 0x04,
GRLOG_CACHE = 0x08, GRLOG_CACHE = 0x08,
GRLOG_OPCODE = 0x80, GRLOG_OPCODE = 0x80,
GRLOG_ALL = 0xFF GRLOG_ALL = 0xFF
} GrLogMask; } GrLogMask;

View file

@ -62,63 +62,63 @@ enum gr_justFlags {
/** Used for looking up slot attributes. Most are already available in other functions **/ /** Used for looking up slot attributes. Most are already available in other functions **/
enum gr_attrCode { enum gr_attrCode {
/// adjusted glyph advance in x direction in design units /// adjusted glyph advance in x direction in design units
gr_slatAdvX = 0, gr_slatAdvX = 0,
/// adjusted glyph advance in y direction (usually 0) in design units /// adjusted glyph advance in y direction (usually 0) in design units
gr_slatAdvY, gr_slatAdvY,
/// returns 0. Deprecated. /// returns 0. Deprecated.
gr_slatAttTo, gr_slatAttTo,
/// This slot attaches to its parent at the given design units in the x direction /// This slot attaches to its parent at the given design units in the x direction
gr_slatAttX, gr_slatAttX,
/// This slot attaches to its parent at the given design units in the y direction /// This slot attaches to its parent at the given design units in the y direction
gr_slatAttY, gr_slatAttY,
/// This slot attaches to its parent at the given glyph point (not implemented) /// This slot attaches to its parent at the given glyph point (not implemented)
gr_slatAttGpt, gr_slatAttGpt,
/// x-direction adjustment from the given glyph point (not implemented) /// x-direction adjustment from the given glyph point (not implemented)
gr_slatAttXOff, gr_slatAttXOff,
/// y-direction adjustment from the given glyph point (not implemented) /// y-direction adjustment from the given glyph point (not implemented)
gr_slatAttYOff, gr_slatAttYOff,
/// Where on this glyph should align with the attachment point on the parent glyph in the x-direction. /// Where on this glyph should align with the attachment point on the parent glyph in the x-direction.
gr_slatAttWithX, gr_slatAttWithX,
/// Where on this glyph should align with the attachment point on the parent glyph in the y-direction /// Where on this glyph should align with the attachment point on the parent glyph in the y-direction
gr_slatAttWithY, gr_slatAttWithY,
/// Which glyph point on this glyph should align with the attachment point on the parent glyph (not implemented). /// Which glyph point on this glyph should align with the attachment point on the parent glyph (not implemented).
gr_slatWithGpt, gr_slatWithGpt,
/// Adjustment to gr_slatWithGpt in x-direction (not implemented) /// Adjustment to gr_slatWithGpt in x-direction (not implemented)
gr_slatAttWithXOff, gr_slatAttWithXOff,
/// Adjustment to gr_slatWithGpt in y-direction (not implemented) /// Adjustment to gr_slatWithGpt in y-direction (not implemented)
gr_slatAttWithYOff, gr_slatAttWithYOff,
/// Attach at given nesting level (not implemented) /// Attach at given nesting level (not implemented)
gr_slatAttLevel, gr_slatAttLevel,
/// Line break breakweight for this glyph /// Line break breakweight for this glyph
gr_slatBreak, gr_slatBreak,
/// Ligature component reference (not implemented) /// Ligature component reference (not implemented)
gr_slatCompRef, gr_slatCompRef,
/// bidi directionality of this glyph (not implemented) /// bidi directionality of this glyph (not implemented)
gr_slatDir, gr_slatDir,
/// Whether insertion is allowed before this glyph /// Whether insertion is allowed before this glyph
gr_slatInsert, gr_slatInsert,
/// Final positioned position of this glyph relative to its parent in x-direction in pixels /// Final positioned position of this glyph relative to its parent in x-direction in pixels
gr_slatPosX, gr_slatPosX,
/// Final positioned position of this glyph relative to its parent in y-direction in pixels /// Final positioned position of this glyph relative to its parent in y-direction in pixels
gr_slatPosY, gr_slatPosY,
/// Amount to shift glyph by in x-direction design units /// Amount to shift glyph by in x-direction design units
gr_slatShiftX, gr_slatShiftX,
/// Amount to shift glyph by in y-direction design units /// Amount to shift glyph by in y-direction design units
gr_slatShiftY, gr_slatShiftY,
/// attribute user1 /// attribute user1
gr_slatUserDefnV1, gr_slatUserDefnV1,
/// not implemented /// not implemented
gr_slatMeasureSol, gr_slatMeasureSol,
/// not implemented /// not implemented
gr_slatMeasureEol, gr_slatMeasureEol,
/// Amount this slot can stretch (not implemented) /// Amount this slot can stretch (not implemented)
gr_slatJStretch, gr_slatJStretch,
/// Amount this slot can shrink (not implemented) /// Amount this slot can shrink (not implemented)
gr_slatJShrink, gr_slatJShrink,
/// Granularity by which this slot can stretch or shrink (not implemented) /// Granularity by which this slot can stretch or shrink (not implemented)
gr_slatJStep, gr_slatJStep,
/// Justification weight for this glyph (not implemented) /// Justification weight for this glyph (not implemented)
gr_slatJWeight, gr_slatJWeight,
/// Amount this slot mush shrink or stretch in design units /// Amount this slot mush shrink or stretch in design units
gr_slatJWidth = 29, gr_slatJWidth = 29,
/// SubSegment split point /// SubSegment split point
@ -159,11 +159,11 @@ enum gr_attrCode {
gr_slatSeqBelowWt, gr_slatSeqBelowWt,
gr_slatSeqValignHt, gr_slatSeqValignHt,
gr_slatSeqValignWt, gr_slatSeqValignWt,
/// not implemented /// not implemented
gr_slatMax, gr_slatMax,
/// not implemented /// not implemented
gr_slatNoEffect = gr_slatMax + 1 gr_slatNoEffect = gr_slatMax + 1
}; };
enum gr_bidirtl { enum gr_bidirtl {
@ -182,13 +182,13 @@ typedef struct gr_segment gr_segment;
typedef struct gr_slot gr_slot; typedef struct gr_slot gr_slot;
/** Returns Unicode character for a charinfo. /** Returns Unicode character for a charinfo.
* *
* @param p Pointer to charinfo to return information on. * @param p Pointer to charinfo to return information on.
*/ */
GR2_API unsigned int gr_cinfo_unicode_char(const gr_char_info* p/*not NULL*/); GR2_API unsigned int gr_cinfo_unicode_char(const gr_char_info* p/*not NULL*/);
/** Returns breakweight for a charinfo. /** Returns breakweight for a charinfo.
* *
* @return Breakweight is a number between -50 and 50 indicating the cost of a * @return Breakweight is a number between -50 and 50 indicating the cost of a
* break before or after this character. If the value < 0, the absolute value * break before or after this character. If the value < 0, the absolute value
* is this character's contribution to the overall breakweight before it. If the value * is this character's contribution to the overall breakweight before it. If the value

View file

@ -40,33 +40,40 @@ enum gr_encform {
gr_utf8 = 1/*sizeof(uint8)*/, gr_utf16 = 2/*sizeof(uint16)*/, gr_utf32 = 4/*sizeof(uint32)*/ 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__ // Define API function declspec/attributes and how each supported compiler or OS
#if defined GRAPHITE2_STATIC // allows us to specify them.
#define GR2_API #if defined __GNUC__
#elif defined GRAPHITE2_EXPORTING #define _gr2_and ,
#if defined __GNUC__ #define _gr2_tag_fn(a) __attribute__((a))
#define GR2_API __attribute__((dllexport)) #define _gr2_deprecated_flag deprecated
#else #define _gr2_export_flag visibility("default")
#define GR2_API __declspec(dllexport) #define _gr2_import_flag visibility("default")
#endif #define _gr2_static_flag visibility("hidden")
#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
#endif #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
View file

@ -22,7 +22,7 @@ fi
TARBALL="https://github.com/silnrsi/graphite/releases/download/$RELEASE/graphite2-minimal-$RELEASE.tgz" TARBALL="https://github.com/silnrsi/graphite/releases/download/$RELEASE/graphite2-minimal-$RELEASE.tgz"
foo=`basename $0` foo=`basename $0`
TMPFILE=`mktemp -t ${foo}` || exit 1 TMPFILE=`mktemp -t ${foo}.XXX` || exit 1
curl -L "$TARBALL" -o "$TMPFILE" curl -L "$TARBALL" -o "$TMPFILE"
tar -x -z -C gfx/graphite2/ --strip-components 1 -f "$TMPFILE" || exit 1 tar -x -z -C gfx/graphite2/ --strip-components 1 -f "$TMPFILE" || exit 1

View file

@ -15,8 +15,8 @@
# #
# You should also have received a copy of the GNU Lesser General Public # You should also have received a copy of the GNU Lesser General Public
# License along with this library in the file named "LICENSE". # License along with this library in the file named "LICENSE".
# If not, write to the Free Software Foundation, 51 Franklin Street, # 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 # Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
# internet at http://www.fsf.org/licenses/lgpl.html. # internet at http://www.fsf.org/licenses/lgpl.html.
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0 FATAL_ERROR) CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0 FATAL_ERROR)
@ -25,7 +25,7 @@ cmake_policy(SET CMP0012 NEW)
INCLUDE(CheckCXXSourceCompiles) INCLUDE(CheckCXXSourceCompiles)
set(GRAPHITE_API_CURRENT 3) set(GRAPHITE_API_CURRENT 3)
set(GRAPHITE_API_REVISION 0) set(GRAPHITE_API_REVISION 2)
set(GRAPHITE_API_AGE 1) set(GRAPHITE_API_AGE 1)
set(GRAPHITE_VERSION ${GRAPHITE_API_CURRENT}.${GRAPHITE_API_REVISION}.${GRAPHITE_API_AGE}) set(GRAPHITE_VERSION ${GRAPHITE_API_CURRENT}.${GRAPHITE_API_REVISION}.${GRAPHITE_API_AGE})
set(GRAPHITE_SO_VERSION ${GRAPHITE_API_CURRENT}) set(GRAPHITE_SO_VERSION ${GRAPHITE_API_CURRENT})
@ -34,12 +34,6 @@ include(TestBigEndian)
include_directories(${PROJECT_SOURCE_DIR}) 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) set(FILEFACE FileFace.cpp)
if (GRAPHITE2_NFILEFACE) if (GRAPHITE2_NFILEFACE)
add_definitions(-DGRAPHITE2_NFILEFACE) add_definitions(-DGRAPHITE2_NFILEFACE)
@ -60,14 +54,14 @@ if (NOT BUILD_SHARED_LIBS)
add_definitions(-DGRAPHITE2_STATIC) add_definitions(-DGRAPHITE2_STATIC)
endif (NOT BUILD_SHARED_LIBS) endif (NOT BUILD_SHARED_LIBS)
set(GRAPHITE_HEADERS set(GRAPHITE_HEADERS
../include/graphite2/Font.h ../include/graphite2/Font.h
../include/graphite2/Segment.h ../include/graphite2/Segment.h
../include/graphite2/Types.h ../include/graphite2/Types.h
../include/graphite2/Log.h ../include/graphite2/Log.h
) )
file(GLOB PRIVATE_HEADERS inc/*.h) file(GLOB PRIVATE_HEADERS inc/*.h)
add_library(graphite2 add_library(graphite2
${GRAPHITE2_VM_TYPE}_machine.cpp ${GRAPHITE2_VM_TYPE}_machine.cpp
@ -78,7 +72,6 @@ add_library(graphite2
gr_logging.cpp gr_logging.cpp
gr_segment.cpp gr_segment.cpp
gr_slot.cpp gr_slot.cpp
CachedFace.cpp
CmapCache.cpp CmapCache.cpp
Code.cpp Code.cpp
Collider.cpp Collider.cpp
@ -100,7 +93,6 @@ add_library(graphite2
TtfUtil.cpp TtfUtil.cpp
UtfCodec.cpp UtfCodec.cpp
${FILEFACE} ${FILEFACE}
${SEGCACHE}
${TRACING}) ${TRACING})
set_target_properties(graphite2 PROPERTIES PUBLIC_HEADER "${GRAPHITE_HEADERS}" set_target_properties(graphite2 PROPERTIES PUBLIC_HEADER "${GRAPHITE_HEADERS}"
@ -123,21 +115,21 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
endif (CMAKE_COMPILER_IS_GNUCXX) endif (CMAKE_COMPILER_IS_GNUCXX)
message(STATUS "Compiler ID is: ${CMAKE_CXX_COMPILER_ID}") message(STATUS "Compiler ID is: ${CMAKE_CXX_COMPILER_ID}")
if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") 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") endif (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
if (${CMAKE_CXX_COMPILER} MATCHES ".*mingw.*") if (${CMAKE_CXX_COMPILER} MATCHES ".*mingw.*")
target_link_libraries(graphite2 kernel32 msvcr90 mingw32 gcc user32) target_link_libraries(graphite2 kernel32 msvcr90 mingw32 gcc user32)
else (${CMAKE_CXX_COMPILER} MATCHES ".*mingw.*") else (${CMAKE_CXX_COMPILER} MATCHES ".*mingw.*")
if (GRAPHITE2_ASAN) if (GRAPHITE2_SANITIZERS)
target_link_libraries(graphite2 c gcc_s) target_link_libraries(graphite2 c gcc_s)
else (GRAPHITE2_ASAN) else ()
target_link_libraries(graphite2 c gcc) target_link_libraries(graphite2 c gcc)
endif (GRAPHITE2_ASAN) endif ()
include(Graphite)
if (BUILD_SHARED_LIBS)
nolib_test(stdc++ $<TARGET_SONAME_FILE:graphite2>)
endif (BUILD_SHARED_LIBS)
endif (${CMAKE_CXX_COMPILER} MATCHES ".*mingw.*") endif (${CMAKE_CXX_COMPILER} MATCHES ".*mingw.*")
include(Graphite)
if (BUILD_SHARED_LIBS)
nolib_test(stdc++ $<TARGET_SONAME_FILE:graphite2>)
endif ()
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "") set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
CREATE_LIBTOOL_FILE(graphite2 "/lib${LIB_SUFFIX}") CREATE_LIBTOOL_FILE(graphite2 "/lib${LIB_SUFFIX}")
endif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") endif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
@ -155,7 +147,7 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
endif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") endif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
set_target_properties(graphite2 PROPERTIES set_target_properties(graphite2 PROPERTIES
COMPILE_DEFINITIONS "_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;UNICODE;GRAPHITE2_EXPORTING") COMPILE_DEFINITIONS "_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;UNICODE;GRAPHITE2_EXPORTING")
endif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") endif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")

View file

@ -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

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -24,7 +24,7 @@ Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
License, as published by the Free Software Foundation, either version 2 License, as published by the Free Software Foundation, either version 2
of the License or (at your option) any later version. of the License or (at your option) any later version.
*/ */
// This class represents loaded graphite stack machine code. It performs // This class represents loaded graphite stack machine code. It performs
// basic sanity checks, on the incoming code to prevent more obvious problems // basic sanity checks, on the incoming code to prevent more obvious problems
// from crashing graphite. // from crashing graphite.
// Author: Tim Eves // Author: Tim Eves
@ -67,7 +67,7 @@ inline bool is_return(const instr i) {
struct context struct context
{ {
context(uint8 ref=0) : codeRef(ref) {flags.changed=false; flags.referenced=false;} context(uint8 ref=0) : codeRef(ref) {flags.changed=false; flags.referenced=false;}
struct { struct {
uint8 changed:1, uint8 changed:1,
referenced:1; referenced:1;
} flags; } flags;
@ -82,14 +82,14 @@ class Machine::Code::decoder
public: public:
struct limits; struct limits;
static const int NUMCONTEXTS = 256; static const int NUMCONTEXTS = 256;
decoder(limits & lims, Code &code, enum passtype pt) throw(); decoder(limits & lims, Code &code, enum passtype pt) throw();
bool load(const byte * bc_begin, const byte * bc_end); bool load(const byte * bc_begin, const byte * bc_end);
void apply_analysis(instr * const code, instr * code_end); void apply_analysis(instr * const code, instr * code_end);
byte max_ref() { return _max_ref; } byte max_ref() { return _max_ref; }
int out_index() const { return _out_index; } int out_index() const { return _out_index; }
private: private:
void set_ref(int index) throw(); void set_ref(int index) throw();
void set_noref(int index) throw(); void set_noref(int index) throw();
@ -102,7 +102,7 @@ private:
bool test_context() const throw(); bool test_context() const throw();
bool test_ref(int8 index) const throw(); bool test_ref(int8 index) const throw();
void failure(const status_t s) const throw() { _code.failure(s); } void failure(const status_t s) const throw() { _code.failure(s); }
Code & _code; Code & _code;
int _out_index; int _out_index;
uint16 _out_length; uint16 _out_length;
@ -128,18 +128,18 @@ struct Machine::Code::decoder::limits
features; features;
const byte attrid[gr_slatMax]; const byte attrid[gr_slatMax];
}; };
inline Machine::Code::decoder::decoder(limits & lims, Code &code, enum passtype pt) throw() inline Machine::Code::decoder::decoder(limits & lims, Code &code, enum passtype pt) throw()
: _code(code), : _code(code),
_out_index(code._constraint ? 0 : lims.pre_context), _out_index(code._constraint ? 0 : lims.pre_context),
_out_length(code._constraint ? 1 : lims.rule_length), _out_length(code._constraint ? 1 : lims.rule_length),
_instr(code._code), _data(code._data), _max(lims), _passtype(pt), _instr(code._code), _data(code._data), _max(lims), _passtype(pt),
_stack_depth(0), _stack_depth(0),
_in_ctxt_item(false), _in_ctxt_item(false),
_slotref(0), _slotref(0),
_max_ref(0) _max_ref(0)
{ } { }
Machine::Code::Code(bool is_constraint, const byte * bytecode_begin, const byte * const bytecode_end, Machine::Code::Code(bool is_constraint, const byte * bytecode_begin, const byte * const bytecode_end,
@ -159,38 +159,38 @@ Machine::Code::Code(bool is_constraint, const byte * bytecode_begin, const byte
} }
assert(bytecode_end > bytecode_begin); assert(bytecode_end > bytecode_begin);
const opcode_t * op_to_fn = Machine::getOpcodeTable(); const opcode_t * op_to_fn = Machine::getOpcodeTable();
// Allocate code and data target buffers, these sizes are a worst case // Allocate code and data target buffers, these sizes are a worst case
// estimate. Once we know their real sizes the we'll shrink them. // estimate. Once we know their real sizes the we'll shrink them.
if (_out) _code = reinterpret_cast<instr *>(*_out); if (_out) _code = reinterpret_cast<instr *>(*_out);
else _code = static_cast<instr *>(malloc(estimateCodeDataOut(bytecode_end-bytecode_begin, 1, is_constraint ? 0 : rule_length))); else _code = static_cast<instr *>(malloc(estimateCodeDataOut(bytecode_end-bytecode_begin, 1, is_constraint ? 0 : rule_length)));
_data = reinterpret_cast<byte *>(_code + (bytecode_end - bytecode_begin)); _data = reinterpret_cast<byte *>(_code + (bytecode_end - bytecode_begin));
if (!_code || !_data) { if (!_code || !_data) {
failure(alloc_failed); failure(alloc_failed);
return; return;
} }
decoder::limits lims = { decoder::limits lims = {
bytecode_end, bytecode_end,
pre_context, pre_context,
rule_length, rule_length,
silf.numClasses(), silf.numClasses(),
face.glyphs().numAttrs(), face.glyphs().numAttrs(),
face.numFeatures(), face.numFeatures(),
{1,1,1,1,1,1,1,1, {1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,255, 1,1,1,1,1,1,1,255,
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
1,1,1,1,1,1,0,0, 1,1,1,1,1,1,0,0,
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0, silf.numUser()} 0,0,0,0,0,0,0, silf.numUser()}
}; };
decoder dec(lims, *this, pt); decoder dec(lims, *this, pt);
if(!dec.load(bytecode_begin, bytecode_end)) if(!dec.load(bytecode_begin, bytecode_end))
return; return;
// Is this an empty program? // Is this an empty program?
if (_instr_count == 0) if (_instr_count == 0)
{ {
@ -198,7 +198,7 @@ Machine::Code::Code(bool is_constraint, const byte * bytecode_begin, const byte
::new (this) Code(); ::new (this) Code();
return; return;
} }
// When we reach the end check we've terminated it correctly // When we reach the end check we've terminated it correctly
if (!is_return(_code[_instr_count-1])) { if (!is_return(_code[_instr_count-1])) {
failure(missing_return); failure(missing_return);
@ -208,9 +208,9 @@ Machine::Code::Code(bool is_constraint, const byte * bytecode_begin, const byte
assert((_constraint && immutable()) || !_constraint); assert((_constraint && immutable()) || !_constraint);
dec.apply_analysis(_code, _code + _instr_count); dec.apply_analysis(_code, _code + _instr_count);
_max_ref = dec.max_ref(); _max_ref = dec.max_ref();
// Now we know exactly how much code and data the program really needs // Now we know exactly how much code and data the program really needs
// realloc the buffers to exactly the right size so we don't waste any // realloc the buffers to exactly the right size so we don't waste any
// memory. // memory.
assert((bytecode_end - bytecode_begin) >= ptrdiff_t(_instr_count)); assert((bytecode_end - bytecode_begin) >= ptrdiff_t(_instr_count));
assert((bytecode_end - bytecode_begin) >= ptrdiff_t(_data_size)); assert((bytecode_end - bytecode_begin) >= ptrdiff_t(_data_size));
@ -255,13 +255,13 @@ bool Machine::Code::decoder::load(const byte * bc, const byte * bc_end)
const opcode opc = fetch_opcode(bc++); const opcode opc = fetch_opcode(bc++);
if (opc == vm::MAX_OPCODE) if (opc == vm::MAX_OPCODE)
return false; return false;
analyse_opcode(opc, reinterpret_cast<const int8 *>(bc)); analyse_opcode(opc, reinterpret_cast<const int8 *>(bc));
if (!emit_opcode(opc, bc)) if (!emit_opcode(opc, bc))
return false; return false;
} }
return bool(_code); return bool(_code);
} }
@ -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 // Do some basic sanity checks based on what we know about the opcode
if (!validate_opcode(opc, bc)) return MAX_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)) switch (opcode(opc))
{ {
case NOP : case NOP :
@ -509,7 +509,7 @@ void Machine::Code::decoder::analyse_opcode(const opcode opc, const int8 * arg)
case NEXT : case NEXT :
case COPY_NEXT : case COPY_NEXT :
++_slotref; ++_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; // if (_analysis.slotref > _analysis.max_ref) _analysis.max_ref = _analysis.slotref;
break; break;
case INSERT : case INSERT :
@ -517,7 +517,7 @@ void Machine::Code::decoder::analyse_opcode(const opcode opc, const int8 * arg)
_code._modify = true; _code._modify = true;
break; break;
case PUT_SUBS_8BIT_OBS : // slotref on 1st parameter case PUT_SUBS_8BIT_OBS : // slotref on 1st parameter
case PUT_SUBS : case PUT_SUBS :
_code._modify = true; _code._modify = true;
set_changed(0); set_changed(0);
GR_FALLTHROUGH; GR_FALLTHROUGH;
@ -559,7 +559,7 @@ bool Machine::Code::decoder::emit_opcode(opcode opc, const byte * & bc)
const size_t param_sz = op.param_sz == VARARGS ? bc[0] + 1 : op.param_sz; const size_t param_sz = op.param_sz == VARARGS ? bc[0] + 1 : op.param_sz;
// Add this instruction // Add this instruction
*_instr++ = op.impl[_code._constraint]; *_instr++ = op.impl[_code._constraint];
++_code._instr_count; ++_code._instr_count;
// Grab the parameters // Grab the parameters
@ -569,8 +569,8 @@ bool Machine::Code::decoder::emit_opcode(opcode opc, const byte * & bc)
_data += param_sz; _data += param_sz;
_code._data_size += param_sz; _code._data_size += param_sz;
} }
// recursively decode a context item so we can split the skip into // recursively decode a context item so we can split the skip into
// instruction and data portions. // instruction and data portions.
if (opc == CNTXT_ITEM) if (opc == CNTXT_ITEM)
{ {
@ -589,8 +589,8 @@ bool Machine::Code::decoder::emit_opcode(opcode opc, const byte * & bc)
if (load(bc, bc + instr_skip)) if (load(bc, bc + instr_skip))
{ {
bc += instr_skip; bc += instr_skip;
data_skip = instr_skip - (_code._instr_count - ctxt_start); data_skip = instr_skip - byte(_code._instr_count - ctxt_start);
instr_skip = _code._instr_count - ctxt_start; instr_skip = byte(_code._instr_count - ctxt_start);
_max.bytecode = curr_end; _max.bytecode = curr_end;
_out_length = 1; _out_length = 1;
@ -605,7 +605,7 @@ bool Machine::Code::decoder::emit_opcode(opcode opc, const byte * & bc)
return false; return false;
} }
} }
return bool(_code); return bool(_code);
} }
@ -620,15 +620,15 @@ void Machine::Code::decoder::apply_analysis(instr * const code, instr * code_end
for (const context * c = _contexts, * const ce = c + _slotref; c < ce; ++c) for (const context * c = _contexts, * const ce = c + _slotref; c < ce; ++c)
{ {
if (!c->flags.referenced || !c->flags.changed) continue; if (!c->flags.referenced || !c->flags.changed) continue;
instr * const tip = code + c->codeRef + tempcount; instr * const tip = code + c->codeRef + tempcount;
memmove(tip+1, tip, (code_end - tip) * sizeof(instr)); memmove(tip+1, tip, (code_end - tip) * sizeof(instr));
*tip = temp_copy; *tip = temp_copy;
++code_end; ++code_end;
++tempcount; ++tempcount;
_code._delete = true; _code._delete = true;
} }
_code._instr_count = code_end - code; _code._instr_count = code_end - code;
} }
@ -695,7 +695,7 @@ bool Machine::Code::decoder::test_context() const throw()
return true; return true;
} }
inline inline
void Machine::Code::failure(const status_t s) throw() { void Machine::Code::failure(const status_t s) throw() {
release_buffers(); release_buffers();
_status = s; _status = s;
@ -750,4 +750,3 @@ int32 Machine::Code::run(Machine & m, slotref * & map) const
return m.run(_code, _data, map); return m.run(_code, _data, map);
} }

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -37,7 +37,7 @@ of the License or (at your option) any later version.
#define ISQRT2 0.707106781f #define ISQRT2 0.707106781f
// Possible rounding error for subbox boundaries: 0.016 = 1/64 = 1/256 * 4 // Possible rounding error for subbox boundaries: 0.016 = 1/64 = 1/256 * 4
// (values in font range from 0..256) // (values in font range from 0..256)
// #define SUBBOX_RND_ERR 0.016 // #define SUBBOX_RND_ERR 0.016
@ -118,7 +118,7 @@ bool ShiftCollider::initSlot(Segment *seg, Slot *aSlot, const Rect &limit, float
_margin = margin; _margin = margin;
_marginWt = marginWeight; _marginWt = marginWeight;
SlotCollision *c = seg->collisionInfo(aSlot); SlotCollision *c = seg->collisionInfo(aSlot);
_seqClass = c->seqClass(); _seqClass = c->seqClass();
_seqProxClass = c->seqProxClass(); _seqProxClass = c->seqProxClass();
@ -166,7 +166,7 @@ void ShiftCollider::addBox_slope(bool isx, const Rect &box, const BBox &bb, cons
_ranges[axis].weighted<XY>(box.bl.y - c, box.tr.y - c, weight, a, 0, 0, org.x, _ranges[axis].weighted<XY>(box.bl.y - c, box.tr.y - c, weight, a, 0, 0, org.x,
m * (a * a + sqr((minright ? box.tr.x : box.bl.x) - 0.5f * (bb.xi + bb.xa))), false); m * (a * a + sqr((minright ? box.tr.x : box.bl.x) - 0.5f * (bb.xi + bb.xa))), false);
else else
_ranges[axis].weighted<XY>(box.bl.y - c, box.tr.y - c, weight, a, m, _ranges[axis].weighted<XY>(box.bl.y - c, box.tr.y - c, weight, a, m,
(minright ? box.tr.y : box.bl.y) - c, a, 0, false); (minright ? box.tr.y : box.bl.y) - c, a, 0, false);
} }
break; break;
@ -230,7 +230,7 @@ inline void ShiftCollider::removeBox(const Rect &box, const BBox &bb, const Slan
} }
break; break;
case 2 : case 2 :
if (box.bl.x - box.tr.y < org.x - org.y + sb.da && box.tr.x - box.bl.y > org.x - org.y + sb.di if (box.bl.x - box.tr.y < org.x - org.y + sb.da && box.tr.x - box.bl.y > org.x - org.y + sb.di
&& box.width() > 0 && box.height() > 0) && box.width() > 0 && box.height() > 0)
{ {
float di = org.x - org.y + sb.di; float di = org.x - org.y + sb.di;
@ -242,7 +242,7 @@ inline void ShiftCollider::removeBox(const Rect &box, const BBox &bb, const Slan
} }
break; break;
case 3 : case 3 :
if (box.bl.x + box.bl.y < org.x + org.y + sb.sa && box.tr.x + box.tr.y > org.x + org.y + sb.si if (box.bl.x + box.bl.y < org.x + org.y + sb.sa && box.tr.x + box.tr.y > org.x + org.y + sb.si
&& box.width() > 0 && box.height() > 0) && box.width() > 0 && box.height() > 0)
{ {
float si = org.x + org.y + sb.si; float si = org.x + org.y + sb.si;
@ -285,7 +285,7 @@ bool ShiftCollider::mergeSlot(Segment *seg, Slot *slot, const SlotCollision *csl
// SlotCollision * cslot = seg->collisionInfo(slot); // SlotCollision * cslot = seg->collisionInfo(slot);
int orderFlags = 0; int orderFlags = 0;
bool sameClass = _seqProxClass == 0 && cslot->seqClass() == _seqClass; bool sameClass = _seqProxClass == 0 && cslot->seqClass() == _seqClass;
if (sameCluster && _seqClass if (sameCluster && _seqClass
&& (sameClass || (_seqProxClass != 0 && cslot->seqClass() == _seqProxClass))) && (sameClass || (_seqProxClass != 0 && cslot->seqClass() == _seqProxClass)))
// Force the target glyph to be in the specified direction from the slot we're testing. // Force the target glyph to be in the specified direction from the slot we're testing.
orderFlags = _seqOrder; orderFlags = _seqOrder;
@ -378,7 +378,7 @@ bool ShiftCollider::mergeSlot(Segment *seg, Slot *slot, const SlotCollision *csl
default : default :
continue; continue;
} }
#if !defined GRAPHITE2_NTRACING #if !defined GRAPHITE2_NTRACING
if (dbgout) if (dbgout)
dbgout->setenv(1, reinterpret_cast<void *>(-1)); dbgout->setenv(1, reinterpret_cast<void *>(-1));
@ -400,7 +400,7 @@ bool ShiftCollider::mergeSlot(Segment *seg, Slot *slot, const SlotCollision *csl
float r1Xedge = cslot->seqAboveXoff() + 0.5f * (bb.xi + bb.xa) + sx; float r1Xedge = cslot->seqAboveXoff() + 0.5f * (bb.xi + bb.xa) + sx;
float r3Xedge = cslot->seqBelowXlim() + bb.xa + sx + 0.5f * (tbb.xa - tbb.xi); float r3Xedge = cslot->seqBelowXlim() + bb.xa + sx + 0.5f * (tbb.xa - tbb.xi);
float r2Yedge = 0.5f * (bb.yi + bb.ya) + sy; float r2Yedge = 0.5f * (bb.yi + bb.ya) + sy;
// DBGTAG(1x) means the regions are up and right // DBGTAG(1x) means the regions are up and right
// region 1 // region 1
DBGTAG(11) DBGTAG(11)
@ -452,7 +452,7 @@ bool ShiftCollider::mergeSlot(Segment *seg, Slot *slot, const SlotCollision *csl
} }
case SlotCollision::SEQ_ORDER_NOABOVE : // enforce neighboring glyph being above case SlotCollision::SEQ_ORDER_NOABOVE : // enforce neighboring glyph being above
DBGTAG(31); DBGTAG(31);
removeBox(Rect(Position(bb.xi - tbb.xa + sx, sy + bb.ya), removeBox(Rect(Position(bb.xi - tbb.xa + sx, sy + bb.ya),
Position(bb.xa - tbb.xi + sx, ypinf)), tbb, tsb, org, i); Position(bb.xa - tbb.xi + sx, ypinf)), tbb, tsb, org, i);
break; break;
case SlotCollision::SEQ_ORDER_NOBELOW : // enforce neighboring glyph being below case SlotCollision::SEQ_ORDER_NOBELOW : // enforce neighboring glyph being below
@ -569,7 +569,7 @@ bool ShiftCollider::mergeSlot(Segment *seg, Slot *slot, const SlotCollision *csl
} }
hasCol |= isCol; hasCol |= isCol;
return res; return res;
} // end of ShiftCollider::mergeSlot } // end of ShiftCollider::mergeSlot
@ -666,7 +666,7 @@ void ShiftCollider::outputJsonDbg(json * const dbgout, Segment *seg, int axis)
{ {
*dbgout << json::flat << json::array << _ranges[iAxis].position(); *dbgout << json::flat << json::array << _ranges[iAxis].position();
for (Zones::const_iterator s = _ranges[iAxis].begin(), e = _ranges[iAxis].end(); s != e; ++s) for (Zones::const_iterator s = _ranges[iAxis].begin(), e = _ranges[iAxis].end(); s != e; ++s)
*dbgout << json::flat << json::array *dbgout << json::flat << json::array
<< Position(s->x, s->xm) << s->sm << s->smx << s->c << Position(s->x, s->xm) << s->sm << s->smx << s->c
<< json::close; << json::close;
*dbgout << json::close; *dbgout << json::close;
@ -703,7 +703,7 @@ void ShiftCollider::outputJsonDbgEndSlot(GR_MAYBE_UNUSED json * const dbgout,
} }
void ShiftCollider::outputJsonDbgOneVector(json * const dbgout, Segment *seg, int axis, void ShiftCollider::outputJsonDbgOneVector(json * const dbgout, Segment *seg, int axis,
float tleft, float bestCost, float bestVal) float tleft, float bestCost, float bestVal)
{ {
const char * label; const char * label;
switch (axis) switch (axis)
@ -718,9 +718,9 @@ void ShiftCollider::outputJsonDbgOneVector(json * const dbgout, Segment *seg, in
*dbgout << json::object // vector *dbgout << json::object // vector
<< "direction" << label << "direction" << label
<< "targetMin" << tleft; << "targetMin" << tleft;
outputJsonDbgRemovals(dbgout, axis, seg); outputJsonDbgRemovals(dbgout, axis, seg);
*dbgout << "ranges"; *dbgout << "ranges";
outputJsonDbg(dbgout, seg, axis); outputJsonDbg(dbgout, seg, axis);
@ -756,7 +756,7 @@ static float localmin(float al, float au, float bl, float bu, float x)
if (bl > al) if (bl > al)
{ if (bu > au) return bl > x ? bl : x; } { if (bu > au) return bl > x ? bl : x; }
else if (au > bu) return al > x ? al : x; else if (au > bu) return al > x ? al : x;
return x; return x;
} }
// Return the given edge of the glyph at height y, taking any slant box into account. // Return the given edge of the glyph at height y, taking any slant box into account.
@ -835,7 +835,7 @@ bool KernCollider::initSlot(Segment *seg, Slot *aSlot, const Rect &limit, float
_limit = limit; _limit = limit;
_offsetPrev = offsetPrev; // kern from a previous pass _offsetPrev = offsetPrev; // kern from a previous pass
// Calculate the height of the glyph and how many horizontal slices to use. // Calculate the height of the glyph and how many horizontal slices to use.
if (_maxy >= 1e37f) if (_maxy >= 1e37f)
{ {
@ -877,7 +877,7 @@ bool KernCollider::initSlot(Segment *seg, Slot *aSlot, const Rect &limit, float
} }
goto done; goto done;
} }
numSlices = _edges.size(); numSlices = int(_edges.size());
#if !defined GRAPHITE2_NTRACING #if !defined GRAPHITE2_NTRACING
// Debugging // Debugging
@ -887,7 +887,7 @@ bool KernCollider::initSlot(Segment *seg, Slot *aSlot, const Rect &limit, float
_nearEdges.clear(); _nearEdges.clear();
_nearEdges.insert(_nearEdges.begin(), numSlices, (dir & 1) ? -1e38f : +1e38f); _nearEdges.insert(_nearEdges.begin(), numSlices, (dir & 1) ? -1e38f : +1e38f);
#endif #endif
// Determine the trailing edge of each slice (ie, left edge for a RTL glyph). // Determine the trailing edge of each slice (ie, left edge for a RTL glyph).
for (s = base; s; s = s->nextInCluster(s)) for (s = base; s; s = s->nextInCluster(s))
{ {
@ -997,7 +997,7 @@ bool KernCollider::mergeSlot(Segment *seg, Slot *slot, const Position &currShift
if (collides && !nooverlap) if (collides && !nooverlap)
_hit = true; _hit = true;
return collides | nooverlap; // note that true is not a necessarily reliable value return collides | nooverlap; // note that true is not a necessarily reliable value
} // end of KernCollider::mergeSlot } // end of KernCollider::mergeSlot
@ -1027,19 +1027,19 @@ Position KernCollider::resolve(GR_MAYBE_UNUSED Segment *seg, GR_MAYBE_UNUSED Slo
<< "slantBox" << seg->getFace()->glyphs().slant(_target->gid()) << "slantBox" << seg->getFace()->glyphs().slant(_target->gid())
<< "fix" << "kern" << "fix" << "kern"
<< json::close; // target object << json::close; // target object
*dbgout << "slices" << json::array; *dbgout << "slices" << json::array;
for (int is = 0; is < (int)_edges.size(); is++) for (int is = 0; is < (int)_edges.size(); is++)
{ {
*dbgout << json::flat << json::object *dbgout << json::flat << json::object
<< "i" << is << "i" << is
<< "targetEdge" << _edges[is] << "targetEdge" << _edges[is]
<< "neighbor" << objectid(dslot(seg, _slotNear[is])) << "neighbor" << objectid(dslot(seg, _slotNear[is]))
<< "nearEdge" << _nearEdges[is] << "nearEdge" << _nearEdges[is]
<< json::close; << json::close;
} }
*dbgout << json::close; // slices array *dbgout << json::close; // slices array
*dbgout *dbgout
<< "xbound" << _xbound << "xbound" << _xbound
<< "minGap" << _mingap << "minGap" << _mingap
@ -1051,7 +1051,7 @@ Position KernCollider::resolve(GR_MAYBE_UNUSED Segment *seg, GR_MAYBE_UNUSED Slo
#endif #endif
return Position(result, 0.); return Position(result, 0.);
} // end of KernCollider::resolve } // end of KernCollider::resolve
void KernCollider::shift(const Position &mv, int dir) void KernCollider::shift(const Position &mv, int dir)
@ -1072,7 +1072,7 @@ SlotCollision::SlotCollision(Segment *seg, Slot *slot)
void SlotCollision::initFromSlot(Segment *seg, Slot *slot) void SlotCollision::initFromSlot(Segment *seg, Slot *slot)
{ {
// Initialize slot attributes from glyph attributes. // Initialize slot attributes from glyph attributes.
// The order here must match the order in the grcompiler code, // The order here must match the order in the grcompiler code,
// GrcSymbolTable::AssignInternalGlyphAttrIDs. // GrcSymbolTable::AssignInternalGlyphAttrIDs.
uint16 gid = slot->gid(); uint16 gid = slot->gid();
uint16 aCol = seg->silf()->aCollision(); // flags attr ID uint16 aCol = seg->silf()->aCollision(); // flags attr ID
@ -1094,7 +1094,7 @@ void SlotCollision::initFromSlot(Segment *seg, Slot *slot)
_seqBelowXlim = p[aCol+12]; _seqBelowXlim = p[aCol+12];
_seqBelowWt = p[aCol+13]; _seqBelowWt = p[aCol+13];
_seqValignHt = p[aCol+14]; _seqValignHt = p[aCol+14];
_seqValignWt = p[aCol+15]; _seqValignWt = p[aCol+15];
// These attributes do not have corresponding glyph attribute: // These attributes do not have corresponding glyph attribute:
_exclGlyph = 0; _exclGlyph = 0;

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -47,7 +47,7 @@ bool read_sequence(u8 const * &src, u8 const * const end, u8 const * &literal,
u32 & literal_len, u32 & match_len, u32 & match_dist) u32 & literal_len, u32 & match_len, u32 & match_dist)
{ {
u8 const token = *src++; u8 const token = *src++;
literal_len = read_literal(src, end, token >> 4); literal_len = read_literal(src, end, token >> 4);
literal = src; literal = src;
src += literal_len; src += literal_len;
@ -55,7 +55,7 @@ bool read_sequence(u8 const * &src, u8 const * const end, u8 const * &literal,
// Normal exit for end of stream, wrap arround check and parital match check. // Normal exit for end of stream, wrap arround check and parital match check.
if (src > end - sizeof(u16) || src < literal) if (src > end - sizeof(u16) || src < literal)
return false; return false;
match_dist = *src++; match_dist = *src++;
match_dist |= *src++ << 8; match_dist |= *src++ << 8;
match_len = read_literal(src, end, token & 0xf) + MINMATCH; match_len = read_literal(src, end, token & 0xf) + MINMATCH;
@ -70,7 +70,7 @@ int lz4::decompress(void const *in, size_t in_size, void *out, size_t out_size)
{ {
if (out_size <= in_size || in_size < MINSRCSIZE) if (out_size <= in_size || in_size < MINSRCSIZE)
return -1; return -1;
u8 const * src = static_cast<u8 const *>(in), u8 const * src = static_cast<u8 const *>(in),
* literal = 0, * literal = 0,
* const src_end = src + in_size; * const src_end = src + in_size;
@ -100,7 +100,7 @@ int lz4::decompress(void const *in, size_t in_size, void *out, size_t out_size)
dst = overrun_copy(dst, literal, literal_len); dst = overrun_copy(dst, literal, literal_len);
out_size -= literal_len; out_size -= literal_len;
} }
// Copy, possibly repeating, match from earlier in the // Copy, possibly repeating, match from earlier in the
// decoded output. // decoded output.
u8 const * const pcpy = dst - match_dist; u8 const * const pcpy = dst - match_dist;
@ -120,7 +120,6 @@ int lz4::decompress(void const *in, size_t in_size, void *out, size_t out_size)
if (literal > src_end - literal_len || literal_len > out_size) if (literal > src_end - literal_len || literal_len > out_size)
return -1; return -1;
dst = fast_copy(dst, literal, literal_len); dst = fast_copy(dst, literal, literal_len);
return dst - (u8*)out;
}
return int(dst - (u8*)out);
}

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -34,7 +34,6 @@ of the License or (at your option) any later version.
#include "inc/FileFace.h" #include "inc/FileFace.h"
#include "inc/GlyphFace.h" #include "inc/GlyphFace.h"
#include "inc/json.h" #include "inc/json.h"
#include "inc/SegCacheStore.h"
#include "inc/Segment.h" #include "inc/Segment.h"
#include "inc/NameTable.h" #include "inc/NameTable.h"
#include "inc/Error.h" #include "inc/Error.h"
@ -142,7 +141,7 @@ bool Face::readGraphite(const Table & silf)
{ {
error_context(EC_ASILF + (i << 8)); error_context(EC_ASILF + (i << 8));
const uint32 offset = be::read<uint32>(p), 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)) if (e.test(next > silf.size() || offset >= next, E_BADSIZE))
return error(e); return error(e);
@ -201,7 +200,7 @@ bool Face::runGraphite(Segment *seg, const Silf *aSilf) const
<< "advance" << seg->advance() << "advance" << seg->advance()
<< "chars" << json::array; << "chars" << json::array;
for(size_t i = 0, n = seg->charInfoCount(); i != n; ++i) 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 *dbgout << json::close // Close up the chars array
<< json::close; // Close up the segment object << json::close; // Close up the segment object
} }
@ -239,7 +238,7 @@ int32 Face::getGlyphMetric(uint16 gid, uint8 metric) const
{ {
case kgmetAscent : return m_ascent; case kgmetAscent : return m_ascent;
case kgmetDescent : return m_descent; case kgmetDescent : return m_descent;
default: default:
if (gid >= glyphs().numGlyphs()) return 0; if (gid >= glyphs().numGlyphs()) return 0;
return glyphs().glyph(gid)->getMetric(metric); return glyphs().glyph(gid)->getMetric(metric);
} }
@ -250,7 +249,7 @@ void Face::takeFileFace(FileFace* pFileFace GR_MAYBE_UNUSED/*takes ownership*/)
#ifndef GRAPHITE2_NFILEFACE #ifndef GRAPHITE2_NFILEFACE
if (m_pFileFace==pFileFace) if (m_pFileFace==pFileFace)
return; return;
delete m_pFileFace; delete m_pFileFace;
m_pFileFace = pFileFace; m_pFileFace = pFileFace;
#endif #endif
@ -276,15 +275,13 @@ uint16 Face::languageForLocale(const char * locale) const
Face::Table::Table(const Face & face, const Tag n, uint32 version) throw() 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));
_p = static_cast<const byte *>((*_f->m_ops.get_table)(_f->m_appFaceHandle, n, &sz));
_sz = uint32(sz);
if (!TtfUtil::CheckTable(n, _p, _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; return;
} }
@ -292,7 +289,7 @@ Face::Table::Table(const Face & face, const Tag n, uint32 version) throw()
decompress(); decompress();
} }
void Face::Table::releaseBuffers() void Face::Table::release()
{ {
if (_compressed) if (_compressed)
free(const_cast<byte *>(_p)); free(const_cast<byte *>(_p));
@ -301,12 +298,11 @@ void Face::Table::releaseBuffers()
_p = 0; _sz = 0; _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; if (this == &rhs) return *this;
release();
this->~Table(); new (this) Table(std::move(rhs));
new (this) Table(rhs);
return *this; return *this;
} }
@ -353,7 +349,7 @@ Error Face::Table::decompress()
// Tell the provider to release the compressed form since were replacing // Tell the provider to release the compressed form since were replacing
// it anyway. // it anyway.
releaseBuffers(); release();
if (e) if (e)
{ {

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -48,7 +48,7 @@ FileFace::FileFace(const char *filename)
// Get the header. // Get the header.
if (!TtfUtil::GetHeaderInfo(tbl_offset, tbl_len)) return; 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); _header_tbl = (TtfUtil::Sfnt::OffsetSubTable*)gralloc<char>(tbl_len);
if (_header_tbl) if (_header_tbl)
{ {
@ -59,7 +59,7 @@ FileFace::FileFace(const char *filename)
// Get the table directory // Get the table directory
if (!TtfUtil::GetTableDirInfo(_header_tbl, tbl_offset, tbl_len)) return; if (!TtfUtil::GetTableDirInfo(_header_tbl, tbl_offset, tbl_len)) return;
_table_dir = (TtfUtil::Sfnt::OffsetSubTable::Entry*)gralloc<char>(tbl_len); _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) if (_table_dir && fread(_table_dir, 1, tbl_len, _file) != tbl_len)
{ {
free(_table_dir); free(_table_dir);
@ -88,7 +88,7 @@ const void *FileFace::get_table_fn(const void* appFaceHandle, unsigned int name,
return 0; return 0;
if (tbl_offset > file_face._file_len || tbl_len > file_face._file_len - tbl_offset 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; return 0;
tbl = malloc(tbl_len); tbl = malloc(tbl_len);

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -56,6 +56,3 @@ Font::Font(float ppm, const Face & f, const void * appFontHandle, const gr_font_
{ {
free(m_advances); free(m_advances);
} }

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -46,7 +46,7 @@ namespace
template<typename W> template<typename W>
class _glat_iterator : public std::iterator<std::input_iterator_tag, std::pair<sparse::key_type, sparse::mapped_type> > 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)); } unsigned int run() const { return be::peek<W>(_e+sizeof(W)); }
void advance_entry() { _n = 0; _e = _v; be::skip<W>(_v,2); } void advance_entry() { _n = 0; _e = _v; be::skip<W>(_v,2); }
public: public:
@ -84,7 +84,7 @@ const SlantBox SlantBox::empty = {0,0,0,0};
class GlyphCache::Loader class GlyphCache::Loader
{ {
public: 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(); operator bool () const throw();
unsigned short int units_per_em() const throw(); unsigned short int units_per_em() const throw();
@ -115,7 +115,7 @@ private:
GlyphCache::GlyphCache(const Face & face, const uint32 face_options) 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() _glyphs(_glyph_loader && *_glyph_loader && _glyph_loader->num_glyphs()
? grzeroalloc<const GlyphFace *>(_glyph_loader->num_glyphs()) : 0), ? grzeroalloc<const GlyphFace *>(_glyph_loader->num_glyphs()) : 0),
_boxes(_glyph_loader && _glyph_loader->has_boxes() && _glyph_loader->num_glyphs() _boxes(_glyph_loader && _glyph_loader->has_boxes() && _glyph_loader->num_glyphs()
@ -210,7 +210,7 @@ GlyphCache::~GlyphCache()
} }
const GlyphFace *GlyphCache::glyph(unsigned short glyphid) const //result may be changed by subsequent call with a different glyphid const GlyphFace *GlyphCache::glyph(unsigned short glyphid) const //result may be changed by subsequent call with a different glyphid
{ {
if (glyphid >= numGlyphs()) if (glyphid >= numGlyphs())
return _glyphs[0]; return _glyphs[0];
const GlyphFace * & p = _glyphs[glyphid]; const GlyphFace * & p = _glyphs[glyphid];
@ -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), : _head(face, Tag::head),
_hhea(face, Tag::hhea), _hhea(face, Tag::hhea),
_hmtx(face, Tag::hmtx), _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); const Face::Table maxp = Face::Table(face, Tag::maxp);
if (!maxp) { _head = Face::Table(); return; } 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. // 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)) if (_glyf && TtfUtil::LocaLookup(_num_glyphs_graphics-1, _loca, _loca.size(), _head) == size_t(-2))
{ {
@ -265,52 +265,49 @@ GlyphCache::Loader::Loader(const Face & face, const bool dumb_font)
return; 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)
{ {
if ((m_pGlat = Face::Table(face, Tag::Glat, 0x00030000)) == NULL _head = Face::Table();
|| (m_pGloc = Face::Table(face, Tag::Gloc)) == NULL return;
|| m_pGloc.size() < 8) }
{ const byte * p = m_pGloc;
_head = Face::Table(); int version = be::read<uint32>(p);
return; const uint16 flags = be::read<uint16>(p);
} _num_attrs = be::read<uint16>(p);
const byte * p = m_pGloc; // We can accurately calculate the number of attributed glyphs by
int version = be::read<uint32>(p); // subtracting the length of the attribids array (numAttribs long if present)
const uint16 flags = be::read<uint16>(p); // and dividing by either 2 or 4 depending on shor or lonf format
_num_attrs = be::read<uint16>(p); _long_fmt = flags & 1;
// We can accurately calculate the number of attributed glyphs by ptrdiff_t tmpnumgattrs = (m_pGloc.size()
// subtracting the length of the attribids array (numAttribs long if present) - (p - m_pGloc)
// and dividing by either 2 or 4 depending on shor or lonf format - sizeof(uint16)*(flags & 0x2 ? _num_attrs : 0))
_long_fmt = flags & 1; / (_long_fmt ? sizeof(uint32) : sizeof(uint16)) - 1;
int tmpnumgattrs = (m_pGloc.size()
- (p - m_pGloc)
- sizeof(uint16)*(flags & 0x2 ? _num_attrs : 0))
/ (_long_fmt ? sizeof(uint32) : sizeof(uint16)) - 1;
if (version >= 0x00020000 || tmpnumgattrs < 0 || tmpnumgattrs > 65535 if (version >= 0x00020000 || tmpnumgattrs < 0 || tmpnumgattrs > 65535
|| _num_attrs == 0 || _num_attrs > 0x3000 // is this hard limit appropriate? || _num_attrs == 0 || _num_attrs > 0x3000 // is this hard limit appropriate?
|| _num_glyphs_graphics > tmpnumgattrs || _num_glyphs_graphics > tmpnumgattrs
|| m_pGlat.size() < 4) || m_pGlat.size() < 4)
{ {
_head = Face::Table(); _head = Face::Table();
return; return;
} }
_num_glyphs_attributes = static_cast<unsigned short>(tmpnumgattrs); _num_glyphs_attributes = static_cast<unsigned short>(tmpnumgattrs);
p = m_pGlat; p = m_pGlat;
version = be::read<uint32>(p); version = be::read<uint32>(p);
if (version >= 0x00040000 || (version >= 0x00030000 && m_pGlat.size() < 8)) // reject Glat tables that are too new if (version >= 0x00040000 || (version >= 0x00030000 && m_pGlat.size() < 8)) // reject Glat tables that are too new
{ {
_head = Face::Table(); _head = Face::Table();
return; return;
} }
else if (version >= 0x00030000) else if (version >= 0x00030000)
{ {
unsigned int glatflags = be::read<uint32>(p); unsigned int glatflags = be::read<uint32>(p);
_has_boxes = glatflags & 1; _has_boxes = glatflags & 1;
// delete this once the compiler is fixed // delete this once the compiler is fixed
_has_boxes = true; _has_boxes = true;
}
} }
} }
@ -486,7 +483,6 @@ GlyphBox * GlyphCache::Loader::read_box(uint16 gid, GlyphBox *curr, const GlyphF
Rect box = readbox((i & 1) ? diamax : bbox, p[0], p[2], p[1], p[3]); Rect box = readbox((i & 1) ? diamax : bbox, p[0], p[2], p[1], p[3]);
curr->addSubBox(i >> 1, i & 1, &box); curr->addSubBox(i >> 1, i & 1, &box);
be::skip<uint8>(p, 4); be::skip<uint8>(p, 4);
} }
return (GlyphBox *)((char *)(curr) + sizeof(GlyphBox) + 2 * num * sizeof(Rect)); return (GlyphBox *)((char *)(curr) + sizeof(GlyphBox) + 2 * num * sizeof(Rect));
} }

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -33,16 +33,16 @@ int32 GlyphFace::getMetric(uint8 metric) const
{ {
switch (metrics(metric)) switch (metrics(metric))
{ {
case kgmetLsb : return m_bbox.bl.x; case kgmetLsb : return int32(m_bbox.bl.x);
case kgmetRsb : return m_advance.x - m_bbox.tr.x; case kgmetRsb : return int32(m_advance.x - m_bbox.tr.x);
case kgmetBbTop : return m_bbox.tr.y; case kgmetBbTop : return int32(m_bbox.tr.y);
case kgmetBbBottom : return m_bbox.bl.y; case kgmetBbBottom : return int32(m_bbox.bl.y);
case kgmetBbLeft : return m_bbox.bl.x; case kgmetBbLeft : return int32(m_bbox.bl.x);
case kgmetBbRight : return m_bbox.tr.x; case kgmetBbRight : return int32(m_bbox.tr.x);
case kgmetBbHeight : return m_bbox.tr.y - m_bbox.bl.y; case kgmetBbHeight : return int32(m_bbox.tr.y - m_bbox.bl.y);
case kgmetBbWidth : return m_bbox.tr.x - m_bbox.bl.x; case kgmetBbWidth : return int32(m_bbox.tr.x - m_bbox.bl.x);
case kgmetAdvWidth : return m_advance.x; case kgmetAdvWidth : return int32(m_advance.x);
case kgmetAdvHeight : return m_advance.y; case kgmetAdvHeight : return int32(m_advance.y);
default : return 0; default : return 0;
} }
} }

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -183,16 +183,16 @@ void Zones::remove(float x, float xm)
Zones::const_iterator Zones::find_exclusion_under(float x) const 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) while (l < h)
{ {
int const p = (l+h) >> 1; size_t const p = (l+h) >> 1;
switch (_exclusions[p].outcode(x)) switch (_exclusions[p].outcode(x))
{ {
case 0 : return _exclusions.begin()+p; case 0 : return _exclusions.begin()+p;
case 1 : h = p; break; case 1 : h = p; break;
case 2 : case 2 :
case 3 : l = p+1; break; case 3 : l = p+1; break;
} }
} }
@ -287,7 +287,7 @@ void Zones::jsonDbgOut(Segment *seg) const {
*_dbg << "remove" << Position(s->_excl.x, s->_excl.xm); *_dbg << "remove" << Position(s->_excl.x, s->_excl.xm);
else else
*_dbg << "exclude" << json::flat << json::array *_dbg << "exclude" << json::flat << json::array
<< s->_excl.x << s->_excl.xm << s->_excl.x << s->_excl.xm
<< s->_excl.sm << s->_excl.smx << s->_excl.c << s->_excl.sm << s->_excl.smx << s->_excl.c
<< json::close; << json::close;
*_dbg << json::close; *_dbg << json::close;
@ -296,4 +296,3 @@ void Zones::jsonDbgOut(Segment *seg) const {
} }
#endif #endif

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -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) 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; float currWidth = 0.0;
const float scale = font ? font->scale() : 1.0f; const float scale = font ? font->scale() : 1.0f;
Position res; 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()) if ((m_dir & 1) != m_silf->dir() && m_silf->bidiPass() != m_silf->numPasses())
{ {
reverseSlots(); reverseSlots();
s = pFirst; std::swap(pFirst, pLast);
pFirst = pLast;
pLast = s;
} }
if (!pFirst) pFirst = pSlot; if (!pFirst) pFirst = pSlot;
while (!pFirst->isBase()) pFirst = pFirst->attachedTo(); 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; width = width / scale;
if ((jflags & gr_justEndInline) == 0) if ((jflags & gr_justEndInline) == 0)
{ {
do { while (pLast != pFirst && pLast)
{
Rect bbox = theGlyphBBoxTemporary(pLast->glyph()); 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) if (bbox.bl.x != 0.f || bbox.bl.y != 0.f || bbox.tr.x != 0.f || bbox.tr.y == 0.f)
break; break;
pLast = pLast->prev(); pLast = pLast->prev();
} while (pLast != pFirst); }
} }
end = pLast->nextSibling(); if (pLast)
pFirst = pFirst->nextSibling(); end = pLast->nextSibling();
if (pFirst)
pFirst = pFirst->nextSibling();
int icount = 0; int icount = 0;
int numLevels = silf()->numJustLevels(); int numLevels = silf()->numJustLevels();
if (!numLevels) 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()); CharInfo *c = charinfo(s->before());
if (isWhitespace(c->unicodeChar())) if (isWhitespace(c->unicodeChar()))
@ -113,7 +114,7 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
} }
if (!icount) 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, 3, 1);
s->setJustify(this, 0, 2, 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); 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; float w = s->origin().x / scale + s->advance() - base;
if (w > currWidth) currWidth = w; 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; diff = width - currWidth;
diffpw = diff / tWeight; diffpw = diff / tWeight;
tWeight = 0; 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); int w = s->getJustify(this, i, 3);
float pref = diffpw * w + error; float pref = diffpw * w + error;
@ -224,8 +225,10 @@ float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUS
if (silf()->flags() & 1) if (silf()->flags() & 1)
{ {
delLineEnd(m_first); if (m_first)
delLineEnd(m_last); delLineEnd(m_first);
if (m_last)
delLineEnd(m_last);
} }
m_first = oldFirst; m_first = oldFirst;
m_last = oldLast; m_last = oldLast;
@ -277,4 +280,3 @@ void Segment::delLineEnd(Slot *s)
s->prev()->next(NULL); s->prev()->next(NULL);
freeSlot(s); freeSlot(s);
} }

View file

@ -51,7 +51,7 @@ NameTable::NameTable(const void* data, size_t length, uint16 platformId, uint16
{ {
m_nameData = reinterpret_cast<const uint8*>(pdata) + offset; m_nameData = reinterpret_cast<const uint8*>(pdata) + offset;
setPlatformEncoding(platformId, encodingID); setPlatformEncoding(platformId, encodingID);
m_nameDataLength = length - offset; m_nameDataLength = uint16(length - offset);
return; return;
} }
} }
@ -180,7 +180,7 @@ void* NameTable::getName(uint16& languageId, uint16 nameId, gr_encform enc, uint
utf8::iterator d = uniBuffer; utf8::iterator d = uniBuffer;
for (utf16::const_iterator s = utf16Name, e = utf16Name + utf16Length; s != e; ++s, ++d) for (utf16::const_iterator s = utf16Name, e = utf16Name + utf16Length; s != e; ++s, ++d)
*d = *s; *d = *s;
length = d - uniBuffer; length = uint32(d - uniBuffer);
uniBuffer[length] = 0; uniBuffer[length] = 0;
free(utf16Name); free(utf16Name);
return uniBuffer; return uniBuffer;
@ -201,7 +201,7 @@ void* NameTable::getName(uint16& languageId, uint16 nameId, gr_encform enc, uint
utf32::iterator d = uniBuffer; utf32::iterator d = uniBuffer;
for (utf16::const_iterator s = utf16Name, e = utf16Name + utf16Length; s != e; ++s, ++d) for (utf16::const_iterator s = utf16Name, e = utf16Name + utf16Length; s != e; ++s, ++d)
*d = *s; *d = *s;
length = d - uniBuffer; length = uint32(d - uniBuffer);
uniBuffer[length] = 0; uniBuffer[length] = 0;
free(utf16Name); free(utf16Name);
return uniBuffer; return uniBuffer;
@ -252,4 +252,3 @@ uint16 NameTable::getLanguageId(const char * bcp47Locale)
} }
return localeId; return localeId;
} }

View file

@ -97,10 +97,10 @@ bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t su
* const pass_end = p + pass_length; * const pass_end = p + pass_length;
size_t numRanges; size_t numRanges;
if (e.test(pass_length < 40, E_BADPASSLENGTH)) return face.error(e); if (e.test(pass_length < 40, E_BADPASSLENGTH)) return face.error(e);
// Read in basic values // Read in basic values
const byte flags = be::read<byte>(p); const byte flags = be::read<byte>(p);
if (e.test((flags & 0x1f) && if (e.test((flags & 0x1f) &&
(pt < PASS_TYPE_POSITIONING || !m_silf->aCollision() || !face.glyphs().hasBoxes() || !(m_silf->flags() & 0x20)), (pt < PASS_TYPE_POSITIONING || !m_silf->aCollision() || !face.glyphs().hasBoxes() || !(m_silf->flags() & 0x20)),
E_BADCOLLISIONPASS)) E_BADCOLLISIONPASS))
return face.error(e); return face.error(e);
@ -191,7 +191,7 @@ bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t su
if (pass_constraint_len) if (pass_constraint_len)
{ {
face.error_context(face.error_context() + 1); face.error_context(face.error_context() + 1);
m_cPConstraint = vm::Machine::Code(true, pcCode, pcCode + pass_constraint_len, m_cPConstraint = vm::Machine::Code(true, pcCode, pcCode + pass_constraint_len,
precontext[0], be::peek<uint16>(sort_keys), *m_silf, face, PASS_TYPE_UNKNOWN); precontext[0], be::peek<uint16>(sort_keys), *m_silf, face, PASS_TYPE_UNKNOWN);
if (e.test(!m_cPConstraint, E_OUTOFMEM) if (e.test(!m_cPConstraint, E_OUTOFMEM)
|| e.test(m_cPConstraint.status() != Code::loaded, m_cPConstraint.status() + E_CODEFAILURE)) || e.test(m_cPConstraint.status() != Code::loaded, m_cPConstraint.status() + E_CODEFAILURE))
@ -246,11 +246,11 @@ bool Pass::readRules(const byte * rule_map, const size_t num_entries,
Rule * r = m_rules + m_numRules - 1; 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) 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->preContext = *--precontext;
r->sort = be::peek<uint16>(--sort_key); r->sort = be::peek<uint16>(--sort_key);
#ifndef NDEBUG #ifndef NDEBUG
r->rule_idx = n - 1; r->rule_idx = uint16(n - 1);
#endif #endif
if (r->sort > 63 || r->preContext >= r->sort || r->preContext > m_maxPreCtxt || r->preContext < m_minPreCtxt) if (r->sort > 63 || r->preContext >= r->sort || r->preContext > m_maxPreCtxt || r->preContext < m_minPreCtxt)
return false; return false;
@ -291,7 +291,7 @@ bool Pass::readRules(const byte * rule_map, const size_t num_entries,
// Load the rule entries map // Load the rule entries map
face.error_context((face.error_context() & 0xFFFF00) + EC_APASS); 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); RuleEntry * re = m_ruleMap = gralloc<RuleEntry>(num_entries);
if (e.test(!re, E_OUTOFMEM)) return face.error(e); if (e.test(!re, E_OUTOFMEM)) return face.error(e);
for (size_t n = num_entries; n; --n, ++re) 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); *s = be::read<uint16>(starts);
if (e.test(*s >= m_numStates, E_BADSTATE)) 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; 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); *t = be::read<uint16>(states);
if (e.test(*t >= m_numStates, E_BADSTATE)) 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); 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)) 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); return face.error(e);
} }
s->rules = begin; s->rules = begin;
@ -774,7 +774,7 @@ bool Pass::collisionShift(Segment *seg, int dir, json * const dbgout) const
*dbgout << json::close << json::close; // phase-1 *dbgout << json::close << json::close; // phase-1
#endif #endif
// phase 2 : loop until happy. // phase 2 : loop until happy.
for (int i = 0; i < m_numCollRuns - 1; ++i) for (int i = 0; i < m_numCollRuns - 1; ++i)
{ {
if (hasCollisions || moved) if (hasCollisions || moved)
@ -820,10 +820,10 @@ bool Pass::collisionShift(Segment *seg, int dir, json * const dbgout) const
<< json::object << "phase" << "2b" << "loop" << i << "moves" << json::array; << json::object << "phase" << "2b" << "loop" << i << "moves" << json::array;
#endif #endif
// phase 2b : redo basic diacritic positioning pass for ALL glyphs. Each successive loop adjusts // phase 2b : redo basic diacritic positioning pass for ALL glyphs. Each successive loop adjusts
// glyphs from their current adjusted position, which has the effect of gradually minimizing the // glyphs from their current adjusted position, which has the effect of gradually minimizing the
// resulting adjustment; ie, the final result will be gradually closer to the original location. // resulting adjustment; ie, the final result will be gradually closer to the original location.
// Also it allows more flexibility in the final adjustment, since it is moving along the // Also it allows more flexibility in the final adjustment, since it is moving along the
// possible 8 vectors from successively different starting locations. // possible 8 vectors from successively different starting locations.
if (moved) if (moved)
{ {
@ -962,7 +962,7 @@ bool Pass::resolveCollisions(Segment *seg, Slot *slotFix, Slot *start,
while (base->attachedTo()) while (base->attachedTo())
base = base->attachedTo(); base = base->attachedTo();
Position zero(0., 0.); Position zero(0., 0.);
// Look for collisions with the neighboring glyphs. // Look for collisions with the neighboring glyphs.
for (nbor = start; nbor; nbor = isRev ? nbor->prev() : nbor->next()) for (nbor = start; nbor; nbor = isRev ? nbor->prev() : nbor->next())
{ {
@ -982,7 +982,7 @@ bool Pass::resolveCollisions(Segment *seg, Slot *slotFix, Slot *start,
else if (nbor == slotFix) else if (nbor == slotFix)
// Switching sides of this glyph - if we were ignoring kernable stuff before, don't anymore. // Switching sides of this glyph - if we were ignoring kernable stuff before, don't anymore.
ignoreForKern = !ignoreForKern; ignoreForKern = !ignoreForKern;
if (nbor != start && (cNbor->flags() & (isRev ? SlotCollision::COLL_START : SlotCollision::COLL_END))) if (nbor != start && (cNbor->flags() & (isRev ? SlotCollision::COLL_START : SlotCollision::COLL_END)))
break; break;
} }
@ -1011,7 +1011,7 @@ bool Pass::resolveCollisions(Segment *seg, Slot *slotFix, Slot *start,
#if !defined GRAPHITE2_NTRACING #if !defined GRAPHITE2_NTRACING
if (dbgout) if (dbgout)
{ {
*dbgout << json::object *dbgout << json::object
<< "missed" << objectid(dslot(seg, slotFix)); << "missed" << objectid(dslot(seg, slotFix));
coll.outputJsonDbg(dbgout, seg, -1); coll.outputJsonDbg(dbgout, seg, -1);
*dbgout << json::close; *dbgout << json::close;
@ -1072,7 +1072,7 @@ float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start
} }
else else
{ {
space_count = 0; space_count = 0;
if (nbor != slotFix && !cNbor->ignore()) if (nbor != slotFix && !cNbor->ignore())
{ {
seenEnd = true; seenEnd = true;
@ -1105,4 +1105,3 @@ float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start
} }
return 0.; return 0.;
} }

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -95,4 +95,3 @@ Position Rect::constrainedAvoid(Position &offset, Rect &box, Rect &sdbox, Positi
return res; return res;
} }
#endif #endif

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -42,7 +42,7 @@ of the License or (at your option) any later version.
using namespace graphite2; 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_freeSlots(NULL),
m_freeJustifies(NULL), m_freeJustifies(NULL),
m_charinfo(new CharInfo[numchars]), 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_bufSize(numchars + 10),
m_numGlyphs(numchars), m_numGlyphs(numchars),
m_numCharinfo(numchars), m_numCharinfo(numchars),
m_passBits(m_silf->aPassBits() ? -1 : 0),
m_defaultOriginal(0), m_defaultOriginal(0),
m_dir(textDir), 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(); freeSlot(newSlot());
if (s)
freeSlot(s);
m_bufSize = log_binary(numchars)+1; m_bufSize = log_binary(numchars)+1;
} }
@ -77,82 +75,17 @@ Segment::~Segment()
free(m_collisions); 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) void Segment::appendSlot(int id, int cid, int gid, int iFeats, size_t coffset)
{ {
Slot *aSlot = newSlot(); Slot *aSlot = newSlot();
if (!aSlot) return; if (!aSlot) return;
m_charinfo[id].init(cid); m_charinfo[id].init(cid);
m_charinfo[id].feats(iFeats); m_charinfo[id].feats(iFeats);
m_charinfo[id].base(coffset); m_charinfo[id].base(coffset);
const GlyphFace * theGlyph = m_face->glyphs().glyphSafe(gid); const GlyphFace * theGlyph = m_face->glyphs().glyphSafe(gid);
m_charinfo[id].breakWeight(theGlyph ? theGlyph->attrs()[m_silf->aBreak()] : 0); m_charinfo[id].breakWeight(theGlyph ? theGlyph->attrs()[m_silf->aBreak()] : 0);
aSlot->child(NULL); aSlot->child(NULL);
aSlot->setGlyph(this, gid, theGlyph); aSlot->setGlyph(this, gid, theGlyph);
aSlot->originate(id); aSlot->originate(id);
@ -163,7 +96,7 @@ void Segment::appendSlot(int id, int cid, int gid, int iFeats, size_t coffset)
m_last = aSlot; m_last = aSlot;
if (!m_first) m_first = aSlot; if (!m_first) m_first = aSlot;
if (theGlyph && m_silf->aPassBits()) if (theGlyph && m_silf->aPassBits())
m_passBits &= theGlyph->attrs()[m_silf->aPassBits()] m_passBits &= theGlyph->attrs()[m_silf->aPassBits()]
| (m_silf->numPasses() > 16 ? (theGlyph->attrs()[m_silf->aPassBits() + 1] << 16) : 0); | (m_silf->numPasses() > 16 ? (theGlyph->attrs()[m_silf->aPassBits() + 1] << 16) : 0);
} }
@ -206,6 +139,7 @@ Slot *Segment::newSlot()
void Segment::freeSlot(Slot *aSlot) void Segment::freeSlot(Slot *aSlot)
{ {
if (aSlot == nullptr) return;
if (m_last == aSlot) m_last = aSlot->prev(); if (m_last == aSlot) m_last = aSlot->prev();
if (m_first == aSlot) m_first = aSlot->next(); if (m_first == aSlot) m_first = aSlot->next();
if (aSlot->attachedTo()) if (aSlot->attachedTo())
@ -214,11 +148,11 @@ void Segment::freeSlot(Slot *aSlot)
{ {
if (aSlot->firstChild()->attachedTo() == aSlot) if (aSlot->firstChild()->attachedTo() == aSlot)
{ {
aSlot->firstChild()->attachTo(NULL); aSlot->firstChild()->attachTo(nullptr);
aSlot->removeChild(aSlot->firstChild()); aSlot->removeChild(aSlot->firstChild());
} }
else else
aSlot->firstChild(NULL); aSlot->firstChild(nullptr);
} }
// reset the slot incase it is reused // reset the slot incase it is reused
::new (aSlot) Slot(aSlot->userAttrs()); ::new (aSlot) Slot(aSlot->userAttrs());
@ -230,7 +164,7 @@ void Segment::freeSlot(Slot *aSlot)
#endif #endif
// update next pointer // update next pointer
if (!m_freeSlots) if (!m_freeSlots)
aSlot->next(NULL); aSlot->next(nullptr);
else else
aSlot->next(m_freeSlots); aSlot->next(m_freeSlots);
m_freeSlots = aSlot; m_freeSlots = aSlot;
@ -243,7 +177,7 @@ SlotJustify *Segment::newJustify()
const size_t justSize = SlotJustify::size_of(m_silf->numJustLevels()); const size_t justSize = SlotJustify::size_of(m_silf->numJustLevels());
byte *justs = grzeroalloc<byte>(justSize * m_bufSize); byte *justs = grzeroalloc<byte>(justSize * m_bufSize);
if (!justs) return NULL; 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 *p = reinterpret_cast<SlotJustify *>(justs + justSize * i);
SlotJustify *next = reinterpret_cast<SlotJustify *>(justs + justSize * (i + 1)); SlotJustify *next = reinterpret_cast<SlotJustify *>(justs + justSize * (i + 1));
@ -267,64 +201,6 @@ void Segment::freeJustify(SlotJustify *aJustify)
m_freeJustifies = 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 // reverse the slots but keep diacritics in their same position after their bases
void Segment::reverseSlots() 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; int i = 0, j = 0;
CharInfo *c, *cend; CharInfo *c, *cend;
@ -476,7 +352,7 @@ void Segment::associateChars(int offset, int numChars)
for (Slot *s = m_first; s; s = s->next()) for (Slot *s = m_first; s; s = s->next())
{ {
int a; 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()); } { charinfo(a)->after(s->index()); }
--a; --a;
s->after(a); s->after(a);

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -199,8 +199,8 @@ bool Silf::readGraphite(const byte * const silf_start, size_t lSilf, Face& face,
{ {
uint32 pass_start = be::read<uint32>(o_passes); uint32 pass_start = be::read<uint32>(o_passes);
uint32 pass_end = be::peek<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) if (e.test(pass_start > pass_end, E_BADPASSSTART)
|| e.test(pass_start < passes_start, E_BADPASSSTART) || e.test(pass_start < passes_start, E_BADPASSSTART)
|| e.test(pass_end > lSilf, E_BADPASSEND)) { || e.test(pass_end > lSilf, E_BADPASSEND)) {
releaseBuffers(); return face.error(e); releaseBuffers(); return face.error(e);
@ -233,9 +233,9 @@ 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) 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 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. // 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) if (e.test(be::peek<T>(p) != cls_off, E_MISALIGNEDCLASSES)
|| e.test(max_off > (data_len - cls_off)/sizeof(uint16), E_HIGHCLASSOFFSET)) || e.test(max_off > (data_len - cls_off)/sizeof(uint16), E_HIGHCLASSOFFSET))
return ERROROFFSET; return ERROROFFSET;
@ -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 bool Silf::runGraphite(Segment *seg, uint8 firstPass, uint8 lastPass, int dobidi) const
{ {
assert(seg != 0); 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); SlotMap map(*seg, m_dir, maxSize);
FiniteStateMachine fsm(map, seg->getFace()->logger()); FiniteStateMachine fsm(map, seg->getFace()->logger());
vm::Machine m(map); vm::Machine m(map);

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -40,7 +40,7 @@ Slot::Slot(int16 *user_attrs) :
m_index(0), m_parent(NULL), m_child(NULL), m_sibling(NULL), m_index(0), m_parent(NULL), m_child(NULL), m_sibling(NULL),
m_position(0, 0), m_shift(0, 0), m_advance(0, 0), m_position(0, 0), m_shift(0, 0), m_advance(0, 0),
m_attach(0, 0), m_with(0, 0), m_just(0.), m_attach(0, 0), m_with(0, 0), m_just(0.),
m_flags(0), m_attLevel(0), m_bidiCls(-1), m_bidiLevel(0), m_flags(0), m_attLevel(0), m_bidiCls(-1), m_bidiLevel(0),
m_userAttr(user_attrs), m_justs(NULL) m_userAttr(user_attrs), m_justs(NULL)
{ {
} }
@ -57,7 +57,7 @@ void Slot::set(const Slot & orig, int charOffset, size_t sizeAttr, size_t justLe
else else
m_before = orig.m_before + charOffset; m_before = orig.m_before + charOffset;
if (charOffset <= 0 && orig.m_after + charOffset >= numChars) if (charOffset <= 0 && orig.m_after + charOffset >= numChars)
m_after = numChars - 1; m_after = int(numChars) - 1;
else else
m_after = orig.m_after + charOffset; m_after = orig.m_after + charOffset;
m_parent = NULL; m_parent = NULL;
@ -107,7 +107,7 @@ Position Slot::finalise(const Segment *seg, const Font *font, Position & base, R
tAdvance = (m_advance.x - glyphFace->theAdvance().x + m_just) * scale + font->advance(glyph()); tAdvance = (m_advance.x - glyphFace->theAdvance().x + m_just) * scale + font->advance(glyph());
else else
tAdvance *= scale; tAdvance *= scale;
} }
Position res; Position res;
m_position = base + shift; m_position = base + shift;
@ -142,7 +142,7 @@ Position Slot::finalise(const Segment *seg, const Font *font, Position & base, R
Position tRes = m_sibling->finalise(seg, font, base, bbox, attrLevel, clusterMin, rtl, isFinal, depth + 1); Position tRes = m_sibling->finalise(seg, font, base, bbox, attrLevel, clusterMin, rtl, isFinal, depth + 1);
if (tRes.x > res.x) res = tRes; if (tRes.x > res.x) res = tRes;
} }
if (!m_parent && clusterMin < base.x) if (!m_parent && clusterMin < base.x)
{ {
Position adj = Position(m_position.x - clusterMin, 0.); Position adj = Position(m_position.x - clusterMin, 0.);
@ -165,25 +165,25 @@ int32 Slot::clusterMetric(const Segment *seg, uint8 metric, uint8 attrLevel, boo
switch (metrics(metric)) switch (metrics(metric))
{ {
case kgmetLsb : case kgmetLsb :
return bbox.bl.x; return int32(bbox.bl.x);
case kgmetRsb : case kgmetRsb :
return res.x - bbox.tr.x; return int32(res.x - bbox.tr.x);
case kgmetBbTop : case kgmetBbTop :
return bbox.tr.y; return int32(bbox.tr.y);
case kgmetBbBottom : case kgmetBbBottom :
return bbox.bl.y; return int32(bbox.bl.y);
case kgmetBbLeft : case kgmetBbLeft :
return bbox.bl.x; return int32(bbox.bl.x);
case kgmetBbRight : case kgmetBbRight :
return bbox.tr.x; return int32(bbox.tr.x);
case kgmetBbWidth : case kgmetBbWidth :
return bbox.tr.x - bbox.bl.x; return int32(bbox.tr.x - bbox.bl.x);
case kgmetBbHeight : case kgmetBbHeight :
return bbox.tr.y - bbox.bl.y; return int32(bbox.tr.y - bbox.bl.y);
case kgmetAdvWidth : case kgmetAdvWidth :
return res.x; return int32(res.x);
case kgmetAdvHeight : case kgmetAdvHeight :
return res.y; return int32(res.y);
default : default :
return 0; 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 int Slot::getAttr(const Segment *seg, attrCode ind, uint8 subindex) const
{ {
if (ind == gr_slatUserDefnV1) if (ind >= gr_slatJStretch && ind < gr_slatJStretch + 20 && ind != gr_slatJWidth)
{
ind = gr_slatUserDefn;
subindex = 0;
if (seg->numAttrs() == 0)
return 0;
}
else if (ind >= gr_slatJStretch && ind < gr_slatJStretch + 20 && ind != gr_slatJWidth)
{ {
int indx = ind - gr_slatJStretch; int indx = ind - gr_slatJStretch;
return getJustify(seg, indx / 5, indx % 5); 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_slatMeasureSol: return -1; // err what's this?
case gr_slatMeasureEol: return -1; case gr_slatMeasureEol: return -1;
case gr_slatJWidth: return int(m_just); 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_slatSegSplit : return seg->charinfo(m_original)->flags() & 3;
case gr_slatBidiLevel: return m_bidiLevel; case gr_slatBidiLevel: return m_bidiLevel;
case gr_slatColFlags : { SlotCollision *c = seg->collisionInfo(this); return c ? c->flags() : 0; } case gr_slatColFlags : { SlotCollision *c = seg->collisionInfo(this); return c ? c->flags() : 0; }
case gr_slatColLimitblx : SLOTGETCOLATTR(limit().bl.x) case gr_slatColLimitblx:SLOTGETCOLATTR(limit().bl.x)
case gr_slatColLimitbly : SLOTGETCOLATTR(limit().bl.y) case gr_slatColLimitbly:SLOTGETCOLATTR(limit().bl.y)
case gr_slatColLimittrx : SLOTGETCOLATTR(limit().tr.x) case gr_slatColLimittrx:SLOTGETCOLATTR(limit().tr.x)
case gr_slatColLimittry : SLOTGETCOLATTR(limit().tr.y) case gr_slatColLimittry:SLOTGETCOLATTR(limit().tr.y)
case gr_slatColShiftx : SLOTGETCOLATTR(offset().x) case gr_slatColShiftx : SLOTGETCOLATTR(offset().x)
case gr_slatColShifty : SLOTGETCOLATTR(offset().y) case gr_slatColShifty : SLOTGETCOLATTR(offset().y)
case gr_slatColMargin : SLOTGETCOLATTR(margin()) case gr_slatColMargin : SLOTGETCOLATTR(margin())
case gr_slatColMarginWt : SLOTGETCOLATTR(marginWt()) case gr_slatColMarginWt:SLOTGETCOLATTR(marginWt())
case gr_slatColExclGlyph : SLOTGETCOLATTR(exclGlyph()) case gr_slatColExclGlyph:SLOTGETCOLATTR(exclGlyph())
case gr_slatColExclOffx : SLOTGETCOLATTR(exclOffset().x) case gr_slatColExclOffx:SLOTGETCOLATTR(exclOffset().x)
case gr_slatColExclOffy : SLOTGETCOLATTR(exclOffset().y) case gr_slatColExclOffy:SLOTGETCOLATTR(exclOffset().y)
case gr_slatSeqClass : SLOTGETCOLATTR(seqClass()) case gr_slatSeqClass : SLOTGETCOLATTR(seqClass())
case gr_slatSeqProxClass : SLOTGETCOLATTR(seqProxClass()) case gr_slatSeqProxClass:SLOTGETCOLATTR(seqProxClass())
case gr_slatSeqOrder : SLOTGETCOLATTR(seqOrder()) case gr_slatSeqOrder : SLOTGETCOLATTR(seqOrder())
case gr_slatSeqAboveXoff : SLOTGETCOLATTR(seqAboveXoff()) case gr_slatSeqAboveXoff:SLOTGETCOLATTR(seqAboveXoff())
case gr_slatSeqAboveWt : SLOTGETCOLATTR(seqAboveWt()) case gr_slatSeqAboveWt: SLOTGETCOLATTR(seqAboveWt())
case gr_slatSeqBelowXlim : SLOTGETCOLATTR(seqBelowXlim()) case gr_slatSeqBelowXlim:SLOTGETCOLATTR(seqBelowXlim())
case gr_slatSeqBelowWt : SLOTGETCOLATTR(seqBelowWt()) case gr_slatSeqBelowWt: SLOTGETCOLATTR(seqBelowWt())
case gr_slatSeqValignHt : SLOTGETCOLATTR(seqValignHt()) case gr_slatSeqValignHt:SLOTGETCOLATTR(seqValignHt())
case gr_slatSeqValignWt : SLOTGETCOLATTR(seqValignWt()) case gr_slatSeqValignWt:SLOTGETCOLATTR(seqValignWt())
default : return 0; default : return 0;
} }
} }
@ -480,7 +475,7 @@ void Slot::setGlyph(Segment *seg, uint16 glyphid, const GlyphFace * theGlyph)
m_advance = Position(aGlyph->theAdvance().x, 0.); m_advance = Position(aGlyph->theAdvance().x, 0.);
if (seg->silf()->aPassBits()) if (seg->silf()->aPassBits())
{ {
seg->mergePassBits(theGlyph->attrs()[seg->silf()->aPassBits()]); seg->mergePassBits(uint8(theGlyph->attrs()[seg->silf()->aPassBits()]));
if (seg->silf()->numPasses() > 16) if (seg->silf()->numPasses() > 16)
seg->mergePassBits(theGlyph->attrs()[seg->silf()->aPassBits()+1] << 16); seg->mergePassBits(theGlyph->attrs()[seg->silf()->aPassBits()+1] << 16);
} }
@ -532,4 +527,3 @@ bool Slot::isChildOf(const Slot *base) const
return true; return true;
return false; return false;
} }

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -31,7 +31,7 @@ Responsibility: Alan Ward
Last reviewed: Not yet. Last reviewed: Not yet.
Description Description
Implements the methods for TtfUtil class. This file should remain portable to any C++ Implements the methods for TtfUtil class. This file should remain portable to any C++
environment by only using standard C++ and the TTF structurs defined in Tt.h. environment by only using standard C++ and the TTF structurs defined in Tt.h.
-------------------------------------------------------------------------------*//*:End Ignore*/ -------------------------------------------------------------------------------*//*:End Ignore*/
@ -60,7 +60,7 @@ Description
/*********************************************************************************************** /***********************************************************************************************
Local Constants and static variables Local Constants and static variables
***********************************************************************************************/ ***********************************************************************************************/
namespace namespace
{ {
#ifdef ALL_TTFUTILS #ifdef ALL_TTFUTILS
// max number of components allowed in composite glyphs // max number of components allowed in composite glyphs
@ -79,45 +79,45 @@ namespace
const int kcPostNames = 258; const int kcPostNames = 258;
const char * rgPostName[kcPostNames] = { const char * rgPostName[kcPostNames] = {
".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl", "numbersign", ".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl", "numbersign",
"dollar", "percent", "ampersand", "quotesingle", "parenleft", "dollar", "percent", "ampersand", "quotesingle", "parenleft",
"parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash",
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight",
"nine", "colon", "semicolon", "less", "equal", "greater", "question", "nine", "colon", "semicolon", "less", "equal", "greater", "question",
"at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"bracketleft", "backslash", "bracketright", "asciicircum", "bracketleft", "backslash", "bracketright", "asciicircum",
"underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i",
"j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
"x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde",
"Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis",
"Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde", "Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde",
"aring", "ccedilla", "eacute", "egrave", "ecircumflex", "edieresis", "aring", "ccedilla", "eacute", "egrave", "ecircumflex", "edieresis",
"iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute", "iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute",
"ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave", "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave",
"ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling",
"section", "bullet", "paragraph", "germandbls", "registered", "section", "bullet", "paragraph", "germandbls", "registered",
"copyright", "trademark", "acute", "dieresis", "notequal", "AE", "copyright", "trademark", "acute", "dieresis", "notequal", "AE",
"Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen",
"mu", "partialdiff", "summation", "product", "pi", "integral", "mu", "partialdiff", "summation", "product", "pi", "integral",
"ordfeminine", "ordmasculine", "Omega", "ae", "oslash", "questiondown", "ordfeminine", "ordmasculine", "Omega", "ae", "oslash", "questiondown",
"exclamdown", "logicalnot", "radical", "florin", "approxequal", "exclamdown", "logicalnot", "radical", "florin", "approxequal",
"Delta", "guillemotleft", "guillemotright", "ellipsis", "nonbreakingspace", "Delta", "guillemotleft", "guillemotright", "ellipsis", "nonbreakingspace",
"Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash", "Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash",
"quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide",
"lozenge", "ydieresis", "Ydieresis", "fraction", "currency", "lozenge", "ydieresis", "Ydieresis", "fraction", "currency",
"guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", "periodcentered", "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", "periodcentered",
"quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex",
"Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute",
"Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex",
"apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi", "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi",
"circumflex", "tilde", "macron", "breve", "dotaccent", "ring", "circumflex", "tilde", "macron", "breve", "dotaccent", "ring",
"cedilla", "hungarumlaut", "ogonek", "caron", "Lslash", "lslash", "cedilla", "hungarumlaut", "ogonek", "caron", "Lslash", "lslash",
"Scaron", "scaron", "Zcaron", "zcaron", "brokenbar", "Eth", "eth", "Scaron", "scaron", "Zcaron", "zcaron", "brokenbar", "Eth", "eth",
"Yacute", "yacute", "Thorn", "thorn", "minus", "multiply", "Yacute", "yacute", "Thorn", "thorn", "minus", "multiply",
"onesuperior", "twosuperior", "threesuperior", "onehalf", "onequarter", "onesuperior", "twosuperior", "threesuperior", "onehalf", "onequarter",
"threequarters", "franc", "Gbreve", "gbreve", "Idotaccent", "Scedilla", "threequarters", "franc", "Gbreve", "gbreve", "Idotaccent", "Scedilla",
"scedilla", "Cacute", "cacute", "Ccaron", "ccaron", "scedilla", "Cacute", "cacute", "Ccaron", "ccaron",
"dcroat" }; "dcroat" };
#endif #endif
@ -128,18 +128,18 @@ namespace
***********************************************************************************************/ ***********************************************************************************************/
/* Note on error processing: The code guards against bad glyph ids being used to look up data /* Note on error processing: The code guards against bad glyph ids being used to look up data
in open ended tables (loca, hmtx). If the glyph id comes from a cmap this shouldn't happen in open ended tables (loca, hmtx). If the glyph id comes from a cmap this shouldn't happen
but it seems prudent to check for user errors here. The code does assume that data obtained but it seems prudent to check for user errors here. The code does assume that data obtained
from the TTF file is valid otherwise (though the CheckTable method seeks to check for from the TTF file is valid otherwise (though the CheckTable method seeks to check for
obvious problems that might accompany a change in table versions). For example an invalid obvious problems that might accompany a change in table versions). For example an invalid
offset in the loca table which could exceed the size of the glyf table is NOT trapped. offset in the loca table which could exceed the size of the glyf table is NOT trapped.
Likewise if numberOf_LongHorMetrics in the hhea table is wrong, this will NOT be trapped, Likewise if numberOf_LongHorMetrics in the hhea table is wrong, this will NOT be trapped,
which could cause a lookup in the hmtx table to exceed the table length. Of course, TTF tables which could cause a lookup in the hmtx table to exceed the table length. Of course, TTF tables
that are completely corrupt will cause unpredictable results. */ that are completely corrupt will cause unpredictable results. */
/* Note on composite glyphs: Glyphs that have components that are themselves composites /* Note on composite glyphs: Glyphs that have components that are themselves composites
are not supported. IsDeepComposite can be used to test for this. False is returned from many are not supported. IsDeepComposite can be used to test for this. False is returned from many
of the methods in this cases. It is unclear how to build composite glyphs in some cases, of the methods in this cases. It is unclear how to build composite glyphs in some cases,
so this code represents my best guess until test cases can be found. See notes on the high- so this code represents my best guess until test cases can be found. See notes on the high-
level GlyfPoints method. */ level GlyfPoints method. */
namespace graphite2 namespace graphite2
@ -167,7 +167,7 @@ bool GetHeaderInfo(size_t & lOffset, size_t & lSize)
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool CheckHeader(const void * pHdr) bool CheckHeader(const void * pHdr)
{ {
const Sfnt::OffsetSubTable * pOffsetTable const Sfnt::OffsetSubTable * pOffsetTable
= reinterpret_cast<const Sfnt::OffsetSubTable *>(pHdr); = reinterpret_cast<const Sfnt::OffsetSubTable *>(pHdr);
return pHdr && be::swap(pOffsetTable->scaler_type) == Sfnt::OffsetSubTable::TrueTypeWin; return pHdr && be::swap(pOffsetTable->scaler_type) == Sfnt::OffsetSubTable::TrueTypeWin;
@ -185,7 +185,7 @@ bool GetTableDirInfo(const void * pHdr, size_t & lOffset, size_t & lSize)
lOffset = offsetof(Sfnt::OffsetSubTable, table_directory); lOffset = offsetof(Sfnt::OffsetSubTable, table_directory);
lSize = be::swap(pOffsetTable->num_tables) lSize = be::swap(pOffsetTable->num_tables)
* sizeof(Sfnt::OffsetSubTable::Entry); * sizeof(Sfnt::OffsetSubTable::Entry);
return true; return true;
} }
@ -197,10 +197,10 @@ bool GetTableDirInfo(const void * pHdr, size_t & lOffset, size_t & lSize)
bool GetTableInfo(const Tag TableTag, const void * pHdr, const void * pTableDir, bool GetTableInfo(const Tag TableTag, const void * pHdr, const void * pTableDir,
size_t & lOffset, size_t & lSize) size_t & lOffset, size_t & lSize)
{ {
const Sfnt::OffsetSubTable * pOffsetTable const Sfnt::OffsetSubTable * pOffsetTable
= reinterpret_cast<const Sfnt::OffsetSubTable *>(pHdr); = reinterpret_cast<const Sfnt::OffsetSubTable *>(pHdr);
const size_t num_tables = be::swap(pOffsetTable->num_tables); const size_t num_tables = be::swap(pOffsetTable->num_tables);
const Sfnt::OffsetSubTable::Entry const Sfnt::OffsetSubTable::Entry
* entry_itr = reinterpret_cast<const Sfnt::OffsetSubTable::Entry *>( * entry_itr = reinterpret_cast<const Sfnt::OffsetSubTable::Entry *>(
pTableDir), pTableDir),
* const dir_end = entry_itr + num_tables; * const dir_end = entry_itr + num_tables;
@ -228,14 +228,14 @@ bool GetTableInfo(const Tag TableTag, const void * pHdr, const void * pTableDir,
bool CheckTable(const Tag TableId, const void * pTable, size_t lTableSize) bool CheckTable(const Tag TableId, const void * pTable, size_t lTableSize)
{ {
using namespace Sfnt; using namespace Sfnt;
if (pTable == 0 || lTableSize < 4) return false; if (pTable == 0 || lTableSize < 4) return false;
switch(TableId) switch(TableId)
{ {
case Tag::cmap: // cmap case Tag::cmap: // cmap
{ {
const Sfnt::CharacterCodeMap * const pCmap const Sfnt::CharacterCodeMap * const pCmap
= reinterpret_cast<const Sfnt::CharacterCodeMap *>(pTable); = reinterpret_cast<const Sfnt::CharacterCodeMap *>(pTable);
if (lTableSize < sizeof(Sfnt::CharacterCodeMap)) if (lTableSize < sizeof(Sfnt::CharacterCodeMap))
return false; return false;
@ -244,39 +244,39 @@ bool CheckTable(const Tag TableId, const void * pTable, size_t lTableSize)
case Tag::head: // head case Tag::head: // head
{ {
const Sfnt::FontHeader * const pHead const Sfnt::FontHeader * const pHead
= reinterpret_cast<const Sfnt::FontHeader *>(pTable); = reinterpret_cast<const Sfnt::FontHeader *>(pTable);
if (lTableSize < sizeof(Sfnt::FontHeader)) if (lTableSize < sizeof(Sfnt::FontHeader))
return false; return false;
bool r = be::swap(pHead->version) == OneFix bool r = be::swap(pHead->version) == OneFix
&& be::swap(pHead->magic_number) == FontHeader::MagicNumber && be::swap(pHead->magic_number) == FontHeader::MagicNumber
&& be::swap(pHead->glyph_data_format) && be::swap(pHead->glyph_data_format)
== FontHeader::GlypDataFormat == FontHeader::GlypDataFormat
&& (be::swap(pHead->index_to_loc_format) && (be::swap(pHead->index_to_loc_format)
== FontHeader::ShortIndexLocFormat == FontHeader::ShortIndexLocFormat
|| be::swap(pHead->index_to_loc_format) || be::swap(pHead->index_to_loc_format)
== FontHeader::LongIndexLocFormat) == FontHeader::LongIndexLocFormat)
&& sizeof(FontHeader) <= lTableSize; && sizeof(FontHeader) <= lTableSize;
return r; return r;
} }
case Tag::post: // post case Tag::post: // post
{ {
const Sfnt::PostScriptGlyphName * const pPost const Sfnt::PostScriptGlyphName * const pPost
= reinterpret_cast<const Sfnt::PostScriptGlyphName *>(pTable); = reinterpret_cast<const Sfnt::PostScriptGlyphName *>(pTable);
if (lTableSize < sizeof(Sfnt::PostScriptGlyphName)) if (lTableSize < sizeof(Sfnt::PostScriptGlyphName))
return false; return false;
const fixed format = be::swap(pPost->format); const fixed format = be::swap(pPost->format);
bool r = format == PostScriptGlyphName::Format1 bool r = format == PostScriptGlyphName::Format1
|| format == PostScriptGlyphName::Format2 || format == PostScriptGlyphName::Format2
|| format == PostScriptGlyphName::Format3 || format == PostScriptGlyphName::Format3
|| format == PostScriptGlyphName::Format25; || format == PostScriptGlyphName::Format25;
return r; return r;
} }
case Tag::hhea: // hhea case Tag::hhea: // hhea
{ {
const Sfnt::HorizontalHeader * pHhea = const Sfnt::HorizontalHeader * pHhea =
reinterpret_cast<const Sfnt::HorizontalHeader *>(pTable); reinterpret_cast<const Sfnt::HorizontalHeader *>(pTable);
if (lTableSize < sizeof(Sfnt::HorizontalHeader)) if (lTableSize < sizeof(Sfnt::HorizontalHeader))
return false; return false;
@ -288,7 +288,7 @@ bool CheckTable(const Tag TableId, const void * pTable, size_t lTableSize)
case Tag::maxp: // maxp case Tag::maxp: // maxp
{ {
const Sfnt::MaximumProfile * pMaxp = const Sfnt::MaximumProfile * pMaxp =
reinterpret_cast<const Sfnt::MaximumProfile *>(pTable); reinterpret_cast<const Sfnt::MaximumProfile *>(pTable);
if (lTableSize < sizeof(Sfnt::MaximumProfile)) if (lTableSize < sizeof(Sfnt::MaximumProfile))
return false; return false;
@ -299,20 +299,20 @@ bool CheckTable(const Tag TableId, const void * pTable, size_t lTableSize)
case Tag::OS_2: // OS/2 case Tag::OS_2: // OS/2
{ {
const Sfnt::Compatibility * pOs2 const Sfnt::Compatibility * pOs2
= reinterpret_cast<const Sfnt::Compatibility *>(pTable); = reinterpret_cast<const Sfnt::Compatibility *>(pTable);
if (be::swap(pOs2->version) == 0) if (be::swap(pOs2->version) == 0)
{ // OS/2 table version 1 size { // OS/2 table version 1 size
// if (sizeof(Sfnt::Compatibility) // if (sizeof(Sfnt::Compatibility)
// - sizeof(uint32)*2 - sizeof(int16)*2 // - sizeof(uint32)*2 - sizeof(int16)*2
// - sizeof(uint16)*3 <= lTableSize) // - sizeof(uint16)*3 <= lTableSize)
if (sizeof(Sfnt::Compatibility0) <= lTableSize) if (sizeof(Sfnt::Compatibility0) <= lTableSize)
return true; return true;
} }
else if (be::swap(pOs2->version) == 1) else if (be::swap(pOs2->version) == 1)
{ // OS/2 table version 2 size { // OS/2 table version 2 size
// if (sizeof(Sfnt::Compatibility) // if (sizeof(Sfnt::Compatibility)
// - sizeof(int16) *2 // - sizeof(int16) *2
// - sizeof(uint16)*3 <= lTableSize) // - sizeof(uint16)*3 <= lTableSize)
if (sizeof(Sfnt::Compatibility1) <= lTableSize) if (sizeof(Sfnt::Compatibility1) <= lTableSize)
return true; return true;
@ -334,7 +334,7 @@ bool CheckTable(const Tag TableId, const void * pTable, size_t lTableSize)
case Tag::name: case Tag::name:
{ {
const Sfnt::FontNames * pName const Sfnt::FontNames * pName
= reinterpret_cast<const Sfnt::FontNames *>(pTable); = reinterpret_cast<const Sfnt::FontNames *>(pTable);
if (lTableSize < sizeof(Sfnt::FontNames)) if (lTableSize < sizeof(Sfnt::FontNames))
return false; return false;
@ -360,7 +360,7 @@ bool CheckTable(const Tag TableId, const void * pTable, size_t lTableSize)
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
size_t GlyphCount(const void * pMaxp) size_t GlyphCount(const void * pMaxp)
{ {
const Sfnt::MaximumProfile * pTable = const Sfnt::MaximumProfile * pTable =
reinterpret_cast<const Sfnt::MaximumProfile *>(pMaxp); reinterpret_cast<const Sfnt::MaximumProfile *>(pMaxp);
return be::swap(pTable->num_glyphs); return be::swap(pTable->num_glyphs);
} }
@ -373,7 +373,7 @@ size_t GlyphCount(const void * pMaxp)
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
size_t MaxCompositeComponentCount(const void * pMaxp) size_t MaxCompositeComponentCount(const void * pMaxp)
{ {
const Sfnt::MaximumProfile * pTable = const Sfnt::MaximumProfile * pTable =
reinterpret_cast<const Sfnt::MaximumProfile *>(pMaxp); reinterpret_cast<const Sfnt::MaximumProfile *>(pMaxp);
return be::swap(pTable->max_component_elements); return be::swap(pTable->max_component_elements);
} }
@ -387,7 +387,7 @@ size_t MaxCompositeComponentCount(const void * pMaxp)
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
size_t MaxCompositeLevelCount(const void * pMaxp) size_t MaxCompositeLevelCount(const void * pMaxp)
{ {
const Sfnt::MaximumProfile * pTable = const Sfnt::MaximumProfile * pTable =
reinterpret_cast<const Sfnt::MaximumProfile *>(pMaxp); reinterpret_cast<const Sfnt::MaximumProfile *>(pMaxp);
return be::swap(pTable->max_component_depth); return be::swap(pTable->max_component_depth);
} }
@ -401,14 +401,14 @@ size_t MaxCompositeLevelCount(const void * pMaxp)
size_t LocaGlyphCount(size_t lLocaSize, const void * pHead) //throw(std::domain_error) size_t LocaGlyphCount(size_t lLocaSize, const void * pHead) //throw(std::domain_error)
{ {
const Sfnt::FontHeader * pTable const Sfnt::FontHeader * pTable
= reinterpret_cast<const Sfnt::FontHeader *>(pHead); = reinterpret_cast<const Sfnt::FontHeader *>(pHead);
if (be::swap(pTable->index_to_loc_format) if (be::swap(pTable->index_to_loc_format)
== Sfnt::FontHeader::ShortIndexLocFormat) == Sfnt::FontHeader::ShortIndexLocFormat)
// loca entries are two bytes and have been divided by two // loca entries are two bytes and have been divided by two
return (lLocaSize >> 1) - 1; return (lLocaSize >> 1) - 1;
if (be::swap(pTable->index_to_loc_format) if (be::swap(pTable->index_to_loc_format)
== Sfnt::FontHeader::LongIndexLocFormat) == Sfnt::FontHeader::LongIndexLocFormat)
// loca entries are four bytes // loca entries are four bytes
@ -424,9 +424,9 @@ size_t LocaGlyphCount(size_t lLocaSize, const void * pHead) //throw(std::domain_
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
int DesignUnits(const void * pHead) int DesignUnits(const void * pHead)
{ {
const Sfnt::FontHeader * pTable = const Sfnt::FontHeader * pTable =
reinterpret_cast<const Sfnt::FontHeader *>(pHead); reinterpret_cast<const Sfnt::FontHeader *>(pHead);
return be::swap(pTable->units_per_em); return be::swap(pTable->units_per_em);
} }
@ -436,9 +436,9 @@ int DesignUnits(const void * pHead)
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
int HeadTableCheckSum(const void * pHead) int HeadTableCheckSum(const void * pHead)
{ {
const Sfnt::FontHeader * pTable = const Sfnt::FontHeader * pTable =
reinterpret_cast<const Sfnt::FontHeader *>(pHead); reinterpret_cast<const Sfnt::FontHeader *>(pHead);
return be::swap(pTable->check_sum_adjustment); return be::swap(pTable->check_sum_adjustment);
} }
@ -451,9 +451,9 @@ int HeadTableCheckSum(const void * pHead)
void HeadTableCreateTime(const void * pHead, void HeadTableCreateTime(const void * pHead,
unsigned int * pnDateBC, unsigned int * pnDateAD) unsigned int * pnDateBC, unsigned int * pnDateAD)
{ {
const Sfnt::FontHeader * pTable = const Sfnt::FontHeader * pTable =
reinterpret_cast<const Sfnt::FontHeader *>(pHead); reinterpret_cast<const Sfnt::FontHeader *>(pHead);
*pnDateBC = be::swap(pTable->created[0]); *pnDateBC = be::swap(pTable->created[0]);
*pnDateAD = be::swap(pTable->created[1]); *pnDateAD = be::swap(pTable->created[1]);
} }
@ -467,9 +467,9 @@ void HeadTableCreateTime(const void * pHead,
void HeadTableModifyTime(const void * pHead, void HeadTableModifyTime(const void * pHead,
unsigned int * pnDateBC, unsigned int *pnDateAD) unsigned int * pnDateBC, unsigned int *pnDateAD)
{ {
const Sfnt::FontHeader * pTable = const Sfnt::FontHeader * pTable =
reinterpret_cast<const Sfnt::FontHeader *>(pHead); reinterpret_cast<const Sfnt::FontHeader *>(pHead);
; ;
*pnDateBC = be::swap(pTable->modified[0]); *pnDateBC = be::swap(pTable->modified[0]);
*pnDateAD = be::swap(pTable->modified[1]); *pnDateAD = be::swap(pTable->modified[1]);
} }
@ -479,7 +479,7 @@ void HeadTableModifyTime(const void * pHead,
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool IsItalic(const void * pHead) bool IsItalic(const void * pHead)
{ {
const Sfnt::FontHeader * pTable = const Sfnt::FontHeader * pTable =
reinterpret_cast<const Sfnt::FontHeader *>(pHead); reinterpret_cast<const Sfnt::FontHeader *>(pHead);
return ((be::swap(pTable->mac_style) & 0x00000002) != 0); return ((be::swap(pTable->mac_style) & 0x00000002) != 0);
@ -518,7 +518,7 @@ bool FontOs2Style(const void *pOs2, bool & fBold, bool & fItalic)
fBold = (be::swap(pTable->fs_selection) & Sfnt::Compatibility::Bold) != 0; fBold = (be::swap(pTable->fs_selection) & Sfnt::Compatibility::Bold) != 0;
fItalic = (be::swap(pTable->fs_selection) & Sfnt::Compatibility::Italic) != 0; fItalic = (be::swap(pTable->fs_selection) & Sfnt::Compatibility::Italic) != 0;
return true; return true;
} }
#endif #endif
@ -615,7 +615,7 @@ int GetLangsForNames(const void * pName, int nPlatformId, int nEncodingId,
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool Get31EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize) bool Get31EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize)
{ {
return GetNameInfo(pName, Sfnt::NameRecord::Microsoft, 1, 1033, return GetNameInfo(pName, Sfnt::NameRecord::Microsoft, 1, 1033,
Sfnt::NameRecord::Family, lOffset, lSize); Sfnt::NameRecord::Family, lOffset, lSize);
} }
@ -628,7 +628,7 @@ bool Get31EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize)
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool Get31EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize) bool Get31EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize)
{ {
return GetNameInfo(pName, Sfnt::NameRecord::Microsoft, 1, 1033, return GetNameInfo(pName, Sfnt::NameRecord::Microsoft, 1, 1033,
Sfnt::NameRecord::Fullname, lOffset, lSize); Sfnt::NameRecord::Fullname, lOffset, lSize);
} }
@ -639,7 +639,7 @@ bool Get31EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize)
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool Get30EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize) bool Get30EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize)
{ {
return GetNameInfo(pName, Sfnt::NameRecord::Microsoft, 0, 1033, return GetNameInfo(pName, Sfnt::NameRecord::Microsoft, 0, 1033,
Sfnt::NameRecord::Family, lOffset, lSize); Sfnt::NameRecord::Family, lOffset, lSize);
} }
@ -652,13 +652,13 @@ bool Get30EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize)
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool Get30EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize) bool Get30EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize)
{ {
return GetNameInfo(pName, Sfnt::NameRecord::Microsoft, 0, 1033, return GetNameInfo(pName, Sfnt::NameRecord::Microsoft, 0, 1033,
Sfnt::NameRecord::Fullname, lOffset, lSize); Sfnt::NameRecord::Fullname, lOffset, lSize);
} }
/*---------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------
Return the Glyph ID for a given Postscript name. This method finds the first glyph which Return the Glyph ID for a given Postscript name. This method finds the first glyph which
matches the requested Postscript name. Ideally every glyph should have a unique Postscript matches the requested Postscript name. Ideally every glyph should have a unique Postscript
name (except for special names such as .notdef), but this is not always true. name (except for special names such as .notdef), but this is not always true.
On failure return value less than zero. On failure return value less than zero.
-1 - table search failed -1 - table search failed
@ -667,12 +667,12 @@ bool Get30EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize)
Note: this method is not currently used by the Graphite engine. Note: this method is not currently used by the Graphite engine.
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
int PostLookup(const void * pPost, size_t lPostSize, const void * pMaxp, int PostLookup(const void * pPost, size_t lPostSize, const void * pMaxp,
const char * pPostName) const char * pPostName)
{ {
using namespace Sfnt; using namespace Sfnt;
const Sfnt::PostScriptGlyphName * pTable const Sfnt::PostScriptGlyphName * pTable
= reinterpret_cast<const Sfnt::PostScriptGlyphName *>(pPost); = reinterpret_cast<const Sfnt::PostScriptGlyphName *>(pPost);
fixed format = be::swap(pTable->format); fixed format = be::swap(pTable->format);
@ -696,19 +696,19 @@ int PostLookup(const void * pPost, size_t lPostSize, const void * pMaxp,
{ // format 1 - use standard Postscript names { // format 1 - use standard Postscript names
return iPostName; return iPostName;
} }
if (format == PostScriptGlyphName::Format25) if (format == PostScriptGlyphName::Format25)
{ {
if (iPostName == -1) if (iPostName == -1)
return -1; return -1;
const PostScriptGlyphName25 * pTable25 const PostScriptGlyphName25 * pTable25
= static_cast<const PostScriptGlyphName25 *>(pTable); = static_cast<const PostScriptGlyphName25 *>(pTable);
int cnGlyphs = GlyphCount(pMaxp); int cnGlyphs = GlyphCount(pMaxp);
for (gid16 nGlyphId = 0; nGlyphId < cnGlyphs && nGlyphId < kcPostNames; for (gid16 nGlyphId = 0; nGlyphId < cnGlyphs && nGlyphId < kcPostNames;
nGlyphId++) nGlyphId++)
{ // glyph_name_index25 contains bytes so no byte swapping needed { // glyph_name_index25 contains bytes so no byte swapping needed
// search for first glyph id that uses the standard name // search for first glyph id that uses the standard name
if (nGlyphId + pTable25->offset[nGlyphId] == iPostName) if (nGlyphId + pTable25->offset[nGlyphId] == iPostName)
return nGlyphId; return nGlyphId;
} }
@ -716,9 +716,9 @@ int PostLookup(const void * pPost, size_t lPostSize, const void * pMaxp,
if (format == PostScriptGlyphName::Format2) if (format == PostScriptGlyphName::Format2)
{ // format 2 { // format 2
const PostScriptGlyphName2 * pTable2 const PostScriptGlyphName2 * pTable2
= static_cast<const PostScriptGlyphName2 *>(pTable); = static_cast<const PostScriptGlyphName2 *>(pTable);
int cnGlyphs = be::swap(pTable2->number_of_glyphs); int cnGlyphs = be::swap(pTable2->number_of_glyphs);
if (iPostName != -1) if (iPostName != -1)
@ -737,9 +737,9 @@ int PostLookup(const void * pPost, size_t lPostSize, const void * pMaxp,
const char * pGlyphName = pFirstGlyphName; const char * pGlyphName = pFirstGlyphName;
int iInNames = 0; // index in font specific names int iInNames = 0; // index in font specific names
bool fFound = false; bool fFound = false;
const char * const endOfTable const char * const endOfTable
= reinterpret_cast<const char *>(pTable2) + lPostSize; = reinterpret_cast<const char *>(pTable2) + lPostSize;
while (pGlyphName < endOfTable && !fFound) while (pGlyphName < endOfTable && !fFound)
{ // search Pascal strings for first matching name { // search Pascal strings for first matching name
size_t nStringSize = size_t(*pGlyphName); size_t nStringSize = size_t(*pGlyphName);
if (nStrSizeGoal != nStringSize || if (nStrSizeGoal != nStringSize ||
@ -770,12 +770,12 @@ int PostLookup(const void * pPost, size_t lPostSize, const void * pMaxp,
} }
/*---------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------
Convert a Unicode character string from big endian (MSB first, Motorola) format to little Convert a Unicode character string from big endian (MSB first, Motorola) format to little
endian (LSB first, Intel) format. endian (LSB first, Intel) format.
nSize is the number of Unicode characters in the string. It should not include any nSize is the number of Unicode characters in the string. It should not include any
terminating null. If nSize is 0, it is assumed the string is null terminated. nSize terminating null. If nSize is 0, it is assumed the string is null terminated. nSize
defaults to 0. defaults to 0.
Return true if successful, false otherwise. Return true if successful, false otherwise.
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
void SwapWString(void * pWStr, size_t nSize /* = 0 */) //throw (std::invalid_argument) void SwapWString(void * pWStr, size_t nSize /* = 0 */) //throw (std::invalid_argument)
{ {
@ -803,17 +803,17 @@ void SwapWString(void * pWStr, size_t nSize /* = 0 */) //throw (std::invalid_arg
Get the left-side bearing and and advance width based on the given tables and Glyph ID Get the left-side bearing and and advance width based on the given tables and Glyph ID
Return true if successful, false otherwise. On false, one or both value could be INT_MIN Return true if successful, false otherwise. On false, one or both value could be INT_MIN
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool HorMetrics(gid16 nGlyphId, const void * pHmtx, size_t lHmtxSize, const void * pHhea, bool HorMetrics(gid16 nGlyphId, const void * pHmtx, size_t lHmtxSize, const void * pHhea,
int & nLsb, unsigned int & nAdvWid) int & nLsb, unsigned int & nAdvWid)
{ {
const Sfnt::HorizontalMetric * phmtx = const Sfnt::HorizontalMetric * phmtx =
reinterpret_cast<const Sfnt::HorizontalMetric *>(pHmtx); reinterpret_cast<const Sfnt::HorizontalMetric *>(pHmtx);
const Sfnt::HorizontalHeader * phhea = const Sfnt::HorizontalHeader * phhea =
reinterpret_cast<const Sfnt::HorizontalHeader *>(pHhea); reinterpret_cast<const Sfnt::HorizontalHeader *>(pHhea);
size_t cLongHorMetrics = be::swap(phhea->num_long_hor_metrics); size_t cLongHorMetrics = be::swap(phhea->num_long_hor_metrics);
if (nGlyphId < cLongHorMetrics) if (nGlyphId < cLongHorMetrics)
{ // glyph id is acceptable { // glyph id is acceptable
if ((nGlyphId + 1) * sizeof(Sfnt::HorizontalMetric) > lHmtxSize) return false; if ((nGlyphId + 1) * sizeof(Sfnt::HorizontalMetric) > lHmtxSize) return false;
nAdvWid = be::swap(phmtx[nGlyphId].advance_width); nAdvWid = be::swap(phmtx[nGlyphId].advance_width);
@ -899,7 +899,7 @@ bool CheckCmapSubtable4(const void * pCmapSubtable4, const void * pCmapEnd /*, u
size_t table_len = (const byte *)pCmapEnd - (const byte *)pCmapSubtable4; size_t table_len = (const byte *)pCmapEnd - (const byte *)pCmapSubtable4;
if (!pCmapSubtable4) return false; if (!pCmapSubtable4) return false;
const Sfnt::CmapSubTable * pTable = reinterpret_cast<const Sfnt::CmapSubTable *>(pCmapSubtable4); const Sfnt::CmapSubTable * pTable = reinterpret_cast<const Sfnt::CmapSubTable *>(pCmapSubtable4);
// Bob H say some freeware TT fonts have version 1 (eg, CALIGULA.TTF) // Bob H say some freeware TT fonts have version 1 (eg, CALIGULA.TTF)
// so don't check subtable version. 21 Mar 2002 spec changes version to language. // so don't check subtable version. 21 Mar 2002 spec changes version to language.
if (table_len < sizeof(*pTable) || be::swap(pTable->format) != 4) return false; if (table_len < sizeof(*pTable) || be::swap(pTable->format) != 4) return false;
const Sfnt::CmapSubTableFormat4 * pTable4 = reinterpret_cast<const Sfnt::CmapSubTableFormat4 *>(pCmapSubtable4); const Sfnt::CmapSubTableFormat4 * pTable4 = reinterpret_cast<const Sfnt::CmapSubTableFormat4 *>(pCmapSubtable4);
@ -958,7 +958,7 @@ gid16 CmapSubtable4Lookup(const void * pCmapSubtabel4, unsigned int nUnicodeId,
const Sfnt::CmapSubTableFormat4 * pTable = reinterpret_cast<const Sfnt::CmapSubTableFormat4 *>(pCmapSubtabel4); const Sfnt::CmapSubTableFormat4 * pTable = reinterpret_cast<const Sfnt::CmapSubTableFormat4 *>(pCmapSubtabel4);
uint16 nSeg = be::swap(pTable->seg_count_x2) >> 1; uint16 nSeg = be::swap(pTable->seg_count_x2) >> 1;
uint16 n; uint16 n;
const uint16 * pLeft, * pMid; const uint16 * pLeft, * pMid;
uint16 cMid, chStart, chEnd; uint16 cMid, chStart, chEnd;
@ -1211,8 +1211,8 @@ unsigned int CmapSubtable12NextCodepoint(const void *pCmap310, unsigned int nUni
Technically this method should return an unsigned long but it is unlikely the offset will Technically this method should return an unsigned long but it is unlikely the offset will
exceed 2^31. exceed 2^31.
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
size_t LocaLookup(gid16 nGlyphId, size_t LocaLookup(gid16 nGlyphId,
const void * pLoca, size_t lLocaSize, const void * pLoca, size_t lLocaSize,
const void * pHead) // throw (std::out_of_range) const void * pHead) // throw (std::out_of_range)
{ {
const Sfnt::FontHeader * pTable = reinterpret_cast<const Sfnt::FontHeader *>(pHead); const Sfnt::FontHeader * pTable = reinterpret_cast<const Sfnt::FontHeader *>(pHead);
@ -1252,8 +1252,8 @@ size_t LocaLookup(gid16 nGlyphId,
void * GlyfLookup(const void * pGlyf, size_t nGlyfOffset, size_t nTableLen) void * GlyfLookup(const void * pGlyf, size_t nGlyfOffset, size_t nTableLen)
{ {
const uint8 * pByte = reinterpret_cast<const uint8 *>(pGlyf); 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 NULL;
return const_cast<uint8 *>(pByte + nGlyfOffset); return const_cast<uint8 *>(pByte + nGlyfOffset);
} }
@ -1261,7 +1261,7 @@ void * GlyfLookup(const void * pGlyf, size_t nGlyfOffset, size_t nTableLen)
Get the bounding box coordinates for a simple glyf entry (non-composite). Get the bounding box coordinates for a simple glyf entry (non-composite).
Return true if successful, false otherwise. Return true if successful, false otherwise.
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool GlyfBox(const void * pSimpleGlyf, int & xMin, int & yMin, bool GlyfBox(const void * pSimpleGlyf, int & xMin, int & yMin,
int & xMax, int & yMax) int & xMax, int & yMax)
{ {
const Sfnt::Glyph * pGlyph = reinterpret_cast<const Sfnt::Glyph *>(pSimpleGlyf); const Sfnt::Glyph * pGlyph = reinterpret_cast<const Sfnt::Glyph *>(pSimpleGlyf);
@ -1287,14 +1287,14 @@ int GlyfContourCount(const void * pSimpleGlyf)
/*---------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------
Get the point numbers for the end points of the glyph contours for a simple Get the point numbers for the end points of the glyph contours for a simple
glyf entry (non-composite). glyf entry (non-composite).
cnPointsTotal - count of contours from GlyfContourCount(); (same as number of end points) cnPointsTotal - count of contours from GlyfContourCount(); (same as number of end points)
prgnContourEndPoints - should point to a buffer large enough to hold cnPoints integers prgnContourEndPoints - should point to a buffer large enough to hold cnPoints integers
cnPoints - count of points placed in above range cnPoints - count of points placed in above range
Return true if successful, false otherwise. Return true if successful, false otherwise.
False could indicate a multi-level composite glyphs. False could indicate a multi-level composite glyphs.
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool GlyfContourEndPoints(const void * pSimpleGlyf, int * prgnContourEndPoint, bool GlyfContourEndPoints(const void * pSimpleGlyf, int * prgnContourEndPoint,
int cnPointsTotal, int & cnPoints) int cnPointsTotal, int & cnPoints)
{ {
const Sfnt::SimpleGlyph * pGlyph = reinterpret_cast<const Sfnt::SimpleGlyph *>(pSimpleGlyf); const Sfnt::SimpleGlyph * pGlyph = reinterpret_cast<const Sfnt::SimpleGlyph *>(pSimpleGlyf);
@ -1316,19 +1316,19 @@ bool GlyfContourEndPoints(const void * pSimpleGlyf, int * prgnContourEndPoint,
Get the points for a simple glyf entry (non-composite) Get the points for a simple glyf entry (non-composite)
cnPointsTotal - count of points from largest end point obtained from GlyfContourEndPoints cnPointsTotal - count of points from largest end point obtained from GlyfContourEndPoints
prgnX & prgnY - should point to buffers large enough to hold cnPointsTotal integers prgnX & prgnY - should point to buffers large enough to hold cnPointsTotal integers
The ranges are parallel so that coordinates for point(n) are found at offset n in both The ranges are parallel so that coordinates for point(n) are found at offset n in both
ranges. This is raw point data with relative coordinates. ranges. This is raw point data with relative coordinates.
prgbFlag - should point to a buffer a large enough to hold cnPointsTotal bytes prgbFlag - should point to a buffer a large enough to hold cnPointsTotal bytes
This range is parallel to the prgnX & prgnY This range is parallel to the prgnX & prgnY
cnPoints - count of points placed in above ranges cnPoints - count of points placed in above ranges
Return true if successful, false otherwise. Return true if successful, false otherwise.
False could indicate a composite glyph False could indicate a composite glyph
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool GlyfPoints(const void * pSimpleGlyf, int * prgnX, int * prgnY, bool GlyfPoints(const void * pSimpleGlyf, int * prgnX, int * prgnY,
char * prgbFlag, int cnPointsTotal, int & cnPoints) char * prgbFlag, int cnPointsTotal, int & cnPoints)
{ {
using namespace Sfnt; using namespace Sfnt;
const Sfnt::SimpleGlyph * pGlyph = reinterpret_cast<const Sfnt::SimpleGlyph *>(pSimpleGlyf); const Sfnt::SimpleGlyph * pGlyph = reinterpret_cast<const Sfnt::SimpleGlyph *>(pSimpleGlyf);
int cContours = be::swap(pGlyph->number_of_contours); int cContours = be::swap(pGlyph->number_of_contours);
// return false for composite glyph // return false for composite glyph
@ -1341,7 +1341,7 @@ bool GlyfPoints(const void * pSimpleGlyf, int * prgnX, int * prgnY,
// skip over bounding box data & point to byte count of instructions (hints) // skip over bounding box data & point to byte count of instructions (hints)
const uint8 * pbGlyph = reinterpret_cast<const uint8 *> const uint8 * pbGlyph = reinterpret_cast<const uint8 *>
(&pGlyph->end_pts_of_contours[cContours]); (&pGlyph->end_pts_of_contours[cContours]);
// skip over hints & point to first flag // skip over hints & point to first flag
int cbHints = be::swap(*(uint16 *)pbGlyph); int cbHints = be::swap(*(uint16 *)pbGlyph);
pbGlyph += sizeof(uint16); pbGlyph += sizeof(uint16);
@ -1403,7 +1403,7 @@ bool GlyfPoints(const void * pSimpleGlyf, int * prgnX, int * prgnY,
} }
iFlag++; iFlag++;
} }
// load y coordinates // load y coordinates
iFlag = 0; iFlag = 0;
while (iFlag < cPts) while (iFlag < cPts)
@ -1432,7 +1432,7 @@ bool GlyfPoints(const void * pSimpleGlyf, int * prgnX, int * prgnY,
} }
iFlag++; iFlag++;
} }
cnPoints = cPts; cnPoints = cPts;
return true; return true;
} }
@ -1441,16 +1441,16 @@ bool GlyfPoints(const void * pSimpleGlyf, int * prgnX, int * prgnY,
Fill prgnCompId with the component Glyph IDs from pSimpleGlyf. Fill prgnCompId with the component Glyph IDs from pSimpleGlyf.
Client must allocate space before calling. Client must allocate space before calling.
pSimpleGlyf - assumed to point to a composite glyph pSimpleGlyf - assumed to point to a composite glyph
cCompIdTotal - the number of elements in prgnCompId cCompIdTotal - the number of elements in prgnCompId
cCompId - the total number of Glyph IDs stored in prgnCompId cCompId - the total number of Glyph IDs stored in prgnCompId
Return true if successful, false otherwise Return true if successful, false otherwise
False could indicate a non-composite glyph or the input array was not big enough False could indicate a non-composite glyph or the input array was not big enough
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool GetComponentGlyphIds(const void * pSimpleGlyf, int * prgnCompId, bool GetComponentGlyphIds(const void * pSimpleGlyf, int * prgnCompId,
size_t cnCompIdTotal, size_t & cnCompId) size_t cnCompIdTotal, size_t & cnCompId)
{ {
using namespace Sfnt; using namespace Sfnt;
if (GlyfContourCount(pSimpleGlyf) >= 0) if (GlyfContourCount(pSimpleGlyf) >= 0)
return false; return false;
@ -1460,13 +1460,13 @@ bool GetComponentGlyphIds(const void * pSimpleGlyf, int * prgnCompId,
uint16 GlyphFlags; uint16 GlyphFlags;
size_t iCurrentComp = 0; size_t iCurrentComp = 0;
do do
{ {
GlyphFlags = be::swap(*((uint16 *)pbGlyph)); GlyphFlags = be::swap(*((uint16 *)pbGlyph));
pbGlyph += sizeof(uint16); pbGlyph += sizeof(uint16);
prgnCompId[iCurrentComp++] = be::swap(*((uint16 *)pbGlyph)); prgnCompId[iCurrentComp++] = be::swap(*((uint16 *)pbGlyph));
pbGlyph += sizeof(uint16); pbGlyph += sizeof(uint16);
if (iCurrentComp >= cnCompIdTotal) if (iCurrentComp >= cnCompIdTotal)
return false; return false;
int nOffset = 0; int nOffset = 0;
nOffset += GlyphFlags & CompoundGlyph::Arg1Arg2Words ? 4 : 2; nOffset += GlyphFlags & CompoundGlyph::Arg1Arg2Words ? 4 : 2;
@ -1495,7 +1495,7 @@ bool GetComponentPlacement(const void * pSimpleGlyf, int nCompId,
bool fOffset, int & a, int & b) bool fOffset, int & a, int & b)
{ {
using namespace Sfnt; using namespace Sfnt;
if (GlyfContourCount(pSimpleGlyf) >= 0) if (GlyfContourCount(pSimpleGlyf) >= 0)
return false; return false;
@ -1504,7 +1504,7 @@ bool GetComponentPlacement(const void * pSimpleGlyf, int nCompId,
const uint8 * pbGlyph = reinterpret_cast<const uint8 *>(&pGlyph->end_pts_of_contours[0]); const uint8 * pbGlyph = reinterpret_cast<const uint8 *>(&pGlyph->end_pts_of_contours[0]);
uint16 GlyphFlags; uint16 GlyphFlags;
do do
{ {
GlyphFlags = be::swap(*((uint16 *)pbGlyph)); GlyphFlags = be::swap(*((uint16 *)pbGlyph));
pbGlyph += sizeof(uint16); pbGlyph += sizeof(uint16);
@ -1548,19 +1548,19 @@ bool GetComponentPlacement(const void * pSimpleGlyf, int nCompId,
pSimpleGlyph - assumed to point to a composite glyph pSimpleGlyph - assumed to point to a composite glyph
nCompId - glyph id for component of interest nCompId - glyph id for component of interest
flt11, flt11, flt11, flt11 - a 2x2 matrix giving the transform flt11, flt11, flt11, flt11 - a 2x2 matrix giving the transform
bTransOffset - whether to transform the offset from above method bTransOffset - whether to transform the offset from above method
The spec is unclear about the meaning of this flag The spec is unclear about the meaning of this flag
Currently - initialize to true for MS rasterizer and false for Mac rasterizer, then Currently - initialize to true for MS rasterizer and false for Mac rasterizer, then
on return it will indicate whether transform should apply to offset (MSDN CD 10/99) on return it will indicate whether transform should apply to offset (MSDN CD 10/99)
Return true if successful, false otherwise Return true if successful, false otherwise
False could indicate a non-composite glyph or that component wasn't found False could indicate a non-composite glyph or that component wasn't found
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool GetComponentTransform(const void * pSimpleGlyf, int nCompId, bool GetComponentTransform(const void * pSimpleGlyf, int nCompId,
float & flt11, float & flt12, float & flt21, float & flt22, float & flt11, float & flt12, float & flt21, float & flt22,
bool & fTransOffset) bool & fTransOffset)
{ {
using namespace Sfnt; using namespace Sfnt;
if (GlyfContourCount(pSimpleGlyf) >= 0) if (GlyfContourCount(pSimpleGlyf) >= 0)
return false; return false;
@ -1569,7 +1569,7 @@ bool GetComponentTransform(const void * pSimpleGlyf, int nCompId,
const uint8 * pbGlyph = reinterpret_cast<const uint8 *>(&pGlyph->end_pts_of_contours[0]); const uint8 * pbGlyph = reinterpret_cast<const uint8 *>(&pGlyph->end_pts_of_contours[0]);
uint16 GlyphFlags; uint16 GlyphFlags;
do do
{ {
GlyphFlags = be::swap(*((uint16 *)pbGlyph)); GlyphFlags = be::swap(*((uint16 *)pbGlyph));
pbGlyph += sizeof(uint16); pbGlyph += sizeof(uint16);
@ -1579,7 +1579,7 @@ bool GetComponentTransform(const void * pSimpleGlyf, int nCompId,
pbGlyph += GlyphFlags & CompoundGlyph::Arg1Arg2Words ? 4 : 2; // skip over placement data pbGlyph += GlyphFlags & CompoundGlyph::Arg1Arg2Words ? 4 : 2; // skip over placement data
if (fTransOffset) // MS rasterizer if (fTransOffset) // MS rasterizer
fTransOffset = !(GlyphFlags & CompoundGlyph::UnscaledOffset); fTransOffset = !(GlyphFlags & CompoundGlyph::UnscaledOffset);
else // Apple rasterizer else // Apple rasterizer
fTransOffset = (GlyphFlags & CompoundGlyph::ScaledOffset) != 0; fTransOffset = (GlyphFlags & CompoundGlyph::ScaledOffset) != 0;
@ -1644,13 +1644,13 @@ bool GetComponentTransform(const void * pSimpleGlyf, int nCompId,
Since this method doesn't check for spaces, it is good to call IsSpace before using it. Since this method doesn't check for spaces, it is good to call IsSpace before using it.
Return NULL on error. Return NULL on error.
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
void * GlyfLookup(gid16 nGlyphId, const void * pGlyf, const void * pLoca, void * GlyfLookup(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
size_t lGlyfSize, size_t lLocaSize, const void * pHead) size_t lGlyfSize, size_t lLocaSize, const void * pHead)
{ {
// test for valid glyph id // test for valid glyph id
// CheckTable verifies the index_to_loc_format is valid // CheckTable verifies the index_to_loc_format is valid
const Sfnt::FontHeader * pTable const Sfnt::FontHeader * pTable
= reinterpret_cast<const Sfnt::FontHeader *>(pHead); = reinterpret_cast<const Sfnt::FontHeader *>(pHead);
if (be::swap(pTable->index_to_loc_format) == Sfnt::FontHeader::ShortIndexLocFormat) if (be::swap(pTable->index_to_loc_format) == Sfnt::FontHeader::ShortIndexLocFormat)
@ -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 void * pSimpleGlyf = GlyfLookup(pGlyf, lGlyfOffset, lGlyfSize); // invalid loca offset returns null
return pSimpleGlyf; return pSimpleGlyf;
} }
@ -1683,7 +1683,7 @@ void * GlyfLookup(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
bool IsSpace(gid16 nGlyphId, const void * pLoca, size_t lLocaSize, const void * pHead) bool IsSpace(gid16 nGlyphId, const void * pLoca, size_t lLocaSize, const void * pHead)
{ {
size_t lGlyfOffset = LocaLookup(nGlyphId, pLoca, lLocaSize, pHead); size_t lGlyfOffset = LocaLookup(nGlyphId, pLoca, lLocaSize, pHead);
// the +1 should always work because there is a sentinel value at the end of the loca table // the +1 should always work because there is a sentinel value at the end of the loca table
size_t lNextGlyfOffset = LocaLookup(nGlyphId + 1, pLoca, lLocaSize, pHead); size_t lNextGlyfOffset = LocaLookup(nGlyphId + 1, pLoca, lLocaSize, pHead);
@ -1693,7 +1693,7 @@ bool IsSpace(gid16 nGlyphId, const void * pLoca, size_t lLocaSize, const void *
/*---------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------
Determine if a particular Glyph ID is a multi-level composite. Determine if a particular Glyph ID is a multi-level composite.
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool IsDeepComposite(gid16 nGlyphId, const void * pGlyf, const void * pLoca, bool IsDeepComposite(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
size_t lGlyfSize, long lLocaSize, const void * pHead) size_t lGlyfSize, long lLocaSize, const void * pHead)
{ {
if (IsSpace(nGlyphId, pLoca, lLocaSize, pHead)) {return false;} if (IsSpace(nGlyphId, pLoca, lLocaSize, pHead)) {return false;}
@ -1714,7 +1714,7 @@ bool IsDeepComposite(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
for (size_t i = 0; i < cCompId; i++) for (size_t i = 0; i < cCompId; i++)
{ {
pSimpleGlyf = GlyfLookup(static_cast<gid16>(rgnCompId[i]), pSimpleGlyf = GlyfLookup(static_cast<gid16>(rgnCompId[i]),
pGlyf, pLoca, lGlyfSize, lLocaSize, pHead); pGlyf, pLoca, lGlyfSize, lLocaSize, pHead);
if (pSimpleGlyf == NULL) {return false;} if (pSimpleGlyf == NULL) {return false;}
@ -1731,7 +1731,7 @@ bool IsDeepComposite(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
Return true if successful, false otherwise. On false, all point values will be INT_MIN Return true if successful, false otherwise. On false, all point values will be INT_MIN
False may indicate a white space glyph False may indicate a white space glyph
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool GlyfBox(gid16 nGlyphId, const void * pGlyf, const void * pLoca, bool GlyfBox(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
size_t lGlyfSize, size_t lLocaSize, const void * pHead, int & xMin, int & yMin, int & xMax, int & yMax) size_t lGlyfSize, size_t lLocaSize, const void * pHead, int & xMin, int & yMin, int & xMax, int & yMax)
{ {
xMin = yMin = xMax = yMax = INT_MIN; xMin = yMin = xMax = yMax = INT_MIN;
@ -1750,7 +1750,7 @@ bool GlyfBox(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
Return true if successful, false otherwise. On false, cnContours will be INT_MIN Return true if successful, false otherwise. On false, cnContours will be INT_MIN
False may indicate a white space glyph or a multi-level composite glyph. False may indicate a white space glyph or a multi-level composite glyph.
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool GlyfContourCount(gid16 nGlyphId, const void * pGlyf, const void * pLoca, bool GlyfContourCount(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
size_t lGlyfSize, size_t lLocaSize, const void * pHead, size_t & cnContours) size_t lGlyfSize, size_t lLocaSize, const void * pHead, size_t & cnContours)
{ {
cnContours = static_cast<size_t>(INT_MIN); cnContours = static_cast<size_t>(INT_MIN);
@ -1766,7 +1766,7 @@ bool GlyfContourCount(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
cnContours = size_t(cRtnContours); cnContours = size_t(cRtnContours);
return true; return true;
} }
//handle composite glyphs //handle composite glyphs
int rgnCompId[kMaxGlyphComponents]; // assumes no glyph will be made of more than 8 components int rgnCompId[kMaxGlyphComponents]; // assumes no glyph will be made of more than 8 components
@ -1781,11 +1781,11 @@ bool GlyfContourCount(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
for (size_t i = 0; i < cCompId; i++) for (size_t i = 0; i < cCompId; i++)
{ {
if (IsSpace(static_cast<gid16>(rgnCompId[i]), pLoca, lLocaSize, pHead)) {return false;} if (IsSpace(static_cast<gid16>(rgnCompId[i]), pLoca, lLocaSize, pHead)) {return false;}
pSimpleGlyf = GlyfLookup(static_cast<gid16>(rgnCompId[i]), pSimpleGlyf = GlyfLookup(static_cast<gid16>(rgnCompId[i]),
pGlyf, pLoca, lGlyfSize, lLocaSize, pHead); pGlyf, pLoca, lGlyfSize, lLocaSize, pHead);
if (pSimpleGlyf == 0) {return false;} if (pSimpleGlyf == 0) {return false;}
// return false on multi-level composite // return false on multi-level composite
if ((cTmp = GlyfContourCount(pSimpleGlyf)) < 0) if ((cTmp = GlyfContourCount(pSimpleGlyf)) < 0)
return false; return false;
cRtnContours += cTmp; cRtnContours += cTmp;
} }
@ -1795,7 +1795,7 @@ bool GlyfContourCount(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
} }
/*---------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------
Get the point numbers for the end points of the glyph contours based on the given tables Get the point numbers for the end points of the glyph contours based on the given tables
and Glyph ID and Glyph ID
Handles both simple and composite glyphs. Handles both simple and composite glyphs.
cnPoints - count of contours from GlyfContourCount (same as number of end points) cnPoints - count of contours from GlyfContourCount (same as number of end points)
@ -1803,7 +1803,7 @@ bool GlyfContourCount(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
Return true if successful, false otherwise. On false, all end points are INT_MIN Return true if successful, false otherwise. On false, all end points are INT_MIN
False may indicate a white space glyph or a multi-level composite glyph. False may indicate a white space glyph or a multi-level composite glyph.
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool GlyfContourEndPoints(gid16 nGlyphId, const void * pGlyf, const void * pLoca, bool GlyfContourEndPoints(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
size_t lGlyfSize, size_t lLocaSize, const void * pHead, size_t lGlyfSize, size_t lLocaSize, const void * pHead,
int * prgnContourEndPoint, size_t cnPoints) int * prgnContourEndPoint, size_t cnPoints)
{ {
@ -1819,9 +1819,9 @@ bool GlyfContourEndPoints(gid16 nGlyphId, const void * pGlyf, const void * pLoca
int cActualPts = 0; int cActualPts = 0;
if (cContours > 0) if (cContours > 0)
return GlyfContourEndPoints(pSimpleGlyf, prgnContourEndPoint, cnPoints, cActualPts); return GlyfContourEndPoints(pSimpleGlyf, prgnContourEndPoint, cnPoints, cActualPts);
// handle composite glyphs // handle composite glyphs
int rgnCompId[kMaxGlyphComponents]; // assumes no glyph will be made of more than 8 components int rgnCompId[kMaxGlyphComponents]; // assumes no glyph will be made of more than 8 components
size_t cCompIdTotal = kMaxGlyphComponents; size_t cCompIdTotal = kMaxGlyphComponents;
size_t cCompId = 0; size_t cCompId = 0;
@ -1858,21 +1858,21 @@ bool GlyfContourEndPoints(gid16 nGlyphId, const void * pGlyf, const void * pLoca
Handles both simple and composite glyphs. Handles both simple and composite glyphs.
cnPoints - count of points from largest end point obtained from GlyfContourEndPoints cnPoints - count of points from largest end point obtained from GlyfContourEndPoints
prgnX & prgnY - should point to buffers large enough to hold cnPoints integers prgnX & prgnY - should point to buffers large enough to hold cnPoints integers
The ranges are parallel so that coordinates for point(n) are found at offset n in The ranges are parallel so that coordinates for point(n) are found at offset n in
both ranges. These points are in absolute coordinates. both ranges. These points are in absolute coordinates.
prgfOnCurve - should point to a buffer a large enough to hold cnPoints bytes (bool) prgfOnCurve - should point to a buffer a large enough to hold cnPoints bytes (bool)
This range is parallel to the prgnX & prgnY This range is parallel to the prgnX & prgnY
Return true if successful, false otherwise. On false, all points may be INT_MIN Return true if successful, false otherwise. On false, all points may be INT_MIN
False may indicate a white space glyph, a multi-level composite, or a corrupt font False may indicate a white space glyph, a multi-level composite, or a corrupt font
It's not clear from the TTF spec when the transforms should be applied. Should the It's not clear from the TTF spec when the transforms should be applied. Should the
transform be done before or after attachment point calcs? (current code - before) transform be done before or after attachment point calcs? (current code - before)
Should the transform be applied to other offsets? (currently - no; however commented Should the transform be applied to other offsets? (currently - no; however commented
out code is in place so that if CompoundGlyph::UnscaledOffset on the MS rasterizer is out code is in place so that if CompoundGlyph::UnscaledOffset on the MS rasterizer is
clear (typical) then yes, and if CompoundGlyph::ScaledOffset on the Apple rasterizer is clear (typical) then yes, and if CompoundGlyph::ScaledOffset on the Apple rasterizer is
clear (typical?) then no). See GetComponentTransform. clear (typical?) then no). See GetComponentTransform.
It's also unclear where point numbering with attachment poinst starts It's also unclear where point numbering with attachment poinst starts
(currently - first point number is relative to whole glyph, second point number is (currently - first point number is relative to whole glyph, second point number is
relative to current glyph). relative to current glyph).
----------------------------------------------------------------------------------------------*/ ----------------------------------------------------------------------------------------------*/
bool GlyfPoints(gid16 nGlyphId, const void * pGlyf, bool GlyfPoints(gid16 nGlyphId, const void * pGlyf,
const void * pLoca, size_t lGlyfSize, size_t lLocaSize, const void * pHead, const void * pLoca, size_t lGlyfSize, size_t lLocaSize, const void * pHead,
@ -1882,7 +1882,7 @@ bool GlyfPoints(gid16 nGlyphId, const void * pGlyf,
memset(prgnX, 0x7F, cnPoints * sizeof(int)); memset(prgnX, 0x7F, cnPoints * sizeof(int));
memset(prgnY, 0x7F, cnPoints * sizeof(int)); memset(prgnY, 0x7F, cnPoints * sizeof(int));
if (IsSpace(nGlyphId, pLoca, lLocaSize, pHead)) if (IsSpace(nGlyphId, pLoca, lLocaSize, pHead))
return false; return false;
void * pSimpleGlyf = GlyfLookup(nGlyphId, pGlyf, pLoca, lGlyfSize, lLocaSize, pHead); void * pSimpleGlyf = GlyfLookup(nGlyphId, pGlyf, pLoca, lGlyfSize, lLocaSize, pHead);
@ -1900,7 +1900,7 @@ bool GlyfPoints(gid16 nGlyphId, const void * pGlyf,
return true; return true;
} }
// handle composite glyphs // handle composite glyphs
int rgnCompId[kMaxGlyphComponents]; // assumes no glyph will be made of more than 8 components int rgnCompId[kMaxGlyphComponents]; // assumes no glyph will be made of more than 8 components
size_t cCompIdTotal = kMaxGlyphComponents; size_t cCompIdTotal = kMaxGlyphComponents;
size_t cCompId = 0; size_t cCompId = 0;
@ -1924,12 +1924,12 @@ bool GlyfPoints(gid16 nGlyphId, const void * pGlyf,
void * pCompGlyf = GlyfLookup(static_cast<gid16>(rgnCompId[i]), pGlyf, pLoca, lGlyfSize, lLocaSize, pHead); void * pCompGlyf = GlyfLookup(static_cast<gid16>(rgnCompId[i]), pGlyf, pLoca, lGlyfSize, lLocaSize, pHead);
if (pCompGlyf == NULL) {return false;} if (pCompGlyf == NULL) {return false;}
// returns false on multi-level composite // returns false on multi-level composite
if (!GlyfPoints(pCompGlyf, prgnCurrentX, prgnCurrentY, prgbCurrentFlag, if (!GlyfPoints(pCompGlyf, prgnCurrentX, prgnCurrentY, prgbCurrentFlag,
cCurrentPoints, cActualPts)) cCurrentPoints, cActualPts))
return false; return false;
if (!GetComponentPlacement(pSimpleGlyf, rgnCompId[i], fOffset, a, b)) if (!GetComponentPlacement(pSimpleGlyf, rgnCompId[i], fOffset, a, b))
return false; return false;
if (!GetComponentTransform(pSimpleGlyf, rgnCompId[i], if (!GetComponentTransform(pSimpleGlyf, rgnCompId[i],
flt11, flt12, flt21, flt22, fTransOff)) flt11, flt12, flt21, flt22, fTransOff))
return false; return false;
bool fIdTrans = flt11 == 1.0 && flt12 == 0.0 && flt21 == 0.0 && flt22 == 1.0; bool fIdTrans = flt11 == 1.0 && flt12 == 0.0 && flt21 == 0.0 && flt22 == 1.0;
@ -1948,18 +1948,18 @@ bool GlyfPoints(gid16 nGlyphId, const void * pGlyf,
prgnCurrentX[j] = (int)(x * flt11 + y * flt12); prgnCurrentX[j] = (int)(x * flt11 + y * flt12);
prgnCurrentY[j] = (int)(x * flt21 + y * flt22); prgnCurrentY[j] = (int)(x * flt21 + y * flt22);
} }
// apply placement - see main method note above // apply placement - see main method note above
int nXOff, nYOff; int nXOff, nYOff;
if (fOffset) // explicit x & y offsets if (fOffset) // explicit x & y offsets
{ {
/* ignore fTransOff for now /* ignore fTransOff for now
if (fTransOff && !fIdTrans) if (fTransOff && !fIdTrans)
{ // transform x & y offsets { // transform x & y offsets
nXOff = (int)(a * flt11 + b * flt12); nXOff = (int)(a * flt11 + b * flt12);
nYOff = (int)(a * flt21 + b * flt22); nYOff = (int)(a * flt21 + b * flt22);
} }
else */ else */
{ // don't transform offset { // don't transform offset
nXOff = a; nXOff = a;
nYOff = b; nYOff = b;
@ -2004,7 +2004,7 @@ bool SimplifyFlags(char * prgbFlags, int cnPoints)
/*---------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------
Convert relative point coordinates to absolute coordinates Convert relative point coordinates to absolute coordinates
Points are stored in the font such that they are offsets from one another except for the Points are stored in the font such that they are offsets from one another except for the
first point of a glyph. first point of a glyph.
---------------------------------------------------------------------------------------------*/ ---------------------------------------------------------------------------------------------*/
bool CalcAbsolutePoints(int * prgnX, int * prgnY, int cnPoints) bool CalcAbsolutePoints(int * prgnX, int * prgnY, int cnPoints)

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -28,8 +28,8 @@ of the License or (at your option) any later version.
// Author: Tim Eves // Author: Tim Eves
// Build either this interpreter or the direct_machine implementation. // Build either this interpreter or the direct_machine implementation.
// The call threaded interpreter is portable across compilers and // The call threaded interpreter is portable across compilers and
// architectures as well as being useful to debug (you can set breakpoints on // architectures as well as being useful to debug (you can set breakpoints on
// opcodes) but is slower that the direct threaded interpreter by a factor of 2 // opcodes) but is slower that the direct threaded interpreter by a factor of 2
#include <cassert> #include <cassert>
@ -117,7 +117,7 @@ Machine::stack_t Machine::run(const instr * program,
* const sb = sp; * const sb = sp;
regbank reg = {*map, map, _map, _map.begin()+_map.context(), ip, _map.dir(), 0, _status}; regbank reg = {*map, map, _map, _map.begin()+_map.context(), ip, _map.dir(), 0, _status};
// Run the program // Run the program
while ((reinterpret_cast<ip_t>(*++ip))(dp, sp, sb, reg)) {} while ((reinterpret_cast<ip_t>(*++ip))(dp, sp, sb, reg)) {}
const stack_t ret = sp == _stack+STACK_GUARD+1 ? *sp-- : 0; const stack_t ret = sp == _stack+STACK_GUARD+1 ? *sp-- : 0;
@ -136,5 +136,3 @@ const opcode_t * Machine::getOpcodeTable() throw()
{ {
return opcode_table; return opcode_table;
} }

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -28,12 +28,12 @@ of the License or (at your option) any later version.
// Author: Tim Eves // Author: Tim Eves
// Build either this interpreter or the call_machine implementation. // Build either this interpreter or the call_machine implementation.
// The direct threaded interpreter is relies upon a gcc feature called // The direct threaded interpreter is relies upon a gcc feature called
// labels-as-values so is only portable to compilers that support the // labels-as-values so is only portable to compilers that support the
// extension (gcc only as far as I know) however it should build on any // extension (gcc only as far as I know) however it should build on any
// architecture gcc supports. // architecture gcc supports.
// This is twice as fast as the call threaded model and is likely faster on // This is twice as fast as the call threaded model and is likely faster on
// inorder processors with short pipelines and little branch prediction such // inorder processors with short pipelines and little branch prediction such
// as the ARM and possibly Atom chips. // as the ARM and possibly Atom chips.
@ -65,7 +65,7 @@ const void * direct_run(const bool get_table_mode,
Machine::status_t & status, Machine::status_t & status,
SlotMap * __smap=0) SlotMap * __smap=0)
{ {
// We need to define and return to opcode table from within this function // We need to define and return to opcode table from within this function
// other inorder to take the addresses of the instruction bodies. // other inorder to take the addresses of the instruction bodies.
#include "inc/opcode_table.h" #include "inc/opcode_table.h"
if (get_table_mode) if (get_table_mode)
@ -83,13 +83,13 @@ const void * direct_run(const bool get_table_mode,
* const mapb = smap.begin()+smap.context(); * const mapb = smap.begin()+smap.context();
uint8 dir = _dir; uint8 dir = _dir;
int8 flags = 0; int8 flags = 0;
// start the program // start the program
goto **ip; goto **ip;
// Pull in the opcode definitions // Pull in the opcode definitions
#include "inc/opcodes.h" #include "inc/opcodes.h"
end: end:
__map = map; __map = map;
*__map = is; *__map = is;
@ -111,11 +111,10 @@ Machine::stack_t Machine::run(const instr * program,
slotref * & is) slotref * & is)
{ {
assert(program != 0); assert(program != 0);
const stack_t *sp = static_cast<const stack_t *>( const stack_t *sp = static_cast<const stack_t *>(
direct_run(false, program, data, _stack, is, _map.dir(), _status, &_map)); direct_run(false, program, data, _stack, is, _map.dir(), _status, &_map));
const stack_t ret = sp == _stack+STACK_GUARD+1 ? *sp-- : 0; const stack_t ret = sp == _stack+STACK_GUARD+1 ? *sp-- : 0;
check_final_stack(sp); check_final_stack(sp);
return ret; return ret;
} }

View file

@ -15,8 +15,8 @@
# #
# You should also have received a copy of the GNU Lesser General Public # You should also have received a copy of the GNU Lesser General Public
# License along with this library in the file named "LICENSE". # License along with this library in the file named "LICENSE".
# If not, write to the Free Software Foundation, 51 Franklin Street, # 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 # Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
# internet at http://www.fsf.org/licenses/lgpl.html. # internet at http://www.fsf.org/licenses/lgpl.html.
# #
# Alternatively, the contents of this file may be used under the terms of the # Alternatively, the contents of this file may be used under the terms of the
@ -63,9 +63,6 @@ $(_NS)_SOURCES = \
$($(_NS)_BASE)/src/NameTable.cpp \ $($(_NS)_BASE)/src/NameTable.cpp \
$($(_NS)_BASE)/src/Pass.cpp \ $($(_NS)_BASE)/src/Pass.cpp \
$($(_NS)_BASE)/src/Position.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/Segment.cpp \
$($(_NS)_BASE)/src/Silf.cpp \ $($(_NS)_BASE)/src/Silf.cpp \
$($(_NS)_BASE)/src/Slot.cpp \ $($(_NS)_BASE)/src/Slot.cpp \
@ -104,9 +101,6 @@ $(_NS)_PRIVATE_HEADERS = \
$($(_NS)_BASE)/src/inc/Pass.h \ $($(_NS)_BASE)/src/inc/Pass.h \
$($(_NS)_BASE)/src/inc/Position.h \ $($(_NS)_BASE)/src/inc/Position.h \
$($(_NS)_BASE)/src/inc/Rule.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/Segment.h \
$($(_NS)_BASE)/src/inc/Silf.h \ $($(_NS)_BASE)/src/inc/Silf.h \
$($(_NS)_BASE)/src/inc/Slot.h \ $($(_NS)_BASE)/src/inc/Slot.h \
@ -120,4 +114,3 @@ $(_NS)_PUBLIC_HEADERS = \
$($(_NS)_BASE)/include/graphite2/Log.h \ $($(_NS)_BASE)/include/graphite2/Log.h \
$($(_NS)_BASE)/include/graphite2/Segment.h \ $($(_NS)_BASE)/include/graphite2/Segment.h \
$($(_NS)_BASE)/include/graphite2/Types.h $($(_NS)_BASE)/include/graphite2/Types.h

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -28,7 +28,6 @@ of the License or (at your option) any later version.
#include "inc/Face.h" #include "inc/Face.h"
#include "inc/FileFace.h" #include "inc/FileFace.h"
#include "inc/GlyphCache.h" #include "inc/GlyphCache.h"
#include "inc/CachedFace.h"
#include "inc/CmapCache.h" #include "inc/CmapCache.h"
#include "inc/Silf.h" #include "inc/Silf.h"
#include "inc/json.h" #include "inc/json.h"
@ -47,8 +46,7 @@ namespace
telemetry::category _misc_cat(face.tele.misc); telemetry::category _misc_cat(face.tele.misc);
#endif #endif
Face::Table silf(face, Tag::Silf, 0x00050000); Face::Table silf(face, Tag::Silf, 0x00050000);
if (silf) options &= ~gr_face_dumbRendering; if (!silf)
else if (!(options & gr_face_dumbRendering))
return false; return false;
if (!face.readGlyphs(options)) if (!face.readGlyphs(options))
@ -74,14 +72,24 @@ namespace
return true; return true;
} }
else 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;
} }
} }
extern "C" { extern "C" {
gr_face* gr_make_face_with_ops(const void* appFaceHandle/*non-NULL*/, const gr_face_ops *ops, unsigned int faceOptions) gr_face* gr_make_face_with_ops(const void* appFaceHandle/*non-NULL*/, const gr_face_ops *ops, unsigned int faceOptions)
//the appFaceHandle must stay alive all the time when the gr_face is alive. When finished with the gr_face, call destroy_face //the appFaceHandle must stay alive all the time when the gr_face is alive. When finished with the gr_face, call destroy_face
{ {
if (ops == 0) return 0; if (ops == 0) return 0;
@ -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); 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) 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)
//the appFaceHandle must stay alive all the time when the GrFace is alive. When finished with the GrFace, call destroy_face
{ {
if (ops == 0) return 0; return gr_make_face_with_ops(appFaceHandle, ops, faceOptions);
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;
} }
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}; const gr_face_ops ops = {sizeof(gr_face_ops), tablefn, NULL};
return gr_make_face_with_seg_cache_and_ops(appFaceHandle, &ops, cacheSize, faceOptions); return gr_make_face_with_ops(appFaceHandle, &ops, faceOptions);
} }
#endif
gr_uint32 gr_str_to_tag(const char *str) gr_uint32 gr_str_to_tag(const char *str)
{ {
uint32 res = 0; uint32 res = 0;
int i = strlen(str); switch(max(strlen(str),size_t(4)))
if (i > 4) i = 4; {
while (--i >= 0) case 4: res |= str[3]; GR_FALLTHROUGH;
res = (res >> 8) + (str[i] << 24); 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; return res;
} }
void gr_tag_to_str(gr_uint32 tag, char *str) void gr_tag_to_str(gr_uint32 tag, char *str)
{ {
int i = 4; if (!str) return;
while (--i >= 0)
{
str[i] = tag & 0xFF;
tag >>= 8;
}
}
inline *str++ = char(tag >> 24);
uint32 zeropad(const uint32 x) *str++ = char(tag >> 16);
{ *str++ = char(tag >> 8);
if (x == 0x20202020) return 0; *str++ = char(tag);
if ((x & 0x00FFFFFF) == 0x00202020) return x & 0xFF000000; *str = '\0';
if ((x & 0x0000FFFF) == 0x00002020) return x & 0xFFFF0000;
if ((x & 0x000000FF) == 0x00000020) return x & 0xFFFFFF00;
return x;
} }
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 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
@ -246,37 +239,18 @@ gr_face* gr_make_file_face(const char *filename, unsigned int faceOptions)
return pRes; return pRes;
} }
} }
//error when loading //error when loading
delete pFileFace; delete pFileFace;
return NULL; return NULL;
} }
#ifndef GRAPHITE2_NSEGCACHE 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
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
//when finished with, call destroy_face //when finished with, call destroy_face
{ {
FileFace* pFileFace = new FileFace(filename); return gr_make_file_face(filename, faceOptions);
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;
} }
#endif
#endif //!GRAPHITE2_NFILEFACE #endif //!GRAPHITE2_NFILEFACE
} // extern "C" } // extern "C"

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -46,7 +46,7 @@ gr_uint16 gr_fref_feature_value(const gr_feature_ref* pfeatureref, const gr_feat
int gr_fref_set_feature_value(const gr_feature_ref* pfeatureref, gr_uint16 val, gr_feature_val* pDest) int gr_fref_set_feature_value(const gr_feature_ref* pfeatureref, gr_uint16 val, gr_feature_val* pDest)
{ {
if (!pfeatureref || !pDest) return 0; if (!pfeatureref || !pDest) return 0;
return pfeatureref->applyValToFeature(val, *pDest); return pfeatureref->applyValToFeature(val, *pDest);
} }
@ -55,7 +55,7 @@ gr_uint32 gr_fref_id(const gr_feature_ref* pfeatureref) //returns 0 if pointe
{ {
if (!pfeatureref) if (!pfeatureref)
return 0; return 0;
return pfeatureref->getId(); return pfeatureref->getId();
} }
@ -125,10 +125,10 @@ void gr_label_destroy(void * label)
} }
gr_feature_val* gr_featureval_clone(const gr_feature_val* pfeatures/*may be NULL*/) gr_feature_val* gr_featureval_clone(const gr_feature_val* pfeatures/*may be NULL*/)
{ //When finished with the Features, call features_destroy { //When finished with the Features, call features_destroy
return static_cast<gr_feature_val*>(pfeatures ? new Features(*pfeatures) : new Features); return static_cast<gr_feature_val*>(pfeatures ? new Features(*pfeatures) : new Features);
} }
void gr_featureval_destroy(gr_feature_val *p) void gr_featureval_destroy(gr_feature_val *p)
{ {
delete static_cast<Features*>(p); delete static_cast<Features*>(p);

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -46,7 +46,7 @@ gr_font* gr_make_font(float ppm/*pixels per em*/, const gr_face *face)
gr_font* gr_make_font_with_ops(float ppm/*pixels per em*/, const void* appFontHandle/*non-NULL*/, const gr_font_ops * font_ops, const gr_face * face/*needed for scaling*/) gr_font* gr_make_font_with_ops(float ppm/*pixels per em*/, const void* appFontHandle/*non-NULL*/, const gr_font_ops * font_ops, const gr_face * face/*needed for scaling*/)
{ //the appFontHandle must stay alive all the time when the gr_font is alive. When finished with the gr_font, call destroy_gr_font { //the appFontHandle must stay alive all the time when the gr_font is alive. When finished with the gr_font, call destroy_gr_font
if (face == 0 || ppm <= 0) return 0; if (face == 0 || ppm <= 0) return 0;
Font * const res = new Font(ppm, *face, appFontHandle, font_ops); Font * const res = new Font(ppm, *face, appFontHandle, font_ops);
@ -72,7 +72,3 @@ void gr_font_destroy(gr_font *font)
} // extern "C" } // extern "C"

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -225,7 +225,7 @@ json & graphite2::operator << (json & j, const dslot & ds) throw()
} }
if (cslot) if (cslot)
{ {
// Note: the reason for using Positions to lump together related attributes is to make the // Note: the reason for using Positions to lump together related attributes is to make the
// JSON output slightly more compact. // JSON output slightly more compact.
j << "collision" << json::flat << json::object j << "collision" << json::flat << json::object
// << "shift" << cslot->shift() -- not used pass level, only within the collision routine itself // << "shift" << cslot->shift() -- not used pass level, only within the collision routine itself
@ -252,14 +252,14 @@ json & graphite2::operator << (json & j, const dslot & ds) throw()
graphite2::objectid::objectid(const dslot & ds) throw() graphite2::objectid::objectid(const dslot & ds) throw()
{ {
const Slot * const p = ds.second; 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)); sprintf(name, "%.4x-%.2x-%.4hx", uint16(s >> 16), uint16(p ? p->userAttrs()[ds.first->silf()->numUser()] : 0), uint16(s));
name[sizeof name-1] = 0; name[sizeof name-1] = 0;
} }
graphite2::objectid::objectid(const Segment * const p) throw() 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)); sprintf(name, "%.4x-%.2x-%.4hx", uint16(s >> 16), 0, uint16(s));
name[sizeof name-1] = 0; name[sizeof name-1] = 0;
} }

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -30,7 +30,7 @@ of the License or (at your option) any later version.
using namespace graphite2; using namespace graphite2;
namespace namespace
{ {
gr_segment* makeAndInitialize(const Font *font, const Face *face, uint32 script, const Features* pFeats/*must not be NULL*/, gr_encform enc, const void* pStart, size_t nChars, int dir) gr_segment* makeAndInitialize(const Font *font, const Face *face, uint32 script, const Features* pFeats/*must not be NULL*/, gr_encform enc, const void* pStart, size_t nChars, int dir)
@ -42,7 +42,7 @@ namespace
// if (!font) return NULL; // if (!font) return NULL;
Segment* pRes=new Segment(nChars, face, script, dir); Segment* pRes=new Segment(nChars, face, script, dir);
if (!pRes->read_text(face, pFeats, enc, pStart, nChars) || !pRes->runGraphite()) if (!pRes->read_text(face, pFeats, enc, pStart, nChars) || !pRes->runGraphite())
{ {
delete pRes; delete pRes;
@ -53,34 +53,37 @@ namespace
return static_cast<gr_segment*>(pRes); 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)
{
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;
}
else
{
while ((usv = *first) != 0 && !first.error())
{
++first;
++n_chars;
}
}
if (error) *error = first.error() ? first : 0;
return n_chars;
}
} }
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)
{
for (;first != last; ++first, ++n_chars)
if ((usv = *first) == 0 || first.error()) break;
}
else
{
while ((usv = *first) != 0 && !first.error())
{
++first;
++n_chars;
}
}
if (error) *error = first.error() ? first : 0;
return n_chars;
}
extern "C" { 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 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) 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; const gr_feature_val * tmp_feats = 0;
if (pFeats == 0) if (pFeats == 0)
pFeats = tmp_feats = static_cast<const gr_feature_val*>(face->theSill().cloneFeatures(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*/) unsigned int gr_seg_n_cinfo(const gr_segment* pSeg/*not NULL*/)
{ {
assert(pSeg); 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*/) unsigned int gr_seg_n_slots(const gr_segment* pSeg/*not NULL*/)
{ {
assert(pSeg); assert(pSeg);
return pSeg->slotCount(); return static_cast<unsigned int>(pSeg->slotCount());
} }
const gr_slot* gr_seg_first_slot(gr_segment* pSeg/*not NULL*/) const gr_slot* gr_seg_first_slot(gr_segment* pSeg/*not NULL*/)

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -58,7 +58,7 @@ const gr_slot* gr_slot_first_attachment(const gr_slot* p/*not NULL*/) //r
return static_cast<const gr_slot*>(p->firstChild()); return static_cast<const gr_slot*>(p->firstChild());
} }
const gr_slot* gr_slot_next_sibling_attachment(const gr_slot* p/*not NULL*/) //returns NULL iff no more attachments. const gr_slot* gr_slot_next_sibling_attachment(const gr_slot* p/*not NULL*/) //returns NULL iff no more attachments.
{ //if slot_next_sibling_attachment(p) is not NULL, then slot_attached_to(slot_next_sibling_attachment(p))==slot_attached_to(p). { //if slot_next_sibling_attachment(p) is not NULL, then slot_attached_to(slot_next_sibling_attachment(p))==slot_attached_to(p).
assert(p); assert(p);
@ -112,7 +112,7 @@ float gr_slot_advance_Y(const gr_slot *p/*not NULL*/, GR_MAYBE_UNUSED const gr_f
else else
return res; return res;
} }
int gr_slot_before(const gr_slot* p/*not NULL*/) int gr_slot_before(const gr_slot* p/*not NULL*/)
{ {
assert(p); assert(p);
@ -170,4 +170,3 @@ size_t id(const gr_slot* p/*not NULL*/)
} // extern "C" } // extern "C"

View file

@ -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

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -64,4 +64,3 @@ private:
} // namespace graphite2 } // namespace graphite2
struct gr_char_info : public graphite2::CharInfo {}; struct gr_char_info : public graphite2::CharInfo {};

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -24,7 +24,7 @@ Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
License, as published by the Free Software Foundation, either version 2 License, as published by the Free Software Foundation, either version 2
of the License or (at your option) any later version. of the License or (at your option) any later version.
*/ */
// This class represents loaded graphite stack machine code. It performs // This class represents loaded graphite stack machine code. It performs
// basic sanity checks, on the incoming code to prevent more obvious problems // basic sanity checks, on the incoming code to prevent more obvious problems
// from crashing graphite. // from crashing graphite.
// Author: Tim Eves // Author: Tim Eves
@ -54,11 +54,11 @@ namespace vm {
class Machine::Code class Machine::Code
{ {
public: public:
enum status_t enum status_t
{ {
loaded, loaded,
alloc_failed, alloc_failed,
invalid_opcode, invalid_opcode,
unimplemented_opcode_used, unimplemented_opcode_used,
out_of_range_data, out_of_range_data,
jump_past_end, jump_past_end,
@ -94,7 +94,7 @@ public:
enum passtype pt, byte * * const _out = 0); enum passtype pt, byte * * const _out = 0);
Code(const Machine::Code &) throw(); Code(const Machine::Code &) throw();
~Code() throw(); ~Code() throw();
Code & operator=(const Code &rhs) throw(); Code & operator=(const Code &rhs) throw();
operator bool () const throw() { return _code && status() == loaded; } operator bool () const throw() { return _code && status() == loaded; }
status_t status() const throw() { return _status; } status_t status() const throw() { return _status; }
@ -107,7 +107,7 @@ public:
void externalProgramMoved(ptrdiff_t) throw(); void externalProgramMoved(ptrdiff_t) throw();
int32 run(Machine &m, slotref * & map) const; int32 run(Machine &m, slotref * & map) const;
CLASS_NEW_DELETE; CLASS_NEW_DELETE;
}; };
@ -128,16 +128,16 @@ inline Machine::Code::Code() throw()
} }
inline Machine::Code::Code(const Machine::Code &obj) throw () inline Machine::Code::Code(const Machine::Code &obj) throw ()
: _code(obj._code), : _code(obj._code),
_data(obj._data), _data(obj._data),
_data_size(obj._data_size), _data_size(obj._data_size),
_instr_count(obj._instr_count), _instr_count(obj._instr_count),
_max_ref(obj._max_ref), _max_ref(obj._max_ref),
_status(obj._status), _status(obj._status),
_constraint(obj._constraint), _constraint(obj._constraint),
_modify(obj._modify), _modify(obj._modify),
_delete(obj._delete), _delete(obj._delete),
_own(obj._own) _own(obj._own)
{ {
obj._own = false; obj._own = false;
} }
@ -145,15 +145,15 @@ inline Machine::Code::Code(const Machine::Code &obj) throw ()
inline Machine::Code & Machine::Code::operator=(const Machine::Code &rhs) throw() { inline Machine::Code & Machine::Code::operator=(const Machine::Code &rhs) throw() {
if (_instr_count > 0) if (_instr_count > 0)
release_buffers(); release_buffers();
_code = rhs._code; _code = rhs._code;
_data = rhs._data; _data = rhs._data;
_data_size = rhs._data_size; _data_size = rhs._data_size;
_instr_count = rhs._instr_count; _instr_count = rhs._instr_count;
_status = rhs._status; _status = rhs._status;
_constraint = rhs._constraint; _constraint = rhs._constraint;
_modify = rhs._modify; _modify = rhs._modify;
_delete = rhs._delete; _delete = rhs._delete;
_own = rhs._own; _own = rhs._own;
rhs._own = false; rhs._own = false;
return *this; return *this;
} }

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -59,7 +59,7 @@ public:
////COLL_JUMPABLE = 128, // moving glyphs may jump this stationary glyph in any direction - DELETE ////COLL_JUMPABLE = 128, // moving glyphs may jump this stationary glyph in any direction - DELETE
////COLL_OVERLAP = 256, // use maxoverlap to restrict - DELETE ////COLL_OVERLAP = 256, // use maxoverlap to restrict - DELETE
}; };
// Behavior for the collision.order attribute. To GDL this is an enum, to us it's a bitfield, with only 1 bit set // Behavior for the collision.order attribute. To GDL this is an enum, to us it's a bitfield, with only 1 bit set
// Allows for easier inversion. // Allows for easier inversion.
enum { enum {
@ -70,10 +70,10 @@ public:
SEQ_ORDER_NOLEFT = 16, SEQ_ORDER_NOLEFT = 16,
SEQ_ORDER_NORIGHT = 32 SEQ_ORDER_NORIGHT = 32
}; };
SlotCollision(Segment *seg, Slot *slot); SlotCollision(Segment *seg, Slot *slot);
void initFromSlot(Segment *seg, Slot *slot); void initFromSlot(Segment *seg, Slot *slot);
const Rect &limit() const { return _limit; } const Rect &limit() const { return _limit; }
void setLimit(const Rect &r) { _limit = r; } void setLimit(const Rect &r) { _limit = r; }
SLOTCOLSETPOSITIONPROP(shift, setShift) SLOTCOLSETPOSITIONPROP(shift, setShift)
@ -95,7 +95,7 @@ public:
float getKern(int dir) const; float getKern(int dir) const;
bool ignore() const; bool ignore() const;
private: private:
Rect _limit; Rect _limit;
Position _shift; // adjustment within the given pass Position _shift; // adjustment within the given pass
@ -114,7 +114,7 @@ private:
uint16 _seqBelowWt; uint16 _seqBelowWt;
uint16 _seqValignHt; uint16 _seqValignHt;
uint16 _seqValignWt; uint16 _seqValignWt;
}; // end of class SlotColllision }; // end of class SlotColllision
struct BBox; struct BBox;
@ -133,7 +133,7 @@ public:
bool initSlot(Segment *seg, Slot *aSlot, const Rect &constraint, bool initSlot(Segment *seg, Slot *aSlot, const Rect &constraint,
float margin, float marginMin, const Position &currShift, float margin, float marginMin, const Position &currShift,
const Position &currOffset, int dir, GR_MAYBE_UNUSED json * const dbgout); const Position &currOffset, int dir, GR_MAYBE_UNUSED json * const dbgout);
bool mergeSlot(Segment *seg, Slot *slot, const SlotCollision *cinfo, const Position &currShift, bool isAfter, bool mergeSlot(Segment *seg, Slot *slot, const SlotCollision *cinfo, const Position &currShift, bool isAfter,
bool sameCluster, bool &hasCol, bool isExclusion, GR_MAYBE_UNUSED json * const dbgout); bool sameCluster, bool &hasCol, bool isExclusion, GR_MAYBE_UNUSED json * const dbgout);
Position resolve(Segment *seg, bool &isCol, GR_MAYBE_UNUSED json * const dbgout); Position resolve(Segment *seg, bool &isCol, GR_MAYBE_UNUSED json * const dbgout);
void addBox_slope(bool isx, const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, float weight, float m, bool minright, int mode); void addBox_slope(bool isx, const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, float weight, float m, bool minright, int mode);
@ -164,7 +164,7 @@ protected:
uint16 _seqClass; uint16 _seqClass;
uint16 _seqProxClass; uint16 _seqProxClass;
uint16 _seqOrder; uint16 _seqOrder;
//bool _scraping[4]; //bool _scraping[4];
}; // end of class ShiftCollider }; // end of class ShiftCollider
@ -212,7 +212,7 @@ private:
float _xbound; // max or min edge float _xbound; // max or min edge
bool _hit; bool _hit;
#if !defined GRAPHITE2_NTRACING #if !defined GRAPHITE2_NTRACING
// Debugging // Debugging
Segment * _seg; Segment * _seg;
Vector<float> _nearEdges; // closest potential collision in each slice Vector<float> _nearEdges; // closest potential collision in each slice
@ -243,4 +243,3 @@ KernCollider::KernCollider(GR_MAYBE_UNUSED json *dbg)
}; };
}; // end of namespace graphite2 }; // end of namespace graphite2

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -53,7 +53,7 @@ ptrdiff_t const MINMATCH = 4,
MINSRCSIZE = 13; MINSRCSIZE = 13;
template<int S> template<int S>
inline inline
void unaligned_copy(void * d, void const * s) { void unaligned_copy(void * d, void const * s) {
::memcpy(d, s, S); ::memcpy(d, s, S);
} }
@ -63,7 +63,7 @@ size_t align(size_t p) {
return (p + sizeof(unsigned long)-1) & ~(sizeof(unsigned long)-1); return (p + sizeof(unsigned long)-1) & ~(sizeof(unsigned long)-1);
} }
inline inline
u8 * safe_copy(u8 * d, u8 const * s, size_t n) { u8 * safe_copy(u8 * d, u8 const * s, size_t n) {
while (n--) *d++ = *s++; while (n--) *d++ = *s++;
return d; return d;
@ -73,7 +73,7 @@ inline
u8 * overrun_copy(u8 * d, u8 const * s, size_t n) { u8 * overrun_copy(u8 * d, u8 const * s, size_t n) {
size_t const WS = sizeof(unsigned long); size_t const WS = sizeof(unsigned long);
u8 const * e = s + n; u8 const * e = s + n;
do do
{ {
unaligned_copy<WS>(d, s); unaligned_copy<WS>(d, s);
d += WS; d += WS;
@ -81,7 +81,7 @@ u8 * overrun_copy(u8 * d, u8 const * s, size_t n) {
} }
while (s < e); while (s < e);
d-=(s-e); d-=(s-e);
return d; return d;
} }
@ -90,7 +90,7 @@ inline
u8 * fast_copy(u8 * d, u8 const * s, size_t n) { u8 * fast_copy(u8 * d, u8 const * s, size_t n) {
size_t const WS = sizeof(unsigned long); size_t const WS = sizeof(unsigned long);
size_t wn = n/WS; size_t wn = n/WS;
while (wn--) while (wn--)
{ {
unaligned_copy<WS>(d, s); unaligned_copy<WS>(d, s);
d += WS; d += WS;
@ -102,5 +102,3 @@ u8 * fast_copy(u8 * d, u8 const * s, size_t n) {
} // end of anonymous namespace } // end of anonymous namespace

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -52,5 +52,3 @@ namespace lz4
int decompress(void const *in, size_t in_size, void *out, size_t out_size); int decompress(void const *in, size_t in_size, void *out, size_t out_size);
} // end of namespace shrinker } // end of namespace shrinker

View file

@ -57,11 +57,11 @@ public:
template<typename T> template<typename T>
inline static T read(const unsigned char * &p) { inline static T read(const unsigned char * &p) {
const T r = T(_peek<sizeof(T)>(p)); const T r = T(_peek<sizeof(T)>(p));
p += sizeof r; p += sizeof r;
return r; return r;
} }
template<typename T> template<typename T>
inline static T swap(const T x) { inline static T swap(const T x) {
return T(_peek<sizeof(T)>(reinterpret_cast<const unsigned char *>(&x))); return T(_peek<sizeof(T)>(reinterpret_cast<const unsigned char *>(&x)));
@ -77,7 +77,7 @@ template<>
inline unsigned long int be::_peek<1>(const unsigned char * p) { return *p; } inline unsigned long int be::_peek<1>(const unsigned char * p) { return *p; }
class le class le
{ {
template<int S> template<int S>
inline static unsigned long int _peek(const unsigned char * p) { inline static unsigned long int _peek(const unsigned char * p) {
@ -91,11 +91,11 @@ public:
template<typename T> template<typename T>
inline static T read(const unsigned char * &p) { inline static T read(const unsigned char * &p) {
const T r = T(_peek<sizeof(T)>(p)); const T r = T(_peek<sizeof(T)>(p));
p += sizeof r; p += sizeof r;
return r; return r;
} }
template<typename T> template<typename T>
inline static T swap(const T x) { inline static T swap(const T x) {
return T(_peek<sizeof(T)>(reinterpret_cast<const unsigned char *>(&x))); return T(_peek<sizeof(T)>(reinterpret_cast<const unsigned char *>(&x)));
@ -109,4 +109,3 @@ public:
template<> template<>
inline unsigned long int le::_peek<1>(const unsigned char * p) { return *p; } inline unsigned long int le::_peek<1>(const unsigned char * p) { return *p; }

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -132,4 +132,3 @@ enum errors {
}; };
} }

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -170,23 +170,23 @@ class Face::Table
{ {
const Face * _f; const Face * _f;
mutable const byte * _p; mutable const byte * _p;
uint32 _sz; size_t _sz;
bool _compressed; bool _compressed;
Error decompress(); Error decompress();
void releaseBuffers(); void release();
public: public:
Table() throw(); Table() throw();
Table(const Face & face, const Tag n, uint32 version=0xffffffff) throw(); Table(const Face & face, const Tag n, uint32 version=0xffffffff) throw();
Table(const Table & rhs) throw();
~Table() throw(); ~Table() throw();
Table(const Table && rhs) throw();
operator const byte * () const throw(); operator const byte * () const throw();
Table & operator = (const Table & rhs) throw();
size_t size() const throw(); size_t size() const throw();
Table & operator = (const Table && rhs) throw();
}; };
inline inline
@ -196,7 +196,7 @@ Face::Table::Table() throw()
} }
inline 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) : _f(rhs._f), _p(rhs._p), _sz(rhs._sz), _compressed(rhs._compressed)
{ {
rhs._p = 0; rhs._p = 0;
@ -205,7 +205,7 @@ Face::Table::Table(const Table & rhs) throw()
inline inline
Face::Table::~Table() throw() Face::Table::~Table() throw()
{ {
releaseBuffers(); release();
} }
inline inline

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -41,7 +41,7 @@ public:
FeatureSetting(int16 theValue, uint16 labelId) : m_label(labelId), m_value(theValue) {}; FeatureSetting(int16 theValue, uint16 labelId) : m_label(labelId), m_value(theValue) {};
uint16 label() const { return m_label; } uint16 label() const { return m_label; }
int16 value() const { return m_value; } int16 value() const { return m_value; }
CLASS_NEW_DELETE; CLASS_NEW_DELETE;
private: private:
FeatureSetting(const FeatureSetting & fs) : m_label(fs.m_label), m_value(fs.m_value) {}; FeatureSetting(const FeatureSetting & fs) : m_label(fs.m_label), m_value(fs.m_value) {};
@ -146,7 +146,7 @@ friend class SillMap;
FeatureRef *m_feats; FeatureRef *m_feats;
NameAndFeatureRef* m_pNamedFeats; //owned NameAndFeatureRef* m_pNamedFeats; //owned
FeatureVal m_defaultFeatures; //owned FeatureVal m_defaultFeatures; //owned
private: //defensive on m_feats, m_pNamedFeats, and m_defaultFeatures private: //defensive on m_feats, m_pNamedFeats, and m_defaultFeatures
FeatureMap(const FeatureMap&); FeatureMap(const FeatureMap&);
FeatureMap& operator=(const FeatureMap&); FeatureMap& operator=(const FeatureMap&);
@ -164,7 +164,7 @@ private:
public: public:
LangFeaturePair() : m_lang(0), m_pFeatures(0) {} LangFeaturePair() : m_lang(0), m_pFeatures(0) {}
~LangFeaturePair() { delete m_pFeatures; } ~LangFeaturePair() { delete m_pFeatures; }
uint32 m_lang; uint32 m_lang;
Features* m_pFeatures; //owns Features* m_pFeatures; //owns
CLASS_NEW_DELETE CLASS_NEW_DELETE

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -48,9 +48,9 @@ public:
{ {
size_t n = size(); size_t n = size();
if (n != b.size()) return false; if (n != b.size()) return false;
for(const_iterator l = begin(), r = b.begin(); n && *l == *r; --n, ++l, ++r); for(const_iterator l = begin(), r = b.begin(); n && *l == *r; --n, ++l, ++r);
return n == 0; return n == 0;
} }

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -71,7 +71,7 @@ class GlyphBox
GlyphBox & operator = (const GlyphBox &); GlyphBox & operator = (const GlyphBox &);
public: public:
GlyphBox(uint8 numsubs, unsigned short bitmap, Rect *slanted) : _num(numsubs), _bitmap(bitmap), _slant(*slanted) {}; GlyphBox(uint8 numsubs, unsigned short bitmap, Rect *slanted) : _num(numsubs), _bitmap(bitmap), _slant(*slanted) {};
void addSubBox(int subindex, int boundary, Rect *val) { _subs[subindex * 2 + boundary] = *val; } void addSubBox(int subindex, int boundary, Rect *val) { _subs[subindex * 2 + boundary] = *val; }
Rect &subVal(int subindex, int boundary) { return _subs[subindex * 2 + boundary]; } Rect &subVal(int subindex, int boundary) { return _subs[subindex * 2 + boundary]; }
@ -115,7 +115,7 @@ public:
bool hasBoxes() const { return _boxes != 0; } bool hasBoxes() const { return _boxes != 0; }
CLASS_NEW_DELETE; CLASS_NEW_DELETE;
private: private:
const Rect _empty_slant_box; const Rect _empty_slant_box;
const Loader * _glyph_loader; const Loader * _glyph_loader;

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -216,7 +216,7 @@ Zones::Exclusion Zones::Exclusion::weighted<XY>(float xmin, float xmax, float f,
float m, float xi, GR_MAYBE_UNUSED float ai, float c, GR_MAYBE_UNUSED bool nega) { float m, float xi, GR_MAYBE_UNUSED float ai, float c, GR_MAYBE_UNUSED bool nega) {
return Exclusion(xmin, xmax, return Exclusion(xmin, xmax,
m + f, m + f,
m * xi, m * xi,
m * xi * xi + f * a0 * a0 + c); m * xi * xi + f * a0 * a0 + c);
} }
@ -225,9 +225,9 @@ inline
Zones::Exclusion Zones::Exclusion::weighted<SD>(float xmin, float xmax, float f, float a0, Zones::Exclusion Zones::Exclusion::weighted<SD>(float xmin, float xmax, float f, float a0,
float m, float xi, float ai,float c, bool nega) { float m, float xi, float ai,float c, bool nega) {
float xia = nega ? xi - ai : xi + ai; float xia = nega ? xi - ai : xi + ai;
return Exclusion(xmin, xmax, return Exclusion(xmin, xmax,
0.25f * (m + 2.f * f), 0.25f * (m + 2.f * f),
0.25f * m * xia, 0.25f * m * xia,
0.25f * (m * xia * xia + 2.f * f * a0 * a0) + c); 0.25f * (m * xia * xia + 2.f * f * a0 * a0) + c);
} }

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -38,12 +38,12 @@ of the License or (at your option) any later version.
namespace graphite2 { namespace graphite2 {
template <typename T> template <typename T>
inline inline
ptrdiff_t distance(T* first, T* last) { return last-first; } ptrdiff_t distance(T* first, T* last) { return last-first; }
template <typename T> template <typename T>
class Vector class Vector
{ {
T * m_first, *m_last, *m_end; T * m_first, *m_last, *m_end;
@ -56,32 +56,32 @@ public:
Vector() : m_first(0), m_last(0), m_end(0) {} Vector() : m_first(0), m_last(0), m_end(0) {}
Vector(size_t n, const T& value = T()) : m_first(0), m_last(0), m_end(0) { insert(begin(), n, value); } Vector(size_t n, const T& value = T()) : m_first(0), m_last(0), m_end(0) { insert(begin(), n, value); }
Vector(const Vector<T> &rhs) : m_first(0), m_last(0), m_end(0) { insert(begin(), rhs.begin(), rhs.end()); } Vector(const Vector<T> &rhs) : m_first(0), m_last(0), m_end(0) { insert(begin(), rhs.begin(), rhs.end()); }
template <typename I> template <typename I>
Vector(I first, const I last) : m_first(0), m_last(0), m_end(0) { insert(begin(), first, last); } Vector(I first, const I last) : m_first(0), m_last(0), m_end(0) { insert(begin(), first, last); }
~Vector() { clear(); free(m_first); } ~Vector() { clear(); free(m_first); }
iterator begin() { return m_first; } iterator begin() { return m_first; }
const_iterator begin() const { return m_first; } const_iterator begin() const { return m_first; }
iterator end() { return m_last; } iterator end() { return m_last; }
const_iterator end() const { return m_last; } const_iterator end() const { return m_last; }
bool empty() const { return m_first == m_last; } bool empty() const { return m_first == m_last; }
size_t size() const { return m_last - m_first; } size_t size() const { return m_last - m_first; }
size_t capacity() const{ return m_end - m_first; } size_t capacity() const{ return m_end - m_first; }
void reserve(size_t n); void reserve(size_t n);
void resize(size_t n, const T & v = T()); void resize(size_t n, const T & v = T());
reference front() { assert(size() > 0); return *begin(); } reference front() { assert(size() > 0); return *begin(); }
const_reference front() const { assert(size() > 0); return *begin(); } const_reference front() const { assert(size() > 0); return *begin(); }
reference back() { assert(size() > 0); return *(end()-1); } reference back() { assert(size() > 0); return *(end()-1); }
const_reference back() const { assert(size() > 0); return *(end()-1); } const_reference back() const { assert(size() > 0); return *(end()-1); }
Vector<T> & operator = (const Vector<T> & rhs) { assign(rhs.begin(), rhs.end()); return *this; } Vector<T> & operator = (const Vector<T> & rhs) { assign(rhs.begin(), rhs.end()); return *this; }
reference operator [] (size_t n) { assert(size() > n); return m_first[n]; } reference operator [] (size_t n) { assert(size() > n); return m_first[n]; }
const_reference operator [] (size_t n) const { assert(size() > n); return m_first[n]; } const_reference operator [] (size_t n) const { assert(size() > n); return m_first[n]; }
void assign(size_t n, const T& u) { clear(); insert(begin(), n, u); } void assign(size_t n, const T& u) { clear(); insert(begin(), n, u); }
void assign(const_iterator first, const_iterator last) { clear(); insert(begin(), first, last); } void assign(const_iterator first, const_iterator last) { clear(); insert(begin(), first, last); }
iterator insert(iterator p, const T & x) { p = _insert_default(p, 1); new (p) T(x); return p; } iterator insert(iterator p, const T & x) { p = _insert_default(p, 1); new (p) T(x); return p; }
@ -97,12 +97,12 @@ public:
private: private:
iterator _insert_default(iterator p, size_t n); iterator _insert_default(iterator p, size_t n);
}; };
template <typename T> template <typename T>
inline inline
void Vector<T>::reserve(size_t n) void Vector<T>::reserve(size_t n)
{ {
if (n > capacity()) if (n > capacity())
{ {
const ptrdiff_t sz = size(); const ptrdiff_t sz = size();
size_t requested; size_t requested;
@ -122,8 +122,8 @@ void Vector<T>::resize(size_t n, const T & v) {
else if (d > 0) insert(end(), d, v); else if (d > 0) insert(end(), d, v);
} }
template<typename T> template<typename T>
inline inline
typename Vector<T>::iterator Vector<T>::_insert_default(iterator p, size_t n) typename Vector<T>::iterator Vector<T>::_insert_default(iterator p, size_t n)
{ {
assert(begin() <= p && p <= end()); assert(begin() <= p && p <= end());
@ -136,8 +136,8 @@ typename Vector<T>::iterator Vector<T>::_insert_default(iterator p, size_t n)
return p; return p;
} }
template<typename T> template<typename T>
inline inline
void Vector<T>::insert(iterator p, size_t n, const T & x) void Vector<T>::insert(iterator p, size_t n, const T & x)
{ {
p = _insert_default(p, n); p = _insert_default(p, n);
@ -146,7 +146,7 @@ void Vector<T>::insert(iterator p, size_t n, const T & x)
} }
template<typename T> template<typename T>
inline inline
void Vector<T>::insert(iterator p, const_iterator first, const_iterator last) void Vector<T>::insert(iterator p, const_iterator first, const_iterator last)
{ {
p = _insert_default(p, distance(first, last)); p = _insert_default(p, distance(first, last));

View file

@ -86,7 +86,7 @@ struct telemetry {};
#define HAVE_BUILTIN_OVERFLOW #define HAVE_BUILTIN_OVERFLOW
#endif #endif
#if defined(__has_include) #if defined(__has_include)
#if __has_include(<intsafe.h>) #if __has_include(<intsafe.h>) && !defined(__CYGWIN__)
#define HAVE_INTSAFE_H #define HAVE_INTSAFE_H
#endif #endif
#elif defined(_WIN32) #elif defined(_WIN32)
@ -172,9 +172,14 @@ inline T max(const T a, const T b)
#define GR_MAYBE_UNUSED #define GR_MAYBE_UNUSED
#endif #endif
#if defined(__clang__) && __cplusplus >= 201103L #ifndef __has_cpp_attribute
/* clang's fallthrough annotations are only available starting in C++11. */ # define __has_cpp_attribute(x) 0
#define GR_FALLTHROUGH [[fallthrough]] #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) #elif defined(_MSC_VER)
/* /*
* MSVC's __fallthrough annotations are checked by /analyze (Code Analysis): * MSVC's __fallthrough annotations are checked by /analyze (Code Analysis):

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -46,11 +46,11 @@ class json;
enum passtype; enum passtype;
class Pass class Pass
{ {
public: public:
Pass(); Pass();
~Pass(); ~Pass();
bool readPass(const byte * pPass, size_t pass_length, size_t subtable_base, Face & face, bool readPass(const byte * pPass, size_t pass_length, size_t subtable_base, Face & face,
enum passtype pt, uint32 version, Error &e); enum passtype pt, uint32 version, Error &e);
bool runGraphite(vm::Machine & m, FiniteStateMachine & fsm, bool reverse) const; bool runGraphite(vm::Machine & m, FiniteStateMachine & fsm, bool reverse) const;
@ -66,7 +66,7 @@ private:
bool testConstraint(const Rule & r, vm::Machine &) const; bool testConstraint(const Rule & r, vm::Machine &) const;
bool readRules(const byte * rule_map, const size_t num_entries, bool readRules(const byte * rule_map, const size_t num_entries,
const byte *precontext, const uint16 * sort_key, const byte *precontext, const uint16 * sort_key,
const uint16 * o_constraint, const byte *constraint_data, const uint16 * o_constraint, const byte *constraint_data,
const uint16 * o_action, const byte * action_data, const uint16 * o_action, const byte * action_data,
Face &, enum passtype pt, Error &e); Face &, enum passtype pt, Error &e);
bool readStates(const byte * starts, const byte * states, const byte * o_rule_map, Face &, Error &e); bool readStates(const byte * starts, const byte * states, const byte * o_rule_map, Face &, Error &e);
@ -109,7 +109,7 @@ private:
byte m_colThreshold; byte m_colThreshold;
bool m_isReverseDir; bool m_isReverseDir;
vm::Machine::Code m_cPConstraint; vm::Machine::Code m_cPConstraint;
private: //defensive private: //defensive
Pass(const Pass&); Pass(const Pass&);
Pass& operator=(const Pass&); Pass& operator=(const Pass&);

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -33,7 +33,7 @@ of the License or (at your option) any later version.
namespace graphite2 { namespace graphite2 {
struct Rule { struct Rule {
const vm::Machine::Code * constraint, const vm::Machine::Code * constraint,
* action; * action;
unsigned short sort; unsigned short sort;
byte preContext; byte preContext;
@ -87,7 +87,7 @@ struct State
{ {
const RuleEntry * rules, const RuleEntry * rules,
* rules_end; * rules_end;
bool empty() const; bool empty() const;
}; };
@ -102,14 +102,14 @@ class SlotMap
{ {
public: public:
enum {MAX_SLOTS=64}; enum {MAX_SLOTS=64};
SlotMap(Segment & seg, uint8 direction, int maxSize); SlotMap(Segment & seg, uint8 direction, size_t maxSize);
Slot * * begin(); Slot * * begin();
Slot * * end(); Slot * * end();
size_t size() const; size_t size() const;
unsigned short context() const; unsigned short context() const;
void reset(Slot &, unsigned short); void reset(Slot &, unsigned short);
Slot * const & operator[](int n) const; Slot * const & operator[](int n) const;
Slot * & operator [] (int); Slot * & operator [] (int);
void pushSlot(Slot * const slot); void pushSlot(Slot * const slot);
@ -149,11 +149,11 @@ private:
const RuleEntry * begin() const; const RuleEntry * begin() const;
const RuleEntry * end() const; const RuleEntry * end() const;
size_t size() const; size_t size() const;
void accumulate_rules(const State &state); void accumulate_rules(const State &state);
private: private:
RuleEntry * m_begin, RuleEntry * m_begin,
* m_end, * m_end,
m_rules[MAX_RULES*2]; m_rules[MAX_RULES*2];
}; };
@ -219,13 +219,13 @@ void FiniteStateMachine::Rules::accumulate_rules(const State &state)
{ {
// Only bother if there are rules in the State object. // Only bother if there are rules in the State object.
if (state.empty()) return; if (state.empty()) return;
// Merge the new sorted rules list into the current sorted result set. // Merge the new sorted rules list into the current sorted result set.
const RuleEntry * lre = begin(), * rre = state.rules; const RuleEntry * lre = begin(), * rre = state.rules;
RuleEntry * out = m_rules + (m_begin == m_rules)*MAX_RULES; RuleEntry * out = m_rules + (m_begin == m_rules)*MAX_RULES;
const RuleEntry * const lrend = out + MAX_RULES, const RuleEntry * const lrend = out + MAX_RULES,
* const rrend = state.rules_end; * const rrend = state.rules_end;
m_begin = out; m_begin = out;
while (lre != end() && out != lrend) while (lre != end() && out != lrend)
{ {
if (*lre < *rre) *out++ = *lre++; if (*lre < *rre) *out++ = *lre++;
@ -233,7 +233,7 @@ void FiniteStateMachine::Rules::accumulate_rules(const State &state)
else { *out++ = *lre++; ++rre; } else { *out++ = *lre++; ++rre; }
if (rre == rrend) if (rre == rrend)
{ {
while (lre != end() && out != lrend) { *out++ = *lre++; } while (lre != end() && out != lrend) { *out++ = *lre++; }
m_end = out; m_end = out;
return; return;
@ -244,9 +244,9 @@ void FiniteStateMachine::Rules::accumulate_rules(const State &state)
} }
inline 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), : 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; m_slot_map[0] = 0;
} }

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -49,9 +49,6 @@ typedef Vector<Slot *> SlotRope;
typedef Vector<int16 *> AttributeRope; typedef Vector<int16 *> AttributeRope;
typedef Vector<SlotJustify *> JustifyRope; typedef Vector<SlotJustify *> JustifyRope;
#ifndef GRAPHITE2_NSEGCACHE
class SegmentScopeState;
#endif
class Font; class Font;
class Segment; class Segment;
class Silf; class Silf;
@ -91,26 +88,18 @@ public:
SEG_HASCOLLISIONS = 2 SEG_HASCOLLISIONS = 2
}; };
unsigned int slotCount() const { return m_numGlyphs; } //one slot per glyph size_t slotCount() const { return m_numGlyphs; } //one slot per glyph
void extendLength(int num) { m_numGlyphs += num; } void extendLength(ptrdiff_t num) { m_numGlyphs += num; }
Position advance() const { return m_advance; } Position advance() const { return m_advance; }
bool runGraphite() { if (m_silf) return m_face->runGraphite(this, m_silf); else return true;}; 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); } void chooseSilf(uint32 script) { m_silf = m_face->chooseSilf(script); }
const Silf *silf() const { return m_silf; } 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; } 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; } 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(); ~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; } uint8 flags() const { return m_flags; }
void flags(uint8 f) { m_flags = f; } void flags(uint8 f) { m_flags = f; }
Slot *first() { return m_first; } Slot *first() { return m_first; }
@ -123,14 +112,14 @@ public:
SlotJustify *newJustify(); SlotJustify *newJustify();
void freeJustify(SlotJustify *aJustify); void freeJustify(SlotJustify *aJustify);
Position positionSlots(const Font *font=0, Slot *first=0, Slot *last=0, bool isRtl = false, bool isFinal = true); 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); void linkClusters(Slot *first, Slot *last);
uint16 getClassGlyph(uint16 cid, uint16 offset) const { return m_silf->getClassGlyph(cid, offset); } 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); } 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]); } 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) { void setFeature(int index, uint8 findex, uint32 val) {
const FeatureRef* pFR=m_face->theSill().theFeatureMap().featureRef(findex); const FeatureRef* pFR=m_face->theSill().theFeatureMap().featureRef(findex);
if (pFR) if (pFR)
{ {
if (val > pFR->maxVal()) val = pFR->maxVal(); if (val > pFR->maxVal()) val = pFR->maxVal();
@ -139,8 +128,8 @@ public:
int8 dir() const { return m_dir; } int8 dir() const { return m_dir; }
void dir(int8 val) { m_dir = val; } void dir(int8 val) { m_dir = val; }
bool currdir() const { return ((m_dir >> 6) ^ m_dir) & 1; } bool currdir() const { return ((m_dir >> 6) ^ m_dir) & 1; }
unsigned int passBits() const { return m_passBits; } uint8 passBits() const { return m_passBits; }
void mergePassBits(const unsigned int val) { m_passBits &= val; } 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; } 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; int32 getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel, bool rtl) const;
float glyphAdvance(uint16 gid) const { return m_face->glyphs().glyph(gid)->theAdvance().x; } float glyphAdvance(uint16 gid) const { return m_face->glyphs().glyph(gid)->theAdvance().x; }
@ -168,7 +157,7 @@ public: //only used by: GrSegment* makeAndInitialize(const GrFont *font, c
void finalise(const Font *font, bool reverse=false); void finalise(const Font *font, bool reverse=false);
float justify(Slot *pSlot, const Font *font, float width, enum justFlags flags, Slot *pFirst, Slot *pLast); float justify(Slot *pSlot, const Font *font, float width, enum justFlags flags, Slot *pFirst, Slot *pLast);
bool initCollisions(); bool initCollisions();
private: private:
Position m_advance; // whole segment advance Position m_advance; // whole segment advance
SlotRope m_slots; // Vector of slot buffers SlotRope m_slots; // Vector of slot buffers
@ -183,13 +172,13 @@ private:
const Silf * m_silf; const Silf * m_silf;
Slot * m_first; // first slot in segment Slot * m_first; // first slot in segment
Slot * m_last; // last 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_numGlyphs,
m_numCharinfo, // size of the array and number of input characters m_numCharinfo; // size of the array and number of input characters
m_passBits; // if bit set then skip pass
int m_defaultOriginal; // number of whitespace chars in the string int m_defaultOriginal; // number of whitespace chars in the string
int8 m_dir; int8 m_dir;
uint8 m_flags; // General purpose flags uint8 m_flags, // General purpose flags
m_passBits; // if bit set then skip pass
}; };
inline inline
@ -245,4 +234,3 @@ bool Segment::isWhitespace(const int cid) const
} // namespace graphite2 } // namespace graphite2
struct gr_segment : public graphite2::Segment {}; struct gr_segment : public graphite2::Segment {};

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -73,7 +73,7 @@ class Silf
public: public:
Silf() throw(); Silf() throw();
~Silf() throw(); ~Silf() throw();
bool readGraphite(const byte * const pSilf, size_t lSilf, Face &face, uint32 version); bool readGraphite(const byte * const pSilf, size_t lSilf, Face &face, uint32 version);
bool runGraphite(Segment *seg, uint8 firstPass=0, uint8 lastPass=0, int dobidi = 0) const; bool runGraphite(Segment *seg, uint8 firstPass=0, uint8 lastPass=0, int dobidi = 0) const;
uint16 findClassIndex(uint16 cid, uint16 gid) const; uint16 findClassIndex(uint16 cid, uint16 gid) const;
@ -121,7 +121,7 @@ private:
uint16 m_aLig, m_numPseudo, m_nClass, m_nLinear, uint16 m_aLig, m_numPseudo, m_nClass, m_nLinear,
m_gEndLine; m_gEndLine;
gr_faceinfo m_silfinfo; gr_faceinfo m_silfinfo;
void releaseBuffers() throw(); void releaseBuffers() throw();
}; };

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -37,7 +37,6 @@ namespace graphite2 {
typedef gr_attrCode attrCode; typedef gr_attrCode attrCode;
class GlyphFace; class GlyphFace;
class SegCacheEntry;
class Segment; class Segment;
struct SlotJustify struct SlotJustify
@ -163,7 +162,6 @@ private:
int16 *m_userAttr; // pointer to user attributes int16 *m_userAttr; // pointer to user attributes
SlotJustify *m_justs; // pointer to justification parameters SlotJustify *m_justs; // pointer to justification parameters
friend class SegCacheEntry;
friend class Segment; friend class Segment;
}; };

View file

@ -138,7 +138,7 @@ sparse::sparse(I attr, const I last)
if (ci != ci_) if (ci != ci_)
{ {
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)); ci->mask |= 1UL << (SIZEOF_CHUNK - 1 - (v.first % SIZEOF_CHUNK));

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -77,11 +77,11 @@ enum
//********************************************************************************************** //**********************************************************************************************
// Table declarations // Table declarations
//********************************************************************************************** //**********************************************************************************************
namespace Sfnt 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 // 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). // MSDN).
struct OffsetSubTable struct OffsetSubTable
@ -99,9 +99,9 @@ namespace Sfnt
length; length;
} table_directory[1]; } table_directory[1];
enum ScalerType enum ScalerType
{ {
TrueTypeMac = 0x74727565U, TrueTypeMac = 0x74727565U,
TrueTypeWin = 0x00010000U, TrueTypeWin = 0x00010000U,
Type1 = 0x74797031U Type1 = 0x74797031U
}; };
@ -109,7 +109,7 @@ namespace Sfnt
struct CharacterCodeMap struct CharacterCodeMap
{ {
uint16 version, uint16 version,
@ -137,7 +137,7 @@ namespace Sfnt
range_shift, range_shift,
end_code[1]; end_code[1];
// There are arrarys after this which need their // There are arrarys after this which need their
// start positions calculated since end_code is // start positions calculated since end_code is
// seg_count uint16s long. // seg_count uint16s long.
}; };
@ -147,7 +147,7 @@ namespace Sfnt
uint32 length, uint32 length,
language, language,
num_groups; num_groups;
struct struct
{ {
uint32 start_char_code, uint32 start_char_code,
end_char_code, end_char_code,
@ -176,9 +176,9 @@ namespace Sfnt
int16 font_direction_hint, int16 font_direction_hint,
index_to_loc_format, index_to_loc_format,
glyph_data_format; glyph_data_format;
enum enum
{ {
MagicNumber = 0x5F0F3CF5, MagicNumber = 0x5F0F3CF5,
GlypDataFormat = 0 GlypDataFormat = 0
}; };
enum {ShortIndexLocFormat, LongIndexLocFormat}; enum {ShortIndexLocFormat, LongIndexLocFormat};
@ -197,37 +197,37 @@ namespace Sfnt
min_mem_type42, min_mem_type42,
max_mem_type42, max_mem_type42,
min_mem_type1, min_mem_type1,
max_mem_type1; max_mem_type1;
enum enum
{ {
Format1 = 0x10000, Format1 = 0x10000,
Format2 = 0x20000, Format2 = 0x20000,
Format25 = 0x28000, Format25 = 0x28000,
Format3 = 0x30000, Format3 = 0x30000,
Format4 = 0x40000 Format4 = 0x40000
}; };
}; };
struct PostScriptGlyphName2 : PostScriptGlyphName struct PostScriptGlyphName2 : PostScriptGlyphName
{ {
uint16 number_of_glyphs, uint16 number_of_glyphs,
glyph_name_index[1]; glyph_name_index[1];
}; };
struct PostScriptGlyphName25 : PostScriptGlyphName struct PostScriptGlyphName25 : PostScriptGlyphName
{ {
uint16 number_of_glyphs; uint16 number_of_glyphs;
int8 offset[1]; int8 offset[1];
}; };
struct PostScriptGlyphName3 : PostScriptGlyphName {}; struct PostScriptGlyphName3 : PostScriptGlyphName {};
struct PostScriptGlyphName4 : PostScriptGlyphName struct PostScriptGlyphName4 : PostScriptGlyphName
{ {
uint16 glyph_to_char_map[1]; uint16 glyph_to_char_map[1];
}; };
struct HorizontalHeader struct HorizontalHeader
{ {
fixed version; fixed version;
@ -245,7 +245,7 @@ namespace Sfnt
metric_data_format; metric_data_format;
uint16 num_long_hor_metrics; uint16 num_long_hor_metrics;
}; };
struct MaximumProfile struct MaximumProfile
{ {
fixed version; fixed version;
@ -297,23 +297,23 @@ namespace Sfnt
type_linegap, type_linegap,
win_ascent, win_ascent,
win_descent; win_descent;
enum enum
{ {
Italic =0x01, Italic =0x01,
Underscore=0x02, Underscore=0x02,
Negative =0x04, Negative =0x04,
Outlined =0x08, Outlined =0x08,
StrikeOut =0x10, StrikeOut =0x10,
Bold =0x20 Bold =0x20
}; };
}; };
struct Compatibility1 : Compatibility0 struct Compatibility1 : Compatibility0
{ {
uint32 codepage_range[2]; uint32 codepage_range[2];
}; };
struct Compatibility2 : Compatibility1 struct Compatibility2 : Compatibility1
{ {
int16 x_height, int16 x_height,
@ -322,12 +322,12 @@ namespace Sfnt
break_char, break_char,
max_context; max_context;
}; };
struct Compatibility3 : Compatibility2 {}; struct Compatibility3 : Compatibility2 {};
typedef Compatibility3 Compatibility; typedef Compatibility3 Compatibility;
struct NameRecord struct NameRecord
{ {
uint16 platform_id, uint16 platform_id,
@ -337,9 +337,9 @@ namespace Sfnt
length, length,
offset; offset;
enum {Unicode, Mactintosh, Reserved, Microsoft}; enum {Unicode, Mactintosh, Reserved, Microsoft};
enum enum
{ {
Copyright, Family, Subfamily, UniqueSubfamily, Copyright, Family, Subfamily, UniqueSubfamily,
Fullname, Version, PostScript Fullname, Version, PostScript
}; };
}; };
@ -357,15 +357,15 @@ namespace Sfnt
string_offset; string_offset;
NameRecord name_record[1]; NameRecord name_record[1];
}; };
struct HorizontalMetric struct HorizontalMetric
{ {
uint16 advance_width; uint16 advance_width;
int16 left_side_bearing; int16 left_side_bearing;
}; };
struct Glyph struct Glyph
{ {
int16 number_of_contours; int16 number_of_contours;
@ -374,11 +374,11 @@ namespace Sfnt
x_max, x_max,
y_max; y_max;
}; };
struct SimpleGlyph : Glyph struct SimpleGlyph : Glyph
{ {
uint16 end_pts_of_contours[1]; uint16 end_pts_of_contours[1];
enum enum
{ {
OnCurve = 0x01, OnCurve = 0x01,
XShort = 0x02, XShort = 0x02,
@ -390,12 +390,12 @@ namespace Sfnt
YIsPos = 0x20 YIsPos = 0x20
}; };
}; };
struct CompoundGlyph : Glyph struct CompoundGlyph : Glyph
{ {
uint16 flags, uint16 flags,
glyph_index; glyph_index;
enum enum
{ {
Arg1Arg2Words = 0x01, Arg1Arg2Words = 0x01,
ArgsAreXYValues = 0x02, ArgsAreXYValues = 0x02,

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -43,6 +43,8 @@ namespace graphite2
namespace TtfUtil namespace TtfUtil
{ {
#define OVERFLOW_OFFSET_CHECK(p, o) (o + reinterpret_cast<size_t>(p) < reinterpret_cast<size_t>(p))
typedef long fontTableId32; typedef long fontTableId32;
typedef unsigned short gid16; typedef unsigned short gid16;
@ -51,12 +53,12 @@ typedef unsigned short gid16;
// Enumeration used to specify a table in a TTF file // Enumeration used to specify a table in a TTF file
class Tag class Tag
{ {
unsigned long _v; unsigned int _v;
public: public:
Tag(const char n[5]) throw() : _v(TTF_TAG(n[0],n[1],n[2],n[3])) {} 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 enum
{ {
@ -100,12 +102,12 @@ public:
size_t & lOffset, size_t & lSize); size_t & lOffset, size_t & lSize);
bool CheckTable(const Tag TableId, const void * pTable, size_t lTableSize); bool CheckTable(const Tag TableId, const void * pTable, size_t lTableSize);
////////////////////////////////// simple font wide info ////////////////////////////////// simple font wide info
size_t GlyphCount(const void * pMaxp); size_t GlyphCount(const void * pMaxp);
#ifdef ALL_TTFUTILS #ifdef ALL_TTFUTILS
size_t MaxCompositeComponentCount(const void * pMaxp); size_t MaxCompositeComponentCount(const void * pMaxp);
size_t MaxCompositeLevelCount(const void * pMaxp); size_t MaxCompositeLevelCount(const void * pMaxp);
size_t LocaGlyphCount(size_t lLocaSize, const void * pHead); // throw (std::domain_error); size_t LocaGlyphCount(size_t lLocaSize, const void * pHead); // throw (std::domain_error);
#endif #endif
int DesignUnits(const void * pHead); int DesignUnits(const void * pHead);
#ifdef ALL_TTFUTILS #ifdef ALL_TTFUTILS
@ -120,7 +122,7 @@ public:
bool Get31EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize); bool Get31EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize);
bool Get30EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize); bool Get30EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize);
bool Get30EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize); bool Get30EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize);
int PostLookup(const void * pPost, size_t lPostSize, const void * pMaxp, int PostLookup(const void * pPost, size_t lPostSize, const void * pMaxp,
const char * pPostName); const char * pPostName);
#endif #endif
@ -134,8 +136,8 @@ public:
void SwapWString(void * pWStr, size_t nSize = 0); // throw (std::invalid_argument); void SwapWString(void * pWStr, size_t nSize = 0); // throw (std::invalid_argument);
#endif #endif
////////////////////////////////// cmap lookup tools ////////////////////////////////// cmap lookup tools
const void * FindCmapSubtable(const void * pCmap, int nPlatformId = 3, const void * FindCmapSubtable(const void * pCmap, int nPlatformId = 3,
int nEncodingId = 1, size_t length = 0); int nEncodingId = 1, size_t length = 0);
bool CheckCmapSubtable4(const void * pCmap31, const void * pCmapEnd /*, unsigned int maxgid*/); bool CheckCmapSubtable4(const void * pCmap31, const void * pCmapEnd /*, unsigned int maxgid*/);
gid16 CmapSubtable4Lookup(const void * pCmapSubtabel4, unsigned int nUnicodeId, int rangeKey = 0); gid16 CmapSubtable4Lookup(const void * pCmapSubtabel4, unsigned int nUnicodeId, int rangeKey = 0);
@ -147,57 +149,57 @@ public:
int * pRangeKey = 0); int * pRangeKey = 0);
///////////////////////////////// horizontal metric data for a glyph ///////////////////////////////// horizontal metric data for a glyph
bool HorMetrics(gid16 nGlyphId, const void * pHmtx, size_t lHmtxSize, bool HorMetrics(gid16 nGlyphId, const void * pHmtx, size_t lHmtxSize,
const void * pHhea, int & nLsb, unsigned int & nAdvWid); const void * pHhea, int & nLsb, unsigned int & nAdvWid);
////////////////////////////////// primitives for loca and glyf lookup ////////////////////////////////// primitives for loca and glyf lookup
size_t LocaLookup(gid16 nGlyphId, const void * pLoca, size_t lLocaSize, size_t LocaLookup(gid16 nGlyphId, const void * pLoca, size_t lLocaSize,
const void * pHead); // throw (std::out_of_range); const void * pHead); // throw (std::out_of_range);
void * GlyfLookup(const void * pGlyf, size_t lGlyfOffset, size_t lTableLen); void * GlyfLookup(const void * pGlyf, size_t lGlyfOffset, size_t lTableLen);
////////////////////////////////// primitves for simple glyph data ////////////////////////////////// primitves for simple glyph data
bool GlyfBox(const void * pSimpleGlyf, int & xMin, int & yMin, bool GlyfBox(const void * pSimpleGlyf, int & xMin, int & yMin,
int & xMax, int & yMax); int & xMax, int & yMax);
#ifdef ALL_TTFUTILS #ifdef ALL_TTFUTILS
int GlyfContourCount(const void * pSimpleGlyf); int GlyfContourCount(const void * pSimpleGlyf);
bool GlyfContourEndPoints(const void * pSimpleGlyf, int * prgnContourEndPoint, bool GlyfContourEndPoints(const void * pSimpleGlyf, int * prgnContourEndPoint,
int cnPointsTotal, size_t & cnPoints); int cnPointsTotal, size_t & cnPoints);
bool GlyfPoints(const void * pSimpleGlyf, int * prgnX, int * prgnY, bool GlyfPoints(const void * pSimpleGlyf, int * prgnX, int * prgnY,
char * prgbFlag, int cnPointsTotal, int & cnPoints); char * prgbFlag, int cnPointsTotal, int & cnPoints);
// primitive to find the glyph ids in a composite glyph // primitive to find the glyph ids in a composite glyph
bool GetComponentGlyphIds(const void * pSimpleGlyf, int * prgnCompId, bool GetComponentGlyphIds(const void * pSimpleGlyf, int * prgnCompId,
size_t cnCompIdTotal, size_t & cnCompId); size_t cnCompIdTotal, size_t & cnCompId);
// primitive to find the placement data for a component in a composite glyph // primitive to find the placement data for a component in a composite glyph
bool GetComponentPlacement(const void * pSimpleGlyf, int nCompId, bool GetComponentPlacement(const void * pSimpleGlyf, int nCompId,
bool fOffset, int & a, int & b); bool fOffset, int & a, int & b);
// primitive to find the transform data for a component in a composite glyph // primitive to find the transform data for a component in a composite glyph
bool GetComponentTransform(const void * pSimpleGlyf, int nCompId, bool GetComponentTransform(const void * pSimpleGlyf, int nCompId,
float & flt11, float & flt12, float & flt21, float & flt22, bool & fTransOffset); float & flt11, float & flt12, float & flt21, float & flt22, bool & fTransOffset);
#endif #endif
////////////////////////////////// operate on composite or simple glyph (auto glyf lookup) ////////////////////////////////// operate on composite or simple glyph (auto glyf lookup)
void * GlyfLookup(gid16 nGlyphId, const void * pGlyf, const void * pLoca, void * GlyfLookup(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
size_t lGlyfSize, size_t lLocaSize, const void * pHead); // primitive used by below methods size_t lGlyfSize, size_t lLocaSize, const void * pHead); // primitive used by below methods
#ifdef ALL_TTFUTILS #ifdef ALL_TTFUTILS
// below are primary user methods for handling glyf data // below are primary user methods for handling glyf data
bool IsSpace(gid16 nGlyphId, const void * pLoca, size_t lLocaSize, const void * pHead); bool IsSpace(gid16 nGlyphId, const void * pLoca, size_t lLocaSize, const void * pHead);
bool IsDeepComposite(gid16 nGlyphId, const void * pGlyf, const void * pLoca, bool IsDeepComposite(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
size_t lGlyfSize, size_t lLocaSize, const void * pHead); size_t lGlyfSize, size_t lLocaSize, const void * pHead);
bool GlyfBox(gid16 nGlyphId, const void * pGlyf, const void * pLoca, size_t lGlyfSize, size_t lLocaSize, bool GlyfBox(gid16 nGlyphId, const void * pGlyf, const void * pLoca, size_t lGlyfSize, size_t lLocaSize,
const void * pHead, int & xMin, int & yMin, int & xMax, int & yMax); const void * pHead, int & xMin, int & yMin, int & xMax, int & yMax);
bool GlyfContourCount(gid16 nGlyphId, const void * pGlyf, const void * pLoca, bool GlyfContourCount(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
size_t lGlyfSize, size_t lLocaSize, const void *pHead, size_t & cnContours); size_t lGlyfSize, size_t lLocaSize, const void *pHead, size_t & cnContours);
bool GlyfContourEndPoints(gid16 nGlyphId, const void * pGlyf, const void * pLoca, bool GlyfContourEndPoints(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
size_t lGlyfSize, size_t lLocaSize, const void * pHead, int * prgnContourEndPoint, size_t cnPoints); size_t lGlyfSize, size_t lLocaSize, const void * pHead, int * prgnContourEndPoint, size_t cnPoints);
bool GlyfPoints(gid16 nGlyphId, const void * pGlyf, const void * pLoca, bool GlyfPoints(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
size_t lGlyfSize, size_t lLocaSize, const void * pHead, const int * prgnContourEndPoint, size_t cnEndPoints, size_t lGlyfSize, size_t lLocaSize, const void * pHead, const int * prgnContourEndPoint, size_t cnEndPoints,
int * prgnX, int * prgnY, bool * prgfOnCurve, size_t cnPoints); int * prgnX, int * prgnY, bool * prgfOnCurve, size_t cnPoints);
// utitily method used by high-level GlyfPoints // utitily method used by high-level GlyfPoints
bool SimplifyFlags(char * prgbFlags, int cnPoints); bool SimplifyFlags(char * prgbFlags, int cnPoints);
bool CalcAbsolutePoints(int * prgnX, int * prgnY, int cnPoints); bool CalcAbsolutePoints(int * prgnX, int * prgnY, int cnPoints);
#endif #endif

View file

@ -40,7 +40,7 @@ struct _utf_codec
static void put(codeunit_t * cp, const uchar_t , int8 & len) throw(); static void put(codeunit_t * cp, const uchar_t , int8 & len) throw();
static uchar_t get(const codeunit_t * cp, 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 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; l = 1;
if (uh < 0xD800|| uh > 0xDFFF) { return uh; } if (uh < 0xD800|| uh > 0xDFFF) { return uh; }
if (uh > 0xDBFF) { l = -1; return 0xFFFD; }
const uint32 ul = cp[1]; 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; ++l;
return (uh<<10) + ul + surrogate_offset; return (uh<<10) + ul + surrogate_offset;
} }
inline 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; const ptrdiff_t n = e-s;
if (n <= 0) return n == 0; 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); return (u < 0xD800 || u > 0xDBFF);
} }
}; };
@ -166,7 +167,7 @@ public:
} }
inline 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; const ptrdiff_t n = e-s;
if (n <= 0) return n == 0; if (n <= 0) return n == 0;
@ -175,7 +176,7 @@ public:
if (*s >= 0xC0) return false; if (*s >= 0xC0) return false;
if (n == 1) return true; if (n == 1) return true;
if (*--s < 0x80) 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 (n == 2 || *s >= 0xC0) return true;
if (*--s < 0x80) return true; if (*--s < 0x80) return true;
if (*s >= 0xF0) return false; if (*s >= 0xF0) return false;
@ -225,6 +226,7 @@ public:
operator codeunit_type * () const throw() { return cp; } operator codeunit_type * () const throw() { return cp; }
bool error() const throw() { return sl < 1; } bool error() const throw() { return sl < 1; }
bool validate(const _utf_iterator & e) { return codec::validate(cp, e.cp); }
}; };
template <typename C> template <typename C>

View file

@ -73,30 +73,34 @@ inline unsigned int bit_set_count(signed long long v)
{ {
return __builtin_popcountll(v); return __builtin_popcountll(v);
} }
#else #else
template<typename T> template<typename T>
inline unsigned int bit_set_count(T v) inline unsigned int bit_set_count(T v)
{ {
v = v - ((v >> 1) & T(~(0UL)/3)); // temp static size_t const ONES = ~0;
v = (v & T(~(0UL)/15*3)) + ((v >> 2) & T(~(0UL)/15*3)); // temp
v = (v + (v >> 4)) & T(~(0UL)/255*15); // temp v = v - ((v >> 1) & T(ONES/3)); // temp
return (T)(v * T(~(0UL)/255)) >> (sizeof(T)-1)*8; // count 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 #endif
//TODO: Changed these to uintmax_t when we go to C++11
template<int S> 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 = _mask_over_val<S/2>(v);
v |= v >> S*4; v |= v >> S*4;
return v; return v;
} }
//TODO: Changed these to uintmax_t when we go to C++11
template<> 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 >> 1;
v |= v >> 2; v |= v >> 2;
@ -107,7 +111,7 @@ inline unsigned long _mask_over_val<1>(unsigned long v)
template<typename T> template<typename T>
inline T mask_over_val(T v) 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> template<typename T>

View file

@ -33,6 +33,7 @@ of the License or (at your option) any later version.
#include "inc/Main.h" #include "inc/Main.h"
#include <cassert> #include <cassert>
#include <cstdio> #include <cstdio>
#include <cstdint>
#include "inc/List.h" #include "inc/List.h"
namespace graphite2 { namespace graphite2 {
@ -44,7 +45,6 @@ class json
json & operator = (const json &); json & operator = (const json &);
typedef void (*_context_t)(json &); typedef void (*_context_t)(json &);
class _null_t {};
FILE * const _stream; FILE * const _stream;
char _contexts[128], // context stack char _contexts[128], // context stack
@ -61,11 +61,12 @@ class json
public: public:
class closer; class closer;
typedef const char * string; using string = const char *;
typedef double number; using number = double;
typedef long signed int integer; enum class integer : std::intmax_t {};
typedef bool boolean; enum class integer_u : std::uintmax_t {};
static const _null_t null; 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 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]; } void *getenv(unsigned int index) const { return _env[index]; }
@ -85,9 +86,9 @@ public:
json & operator << (string) throw(); json & operator << (string) throw();
json & operator << (number) throw(); json & operator << (number) throw();
json & operator << (integer) throw(); json & operator << (integer) throw();
json & operator << (long unsigned int d) throw(); json & operator << (integer_u) throw();
json & operator << (boolean) throw(); json & operator << (boolean) throw();
json & operator << (_null_t) throw(); json & operator << (std::nullptr_t) throw();
json & operator << (_context_t) throw(); json & operator << (_context_t) throw();
operator bool() const throw(); operator bool() const throw();
@ -136,29 +137,34 @@ json & json::operator << (json::_context_t ctxt) throw()
} }
inline inline
json & operator << (json & j, signed char d) throw() { return j << json::integer(d); } json & operator << (json & j, signed char d) throw() { return j << json::integer(d); }
inline 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 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 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 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 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 inline
json & operator << (json & j, char c) throw () json & operator << (json & j, long int d) throw() { return j << json::integer(d); }
{
const char str[2] = {c,0}; inline
return j << str; 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 inline
json::operator bool() const throw() { return good(); } json::operator bool() const throw() { return good(); }

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -41,7 +41,7 @@ of the License or (at your option) any later version.
// gmetric - 0 .. 11 (kgmetDescent) // gmetric - 0 .. 11 (kgmetDescent)
// featidx - 0 .. face.numFeatures() // featidx - 0 .. face.numFeatures()
// level - any byte // level - any byte
static const opcode_t opcode_table[] = static const opcode_t opcode_table[] =
{ {
{{do2(nop)}, 0, "NOP"}, {{do2(nop)}, 0, "NOP"},
@ -122,4 +122,3 @@ static const opcode_t opcode_table[] =
// private opcodes for internal use only, comes after all other on disk opcodes. // private opcodes for internal use only, comes after all other on disk opcodes.
{{do_(temp_copy), NILOP}, 0, "TEMP_COPY"} {{do_(temp_copy), NILOP}, 0, "TEMP_COPY"}
}; };

View file

@ -15,8 +15,8 @@
You should also have received a copy of the GNU Lesser General Public You should also have received a copy of the GNU Lesser General Public
License along with this library in the file named "LICENSE". License along with this library in the file named "LICENSE".
If not, write to the Free Software Foundation, 51 Franklin Street, 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 Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
internet at http://www.fsf.org/licenses/lgpl.html. internet at http://www.fsf.org/licenses/lgpl.html.
Alternatively, the contents of this file may be used under the terms of the Alternatively, the contents of this file may be used under the terms of the
@ -33,20 +33,20 @@ of the License or (at your option) any later version.
// ================== // ==================
// You have access to a few primitives and the full C++ code: // You have access to a few primitives and the full C++ code:
// declare_params(n) Tells the interpreter how many bytes of parameter // declare_params(n) Tells the interpreter how many bytes of parameter
// space to claim for this instruction uses and // space to claim for this instruction uses and
// initialises the param pointer. You *must* before the // initialises the param pointer. You *must* before the
// first use of param. // first use of param.
// use_params(n) Claim n extra bytes of param space beyond what was // use_params(n) Claim n extra bytes of param space beyond what was
// claimed using delcare_param. // claimed using delcare_param.
// param A const byte pointer for the parameter space claimed by // param A const byte pointer for the parameter space claimed by
// this instruction. // this instruction.
// binop(op) Implement a binary operation on the stack using the // binop(op) Implement a binary operation on the stack using the
// specified C++ operator. // specified C++ operator.
// NOT_IMPLEMENTED Any instruction body containing this will exit the // NOT_IMPLEMENTED Any instruction body containing this will exit the
// program with an assertion error. Instructions that are // program with an assertion error. Instructions that are
// not implemented should also be marked NILOP in the // not implemented should also be marked NILOP in the
// opcodes tables this will cause the code class to spot // opcodes tables this will cause the code class to spot
// them in a live code stream and throw a runtime_error // them in a live code stream and throw a runtime_error
// instead. // instead.
// push(n) Push the value n onto the stack. // push(n) Push the value n onto the stack.
// pop() Pop the top most value and return it. // pop() Pop the top most value and return it.
@ -62,7 +62,7 @@ of the License or (at your option) any later version.
// ip = The current instruction pointer // ip = The current instruction pointer
// endPos = Position of advance of last cluster // endPos = Position of advance of last cluster
// dir = writing system directionality of the font // dir = writing system directionality of the font
// #define NOT_IMPLEMENTED assert(false) // #define NOT_IMPLEMENTED assert(false)
// #define NOT_IMPLEMENTED // #define NOT_IMPLEMENTED
@ -96,7 +96,7 @@ ENDOP
STARTOP(push_short) STARTOP(push_short)
declare_params(2); declare_params(2);
const int16 r = int16(param[0]) << 8 const int16 r = int16(param[0]) << 8
| uint8(param[1]); | uint8(param[1]);
push(r); push(r);
ENDOP ENDOP
@ -322,7 +322,7 @@ STARTOP(insert)
smap.highpassed(false); smap.highpassed(false);
is = newSlot; is = newSlot;
seg.extendLength(1); seg.extendLength(1);
if (map != &smap[-1]) if (map != &smap[-1])
--map; --map;
ENDOP ENDOP
@ -333,12 +333,12 @@ STARTOP(delete_)
is->prev()->next(is->next()); is->prev()->next(is->next());
else else
seg.first(is->next()); seg.first(is->next());
if (is->next()) if (is->next())
is->next()->prev(is->prev()); is->next()->prev(is->prev());
else else
seg.last(is->prev()); seg.last(is->prev());
if (is == smap.highwater()) if (is == smap.highwater())
smap.highwater(is->next()); smap.highwater(is->next());
@ -371,7 +371,7 @@ ENDOP
STARTOP(cntxt_item) STARTOP(cntxt_item)
// It turns out this is a cunningly disguised condition forward jump. // It turns out this is a cunningly disguised condition forward jump.
declare_params(3); declare_params(3);
const int is_arg = int8(param[0]); const int is_arg = int8(param[0]);
const size_t iskip = uint8(param[1]), const size_t iskip = uint8(param[1]),
dskip = uint8(param[2]); dskip = uint8(param[2]);
@ -387,49 +387,49 @@ ENDOP
STARTOP(attr_set) STARTOP(attr_set)
declare_params(1); declare_params(1);
const attrCode slat = attrCode(uint8(*param)); const attrCode slat = attrCode(uint8(*param));
const int val = int(pop()); const int val = pop();
is->setAttr(&seg, slat, 0, val, smap); is->setAttr(&seg, slat, 0, val, smap);
ENDOP ENDOP
STARTOP(attr_add) STARTOP(attr_add)
declare_params(1); declare_params(1);
const attrCode slat = attrCode(uint8(*param)); 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) if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
{ {
seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir()); seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
flags |= POSITIONED; flags |= POSITIONED;
} }
int res = is->getAttr(&seg, slat, 0); uint32_t res = uint32_t(is->getAttr(&seg, slat, 0));
is->setAttr(&seg, slat, 0, val + res, smap); is->setAttr(&seg, slat, 0, int32_t(val + res), smap);
ENDOP ENDOP
STARTOP(attr_sub) STARTOP(attr_sub)
declare_params(1); declare_params(1);
const attrCode slat = attrCode(uint8(*param)); 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) if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
{ {
seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir()); seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
flags |= POSITIONED; flags |= POSITIONED;
} }
int res = is->getAttr(&seg, slat, 0); uint32_t res = uint32_t(is->getAttr(&seg, slat, 0));
is->setAttr(&seg, slat, 0, res - val, smap); is->setAttr(&seg, slat, 0, int32_t(res - val), smap);
ENDOP ENDOP
STARTOP(attr_set_slot) STARTOP(attr_set_slot)
declare_params(1); declare_params(1);
const attrCode slat = attrCode(uint8(*param)); const attrCode slat = attrCode(uint8(*param));
const int offset = (map - smap.begin())*int(slat == gr_slatAttTo); const int offset = int(map - smap.begin())*int(slat == gr_slatAttTo);
const int val = int(pop()) + offset; const int val = pop() + offset;
is->setAttr(&seg, slat, offset, val, smap); is->setAttr(&seg, slat, offset, val, smap);
ENDOP ENDOP
STARTOP(iattr_set_slot) STARTOP(iattr_set_slot)
declare_params(2); declare_params(2);
const attrCode slat = attrCode(uint8(param[0])); const attrCode slat = attrCode(uint8(param[0]));
const size_t idx = uint8(param[1]); const uint8 idx = uint8(param[1]);
const int val = int(pop()) + (map - smap.begin())*int(slat == gr_slatAttTo); const int val = int(pop() + (map - smap.begin())*int(slat == gr_slatAttTo));
is->setAttr(&seg, slat, idx, val, smap); is->setAttr(&seg, slat, idx, val, smap);
ENDOP ENDOP
@ -531,7 +531,7 @@ STARTOP(push_iglyph_attr) // not implemented
NOT_IMPLEMENTED; NOT_IMPLEMENTED;
ENDOP ENDOP
#endif #endif
STARTOP(pop_ret) STARTOP(pop_ret)
const uint32 ret = pop(); const uint32 ret = pop();
EXIT(ret); EXIT(ret);
@ -548,37 +548,37 @@ ENDOP
STARTOP(iattr_set) STARTOP(iattr_set)
declare_params(2); declare_params(2);
const attrCode slat = attrCode(uint8(param[0])); const attrCode slat = attrCode(uint8(param[0]));
const size_t idx = uint8(param[1]); const uint8 idx = uint8(param[1]);
const int val = int(pop()); const int val = pop();
is->setAttr(&seg, slat, idx, val, smap); is->setAttr(&seg, slat, idx, val, smap);
ENDOP ENDOP
STARTOP(iattr_add) STARTOP(iattr_add)
declare_params(2); declare_params(2);
const attrCode slat = attrCode(uint8(param[0])); const attrCode slat = attrCode(uint8(param[0]));
const size_t idx = uint8(param[1]); const uint8 idx = uint8(param[1]);
const int val = int(pop()); const uint32_t val = pop();
if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0) if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
{ {
seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir()); seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
flags |= POSITIONED; flags |= POSITIONED;
} }
int res = is->getAttr(&seg, slat, idx); uint32_t res = uint32_t(is->getAttr(&seg, slat, idx));
is->setAttr(&seg, slat, idx, val + res, smap); is->setAttr(&seg, slat, idx, int32_t(val + res), smap);
ENDOP ENDOP
STARTOP(iattr_sub) STARTOP(iattr_sub)
declare_params(2); declare_params(2);
const attrCode slat = attrCode(uint8(param[0])); const attrCode slat = attrCode(uint8(param[0]));
const size_t idx = uint8(param[1]); const uint8 idx = uint8(param[1]);
const int val = int(pop()); const uint32_t val = pop();
if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0) if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
{ {
seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir()); seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
flags |= POSITIONED; flags |= POSITIONED;
} }
int res = is->getAttr(&seg, slat, idx); uint32_t res = uint32_t(is->getAttr(&seg, slat, idx));
is->setAttr(&seg, slat, idx, res - val, smap); is->setAttr(&seg, slat, idx, int32_t(res - val), smap);
ENDOP ENDOP
STARTOP(push_proc_state) STARTOP(push_proc_state)
@ -689,4 +689,3 @@ STARTOP(set_feat)
seg.setFeature(fid, feat, pop()); seg.setFeature(fid, feat, pop());
} }
ENDOP ENDOP

View file

@ -33,6 +33,14 @@ of the License or (at your option) any later version.
#include <limits> #include <limits>
#include "inc/json.h" #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; using namespace graphite2;
namespace namespace
@ -45,7 +53,7 @@ namespace
}; };
} }
const json::_null_t json::null = {}; const std::nullptr_t json::null = nullptr;
inline inline
void json::context(const char current) throw() void json::context(const char current) throw()
@ -118,8 +126,8 @@ json & json::operator << (json::string s) throw()
} }
json & json::operator << (json::number f) throw() json & json::operator << (json::number f) throw()
{ {
context(seq); context(seq);
if (std::numeric_limits<json::number>::infinity() == f) if (std::numeric_limits<json::number>::infinity() == f)
fputs("Infinity", _stream); fputs("Infinity", _stream);
else if (-std::numeric_limits<json::number>::infinity() == f) else if (-std::numeric_limits<json::number>::infinity() == f)
@ -128,13 +136,12 @@ json & json::operator << (json::number f) throw()
std::numeric_limits<json::number>::signaling_NaN() == f) std::numeric_limits<json::number>::signaling_NaN() == f)
fputs("NaN", _stream); fputs("NaN", _stream);
else else
fprintf(_stream, "%g", f); fprintf(_stream, "%g", f);
return *this; return *this;
} }
json & json::operator << (json::integer 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 << (long unsigned d) throw() { context(seq); fprintf(_stream, "%ld", 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::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 #endif

View file

@ -23,7 +23,6 @@ else:
# This should contain all of the _SOURCES from files.mk, except *_machine.cpp # This should contain all of the _SOURCES from files.mk, except *_machine.cpp
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
'CachedFace.cpp',
'CmapCache.cpp', 'CmapCache.cpp',
'Code.cpp', 'Code.cpp',
'Collider.cpp', 'Collider.cpp',
@ -46,9 +45,6 @@ UNIFIED_SOURCES += [
'Justifier.cpp', 'Justifier.cpp',
'Pass.cpp', 'Pass.cpp',
'Position.cpp', 'Position.cpp',
'SegCache.cpp',
'SegCacheEntry.cpp',
'SegCacheStore.cpp',
'Segment.cpp', 'Segment.cpp',
'Silf.cpp', 'Silf.cpp',
'Slot.cpp', 'Slot.cpp',