diff --git a/dtool/src/dtoolbase/pdtoa.cxx b/dtool/src/dtoolbase/pdtoa.cxx index 8055f6d49d..552391a6fc 100644 --- a/dtool/src/dtoolbase/pdtoa.cxx +++ b/dtool/src/dtoolbase/pdtoa.cxx @@ -32,6 +32,8 @@ THE SOFTWARE. #include #include #define copysign _copysign + +#pragma float_control(precise, on, push) #endif #define UINT64_C2(h, l) ((static_cast(h) << 32) | static_cast(l)) @@ -586,3 +588,7 @@ void pftoa(float value, char *buffer) { } } } + +#ifdef _MSC_VER +#pragma float_control(pop) +#endif diff --git a/panda/src/express/virtualFileMountRamdisk.cxx b/panda/src/express/virtualFileMountRamdisk.cxx index feda85d1f6..2d0449d41d 100644 --- a/panda/src/express/virtualFileMountRamdisk.cxx +++ b/panda/src/express/virtualFileMountRamdisk.cxx @@ -30,6 +30,7 @@ TypeHandle VirtualFileMountRamdisk::Directory::_type_handle; */ VirtualFileMountRamdisk:: VirtualFileMountRamdisk() : _root("") { + _root.local_object(); } /** @@ -477,6 +478,10 @@ PT(VirtualFileMountRamdisk::FileBase) VirtualFileMountRamdisk::Directory:: do_find_file(const string &filename) const { size_t slash = filename.find('/'); if (slash == string::npos) { + if (filename.empty()) { + return (FileBase *)this; + } + // Search for a file within the local directory. FileBase tfile(filename); tfile.local_object(); diff --git a/panda/src/express/virtualFileSystem.cxx b/panda/src/express/virtualFileSystem.cxx index 37c220f4ca..1f67b98840 100644 --- a/panda/src/express/virtualFileSystem.cxx +++ b/panda/src/express/virtualFileSystem.cxx @@ -1206,7 +1206,7 @@ scan_mount_points(vector_string &names, const Filename &path) const { mount_point[prefix.length()] == '/') { // This mount point is below the indicated path. Is it only one // directory below? - string basename = mount_point.substr(prefix.length()); + string basename = mount_point.substr(prefix.length() + 1); if (basename.find('/') == string::npos) { // No embedded slashes, so it's only one directory below. names.push_back(basename); diff --git a/panda/src/parametrics/ropeNode.cxx b/panda/src/parametrics/ropeNode.cxx index 21c551aebe..cf1e073c9b 100644 --- a/panda/src/parametrics/ropeNode.cxx +++ b/panda/src/parametrics/ropeNode.cxx @@ -515,8 +515,16 @@ get_connected_segments(RopeNode::CurveSegments &curve_segments, LPoint3 point; result->eval_segment_point(segment, 0.0f, point); + // We need a bit more relaxed threshold to prevent breaks between + // segments, see GitHub issue #1325. +#ifdef STDFLOAT_DOUBLE + static const double threshold = 1.0e-8; +#else + static const float threshold = 1.0e-4f; +#endif + if (curve_segment == nullptr || - !point.almost_equal(last_point)) { + !point.almost_equal(last_point, threshold)) { // If the first point of this segment is different from the last point // of the previous segment, end the previous segment and begin a new // one. diff --git a/panda/src/text/textAssembler.cxx b/panda/src/text/textAssembler.cxx index 8843ab0edb..a98abb68b3 100644 --- a/panda/src/text/textAssembler.cxx +++ b/panda/src/text/textAssembler.cxx @@ -44,6 +44,10 @@ using std::max; using std::min; using std::wstring; +enum ClusterFlags { + CF_small_caps = 0x200000, +}; + // This is the factor by which CT_small scales the character down. static const PN_stdfloat small_accent_scale = 0.6f; @@ -1538,7 +1542,20 @@ assemble_row(TextAssembler::TextRow &row, } if (graphic == nullptr && harfbuff != nullptr) { - hb_buffer_add(harfbuff, character, character); + unsigned int cluster = character; + + if (properties->get_small_caps()) { + const UnicodeLatinMap::Entry *map_entry = + UnicodeLatinMap::look_up((char32_t)character); + if (map_entry != nullptr && + map_entry->_toupper_character != (char32_t)character) { + character = map_entry->_toupper_character; + + // Set a high bit on the cluster to flag this as needing a scale. + cluster |= CF_small_caps; + } + } + hb_buffer_add(harfbuff, character, cluster); continue; } #endif @@ -1810,7 +1827,8 @@ shape_buffer(hb_buffer_t *buf, PlacedGlyphs &placed_glyphs, PN_stdfloat &xpos, hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &glyph_count); for (unsigned int i = 0; i < glyph_count; ++i) { - int character = glyph_info[i].cluster; + unsigned int cluster = glyph_info[i].cluster; + int character = cluster & 0x1fffff; int glyph_index = glyph_info[i].codepoint; CPT(TextGlyph) glyph; @@ -1849,6 +1867,12 @@ shape_buffer(hb_buffer_t *buf, PlacedGlyphs &placed_glyphs, PN_stdfloat &xpos, placement._ypos = properties.get_glyph_shift() + y_offset; placement._slant = properties.get_slant(); placement._properties = &properties; + + if (cluster & CF_small_caps) { + advance *= properties.get_small_caps_scale(); + placement._scale *= properties.get_small_caps_scale(); + } + placed_glyphs.push_back(placement); xpos += advance;