mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 23:02:20 +00:00
Bug 1443095 - Update graphite2 library to release 1.3.11 (plus upstream commit 6e24eb7e to fix leak). r=jrmuizel
This commit is contained in:
parent
8dfb05971f
commit
243822d04c
@ -1,5 +1,12 @@
|
||||
# Graphite engine
|
||||
|
||||
## 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)
|
||||
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)
|
||||
|
||||
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?
|
||||
|
||||
Graphite is a system that can be used to create “smart fonts” capable of displaying writing systems with various complex behaviors. A smart font contains not only letter shapes but also additional instructions indicating how to combine and position the letters in complex ways.
|
||||
|
@ -1,3 +1,7 @@
|
||||
This directory contains the Graphite2 library release 1.3.10 from
|
||||
https://github.com/silnrsi/graphite/releases/download/1.3.10/graphite2-minimal-1.3.10.tgz
|
||||
This directory contains the Graphite2 library release 1.3.11 from
|
||||
https://github.com/silnrsi/graphite/releases/download/1.3.11/graphite2-minimal-1.3.11.tgz
|
||||
See ./gfx/graphite2/moz-gr-update.sh for update procedure.
|
||||
|
||||
Note (2018-03-10):
|
||||
Cherry-picked 6e24eb7edbd0872b46441d7397e8b87cccfede73 from upstream to fix memory leak
|
||||
as noted in bug https://bugzilla.mozilla.org/show_bug.cgi?id=1443095.
|
@ -30,7 +30,7 @@
|
||||
|
||||
#define GR2_VERSION_MAJOR 1
|
||||
#define GR2_VERSION_MINOR 3
|
||||
#define GR2_VERSION_BUGFIX 10
|
||||
#define GR2_VERSION_BUGFIX 11
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
@ -56,6 +56,10 @@ if (GRAPHITE2_TELEMETRY)
|
||||
add_definitions(-DGRAPHITE2_TELEMETRY)
|
||||
endif (GRAPHITE2_TELEMETRY)
|
||||
|
||||
if (NOT BUILD_SHARED_LIBS)
|
||||
add_definitions(-DGRAPHITE2_STATIC)
|
||||
endif (NOT BUILD_SHARED_LIBS)
|
||||
|
||||
set(GRAPHITE_HEADERS
|
||||
../include/graphite2/Font.h
|
||||
../include/graphite2/Segment.h
|
||||
@ -65,7 +69,7 @@ set(GRAPHITE_HEADERS
|
||||
|
||||
file(GLOB PRIVATE_HEADERS inc/*.h)
|
||||
|
||||
add_library(graphite2 SHARED
|
||||
add_library(graphite2
|
||||
${GRAPHITE2_VM_TYPE}_machine.cpp
|
||||
gr_char_info.cpp
|
||||
gr_features.cpp
|
||||
@ -107,9 +111,9 @@ set_target_properties(graphite2 PROPERTIES PUBLIC_HEADER "${GRAPHITE_HEADERS}"
|
||||
LT_VERSION_AGE ${GRAPHITE_API_AGE})
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
set_target_properties(graphite2 PROPERTIES
|
||||
COMPILE_FLAGS "-Wall -Wextra -Wno-unknown-pragmas -Wendif-labels -Wshadow -Wctor-dtor-privacy -Wnon-virtual-dtor -fno-rtti -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -fno-stack-protector"
|
||||
LINK_FLAGS "-nodefaultlibs ${GRAPHITE_LINK_FLAGS}"
|
||||
set_target_properties(graphite2 PROPERTIES
|
||||
COMPILE_FLAGS "-Wall -Wextra -Wno-unknown-pragmas -Wendif-labels -Wshadow -Wctor-dtor-privacy -Wnon-virtual-dtor -fno-rtti -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden"
|
||||
LINK_FLAGS "-nodefaultlibs ${GRAPHITE_LINK_FLAGS}"
|
||||
LINKER_LANGUAGE C)
|
||||
if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86|i.86")
|
||||
add_definitions(-mfpmath=sse -msse2)
|
||||
@ -130,16 +134,18 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
target_link_libraries(graphite2 c gcc)
|
||||
endif (GRAPHITE2_ASAN)
|
||||
include(Graphite)
|
||||
nolib_test(stdc++ $<TARGET_SONAME_FILE:graphite2>)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
nolib_test(stdc++ $<TARGET_SONAME_FILE:graphite2>)
|
||||
endif (BUILD_SHARED_LIBS)
|
||||
endif (${CMAKE_CXX_COMPILER} MATCHES ".*mingw.*")
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
|
||||
CREATE_LIBTOOL_FILE(graphite2 "/lib${LIB_SUFFIX}")
|
||||
endif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
|
||||
set_target_properties(graphite2 PROPERTIES
|
||||
COMPILE_FLAGS "-Wall -Wextra -Wno-unknown-pragmas -Wimplicit-fallthrough -Wendif-labels -Wshadow -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor -fno-rtti -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -fno-stack-protector -mfpmath=sse -msse2"
|
||||
LINK_FLAGS "-nodefaultlibs"
|
||||
set_target_properties(graphite2 PROPERTIES
|
||||
COMPILE_FLAGS "-Wall -Wextra -Wno-unknown-pragmas -Wimplicit-fallthrough -Wendif-labels -Wshadow -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor -fno-rtti -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -mfpmath=sse -msse2"
|
||||
LINK_FLAGS "-nodefaultlibs"
|
||||
LINKER_LANGUAGE C)
|
||||
target_link_libraries(graphite2 c)
|
||||
include(Graphite)
|
||||
|
@ -219,7 +219,11 @@ Machine::Code::Code(bool is_constraint, const byte * bytecode_begin, const byte
|
||||
if (_out)
|
||||
*_out += total_sz;
|
||||
else
|
||||
_code = static_cast<instr *>(realloc(_code, total_sz));
|
||||
{
|
||||
instr * const old_code = _code;
|
||||
_code = static_cast<instr *>(realloc(_code, total_sz));
|
||||
if (!_code) free(old_code);
|
||||
}
|
||||
_data = reinterpret_cast<byte *>(_code + (_instr_count+1));
|
||||
|
||||
if (!_code)
|
||||
@ -316,8 +320,9 @@ opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
|
||||
if (_stack_depth <= 0)
|
||||
failure(underfull_stack);
|
||||
break;
|
||||
case NEXT :
|
||||
case NEXT_N : // runtime checked
|
||||
break;
|
||||
case NEXT :
|
||||
case COPY_NEXT :
|
||||
++_out_index;
|
||||
if (_out_index < -1 || _out_index > _out_length || _slotref > _max.rule_length)
|
||||
|
@ -306,7 +306,7 @@ bool ShiftCollider::mergeSlot(Segment *seg, Slot *slot, const SlotCollision *csl
|
||||
float seq_above_wt = cslot->seqAboveWt();
|
||||
float seq_below_wt = cslot->seqBelowWt();
|
||||
float seq_valign_wt = cslot->seqValignWt();
|
||||
float lmargin = _margin;
|
||||
float lmargin;
|
||||
// if isAfter, invert orderFlags for diagonal orders.
|
||||
if (isAfter)
|
||||
{
|
||||
@ -558,6 +558,8 @@ bool ShiftCollider::mergeSlot(Segment *seg, Slot *slot, const SlotCollision *csl
|
||||
{
|
||||
// Set up the bogus slot representing the exclusion glyph.
|
||||
Slot *exclSlot = seg->newSlot();
|
||||
if (!exclSlot)
|
||||
return res;
|
||||
exclSlot->setGlyph(seg, cslot->exclGlyph());
|
||||
Position exclOrigin(slot->origin() + cslot->exclOffset());
|
||||
exclSlot->origin(exclOrigin);
|
||||
@ -805,6 +807,8 @@ static float get_edge(Segment *seg, const Slot *s, const Position &shift, float
|
||||
{
|
||||
const BBox &bb = gc.getBoundingBBox(gid);
|
||||
const SlantBox &sb = gc.getBoundingSlantBox(gid);
|
||||
if (sy + bb.yi - margin > y + width / 2 || sy + bb.ya + margin < y - width / 2)
|
||||
return res;
|
||||
float td = sx - sy + y;
|
||||
float ts = sx + sy - y;
|
||||
if (isRight)
|
||||
@ -924,7 +928,7 @@ bool KernCollider::initSlot(Segment *seg, Slot *aSlot, const Rect &limit, float
|
||||
}
|
||||
}
|
||||
done:
|
||||
_mingap = (float)1e38;
|
||||
_mingap = (float)1e37; // less than 1e38 s.t. 1e38-_mingap is really big
|
||||
_target = aSlot;
|
||||
_margin = margin;
|
||||
_currShift = currShift;
|
||||
@ -945,7 +949,7 @@ bool KernCollider::mergeSlot(Segment *seg, Slot *slot, const Position &currShift
|
||||
const float sx = slot->origin().x + currShift.x;
|
||||
float x = (sx + (rtl > 0 ? bb.tr.x : bb.bl.x)) * rtl;
|
||||
// this isn't going to reduce _mingap so skip
|
||||
if (x < rtl * (_xbound - _mingap - currSpace))
|
||||
if (_hit && x < rtl * (_xbound - _mingap - currSpace))
|
||||
return false;
|
||||
|
||||
const float sy = slot->origin().y + currShift.y;
|
||||
@ -954,19 +958,24 @@ bool KernCollider::mergeSlot(Segment *seg, Slot *slot, const Position &currShift
|
||||
if (smin > smax)
|
||||
return false;
|
||||
bool collides = false;
|
||||
bool nooverlap = true;
|
||||
|
||||
for (int i = smin; i <= smax; ++i)
|
||||
{
|
||||
float t;
|
||||
float here = _edges[i] * rtl;
|
||||
float y = (float)(_miny - 1 + (i + .5f) * _sliceWidth); // vertical center of slice
|
||||
if ( (x > here - _mingap - currSpace) )
|
||||
if (here > (float)9e37)
|
||||
continue;
|
||||
if (!_hit || x > here - _mingap - currSpace)
|
||||
{
|
||||
float y = (float)(_miny - 1 + (i + .5f) * _sliceWidth); // vertical center of slice
|
||||
// 2 * currSpace to account for the space that is already separating them and the space we want to add
|
||||
float m = get_edge(seg, slot, currShift, y, _sliceWidth, 0., rtl > 0) * rtl + 2 * currSpace;
|
||||
t = here - m;
|
||||
if (m < (float)-8e37) // only true if the glyph has a gap in it
|
||||
continue;
|
||||
nooverlap = false;
|
||||
float t = here - m;
|
||||
// _mingap is positive to shrink
|
||||
if (t < _mingap)
|
||||
if (t < _mingap || (!_hit && !collides))
|
||||
{
|
||||
_mingap = t;
|
||||
collides = true;
|
||||
@ -980,8 +989,14 @@ bool KernCollider::mergeSlot(Segment *seg, Slot *slot, const Position &currShift
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
nooverlap = false;
|
||||
}
|
||||
return collides; // note that true is not a necessarily reliable value
|
||||
if (nooverlap)
|
||||
_mingap = max(_mingap, _xbound + currSpace + _margin - x);
|
||||
if (collides && !nooverlap)
|
||||
_hit = true;
|
||||
return collides | nooverlap; // note that true is not a necessarily reliable value
|
||||
|
||||
} // end of KernCollider::mergeSlot
|
||||
|
||||
|
@ -43,29 +43,32 @@ u32 read_literal(u8 const * &s, u8 const * const e, u32 l) {
|
||||
return l;
|
||||
}
|
||||
|
||||
bool read_sequence(u8 const * &src, u8 const * const end, u8 const * &literal, u32 & literal_len, u32 & match_len, u32 & match_dist)
|
||||
bool read_sequence(u8 const * &src, u8 const * const end, u8 const * &literal,
|
||||
u32 & literal_len, u32 & match_len, u32 & match_dist)
|
||||
{
|
||||
u8 const token = *src++;
|
||||
|
||||
literal_len = read_literal(src, end, token >> 4);
|
||||
literal = src;
|
||||
src += literal_len;
|
||||
|
||||
if (src > end - 2 || src < literal)
|
||||
|
||||
// Normal exit for end of stream, wrap arround check and parital match check.
|
||||
if (src > end - sizeof(u16) || src < literal)
|
||||
return false;
|
||||
|
||||
match_dist = *src++;
|
||||
match_dist |= *src++ << 8;
|
||||
match_len = read_literal(src, end, token & 0xf);
|
||||
|
||||
return src <= end-5;
|
||||
match_len = read_literal(src, end, token & 0xf) + MINMATCH;
|
||||
|
||||
// Malformed stream check.
|
||||
return src <= end-MINCODA;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int lz4::decompress(void const *in, size_t in_size, void *out, size_t out_size)
|
||||
{
|
||||
if (out_size <= in_size || in_size < sizeof(unsigned long)+1)
|
||||
if (out_size <= in_size || in_size < MINSRCSIZE)
|
||||
return -1;
|
||||
|
||||
u8 const * src = static_cast<u8 const *>(in),
|
||||
@ -74,39 +77,47 @@ int lz4::decompress(void const *in, size_t in_size, void *out, size_t out_size)
|
||||
|
||||
u8 * dst = static_cast<u8*>(out),
|
||||
* const dst_end = dst + out_size;
|
||||
|
||||
|
||||
// Check the in and out size hasn't wrapped around.
|
||||
if (src >= src_end || dst >= dst_end)
|
||||
return -1;
|
||||
|
||||
u32 literal_len = 0,
|
||||
match_len = 0,
|
||||
match_dist = 0;
|
||||
|
||||
while (read_sequence(src, src_end, literal, literal_len, match_len, match_dist))
|
||||
|
||||
while (read_sequence(src, src_end, literal, literal_len, match_len,
|
||||
match_dist))
|
||||
{
|
||||
if (literal_len != 0)
|
||||
{
|
||||
// Copy in literal. At this point the last full sequence must be at
|
||||
// least MINMATCH + 5 from the end of the output buffer.
|
||||
if (align(literal_len) > unsigned(dst_end - dst - (MINMATCH+5)) || dst_end - dst < MINMATCH + 5)
|
||||
// Copy in literal. At this point the a minimal literal + minminal
|
||||
// match plus the coda (1 + 2 + 5) must be 8 bytes or more allowing
|
||||
// us to remain within the src buffer for an overrun_copy on
|
||||
// machines upto 64 bits.
|
||||
if (align(literal_len) > out_size)
|
||||
return -1;
|
||||
dst = overrun_copy(dst, literal, literal_len);
|
||||
out_size -= literal_len;
|
||||
}
|
||||
|
||||
// Copy, possibly repeating, match from earlier in the
|
||||
// decoded output.
|
||||
u8 const * const pcpy = dst - match_dist;
|
||||
if (pcpy < static_cast<u8*>(out)
|
||||
|| pcpy >= dst
|
||||
|| match_len > unsigned(dst_end - dst - (MINMATCH+5))
|
||||
|| dst_end - dst < MINMATCH + 5)
|
||||
|| match_len > unsigned(out_size - LASTLITERALS)
|
||||
// Wrap around checks:
|
||||
|| out_size < LASTLITERALS || pcpy >= dst)
|
||||
return -1;
|
||||
if (dst > pcpy+sizeof(unsigned long)
|
||||
&& dst + align(match_len + MINMATCH) <= dst_end)
|
||||
dst = overrun_copy(dst, pcpy, match_len + MINMATCH);
|
||||
else
|
||||
dst = safe_copy(dst, pcpy, match_len + MINMATCH);
|
||||
if (dst > pcpy+sizeof(unsigned long)
|
||||
&& align(match_len) <= out_size)
|
||||
dst = overrun_copy(dst, pcpy, match_len);
|
||||
else
|
||||
dst = safe_copy(dst, pcpy, match_len);
|
||||
out_size -= match_len;
|
||||
}
|
||||
|
||||
if (literal_len > src_end - literal
|
||||
|| literal_len > dst_end - dst)
|
||||
|
||||
if (literal > src_end - literal_len || literal_len > out_size)
|
||||
return -1;
|
||||
dst = fast_copy(dst, literal, literal_len);
|
||||
|
||||
|
@ -73,7 +73,7 @@ FeatureRef::FeatureRef(const Face & face,
|
||||
unsigned short & bits_offset, uint32 max_val,
|
||||
uint32 name, uint16 uiName, uint16 flags,
|
||||
FeatureSetting *settings, uint16 num_set) throw()
|
||||
: m_pFace(&face),
|
||||
: m_face(&face),
|
||||
m_nameValues(settings),
|
||||
m_mask(mask_over_val(max_val)),
|
||||
m_max(max_val),
|
||||
@ -135,7 +135,7 @@ bool FeatureMap::readFeats(const Face & face)
|
||||
const uint16 flags = be::read<uint16>(p),
|
||||
uiName = be::read<uint16>(p);
|
||||
|
||||
if (settings_offset > size_t(feat_end - feat_start)
|
||||
if (settings_offset > size_t(feat_end - feat_start)
|
||||
|| settings_offset + num_settings * FEATURE_SETTING_SIZE > size_t(feat_end - feat_start))
|
||||
{
|
||||
free(defVals);
|
||||
@ -176,9 +176,9 @@ bool FeatureMap::readFeats(const Face & face)
|
||||
for (int i = 0; i < m_numFeats; ++i)
|
||||
{
|
||||
m_feats[i].applyValToFeature(defVals[i], m_defaultFeatures);
|
||||
m_pNamedFeats[i] = m_feats+i;
|
||||
m_pNamedFeats[i] = m_feats[i];
|
||||
}
|
||||
|
||||
|
||||
free(defVals);
|
||||
|
||||
qsort(m_pNamedFeats, m_numFeats, sizeof(NameAndFeatureRef), &cmpNameAndFeatures);
|
||||
@ -259,7 +259,7 @@ Features* SillMap::cloneFeatures(uint32 langname/*0 means default*/) const
|
||||
const FeatureRef *FeatureMap::findFeatureRef(uint32 name) const
|
||||
{
|
||||
NameAndFeatureRef *it;
|
||||
|
||||
|
||||
for (it = m_pNamedFeats; it < m_pNamedFeats + m_numFeats; ++it)
|
||||
if (it->m_name == name)
|
||||
return it->m_pFRef;
|
||||
@ -267,13 +267,13 @@ const FeatureRef *FeatureMap::findFeatureRef(uint32 name) const
|
||||
}
|
||||
|
||||
bool FeatureRef::applyValToFeature(uint32 val, Features & pDest) const
|
||||
{
|
||||
if (val>maxVal() || !m_pFace)
|
||||
{
|
||||
if (val>maxVal() || !m_face)
|
||||
return false;
|
||||
if (pDest.m_pMap==NULL)
|
||||
pDest.m_pMap = &m_pFace->theSill().theFeatureMap();
|
||||
pDest.m_pMap = &m_face->theSill().theFeatureMap();
|
||||
else
|
||||
if (pDest.m_pMap!=&m_pFace->theSill().theFeatureMap())
|
||||
if (pDest.m_pMap!=&m_face->theSill().theFeatureMap())
|
||||
return false; //incompatible
|
||||
if (m_index >= pDest.size())
|
||||
pDest.resize(m_index+1);
|
||||
@ -283,11 +283,10 @@ bool FeatureRef::applyValToFeature(uint32 val, Features & pDest) const
|
||||
}
|
||||
|
||||
uint32 FeatureRef::getFeatureVal(const Features& feats) const
|
||||
{
|
||||
if (m_index < feats.size() && &m_pFace->theSill().theFeatureMap()==feats.m_pMap)
|
||||
return (feats[m_index] & m_mask) >> m_bits;
|
||||
{
|
||||
if (m_index < feats.size() && m_face
|
||||
&& &m_face->theSill().theFeatureMap()==feats.m_pMap)
|
||||
return (feats[m_index] & m_mask) >> m_bits;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,7 +92,7 @@ const void *FileFace::get_table_fn(const void* appFaceHandle, unsigned int name,
|
||||
return 0;
|
||||
|
||||
tbl = malloc(tbl_len);
|
||||
if (fread(tbl, 1, tbl_len, file_face._file) != tbl_len)
|
||||
if (!tbl || fread(tbl, 1, tbl_len, file_face._file) != tbl_len)
|
||||
{
|
||||
free(tbl);
|
||||
return 0;
|
||||
|
@ -171,7 +171,9 @@ bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t su
|
||||
const uint16 * const o_actions = reinterpret_cast<const uint16 *>(p);
|
||||
be::skip<uint16>(p, m_numRules + 1);
|
||||
const byte * const states = p;
|
||||
if (e.test(2u*m_numTransition*m_numColumns >= (unsigned)(pass_end - p), E_BADPASSLENGTH)) return face.error(e);
|
||||
if (e.test(2u*m_numTransition*m_numColumns >= (unsigned)(pass_end - p), E_BADPASSLENGTH)
|
||||
|| e.test(p >= pass_end, E_BADPASSLENGTH))
|
||||
return face.error(e);
|
||||
be::skip<int16>(p, m_numTransition*m_numColumns);
|
||||
be::skip<uint8>(p);
|
||||
if (e.test(p != pcCode, E_BADPASSCCODEPTR)) return face.error(e);
|
||||
@ -270,10 +272,11 @@ bool Pass::readRules(const byte * rule_map, const size_t num_entries,
|
||||
return face.error(e);
|
||||
}
|
||||
|
||||
byte * moved_progs = static_cast<byte *>(realloc(m_progs, prog_pool_free - m_progs));
|
||||
byte * const moved_progs = prog_pool_free > m_progs ? static_cast<byte *>(realloc(m_progs, prog_pool_free - m_progs)) : 0;
|
||||
if (e.test(!moved_progs, E_OUTOFMEM))
|
||||
{
|
||||
if (prog_pool_free - m_progs == 0) m_progs = 0;
|
||||
free(m_progs);
|
||||
m_progs = 0;
|
||||
return face.error(e);
|
||||
}
|
||||
|
||||
@ -714,18 +717,18 @@ void Pass::adjustSlot(int delta, Slot * & slot_out, SlotMap & smap) const
|
||||
{
|
||||
while (++delta <= 0 && slot_out)
|
||||
{
|
||||
slot_out = slot_out->prev();
|
||||
if (smap.highpassed() && smap.highwater() == slot_out)
|
||||
smap.highpassed(false);
|
||||
slot_out = slot_out->prev();
|
||||
}
|
||||
}
|
||||
else if (delta > 0)
|
||||
{
|
||||
while (--delta >= 0 && slot_out)
|
||||
{
|
||||
slot_out = slot_out->next();
|
||||
if (slot_out == smap.highwater() && slot_out)
|
||||
smap.highpassed(true);
|
||||
slot_out = slot_out->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -968,8 +971,8 @@ bool Pass::resolveCollisions(Segment *seg, Slot *slotFix, Slot *start,
|
||||
if (nbor != slotFix // don't process if this is the slot of interest
|
||||
&& !(cNbor->ignore()) // don't process if ignoring
|
||||
&& (nbor == base || sameCluster // process if in the same cluster as slotFix
|
||||
|| !inKernCluster(seg, nbor) // or this cluster is not to be kerned
|
||||
|| (rtl ^ ignoreForKern)) // or it comes before(ltr) or after(rtl)
|
||||
|| !inKernCluster(seg, nbor)) // or this cluster is not to be kerned
|
||||
// || (rtl ^ ignoreForKern)) // or it comes before(ltr) or after(rtl)
|
||||
&& (!isRev // if processing forwards then good to merge otherwise only:
|
||||
|| !(cNbor->flags() & SlotCollision::COLL_FIX) // merge in immovable stuff
|
||||
|| ((cNbor->flags() & SlotCollision::COLL_KERN) && !sameCluster) // ignore other kernable clusters
|
||||
@ -1037,6 +1040,8 @@ float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start
|
||||
base = base->attachedTo();
|
||||
SlotCollision *cFix = seg->collisionInfo(base);
|
||||
const GlyphCache &gc = seg->getFace()->glyphs();
|
||||
const Rect &bbb = seg->theGlyphBBoxTemporary(slotFix->gid());
|
||||
const float by = slotFix->origin().y + cFix->shift().y;
|
||||
|
||||
if (base != slotFix)
|
||||
{
|
||||
@ -1047,6 +1052,8 @@ float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start
|
||||
bool isInit = false;
|
||||
KernCollider coll(dbgout);
|
||||
|
||||
ymax = max(by + bbb.tr.y, ymax);
|
||||
ymin = min(by + bbb.bl.y, ymin);
|
||||
for (nbor = slotFix->next(); nbor; nbor = nbor->next())
|
||||
{
|
||||
if (nbor->isChildOf(base))
|
||||
@ -1066,9 +1073,6 @@ float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start
|
||||
else
|
||||
{
|
||||
space_count = 0;
|
||||
float y = nbor->origin().y + cNbor->shift().y;
|
||||
ymax = max(y + bb.tr.y, ymax);
|
||||
ymin = min(y + bb.bl.y, ymin);
|
||||
if (nbor != slotFix && !cNbor->ignore())
|
||||
{
|
||||
seenEnd = true;
|
||||
|
@ -42,7 +42,7 @@ SegCacheEntry::SegCacheEntry(const uint16* cmapGlyphs, size_t length, Segment *
|
||||
m_accessCount(0), m_lastAccess(cacheTime)
|
||||
{
|
||||
if (m_unicode)
|
||||
for (uint16 i = 0; i < length; i++)
|
||||
for (size_t i = 0; i < length; i++)
|
||||
m_unicode[i] = cmapGlyphs[i];
|
||||
|
||||
const size_t glyphCount = seg->slotCount(),
|
||||
|
@ -59,7 +59,9 @@ Segment::Segment(unsigned int numchars, const Face* face, uint32 script, int tex
|
||||
m_dir(textDir),
|
||||
m_flags(((m_silf->flags() & 0x20) != 0) << 1)
|
||||
{
|
||||
freeSlot(newSlot());
|
||||
Slot *s = newSlot();
|
||||
if (s)
|
||||
freeSlot(s);
|
||||
m_bufSize = log_binary(numchars)+1;
|
||||
}
|
||||
|
||||
|
@ -276,6 +276,7 @@ size_t Silf::readClassMap(const byte *p, size_t data_len, uint32 version, Error
|
||||
return ERROROFFSET;
|
||||
|
||||
// Check the linear offsets are sane, these must be monotonically increasing.
|
||||
assert(m_nClass >= m_nLinear);
|
||||
for (const uint32 *o = m_classOffsets, * const o_end = o + m_nLinear; o != o_end; ++o)
|
||||
if (e.test(o[0] > o[1], E_BADCLASSOFFSET))
|
||||
return ERROROFFSET;
|
||||
|
@ -341,6 +341,11 @@ bool CheckTable(const Tag TableId, const void * pTable, size_t lTableSize)
|
||||
return be::swap(pName->format) == 0;
|
||||
}
|
||||
|
||||
case Tag::glyf:
|
||||
{
|
||||
return (lTableSize >= sizeof(Sfnt::Glyph));
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -464,7 +469,7 @@ void HeadTableModifyTime(const void * pHead,
|
||||
{
|
||||
const Sfnt::FontHeader * pTable =
|
||||
reinterpret_cast<const Sfnt::FontHeader *>(pHead);
|
||||
|
||||
;
|
||||
*pnDateBC = be::swap(pTable->modified[0]);
|
||||
*pnDateAD = be::swap(pTable->modified[1]);
|
||||
}
|
||||
@ -1247,7 +1252,7 @@ size_t LocaLookup(gid16 nGlyphId,
|
||||
void * GlyfLookup(const void * pGlyf, size_t nGlyfOffset, size_t nTableLen)
|
||||
{
|
||||
const uint8 * pByte = reinterpret_cast<const uint8 *>(pGlyf);
|
||||
if (nGlyfOffset + pByte < pByte || nGlyfOffset + sizeof(Sfnt::Glyph) >= nTableLen)
|
||||
if (nGlyfOffset + pByte < pByte || nGlyfOffset >= nTableLen - sizeof(Sfnt::Glyph))
|
||||
return NULL;
|
||||
return const_cast<uint8 *>(pByte + nGlyfOffset);
|
||||
}
|
||||
|
@ -195,7 +195,7 @@ gr_uint32 gr_face_lang_by_index(const gr_face* pFace, gr_uint16 i)
|
||||
|
||||
void gr_face_destroy(gr_face *face)
|
||||
{
|
||||
delete face;
|
||||
delete static_cast<Face*>(face);
|
||||
}
|
||||
|
||||
|
||||
|
@ -80,14 +80,14 @@ gr_int16 gr_fref_value(const gr_feature_ref* pfeatureref, gr_uint16 settingno)
|
||||
|
||||
void* gr_fref_label(const gr_feature_ref* pfeatureref, gr_uint16 *langId, gr_encform utf, gr_uint32 *length)
|
||||
{
|
||||
if(!pfeatureref || !pfeatureref->getFace())
|
||||
if(!pfeatureref)
|
||||
{
|
||||
langId = 0;
|
||||
length = 0;
|
||||
return NULL;
|
||||
}
|
||||
uint16 label = pfeatureref->getNameId();
|
||||
NameTable * names = pfeatureref->getFace()->nameTable();
|
||||
NameTable * names = pfeatureref->getFace().nameTable();
|
||||
if (!names)
|
||||
{
|
||||
langId = 0;
|
||||
@ -101,14 +101,14 @@ void* gr_fref_label(const gr_feature_ref* pfeatureref, gr_uint16 *langId, gr_enc
|
||||
void* gr_fref_value_label(const gr_feature_ref*pfeatureref, gr_uint16 setting,
|
||||
gr_uint16 *langId, gr_encform utf, gr_uint32 *length)
|
||||
{
|
||||
if(!pfeatureref || (setting >= pfeatureref->getNumSettings()) || !pfeatureref->getFace())
|
||||
if(!pfeatureref || (setting >= pfeatureref->getNumSettings()))
|
||||
{
|
||||
langId = 0;
|
||||
length = 0;
|
||||
return NULL;
|
||||
}
|
||||
uint16 label = pfeatureref->getSettingName(setting);
|
||||
NameTable * names = pfeatureref->getFace()->nameTable();
|
||||
NameTable * names = pfeatureref->getFace().nameTable();
|
||||
if (!names)
|
||||
{
|
||||
langId = 0;
|
||||
@ -131,7 +131,7 @@ gr_feature_val* gr_featureval_clone(const gr_feature_val* pfeatures/*may be NULL
|
||||
|
||||
void gr_featureval_destroy(gr_feature_val *p)
|
||||
{
|
||||
delete p;
|
||||
delete static_cast<Features*>(p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,10 +47,16 @@ 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*/)
|
||||
{ //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) return 0;
|
||||
if (face == 0 || ppm <= 0) return 0;
|
||||
|
||||
Font * const res = new Font(ppm, *face, appFontHandle, font_ops);
|
||||
return static_cast<gr_font*>(res);
|
||||
if (*res)
|
||||
return static_cast<gr_font*>(res);
|
||||
else
|
||||
{
|
||||
delete res;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
gr_font* gr_make_font_with_advance_fn(float ppm/*pixels per em*/, const void* appFontHandle/*non-NULL*/, gr_advance_fn getAdvance, const gr_face * face/*needed for scaling*/)
|
||||
@ -61,7 +67,7 @@ gr_font* gr_make_font_with_advance_fn(float ppm/*pixels per em*/, const void* ap
|
||||
|
||||
void gr_font_destroy(gr_font *font)
|
||||
{
|
||||
delete font;
|
||||
delete static_cast<Font*>(font);
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,7 +41,7 @@ of the License or (at your option) any later version.
|
||||
using namespace graphite2;
|
||||
|
||||
#if !defined GRAPHITE2_NTRACING
|
||||
json *global_log = NULL;
|
||||
json *global_log = 0;
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
@ -120,6 +120,7 @@ void gr_stop_logging(GR_MAYBE_UNUSED gr_face * face)
|
||||
{
|
||||
FILE * log = global_log->stream();
|
||||
delete global_log;
|
||||
global_log = 0;
|
||||
fclose(log);
|
||||
}
|
||||
#endif
|
||||
@ -214,7 +215,7 @@ json & graphite2::operator << (json & j, const dslot & ds) throw()
|
||||
j << "user" << json::flat << json::array;
|
||||
for (int n = 0; n!= seg.numAttrs(); ++n)
|
||||
j << s.userAttrs()[n];
|
||||
j << json::close;
|
||||
j << json::close;
|
||||
if (s.firstChild())
|
||||
{
|
||||
j << "children" << json::flat << json::array;
|
||||
|
@ -103,7 +103,7 @@ gr_segment* gr_make_seg(const gr_font *font, const gr_face *face, gr_uint32 scri
|
||||
if (pFeats == 0)
|
||||
pFeats = tmp_feats = static_cast<const gr_feature_val*>(face->theSill().cloneFeatures(0));
|
||||
gr_segment * seg = makeAndInitialize(font, face, script, pFeats, enc, pStart, nChars, dir);
|
||||
delete tmp_feats;
|
||||
delete static_cast<const FeatureVal*>(tmp_feats);
|
||||
|
||||
return seg;
|
||||
}
|
||||
@ -111,7 +111,7 @@ gr_segment* gr_make_seg(const gr_font *font, const gr_face *face, gr_uint32 scri
|
||||
|
||||
void gr_seg_destroy(gr_segment* p)
|
||||
{
|
||||
delete p;
|
||||
delete static_cast<Segment*>(p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -162,7 +162,7 @@ inline void Machine::Code::externalProgramMoved(ptrdiff_t dist) throw()
|
||||
{
|
||||
if (_code && !_own)
|
||||
{
|
||||
_code += dist / sizeof(instr);
|
||||
_code += dist / signed(sizeof(instr));
|
||||
_data += dist;
|
||||
}
|
||||
}
|
||||
|
@ -210,6 +210,7 @@ private:
|
||||
float _sliceWidth; // width of each slice
|
||||
float _mingap;
|
||||
float _xbound; // max or min edge
|
||||
bool _hit;
|
||||
|
||||
#if !defined GRAPHITE2_NTRACING
|
||||
// Debugging
|
||||
@ -233,7 +234,8 @@ KernCollider::KernCollider(GR_MAYBE_UNUSED json *dbg)
|
||||
_maxy(1e38f),
|
||||
_sliceWidth(0.0f),
|
||||
_mingap(0.0f),
|
||||
_xbound(0.0)
|
||||
_xbound(0.0),
|
||||
_hit(false)
|
||||
{
|
||||
#if !defined GRAPHITE2_NTRACING
|
||||
_seg = 0;
|
||||
|
@ -47,7 +47,10 @@ typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
#endif
|
||||
|
||||
ptrdiff_t const MINMATCH = 4;
|
||||
ptrdiff_t const MINMATCH = 4,
|
||||
LASTLITERALS = 5,
|
||||
MINCODA = LASTLITERALS+1,
|
||||
MINSRCSIZE = 13;
|
||||
|
||||
template<int S>
|
||||
inline
|
||||
|
@ -56,7 +56,7 @@ class FeatureRef
|
||||
static const uint8 SIZEOF_CHUNK = sizeof(chunk_t)*8;
|
||||
|
||||
public:
|
||||
FeatureRef();
|
||||
FeatureRef() throw();
|
||||
FeatureRef(const Face & face, unsigned short & bits_offset, uint32 max_val,
|
||||
uint32 name, uint16 uiName, uint16 flags,
|
||||
FeatureSetting *settings, uint16 num_set) throw();
|
||||
@ -65,7 +65,7 @@ public:
|
||||
bool applyValToFeature(uint32 val, Features& pDest) const; //defined in GrFaceImp.h
|
||||
void maskFeature(Features & pDest) const {
|
||||
if (m_index < pDest.size()) //defensive
|
||||
pDest[m_index] |= m_mask;
|
||||
pDest[m_index] |= m_mask;
|
||||
}
|
||||
|
||||
uint32 getFeatureVal(const Features& feats) const; //defined in GrFaceImp.h
|
||||
@ -76,14 +76,14 @@ public:
|
||||
uint16 getSettingName(uint16 index) const { return m_nameValues[index].label(); }
|
||||
int16 getSettingValue(uint16 index) const { return m_nameValues[index].value(); }
|
||||
uint32 maxVal() const { return m_max; }
|
||||
const Face* getFace() const { return m_pFace;}
|
||||
const Face & getFace() const { assert(m_face); return *m_face;}
|
||||
const FeatureMap* getFeatureMap() const;// { return m_pFace;}
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
private:
|
||||
FeatureRef(const FeatureRef & rhs);
|
||||
|
||||
const Face * m_pFace; //not NULL
|
||||
const Face * m_face;
|
||||
FeatureSetting * m_nameValues; // array of name table ids for feature values
|
||||
chunk_t m_mask, // bit mask to get the value from the vector
|
||||
m_max; // max value the value can take
|
||||
@ -98,11 +98,12 @@ private: //unimplemented
|
||||
FeatureRef& operator=(const FeatureRef&);
|
||||
};
|
||||
|
||||
|
||||
inline
|
||||
FeatureRef::FeatureRef()
|
||||
: m_pFace(0), m_nameValues(0),
|
||||
m_mask(0), m_max(0), m_id(0),
|
||||
FeatureRef::FeatureRef() throw()
|
||||
: m_face(0),
|
||||
m_nameValues(0),
|
||||
m_mask(0), m_max(0),
|
||||
m_id(0),
|
||||
m_nameid(0), m_flags(0), m_numSet(0),
|
||||
m_bits(0), m_index(0)
|
||||
{
|
||||
@ -113,13 +114,13 @@ class NameAndFeatureRef
|
||||
{
|
||||
public:
|
||||
NameAndFeatureRef(uint32 name = 0) : m_name(name) , m_pFRef(NULL){}
|
||||
NameAndFeatureRef(const FeatureRef* p/*not NULL*/) : m_name(p->getId()), m_pFRef(p) {}
|
||||
NameAndFeatureRef(FeatureRef const & p) : m_name(p.getId()), m_pFRef(&p) {}
|
||||
|
||||
bool operator<(const NameAndFeatureRef& rhs) const //orders by m_name
|
||||
{ return m_name<rhs.m_name; }
|
||||
|
||||
CLASS_NEW_DELETE
|
||||
|
||||
|
||||
uint32 m_name;
|
||||
const FeatureRef* m_pFRef;
|
||||
};
|
||||
@ -128,7 +129,7 @@ class FeatureMap
|
||||
{
|
||||
public:
|
||||
FeatureMap() : m_numFeats(0), m_feats(NULL), m_pNamedFeats(NULL) {}
|
||||
~FeatureMap() { delete [] m_feats; delete[] m_pNamedFeats; }
|
||||
~FeatureMap() { delete[] m_feats; delete[] m_pNamedFeats; }
|
||||
|
||||
bool readFeats(const Face & face);
|
||||
const FeatureRef *findFeatureRef(uint32 name) const;
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
float scale() const;
|
||||
bool isHinted() const;
|
||||
const Face & face() const;
|
||||
operator bool () const throw() { return m_advances; }
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
private:
|
||||
|
@ -34,6 +34,7 @@ of the License or (at your option) any later version.
|
||||
#include <cstdlib>
|
||||
#include <new>
|
||||
|
||||
#include "Main.h"
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
@ -104,7 +105,9 @@ void Vector<T>::reserve(size_t n)
|
||||
if (n > capacity())
|
||||
{
|
||||
const ptrdiff_t sz = size();
|
||||
m_first = static_cast<T*>(realloc(m_first, n*sizeof(T)));
|
||||
size_t requested;
|
||||
if (checked_mul(n,sizeof(T), requested)) std::abort();
|
||||
m_first = static_cast<T*>(realloc(m_first, requested));
|
||||
if (!m_first) std::abort();
|
||||
m_last = m_first + sz;
|
||||
m_end = m_first + n;
|
||||
|
@ -15,8 +15,8 @@
|
||||
|
||||
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
|
||||
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
|
||||
@ -27,11 +27,12 @@ of the License or (at your option) any later version.
|
||||
// This general interpreter interface.
|
||||
// Author: Tim Eves
|
||||
|
||||
// Build one of direct_machine.cpp or call_machine.cpp to implement this
|
||||
// Build one of direct_machine.cpp or call_machine.cpp to implement this
|
||||
// interface.
|
||||
|
||||
#pragma once
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <graphite2/Types.h>
|
||||
#include "inc/Main.h"
|
||||
|
||||
@ -56,6 +57,13 @@ of the License or (at your option) any later version.
|
||||
#define REGPARM(n)
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
// MinGW's <limits> at some point includes winnt.h which #define's a
|
||||
// DELETE macro, which conflicts with enum opcode below, so we undefine
|
||||
// it here.
|
||||
#undef DELETE
|
||||
#endif
|
||||
|
||||
namespace graphite2 {
|
||||
|
||||
// Forward declarations
|
||||
@ -64,7 +72,7 @@ class Slot;
|
||||
class SlotMap;
|
||||
|
||||
|
||||
namespace vm
|
||||
namespace vm
|
||||
{
|
||||
|
||||
|
||||
@ -112,12 +120,12 @@ enum opcode {
|
||||
PUT_GLYPH, PUSH_GLYPH_ATTR, PUSH_ATT_TO_GLYPH_ATTR,
|
||||
BITOR, BITAND, BITNOT,
|
||||
BITSET, SET_FEAT,
|
||||
MAX_OPCODE,
|
||||
MAX_OPCODE,
|
||||
// private opcodes for internal use only, comes after all other on disk opcodes
|
||||
TEMP_COPY = MAX_OPCODE
|
||||
};
|
||||
|
||||
struct opcode_t
|
||||
struct opcode_t
|
||||
{
|
||||
instr impl[2];
|
||||
uint8 param_sz;
|
||||
@ -186,6 +194,8 @@ inline Machine::status_t Machine::status() const throw()
|
||||
|
||||
inline void Machine::check_final_stack(const stack_t * const sp)
|
||||
{
|
||||
if (_status != finished) return;
|
||||
|
||||
stack_t const * const base = _stack + STACK_GUARD,
|
||||
* const limit = base + STACK_MAX;
|
||||
if (sp < base) _status = stack_underflow; // This should be impossible now.
|
||||
@ -195,6 +205,3 @@ inline void Machine::check_final_stack(const stack_t * const sp)
|
||||
|
||||
} // namespace vm
|
||||
} // namespace graphite2
|
||||
|
||||
|
||||
|
||||
|
@ -15,8 +15,8 @@
|
||||
|
||||
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
|
||||
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
|
||||
@ -77,15 +77,61 @@ public:
|
||||
struct telemetry {};
|
||||
#endif
|
||||
|
||||
// Checked multiplaction to catch overflow or underflow when allocating memory
|
||||
#if defined(__has_builtin)
|
||||
#if __has_builtin(__builtin_mul_overflow)
|
||||
#define HAVE_BUILTIN_OVERFLOW
|
||||
#endif
|
||||
#elif defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__INTEL_COMPILER)
|
||||
#define HAVE_BUILTIN_OVERFLOW
|
||||
#endif
|
||||
#if defined(__has_include)
|
||||
#if __has_include(<intsafe.h>)
|
||||
#define HAVE_INTSAFE_H
|
||||
#endif
|
||||
#elif defined(_WIN32)
|
||||
#define HAVE_INTSAFE_H
|
||||
#endif
|
||||
|
||||
// Need to import intsafe into the top level namespace
|
||||
#if defined(HAVE_INTSAFE_H)
|
||||
} // namespace graphite2
|
||||
|
||||
#include <intsafe.h>
|
||||
|
||||
namespace graphite2 {
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_BUILTIN_OVERFLOW)
|
||||
inline
|
||||
bool checked_mul(const size_t a, const size_t b, size_t & t) {
|
||||
return __builtin_mul_overflow(a, b, &t);
|
||||
}
|
||||
#elif defined(HAVE_INTSAFE_H)
|
||||
inline
|
||||
bool checked_mul(const size_t a, const size_t b, size_t & t) {
|
||||
return SizeTMult(a, b, &t) == INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
#else
|
||||
inline
|
||||
bool checked_mul(const size_t a, const size_t b, size_t & t) {
|
||||
t = a*b;
|
||||
return (((a | b) & (~size_t(0) << (sizeof(size_t) << 2))) && (t / a != b));
|
||||
}
|
||||
#endif
|
||||
|
||||
// typesafe wrapper around malloc for simple types
|
||||
// use free(pointer) to deallocate
|
||||
|
||||
template <typename T> T * gralloc(size_t n)
|
||||
{
|
||||
size_t total;
|
||||
if (checked_mul(n, sizeof(T), total))
|
||||
return 0;
|
||||
#ifdef GRAPHITE2_TELEMETRY
|
||||
telemetry::count_bytes(sizeof(T) * n);
|
||||
telemetry::count_bytes(total);
|
||||
#endif
|
||||
return static_cast<T*>(malloc(sizeof(T) * n));
|
||||
return static_cast<T*>(malloc(total));
|
||||
}
|
||||
|
||||
template <typename T> T * grzeroalloc(size_t n)
|
||||
@ -128,7 +174,7 @@ inline T max(const T a, const T b)
|
||||
|
||||
#if defined(__clang__) && __cplusplus >= 201103L
|
||||
/* clang's fallthrough annotations are only available starting in C++11. */
|
||||
#define GR_FALLTHROUGH [[clang::fallthrough]]
|
||||
#define GR_FALLTHROUGH [[fallthrough]]
|
||||
#elif defined(_MSC_VER)
|
||||
/*
|
||||
* MSVC's __fallthrough annotations are checked by /analyze (Code Analysis):
|
||||
@ -136,6 +182,8 @@ inline T max(const T a, const T b)
|
||||
*/
|
||||
#include <sal.h>
|
||||
#define GR_FALLTHROUGH __fallthrough
|
||||
#elif __GNUC__ >= 7
|
||||
#define GR_FALLTHROUGH __attribute__ ((fallthrough))
|
||||
#else
|
||||
#define GR_FALLTHROUGH /* fallthrough */
|
||||
#endif
|
||||
|
@ -205,7 +205,7 @@ int8 Segment::getSlotBidiClass(Slot *s) const
|
||||
inline
|
||||
void Segment::finalise(const Font *font, bool reverse)
|
||||
{
|
||||
if (!m_first) return;
|
||||
if (!m_first || !m_last) return;
|
||||
|
||||
m_advance = positionSlots(font, m_first, m_last, m_silf->dir(), true);
|
||||
//associateChars(0, m_numCharinfo);
|
||||
|
@ -15,8 +15,8 @@
|
||||
|
||||
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
|
||||
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
|
||||
@ -73,7 +73,7 @@ public:
|
||||
size_t size() const throw();
|
||||
|
||||
size_t _sizeof() const throw();
|
||||
|
||||
|
||||
CLASS_NEW_DELETE;
|
||||
|
||||
private:
|
||||
@ -122,10 +122,7 @@ sparse::sparse(I attr, const I last)
|
||||
+ n_values);
|
||||
|
||||
if (m_array.values == 0)
|
||||
{
|
||||
free(m_array.values); m_array.map=0;
|
||||
return;
|
||||
}
|
||||
|
||||
// coverity[forward_null : FALSE] Since m_array is union and m_array.values is not NULL
|
||||
chunk * ci = m_array.map;
|
||||
|
@ -73,7 +73,7 @@ static const opcode_t opcode_table[] =
|
||||
{{do2(gtr_eq)}, 0, "GTR_EQ"}, // 0x18
|
||||
|
||||
{{do_(next), NILOP}, 0, "NEXT"},
|
||||
{{do_(next_n), NILOP}, 1, "NEXT_N"}, // number <= smap.end - map
|
||||
{{NILOP, NILOP}, 1, "NEXT_N"}, // number <= smap.end - map
|
||||
{{do_(next), NILOP}, 0, "COPY_NEXT"},
|
||||
{{do_(put_glyph_8bit_obs), NILOP}, 1, "PUT_GLYPH_8BIT_OBS"}, // output_class
|
||||
{{do_(put_subs_8bit_obs), NILOP}, 3, "PUT_SUBS_8BIT_OBS"}, // slot input_class output_class
|
||||
|
@ -26,7 +26,7 @@ of the License or (at your option) any later version.
|
||||
*/
|
||||
#pragma once
|
||||
// This file will be pulled into and integrated into a machine implmentation
|
||||
// DO NOT build directly and under no circumstances every #include headers in
|
||||
// DO NOT build directly and under no circumstances ever #include headers in
|
||||
// here or you will break the direct_machine.
|
||||
//
|
||||
// Implementers' notes
|
||||
@ -65,7 +65,7 @@ of the License or (at your option) any later version.
|
||||
|
||||
|
||||
// #define NOT_IMPLEMENTED assert(false)
|
||||
#define NOT_IMPLEMENTED
|
||||
// #define NOT_IMPLEMENTED
|
||||
|
||||
#define binop(op) const uint32 a = pop(); *sp = uint32(*sp) op a
|
||||
#define sbinop(op) const int32 a = pop(); *sp = int32(*sp) op a
|
||||
@ -130,8 +130,10 @@ STARTOP(mul)
|
||||
ENDOP
|
||||
|
||||
STARTOP(div_)
|
||||
if (*sp == 0) DIE;
|
||||
sbinop(/);
|
||||
const int32 b = pop();
|
||||
const int32 a = int32(*sp);
|
||||
if (b == 0 || (a == std::numeric_limits<int32>::min() && b == -1)) DIE;
|
||||
*sp = int32(*sp) / b;
|
||||
ENDOP
|
||||
|
||||
STARTOP(min_)
|
||||
@ -208,12 +210,12 @@ STARTOP(next)
|
||||
++map;
|
||||
ENDOP
|
||||
|
||||
STARTOP(next_n)
|
||||
use_params(1);
|
||||
NOT_IMPLEMENTED;
|
||||
//STARTOP(next_n)
|
||||
// use_params(1);
|
||||
// NOT_IMPLEMENTED;
|
||||
//declare_params(1);
|
||||
//const size_t num = uint8(*param);
|
||||
ENDOP
|
||||
//ENDOP
|
||||
|
||||
//STARTOP(copy_next)
|
||||
// if (is) is = is->next();
|
||||
@ -337,6 +339,7 @@ STARTOP(delete_)
|
||||
else
|
||||
seg.last(is->prev());
|
||||
|
||||
|
||||
if (is == smap.highwater())
|
||||
smap.highwater(is->next());
|
||||
if (is->prev())
|
||||
|
Loading…
Reference in New Issue
Block a user